From 1f4ed72983b9ed2505352181c7ab63bde7a24f3e Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 13 Oct 2023 18:43:41 -0700 Subject: [PATCH 001/238] Add location_name_groups for Dark Souls III This allows regions and logical groups of locations to be enabled or disabled as a group from the YAML file. --- worlds/dark_souls_3/Locations.py | 112 ++++++++++++++++++++++++++++++- worlds/dark_souls_3/__init__.py | 3 +- 2 files changed, 112 insertions(+), 3 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index df241a5fd1fb..97930831315b 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1,5 +1,5 @@ from enum import IntEnum -from typing import Optional, NamedTuple, Dict +from typing import Optional, NamedTuple, Dict, Set from BaseClasses import Location, Region @@ -688,6 +688,114 @@ def get_name_to_id() -> dict: [DS3LocationData(f"Undead Bone Shard #{i + 1}", "Undead Bone Shard", DS3LocationCategory.HEALTH) for i in range(10)], } +# In addition to these hand-authored location groups, every region automatically +# has a location group added in the loop below. +location_name_groups: Dict[str, Set[str]] = { + # Locations that are very obvious: boss/miniboss drops (one per boss), keys, + # items unlocked by keys, visibly guarded items, or items at the end of a + # bossless area. Intended for players without broad DS3 knowledge or who + # want fewer, more obvious checks. + "Prominent Locations": frozenset([ + "FS: Tower Key", + "FS: Uchigatana", + "FSBT: Covetous Silver Serpent Ring", + "FSBT: Fire Keeper Robe", + "FSBT: Fire Keeper Gloves", + "FSBT: Fire Keeper Skirt", + "FSBT: Estus Ring", + "FSBT: Fire Keeper Soul", + "HWL: Basin of Vows", + "HWL: Small Lothric Banner", + "HWL: Cell Key", + "HWL: Soul of Boreal Valley Vordt", + "HWL: Soul of the Dancer", + "US: Soul of the Rotted Greatwood", + "US: Flynn's Ring", # Reward for killing the Fire Demon + "US: Irithyll Straight Sword", # Irithyll Outrider drop + "RS: Farron Coal", + "RS: Soul of a Crystal Sage", + "FK: Cinders of a Lord - Abyss Watcher", + "FK: Soul of a Stray Demon", + "CD: Spider Shield", # NPC drop + "CD: Small Doll", + "CC: Soul of a Demon", + "CC: Soul of High Lord Wolnir", + "SL: Lightning Stake", + "SL: Soul of Old Demon King", + "SL: Fume Ultra Greatsword", # Knight Slayer Tsorig drop + "SL: Dragonrider Bow", # Reward for making it through the Smouldering + # Lake dungeon. + "IBV: Pontiff's Right Eye", # Sulyvahn's Beast drop + "IBV: Soul of Pontiff Sulyvahn", + "IBV: Ring of Favor", # Sulyvahn's Beast Duo drop + "ID: Jailbreaker's Key", + "ID: Old Cell Key", + "ID: Profaned Coal", + "ID: Jailer's Key King", + "PC: Logan's Scroll", # NPC drop + "PC: Cinders of a Lord - Yhorm the Giant", + "AL: Cinders of a Lord - Aldritch", + "LC: Irithyll Rapier", # Boreal Outrider drop + "LC: Soul of Dragonslayer Armour", + "LC: Grand Archives Key", + "CKG: Soul of Consumed Oceiros", + "UG: Soul of Champion Gundyr", + "UG: Eyes of a Fire Keeper", + "GA: Crystal Scroll", # Crystal Sage drop + "GA: Golden Wing Crest Shield", # NPC drop + "GA: Onikiri and Ubadachi", # NPC drop + "GA: Sage's Crystal Staff", # NPC drop + "GA: Outrider Knight Helm", # Boreal Outrider drop + "GA: Cinders of a Lord - Lothric Prince", + "AP: Dragon Head Stone", # Ancient Wyvern drop + "AP: Dragon Tooth", # NPC drop + "AP: Soul of the Nameless King", + "PW: Valorheart", # Champion's Graveyender drop + "PW: Contraption Key", + "PW: Soul of Sister Friede", + "DH: Soul of the Demon Prince", + "DH: Flame Fan", # Desert Pyromancer Zoey drop + "DH: Small Envoy Banner", + "RC: Fillianore's Spear Ornament", + "RC: Soul of Darkeater Midir", + "RC: Crucifix of the Mad King", # Shira drop + "RC: Soul of Slave Knight Gael", + ]), + + # Locations that are particularly tricky to find or get to, for players + # without an encyclopedic knowledge of DS3 who don't want to get stuck + # looking for an invisible wall or one random mob with a guaranteed drop. + "Hidden Locations": frozenset([ + # TODO: this list isn't at all comprehensive, expand it + + # Behind illusory walls + "FS: Covetous Silver Serpent Ring", + "IBV: Ring of Favor", + "GA: Outrider Knight Helm", + "GA: Soul Stream", + + "UG: Ashen Estus Ring", + "UG: Black Knight Glaive", + "UG: Hornet Ring", + "UG: Chaos Blade", + "UG: Blacksmith Hammer", + "UG: Eyes of a Fire Keeper", + "UG: Coiled Sword Fragment", + "UG: Soul of Champion Gundyr", + ]) +} + location_dictionary: Dict[str, DS3LocationData] = {} -for location_table in location_tables.values(): +for location_name, location_table in location_tables.items(): location_dictionary.update({location_data.name: location_data for location_data in location_table}) + + # Allow entire locations to be added to location sets. + location_name_groups[location_name] = frozenset([ + location_data.name for location_data in location_table + if not location_data.name.startswith("Progressive Items") + ]) + +location_name_groups["Painted World of Ariandel"] = \ + location_name_groups["Painted World of Ariandel 1"].union(location_name_groups["Painted World of Ariandel 2"]) +del location_name_groups["Painted World of Ariandel 1"] +del location_name_groups["Painted World of Ariandel 2"] diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 195d319887d5..76d2cfb846c2 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -8,7 +8,7 @@ from worlds.generic.Rules import set_rule, add_rule, add_item_rule from .Items import DarkSouls3Item, DS3ItemCategory, item_dictionary, key_item_names -from .Locations import DarkSouls3Location, DS3LocationCategory, location_tables, location_dictionary +from .Locations import DarkSouls3Location, DS3LocationCategory, location_tables, location_dictionary, location_name_groups from .Options import RandomizeWeaponLevelOption, PoolTypeOption, dark_souls_options @@ -52,6 +52,7 @@ class DarkSouls3World(World): required_client_version = (0, 4, 2) item_name_to_id = DarkSouls3Item.get_name_to_id() location_name_to_id = DarkSouls3Location.get_name_to_id() + location_name_groups = location_name_groups item_name_groups = { "Cinders": { "Cinders of a Lord - Abyss Watcher", From f5a8ee169dc51c1721f54d8201e59c686d4b8e09 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 13 Oct 2023 21:34:25 -0700 Subject: [PATCH 002/238] Add DC: Dragonhead Shield as a hidden item --- worlds/dark_souls_3/Locations.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 97930831315b..1b986d5525f1 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -768,6 +768,8 @@ def get_name_to_id() -> dict: "Hidden Locations": frozenset([ # TODO: this list isn't at all comprehensive, expand it + "DC: Dragonhead Shield", # requires gesture + # Behind illusory walls "FS: Covetous Silver Serpent Ring", "IBV: Ring of Favor", From 908159b87da8a7888bec674f6262172029c3c4c6 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 14 Oct 2023 21:05:08 -0700 Subject: [PATCH 003/238] Add more hidden locations --- worlds/dark_souls_3/Locations.py | 37 +++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 1b986d5525f1..fa1ca6c18ed0 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -769,13 +769,48 @@ def get_name_to_id() -> dict: # TODO: this list isn't at all comprehensive, expand it "DC: Dragonhead Shield", # requires gesture + "SL: Speckled Stoneplate Ring", # requires careful ballista shot + + # Out-of-the-way cave + "FK: Golden Scroll", + "FK: Antiquated Dress", + "FK: Antiquated Gloves", + "FK: Antiquated Skirt", + + # In lava + "SL: Toxic Mist", + "SL: White Hair Talisman", + "SL: Sacred Flame" + + # Guaranteed drop from normalish enemy + "CD: Deep Ring" + + # Hidden falls + "US: Chloranthy Ring", + "US: Mirrah Vest", + "US: Mirrah Gloves", + "US: Mirrah Trousers", + "RS: Braille Divine Tome of Carim", + "RS: Morne's Ring", + "RS: Sorcerer Hood", + "RS: Sorcerer Robe", + "RS: Sorcerer Gloves", + "RS: Sorcerer Trousers", + "RS: Sage Ring", + "FK: Atonement", + "SL: Dragonrider Bow", + "CD: Arbalest", # Behind illusory walls "FS: Covetous Silver Serpent Ring", "IBV: Ring of Favor", "GA: Outrider Knight Helm", "GA: Soul Stream", - + "FK: Dreamchaser's Ashes", + "CC: Carthus Pyromancy Tome", + "SL: Black Knight Sword", + "SL: Quelana Pyromancy Tome", + "SL: Izalith Staff", "UG: Ashen Estus Ring", "UG: Black Knight Glaive", "UG: Hornet Ring", From 5d5f8aea9e2d08b200e9ba2e776695432dfa02e3 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 14 Oct 2023 21:10:23 -0700 Subject: [PATCH 004/238] Update a couple prominent locations --- worlds/dark_souls_3/Locations.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index fa1ca6c18ed0..a588ecd6e550 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -710,7 +710,9 @@ def get_name_to_id() -> dict: "HWL: Soul of Boreal Valley Vordt", "HWL: Soul of the Dancer", "US: Soul of the Rotted Greatwood", - "US: Flynn's Ring", # Reward for killing the Fire Demon + "US: Flynn's Ring", # The Fire Demon in Undead Settlement doesn't drop a + # randomizable item, so this is the next best option + # as a reward for that section. "US: Irithyll Straight Sword", # Irithyll Outrider drop "RS: Farron Coal", "RS: Soul of a Crystal Sage", @@ -718,13 +720,14 @@ def get_name_to_id() -> dict: "FK: Soul of a Stray Demon", "CD: Spider Shield", # NPC drop "CD: Small Doll", + "CD: Saint Biden", # Guarded by giant "CC: Soul of a Demon", "CC: Soul of High Lord Wolnir", "SL: Lightning Stake", "SL: Soul of Old Demon King", "SL: Fume Ultra Greatsword", # Knight Slayer Tsorig drop - "SL: Dragonrider Bow", # Reward for making it through the Smouldering - # Lake dungeon. + "SL: Izalith Pyromancy Tome", # Reward for making it through the + # Smouldering Lake dungeon. "IBV: Pontiff's Right Eye", # Sulyvahn's Beast drop "IBV: Soul of Pontiff Sulyvahn", "IBV: Ring of Favor", # Sulyvahn's Beast Duo drop From 3f70dfa708e128bb76fccfa67a3188539d6e675d Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 15 Oct 2023 15:51:40 -0700 Subject: [PATCH 005/238] Update worlds/dark_souls_3/Locations.py Co-authored-by: el-u <109771707+el-u@users.noreply.github.com> --- worlds/dark_souls_3/Locations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index a588ecd6e550..9dc48d4f4da7 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -720,7 +720,7 @@ def get_name_to_id() -> dict: "FK: Soul of a Stray Demon", "CD: Spider Shield", # NPC drop "CD: Small Doll", - "CD: Saint Biden", # Guarded by giant + "CD: Saint Bident", # Guarded by giant "CC: Soul of a Demon", "CC: Soul of High Lord Wolnir", "SL: Lightning Stake", From 06b0c81c5016e5a862b766b783edf50abd31c257 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 15 Oct 2023 16:28:11 -0700 Subject: [PATCH 006/238] Add a few more hidden locations --- worlds/dark_souls_3/Locations.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 9dc48d4f4da7..1a5ba18bce2e 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -788,6 +788,11 @@ def get_name_to_id() -> dict: # Guaranteed drop from normalish enemy "CD: Deep Ring" + # Have to return to cleared area + "CD: Archdeacon White Crown", + "CD: Archdeacon Holy Garb", + "CD: Archdeacon Skirt", + # Hidden falls "US: Chloranthy Ring", "US: Mirrah Vest", @@ -803,6 +808,9 @@ def get_name_to_id() -> dict: "FK: Atonement", "SL: Dragonrider Bow", "CD: Arbalest", + "LC: Sunlight Straight Sword", + "LC: Braille Divine Tome of Lothric", + "CD: Rosaria's Fingers", # Behind illusory walls "FS: Covetous Silver Serpent Ring", From 632b04f625e3b4029cd334dec3ed11e554e8115c Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 15 Oct 2023 17:57:20 -0700 Subject: [PATCH 007/238] Split into more semantic location name groups --- worlds/dark_souls_3/Locations.py | 185 ++++++++++++++++++++++--------- 1 file changed, 135 insertions(+), 50 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 1a5ba18bce2e..2944c5937a1f 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -691,78 +691,163 @@ def get_name_to_id() -> dict: # In addition to these hand-authored location groups, every region automatically # has a location group added in the loop below. location_name_groups: Dict[str, Set[str]] = { - # Locations that are very obvious: boss/miniboss drops (one per boss), keys, - # items unlocked by keys, visibly guarded items, or items at the end of a - # bossless area. Intended for players without broad DS3 knowledge or who - # want fewer, more obvious checks. + # A small number of locations (boss drops and progression locations) + # intended to be set as priority progression locations for players who don't + # want a lot of mandatory checks. "Prominent Locations": frozenset([ - "FS: Tower Key", - "FS: Uchigatana", - "FSBT: Covetous Silver Serpent Ring", - "FSBT: Fire Keeper Robe", - "FSBT: Fire Keeper Gloves", - "FSBT: Fire Keeper Skirt", - "FSBT: Estus Ring", - "FSBT: Fire Keeper Soul", "HWL: Basin of Vows", "HWL: Small Lothric Banner", - "HWL: Cell Key", + "CD: Small Doll", + "FK: Cinders of a Lord - Abyss Watcher", + "PC: Cinders of a Lord - Yhorm the Giant", + "AL: Cinders of a Lord - Aldrich", + "GA: Cinders of a Lord - Lothric Prince", + "LC: Grand Archives Key", + "PW: Contraption Key", + "HWL: Soul of Boreal Valley Vordt", + "US: Soul of the Rotted Greatwood", + "RS: Soul of a Crystal Sage", + "CC: Soul of High Lord Wolnir", + "SL: Soul of the Old Demon King", + "IBV: Soul of Pontiff Sulyvahn", "HWL: Soul of the Dancer", + "LC: Soul of Dragonslayer Armour", + "CKG: Soul of Consumed Oceiros", + "UG: Soul of Champion Gundyr", + "AP: Soul of the Nameless King", + "PW: Soul of Sister Friede", + "PW: Valorheart", + "DH: Soul of the Demon Prince", + "RC: Soul of Darkeater Midir", + ]), + + # Locations that contain items which block forward progress in the normal + # game order. + "Progression Locations": frozenset([ + "HWL: Basin of Vows", + "HWL: Small Lothric Banner", + "CD: Small Doll", + "FK: Cinders of a Lord - Abyss Watcher", + "PC: Cinders of a Lord - Yhorm the Giant", + "AL: Cinders of a Lord - Aldrich", + "GA: Cinders of a Lord - Lothric Prince", + "LC: Grand Archives Key", + "PW: Contraption Key", + ]), + + "Boss Rewards": frozenset([ + "HWL: Soul of Boreal Valley Vordt", + "US: Transposing Kiln", "US: Soul of the Rotted Greatwood", - "US: Flynn's Ring", # The Fire Demon in Undead Settlement doesn't drop a - # randomizable item, so this is the next best option - # as a reward for that section. - "US: Irithyll Straight Sword", # Irithyll Outrider drop - "RS: Farron Coal", "RS: Soul of a Crystal Sage", + "FK: Soul of the Blood of the Wolf", "FK: Cinders of a Lord - Abyss Watcher", - "FK: Soul of a Stray Demon", - "CD: Spider Shield", # NPC drop "CD: Small Doll", - "CD: Saint Bident", # Guarded by giant - "CC: Soul of a Demon", + "CD: Soul of the Deacons of the Deep", + "CD: Archdeacon White Crown", + "CD: Archdeacon Holy Garb", + "CD: Archdeacon Skirt", "CC: Soul of High Lord Wolnir", - "SL: Lightning Stake", - "SL: Soul of Old Demon King", - "SL: Fume Ultra Greatsword", # Knight Slayer Tsorig drop - "SL: Izalith Pyromancy Tome", # Reward for making it through the - # Smouldering Lake dungeon. - "IBV: Pontiff's Right Eye", # Sulyvahn's Beast drop + "SL: Soul of the Old Demon King", "IBV: Soul of Pontiff Sulyvahn", - "IBV: Ring of Favor", # Sulyvahn's Beast Duo drop - "ID: Jailbreaker's Key", - "ID: Old Cell Key", - "ID: Profaned Coal", - "ID: Jailer's Key King", - "PC: Logan's Scroll", # NPC drop + "PC: Soul of Yhorm the Giant", "PC: Cinders of a Lord - Yhorm the Giant", - "AL: Cinders of a Lord - Aldritch", - "LC: Irithyll Rapier", # Boreal Outrider drop + "AL: Soul of Aldrich", + "AL: Cinders of a Lord - Aldrich", + "HWL: Soul of the Dancer", "LC: Soul of Dragonslayer Armour", - "LC: Grand Archives Key", "CKG: Soul of Consumed Oceiros", "UG: Soul of Champion Gundyr", - "UG: Eyes of a Fire Keeper", - "GA: Crystal Scroll", # Crystal Sage drop - "GA: Golden Wing Crest Shield", # NPC drop - "GA: Onikiri and Ubadachi", # NPC drop - "GA: Sage's Crystal Staff", # NPC drop - "GA: Outrider Knight Helm", # Boreal Outrider drop + "UG: Coiled Sword Fragment", + "GA: Soul of the Twin Princes", "GA: Cinders of a Lord - Lothric Prince", - "AP: Dragon Head Stone", # Ancient Wyvern drop - "AP: Dragon Tooth", # NPC drop "AP: Soul of the Nameless King", - "PW: Valorheart", # Champion's Graveyender drop - "PW: Contraption Key", "PW: Soul of Sister Friede", + "PW: Valorheart", + "PW: Champion's Bones", "DH: Soul of the Demon Prince", - "DH: Flame Fan", # Desert Pyromancer Zoey drop "DH: Small Envoy Banner", - "RC: Fillianore's Spear Ornament", "RC: Soul of Darkeater Midir", + + # Not currently randomized + # "FS: Coiled Sword", + # "AP: Dragon Head Stone", + # "RC: Fillianore's Spear Ornament", + # "RC: Spears of the Church", + ]), + + "Miniboss Rewards": frozenset([ + "FS: Uchigatana", # NPC drop + "FK: Soul of a Stray Demon", + "US: Irithyll Straight Sword", # Irithyll Outrider drop + "CC: Soul of a Demon", + "SL: Lightning Stake", # Sand Worm drop + "SL: Fume Ultra Greatsword", # Knight Slayer Tsorig drop + "CD: Aldrich's Sapphire", # Deep Accursed drop + "CD: Spider Shield", # NPC drop + "CD: Saint Bident", # Guarded by giant + "IBV: Pontiff's Right Eye", # Sulyvahn's Beast drop + "IBV: Ring of Favor", # Sulyvahn's Beast Duo drop + "AL: Aldrich's Ruby", # Deep Accursed drop + "PC: Logan's Scroll", # NPC drop + "LC: Irithyll Rapier", # Boreal Outrider drop + "GA: Crystal Scroll", # Crystal Sage drop + "GA: Outrider Knight Helm", + "GA: Outrider Knight Armor", + "GA: Outrider Knight Gauntlets", + "GA: Outrider Knight Leggings", + "GA: Golden Wing Crest Shield", # NPC drop + "GA: Onikiri and Ubadachi", # NPC drop + "GA: Sage's Crystal Staff", # NPC drop + "AP: Dragon Tooth", # NPC drop + "DH: Flame Fan", # Desert Pyromancer Zoey drop + "RC: Iron Dragonslayer Helm", + "RC: Iron Dragonslayer Armor", + "RC: Iron Dragonslayer Gauntlets", + "RC: Iron Dragonslayer Leggings", "RC: Crucifix of the Mad King", # Shira drop - "RC: Soul of Slave Knight Gael", + ]), + + "Key Locations": frozenset([ + "HWL: Cell Key", + "ID: Jailer's Key King", + "ID: Jailbreaker's Key", + "ID: Old Cell Key", + "LC: Grand Archives Key", + "PW: Contraption Key", + + # Not currently randomized: + # "FS: Grave Key", + # "FS: Lift Chamber Key", + # "FS: Tower Key", + ]), + + "Guarded by Keys": frozenset([ + # Guarded by Tower Key + "FSBT: Covetous Silver Serpent Ring", + "FSBT: Fire Keeper Robe", + "FSBT: Fire Keeper Gloves", + "FSBT: Fire Keeper Skirt", + "FSBT: Estus Ring", + "FSBT: Fire Keeper Soul", + + # Guarded by Cell Key + "HWL: Greirat's Ashes", + + # Guarded by Jailer's Key Ring + "ID: Prisoner Chief's Ashes", + "ID: Karla's Ashes", + "ID: Karla's Pointed Hat", + "ID: Karla's Coat", + "ID: Karla's Gloves", + "ID: Karla's Trousers", + + # Guarded by Jailbreaker's Key + "ID: Bellowing Dragoncrest Ring", + + # Guarded by Old Cell Key + "ID: Covetous Gold Serpent Ring", ]), # Locations that are particularly tricky to find or get to, for players From f5fbe9c53be529ac4da8df3373ad9f41714d6770 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 15 Oct 2023 18:52:17 -0700 Subject: [PATCH 008/238] Properly exclude progressive items from location groups --- worlds/dark_souls_3/Locations.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 2944c5937a1f..345166b0a232 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -923,10 +923,10 @@ def get_name_to_id() -> dict: location_dictionary.update({location_data.name: location_data for location_data in location_table}) # Allow entire locations to be added to location sets. - location_name_groups[location_name] = frozenset([ - location_data.name for location_data in location_table - if not location_data.name.startswith("Progressive Items") - ]) + if not location_name.startswith("Progressive Items"): + location_name_groups[location_name] = frozenset([ + location_data.name for location_data in location_table + ]) location_name_groups["Painted World of Ariandel"] = \ location_name_groups["Painted World of Ariandel 1"].union(location_name_groups["Painted World of Ariandel 2"]) From 274e81ef0bf373e267bd53cb8478715a5e5021d9 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 17 Oct 2023 02:51:22 -0700 Subject: [PATCH 009/238] Add more hidden items --- worlds/dark_souls_3/Locations.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 345166b0a232..2cfc9014331c 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -789,8 +789,10 @@ def get_name_to_id() -> dict: "CD: Saint Bident", # Guarded by giant "IBV: Pontiff's Right Eye", # Sulyvahn's Beast drop "IBV: Ring of Favor", # Sulyvahn's Beast Duo drop + "IBV: Aldrich Faithful", # Sulyvahn's Beast Duo reward "AL: Aldrich's Ruby", # Deep Accursed drop "PC: Logan's Scroll", # NPC drop + "PC: Eleonora", # Monstrosity of Sin drop "LC: Irithyll Rapier", # Boreal Outrider drop "GA: Crystal Scroll", # Crystal Sage drop "GA: Outrider Knight Helm", @@ -868,16 +870,29 @@ def get_name_to_id() -> dict: # In lava "SL: Toxic Mist", "SL: White Hair Talisman", - "SL: Sacred Flame" + "SL: Sacred Flame", # Guaranteed drop from normalish enemy - "CD: Deep Ring" + "CD: Deep Ring", + "PC: Eleonora", + "ID: Great Magic Shield", # Have to return to cleared area "CD: Archdeacon White Crown", "CD: Archdeacon Holy Garb", "CD: Archdeacon Skirt", + # Invisible walkway + "IBV: Painting Guardian's Curved Sword", + "IBV: Painting Guardian Hood", + "IBV: Painting Guardian Gown", + "IBV: Painting Guardian Gloves", + "IBV: Painting Guardian Waistcloth", + + # Switch in darkened room + "GA: Witch's Locks", + "GA: Power Within", + # Hidden falls "US: Chloranthy Ring", "US: Mirrah Vest", @@ -896,6 +911,9 @@ def get_name_to_id() -> dict: "LC: Sunlight Straight Sword", "LC: Braille Divine Tome of Lothric", "CD: Rosaria's Fingers", + "PW: Crow Quills", + # "PC: Onislayer Greatbow", # Not currently randomized + "GA: Avelyn", # Behind illusory walls "FS: Covetous Silver Serpent Ring", @@ -907,6 +925,10 @@ def get_name_to_id() -> dict: "SL: Black Knight Sword", "SL: Quelana Pyromancy Tome", "SL: Izalith Staff", + "IBV: Magic Clutch Ring", + "IBV: Dorhys' Gnawing", + "IBV: Witchtree Branch", + "IBV: Aldrich Faithful", "UG: Ashen Estus Ring", "UG: Black Knight Glaive", "UG: Hornet Ring", From c8345723dbfe1683cfe53e9b894ff382e9103ec2 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 17 Oct 2023 13:30:04 -0700 Subject: [PATCH 010/238] Remove Eleonora from miniboss drops --- worlds/dark_souls_3/Locations.py | 1 - 1 file changed, 1 deletion(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 2cfc9014331c..75012b69b5fa 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -792,7 +792,6 @@ def get_name_to_id() -> dict: "IBV: Aldrich Faithful", # Sulyvahn's Beast Duo reward "AL: Aldrich's Ruby", # Deep Accursed drop "PC: Logan's Scroll", # NPC drop - "PC: Eleonora", # Monstrosity of Sin drop "LC: Irithyll Rapier", # Boreal Outrider drop "GA: Crystal Scroll", # Crystal Sage drop "GA: Outrider Knight Helm", From 4b6515b37820217bcb498b715e5fc5fcd7b296ea Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 18 Oct 2023 18:09:07 -0700 Subject: [PATCH 011/238] Add a few more hidden items --- worlds/dark_souls_3/Locations.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 75012b69b5fa..b2e249654737 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -936,6 +936,11 @@ def get_name_to_id() -> dict: "UG: Eyes of a Fire Keeper", "UG: Coiled Sword Fragment", "UG: Soul of Champion Gundyr", + "LC: Sacred Bloom Shield", + "LC: Winged Knight Helm", + "LC: Winged Knight Armor", + "LC: Winged Knight Gauntlets", + "LC: Winged Knight Leggings", ]) } From c547843c7ddd545b235bbeabcbe8e0f1de91d43c Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 19 Oct 2023 13:02:00 -0700 Subject: [PATCH 012/238] Update worlds/dark_souls_3/Locations.py Co-authored-by: Scipio Wright --- worlds/dark_souls_3/Locations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index b2e249654737..f5d3e45655ce 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -812,7 +812,7 @@ def get_name_to_id() -> dict: "Key Locations": frozenset([ "HWL: Cell Key", - "ID: Jailer's Key King", + "ID: Jailer's Key Ring", "ID: Jailbreaker's Key", "ID: Old Cell Key", "LC: Grand Archives Key", From 6be4ad31efe25e120ebe52f6eebf106380f43c66 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 19 Oct 2023 13:02:08 -0700 Subject: [PATCH 013/238] Update worlds/dark_souls_3/Locations.py Co-authored-by: Scipio Wright --- worlds/dark_souls_3/Locations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index f5d3e45655ce..9fb4b8ddd68f 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -857,7 +857,7 @@ def get_name_to_id() -> dict: "Hidden Locations": frozenset([ # TODO: this list isn't at all comprehensive, expand it - "DC: Dragonhead Shield", # requires gesture + "RC: Dragonhead Shield", # requires gesture "SL: Speckled Stoneplate Ring", # requires careful ballista shot # Out-of-the-way cave From 21c29857e9c70913c7e17f44d328a60357cc929a Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 19 Oct 2023 13:35:29 -0700 Subject: [PATCH 014/238] Fix Covetous Silver Serpent Ring location --- worlds/dark_souls_3/Locations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 9fb4b8ddd68f..abc5fd6b11d6 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -915,7 +915,7 @@ def get_name_to_id() -> dict: "GA: Avelyn", # Behind illusory walls - "FS: Covetous Silver Serpent Ring", + "FSBT: Covetous Silver Serpent Ring", "IBV: Ring of Favor", "GA: Outrider Knight Helm", "GA: Soul Stream", From a53dea3706999026a447be3e1042996bf1c58416 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 24 Oct 2023 01:09:33 -0700 Subject: [PATCH 015/238] 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. --- worlds/dark_souls_3/Locations.py | 93 +++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 18 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index abc5fd6b11d6..a241c987a9de 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -294,6 +294,7 @@ def get_name_to_id() -> dict: DS3LocationData("CC: Black Blade", "Black Blade", DS3LocationCategory.WEAPON), DS3LocationData("CC: Soul of High Lord Wolnir", "Soul of High Lord Wolnir", DS3LocationCategory.BOSS), DS3LocationData("CC: Soul of a Demon", "Soul of a Demon", DS3LocationCategory.BOSS), + DS3LocationData("CC: Knight Slayer's Ring", "Knight Slayer's Ring", DS3LocationCategory.RING), ], "Smouldering Lake": [ DS3LocationData("SL: Shield of Want", "Shield of Want", DS3LocationCategory.SHIELD), @@ -310,7 +311,6 @@ def get_name_to_id() -> dict: DS3LocationData("SL: Fume Ultra Greatsword", "Fume Ultra Greatsword", DS3LocationCategory.WEAPON), DS3LocationData("SL: Black Iron Greatshield", "Black Iron Greatshield", DS3LocationCategory.SHIELD), DS3LocationData("SL: Soul of the Old Demon King", "Soul of the Old Demon King", DS3LocationCategory.BOSS), - DS3LocationData("SL: Knight Slayer's Ring", "Knight Slayer's Ring", DS3LocationCategory.RING), ], "Irithyll of the Boreal Valley": [ DS3LocationData("IBV: Dorhys' Gnawing", "Dorhys' Gnawing", DS3LocationCategory.SPELL), @@ -778,36 +778,68 @@ def get_name_to_id() -> dict: ]), "Miniboss Rewards": frozenset([ - "FS: Uchigatana", # NPC drop - "FK: Soul of a Stray Demon", + "US: Bloodbite Ring", # Giant Rat drop "US: Irithyll Straight Sword", # Irithyll Outrider drop + "RS: Great Swamp Ring", # Great Crab drop + "FK: Soul of a Stray Demon", + "FK: Lingering Dragoncrest Ring", # Great Crab drop "CC: Soul of a Demon", "SL: Lightning Stake", # Sand Worm drop - "SL: Fume Ultra Greatsword", # Knight Slayer Tsorig drop "CD: Aldrich's Sapphire", # Deep Accursed drop - "CD: Spider Shield", # NPC drop "CD: Saint Bident", # Guarded by giant "IBV: Pontiff's Right Eye", # Sulyvahn's Beast drop "IBV: Ring of Favor", # Sulyvahn's Beast Duo drop "IBV: Aldrich Faithful", # Sulyvahn's Beast Duo reward "AL: Aldrich's Ruby", # Deep Accursed drop - "PC: Logan's Scroll", # NPC drop "LC: Irithyll Rapier", # Boreal Outrider drop "GA: Crystal Scroll", # Crystal Sage drop "GA: Outrider Knight Helm", "GA: Outrider Knight Armor", "GA: Outrider Knight Gauntlets", "GA: Outrider Knight Leggings", - "GA: Golden Wing Crest Shield", # NPC drop - "GA: Onikiri and Ubadachi", # NPC drop - "GA: Sage's Crystal Staff", # NPC drop - "AP: Dragon Tooth", # NPC drop - "DH: Flame Fan", # Desert Pyromancer Zoey drop "RC: Iron Dragonslayer Helm", "RC: Iron Dragonslayer Armor", "RC: Iron Dragonslayer Gauntlets", "RC: Iron Dragonslayer Leggings", - "RC: Crucifix of the Mad King", # Shira drop + ]), + + "Mimic Rewards": frozenset([ + "HWL: Deep Battle Axe", + "CC: Black Blade", + "CD: Deep Braille Divine Tome", + "IBV: Golden Ritual Spear", + "ID: Dark Clutch Ring", + "PC: Court Sorcerer's Staff", + "PC: Greatshield of Glory", + "LC: Sunlight Straight Sword", + "RC: Ring of the Evil Eye+3", + ]), + + "Hostile NPC Rewards": frozenset([ + "FS: Uchigatana", # Sword Master + "FS: Master's Attire", # Sword Master + "FS: Master's Gloves", # Sword Master + "RS: Exile Greatsword", # Exile Knight #1 + "RS: Great Club", # Exile Knight #2 + "CC: Knight Slayer's Ring", # Knight Slayer Tsorig (ember required) + "SL: Fume Ultra Greatsword", # Knight Slayer Tsorig + "SL: Black Iron Greatshield", # Knight Slayer Tsorig + "CD: Spider Shield", # Brigand + "PC: Logan's Scroll", # Sorcerer on roof in toxic pool + "GA: Golden Wing Crest Shield", # Lion Knight Albert + "GA: Onikiri and Ubadachi", # Black Hand Kamui + "GA: Sage's Crystal Staff", # Daughter of Crystal Kriemhild + "AP: Dragon Tooth", # Havel Knight + "DH: Flame Fan", # Desert Pyromancer Zoey drop + "RC: Wolf Ring+3", # Alva + "RC: Crucifix of the Mad King", # Shira + "PW: Contraption Key", # Sir Vilhelm + "PW: Onyx Blade", # Sir Vilhelm + + # Not currently randomized: + # "AP: Havel's Greatshield", # Havel Knight + # "RC: Ledo's Great Hammer", # Silver Knight Ledo + # "RC: Blindfold Mask", # Moaning Knight ]), "Key Locations": frozenset([ @@ -855,8 +887,6 @@ def get_name_to_id() -> dict: # without an encyclopedic knowledge of DS3 who don't want to get stuck # looking for an invisible wall or one random mob with a guaranteed drop. "Hidden Locations": frozenset([ - # TODO: this list isn't at all comprehensive, expand it - "RC: Dragonhead Shield", # requires gesture "SL: Speckled Stoneplate Ring", # requires careful ballista shot @@ -872,9 +902,14 @@ def get_name_to_id() -> dict: "SL: Sacred Flame", # Guaranteed drop from normalish enemy - "CD: Deep Ring", - "PC: Eleonora", - "ID: Great Magic Shield", + "RS: Butcher Knife", # Butcher drop + "CD: Deep Ring", # Deacon drop + "FK: Pharis's Hat", # Elder Ghru drop + "FK: Black Bow of Pharis", # Elder Ghru drop + "ID: Great Magic Shield", # Corpse-Grub drop + "PC: Eleonora", # Monstrosity of Sin drop + "CKG: Magic Stoneplate Ring", # Consumed King's Knight drop + "RC: Ringed Knight Paired Greatswords", # Ringed Knight drop # Have to return to cleared area "CD: Archdeacon White Crown", @@ -892,8 +927,24 @@ def get_name_to_id() -> dict: "GA: Witch's Locks", "GA: Power Within", + # Ember-required invader rewards + "CC: Knight Slayer's Ring", + + # Gesture requirements + "AP: Calamity Ring", + "AP: Twinkling Dragon Torso Stone", + + # Drop from a summon who may or may not appear + "AP: Drakeblood Greatsword", + "AP: Ricard's Rapier", + + # "Show Your Humanity" puzzle + "RC: Dragonhead Shield", + # Hidden falls + "HWL: Astora's Straight Sword", "US: Chloranthy Ring", + "US: Warrior of Sunlight", "US: Mirrah Vest", "US: Mirrah Gloves", "US: Mirrah Trousers", @@ -911,8 +962,11 @@ def get_name_to_id() -> dict: "LC: Braille Divine Tome of Lothric", "CD: Rosaria's Fingers", "PW: Crow Quills", - # "PC: Onislayer Greatbow", # Not currently randomized "GA: Avelyn", + "RC: Chloranthy Ring+3", + "RC: Havel's Ring+3", + # "CC: Ring of Steel Protection+2", # Not currently randomized + # "PC: Onislayer Greatbow", # Not currently randomized # Behind illusory walls "FSBT: Covetous Silver Serpent Ring", @@ -941,6 +995,9 @@ def get_name_to_id() -> dict: "LC: Winged Knight Armor", "LC: Winged Knight Gauntlets", "LC: Winged Knight Leggings", + "DH: Great Soul Dregs", + "DH: Covetous Silver Serpent Ring+3", + # "SL: Flame Stoneplate Ring+2", # Not currently randomized ]) } From 2de3b255737a8f3cb32d07c27055c4d0f545bb6e Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 24 Oct 2023 02:34:37 -0700 Subject: [PATCH 016/238] 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". --- worlds/dark_souls_3/Locations.py | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index a241c987a9de..d52117188954 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -856,33 +856,6 @@ def get_name_to_id() -> dict: # "FS: Tower Key", ]), - "Guarded by Keys": frozenset([ - # Guarded by Tower Key - "FSBT: Covetous Silver Serpent Ring", - "FSBT: Fire Keeper Robe", - "FSBT: Fire Keeper Gloves", - "FSBT: Fire Keeper Skirt", - "FSBT: Estus Ring", - "FSBT: Fire Keeper Soul", - - # Guarded by Cell Key - "HWL: Greirat's Ashes", - - # Guarded by Jailer's Key Ring - "ID: Prisoner Chief's Ashes", - "ID: Karla's Ashes", - "ID: Karla's Pointed Hat", - "ID: Karla's Coat", - "ID: Karla's Gloves", - "ID: Karla's Trousers", - - # Guarded by Jailbreaker's Key - "ID: Bellowing Dragoncrest Ring", - - # Guarded by Old Cell Key - "ID: Covetous Gold Serpent Ring", - ]), - # Locations that are particularly tricky to find or get to, for players # without an encyclopedic knowledge of DS3 who don't want to get stuck # looking for an invisible wall or one random mob with a guaranteed drop. From 4b9f65fae53d1e82d564f9fb4398a6d0fc420d88 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 24 Oct 2023 02:36:12 -0700 Subject: [PATCH 017/238] Restore Knight Slayer's Ring classification --- worlds/dark_souls_3/Locations.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index d52117188954..a075adaa3e86 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -294,7 +294,6 @@ def get_name_to_id() -> dict: DS3LocationData("CC: Black Blade", "Black Blade", DS3LocationCategory.WEAPON), DS3LocationData("CC: Soul of High Lord Wolnir", "Soul of High Lord Wolnir", DS3LocationCategory.BOSS), DS3LocationData("CC: Soul of a Demon", "Soul of a Demon", DS3LocationCategory.BOSS), - DS3LocationData("CC: Knight Slayer's Ring", "Knight Slayer's Ring", DS3LocationCategory.RING), ], "Smouldering Lake": [ DS3LocationData("SL: Shield of Want", "Shield of Want", DS3LocationCategory.SHIELD), @@ -308,6 +307,7 @@ def get_name_to_id() -> dict: DS3LocationData("SL: White Hair Talisman", "White Hair Talisman", DS3LocationCategory.WEAPON), DS3LocationData("SL: Izalith Staff", "Izalith Staff", DS3LocationCategory.WEAPON), DS3LocationData("SL: Sacred Flame", "Sacred Flame", DS3LocationCategory.SPELL), + DS3LocationData("SL: Knight Slayer's Ring", "Knight Slayer's Ring", DS3LocationCategory.RING), DS3LocationData("SL: Fume Ultra Greatsword", "Fume Ultra Greatsword", DS3LocationCategory.WEAPON), DS3LocationData("SL: Black Iron Greatshield", "Black Iron Greatshield", DS3LocationCategory.SHIELD), DS3LocationData("SL: Soul of the Old Demon King", "Soul of the Old Demon King", DS3LocationCategory.BOSS), @@ -821,7 +821,7 @@ def get_name_to_id() -> dict: "FS: Master's Gloves", # Sword Master "RS: Exile Greatsword", # Exile Knight #1 "RS: Great Club", # Exile Knight #2 - "CC: Knight Slayer's Ring", # Knight Slayer Tsorig (ember required) + "SL: Knight Slayer's Ring", # Knight Slayer Tsorig "SL: Fume Ultra Greatsword", # Knight Slayer Tsorig "SL: Black Iron Greatshield", # Knight Slayer Tsorig "CD: Spider Shield", # Brigand @@ -900,9 +900,6 @@ def get_name_to_id() -> dict: "GA: Witch's Locks", "GA: Power Within", - # Ember-required invader rewards - "CC: Knight Slayer's Ring", - # Gesture requirements "AP: Calamity Ring", "AP: Twinkling Dragon Torso Stone", From 150b0fea217dcabfd526c648185fe65bb16bdc1b Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 22 Oct 2023 23:13:29 -0700 Subject: [PATCH 018/238] Support infusions/upgrades in the new DS3 mod system --- worlds/dark_souls_3/Options.py | 10 -------- worlds/dark_souls_3/__init__.py | 41 ++++----------------------------- 2 files changed, 4 insertions(+), 47 deletions(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index d613e4733406..a3743ebe42a5 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -53,15 +53,6 @@ class RandomizeHealthLocations(Toggle): display_name = "Randomize Health Upgrade Locations" -class RandomizeProgressiveLocationsOption(Toggle): - """Randomizes upgrade materials and consumables such as the titanite shards, firebombs, resin, etc... - - Instead of specific locations, these are progressive, so Titanite Shard #1 is the first titanite shard - you pick up, regardless of whether it's from an enemy drop late in the game or an item on the ground in the - first 5 minutes.""" - display_name = "Randomize Progressive Locations" - - class PoolTypeOption(Choice): """Changes which non-progression items you add to the pool @@ -201,7 +192,6 @@ class EnableDLCOption(Toggle): "enable_npc_locations": RandomizeNPCLocations, "enable_misc_locations": RandomizeMiscLocations, "enable_health_upgrade_locations": RandomizeHealthLocations, - "enable_progressive_locations": RandomizeProgressiveLocationsOption, "pool_type": PoolTypeOption, "guaranteed_items": GuaranteedItemsOption, "auto_equip": AutoEquipOption, diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 76d2cfb846c2..68b19a328b44 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -92,28 +92,12 @@ def generate_early(self): self.enabled_location_categories.add(DS3LocationCategory.MISC) if self.multiworld.enable_health_upgrade_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.HEALTH) - if self.multiworld.enable_progressive_locations[self.player] == Toggle.option_true: - self.enabled_location_categories.add(DS3LocationCategory.PROGRESSIVE_ITEM) def create_regions(self): - progressive_location_table = [] - if self.multiworld.enable_progressive_locations[self.player]: - progressive_location_table = [] + \ - location_tables["Progressive Items 1"] + \ - location_tables["Progressive Items 2"] + \ - location_tables["Progressive Items 3"] + \ - location_tables["Progressive Items 4"] - - if self.multiworld.enable_dlc[self.player].value: - progressive_location_table += location_tables["Progressive Items DLC"] - - if self.multiworld.enable_health_upgrade_locations[self.player]: - progressive_location_table += location_tables["Progressive Items Health"] - # Create Vanilla Regions regions: Dict[str, Region] = {} - regions["Menu"] = self.create_region("Menu", progressive_location_table) + regions["Menu"] = self.create_region("Menu", {}) regions.update({region_name: self.create_region(region_name, location_tables[region_name]) for region_name in [ "Firelink Shrine", "Firelink Shrine Bell Tower", @@ -490,27 +474,14 @@ def fill_slot_data(self) -> Dict[str, object]: name_to_ds3_code[item.name] += 100 * self.multiworld.per_slot_randoms[self.player].randint(0, 15) # Create the mandatory lists to generate the player's output file - items_id = [] - items_address = [] - locations_id = [] - locations_address = [] - locations_target = [] + ap_ids_to_ds3_ids: Dict[str, int] = {} for location in self.multiworld.get_filled_locations(): # Skip events if location.item.code is None: continue if location.item.player == self.player: - items_id.append(location.item.code) - items_address.append(name_to_ds3_code[location.item.name]) - - if location.player == self.player: - locations_address.append(item_dictionary[location_dictionary[location.name].default_item].ds3_code) - locations_id.append(location.address) - if location.item.player == self.player: - locations_target.append(name_to_ds3_code[location.item.name]) - else: - locations_target.append(0) + ap_ids_to_ds3_ids[str(location.item.code)] = name_to_ds3_code[location.item.name] slot_data = { "options": { @@ -534,11 +505,7 @@ def fill_slot_data(self) -> Dict[str, object]: "seed": self.multiworld.seed_name, # to verify the server's multiworld "slot": self.multiworld.player_name[self.player], # to connect to server "base_id": self.base_id, # to merge location and items lists - "locationsId": locations_id, - "locationsAddress": locations_address, - "locationsTarget": locations_target, - "itemsId": items_id, - "itemsAddress": items_address + "apIdsToItemIds": ap_ids_to_ds3_ids } return slot_data From df0d2543960f9cc28730ed7c44ab895e7a0097dc Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 22 Oct 2023 23:45:10 -0700 Subject: [PATCH 019/238] Support random starting loadouts --- worlds/dark_souls_3/Options.py | 12 ++++++++++++ worlds/dark_souls_3/__init__.py | 2 ++ 2 files changed, 14 insertions(+) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index a3743ebe42a5..d305f0ef256e 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -53,6 +53,16 @@ class RandomizeHealthLocations(Toggle): display_name = "Randomize Health Upgrade Locations" +class RandomizeStartingLoadout(DefaultOnToggle): + """Randomizes the equipment characters begin with.""" + display_name = "Randomize Starting Loadout" + + +class RequireOneHandedStartingWeapons(Toggle): + """Require starting equipment to be usable one-handed.""" + display_name = "Require One-Handed Starting Weapons" + + class PoolTypeOption(Choice): """Changes which non-progression items you add to the pool @@ -192,6 +202,8 @@ class EnableDLCOption(Toggle): "enable_npc_locations": RandomizeNPCLocations, "enable_misc_locations": RandomizeMiscLocations, "enable_health_upgrade_locations": RandomizeHealthLocations, + "random_starting_loadout": RandomizeStartingLoadout, + "require_one_handed_starting_weapons": RequireOneHandedStartingWeapons, "pool_type": PoolTypeOption, "guaranteed_items": GuaranteedItemsOption, "auto_equip": AutoEquipOption, diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 68b19a328b44..e61b3ed9d303 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -494,6 +494,8 @@ def fill_slot_data(self) -> Dict[str, object]: "enable_boss_locations": self.multiworld.enable_boss_locations[self.player].value, "enable_npc_locations": self.multiworld.enable_npc_locations[self.player].value, "enable_misc_locations": self.multiworld.enable_misc_locations[self.player].value, + "random_starting_loadout": self.multiworld.random_starting_loadout[self.player].value, + "require_one_handed_starting_weapons": self.multiworld.require_one_handed_starting_weapons[self.player].value, "auto_equip": self.multiworld.auto_equip[self.player].value, "lock_equip": self.multiworld.lock_equip[self.player].value, "no_weapon_requirements": self.multiworld.no_weapon_requirements[self.player].value, From a7d3358f0819a5e86a86141575cebb5be81d692c Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 23 Oct 2023 01:06:50 -0700 Subject: [PATCH 020/238] Make an item's NPC status orthogonal to its category --- worlds/dark_souls_3/Locations.py | 76 +++++++++++++++++++++----------- worlds/dark_souls_3/__init__.py | 10 +++-- 2 files changed, 57 insertions(+), 29 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index a075adaa3e86..4553cdd9ee77 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1,5 +1,6 @@ from enum import IntEnum -from typing import Optional, NamedTuple, Dict, Set +from typing import Optional, Dict, Set +from dataclasses import dataclass from BaseClasses import Location, Region @@ -10,19 +11,29 @@ class DS3LocationCategory(IntEnum): ARMOR = 2 RING = 3 SPELL = 4 - NPC = 5 - KEY = 6 - BOSS = 7 - MISC = 8 - HEALTH = 9 - PROGRESSIVE_ITEM = 10 - EVENT = 11 + KEY = 5 + BOSS = 6 + MISC = 7 + HEALTH = 8 + PROGRESSIVE_ITEM = 9 + EVENT = 10 -class DS3LocationData(NamedTuple): +@dataclass +class DS3LocationData: name: str - default_item: str + """The name of this location according to Archipelago. + + This needs to be unique within this world.""" + + default_item_name: str + """The name of the item that appears by default in this location.""" + category: DS3LocationCategory + """The category into which this location falls.""" + + npc: bool = False + """Whether this item is contingent on killing an NPC or following their quest.""" class DarkSouls3Location(Location): @@ -124,8 +135,10 @@ def get_name_to_id() -> dict: DS3LocationData("HWL: Soul of Boreal Valley Vordt", "Soul of Boreal Valley Vordt", DS3LocationCategory.BOSS), DS3LocationData("HWL: Soul of the Dancer", "Soul of the Dancer", DS3LocationCategory.BOSS), DS3LocationData("HWL: Way of Blue", "Way of Blue", DS3LocationCategory.MISC), - DS3LocationData("HWL: Greirat's Ashes", "Greirat's Ashes", DS3LocationCategory.NPC), - DS3LocationData("HWL: Blue Tearstone Ring", "Blue Tearstone Ring", DS3LocationCategory.NPC), + DS3LocationData("HWL: Greirat's Ashes", "Greirat's Ashes", DS3LocationCategory.KEY, + npc = True), + DS3LocationData("HWL: Blue Tearstone Ring", "Blue Tearstone Ring", DS3LocationCategory.RING, + npc = True), ], "Undead Settlement": [ DS3LocationData("US: Small Leather Shield", "Small Leather Shield", DS3LocationCategory.SHIELD), @@ -166,14 +179,21 @@ def get_name_to_id() -> dict: DS3LocationData("US: Hawk Ring", "Hawk Ring", DS3LocationCategory.RING), DS3LocationData("US: Warrior of Sunlight", "Warrior of Sunlight", DS3LocationCategory.MISC), DS3LocationData("US: Blessed Red and White Shield+1", "Blessed Red and White Shield+1", DS3LocationCategory.SHIELD), - DS3LocationData("US: Irina's Ashes", "Irina's Ashes", DS3LocationCategory.NPC), - DS3LocationData("US: Cornyx's Ashes", "Cornyx's Ashes", DS3LocationCategory.NPC), - DS3LocationData("US: Cornyx's Wrap", "Cornyx's Wrap", DS3LocationCategory.NPC), - DS3LocationData("US: Cornyx's Garb", "Cornyx's Garb", DS3LocationCategory.NPC), - DS3LocationData("US: Cornyx's Skirt", "Cornyx's Skirt", DS3LocationCategory.NPC), - DS3LocationData("US: Pyromancy Flame", "Pyromancy Flame", DS3LocationCategory.NPC), + DS3LocationData("US: Irina's Ashes", "Irina's Ashes", DS3LocationCategory.KEY, + npc = True), + DS3LocationData("US: Cornyx's Ashes", "Cornyx's Ashes", DS3LocationCategory.KEY, + npc = True), + DS3LocationData("US: Cornyx's Wrap", "Cornyx's Wrap", DS3LocationCategory.ARMOR, + npc = True), + DS3LocationData("US: Cornyx's Garb", "Cornyx's Garb", DS3LocationCategory.ARMOR, + npc = True), + DS3LocationData("US: Cornyx's Skirt", "Cornyx's Skirt", DS3LocationCategory.ARMOR, + npc = True), + DS3LocationData("US: Pyromancy Flame", "Pyromancy Flame", DS3LocationCategory.ARMOR, + npc = True), DS3LocationData("US: Transposing Kiln", "Transposing Kiln", DS3LocationCategory.MISC), - DS3LocationData("US: Tower Key", "Tower Key", DS3LocationCategory.NPC), + DS3LocationData("US: Tower Key", "Tower Key", DS3LocationCategory.KEY, + npc = True), ], "Road of Sacrifices": [ DS3LocationData("RS: Brigand Twindaggers", "Brigand Twindaggers", DS3LocationCategory.WEAPON), @@ -217,7 +237,8 @@ def get_name_to_id() -> dict: DS3LocationData("RS: Grass Crest Shield", "Grass Crest Shield", DS3LocationCategory.SHIELD), DS3LocationData("RS: Soul of a Crystal Sage", "Soul of a Crystal Sage", DS3LocationCategory.BOSS), DS3LocationData("RS: Great Swamp Ring", "Great Swamp Ring", DS3LocationCategory.RING), - DS3LocationData("RS: Orbeck's Ashes", "Orbeck's Ashes", DS3LocationCategory.NPC), + DS3LocationData("RS: Orbeck's Ashes", "Orbeck's Ashes", DS3LocationCategory.KEY, + npc = True), ], "Cathedral of the Deep": [ DS3LocationData("CD: Paladin's Ashes", "Paladin's Ashes", DS3LocationCategory.MISC), @@ -363,11 +384,16 @@ def get_name_to_id() -> dict: DS3LocationData("ID: Jailer's Key Ring", "Jailer's Key Ring", DS3LocationCategory.KEY), DS3LocationData("ID: Dusk Crown Ring", "Dusk Crown Ring", DS3LocationCategory.RING), DS3LocationData("ID: Dark Clutch Ring", "Dark Clutch Ring", DS3LocationCategory.RING), - DS3LocationData("ID: Karla's Ashes", "Karla's Ashes", DS3LocationCategory.NPC), - DS3LocationData("ID: Karla's Pointed Hat", "Karla's Pointed Hat", DS3LocationCategory.NPC), - DS3LocationData("ID: Karla's Coat", "Karla's Coat", DS3LocationCategory.NPC), - DS3LocationData("ID: Karla's Gloves", "Karla's Gloves", DS3LocationCategory.NPC), - DS3LocationData("ID: Karla's Trousers", "Karla's Trousers", DS3LocationCategory.NPC), + DS3LocationData("ID: Karla's Ashes", "Karla's Ashes", DS3LocationCategory.KEY, + npc = True), + DS3LocationData("ID: Karla's Pointed Hat", "Karla's Pointed Hat", DS3LocationCategory.ARMOR, + npc = True), + DS3LocationData("ID: Karla's Coat", "Karla's Coat", DS3LocationCategory.ARMOR, + npc = True), + DS3LocationData("ID: Karla's Gloves", "Karla's Gloves", DS3LocationCategory.ARMOR, + npc = True), + DS3LocationData("ID: Karla's Trousers", "Karla's Trousers", DS3LocationCategory.ARMOR, + npc = True), ], "Profaned Capital": [ DS3LocationData("PC: Cursebite Ring", "Cursebite Ring", DS3LocationCategory.RING), diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index e61b3ed9d303..9bf94327e78c 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -82,8 +82,6 @@ def generate_early(self): self.enabled_location_categories.add(DS3LocationCategory.RING) if self.multiworld.enable_spell_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.SPELL) - if self.multiworld.enable_npc_locations[self.player] == Toggle.option_true: - self.enabled_location_categories.add(DS3LocationCategory.NPC) if self.multiworld.enable_key_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.KEY) if self.multiworld.enable_boss_locations[self.player] == Toggle.option_true: @@ -99,6 +97,7 @@ def create_regions(self): regions: Dict[str, Region] = {} regions["Menu"] = self.create_region("Menu", {}) regions.update({region_name: self.create_region(region_name, location_tables[region_name]) for region_name in [ + "Cemetery of Ash", "Firelink Shrine", "Firelink Shrine Bell Tower", "High Wall of Lothric", @@ -141,7 +140,9 @@ def create_connection(from_region: str, to_region: str): connection.connect(regions[to_region]) regions["Menu"].exits.append(Entrance(self.player, "New Game", regions["Menu"])) - self.multiworld.get_entrance("New Game", self.player).connect(regions["Firelink Shrine"]) + self.multiworld.get_entrance("New Game", self.player).connect(regions["Cemetery of Ash"]) + + create_connection("Cemetery of Ash", "Firelink Shrine") create_connection("Firelink Shrine", "High Wall of Lothric") create_connection("Firelink Shrine", "Firelink Shrine Bell Tower") @@ -184,7 +185,8 @@ def create_region(self, region_name, location_table) -> Region: new_region = Region(region_name, self.player, self.multiworld) for location in location_table: - if location.category in self.enabled_location_categories: + if (location.category in self.enabled_location_categories and + (not location.npc or self.multiworld.enable_npc_locations[self.player] == Toggle.option_true)): new_location = DarkSouls3Location( self.player, location.name, From 129beb33ef834b4af85653218ea98c0fc1de2c55 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 24 Oct 2023 02:54:55 -0700 Subject: [PATCH 021/238] Track location groups with flags --- worlds/dark_souls_3/Locations.py | 844 +++++++++++++++---------------- 1 file changed, 402 insertions(+), 442 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 4553cdd9ee77..604d9cf67cda 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -35,6 +35,68 @@ class DS3LocationData: npc: bool = False """Whether this item is contingent on killing an NPC or following their quest.""" + prominent: bool = False + """Whether this is one of few particularly prominent places for items to appear. + + This is a small number of locations (boss drops and progression locations) + intended to be set as priority locations for players who don't want a lot of + mandatory checks. + + For bosses with multiple drops, only one should be marked prominent. + """ + + progression: bool = False + """Whether this location normally contains an item that blocks forward progress.""" + + boss: bool = False + """Whether this location is a reward for defeating a full boss.""" + + miniboss: bool = False + """Whether this location is a reward for defeating a miniboss. + + The classification of "miniboss" is a bit fuzzy, but we consider them to be enemies that are + visually distinctive in their locations, usually bigger than normal enemies, with a guaranteed + item drop. NPCs are never considered minibosses, and some normal-looking enemies with guaranteed + drops aren't either (these are instead classified as hidden locations).""" + + mimic: bool = False + """Whether this location is dropped by a mimic.""" + + hostile_npc: bool = False + """Whether this location is dropped by a hostile NPC. + + An "NPC" is specifically a human (or rather, ash) is built like a player character rather than a + monster. This includes both scripted invaders and NPCs who are always on the overworld. + """ + + key: bool = False + """Whether this location normally contains a key. + + This is a literal key, not just a key item or a progression item. + """ + + hidden: bool = False + """Whether this location is particularly tricky to find. + + This is for players without an encyclopedic knowledge of DS3 who don't want to get stuck looking + for an invisible wall or one random mob with a guaranteed drop. + """ + + def location_groups(): + """The names of location groups this location should appear in. + + This is computed from the properties assigned to this location.""" + names = [] + if prominent: names.add("Prominent") + if progression: names.add("Progression") + if boss: names.add("Boss Rewards") + if miniboss: names.add("Miniboss Rewards") + if mimic: names.add("Mimic Rewards") + if hostile_npc: names.add("Hostile NPC Rewards") + if key: names.add("Keys") + if hidden: names.add("Hidden") + return names + class DarkSouls3Location(Location): game: str = "Dark Souls III" @@ -105,12 +167,17 @@ def get_name_to_id() -> dict: "Firelink Shrine": [ DS3LocationData("FS: Broken Straight Sword", "Broken Straight Sword", DS3LocationCategory.WEAPON), DS3LocationData("FS: East-West Shield", "East-West Shield", DS3LocationCategory.SHIELD), - DS3LocationData("FS: Uchigatana", "Uchigatana", DS3LocationCategory.WEAPON), - DS3LocationData("FS: Master's Attire", "Master's Attire", DS3LocationCategory.ARMOR), - DS3LocationData("FS: Master's Gloves", "Master's Gloves", DS3LocationCategory.ARMOR), + DS3LocationData("FS: Uchigatana", "Uchigatana", DS3LocationCategory.WEAPON, + hostile_npc = True), # Sword Master drop + DS3LocationData("FS: Master's Attire", "Master's Attire", DS3LocationCategory.ARMOR, + hostile_npc = True), # Sword Master drop + DS3LocationData("FS: Master's Gloves", "Master's Gloves", DS3LocationCategory.ARMOR, + hostile_npc = True), # Sword Master drop ], "Firelink Shrine Bell Tower": [ - DS3LocationData("FSBT: Covetous Silver Serpent Ring", "Covetous Silver Serpent Ring", DS3LocationCategory.RING), + # Guarded by Tower Key + DS3LocationData("FSBT: Covetous Silver Serpent Ring", "Covetous Silver Serpent Ring", DS3LocationCategory.RING, + hidden = True), # Behind invisible wall DS3LocationData("FSBT: Fire Keeper Robe", "Fire Keeper Robe", DS3LocationCategory.ARMOR), DS3LocationData("FSBT: Fire Keeper Gloves", "Fire Keeper Gloves", DS3LocationCategory.ARMOR), DS3LocationData("FSBT: Fire Keeper Skirt", "Fire Keeper Skirt", DS3LocationCategory.ARMOR), @@ -118,7 +185,8 @@ def get_name_to_id() -> dict: DS3LocationData("FSBT: Fire Keeper Soul", "Fire Keeper Soul", DS3LocationCategory.MISC), ], "High Wall of Lothric": [ - DS3LocationData("HWL: Deep Battle Axe", "Deep Battle Axe", DS3LocationCategory.WEAPON), + DS3LocationData("HWL: Deep Battle Axe", "Deep Battle Axe", DS3LocationCategory.WEAPON, + mimic = True), DS3LocationData("HWL: Club", "Club", DS3LocationCategory.WEAPON), DS3LocationData("HWL: Claymore", "Claymore", DS3LocationCategory.WEAPON), DS3LocationData("HWL: Binoculars", "Binoculars", DS3LocationCategory.MISC), @@ -126,14 +194,20 @@ def get_name_to_id() -> dict: DS3LocationData("HWL: Mail Breaker", "Mail Breaker", DS3LocationCategory.WEAPON), DS3LocationData("HWL: Broadsword", "Broadsword", DS3LocationCategory.WEAPON), DS3LocationData("HWL: Silver Eagle Kite Shield", "Silver Eagle Kite Shield", DS3LocationCategory.SHIELD), - DS3LocationData("HWL: Astora's Straight Sword", "Astora's Straight Sword", DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Cell Key", "Cell Key", DS3LocationCategory.KEY), + DS3LocationData("HWL: Astora's Straight Sword", "Astora's Straight Sword", DS3LocationCategory.WEAPON, + hidden = True), # Hidden fall + DS3LocationData("HWL: Cell Key", "Cell Key", DS3LocationCategory.KEY, + key = True), DS3LocationData("HWL: Rapier", "Rapier", DS3LocationCategory.WEAPON), DS3LocationData("HWL: Lucerne", "Lucerne", DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Small Lothric Banner", "Small Lothric Banner", DS3LocationCategory.KEY), - DS3LocationData("HWL: Basin of Vows", "Basin of Vows", DS3LocationCategory.KEY), - DS3LocationData("HWL: Soul of Boreal Valley Vordt", "Soul of Boreal Valley Vordt", DS3LocationCategory.BOSS), - DS3LocationData("HWL: Soul of the Dancer", "Soul of the Dancer", DS3LocationCategory.BOSS), + DS3LocationData("HWL: Small Lothric Banner", "Small Lothric Banner", DS3LocationCategory.KEY, + prominent = True, progression = True), + DS3LocationData("HWL: Basin of Vows", "Basin of Vows", DS3LocationCategory.KEY, + prominent = True, progression = True), + DS3LocationData("HWL: Soul of Boreal Valley Vordt", "Soul of Boreal Valley Vordt", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("HWL: Soul of the Dancer", "Soul of the Dancer", DS3LocationCategory.BOSS, + prominent = True, boss = True), DS3LocationData("HWL: Way of Blue", "Way of Blue", DS3LocationCategory.MISC), DS3LocationData("HWL: Greirat's Ashes", "Greirat's Ashes", DS3LocationCategory.KEY, npc = True), @@ -156,28 +230,36 @@ def get_name_to_id() -> dict: DS3LocationData("US: Caduceus Round Shield", "Caduceus Round Shield", DS3LocationCategory.SHIELD), DS3LocationData("US: Fire Clutch Ring", "Fire Clutch Ring", DS3LocationCategory.RING), DS3LocationData("US: Partizan", "Partizan", DS3LocationCategory.WEAPON), - DS3LocationData("US: Bloodbite Ring", "Bloodbite Ring", DS3LocationCategory.RING), + DS3LocationData("US: Bloodbite Ring", "Bloodbite Ring", DS3LocationCategory.RING, + miniboss = True), # Giant Rat drop DS3LocationData("US: Red Hilted Halberd", "Red Hilted Halberd", DS3LocationCategory.WEAPON), DS3LocationData("US: Saint's Talisman", "Saint's Talisman", DS3LocationCategory.WEAPON), - DS3LocationData("US: Irithyll Straight Sword", "Irithyll Straight Sword", DS3LocationCategory.WEAPON), + DS3LocationData("US: Irithyll Straight Sword", "Irithyll Straight Sword", DS3LocationCategory.WEAPON, + miniboss = True), # Boreal Outrider drop DS3LocationData("US: Large Club", "Large Club", DS3LocationCategory.WEAPON), DS3LocationData("US: Northern Helm", "Northern Helm", DS3LocationCategory.ARMOR), DS3LocationData("US: Northern Armor", "Northern Armor", DS3LocationCategory.ARMOR), DS3LocationData("US: Northern Gloves", "Northern Gloves", DS3LocationCategory.ARMOR), DS3LocationData("US: Northern Trousers", "Northern Trousers", DS3LocationCategory.ARMOR), DS3LocationData("US: Flynn's Ring", "Flynn's Ring", DS3LocationCategory.RING), - DS3LocationData("US: Mirrah Vest", "Mirrah Vest", DS3LocationCategory.ARMOR), - DS3LocationData("US: Mirrah Gloves", "Mirrah Gloves", DS3LocationCategory.ARMOR), - DS3LocationData("US: Mirrah Trousers", "Mirrah Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("US: Chloranthy Ring", "Chloranthy Ring", DS3LocationCategory.RING), + DS3LocationData("US: Mirrah Vest", "Mirrah Vest", DS3LocationCategory.ARMOR, + hidden = True), # Hidden fall + DS3LocationData("US: Mirrah Gloves", "Mirrah Gloves", DS3LocationCategory.ARMOR, + hidden = True), # Hidden fall + DS3LocationData("US: Mirrah Trousers", "Mirrah Trousers", DS3LocationCategory.ARMOR, + hidden = True), # Hidden fall + DS3LocationData("US: Chloranthy Ring", "Chloranthy Ring", DS3LocationCategory.RING, + hidden = True), # Hidden fall DS3LocationData("US: Loincloth", "Loincloth", DS3LocationCategory.ARMOR), DS3LocationData("US: Wargod Wooden Shield", "Wargod Wooden Shield", DS3LocationCategory.SHIELD), DS3LocationData("US: Loretta's Bone", "Loretta's Bone", DS3LocationCategory.KEY), DS3LocationData("US: Hand Axe", "Hand Axe", DS3LocationCategory.WEAPON), DS3LocationData("US: Great Scythe", "Great Scythe", DS3LocationCategory.WEAPON), - DS3LocationData("US: Soul of the Rotted Greatwood", "Soul of the Rotted Greatwood", DS3LocationCategory.BOSS), + DS3LocationData("US: Soul of the Rotted Greatwood", "Soul of the Rotted Greatwood", DS3LocationCategory.BOSS, + prominent = True, boss = True), DS3LocationData("US: Hawk Ring", "Hawk Ring", DS3LocationCategory.RING), - DS3LocationData("US: Warrior of Sunlight", "Warrior of Sunlight", DS3LocationCategory.MISC), + DS3LocationData("US: Warrior of Sunlight", "Warrior of Sunlight", DS3LocationCategory.MISC, + hidden = True), # Hidden fall DS3LocationData("US: Blessed Red and White Shield+1", "Blessed Red and White Shield+1", DS3LocationCategory.SHIELD), DS3LocationData("US: Irina's Ashes", "Irina's Ashes", DS3LocationCategory.KEY, npc = True), @@ -191,7 +273,8 @@ def get_name_to_id() -> dict: npc = True), DS3LocationData("US: Pyromancy Flame", "Pyromancy Flame", DS3LocationCategory.ARMOR, npc = True), - DS3LocationData("US: Transposing Kiln", "Transposing Kiln", DS3LocationCategory.MISC), + DS3LocationData("US: Transposing Kiln", "Transposing Kiln", DS3LocationCategory.MISC, + boss = True), DS3LocationData("US: Tower Key", "Tower Key", DS3LocationCategory.KEY, npc = True), ], @@ -201,17 +284,25 @@ def get_name_to_id() -> dict: DS3LocationData("RS: Brigand Armor", "Brigand Armor", DS3LocationCategory.ARMOR), DS3LocationData("RS: Brigand Gauntlets", "Brigand Gauntlets", DS3LocationCategory.ARMOR), DS3LocationData("RS: Brigand Trousers", "Brigand Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Butcher Knife", "Butcher Knife", DS3LocationCategory.WEAPON), + DS3LocationData("RS: Butcher Knife", "Butcher Knife", DS3LocationCategory.WEAPON, + hidden = True), # Guaranteed drop from a normal-looking Butcher DS3LocationData("RS: Brigand Axe", "Brigand Axe", DS3LocationCategory.WEAPON), - DS3LocationData("RS: Braille Divine Tome of Carim", "Braille Divine Tome of Carim", DS3LocationCategory.MISC), - DS3LocationData("RS: Morne's Ring", "Morne's Ring", DS3LocationCategory.RING), + DS3LocationData("RS: Braille Divine Tome of Carim", "Braille Divine Tome of Carim", DS3LocationCategory.MISC, + hidden = True), # Hidden fall + DS3LocationData("RS: Morne's Ring", "Morne's Ring", DS3LocationCategory.RING, + hidden = True), # Hidden fall DS3LocationData("RS: Twin Dragon Greatshield", "Twin Dragon Greatshield", DS3LocationCategory.SHIELD), DS3LocationData("RS: Heretic's Staff", "Heretic's Staff", DS3LocationCategory.WEAPON), - DS3LocationData("RS: Sorcerer Hood", "Sorcerer Hood", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Sorcerer Robe", "Sorcerer Robe", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Sorcerer Gloves", "Sorcerer Gloves", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Sorcerer Trousers", "Sorcerer Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Sage Ring", "Sage Ring", DS3LocationCategory.RING), + DS3LocationData("RS: Sorcerer Hood", "Sorcerer Hood", DS3LocationCategory.ARMOR, + hidden = True), # Hidden fall + DS3LocationData("RS: Sorcerer Robe", "Sorcerer Robe", DS3LocationCategory.ARMOR, + hidden = True), # Hidden fall + DS3LocationData("RS: Sorcerer Gloves", "Sorcerer Gloves", DS3LocationCategory.ARMOR, + hidden = True), # Hidden fall + DS3LocationData("RS: Sorcerer Trousers", "Sorcerer Trousers", DS3LocationCategory.ARMOR, + hidden = True), # Hidden fall + DS3LocationData("RS: Sage Ring", "Sage Ring", DS3LocationCategory.RING, + hidden = True), # Hidden fall DS3LocationData("RS: Fallen Knight Helm", "Fallen Knight Helm", DS3LocationCategory.ARMOR), DS3LocationData("RS: Fallen Knight Armor", "Fallen Knight Armor", DS3LocationCategory.ARMOR), DS3LocationData("RS: Fallen Knight Gauntlets", "Fallen Knight Gauntlets", DS3LocationCategory.ARMOR), @@ -221,8 +312,10 @@ def get_name_to_id() -> dict: DS3LocationData("RS: Conjurator Manchettes", "Conjurator Manchettes", DS3LocationCategory.ARMOR), DS3LocationData("RS: Conjurator Boots", "Conjurator Boots", DS3LocationCategory.ARMOR), DS3LocationData("RS: Great Swamp Pyromancy Tome", "Great Swamp Pyromancy Tome", DS3LocationCategory.MISC), - DS3LocationData("RS: Great Club", "Great Club", DS3LocationCategory.WEAPON), - DS3LocationData("RS: Exile Greatsword", "Exile Greatsword", DS3LocationCategory.WEAPON), + DS3LocationData("RS: Great Club", "Great Club", DS3LocationCategory.WEAPON, + hostile_npc = True), # Exile Knight #1 drop + DS3LocationData("RS: Exile Greatsword", "Exile Greatsword", DS3LocationCategory.WEAPON, + hostile_npc = True), # Exile Knight #2 drop DS3LocationData("RS: Farron Coal", "Farron Coal", DS3LocationCategory.MISC), DS3LocationData("RS: Sellsword Twinblades", "Sellsword Twinblades", DS3LocationCategory.WEAPON), DS3LocationData("RS: Sellsword Helm", "Sellsword Helm", DS3LocationCategory.ARMOR), @@ -235,14 +328,17 @@ def get_name_to_id() -> dict: DS3LocationData("RS: Herald Gloves", "Herald Gloves", DS3LocationCategory.ARMOR), DS3LocationData("RS: Herald Trousers", "Herald Trousers", DS3LocationCategory.ARMOR), DS3LocationData("RS: Grass Crest Shield", "Grass Crest Shield", DS3LocationCategory.SHIELD), - DS3LocationData("RS: Soul of a Crystal Sage", "Soul of a Crystal Sage", DS3LocationCategory.BOSS), - DS3LocationData("RS: Great Swamp Ring", "Great Swamp Ring", DS3LocationCategory.RING), + DS3LocationData("RS: Soul of a Crystal Sage", "Soul of a Crystal Sage", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("RS: Great Swamp Ring", "Great Swamp Ring", DS3LocationCategory.RING, + miniboss = True), # Giant Crab drop DS3LocationData("RS: Orbeck's Ashes", "Orbeck's Ashes", DS3LocationCategory.KEY, npc = True), ], "Cathedral of the Deep": [ DS3LocationData("CD: Paladin's Ashes", "Paladin's Ashes", DS3LocationCategory.MISC), - DS3LocationData("CD: Spider Shield", "Spider Shield", DS3LocationCategory.SHIELD), + DS3LocationData("CD: Spider Shield", "Spider Shield", DS3LocationCategory.SHIELD, + hostile_npc = True), # Brigand DS3LocationData("CD: Crest Shield", "Crest Shield", DS3LocationCategory.SHIELD), DS3LocationData("CD: Notched Whip", "Notched Whip", DS3LocationCategory.WEAPON), DS3LocationData("CD: Astora Greatsword", "Astora Greatsword", DS3LocationCategory.WEAPON), @@ -252,9 +348,12 @@ def get_name_to_id() -> dict: DS3LocationData("CD: Poisonbite Ring", "Poisonbite Ring", DS3LocationCategory.RING), DS3LocationData("CD: Lloyd's Sword Ring", "Lloyd's Sword Ring", DS3LocationCategory.RING), DS3LocationData("CD: Seek Guidance", "Seek Guidance", DS3LocationCategory.SPELL), - DS3LocationData("CD: Aldrich's Sapphire", "Aldrich's Sapphire", DS3LocationCategory.RING), - DS3LocationData("CD: Deep Braille Divine Tome", "Deep Braille Divine Tome", DS3LocationCategory.MISC), - DS3LocationData("CD: Saint Bident", "Saint Bident", DS3LocationCategory.WEAPON), + DS3LocationData("CD: Aldrich's Sapphire", "Aldrich's Sapphire", DS3LocationCategory.RING, + miniboss = True), # Deep Accursed Drop + DS3LocationData("CD: Deep Braille Divine Tome", "Deep Braille Divine Tome", DS3LocationCategory.MISC, + mimic = True), + DS3LocationData("CD: Saint Bident", "Saint Bident", DS3LocationCategory.WEAPON, + miniboss = True), # Guarded by giant DS3LocationData("CD: Maiden Hood", "Maiden Hood", DS3LocationCategory.ARMOR), DS3LocationData("CD: Maiden Robe", "Maiden Robe", DS3LocationCategory.ARMOR), DS3LocationData("CD: Maiden Gloves", "Maiden Gloves", DS3LocationCategory.ARMOR), @@ -263,22 +362,34 @@ def get_name_to_id() -> dict: DS3LocationData("CD: Drang Gauntlets", "Drang Gauntlets", DS3LocationCategory.ARMOR), DS3LocationData("CD: Drang Shoes", "Drang Shoes", DS3LocationCategory.ARMOR), DS3LocationData("CD: Drang Hammers", "Drang Hammers", DS3LocationCategory.WEAPON), - DS3LocationData("CD: Deep Ring", "Deep Ring", DS3LocationCategory.RING), - DS3LocationData("CD: Archdeacon White Crown", "Archdeacon White Crown", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Archdeacon Holy Garb", "Archdeacon Holy Garb", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Archdeacon Skirt", "Archdeacon Skirt", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Arbalest", "Arbalest", DS3LocationCategory.WEAPON), - DS3LocationData("CD: Small Doll", "Small Doll", DS3LocationCategory.KEY), - DS3LocationData("CD: Soul of the Deacons of the Deep", "Soul of the Deacons of the Deep", DS3LocationCategory.BOSS), - DS3LocationData("CD: Rosaria's Fingers", "Rosaria's Fingers", DS3LocationCategory.MISC) + DS3LocationData("CD: Deep Ring", "Deep Ring", DS3LocationCategory.RING, + hidden = True), # Guaranteed drop from a normal-looking Deacon + DS3LocationData("CD: Archdeacon White Crown", "Archdeacon White Crown", DS3LocationCategory.ARMOR, + boss = True, hidden = True), # Have to return to a cleared area + DS3LocationData("CD: Archdeacon Holy Garb", "Archdeacon Holy Garb", DS3LocationCategory.ARMOR, + boss = True, hidden = True), # Have to return to a cleared area + DS3LocationData("CD: Archdeacon Skirt", "Archdeacon Skirt", DS3LocationCategory.ARMOR, + boss = True, hidden = True), # Have to return to a cleared area + DS3LocationData("CD: Arbalest", "Arbalest", DS3LocationCategory.WEAPON, + hidden = True), # Hidden fall + DS3LocationData("CD: Small Doll", "Small Doll", DS3LocationCategory.KEY, + prominent = True, progression = True, boss = True), + DS3LocationData("CD: Soul of the Deacons of the Deep", "Soul of the Deacons of the Deep", DS3LocationCategory.BOSS, + boss = True), + DS3LocationData("CD: Rosaria's Fingers", "Rosaria's Fingers", DS3LocationCategory.MISC, + hidden = True) # Hidden fall ], "Farron Keep": [ DS3LocationData("FK: Ragged Mask", "Ragged Mask", DS3LocationCategory.ARMOR), DS3LocationData("FK: Iron Flesh", "Iron Flesh", DS3LocationCategory.SPELL), - DS3LocationData("FK: Golden Scroll", "Golden Scroll", DS3LocationCategory.MISC), - DS3LocationData("FK: Antiquated Dress", "Antiquated Dress", DS3LocationCategory.ARMOR), - DS3LocationData("FK: Antiquated Gloves", "Antiquated Gloves", DS3LocationCategory.ARMOR), - DS3LocationData("FK: Antiquated Skirt", "Antiquated Skirt", DS3LocationCategory.ARMOR), + DS3LocationData("FK: Golden Scroll", "Golden Scroll", DS3LocationCategory.MISC, + hostile_npc = True), # Out-of-the-way hard-to-see cave + DS3LocationData("FK: Antiquated Dress", "Antiquated Dress", DS3LocationCategory.ARMOR, + hostile_npc = True), # Out-of-the-way hard-to-see cave + DS3LocationData("FK: Antiquated Gloves", "Antiquated Gloves", DS3LocationCategory.ARMOR, + hostile_npc = True), # Out-of-the-way hard-to-see cave + DS3LocationData("FK: Antiquated Skirt", "Antiquated Skirt", DS3LocationCategory.ARMOR, + hostile_npc = True), # Out-of-the-way hard-to-see cave DS3LocationData("FK: Nameless Knight Helm", "Nameless Knight Helm", DS3LocationCategory.ARMOR), DS3LocationData("FK: Nameless Knight Armor", "Nameless Knight Armor", DS3LocationCategory.ARMOR), DS3LocationData("FK: Nameless Knight Gauntlets", "Nameless Knight Gauntlets", DS3LocationCategory.ARMOR), @@ -290,56 +401,83 @@ def get_name_to_id() -> dict: DS3LocationData("FK: Stone Parma", "Stone Parma", DS3LocationCategory.SHIELD), DS3LocationData("FK: Sage's Scroll", "Sage's Scroll", DS3LocationCategory.MISC), DS3LocationData("FK: Crown of Dusk", "Crown of Dusk", DS3LocationCategory.ARMOR), - DS3LocationData("FK: Lingering Dragoncrest Ring", "Lingering Dragoncrest Ring", DS3LocationCategory.RING), - DS3LocationData("FK: Pharis's Hat", "Pharis's Hat", DS3LocationCategory.ARMOR), - DS3LocationData("FK: Black Bow of Pharis", "Black Bow of Pharis", DS3LocationCategory.WEAPON), - DS3LocationData("FK: Dreamchaser's Ashes", "Dreamchaser's Ashes", DS3LocationCategory.MISC), + DS3LocationData("FK: Lingering Dragoncrest Ring", "Lingering Dragoncrest Ring", DS3LocationCategory.RING, + miniboss = True), # Great Crab drop + DS3LocationData("FK: Pharis's Hat", "Pharis's Hat", DS3LocationCategory.ARMOR, + hidden = True), # Guaranteed drop from a normal-looking Elder Ghru + DS3LocationData("FK: Black Bow of Pharis", "Black Bow of Pharis", DS3LocationCategory.WEAPON, + hidden = True), # Guaranteed drop from a normal-looking Elder Ghru + DS3LocationData("FK: Dreamchaser's Ashes", "Dreamchaser's Ashes", DS3LocationCategory.MISC, + hidden = True), # Behind invisible wall DS3LocationData("FK: Great Axe", "Great Axe", DS3LocationCategory.WEAPON), DS3LocationData("FK: Dragon Crest Shield", "Dragon Crest Shield", DS3LocationCategory.SHIELD), DS3LocationData("FK: Lightning Spear", "Lightning Spear", DS3LocationCategory.SPELL), - DS3LocationData("FK: Atonement", "Atonement", DS3LocationCategory.SPELL), + DS3LocationData("FK: Atonement", "Atonement", DS3LocationCategory.SPELL, + hidden = True), # Hidden fall DS3LocationData("FK: Great Magic Weapon", "Great Magic Weapon", DS3LocationCategory.SPELL), - DS3LocationData("FK: Cinders of a Lord - Abyss Watcher", "Cinders of a Lord - Abyss Watcher", DS3LocationCategory.KEY), - DS3LocationData("FK: Soul of the Blood of the Wolf", "Soul of the Blood of the Wolf", DS3LocationCategory.BOSS), - DS3LocationData("FK: Soul of a Stray Demon", "Soul of a Stray Demon", DS3LocationCategory.BOSS), + DS3LocationData("FK: Cinders of a Lord - Abyss Watcher", "Cinders of a Lord - Abyss Watcher", DS3LocationCategory.KEY, + prominent = True, progression = True, boss = True), + DS3LocationData("FK: Soul of the Blood of the Wolf", "Soul of the Blood of the Wolf", DS3LocationCategory.BOSS, + boss = True), + DS3LocationData("FK: Soul of a Stray Demon", "Soul of a Stray Demon", DS3LocationCategory.BOSS, + miniboss = True), DS3LocationData("FK: Watchdogs of Farron", "Watchdogs of Farron", DS3LocationCategory.MISC), ], "Catacombs of Carthus": [ - DS3LocationData("CC: Carthus Pyromancy Tome", "Carthus Pyromancy Tome", DS3LocationCategory.MISC), + DS3LocationData("CC: Carthus Pyromancy Tome", "Carthus Pyromancy Tome", DS3LocationCategory.MISC, + hidden = True), # Behind invisible wall DS3LocationData("CC: Carthus Milkring", "Carthus Milkring", DS3LocationCategory.RING), DS3LocationData("CC: Grave Warden's Ashes", "Grave Warden's Ashes", DS3LocationCategory.MISC), DS3LocationData("CC: Carthus Bloodring", "Carthus Bloodring", DS3LocationCategory.RING), DS3LocationData("CC: Grave Warden Pyromancy Tome", "Grave Warden Pyromancy Tome", DS3LocationCategory.MISC), DS3LocationData("CC: Old Sage's Blindfold", "Old Sage's Blindfold", DS3LocationCategory.ARMOR), DS3LocationData("CC: Witch's Ring", "Witch's Ring", DS3LocationCategory.RING), - DS3LocationData("CC: Black Blade", "Black Blade", DS3LocationCategory.WEAPON), - DS3LocationData("CC: Soul of High Lord Wolnir", "Soul of High Lord Wolnir", DS3LocationCategory.BOSS), - DS3LocationData("CC: Soul of a Demon", "Soul of a Demon", DS3LocationCategory.BOSS), + DS3LocationData("CC: Black Blade", "Black Blade", DS3LocationCategory.WEAPON, + mimic = True), + DS3LocationData("CC: Soul of High Lord Wolnir", "Soul of High Lord Wolnir", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("CC: Soul of a Demon", "Soul of a Demon", DS3LocationCategory.BOSS, + miniboss = True), ], "Smouldering Lake": [ DS3LocationData("SL: Shield of Want", "Shield of Want", DS3LocationCategory.SHIELD), - DS3LocationData("SL: Speckled Stoneplate Ring", "Speckled Stoneplate Ring", DS3LocationCategory.RING), - DS3LocationData("SL: Dragonrider Bow", "Dragonrider Bow", DS3LocationCategory.WEAPON), - DS3LocationData("SL: Lightning Stake", "Lightning Stake", DS3LocationCategory.SPELL), + DS3LocationData("SL: Speckled Stoneplate Ring", "Speckled Stoneplate Ring", DS3LocationCategory.RING, + hidden = True), # Requires careful ballista shot + DS3LocationData("SL: Dragonrider Bow", "Dragonrider Bow", DS3LocationCategory.WEAPON, + hidden = True), # Hidden fall + DS3LocationData("SL: Lightning Stake", "Lightning Stake", DS3LocationCategory.SPELL, + miniboss = True), # Sand Worm drop DS3LocationData("SL: Izalith Pyromancy Tome", "Izalith Pyromancy Tome", DS3LocationCategory.MISC), DS3LocationData("SL: Black Knight Sword", "Black Knight Sword", DS3LocationCategory.WEAPON), DS3LocationData("SL: Quelana Pyromancy Tome", "Quelana Pyromancy Tome", DS3LocationCategory.MISC), - DS3LocationData("SL: Toxic Mist", "Toxic Mist", DS3LocationCategory.SPELL), - DS3LocationData("SL: White Hair Talisman", "White Hair Talisman", DS3LocationCategory.WEAPON), - DS3LocationData("SL: Izalith Staff", "Izalith Staff", DS3LocationCategory.WEAPON), - DS3LocationData("SL: Sacred Flame", "Sacred Flame", DS3LocationCategory.SPELL), - DS3LocationData("SL: Knight Slayer's Ring", "Knight Slayer's Ring", DS3LocationCategory.RING), - DS3LocationData("SL: Fume Ultra Greatsword", "Fume Ultra Greatsword", DS3LocationCategory.WEAPON), - DS3LocationData("SL: Black Iron Greatshield", "Black Iron Greatshield", DS3LocationCategory.SHIELD), - DS3LocationData("SL: Soul of the Old Demon King", "Soul of the Old Demon King", DS3LocationCategory.BOSS), + DS3LocationData("SL: Toxic Mist", "Toxic Mist", DS3LocationCategory.SPELL, + hidden = True), # In lava + DS3LocationData("SL: White Hair Talisman", "White Hair Talisman", DS3LocationCategory.WEAPON, + hidden = True), # In lava + DS3LocationData("SL: Izalith Staff", "Izalith Staff", DS3LocationCategory.WEAPON, + hidden = True), # Behind invisible wall + DS3LocationData("SL: Sacred Flame", "Sacred Flame", DS3LocationCategory.SPELL, + hidden = True), # In lava + DS3LocationData("CC: Knight Slayer's Ring", "Knight Slayer's Ring", DS3LocationCategory.RING, + hostile_npc = True), # Knight Slayer Tsorig drop + DS3LocationData("SL: Fume Ultra Greatsword", "Fume Ultra Greatsword", DS3LocationCategory.WEAPON, + hostile_npc = True), # Knight Slayer Tsorig drop + DS3LocationData("SL: Black Iron Greatshield", "Black Iron Greatshield", DS3LocationCategory.SHIELD, + hostile_npc = True), # Knight Slayer Tsorig drop + DS3LocationData("SL: Soul of the Old Demon King", "Soul of the Old Demon King", DS3LocationCategory.BOSS, + prominent = True, boss = True), ], "Irithyll of the Boreal Valley": [ - DS3LocationData("IBV: Dorhys' Gnawing", "Dorhys' Gnawing", DS3LocationCategory.SPELL), - DS3LocationData("IBV: Witchtree Branch", "Witchtree Branch", DS3LocationCategory.WEAPON), - DS3LocationData("IBV: Magic Clutch Ring", "Magic Clutch Ring", DS3LocationCategory.RING), + DS3LocationData("IBV: Dorhys' Gnawing", "Dorhys' Gnawing", DS3LocationCategory.SPELL, + hidden = True), # Behind invisible wall + DS3LocationData("IBV: Witchtree Branch", "Witchtree Branch", DS3LocationCategory.WEAPON, + hidden = True), # Behind invisible wall + DS3LocationData("IBV: Magic Clutch Ring", "Magic Clutch Ring", DS3LocationCategory.RING, + hidden = True), # Behind invisible wall DS3LocationData("IBV: Ring of the Sun's First Born", "Ring of the Sun's First Born", DS3LocationCategory.RING), DS3LocationData("IBV: Roster of Knights", "Roster of Knights", DS3LocationCategory.MISC), - DS3LocationData("IBV: Pontiff's Right Eye", "Pontiff's Right Eye", DS3LocationCategory.RING), + DS3LocationData("IBV: Pontiff's Right Eye", "Pontiff's Right Eye", DS3LocationCategory.RING, + miniboss = True), # Sullyvahn's Beast drop DS3LocationData("IBV: Yorshka's Spear", "Yorshka's Spear", DS3LocationCategory.WEAPON), DS3LocationData("IBV: Great Heal", "Great Heal", DS3LocationCategory.SPELL), DS3LocationData("IBV: Smough's Great Hammer", "Smough's Great Hammer", DS3LocationCategory.WEAPON), @@ -347,43 +485,57 @@ def get_name_to_id() -> dict: DS3LocationData("IBV: Excrement-covered Ashes", "Excrement-covered Ashes", DS3LocationCategory.MISC), DS3LocationData("IBV: Dark Stoneplate Ring", "Dark Stoneplate Ring", DS3LocationCategory.RING), DS3LocationData("IBV: Easterner's Ashes", "Easterner's Ashes", DS3LocationCategory.MISC), - DS3LocationData("IBV: Painting Guardian's Curved Sword", "Painting Guardian's Curved Sword", DS3LocationCategory.WEAPON), - DS3LocationData("IBV: Painting Guardian Hood", "Painting Guardian Hood", DS3LocationCategory.ARMOR), - DS3LocationData("IBV: Painting Guardian Gown", "Painting Guardian Gown", DS3LocationCategory.ARMOR), - DS3LocationData("IBV: Painting Guardian Gloves", "Painting Guardian Gloves", DS3LocationCategory.ARMOR), - DS3LocationData("IBV: Painting Guardian Waistcloth", "Painting Guardian Waistcloth", DS3LocationCategory.ARMOR), + DS3LocationData("IBV: Painting Guardian's Curved Sword", "Painting Guardian's Curved Sword", DS3LocationCategory.WEAPON, + hidden = True), # Invisible walkway + DS3LocationData("IBV: Painting Guardian Hood", "Painting Guardian Hood", DS3LocationCategory.ARMOR, + hidden = True), # Invisible walkway + DS3LocationData("IBV: Painting Guardian Gown", "Painting Guardian Gown", DS3LocationCategory.ARMOR, + hidden = True), # Invisible walkway + DS3LocationData("IBV: Painting Guardian Gloves", "Painting Guardian Gloves", DS3LocationCategory.ARMOR, + hidden = True), # Invisible walkway + DS3LocationData("IBV: Painting Guardian Waistcloth", "Painting Guardian Waistcloth", DS3LocationCategory.ARMOR, + hidden = True), # Invisible walkway DS3LocationData("IBV: Dragonslayer Greatbow", "Dragonslayer Greatbow", DS3LocationCategory.WEAPON), DS3LocationData("IBV: Reversal Ring", "Reversal Ring", DS3LocationCategory.RING), DS3LocationData("IBV: Brass Helm", "Brass Helm", DS3LocationCategory.ARMOR), DS3LocationData("IBV: Brass Armor", "Brass Armor", DS3LocationCategory.ARMOR), DS3LocationData("IBV: Brass Gauntlets", "Brass Gauntlets", DS3LocationCategory.ARMOR), DS3LocationData("IBV: Brass Leggings", "Brass Leggings", DS3LocationCategory.ARMOR), - DS3LocationData("IBV: Ring of Favor", "Ring of Favor", DS3LocationCategory.RING), - DS3LocationData("IBV: Golden Ritual Spear", "Golden Ritual Spear", DS3LocationCategory.WEAPON), - DS3LocationData("IBV: Soul of Pontiff Sulyvahn", "Soul of Pontiff Sulyvahn", DS3LocationCategory.BOSS), - DS3LocationData("IBV: Aldrich Faithful", "Aldrich Faithful", DS3LocationCategory.MISC), + DS3LocationData("IBV: Ring of Favor", "Ring of Favor", DS3LocationCategory.RING, + miniboss = True, hidden = True), # Sulyvahn's Beast Duo drop, behind invisible wall + DS3LocationData("IBV: Golden Ritual Spear", "Golden Ritual Spear", DS3LocationCategory.WEAPON, + mimic = True), + DS3LocationData("IBV: Soul of Pontiff Sulyvahn", "Soul of Pontiff Sulyvahn", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("IBV: Aldrich Faithful", "Aldrich Faithful", DS3LocationCategory.MISC, + miniboss = True, hidden = True), # Sulyvahn's Beast Duo reward, behind invisible wall DS3LocationData("IBV: Drang Twinspears", "Drang Twinspears", DS3LocationCategory.WEAPON), ], "Irithyll Dungeon": [ DS3LocationData("ID: Bellowing Dragoncrest Ring", "Bellowing Dragoncrest Ring", DS3LocationCategory.RING), - DS3LocationData("ID: Jailbreaker's Key", "Jailbreaker's Key", DS3LocationCategory.KEY), + DS3LocationData("ID: Jailbreaker's Key", "Jailbreaker's Key", DS3LocationCategory.KEY, + key = True), DS3LocationData("ID: Prisoner Chief's Ashes", "Prisoner Chief's Ashes", DS3LocationCategory.KEY), DS3LocationData("ID: Old Sorcerer Hat", "Old Sorcerer Hat", DS3LocationCategory.ARMOR), DS3LocationData("ID: Old Sorcerer Coat", "Old Sorcerer Coat", DS3LocationCategory.ARMOR), DS3LocationData("ID: Old Sorcerer Gauntlets", "Old Sorcerer Gauntlets", DS3LocationCategory.ARMOR), DS3LocationData("ID: Old Sorcerer Boots", "Old Sorcerer Boots", DS3LocationCategory.ARMOR), - DS3LocationData("ID: Great Magic Shield", "Great Magic Shield", DS3LocationCategory.SPELL), + DS3LocationData("ID: Great Magic Shield", "Great Magic Shield", DS3LocationCategory.SPELL, + hidden = True), # Guaranteed drop from a normal-looking Corpse-Grub DS3LocationData("ID: Dragon Torso Stone", "Dragon Torso Stone", DS3LocationCategory.MISC), DS3LocationData("ID: Lightning Blade", "Lightning Blade", DS3LocationCategory.SPELL), DS3LocationData("ID: Profaned Coal", "Profaned Coal", DS3LocationCategory.MISC), DS3LocationData("ID: Xanthous Ashes", "Xanthous Ashes", DS3LocationCategory.MISC), - DS3LocationData("ID: Old Cell Key", "Old Cell Key", DS3LocationCategory.KEY), + DS3LocationData("ID: Old Cell Key", "Old Cell Key", DS3LocationCategory.KEY, + key = True), DS3LocationData("ID: Pickaxe", "Pickaxe", DS3LocationCategory.WEAPON), DS3LocationData("ID: Profaned Flame", "Profaned Flame", DS3LocationCategory.SPELL), DS3LocationData("ID: Covetous Gold Serpent Ring", "Covetous Gold Serpent Ring", DS3LocationCategory.RING), - DS3LocationData("ID: Jailer's Key Ring", "Jailer's Key Ring", DS3LocationCategory.KEY), + DS3LocationData("ID: Jailer's Key Ring", "Jailer's Key Ring", DS3LocationCategory.KEY, + key = True), DS3LocationData("ID: Dusk Crown Ring", "Dusk Crown Ring", DS3LocationCategory.RING), - DS3LocationData("ID: Dark Clutch Ring", "Dark Clutch Ring", DS3LocationCategory.RING), + DS3LocationData("ID: Dark Clutch Ring", "Dark Clutch Ring", DS3LocationCategory.RING, + mimic = True), DS3LocationData("ID: Karla's Ashes", "Karla's Ashes", DS3LocationCategory.KEY, npc = True), DS3LocationData("ID: Karla's Pointed Hat", "Karla's Pointed Hat", DS3LocationCategory.ARMOR, @@ -402,41 +554,60 @@ def get_name_to_id() -> dict: DS3LocationData("PC: Court Sorcerer Gloves", "Court Sorcerer Gloves", DS3LocationCategory.ARMOR), DS3LocationData("PC: Court Sorcerer Trousers", "Court Sorcerer Trousers", DS3LocationCategory.ARMOR), DS3LocationData("PC: Wrath of the Gods", "Wrath of the Gods", DS3LocationCategory.SPELL), - DS3LocationData("PC: Logan's Scroll", "Logan's Scroll", DS3LocationCategory.MISC), - DS3LocationData("PC: Eleonora", "Eleonora", DS3LocationCategory.WEAPON), - DS3LocationData("PC: Court Sorcerer's Staff", "Court Sorcerer's Staff", DS3LocationCategory.WEAPON), - DS3LocationData("PC: Greatshield of Glory", "Greatshield of Glory", DS3LocationCategory.SHIELD), + DS3LocationData("PC: Logan's Scroll", "Logan's Scroll", DS3LocationCategory.MISC, + hostile_npc = True), # Sorcerer + DS3LocationData("PC: Eleonora", "Eleonora", DS3LocationCategory.WEAPON, + hidden = True), # Guaranteed drop from a normal-looking Monstrosity of Sin + DS3LocationData("PC: Court Sorcerer's Staff", "Court Sorcerer's Staff", DS3LocationCategory.WEAPON, + mimic = True), + DS3LocationData("PC: Greatshield of Glory", "Greatshield of Glory", DS3LocationCategory.SHIELD, + mimic = True), DS3LocationData("PC: Storm Ruler", "Storm Ruler", DS3LocationCategory.KEY), - DS3LocationData("PC: Cinders of a Lord - Yhorm the Giant", "Cinders of a Lord - Yhorm the Giant", DS3LocationCategory.KEY), - DS3LocationData("PC: Soul of Yhorm the Giant", "Soul of Yhorm the Giant", DS3LocationCategory.BOSS), + DS3LocationData("PC: Cinders of a Lord - Yhorm the Giant", "Cinders of a Lord - Yhorm the Giant", DS3LocationCategory.KEY, + prominent = True, progression = True, boss = True), + DS3LocationData("PC: Soul of Yhorm the Giant", "Soul of Yhorm the Giant", DS3LocationCategory.BOSS, + boss = True), ], "Anor Londo": [ DS3LocationData("AL: Giant's Coal", "Giant's Coal", DS3LocationCategory.MISC), DS3LocationData("AL: Sun Princess Ring", "Sun Princess Ring", DS3LocationCategory.RING), - DS3LocationData("AL: Aldrich's Ruby", "Aldrich's Ruby", DS3LocationCategory.RING), - DS3LocationData("AL: Cinders of a Lord - Aldrich", "Cinders of a Lord - Aldrich", DS3LocationCategory.KEY), - DS3LocationData("AL: Soul of Aldrich", "Soul of Aldrich", DS3LocationCategory.BOSS), + DS3LocationData("AL: Aldrich's Ruby", "Aldrich's Ruby", DS3LocationCategory.RING, + miniboss = True), # Deep Accursed drop + DS3LocationData("AL: Cinders of a Lord - Aldrich", "Cinders of a Lord - Aldrich", DS3LocationCategory.KEY, + prominent = True, progression = True, boss = True), + DS3LocationData("AL: Soul of Aldrich", "Soul of Aldrich", DS3LocationCategory.BOSS, + boss = True), ], "Lothric Castle": [ DS3LocationData("LC: Hood of Prayer", "Hood of Prayer", DS3LocationCategory.ARMOR), DS3LocationData("LC: Robe of Prayer", "Robe of Prayer", DS3LocationCategory.ARMOR), DS3LocationData("LC: Skirt of Prayer", "Skirt of Prayer", DS3LocationCategory.ARMOR), - DS3LocationData("LC: Sacred Bloom Shield", "Sacred Bloom Shield", DS3LocationCategory.SHIELD), - DS3LocationData("LC: Winged Knight Helm", "Winged Knight Helm", DS3LocationCategory.ARMOR), - DS3LocationData("LC: Winged Knight Armor", "Winged Knight Armor", DS3LocationCategory.ARMOR), - DS3LocationData("LC: Winged Knight Gauntlets", "Winged Knight Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("LC: Winged Knight Leggings", "Winged Knight Leggings", DS3LocationCategory.ARMOR), + DS3LocationData("LC: Sacred Bloom Shield", "Sacred Bloom Shield", DS3LocationCategory.SHIELD, + hidden = True), # Behind invisible wall + DS3LocationData("LC: Winged Knight Helm", "Winged Knight Helm", DS3LocationCategory.ARMOR, + hidden = True), # Behind invisible wall + DS3LocationData("LC: Winged Knight Armor", "Winged Knight Armor", DS3LocationCategory.ARMOR, + hidden = True), # Behind invisible wall + DS3LocationData("LC: Winged Knight Gauntlets", "Winged Knight Gauntlets", DS3LocationCategory.ARMOR, + hidden = True), # Behind invisible wall + DS3LocationData("LC: Winged Knight Leggings", "Winged Knight Leggings", DS3LocationCategory.ARMOR, + hidden = True), # Behind invisible wall DS3LocationData("LC: Greatlance", "Greatlance", DS3LocationCategory.WEAPON), DS3LocationData("LC: Sniper Crossbow", "Sniper Crossbow", DS3LocationCategory.WEAPON), DS3LocationData("LC: Spirit Tree Crest Shield", "Spirit Tree Crest Shield", DS3LocationCategory.SHIELD), DS3LocationData("LC: Red Tearstone Ring", "Red Tearstone Ring", DS3LocationCategory.RING), DS3LocationData("LC: Caitha's Chime", "Caitha's Chime", DS3LocationCategory.WEAPON), - DS3LocationData("LC: Braille Divine Tome of Lothric", "Braille Divine Tome of Lothric", DS3LocationCategory.MISC), + DS3LocationData("LC: Braille Divine Tome of Lothric", "Braille Divine Tome of Lothric", DS3LocationCategory.MISC, + hidden = True), # Hidden fall DS3LocationData("LC: Knight's Ring", "Knight's Ring", DS3LocationCategory.RING), - DS3LocationData("LC: Irithyll Rapier", "Irithyll Rapier", DS3LocationCategory.WEAPON), - DS3LocationData("LC: Sunlight Straight Sword", "Sunlight Straight Sword", DS3LocationCategory.WEAPON), - DS3LocationData("LC: Soul of Dragonslayer Armour", "Soul of Dragonslayer Armour", DS3LocationCategory.BOSS), - DS3LocationData("LC: Grand Archives Key", "Grand Archives Key", DS3LocationCategory.KEY), + DS3LocationData("LC: Irithyll Rapier", "Irithyll Rapier", DS3LocationCategory.WEAPON, + miniboss = True), # Boreal Outrider drop + DS3LocationData("LC: Sunlight Straight Sword", "Sunlight Straight Sword", DS3LocationCategory.WEAPON, + mimic = True, hidden = True), # Hidden fall + DS3LocationData("LC: Soul of Dragonslayer Armour", "Soul of Dragonslayer Armour", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("LC: Grand Archives Key", "Grand Archives Key", DS3LocationCategory.KEY, + prominent = True, progression = True, key = True), DS3LocationData("LC: Gotthard Twinswords", "Gotthard Twinswords", DS3LocationCategory.WEAPON), ], "Consumed King's Garden": [ @@ -446,59 +617,90 @@ def get_name_to_id() -> dict: DS3LocationData("CKG: Shadow Gauntlets", "Shadow Gauntlets", DS3LocationCategory.ARMOR), DS3LocationData("CKG: Shadow Leggings", "Shadow Leggings", DS3LocationCategory.ARMOR), DS3LocationData("CKG: Claw", "Claw", DS3LocationCategory.WEAPON), - DS3LocationData("CKG: Soul of Consumed Oceiros", "Soul of Consumed Oceiros", DS3LocationCategory.BOSS), - DS3LocationData("CKG: Magic Stoneplate Ring", "Magic Stoneplate Ring", DS3LocationCategory.RING), + DS3LocationData("CKG: Soul of Consumed Oceiros", "Soul of Consumed Oceiros", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("CKG: Magic Stoneplate Ring", "Magic Stoneplate Ring", DS3LocationCategory.RING, + hidden = True), # Guaranteed drop from a normal-looking Consumed King's Knight ], "Grand Archives": [ - DS3LocationData("GA: Avelyn", "Avelyn", DS3LocationCategory.WEAPON), - DS3LocationData("GA: Witch's Locks", "Witch's Locks", DS3LocationCategory.WEAPON), - DS3LocationData("GA: Power Within", "Power Within", DS3LocationCategory.SPELL), + DS3LocationData("GA: Avelyn", "Avelyn", DS3LocationCategory.WEAPON, + hidden = True), # Hidden fall + DS3LocationData("GA: Witch's Locks", "Witch's Locks", DS3LocationCategory.WEAPON, + hidden = True), # Switch in darkened room + DS3LocationData("GA: Power Within", "Power Within", DS3LocationCategory.SPELL, + hidden = True), # Switch in darkened room DS3LocationData("GA: Scholar Ring", "Scholar Ring", DS3LocationCategory.RING), - DS3LocationData("GA: Soul Stream", "Soul Stream", DS3LocationCategory.SPELL), + DS3LocationData("GA: Soul Stream", "Soul Stream", DS3LocationCategory.SPELL, + hidden = True), # Behind invisible wall DS3LocationData("GA: Fleshbite Ring", "Fleshbite Ring", DS3LocationCategory.RING), DS3LocationData("GA: Crystal Chime", "Crystal Chime", DS3LocationCategory.WEAPON), - DS3LocationData("GA: Golden Wing Crest Shield", "Golden Wing Crest Shield", DS3LocationCategory.SHIELD), - DS3LocationData("GA: Onikiri and Ubadachi", "Onikiri and Ubadachi", DS3LocationCategory.WEAPON), - DS3LocationData("GA: Hunter's Ring", "Hunter's Ring", DS3LocationCategory.RING), + DS3LocationData("GA: Golden Wing Crest Shield", "Golden Wing Crest Shield", DS3LocationCategory.SHIELD, + hostile_npc = True), # Lion Knight Albert drop + DS3LocationData("GA: Onikiri and Ubadachi", "Onikiri and Ubadachi", DS3LocationCategory.WEAPON, + hostile_npc = True), # Black Hand Kamui drop + DS3LocationData("GA: Hunter's Ring", "Hunter's Ring", DS3LocationCategory.RING, + hostile_npc = True), # Daughter of Crystal Kriemhild drop DS3LocationData("GA: Divine Pillars of Light", "Divine Pillars of Light", DS3LocationCategory.SPELL), - DS3LocationData("GA: Cinders of a Lord - Lothric Prince", "Cinders of a Lord - Lothric Prince", DS3LocationCategory.KEY), - DS3LocationData("GA: Soul of the Twin Princes", "Soul of the Twin Princes", DS3LocationCategory.BOSS), + DS3LocationData("GA: Cinders of a Lord - Lothric Prince", "Cinders of a Lord - Lothric Prince", DS3LocationCategory.KEY, + prominent = True, progression = True, boss = True), + DS3LocationData("GA: Soul of the Twin Princes", "Soul of the Twin Princes", DS3LocationCategory.BOSS, + boss = True), DS3LocationData("GA: Sage's Crystal Staff", "Sage's Crystal Staff", DS3LocationCategory.WEAPON), - DS3LocationData("GA: Outrider Knight Helm", "Outrider Knight Helm", DS3LocationCategory.ARMOR), - DS3LocationData("GA: Outrider Knight Armor", "Outrider Knight Armor", DS3LocationCategory.ARMOR), - DS3LocationData("GA: Outrider Knight Gauntlets", "Outrider Knight Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("GA: Outrider Knight Leggings", "Outrider Knight Leggings", DS3LocationCategory.ARMOR), - DS3LocationData("GA: Crystal Scroll", "Crystal Scroll", DS3LocationCategory.MISC), + DS3LocationData("GA: Outrider Knight Helm", "Outrider Knight Helm", DS3LocationCategory.ARMOR, + miniboss = True, hidden = True), # Behind invisible wall + DS3LocationData("GA: Outrider Knight Armor", "Outrider Knight Armor", DS3LocationCategory.ARMOR, + miniboss = True, hidden = True), # Behind invisible wall + DS3LocationData("GA: Outrider Knight Gauntlets", "Outrider Knight Gauntlets", DS3LocationCategory.ARMOR, + miniboss = True, hidden = True), # Behind invisible wall + DS3LocationData("GA: Outrider Knight Leggings", "Outrider Knight Leggings", DS3LocationCategory.ARMOR, + miniboss = True, hidden = True), # Behind invisible wall + DS3LocationData("GA: Crystal Scroll", "Crystal Scroll", DS3LocationCategory.MISC, + miniboss = True), # Crystal Sage drop ], "Untended Graves": [ - DS3LocationData("UG: Ashen Estus Ring", "Ashen Estus Ring", DS3LocationCategory.RING), - DS3LocationData("UG: Black Knight Glaive", "Black Knight Glaive", DS3LocationCategory.WEAPON), - DS3LocationData("UG: Hornet Ring", "Hornet Ring", DS3LocationCategory.RING), - DS3LocationData("UG: Chaos Blade", "Chaos Blade", DS3LocationCategory.WEAPON), - DS3LocationData("UG: Blacksmith Hammer", "Blacksmith Hammer", DS3LocationCategory.WEAPON), - DS3LocationData("UG: Eyes of a Fire Keeper", "Eyes of a Fire Keeper", DS3LocationCategory.KEY), - DS3LocationData("UG: Coiled Sword Fragment", "Coiled Sword Fragment", DS3LocationCategory.MISC), - DS3LocationData("UG: Soul of Champion Gundyr", "Soul of Champion Gundyr", DS3LocationCategory.BOSS), + DS3LocationData("UG: Ashen Estus Ring", "Ashen Estus Ring", DS3LocationCategory.RING, + hidden = True), # Behind invisible wall + DS3LocationData("UG: Black Knight Glaive", "Black Knight Glaive", DS3LocationCategory.WEAPON, + hidden = True), # Behind invisible wall + DS3LocationData("UG: Hornet Ring", "Hornet Ring", DS3LocationCategory.RING, + hidden = True), # Behind invisible wall + DS3LocationData("UG: Chaos Blade", "Chaos Blade", DS3LocationCategory.WEAPON, + hidden = True), # Behind invisible wall + DS3LocationData("UG: Blacksmith Hammer", "Blacksmith Hammer", DS3LocationCategory.WEAPON, + hidden = True), # Behind invisible wall + DS3LocationData("UG: Eyes of a Fire Keeper", "Eyes of a Fire Keeper", DS3LocationCategory.KEY, + hidden = True), # Behind invisible wall + DS3LocationData("UG: Coiled Sword Fragment", "Coiled Sword Fragment", DS3LocationCategory.MISC, + boss = True, hidden = True), # Behind invisible wall + DS3LocationData("UG: Soul of Champion Gundyr", "Soul of Champion Gundyr", DS3LocationCategory.BOSS, + prominent = True, boss = True, hidden = True), # Behind invisible wall ], "Archdragon Peak": [ DS3LocationData("AP: Lightning Clutch Ring", "Lightning Clutch Ring", DS3LocationCategory.RING), DS3LocationData("AP: Ancient Dragon Greatshield", "Ancient Dragon Greatshield", DS3LocationCategory.SHIELD), DS3LocationData("AP: Ring of Steel Protection", "Ring of Steel Protection", DS3LocationCategory.RING), - DS3LocationData("AP: Calamity Ring", "Calamity Ring", DS3LocationCategory.RING), - DS3LocationData("AP: Drakeblood Greatsword", "Drakeblood Greatsword", DS3LocationCategory.WEAPON), + DS3LocationData("AP: Calamity Ring", "Calamity Ring", DS3LocationCategory.RING, + hidden = True), # Requires gesture + DS3LocationData("AP: Drakeblood Greatsword", "Drakeblood Greatsword", DS3LocationCategory.WEAPON, + hostile_npc = True, hidden = True), # Drop from a summon who may or may not appear DS3LocationData("AP: Dragonslayer Spear", "Dragonslayer Spear", DS3LocationCategory.WEAPON), DS3LocationData("AP: Thunder Stoneplate Ring", "Thunder Stoneplate Ring", DS3LocationCategory.RING), DS3LocationData("AP: Great Magic Barrier", "Great Magic Barrier", DS3LocationCategory.SPELL), DS3LocationData("AP: Dragon Chaser's Ashes", "Dragon Chaser's Ashes", DS3LocationCategory.MISC), - DS3LocationData("AP: Twinkling Dragon Torso Stone", "Twinkling Dragon Torso Stone", DS3LocationCategory.MISC), + DS3LocationData("AP: Twinkling Dragon Torso Stone", "Twinkling Dragon Torso Stone", DS3LocationCategory.MISC, + hidden = True), # Requires gesture DS3LocationData("AP: Dragonslayer Helm", "Dragonslayer Helm", DS3LocationCategory.ARMOR), DS3LocationData("AP: Dragonslayer Armor", "Dragonslayer Armor", DS3LocationCategory.ARMOR), DS3LocationData("AP: Dragonslayer Gauntlets", "Dragonslayer Gauntlets", DS3LocationCategory.ARMOR), DS3LocationData("AP: Dragonslayer Leggings", "Dragonslayer Leggings", DS3LocationCategory.ARMOR), - DS3LocationData("AP: Ricard's Rapier", "Ricard's Rapier", DS3LocationCategory.WEAPON), - DS3LocationData("AP: Soul of the Nameless King", "Soul of the Nameless King", DS3LocationCategory.BOSS), - DS3LocationData("AP: Dragon Tooth", "Dragon Tooth", DS3LocationCategory.WEAPON), - DS3LocationData("AP: Havel's Greatshield", "Havel's Greatshield", DS3LocationCategory.SHIELD), + DS3LocationData("AP: Ricard's Rapier", "Ricard's Rapier", DS3LocationCategory.WEAPON, + hostile_npc = True, hidden = True), # Drop from a summon who may or may not appear + DS3LocationData("AP: Soul of the Nameless King", "Soul of the Nameless King", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("AP: Dragon Tooth", "Dragon Tooth", DS3LocationCategory.WEAPON, + hostile_npc = True), # Havel Knight drop + DS3LocationData("AP: Havel's Greatshield", "Havel's Greatshield", DS3LocationCategory.SHIELD, + hostile_npc = True), # Havel Knight drop ], "Kiln of the First Flame": [], @@ -510,15 +712,18 @@ def get_name_to_id() -> dict: DS3LocationData("PW: Captain's Ashes", "Captain's Ashes", DS3LocationCategory.MISC), DS3LocationData("PW: Millwood Battle Axe", "Millwood Battle Axe", DS3LocationCategory.WEAPON), DS3LocationData("PW: Ethereal Oak Shield", "Ethereal Oak Shield", DS3LocationCategory.SHIELD), - DS3LocationData("PW: Crow Quills", "Crow Quills", DS3LocationCategory.WEAPON), + DS3LocationData("PW: Crow Quills", "Crow Quills", DS3LocationCategory.WEAPON, + hidden = True), # Hidden fall DS3LocationData("PW: Slave Knight Hood", "Slave Knight Hood", DS3LocationCategory.ARMOR), DS3LocationData("PW: Slave Knight Armor", "Slave Knight Armor", DS3LocationCategory.ARMOR), DS3LocationData("PW: Slave Knight Gauntlets", "Slave Knight Gauntlets", DS3LocationCategory.ARMOR), DS3LocationData("PW: Slave Knight Leggings", "Slave Knight Leggings", DS3LocationCategory.ARMOR), DS3LocationData("PW: Way of White Corona", "Way of White Corona", DS3LocationCategory.SPELL), DS3LocationData("PW: Crow Talons", "Crow Talons", DS3LocationCategory.WEAPON), - DS3LocationData("PW: Onyx Blade", "Onyx Blade", DS3LocationCategory.WEAPON), - DS3LocationData("PW: Contraption Key", "Contraption Key", DS3LocationCategory.KEY), + DS3LocationData("PW: Onyx Blade", "Onyx Blade", DS3LocationCategory.WEAPON, + hostile_npc = True), # Sir Vilhelm drop + DS3LocationData("PW: Contraption Key", "Contraption Key", DS3LocationCategory.KEY, + prominent = True, progression = True, hostile_npc = True, key = True), # Sir Vilhelm drop ], "Painted World of Ariandel 2": [ DS3LocationData("PW: Quakestone Hammer", "Quakestone Hammer", DS3LocationCategory.WEAPON), @@ -533,9 +738,12 @@ def get_name_to_id() -> dict: DS3LocationData("PW: Vilhelm's Armor", "Vilhelm's Armor", DS3LocationCategory.ARMOR), DS3LocationData("PW: Vilhelm's Gauntlets", "Vilhelm's Gauntlets", DS3LocationCategory.ARMOR), DS3LocationData("PW: Vilhelm's Leggings", "Vilhelm's Leggings", DS3LocationCategory.ARMOR), - DS3LocationData("PW: Valorheart", "Valorheart", DS3LocationCategory.WEAPON), - DS3LocationData("PW: Champion's Bones", "Champion's Bones", DS3LocationCategory.MISC), - DS3LocationData("PW: Soul of Sister Friede", "Soul of Sister Friede", DS3LocationCategory.BOSS), + DS3LocationData("PW: Valorheart", "Valorheart", DS3LocationCategory.WEAPON, + prominent = True, boss = True), + DS3LocationData("PW: Champion's Bones", "Champion's Bones", DS3LocationCategory.MISC, + boss = True), + DS3LocationData("PW: Soul of Sister Friede", "Soul of Sister Friede", DS3LocationCategory.BOSS, + prominent = True, boss = True), DS3LocationData("PW: Chillbite Ring", "Chillbite Ring", DS3LocationCategory.RING), ], "Dreg Heap": [ @@ -543,7 +751,8 @@ def get_name_to_id() -> dict: DS3LocationData("DH: Aquamarine Dagger", "Aquamarine Dagger", DS3LocationCategory.WEAPON), DS3LocationData("DH: Murky Hand Scythe", "Murky Hand Scythe", DS3LocationCategory.WEAPON), DS3LocationData("DH: Murky Longstaff", "Murky Longstaff", DS3LocationCategory.WEAPON), - DS3LocationData("DH: Great Soul Dregs", "Great Soul Dregs", DS3LocationCategory.SPELL), + DS3LocationData("DH: Great Soul Dregs", "Great Soul Dregs", DS3LocationCategory.SPELL, + hidden = True), # Behind invisible wall DS3LocationData("DH: Lothric War Banner", "Lothric War Banner", DS3LocationCategory.WEAPON), DS3LocationData("DH: Projected Heal", "Projected Heal", DS3LocationCategory.SPELL), DS3LocationData("DH: Desert Pyromancer Hood", "Desert Pyromancer Hood", DS3LocationCategory.ARMOR), @@ -552,11 +761,15 @@ def get_name_to_id() -> dict: DS3LocationData("DH: Desert Pyromancer Skirt", "Desert Pyromancer Skirt", DS3LocationCategory.ARMOR), DS3LocationData("DH: Giant Door Shield", "Giant Door Shield", DS3LocationCategory.SHIELD), DS3LocationData("DH: Herald Curved Greatsword", "Herald Curved Greatsword", DS3LocationCategory.WEAPON), - DS3LocationData("DH: Flame Fan", "Flame Fan", DS3LocationCategory.SPELL), - DS3LocationData("DH: Soul of the Demon Prince", "Soul of the Demon Prince", DS3LocationCategory.BOSS), - DS3LocationData("DH: Small Envoy Banner", "Small Envoy Banner", DS3LocationCategory.KEY), + DS3LocationData("DH: Flame Fan", "Flame Fan", DS3LocationCategory.SPELL, + hostile_npc = True), # Desert Pyromancer Zoey drop + DS3LocationData("DH: Soul of the Demon Prince", "Soul of the Demon Prince", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("DH: Small Envoy Banner", "Small Envoy Banner", DS3LocationCategory.KEY, + boss = True), DS3LocationData("DH: Ring of Favor+3", "Ring of Favor+3", DS3LocationCategory.RING), - DS3LocationData("DH: Covetous Silver Serpent Ring+3", "Covetous Silver Serpent Ring+3", DS3LocationCategory.RING), + DS3LocationData("DH: Covetous Silver Serpent Ring+3", "Covetous Silver Serpent Ring+3", DS3LocationCategory.RING, + hidden = True), # Behind invisible wall DS3LocationData("DH: Ring of Steel Protection+3", "Ring of Steel Protection+3", DS3LocationCategory.RING), ], "Ringed City": [ @@ -570,36 +783,48 @@ def get_name_to_id() -> dict: DS3LocationData("RC: Black Witch Wrappings", "Black Witch Wrappings", DS3LocationCategory.ARMOR), DS3LocationData("RC: Black Witch Trousers", "Black Witch Trousers", DS3LocationCategory.ARMOR), DS3LocationData("RC: White Preacher Head", "White Preacher Head", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Havel's Ring+3", "Havel's Ring+3", DS3LocationCategory.RING), + DS3LocationData("RC: Havel's Ring+3", "Havel's Ring+3", DS3LocationCategory.RING, + hidden = True), # Hidden fall DS3LocationData("RC: Ringed Knight Spear", "Ringed Knight Spear", DS3LocationCategory.WEAPON), - DS3LocationData("RC: Dragonhead Shield", "Dragonhead Shield", DS3LocationCategory.SHIELD), + DS3LocationData("RC: Dragonhead Shield", "Dragonhead Shield", DS3LocationCategory.SHIELD, + hidden = true), # "Show Your Humanity" puzzle DS3LocationData("RC: Ringed Knight Straight Sword", "Ringed Knight Straight Sword", DS3LocationCategory.WEAPON), DS3LocationData("RC: Preacher's Right Arm", "Preacher's Right Arm", DS3LocationCategory.WEAPON), DS3LocationData("RC: White Birch Bow", "White Birch Bow", DS3LocationCategory.WEAPON), DS3LocationData("RC: Church Guardian Shiv", "Church Guardian Shiv", DS3LocationCategory.MISC), DS3LocationData("RC: Dragonhead Greatshield", "Dragonhead Greatshield", DS3LocationCategory.SHIELD), - DS3LocationData("RC: Ringed Knight Paired Greatswords", "Ringed Knight Paired Greatswords", DS3LocationCategory.WEAPON), + DS3LocationData("RC: Ringed Knight Paired Greatswords", "Ringed Knight Paired Greatswords", DS3LocationCategory.WEAPON, + hidden = True), # Guaranteed drop from a normal-looking Ringed Knight DS3LocationData("RC: Shira's Crown", "Shira's Crown", DS3LocationCategory.ARMOR), DS3LocationData("RC: Shira's Armor", "Shira's Armor", DS3LocationCategory.ARMOR), DS3LocationData("RC: Shira's Gloves", "Shira's Gloves", DS3LocationCategory.ARMOR), DS3LocationData("RC: Shira's Trousers", "Shira's Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Crucifix of the Mad King", "Crucifix of the Mad King", DS3LocationCategory.WEAPON), + DS3LocationData("RC: Crucifix of the Mad King", "Crucifix of the Mad King", DS3LocationCategory.WEAPON, + hostile_npc = True), # Shira drop DS3LocationData("RC: Sacred Chime of Filianore", "Sacred Chime of Filianore", DS3LocationCategory.WEAPON), - DS3LocationData("RC: Iron Dragonslayer Helm", "Iron Dragonslayer Helm", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Iron Dragonslayer Armor", "Iron Dragonslayer Armor", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Iron Dragonslayer Gauntlets", "Iron Dragonslayer Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Iron Dragonslayer Leggings", "Iron Dragonslayer Leggings", DS3LocationCategory.ARMOR), + DS3LocationData("RC: Iron Dragonslayer Helm", "Iron Dragonslayer Helm", DS3LocationCategory.ARMOR, + miniboss = True), + DS3LocationData("RC: Iron Dragonslayer Armor", "Iron Dragonslayer Armor", DS3LocationCategory.ARMOR, + miniboss = True), + DS3LocationData("RC: Iron Dragonslayer Gauntlets", "Iron Dragonslayer Gauntlets", DS3LocationCategory.ARMOR, + miniboss = True), + DS3LocationData("RC: Iron Dragonslayer Leggings", "Iron Dragonslayer Leggings", DS3LocationCategory.ARMOR, + miniboss = True), DS3LocationData("RC: Lightning Arrow", "Lightning Arrow", DS3LocationCategory.SPELL), DS3LocationData("RC: Ritual Spear Fragment", "Ritual Spear Fragment", DS3LocationCategory.MISC), DS3LocationData("RC: Antiquated Plain Garb", "Antiquated Plain Garb", DS3LocationCategory.ARMOR), DS3LocationData("RC: Violet Wrappings", "Violet Wrappings", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Soul of Darkeater Midir", "Soul of Darkeater Midir", DS3LocationCategory.BOSS), + DS3LocationData("RC: Soul of Darkeater Midir", "Soul of Darkeater Midir", DS3LocationCategory.BOSS, + prominent = True, boss = True), DS3LocationData("RC: Soul of Slave Knight Gael", "Soul of Slave Knight Gael", DS3LocationCategory.BOSS), DS3LocationData("RC: Blood of the Dark Soul", "Blood of the Dark Soul", DS3LocationCategory.KEY), - DS3LocationData("RC: Chloranthy Ring+3", "Chloranthy Ring+3", DS3LocationCategory.RING), + DS3LocationData("RC: Chloranthy Ring+3", "Chloranthy Ring+3", DS3LocationCategory.RING, + hidden = True), # Hidden fall DS3LocationData("RC: Covetous Gold Serpent Ring+3", "Covetous Gold Serpent Ring+3", DS3LocationCategory.RING), - DS3LocationData("RC: Ring of the Evil Eye+3", "Ring of the Evil Eye+3", DS3LocationCategory.RING), - DS3LocationData("RC: Wolf Ring+3", "Wolf Ring+3", DS3LocationCategory.RING), + DS3LocationData("RC: Ring of the Evil Eye+3", "Ring of the Evil Eye+3", DS3LocationCategory.RING, + mimic = True), + DS3LocationData("RC: Wolf Ring+3", "Wolf Ring+3", DS3LocationCategory.RING, + hostile_npc = True), # Alva drop ], # Progressive @@ -714,293 +939,28 @@ def get_name_to_id() -> dict: [DS3LocationData(f"Undead Bone Shard #{i + 1}", "Undead Bone Shard", DS3LocationCategory.HEALTH) for i in range(10)], } -# In addition to these hand-authored location groups, every region automatically -# has a location group added in the loop below. location_name_groups: Dict[str, Set[str]] = { - # A small number of locations (boss drops and progression locations) - # intended to be set as priority progression locations for players who don't - # want a lot of mandatory checks. - "Prominent Locations": frozenset([ - "HWL: Basin of Vows", - "HWL: Small Lothric Banner", - "CD: Small Doll", - "FK: Cinders of a Lord - Abyss Watcher", - "PC: Cinders of a Lord - Yhorm the Giant", - "AL: Cinders of a Lord - Aldrich", - "GA: Cinders of a Lord - Lothric Prince", - "LC: Grand Archives Key", - "PW: Contraption Key", - - "HWL: Soul of Boreal Valley Vordt", - "US: Soul of the Rotted Greatwood", - "RS: Soul of a Crystal Sage", - "CC: Soul of High Lord Wolnir", - "SL: Soul of the Old Demon King", - "IBV: Soul of Pontiff Sulyvahn", - "HWL: Soul of the Dancer", - "LC: Soul of Dragonslayer Armour", - "CKG: Soul of Consumed Oceiros", - "UG: Soul of Champion Gundyr", - "AP: Soul of the Nameless King", - "PW: Soul of Sister Friede", - "PW: Valorheart", - "DH: Soul of the Demon Prince", - "RC: Soul of Darkeater Midir", - ]), - - # Locations that contain items which block forward progress in the normal - # game order. - "Progression Locations": frozenset([ - "HWL: Basin of Vows", - "HWL: Small Lothric Banner", - "CD: Small Doll", - "FK: Cinders of a Lord - Abyss Watcher", - "PC: Cinders of a Lord - Yhorm the Giant", - "AL: Cinders of a Lord - Aldrich", - "GA: Cinders of a Lord - Lothric Prince", - "LC: Grand Archives Key", - "PW: Contraption Key", - ]), - - "Boss Rewards": frozenset([ - "HWL: Soul of Boreal Valley Vordt", - "US: Transposing Kiln", - "US: Soul of the Rotted Greatwood", - "RS: Soul of a Crystal Sage", - "FK: Soul of the Blood of the Wolf", - "FK: Cinders of a Lord - Abyss Watcher", - "CD: Small Doll", - "CD: Soul of the Deacons of the Deep", - "CD: Archdeacon White Crown", - "CD: Archdeacon Holy Garb", - "CD: Archdeacon Skirt", - "CC: Soul of High Lord Wolnir", - "SL: Soul of the Old Demon King", - "IBV: Soul of Pontiff Sulyvahn", - "PC: Soul of Yhorm the Giant", - "PC: Cinders of a Lord - Yhorm the Giant", - "AL: Soul of Aldrich", - "AL: Cinders of a Lord - Aldrich", - "HWL: Soul of the Dancer", - "LC: Soul of Dragonslayer Armour", - "CKG: Soul of Consumed Oceiros", - "UG: Soul of Champion Gundyr", - "UG: Coiled Sword Fragment", - "GA: Soul of the Twin Princes", - "GA: Cinders of a Lord - Lothric Prince", - "AP: Soul of the Nameless King", - "PW: Soul of Sister Friede", - "PW: Valorheart", - "PW: Champion's Bones", - "DH: Soul of the Demon Prince", - "DH: Small Envoy Banner", - "RC: Soul of Darkeater Midir", - - # Not currently randomized - # "FS: Coiled Sword", - # "AP: Dragon Head Stone", - # "RC: Fillianore's Spear Ornament", - # "RC: Spears of the Church", - ]), - - "Miniboss Rewards": frozenset([ - "US: Bloodbite Ring", # Giant Rat drop - "US: Irithyll Straight Sword", # Irithyll Outrider drop - "RS: Great Swamp Ring", # Great Crab drop - "FK: Soul of a Stray Demon", - "FK: Lingering Dragoncrest Ring", # Great Crab drop - "CC: Soul of a Demon", - "SL: Lightning Stake", # Sand Worm drop - "CD: Aldrich's Sapphire", # Deep Accursed drop - "CD: Saint Bident", # Guarded by giant - "IBV: Pontiff's Right Eye", # Sulyvahn's Beast drop - "IBV: Ring of Favor", # Sulyvahn's Beast Duo drop - "IBV: Aldrich Faithful", # Sulyvahn's Beast Duo reward - "AL: Aldrich's Ruby", # Deep Accursed drop - "LC: Irithyll Rapier", # Boreal Outrider drop - "GA: Crystal Scroll", # Crystal Sage drop - "GA: Outrider Knight Helm", - "GA: Outrider Knight Armor", - "GA: Outrider Knight Gauntlets", - "GA: Outrider Knight Leggings", - "RC: Iron Dragonslayer Helm", - "RC: Iron Dragonslayer Armor", - "RC: Iron Dragonslayer Gauntlets", - "RC: Iron Dragonslayer Leggings", - ]), - - "Mimic Rewards": frozenset([ - "HWL: Deep Battle Axe", - "CC: Black Blade", - "CD: Deep Braille Divine Tome", - "IBV: Golden Ritual Spear", - "ID: Dark Clutch Ring", - "PC: Court Sorcerer's Staff", - "PC: Greatshield of Glory", - "LC: Sunlight Straight Sword", - "RC: Ring of the Evil Eye+3", - ]), - - "Hostile NPC Rewards": frozenset([ - "FS: Uchigatana", # Sword Master - "FS: Master's Attire", # Sword Master - "FS: Master's Gloves", # Sword Master - "RS: Exile Greatsword", # Exile Knight #1 - "RS: Great Club", # Exile Knight #2 - "SL: Knight Slayer's Ring", # Knight Slayer Tsorig - "SL: Fume Ultra Greatsword", # Knight Slayer Tsorig - "SL: Black Iron Greatshield", # Knight Slayer Tsorig - "CD: Spider Shield", # Brigand - "PC: Logan's Scroll", # Sorcerer on roof in toxic pool - "GA: Golden Wing Crest Shield", # Lion Knight Albert - "GA: Onikiri and Ubadachi", # Black Hand Kamui - "GA: Sage's Crystal Staff", # Daughter of Crystal Kriemhild - "AP: Dragon Tooth", # Havel Knight - "DH: Flame Fan", # Desert Pyromancer Zoey drop - "RC: Wolf Ring+3", # Alva - "RC: Crucifix of the Mad King", # Shira - "PW: Contraption Key", # Sir Vilhelm - "PW: Onyx Blade", # Sir Vilhelm - - # Not currently randomized: - # "AP: Havel's Greatshield", # Havel Knight - # "RC: Ledo's Great Hammer", # Silver Knight Ledo - # "RC: Blindfold Mask", # Moaning Knight - ]), - - "Key Locations": frozenset([ - "HWL: Cell Key", - "ID: Jailer's Key Ring", - "ID: Jailbreaker's Key", - "ID: Old Cell Key", - "LC: Grand Archives Key", - "PW: Contraption Key", - - # Not currently randomized: - # "FS: Grave Key", - # "FS: Lift Chamber Key", - # "FS: Tower Key", - ]), - - # Locations that are particularly tricky to find or get to, for players - # without an encyclopedic knowledge of DS3 who don't want to get stuck - # looking for an invisible wall or one random mob with a guaranteed drop. - "Hidden Locations": frozenset([ - "RC: Dragonhead Shield", # requires gesture - "SL: Speckled Stoneplate Ring", # requires careful ballista shot - - # Out-of-the-way cave - "FK: Golden Scroll", - "FK: Antiquated Dress", - "FK: Antiquated Gloves", - "FK: Antiquated Skirt", - - # In lava - "SL: Toxic Mist", - "SL: White Hair Talisman", - "SL: Sacred Flame", - - # Guaranteed drop from normalish enemy - "RS: Butcher Knife", # Butcher drop - "CD: Deep Ring", # Deacon drop - "FK: Pharis's Hat", # Elder Ghru drop - "FK: Black Bow of Pharis", # Elder Ghru drop - "ID: Great Magic Shield", # Corpse-Grub drop - "PC: Eleonora", # Monstrosity of Sin drop - "CKG: Magic Stoneplate Ring", # Consumed King's Knight drop - "RC: Ringed Knight Paired Greatswords", # Ringed Knight drop - - # Have to return to cleared area - "CD: Archdeacon White Crown", - "CD: Archdeacon Holy Garb", - "CD: Archdeacon Skirt", - - # Invisible walkway - "IBV: Painting Guardian's Curved Sword", - "IBV: Painting Guardian Hood", - "IBV: Painting Guardian Gown", - "IBV: Painting Guardian Gloves", - "IBV: Painting Guardian Waistcloth", - - # Switch in darkened room - "GA: Witch's Locks", - "GA: Power Within", - - # Gesture requirements - "AP: Calamity Ring", - "AP: Twinkling Dragon Torso Stone", - - # Drop from a summon who may or may not appear - "AP: Drakeblood Greatsword", - "AP: Ricard's Rapier", - - # "Show Your Humanity" puzzle - "RC: Dragonhead Shield", - - # Hidden falls - "HWL: Astora's Straight Sword", - "US: Chloranthy Ring", - "US: Warrior of Sunlight", - "US: Mirrah Vest", - "US: Mirrah Gloves", - "US: Mirrah Trousers", - "RS: Braille Divine Tome of Carim", - "RS: Morne's Ring", - "RS: Sorcerer Hood", - "RS: Sorcerer Robe", - "RS: Sorcerer Gloves", - "RS: Sorcerer Trousers", - "RS: Sage Ring", - "FK: Atonement", - "SL: Dragonrider Bow", - "CD: Arbalest", - "LC: Sunlight Straight Sword", - "LC: Braille Divine Tome of Lothric", - "CD: Rosaria's Fingers", - "PW: Crow Quills", - "GA: Avelyn", - "RC: Chloranthy Ring+3", - "RC: Havel's Ring+3", - # "CC: Ring of Steel Protection+2", # Not currently randomized - # "PC: Onislayer Greatbow", # Not currently randomized - - # Behind illusory walls - "FSBT: Covetous Silver Serpent Ring", - "IBV: Ring of Favor", - "GA: Outrider Knight Helm", - "GA: Soul Stream", - "FK: Dreamchaser's Ashes", - "CC: Carthus Pyromancy Tome", - "SL: Black Knight Sword", - "SL: Quelana Pyromancy Tome", - "SL: Izalith Staff", - "IBV: Magic Clutch Ring", - "IBV: Dorhys' Gnawing", - "IBV: Witchtree Branch", - "IBV: Aldrich Faithful", - "UG: Ashen Estus Ring", - "UG: Black Knight Glaive", - "UG: Hornet Ring", - "UG: Chaos Blade", - "UG: Blacksmith Hammer", - "UG: Eyes of a Fire Keeper", - "UG: Coiled Sword Fragment", - "UG: Soul of Champion Gundyr", - "LC: Sacred Bloom Shield", - "LC: Winged Knight Helm", - "LC: Winged Knight Armor", - "LC: Winged Knight Gauntlets", - "LC: Winged Knight Leggings", - "DH: Great Soul Dregs", - "DH: Covetous Silver Serpent Ring+3", - # "SL: Flame Stoneplate Ring+2", # Not currently randomized - ]) + # We could insert these locations automatically with setdefault(), but we set them up explicitly + # instead so we can choose the ordering. + "Prominent": set(), + "Progression": set(), + "Boss Rewards": set(), + "Miniboss Rewards": set(), + "Mimic Rewards": set(), + "Hostile NPC Rewards": set(), + "Keys": set(), + "Hidden": set() } + location_dictionary: Dict[str, DS3LocationData] = {} for location_name, location_table in location_tables.items(): location_dictionary.update({location_data.name: location_data for location_data in location_table}) + for location_data in location_table: + for group_name in location_data.location_groups(): + location_name[group_name].add(group_name) + # Allow entire locations to be added to location sets. if not location_name.startswith("Progressive Items"): location_name_groups[location_name] = frozenset([ From 653bbaff5844eb0f59cd27e4b9aaa1c55ee95deb Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 24 Oct 2023 18:57:23 -0700 Subject: [PATCH 022/238] Track Archipelago/Offline mismatches on the server Also fix a few incorrect item names. --- worlds/dark_souls_3/Items.py | 4 +-- worlds/dark_souls_3/Locations.py | 50 ++++++++++++++++++++------------ 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 754282e73647..e3cba09fc899 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -98,7 +98,7 @@ def get_name_to_id() -> dict: ("Irithyll Straight Sword", 0x0020A760, DS3ItemCategory.WEAPON_UPGRADE_5), ("Cleric's Candlestick", 0x0020F580, DS3ItemCategory.WEAPON_UPGRADE_5), ("Morion Blade", 0x002143A0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Astora's Straight Sword", 0x002191C0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + ("Astora Straight Sword", 0x002191C0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), ("Barbed Straight Sword", 0x0021B8D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), ("Executioner's Greatsword", 0x0021DFE0, DS3ItemCategory.WEAPON_UPGRADE_10), ("Anri's Straight Sword", 0x002206F0, DS3ItemCategory.WEAPON_UPGRADE_5), @@ -158,7 +158,7 @@ def get_name_to_id() -> dict: ("Deep Battle Axe", 0x006AFA54, DS3ItemCategory.WEAPON_UPGRADE_10), ("Brigand Axe", 0x006B1DE0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), ("Crescent Axe", 0x006B6C00, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Great Axe", 0x006B9310, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + ("Greataxe", 0x006B9310, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), ("Butcher Knife", 0x006BE130, DS3ItemCategory.WEAPON_UPGRADE_10), ("Dragonslayer's Axe", 0x006C0840, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), ("Thrall Axe", 0x006C5660, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 604d9cf67cda..9e2c380c8361 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -32,6 +32,13 @@ class DS3LocationData: category: DS3LocationCategory """The category into which this location falls.""" + offline: str + """The key in the offline randomizer's Slots table that corresponds to this location. + + In most cases, the offline randomizer can automatically associate Archipelago location names + with its own notion of locations, but there are cases (multiple copies of the same item in the + same region, different region categorizations) where this heuristic doesn't work.""" + npc: bool = False """Whether this item is contingent on killing an NPC or following their quest.""" @@ -194,7 +201,7 @@ def get_name_to_id() -> dict: DS3LocationData("HWL: Mail Breaker", "Mail Breaker", DS3LocationCategory.WEAPON), DS3LocationData("HWL: Broadsword", "Broadsword", DS3LocationCategory.WEAPON), DS3LocationData("HWL: Silver Eagle Kite Shield", "Silver Eagle Kite Shield", DS3LocationCategory.SHIELD), - DS3LocationData("HWL: Astora's Straight Sword", "Astora's Straight Sword", DS3LocationCategory.WEAPON, + DS3LocationData("HWL: Astora Straight Sword", "Astora Straight Sword", DS3LocationCategory.WEAPON, hidden = True), # Hidden fall DS3LocationData("HWL: Cell Key", "Cell Key", DS3LocationCategory.KEY, key = True), @@ -260,7 +267,8 @@ def get_name_to_id() -> dict: DS3LocationData("US: Hawk Ring", "Hawk Ring", DS3LocationCategory.RING), DS3LocationData("US: Warrior of Sunlight", "Warrior of Sunlight", DS3LocationCategory.MISC, hidden = True), # Hidden fall - DS3LocationData("US: Blessed Red and White Shield+1", "Blessed Red and White Shield+1", DS3LocationCategory.SHIELD), + DS3LocationData("US: Blessed Red and White Shield+1", "Blessed Red and White Shield+1", DS3LocationCategory.SHIELD, + offline = "02,0:53100740::"), DS3LocationData("US: Irina's Ashes", "Irina's Ashes", DS3LocationCategory.KEY, npc = True), DS3LocationData("US: Cornyx's Ashes", "Cornyx's Ashes", DS3LocationCategory.KEY, @@ -323,10 +331,14 @@ def get_name_to_id() -> dict: DS3LocationData("RS: Sellsword Gauntlet", "Sellsword Gauntlet", DS3LocationCategory.ARMOR), DS3LocationData("RS: Sellsword Trousers", "Sellsword Trousers", DS3LocationCategory.ARMOR), DS3LocationData("RS: Golden Falcon Shield", "Golden Falcon Shield", DS3LocationCategory.SHIELD), - DS3LocationData("RS: Herald Helm", "Herald Helm", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Herald Armor", "Herald Armor", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Herald Gloves", "Herald Gloves", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Herald Trousers", "Herald Trousers", DS3LocationCategory.ARMOR), + DS3LocationData("RS: Herald Helm", "Herald Helm", DS3LocationCategory.ARMOR, + offline = "03,0:53300740::"), + DS3LocationData("RS: Herald Armor", "Herald Armor", DS3LocationCategory.ARMOR, + offline = "03,0:53300740::"), + DS3LocationData("RS: Herald Gloves", "Herald Gloves", DS3LocationCategory.ARMOR, + offline = "03,0:53300740::"), + DS3LocationData("RS: Herald Trousers", "Herald Trousers", DS3LocationCategory.ARMOR, + offline = "03,0:53300740::"), DS3LocationData("RS: Grass Crest Shield", "Grass Crest Shield", DS3LocationCategory.SHIELD), DS3LocationData("RS: Soul of a Crystal Sage", "Soul of a Crystal Sage", DS3LocationCategory.BOSS, prominent = True, boss = True), @@ -349,7 +361,7 @@ def get_name_to_id() -> dict: DS3LocationData("CD: Lloyd's Sword Ring", "Lloyd's Sword Ring", DS3LocationCategory.RING), DS3LocationData("CD: Seek Guidance", "Seek Guidance", DS3LocationCategory.SPELL), DS3LocationData("CD: Aldrich's Sapphire", "Aldrich's Sapphire", DS3LocationCategory.RING, - miniboss = True), # Deep Accursed Drop + offline = "06,0:50002130::", miniboss = True), # Deep Accursed Drop DS3LocationData("CD: Deep Braille Divine Tome", "Deep Braille Divine Tome", DS3LocationCategory.MISC, mimic = True), DS3LocationData("CD: Saint Bident", "Saint Bident", DS3LocationCategory.WEAPON, @@ -409,14 +421,14 @@ def get_name_to_id() -> dict: hidden = True), # Guaranteed drop from a normal-looking Elder Ghru DS3LocationData("FK: Dreamchaser's Ashes", "Dreamchaser's Ashes", DS3LocationCategory.MISC, hidden = True), # Behind invisible wall - DS3LocationData("FK: Great Axe", "Great Axe", DS3LocationCategory.WEAPON), + DS3LocationData("FK: Greataxe", "Greataxe", DS3LocationCategory.WEAPON), DS3LocationData("FK: Dragon Crest Shield", "Dragon Crest Shield", DS3LocationCategory.SHIELD), DS3LocationData("FK: Lightning Spear", "Lightning Spear", DS3LocationCategory.SPELL), DS3LocationData("FK: Atonement", "Atonement", DS3LocationCategory.SPELL, hidden = True), # Hidden fall DS3LocationData("FK: Great Magic Weapon", "Great Magic Weapon", DS3LocationCategory.SPELL), DS3LocationData("FK: Cinders of a Lord - Abyss Watcher", "Cinders of a Lord - Abyss Watcher", DS3LocationCategory.KEY, - prominent = True, progression = True, boss = True), + offline = "03,0:50002100::", prominent = True, progression = True, boss = True), DS3LocationData("FK: Soul of the Blood of the Wolf", "Soul of the Blood of the Wolf", DS3LocationCategory.BOSS, boss = True), DS3LocationData("FK: Soul of a Stray Demon", "Soul of a Stray Demon", DS3LocationCategory.BOSS, @@ -459,7 +471,7 @@ def get_name_to_id() -> dict: DS3LocationData("SL: Sacred Flame", "Sacred Flame", DS3LocationCategory.SPELL, hidden = True), # In lava DS3LocationData("CC: Knight Slayer's Ring", "Knight Slayer's Ring", DS3LocationCategory.RING, - hostile_npc = True), # Knight Slayer Tsorig drop + offline = "05,0:50006840::", hostile_npc = True), # Knight Slayer Tsorig drop DS3LocationData("SL: Fume Ultra Greatsword", "Fume Ultra Greatsword", DS3LocationCategory.WEAPON, hostile_npc = True), # Knight Slayer Tsorig drop DS3LocationData("SL: Black Iron Greatshield", "Black Iron Greatshield", DS3LocationCategory.SHIELD, @@ -477,7 +489,7 @@ def get_name_to_id() -> dict: DS3LocationData("IBV: Ring of the Sun's First Born", "Ring of the Sun's First Born", DS3LocationCategory.RING), DS3LocationData("IBV: Roster of Knights", "Roster of Knights", DS3LocationCategory.MISC), DS3LocationData("IBV: Pontiff's Right Eye", "Pontiff's Right Eye", DS3LocationCategory.RING, - miniboss = True), # Sullyvahn's Beast drop + offline = "06,0:53700995::", miniboss = True), # Sullyvahn's Beast drop DS3LocationData("IBV: Yorshka's Spear", "Yorshka's Spear", DS3LocationCategory.WEAPON), DS3LocationData("IBV: Great Heal", "Great Heal", DS3LocationCategory.SPELL), DS3LocationData("IBV: Smough's Great Hammer", "Smough's Great Hammer", DS3LocationCategory.WEAPON), @@ -532,7 +544,7 @@ def get_name_to_id() -> dict: DS3LocationData("ID: Profaned Flame", "Profaned Flame", DS3LocationCategory.SPELL), DS3LocationData("ID: Covetous Gold Serpent Ring", "Covetous Gold Serpent Ring", DS3LocationCategory.RING), DS3LocationData("ID: Jailer's Key Ring", "Jailer's Key Ring", DS3LocationCategory.KEY, - key = True), + offline = "07,0:53900520::", key = True), DS3LocationData("ID: Dusk Crown Ring", "Dusk Crown Ring", DS3LocationCategory.RING), DS3LocationData("ID: Dark Clutch Ring", "Dark Clutch Ring", DS3LocationCategory.RING, mimic = True), @@ -564,15 +576,17 @@ def get_name_to_id() -> dict: mimic = True), DS3LocationData("PC: Storm Ruler", "Storm Ruler", DS3LocationCategory.KEY), DS3LocationData("PC: Cinders of a Lord - Yhorm the Giant", "Cinders of a Lord - Yhorm the Giant", DS3LocationCategory.KEY, - prominent = True, progression = True, boss = True), + offline = "07,0:50002170::", prominent = True, progression = True, boss = True), DS3LocationData("PC: Soul of Yhorm the Giant", "Soul of Yhorm the Giant", DS3LocationCategory.BOSS, boss = True), ], "Anor Londo": [ - DS3LocationData("AL: Giant's Coal", "Giant's Coal", DS3LocationCategory.MISC), - DS3LocationData("AL: Sun Princess Ring", "Sun Princess Ring", DS3LocationCategory.RING), + DS3LocationData("AL: Giant's Coal", "Giant's Coal", DS3LocationCategory.MISC, + offline = "06,0:53700800::"), + DS3LocationData("AL: Sun Princess Ring", "Sun Princess Ring", DS3LocationCategory.RING, + offline = "06,0:53700840::"), DS3LocationData("AL: Aldrich's Ruby", "Aldrich's Ruby", DS3LocationCategory.RING, - miniboss = True), # Deep Accursed drop + offline = "06,1:3700355::", miniboss = True), # Deep Accursed drop DS3LocationData("AL: Cinders of a Lord - Aldrich", "Cinders of a Lord - Aldrich", DS3LocationCategory.KEY, prominent = True, progression = True, boss = True), DS3LocationData("AL: Soul of Aldrich", "Soul of Aldrich", DS3LocationCategory.BOSS, @@ -642,7 +656,7 @@ def get_name_to_id() -> dict: hostile_npc = True), # Daughter of Crystal Kriemhild drop DS3LocationData("GA: Divine Pillars of Light", "Divine Pillars of Light", DS3LocationCategory.SPELL), DS3LocationData("GA: Cinders of a Lord - Lothric Prince", "Cinders of a Lord - Lothric Prince", DS3LocationCategory.KEY, - prominent = True, progression = True, boss = True), + offline = "09,0:50002040::", prominent = True, progression = True, boss = True), DS3LocationData("GA: Soul of the Twin Princes", "Soul of the Twin Princes", DS3LocationCategory.BOSS, boss = True), DS3LocationData("GA: Sage's Crystal Staff", "Sage's Crystal Staff", DS3LocationCategory.WEAPON), @@ -663,7 +677,7 @@ def get_name_to_id() -> dict: DS3LocationData("UG: Black Knight Glaive", "Black Knight Glaive", DS3LocationCategory.WEAPON, hidden = True), # Behind invisible wall DS3LocationData("UG: Hornet Ring", "Hornet Ring", DS3LocationCategory.RING, - hidden = True), # Behind invisible wall + offline = "00,0:54000330::", hidden = True), # Behind invisible wall DS3LocationData("UG: Chaos Blade", "Chaos Blade", DS3LocationCategory.WEAPON, hidden = True), # Behind invisible wall DS3LocationData("UG: Blacksmith Hammer", "Blacksmith Hammer", DS3LocationCategory.WEAPON, From 3f9ba46c5d5b3c3ceff5224fffe82f193aca8359 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 25 Oct 2023 02:54:11 -0700 Subject: [PATCH 023/238] Add additional locations that are now randomizable --- Utils.py | 11 +- worlds/dark_souls_3/Items.py | 2440 +++++++++-------- worlds/dark_souls_3/Locations.py | 2874 ++++++++++++++++---- worlds/dark_souls_3/__init__.py | 173 +- worlds/dark_souls_3/test/TestDarkSouls3.py | 11 + worlds/dark_souls_3/test/__init__.py | 0 worlds/sm/variaRandomizer/logic/smbool.py | 6 +- 7 files changed, 3735 insertions(+), 1780 deletions(-) create mode 100644 worlds/dark_souls_3/test/TestDarkSouls3.py create mode 100644 worlds/dark_souls_3/test/__init__.py diff --git a/Utils.py b/Utils.py index 5fb037a17325..ce8d5c87860f 100644 --- a/Utils.py +++ b/Utils.py @@ -2,6 +2,7 @@ import asyncio import json +import types import typing import builtins import os @@ -17,7 +18,7 @@ from argparse import Namespace from settings import Settings, get_settings -from typing import BinaryIO, Coroutine, Optional, Set, Dict, Any, Union +from typing import BinaryIO, Coroutine, Generator, Generic, List, Optional, Set, TypeVar, Dict, Any, Union from yaml import load, load_all, dump, SafeLoader try: @@ -743,6 +744,14 @@ def async_start(co: Coroutine[None, None, typing.Any], name: Optional[str] = Non task.add_done_callback(_faf_tasks.discard) +T = TypeVar("T") +def flatten(l: List[T] | Generator[T] | T) -> List[T]: + if type(l) is list or type(l) is types.GeneratorType: + return [ y for x in l for y in flatten(x) ] + else: + return [ l ] + + def deprecate(message: str): if __debug__: raise Exception(message) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index e3cba09fc899..9a8a39403dcf 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -1,7 +1,12 @@ +from collections.abc import Generator +from dataclasses import dataclass, field +import dataclasses from enum import IntEnum -from typing import NamedTuple +import itertools +from typing import List, NamedTuple, Optional, Self, TypeVar -from BaseClasses import Item +from BaseClasses import Item, ItemClassification +from Utils import flatten class DS3ItemCategory(IntEnum): @@ -19,15 +24,57 @@ class DS3ItemCategory(IntEnum): SKIP = 11 -class DS3ItemData(NamedTuple): +@dataclass +class DS3ItemData(): name: str ds3_code: int - is_dlc: bool category: DS3ItemCategory + is_dlc: bool = False + """Whether this item is only found in one of the two DLC packs.""" + + count: int = 1 + """The number of copies of this item included in each drop.""" + + inject: bool = False + """If this is set, the randomizer will try to inject this item into the game. + + This is used for items such as covenant rewards that aren't realistically reachable in a + randomizer run, but are still fun to have available to the player. If there are more locations + available than there are items in the item pool, these items will be used to help make up the + difference. + """ + + def counts(self, counts: List[int]) -> Generator[Self]: + """Returns an iterable of copies of this item with the given counts.""" + yield self + for count in counts: + yield dataclasses.replace( + self, + name = "{} x{}".format(self.name, count), + count = count, + ) + + def __hash__(self): + return hash((name, count)) + + def __eq__(self, other): + return self.name == other.name and self.count == other.count + class DarkSouls3Item(Item): game: str = "Dark Souls III" + count: int = 1 + + def __init__( + self, + name: str, + classification: ItemClassification, + code: Optional[int], + player: int, + count: Optional[int] = None): + super().__init__(name, classification, code, player) + self.count = count or 1 @staticmethod def get_name_to_id() -> dict: @@ -46,1230 +93,1275 @@ def get_name_to_id() -> dict: "Cinders of a Lord - Aldrich", "Cinders of a Lord - Lothric Prince", "Mortician's Ashes", + "Dreamchaser's Ashes", + "Paladin's Ashes", + "Grave Warden's Ashes", + "Prisoner Chief's Ashes", + "Xanthus Ashes", + "Dragon Chaser's Ashes", + "Easterner's Ashes", + "Captain's Ashes", "Cell Key", - #"Tower Key", #Not a relevant key item atm + "Tower Key", + "Lift Chamber Key", "Jailbreaker's Key", - "Prisoner Chief's Ashes", "Old Cell Key", "Jailer's Key Ring", "Contraption Key", "Small Envoy Banner" } - -_vanilla_items = [DS3ItemData(row[0], row[1], False, row[2]) for row in [ +_vanilla_items = flatten([ # Ammunition - ("Standard Arrow", 0x00061A80, DS3ItemCategory.SKIP), - ("Fire Arrow", 0x00061AE4, DS3ItemCategory.SKIP), - ("Poison Arrow", 0x00061B48, DS3ItemCategory.SKIP), - ("Large Arrow", 0x00061BAC, DS3ItemCategory.SKIP), - ("Feather Arrow", 0x00061C10, DS3ItemCategory.SKIP), - ("Moonlight Arrow", 0x00061C74, DS3ItemCategory.SKIP), - ("Wood Arrow", 0x00061CD8, DS3ItemCategory.SKIP), - ("Dark Arrow", 0x00061D3C, DS3ItemCategory.SKIP), - ("Dragonslayer Greatarrow", 0x00062250, DS3ItemCategory.SKIP), - ("Dragonslayer Lightning Arrow", 0x00062318, DS3ItemCategory.SKIP), - ("Onislayer Greatarrow", 0x0006237C, DS3ItemCategory.SKIP), - ("Standard Bolt", 0x00062A20, DS3ItemCategory.SKIP), - ("Heavy Bolt", 0x00062A84, DS3ItemCategory.SKIP), - ("Sniper Bolt", 0x00062AE8, DS3ItemCategory.SKIP), - ("Wood Bolt", 0x00062B4C, DS3ItemCategory.SKIP), - ("Lightning Bolt", 0x00062BB0, DS3ItemCategory.SKIP), - ("Splintering Bolt", 0x00062C14, DS3ItemCategory.SKIP), - ("Exploding Bolt", 0x00062C78, DS3ItemCategory.SKIP), + DS3ItemData("Standard Arrow x12", 0x00061A80, DS3ItemCategory.MISC).counts([12]), + DS3ItemData("Fire Arrow", 0x00061AE4, DS3ItemCategory.MISC), + DS3ItemData("Poison Arrow x18", 0x00061B48, DS3ItemCategory.MISC).counts([18]), + DS3ItemData("Large Arrow", 0x00061BAC, DS3ItemCategory.MISC), + DS3ItemData("Feather Arrow", 0x00061C10, DS3ItemCategory.MISC), + DS3ItemData("Moonlight Arrow x6", 0x00061C74, DS3ItemCategory.MISC).counts([6]), + DS3ItemData("Wood Arrow", 0x00061CD8, DS3ItemCategory.MISC), + DS3ItemData("Dark Arrow", 0x00061D3C, DS3ItemCategory.MISC), + DS3ItemData("Dragonslayer Greatarrow x5", 0x00062250, DS3ItemCategory.MISC).counts([5]), + DS3ItemData("Dragonslayer Lightning Arrow x10", 0x00062318, DS3ItemCategory.MISC).counts([10]), + DS3ItemData("Onislayer Greatarrow x8", 0x0006237C, DS3ItemCategory.MISC).counts([8]), + DS3ItemData("Standard Bolt", 0x00062A20, DS3ItemCategory.MISC), + DS3ItemData("Heavy Bolt", 0x00062A84, DS3ItemCategory.MISC), + DS3ItemData("Sniper Bolt x11", 0x00062AE8, DS3ItemCategory.MISC).counts([11]), + DS3ItemData("Wood Bolt", 0x00062B4C, DS3ItemCategory.MISC), + DS3ItemData("Lightning Bolt x9", 0x00062BB0, DS3ItemCategory.MISC).counts([9]), + DS3ItemData("Lightning Bolt x12", 0x00062BB0, DS3ItemCategory.MISC).counts([12]), + DS3ItemData("Splintering Bolt", 0x00062C14, DS3ItemCategory.MISC), + DS3ItemData("Exploding Bolt x6", 0x00062C78, DS3ItemCategory.MISC).counts([6]), # Weapons - ("Dagger", 0x000F4240, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Bandit's Knife", 0x000F6950, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Parrying Dagger", 0x000F9060, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Rotten Ghru Dagger", 0x000FDE80, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Harpe", 0x00102CA0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Scholar's Candlestick", 0x001053B0, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Tailbone Short Sword", 0x00107AC0, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Corvian Greatknife", 0x0010A1D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Handmaid's Dagger", 0x00111700, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Shortsword", 0x001E8480, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Longsword", 0x001EAB90, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Broadsword", 0x001ED2A0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Broken Straight Sword", 0x001EF9B0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Lothric Knight Sword", 0x001F6EE0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Sunlight Straight Sword", 0x00203230, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Rotten Ghru Curved Sword", 0x00205940, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Irithyll Straight Sword", 0x0020A760, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Cleric's Candlestick", 0x0020F580, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Morion Blade", 0x002143A0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Astora Straight Sword", 0x002191C0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Barbed Straight Sword", 0x0021B8D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Executioner's Greatsword", 0x0021DFE0, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Anri's Straight Sword", 0x002206F0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Estoc", 0x002DC6C0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Mail Breaker", 0x002DEDD0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Rapier", 0x002E14E0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Ricard's Rapier", 0x002E3BF0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Crystal Sage's Rapier", 0x002E6300, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Irithyll Rapier", 0x002E8A10, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Shotel", 0x003D3010, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Scimitar", 0x003D7E30, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Falchion", 0x003DA540, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Carthus Curved Sword", 0x003DCC50, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Carthus Curved Greatsword", 0x003DF360, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Pontiff Knight Curved Sword", 0x003E1A70, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Storm Curved Sword", 0x003E4180, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Painting Guardian's Curved Sword", 0x003E6890, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Crescent Moon Sword", 0x003E8FA0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Carthus Shotel", 0x003EB6B0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Uchigatana", 0x004C4B40, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Washing Pole", 0x004C7250, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Chaos Blade", 0x004C9960, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Black Blade", 0x004CC070, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Bloodlust", 0x004CE780, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Darkdrift", 0x004D0E90, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Bastard Sword", 0x005B8D80, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Claymore", 0x005BDBA0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Zweihander", 0x005C29C0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Greatsword", 0x005C50D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Astora Greatsword", 0x005C9EF0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Murakumo", 0x005CC600, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Lothric Knight Greatsword", 0x005D1420, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Flamberge", 0x005DB060, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Exile Greatsword", 0x005DD770, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Greatsword of Judgment", 0x005E2590, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Profaned Greatsword", 0x005E4CA0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Cathedral Knight Greatsword", 0x005E73B0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Farron Greatsword", 0x005E9AC0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Yhorm's Great Machete", 0x005F0FF0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Dark Sword", 0x005F3700, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Black Knight Sword", 0x005F5E10, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Lorian's Greatsword", 0x005F8520, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Twin Princes' Greatsword", 0x005FAC30, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Lothric's Holy Sword", 0x005FD340, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Wolnir's Holy Sword", 0x005FFA50, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Wolf Knight's Greatsword", 0x00602160, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Greatsword of Artorias", 0x0060216A, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Hollowslayer Greatsword", 0x00604870, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Moonlight Greatsword", 0x00606F80, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Drakeblood Greatsword", 0x00609690, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Firelink Greatsword", 0x0060BDA0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Fume Ultra Greatsword", 0x0060E4B0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Old Wolf Curved Sword", 0x00610BC0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Storm Ruler", 0x006132D0, DS3ItemCategory.KEY), - ("Hand Axe", 0x006ACFC0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Battle Axe", 0x006AF6D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Deep Battle Axe", 0x006AFA54, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Brigand Axe", 0x006B1DE0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Crescent Axe", 0x006B6C00, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Greataxe", 0x006B9310, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Butcher Knife", 0x006BE130, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Dragonslayer's Axe", 0x006C0840, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Thrall Axe", 0x006C5660, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Dragonslayer Greataxe", 0x006C7D70, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Demon's Greataxe", 0x006CA480, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Eleonora", 0x006CCB90, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Man Serpent Hatchet", 0x006D19B0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Club", 0x007A1200, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Mace", 0x007A3910, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Morning Star", 0x007A6020, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Reinforced Club", 0x007A8730, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Large Club", 0x007AFC60, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Great Club", 0x007B4A80, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Great Mace", 0x007BBFB0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Great Wooden Hammer", 0x007C8300, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Gargoyle Flame Hammer", 0x007CAA10, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Vordt's Great Hammer", 0x007CD120, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Old King's Great Hammer", 0x007CF830, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Heysel Pick", 0x007D6D60, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Warpick", 0x007DBB80, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Pickaxe", 0x007DE290, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Dragon Tooth", 0x007E09A0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Smough's Great Hammer", 0x007E30B0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Blacksmith Hammer", 0x007E57C0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Morne's Great Hammer", 0x007E7ED0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Spiked Mace", 0x007EA5E0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Spear", 0x00895440, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Winged Spear", 0x00897B50, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Partizan", 0x0089C970, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Greatlance", 0x008A8CC0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Lothric Knight Long Spear", 0x008AB3D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Gargoyle Flame Spear", 0x008B01F0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Rotten Ghru Spear", 0x008B2900, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Tailbone Spear", 0x008B5010, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Soldering Iron", 0x008B7720, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Arstor's Spear", 0x008BEC50, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Saint Bident", 0x008C1360, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Yorshka's Spear", 0x008C3A70, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Pike", 0x008C6180, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Heavy Four-pronged Plow", 0x008ADAE0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Dragonslayer Spear", 0x008CAFA0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Great Scythe", 0x00989680, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Lucerne", 0x0098BD90, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Glaive", 0x0098E4A0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Halberd", 0x00990BB0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Black Knight Greataxe", 0x009959D0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Pontiff Knight Great Scythe", 0x0099A7F0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Great Corvian Scythe", 0x0099CF00, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Winged Knight Halberd", 0x0099F610, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Gundyr's Halberd", 0x009A1D20, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Red Hilted Halberd", 0x009AB960, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Black Knight Glaive", 0x009AE070, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Immolation Tinder", 0x009B0780, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Claw", 0x00A7D8C0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Caestus", 0x00A7FFD0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Manikin Claws", 0x00A826E0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Demon's Fist", 0x00A84DF0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Dark Hand", 0x00A87500, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Whip", 0x00B71B00, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Witch's Locks", 0x00B7B740, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Notched Whip", 0x00B7DE50, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Spotted Whip", 0x00B80560, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Talisman", 0x00C72090, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Sorcerer's Staff", 0x00C747A0, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Storyteller's Staff", 0x00C76EB0, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Mendicant's Staff", 0x00C795C0, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Man-grub's Staff", 0x00C7E3E0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Archdeacon's Great Staff", 0x00C80AF0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Golden Ritual Spear", 0x00C83200, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Yorshka's Chime", 0x00C88020, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Sage's Crystal Staff", 0x00C8CE40, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Heretic's Staff", 0x00C8F550, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Court Sorcerer's Staff", 0x00C91C60, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Witchtree Branch", 0x00C94370, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Izalith Staff", 0x00C96A80, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Cleric's Sacred Chime", 0x00C99190, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Priest's Chime", 0x00C9B8A0, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Saint-tree Bellvine", 0x00C9DFB0, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Caitha's Chime", 0x00CA06C0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Crystal Chime", 0x00CA2DD0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Sunlight Talisman", 0x00CA54E0, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Canvas Talisman", 0x00CA7BF0, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Sunless Talisman", 0x00CAA300, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Saint's Talisman", 0x00CACA10, DS3ItemCategory.WEAPON_UPGRADE_10), - ("White Hair Talisman", 0x00CAF120, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Pyromancy Flame", 0x00CC77C0, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Dragonslayer Greatbow", 0x00CF8500, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Short Bow", 0x00D5C690, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Composite Bow", 0x00D5EDA0, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Light Crossbow", 0x00D63BC0, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Arbalest", 0x00D662D0, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Longbow", 0x00D689E0, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Dragonrider Bow", 0x00D6B0F0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Avelyn", 0x00D6FF10, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Knight's Crossbow", 0x00D72620, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Heavy Crossbow", 0x00D74D30, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Darkmoon Longbow", 0x00D79B50, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Onislayer Greatbow", 0x00D7C260, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Black Bow of Pharis", 0x00D7E970, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Sniper Crossbow", 0x00D83790, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Sellsword Twinblades", 0x00F42400, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Warden Twinblades", 0x00F47220, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Winged Knight Twinaxes", 0x00F49930, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Dancer's Enchanted Swords", 0x00F4C040, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Great Machete", 0x00F4E750, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Brigand Twindaggers", 0x00F50E60, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Gotthard Twinswords", 0x00F53570, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Onikiri and Ubadachi", 0x00F58390, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Drang Twinspears", 0x00F5AAA0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Drang Hammers", 0x00F61FD0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Dagger", 0x000F4240, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Bandit's Knife", 0x000F6950, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Parrying Dagger", 0x000F9060, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Rotten Ghru Dagger", 0x000FDE80, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Harpe", 0x00102CA0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Scholar's Candlestick", 0x001053B0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Tailbone Short Sword", 0x00107AC0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Corvian Greatknife", 0x0010A1D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Handmaid's Dagger", 0x00111700, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Shortsword", 0x001E8480, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Longsword", 0x001EAB90, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Broadsword", 0x001ED2A0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Broken Straight Sword", 0x001EF9B0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Lothric Knight Sword", 0x001F6EE0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Sunlight Straight Sword", 0x00203230, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Rotten Ghru Curved Sword", 0x00205940, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Irithyll Straight Sword", 0x0020A760, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Cleric's Candlestick", 0x0020F580, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Morion Blade", 0x002143A0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Astora Straight Sword", 0x002191C0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Barbed Straight Sword", 0x0021B8D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Executioner's Greatsword", 0x0021DFE0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Anri's Straight Sword", 0x002206F0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Estoc", 0x002DC6C0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Mail Breaker", 0x002DEDD0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Rapier", 0x002E14E0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Ricard's Rapier", 0x002E3BF0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Crystal Sage's Rapier", 0x002E6300, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Irithyll Rapier", 0x002E8A10, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Shotel", 0x003D3010, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Scimitar", 0x003D7E30, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Falchion", 0x003DA540, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Carthus Curved Sword", 0x003DCC50, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Carthus Curved Greatsword", 0x003DF360, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Pontiff Knight Curved Sword", 0x003E1A70, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Storm Curved Sword", 0x003E4180, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Painting Guardian's Curved Sword", 0x003E6890, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Crescent Moon Sword", 0x003E8FA0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Carthus Shotel", 0x003EB6B0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Uchigatana", 0x004C4B40, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Washing Pole", 0x004C7250, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Chaos Blade", 0x004C9960, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Black Blade", 0x004CC070, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Bloodlust", 0x004CE780, DS3ItemCategory.WEAPON_UPGRADE_5, + inject = True), # Covenant reward + DS3ItemData("Darkdrift", 0x004D0E90, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Bastard Sword", 0x005B8D80, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Claymore", 0x005BDBA0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Zweihander", 0x005C29C0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Greatsword", 0x005C50D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Astora Greatsword", 0x005C9EF0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Murakumo", 0x005CC600, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Lothric Knight Greatsword", 0x005D1420, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Flamberge", 0x005DB060, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Exile Greatsword", 0x005DD770, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Greatsword of Judgment", 0x005E2590, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Profaned Greatsword", 0x005E4CA0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Cathedral Knight Greatsword", 0x005E73B0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Farron Greatsword", 0x005E9AC0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Yhorm's Great Machete", 0x005F0FF0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Dark Sword", 0x005F3700, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Black Knight Sword", 0x005F5E10, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Lorian's Greatsword", 0x005F8520, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Twin Princes' Greatsword", 0x005FAC30, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Lothric's Holy Sword", 0x005FD340, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Wolnir's Holy Sword", 0x005FFA50, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Wolf Knight's Greatsword", 0x00602160, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Greatsword of Artorias", 0x0060216A, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Hollowslayer Greatsword", 0x00604870, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Moonlight Greatsword", 0x00606F80, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Drakeblood Greatsword", 0x00609690, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Firelink Greatsword", 0x0060BDA0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Fume Ultra Greatsword", 0x0060E4B0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Old Wolf Curved Sword", 0x00610BC0, DS3ItemCategory.WEAPON_UPGRADE_5, + inject = True), # Covenant reward + DS3ItemData("Storm Ruler", 0x006132D0, DS3ItemCategory.KEY), + DS3ItemData("Hand Axe", 0x006ACFC0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Battle Axe", 0x006AF6D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Deep Battle Axe", 0x006AFA54, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Brigand Axe", 0x006B1DE0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Crescent Axe", 0x006B6C00, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Greataxe", 0x006B9310, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Butcher Knife", 0x006BE130, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Dragonslayer's Axe", 0x006C0840, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Thrall Axe", 0x006C5660, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Dragonslayer Greataxe", 0x006C7D70, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Demon's Greataxe", 0x006CA480, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Eleonora", 0x006CCB90, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Man Serpent Hatchet", 0x006D19B0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Club", 0x007A1200, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Mace", 0x007A3910, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Morning Star", 0x007A6020, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Reinforced Club", 0x007A8730, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Large Club", 0x007AFC60, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Great Club", 0x007B4A80, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Great Mace", 0x007BBFB0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Great Wooden Hammer", 0x007C8300, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Gargoyle Flame Hammer", 0x007CAA10, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Vordt's Great Hammer", 0x007CD120, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Old King's Great Hammer", 0x007CF830, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Heysel Pick", 0x007D6D60, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Warpick", 0x007DBB80, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Pickaxe", 0x007DE290, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Dragon Tooth", 0x007E09A0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Smough's Great Hammer", 0x007E30B0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Blacksmith Hammer", 0x007E57C0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Morne's Great Hammer", 0x007E7ED0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Spiked Mace", 0x007EA5E0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Spear", 0x00895440, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Winged Spear", 0x00897B50, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Partizan", 0x0089C970, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Greatlance", 0x008A8CC0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Lothric Knight Long Spear", 0x008AB3D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Gargoyle Flame Spear", 0x008B01F0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Rotten Ghru Spear", 0x008B2900, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Tailbone Spear", 0x008B5010, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Soldering Iron", 0x008B7720, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Dragonslayer Swordspear", 0x008BC540, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Arstor's Spear", 0x008BEC50, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Saint Bident", 0x008C1360, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Yorshka's Spear", 0x008C3A70, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Pike", 0x008C6180, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Heavy Four-pronged Plow", 0x008ADAE0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Dragonslayer Spear", 0x008CAFA0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Great Scythe", 0x00989680, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Lucerne", 0x0098BD90, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Glaive", 0x0098E4A0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Halberd", 0x00990BB0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Black Knight Greataxe", 0x009959D0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Pontiff Knight Great Scythe", 0x0099A7F0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Great Corvian Scythe", 0x0099CF00, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Winged Knight Halberd", 0x0099F610, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Gundyr's Halberd", 0x009A1D20, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Red Hilted Halberd", 0x009AB960, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Black Knight Glaive", 0x009AE070, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Immolation Tinder", 0x009B0780, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Claw", 0x00A7D8C0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Caestus", 0x00A7FFD0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Manikin Claws", 0x00A826E0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Demon's Fist", 0x00A84DF0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Dark Hand", 0x00A87500, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Whip", 0x00B71B00, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Witch's Locks", 0x00B7B740, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Notched Whip", 0x00B7DE50, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Spotted Whip", 0x00B80560, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Talisman", 0x00C72090, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Sorcerer's Staff", 0x00C747A0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Storyteller's Staff", 0x00C76EB0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Mendicant's Staff", 0x00C795C0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Man-grub's Staff", 0x00C7E3E0, DS3ItemCategory.WEAPON_UPGRADE_5, + inject = True), # Covenant reward + DS3ItemData("Archdeacon's Great Staff", 0x00C80AF0, DS3ItemCategory.WEAPON_UPGRADE_5, + inject = True), # Covenant reward + DS3ItemData("Golden Ritual Spear", 0x00C83200, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Yorshka's Chime", 0x00C88020, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Sage's Crystal Staff", 0x00C8CE40, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Heretic's Staff", 0x00C8F550, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Court Sorcerer's Staff", 0x00C91C60, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Witchtree Branch", 0x00C94370, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Izalith Staff", 0x00C96A80, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Cleric's Sacred Chime", 0x00C99190, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Priest's Chime", 0x00C9B8A0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Saint-tree Bellvine", 0x00C9DFB0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Caitha's Chime", 0x00CA06C0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Crystal Chime", 0x00CA2DD0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Sunlight Talisman", 0x00CA54E0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Canvas Talisman", 0x00CA7BF0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Sunless Talisman", 0x00CAA300, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Saint's Talisman", 0x00CACA10, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("White Hair Talisman", 0x00CAF120, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Pyromancy Flame", 0x00CC77C0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Dragonslayer Greatbow", 0x00CF8500, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Short Bow", 0x00D5C690, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Composite Bow", 0x00D5EDA0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Light Crossbow", 0x00D63BC0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Arbalest", 0x00D662D0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Longbow", 0x00D689E0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Dragonrider Bow", 0x00D6B0F0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Avelyn", 0x00D6FF10, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Knight's Crossbow", 0x00D72620, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Heavy Crossbow", 0x00D74D30, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Darkmoon Longbow", 0x00D79B50, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Onislayer Greatbow", 0x00D7C260, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Black Bow of Pharis", 0x00D7E970, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Sniper Crossbow", 0x00D83790, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Sellsword Twinblades", 0x00F42400, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Warden Twinblades", 0x00F47220, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Winged Knight Twinaxes", 0x00F49930, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Dancer's Enchanted Swords", 0x00F4C040, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Great Machete", 0x00F4E750, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Brigand Twindaggers", 0x00F50E60, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Gotthard Twinswords", 0x00F53570, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Onikiri and Ubadachi", 0x00F58390, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Drang Twinspears", 0x00F5AAA0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Drang Hammers", 0x00F61FD0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), # Shields - ("Buckler", 0x01312D00, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Small Leather Shield", 0x01315410, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Round Shield", 0x0131A230, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Large Leather Shield", 0x0131C940, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Hawkwood's Shield", 0x01323E70, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Iron Round Shield", 0x01326580, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Wooden Shield", 0x0132DAB0, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Kite Shield", 0x013301C0, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Ghru Rotshield", 0x013328D0, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Havel's Greatshield", 0x013376F0, DS3ItemCategory.SHIELD), - ("Target Shield", 0x01339E00, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Elkhorn Round Shield", 0x0133C510, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Warrior's Round Shield", 0x0133EC20, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Caduceus Round Shield", 0x01341330, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Red and White Shield", 0x01343A40, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Blessed Red and White Shield+1", 0x01343FB9, DS3ItemCategory.SHIELD), - ("Plank Shield", 0x01346150, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Leather Shield", 0x01348860, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Crimson Parma", 0x0134AF70, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Eastern Iron Shield", 0x0134D680, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Llewellyn Shield", 0x0134FD90, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Golden Falcon Shield", 0x01354BB0, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Sacred Bloom Shield", 0x013572C0, DS3ItemCategory.SHIELD), - ("Ancient Dragon Greatshield", 0x013599D0, DS3ItemCategory.SHIELD), - ("Lothric Knight Shield", 0x01409650, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Knight Shield", 0x01410B80, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Pontiff Knight Shield", 0x014159A0, DS3ItemCategory.SHIELD), - ("Carthus Shield", 0x014180B0, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Black Knight Shield", 0x0141F5E0, DS3ItemCategory.SHIELD), - ("Silver Knight Shield", 0x01424400, DS3ItemCategory.SHIELD), - ("Spiked Shield", 0x01426B10, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Pierce Shield", 0x01429220, DS3ItemCategory.SHIELD_INFUSIBLE), - ("East-West Shield", 0x0142B930, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Sunlight Shield", 0x0142E040, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Crest Shield", 0x01430750, DS3ItemCategory.SHIELD), - ("Dragon Crest Shield", 0x01432E60, DS3ItemCategory.SHIELD), - ("Spider Shield", 0x01435570, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Grass Crest Shield", 0x01437C80, DS3ItemCategory.SHIELD), - ("Sunset Shield", 0x0143A390, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Golden Wing Crest Shield", 0x0143CAA0, DS3ItemCategory.SHIELD), - ("Blue Wooden Shield", 0x0143F1B0, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Silver Eagle Kite Shield", 0x014418C0, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Stone Parma", 0x01443FD0, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Spirit Tree Crest Shield", 0x014466E0, DS3ItemCategory.SHIELD), - ("Porcine Shield", 0x01448DF0, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Shield of Want", 0x0144B500, DS3ItemCategory.SHIELD), - ("Wargod Wooden Shield", 0x0144DC10, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Lothric Knight Greatshield", 0x014FD890, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Cathedral Knight Greatshield", 0x014FFFA0, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Dragonslayer Greatshield", 0x01504DC0, DS3ItemCategory.SHIELD), - ("Moaning Shield", 0x015074D0, DS3ItemCategory.SHIELD), - ("Yhorm's Greatshield", 0x0150C2F0, DS3ItemCategory.SHIELD), - ("Black Iron Greatshield", 0x0150EA00, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Wolf Knight's Greatshield", 0x01511110, DS3ItemCategory.SHIELD), - ("Twin Dragon Greatshield", 0x01513820, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Greatshield of Glory", 0x01515F30, DS3ItemCategory.SHIELD), - ("Curse Ward Greatshield", 0x01518640, DS3ItemCategory.SHIELD), - ("Bonewheel Shield", 0x0151AD50, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Stone Greatshield", 0x0151D460, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Buckler", 0x01312D00, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Small Leather Shield", 0x01315410, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Round Shield", 0x0131A230, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Large Leather Shield", 0x0131C940, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Hawkwood's Shield", 0x01323E70, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Iron Round Shield", 0x01326580, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Wooden Shield", 0x0132DAB0, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Kite Shield", 0x013301C0, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Ghru Rotshield", 0x013328D0, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Havel's Greatshield", 0x013376F0, DS3ItemCategory.SHIELD), + DS3ItemData("Target Shield", 0x01339E00, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Elkhorn Round Shield", 0x0133C510, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Warrior's Round Shield", 0x0133EC20, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Caduceus Round Shield", 0x01341330, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Red and White Shield", 0x01343A40, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Blessed Red and White Shield+1", 0x01343FB9, DS3ItemCategory.SHIELD), + DS3ItemData("Plank Shield", 0x01346150, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Leather Shield", 0x01348860, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Crimson Parma", 0x0134AF70, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Eastern Iron Shield", 0x0134D680, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Llewellyn Shield", 0x0134FD90, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Golden Falcon Shield", 0x01354BB0, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Sacred Bloom Shield", 0x013572C0, DS3ItemCategory.SHIELD), + DS3ItemData("Ancient Dragon Greatshield", 0x013599D0, DS3ItemCategory.SHIELD), + DS3ItemData("Lothric Knight Shield", 0x01409650, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Knight Shield", 0x01410B80, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Pontiff Knight Shield", 0x014159A0, DS3ItemCategory.SHIELD), + DS3ItemData("Carthus Shield", 0x014180B0, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Black Knight Shield", 0x0141F5E0, DS3ItemCategory.SHIELD), + DS3ItemData("Silver Knight Shield", 0x01424400, DS3ItemCategory.SHIELD), + DS3ItemData("Spiked Shield", 0x01426B10, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Pierce Shield", 0x01429220, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("East-West Shield", 0x0142B930, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Sunlight Shield", 0x0142E040, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Crest Shield", 0x01430750, DS3ItemCategory.SHIELD), + DS3ItemData("Dragon Crest Shield", 0x01432E60, DS3ItemCategory.SHIELD), + DS3ItemData("Spider Shield", 0x01435570, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Grass Crest Shield", 0x01437C80, DS3ItemCategory.SHIELD), + DS3ItemData("Sunset Shield", 0x0143A390, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Golden Wing Crest Shield", 0x0143CAA0, DS3ItemCategory.SHIELD), + DS3ItemData("Blue Wooden Shield", 0x0143F1B0, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Silver Eagle Kite Shield", 0x014418C0, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Stone Parma", 0x01443FD0, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Spirit Tree Crest Shield", 0x014466E0, DS3ItemCategory.SHIELD), + DS3ItemData("Porcine Shield", 0x01448DF0, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Shield of Want", 0x0144B500, DS3ItemCategory.SHIELD), + DS3ItemData("Wargod Wooden Shield", 0x0144DC10, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Lothric Knight Greatshield", 0x014FD890, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Cathedral Knight Greatshield", 0x014FFFA0, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Dragonslayer Greatshield", 0x01504DC0, DS3ItemCategory.SHIELD), + DS3ItemData("Moaning Shield", 0x015074D0, DS3ItemCategory.SHIELD), + DS3ItemData("Yhorm's Greatshield", 0x0150C2F0, DS3ItemCategory.SHIELD), + DS3ItemData("Black Iron Greatshield", 0x0150EA00, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Wolf Knight's Greatshield", 0x01511110, DS3ItemCategory.SHIELD, + inject = True), # Covenant reward + DS3ItemData("Twin Dragon Greatshield", 0x01513820, DS3ItemCategory.SHIELD_INFUSIBLE, + inject = True), # Covenant reward + DS3ItemData("Greatshield of Glory", 0x01515F30, DS3ItemCategory.SHIELD), + DS3ItemData("Curse Ward Greatshield", 0x01518640, DS3ItemCategory.SHIELD), + DS3ItemData("Bonewheel Shield", 0x0151AD50, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Stone Greatshield", 0x0151D460, DS3ItemCategory.SHIELD_INFUSIBLE), # Armor - ("Fallen Knight Helm", 0x1121EAC0, DS3ItemCategory.ARMOR), - ("Fallen Knight Armor", 0x1121EEA8, DS3ItemCategory.ARMOR), - ("Fallen Knight Gauntlets", 0x1121F290, DS3ItemCategory.ARMOR), - ("Fallen Knight Trousers", 0x1121F678, DS3ItemCategory.ARMOR), - ("Knight Helm", 0x11298BE0, DS3ItemCategory.ARMOR), - ("Knight Armor", 0x11298FC8, DS3ItemCategory.ARMOR), - ("Knight Gauntlets", 0x112993B0, DS3ItemCategory.ARMOR), - ("Knight Leggings", 0x11299798, DS3ItemCategory.ARMOR), - ("Firelink Helm", 0x11406F40, DS3ItemCategory.ARMOR), - ("Firelink Armor", 0x11407328, DS3ItemCategory.ARMOR), - ("Firelink Gauntlets", 0x11407710, DS3ItemCategory.ARMOR), - ("Firelink Leggings", 0x11407AF8, DS3ItemCategory.ARMOR), - ("Sellsword Helm", 0x11481060, DS3ItemCategory.ARMOR), - ("Sellsword Armor", 0x11481448, DS3ItemCategory.ARMOR), - ("Sellsword Gauntlet", 0x11481830, DS3ItemCategory.ARMOR), - ("Sellsword Trousers", 0x11481C18, DS3ItemCategory.ARMOR), - ("Herald Helm", 0x114FB180, DS3ItemCategory.ARMOR), - ("Herald Armor", 0x114FB568, DS3ItemCategory.ARMOR), - ("Herald Gloves", 0x114FB950, DS3ItemCategory.ARMOR), - ("Herald Trousers", 0x114FBD38, DS3ItemCategory.ARMOR), - ("Sunless Veil", 0x115752A0, DS3ItemCategory.ARMOR), - ("Sunless Armor", 0x11575688, DS3ItemCategory.ARMOR), - ("Sunless Gauntlets", 0x11575A70, DS3ItemCategory.ARMOR), - ("Sunless Leggings", 0x11575E58, DS3ItemCategory.ARMOR), - ("Black Hand Hat", 0x115EF3C0, DS3ItemCategory.ARMOR), - ("Black Hand Armor", 0x115EF7A8, DS3ItemCategory.ARMOR), - ("Assassin Gloves", 0x115EFB90, DS3ItemCategory.ARMOR), - ("Assassin Trousers", 0x115EFF78, DS3ItemCategory.ARMOR), - ("Assassin Hood", 0x11607A60, DS3ItemCategory.ARMOR), - ("Assassin Armor", 0x11607E48, DS3ItemCategory.ARMOR), - ("Xanthous Crown", 0x116694E0, DS3ItemCategory.ARMOR), - ("Xanthous Overcoat", 0x116698C8, DS3ItemCategory.ARMOR), - ("Xanthous Gloves", 0x11669CB0, DS3ItemCategory.ARMOR), - ("Xanthous Trousers", 0x1166A098, DS3ItemCategory.ARMOR), - ("Northern Helm", 0x116E3600, DS3ItemCategory.ARMOR), - ("Northern Armor", 0x116E39E8, DS3ItemCategory.ARMOR), - ("Northern Gloves", 0x116E3DD0, DS3ItemCategory.ARMOR), - ("Northern Trousers", 0x116E41B8, DS3ItemCategory.ARMOR), - ("Morne's Helm", 0x1175D720, DS3ItemCategory.ARMOR), - ("Morne's Armor", 0x1175DB08, DS3ItemCategory.ARMOR), - ("Morne's Gauntlets", 0x1175DEF0, DS3ItemCategory.ARMOR), - ("Morne's Leggings", 0x1175E2D8, DS3ItemCategory.ARMOR), - ("Silver Mask", 0x117D7840, DS3ItemCategory.ARMOR), - ("Leonhard's Garb", 0x117D7C28, DS3ItemCategory.ARMOR), - ("Leonhard's Gauntlets", 0x117D8010, DS3ItemCategory.ARMOR), - ("Leonhard's Trousers", 0x117D83F8, DS3ItemCategory.ARMOR), - ("Sneering Mask", 0x11851960, DS3ItemCategory.ARMOR), - ("Pale Shade Robe", 0x11851D48, DS3ItemCategory.ARMOR), - ("Pale Shade Gloves", 0x11852130, DS3ItemCategory.ARMOR), - ("Pale Shade Trousers", 0x11852518, DS3ItemCategory.ARMOR), - ("Sunset Helm", 0x118CBA80, DS3ItemCategory.ARMOR), - ("Sunset Armor", 0x118CBE68, DS3ItemCategory.ARMOR), - ("Sunset Gauntlets", 0x118CC250, DS3ItemCategory.ARMOR), - ("Sunset Leggings", 0x118CC638, DS3ItemCategory.ARMOR), - ("Old Sage's Blindfold", 0x11945BA0, DS3ItemCategory.ARMOR), - ("Cornyx's Garb", 0x11945F88, DS3ItemCategory.ARMOR), - ("Cornyx's Wrap", 0x11946370, DS3ItemCategory.ARMOR), - ("Cornyx's Skirt", 0x11946758, DS3ItemCategory.ARMOR), - ("Executioner Helm", 0x119BFCC0, DS3ItemCategory.ARMOR), - ("Executioner Armor", 0x119C00A8, DS3ItemCategory.ARMOR), - ("Executioner Gauntlets", 0x119C0490, DS3ItemCategory.ARMOR), - ("Executioner Leggings", 0x119C0878, DS3ItemCategory.ARMOR), - ("Billed Mask", 0x11A39DE0, DS3ItemCategory.ARMOR), - ("Black Dress", 0x11A3A1C8, DS3ItemCategory.ARMOR), - ("Black Gauntlets", 0x11A3A5B0, DS3ItemCategory.ARMOR), - ("Black Leggings", 0x11A3A998, DS3ItemCategory.ARMOR), - ("Pyromancer Crown", 0x11AB3F00, DS3ItemCategory.ARMOR), - ("Pyromancer Garb", 0x11AB42E8, DS3ItemCategory.ARMOR), - ("Pyromancer Wrap", 0x11AB46D0, DS3ItemCategory.ARMOR), - ("Pyromancer Trousers", 0x11AB4AB8, DS3ItemCategory.ARMOR), - ("Court Sorcerer Hood", 0x11BA8140, DS3ItemCategory.ARMOR), - ("Court Sorcerer Robe", 0x11BA8528, DS3ItemCategory.ARMOR), - ("Court Sorcerer Gloves", 0x11BA8910, DS3ItemCategory.ARMOR), - ("Court Sorcerer Trousers", 0x11BA8CF8, DS3ItemCategory.ARMOR), - ("Sorcerer Hood", 0x11C9C380, DS3ItemCategory.ARMOR), - ("Sorcerer Robe", 0x11C9C768, DS3ItemCategory.ARMOR), - ("Sorcerer Gloves", 0x11C9CB50, DS3ItemCategory.ARMOR), - ("Sorcerer Trousers", 0x11C9CF38, DS3ItemCategory.ARMOR), - ("Clandestine Coat", 0x11CB4E08, DS3ItemCategory.ARMOR), - ("Cleric Hat", 0x11D905C0, DS3ItemCategory.ARMOR), - ("Cleric Blue Robe", 0x11D909A8, DS3ItemCategory.ARMOR), - ("Cleric Gloves", 0x11D90D90, DS3ItemCategory.ARMOR), - ("Cleric Trousers", 0x11D91178, DS3ItemCategory.ARMOR), - ("Steel Soldier Helm", 0x12625A00, DS3ItemCategory.ARMOR), - ("Deserter Armor", 0x12625DE8, DS3ItemCategory.ARMOR), - ("Deserter Trousers", 0x126265B8, DS3ItemCategory.ARMOR), - ("Thief Mask", 0x12656740, DS3ItemCategory.ARMOR), - ("Sage's Big Hat", 0x129020C0, DS3ItemCategory.ARMOR), - ("Aristocrat's Mask", 0x129F6300, DS3ItemCategory.ARMOR), - ("Jailer Robe", 0x129F66E8, DS3ItemCategory.ARMOR), - ("Jailer Gloves", 0x129F6AD0, DS3ItemCategory.ARMOR), - ("Jailer Trousers", 0x129F6EB8, DS3ItemCategory.ARMOR), - ("Grave Warden Hood", 0x12BDE780, DS3ItemCategory.ARMOR), - ("Grave Warden Robe", 0x12BDEB68, DS3ItemCategory.ARMOR), - ("Grave Warden Wrap", 0x12BDEF50, DS3ItemCategory.ARMOR), - ("Grave Warden Skirt", 0x12BDF338, DS3ItemCategory.ARMOR), - ("Worker Hat", 0x12CD29C0, DS3ItemCategory.ARMOR), - ("Worker Garb", 0x12CD2DA8, DS3ItemCategory.ARMOR), - ("Worker Gloves", 0x12CD3190, DS3ItemCategory.ARMOR), - ("Worker Trousers", 0x12CD3578, DS3ItemCategory.ARMOR), - ("Thrall Hood", 0x12D4CAE0, DS3ItemCategory.ARMOR), - ("Evangelist Hat", 0x12DC6C00, DS3ItemCategory.ARMOR), - ("Evangelist Robe", 0x12DC6FE8, DS3ItemCategory.ARMOR), - ("Evangelist Gloves", 0x12DC73D0, DS3ItemCategory.ARMOR), - ("Evangelist Trousers", 0x12DC77B8, DS3ItemCategory.ARMOR), - ("Scholar's Robe", 0x12E41108, DS3ItemCategory.ARMOR), - ("Winged Knight Helm", 0x12EBAE40, DS3ItemCategory.ARMOR), - ("Winged Knight Armor", 0x12EBB228, DS3ItemCategory.ARMOR), - ("Winged Knight Gauntlets", 0x12EBB610, DS3ItemCategory.ARMOR), - ("Winged Knight Leggings", 0x12EBB9F8, DS3ItemCategory.ARMOR), - ("Cathedral Knight Helm", 0x130291A0, DS3ItemCategory.ARMOR), - ("Cathedral Knight Armor", 0x13029588, DS3ItemCategory.ARMOR), - ("Cathedral Knight Gauntlets", 0x13029970, DS3ItemCategory.ARMOR), - ("Cathedral Knight Leggings", 0x13029D58, DS3ItemCategory.ARMOR), - ("Lothric Knight Helm", 0x13197500, DS3ItemCategory.ARMOR), - ("Lothric Knight Armor", 0x131978E8, DS3ItemCategory.ARMOR), - ("Lothric Knight Gauntlets", 0x13197CD0, DS3ItemCategory.ARMOR), - ("Lothric Knight Leggings", 0x131980B8, DS3ItemCategory.ARMOR), - ("Outrider Knight Helm", 0x1328B740, DS3ItemCategory.ARMOR), - ("Outrider Knight Armor", 0x1328BB28, DS3ItemCategory.ARMOR), - ("Outrider Knight Gauntlets", 0x1328BF10, DS3ItemCategory.ARMOR), - ("Outrider Knight Leggings", 0x1328C2F8, DS3ItemCategory.ARMOR), - ("Black Knight Helm", 0x1337F980, DS3ItemCategory.ARMOR), - ("Black Knight Armor", 0x1337FD68, DS3ItemCategory.ARMOR), - ("Black Knight Gauntlets", 0x13380150, DS3ItemCategory.ARMOR), - ("Black Knight Leggings", 0x13380538, DS3ItemCategory.ARMOR), - ("Dark Mask", 0x133F9AA0, DS3ItemCategory.ARMOR), - ("Dark Armor", 0x133F9E88, DS3ItemCategory.ARMOR), - ("Dark Gauntlets", 0x133FA270, DS3ItemCategory.ARMOR), - ("Dark Leggings", 0x133FA658, DS3ItemCategory.ARMOR), - ("Exile Mask", 0x13473BC0, DS3ItemCategory.ARMOR), - ("Exile Armor", 0x13473FA8, DS3ItemCategory.ARMOR), - ("Exile Gauntlets", 0x13474390, DS3ItemCategory.ARMOR), - ("Exile Leggings", 0x13474778, DS3ItemCategory.ARMOR), - ("Pontiff Knight Crown", 0x13567E00, DS3ItemCategory.ARMOR), - ("Pontiff Knight Armor", 0x135681E8, DS3ItemCategory.ARMOR), - ("Pontiff Knight Gauntlets", 0x135685D0, DS3ItemCategory.ARMOR), - ("Pontiff Knight Leggings", 0x135689B8, DS3ItemCategory.ARMOR), - ("Golden Crown", 0x1365C040, DS3ItemCategory.ARMOR), - ("Dragonscale Armor", 0x1365C428, DS3ItemCategory.ARMOR), - ("Golden Bracelets", 0x1365C810, DS3ItemCategory.ARMOR), - ("Dragonscale Waistcloth", 0x1365CBF8, DS3ItemCategory.ARMOR), - ("Wolnir's Crown", 0x136D6160, DS3ItemCategory.ARMOR), - ("Undead Legion Helm", 0x13750280, DS3ItemCategory.ARMOR), - ("Undead Legion Armor", 0x13750668, DS3ItemCategory.ARMOR), - ("Undead Legion Gauntlets", 0x13750A50, DS3ItemCategory.ARMOR), - ("Undead Legion Leggings", 0x13750E38, DS3ItemCategory.ARMOR), - ("Fire Witch Helm", 0x13938700, DS3ItemCategory.ARMOR), - ("Fire Witch Armor", 0x13938AE8, DS3ItemCategory.ARMOR), - ("Fire Witch Gauntlets", 0x13938ED0, DS3ItemCategory.ARMOR), - ("Fire Witch Leggings", 0x139392B8, DS3ItemCategory.ARMOR), - ("Lorian's Helm", 0x13A2C940, DS3ItemCategory.ARMOR), - ("Lorian's Armor", 0x13A2CD28, DS3ItemCategory.ARMOR), - ("Lorian's Gauntlets", 0x13A2D110, DS3ItemCategory.ARMOR), - ("Lorian's Leggings", 0x13A2D4F8, DS3ItemCategory.ARMOR), - ("Hood of Prayer", 0x13AA6A60, DS3ItemCategory.ARMOR), - ("Robe of Prayer", 0x13AA6E48, DS3ItemCategory.ARMOR), - ("Skirt of Prayer", 0x13AA7618, DS3ItemCategory.ARMOR), - ("Dancer's Crown", 0x13C14DC0, DS3ItemCategory.ARMOR), - ("Dancer's Armor", 0x13C151A8, DS3ItemCategory.ARMOR), - ("Dancer's Gauntlets", 0x13C15590, DS3ItemCategory.ARMOR), - ("Dancer's Leggings", 0x13C15978, DS3ItemCategory.ARMOR), - ("Gundyr's Helm", 0x13D09000, DS3ItemCategory.ARMOR), - ("Gundyr's Armor", 0x13D093E8, DS3ItemCategory.ARMOR), - ("Gundyr's Gauntlets", 0x13D097D0, DS3ItemCategory.ARMOR), - ("Gundyr's Leggings", 0x13D09BB8, DS3ItemCategory.ARMOR), - ("Archdeacon White Crown", 0x13EF1480, DS3ItemCategory.ARMOR), - ("Archdeacon Holy Garb", 0x13EF1868, DS3ItemCategory.ARMOR), - ("Archdeacon Skirt", 0x13EF2038, DS3ItemCategory.ARMOR), - ("Deacon Robe", 0x13F6B988, DS3ItemCategory.ARMOR), - ("Deacon Skirt", 0x13F6C158, DS3ItemCategory.ARMOR), - ("Fire Keeper Robe", 0x140D9CE8, DS3ItemCategory.ARMOR), - ("Fire Keeper Gloves", 0x140DA0D0, DS3ItemCategory.ARMOR), - ("Fire Keeper Skirt", 0x140DA4B8, DS3ItemCategory.ARMOR), - ("Chain Helm", 0x142C1D80, DS3ItemCategory.ARMOR), - ("Chain Armor", 0x142C2168, DS3ItemCategory.ARMOR), - ("Leather Gauntlets", 0x142C2550, DS3ItemCategory.ARMOR), - ("Chain Leggings", 0x142C2938, DS3ItemCategory.ARMOR), - ("Nameless Knight Helm", 0x143B5FC0, DS3ItemCategory.ARMOR), - ("Nameless Knight Armor", 0x143B63A8, DS3ItemCategory.ARMOR), - ("Nameless Knight Gauntlets", 0x143B6790, DS3ItemCategory.ARMOR), - ("Nameless Knight Leggings", 0x143B6B78, DS3ItemCategory.ARMOR), - ("Elite Knight Helm", 0x144AA200, DS3ItemCategory.ARMOR), - ("Elite Knight Armor", 0x144AA5E8, DS3ItemCategory.ARMOR), - ("Elite Knight Gauntlets", 0x144AA9D0, DS3ItemCategory.ARMOR), - ("Elite Knight Leggings", 0x144AADB8, DS3ItemCategory.ARMOR), - ("Faraam Helm", 0x1459E440, DS3ItemCategory.ARMOR), - ("Faraam Armor", 0x1459E828, DS3ItemCategory.ARMOR), - ("Faraam Gauntlets", 0x1459EC10, DS3ItemCategory.ARMOR), - ("Faraam Boots", 0x1459EFF8, DS3ItemCategory.ARMOR), - ("Catarina Helm", 0x14692680, DS3ItemCategory.ARMOR), - ("Catarina Armor", 0x14692A68, DS3ItemCategory.ARMOR), - ("Catarina Gauntlets", 0x14692E50, DS3ItemCategory.ARMOR), - ("Catarina Leggings", 0x14693238, DS3ItemCategory.ARMOR), - ("Standard Helm", 0x1470C7A0, DS3ItemCategory.ARMOR), - ("Hard Leather Armor", 0x1470CB88, DS3ItemCategory.ARMOR), - ("Hard Leather Gauntlets", 0x1470CF70, DS3ItemCategory.ARMOR), - ("Hard Leather Boots", 0x1470D358, DS3ItemCategory.ARMOR), - ("Havel's Helm", 0x147868C0, DS3ItemCategory.ARMOR), - ("Havel's Armor", 0x14786CA8, DS3ItemCategory.ARMOR), - ("Havel's Gauntlets", 0x14787090, DS3ItemCategory.ARMOR), - ("Havel's Leggings", 0x14787478, DS3ItemCategory.ARMOR), - ("Brigand Hood", 0x148009E0, DS3ItemCategory.ARMOR), - ("Brigand Armor", 0x14800DC8, DS3ItemCategory.ARMOR), - ("Brigand Gauntlets", 0x148011B0, DS3ItemCategory.ARMOR), - ("Brigand Trousers", 0x14801598, DS3ItemCategory.ARMOR), - ("Pharis's Hat", 0x1487AB00, DS3ItemCategory.ARMOR), - ("Leather Armor", 0x1487AEE8, DS3ItemCategory.ARMOR), - ("Leather Gloves", 0x1487B2D0, DS3ItemCategory.ARMOR), - ("Leather Boots", 0x1487B6B8, DS3ItemCategory.ARMOR), - ("Ragged Mask", 0x148F4C20, DS3ItemCategory.ARMOR), - ("Master's Attire", 0x148F5008, DS3ItemCategory.ARMOR), - ("Master's Gloves", 0x148F53F0, DS3ItemCategory.ARMOR), - ("Loincloth", 0x148F57D8, DS3ItemCategory.ARMOR), - ("Old Sorcerer Hat", 0x1496ED40, DS3ItemCategory.ARMOR), - ("Old Sorcerer Coat", 0x1496F128, DS3ItemCategory.ARMOR), - ("Old Sorcerer Gauntlets", 0x1496F510, DS3ItemCategory.ARMOR), - ("Old Sorcerer Boots", 0x1496F8F8, DS3ItemCategory.ARMOR), - ("Conjurator Hood", 0x149E8E60, DS3ItemCategory.ARMOR), - ("Conjurator Robe", 0x149E9248, DS3ItemCategory.ARMOR), - ("Conjurator Manchettes", 0x149E9630, DS3ItemCategory.ARMOR), - ("Conjurator Boots", 0x149E9A18, DS3ItemCategory.ARMOR), - ("Black Leather Armor", 0x14A63368, DS3ItemCategory.ARMOR), - ("Black Leather Gloves", 0x14A63750, DS3ItemCategory.ARMOR), - ("Black Leather Boots", 0x14A63B38, DS3ItemCategory.ARMOR), - ("Symbol of Avarice", 0x14ADD0A0, DS3ItemCategory.ARMOR), - ("Creighton's Steel Mask", 0x14B571C0, DS3ItemCategory.ARMOR), - ("Mirrah Chain Mail", 0x14B575A8, DS3ItemCategory.ARMOR), - ("Mirrah Chain Gloves", 0x14B57990, DS3ItemCategory.ARMOR), - ("Mirrah Chain Leggings", 0x14B57D78, DS3ItemCategory.ARMOR), - ("Maiden Hood", 0x14BD12E0, DS3ItemCategory.ARMOR), - ("Maiden Robe", 0x14BD16C8, DS3ItemCategory.ARMOR), - ("Maiden Gloves", 0x14BD1AB0, DS3ItemCategory.ARMOR), - ("Maiden Skirt", 0x14BD1E98, DS3ItemCategory.ARMOR), - ("Alva Helm", 0x14C4B400, DS3ItemCategory.ARMOR), - ("Alva Armor", 0x14C4B7E8, DS3ItemCategory.ARMOR), - ("Alva Gauntlets", 0x14C4BBD0, DS3ItemCategory.ARMOR), - ("Alva Leggings", 0x14C4BFB8, DS3ItemCategory.ARMOR), - ("Shadow Mask", 0x14D3F640, DS3ItemCategory.ARMOR), - ("Shadow Garb", 0x14D3FA28, DS3ItemCategory.ARMOR), - ("Shadow Gauntlets", 0x14D3FE10, DS3ItemCategory.ARMOR), - ("Shadow Leggings", 0x14D401F8, DS3ItemCategory.ARMOR), - ("Eastern Helm", 0x14E33880, DS3ItemCategory.ARMOR), - ("Eastern Armor", 0x14E33C68, DS3ItemCategory.ARMOR), - ("Eastern Gauntlets", 0x14E34050, DS3ItemCategory.ARMOR), - ("Eastern Leggings", 0x14E34438, DS3ItemCategory.ARMOR), - ("Helm of Favor", 0x14F27AC0, DS3ItemCategory.ARMOR), - ("Embraced Armor of Favor", 0x14F27EA8, DS3ItemCategory.ARMOR), - ("Gauntlets of Favor", 0x14F28290, DS3ItemCategory.ARMOR), - ("Leggings of Favor", 0x14F28678, DS3ItemCategory.ARMOR), - ("Brass Helm", 0x1501BD00, DS3ItemCategory.ARMOR), - ("Brass Armor", 0x1501C0E8, DS3ItemCategory.ARMOR), - ("Brass Gauntlets", 0x1501C4D0, DS3ItemCategory.ARMOR), - ("Brass Leggings", 0x1501C8B8, DS3ItemCategory.ARMOR), - ("Silver Knight Helm", 0x1510FF40, DS3ItemCategory.ARMOR), - ("Silver Knight Armor", 0x15110328, DS3ItemCategory.ARMOR), - ("Silver Knight Gauntlets", 0x15110710, DS3ItemCategory.ARMOR), - ("Silver Knight Leggings", 0x15110AF8, DS3ItemCategory.ARMOR), - ("Lucatiel's Mask", 0x15204180, DS3ItemCategory.ARMOR), - ("Mirrah Vest", 0x15204568, DS3ItemCategory.ARMOR), - ("Mirrah Gloves", 0x15204950, DS3ItemCategory.ARMOR), - ("Mirrah Trousers", 0x15204D38, DS3ItemCategory.ARMOR), - ("Iron Helm", 0x152F83C0, DS3ItemCategory.ARMOR), - ("Armor of the Sun", 0x152F87A8, DS3ItemCategory.ARMOR), - ("Iron Bracelets", 0x152F8B90, DS3ItemCategory.ARMOR), - ("Iron Leggings", 0x152F8F78, DS3ItemCategory.ARMOR), - ("Drakeblood Helm", 0x153EC600, DS3ItemCategory.ARMOR), - ("Drakeblood Armor", 0x153EC9E8, DS3ItemCategory.ARMOR), - ("Drakeblood Gauntlets", 0x153ECDD0, DS3ItemCategory.ARMOR), - ("Drakeblood Leggings", 0x153ED1B8, DS3ItemCategory.ARMOR), - ("Drang Armor", 0x154E0C28, DS3ItemCategory.ARMOR), - ("Drang Gauntlets", 0x154E1010, DS3ItemCategory.ARMOR), - ("Drang Shoes", 0x154E13F8, DS3ItemCategory.ARMOR), - ("Black Iron Helm", 0x155D4A80, DS3ItemCategory.ARMOR), - ("Black Iron Armor", 0x155D4E68, DS3ItemCategory.ARMOR), - ("Black Iron Gauntlets", 0x155D5250, DS3ItemCategory.ARMOR), - ("Black Iron Leggings", 0x155D5638, DS3ItemCategory.ARMOR), - ("Painting Guardian Hood", 0x156C8CC0, DS3ItemCategory.ARMOR), - ("Painting Guardian Gown", 0x156C90A8, DS3ItemCategory.ARMOR), - ("Painting Guardian Gloves", 0x156C9490, DS3ItemCategory.ARMOR), - ("Painting Guardian Waistcloth", 0x156C9878, DS3ItemCategory.ARMOR), - ("Wolf Knight Helm", 0x157BCF00, DS3ItemCategory.ARMOR), - ("Wolf Knight Armor", 0x157BD2E8, DS3ItemCategory.ARMOR), - ("Wolf Knight Gauntlets", 0x157BD6D0, DS3ItemCategory.ARMOR), - ("Wolf Knight Leggings", 0x157BDAB8, DS3ItemCategory.ARMOR), - ("Dragonslayer Helm", 0x158B1140, DS3ItemCategory.ARMOR), - ("Dragonslayer Armor", 0x158B1528, DS3ItemCategory.ARMOR), - ("Dragonslayer Gauntlets", 0x158B1910, DS3ItemCategory.ARMOR), - ("Dragonslayer Leggings", 0x158B1CF8, DS3ItemCategory.ARMOR), - ("Smough's Helm", 0x159A5380, DS3ItemCategory.ARMOR), - ("Smough's Armor", 0x159A5768, DS3ItemCategory.ARMOR), - ("Smough's Gauntlets", 0x159A5B50, DS3ItemCategory.ARMOR), - ("Smough's Leggings", 0x159A5F38, DS3ItemCategory.ARMOR), - ("Helm of Thorns", 0x15B8D800, DS3ItemCategory.ARMOR), - ("Armor of Thorns", 0x15B8DBE8, DS3ItemCategory.ARMOR), - ("Gauntlets of Thorns", 0x15B8DFD0, DS3ItemCategory.ARMOR), - ("Leggings of Thorns", 0x15B8E3B8, DS3ItemCategory.ARMOR), - ("Crown of Dusk", 0x15D75C80, DS3ItemCategory.ARMOR), - ("Antiquated Dress", 0x15D76068, DS3ItemCategory.ARMOR), - ("Antiquated Gloves", 0x15D76450, DS3ItemCategory.ARMOR), - ("Antiquated Skirt", 0x15D76838, DS3ItemCategory.ARMOR), - ("Karla's Pointed Hat", 0x15E69EC0, DS3ItemCategory.ARMOR), - ("Karla's Coat", 0x15E6A2A8, DS3ItemCategory.ARMOR), - ("Karla's Gloves", 0x15E6A690, DS3ItemCategory.ARMOR), - ("Karla's Trousers", 0x15E6AA78, DS3ItemCategory.ARMOR), + DS3ItemData("Fallen Knight Helm", 0x1121EAC0, DS3ItemCategory.ARMOR), + DS3ItemData("Fallen Knight Armor", 0x1121EEA8, DS3ItemCategory.ARMOR), + DS3ItemData("Fallen Knight Gauntlets", 0x1121F290, DS3ItemCategory.ARMOR), + DS3ItemData("Fallen Knight Trousers", 0x1121F678, DS3ItemCategory.ARMOR), + DS3ItemData("Knight Helm", 0x11298BE0, DS3ItemCategory.ARMOR), + DS3ItemData("Knight Armor", 0x11298FC8, DS3ItemCategory.ARMOR), + DS3ItemData("Knight Gauntlets", 0x112993B0, DS3ItemCategory.ARMOR), + DS3ItemData("Knight Leggings", 0x11299798, DS3ItemCategory.ARMOR), + DS3ItemData("Firelink Helm", 0x11406F40, DS3ItemCategory.ARMOR), + DS3ItemData("Firelink Armor", 0x11407328, DS3ItemCategory.ARMOR), + DS3ItemData("Firelink Gauntlets", 0x11407710, DS3ItemCategory.ARMOR), + DS3ItemData("Firelink Leggings", 0x11407AF8, DS3ItemCategory.ARMOR), + DS3ItemData("Sellsword Helm", 0x11481060, DS3ItemCategory.ARMOR), + DS3ItemData("Sellsword Armor", 0x11481448, DS3ItemCategory.ARMOR), + DS3ItemData("Sellsword Gauntlet", 0x11481830, DS3ItemCategory.ARMOR), + DS3ItemData("Sellsword Trousers", 0x11481C18, DS3ItemCategory.ARMOR), + DS3ItemData("Herald Helm", 0x114FB180, DS3ItemCategory.ARMOR), + DS3ItemData("Herald Armor", 0x114FB568, DS3ItemCategory.ARMOR), + DS3ItemData("Herald Gloves", 0x114FB950, DS3ItemCategory.ARMOR), + DS3ItemData("Herald Trousers", 0x114FBD38, DS3ItemCategory.ARMOR), + DS3ItemData("Sunless Veil", 0x115752A0, DS3ItemCategory.ARMOR), + DS3ItemData("Sunless Armor", 0x11575688, DS3ItemCategory.ARMOR), + DS3ItemData("Sunless Gauntlets", 0x11575A70, DS3ItemCategory.ARMOR), + DS3ItemData("Sunless Leggings", 0x11575E58, DS3ItemCategory.ARMOR), + DS3ItemData("Black Hand Hat", 0x115EF3C0, DS3ItemCategory.ARMOR), + DS3ItemData("Black Hand Armor", 0x115EF7A8, DS3ItemCategory.ARMOR), + DS3ItemData("Assassin Gloves", 0x115EFB90, DS3ItemCategory.ARMOR), + DS3ItemData("Assassin Trousers", 0x115EFF78, DS3ItemCategory.ARMOR), + DS3ItemData("Assassin Hood", 0x11607A60, DS3ItemCategory.ARMOR), + DS3ItemData("Assassin Armor", 0x11607E48, DS3ItemCategory.ARMOR), + DS3ItemData("Xanthous Crown", 0x116694E0, DS3ItemCategory.ARMOR), + DS3ItemData("Xanthous Overcoat", 0x116698C8, DS3ItemCategory.ARMOR), + DS3ItemData("Xanthous Gloves", 0x11669CB0, DS3ItemCategory.ARMOR), + DS3ItemData("Xanthous Trousers", 0x1166A098, DS3ItemCategory.ARMOR), + DS3ItemData("Northern Helm", 0x116E3600, DS3ItemCategory.ARMOR), + DS3ItemData("Northern Armor", 0x116E39E8, DS3ItemCategory.ARMOR), + DS3ItemData("Northern Gloves", 0x116E3DD0, DS3ItemCategory.ARMOR), + DS3ItemData("Northern Trousers", 0x116E41B8, DS3ItemCategory.ARMOR), + DS3ItemData("Morne's Helm", 0x1175D720, DS3ItemCategory.ARMOR), + DS3ItemData("Morne's Armor", 0x1175DB08, DS3ItemCategory.ARMOR), + DS3ItemData("Morne's Gauntlets", 0x1175DEF0, DS3ItemCategory.ARMOR), + DS3ItemData("Morne's Leggings", 0x1175E2D8, DS3ItemCategory.ARMOR), + DS3ItemData("Silver Mask", 0x117D7840, DS3ItemCategory.ARMOR), + DS3ItemData("Leonhard's Garb", 0x117D7C28, DS3ItemCategory.ARMOR), + DS3ItemData("Leonhard's Gauntlets", 0x117D8010, DS3ItemCategory.ARMOR), + DS3ItemData("Leonhard's Trousers", 0x117D83F8, DS3ItemCategory.ARMOR), + DS3ItemData("Sneering Mask", 0x11851960, DS3ItemCategory.ARMOR), + DS3ItemData("Pale Shade Robe", 0x11851D48, DS3ItemCategory.ARMOR), + DS3ItemData("Pale Shade Gloves", 0x11852130, DS3ItemCategory.ARMOR), + DS3ItemData("Pale Shade Trousers", 0x11852518, DS3ItemCategory.ARMOR), + DS3ItemData("Sunset Helm", 0x118CBA80, DS3ItemCategory.ARMOR), + DS3ItemData("Sunset Armor", 0x118CBE68, DS3ItemCategory.ARMOR), + DS3ItemData("Sunset Gauntlets", 0x118CC250, DS3ItemCategory.ARMOR), + DS3ItemData("Sunset Leggings", 0x118CC638, DS3ItemCategory.ARMOR), + DS3ItemData("Old Sage's Blindfold", 0x11945BA0, DS3ItemCategory.ARMOR), + DS3ItemData("Cornyx's Garb", 0x11945F88, DS3ItemCategory.ARMOR), + DS3ItemData("Cornyx's Wrap", 0x11946370, DS3ItemCategory.ARMOR), + DS3ItemData("Cornyx's Skirt", 0x11946758, DS3ItemCategory.ARMOR), + DS3ItemData("Executioner Helm", 0x119BFCC0, DS3ItemCategory.ARMOR), + DS3ItemData("Executioner Armor", 0x119C00A8, DS3ItemCategory.ARMOR), + DS3ItemData("Executioner Gauntlets", 0x119C0490, DS3ItemCategory.ARMOR), + DS3ItemData("Executioner Leggings", 0x119C0878, DS3ItemCategory.ARMOR), + DS3ItemData("Billed Mask", 0x11A39DE0, DS3ItemCategory.ARMOR), + DS3ItemData("Black Dress", 0x11A3A1C8, DS3ItemCategory.ARMOR), + DS3ItemData("Black Gauntlets", 0x11A3A5B0, DS3ItemCategory.ARMOR), + DS3ItemData("Black Leggings", 0x11A3A998, DS3ItemCategory.ARMOR), + DS3ItemData("Pyromancer Crown", 0x11AB3F00, DS3ItemCategory.ARMOR), + DS3ItemData("Pyromancer Garb", 0x11AB42E8, DS3ItemCategory.ARMOR), + DS3ItemData("Pyromancer Wrap", 0x11AB46D0, DS3ItemCategory.ARMOR), + DS3ItemData("Pyromancer Trousers", 0x11AB4AB8, DS3ItemCategory.ARMOR), + DS3ItemData("Court Sorcerer Hood", 0x11BA8140, DS3ItemCategory.ARMOR), + DS3ItemData("Court Sorcerer Robe", 0x11BA8528, DS3ItemCategory.ARMOR), + DS3ItemData("Court Sorcerer Gloves", 0x11BA8910, DS3ItemCategory.ARMOR), + DS3ItemData("Court Sorcerer Trousers", 0x11BA8CF8, DS3ItemCategory.ARMOR), + DS3ItemData("Sorcerer Hood", 0x11C9C380, DS3ItemCategory.ARMOR), + DS3ItemData("Sorcerer Robe", 0x11C9C768, DS3ItemCategory.ARMOR), + DS3ItemData("Sorcerer Gloves", 0x11C9CB50, DS3ItemCategory.ARMOR), + DS3ItemData("Sorcerer Trousers", 0x11C9CF38, DS3ItemCategory.ARMOR), + DS3ItemData("Clandestine Coat", 0x11CB4E08, DS3ItemCategory.ARMOR), + DS3ItemData("Cleric Hat", 0x11D905C0, DS3ItemCategory.ARMOR), + DS3ItemData("Cleric Blue Robe", 0x11D909A8, DS3ItemCategory.ARMOR), + DS3ItemData("Cleric Gloves", 0x11D90D90, DS3ItemCategory.ARMOR), + DS3ItemData("Cleric Trousers", 0x11D91178, DS3ItemCategory.ARMOR), + DS3ItemData("Steel Soldier Helm", 0x12625A00, DS3ItemCategory.ARMOR), + DS3ItemData("Deserter Armor", 0x12625DE8, DS3ItemCategory.ARMOR), + DS3ItemData("Deserter Trousers", 0x126265B8, DS3ItemCategory.ARMOR), + DS3ItemData("Thief Mask", 0x12656740, DS3ItemCategory.ARMOR), + DS3ItemData("Sage's Big Hat", 0x129020C0, DS3ItemCategory.ARMOR), + DS3ItemData("Aristocrat's Mask", 0x129F6300, DS3ItemCategory.ARMOR), + DS3ItemData("Jailer Robe", 0x129F66E8, DS3ItemCategory.ARMOR), + DS3ItemData("Jailer Gloves", 0x129F6AD0, DS3ItemCategory.ARMOR), + DS3ItemData("Jailer Trousers", 0x129F6EB8, DS3ItemCategory.ARMOR), + DS3ItemData("Grave Warden Hood", 0x12BDE780, DS3ItemCategory.ARMOR), + DS3ItemData("Grave Warden Robe", 0x12BDEB68, DS3ItemCategory.ARMOR), + DS3ItemData("Grave Warden Wrap", 0x12BDEF50, DS3ItemCategory.ARMOR), + DS3ItemData("Grave Warden Skirt", 0x12BDF338, DS3ItemCategory.ARMOR), + DS3ItemData("Worker Hat", 0x12CD29C0, DS3ItemCategory.ARMOR), + DS3ItemData("Worker Garb", 0x12CD2DA8, DS3ItemCategory.ARMOR), + DS3ItemData("Worker Gloves", 0x12CD3190, DS3ItemCategory.ARMOR), + DS3ItemData("Worker Trousers", 0x12CD3578, DS3ItemCategory.ARMOR), + DS3ItemData("Thrall Hood", 0x12D4CAE0, DS3ItemCategory.ARMOR), + DS3ItemData("Evangelist Hat", 0x12DC6C00, DS3ItemCategory.ARMOR), + DS3ItemData("Evangelist Robe", 0x12DC6FE8, DS3ItemCategory.ARMOR), + DS3ItemData("Evangelist Gloves", 0x12DC73D0, DS3ItemCategory.ARMOR), + DS3ItemData("Evangelist Trousers", 0x12DC77B8, DS3ItemCategory.ARMOR), + DS3ItemData("Scholar's Robe", 0x12E41108, DS3ItemCategory.ARMOR), + DS3ItemData("Winged Knight Helm", 0x12EBAE40, DS3ItemCategory.ARMOR), + DS3ItemData("Winged Knight Armor", 0x12EBB228, DS3ItemCategory.ARMOR), + DS3ItemData("Winged Knight Gauntlets", 0x12EBB610, DS3ItemCategory.ARMOR), + DS3ItemData("Winged Knight Leggings", 0x12EBB9F8, DS3ItemCategory.ARMOR), + DS3ItemData("Cathedral Knight Helm", 0x130291A0, DS3ItemCategory.ARMOR), + DS3ItemData("Cathedral Knight Armor", 0x13029588, DS3ItemCategory.ARMOR), + DS3ItemData("Cathedral Knight Gauntlets", 0x13029970, DS3ItemCategory.ARMOR), + DS3ItemData("Cathedral Knight Leggings", 0x13029D58, DS3ItemCategory.ARMOR), + DS3ItemData("Lothric Knight Helm", 0x13197500, DS3ItemCategory.ARMOR), + DS3ItemData("Lothric Knight Armor", 0x131978E8, DS3ItemCategory.ARMOR), + DS3ItemData("Lothric Knight Gauntlets", 0x13197CD0, DS3ItemCategory.ARMOR), + DS3ItemData("Lothric Knight Leggings", 0x131980B8, DS3ItemCategory.ARMOR), + DS3ItemData("Outrider Knight Helm", 0x1328B740, DS3ItemCategory.ARMOR), + DS3ItemData("Outrider Knight Armor", 0x1328BB28, DS3ItemCategory.ARMOR), + DS3ItemData("Outrider Knight Gauntlets", 0x1328BF10, DS3ItemCategory.ARMOR), + DS3ItemData("Outrider Knight Leggings", 0x1328C2F8, DS3ItemCategory.ARMOR), + DS3ItemData("Black Knight Helm", 0x1337F980, DS3ItemCategory.ARMOR), + DS3ItemData("Black Knight Armor", 0x1337FD68, DS3ItemCategory.ARMOR), + DS3ItemData("Black Knight Gauntlets", 0x13380150, DS3ItemCategory.ARMOR), + DS3ItemData("Black Knight Leggings", 0x13380538, DS3ItemCategory.ARMOR), + DS3ItemData("Dark Mask", 0x133F9AA0, DS3ItemCategory.ARMOR), + DS3ItemData("Dark Armor", 0x133F9E88, DS3ItemCategory.ARMOR), + DS3ItemData("Dark Gauntlets", 0x133FA270, DS3ItemCategory.ARMOR), + DS3ItemData("Dark Leggings", 0x133FA658, DS3ItemCategory.ARMOR), + DS3ItemData("Exile Mask", 0x13473BC0, DS3ItemCategory.ARMOR), + DS3ItemData("Exile Armor", 0x13473FA8, DS3ItemCategory.ARMOR), + DS3ItemData("Exile Gauntlets", 0x13474390, DS3ItemCategory.ARMOR), + DS3ItemData("Exile Leggings", 0x13474778, DS3ItemCategory.ARMOR), + DS3ItemData("Pontiff Knight Crown", 0x13567E00, DS3ItemCategory.ARMOR), + DS3ItemData("Pontiff Knight Armor", 0x135681E8, DS3ItemCategory.ARMOR), + DS3ItemData("Pontiff Knight Gauntlets", 0x135685D0, DS3ItemCategory.ARMOR), + DS3ItemData("Pontiff Knight Leggings", 0x135689B8, DS3ItemCategory.ARMOR), + DS3ItemData("Golden Crown", 0x1365C040, DS3ItemCategory.ARMOR), + DS3ItemData("Dragonscale Armor", 0x1365C428, DS3ItemCategory.ARMOR), + DS3ItemData("Golden Bracelets", 0x1365C810, DS3ItemCategory.ARMOR), + DS3ItemData("Dragonscale Waistcloth", 0x1365CBF8, DS3ItemCategory.ARMOR), + DS3ItemData("Wolnir's Crown", 0x136D6160, DS3ItemCategory.ARMOR), + DS3ItemData("Undead Legion Helm", 0x13750280, DS3ItemCategory.ARMOR), + DS3ItemData("Undead Legion Armor", 0x13750668, DS3ItemCategory.ARMOR), + DS3ItemData("Undead Legion Gauntlet", 0x13750A50, DS3ItemCategory.ARMOR), + DS3ItemData("Undead Legion Leggings", 0x13750E38, DS3ItemCategory.ARMOR), + DS3ItemData("Fire Witch Helm", 0x13938700, DS3ItemCategory.ARMOR), + DS3ItemData("Fire Witch Armor", 0x13938AE8, DS3ItemCategory.ARMOR), + DS3ItemData("Fire Witch Gauntlets", 0x13938ED0, DS3ItemCategory.ARMOR), + DS3ItemData("Fire Witch Leggings", 0x139392B8, DS3ItemCategory.ARMOR), + DS3ItemData("Lorian's Helm", 0x13A2C940, DS3ItemCategory.ARMOR), + DS3ItemData("Lorian's Armor", 0x13A2CD28, DS3ItemCategory.ARMOR), + DS3ItemData("Lorian's Gauntlets", 0x13A2D110, DS3ItemCategory.ARMOR), + DS3ItemData("Lorian's Leggings", 0x13A2D4F8, DS3ItemCategory.ARMOR), + DS3ItemData("Hood of Prayer", 0x13AA6A60, DS3ItemCategory.ARMOR), + DS3ItemData("Robe of Prayer", 0x13AA6E48, DS3ItemCategory.ARMOR), + DS3ItemData("Skirt of Prayer", 0x13AA7618, DS3ItemCategory.ARMOR), + DS3ItemData("Dancer's Crown", 0x13C14DC0, DS3ItemCategory.ARMOR), + DS3ItemData("Dancer's Armor", 0x13C151A8, DS3ItemCategory.ARMOR), + DS3ItemData("Dancer's Gauntlets", 0x13C15590, DS3ItemCategory.ARMOR), + DS3ItemData("Dancer's Leggings", 0x13C15978, DS3ItemCategory.ARMOR), + DS3ItemData("Gundyr's Helm", 0x13D09000, DS3ItemCategory.ARMOR), + DS3ItemData("Gundyr's Armor", 0x13D093E8, DS3ItemCategory.ARMOR), + DS3ItemData("Gundyr's Gauntlets", 0x13D097D0, DS3ItemCategory.ARMOR), + DS3ItemData("Gundyr's Leggings", 0x13D09BB8, DS3ItemCategory.ARMOR), + DS3ItemData("Archdeacon White Crown", 0x13EF1480, DS3ItemCategory.ARMOR), + DS3ItemData("Archdeacon Holy Garb", 0x13EF1868, DS3ItemCategory.ARMOR), + DS3ItemData("Archdeacon Skirt", 0x13EF2038, DS3ItemCategory.ARMOR), + DS3ItemData("Deacon Robe", 0x13F6B988, DS3ItemCategory.ARMOR), + DS3ItemData("Deacon Skirt", 0x13F6C158, DS3ItemCategory.ARMOR), + DS3ItemData("Fire Keeper Robe", 0x140D9CE8, DS3ItemCategory.ARMOR), + DS3ItemData("Fire Keeper Gloves", 0x140DA0D0, DS3ItemCategory.ARMOR), + DS3ItemData("Fire Keeper Skirt", 0x140DA4B8, DS3ItemCategory.ARMOR), + DS3ItemData("Chain Helm", 0x142C1D80, DS3ItemCategory.ARMOR), + DS3ItemData("Chain Armor", 0x142C2168, DS3ItemCategory.ARMOR), + DS3ItemData("Leather Gauntlets", 0x142C2550, DS3ItemCategory.ARMOR), + DS3ItemData("Chain Leggings", 0x142C2938, DS3ItemCategory.ARMOR), + DS3ItemData("Nameless Knight Helm", 0x143B5FC0, DS3ItemCategory.ARMOR), + DS3ItemData("Nameless Knight Armor", 0x143B63A8, DS3ItemCategory.ARMOR), + DS3ItemData("Nameless Knight Gauntlets", 0x143B6790, DS3ItemCategory.ARMOR), + DS3ItemData("Nameless Knight Leggings", 0x143B6B78, DS3ItemCategory.ARMOR), + DS3ItemData("Elite Knight Helm", 0x144AA200, DS3ItemCategory.ARMOR), + DS3ItemData("Elite Knight Armor", 0x144AA5E8, DS3ItemCategory.ARMOR), + DS3ItemData("Elite Knight Gauntlets", 0x144AA9D0, DS3ItemCategory.ARMOR), + DS3ItemData("Elite Knight Leggings", 0x144AADB8, DS3ItemCategory.ARMOR), + DS3ItemData("Faraam Helm", 0x1459E440, DS3ItemCategory.ARMOR), + DS3ItemData("Faraam Armor", 0x1459E828, DS3ItemCategory.ARMOR), + DS3ItemData("Faraam Gauntlets", 0x1459EC10, DS3ItemCategory.ARMOR), + DS3ItemData("Faraam Boots", 0x1459EFF8, DS3ItemCategory.ARMOR), + DS3ItemData("Catarina Helm", 0x14692680, DS3ItemCategory.ARMOR), + DS3ItemData("Catarina Armor", 0x14692A68, DS3ItemCategory.ARMOR), + DS3ItemData("Catarina Gauntlets", 0x14692E50, DS3ItemCategory.ARMOR), + DS3ItemData("Catarina Leggings", 0x14693238, DS3ItemCategory.ARMOR), + DS3ItemData("Standard Helm", 0x1470C7A0, DS3ItemCategory.ARMOR), + DS3ItemData("Hard Leather Armor", 0x1470CB88, DS3ItemCategory.ARMOR), + DS3ItemData("Hard Leather Gauntlets", 0x1470CF70, DS3ItemCategory.ARMOR), + DS3ItemData("Hard Leather Boots", 0x1470D358, DS3ItemCategory.ARMOR), + DS3ItemData("Havel's Helm", 0x147868C0, DS3ItemCategory.ARMOR), + DS3ItemData("Havel's Armor", 0x14786CA8, DS3ItemCategory.ARMOR), + DS3ItemData("Havel's Gauntlets", 0x14787090, DS3ItemCategory.ARMOR), + DS3ItemData("Havel's Leggings", 0x14787478, DS3ItemCategory.ARMOR), + DS3ItemData("Brigand Hood", 0x148009E0, DS3ItemCategory.ARMOR), + DS3ItemData("Brigand Armor", 0x14800DC8, DS3ItemCategory.ARMOR), + DS3ItemData("Brigand Gauntlets", 0x148011B0, DS3ItemCategory.ARMOR), + DS3ItemData("Brigand Trousers", 0x14801598, DS3ItemCategory.ARMOR), + DS3ItemData("Pharis's Hat", 0x1487AB00, DS3ItemCategory.ARMOR), + DS3ItemData("Leather Armor", 0x1487AEE8, DS3ItemCategory.ARMOR), + DS3ItemData("Leather Gloves", 0x1487B2D0, DS3ItemCategory.ARMOR), + DS3ItemData("Leather Boots", 0x1487B6B8, DS3ItemCategory.ARMOR), + DS3ItemData("Ragged Mask", 0x148F4C20, DS3ItemCategory.ARMOR), + DS3ItemData("Master's Attire", 0x148F5008, DS3ItemCategory.ARMOR), + DS3ItemData("Master's Gloves", 0x148F53F0, DS3ItemCategory.ARMOR), + DS3ItemData("Loincloth", 0x148F57D8, DS3ItemCategory.ARMOR), + DS3ItemData("Old Sorcerer Hat", 0x1496ED40, DS3ItemCategory.ARMOR), + DS3ItemData("Old Sorcerer Coat", 0x1496F128, DS3ItemCategory.ARMOR), + DS3ItemData("Old Sorcerer Gauntlets", 0x1496F510, DS3ItemCategory.ARMOR), + DS3ItemData("Old Sorcerer Boots", 0x1496F8F8, DS3ItemCategory.ARMOR), + DS3ItemData("Conjurator Hood", 0x149E8E60, DS3ItemCategory.ARMOR), + DS3ItemData("Conjurator Robe", 0x149E9248, DS3ItemCategory.ARMOR), + DS3ItemData("Conjurator Manchettes", 0x149E9630, DS3ItemCategory.ARMOR), + DS3ItemData("Conjurator Boots", 0x149E9A18, DS3ItemCategory.ARMOR), + DS3ItemData("Black Leather Armor", 0x14A63368, DS3ItemCategory.ARMOR), + DS3ItemData("Black Leather Gloves", 0x14A63750, DS3ItemCategory.ARMOR), + DS3ItemData("Black Leather Boots", 0x14A63B38, DS3ItemCategory.ARMOR), + DS3ItemData("Symbol of Avarice", 0x14ADD0A0, DS3ItemCategory.ARMOR), + DS3ItemData("Creighton's Steel Mask", 0x14B571C0, DS3ItemCategory.ARMOR), + DS3ItemData("Mirrah Chain Mail", 0x14B575A8, DS3ItemCategory.ARMOR), + DS3ItemData("Mirrah Chain Gloves", 0x14B57990, DS3ItemCategory.ARMOR), + DS3ItemData("Mirrah Chain Leggings", 0x14B57D78, DS3ItemCategory.ARMOR), + DS3ItemData("Maiden Hood", 0x14BD12E0, DS3ItemCategory.ARMOR), + DS3ItemData("Maiden Robe", 0x14BD16C8, DS3ItemCategory.ARMOR), + DS3ItemData("Maiden Gloves", 0x14BD1AB0, DS3ItemCategory.ARMOR), + DS3ItemData("Maiden Skirt", 0x14BD1E98, DS3ItemCategory.ARMOR), + DS3ItemData("Alva Helm", 0x14C4B400, DS3ItemCategory.ARMOR), + DS3ItemData("Alva Armor", 0x14C4B7E8, DS3ItemCategory.ARMOR), + DS3ItemData("Alva Gauntlets", 0x14C4BBD0, DS3ItemCategory.ARMOR), + DS3ItemData("Alva Leggings", 0x14C4BFB8, DS3ItemCategory.ARMOR), + DS3ItemData("Shadow Mask", 0x14D3F640, DS3ItemCategory.ARMOR), + DS3ItemData("Shadow Garb", 0x14D3FA28, DS3ItemCategory.ARMOR), + DS3ItemData("Shadow Gauntlets", 0x14D3FE10, DS3ItemCategory.ARMOR), + DS3ItemData("Shadow Leggings", 0x14D401F8, DS3ItemCategory.ARMOR), + DS3ItemData("Eastern Helm", 0x14E33880, DS3ItemCategory.ARMOR), + DS3ItemData("Eastern Armor", 0x14E33C68, DS3ItemCategory.ARMOR), + DS3ItemData("Eastern Gauntlets", 0x14E34050, DS3ItemCategory.ARMOR), + DS3ItemData("Eastern Leggings", 0x14E34438, DS3ItemCategory.ARMOR), + DS3ItemData("Helm of Favor", 0x14F27AC0, DS3ItemCategory.ARMOR), + DS3ItemData("Embraced Armor of Favor", 0x14F27EA8, DS3ItemCategory.ARMOR), + DS3ItemData("Gauntlets of Favor", 0x14F28290, DS3ItemCategory.ARMOR), + DS3ItemData("Leggings of Favor", 0x14F28678, DS3ItemCategory.ARMOR), + DS3ItemData("Brass Helm", 0x1501BD00, DS3ItemCategory.ARMOR), + DS3ItemData("Brass Armor", 0x1501C0E8, DS3ItemCategory.ARMOR), + DS3ItemData("Brass Gauntlets", 0x1501C4D0, DS3ItemCategory.ARMOR), + DS3ItemData("Brass Leggings", 0x1501C8B8, DS3ItemCategory.ARMOR), + DS3ItemData("Silver Knight Helm", 0x1510FF40, DS3ItemCategory.ARMOR), + DS3ItemData("Silver Knight Armor", 0x15110328, DS3ItemCategory.ARMOR), + DS3ItemData("Silver Knight Gauntlets", 0x15110710, DS3ItemCategory.ARMOR), + DS3ItemData("Silver Knight Leggings", 0x15110AF8, DS3ItemCategory.ARMOR), + DS3ItemData("Lucatiel's Mask", 0x15204180, DS3ItemCategory.ARMOR), + DS3ItemData("Mirrah Vest", 0x15204568, DS3ItemCategory.ARMOR), + DS3ItemData("Mirrah Gloves", 0x15204950, DS3ItemCategory.ARMOR), + DS3ItemData("Mirrah Trousers", 0x15204D38, DS3ItemCategory.ARMOR), + DS3ItemData("Iron Helm", 0x152F83C0, DS3ItemCategory.ARMOR), + DS3ItemData("Armor of the Sun", 0x152F87A8, DS3ItemCategory.ARMOR), + DS3ItemData("Iron Bracelets", 0x152F8B90, DS3ItemCategory.ARMOR), + DS3ItemData("Iron Leggings", 0x152F8F78, DS3ItemCategory.ARMOR), + DS3ItemData("Drakeblood Helm", 0x153EC600, DS3ItemCategory.ARMOR), + DS3ItemData("Drakeblood Armor", 0x153EC9E8, DS3ItemCategory.ARMOR), + DS3ItemData("Drakeblood Gauntlets", 0x153ECDD0, DS3ItemCategory.ARMOR), + DS3ItemData("Drakeblood Leggings", 0x153ED1B8, DS3ItemCategory.ARMOR), + DS3ItemData("Drang Armor", 0x154E0C28, DS3ItemCategory.ARMOR), + DS3ItemData("Drang Gauntlets", 0x154E1010, DS3ItemCategory.ARMOR), + DS3ItemData("Drang Shoes", 0x154E13F8, DS3ItemCategory.ARMOR), + DS3ItemData("Black Iron Helm", 0x155D4A80, DS3ItemCategory.ARMOR), + DS3ItemData("Black Iron Armor", 0x155D4E68, DS3ItemCategory.ARMOR), + DS3ItemData("Black Iron Gauntlets", 0x155D5250, DS3ItemCategory.ARMOR), + DS3ItemData("Black Iron Leggings", 0x155D5638, DS3ItemCategory.ARMOR), + DS3ItemData("Painting Guardian Hood", 0x156C8CC0, DS3ItemCategory.ARMOR), + DS3ItemData("Painting Guardian Gown", 0x156C90A8, DS3ItemCategory.ARMOR), + DS3ItemData("Painting Guardian Gloves", 0x156C9490, DS3ItemCategory.ARMOR), + DS3ItemData("Painting Guardian Waistcloth", 0x156C9878, DS3ItemCategory.ARMOR), + DS3ItemData("Wolf Knight Helm", 0x157BCF00, DS3ItemCategory.ARMOR), + DS3ItemData("Wolf Knight Armor", 0x157BD2E8, DS3ItemCategory.ARMOR), + DS3ItemData("Wolf Knight Gauntlets", 0x157BD6D0, DS3ItemCategory.ARMOR), + DS3ItemData("Wolf Knight Leggings", 0x157BDAB8, DS3ItemCategory.ARMOR), + DS3ItemData("Dragonslayer Helm", 0x158B1140, DS3ItemCategory.ARMOR), + DS3ItemData("Dragonslayer Armor", 0x158B1528, DS3ItemCategory.ARMOR), + DS3ItemData("Dragonslayer Gauntlets", 0x158B1910, DS3ItemCategory.ARMOR), + DS3ItemData("Dragonslayer Leggings", 0x158B1CF8, DS3ItemCategory.ARMOR), + DS3ItemData("Smough's Helm", 0x159A5380, DS3ItemCategory.ARMOR), + DS3ItemData("Smough's Armor", 0x159A5768, DS3ItemCategory.ARMOR), + DS3ItemData("Smough's Gauntlets", 0x159A5B50, DS3ItemCategory.ARMOR), + DS3ItemData("Smough's Leggings", 0x159A5F38, DS3ItemCategory.ARMOR), + DS3ItemData("Helm of Thorns", 0x15B8D800, DS3ItemCategory.ARMOR), + DS3ItemData("Armor of Thorns", 0x15B8DBE8, DS3ItemCategory.ARMOR), + DS3ItemData("Gauntlets of Thorns", 0x15B8DFD0, DS3ItemCategory.ARMOR), + DS3ItemData("Leggings of Thorns", 0x15B8E3B8, DS3ItemCategory.ARMOR), + DS3ItemData("Crown of Dusk", 0x15D75C80, DS3ItemCategory.ARMOR), + DS3ItemData("Antiquated Dress", 0x15D76068, DS3ItemCategory.ARMOR), + DS3ItemData("Antiquated Gloves", 0x15D76450, DS3ItemCategory.ARMOR), + DS3ItemData("Antiquated Skirt", 0x15D76838, DS3ItemCategory.ARMOR), + DS3ItemData("Karla's Pointed Hat", 0x15E69EC0, DS3ItemCategory.ARMOR), + DS3ItemData("Karla's Coat", 0x15E6A2A8, DS3ItemCategory.ARMOR), + DS3ItemData("Karla's Gloves", 0x15E6A690, DS3ItemCategory.ARMOR), + DS3ItemData("Karla's Trousers", 0x15E6AA78, DS3ItemCategory.ARMOR), # Covenants - ("Blade of the Darkmoon", 0x20002710, DS3ItemCategory.SKIP), - ("Watchdogs of Farron", 0x20002724, DS3ItemCategory.SKIP), - ("Aldrich Faithful", 0x2000272E, DS3ItemCategory.SKIP), - ("Warrior of Sunlight", 0x20002738, DS3ItemCategory.SKIP), - ("Mound-makers", 0x20002742, DS3ItemCategory.SKIP), - ("Way of Blue", 0x2000274C, DS3ItemCategory.SKIP), - ("Blue Sentinels", 0x20002756, DS3ItemCategory.SKIP), - ("Rosaria's Fingers", 0x20002760, DS3ItemCategory.SKIP), + DS3ItemData("Blade of the Darkmoon", 0x20002710, DS3ItemCategory.SKIP), + DS3ItemData("Watchdogs of Farron", 0x20002724, DS3ItemCategory.SKIP), + DS3ItemData("Aldrich Faithful", 0x2000272E, DS3ItemCategory.SKIP), + DS3ItemData("Warrior of Sunlight", 0x20002738, DS3ItemCategory.SKIP), + DS3ItemData("Mound-makers", 0x20002742, DS3ItemCategory.SKIP), + DS3ItemData("Way of Blue", 0x2000274C, DS3ItemCategory.SKIP), + DS3ItemData("Blue Sentinels", 0x20002756, DS3ItemCategory.SKIP), + DS3ItemData("Rosaria's Fingers", 0x20002760, DS3ItemCategory.SKIP), + DS3ItemData("Spears of the Church", 0x2000276A, DS3ItemCategory.SKIP), # Rings - ("Life Ring", 0x20004E20, DS3ItemCategory.RING), - ("Life Ring+1", 0x20004E21, DS3ItemCategory.RING), - ("Life Ring+2", 0x20004E22, DS3ItemCategory.RING), - ("Life Ring+3", 0x20004E23, DS3ItemCategory.RING), - ("Chloranthy Ring", 0x20004E2A, DS3ItemCategory.RING), - ("Chloranthy Ring+1", 0x20004E2B, DS3ItemCategory.RING), - ("Chloranthy Ring+2", 0x20004E2C, DS3ItemCategory.RING), - ("Havel's Ring", 0x20004E34, DS3ItemCategory.RING), - ("Havel's Ring+1", 0x20004E35, DS3ItemCategory.RING), - ("Havel's Ring+2", 0x20004E36, DS3ItemCategory.RING), - ("Ring of Favor", 0x20004E3E, DS3ItemCategory.RING), - ("Ring of Favor+1", 0x20004E3F, DS3ItemCategory.RING), - ("Ring of Favor+2", 0x20004E40, DS3ItemCategory.RING), - ("Ring of Steel Protection", 0x20004E48, DS3ItemCategory.RING), - ("Ring of Steel Protection+1", 0x20004E49, DS3ItemCategory.RING), - ("Ring of Steel Protection+2", 0x20004E4A, DS3ItemCategory.RING), - ("Flame Stoneplate Ring", 0x20004E52, DS3ItemCategory.RING), - ("Flame Stoneplate Ring+1", 0x20004E53, DS3ItemCategory.RING), - ("Flame Stoneplate Ring+2", 0x20004E54, DS3ItemCategory.RING), - ("Thunder Stoneplate Ring", 0x20004E5C, DS3ItemCategory.RING), - ("Thunder Stoneplate Ring+1", 0x20004E5D, DS3ItemCategory.RING), - ("Thunder Stoneplate Ring+2", 0x20004E5E, DS3ItemCategory.RING), - ("Magic Stoneplate Ring", 0x20004E66, DS3ItemCategory.RING), - ("Magic Stoneplate Ring+1", 0x20004E67, DS3ItemCategory.RING), - ("Magic Stoneplate Ring+2", 0x20004E68, DS3ItemCategory.RING), - ("Dark Stoneplate Ring", 0x20004E70, DS3ItemCategory.RING), - ("Dark Stoneplate Ring+1", 0x20004E71, DS3ItemCategory.RING), - ("Dark Stoneplate Ring+2", 0x20004E72, DS3ItemCategory.RING), - ("Speckled Stoneplate Ring", 0x20004E7A, DS3ItemCategory.RING), - ("Speckled Stoneplate Ring+1", 0x20004E7B, DS3ItemCategory.RING), - ("Bloodbite Ring", 0x20004E84, DS3ItemCategory.RING), - ("Bloodbite Ring+1", 0x20004E85, DS3ItemCategory.RING), - ("Poisonbite Ring", 0x20004E8E, DS3ItemCategory.RING), - ("Poisonbite Ring+1", 0x20004E8F, DS3ItemCategory.RING), - ("Cursebite Ring", 0x20004E98, DS3ItemCategory.RING), - ("Fleshbite Ring", 0x20004EA2, DS3ItemCategory.RING), - ("Fleshbite Ring+1", 0x20004EA3, DS3ItemCategory.RING), - ("Wood Grain Ring", 0x20004EAC, DS3ItemCategory.RING), - ("Wood Grain Ring+1", 0x20004EAD, DS3ItemCategory.RING), - ("Wood Grain Ring+2", 0x20004EAE, DS3ItemCategory.RING), - ("Scholar Ring", 0x20004EB6, DS3ItemCategory.RING), - ("Priestess Ring", 0x20004EC0, DS3ItemCategory.RING), - ("Red Tearstone Ring", 0x20004ECA, DS3ItemCategory.RING), - ("Blue Tearstone Ring", 0x20004ED4, DS3ItemCategory.RING), - ("Wolf Ring", 0x20004EDE, DS3ItemCategory.RING), - ("Wolf Ring+1", 0x20004EDF, DS3ItemCategory.RING), - ("Wolf Ring+2", 0x20004EE0, DS3ItemCategory.RING), - ("Leo Ring", 0x20004EE8, DS3ItemCategory.RING), - ("Ring of Sacrifice", 0x20004EF2, DS3ItemCategory.RING), - ("Young Dragon Ring", 0x20004F06, DS3ItemCategory.RING), - ("Bellowing Dragoncrest Ring", 0x20004F07, DS3ItemCategory.RING), - ("Great Swamp Ring", 0x20004F10, DS3ItemCategory.RING), - ("Witch's Ring", 0x20004F11, DS3ItemCategory.RING), - ("Morne's Ring", 0x20004F1A, DS3ItemCategory.RING), - ("Ring of the Sun's First Born", 0x20004F1B, DS3ItemCategory.RING), - ("Lingering Dragoncrest Ring", 0x20004F2E, DS3ItemCategory.RING), - ("Lingering Dragoncrest Ring+1", 0x20004F2F, DS3ItemCategory.RING), - ("Lingering Dragoncrest Ring+2", 0x20004F30, DS3ItemCategory.RING), - ("Sage Ring", 0x20004F38, DS3ItemCategory.RING), - ("Sage Ring+1", 0x20004F39, DS3ItemCategory.RING), - ("Sage Ring+2", 0x20004F3A, DS3ItemCategory.RING), - ("Slumbering Dragoncrest Ring", 0x20004F42, DS3ItemCategory.RING), - ("Dusk Crown Ring", 0x20004F4C, DS3ItemCategory.RING), - ("Saint's Ring", 0x20004F56, DS3ItemCategory.RING), - ("Deep Ring", 0x20004F60, DS3ItemCategory.RING), - ("Darkmoon Ring", 0x20004F6A, DS3ItemCategory.RING), - ("Hawk Ring", 0x20004F92, DS3ItemCategory.RING), - ("Hornet Ring", 0x20004F9C, DS3ItemCategory.RING), - ("Covetous Gold Serpent Ring", 0x20004FA6, DS3ItemCategory.RING), - ("Covetous Gold Serpent Ring+1", 0x20004FA7, DS3ItemCategory.RING), - ("Covetous Gold Serpent Ring+2", 0x20004FA8, DS3ItemCategory.RING), - ("Covetous Silver Serpent Ring", 0x20004FB0, DS3ItemCategory.RING), - ("Covetous Silver Serpent Ring+1", 0x20004FB1, DS3ItemCategory.RING), - ("Covetous Silver Serpent Ring+2", 0x20004FB2, DS3ItemCategory.RING), - ("Sun Princess Ring", 0x20004FBA, DS3ItemCategory.RING), - ("Silvercat Ring", 0x20004FC4, DS3ItemCategory.RING), - ("Skull Ring", 0x20004FCE, DS3ItemCategory.RING), - ("Untrue White Ring", 0x20004FD8, DS3ItemCategory.RING), - ("Carthus Milkring", 0x20004FE2, DS3ItemCategory.RING), - ("Knight's Ring", 0x20004FEC, DS3ItemCategory.RING), - ("Hunter's Ring", 0x20004FF6, DS3ItemCategory.RING), - ("Knight Slayer's Ring", 0x20005000, DS3ItemCategory.RING), - ("Magic Clutch Ring", 0x2000500A, DS3ItemCategory.RING), - ("Lightning Clutch Ring", 0x20005014, DS3ItemCategory.RING), - ("Fire Clutch Ring", 0x2000501E, DS3ItemCategory.RING), - ("Dark Clutch Ring", 0x20005028, DS3ItemCategory.RING), - ("Flynn's Ring", 0x2000503C, DS3ItemCategory.RING), - ("Prisoner's Chain", 0x20005046, DS3ItemCategory.RING), - ("Untrue Dark Ring", 0x20005050, DS3ItemCategory.RING), - ("Obscuring Ring", 0x20005064, DS3ItemCategory.RING), - ("Ring of the Evil Eye", 0x2000506E, DS3ItemCategory.RING), - ("Ring of the Evil Eye+1", 0x2000506F, DS3ItemCategory.RING), - ("Ring of the Evil Eye+2", 0x20005070, DS3ItemCategory.RING), - ("Calamity Ring", 0x20005078, DS3ItemCategory.RING), - ("Farron Ring", 0x20005082, DS3ItemCategory.RING), - ("Aldrich's Ruby", 0x2000508C, DS3ItemCategory.RING), - ("Aldrich's Sapphire", 0x20005096, DS3ItemCategory.RING), - ("Lloyd's Sword Ring", 0x200050B4, DS3ItemCategory.RING), - ("Lloyd's Shield Ring", 0x200050BE, DS3ItemCategory.RING), - ("Estus Ring", 0x200050DC, DS3ItemCategory.RING), - ("Ashen Estus Ring", 0x200050E6, DS3ItemCategory.RING), - ("Carthus Bloodring", 0x200050FA, DS3ItemCategory.RING), - ("Reversal Ring", 0x20005104, DS3ItemCategory.RING), - ("Pontiff's Right Eye", 0x2000510E, DS3ItemCategory.RING), - ("Pontiff's Left Eye", 0x20005136, DS3ItemCategory.RING), - ("Dragonscale Ring", 0x2000515E, DS3ItemCategory.RING), + DS3ItemData("Life Ring", 0x20004E20, DS3ItemCategory.RING), + DS3ItemData("Life Ring+1", 0x20004E21, DS3ItemCategory.RING), + DS3ItemData("Life Ring+2", 0x20004E22, DS3ItemCategory.RING), + DS3ItemData("Life Ring+3", 0x20004E23, DS3ItemCategory.RING), + DS3ItemData("Chloranthy Ring", 0x20004E2A, DS3ItemCategory.RING), + DS3ItemData("Chloranthy Ring+1", 0x20004E2B, DS3ItemCategory.RING), + DS3ItemData("Chloranthy Ring+2", 0x20004E2C, DS3ItemCategory.RING), + DS3ItemData("Havel's Ring", 0x20004E34, DS3ItemCategory.RING), + DS3ItemData("Havel's Ring+1", 0x20004E35, DS3ItemCategory.RING), + DS3ItemData("Havel's Ring+2", 0x20004E36, DS3ItemCategory.RING), + DS3ItemData("Ring of Favor", 0x20004E3E, DS3ItemCategory.RING), + DS3ItemData("Ring of Favor+1", 0x20004E3F, DS3ItemCategory.RING), + DS3ItemData("Ring of Favor+2", 0x20004E40, DS3ItemCategory.RING), + DS3ItemData("Ring of Steel Protection", 0x20004E48, DS3ItemCategory.RING), + DS3ItemData("Ring of Steel Protection+1", 0x20004E49, DS3ItemCategory.RING), + DS3ItemData("Ring of Steel Protection+2", 0x20004E4A, DS3ItemCategory.RING), + DS3ItemData("Flame Stoneplate Ring", 0x20004E52, DS3ItemCategory.RING), + DS3ItemData("Flame Stoneplate Ring+1", 0x20004E53, DS3ItemCategory.RING), + DS3ItemData("Flame Stoneplate Ring+2", 0x20004E54, DS3ItemCategory.RING), + DS3ItemData("Thunder Stoneplate Ring", 0x20004E5C, DS3ItemCategory.RING), + DS3ItemData("Thunder Stoneplate Ring+1", 0x20004E5D, DS3ItemCategory.RING), + DS3ItemData("Thunder Stoneplate Ring+2", 0x20004E5E, DS3ItemCategory.RING), + DS3ItemData("Magic Stoneplate Ring", 0x20004E66, DS3ItemCategory.RING), + DS3ItemData("Magic Stoneplate Ring+1", 0x20004E67, DS3ItemCategory.RING), + DS3ItemData("Magic Stoneplate Ring+2", 0x20004E68, DS3ItemCategory.RING), + DS3ItemData("Dark Stoneplate Ring", 0x20004E70, DS3ItemCategory.RING), + DS3ItemData("Dark Stoneplate Ring+1", 0x20004E71, DS3ItemCategory.RING), + DS3ItemData("Dark Stoneplate Ring+2", 0x20004E72, DS3ItemCategory.RING), + DS3ItemData("Speckled Stoneplate Ring", 0x20004E7A, DS3ItemCategory.RING), + DS3ItemData("Speckled Stoneplate Ring+1", 0x20004E7B, DS3ItemCategory.RING), + DS3ItemData("Bloodbite Ring", 0x20004E84, DS3ItemCategory.RING), + DS3ItemData("Bloodbite Ring+1", 0x20004E85, DS3ItemCategory.RING), + DS3ItemData("Poisonbite Ring", 0x20004E8E, DS3ItemCategory.RING), + DS3ItemData("Poisonbite Ring+1", 0x20004E8F, DS3ItemCategory.RING), + DS3ItemData("Cursebite Ring", 0x20004E98, DS3ItemCategory.RING), + DS3ItemData("Fleshbite Ring", 0x20004EA2, DS3ItemCategory.RING), + DS3ItemData("Fleshbite Ring+1", 0x20004EA3, DS3ItemCategory.RING), + DS3ItemData("Wood Grain Ring", 0x20004EAC, DS3ItemCategory.RING), + DS3ItemData("Wood Grain Ring+1", 0x20004EAD, DS3ItemCategory.RING), + DS3ItemData("Wood Grain Ring+2", 0x20004EAE, DS3ItemCategory.RING), + DS3ItemData("Scholar Ring", 0x20004EB6, DS3ItemCategory.RING), + DS3ItemData("Priestess Ring", 0x20004EC0, DS3ItemCategory.RING), + DS3ItemData("Red Tearstone Ring", 0x20004ECA, DS3ItemCategory.RING), + DS3ItemData("Blue Tearstone Ring", 0x20004ED4, DS3ItemCategory.RING), + DS3ItemData("Wolf Ring", 0x20004EDE, DS3ItemCategory.RING, + inject = True), # Covenant reward + DS3ItemData("Wolf Ring+1", 0x20004EDF, DS3ItemCategory.RING), + DS3ItemData("Wolf Ring+2", 0x20004EE0, DS3ItemCategory.RING), + DS3ItemData("Leo Ring", 0x20004EE8, DS3ItemCategory.RING), + DS3ItemData("Ring of Sacrifice", 0x20004EF2, DS3ItemCategory.RING), + DS3ItemData("Young Dragon Ring", 0x20004F06, DS3ItemCategory.RING), + DS3ItemData("Bellowing Dragoncrest Ring", 0x20004F07, DS3ItemCategory.RING), + DS3ItemData("Great Swamp Ring", 0x20004F10, DS3ItemCategory.RING), + DS3ItemData("Witch's Ring", 0x20004F11, DS3ItemCategory.RING), + DS3ItemData("Morne's Ring", 0x20004F1A, DS3ItemCategory.RING), + DS3ItemData("Ring of the Sun's First Born", 0x20004F1B, DS3ItemCategory.RING), + DS3ItemData("Lingering Dragoncrest Ring", 0x20004F2E, DS3ItemCategory.RING), + DS3ItemData("Lingering Dragoncrest Ring+1", 0x20004F2F, DS3ItemCategory.RING), + DS3ItemData("Lingering Dragoncrest Ring+2", 0x20004F30, DS3ItemCategory.RING), + DS3ItemData("Sage Ring", 0x20004F38, DS3ItemCategory.RING), + DS3ItemData("Sage Ring+1", 0x20004F39, DS3ItemCategory.RING), + DS3ItemData("Sage Ring+2", 0x20004F3A, DS3ItemCategory.RING), + DS3ItemData("Slumbering Dragoncrest Ring", 0x20004F42, DS3ItemCategory.RING), + DS3ItemData("Dusk Crown Ring", 0x20004F4C, DS3ItemCategory.RING), + DS3ItemData("Saint's Ring", 0x20004F56, DS3ItemCategory.RING), + DS3ItemData("Deep Ring", 0x20004F60, DS3ItemCategory.RING), + DS3ItemData("Darkmoon Ring", 0x20004F6A, DS3ItemCategory.RING, + inject = True), # Covenant reward + DS3ItemData("Hawk Ring", 0x20004F92, DS3ItemCategory.RING), + DS3ItemData("Hornet Ring", 0x20004F9C, DS3ItemCategory.RING), + DS3ItemData("Covetous Gold Serpent Ring", 0x20004FA6, DS3ItemCategory.RING), + DS3ItemData("Covetous Gold Serpent Ring+1", 0x20004FA7, DS3ItemCategory.RING), + DS3ItemData("Covetous Gold Serpent Ring+2", 0x20004FA8, DS3ItemCategory.RING), + DS3ItemData("Covetous Silver Serpent Ring", 0x20004FB0, DS3ItemCategory.RING), + DS3ItemData("Covetous Silver Serpent Ring+1", 0x20004FB1, DS3ItemCategory.RING), + DS3ItemData("Covetous Silver Serpent Ring+2", 0x20004FB2, DS3ItemCategory.RING), + DS3ItemData("Sun Princess Ring", 0x20004FBA, DS3ItemCategory.RING), + DS3ItemData("Silvercat Ring", 0x20004FC4, DS3ItemCategory.RING), + DS3ItemData("Skull Ring", 0x20004FCE, DS3ItemCategory.RING), + DS3ItemData("Untrue White Ring", 0x20004FD8, DS3ItemCategory.RING), + DS3ItemData("Carthus Milkring", 0x20004FE2, DS3ItemCategory.RING), + DS3ItemData("Knight's Ring", 0x20004FEC, DS3ItemCategory.RING), + DS3ItemData("Hunter's Ring", 0x20004FF6, DS3ItemCategory.RING), + DS3ItemData("Knight Slayer's Ring", 0x20005000, DS3ItemCategory.RING), + DS3ItemData("Magic Clutch Ring", 0x2000500A, DS3ItemCategory.RING), + DS3ItemData("Lightning Clutch Ring", 0x20005014, DS3ItemCategory.RING), + DS3ItemData("Fire Clutch Ring", 0x2000501E, DS3ItemCategory.RING), + DS3ItemData("Dark Clutch Ring", 0x20005028, DS3ItemCategory.RING), + DS3ItemData("Flynn's Ring", 0x2000503C, DS3ItemCategory.RING), + DS3ItemData("Prisoner's Chain", 0x20005046, DS3ItemCategory.RING), + DS3ItemData("Untrue Dark Ring", 0x20005050, DS3ItemCategory.RING), + DS3ItemData("Obscuring Ring", 0x20005064, DS3ItemCategory.RING), + DS3ItemData("Ring of the Evil Eye", 0x2000506E, DS3ItemCategory.RING), + DS3ItemData("Ring of the Evil Eye+1", 0x2000506F, DS3ItemCategory.RING), + DS3ItemData("Ring of the Evil Eye+2", 0x20005070, DS3ItemCategory.RING), + DS3ItemData("Calamity Ring", 0x20005078, DS3ItemCategory.RING), + DS3ItemData("Farron Ring", 0x20005082, DS3ItemCategory.RING), + DS3ItemData("Aldrich's Ruby", 0x2000508C, DS3ItemCategory.RING), + DS3ItemData("Aldrich's Sapphire", 0x20005096, DS3ItemCategory.RING), + DS3ItemData("Lloyd's Sword Ring", 0x200050B4, DS3ItemCategory.RING), + DS3ItemData("Lloyd's Shield Ring", 0x200050BE, DS3ItemCategory.RING), + DS3ItemData("Estus Ring", 0x200050DC, DS3ItemCategory.RING), + DS3ItemData("Ashen Estus Ring", 0x200050E6, DS3ItemCategory.RING), + DS3ItemData("Horsehoof Ring", 0x200050F0, DS3ItemCategory.RING), + DS3ItemData("Carthus Bloodring", 0x200050FA, DS3ItemCategory.RING), + DS3ItemData("Reversal Ring", 0x20005104, DS3ItemCategory.RING), + DS3ItemData("Pontiff's Right Eye", 0x2000510E, DS3ItemCategory.RING), + DS3ItemData("Pontiff's Left Eye", 0x20005136, DS3ItemCategory.RING), + DS3ItemData("Dragonscale Ring", 0x2000515E, DS3ItemCategory.RING), # Items - ("Roster of Knights", 0x4000006C, DS3ItemCategory.SKIP), - ("Cracked Red Eye Orb", 0x4000006F, DS3ItemCategory.SKIP), - ("Divine Blessing", 0x400000F0, DS3ItemCategory.MISC), - ("Hidden Blessing", 0x400000F1, DS3ItemCategory.MISC), - ("Silver Pendant", 0x400000F2, DS3ItemCategory.SKIP), - ("Green Blossom", 0x40000104, DS3ItemCategory.MISC), - ("Budding Green Blossom", 0x40000106, DS3ItemCategory.MISC), - ("Bloodred Moss Clump", 0x4000010E, DS3ItemCategory.SKIP), - ("Purple Moss Clump", 0x4000010F, DS3ItemCategory.MISC), - ("Blooming Purple Moss Clump", 0x40000110, DS3ItemCategory.SKIP), - ("Purging Stone", 0x40000112, DS3ItemCategory.SKIP), - ("Rime-blue Moss Clump", 0x40000114, DS3ItemCategory.SKIP), - ("Repair Powder", 0x40000118, DS3ItemCategory.MISC), - ("Kukri", 0x40000122, DS3ItemCategory.SKIP), - ("Firebomb", 0x40000124, DS3ItemCategory.MISC), - ("Dung Pie", 0x40000125, DS3ItemCategory.SKIP), - ("Alluring Skull", 0x40000126, DS3ItemCategory.MISC), - ("Undead Hunter Charm", 0x40000128, DS3ItemCategory.MISC), - ("Black Firebomb", 0x40000129, DS3ItemCategory.MISC), - ("Rope Firebomb", 0x4000012B, DS3ItemCategory.MISC), - ("Lightning Urn", 0x4000012C, DS3ItemCategory.MISC), - ("Rope Black Firebomb", 0x4000012E, DS3ItemCategory.MISC), - ("Stalk Dung Pie", 0x4000012F, DS3ItemCategory.SKIP), - ("Duel Charm", 0x40000130, DS3ItemCategory.MISC), - ("Throwing Knife", 0x40000136, DS3ItemCategory.MISC), - ("Poison Throwing Knife", 0x40000137, DS3ItemCategory.MISC), - ("Charcoal Pine Resin", 0x4000014A, DS3ItemCategory.MISC), - ("Gold Pine Resin", 0x4000014B, DS3ItemCategory.MISC), - ("Human Pine Resin", 0x4000014E, DS3ItemCategory.MISC), - ("Carthus Rouge", 0x4000014F, DS3ItemCategory.MISC), - ("Pale Pine Resin", 0x40000150, DS3ItemCategory.MISC), - ("Charcoal Pine Bundle", 0x40000154, DS3ItemCategory.MISC), - ("Gold Pine Bundle", 0x40000155, DS3ItemCategory.MISC), - ("Rotten Pine Resin", 0x40000157, DS3ItemCategory.MISC), - ("Homeward Bone", 0x4000015E, DS3ItemCategory.MISC), - ("Coiled Sword Fragment", 0x4000015F, DS3ItemCategory.MISC), - ("Wolf's Blood Swordgrass", 0x4000016E, DS3ItemCategory.MISC), - ("Human Dregs", 0x4000016F, DS3ItemCategory.SKIP), - ("Forked Pale Tongue", 0x40000170, DS3ItemCategory.MISC), - ("Proof of a Concord Well Kept", 0x40000171, DS3ItemCategory.SKIP), - ("Prism Stone", 0x40000172, DS3ItemCategory.SKIP), - ("Binoculars", 0x40000173, DS3ItemCategory.MISC), - ("Proof of a Concord Kept", 0x40000174, DS3ItemCategory.SKIP), - ("Pale Tongue", 0x40000175, DS3ItemCategory.MISC), - ("Vertebra Shackle", 0x40000176, DS3ItemCategory.SKIP), - ("Sunlight Medal", 0x40000177, DS3ItemCategory.SKIP), - ("Dragon Head Stone", 0x40000179, DS3ItemCategory.MISC), - ("Dragon Torso Stone", 0x4000017A, DS3ItemCategory.MISC), - ("Rubbish", 0x4000017C, DS3ItemCategory.SKIP), - ("Dried Finger", 0x40000181, DS3ItemCategory.SKIP), - ("Twinkling Dragon Head Stone", 0x40000183, DS3ItemCategory.MISC), - ("Twinkling Dragon Torso Stone", 0x40000184, DS3ItemCategory.MISC), - ("Fire Keeper Soul", 0x40000186, DS3ItemCategory.MISC), - ("Fading Soul", 0x40000190, DS3ItemCategory.MISC), - ("Soul of a Deserted Corpse", 0x40000191, DS3ItemCategory.MISC), - ("Large Soul of a Deserted Corpse", 0x40000192, DS3ItemCategory.MISC), - ("Soul of an Unknown Traveler", 0x40000193, DS3ItemCategory.MISC), - ("Large Soul of an Unknown Traveler", 0x40000194, DS3ItemCategory.MISC), - ("Soul of a Nameless Soldier", 0x40000195, DS3ItemCategory.MISC), - ("Large Soul of a Nameless Soldier", 0x40000196, DS3ItemCategory.MISC), - ("Soul of a Weary Warrior", 0x40000197, DS3ItemCategory.MISC), - ("Large Soul of a Weary Warrior", 0x40000198, DS3ItemCategory.MISC), - ("Soul of a Crestfallen Knight", 0x40000199, DS3ItemCategory.MISC), - ("Large Soul of a Crestfallen Knight", 0x4000019A, DS3ItemCategory.MISC), - ("Soul of a Proud Paladin", 0x4000019B, DS3ItemCategory.MISC), - ("Large Soul of a Proud Paladin", 0x4000019C, DS3ItemCategory.MISC), - ("Soul of an Intrepid Hero", 0x4000019D, DS3ItemCategory.MISC), - ("Large Soul of an Intrepid Hero", 0x4000019E, DS3ItemCategory.MISC), - ("Soul of a Seasoned Warrior", 0x4000019F, DS3ItemCategory.MISC), - ("Large Soul of a Seasoned Warrior", 0x400001A0, DS3ItemCategory.MISC), - ("Soul of an Old Hand", 0x400001A1, DS3ItemCategory.MISC), - ("Soul of a Venerable Old Hand", 0x400001A2, DS3ItemCategory.MISC), - ("Soul of a Champion", 0x400001A3, DS3ItemCategory.MISC), - ("Soul of a Great Champion", 0x400001A4, DS3ItemCategory.MISC), - ("Seed of a Giant Tree", 0x400001B8, DS3ItemCategory.SKIP), - ("Young White Branch", 0x400001C6, DS3ItemCategory.SKIP), - ("Rusted Coin", 0x400001C7, DS3ItemCategory.MISC), - ("Siegbräu", 0x400001C8, DS3ItemCategory.SKIP), - ("Rusted Gold Coin", 0x400001C9, DS3ItemCategory.MISC), - ("Blue Bug Pellet", 0x400001CA, DS3ItemCategory.SKIP), - ("Red Bug Pellet", 0x400001CB, DS3ItemCategory.SKIP), - ("Yellow Bug Pellet", 0x400001CC, DS3ItemCategory.SKIP), - ("Black Bug Pellet", 0x400001CD, DS3ItemCategory.SKIP), - ("Young White Branch", 0x400001CF, DS3ItemCategory.SKIP), - ("Dark Sigil", 0x400001EA, DS3ItemCategory.SKIP), - ("Ember", 0x400001F4, DS3ItemCategory.MISC), - ("Soul of Champion Gundyr", 0x400002C8, DS3ItemCategory.BOSS), - ("Soul of the Dancer", 0x400002CA, DS3ItemCategory.BOSS), - ("Soul of a Crystal Sage", 0x400002CB, DS3ItemCategory.BOSS), - ("Soul of the Blood of the Wolf", 0x400002CD, DS3ItemCategory.BOSS), - ("Soul of Consumed Oceiros", 0x400002CE, DS3ItemCategory.BOSS), - ("Soul of Boreal Valley Vordt", 0x400002CF, DS3ItemCategory.BOSS), - ("Soul of the Old Demon King", 0x400002D0, DS3ItemCategory.BOSS), - ("Soul of Dragonslayer Armour", 0x400002D1, DS3ItemCategory.BOSS), - ("Soul of the Nameless King", 0x400002D2, DS3ItemCategory.BOSS), - ("Soul of Pontiff Sulyvahn", 0x400002D4, DS3ItemCategory.BOSS), - ("Soul of Aldrich", 0x400002D5, DS3ItemCategory.BOSS), - ("Soul of High Lord Wolnir", 0x400002D6, DS3ItemCategory.BOSS), - ("Soul of the Rotted Greatwood", 0x400002D7, DS3ItemCategory.BOSS), - ("Soul of Rosaria", 0x400002D8, DS3ItemCategory.MISC), - ("Soul of the Deacons of the Deep", 0x400002D9, DS3ItemCategory.BOSS), - ("Soul of the Twin Princes", 0x400002DB, DS3ItemCategory.BOSS), - ("Soul of Yhorm the Giant", 0x400002DC, DS3ItemCategory.BOSS), - ("Soul of the Lords", 0x400002DD, DS3ItemCategory.MISC), - ("Soul of a Demon", 0x400002E3, DS3ItemCategory.BOSS), - ("Soul of a Stray Demon", 0x400002E7, DS3ItemCategory.BOSS), - ("Titanite Shard", 0x400003E8, DS3ItemCategory.MISC), - ("Large Titanite Shard", 0x400003E9, DS3ItemCategory.MISC), - ("Titanite Chunk", 0x400003EA, DS3ItemCategory.MISC), - ("Titanite Slab", 0x400003EB, DS3ItemCategory.MISC), - ("Titanite Scale", 0x400003FC, DS3ItemCategory.MISC), - ("Twinkling Titanite", 0x40000406, DS3ItemCategory.MISC), - ("Heavy Gem", 0x4000044C, DS3ItemCategory.MISC), - ("Sharp Gem", 0x40000456, DS3ItemCategory.MISC), - ("Refined Gem", 0x40000460, DS3ItemCategory.MISC), - ("Crystal Gem", 0x4000046A, DS3ItemCategory.MISC), - ("Simple Gem", 0x40000474, DS3ItemCategory.MISC), - ("Fire Gem", 0x4000047E, DS3ItemCategory.MISC), - ("Chaos Gem", 0x40000488, DS3ItemCategory.MISC), - ("Lightning Gem", 0x40000492, DS3ItemCategory.MISC), - ("Deep Gem", 0x4000049C, DS3ItemCategory.MISC), - ("Dark Gem", 0x400004A6, DS3ItemCategory.MISC), - ("Poison Gem", 0x400004B0, DS3ItemCategory.MISC), - ("Blood Gem", 0x400004BA, DS3ItemCategory.MISC), - ("Raw Gem", 0x400004C4, DS3ItemCategory.MISC), - ("Blessed Gem", 0x400004CE, DS3ItemCategory.MISC), - ("Hollow Gem", 0x400004D8, DS3ItemCategory.MISC), - ("Shriving Stone", 0x400004E2, DS3ItemCategory.MISC), - ("Lift Chamber Key", 0x400007D1, DS3ItemCategory.KEY), - ("Small Doll", 0x400007D5, DS3ItemCategory.KEY), - ("Jailbreaker's Key", 0x400007D7, DS3ItemCategory.KEY), - ("Jailer's Key Ring", 0x400007D8, DS3ItemCategory.KEY), - ("Grave Key", 0x400007D9, DS3ItemCategory.KEY), - ("Cell Key", 0x400007DA, DS3ItemCategory.KEY), - ("Dungeon Ground Floor Key", 0x400007DB, DS3ItemCategory.KEY), - ("Old Cell Key", 0x400007DC, DS3ItemCategory.KEY), - ("Grand Archives Key", 0x400007DE, DS3ItemCategory.KEY), - ("Tower Key", 0x400007DF, DS3ItemCategory.KEY), - ("Small Lothric Banner", 0x40000836, DS3ItemCategory.KEY), - ("Farron Coal", 0x40000837, DS3ItemCategory.MISC), - ("Sage's Coal", 0x40000838, DS3ItemCategory.MISC), - ("Giant's Coal", 0x40000839, DS3ItemCategory.MISC), - ("Profaned Coal", 0x4000083A, DS3ItemCategory.MISC), - ("Mortician's Ashes", 0x4000083B, DS3ItemCategory.MISC), - ("Dreamchaser's Ashes", 0x4000083C, DS3ItemCategory.MISC), - ("Paladin's Ashes", 0x4000083D, DS3ItemCategory.MISC), - ("Grave Warden's Ashes", 0x4000083E, DS3ItemCategory.MISC), - ("Greirat's Ashes", 0x4000083F, DS3ItemCategory.MISC), - ("Orbeck's Ashes", 0x40000840, DS3ItemCategory.MISC), - ("Cornyx's Ashes", 0x40000841, DS3ItemCategory.MISC), - ("Karla's Ashes", 0x40000842, DS3ItemCategory.MISC), - ("Irina's Ashes", 0x40000843, DS3ItemCategory.MISC), - ("Yuria's Ashes", 0x40000844, DS3ItemCategory.MISC), - ("Basin of Vows", 0x40000845, DS3ItemCategory.KEY), - ("Loretta's Bone", 0x40000846, DS3ItemCategory.KEY), - ("Braille Divine Tome of Carim", 0x40000847, DS3ItemCategory.MISC), - ("Braille Divine Tome of Lothric", 0x40000848, DS3ItemCategory.MISC), - ("Cinders of a Lord - Abyss Watcher", 0x4000084B, DS3ItemCategory.KEY), - ("Cinders of a Lord - Aldrich", 0x4000084C, DS3ItemCategory.KEY), - ("Cinders of a Lord - Yhorm the Giant", 0x4000084D, DS3ItemCategory.KEY), - ("Cinders of a Lord - Lothric Prince", 0x4000084E, DS3ItemCategory.KEY), - ("Great Swamp Pyromancy Tome", 0x4000084F, DS3ItemCategory.MISC), - ("Carthus Pyromancy Tome", 0x40000850, DS3ItemCategory.MISC), - ("Izalith Pyromancy Tome", 0x40000851, DS3ItemCategory.MISC), - ("Quelana Pyromancy Tome", 0x40000852, DS3ItemCategory.MISC), - ("Grave Warden Pyromancy Tome", 0x40000853, DS3ItemCategory.MISC), - ("Sage's Scroll", 0x40000854, DS3ItemCategory.MISC), - ("Logan's Scroll", 0x40000855, DS3ItemCategory.MISC), - ("Crystal Scroll", 0x40000856, DS3ItemCategory.MISC), - ("Transposing Kiln", 0x40000857, DS3ItemCategory.MISC), - ("Coiled Sword", 0x40000859, DS3ItemCategory.SKIP), # Useless - ("Eyes of a Fire Keeper", 0x4000085A, DS3ItemCategory.KEY), - ("Sword of Avowal", 0x4000085B, DS3ItemCategory.KEY), - ("Golden Scroll", 0x4000085C, DS3ItemCategory.MISC), - ("Estus Shard", 0x4000085D, DS3ItemCategory.MISC), - ("Hawkwood's Swordgrass", 0x4000085E, DS3ItemCategory.SKIP), - ("Undead Bone Shard", 0x4000085F, DS3ItemCategory.MISC), - ("Deep Braille Divine Tome", 0x40000860, DS3ItemCategory.MISC), - ("Londor Braille Divine Tome", 0x40000861, DS3ItemCategory.MISC), - ("Excrement-covered Ashes", 0x40000862, DS3ItemCategory.MISC), - ("Prisoner Chief's Ashes", 0x40000863, DS3ItemCategory.MISC), - ("Xanthous Ashes", 0x40000864, DS3ItemCategory.MISC), - ("Hollow's Ashes", 0x40000865, DS3ItemCategory.MISC), - ("Patches' Ashes", 0x40000866, DS3ItemCategory.MISC), - ("Dragon Chaser's Ashes", 0x40000867, DS3ItemCategory.MISC), - ("Easterner's Ashes", 0x40000868, DS3ItemCategory.MISC), + DS3ItemData("White Sign Soapstone", 0x40000064, DS3ItemCategory.SKIP), + DS3ItemData("Red Sign Soapstone", 0x40000066, DS3ItemCategory.SKIP), + DS3ItemData("Red Eye Orb", 0x40000066, DS3ItemCategory.SKIP), + DS3ItemData("Roster of Knights", 0x4000006C, DS3ItemCategory.SKIP), + DS3ItemData("Cracked Red Eye Orb", 0x4000006F, DS3ItemCategory.SKIP), + DS3ItemData("Cracked Red Eye Orb x5", 0x4000006F, DS3ItemCategory.SKIP).counts([5]), + DS3ItemData("Black Eye Orb", 0x40000073, DS3ItemCategory.KEY), + DS3ItemData("Divine Blessing", 0x400000F0, DS3ItemCategory.MISC), + DS3ItemData("Hidden Blessing", 0x400000F1, DS3ItemCategory.MISC), + DS3ItemData("Green Blossom", 0x40000104, DS3ItemCategory.MISC), + DS3ItemData("Green Blossom x2", 0x40000104, DS3ItemCategory.MISC).counts([2]), + DS3ItemData("Green Blossom x3", 0x40000104, DS3ItemCategory.MISC).counts([3]), + DS3ItemData("Green Blossom x4", 0x40000104, DS3ItemCategory.MISC).counts([4]), + DS3ItemData("Budding Green Blossom", 0x40000106, DS3ItemCategory.MISC), + DS3ItemData("Budding Green Blossom x2", 0x40000106, DS3ItemCategory.MISC).counts([2]), + DS3ItemData("Budding Green Blossom x3", 0x40000106, DS3ItemCategory.MISC).counts([3]), + DS3ItemData("Bloodred Moss Clump", 0x4000010E, DS3ItemCategory.MISC), + DS3ItemData("Bloodred Moss Clump x3", 0x4000010E, DS3ItemCategory.MISC), + DS3ItemData("Purple Moss Clump", 0x4000010F, DS3ItemCategory.MISC).counts([2, 3, 4]), + DS3ItemData("Blooming Purple Moss Clump", 0x40000110, DS3ItemCategory.MISC).counts([3]), + DS3ItemData("Purging Stone", 0x40000112, DS3ItemCategory.SKIP).counts([2, 3]), + DS3ItemData("Rime-blue Moss Clump", 0x40000114, DS3ItemCategory.MISC).counts([2, 4]), + DS3ItemData("Repair Powder", 0x40000118, DS3ItemCategory.MISC).counts([2, 3, 4]), + DS3ItemData("Kukri", 0x40000122, DS3ItemCategory.MISC).counts([8, 9]), + DS3ItemData("Firebomb", 0x40000124, DS3ItemCategory.MISC).counts([2, 3, 5, 6]), + DS3ItemData("Dung Pie", 0x40000125, DS3ItemCategory.MISC).counts([2, 3, 4]), + DS3ItemData("Alluring Skull", 0x40000126, DS3ItemCategory.MISC).counts([2, 3]), + DS3ItemData("Undead Hunter Charm", 0x40000128, DS3ItemCategory.MISC).counts([2, 3]), + DS3ItemData("Black Firebomb", 0x40000129, DS3ItemCategory.MISC).counts([2, 3, 4]), + DS3ItemData("Rope Firebomb", 0x4000012B, DS3ItemCategory.MISC), + DS3ItemData("Lightning Urn", 0x4000012C, DS3ItemCategory.MISC).counts([3, 4, 6]), + DS3ItemData("Rope Black Firebomb", 0x4000012E, DS3ItemCategory.MISC), + DS3ItemData("Stalk Dung Pie", 0x4000012F, DS3ItemCategory.MISC).counts([6]), + DS3ItemData("Duel Charm", 0x40000130, DS3ItemCategory.MISC).counts([3]), + DS3ItemData("Throwing Knife", 0x40000136, DS3ItemCategory.MISC).counts([6, 8]), + DS3ItemData("Poison Throwing Knife", 0x40000137, DS3ItemCategory.MISC), + DS3ItemData("Charcoal Pine Resin", 0x4000014A, DS3ItemCategory.MISC).counts([2]), + DS3ItemData("Gold Pine Resin", 0x4000014B, DS3ItemCategory.MISC).counts([2]), + DS3ItemData("Human Pine Resin", 0x4000014E, DS3ItemCategory.MISC).counts([2, 4]), + DS3ItemData("Carthus Rouge", 0x4000014F, DS3ItemCategory.MISC).counts([2, 3]), + DS3ItemData("Pale Pine Resin", 0x40000150, DS3ItemCategory.MISC).counts([2]), + DS3ItemData("Charcoal Pine Bundle", 0x40000154, DS3ItemCategory.MISC).counts([2]), + DS3ItemData("Gold Pine Bundle", 0x40000155, DS3ItemCategory.MISC).counts([6]), + DS3ItemData("Rotten Pine Resin", 0x40000157, DS3ItemCategory.MISC).counts([2, 4]), + DS3ItemData("Homeward Bone", 0x4000015E, DS3ItemCategory.MISC).counts([2, 3, 6]), + DS3ItemData("Coiled Sword Fragment", 0x4000015F, DS3ItemCategory.MISC), + DS3ItemData("Wolf's Blood Swordgrass", 0x4000016E, DS3ItemCategory.SKIP), + DS3ItemData("Human Dregs", 0x4000016F, DS3ItemCategory.SKIP), + DS3ItemData("Forked Pale Tongue", 0x40000170, DS3ItemCategory.SKIP), + DS3ItemData("Proof of a Concord Well Kept", 0x40000171, DS3ItemCategory.SKIP), + DS3ItemData("Prism Stone", 0x40000172, DS3ItemCategory.SKIP).counts([4, 6, 10]), + DS3ItemData("Binoculars", 0x40000173, DS3ItemCategory.MISC), + DS3ItemData("Proof of a Concord Kept", 0x40000174, DS3ItemCategory.SKIP), + DS3ItemData("Pale Tongue", 0x40000175, DS3ItemCategory.SKIP, + inject = True), # Inject one of these for Leonhard's quest + DS3ItemData("Vertebra Shackle", 0x40000176, DS3ItemCategory.SKIP, + inject = True), # Inject one of these to trade to the crow + DS3ItemData("Sunlight Medal", 0x40000177, DS3ItemCategory.SKIP), + DS3ItemData("Dragon Head Stone", 0x40000179, DS3ItemCategory.MISC), + DS3ItemData("Dragon Torso Stone", 0x4000017A, DS3ItemCategory.MISC), + DS3ItemData("Rubbish", 0x4000017C, DS3ItemCategory.SKIP), + DS3ItemData("Dried Finger", 0x40000181, DS3ItemCategory.SKIP), + DS3ItemData("Twinkling Dragon Head Stone", 0x40000183, DS3ItemCategory.MISC), + DS3ItemData("Twinkling Dragon Torso Stone", 0x40000184, DS3ItemCategory.MISC), + DS3ItemData("Fire Keeper Soul", 0x40000186, DS3ItemCategory.MISC), + DS3ItemData("Fading Soul", 0x40000190, DS3ItemCategory.MISC), + DS3ItemData("Soul of a Deserted Corpse", 0x40000191, DS3ItemCategory.MISC), + DS3ItemData("Large Soul of a Deserted Corpse", 0x40000192, DS3ItemCategory.MISC), + DS3ItemData("Soul of an Unknown Traveler", 0x40000193, DS3ItemCategory.MISC), + DS3ItemData("Large Soul of an Unknown Traveler", 0x40000194, DS3ItemCategory.MISC), + DS3ItemData("Soul of a Nameless Soldier", 0x40000195, DS3ItemCategory.MISC), + DS3ItemData("Large Soul of a Nameless Soldier", 0x40000196, DS3ItemCategory.MISC), + DS3ItemData("Soul of a Weary Warrior", 0x40000197, DS3ItemCategory.MISC), + DS3ItemData("Large Soul of a Weary Warrior", 0x40000198, DS3ItemCategory.MISC), + DS3ItemData("Soul of a Crestfallen Knight", 0x40000199, DS3ItemCategory.MISC), + DS3ItemData("Large Soul of a Crestfallen Knight", 0x4000019A, DS3ItemCategory.MISC), + DS3ItemData("Soul of a Proud Paladin", 0x4000019B, DS3ItemCategory.MISC), + DS3ItemData("Large Soul of a Proud Paladin", 0x4000019C, DS3ItemCategory.MISC), + DS3ItemData("Soul of an Intrepid Hero", 0x4000019D, DS3ItemCategory.MISC), + DS3ItemData("Large Soul of an Intrepid Hero", 0x4000019E, DS3ItemCategory.MISC), + DS3ItemData("Soul of a Seasoned Warrior", 0x4000019F, DS3ItemCategory.MISC), + DS3ItemData("Large Soul of a Seasoned Warrior", 0x400001A0, DS3ItemCategory.MISC), + DS3ItemData("Soul of an Old Hand", 0x400001A1, DS3ItemCategory.MISC), + DS3ItemData("Soul of a Venerable Old Hand", 0x400001A2, DS3ItemCategory.MISC), + DS3ItemData("Soul of a Champion", 0x400001A3, DS3ItemCategory.MISC), + DS3ItemData("Soul of a Great Champion", 0x400001A4, DS3ItemCategory.MISC), + DS3ItemData("Seed of a Giant Tree", 0x400001B8, DS3ItemCategory.SKIP, + inject = True), + DS3ItemData("Mossfruit", 0x400001C4, DS3ItemCategory.SKIP).counts([2]), + DS3ItemData("Young White Branch", 0x400001C6, DS3ItemCategory.SKIP), + DS3ItemData("Rusted Coin", 0x400001C7, DS3ItemCategory.MISC).counts([2]), + DS3ItemData("Siegbräu", 0x400001C8, DS3ItemCategory.SKIP), + DS3ItemData("Rusted Gold Coin", 0x400001C9, DS3ItemCategory.MISC).counts([2, 3]), + DS3ItemData("Blue Bug Pellet", 0x400001CA, DS3ItemCategory.SKIP).counts([2]), + DS3ItemData("Red Bug Pellet", 0x400001CB, DS3ItemCategory.SKIP).counts([2, 3]), + DS3ItemData("Yellow Bug Pellet", 0x400001CC, DS3ItemCategory.SKIP).counts([2, 3]), + DS3ItemData("Black Bug Pellet", 0x400001CD, DS3ItemCategory.SKIP).counts([2, 3]), + DS3ItemData("Young White Branch", 0x400001CF, DS3ItemCategory.SKIP), + DS3ItemData("Dark Sigil", 0x400001EA, DS3ItemCategory.SKIP), + DS3ItemData("Ember", 0x400001F4, DS3ItemCategory.MISC).counts([2]), + DS3ItemData("Hello Carving", 0x40000208, DS3ItemCategory.SKIP), + DS3ItemData("Thank you Carving", 0x40000209, DS3ItemCategory.SKIP), + DS3ItemData("Very good! Carving", 0x4000020A, DS3ItemCategory.SKIP), + DS3ItemData("I'm sorry Carving", 0x4000020B, DS3ItemCategory.SKIP), + DS3ItemData("Help me! Carving", 0x4000020C, DS3ItemCategory.SKIP), + DS3ItemData("Soul of Champion Gundyr", 0x400002C8, DS3ItemCategory.BOSS), + DS3ItemData("Soul of the Dancer", 0x400002CA, DS3ItemCategory.BOSS), + DS3ItemData("Soul of a Crystal Sage", 0x400002CB, DS3ItemCategory.BOSS), + DS3ItemData("Soul of the Blood of the Wolf", 0x400002CD, DS3ItemCategory.BOSS), + DS3ItemData("Soul of Consumed Oceiros", 0x400002CE, DS3ItemCategory.BOSS), + DS3ItemData("Soul of Boreal Valley Vordt", 0x400002CF, DS3ItemCategory.BOSS), + DS3ItemData("Soul of the Old Demon King", 0x400002D0, DS3ItemCategory.BOSS), + DS3ItemData("Soul of Dragonslayer Armour", 0x400002D1, DS3ItemCategory.BOSS), + DS3ItemData("Soul of the Nameless King", 0x400002D2, DS3ItemCategory.BOSS), + DS3ItemData("Soul of Pontiff Sulyvahn", 0x400002D4, DS3ItemCategory.BOSS), + DS3ItemData("Soul of Aldrich", 0x400002D5, DS3ItemCategory.BOSS), + DS3ItemData("Soul of High Lord Wolnir", 0x400002D6, DS3ItemCategory.BOSS), + DS3ItemData("Soul of the Rotted Greatwood", 0x400002D7, DS3ItemCategory.BOSS), + DS3ItemData("Soul of Rosaria", 0x400002D8, DS3ItemCategory.MISC), + DS3ItemData("Soul of the Deacons of the Deep", 0x400002D9, DS3ItemCategory.BOSS), + DS3ItemData("Soul of the Twin Princes", 0x400002DB, DS3ItemCategory.BOSS), + DS3ItemData("Soul of Yhorm the Giant", 0x400002DC, DS3ItemCategory.BOSS), + DS3ItemData("Soul of the Lords", 0x400002DD, DS3ItemCategory.MISC), + DS3ItemData("Soul of a Demon", 0x400002E3, DS3ItemCategory.BOSS), + DS3ItemData("Soul of a Stray Demon", 0x400002E7, DS3ItemCategory.BOSS), + DS3ItemData("Titanite Shard", 0x400003E8, DS3ItemCategory.MISC).counts([2]), + DS3ItemData("Large Titanite Shard", 0x400003E9, DS3ItemCategory.MISC).counts([2, 3]), + DS3ItemData("Titanite Chunk", 0x400003EA, DS3ItemCategory.MISC).counts([2, 6]), + DS3ItemData("Titanite Slab", 0x400003EB, DS3ItemCategory.MISC), + DS3ItemData("Titanite Scale", 0x400003FC, DS3ItemCategory.MISC).counts([2, 3]), + DS3ItemData("Twinkling Titanite", 0x40000406, DS3ItemCategory.MISC).counts([2, 3]), + DS3ItemData("Heavy Gem", 0x4000044C, DS3ItemCategory.MISC), + DS3ItemData("Sharp Gem", 0x40000456, DS3ItemCategory.MISC), + DS3ItemData("Refined Gem", 0x40000460, DS3ItemCategory.MISC), + DS3ItemData("Crystal Gem", 0x4000046A, DS3ItemCategory.MISC), + DS3ItemData("Simple Gem", 0x40000474, DS3ItemCategory.MISC), + DS3ItemData("Fire Gem", 0x4000047E, DS3ItemCategory.MISC), + DS3ItemData("Chaos Gem", 0x40000488, DS3ItemCategory.MISC), + DS3ItemData("Lightning Gem", 0x40000492, DS3ItemCategory.MISC), + DS3ItemData("Deep Gem", 0x4000049C, DS3ItemCategory.MISC), + DS3ItemData("Dark Gem", 0x400004A6, DS3ItemCategory.MISC), + DS3ItemData("Poison Gem", 0x400004B0, DS3ItemCategory.MISC), + DS3ItemData("Blood Gem", 0x400004BA, DS3ItemCategory.MISC), + DS3ItemData("Raw Gem", 0x400004C4, DS3ItemCategory.MISC), + DS3ItemData("Blessed Gem", 0x400004CE, DS3ItemCategory.MISC), + DS3ItemData("Hollow Gem", 0x400004D8, DS3ItemCategory.MISC), + DS3ItemData("Shriving Stone", 0x400004E2, DS3ItemCategory.MISC), + DS3ItemData("Lift Chamber Key", 0x400007D1, DS3ItemCategory.KEY), + DS3ItemData("Small Doll", 0x400007D5, DS3ItemCategory.KEY), + DS3ItemData("Jailbreaker's Key", 0x400007D7, DS3ItemCategory.KEY), + DS3ItemData("Jailer's Key Ring", 0x400007D8, DS3ItemCategory.KEY), + DS3ItemData("Grave Key", 0x400007D9, DS3ItemCategory.KEY), + DS3ItemData("Cell Key", 0x400007DA, DS3ItemCategory.KEY), + DS3ItemData("Dungeon Ground Floor Key", 0x400007DB, DS3ItemCategory.KEY), + DS3ItemData("Old Cell Key", 0x400007DC, DS3ItemCategory.KEY), + DS3ItemData("Grand Archives Key", 0x400007DE, DS3ItemCategory.KEY), + DS3ItemData("Tower Key", 0x400007DF, DS3ItemCategory.KEY), + DS3ItemData("Small Lothric Banner", 0x40000836, DS3ItemCategory.KEY), + DS3ItemData("Farron Coal", 0x40000837, DS3ItemCategory.MISC), + DS3ItemData("Sage's Coal", 0x40000838, DS3ItemCategory.MISC), + DS3ItemData("Giant's Coal", 0x40000839, DS3ItemCategory.MISC), + DS3ItemData("Profaned Coal", 0x4000083A, DS3ItemCategory.MISC), + DS3ItemData("Mortician's Ashes", 0x4000083B, DS3ItemCategory.MISC), + DS3ItemData("Dreamchaser's Ashes", 0x4000083C, DS3ItemCategory.MISC), + DS3ItemData("Paladin's Ashes", 0x4000083D, DS3ItemCategory.MISC), + DS3ItemData("Grave Warden's Ashes", 0x4000083E, DS3ItemCategory.MISC), + DS3ItemData("Greirat's Ashes", 0x4000083F, DS3ItemCategory.MISC), + DS3ItemData("Orbeck's Ashes", 0x40000840, DS3ItemCategory.MISC), + DS3ItemData("Cornyx's Ashes", 0x40000841, DS3ItemCategory.MISC), + DS3ItemData("Karla's Ashes", 0x40000842, DS3ItemCategory.MISC), + DS3ItemData("Irina's Ashes", 0x40000843, DS3ItemCategory.MISC), + DS3ItemData("Yuria's Ashes", 0x40000844, DS3ItemCategory.MISC), + DS3ItemData("Basin of Vows", 0x40000845, DS3ItemCategory.KEY), + DS3ItemData("Loretta's Bone", 0x40000846, DS3ItemCategory.KEY), + DS3ItemData("Braille Divine Tome of Carim", 0x40000847, DS3ItemCategory.MISC), + DS3ItemData("Braille Divine Tome of Lothric", 0x40000848, DS3ItemCategory.MISC), + DS3ItemData("Cinders of a Lord - Abyss Watcher", 0x4000084B, DS3ItemCategory.KEY), + DS3ItemData("Cinders of a Lord - Aldrich", 0x4000084C, DS3ItemCategory.KEY), + DS3ItemData("Cinders of a Lord - Yhorm the Giant", 0x4000084D, DS3ItemCategory.KEY), + DS3ItemData("Cinders of a Lord - Lothric Prince", 0x4000084E, DS3ItemCategory.KEY), + DS3ItemData("Great Swamp Pyromancy Tome", 0x4000084F, DS3ItemCategory.MISC), + DS3ItemData("Carthus Pyromancy Tome", 0x40000850, DS3ItemCategory.MISC), + DS3ItemData("Izalith Pyromancy Tome", 0x40000851, DS3ItemCategory.MISC), + DS3ItemData("Quelana Pyromancy Tome", 0x40000852, DS3ItemCategory.MISC), + DS3ItemData("Grave Warden Pyromancy Tome", 0x40000853, DS3ItemCategory.MISC), + DS3ItemData("Sage's Scroll", 0x40000854, DS3ItemCategory.MISC), + DS3ItemData("Logan's Scroll", 0x40000855, DS3ItemCategory.MISC), + DS3ItemData("Crystal Scroll", 0x40000856, DS3ItemCategory.MISC), + DS3ItemData("Transposing Kiln", 0x40000857, DS3ItemCategory.MISC), + DS3ItemData("Coiled Sword", 0x40000859, DS3ItemCategory.SKIP), # Useless + DS3ItemData("Eyes of a Fire Keeper", 0x4000085A, DS3ItemCategory.KEY), + DS3ItemData("Sword of Avowal", 0x4000085B, DS3ItemCategory.KEY), + DS3ItemData("Golden Scroll", 0x4000085C, DS3ItemCategory.MISC), + DS3ItemData("Estus Shard", 0x4000085D, DS3ItemCategory.MISC), + DS3ItemData("Hawkwood's Swordgrass", 0x4000085E, DS3ItemCategory.SKIP), + DS3ItemData("Undead Bone Shard", 0x4000085F, DS3ItemCategory.MISC), + DS3ItemData("Deep Braille Divine Tome", 0x40000860, DS3ItemCategory.MISC), + DS3ItemData("Londor Braille Divine Tome", 0x40000861, DS3ItemCategory.MISC), + DS3ItemData("Excrement-covered Ashes", 0x40000862, DS3ItemCategory.MISC), + DS3ItemData("Prisoner Chief's Ashes", 0x40000863, DS3ItemCategory.MISC), + DS3ItemData("Xanthous Ashes", 0x40000864, DS3ItemCategory.MISC), + DS3ItemData("Hollow's Ashes", 0x40000865, DS3ItemCategory.MISC), + DS3ItemData("Patches' Ashes", 0x40000866, DS3ItemCategory.MISC), + DS3ItemData("Dragon Chaser's Ashes", 0x40000867, DS3ItemCategory.MISC), + DS3ItemData("Easterner's Ashes", 0x40000868, DS3ItemCategory.MISC), # Spells - ("Farron Dart", 0x40124F80, DS3ItemCategory.SPELL), - ("Great Farron Dart", 0x40127690, DS3ItemCategory.SPELL), - ("Soul Arrow", 0x4013D620, DS3ItemCategory.SPELL), - ("Great Soul Arrow", 0x4013DA08, DS3ItemCategory.SPELL), - ("Heavy Soul Arrow", 0x4013DDF0, DS3ItemCategory.SPELL), - ("Great Heavy Soul Arrow", 0x4013E1D8, DS3ItemCategory.SPELL), - ("Homing Soulmass", 0x4013E5C0, DS3ItemCategory.SPELL), - ("Homing Crystal Soulmass", 0x4013E9A8, DS3ItemCategory.SPELL), - ("Soul Spear", 0x4013ED90, DS3ItemCategory.SPELL), - ("Crystal Soul Spear", 0x4013F178, DS3ItemCategory.SPELL), - ("Deep Soul", 0x4013F560, DS3ItemCategory.SPELL), - ("Great Deep Soul", 0x4013F948, DS3ItemCategory.SPELL), - ("Magic Weapon", 0x4013FD30, DS3ItemCategory.SPELL), - ("Great Magic Weapon", 0x40140118, DS3ItemCategory.SPELL), - ("Crystal Magic Weapon", 0x40140500, DS3ItemCategory.SPELL), - ("Magic Shield", 0x40144B50, DS3ItemCategory.SPELL), - ("Great Magic Shield", 0x40144F38, DS3ItemCategory.SPELL), - ("Hidden Weapon", 0x40147260, DS3ItemCategory.SPELL), - ("Hidden Body", 0x40147648, DS3ItemCategory.SPELL), - ("Cast Light", 0x40149970, DS3ItemCategory.SPELL), - ("Repair", 0x4014A528, DS3ItemCategory.SPELL), - ("Spook", 0x4014A910, DS3ItemCategory.SPELL), - ("Chameleon", 0x4014ACF8, DS3ItemCategory.SPELL), - ("Aural Decoy", 0x4014B0E0, DS3ItemCategory.SPELL), - ("White Dragon Breath", 0x4014E790, DS3ItemCategory.SPELL), - ("Farron Hail", 0x4014EF60, DS3ItemCategory.SPELL), - ("Crystal Hail", 0x4014F348, DS3ItemCategory.SPELL), - ("Soul Greatsword", 0x4014F730, DS3ItemCategory.SPELL), - ("Farron Flashsword", 0x4014FB18, DS3ItemCategory.SPELL), - ("Affinity", 0x401875B8, DS3ItemCategory.SPELL), - ("Dark Edge", 0x40189CC8, DS3ItemCategory.SPELL), - ("Soul Stream", 0x4018B820, DS3ItemCategory.SPELL), - ("Twisted Wall of Light", 0x40193138, DS3ItemCategory.SPELL), - ("Pestilent Mist", 0x401A8CE0, DS3ItemCategory.SPELL), # Originally called "Pestilent Mercury" pre 1.15 - ("Fireball", 0x40249F00, DS3ItemCategory.SPELL), - ("Fire Orb", 0x4024A6D0, DS3ItemCategory.SPELL), - ("Firestorm", 0x4024AAB8, DS3ItemCategory.SPELL), - ("Fire Surge", 0x4024B288, DS3ItemCategory.SPELL), - ("Black Serpent", 0x4024BA58, DS3ItemCategory.SPELL), - ("Combustion", 0x4024C610, DS3ItemCategory.SPELL), - ("Great Combustion", 0x4024C9F8, DS3ItemCategory.SPELL), - ("Poison Mist", 0x4024ED20, DS3ItemCategory.SPELL), - ("Toxic Mist", 0x4024F108, DS3ItemCategory.SPELL), - ("Acid Surge", 0x4024F4F0, DS3ItemCategory.SPELL), - ("Iron Flesh", 0x40251430, DS3ItemCategory.SPELL), - ("Flash Sweat", 0x40251818, DS3ItemCategory.SPELL), - ("Carthus Flame Arc", 0x402527B8, DS3ItemCategory.SPELL), - ("Rapport", 0x40252BA0, DS3ItemCategory.SPELL), - ("Power Within", 0x40253B40, DS3ItemCategory.SPELL), - ("Great Chaos Fire Orb", 0x40256250, DS3ItemCategory.SPELL), - ("Chaos Storm", 0x40256638, DS3ItemCategory.SPELL), - ("Fire Whip", 0x40256A20, DS3ItemCategory.SPELL), - ("Black Flame", 0x40256E08, DS3ItemCategory.SPELL), - ("Profaned Flame", 0x402575D8, DS3ItemCategory.SPELL), - ("Chaos Bed Vestiges", 0x402579C0, DS3ItemCategory.SPELL), - ("Warmth", 0x4025B070, DS3ItemCategory.SPELL), - ("Profuse Sweat", 0x402717D0, DS3ItemCategory.SPELL), - ("Black Fire Orb", 0x4027D350, DS3ItemCategory.SPELL), - ("Bursting Fireball", 0x4027FA60, DS3ItemCategory.SPELL), - ("Boulder Heave", 0x40282170, DS3ItemCategory.SPELL), - ("Sacred Flame", 0x40284880, DS3ItemCategory.SPELL), - ("Carthus Beacon", 0x40286F90, DS3ItemCategory.SPELL), - ("Heal Aid", 0x403540D0, DS3ItemCategory.SPELL), - ("Heal", 0x403567E0, DS3ItemCategory.SPELL), - ("Med Heal", 0x40356BC8, DS3ItemCategory.SPELL), - ("Great Heal", 0x40356FB0, DS3ItemCategory.SPELL), - ("Soothing Sunlight", 0x40357398, DS3ItemCategory.SPELL), - ("Replenishment", 0x40357780, DS3ItemCategory.SPELL), - ("Bountiful Sunlight", 0x40357B68, DS3ItemCategory.SPELL), - ("Bountiful Light", 0x40358338, DS3ItemCategory.SPELL), - ("Caressing Tears", 0x40358720, DS3ItemCategory.SPELL), - ("Tears of Denial", 0x4035B600, DS3ItemCategory.SPELL), - ("Homeward", 0x4035B9E8, DS3ItemCategory.SPELL), - ("Force", 0x4035DD10, DS3ItemCategory.SPELL), - ("Wrath of the Gods", 0x4035E0F8, DS3ItemCategory.SPELL), - ("Emit Force", 0x4035E4E0, DS3ItemCategory.SPELL), - ("Seek Guidance", 0x40360420, DS3ItemCategory.SPELL), - ("Lightning Spear", 0x40362B30, DS3ItemCategory.SPELL), - ("Great Lightning Spear", 0x40362F18, DS3ItemCategory.SPELL), - ("Sunlight Spear", 0x40363300, DS3ItemCategory.SPELL), - ("Lightning Storm", 0x403636E8, DS3ItemCategory.SPELL), - ("Gnaw", 0x40363AD0, DS3ItemCategory.SPELL), - ("Dorhys' Gnawing", 0x40363EB8, DS3ItemCategory.SPELL), - ("Magic Barrier", 0x40365240, DS3ItemCategory.SPELL), - ("Great Magic Barrier", 0x40365628, DS3ItemCategory.SPELL), - ("Sacred Oath", 0x40365DF8, DS3ItemCategory.SPELL), - ("Vow of Silence", 0x4036A448, DS3ItemCategory.SPELL), - ("Lightning Blade", 0x4036C770, DS3ItemCategory.SPELL), - ("Darkmoon Blade", 0x4036CB58, DS3ItemCategory.SPELL), - ("Dark Blade", 0x40378AC0, DS3ItemCategory.SPELL), - ("Dead Again", 0x40387520, DS3ItemCategory.SPELL), - ("Lightning Stake", 0x40389C30, DS3ItemCategory.SPELL), - ("Divine Pillars of Light", 0x4038C340, DS3ItemCategory.SPELL), - ("Lifehunt Scythe", 0x4038EA50, DS3ItemCategory.SPELL), - ("Blessed Weapon", 0x40395F80, DS3ItemCategory.SPELL), - ("Deep Protection", 0x40398690, DS3ItemCategory.SPELL), - ("Atonement", 0x4039ADA0, DS3ItemCategory.SPELL), -]] + DS3ItemData("Farron Dart", 0x40124F80, DS3ItemCategory.SPELL), + DS3ItemData("Great Farron Dart", 0x40127690, DS3ItemCategory.SPELL), + DS3ItemData("Soul Arrow", 0x4013D620, DS3ItemCategory.SPELL), + DS3ItemData("Great Soul Arrow", 0x4013DA08, DS3ItemCategory.SPELL), + DS3ItemData("Heavy Soul Arrow", 0x4013DDF0, DS3ItemCategory.SPELL), + DS3ItemData("Great Heavy Soul Arrow", 0x4013E1D8, DS3ItemCategory.SPELL), + DS3ItemData("Homing Soulmass", 0x4013E5C0, DS3ItemCategory.SPELL), + DS3ItemData("Homing Crystal Soulmass", 0x4013E9A8, DS3ItemCategory.SPELL), + DS3ItemData("Soul Spear", 0x4013ED90, DS3ItemCategory.SPELL), + DS3ItemData("Crystal Soul Spear", 0x4013F178, DS3ItemCategory.SPELL), + DS3ItemData("Deep Soul", 0x4013F560, DS3ItemCategory.SPELL), + DS3ItemData("Great Deep Soul", 0x4013F948, DS3ItemCategory.SPELL, + inject = True), # Covenant reward + DS3ItemData("Magic Weapon", 0x4013FD30, DS3ItemCategory.SPELL), + DS3ItemData("Great Magic Weapon", 0x40140118, DS3ItemCategory.SPELL), + DS3ItemData("Crystal Magic Weapon", 0x40140500, DS3ItemCategory.SPELL), + DS3ItemData("Magic Shield", 0x40144B50, DS3ItemCategory.SPELL), + DS3ItemData("Great Magic Shield", 0x40144F38, DS3ItemCategory.SPELL), + DS3ItemData("Hidden Weapon", 0x40147260, DS3ItemCategory.SPELL), + DS3ItemData("Hidden Body", 0x40147648, DS3ItemCategory.SPELL), + DS3ItemData("Cast Light", 0x40149970, DS3ItemCategory.SPELL), + DS3ItemData("Repair", 0x4014A528, DS3ItemCategory.SPELL), + DS3ItemData("Spook", 0x4014A910, DS3ItemCategory.SPELL), + DS3ItemData("Chameleon", 0x4014ACF8, DS3ItemCategory.SPELL), + DS3ItemData("Aural Decoy", 0x4014B0E0, DS3ItemCategory.SPELL), + DS3ItemData("White Dragon Breath", 0x4014E790, DS3ItemCategory.SPELL), + DS3ItemData("Farron Hail", 0x4014EF60, DS3ItemCategory.SPELL), + DS3ItemData("Crystal Hail", 0x4014F348, DS3ItemCategory.SPELL), + DS3ItemData("Soul Greatsword", 0x4014F730, DS3ItemCategory.SPELL), + DS3ItemData("Farron Flashsword", 0x4014FB18, DS3ItemCategory.SPELL), + DS3ItemData("Affinity", 0x401875B8, DS3ItemCategory.SPELL), + DS3ItemData("Dark Edge", 0x40189CC8, DS3ItemCategory.SPELL), + DS3ItemData("Soul Stream", 0x4018B820, DS3ItemCategory.SPELL), + DS3ItemData("Twisted Wall of Light", 0x40193138, DS3ItemCategory.SPELL), + DS3ItemData("Pestilent Mist", 0x401A8CE0, DS3ItemCategory.SPELL), # Originally called "Pestilent Mercury" pre 1.15 + DS3ItemData("Fireball", 0x40249F00, DS3ItemCategory.SPELL), + DS3ItemData("Fire Orb", 0x4024A6D0, DS3ItemCategory.SPELL), + DS3ItemData("Firestorm", 0x4024AAB8, DS3ItemCategory.SPELL), + DS3ItemData("Fire Surge", 0x4024B288, DS3ItemCategory.SPELL), + DS3ItemData("Black Serpent", 0x4024BA58, DS3ItemCategory.SPELL), + DS3ItemData("Combustion", 0x4024C610, DS3ItemCategory.SPELL), + DS3ItemData("Great Combustion", 0x4024C9F8, DS3ItemCategory.SPELL), + DS3ItemData("Poison Mist", 0x4024ED20, DS3ItemCategory.SPELL), + DS3ItemData("Toxic Mist", 0x4024F108, DS3ItemCategory.SPELL), + DS3ItemData("Acid Surge", 0x4024F4F0, DS3ItemCategory.SPELL), + DS3ItemData("Iron Flesh", 0x40251430, DS3ItemCategory.SPELL), + DS3ItemData("Flash Sweat", 0x40251818, DS3ItemCategory.SPELL), + DS3ItemData("Carthus Flame Arc", 0x402527B8, DS3ItemCategory.SPELL), + DS3ItemData("Rapport", 0x40252BA0, DS3ItemCategory.SPELL), + DS3ItemData("Power Within", 0x40253B40, DS3ItemCategory.SPELL), + DS3ItemData("Great Chaos Fire Orb", 0x40256250, DS3ItemCategory.SPELL), + DS3ItemData("Chaos Storm", 0x40256638, DS3ItemCategory.SPELL), + DS3ItemData("Fire Whip", 0x40256A20, DS3ItemCategory.SPELL), + DS3ItemData("Black Flame", 0x40256E08, DS3ItemCategory.SPELL), + DS3ItemData("Profaned Flame", 0x402575D8, DS3ItemCategory.SPELL), + DS3ItemData("Chaos Bed Vestiges", 0x402579C0, DS3ItemCategory.SPELL), + DS3ItemData("Warmth", 0x4025B070, DS3ItemCategory.SPELL, + inject = True), # Covenant reward + DS3ItemData("Profuse Sweat", 0x402717D0, DS3ItemCategory.SPELL), + DS3ItemData("Black Fire Orb", 0x4027D350, DS3ItemCategory.SPELL), + DS3ItemData("Bursting Fireball", 0x4027FA60, DS3ItemCategory.SPELL), + DS3ItemData("Boulder Heave", 0x40282170, DS3ItemCategory.SPELL), + DS3ItemData("Sacred Flame", 0x40284880, DS3ItemCategory.SPELL), + DS3ItemData("Carthus Beacon", 0x40286F90, DS3ItemCategory.SPELL), + DS3ItemData("Heal Aid", 0x403540D0, DS3ItemCategory.SPELL), + DS3ItemData("Heal", 0x403567E0, DS3ItemCategory.SPELL), + DS3ItemData("Med Heal", 0x40356BC8, DS3ItemCategory.SPELL), + DS3ItemData("Great Heal", 0x40356FB0, DS3ItemCategory.SPELL), + DS3ItemData("Soothing Sunlight", 0x40357398, DS3ItemCategory.SPELL), + DS3ItemData("Replenishment", 0x40357780, DS3ItemCategory.SPELL), + DS3ItemData("Bountiful Sunlight", 0x40357B68, DS3ItemCategory.SPELL), + DS3ItemData("Bountiful Light", 0x40358338, DS3ItemCategory.SPELL), + DS3ItemData("Caressing Tears", 0x40358720, DS3ItemCategory.SPELL), + DS3ItemData("Tears of Denial", 0x4035B600, DS3ItemCategory.SPELL), + DS3ItemData("Homeward", 0x4035B9E8, DS3ItemCategory.SPELL), + DS3ItemData("Force", 0x4035DD10, DS3ItemCategory.SPELL), + DS3ItemData("Wrath of the Gods", 0x4035E0F8, DS3ItemCategory.SPELL), + DS3ItemData("Emit Force", 0x4035E4E0, DS3ItemCategory.SPELL), + DS3ItemData("Seek Guidance", 0x40360420, DS3ItemCategory.SPELL), + DS3ItemData("Lightning Spear", 0x40362B30, DS3ItemCategory.SPELL), + DS3ItemData("Great Lightning Spear", 0x40362F18, DS3ItemCategory.SPELL, + inject = True), # Covenant reward + DS3ItemData("Sunlight Spear", 0x40363300, DS3ItemCategory.SPELL), + DS3ItemData("Lightning Storm", 0x403636E8, DS3ItemCategory.SPELL), + DS3ItemData("Gnaw", 0x40363AD0, DS3ItemCategory.SPELL), + DS3ItemData("Dorhys' Gnawing", 0x40363EB8, DS3ItemCategory.SPELL), + DS3ItemData("Magic Barrier", 0x40365240, DS3ItemCategory.SPELL), + DS3ItemData("Great Magic Barrier", 0x40365628, DS3ItemCategory.SPELL), + DS3ItemData("Sacred Oath", 0x40365DF8, DS3ItemCategory.SPELL, + inject = True), # Covenant reward + DS3ItemData("Vow of Silence", 0x4036A448, DS3ItemCategory.SPELL), + DS3ItemData("Lightning Blade", 0x4036C770, DS3ItemCategory.SPELL), + DS3ItemData("Darkmoon Blade", 0x4036CB58, DS3ItemCategory.SPELL, + inject = True), # Covenant reward + DS3ItemData("Dark Blade", 0x40378AC0, DS3ItemCategory.SPELL), + DS3ItemData("Dead Again", 0x40387520, DS3ItemCategory.SPELL), + DS3ItemData("Lightning Stake", 0x40389C30, DS3ItemCategory.SPELL), + DS3ItemData("Divine Pillars of Light", 0x4038C340, DS3ItemCategory.SPELL), + DS3ItemData("Lifehunt Scythe", 0x4038EA50, DS3ItemCategory.SPELL), + DS3ItemData("Blessed Weapon", 0x40395F80, DS3ItemCategory.SPELL), + DS3ItemData("Deep Protection", 0x40398690, DS3ItemCategory.SPELL), + DS3ItemData("Atonement", 0x4039ADA0, DS3ItemCategory.SPELL), +]) -_dlc_items = [DS3ItemData(row[0], row[1], True, row[2]) for row in [ +_dlc_items = flatten([ # Ammunition - ("Millwood Greatarrow", 0x000623E0, DS3ItemCategory.SKIP), + DS3ItemData("Millwood Greatarrow", 0x000623E0, DS3ItemCategory.SKIP).counts([5]), # Weapons - ("Aquamarine Dagger", 0x00116520, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Murky Hand Scythe", 0x00118C30, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Onyx Blade", 0x00222E00, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Ringed Knight Straight Sword", 0x00225510, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Gael's Greatsword", 0x00227C20, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Follower Sabre", 0x003EDDC0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Demon's Scar", 0x003F04D0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Frayed Blade", 0x004D35A0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Herald Curved Greatsword", 0x006159E0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Millwood Battle Axe", 0x006D67D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Earth Seeker", 0x006D8EE0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Quakestone Hammer", 0x007ECCF0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Ledo's Great Hammer", 0x007EF400, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Follower Javelin", 0x008CD6B0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Ringed Knight Spear", 0x008CFDC0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Lothric War Banner", 0x008D24D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Crucifix of the Mad King", 0x008D4BE0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Splitleaf Greatsword", 0x009B2E90, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Friede's Great Scythe", 0x009B55A0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Crow Talons", 0x00A89C10, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Rose of Ariandel", 0x00B82C70, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Pyromancer's Parting Flame", 0x00CC9ED0, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Murky Longstaff", 0x00CCC5E0, DS3ItemCategory.WEAPON_UPGRADE_10), - ("Sacred Chime of Filianore", 0x00CCECF0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Preacher's Right Arm", 0x00CD1400, DS3ItemCategory.WEAPON_UPGRADE_5), - ("White Birch Bow", 0x00D77440, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Millwood Greatbow", 0x00D85EA0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Repeating Crossbow", 0x00D885B0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Giant Door Shield", 0x00F5F8C0, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Valorheart", 0x00F646E0, DS3ItemCategory.WEAPON_UPGRADE_5), - ("Crow Quills", 0x00F66DF0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), - ("Ringed Knight Paired Greatswords", 0x00F69500, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Aquamarine Dagger", 0x00116520, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Murky Hand Scythe", 0x00118C30, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Onyx Blade", 0x00222E00, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Ringed Knight Straight Sword", 0x00225510, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Gael's Greatsword", 0x00227C20, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Follower Sabre", 0x003EDDC0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Demon's Scar", 0x003F04D0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Frayed Blade", 0x004D35A0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Herald Curved Greatsword", 0x006159E0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Millwood Battle Axe", 0x006D67D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Earth Seeker", 0x006D8EE0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Quakestone Hammer", 0x007ECCF0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Ledo's Great Hammer", 0x007EF400, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Follower Javelin", 0x008CD6B0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Ringed Knight Spear", 0x008CFDC0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Lothric War Banner", 0x008D24D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Crucifix of the Mad King", 0x008D4BE0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Splitleaf Greatsword", 0x009B2E90, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Friede's Great Scythe", 0x009B55A0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Crow Talons", 0x00A89C10, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Rose of Ariandel", 0x00B82C70, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Pyromancer's Parting Flame", 0x00CC9ED0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Murky Longstaff", 0x00CCC5E0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Sacred Chime of Filianore", 0x00CCECF0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Preacher's Right Arm", 0x00CD1400, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("White Birch Bow", 0x00D77440, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Millwood Greatbow", 0x00D85EA0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Repeating Crossbow", 0x00D885B0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Giant Door Shield", 0x00F5F8C0, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Valorheart", 0x00F646E0, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Crow Quills", 0x00F66DF0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Ringed Knight Paired Greatswords", 0x00F69500, DS3ItemCategory.WEAPON_UPGRADE_5), # Shields - ("Follower Shield", 0x0135C0E0, DS3ItemCategory.SHIELD_INFUSIBLE), - ("Dragonhead Shield", 0x0135E7F0, DS3ItemCategory.SHIELD), - ("Ethereal Oak Shield", 0x01450320, DS3ItemCategory.SHIELD), - ("Dragonhead Greatshield", 0x01452A30, DS3ItemCategory.SHIELD), - ("Follower Torch", 0x015F1AD0, DS3ItemCategory.SHIELD), + DS3ItemData("Follower Shield", 0x0135C0E0, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Dragonhead Shield", 0x0135E7F0, DS3ItemCategory.SHIELD), + DS3ItemData("Ethereal Oak Shield", 0x01450320, DS3ItemCategory.SHIELD), + DS3ItemData("Dragonhead Greatshield", 0x01452A30, DS3ItemCategory.SHIELD), + DS3ItemData("Follower Torch", 0x015F1AD0, DS3ItemCategory.SHIELD), # Armor - ("Vilhelm's Helm", 0x11312D00, DS3ItemCategory.ARMOR), - ("Vilhelm's Armor", 0x113130E8, DS3ItemCategory.ARMOR), - ("Vilhelm's Gauntlets", 0x113134D0, DS3ItemCategory.ARMOR), - ("Vilhelm's Leggings", 0x113138B8, DS3ItemCategory.ARMOR), - ("Antiquated Plain Garb", 0x11B2E408, DS3ItemCategory.ARMOR), - ("Violet Wrappings", 0x11B2E7F0, DS3ItemCategory.ARMOR), - ("Loincloth 2", 0x11B2EBD8, DS3ItemCategory.ARMOR), - ("Shira's Crown", 0x11C22260, DS3ItemCategory.ARMOR), - ("Shira's Armor", 0x11C22648, DS3ItemCategory.ARMOR), - ("Shira's Gloves", 0x11C22A30, DS3ItemCategory.ARMOR), - ("Shira's Trousers", 0x11C22E18, DS3ItemCategory.ARMOR), - ("Lapp's Helm", 0x11E84800, DS3ItemCategory.ARMOR), - ("Lapp's Armor", 0x11E84BE8, DS3ItemCategory.ARMOR), - ("Lapp's Gauntlets", 0x11E84FD0, DS3ItemCategory.ARMOR), - ("Lapp's Leggings", 0x11E853B8, DS3ItemCategory.ARMOR), - ("Slave Knight Hood", 0x134EDCE0, DS3ItemCategory.ARMOR), - ("Slave Knight Armor", 0x134EE0C8, DS3ItemCategory.ARMOR), - ("Slave Knight Gauntlets", 0x134EE4B0, DS3ItemCategory.ARMOR), - ("Slave Knight Leggings", 0x134EE898, DS3ItemCategory.ARMOR), - ("Ordained Hood", 0x135E1F20, DS3ItemCategory.ARMOR), - ("Ordained Dress", 0x135E2308, DS3ItemCategory.ARMOR), - ("Ordained Trousers", 0x135E2AD8, DS3ItemCategory.ARMOR), - ("Follower Helm", 0x137CA3A0, DS3ItemCategory.ARMOR), - ("Follower Armor", 0x137CA788, DS3ItemCategory.ARMOR), - ("Follower Gloves", 0x137CAB70, DS3ItemCategory.ARMOR), - ("Follower Boots", 0x137CAF58, DS3ItemCategory.ARMOR), - ("Millwood Knight Helm", 0x139B2820, DS3ItemCategory.ARMOR), - ("Millwood Knight Armor", 0x139B2C08, DS3ItemCategory.ARMOR), - ("Millwood Knight Gauntlets", 0x139B2FF0, DS3ItemCategory.ARMOR), - ("Millwood Knight Leggings", 0x139B33D8, DS3ItemCategory.ARMOR), - ("Ringed Knight Hood", 0x13C8EEE0, DS3ItemCategory.ARMOR), - ("Ringed Knight Armor", 0x13C8F2C8, DS3ItemCategory.ARMOR), - ("Ringed Knight Gauntlets", 0x13C8F6B0, DS3ItemCategory.ARMOR), - ("Ringed Knight Leggings", 0x13C8FA98, DS3ItemCategory.ARMOR), - ("Harald Legion Armor", 0x13D83508, DS3ItemCategory.ARMOR), - ("Harald Legion Gauntlets", 0x13D838F0, DS3ItemCategory.ARMOR), - ("Harald Legion Leggings", 0x13D83CD8, DS3ItemCategory.ARMOR), - ("Iron Dragonslayer Helm", 0x1405F7E0, DS3ItemCategory.ARMOR), - ("Iron Dragonslayer Armor", 0x1405FBC8, DS3ItemCategory.ARMOR), - ("Iron Dragonslayer Gauntlets", 0x1405FFB0, DS3ItemCategory.ARMOR), - ("Iron Dragonslayer Leggings", 0x14060398, DS3ItemCategory.ARMOR), - ("White Preacher Head", 0x14153A20, DS3ItemCategory.ARMOR), - ("Ruin Sentinel Helm", 0x14CC5520, DS3ItemCategory.ARMOR), - ("Ruin Sentinel Armor", 0x14CC5908, DS3ItemCategory.ARMOR), - ("Ruin Sentinel Gauntlets", 0x14CC5CF0, DS3ItemCategory.ARMOR), - ("Ruin Sentinel Leggings", 0x14CC60D8, DS3ItemCategory.ARMOR), - ("Desert Pyromancer Hood", 0x14DB9760, DS3ItemCategory.ARMOR), - ("Desert Pyromancer Garb", 0x14DB9B48, DS3ItemCategory.ARMOR), - ("Desert Pyromancer Gloves", 0x14DB9F30, DS3ItemCategory.ARMOR), - ("Desert Pyromancer Skirt", 0x14DBA318, DS3ItemCategory.ARMOR), - ("Black Witch Hat", 0x14EAD9A0, DS3ItemCategory.ARMOR), - ("Black Witch Garb", 0x14EADD88, DS3ItemCategory.ARMOR), - ("Black Witch Wrappings", 0x14EAE170, DS3ItemCategory.ARMOR), - ("Black Witch Trousers", 0x14EAE558, DS3ItemCategory.ARMOR), - ("Black Witch Veil", 0x14FA1BE0, DS3ItemCategory.ARMOR), - ("Blindfold Mask", 0x15095E20, DS3ItemCategory.ARMOR), + DS3ItemData("Vilhelm's Helm", 0x11312D00, DS3ItemCategory.ARMOR), + DS3ItemData("Vilhelm's Armor", 0x113130E8, DS3ItemCategory.ARMOR), + DS3ItemData("Vilhelm's Gauntlets", 0x113134D0, DS3ItemCategory.ARMOR), + DS3ItemData("Vilhelm's Leggings", 0x113138B8, DS3ItemCategory.ARMOR), + DS3ItemData("Antiquated Plain Garb", 0x11B2E408, DS3ItemCategory.ARMOR), + DS3ItemData("Violet Wrappings", 0x11B2E7F0, DS3ItemCategory.ARMOR), + DS3ItemData("Loincloth 2", 0x11B2EBD8, DS3ItemCategory.ARMOR), + DS3ItemData("Shira's Crown", 0x11C22260, DS3ItemCategory.ARMOR), + DS3ItemData("Shira's Armor", 0x11C22648, DS3ItemCategory.ARMOR), + DS3ItemData("Shira's Gloves", 0x11C22A30, DS3ItemCategory.ARMOR), + DS3ItemData("Shira's Trousers", 0x11C22E18, DS3ItemCategory.ARMOR), + DS3ItemData("Lapp's Helm", 0x11E84800, DS3ItemCategory.ARMOR), + DS3ItemData("Lapp's Armor", 0x11E84BE8, DS3ItemCategory.ARMOR), + DS3ItemData("Lapp's Gauntlets", 0x11E84FD0, DS3ItemCategory.ARMOR), + DS3ItemData("Lapp's Leggings", 0x11E853B8, DS3ItemCategory.ARMOR), + DS3ItemData("Slave Knight Hood", 0x134EDCE0, DS3ItemCategory.ARMOR), + DS3ItemData("Slave Knight Armor", 0x134EE0C8, DS3ItemCategory.ARMOR), + DS3ItemData("Slave Knight Gauntlets", 0x134EE4B0, DS3ItemCategory.ARMOR), + DS3ItemData("Slave Knight Leggings", 0x134EE898, DS3ItemCategory.ARMOR), + DS3ItemData("Ordained Hood", 0x135E1F20, DS3ItemCategory.ARMOR), + DS3ItemData("Ordained Dress", 0x135E2308, DS3ItemCategory.ARMOR), + DS3ItemData("Ordained Trousers", 0x135E2AD8, DS3ItemCategory.ARMOR), + DS3ItemData("Follower Helm", 0x137CA3A0, DS3ItemCategory.ARMOR), + DS3ItemData("Follower Armor", 0x137CA788, DS3ItemCategory.ARMOR), + DS3ItemData("Follower Gloves", 0x137CAB70, DS3ItemCategory.ARMOR), + DS3ItemData("Follower Boots", 0x137CAF58, DS3ItemCategory.ARMOR), + DS3ItemData("Millwood Knight Helm", 0x139B2820, DS3ItemCategory.ARMOR), + DS3ItemData("Millwood Knight Armor", 0x139B2C08, DS3ItemCategory.ARMOR), + DS3ItemData("Millwood Knight Gauntlets", 0x139B2FF0, DS3ItemCategory.ARMOR), + DS3ItemData("Millwood Knight Leggings", 0x139B33D8, DS3ItemCategory.ARMOR), + DS3ItemData("Ringed Knight Hood", 0x13C8EEE0, DS3ItemCategory.ARMOR), + DS3ItemData("Ringed Knight Armor", 0x13C8F2C8, DS3ItemCategory.ARMOR), + DS3ItemData("Ringed Knight Gauntlets", 0x13C8F6B0, DS3ItemCategory.ARMOR), + DS3ItemData("Ringed Knight Leggings", 0x13C8FA98, DS3ItemCategory.ARMOR), + DS3ItemData("Harald Legion Armor", 0x13D83508, DS3ItemCategory.ARMOR), + DS3ItemData("Harald Legion Gauntlets", 0x13D838F0, DS3ItemCategory.ARMOR), + DS3ItemData("Harald Legion Leggings", 0x13D83CD8, DS3ItemCategory.ARMOR), + DS3ItemData("Iron Dragonslayer Helm", 0x1405F7E0, DS3ItemCategory.ARMOR), + DS3ItemData("Iron Dragonslayer Armor", 0x1405FBC8, DS3ItemCategory.ARMOR), + DS3ItemData("Iron Dragonslayer Gauntlets", 0x1405FFB0, DS3ItemCategory.ARMOR), + DS3ItemData("Iron Dragonslayer Leggings", 0x14060398, DS3ItemCategory.ARMOR), + DS3ItemData("White Preacher Head", 0x14153A20, DS3ItemCategory.ARMOR), + DS3ItemData("Ruin Helm", 0x14CC5520, DS3ItemCategory.ARMOR), + DS3ItemData("Ruin Armor", 0x14CC5908, DS3ItemCategory.ARMOR), + DS3ItemData("Ruin Gauntlets", 0x14CC5CF0, DS3ItemCategory.ARMOR), + DS3ItemData("Ruin Leggings", 0x14CC60D8, DS3ItemCategory.ARMOR), + DS3ItemData("Desert Pyromancer Hood", 0x14DB9760, DS3ItemCategory.ARMOR), + DS3ItemData("Desert Pyromancer Garb", 0x14DB9B48, DS3ItemCategory.ARMOR), + DS3ItemData("Desert Pyromancer Gloves", 0x14DB9F30, DS3ItemCategory.ARMOR), + DS3ItemData("Desert Pyromancer Skirt", 0x14DBA318, DS3ItemCategory.ARMOR), + DS3ItemData("Black Witch Hat", 0x14EAD9A0, DS3ItemCategory.ARMOR), + DS3ItemData("Black Witch Garb", 0x14EADD88, DS3ItemCategory.ARMOR), + DS3ItemData("Black Witch Wrappings", 0x14EAE170, DS3ItemCategory.ARMOR), + DS3ItemData("Black Witch Trousers", 0x14EAE558, DS3ItemCategory.ARMOR), + DS3ItemData("Black Witch Veil", 0x14FA1BE0, DS3ItemCategory.ARMOR), + DS3ItemData("Blindfold Mask", 0x15095E20, DS3ItemCategory.ARMOR), # Covenants - ("Spear of the Church", 0x2000276A, DS3ItemCategory.SKIP), + DS3ItemData("Spear of the Church", 0x2000276A, DS3ItemCategory.SKIP), # Rings - ("Chloranthy Ring+3", 0x20004E2D, DS3ItemCategory.RING), - ("Havel's Ring+3", 0x20004E37, DS3ItemCategory.RING), - ("Ring of Favor+3", 0x20004E41, DS3ItemCategory.RING), - ("Ring of Steel Protection+3", 0x20004E4B, DS3ItemCategory.RING), - ("Wolf Ring+3", 0x20004EE1, DS3ItemCategory.RING), - ("Covetous Gold Serpent Ring+3", 0x20004FA9, DS3ItemCategory.RING), - ("Covetous Silver Serpent Ring+3", 0x20004FB3, DS3ItemCategory.RING), - ("Ring of the Evil Eye+3", 0x20005071, DS3ItemCategory.RING), - ("Chillbite Ring", 0x20005208, DS3ItemCategory.RING), + DS3ItemData("Chloranthy Ring+3", 0x20004E2D, DS3ItemCategory.RING), + DS3ItemData("Havel's Ring+3", 0x20004E37, DS3ItemCategory.RING), + DS3ItemData("Ring of Favor+3", 0x20004E41, DS3ItemCategory.RING), + DS3ItemData("Ring of Steel Protection+3", 0x20004E4B, DS3ItemCategory.RING), + DS3ItemData("Wolf Ring+3", 0x20004EE1, DS3ItemCategory.RING), + DS3ItemData("Covetous Gold Serpent Ring+3", 0x20004FA9, DS3ItemCategory.RING), + DS3ItemData("Covetous Silver Serpent Ring+3", 0x20004FB3, DS3ItemCategory.RING), + DS3ItemData("Ring of the Evil Eye+3", 0x20005071, DS3ItemCategory.RING), + DS3ItemData("Chillbite Ring", 0x20005208, DS3ItemCategory.RING), # Items - ("Church Guardian Shiv", 0x4000013B, DS3ItemCategory.MISC), - ("Filianore's Spear Ornament", 0x4000017B, DS3ItemCategory.SKIP), - ("Ritual Spear Fragment", 0x4000028A, DS3ItemCategory.MISC), - ("Divine Spear Fragment", 0x4000028B, DS3ItemCategory.SKIP), - ("Soul of Sister Friede", 0x400002E8, DS3ItemCategory.BOSS), - ("Soul of Slave Knight Gael", 0x400002E9, DS3ItemCategory.BOSS), - ("Soul of the Demon Prince", 0x400002EA, DS3ItemCategory.BOSS), - ("Soul of Darkeater Midir", 0x400002EB, DS3ItemCategory.BOSS), - ("Champion's Bones", 0x40000869, DS3ItemCategory.SKIP), - ("Captain's Ashes", 0x4000086A, DS3ItemCategory.MISC), - ("Contraption Key", 0x4000086B, DS3ItemCategory.KEY), - ("Small Envoy Banner", 0x4000086C, DS3ItemCategory.KEY), - ("Old Woman's Ashes", 0x4000086D, DS3ItemCategory.SKIP), - ("Blood of the Dark Soul", 0x4000086E, DS3ItemCategory.SKIP), + DS3ItemData("Church Guardian Shiv", 0x4000013B, DS3ItemCategory.MISC), + DS3ItemData("Filianore's Spear Ornament", 0x4000017B, DS3ItemCategory.SKIP), + DS3ItemData("Ritual Spear Fragment", 0x4000028A, DS3ItemCategory.SKIP), + DS3ItemData("Divine Spear Fragment", 0x4000028B, DS3ItemCategory.SKIP), + DS3ItemData("Soul of Sister Friede", 0x400002E8, DS3ItemCategory.BOSS), + DS3ItemData("Soul of Slave Knight Gael", 0x400002E9, DS3ItemCategory.BOSS), + DS3ItemData("Soul of the Demon Prince", 0x400002EA, DS3ItemCategory.BOSS), + DS3ItemData("Soul of Darkeater Midir", 0x400002EB, DS3ItemCategory.BOSS), + DS3ItemData("Champion's Bones", 0x40000869, DS3ItemCategory.SKIP), + DS3ItemData("Captain's Ashes", 0x4000086A, DS3ItemCategory.MISC), + DS3ItemData("Contraption Key", 0x4000086B, DS3ItemCategory.KEY), + DS3ItemData("Small Envoy Banner", 0x4000086C, DS3ItemCategory.KEY), + DS3ItemData("Old Woman's Ashes", 0x4000086D, DS3ItemCategory.SKIP), + DS3ItemData("Blood of the Dark Soul", 0x4000086E, DS3ItemCategory.SKIP), # Spells - ("Frozen Weapon", 0x401408E8, DS3ItemCategory.SPELL), - ("Old Moonlight", 0x4014FF00, DS3ItemCategory.SPELL), - ("Great Soul Dregs", 0x401879A0, DS3ItemCategory.SPELL), - ("Snap Freeze", 0x401A90C8, DS3ItemCategory.SPELL), - ("Floating Chaos", 0x40257DA8, DS3ItemCategory.SPELL), - ("Flame Fan", 0x40258190, DS3ItemCategory.SPELL), - ("Seething Chaos", 0x402896A0, DS3ItemCategory.SPELL), - ("Lightning Arrow", 0x40358B08, DS3ItemCategory.SPELL), - ("Way of White Corona", 0x403642A0, DS3ItemCategory.SPELL), - ("Projected Heal", 0x40364688, DS3ItemCategory.SPELL), -]] + DS3ItemData("Frozen Weapon", 0x401408E8, DS3ItemCategory.SPELL), + DS3ItemData("Old Moonlight", 0x4014FF00, DS3ItemCategory.SPELL), + DS3ItemData("Great Soul Dregs", 0x401879A0, DS3ItemCategory.SPELL), + DS3ItemData("Snap Freeze", 0x401A90C8, DS3ItemCategory.SPELL), + DS3ItemData("Floating Chaos", 0x40257DA8, DS3ItemCategory.SPELL), + DS3ItemData("Flame Fan", 0x40258190, DS3ItemCategory.SPELL), + DS3ItemData("Seething Chaos", 0x402896A0, DS3ItemCategory.SPELL), + DS3ItemData("Lightning Arrow", 0x40358B08, DS3ItemCategory.SPELL), + DS3ItemData("Way of White Corona", 0x403642A0, DS3ItemCategory.SPELL), + DS3ItemData("Projected Heal", 0x40364688, DS3ItemCategory.SPELL), +]) +for item in _dlc_items: + item.is_dlc = True # Unused list for future reference # These items exist to some degree in the code, but aren't accessible # in-game and can't be picked up without modifications -_cut_content_items = [DS3ItemData(row[0], row[1], False, row[2]) for row in [ +_cut_content_items = [ # Weapons - ("Blood-stained Short Sword", 0x00100590, DS3ItemCategory.SKIP), - ("Missionary's Axe", 0x006C2F50, DS3ItemCategory.SKIP), - ("Dragon King Greataxe", 0x006D40C0, DS3ItemCategory.SKIP), - ("Four Knights Hammer", 0x007D4650, DS3ItemCategory.SKIP), - ("Hammer of the Great Tree", 0x007D9470, DS3ItemCategory.SKIP), - ("Lothric's Scythe", 0x009A4430, DS3ItemCategory.SKIP), - ("Ancient Dragon Halberd", 0x009A6B40, DS3ItemCategory.SKIP), - ("Scythe of Want", 0x009A9250, DS3ItemCategory.SKIP), - ("Sacred Beast Catalyst", 0x00C8A730, DS3ItemCategory.SKIP), - ("Deep Pyromancy Flame", 0x00CC9ED0, DS3ItemCategory.SKIP), # Duplicate? - ("Flickering Pyromancy Flame", 0x00CD3B10, DS3ItemCategory.SKIP), - ("Strong Pyromancy Flame", 0x00CD6220, DS3ItemCategory.SKIP), - ("Deep Pyromancy Flame", 0x00CDFE60, DS3ItemCategory.SKIP), # Duplicate? - ("Pitch-Dark Pyromancy Flame", 0x00CE2570, DS3ItemCategory.SKIP), - ("Dancer's Short Bow", 0x00D77440, DS3ItemCategory.SKIP), - ("Shield Crossbow", 0x00D81080, DS3ItemCategory.SKIP), - ("Golden Dual Swords", 0x00F55C80, DS3ItemCategory.SKIP), - ("Channeler's Trident", 0x008C8890, DS3ItemCategory.SKIP), + DS3ItemData("Blood-stained Short Sword", 0x00100590, DS3ItemCategory.SKIP), + DS3ItemData("Missionary's Axe", 0x006C2F50, DS3ItemCategory.SKIP), + DS3ItemData("Dragon King Greataxe", 0x006D40C0, DS3ItemCategory.SKIP), + DS3ItemData("Four Knights Hammer", 0x007D4650, DS3ItemCategory.SKIP), + DS3ItemData("Hammer of the Great Tree", 0x007D9470, DS3ItemCategory.SKIP), + DS3ItemData("Lothric's Scythe", 0x009A4430, DS3ItemCategory.SKIP), + DS3ItemData("Ancient Dragon Halberd", 0x009A6B40, DS3ItemCategory.SKIP), + DS3ItemData("Scythe of Want", 0x009A9250, DS3ItemCategory.SKIP), + DS3ItemData("Sacred Beast Catalyst", 0x00C8A730, DS3ItemCategory.SKIP), + DS3ItemData("Deep Pyromancy Flame", 0x00CC9ED0, DS3ItemCategory.SKIP), # Duplicate? + DS3ItemData("Flickering Pyromancy Flame", 0x00CD3B10, DS3ItemCategory.SKIP), + DS3ItemData("Strong Pyromancy Flame", 0x00CD6220, DS3ItemCategory.SKIP), + DS3ItemData("Deep Pyromancy Flame", 0x00CDFE60, DS3ItemCategory.SKIP), # Duplicate? + DS3ItemData("Pitch-Dark Pyromancy Flame", 0x00CE2570, DS3ItemCategory.SKIP), + DS3ItemData("Dancer's Short Bow", 0x00D77440, DS3ItemCategory.SKIP), + DS3ItemData("Shield Crossbow", 0x00D81080, DS3ItemCategory.SKIP), + DS3ItemData("Golden Dual Swords", 0x00F55C80, DS3ItemCategory.SKIP), + DS3ItemData("Channeler's Trident", 0x008C8890, DS3ItemCategory.SKIP), # Shields - ("Cleric's Parma", 0x013524A0, DS3ItemCategory.SKIP), - ("Prince's Shield", 0x01421CF0, DS3ItemCategory.SKIP), + DS3ItemData("Cleric's Parma", 0x013524A0, DS3ItemCategory.SKIP), + DS3ItemData("Prince's Shield", 0x01421CF0, DS3ItemCategory.SKIP), # Armor - ("Dingy Maiden's Overcoat", 0x11DA9048, DS3ItemCategory.SKIP), - ("Grotto Hat", 0x11F78A40, DS3ItemCategory.SKIP), - ("Grotto Robe", 0x11F78E28, DS3ItemCategory.SKIP), - ("Grotto Wrap", 0x11F79210, DS3ItemCategory.SKIP), - ("Grotto Trousers", 0x11F795F8, DS3ItemCategory.SKIP), - ("Soldier's Gauntlets", 0x126261D0, DS3ItemCategory.SKIP), - ("Soldier's Hood", 0x1263E0A0, DS3ItemCategory.SKIP), - ("Elder's Robe", 0x129024A8, DS3ItemCategory.SKIP), - ("Saint's Veil", 0x12A70420, DS3ItemCategory.SKIP), - ("Saint's Dress", 0x12A70808, DS3ItemCategory.SKIP), - ("Footman's Hood", 0x12AEA540, DS3ItemCategory.SKIP), - ("Footman's Overcoat", 0x12AEA928, DS3ItemCategory.SKIP), - ("Footman's Bracelets", 0x12AEAD10, DS3ItemCategory.SKIP), - ("Footman's Trousers", 0x12AEB0F8, DS3ItemCategory.SKIP), - ("Scholar's Shed Skin", 0x12E40D20, DS3ItemCategory.SKIP), - ("Man Serpent's Mask", 0x138BE5E0, DS3ItemCategory.SKIP), - ("Man Serpent's Robe", 0x138BE9C8, DS3ItemCategory.SKIP), - ("Old Monarch's Crown", 0x13DFD240, DS3ItemCategory.SKIP), - ("Old Monarch's Robe", 0x13DFD628, DS3ItemCategory.SKIP), - ("Frigid Valley Mask", 0x13FE56C0, DS3ItemCategory.SKIP), - ("Dingy Hood", 0x140D9900, DS3ItemCategory.SKIP), - ("Hexer's Hood", 0x15A995C0, DS3ItemCategory.SKIP), - ("Hexer's Robes", 0x15A999A8, DS3ItemCategory.SKIP), - ("Hexer's Gloves", 0x15A99D90, DS3ItemCategory.SKIP), - ("Hexer's Boots", 0x15A9A178, DS3ItemCategory.SKIP), - ("Varangian Helm", 0x15C81A40, DS3ItemCategory.SKIP), - ("Varangian Armor", 0x15C81E28, DS3ItemCategory.SKIP), - ("Varangian Cuffs", 0x15C82210, DS3ItemCategory.SKIP), - ("Varangian Leggings", 0x15C825F8, DS3ItemCategory.SKIP), + DS3ItemData("Dingy Maiden's Overcoat", 0x11DA9048, DS3ItemCategory.SKIP), + DS3ItemData("Grotto Hat", 0x11F78A40, DS3ItemCategory.SKIP), + DS3ItemData("Grotto Robe", 0x11F78E28, DS3ItemCategory.SKIP), + DS3ItemData("Grotto Wrap", 0x11F79210, DS3ItemCategory.SKIP), + DS3ItemData("Grotto Trousers", 0x11F795F8, DS3ItemCategory.SKIP), + DS3ItemData("Soldier's Gauntlets", 0x126261D0, DS3ItemCategory.SKIP), + DS3ItemData("Soldier's Hood", 0x1263E0A0, DS3ItemCategory.SKIP), + DS3ItemData("Elder's Robe", 0x129024A8, DS3ItemCategory.SKIP), + DS3ItemData("Saint's Veil", 0x12A70420, DS3ItemCategory.SKIP), + DS3ItemData("Saint's Dress", 0x12A70808, DS3ItemCategory.SKIP), + DS3ItemData("Footman's Hood", 0x12AEA540, DS3ItemCategory.SKIP), + DS3ItemData("Footman's Overcoat", 0x12AEA928, DS3ItemCategory.SKIP), + DS3ItemData("Footman's Bracelets", 0x12AEAD10, DS3ItemCategory.SKIP), + DS3ItemData("Footman's Trousers", 0x12AEB0F8, DS3ItemCategory.SKIP), + DS3ItemData("Scholar's Shed Skin", 0x12E40D20, DS3ItemCategory.SKIP), + DS3ItemData("Man Serpent's Mask", 0x138BE5E0, DS3ItemCategory.SKIP), + DS3ItemData("Man Serpent's Robe", 0x138BE9C8, DS3ItemCategory.SKIP), + DS3ItemData("Old Monarch's Crown", 0x13DFD240, DS3ItemCategory.SKIP), + DS3ItemData("Old Monarch's Robe", 0x13DFD628, DS3ItemCategory.SKIP), + DS3ItemData("Frigid Valley Mask", 0x13FE56C0, DS3ItemCategory.SKIP), + DS3ItemData("Dingy Hood", 0x140D9900, DS3ItemCategory.SKIP), + DS3ItemData("Hexer's Hood", 0x15A995C0, DS3ItemCategory.SKIP), + DS3ItemData("Hexer's Robes", 0x15A999A8, DS3ItemCategory.SKIP), + DS3ItemData("Hexer's Gloves", 0x15A99D90, DS3ItemCategory.SKIP), + DS3ItemData("Hexer's Boots", 0x15A9A178, DS3ItemCategory.SKIP), + DS3ItemData("Varangian Helm", 0x15C81A40, DS3ItemCategory.SKIP), + DS3ItemData("Varangian Armor", 0x15C81E28, DS3ItemCategory.SKIP), + DS3ItemData("Varangian Cuffs", 0x15C82210, DS3ItemCategory.SKIP), + DS3ItemData("Varangian Leggings", 0x15C825F8, DS3ItemCategory.SKIP), # Rings - ("Rare Ring of Sacrifice", 0x20004EFC, DS3ItemCategory.SKIP), - ("Baneful Bird Ring", 0x20005032, DS3ItemCategory.SKIP), - ("Darkmoon Blade Covenant Ring", 0x20004F7E, DS3ItemCategory.SKIP), - ("Yorgh's Ring", 0x2000505A, DS3ItemCategory.SKIP), - ("Ring of Hiding", 0x200050D2, DS3ItemCategory.SKIP), - ("Ring of Sustained Toughness", 0x20005118, DS3ItemCategory.SKIP), - ("Ring of Sustained Energy", 0x20005122, DS3ItemCategory.SKIP), - ("Ring of Sustained Magic", 0x2000512C, DS3ItemCategory.SKIP), - ("Ring of Sustained Essence", 0x20005140, DS3ItemCategory.SKIP), - ("Ring of Sustained Might", 0x2000514A, DS3ItemCategory.SKIP), - ("Ring of Sustained Fortune", 0x20005154, DS3ItemCategory.SKIP), + DS3ItemData("Rare Ring of Sacrifice", 0x20004EFC, DS3ItemCategory.SKIP), + DS3ItemData("Baneful Bird Ring", 0x20005032, DS3ItemCategory.SKIP), + DS3ItemData("Darkmoon Blade Covenant Ring", 0x20004F7E, DS3ItemCategory.SKIP), + DS3ItemData("Yorgh's Ring", 0x2000505A, DS3ItemCategory.SKIP), + DS3ItemData("Ring of Hiding", 0x200050D2, DS3ItemCategory.SKIP), + DS3ItemData("Ring of Sustained Toughness", 0x20005118, DS3ItemCategory.SKIP), + DS3ItemData("Ring of Sustained Energy", 0x20005122, DS3ItemCategory.SKIP), + DS3ItemData("Ring of Sustained Magic", 0x2000512C, DS3ItemCategory.SKIP), + DS3ItemData("Ring of Sustained Essence", 0x20005140, DS3ItemCategory.SKIP), + DS3ItemData("Ring of Sustained Might", 0x2000514A, DS3ItemCategory.SKIP), + DS3ItemData("Ring of Sustained Fortune", 0x20005154, DS3ItemCategory.SKIP), # Items - ("Soul of a Wicked Spirit", 0x400002C9, DS3ItemCategory.SKIP), + DS3ItemData("Soul of a Wicked Spirit", 0x400002C9, DS3ItemCategory.SKIP), # Spells - ("Dark Orb", 0x4027AC40, DS3ItemCategory.SKIP), - ("Morbid Temptation", 0x40359AA8, DS3ItemCategory.SKIP), - ("Dorris Swarm", 0x40393870, DS3ItemCategory.SKIP), -]] + DS3ItemData("Dark Orb", 0x4027AC40, DS3ItemCategory.SKIP), + DS3ItemData("Morbid Temptation", 0x40359AA8, DS3ItemCategory.SKIP), + DS3ItemData("Dorris Swarm", 0x40393870, DS3ItemCategory.SKIP), +] _all_items = _vanilla_items + _dlc_items diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 9e2c380c8361..389d978a82e7 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -2,7 +2,7 @@ from typing import Optional, Dict, Set from dataclasses import dataclass -from BaseClasses import Location, Region +from BaseClasses import Location, LocationProgressType, Region class DS3LocationCategory(IntEnum): @@ -15,8 +15,13 @@ class DS3LocationCategory(IntEnum): BOSS = 6 MISC = 7 HEALTH = 8 - PROGRESSIVE_ITEM = 9 - EVENT = 10 + EVENT = 9 + + UPGRADE = 10 + """Any upgrade material. + + This includes various forms of titanite as well as infusion gems and shriving stones. + """ @dataclass @@ -32,12 +37,36 @@ class DS3LocationData: category: DS3LocationCategory """The category into which this location falls.""" - offline: str + offline: Optional[str] = None """The key in the offline randomizer's Slots table that corresponds to this location. - In most cases, the offline randomizer can automatically associate Archipelago location names - with its own notion of locations, but there are cases (multiple copies of the same item in the - same region, different region categorizations) where this heuristic doesn't work.""" + By default, the offline randomizer chooses its location based on the region and the item name. + If the item name is unique across the whole game, it can also look it up based on that alone. If + there are multiple instances of the same item type in the same region, it will assume its order + (in annotations.txt) matches Archipelago's order. + + In cases where this heuristic doesn't work, such as when Archipelago's region categorization or + item name disagrees with the offline randomizer's, this field is used to provide an explicit + association instead. + """ + + missable: bool = False + """Whether this item is possible to permanently lose access to. + + This is also used for items that are *technically* possible to get at any time, but are + prohibitively difficult without blocking off other checks (items dropped by NPCs on death + generally fall into this category). + + Missable locations are always marked as excluded, so they will never contain + progression or useful items. + """ + + # TODO: implement this properly + ngp: bool = False + """Whether this location only contains an item in NG+ and later. + + By default, these items aren't randomized or included in the randomization pool, but an option + can be set to enable them even for NG runs.""" npc: bool = False """Whether this item is contingent on killing an NPC or following their quest.""" @@ -73,9 +102,17 @@ class DS3LocationData: """Whether this location is dropped by a hostile NPC. An "NPC" is specifically a human (or rather, ash) is built like a player character rather than a - monster. This includes both scripted invaders and NPCs who are always on the overworld. + monster. This includes both scripted invaders and NPCs who are always on the overworld. It does + not include initially-friendly NPCs who become hostile as part of a quest or because you attack + them. """ + lizard: bool = False + """Whether this location is dropped by a (small) Crystal Lizard.""" + + shop: bool = False + """Whether this location appears in an NPC's shop.""" + key: bool = False """Whether this location normally contains a key. @@ -86,22 +123,23 @@ class DS3LocationData: """Whether this location is particularly tricky to find. This is for players without an encyclopedic knowledge of DS3 who don't want to get stuck looking - for an invisible wall or one random mob with a guaranteed drop. + for an illusory wall or one random mob with a guaranteed drop. """ - def location_groups(): + def location_groups(self): """The names of location groups this location should appear in. This is computed from the properties assigned to this location.""" names = [] - if prominent: names.add("Prominent") - if progression: names.add("Progression") - if boss: names.add("Boss Rewards") - if miniboss: names.add("Miniboss Rewards") - if mimic: names.add("Mimic Rewards") - if hostile_npc: names.add("Hostile NPC Rewards") - if key: names.add("Keys") - if hidden: names.add("Hidden") + if self.prominent: names.append("Prominent") + if self.progression: names.append("Progression") + if self.boss: names.append("Boss Rewards") + if self.miniboss: names.append("Miniboss Rewards") + if self.mimic: names.append("Mimic Rewards") + if self.hostile_npc: names.append("Hostile NPC Rewards") + if self.lizard: names.append("Small Crystal Lizards") + if self.key: names.append("Keys") + if self.hidden: names.append("Hidden") return names @@ -109,6 +147,7 @@ class DarkSouls3Location(Location): game: str = "Dark Souls III" category: DS3LocationCategory default_item_name: str + offline: Optional[str] def __init__( self, @@ -122,12 +161,33 @@ def __init__( self.default_item_name = default_item_name self.category = category + @staticmethod + def from_data( + player: int, + data: DS3LocationData, + address: Optional[int] = None, + parent: Optional[Region] = None): + location = DarkSouls3Location( + player, + data.name, + data.category, + data.default_item_name, + address, + parent + ) + location.offline = data.offline + if data.missable: + location.progress_type = LocationProgressType.EXCLUDED + return location + + @staticmethod def get_name_to_id() -> dict: base_id = 100000 - table_offset = 100 + table_offset = 150 table_order = [ + "Cemetery of Ash", "Firelink Shrine", "Firelink Shrine Bell Tower", "High Wall of Lothric", @@ -146,24 +206,33 @@ def get_name_to_id() -> dict: "Grand Archives", "Untended Graves", "Archdragon Peak", + "Kiln of the First Flame", - "Painted World of Ariandel 1", - "Painted World of Ariandel 2", + "Painted World of Ariandel (Before Contraption)", + "Painted World of Ariandel (After Contraption)", "Dreg Heap", "Ringed City", - "Progressive Items 1", - "Progressive Items 2", - "Progressive Items 3", - "Progressive Items 4", - "Progressive Items DLC", - "Progressive Items Health", + "Greirat's Shop", + "Karla's Shop", ] + if len(location_tables) != len(table_order): + for location in location_tables.keys(): + if location not in table_order: + raise Exception("Location table is missing location {}".format(location)) + for location in table_order: + if location not in location_tables: + raise Exception("Table order is missing location {}".format(location)) + output = {} for i, region_name in enumerate(table_order): if len(location_tables[region_name]) > table_offset: - raise Exception("A location table has {} entries, that is more than {} entries (table #{})".format(len(location_tables[region_name]), table_offset, i)) + raise Exception("The location table for {} has {} entries, that is more than {} entries".format( + region_name, + len(location_tables[region_name]), + table_offset, + )) output.update({location_data.name: id for id, location_data in enumerate(location_tables[region_name], base_id + (table_offset * i))}) @@ -171,136 +240,540 @@ def get_name_to_id() -> dict: location_tables = { + "Cemetery of Ash": [ + DS3LocationData("CA: Soul of a Deserted Corpse", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("CA: Firebomb", "Firebomb x5", DS3LocationCategory.MISC), + DS3LocationData("CA: Titanite Shard", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("CA: Soul of an Unknown Traveler", "Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("CA: Speckled Stoneplate Ring+1", "Speckled Stoneplate Ring+1", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("CA: Titanite Scale", "Titanite Scale", DS3LocationCategory.UPGRADE, + miniboss = True), + ], "Firelink Shrine": [ - DS3LocationData("FS: Broken Straight Sword", "Broken Straight Sword", DS3LocationCategory.WEAPON), - DS3LocationData("FS: East-West Shield", "East-West Shield", DS3LocationCategory.SHIELD), + DS3LocationData("FS: Skull Ring", "Skull Ring", DS3LocationCategory.RING, + hidden = True, npc = True), # Ludleth drop, does not permanently die DS3LocationData("FS: Uchigatana", "Uchigatana", DS3LocationCategory.WEAPON, hostile_npc = True), # Sword Master drop DS3LocationData("FS: Master's Attire", "Master's Attire", DS3LocationCategory.ARMOR, hostile_npc = True), # Sword Master drop DS3LocationData("FS: Master's Gloves", "Master's Gloves", DS3LocationCategory.ARMOR, hostile_npc = True), # Sword Master drop + DS3LocationData("FS: Broken Straight Sword", "Broken Straight Sword", DS3LocationCategory.WEAPON), + DS3LocationData("FS: Homeward Bone #1", "Homeward Bone", DS3LocationCategory.MISC), + DS3LocationData("FS: Ember #1", "Ember", DS3LocationCategory.MISC), + DS3LocationData("FS: Soul of a Deserted Corpse", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("FS: East-West Shield", "East-West Shield", DS3LocationCategory.SHIELD), + DS3LocationData("FS: Homeward Bone #2", "Homeward Bone", DS3LocationCategory.MISC), + DS3LocationData("FS: Ember #2", "Ember", DS3LocationCategory.MISC), + DS3LocationData("FS: Wolf Ring+2", "Wolf Ring+2", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("FS: Cracked Red Eye Orb", "Cracked Red Eye Orb x5", DS3LocationCategory.MISC, + missable = True, npc = True), # Leonhard (quest) + DS3LocationData("FS: Lift Chamber Key", "Lift Chamber Key", DS3LocationCategory.KEY, + progression = True, npc = True, key = True), # Leonhard (kill or quest, after giving Pale Tongue and lighting Cliff Underside or killing Greatwood) + + # Shrine Handmaid shop + DS3LocationData("FS: White Sign Soapstone", "White Sign Soapstone", DS3LocationCategory.MISC, + shop = True), + DS3LocationData("FS: Dried Finger", "Dried Finger", DS3LocationCategory.MISC, + shop = True), + DS3LocationData("FS: Tower Key", "Tower Key", DS3LocationCategory.KEY, + progression = True, shop = True, key = True), + DS3LocationData("FS: Ember (Handmaid)", "Ember", DS3LocationCategory.MISC, + offline = '99,0:-1:110000:', shop = True), + DS3LocationData("FS: Farron Dart", "Farron Dart", DS3LocationCategory.SPELL, + offline = '99,0:-1:110000:', shop = True), + DS3LocationData("FS: Soul Arrow", "Soul Arrow", DS3LocationCategory.SPELL, + offline = '99,0:-1:110000:', shop = True), + DS3LocationData("FS: Heal Aid", "Heal Aid", DS3LocationCategory.SPELL, + shop = True), + # Mortician's Ashes + DS3LocationData("FS: Alluring Skull", "Alluring Skull", DS3LocationCategory.MISC, + shop = True), + DS3LocationData("FS: Ember (Mortician)" , "Ember", DS3LocationCategory.MISC, + offline = '99,0:-1:110000,70000100:', shop = True), + DS3LocationData("FS: Grave Key", "Grave Key", DS3LocationCategory.MISC, + shop = True, key = True), + # Dreamchaser's Ashes + DS3LocationData("FS: Life Ring", "Life Ring", DS3LocationCategory.RING, + shop = True), + DS3LocationData("FS: Hidden Blessing #2", "Hidden Blessing", DS3LocationCategory.MISC, + missable = True, shop = True), # only if you say where the ashes were found + # Paladin's Ashes + DS3LocationData("FS: Lloyd's Shield Ring", "Lloyd's Shield Ring", DS3LocationCategory.RING, + shop = True), + # Grave Warden's Ashes + DS3LocationData("FS: Ember (Grave Warden)", "Ember", DS3LocationCategory.MISC, + offline = '99,0:-1:110000,70000103:', shop = True), + # Prisoner Chief's Ashes + DS3LocationData("FS: Karla's Pointed Hat", "Karla's Pointed Hat", DS3LocationCategory.ARMOR, + offline = '99,0:-1:110000,70000105:', shop = True), + DS3LocationData("FS: Karla's Coat", "Karla's Coat", DS3LocationCategory.ARMOR, + offline = '99,0:-1:110000,70000105:', shop = True), + DS3LocationData("FS: Karla's Gloves", "Karla's Gloves", DS3LocationCategory.ARMOR, + offline = '99,0:-1:110000,70000105:', shop = True), + DS3LocationData("FS: Karla's Trousers", "Karla's Trousers", DS3LocationCategory.ARMOR, + offline = '99,0:-1:110000,70000105:', shop = True), + # Xanthous Ashes + DS3LocationData("FS: Xanthous Overcoat", "Xanthous Overcoat", DS3LocationCategory.ARMOR, + shop = True), + DS3LocationData("FS: Xanthous Gloves", "Xanthous Gloves", DS3LocationCategory.ARMOR, + shop = True), + DS3LocationData("FS: Xanthous Trousers", "Xanthous Trousers", DS3LocationCategory.ARMOR, + shop = True), + # Dragon Chaser's Ashes + DS3LocationData("FS: Ember (Dragon Chaser)", "Ember", DS3LocationCategory.MISC, + offline = '99,3:-1:110000,70000108:', shop = True), + # Easterner's Ashes + DS3LocationData("FS: Washing Pole", "Washing Pole", DS3LocationCategory.WEAPON, + shop = True), + DS3LocationData("FS: Eastern Helm", "Eastern Helm", DS3LocationCategory.ARMOR, + shop = True), + DS3LocationData("FS: Eastern Armor", "Eastern Armor", DS3LocationCategory.ARMOR, + shop = True), + DS3LocationData("FS: Eastern Gauntlets", "Eastern Gauntlets", DS3LocationCategory.ARMOR, + shop = True), + DS3LocationData("FS: Eastern Leggings", "Eastern Leggings", DS3LocationCategory.ARMOR, + shop = True), + DS3LocationData("FS: Wood Grain Ring", "Wood Grain Ring", DS3LocationCategory.RING, + shop = True), + # Captain's Ashes + DS3LocationData("FS: Millwood Knight Helm", "Millwood Knight Helm", DS3LocationCategory.ARMOR, + shop = True), + DS3LocationData("FS: Millwood Knight Armor", "Millwood Knight Armor", DS3LocationCategory.ARMOR, + shop = True), + DS3LocationData("FS: Millwood Knight Gauntlets", "Millwood Knight Gauntlets", DS3LocationCategory.ARMOR, + shop = True), + DS3LocationData("FS: Millwood Knight Leggings", "Millwood Knight Leggings", DS3LocationCategory.ARMOR, + shop = True), + DS3LocationData("FS: Refined Gem", "Refined Gem", DS3LocationCategory.UPGRADE, + shop = True), ], "Firelink Shrine Bell Tower": [ # Guarded by Tower Key - DS3LocationData("FSBT: Covetous Silver Serpent Ring", "Covetous Silver Serpent Ring", DS3LocationCategory.RING, - hidden = True), # Behind invisible wall + DS3LocationData("FSBT: Homeward Bone", "Homeward Bone x3", DS3LocationCategory.MISC), + DS3LocationData("FSBT: Estus Ring", "Estus Ring", DS3LocationCategory.RING), + DS3LocationData("FSBT: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), + DS3LocationData("FSBT: Fire Keeper Soul", "Fire Keeper Soul", DS3LocationCategory.MISC), DS3LocationData("FSBT: Fire Keeper Robe", "Fire Keeper Robe", DS3LocationCategory.ARMOR), DS3LocationData("FSBT: Fire Keeper Gloves", "Fire Keeper Gloves", DS3LocationCategory.ARMOR), DS3LocationData("FSBT: Fire Keeper Skirt", "Fire Keeper Skirt", DS3LocationCategory.ARMOR), - DS3LocationData("FSBT: Estus Ring", "Estus Ring", DS3LocationCategory.RING), - DS3LocationData("FSBT: Fire Keeper Soul", "Fire Keeper Soul", DS3LocationCategory.MISC), + DS3LocationData("FSBT: Covetous Silver Serpent Ring", "Covetous Silver Serpent Ring", DS3LocationCategory.RING, + hidden = True), # Behind illusory wall + DS3LocationData("FSBT: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + + # Mark all crow trades as missable since no one wants to have to try trading everything just + # in case it gives a progression item. + DS3LocationData("FSBT: Iron Bracelets", "Iron Bracelets", DS3LocationCategory.ARMOR, + missable = True), + DS3LocationData("FSBT: Ring of Sacrifice", "Ring of Sacrifice", DS3LocationCategory.MISC, + missable = True), + DS3LocationData("FSBT: Porcine Shield", "Porcine Shield", DS3LocationCategory.SHIELD, + missable = True), + DS3LocationData("FSBT: Lucatiel's Mask", "Lucatiel's Mask", DS3LocationCategory.ARMOR, + missable = True), + DS3LocationData("FSBT: Very good! Carving", "Very good! Carving", DS3LocationCategory.MISC, + missable = True), + DS3LocationData("FSBT: Thank you Carving", "Thank you Carving", DS3LocationCategory.MISC, + missable = True), + DS3LocationData("FSBT: I'm sorry Carving", "I'm sorry Carving", DS3LocationCategory.MISC, + missable = True), + DS3LocationData("FSBT: Sunlight Shield", "Sunlight Shield", DS3LocationCategory.SHIELD, + missable = True), + DS3LocationData("FSBT: Hollow Gem", "Hollow Gem", DS3LocationCategory.UPGRADE, + missable = True), + DS3LocationData("FSBT: Titanite Scale #1", "Titanite Scale x3", DS3LocationCategory.UPGRADE, + missable = True), + DS3LocationData("FSBT: Help me! Carving", "Help me! Carving", DS3LocationCategory.MISC, + missable = True), + DS3LocationData("FSBT: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE, + missable = True), + DS3LocationData("FSBT: Hello Carving", "Hello Carving", DS3LocationCategory.MISC, + missable = True), + DS3LocationData("FSBT: Armor of the Sun", "Armor of the Sun", DS3LocationCategory.ARMOR, + missable = True), + DS3LocationData("FSBT: Large Titanite Shard", "Large Titanite Shard", DS3LocationCategory.UPGRADE, + missable = True), + DS3LocationData("FSBT: Titanite Chunk", "Titanite Chunk", DS3LocationCategory.UPGRADE, + missable = True), + DS3LocationData("FSBT: Iron Helm", "Iron Helm", DS3LocationCategory.ARMOR, + missable = True), + DS3LocationData("FSBT: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + missable = True), + DS3LocationData("FSBT: Iron Leggings", "Iron Leggings", DS3LocationCategory.ARMOR, + missable = True), + DS3LocationData("FSBT: Lightning Gem", "Lightning Gem", DS3LocationCategory.UPGRADE, + missable = True), + DS3LocationData("FSBT: Twinkling Titanite #3", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + missable = True), + DS3LocationData("FSBT: Blessed Gem", "Blessed Gem", DS3LocationCategory.UPGRADE, + missable = True), + DS3LocationData("FSBT: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE, + missable = True), ], "High Wall of Lothric": [ - DS3LocationData("HWL: Deep Battle Axe", "Deep Battle Axe", DS3LocationCategory.WEAPON, - mimic = True), + DS3LocationData("HWL: Soul of Boreal Valley Vordt", "Soul of Boreal Valley Vordt", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("HWL: Soul of the Dancer", "Soul of the Dancer", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("HWL: Basin of Vows", "Basin of Vows", DS3LocationCategory.KEY, + prominent = True, progression = True), + DS3LocationData("HWL: Small Lothric Banner", "Small Lothric Banner", DS3LocationCategory.KEY, + prominent = True, progression = True), + DS3LocationData("HWL: Green Blossom #1", "Green Blossom x2", DS3LocationCategory.MISC, + hidden = True), # Down an obscured hallway + DS3LocationData("HWL: Gold Pine Resin", "Gold Pine Resin x2", DS3LocationCategory.MISC, + hidden = True), # Hidden fall + DS3LocationData("HWL: Large Soul of a Deserted Corpse #1", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("HWL: Soul of a Deserted Corpse #1", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("HWL: Standard Arrow", "Standard Arrow x12", DS3LocationCategory.MISC), + DS3LocationData("HWL: Longbow", "Longbow", DS3LocationCategory.WEAPON), + DS3LocationData("HWL: Firebomb #1", "Firebomb x3", DS3LocationCategory.MISC), + DS3LocationData("HWL: Throwing Knife #1", "Throwing Knife x8", DS3LocationCategory.MISC), + DS3LocationData("HWL: Soul of a Deserted Corpse #2", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), DS3LocationData("HWL: Club", "Club", DS3LocationCategory.WEAPON), DS3LocationData("HWL: Claymore", "Claymore", DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Binoculars", "Binoculars", DS3LocationCategory.MISC), - DS3LocationData("HWL: Longbow", "Longbow", DS3LocationCategory.WEAPON), + DS3LocationData("HWL: Ember #1", "Ember", DS3LocationCategory.MISC), + DS3LocationData("HWL: Firebomb #2", "Firebomb x2", DS3LocationCategory.MISC, + hidden = True), # In crates and furniture + DS3LocationData("HWL: Titanite Shard #1", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("HWL: Undead Hunter Charm", "Undead Hunter Charm x2", DS3LocationCategory.MISC, + hidden = True), # In a pot + DS3LocationData("HWL: Firebomb #3", "Firebomb x3", DS3LocationCategory.MISC), + DS3LocationData("HWL: Cell Key", "Cell Key", DS3LocationCategory.KEY, + key = True), + DS3LocationData("HWL: Ember #2", "Ember", DS3LocationCategory.MISC), + DS3LocationData("HWL: Soul of a Deserted Corpse #3", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("HWL: Lucerne", "Lucerne", DS3LocationCategory.WEAPON), DS3LocationData("HWL: Mail Breaker", "Mail Breaker", DS3LocationCategory.WEAPON), + DS3LocationData("HWL: Titanite Shard #2", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("HWL: Rapier", "Rapier", DS3LocationCategory.WEAPON), + DS3LocationData("HWL: Titanite Shard #3", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("HWL: Large Soul of a Deserted Corpse #2", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("HWL: Black Firebomb", "Black Firebomb x3", DS3LocationCategory.MISC), + DS3LocationData("HWL: Soul of a Deserted Corpse #4", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("HWL: Ember #3", "Ember", DS3LocationCategory.MISC), + DS3LocationData("HWL: Large Soul of a Deserted Corpse #3", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC, + hidden = True), # Easily missed turnoff + DS3LocationData("HWL: Binoculars", "Binoculars", DS3LocationCategory.MISC), + DS3LocationData("HWL: Ring of Sacrifice", "Ring of Sacrifice", DS3LocationCategory.MISC, + hidden = True), # Easily missed turnoff + DS3LocationData("HWL: Throwing Knife #2", "Throwing Knife x6", DS3LocationCategory.MISC), + DS3LocationData("HWL: Soul of a Deserted Corpse #5", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("HWL: Green Blossom #2", "Green Blossom x3", DS3LocationCategory.MISC), DS3LocationData("HWL: Broadsword", "Broadsword", DS3LocationCategory.WEAPON), + DS3LocationData("HWL: Soul of a Deserted Corpse #6", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("HWL: Firebomb #4", "Firebomb x3", DS3LocationCategory.MISC), + DS3LocationData("HWL: Soul of a Deserted Corpse #7", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("HWL: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), + DS3LocationData("HWL: Fleshbite Ring+1", "Fleshbite Ring+1", DS3LocationCategory.RING, + hidden = True, ngp = True), # Hidden jump + DS3LocationData("HWL: Ring of the Evil Eye+2", "Ring of the Evil Eye+2", DS3LocationCategory.RING, + hidden = True, ngp = True), # In barrels DS3LocationData("HWL: Silver Eagle Kite Shield", "Silver Eagle Kite Shield", DS3LocationCategory.SHIELD), DS3LocationData("HWL: Astora Straight Sword", "Astora Straight Sword", DS3LocationCategory.WEAPON, hidden = True), # Hidden fall - DS3LocationData("HWL: Cell Key", "Cell Key", DS3LocationCategory.KEY, - key = True), - DS3LocationData("HWL: Rapier", "Rapier", DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Lucerne", "Lucerne", DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Small Lothric Banner", "Small Lothric Banner", DS3LocationCategory.KEY, - prominent = True, progression = True), - DS3LocationData("HWL: Basin of Vows", "Basin of Vows", DS3LocationCategory.KEY, - prominent = True, progression = True), - DS3LocationData("HWL: Soul of Boreal Valley Vordt", "Soul of Boreal Valley Vordt", DS3LocationCategory.BOSS, - prominent = True, boss = True), - DS3LocationData("HWL: Soul of the Dancer", "Soul of the Dancer", DS3LocationCategory.BOSS, - prominent = True, boss = True), + DS3LocationData("HWL: Battle Axe", "Battle Axe", DS3LocationCategory.WEAPON, + offline = '01,0:53000960::', mimic = True), + DS3LocationData("HWL: Ember #4", "Ember", DS3LocationCategory.MISC, + hidden = True, miniboss = True), # Only dropped by Pus of Man after transformation + DS3LocationData("HWL: Titanite Shard #4", "Titanite Shard", DS3LocationCategory.UPGRADE, + hidden = True, miniboss = True), # Only dropped by Pus of Man after transformation + DS3LocationData("HWL: Ember #5", "Ember", DS3LocationCategory.MISC, + hidden = True, miniboss = True), # Only dropped by Pus of Man after transformation + DS3LocationData("HWL: Titanite Shard #5", "Titanite Shard", DS3LocationCategory.MISC, + hidden = True, miniboss = True), # Only dropped by Pus of Man after transformation + DS3LocationData("HWL: Large Titanite Shard", "Large Titanite Shard", DS3LocationCategory.UPGRADE, + missable = True), # Getting fire-breathing wyvern down to 20% HP. Missable + # because it requires range and is a crazy thing to do + DS3LocationData("HWL: Refined Gem", "Refined Gem", DS3LocationCategory.UPGRADE, + miniboss = True), # Red-Eyed Lothric Knight drop DS3LocationData("HWL: Way of Blue", "Way of Blue", DS3LocationCategory.MISC), - DS3LocationData("HWL: Greirat's Ashes", "Greirat's Ashes", DS3LocationCategory.KEY, - npc = True), - DS3LocationData("HWL: Blue Tearstone Ring", "Blue Tearstone Ring", DS3LocationCategory.RING, - npc = True), + DS3LocationData("HWL: Raw Gem", "Raw Gem", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("HWL: Red Eye Orb", "Red Eye Orb", DS3LocationCategory.MISC, + miniboss = True), + DS3LocationData("HWL: Vordt's Great Hammer", "Vordt's Great Hammer", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("HWL: Pontiff's Left Eye", "Pontiff's Left Eye", DS3LocationCategory.RING, + missable = True, boss = True, shop = True), ], "Undead Settlement": [ - DS3LocationData("US: Small Leather Shield", "Small Leather Shield", DS3LocationCategory.SHIELD), - DS3LocationData("US: Whip", "Whip", DS3LocationCategory.WEAPON), - DS3LocationData("US: Reinforced Club", "Reinforced Club", DS3LocationCategory.WEAPON), + DS3LocationData("US: Soul of the Rotted Greatwood", "Soul of the Rotted Greatwood", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("US: Transposing Kiln", "Transposing Kiln", DS3LocationCategory.MISC, + boss = True), + DS3LocationData("US: Pyromancy Flame", "Pyromancy Flame", DS3LocationCategory.WEAPON, + missable = True, npc = True), + DS3LocationData("US: Old Sage's Blindfold", "Old Sage's Blindfold", DS3LocationCategory.ARMOR, + missable = True, npc = True), + DS3LocationData("US: Cornyx's Garb", "Cornyx's Garb", DS3LocationCategory.ARMOR, + missable = True, npc = True), + DS3LocationData("US: Cornyx's Wrap", "Cornyx's Wrap", DS3LocationCategory.ARMOR, + missable = True, npc = True), + DS3LocationData("US: Cornyx's Skirt", "Cornyx's Skirt", DS3LocationCategory.ARMOR, + missable = True, npc = True), + DS3LocationData("US: Tower Key", "Tower Key", DS3LocationCategory.KEY, + missable = True, npc = True, key = True), + DS3LocationData("US: Morne's Great Hammer", "Morne's Great Hammer", DS3LocationCategory.WEAPON, + npc = True), # Eygon (kill or quest) + DS3LocationData("US: Moaning Shield", "Moaning Shield", DS3LocationCategory.SHIELD, + npc = True), # Eygon (kill or quest) + DS3LocationData("US: Hawk Ring", "Hawk Ring", DS3LocationCategory.RING, + npc = True), # Giant archer (kill or quest) + DS3LocationData("US: Flynn's Ring", "Flynn's Ring", DS3LocationCategory.RING), + DS3LocationData("US: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), + DS3LocationData("US: Alluring Skull #1", "Alluring Skull x2", DS3LocationCategory.MISC), + DS3LocationData("US: Mortician's Ashes", "Mortician's Ashes", DS3LocationCategory.KEY, + progression = True), + DS3LocationData("US: Homeward Bone #1", "Homeward Bone x2", DS3LocationCategory.MISC, + hidden = True), # Hidden fall + DS3LocationData("US: Caduceus Round Shield", "Caduceus Round Shield", DS3LocationCategory.SHIELD), + DS3LocationData("US: Ember #1", "Ember", DS3LocationCategory.MISC), + DS3LocationData("US: Soul of an Unknown Traveler #1", "Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("US: Repair Powder", "Repair Powder x2", DS3LocationCategory.MISC), + DS3LocationData("US: Homeward Bone #2", "Homeward Bone x2", DS3LocationCategory.MISC), + DS3LocationData("US: Titanite Shard #1", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("US: Wargod Wooden Shield", "Wargod Wooden Shield", DS3LocationCategory.SHIELD), + DS3LocationData("US: Large Soul of a Deserted Corpse #1", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("US: Ember #2", "Ember", DS3LocationCategory.MISC), + DS3LocationData("US: Large Soul of a Deserted Corpse #2", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("US: Titanite Shard #2", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("US: Alluring Skull #2", "Alluring Skull x2", DS3LocationCategory.MISC), + DS3LocationData("US: Charcoal Pine Bundle #1", "Charcoal Pine Bundle x2", DS3LocationCategory.MISC), DS3LocationData("US: Blue Wooden Shield", "Blue Wooden Shield", DS3LocationCategory.SHIELD), DS3LocationData("US: Cleric Hat", "Cleric Hat", DS3LocationCategory.ARMOR), DS3LocationData("US: Cleric Blue Robe", "Cleric Blue Robe", DS3LocationCategory.ARMOR), DS3LocationData("US: Cleric Gloves", "Cleric Gloves", DS3LocationCategory.ARMOR), DS3LocationData("US: Cleric Trousers", "Cleric Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("US: Mortician's Ashes", "Mortician's Ashes", DS3LocationCategory.KEY), - DS3LocationData("US: Caestus", "Caestus", DS3LocationCategory.WEAPON), - DS3LocationData("US: Plank Shield", "Plank Shield", DS3LocationCategory.SHIELD), - DS3LocationData("US: Flame Stoneplate Ring", "Flame Stoneplate Ring", DS3LocationCategory.RING), - DS3LocationData("US: Caduceus Round Shield", "Caduceus Round Shield", DS3LocationCategory.SHIELD), - DS3LocationData("US: Fire Clutch Ring", "Fire Clutch Ring", DS3LocationCategory.RING), - DS3LocationData("US: Partizan", "Partizan", DS3LocationCategory.WEAPON), + DS3LocationData("US: Soul of an Unknown Traveler #2", "Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("US: Charcoal Pine Resin", "Charcoal Pine Resin x2", DS3LocationCategory.MISC), + DS3LocationData("US: Loincloth", "Loincloth", DS3LocationCategory.ARMOR), DS3LocationData("US: Bloodbite Ring", "Bloodbite Ring", DS3LocationCategory.RING, miniboss = True), # Giant Rat drop + DS3LocationData("US: Charcoal Pine Bundle #2", "Charcoal Pine Bundle x2", DS3LocationCategory.MISC), + DS3LocationData("US: Soul of an Unknown Traveler #3", "Soul of an Unknown Traveler", DS3LocationCategory.MISC, + hidden = True), # In crates + DS3LocationData("US: Titanite Shard #3", "Titanite Shard", DS3LocationCategory.MISC), DS3LocationData("US: Red Hilted Halberd", "Red Hilted Halberd", DS3LocationCategory.WEAPON), + DS3LocationData("US: Rusted Coin", "Rusted Coin x2", DS3LocationCategory.MISC), + DS3LocationData("US: Caestus", "Caestus", DS3LocationCategory.WEAPON), DS3LocationData("US: Saint's Talisman", "Saint's Talisman", DS3LocationCategory.WEAPON), - DS3LocationData("US: Irithyll Straight Sword", "Irithyll Straight Sword", DS3LocationCategory.WEAPON, - miniboss = True), # Boreal Outrider drop + DS3LocationData("US: Alluring Skull #3", "Alluring Skull x3", DS3LocationCategory.MISC), DS3LocationData("US: Large Club", "Large Club", DS3LocationCategory.WEAPON), - DS3LocationData("US: Northern Helm", "Northern Helm", DS3LocationCategory.ARMOR), - DS3LocationData("US: Northern Armor", "Northern Armor", DS3LocationCategory.ARMOR), - DS3LocationData("US: Northern Gloves", "Northern Gloves", DS3LocationCategory.ARMOR), - DS3LocationData("US: Northern Trousers", "Northern Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("US: Flynn's Ring", "Flynn's Ring", DS3LocationCategory.RING), + DS3LocationData("US: Titanite Shard #4", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("US: Titanite Shard #5", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("US: Fading Soul #1", "Fading Soul", DS3LocationCategory.MISC), + DS3LocationData("US: Titanite Shard #6", "Titanite Shard", DS3LocationCategory.UPGRADE, + hidden = True), # hidden fall + DS3LocationData("US: Hand Axe", "Hand Axe", DS3LocationCategory.WEAPON), + DS3LocationData("US: Soul of an Unknown Traveler #4", "Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("US: Ember #3", "Ember", DS3LocationCategory.MISC), DS3LocationData("US: Mirrah Vest", "Mirrah Vest", DS3LocationCategory.ARMOR, hidden = True), # Hidden fall DS3LocationData("US: Mirrah Gloves", "Mirrah Gloves", DS3LocationCategory.ARMOR, hidden = True), # Hidden fall DS3LocationData("US: Mirrah Trousers", "Mirrah Trousers", DS3LocationCategory.ARMOR, hidden = True), # Hidden fall + DS3LocationData("US: Plank Shield", "Plank Shield", DS3LocationCategory.SHIELD), + DS3LocationData("US: Red Bug Pellet", "Red Bug Pellet x2", DS3LocationCategory.MISC), DS3LocationData("US: Chloranthy Ring", "Chloranthy Ring", DS3LocationCategory.RING, hidden = True), # Hidden fall - DS3LocationData("US: Loincloth", "Loincloth", DS3LocationCategory.ARMOR), - DS3LocationData("US: Wargod Wooden Shield", "Wargod Wooden Shield", DS3LocationCategory.SHIELD), - DS3LocationData("US: Loretta's Bone", "Loretta's Bone", DS3LocationCategory.KEY), - DS3LocationData("US: Hand Axe", "Hand Axe", DS3LocationCategory.WEAPON), + DS3LocationData("US: Fire Clutch Ring", "Fire Clutch Ring", DS3LocationCategory.RING), + DS3LocationData("US: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), + DS3LocationData("US: Firebomb", "Firebomb x6", DS3LocationCategory.MISC), + DS3LocationData("US: Whip", "Whip", DS3LocationCategory.WEAPON), DS3LocationData("US: Great Scythe", "Great Scythe", DS3LocationCategory.WEAPON), - DS3LocationData("US: Soul of the Rotted Greatwood", "Soul of the Rotted Greatwood", DS3LocationCategory.BOSS, - prominent = True, boss = True), - DS3LocationData("US: Hawk Ring", "Hawk Ring", DS3LocationCategory.RING), - DS3LocationData("US: Warrior of Sunlight", "Warrior of Sunlight", DS3LocationCategory.MISC, - hidden = True), # Hidden fall - DS3LocationData("US: Blessed Red and White Shield+1", "Blessed Red and White Shield+1", DS3LocationCategory.SHIELD, + DS3LocationData("US: Homeward Bone #3", "Homeward Bone x2", DS3LocationCategory.MISC), + DS3LocationData("US: Large Soul of a Deserted Corpse #3", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("US: Ember #4", "Ember", DS3LocationCategory.MISC), + DS3LocationData("US: Large Soul of a Deserted Corpse #4", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("US: Fading Soul #2", "Fading Soul", DS3LocationCategory.MISC), + DS3LocationData("US: Young White Branch #1", "Young White Branch", DS3LocationCategory.MISC), + DS3LocationData("US: Ember #5", "Ember", DS3LocationCategory.MISC), + DS3LocationData("US: Large Soul of a Deserted Corpse #5", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("US: Young White Branch #2", "Young White Branch", DS3LocationCategory.MISC), + DS3LocationData("US: Reinforced Club", "Reinforced Club", DS3LocationCategory.WEAPON), + DS3LocationData("US: Soul of a Nameless Soldier", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("US: Loretta's Bone", "Loretta's Bone", DS3LocationCategory.KEY), + DS3LocationData("US: Northern Helm", "Northern Helm", DS3LocationCategory.ARMOR), + DS3LocationData("US: Northern Armor", "Northern Armor", DS3LocationCategory.ARMOR), + DS3LocationData("US: Northern Gloves", "Northern Gloves", DS3LocationCategory.ARMOR), + DS3LocationData("US: Northern Trousers", "Northern Trousers", DS3LocationCategory.ARMOR), + DS3LocationData("US: Partizan", "Partizan", DS3LocationCategory.WEAPON, + missable = True), # requires projectile + DS3LocationData("US: Flame Stoneplate Ring", "Flame Stoneplate Ring", DS3LocationCategory.RING), + DS3LocationData("US: Red and White Shield", "Red and White Shield", DS3LocationCategory.SHIELD, offline = "02,0:53100740::"), - DS3LocationData("US: Irina's Ashes", "Irina's Ashes", DS3LocationCategory.KEY, - npc = True), - DS3LocationData("US: Cornyx's Ashes", "Cornyx's Ashes", DS3LocationCategory.KEY, - npc = True), - DS3LocationData("US: Cornyx's Wrap", "Cornyx's Wrap", DS3LocationCategory.ARMOR, - npc = True), - DS3LocationData("US: Cornyx's Garb", "Cornyx's Garb", DS3LocationCategory.ARMOR, - npc = True), - DS3LocationData("US: Cornyx's Skirt", "Cornyx's Skirt", DS3LocationCategory.ARMOR, - npc = True), - DS3LocationData("US: Pyromancy Flame", "Pyromancy Flame", DS3LocationCategory.ARMOR, - npc = True), - DS3LocationData("US: Transposing Kiln", "Transposing Kiln", DS3LocationCategory.MISC, - boss = True), - DS3LocationData("US: Tower Key", "Tower Key", DS3LocationCategory.KEY, - npc = True), + DS3LocationData("US: Small Leather Shield", "Small Leather Shield", DS3LocationCategory.SHIELD), + DS3LocationData("US: Pale Tongue", "Pale Tongue", DS3LocationCategory.MISC), + DS3LocationData("US: Large Soul of a Deserted Corpse #6", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("US: Kukri", "Kukri x9", DS3LocationCategory.MISC, + missable = True), # requires projectile + DS3LocationData("US: Life Ring+1", "Life Ring+1", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("US: Poisonbite Ring+1", "Poisonbite Ring+1", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("US: Covetous Silver Serpent Ring+2", "Covetous Silver Serpent Ring+2", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("US: Human Pine Resin", "Human Pine Resin x4", DS3LocationCategory.MISC), + DS3LocationData("US: Homeward Bone #4", "Homeward Bone", DS3LocationCategory.MISC), + DS3LocationData("US: Irithyll Straight Sword", "Irithyll Straight Sword", DS3LocationCategory.WEAPON, + miniboss = True), # Boreal Outrider drop + DS3LocationData("US: Fire Gem", "Fire Gem", DS3LocationCategory.UPGRADE, + miniboss = True), # Fire Demon drop + DS3LocationData("US: Warrior of Sunlight", "Warrior of Sunlight", DS3LocationCategory.MISC, + hidden = True), # hidden fall + DS3LocationData("US: Mound-makers", "Mound-makers", DS3LocationCategory.MISC, + missable = True), + DS3LocationData("US: Sharp Gem", "Sharp Gem", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("US: Heavy Gem", "Heavy Gem", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("US: Siegbräu", "Siegbräu", DS3LocationCategory.MISC, + missable = True, npc = True), + DS3LocationData("US: Heavy Gem (Hawkwood)", "Heavy Gem", DS3LocationCategory.UPGRADE, + missable = True, npc = True), # Hawkwood (quest, after Greatwood or Sage) + DS3LocationData("US: Hollowslayer Greatsword", "Hollowslayer Greatsword", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("US: Arstor's Spear", "Arstor's Spear", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + + # Yoel/Yuria of Londor + DS3LocationData("US: Soul Arrow", "Soul Arrow", DS3LocationCategory.SPELL, + offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, shop = True), + DS3LocationData("US: Heavy Soul Arrow", "Heavy Soul Arrow", DS3LocationCategory.SPELL, + offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, shop = True), + DS3LocationData("US: Magic Weapon", "Magic Weapon", DS3LocationCategory.SPELL, + offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, shop = True), + DS3LocationData("US: Magic Shield", "Magic Shield", DS3LocationCategory.SPELL, + offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, shop = True), + DS3LocationData("US: Soul Greatsword", "Soul Greatsword", DS3LocationCategory.SPELL, + offline = '99,0:-1:50000,110000,70000450,70000475:', missable = True, npc = True, shop = True), + DS3LocationData("US: Dark Hand", "Dark Hand", DS3LocationCategory.WEAPON, + missable = True, npc = True), + DS3LocationData("US: Untrue White Ring", "Untrue White Ring", DS3LocationCategory.RING, + missable = True, npc = True), + DS3LocationData("US: Untrue Dark Ring", "Untrue Dark Ring", DS3LocationCategory.RING, + missable = True, npc = True), + DS3LocationData("US: Londor Braille Divine Tome", "Londor Braille Divine Tome", DS3LocationCategory.MISC, + missable = True, npc = True), + DS3LocationData("US: Darkdrift", "Darkdrift", DS3LocationCategory.WEAPON, + missable = True, npc = True), # kill her or kill Soul of Cinder + + # Cornyx of the Great Swamp + # These aren't missable because the Shrine Handmaid will carry them if you kill Cornyx. + DS3LocationData("US: Fireball", "Fireball", DS3LocationCategory.SPELL, + npc = True, shop = True), + DS3LocationData("US: Fire Surge", "Fire Surge", DS3LocationCategory.SPELL, + npc = True, shop = True), + DS3LocationData("US: Great Combustion", "Great Combustion", DS3LocationCategory.SPELL, + npc = True, shop = True), + DS3LocationData("US: Flash Sweat", "Flash Sweat", DS3LocationCategory.SPELL, + npc = True, shop = True), + DS3LocationData("US: Pyromancer Crown", "Pyromancer Crown", DS3LocationCategory.ARMOR, + npc = True, shop = True), + DS3LocationData("US: Pyromancer Garb", "Pyromancer Garb", DS3LocationCategory.ARMOR, + npc = True, shop = True), + DS3LocationData("US: Pyromancer Wrap", "Pyromancer Wrap", DS3LocationCategory.ARMOR, + npc = True, shop = True), + DS3LocationData("US: Pyromancer Trousers", "Pyromancer Trousers", DS3LocationCategory.ARMOR, + npc = True, shop = True), + # These are missable if you kill Cornyx before giving him the right tomes. + DS3LocationData("US: Poison Mist", "Poison Mist", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("US: Fire Orb", "Fire Orb", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("US: Profuse Sweat", "Profuse Sweat", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("US: Bursting Fireball", "Bursting Fireball", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("US: Acid Surge", "Acid Surge", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("US: Carthus Flame Arc", "Carthus Flame Arc", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("US: Carthus Beacon", "Carthus Beacon", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("US: Great Chaos Fire Orb", "Great Chaos Fire Orb", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("US: Chaos Storm", "Chaos Storm", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + + # Irina of Carim + # These aren't in their own location because you don't actually need the Grave Key to access + # Irena—you can just fall down the cliff near Eygon. + DS3LocationData("US: Saint's Ring", "Saint's Ring", DS3LocationCategory.RING, + npc = True, shop = True), + DS3LocationData("US: Heal", "Heal", DS3LocationCategory.SPELL, + npc = True, shop = True), + DS3LocationData("US: Replenishment", "Replenishment", DS3LocationCategory.SPELL, + npc = True, shop = True), + DS3LocationData("US: Caressing Tears", "Caressing Tears", DS3LocationCategory.SPELL, + npc = True, shop = True), + DS3LocationData("US: Homeward", "Homeward", DS3LocationCategory.SPELL, + npc = True, shop = True), + DS3LocationData("US: Med Heal", "Med Heal", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("US: Tears of Denial", "Tears of Denial", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("US: Force", "Force", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("US: Bountiful Light", "Bountiful Light", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("US: Magic Barrier", "Magic Barrier", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("US: Blessed Weapon", "Blessed Weapon", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + # You can also get these from Karla + DS3LocationData("US: Gnaw", "Gnaw", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("US: Deep Protection", "Deep Protection", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("US: Vow of Silence", "Vow of Silence", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("US: Dark Blade", "Dark Blade", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("US: Dead Again", "Dead Again", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), ], "Road of Sacrifices": [ - DS3LocationData("RS: Brigand Twindaggers", "Brigand Twindaggers", DS3LocationCategory.WEAPON), - DS3LocationData("RS: Brigand Hood", "Brigand Hood", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Brigand Armor", "Brigand Armor", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Brigand Gauntlets", "Brigand Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Brigand Trousers", "Brigand Trousers", DS3LocationCategory.ARMOR), + DS3LocationData("RS: Soul of a Crystal Sage", "Soul of a Crystal Sage", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("RS: Exile Greatsword", "Exile Greatsword", DS3LocationCategory.WEAPON, + hostile_npc = True), # Exile Knight #2 drop + DS3LocationData("RS: Great Club", "Great Club", DS3LocationCategory.WEAPON, + hostile_npc = True), # Exile Knight #1 drop + DS3LocationData("RS: Heysel Pick", "Heysel Pick", DS3LocationCategory.WEAPON, + missable = True, hostile_npc = True), # Heysel drop + DS3LocationData("RS: Xanthous Crown", "Xanthous Crown", DS3LocationCategory.WEAPON, + missable = True, hostile_npc = True), # Heysel drop DS3LocationData("RS: Butcher Knife", "Butcher Knife", DS3LocationCategory.WEAPON, hidden = True), # Guaranteed drop from a normal-looking Butcher - DS3LocationData("RS: Brigand Axe", "Brigand Axe", DS3LocationCategory.WEAPON), - DS3LocationData("RS: Braille Divine Tome of Carim", "Braille Divine Tome of Carim", DS3LocationCategory.MISC, - hidden = True), # Hidden fall - DS3LocationData("RS: Morne's Ring", "Morne's Ring", DS3LocationCategory.RING, - hidden = True), # Hidden fall - DS3LocationData("RS: Twin Dragon Greatshield", "Twin Dragon Greatshield", DS3LocationCategory.SHIELD), + DS3LocationData("RS: Titanite Shard #1", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("RS: Titanite Shard #2", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("RS: Green Blossom #1", "Green Blossom x4", DS3LocationCategory.MISC), + DS3LocationData("RS: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), + DS3LocationData("RS: Ring of Sacrifice", "Ring of Sacrifice", DS3LocationCategory.MISC, + hidden = True), # hidden fall + DS3LocationData("RS: Soul of an Unknown Traveler #1", "Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("RS: Fallen Knight Helm", "Fallen Knight Helm", DS3LocationCategory.ARMOR), + DS3LocationData("RS: Fallen Knight Armor", "Fallen Knight Armor", DS3LocationCategory.ARMOR), + DS3LocationData("RS: Fallen Knight Gauntlets", "Fallen Knight Gauntlets", DS3LocationCategory.ARMOR), + DS3LocationData("RS: Fallen Knight Trousers", "Fallen Knight Trousers", DS3LocationCategory.ARMOR), DS3LocationData("RS: Heretic's Staff", "Heretic's Staff", DS3LocationCategory.WEAPON), + DS3LocationData("RS: Large Soul of an Unknown Traveler", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("RS: Conjurator Hood", "Conjurator Hood", DS3LocationCategory.ARMOR), + DS3LocationData("RS: Conjurator Robe", "Conjurator Robe", DS3LocationCategory.ARMOR), + DS3LocationData("RS: Conjurator Manchettes", "Conjurator Manchettes", DS3LocationCategory.ARMOR), + DS3LocationData("RS: Conjurator Boots", "Conjurator Boots", DS3LocationCategory.ARMOR), + DS3LocationData("RS: Soul of an Unknown Traveler #2", "Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("RS: Green Blossom #2", "Green Blossom x2", DS3LocationCategory.MISC), + DS3LocationData("RS: Great Swamp Pyromancy Tome", "Great Swamp Pyromancy Tome", DS3LocationCategory.MISC), + DS3LocationData("RS: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC), + DS3LocationData("RS: Titanite Shard #3", "Titanite Shard", DS3LocationCategory.MISC), + DS3LocationData("RS: Twin Dragon Greatshield", "Twin Dragon Greatshield", DS3LocationCategory.SHIELD), DS3LocationData("RS: Sorcerer Hood", "Sorcerer Hood", DS3LocationCategory.ARMOR, hidden = True), # Hidden fall DS3LocationData("RS: Sorcerer Robe", "Sorcerer Robe", DS3LocationCategory.ARMOR, @@ -311,107 +784,344 @@ def get_name_to_id() -> dict: hidden = True), # Hidden fall DS3LocationData("RS: Sage Ring", "Sage Ring", DS3LocationCategory.RING, hidden = True), # Hidden fall - DS3LocationData("RS: Fallen Knight Helm", "Fallen Knight Helm", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Fallen Knight Armor", "Fallen Knight Armor", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Fallen Knight Gauntlets", "Fallen Knight Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Fallen Knight Trousers", "Fallen Knight Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Conjurator Hood", "Conjurator Hood", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Conjurator Robe", "Conjurator Robe", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Conjurator Manchettes", "Conjurator Manchettes", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Conjurator Boots", "Conjurator Boots", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Great Swamp Pyromancy Tome", "Great Swamp Pyromancy Tome", DS3LocationCategory.MISC), - DS3LocationData("RS: Great Club", "Great Club", DS3LocationCategory.WEAPON, - hostile_npc = True), # Exile Knight #1 drop - DS3LocationData("RS: Exile Greatsword", "Exile Greatsword", DS3LocationCategory.WEAPON, - hostile_npc = True), # Exile Knight #2 drop - DS3LocationData("RS: Farron Coal", "Farron Coal", DS3LocationCategory.MISC), + DS3LocationData("RS: Grass Crest Shield", "Grass Crest Shield", DS3LocationCategory.SHIELD), + DS3LocationData("RS: Ember #1", "Ember", DS3LocationCategory.MISC), + DS3LocationData("RS: Blue Bug Pellet", "Blue Bug Pellet x2", DS3LocationCategory.MISC), + DS3LocationData("RS: Soul of an Unknown Traveler #3", "Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("RS: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), + DS3LocationData("RS: Titanite Shard #4", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("RS: Brigand Twindaggers", "Brigand Twindaggers", DS3LocationCategory.WEAPON), + DS3LocationData("RS: Braille Divine Tome of Carim", "Braille Divine Tome of Carim", DS3LocationCategory.MISC, + hidden = True), # Hidden fall + DS3LocationData("RS: Ember #2", "Ember", DS3LocationCategory.MISC), DS3LocationData("RS: Sellsword Twinblades", "Sellsword Twinblades", DS3LocationCategory.WEAPON), + DS3LocationData("RS: Golden Falcon Shield", "Golden Falcon Shield", DS3LocationCategory.SHIELD), + DS3LocationData("RS: Brigand Axe", "Brigand Axe", DS3LocationCategory.WEAPON), + DS3LocationData("RS: Brigand Hood", "Brigand Hood", DS3LocationCategory.ARMOR), + DS3LocationData("RS: Brigand Armor", "Brigand Armor", DS3LocationCategory.ARMOR), + DS3LocationData("RS: Brigand Gauntlets", "Brigand Gauntlets", DS3LocationCategory.ARMOR), + DS3LocationData("RS: Brigand Trousers", "Brigand Trousers", DS3LocationCategory.ARMOR), + DS3LocationData("RS: Morne's Ring", "Morne's Ring", DS3LocationCategory.RING, + hidden = True), # Hidden fall DS3LocationData("RS: Sellsword Helm", "Sellsword Helm", DS3LocationCategory.ARMOR), DS3LocationData("RS: Sellsword Armor", "Sellsword Armor", DS3LocationCategory.ARMOR), DS3LocationData("RS: Sellsword Gauntlet", "Sellsword Gauntlet", DS3LocationCategory.ARMOR), DS3LocationData("RS: Sellsword Trousers", "Sellsword Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Golden Falcon Shield", "Golden Falcon Shield", DS3LocationCategory.SHIELD), - DS3LocationData("RS: Herald Helm", "Herald Helm", DS3LocationCategory.ARMOR, - offline = "03,0:53300740::"), - DS3LocationData("RS: Herald Armor", "Herald Armor", DS3LocationCategory.ARMOR, - offline = "03,0:53300740::"), - DS3LocationData("RS: Herald Gloves", "Herald Gloves", DS3LocationCategory.ARMOR, - offline = "03,0:53300740::"), - DS3LocationData("RS: Herald Trousers", "Herald Trousers", DS3LocationCategory.ARMOR, - offline = "03,0:53300740::"), - DS3LocationData("RS: Grass Crest Shield", "Grass Crest Shield", DS3LocationCategory.SHIELD), - DS3LocationData("RS: Soul of a Crystal Sage", "Soul of a Crystal Sage", DS3LocationCategory.BOSS, - prominent = True, boss = True), + DS3LocationData("RS: Farron Coal", "Farron Coal", DS3LocationCategory.MISC), + DS3LocationData("RS: Chloranthy Ring+2", "Chloranthy Ring+2", DS3LocationCategory.RING, + hidden = True, ngp = True), # Hidden fall + DS3LocationData("RS: Lingering Dragoncrest Ring+1", "Lingering Dragoncrest Ring+1", DS3LocationCategory.RING, + ngp = True), DS3LocationData("RS: Great Swamp Ring", "Great Swamp Ring", DS3LocationCategory.RING, miniboss = True), # Giant Crab drop - DS3LocationData("RS: Orbeck's Ashes", "Orbeck's Ashes", DS3LocationCategory.KEY, - npc = True), + DS3LocationData("RS: Blue Sentinels", "Blue Sentinels", DS3LocationCategory.MISC, + missable = True, npc = True), # Horace quest + DS3LocationData("RS: Crystal Gem", "Crystal Gem", DS3LocationCategory.UPGRADE), + + # Orbeck shop, all missable because he'll disappear if you don't talk to him for too long or + # if you don't give him a scroll. + DS3LocationData("RS: Farron Dart", "Farron Dart", DS3LocationCategory.SPELL, + offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), + DS3LocationData("RS: Soul Arrow", "Soul Arrow", DS3LocationCategory.SPELL, + offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), + DS3LocationData("RS: Great Soul Arrow", "Great Soul Arrow", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Heavy Soul Arrow", "Heavy Soul Arrow", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Great Heavy Soul Arrow", "Great Heavy Soul Arrow", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Magic Weapon", "Magic Weapon", DS3LocationCategory.SPELL, + offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), + DS3LocationData("RS: Magic Shield", "Magic Shield", DS3LocationCategory.SPELL, + offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), + DS3LocationData("RS: Spook", "Spook", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Aural Decoy", "Aural Decoy", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Soul Greatsword", "Soul Greatsword", DS3LocationCategory.SPELL, + offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True), + DS3LocationData("RS: Farron Flashsword", "Farron Flashsword", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Pestilent Mist", "Pestilent Mist", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Great Farron Dart", "Great Farron Dart", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Farron Hail", "Farron Hail", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Homing Soulmass", "Homing Soulmass", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Soul Spear", "Soul Spear", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Homing Crystal Soulmass", "Homing Crystal Soulmass", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Crystal Soul Spear", "Crystal Soul Spear", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Crystal Magic Weapon", "Crystal Magic Weapon", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Cast Light", "Cast Light", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Twisted Wall of Light", "Twisted Wall of Light", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Hidden Weapon", "Hidden Weapon", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Hidden Body", "Hidden Body", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Repair", "Repair", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("RS: Clandestine Coat", "Clandestine Coat", DS3LocationCategory.ARMOR, + missable = True, npc = True, shop = True), # Shrine Handmaid with Orbeck's Ashes + reload + DS3LocationData("RS: Young Dragon Ring", "Young Dragon Ring", DS3LocationCategory.RING, + missable = True, npc = True), + DS3LocationData("RS: Slumbering Dragoncrest Ring", "Slumbering Dragoncrest Ring", DS3LocationCategory.RING, + missable = True, npc = True), + DS3LocationData("RS: Crystal Sage's Rapier", "Crystal Sage's Rapier", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("RS: Crystal Hail", "Crystal Hail", DS3LocationCategory.SPELL, + missable = True, boss = True, shop = True), + DS3LocationData("RS: Farron Greatsword", "Farron Greatsword", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("RS: Wolf Knight's Greatsword", "Wolf Knight's Greatsword", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + + # Shrine Handmaid after killing Crystal Sage + DS3LocationData("RS: Sage's Big Hat", "Sage's Big Hat", DS3LocationCategory.ARMOR, + boss = True, shop = True), + + # Yuria of Londor for Orbeck's Ashes + DS3LocationData("RS: Morion Blade", "Morion Blade", DS3LocationCategory.WEAPON, + missable = True, npc = True), + + # Hawkwood after killing Abyss Watchers + DS3LocationData("RS: Farron Ring", "Farron Ring", DS3LocationCategory.RING, + missable = True, npc = True), ], "Cathedral of the Deep": [ - DS3LocationData("CD: Paladin's Ashes", "Paladin's Ashes", DS3LocationCategory.MISC), + DS3LocationData("CD: Herald Helm", "Herald Helm", DS3LocationCategory.ARMOR), + DS3LocationData("CD: Herald Armor", "Herald Armor", DS3LocationCategory.ARMOR), + DS3LocationData("CD: Herald Gloves", "Herald Gloves", DS3LocationCategory.ARMOR), + DS3LocationData("CD: Herald Trousers", "Herald Trousers", DS3LocationCategory.ARMOR), + DS3LocationData("CD: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("CD: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("CD: Small Doll", "Small Doll", DS3LocationCategory.KEY, + prominent = True, progression = True, boss = True), + DS3LocationData("CD: Soul of the Deacons of the Deep", "Soul of the Deacons of the Deep", DS3LocationCategory.BOSS, + boss = True), + DS3LocationData("CD: Black Eye Orb", "Black Eye Orb", DS3LocationCategory.MISC, + missable = True, npc = True), + DS3LocationData("CD: Winged Spear #1", "Winged Spear", DS3LocationCategory.WEAPON, + missable = True), # Patches (kill) DS3LocationData("CD: Spider Shield", "Spider Shield", DS3LocationCategory.SHIELD, hostile_npc = True), # Brigand - DS3LocationData("CD: Crest Shield", "Crest Shield", DS3LocationCategory.SHIELD), DS3LocationData("CD: Notched Whip", "Notched Whip", DS3LocationCategory.WEAPON), + DS3LocationData("CD: Titanite Shard #1", "Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("CD: Astora Greatsword", "Astora Greatsword", DS3LocationCategory.WEAPON), DS3LocationData("CD: Executioner's Greatsword", "Executioner's Greatsword", DS3LocationCategory.WEAPON), + DS3LocationData("CD: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), DS3LocationData("CD: Curse Ward Greatshield", "Curse Ward Greatshield", DS3LocationCategory.SHIELD), - DS3LocationData("CD: Saint-tree Bellvine", "Saint-tree Bellvine", DS3LocationCategory.WEAPON), + DS3LocationData("CD: Titanite Shard #2", "Titanite Shard", DS3LocationCategory.MISC), + DS3LocationData("CD: Large Soul of an Unknown Traveler #1", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("CD: Paladin's Ashes", "Paladin's Ashes", DS3LocationCategory.KEY, + progression = True), + DS3LocationData("CD: Arbalest", "Arbalest", DS3LocationCategory.WEAPON, + hidden = True), # Hidden fall + DS3LocationData("CD: Ember #1", "Ember", DS3LocationCategory.MISC), + DS3LocationData("CD: Ember #2", "Ember", DS3LocationCategory.MISC), DS3LocationData("CD: Poisonbite Ring", "Poisonbite Ring", DS3LocationCategory.RING), - DS3LocationData("CD: Lloyd's Sword Ring", "Lloyd's Sword Ring", DS3LocationCategory.RING), + DS3LocationData("CD: Drang Armor", "Drang Armor", DS3LocationCategory.ARMOR), + DS3LocationData("CD: Ember #3", "Ember", DS3LocationCategory.MISC), + DS3LocationData("CD: Duel Charm #1", "Duel Charm x3", DS3LocationCategory.MISC), DS3LocationData("CD: Seek Guidance", "Seek Guidance", DS3LocationCategory.SPELL), - DS3LocationData("CD: Aldrich's Sapphire", "Aldrich's Sapphire", DS3LocationCategory.RING, - offline = "06,0:50002130::", miniboss = True), # Deep Accursed Drop - DS3LocationData("CD: Deep Braille Divine Tome", "Deep Braille Divine Tome", DS3LocationCategory.MISC, - mimic = True), - DS3LocationData("CD: Saint Bident", "Saint Bident", DS3LocationCategory.WEAPON, - miniboss = True), # Guarded by giant + DS3LocationData("CD: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), DS3LocationData("CD: Maiden Hood", "Maiden Hood", DS3LocationCategory.ARMOR), DS3LocationData("CD: Maiden Robe", "Maiden Robe", DS3LocationCategory.ARMOR), DS3LocationData("CD: Maiden Gloves", "Maiden Gloves", DS3LocationCategory.ARMOR), DS3LocationData("CD: Maiden Skirt", "Maiden Skirt", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Drang Armor", "Drang Armor", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Drang Gauntlets", "Drang Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Drang Shoes", "Drang Shoes", DS3LocationCategory.ARMOR), + DS3LocationData("CD: Pale Tongue #1", "Pale Tongue", DS3LocationCategory.MISC, + hidden = True), # hidden fall + DS3LocationData("CD: Fading Soul", "Fading Soul", DS3LocationCategory.MISC), + DS3LocationData("CD: Blessed Gem", "Blessed Gem", DS3LocationCategory.UPGRADE, + hidden = True), # hidden fall + DS3LocationData("CD: Red Bug Pellet #1", "Red Bug Pellet", DS3LocationCategory.MISC), + DS3LocationData("CD: Soul of a Nameless Soldier #1", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("CD: Duel Charm #2", "Duel Charm", DS3LocationCategory.MISC), + DS3LocationData("CD: Large Soul of an Unknown Traveler #2", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("CD: Ember #4", "Ember", DS3LocationCategory.MISC), + DS3LocationData("CD: Repair Powder", "Repair Powder x3", DS3LocationCategory.MISC), + DS3LocationData("CD: Large Soul of an Unknown Traveler #3", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("CD: Large Soul of an Unknown Traveler #4", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("CD: Undead Hunter Charm", "Undead Hunter Charm x3", DS3LocationCategory.MISC, + hidden = True), # Have to jump from a buttress + DS3LocationData("CD: Red Bug Pellet #2", "Red Bug Pellet x3", DS3LocationCategory.MISC), + DS3LocationData("CD: Titanite Shard #3", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("CD: Titanite Shard #4", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("CD: Rusted Coin #1", "Rusted Coin x2", DS3LocationCategory.MISC), DS3LocationData("CD: Drang Hammers", "Drang Hammers", DS3LocationCategory.WEAPON), - DS3LocationData("CD: Deep Ring", "Deep Ring", DS3LocationCategory.RING, - hidden = True), # Guaranteed drop from a normal-looking Deacon + DS3LocationData("CD: Drang Shoes", "Drang Shoes", DS3LocationCategory.ARMOR), + DS3LocationData("CD: Large Soul of an Unknown Traveler #5", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("CD: Pale Tongue #2", "Pale Tongue", DS3LocationCategory.MISC), + DS3LocationData("CD: Drang Gauntlets", "Drang Gauntlets", DS3LocationCategory.ARMOR), + DS3LocationData("CD: Soul of a Nameless Soldier #2", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("CD: Exploding Bolt", "Exploding Bolt x6", DS3LocationCategory.MISC), + DS3LocationData("CD: Lloyd's Sword Ring", "Lloyd's Sword Ring", DS3LocationCategory.RING), + DS3LocationData("CD: Soul of a Nameless Soldier #3", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("CD: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC), + DS3LocationData("CD: Deep Gem", "Deep Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("CD: Titanite Shard #5", "Titanite Shard", DS3LocationCategory.MISC), + DS3LocationData("CD: Large Soul of an Unknown Traveler #6", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + # Before the stairs leading down into the Deacons fight + DS3LocationData("CD: Ring of the Evil Eye+1", "Ring of the Evil Eye+1", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("CD: Ring of Favor+2", "Ring of Favor+2", DS3LocationCategory.RING, + hidden = True, ngp = True), # Hidden fall + DS3LocationData("CD: Crest Shield", "Crest Shield", DS3LocationCategory.SHIELD, + hidden = True), # Hidden fall + DS3LocationData("CD: Young White Branch #1", "Young White Branch", DS3LocationCategory.MISC), + DS3LocationData("CD: Young White Branch #2", "Young White Branch", DS3LocationCategory.MISC), + DS3LocationData("CD: Saint-tree Bellvine", "Saint-tree Bellvine", DS3LocationCategory.WEAPON), + DS3LocationData("CD: Saint Bident", "Saint Bident", DS3LocationCategory.WEAPON), DS3LocationData("CD: Archdeacon White Crown", "Archdeacon White Crown", DS3LocationCategory.ARMOR, boss = True, hidden = True), # Have to return to a cleared area DS3LocationData("CD: Archdeacon Holy Garb", "Archdeacon Holy Garb", DS3LocationCategory.ARMOR, boss = True, hidden = True), # Have to return to a cleared area DS3LocationData("CD: Archdeacon Skirt", "Archdeacon Skirt", DS3LocationCategory.ARMOR, boss = True, hidden = True), # Have to return to a cleared area - DS3LocationData("CD: Arbalest", "Arbalest", DS3LocationCategory.WEAPON, - hidden = True), # Hidden fall - DS3LocationData("CD: Small Doll", "Small Doll", DS3LocationCategory.KEY, - prominent = True, progression = True, boss = True), - DS3LocationData("CD: Soul of the Deacons of the Deep", "Soul of the Deacons of the Deep", DS3LocationCategory.BOSS, - boss = True), + DS3LocationData("CD: Heysel Pick", "Heysel Pick", DS3LocationCategory.WEAPON, + missable = True), + DS3LocationData("CD: Xanthous Crown", "Xanthous Crown", DS3LocationCategory.WEAPON, + missable = True), + DS3LocationData("CD: Deep Ring", "Deep Ring", DS3LocationCategory.RING, + hidden = True), # Guaranteed drop from a normal-looking Deacon + DS3LocationData("CD: Deep Braille Divine Tome", "Deep Braille Divine Tome", DS3LocationCategory.MISC, + mimic = True), + DS3LocationData("CD: Red Sign Soapstone", "Red Sign Soapstone", DS3LocationCategory.MISC, + hidden = True), # Guaranteed drop from a normal-looking Corpse-grub + DS3LocationData("CD: Aldrich's Sapphire", "Aldrich's Sapphire", DS3LocationCategory.RING, + miniboss = True), # Deep Accursed Drop + DS3LocationData("CD: Dung Pie", "Dung Pie x4", DS3LocationCategory.MISC, + miniboss = True), # Giant Slave drop + DS3LocationData("CD: Large Titanite Shard", "Large Titanite Shard", DS3LocationCategory.UPGRADE, + miniboss = True), # Giant Slave drop + DS3LocationData("CD: Titanite Scale", "Titanite Scale", DS3LocationCategory.UPGRADE, + miniboss = True), # Ravenous Crystal Lizard drop + DS3LocationData("CD: Twinkling Titanite #3", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("CD: Twinkling Titanite #4", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), DS3LocationData("CD: Rosaria's Fingers", "Rosaria's Fingers", DS3LocationCategory.MISC, - hidden = True) # Hidden fall + hidden = True), # Hidden fall + DS3LocationData("CD: Cleric's Candlestick", "Cleric's Candlestick", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("CD: Deep Soul", "Deep Soul", DS3LocationCategory.SPELL, + missable = True, boss = True, shop = True), + + # Longfinger Kirk drops + DS3LocationData("CD: Barbed Straight Sword", "Barbed Straight Sword", DS3LocationCategory.WEAPON, + missable = True, hostile_npc = True), + DS3LocationData("CD: Spiked Shield", "Spiked Shield", DS3LocationCategory.SHIELD, + missable = True, hostile_npc = True), + # In Rosaria's Bed Chamber + DS3LocationData("CD: Helm of Thorns", "Helm of Thorns", DS3LocationCategory.ARMOR, + missable = True, hostile_npc = True), + DS3LocationData("CD: Armor of Thorns", "Armor of Thorns", DS3LocationCategory.ARMOR, + missable = True, hostile_npc = True), + DS3LocationData("CD: Gauntlets of Thorns", "Gauntlets of Thorns", DS3LocationCategory.ARMOR, + missable = True, hostile_npc = True), + DS3LocationData("CD: Leggings of Thorns", "Leggings of Thorns", DS3LocationCategory.ARMOR, + missable = True, hostile_npc = True), + + # Unbreakable Patches + DS3LocationData("CD: Rusted Coin #2", "Rusted Coin", DS3LocationCategory.MISC, + missable = True, npc = True), + DS3LocationData("CD: Rusted Gold Coin", "Rusted Gold Coin", DS3LocationCategory.MISC, + offline = '99,0:50006201::', missable = True, npc = True), # Don't forgive Patches + DS3LocationData("CD: Shotel", "Shotel", DS3LocationCategory.WEAPON, + missable = True, npc = True, shop = True), + DS3LocationData("CD: Ember #5", "Ember", DS3LocationCategory.MISC, + missable = True, npc = True, shop = True), + DS3LocationData("CD: Hidden Blessing", "Hidden Blessing", DS3LocationCategory.MISC, + missable = True, npc = True, shop = True), + DS3LocationData("CD: Horsehoof Ring", "Horsehoof Ring", DS3LocationCategory.RING, + missable = True, npc = True, shop = True), # (kill or buy) ], "Farron Keep": [ - DS3LocationData("FK: Ragged Mask", "Ragged Mask", DS3LocationCategory.ARMOR), + DS3LocationData("FK: Lightning Spear", "Lightning Spear", DS3LocationCategory.WEAPON), + DS3LocationData("FK: Dragon Crest Shield", "Dragon Crest Shield", DS3LocationCategory.SHIELD), + DS3LocationData("FK: Soul of the Blood of the Wolf", "Soul of the Blood of the Wolf", DS3LocationCategory.BOSS, + boss = True), + DS3LocationData("FK: Cinders of a Lord - Abyss Watcher", "Cinders of a Lord - Abyss Watcher", DS3LocationCategory.KEY, + offline = "03,0:50002100::", prominent = True, progression = True, boss = True), + DS3LocationData("FK: Manikin Claws", "Manikin Claws", DS3LocationCategory.WEAPON, + missable = True, hostile_npc = True, npc = True), # Londor Pale Shade (if Yoel/Yuria hostile) + DS3LocationData("FK: Purple Moss Clump #1", "Purple Moss Clump x2", DS3LocationCategory.MISC), + DS3LocationData("FK: Purple Moss Clump #2", "Purple Moss Clump x4", DS3LocationCategory.MISC), + DS3LocationData("FK: Greatsword", "Greatsword", DS3LocationCategory.WEAPON), + DS3LocationData("FK: Hollow Gem", "Hollow Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Fading Soul", "Fading Soul", DS3LocationCategory.MISC), + DS3LocationData("FK: Purple Moss Clump #3", "Purple Moss Clump x3", DS3LocationCategory.MISC), + DS3LocationData("FK: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), + DS3LocationData("FK: Atonement", "Atonement", DS3LocationCategory.SPELL, + hidden = True), # Hidden fall + DS3LocationData("FK: Titanite Shard #1", "Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("FK: Iron Flesh", "Iron Flesh", DS3LocationCategory.SPELL), + DS3LocationData("FK: Stone Parma", "Stone Parma", DS3LocationCategory.SHIELD), + DS3LocationData("FK: Rotten Pine Resin #1", "Rotten Pine Resin x2", DS3LocationCategory.MISC), + DS3LocationData("FK: Titanite Shard #2", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Rusted Gold Coin", "Rusted Gold Coin", DS3LocationCategory.MISC, + hidden = True), # Hidden behind a wall + DS3LocationData("FK: Nameless Knight Helm", "Nameless Knight Helm", DS3LocationCategory.ARMOR), + DS3LocationData("FK: Nameless Knight Armor", "Nameless Knight Armor", DS3LocationCategory.ARMOR), + DS3LocationData("FK: Nameless Knight Gauntlets", "Nameless Knight Gauntlets", DS3LocationCategory.ARMOR), + DS3LocationData("FK: Nameless Knight Leggings", "Nameless Knight Leggings", DS3LocationCategory.ARMOR), + DS3LocationData("FK: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Repair Powder", "Repair Powder x4", DS3LocationCategory.MISC, + hidden = True), # Out-of-the-way hard-to-see cave DS3LocationData("FK: Golden Scroll", "Golden Scroll", DS3LocationCategory.MISC, hostile_npc = True), # Out-of-the-way hard-to-see cave + DS3LocationData("FK: Sage's Scroll", "Sage's Scroll", DS3LocationCategory.MISC), + DS3LocationData("FK: Dreamchaser's Ashes", "Dreamchaser's Ashes", DS3LocationCategory.KEY, + progression = True, hidden = True), # Behind illusory wall + DS3LocationData("FK: Titanite Shard #3", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Wolf's Blood Swordgrass", "Wolf's Blood Swordgrass", DS3LocationCategory.MISC), + DS3LocationData("FK: Great Magic Weapon", "Great Magic Weapon", DS3LocationCategory.SPELL), + DS3LocationData("FK: Ember #1", "Ember", DS3LocationCategory.MISC), + DS3LocationData("FK: Titanite Shard #4", "Titanite Shard x2", DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Titanite Shard #5", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Titanite Shard #6", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Black Bug Pellet", "Black Bug Pellet x3", DS3LocationCategory.MISC), + DS3LocationData("FK: Rotten Pine Resin #2", "Rotten Pine Resin x4", DS3LocationCategory.MISC), + DS3LocationData("FK: Poison Gem", "Poison Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Ragged Mask", "Ragged Mask", DS3LocationCategory.ARMOR), + DS3LocationData("FK: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), + DS3LocationData("FK: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.HEALTH), + DS3LocationData("FK: Titanite Shard #7", "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("FK: Prism Stone", "Prism Stone x10", DS3LocationCategory.MISC), + DS3LocationData("FK: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("FK: Sage's Coal", "Sage's Coal", DS3LocationCategory.MISC), + DS3LocationData("FK: Gold Pine Bundle", "Gold Pine Bundle x6", DS3LocationCategory.MISC), + DS3LocationData("FK: Ember #2", "Ember", DS3LocationCategory.MISC), + DS3LocationData("FK: Soul of a Nameless Soldier", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("FK: Large Soul of an Unknown Traveler", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("FK: Greataxe", "Greataxe", DS3LocationCategory.WEAPON), + DS3LocationData("FK: Ember #3", "Ember", DS3LocationCategory.MISC), + DS3LocationData("FK: Ember #4", "Ember", DS3LocationCategory.MISC), + DS3LocationData("FK: Dark Stoneplate Ring+2", "Dark Stoneplate Ring+2", DS3LocationCategory.RING, + hidden = True, ngp = True), # Hidden behind wall + DS3LocationData("FK: Magic Stoneplate Ring+1", "Magic Stoneplate Ring+1", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("FK: Wolf Ring+1", "Wolf Ring+1", DS3LocationCategory.RING, + ngp = True), DS3LocationData("FK: Antiquated Dress", "Antiquated Dress", DS3LocationCategory.ARMOR, hostile_npc = True), # Out-of-the-way hard-to-see cave DS3LocationData("FK: Antiquated Gloves", "Antiquated Gloves", DS3LocationCategory.ARMOR, hostile_npc = True), # Out-of-the-way hard-to-see cave DS3LocationData("FK: Antiquated Skirt", "Antiquated Skirt", DS3LocationCategory.ARMOR, hostile_npc = True), # Out-of-the-way hard-to-see cave - DS3LocationData("FK: Nameless Knight Helm", "Nameless Knight Helm", DS3LocationCategory.ARMOR), - DS3LocationData("FK: Nameless Knight Armor", "Nameless Knight Armor", DS3LocationCategory.ARMOR), - DS3LocationData("FK: Nameless Knight Gauntlets", "Nameless Knight Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("FK: Nameless Knight Leggings", "Nameless Knight Leggings", DS3LocationCategory.ARMOR), DS3LocationData("FK: Sunlight Talisman", "Sunlight Talisman", DS3LocationCategory.WEAPON), - DS3LocationData("FK: Wolf's Blood Swordgrass", "Wolf's Blood Swordgrass", DS3LocationCategory.MISC), - DS3LocationData("FK: Greatsword", "Greatsword", DS3LocationCategory.WEAPON), - DS3LocationData("FK: Sage's Coal", "Sage's Coal", DS3LocationCategory.MISC), - DS3LocationData("FK: Stone Parma", "Stone Parma", DS3LocationCategory.SHIELD), - DS3LocationData("FK: Sage's Scroll", "Sage's Scroll", DS3LocationCategory.MISC), + DS3LocationData("FK: Young White Branch #1", "Young White Branch", DS3LocationCategory.MISC), + DS3LocationData("FK: Young White Branch #2", "Young White Branch", DS3LocationCategory.MISC), DS3LocationData("FK: Crown of Dusk", "Crown of Dusk", DS3LocationCategory.ARMOR), DS3LocationData("FK: Lingering Dragoncrest Ring", "Lingering Dragoncrest Ring", DS3LocationCategory.RING, miniboss = True), # Great Crab drop @@ -419,403 +1129,1475 @@ def get_name_to_id() -> dict: hidden = True), # Guaranteed drop from a normal-looking Elder Ghru DS3LocationData("FK: Black Bow of Pharis", "Black Bow of Pharis", DS3LocationCategory.WEAPON, hidden = True), # Guaranteed drop from a normal-looking Elder Ghru - DS3LocationData("FK: Dreamchaser's Ashes", "Dreamchaser's Ashes", DS3LocationCategory.MISC, - hidden = True), # Behind invisible wall - DS3LocationData("FK: Greataxe", "Greataxe", DS3LocationCategory.WEAPON), - DS3LocationData("FK: Dragon Crest Shield", "Dragon Crest Shield", DS3LocationCategory.SHIELD), - DS3LocationData("FK: Lightning Spear", "Lightning Spear", DS3LocationCategory.SPELL), - DS3LocationData("FK: Atonement", "Atonement", DS3LocationCategory.SPELL, - hidden = True), # Hidden fall - DS3LocationData("FK: Great Magic Weapon", "Great Magic Weapon", DS3LocationCategory.SPELL), - DS3LocationData("FK: Cinders of a Lord - Abyss Watcher", "Cinders of a Lord - Abyss Watcher", DS3LocationCategory.KEY, - offline = "03,0:50002100::", prominent = True, progression = True, boss = True), - DS3LocationData("FK: Soul of the Blood of the Wolf", "Soul of the Blood of the Wolf", DS3LocationCategory.BOSS, - boss = True), + DS3LocationData("FK: Titanite Scale", "Titanite Scale x2", DS3LocationCategory.UPGRADE, + miniboss = True), # Ravenous Crystal Lizard drop + DS3LocationData("FK: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Heavy Gem", "Heavy Gem", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("FK: Twinkling Titanite", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), DS3LocationData("FK: Soul of a Stray Demon", "Soul of a Stray Demon", DS3LocationCategory.BOSS, miniboss = True), DS3LocationData("FK: Watchdogs of Farron", "Watchdogs of Farron", DS3LocationCategory.MISC), + DS3LocationData("FK: Hawkwood's Shield", "Hawkwood's Shield", DS3LocationCategory.SHIELD, + missable = True, npc = True), # Hawkwood (quest, after Greatwood, Sage, Watchers, and Deacons) + DS3LocationData("FK: Havel's Ring", "Havel's Ring", DS3LocationCategory.RING, + missable = True, boss = True, shop = True), + DS3LocationData("FK: Boulder Heave", "Boulder Heave", DS3LocationCategory.SPELL, + missable = True, boss = True, shop = True), + + # Shrine Handmaid after killing exiles + DS3LocationData("FK: Exile Mask", "Exile Mask", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True, shop = True), + DS3LocationData("FK: Exile Armor", "Exile Armor", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True, shop = True), + DS3LocationData("FK: Exile Gauntlets", "Exile Gauntlets", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True, shop = True), + DS3LocationData("FK: Exile Leggings", "Exile Leggings", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True, shop = True), + + # Shrine Handmaid after killing Abyss Watchers + DS3LocationData("FK: Undead Legion Helm", "Undead Legion Helm", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("FK: Undead Legion Armor", "Undead Legion Armor", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("FK: Undead Legion Gauntlet", "Undead Legion Gauntlet", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("FK: Undead Legion Leggings", "Undead Legion Leggings", DS3LocationCategory.ARMOR, + boss = True, shop = True), ], "Catacombs of Carthus": [ - DS3LocationData("CC: Carthus Pyromancy Tome", "Carthus Pyromancy Tome", DS3LocationCategory.MISC, - hidden = True), # Behind invisible wall + DS3LocationData("CC: Soul of High Lord Wolnir", "Soul of High Lord Wolnir", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("CC: Carthus Rouge #1", "Carthus Rouge x2", DS3LocationCategory.MISC), + DS3LocationData("CC: Sharp Gem", "Sharp Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("CC: Soul of a Nameless Soldier #1", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("CC: Titanite Shard #1", "Titanite Shard x2", DS3LocationCategory.UPGRADE), + DS3LocationData("CC: Bloodred Moss Clump", "Bloodred Moss Clump x3", DS3LocationCategory.MISC), DS3LocationData("CC: Carthus Milkring", "Carthus Milkring", DS3LocationCategory.RING), - DS3LocationData("CC: Grave Warden's Ashes", "Grave Warden's Ashes", DS3LocationCategory.MISC), + DS3LocationData("CC: Ember #1", "Ember", DS3LocationCategory.MISC), + DS3LocationData("CC: Carthus Rouge #2", "Carthus Rouge x3", DS3LocationCategory.MISC), + DS3LocationData("CC: Ember #2", "Ember", DS3LocationCategory.MISC), DS3LocationData("CC: Carthus Bloodring", "Carthus Bloodring", DS3LocationCategory.RING), - DS3LocationData("CC: Grave Warden Pyromancy Tome", "Grave Warden Pyromancy Tome", DS3LocationCategory.MISC), + DS3LocationData("CC: Titanite Shard #2", "Titanite Shard x2", DS3LocationCategory.UPGRADE), + DS3LocationData("CC: Titanite Shard #3", "Titanite Shard x2", DS3LocationCategory.UPGRADE), + DS3LocationData("CC: Ember #3", "Ember", DS3LocationCategory.MISC), + DS3LocationData("CC: Carthus Pyromancy Tome", "Carthus Pyromancy Tome", DS3LocationCategory.MISC, + hidden = True), # Behind illusory wall + DS3LocationData("CC: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.MISC), + DS3LocationData("CC: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.MISC), + DS3LocationData("CC: Yellow Bug Pellet", "Yellow Bug Pellet x3", DS3LocationCategory.MISC), + DS3LocationData("CC: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("CC: Black Bug Pellet", "Black Bug Pellet x2", DS3LocationCategory.MISC), + DS3LocationData("CC: Grave Warden's Ashes", "Grave Warden's Ashes", DS3LocationCategory.KEY, + progression = True), + DS3LocationData("CC: Large Titanite Shard #3", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("CC: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), DS3LocationData("CC: Old Sage's Blindfold", "Old Sage's Blindfold", DS3LocationCategory.ARMOR), DS3LocationData("CC: Witch's Ring", "Witch's Ring", DS3LocationCategory.RING), + DS3LocationData("CC: Soul of a Nameless Soldier #2", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("CC: Grave Warden Pyromancy Tome", "Grave Warden Pyromancy Tome", DS3LocationCategory.MISC), + DS3LocationData("CC: Large Soul of an Unknown Traveler", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("CC: Ring of Steel Protection+2", "Ring of Steel Protection+2", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("CC: Thunder Stoneplate Ring+1", "Thunder Stoneplate Ring+1", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("CC: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH, + hidden = True), # Skeleton Ball puzzle + DS3LocationData("CC: Dark Gem", "Dark Gem", DS3LocationCategory.UPGRADE, + hidden = True), # Skeleton Ball puzzle DS3LocationData("CC: Black Blade", "Black Blade", DS3LocationCategory.WEAPON, mimic = True), - DS3LocationData("CC: Soul of High Lord Wolnir", "Soul of High Lord Wolnir", DS3LocationCategory.BOSS, - prominent = True, boss = True), DS3LocationData("CC: Soul of a Demon", "Soul of a Demon", DS3LocationCategory.BOSS, miniboss = True), + DS3LocationData("CC: Twinkling Titanite", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("CC: Fire Gem", "Fire Gem", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("CC: Homeward Bone", "Homeward Bone", DS3LocationCategory.MISC), + DS3LocationData("CC: Pontiff's Right Eye", "Pontiff's Right Eye", DS3LocationCategory.RING, + miniboss = True), # Sullyvahn's Beast drop, in CC because it doesn't require Small Doll + DS3LocationData("CC: Wolnir's Holy Sword", "Wolnir's Holy Sword", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("CC: Black Serpent", "Black Serpent", DS3LocationCategory.SPELL, + missable = True, boss = True, shop = True), + DS3LocationData("CC: Demon's Greataxe", "Demon's Greataxe", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("CC: Demon's Fist", "Demon's Fist", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + + # Shrine Handmaid after killing High Lord Wolnir + DS3LocationData("CC: Wolnir's Crown", "Wolnir's Crown", DS3LocationCategory.ARMOR, + boss = True, shop = True), ], "Smouldering Lake": [ - DS3LocationData("SL: Shield of Want", "Shield of Want", DS3LocationCategory.SHIELD), + DS3LocationData("SL: Soul of the Old Demon King", "Soul of the Old Demon King", DS3LocationCategory.BOSS, + prominent = True, boss = True), + + DS3LocationData("SL: Fume Ultra Greatsword", "Fume Ultra Greatsword", DS3LocationCategory.WEAPON, + hostile_npc = True), # Knight Slayer Tsorig drop + DS3LocationData("SL: Black Iron Greatshield", "Black Iron Greatshield", DS3LocationCategory.SHIELD, + hostile_npc = True), # Knight Slayer Tsorig drop + DS3LocationData("SL: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Large Titanite Shard #3", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Large Titanite Shard #4", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Large Titanite Shard #5", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Yellow Bug Pellet", "Yellow Bug Pellet x2", DS3LocationCategory.MISC), + DS3LocationData("SL: Large Titanite Shard #6", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Large Titanite Shard #7", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Large Titanite Shard #8", "Large Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("SL: Speckled Stoneplate Ring", "Speckled Stoneplate Ring", DS3LocationCategory.RING, hidden = True), # Requires careful ballista shot - DS3LocationData("SL: Dragonrider Bow", "Dragonrider Bow", DS3LocationCategory.WEAPON, - hidden = True), # Hidden fall - DS3LocationData("SL: Lightning Stake", "Lightning Stake", DS3LocationCategory.SPELL, - miniboss = True), # Sand Worm drop + DS3LocationData("SL: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC), + DS3LocationData("SL: Ember #1", "Ember", DS3LocationCategory.MISC), + DS3LocationData("SL: Chaos Gem #1", "Chaos Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Ember #2", "Ember", DS3LocationCategory.MISC), DS3LocationData("SL: Izalith Pyromancy Tome", "Izalith Pyromancy Tome", DS3LocationCategory.MISC), - DS3LocationData("SL: Black Knight Sword", "Black Knight Sword", DS3LocationCategory.WEAPON), + DS3LocationData("SL: Black Knight Sword", "Black Knight Sword", DS3LocationCategory.WEAPON, + hidden = True), # Behind illusory wall + DS3LocationData("SL: Ember #3", "Ember", DS3LocationCategory.MISC), DS3LocationData("SL: Quelana Pyromancy Tome", "Quelana Pyromancy Tome", DS3LocationCategory.MISC), - DS3LocationData("SL: Toxic Mist", "Toxic Mist", DS3LocationCategory.SPELL, - hidden = True), # In lava - DS3LocationData("SL: White Hair Talisman", "White Hair Talisman", DS3LocationCategory.WEAPON, - hidden = True), # In lava DS3LocationData("SL: Izalith Staff", "Izalith Staff", DS3LocationCategory.WEAPON, - hidden = True), # Behind invisible wall + hidden = True), # Behind illusory wall + DS3LocationData("SL: White Hair Talisman", "White Hair Talisman", DS3LocationCategory.WEAPON, + missable = True), # In lava + DS3LocationData("SL: Toxic Mist", "Toxic Mist", DS3LocationCategory.SPELL, + missable = True), # In lava + DS3LocationData("SL: Undead Bone Shard #1", "Undead Bone Shard", DS3LocationCategory.HEALTH), + DS3LocationData("SL: Titanite Scale", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Shield of Want", "Shield of Want", DS3LocationCategory.SHIELD), + DS3LocationData("SL: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("SL: Ember #4", "Ember", DS3LocationCategory.MISC, + missable = True), # In lava DS3LocationData("SL: Sacred Flame", "Sacred Flame", DS3LocationCategory.SPELL, - hidden = True), # In lava - DS3LocationData("CC: Knight Slayer's Ring", "Knight Slayer's Ring", DS3LocationCategory.RING, - offline = "05,0:50006840::", hostile_npc = True), # Knight Slayer Tsorig drop - DS3LocationData("SL: Fume Ultra Greatsword", "Fume Ultra Greatsword", DS3LocationCategory.WEAPON, - hostile_npc = True), # Knight Slayer Tsorig drop - DS3LocationData("SL: Black Iron Greatshield", "Black Iron Greatshield", DS3LocationCategory.SHIELD, + missable = True, hidden = True), # In lava + DS3LocationData("SL: Dragonrider Bow", "Dragonrider Bow", DS3LocationCategory.WEAPON, + hidden = True), # Hidden fall + DS3LocationData("SL: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH, + hidden = True), # Behind illusory wall + DS3LocationData("SL: Bloodbite Ring+1", "Bloodbite Ring+1", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("SL: Flame Stoneplate Ring+2", "Flame Stoneplate Ring+2", DS3LocationCategory.RING, + ngp = True, hidden = True), # Behind illusory wall + DS3LocationData("SL: Large Titanite Shard #9", "Large Titanite Shard x3", DS3LocationCategory.UPGRADE, + hidden = True), # Behind illusory wall + DS3LocationData("SL: Undead Bone Shard #2", "Undead Bone Shard", DS3LocationCategory.HEALTH, + miniboss = True), # Sand Worm drop + DS3LocationData("SL: Lightning Stake", "Lightning Stake", DS3LocationCategory.SPELL, + miniboss = True), # Sand Worm drop + DS3LocationData("SL: Twinkling Titanite", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("SL: Titanite Chunk", "Titanite Chunk", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("SL: Chaos Gem #2", "Chaos Gem", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("SL: Knight Slayer's Ring", "Knight Slayer's Ring", DS3LocationCategory.RING, hostile_npc = True), # Knight Slayer Tsorig drop - DS3LocationData("SL: Soul of the Old Demon King", "Soul of the Old Demon King", DS3LocationCategory.BOSS, - prominent = True, boss = True), + DS3LocationData("SL: Old King's Great Hammer", "Old King's Great Hammer", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("SL: Chaos Bed Vestiges", "Chaos Bed Vestiges", DS3LocationCategory.SPELL, + missable = True, boss = True, shop = True), + DS3LocationData("SL: Llewellyn Shield", "Llewellyn Shield", DS3LocationCategory.SHIELD, + missable = True, npc = True), # Horace (kill or quest) + + # Shrine Handmaid after killing Horace the Hushed + # These are listed here even though you can kill Horace in the Road of Sacrifices because + # the player may want to complete his and Anri's quest first. + DS3LocationData("SL: Executioner Helm", "Executioner Helm", DS3LocationCategory.ARMOR, + hidden = True, npc = True, shop = True), + DS3LocationData("SL: Executioner Armor", "Executioner Armor", DS3LocationCategory.ARMOR, + hidden = True, npc = True, shop = True), + DS3LocationData("SL: Executioner Gauntlets", "Executioner Gauntlets", DS3LocationCategory.ARMOR, + hidden = True, npc = True, shop = True), + DS3LocationData("SL: Executioner Leggings", "Executioner Leggings", DS3LocationCategory.ARMOR, + hidden = True, npc = True, shop = True), + + # Shrine Handmaid after killing Knight Slayer Tsorig + DS3LocationData("SL: Black Iron Helm", "Black Iron Helm", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True, shop = True), + DS3LocationData("SL: Black Iron Armor", "Black Iron Armor", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True, shop = True), + DS3LocationData("SL: Black Iron Gauntlets", "Black Iron Gauntlets", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True, shop = True), + DS3LocationData("SL: Black Iron Leggings", "Black Iron Leggings", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True, shop = True), + + # Near Cornyx's cage after killing Old Demon King with Cuculus + DS3LocationData("SL: Spotted Whip", "Spotted Whip", DS3LocationCategory.WEAPON, + missable = True, boss = True, npc = True), + DS3LocationData("SL: Cornyx's Garb", "Cornyx's Garb", DS3LocationCategory.ARMOR, + offline = '02,0:53100100::', missable = True, boss = True, npc = True), + DS3LocationData("SL: Cornyx's Wrap", "Cornyx's Wrap", DS3LocationCategory.ARMOR, + offline = '02,0:53100100::', missable = True, boss = True, npc = True), + DS3LocationData("SL: Cornyx's Skirt", "Cornyx's Skirt", DS3LocationCategory.ARMOR, + offline = '02,0:53100100::', missable = True, boss = True, npc = True), ], "Irithyll of the Boreal Valley": [ - DS3LocationData("IBV: Dorhys' Gnawing", "Dorhys' Gnawing", DS3LocationCategory.SPELL, - hidden = True), # Behind invisible wall + DS3LocationData("IBV: Soul of Pontiff Sulyvahn", "Soul of Pontiff Sulyvahn", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("IBV: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("IBV: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Soul of a Weary Warrior #1", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("IBV: Soul of a Weary Warrior #2", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("IBV: Rime-blue Moss Clump #1", "Rime-blue Moss Clump", DS3LocationCategory.MISC), DS3LocationData("IBV: Witchtree Branch", "Witchtree Branch", DS3LocationCategory.WEAPON, - hidden = True), # Behind invisible wall + hidden = True), # Behind illusory wall + DS3LocationData("IBV: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Budding Green Blossom", "Budding Green Blossom", DS3LocationCategory.MISC), + DS3LocationData("IBV: Rime-blue Moss Clump #2", "Rime-blue Moss Clump x2", DS3LocationCategory.MISC), + DS3LocationData("IBV: Large Titanite Shard #3", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Large Titanite Shard #4", "Large Titanite Shard", DS3LocationCategory.UPGRADE, + hidden = True), # Behind illusory wall + DS3LocationData("IBV: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("IBV: Large Titanite Shard #5", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Large Titanite Shard #6", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Soul of a Weary Warrior #3", "Soul of a Weary Warrior", DS3LocationCategory.MISC), DS3LocationData("IBV: Magic Clutch Ring", "Magic Clutch Ring", DS3LocationCategory.RING, - hidden = True), # Behind invisible wall - DS3LocationData("IBV: Ring of the Sun's First Born", "Ring of the Sun's First Born", DS3LocationCategory.RING), - DS3LocationData("IBV: Roster of Knights", "Roster of Knights", DS3LocationCategory.MISC), - DS3LocationData("IBV: Pontiff's Right Eye", "Pontiff's Right Eye", DS3LocationCategory.RING, - offline = "06,0:53700995::", miniboss = True), # Sullyvahn's Beast drop - DS3LocationData("IBV: Yorshka's Spear", "Yorshka's Spear", DS3LocationCategory.WEAPON), + hidden = True), # Behind illusory wall + DS3LocationData("IBV: Fading Soul #1", "Fading Soul", DS3LocationCategory.MISC), + DS3LocationData("IBV: Fading Soul #2", "Fading Soul", DS3LocationCategory.MISC), + DS3LocationData("IBV: Homeward Bone", "Homeward Bone x3", DS3LocationCategory.MISC), + DS3LocationData("IBV: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH, + hidden = True), # Hidden behind gravestone + DS3LocationData("IBV: Kukri", "Kukri x8", DS3LocationCategory.MISC), + DS3LocationData("IBV: Rusted Gold Coin #1", "Rusted Gold Coin", DS3LocationCategory.MISC), + DS3LocationData("IBV: Blue Bug Pellet #1", "Blue Bug Pellet x2", DS3LocationCategory.MISC), + DS3LocationData("IBV: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Blood Gem", "Blood Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Green Blossom #1", "Green Blossom x3", DS3LocationCategory.MISC), + DS3LocationData("IBV: Ring of Sacrifice", "Ring of Sacrifice", DS3LocationCategory.MISC), DS3LocationData("IBV: Great Heal", "Great Heal", DS3LocationCategory.SPELL), + DS3LocationData("IBV: Large Soul of a Nameless Soldier #3", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("IBV: Green Blossom #2", "Green Blossom x3", DS3LocationCategory.MISC), + DS3LocationData("IBV: Dung Pie #1", "Dung Pie x3", DS3LocationCategory.MISC), + DS3LocationData("IBV: Dung Pie #2", "Dung Pie x3", DS3LocationCategory.MISC), + # These don't actually guard any single item sales. Maybe we can inject one manually? + DS3LocationData("IBV: Excrement-covered Ashes", "Excrement-covered Ashes", DS3LocationCategory.MISC), + DS3LocationData("IBV: Large Soul of a Nameless Soldier #4", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("IBV: Soul of a Weary Warrior #4", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("IBV: Large Titanite Shard #7", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Blue Bug Pellet #2", "Blue Bug Pellet x2", DS3LocationCategory.MISC), + DS3LocationData("IBV: Ember", "Ember", DS3LocationCategory.MISC), + DS3LocationData("IBV: Large Titanite Shard #8", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Green Blossom #3", "Green Blossom", DS3LocationCategory.MISC), + DS3LocationData("IBV: Lightning Gem", "Lightning Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Large Soul of a Nameless Soldier #5", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("IBV: Soul of a Weary Warrior #5", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("IBV: Proof of a Concord Kept", "Proof of a Concord Kept", DS3LocationCategory.MISC), + DS3LocationData("IBV: Rusted Gold Coin #2", "Rusted Gold Coin", DS3LocationCategory.MISC, + hidden = True), # Hidden fall + DS3LocationData("IBV: Chloranthy Ring+1", "Chloranthy Ring+1", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("IBV: Covetous Gold Serpent Ring+1", "Covetous Gold Serpent Ring+1", DS3LocationCategory.RING, + ngp = True, hidden = True), # Hidden fall + DS3LocationData("IBV: Wood Grain Ring+2", "Wood Grain Ring+2", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("IBV: Divine Blessing #1", "Divine Blessing", DS3LocationCategory.MISC), DS3LocationData("IBV: Smough's Great Hammer", "Smough's Great Hammer", DS3LocationCategory.WEAPON), + DS3LocationData("IBV: Yorshka's Spear", "Yorshka's Spear", DS3LocationCategory.WEAPON), DS3LocationData("IBV: Leo Ring", "Leo Ring", DS3LocationCategory.RING), - DS3LocationData("IBV: Excrement-covered Ashes", "Excrement-covered Ashes", DS3LocationCategory.MISC), - DS3LocationData("IBV: Dark Stoneplate Ring", "Dark Stoneplate Ring", DS3LocationCategory.RING), - DS3LocationData("IBV: Easterner's Ashes", "Easterner's Ashes", DS3LocationCategory.MISC), - DS3LocationData("IBV: Painting Guardian's Curved Sword", "Painting Guardian's Curved Sword", DS3LocationCategory.WEAPON, - hidden = True), # Invisible walkway - DS3LocationData("IBV: Painting Guardian Hood", "Painting Guardian Hood", DS3LocationCategory.ARMOR, - hidden = True), # Invisible walkway - DS3LocationData("IBV: Painting Guardian Gown", "Painting Guardian Gown", DS3LocationCategory.ARMOR, - hidden = True), # Invisible walkway - DS3LocationData("IBV: Painting Guardian Gloves", "Painting Guardian Gloves", DS3LocationCategory.ARMOR, - hidden = True), # Invisible walkway - DS3LocationData("IBV: Painting Guardian Waistcloth", "Painting Guardian Waistcloth", DS3LocationCategory.ARMOR, - hidden = True), # Invisible walkway - DS3LocationData("IBV: Dragonslayer Greatbow", "Dragonslayer Greatbow", DS3LocationCategory.WEAPON), - DS3LocationData("IBV: Reversal Ring", "Reversal Ring", DS3LocationCategory.RING), - DS3LocationData("IBV: Brass Helm", "Brass Helm", DS3LocationCategory.ARMOR), - DS3LocationData("IBV: Brass Armor", "Brass Armor", DS3LocationCategory.ARMOR), - DS3LocationData("IBV: Brass Gauntlets", "Brass Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("IBV: Brass Leggings", "Brass Leggings", DS3LocationCategory.ARMOR), - DS3LocationData("IBV: Ring of Favor", "Ring of Favor", DS3LocationCategory.RING, - miniboss = True, hidden = True), # Sulyvahn's Beast Duo drop, behind invisible wall - DS3LocationData("IBV: Golden Ritual Spear", "Golden Ritual Spear", DS3LocationCategory.WEAPON, - mimic = True), - DS3LocationData("IBV: Soul of Pontiff Sulyvahn", "Soul of Pontiff Sulyvahn", DS3LocationCategory.BOSS, - prominent = True, boss = True), - DS3LocationData("IBV: Aldrich Faithful", "Aldrich Faithful", DS3LocationCategory.MISC, - miniboss = True, hidden = True), # Sulyvahn's Beast Duo reward, behind invisible wall - DS3LocationData("IBV: Drang Twinspears", "Drang Twinspears", DS3LocationCategory.WEAPON), + DS3LocationData("IBV: Dorhys' Gnawing", "Dorhys' Gnawing", DS3LocationCategory.SPELL, + hidden = True), # Behind illusory wall + DS3LocationData("IBV: Divine Blessing #2", "Divine Blessing", DS3LocationCategory.MISC, + hidden = True), # Guaranteed drop from normal-looking Silver Knight + DS3LocationData("IBV: Large Titanite Shard #9", "Large Titanite Shard", DS3LocationCategory.UPGRADE, + hidden = True), # Guaranteed drop from normal-looking Silver Knight + DS3LocationData("IBV: Large Titanite Shard #10", "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, + hidden = True), # Guaranteed drop from normal-looking Silver Knight + DS3LocationData("IBV: Large Titanite Shard #11", "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, + hidden = True), # Guaranteed drop from normal-looking Silver Knight + DS3LocationData("IBV: Roster of Knights", "Roster of Knights", DS3LocationCategory.MISC), + DS3LocationData("IBV: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True, hidden = True), # Behind illusory wall + DS3LocationData("IBV: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("IBV: Siegbräu", "Siegbräu", DS3LocationCategory.MISC, + missable = True, npc = True), + DS3LocationData("IBV: Emit Force", "Emit Force", DS3LocationCategory.SPELL, + missable = True, npc = True), + DS3LocationData("IBV: Sneering Mask", "Sneering Mask", DS3LocationCategory.ARMOR, + missable = True, hostile_npc = True), # Londor Pale Shade (win both invasions) + DS3LocationData("IBV: Pale Shade Robe", "Pale Shade Robe", DS3LocationCategory.ARMOR, + missable = True, hostile_npc = True), # Londor Pale Shade (win both invasions) + DS3LocationData("IBV: Pale Shade Gloves", "Pale Shade Gloves", DS3LocationCategory.ARMOR, + missable = True, hostile_npc = True), # Londor Pale Shade (win both invasions) + DS3LocationData("IBV: Pale Shade Trousers", "Pale Shade Trousers", DS3LocationCategory.ARMOR, + missable = True, hostile_npc = True), # Londor Pale Shade (win both invasions) + DS3LocationData("IBV: Greatsword of Judgment", "Greatsword of Judgment", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("IBV: Profaned Greatsword", "Profaned Greatsword", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + + # Anri of Astora + DS3LocationData("IBV: Anri's Straight Sword", "Anri's Straight Sword", DS3LocationCategory.WEAPON, + missable = True, npc = True), + DS3LocationData("IBV: Ring of the Evil Eye", "Ring of the Evil Eye", DS3LocationCategory.RING, + missable = True, npc = True), + + # Shrine Handmaid after killing Sulyvahn's Beast Duo + DS3LocationData("IBV: Helm of Favor", "Helm of Favor", DS3LocationCategory.ARMOR, + hidden = True, miniboss = True, shop = True), + DS3LocationData("IBV: Embraced Armor of Favor", "Embraced Armor of Favor", DS3LocationCategory.ARMOR, + hidden = True, miniboss = True, shop = True), + DS3LocationData("IBV: Gauntlets of Favor", "Gauntlets of Favor", DS3LocationCategory.ARMOR, + hidden = True, miniboss = True, shop = True), + DS3LocationData("IBV: Leggings of Favor", "Leggings of Favor", DS3LocationCategory.ARMOR, + hidden = True, miniboss = True, shop = True), + + # Sirris after killing Creighton + DS3LocationData("IBV: Mail Breaker", "Mail Breaker", DS3LocationCategory.WEAPON, + missable = True, npc = True), + DS3LocationData("IBC: Silvercat Ring", "Silvercat Ring", DS3LocationCategory.RING, + missable = True, npc = True), + DS3LocationData("IBV: Dragonslayer's Axe", "Dragonslayer's Axe", DS3LocationCategory.WEAPON, + missable = True, npc = True), + DS3LocationData("IBV: Creighton's Steel Mask", "Creighton's Steel Mask", DS3LocationCategory.ARMOR, + missable = True, npc = True), + DS3LocationData("IBV: Mirrah Chain Mail", "Mirrah Chain Mail", DS3LocationCategory.ARMOR, + missable = True, npc = True), + DS3LocationData("IBV: Mirrah Chain Gloves", "Mirrah Chain Gloves", DS3LocationCategory.ARMOR, + missable = True, npc = True), + DS3LocationData("IBV: Mirrah Chain Leggings", "Mirrah Chain Leggings", DS3LocationCategory.ARMOR, + missable = True, npc = True), ], "Irithyll Dungeon": [ - DS3LocationData("ID: Bellowing Dragoncrest Ring", "Bellowing Dragoncrest Ring", DS3LocationCategory.RING), + DS3LocationData("ID: Titanite Slab", "Titanite Slab", DS3LocationCategory.MISC, + missable = True, npc = True), # Siegward (quest) + DS3LocationData("ID: Murakumo", "Murakumo", DS3LocationCategory.WEAPON, + missable = True, npc = True), # Alva (requires ember) + DS3LocationData("ID: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("ID: Fading Soul", "Fading Soul", DS3LocationCategory.MISC), + DS3LocationData("ID: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), DS3LocationData("ID: Jailbreaker's Key", "Jailbreaker's Key", DS3LocationCategory.KEY, key = True), - DS3LocationData("ID: Prisoner Chief's Ashes", "Prisoner Chief's Ashes", DS3LocationCategory.KEY), + DS3LocationData("ID: Pale Pine Resin", "Pale Pine Resin x2", DS3LocationCategory.MISC), + DS3LocationData("ID: Simple Gem", "Simple Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("ID: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("ID: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("ID: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC), + DS3LocationData("ID: Bellowing Dragoncrest Ring", "Bellowing Dragoncrest Ring", DS3LocationCategory.RING), + DS3LocationData("ID: Soul of a Weary Warrior #1", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("ID: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("ID: Lightning Bolt", "Lightning Bolt x9", DS3LocationCategory.MISC), + DS3LocationData("ID: Large Titanite Shard #3", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("ID: Profaned Flame", "Profaned Flame", DS3LocationCategory.SPELL), + DS3LocationData("ID: Large Titanite Shard #4", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("ID: Soul of a Weary Warrior #2", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("ID: Dung Pie #1", "Dung Pie x4", DS3LocationCategory.MISC), + DS3LocationData("ID: Ember #1", "Ember", DS3LocationCategory.MISC), + DS3LocationData("ID: Ember #2", "Ember", DS3LocationCategory.MISC), + DS3LocationData("ID: Profaned Coal", "Profaned Coal", DS3LocationCategory.MISC), + DS3LocationData("ID: Large Titanite Shard #5", "Large Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("ID: Old Sorcerer Hat", "Old Sorcerer Hat", DS3LocationCategory.ARMOR), DS3LocationData("ID: Old Sorcerer Coat", "Old Sorcerer Coat", DS3LocationCategory.ARMOR), DS3LocationData("ID: Old Sorcerer Gauntlets", "Old Sorcerer Gauntlets", DS3LocationCategory.ARMOR), DS3LocationData("ID: Old Sorcerer Boots", "Old Sorcerer Boots", DS3LocationCategory.ARMOR), - DS3LocationData("ID: Great Magic Shield", "Great Magic Shield", DS3LocationCategory.SPELL, - hidden = True), # Guaranteed drop from a normal-looking Corpse-Grub - DS3LocationData("ID: Dragon Torso Stone", "Dragon Torso Stone", DS3LocationCategory.MISC), + DS3LocationData("ID: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("ID: Covetous Gold Serpent Ring", "Covetous Gold Serpent Ring", DS3LocationCategory.RING), DS3LocationData("ID: Lightning Blade", "Lightning Blade", DS3LocationCategory.SPELL), - DS3LocationData("ID: Profaned Coal", "Profaned Coal", DS3LocationCategory.MISC), - DS3LocationData("ID: Xanthous Ashes", "Xanthous Ashes", DS3LocationCategory.MISC), + DS3LocationData("ID: Rusted Coin", "Rusted Coin", DS3LocationCategory.MISC), + DS3LocationData("ID: Dusk Crown Ring", "Dusk Crown Ring", DS3LocationCategory.RING), + DS3LocationData("ID: Pickaxe", "Pickaxe", DS3LocationCategory.WEAPON), + DS3LocationData("ID: Xanthous Ashes", "Xanthous Ashes", DS3LocationCategory.KEY, + progression = True), + DS3LocationData("ID: Rusted Gold Coin", "Rusted Gold Coin", DS3LocationCategory.MISC), + DS3LocationData("ID: Large Titanite Shard #6", "Large Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("ID: Old Cell Key", "Old Cell Key", DS3LocationCategory.KEY, key = True), - DS3LocationData("ID: Pickaxe", "Pickaxe", DS3LocationCategory.WEAPON), - DS3LocationData("ID: Profaned Flame", "Profaned Flame", DS3LocationCategory.SPELL), - DS3LocationData("ID: Covetous Gold Serpent Ring", "Covetous Gold Serpent Ring", DS3LocationCategory.RING), - DS3LocationData("ID: Jailer's Key Ring", "Jailer's Key Ring", DS3LocationCategory.KEY, - offline = "07,0:53900520::", key = True), - DS3LocationData("ID: Dusk Crown Ring", "Dusk Crown Ring", DS3LocationCategory.RING), + DS3LocationData("ID: Covetous Silver Serpent Ring+1", "Covetous Silver Serpent Ring+1", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("ID: Dragon Torso Stone", "Dragon Torso Stone", DS3LocationCategory.MISC), + DS3LocationData("ID: Prisoner Chief's Ashes", "Prisoner Chief's Ashes", DS3LocationCategory.KEY, + progression = True), + DS3LocationData("ID: Great Magic Shield", "Great Magic Shield", DS3LocationCategory.SPELL, + hidden = True), # Guaranteed drop from a normal-looking Corpse-Grub + DS3LocationData("ID: Dragonslayer Lightning Arrow", "Dragonslayer Lightning Arrow x10", DS3LocationCategory.MISC, + mimic = True), + DS3LocationData("ID: Titanite Scale #1", "Titanite Scale x2", DS3LocationCategory.UPGRADE, + mimic = True), DS3LocationData("ID: Dark Clutch Ring", "Dark Clutch Ring", DS3LocationCategory.RING, mimic = True), - DS3LocationData("ID: Karla's Ashes", "Karla's Ashes", DS3LocationCategory.KEY, - npc = True), - DS3LocationData("ID: Karla's Pointed Hat", "Karla's Pointed Hat", DS3LocationCategory.ARMOR, - npc = True), - DS3LocationData("ID: Karla's Coat", "Karla's Coat", DS3LocationCategory.ARMOR, - npc = True), - DS3LocationData("ID: Karla's Gloves", "Karla's Gloves", DS3LocationCategory.ARMOR, - npc = True), - DS3LocationData("ID: Karla's Trousers", "Karla's Trousers", DS3LocationCategory.ARMOR, - npc = True), + DS3LocationData("ID: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH, + mimic = True), + DS3LocationData("ID: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("ID: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("ID: Dung Pie #2", "Dung Pie x4", DS3LocationCategory.MISC), + DS3LocationData("ID: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE, + miniboss = True), # Giant Slave Drop + + # Alva (requires ember) + DS3LocationData("ID: Alva Helm", "Alva Helm", DS3LocationCategory.ARMOR, + missable = True, npc = True), + DS3LocationData("ID: Alva Armor", "Alva Armor", DS3LocationCategory.ARMOR, + missable = True, npc = True), + DS3LocationData("ID: Alva Gauntlets", "Alva Gauntlets", DS3LocationCategory.ARMOR, + missable = True, npc = True), + DS3LocationData("ID: Alva Leggings", "Alva Leggings", DS3LocationCategory.ARMOR, + missable = True, npc = True), ], "Profaned Capital": [ + DS3LocationData("PC: Soul of Yhorm the Giant", "Soul of Yhorm the Giant", DS3LocationCategory.BOSS, + boss = True), + DS3LocationData("PC: Cinders of a Lord - Yhorm the Giant", "Cinders of a Lord - Yhorm the Giant", DS3LocationCategory.KEY, + offline = "07,0:50002170::", prominent = True, progression = True, boss = True), + DS3LocationData("PC: Logan's Scroll", "Logan's Scroll", DS3LocationCategory.MISC, + hostile_npc = True), # Sorcerer + DS3LocationData("PC: Purging Stone #1", "Purging Stone x3", DS3LocationCategory.MISC), + DS3LocationData("PC: Rusted Coin #1", "Rusted Coin x2", DS3LocationCategory.MISC), + DS3LocationData("PC: Rusted Gold Coin #1", "Rusted Gold Coin", DS3LocationCategory.MISC), + DS3LocationData("PC: Purging Stone #2", "Purging Stone", DS3LocationCategory.MISC), DS3LocationData("PC: Cursebite Ring", "Cursebite Ring", DS3LocationCategory.RING), + DS3LocationData("PC: Poison Gem", "Poison Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("PC: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), + DS3LocationData("PC: Poison Arrow", "Poison Arrow x18", DS3LocationCategory.MISC), + DS3LocationData("PC: Rubbish", "Rubbish", DS3LocationCategory.MISC), + DS3LocationData("PC: Onislayer Greatarrow", "Onislayer Greatarrow x8", DS3LocationCategory.MISC), + DS3LocationData("PC: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("PC: Rusted Coin #2", "Rusted Coin", DS3LocationCategory.MISC), + DS3LocationData("PC: Rusted Coin #3", "Rusted Coin", DS3LocationCategory.MISC), + DS3LocationData("PC: Blooming Purple Moss Clump", "Blooming Purple Moss Clump x3", DS3LocationCategory.MISC), + DS3LocationData("PC: Wrath of the Gods", "Wrath of the Gods", DS3LocationCategory.SPELL), + DS3LocationData("PC: Onislayer Greatbow", "Onislayer Greatbow", DS3LocationCategory.WEAPON, + hidden = True), # Hidden fall + DS3LocationData("PC: Jailer's Key Ring", "Jailer's Key Ring", DS3LocationCategory.KEY, + progression = True, key = True), + DS3LocationData("PC: Ember", "Ember", DS3LocationCategory.MISC), + DS3LocationData("PC: Flame Stoneplate Ring+1", "Flame Stoneplate Ring+1", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("PC: Magic Stoneplate Ring+2", "Magic Stoneplate Ring+2", DS3LocationCategory.RING, + ngp = True), DS3LocationData("PC: Court Sorcerer Hood", "Court Sorcerer Hood", DS3LocationCategory.ARMOR), DS3LocationData("PC: Court Sorcerer Robe", "Court Sorcerer Robe", DS3LocationCategory.ARMOR), DS3LocationData("PC: Court Sorcerer Gloves", "Court Sorcerer Gloves", DS3LocationCategory.ARMOR), DS3LocationData("PC: Court Sorcerer Trousers", "Court Sorcerer Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("PC: Wrath of the Gods", "Wrath of the Gods", DS3LocationCategory.SPELL), - DS3LocationData("PC: Logan's Scroll", "Logan's Scroll", DS3LocationCategory.MISC, - hostile_npc = True), # Sorcerer + DS3LocationData("PC: Storm Ruler", "Storm Ruler", DS3LocationCategory.KEY), + DS3LocationData("PC: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), DS3LocationData("PC: Eleonora", "Eleonora", DS3LocationCategory.WEAPON, hidden = True), # Guaranteed drop from a normal-looking Monstrosity of Sin + DS3LocationData("PC: Rusted Gold Coin #2", "Rusted Gold Coin x2", DS3LocationCategory.MISC, + mimic = True), DS3LocationData("PC: Court Sorcerer's Staff", "Court Sorcerer's Staff", DS3LocationCategory.WEAPON, mimic = True), DS3LocationData("PC: Greatshield of Glory", "Greatshield of Glory", DS3LocationCategory.SHIELD, mimic = True), - DS3LocationData("PC: Storm Ruler", "Storm Ruler", DS3LocationCategory.KEY), - DS3LocationData("PC: Cinders of a Lord - Yhorm the Giant", "Cinders of a Lord - Yhorm the Giant", DS3LocationCategory.KEY, - offline = "07,0:50002170::", prominent = True, progression = True, boss = True), - DS3LocationData("PC: Soul of Yhorm the Giant", "Soul of Yhorm the Giant", DS3LocationCategory.BOSS, - boss = True), + DS3LocationData("PC: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("PC: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("US: Siegbräu", "Siegbräu", DS3LocationCategory.MISC, + missable = True, npc = True), + DS3LocationData("PC: Yhorm's Great Machete", "Yhorm's Great Machete", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("PC: Yhorm's Greatshield", "Yhorm's Greatshield", DS3LocationCategory.SHIELD, + missable = True, boss = True, shop = True), + + # Siegward drops (kill or quest) + DS3LocationData("PC: Storm Ruler", "Storm Ruler", DS3LocationCategory.WEAPON, + offline = '02,0:50006218::', missable = True, npc = True), + DS3LocationData("PC: Pierce Shield", "Pierce Shield", DS3LocationCategory.SHIELD, + missable = True, npc = True), ], + # We consider "Anor Londo" to be everything accessible only after killing Pontiff. This doesn't + # match up one-to-one with where the game pops up the region name, but it balances items better + # and covers the region that's full of DS1 Anor Londo references. "Anor Londo": [ - DS3LocationData("AL: Giant's Coal", "Giant's Coal", DS3LocationCategory.MISC, - offline = "06,0:53700800::"), - DS3LocationData("AL: Sun Princess Ring", "Sun Princess Ring", DS3LocationCategory.RING, - offline = "06,0:53700840::"), - DS3LocationData("AL: Aldrich's Ruby", "Aldrich's Ruby", DS3LocationCategory.RING, - offline = "06,1:3700355::", miniboss = True), # Deep Accursed drop - DS3LocationData("AL: Cinders of a Lord - Aldrich", "Cinders of a Lord - Aldrich", DS3LocationCategory.KEY, - prominent = True, progression = True, boss = True), DS3LocationData("AL: Soul of Aldrich", "Soul of Aldrich", DS3LocationCategory.BOSS, boss = True), + DS3LocationData("AL: Cinders of a Lord - Aldrich", "Cinders of a Lord - Aldrich", DS3LocationCategory.KEY, + offline = '06,0:50002130::', prominent = True, progression = True, boss = True), + DS3LocationData("AL: Yorshka's Chime", "Yorshka's Chime", DS3LocationCategory.WEAPON, + missable = True, npc = True), # Yorshka (kill), invisible walkway + DS3LocationData("AL: Drang Twinspears", "Drang Twinspears", DS3LocationCategory.WEAPON, + hidden = True), # Guaranteed drop from a normal-loking knight + DS3LocationData("AL: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), + DS3LocationData("AL: Painting Guardian's Curved Sword", "Painting Guardian's Curved Sword", DS3LocationCategory.WEAPON, + hidden = True), # Invisible walkway + DS3LocationData("AL: Brass Helm", "Brass Helm", DS3LocationCategory.ARMOR, + hidden = True), # Behind illusory wall + DS3LocationData("AL: Brass Armor", "Brass Armor", DS3LocationCategory.ARMOR, + hidden = True), # Behind illusory wall + DS3LocationData("AL: Brass Gauntlets", "Brass Gauntlets", DS3LocationCategory.ARMOR, + hidden = True), # Behind illusory wall + DS3LocationData("AL: Brass Leggings", "Brass Leggings", DS3LocationCategory.ARMOR, + hidden = True), # Behind illusory wall + DS3LocationData("AL: Human Dregs", "Human Dregs", DS3LocationCategory.MISC, + hidden = True), # Behind illusory wall + DS3LocationData("AL: Ember #1", "Ember", DS3LocationCategory.MISC), + DS3LocationData("AL: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("AL: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("AL: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("AL: Ember #2", "Ember", DS3LocationCategory.MISC), + DS3LocationData("AL: Ember #3", "Ember", DS3LocationCategory.MISC), + DS3LocationData("AL: Large Titanite Shard #3", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("AL: Dark Stoneplate Ring", "Dark Stoneplate Ring", DS3LocationCategory.RING), + DS3LocationData("AL: Large Titanite Shard #4", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("AL: Deep Gem", "Deep Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("AL: Titanite Scale", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("AL: Dragonslayer Greatarrow", "Dragonslayer Greatarrow x5", DS3LocationCategory.MISC, + hidden = True), # Hidden fall + DS3LocationData("AL: Dragonslayer Greatbow", "Dragonslayer Greatbow", DS3LocationCategory.WEAPON, + hidden = True), # Hidden fall + DS3LocationData("AL: Easterner's Ashes", "Easterner's Ashes", DS3LocationCategory.KEY, + progression = True), + DS3LocationData("AL: Painting Guardian Hood", "Painting Guardian Hood", DS3LocationCategory.ARMOR, + hidden = True), # Invisible walkway + DS3LocationData("AL: Painting Guardian Gown", "Painting Guardian Gown", DS3LocationCategory.ARMOR, + hidden = True), # Invisible walkway + DS3LocationData("AL: Painting Guardian Gloves", "Painting Guardian Gloves", DS3LocationCategory.ARMOR, + hidden = True), # Invisible walkway + DS3LocationData("AL: Painting Guardian Waistcloth", "Painting Guardian Waistcloth", DS3LocationCategory.ARMOR, + hidden = True), # Invisible walkway + DS3LocationData("AL: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("AL: Moonlight Arrow", "Moonlight Arrow x6", DS3LocationCategory.MISC), + DS3LocationData("AL: Proof of a Concord Kept", "Proof of a Concord Kept", DS3LocationCategory.MISC), + DS3LocationData("AL: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("AL: Giant's Coal", "Giant's Coal", DS3LocationCategory.MISC), + DS3LocationData("AL: Havel's Ring+2", "Havel's Ring+2", DS3LocationCategory.RING, + ngp = True, hidden = True), # Invisible walkway + DS3LocationData("AL: Ring of Favor+1", "Ring of Favor+1", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("AL: Sun Princess Ring", "Sun Princess Ring", DS3LocationCategory.RING), + DS3LocationData("AL: Reversal Ring", "Reversal Ring", DS3LocationCategory.RING, + hidden = True), # Behind illusory wall + DS3LocationData("AL: Golden Ritual Spear", "Golden Ritual Spear", DS3LocationCategory.WEAPON, + mimic = True), + DS3LocationData("AL: Ring of Favor", "Ring of Favor", DS3LocationCategory.RING, + miniboss = True, hidden = True), # Sulyvahn's Beast Duo drop, behind illusory wall + DS3LocationData("AL: Blade of the Darkmoon", "Blade of the Darkmoon", DS3LocationCategory.MISC, + missable = True, npc = True), # Yorshka (quest or kill) + DS3LocationData("AL: Simple Gem", "Simple Gem", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("AL: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("AL: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("AL: Aldrich's Ruby", "Aldrich's Ruby", DS3LocationCategory.RING, + miniboss = True), # Deep Accursed drop + DS3LocationData("AL: Aldrich Faithful", "Aldrich Faithful", DS3LocationCategory.MISC, + hidden = True), # Behind illusory wall + DS3LocationData("AL: Budding Green Blossom", "Budding Green Blossom", DS3LocationCategory.MISC, + missable = True, npc = True, shop = True), # sold by Shrine Maiden after helping Sirris and defeating Aldrich + DS3LocationData("AL: Bountiful Sunlight", "Bountiful Sunlight", DS3LocationCategory.SPELL, + missable = True, boss = True, shop = True), + DS3LocationData("AL: Darkmoon Longbow", "Darkmoon Longbow", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("AL: Lifehunt Scythe", "Lifehunt Scythe", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + + # Sirris (quest completion) + DS3LocationData("AL: Sunset Shield", "Sunset Shield", DS3LocationCategory.SHIELD, + missable = True, npc = True), + DS3LocationData("AL: Sunless Talisman", "Sunless Talisman", DS3LocationCategory.WEAPON, + missable = True, npc = True), + DS3LocationData("AL: Sunless Veil", "Sunless Veil", DS3LocationCategory.ARMOR, + missable = True, npc = True, shop = True), + DS3LocationData("AL: Sunless Armor", "Sunless Armor", DS3LocationCategory.ARMOR, + missable = True, npc = True, shop = True), + DS3LocationData("AL: Sunless Gauntlets", "Sunless Gauntlets", DS3LocationCategory.ARMOR, + missable = True, npc = True, shop = True), + DS3LocationData("AL: Sunless Leggings", "Sunless Leggings", DS3LocationCategory.ARMOR, + missable = True, npc = True, shop = True), + # In Pit of Hollows after completion + DS3LocationData("AL: Sunset Helm", "Sunset Helm", DS3LocationCategory.ARMOR, + missable = True, npc = True), + DS3LocationData("AL: Sunset Armor", "Sunset Armor", DS3LocationCategory.ARMOR, + missable = True, npc = True), + DS3LocationData("AL: Sunset Gauntlets", "Sunset Gauntlets", DS3LocationCategory.ARMOR, + missable = True, npc = True), + DS3LocationData("AL: Sunset Leggings", "Sunset Leggings", DS3LocationCategory.ARMOR, + missable = True, npc = True), + + # Anri of Astora + DS3LocationData("AL: Chameleon", "Chameleon", DS3LocationCategory.SPELL, + missable = True, npc = True), + + # Shrine Handmaid after killing Ringfinger Leonhard + # This is listed here even though you can kill Leonhard immediately because we don't want to + # make people do that until they have a chance to complete his quest and Sirris's. + DS3LocationData("AL: Leonhard's Garb", "Leonhard's Garb", DS3LocationCategory.ARMOR, + hidden = True, npc = True, shop = True), + DS3LocationData("AL: Leonhard's Gauntlets", "Leonhard's Gauntlets", DS3LocationCategory.ARMOR, + hidden = True, npc = True, shop = True), + DS3LocationData("AL: Leonhard's Trousers", "Leonhard's Trousers", DS3LocationCategory.ARMOR, + hidden = True, npc = True, shop = True), + + # Shrine Handmaid after killing Alrich, Devourer of Gods + DS3LocationData("AL: Smough's Helm", "Smough's Helm", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("AL: Smough's Armor", "Smough's Armor", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("AL: Smough's Gauntlets", "Smough's Gauntlets", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("AL: Smough's Leggings", "Smough's Leggings", DS3LocationCategory.ARMOR, + boss = True, shop = True), + + # Shrine Handmaid after killing Anri or completing their quest + DS3LocationData("AL: Elite Knight Helm", "Elite Knight Helm", DS3LocationCategory.ARMOR, + missable = True, npc = True, shop = True), + DS3LocationData("AL: Elite Knight Armor", "Elite Knight Armor", DS3LocationCategory.ARMOR, + missable = True, npc = True, shop = True), + DS3LocationData("AL: Elite Knight Gauntlets", "Elite Knight Gauntlets", DS3LocationCategory.ARMOR, + missable = True, npc = True, shop = True), + DS3LocationData("AL: Elite Knight Leggings", "Elite Knight Leggings", DS3LocationCategory.ARMOR, + missable = True, npc = True, shop = True), + + # Ringfinger Leonhard (quest or kill) + DS3LocationData("AL: Crescent Moon Sword", "Crescent Moon Sword", DS3LocationCategory.WEAPON, + missable = True, npc = True), + DS3LocationData("AL: Silver Mask", "Silver Mask", DS3LocationCategory.ARMOR, + missable = True, npc = True), + DS3LocationData("AL: Soul of Rosaria", "Soul of Rosaria", DS3LocationCategory.MISC, + missable = True, npc = True), + ], "Lothric Castle": [ - DS3LocationData("LC: Hood of Prayer", "Hood of Prayer", DS3LocationCategory.ARMOR), - DS3LocationData("LC: Robe of Prayer", "Robe of Prayer", DS3LocationCategory.ARMOR), - DS3LocationData("LC: Skirt of Prayer", "Skirt of Prayer", DS3LocationCategory.ARMOR), + DS3LocationData("LC: Soul of Dragonslayer Armour", "Soul of Dragonslayer Armour", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("LC: Sniper Bolt", "Sniper Bolt x11", DS3LocationCategory.MISC), + DS3LocationData("LC: Sniper Crossbow", "Sniper Crossbow", DS3LocationCategory.WEAPON), + DS3LocationData("LC: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Greatlance", "Greatlance", DS3LocationCategory.WEAPON), + DS3LocationData("LC: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Titanite Chunk #3", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("LC: Sacred Bloom Shield", "Sacred Bloom Shield", DS3LocationCategory.SHIELD, - hidden = True), # Behind invisible wall + hidden = True), # Behind illusory wall + DS3LocationData("LC: Titanite Chunk #4", "Titanite Chunk x2", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Refined Gem", "Refined Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("LC: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), + DS3LocationData("LC: Lightning Urn #1", "Lightning Urn x3", DS3LocationCategory.MISC), + DS3LocationData("LC: Titanite Chunk #5", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Titanite Chunk #6", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Titanite Chunk #7", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Caitha's Chime", "Caitha's Chime", DS3LocationCategory.WEAPON), + DS3LocationData("LC: Lightning Urn #2", "Lightning Urn x6", DS3LocationCategory.MISC), + DS3LocationData("LC: Ember #1", "Ember", DS3LocationCategory.MISC), + DS3LocationData("LC: Raw Gem", "Raw Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Black Firebomb", "Black Firebomb x3", DS3LocationCategory.MISC), + DS3LocationData("LC: Pale Pine Resin", "Pale Pine Resin", DS3LocationCategory.MISC), + DS3LocationData("LC: Large Soul of a Weary Warrior #1", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("LC: Sunlight Medal", "Sunlight Medal", DS3LocationCategory.MISC), + DS3LocationData("LC: Soul of a Crestfallen Knight #2", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC, + hidden = True), # Hidden fall + DS3LocationData("LC: Titanite Chunk #8", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("LC: Knight's Ring", "Knight's Ring", DS3LocationCategory.RING), + DS3LocationData("LC: Ember #2", "Ember", DS3LocationCategory.MISC), + DS3LocationData("LC: Large Soul of a Weary Warrior #2", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("LC: Ember #3", "Ember", DS3LocationCategory.MISC), + DS3LocationData("LC: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.MISC), + DS3LocationData("LC: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("LC: Ember #4", "Ember", DS3LocationCategory.MISC), DS3LocationData("LC: Winged Knight Helm", "Winged Knight Helm", DS3LocationCategory.ARMOR, - hidden = True), # Behind invisible wall + hidden = True), # Behind illusory wall DS3LocationData("LC: Winged Knight Armor", "Winged Knight Armor", DS3LocationCategory.ARMOR, - hidden = True), # Behind invisible wall + hidden = True), # Behind illusory wall DS3LocationData("LC: Winged Knight Gauntlets", "Winged Knight Gauntlets", DS3LocationCategory.ARMOR, - hidden = True), # Behind invisible wall + hidden = True), # Behind illusory wall DS3LocationData("LC: Winged Knight Leggings", "Winged Knight Leggings", DS3LocationCategory.ARMOR, - hidden = True), # Behind invisible wall - DS3LocationData("LC: Greatlance", "Greatlance", DS3LocationCategory.WEAPON), - DS3LocationData("LC: Sniper Crossbow", "Sniper Crossbow", DS3LocationCategory.WEAPON), - DS3LocationData("LC: Spirit Tree Crest Shield", "Spirit Tree Crest Shield", DS3LocationCategory.SHIELD), - DS3LocationData("LC: Red Tearstone Ring", "Red Tearstone Ring", DS3LocationCategory.RING), - DS3LocationData("LC: Caitha's Chime", "Caitha's Chime", DS3LocationCategory.WEAPON), + hidden = True), # Behind illusory wall + DS3LocationData("LC: Rusted Coin", "Rusted Coin x2", DS3LocationCategory.MISC), DS3LocationData("LC: Braille Divine Tome of Lothric", "Braille Divine Tome of Lothric", DS3LocationCategory.MISC, hidden = True), # Hidden fall - DS3LocationData("LC: Knight's Ring", "Knight's Ring", DS3LocationCategory.RING), - DS3LocationData("LC: Irithyll Rapier", "Irithyll Rapier", DS3LocationCategory.WEAPON, - miniboss = True), # Boreal Outrider drop + DS3LocationData("LC: Red Tearstone Ring", "Red Tearstone Ring", DS3LocationCategory.RING), + DS3LocationData("LC: Twinkling Titanite #2", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Large Soul of a Nameless Soldier #3", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("LC: Titanite Scale #3", "Titanite Scale x3", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Titanite Scale #4", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Hood of Prayer", "Hood of Prayer", DS3LocationCategory.ARMOR), + DS3LocationData("LC: Robe of Prayer", "Robe of Prayer", DS3LocationCategory.ARMOR), + DS3LocationData("LC: Skirt of Prayer", "Skirt of Prayer", DS3LocationCategory.ARMOR), + DS3LocationData("LC: Spirit Tree Crest Shield", "Spirit Tree Crest Shield", DS3LocationCategory.SHIELD), + DS3LocationData("LC: Titanite Scale #5", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Twinkling Titanite #3", "Twinkling Titanite", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Twinkling Titanite #4", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Life Ring+2", "Life Ring+2", DS3LocationCategory.RING, + ngp = True, hidden = True), # Hidden fall + DS3LocationData("LC: Dark Stoneplate Ring+1", "Dark Stoneplate Ring+1", DS3LocationCategory.RING, + ngp = True, hidden = True), # Hidden fall + DS3LocationData("LC: Thunder Stoneplate Ring+2", "Thunder Stoneplate Ring+2", DS3LocationCategory.RING, + ngp = True), DS3LocationData("LC: Sunlight Straight Sword", "Sunlight Straight Sword", DS3LocationCategory.WEAPON, mimic = True, hidden = True), # Hidden fall - DS3LocationData("LC: Soul of Dragonslayer Armour", "Soul of Dragonslayer Armour", DS3LocationCategory.BOSS, - prominent = True, boss = True), + DS3LocationData("LC: Titanite Scale #6", "Titanite Scale x3", DS3LocationCategory.UPGRADE, + mimic = True), + DS3LocationData("LC: Ember #5", "Ember x2", DS3LocationCategory.MISC, + miniboss = True, hidden = True), # Hidden fall, Pus of Man Wyvern drop + DS3LocationData("LC: Titanite Chunk #9", "Titanite Chunk x2", DS3LocationCategory.UPGRADE, + miniboss = True, hidden = True), # Hidden fall, Pus of Man Wyvern drop + DS3LocationData("LC: Ember #6", "Ember x2", DS3LocationCategory.MISC, + miniboss = True), # Pus of Man Wyvern drop + DS3LocationData("LC: Titanite Chunk #10", "Titanite Chunk x2", DS3LocationCategory.UPGRADE, + miniboss = True), + DS3LocationData("LC: Irithyll Rapier", "Irithyll Rapier", DS3LocationCategory.WEAPON, + miniboss = True), # Boreal Outrider drop + DS3LocationData("LC: Twinkling Titanite #5", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("LC: Twinkling Titanite #6", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("LC: Gotthard Twinswords", "Gotthard Twinswords", DS3LocationCategory.WEAPON), DS3LocationData("LC: Grand Archives Key", "Grand Archives Key", DS3LocationCategory.KEY, prominent = True, progression = True, key = True), - DS3LocationData("LC: Gotthard Twinswords", "Gotthard Twinswords", DS3LocationCategory.WEAPON), + DS3LocationData("LC: Titanite Chunk #11", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Dancer's Enchanted Swords", "Dancer's Enchanted Swords", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("LC: Soothing Sunlight", "Soothing Sunlight", DS3LocationCategory.SPELL, + missable = True, boss = True, shop = True), + DS3LocationData("LC: Dragonslayer Greataxe", "Dragonslayer Greataxe", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("LC: Dragonslayer Greatshield", "Dragonslayer Greatshield", DS3LocationCategory.SHIELD, + missable = True, boss = True, shop = True), + + # Shrine Handmaid after killing Dancer of the Boreal Valley + DS3LocationData("LC: Dancer's Crown", "Dancer's Crown", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("LC: Dancer's Armor", "Dancer's Armor", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("LC: Dancer's Gauntlets", "Dancer's Gauntlets", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("LC: Dancer's Leggings", "Dancer's Leggings", DS3LocationCategory.ARMOR, + boss = True, shop = True), + + # Shrine Handmaid after killing Dragonslayer Armour (or Eygon of Carim) + DS3LocationData("LC: Morne's Helm", "Morne's Helm", DS3LocationCategory.ARMOR), + DS3LocationData("LC: Morne's Armor", "Morne's Armor", DS3LocationCategory.ARMOR), + DS3LocationData("LC: Morne's Gauntlets", "Morne's Gauntlets", DS3LocationCategory.ARMOR), + DS3LocationData("LC: Morne's Leggings", "Morne's Leggings", DS3LocationCategory.ARMOR), ], "Consumed King's Garden": [ - DS3LocationData("CKG: Dragonscale Ring", "Dragonscale Ring", DS3LocationCategory.RING), + + DS3LocationData("CKG: Soul of Consumed Oceiros", "Soul of Consumed Oceiros", DS3LocationCategory.BOSS, + prominent = True, boss = True), + # Could classify this as "hidden" because it's midway down an elevator, but the elevator is + # so slow and the midway point is so obvious that it's not actually hard to find. + DS3LocationData("CKG: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), DS3LocationData("CKG: Shadow Mask", "Shadow Mask", DS3LocationCategory.ARMOR), DS3LocationData("CKG: Shadow Garb", "Shadow Garb", DS3LocationCategory.ARMOR), DS3LocationData("CKG: Shadow Gauntlets", "Shadow Gauntlets", DS3LocationCategory.ARMOR), DS3LocationData("CKG: Shadow Leggings", "Shadow Leggings", DS3LocationCategory.ARMOR), + DS3LocationData("CKG: Black Firebomb", "Black Firebomb x2", DS3LocationCategory.MISC), DS3LocationData("CKG: Claw", "Claw", DS3LocationCategory.WEAPON), - DS3LocationData("CKG: Soul of Consumed Oceiros", "Soul of Consumed Oceiros", DS3LocationCategory.BOSS, - prominent = True, boss = True), + DS3LocationData("CKG: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("CKG: Dragonscale Ring", "Dragonscale Ring", DS3LocationCategory.RING), + DS3LocationData("CKG: Human Pine Resin #1", "Human Pine Resin", DS3LocationCategory.MISC), + DS3LocationData("CKG: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("CKG: Titanite Chunk #3", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("CKG: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("CKG: Dark Gem", "Dark Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("CKG: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("CKG: Human Pine Resin #2", "Human Pine Resin x2", DS3LocationCategory.MISC), + DS3LocationData("CKG: Titanite Chunk #4", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("CKG: Ring of Sacrifice", "Ring of Sacrifice", DS3LocationCategory.MISC), + DS3LocationData("CKG: Wood Grain Ring+1", "Wood Grain Ring+1", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("CKG: Sage Ring+2", "Sage Ring+2", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("CKG: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("CKG: Titanite Scale #3", "Titanite Scale", DS3LocationCategory.UPGRADE), DS3LocationData("CKG: Magic Stoneplate Ring", "Magic Stoneplate Ring", DS3LocationCategory.RING, hidden = True), # Guaranteed drop from a normal-looking Consumed King's Knight + DS3LocationData("CKG: Moonlight Greatsword", "Moonlight Greatsword", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("CKG: White Dragon Breath", "White Dragon Breath", DS3LocationCategory.SPELL, + missable = True, boss = True, shop = True), ], "Grand Archives": [ + # At the bottom of the shortcut elevator right outside the Twin Princes fight. Requires sending the elevator up to the top from the middle, and then riding the lower elevator down. + DS3LocationData("GA: Titanite Slab #1", "Titanite Slab", DS3LocationCategory.UPGRADE, + hidden = True), # Elevator secret + DS3LocationData("GA: Soul of the Twin Princes", "Soul of the Twin Princes", DS3LocationCategory.BOSS, + boss = True), + DS3LocationData("GA: Cinders of a Lord - Lothric Prince", "Cinders of a Lord - Lothric Prince", DS3LocationCategory.KEY, + offline = "09,0:50002040::", prominent = True, progression = True, boss = True), + DS3LocationData("GA: Onikiri and Ubadachi", "Onikiri and Ubadachi", DS3LocationCategory.WEAPON, + hostile_npc = True), # Black Hand Kamui drop + DS3LocationData("GA: Golden Wing Crest Shield", "Golden Wing Crest Shield", DS3LocationCategory.SHIELD, + hostile_npc = True), # Lion Knight Albert drop + DS3LocationData("GA: Sage's Crystal Staff", "Sage's Crystal Staff", DS3LocationCategory.WEAPON, + hostile_npc = True), # Daughter of Crystal Kriemhild drop + DS3LocationData("GA: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("GA: Titanite Chunk #3", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Fleshbite Ring", "Fleshbite Ring", DS3LocationCategory.RING), + DS3LocationData("GA: Soul of a Crestfallen Knight #2", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("GA: Soul of a Nameless Soldier", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("GA: Crystal Chime", "Crystal Chime", DS3LocationCategory.WEAPON), + DS3LocationData("GA: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), + DS3LocationData("GA: Homeward Bone", "Homeward Bone x3", DS3LocationCategory.MISC), + DS3LocationData("GA: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE, + hidden = True), # Hidden fall + DS3LocationData("GA: Titanite Chunk #4", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Hollow Gem", "Hollow Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Titanite Scale #3", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Titanite Scale #4", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Titanite Scale #5", "Titanite Scale", DS3LocationCategory.UPGRADE, + hidden = True), # Hidden by a table + DS3LocationData("GA: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Large Soul of a Crestfallen Knight #1", "Large Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("GA: Titanite Chunk #5", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Titanite Scale #6", "Titanite Scale x3", DS3LocationCategory.UPGRADE, + hidden = True), # Hidden fall + DS3LocationData("GA: Titanite Chunk #6", "Titanite Chunk", DS3LocationCategory.UPGRADE, + hidden = True), # Hidden fall + DS3LocationData("GA: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("GA: Titanite Chunk #7", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Ember", "Ember", DS3LocationCategory.MISC), + DS3LocationData("GA: Blessed Gem", "Blessed Gem", DS3LocationCategory.UPGRADE, + hidden = True), # Hidden fall + DS3LocationData("GA: Titanite Chunk #8", "Titanite Chunk x2", DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Large Soul of a Crestfallen Knight #2", "Large Soul of a Crestfallen Knight", DS3LocationCategory.MISC), DS3LocationData("GA: Avelyn", "Avelyn", DS3LocationCategory.WEAPON, hidden = True), # Hidden fall - DS3LocationData("GA: Witch's Locks", "Witch's Locks", DS3LocationCategory.WEAPON, - hidden = True), # Switch in darkened room + DS3LocationData("GA: Titanite Chunk #9", "Titanite Chunk", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("GA: Hunter's Ring", "Hunter's Ring", DS3LocationCategory.RING, + hostile_npc = True), # Daughter of Crystal Kriemhild drop + DS3LocationData("GA: Divine Pillars of Light", "Divine Pillars of Light", DS3LocationCategory.SPELL, + hidden = True), # Hidden fall DS3LocationData("GA: Power Within", "Power Within", DS3LocationCategory.SPELL, hidden = True), # Switch in darkened room - DS3LocationData("GA: Scholar Ring", "Scholar Ring", DS3LocationCategory.RING), + DS3LocationData("GA: Sage Ring+1", "Sage Ring+1", DS3LocationCategory.RING, + ngp = True, hidden = True), # Hidden fall + DS3LocationData("GA: Lingering Dragoncrest Ring+2", "Lingering Dragoncrest Ring+2", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("GA: Divine Blessing", "Divine Blessing", DS3LocationCategory.MISC, + hidden = True), # Hidden fall + DS3LocationData("GA: Twinkling Titanite #1", "Twinkling Titanite x3", DS3LocationCategory.MISC, + hidden = True), # Hidden fall + DS3LocationData("GA: Witch's Locks", "Witch's Locks", DS3LocationCategory.WEAPON, + hidden = True), # Switch in darkened room + DS3LocationData("GA: Titanite Slab #2", "Titanite Slab", DS3LocationCategory.UPGRADE, + hidden = True), # Backtrack after flipping bridge switch + DS3LocationData("GA: Titanite Scale #7", "Titanite Scale x3", DS3LocationCategory.MISC), DS3LocationData("GA: Soul Stream", "Soul Stream", DS3LocationCategory.SPELL, - hidden = True), # Behind invisible wall - DS3LocationData("GA: Fleshbite Ring", "Fleshbite Ring", DS3LocationCategory.RING), - DS3LocationData("GA: Crystal Chime", "Crystal Chime", DS3LocationCategory.WEAPON), - DS3LocationData("GA: Golden Wing Crest Shield", "Golden Wing Crest Shield", DS3LocationCategory.SHIELD, - hostile_npc = True), # Lion Knight Albert drop - DS3LocationData("GA: Onikiri and Ubadachi", "Onikiri and Ubadachi", DS3LocationCategory.WEAPON, - hostile_npc = True), # Black Hand Kamui drop - DS3LocationData("GA: Hunter's Ring", "Hunter's Ring", DS3LocationCategory.RING, - hostile_npc = True), # Daughter of Crystal Kriemhild drop - DS3LocationData("GA: Divine Pillars of Light", "Divine Pillars of Light", DS3LocationCategory.SPELL), - DS3LocationData("GA: Cinders of a Lord - Lothric Prince", "Cinders of a Lord - Lothric Prince", DS3LocationCategory.KEY, - offline = "09,0:50002040::", prominent = True, progression = True, boss = True), - DS3LocationData("GA: Soul of the Twin Princes", "Soul of the Twin Princes", DS3LocationCategory.BOSS, - boss = True), - DS3LocationData("GA: Sage's Crystal Staff", "Sage's Crystal Staff", DS3LocationCategory.WEAPON), + hidden = True), # Behind illusory wall + DS3LocationData("GA: Scholar Ring", "Scholar Ring", DS3LocationCategory.RING), + DS3LocationData("GA: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), + DS3LocationData("GA: Titanite Slab #3", "Titanite Slab", DS3LocationCategory.UPGRADE, + hidden = True), # Guaranteed drop from killing all Winged Knights DS3LocationData("GA: Outrider Knight Helm", "Outrider Knight Helm", DS3LocationCategory.ARMOR, - miniboss = True, hidden = True), # Behind invisible wall + miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop DS3LocationData("GA: Outrider Knight Armor", "Outrider Knight Armor", DS3LocationCategory.ARMOR, - miniboss = True, hidden = True), # Behind invisible wall + miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop DS3LocationData("GA: Outrider Knight Gauntlets", "Outrider Knight Gauntlets", DS3LocationCategory.ARMOR, - miniboss = True, hidden = True), # Behind invisible wall + miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop DS3LocationData("GA: Outrider Knight Leggings", "Outrider Knight Leggings", DS3LocationCategory.ARMOR, - miniboss = True, hidden = True), # Behind invisible wall + miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop DS3LocationData("GA: Crystal Scroll", "Crystal Scroll", DS3LocationCategory.MISC, miniboss = True), # Crystal Sage drop + DS3LocationData("GA: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("GA: Chaos Gem", "Chaos Gem", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("GA: Twinkling Titanite #3", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("GA: Crystal Gem", "Crystal Gem", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("GA: Twinkling Titanite #4", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("GA: Titanite Scale #8", "Titanite Scale x2", DS3LocationCategory.UPGRADE, + hidden = True, lizard = True), # Hidden fall + DS3LocationData("GA: Twinkling Titanite #5", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("GA: Heavy Gem", "Heavy Gem", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("GA: Twinkling Titanite #6", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("GA: Sharp Gem", "Sharp Gem", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("GA: Twinkling Titanite #7", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("GA: Refined Gem", "Refined Gem", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("GA: Twinkling Titanite #8", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("GA: Lorian's Greatsword", "Lorian's Greatsword", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("GA: Lothric's Holy Sword", "Lothric's Holy Sword", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + + # Shrine Handmaid after killing NPCs + DS3LocationData("GA: Faraam Helm", "Faraam Helm", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True, shop = True), + DS3LocationData("GA: Faraam Armor", "Faraam Armor", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True, shop = True), + DS3LocationData("GA: Faraam Gauntlets", "Faraam Gauntlets", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True, shop = True), + DS3LocationData("GA: Faraam Boots", "Faraam Boots", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True, shop = True), + DS3LocationData("GA: Black Hand Hat", "Black Hand Hat", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True, shop = True), + DS3LocationData("GA: Black Hand Armor", "Black Hand Armor", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True, shop = True), + + # Shrine Handmaid after killing Lothric, Younger Prince + DS3LocationData("GA: Lorian's Helm", "Lorian's Helm", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("GA: Lorian's Armor", "Lorian's Armor", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("GA: Lorian's Gauntlets", "Lorian's Gauntlets", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("GA: Lorian's Leggings", "Lorian's Leggings", DS3LocationCategory.ARMOR, + boss = True, shop = True), ], + # The whole area is behind an illusory wall and thus marked hidden "Untended Graves": [ + DS3LocationData("UG: Soul of Champion Gundyr", "Soul of Champion Gundyr", DS3LocationCategory.BOSS, + prominent = True, boss = True, hidden = True), + DS3LocationData("UG: Priestess Ring", "Priestess Ring", DS3LocationCategory.RING, + hidden = True), + DS3LocationData("UG: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE, + hidden = True), + DS3LocationData("UG: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE, + hidden = True), + DS3LocationData("UG: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC, + hidden = True), + DS3LocationData("UG: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE, + hidden = True), DS3LocationData("UG: Ashen Estus Ring", "Ashen Estus Ring", DS3LocationCategory.RING, - hidden = True), # Behind invisible wall + hidden = True), DS3LocationData("UG: Black Knight Glaive", "Black Knight Glaive", DS3LocationCategory.WEAPON, - hidden = True), # Behind invisible wall - DS3LocationData("UG: Hornet Ring", "Hornet Ring", DS3LocationCategory.RING, - offline = "00,0:54000330::", hidden = True), # Behind invisible wall - DS3LocationData("UG: Chaos Blade", "Chaos Blade", DS3LocationCategory.WEAPON, - hidden = True), # Behind invisible wall - DS3LocationData("UG: Blacksmith Hammer", "Blacksmith Hammer", DS3LocationCategory.WEAPON, - hidden = True), # Behind invisible wall + hidden = True), + DS3LocationData("UG: Hidden Blessing", "Hidden Blessing", DS3LocationCategory.MISC, + hidden = True), DS3LocationData("UG: Eyes of a Fire Keeper", "Eyes of a Fire Keeper", DS3LocationCategory.KEY, - hidden = True), # Behind invisible wall + hidden = True), + DS3LocationData("UG: Soul of a Crestfallen Knight #2", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC, + hidden = True), + DS3LocationData("UG: Blacksmith Hammer", "Blacksmith Hammer", DS3LocationCategory.WEAPON, + hidden = True), + DS3LocationData("UG: Chaos Blade", "Chaos Blade", DS3LocationCategory.WEAPON, + hidden = True), DS3LocationData("UG: Coiled Sword Fragment", "Coiled Sword Fragment", DS3LocationCategory.MISC, - boss = True, hidden = True), # Behind invisible wall - DS3LocationData("UG: Soul of Champion Gundyr", "Soul of Champion Gundyr", DS3LocationCategory.BOSS, - prominent = True, boss = True, hidden = True), # Behind invisible wall + boss = True, hidden = True), + DS3LocationData("UG: Life Ring+3", "Life Ring+3", DS3LocationCategory.RING, + ngp = True, hidden = True), + DS3LocationData("UG: Ring of Steel Protection+1", "Ring of Steel Protection+1", DS3LocationCategory.RING, + ngp = True, hidden = True), + DS3LocationData("UG: Hornet Ring", "Hornet Ring", DS3LocationCategory.RING, + hidden = True), + DS3LocationData("FS: Gundyr's Halberd", "Gundyr's Halberd", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("FS: Prisoner's Chain", "Prisoner's Chain", DS3LocationCategory.RING, + missable = True, boss = True, shop = True), + + # Yuria shop, or Shrine Handmaiden with Hollow's Ashes + # This is here because this is where the ashes end up if you kill Yoel or Yuria + DS3LocationData("UG: Ring of Sacrifice", "Ring of Sacrifice", DS3LocationCategory.MISC, + offline = '99,0:-1:40000,110000,70000107,70000116:', hidden = True, npc = True, shop = True), + + # Untended Graves Handmaid + DS3LocationData("UG: Ember", "Ember", DS3LocationCategory.RING, + hidden = True, shop = True), + # Untended Graves Handmaid after killing Abyss Watchers + DS3LocationData("UG: Wolf Knight Helm", "Wolf Knight Helm", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("UG: Wolf Knight Armor", "Wolf Knight Armor", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("UG: Wolf Knight Gauntlets", "Wolf Knight Gauntlets", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("UG: Wolf Knight Leggings", "Wolf Knight Leggings", DS3LocationCategory.ARMOR, + boss = True, shop = True), + + # Shrine Handmaid after killing Champion Gundyr + DS3LocationData("UG: Gundyr's Helm", "Gundyr's Helm", DS3LocationCategory.ARMOR, + hidden = True, boss = True, shop = True), + DS3LocationData("UG: Gundyr's Armor", "Gundyr's Armor", DS3LocationCategory.ARMOR, + hidden = True, boss = True, shop = True), + DS3LocationData("UG: Gundyr's Gauntlets", "Gundyr's Gauntlets", DS3LocationCategory.ARMOR, + hidden = True, boss = True, shop = True), + DS3LocationData("UG: Gundyr's Leggings", "Gundyr's Leggings", DS3LocationCategory.ARMOR, + hidden = True, boss = True, shop = True), ], "Archdragon Peak": [ - DS3LocationData("AP: Lightning Clutch Ring", "Lightning Clutch Ring", DS3LocationCategory.RING), - DS3LocationData("AP: Ancient Dragon Greatshield", "Ancient Dragon Greatshield", DS3LocationCategory.SHIELD), - DS3LocationData("AP: Ring of Steel Protection", "Ring of Steel Protection", DS3LocationCategory.RING), - DS3LocationData("AP: Calamity Ring", "Calamity Ring", DS3LocationCategory.RING, - hidden = True), # Requires gesture + + DS3LocationData("AP: Dragon Head Stone", "Dragon Head Stone", DS3LocationCategory.MISC, + prominent = True, boss = True), + DS3LocationData("AP: Soul of the Nameless King", "Soul of the Nameless King", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("AP: Dragon Tooth", "Dragon Tooth", DS3LocationCategory.WEAPON, + hostile_npc = True), # Havel Knight drop + DS3LocationData("AP: Havel's Greatshield", "Havel's Greatshield", DS3LocationCategory.SHIELD, + hostile_npc = True), # Havel Knight drop DS3LocationData("AP: Drakeblood Greatsword", "Drakeblood Greatsword", DS3LocationCategory.WEAPON, hostile_npc = True, hidden = True), # Drop from a summon who may or may not appear - DS3LocationData("AP: Dragonslayer Spear", "Dragonslayer Spear", DS3LocationCategory.WEAPON), + DS3LocationData("AP: Ricard's Rapier", "Ricard's Rapier", DS3LocationCategory.WEAPON, + hostile_npc = True, hidden = True), # Drop from a summon who may or may not appear + DS3LocationData("AP: Lightning Clutch Ring", "Lightning Clutch Ring", DS3LocationCategory.RING), + DS3LocationData("AP: Stalk Dung Pie", "Stalk Dung Pie x6", DS3LocationCategory.MISC), + DS3LocationData("AP: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Soul of a Weary Warrior #1", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("AP: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Lightning Gem", "Lightning Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC), + DS3LocationData("AP: Soul of a Nameless Soldier", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("AP: Titanite Chunk #3", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Ember #1", "Ember", DS3LocationCategory.MISC), + DS3LocationData("AP: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("AP: Large Soul of a Nameless Soldier", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("AP: Lightning Urn", "Lightning Urn x4", DS3LocationCategory.MISC), + DS3LocationData("AP: Lightning Bolt", "Lightning Bolt x12", DS3LocationCategory.MISC), + DS3LocationData("AP: Titanite Chunk #4", "Titanite Chunk x2", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Dung Pie", "Dung Pie x3", DS3LocationCategory.MISC), + DS3LocationData("AP: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Soul of a Weary Warrior #2", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("AP: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("AP: Titanite Chunk #5", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Ember #2", "Ember", DS3LocationCategory.MISC), DS3LocationData("AP: Thunder Stoneplate Ring", "Thunder Stoneplate Ring", DS3LocationCategory.RING), - DS3LocationData("AP: Great Magic Barrier", "Great Magic Barrier", DS3LocationCategory.SPELL), - DS3LocationData("AP: Dragon Chaser's Ashes", "Dragon Chaser's Ashes", DS3LocationCategory.MISC), - DS3LocationData("AP: Twinkling Dragon Torso Stone", "Twinkling Dragon Torso Stone", DS3LocationCategory.MISC, - hidden = True), # Requires gesture + DS3LocationData("AP: Titanite Scale #3", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Ember #3", "Ember", DS3LocationCategory.MISC), + DS3LocationData("AP: Ancient Dragon Greatshield", "Ancient Dragon Greatshield", DS3LocationCategory.SHIELD), + DS3LocationData("AP: Large Soul of a Crestfallen Knight", "Large Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("AP: Dragon Chaser's Ashes", "Dragon Chaser's Ashes", DS3LocationCategory.KEY, + progression = True), + DS3LocationData("AP: Ember #4", "Ember", DS3LocationCategory.MISC), + DS3LocationData("AP: Dragonslayer Spear", "Dragonslayer Spear", DS3LocationCategory.WEAPON), DS3LocationData("AP: Dragonslayer Helm", "Dragonslayer Helm", DS3LocationCategory.ARMOR), DS3LocationData("AP: Dragonslayer Armor", "Dragonslayer Armor", DS3LocationCategory.ARMOR), DS3LocationData("AP: Dragonslayer Gauntlets", "Dragonslayer Gauntlets", DS3LocationCategory.ARMOR), DS3LocationData("AP: Dragonslayer Leggings", "Dragonslayer Leggings", DS3LocationCategory.ARMOR), - DS3LocationData("AP: Ricard's Rapier", "Ricard's Rapier", DS3LocationCategory.WEAPON, - hostile_npc = True, hidden = True), # Drop from a summon who may or may not appear - DS3LocationData("AP: Soul of the Nameless King", "Soul of the Nameless King", DS3LocationCategory.BOSS, - prominent = True, boss = True), - DS3LocationData("AP: Dragon Tooth", "Dragon Tooth", DS3LocationCategory.WEAPON, - hostile_npc = True), # Havel Knight drop - DS3LocationData("AP: Havel's Greatshield", "Havel's Greatshield", DS3LocationCategory.SHIELD, - hostile_npc = True), # Havel Knight drop + DS3LocationData("AP: Twinkling Titanite #1", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Twinkling Titanite #2", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Titanite Slab #1", "Titanite Slab", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Great Magic Barrier", "Great Magic Barrier", DS3LocationCategory.SPELL, + hidden = True), # Hidden fall + DS3LocationData("AP: Titanite Slab #2", "Titanite Slab", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Ring of Steel Protection", "Ring of Steel Protection", DS3LocationCategory.RING), + DS3LocationData("AP: Havel's Ring+1", "Havel's Ring+1", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("AP: Covetous Gold Serpent Ring+2", "Covetous Gold Serpent Ring+2", DS3LocationCategory.RING, + ngp = True), + DS3LocationData("AP: Titanite Scale #4", "Titanite Scale x3", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Twinkling Titanite #3", "Twinkling Titanite x3", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Twinkling Dragon Torso Stone", "Twinkling Dragon Torso Stone", DS3LocationCategory.MISC, + hidden = True), # Requires gesture + DS3LocationData("AP: Calamity Ring", "Calamity Ring", DS3LocationCategory.RING, + hidden = True), # Requires gesture + DS3LocationData("AP: Twinkling Titanite #4", "Twinkling Titanite x3", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("AP: Titanite Chunk #6", "Titanite Chunk x6", DS3LocationCategory.UPGRADE, + miniboss = True), # Wyvern miniboss drop + DS3LocationData("AP: Titanite Scale #5", "Titanite Scale x3", DS3LocationCategory.UPGRADE, + miniboss = True), # Wyvern miniboss drop + DS3LocationData("AP: Twinkling Titanite #5", "Twinkling Titanite x3", DS3LocationCategory.UPGRADE, + miniboss = True), # Wyvern miniboss drop + DS3LocationData("AP: Hawkwood's Swordgrass", "Hawkwood's Swordgrass", DS3LocationCategory.MISC, + hidden = True), + DS3LocationData("AP: Storm Curved Sword", "Storm Curved Sword", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("AP: Dragonslayer Swordspear", "Dragonslayer Swordspear", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("AP: Lightning Storm", "Lightning Storm", DS3LocationCategory.SPELL, + missable = True, boss = True, shop = True), + + # Shrine Handmaid after killing Nameless King + DS3LocationData("AP: Golden Crown", "Golden Crown", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("AP: Dragonscale Armor", "Dragonscale Armor", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("AP: Golden Bracelets", "Golden Bracelets", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("AP: Dragonscale Waistcloth", "Dragonscale Waistcloth", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("AP: Twinkling Dragon Head Stone", "Twinkling Dragon Head Stone", DS3LocationCategory.MISC, + missable = True, npc = True), # Hawkwood (quest) + + # After Oceiros's boss room, only once the Drakeblood summon in AP has been killed + DS3LocationData("AP: Drakeblood Helm", "Drakeblood Helm", DS3LocationCategory.ARMOR, + missable = True, hostile_npc = True), + DS3LocationData("AP: Drakeblood Armor", "Drakeblood Armor", DS3LocationCategory.ARMOR, + missable = True, hostile_npc = True), + DS3LocationData("AP: Drakeblood Gauntlets", "Drakeblood Gauntlets", DS3LocationCategory.ARMOR, + missable = True, hostile_npc = True), + DS3LocationData("AP: Drakeblood Leggings", "Drakeblood Leggings", DS3LocationCategory.ARMOR, + missable = True, hostile_npc = True), + + # Appears by Stray Demon after killing Havel Knight + DS3LocationData("AP: Havel's Helm", "Havel's Helm", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True), + DS3LocationData("AP: Havel's Armor", "Havel's Armor", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True), + DS3LocationData("AP: Havel's Gauntlets", "Havel's Gauntlets", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True), + DS3LocationData("AP: Havel's Leggings", "Havel's Leggings", DS3LocationCategory.ARMOR, + hidden = True, hostile_npc = True), ], - "Kiln of the First Flame": [], + "Kiln of the First Flame": [ + DS3LocationData("KFF: Firelink Greatsword", "Firelink Greatsword", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("KFF: Sunlight Spear", "Sunlight Spear", DS3LocationCategory.SPELL, + missable = True, boss = True, shop = True), - # DLC - "Painted World of Ariandel 1": [ - DS3LocationData("PW: Follower Javelin", "Follower Javelin", DS3LocationCategory.WEAPON), - DS3LocationData("PW: Frozen Weapon", "Frozen Weapon", DS3LocationCategory.SPELL), - DS3LocationData("PW: Millwood Greatbow", "Millwood Greatbow", DS3LocationCategory.WEAPON), - DS3LocationData("PW: Captain's Ashes", "Captain's Ashes", DS3LocationCategory.MISC), - DS3LocationData("PW: Millwood Battle Axe", "Millwood Battle Axe", DS3LocationCategory.WEAPON), - DS3LocationData("PW: Ethereal Oak Shield", "Ethereal Oak Shield", DS3LocationCategory.SHIELD), - DS3LocationData("PW: Crow Quills", "Crow Quills", DS3LocationCategory.WEAPON, - hidden = True), # Hidden fall - DS3LocationData("PW: Slave Knight Hood", "Slave Knight Hood", DS3LocationCategory.ARMOR), - DS3LocationData("PW: Slave Knight Armor", "Slave Knight Armor", DS3LocationCategory.ARMOR), - DS3LocationData("PW: Slave Knight Gauntlets", "Slave Knight Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("PW: Slave Knight Leggings", "Slave Knight Leggings", DS3LocationCategory.ARMOR), - DS3LocationData("PW: Way of White Corona", "Way of White Corona", DS3LocationCategory.SPELL), - DS3LocationData("PW: Crow Talons", "Crow Talons", DS3LocationCategory.WEAPON), - DS3LocationData("PW: Onyx Blade", "Onyx Blade", DS3LocationCategory.WEAPON, - hostile_npc = True), # Sir Vilhelm drop - DS3LocationData("PW: Contraption Key", "Contraption Key", DS3LocationCategory.KEY, - prominent = True, progression = True, hostile_npc = True, key = True), # Sir Vilhelm drop + # Shrine Handmaid after placing all Cinders of a Lord + DS3LocationData("KFF: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE, + hidden = True), + DS3LocationData("KFF: Firelink Helm", "Firelink Helm", DS3LocationCategory.ARMOR, + missable = True), + DS3LocationData("KFF: Firelink Armor", "Firelink Armor", DS3LocationCategory.ARMOR, + missable = True), + DS3LocationData("KFF: Firelink Gauntlets", "Firelink Gauntlets", DS3LocationCategory.ARMOR, + missable = True), + DS3LocationData("KFF: Firelink Leggings", "Firelink Leggings", DS3LocationCategory.ARMOR, + missable = True), + + # Yuria (quest, after Soul of Cinder) + DS3LocationData("KFF: Billed Mask", "Billed Mask", DS3LocationCategory.ARMOR, + missable = True, npc = True), + DS3LocationData("KFF: Black Dress", "Black Dress", DS3LocationCategory.ARMOR, + missable = True, npc = True), + DS3LocationData("KFF: Black Gauntlets", "Black Gauntlets", DS3LocationCategory.ARMOR, + missable = True, npc = True), + DS3LocationData("KFF: Black Leggings", "Black Leggings", DS3LocationCategory.ARMOR, + missable = True, npc = True), ], - "Painted World of Ariandel 2": [ - DS3LocationData("PW: Quakestone Hammer", "Quakestone Hammer", DS3LocationCategory.WEAPON), - DS3LocationData("PW: Earth Seeker", "Earth Seeker", DS3LocationCategory.WEAPON), - DS3LocationData("PW: Follower Torch", "Follower Torch", DS3LocationCategory.SHIELD), - DS3LocationData("PW: Follower Shield", "Follower Shield", DS3LocationCategory.SHIELD), - DS3LocationData("PW: Follower Sabre", "Follower Sabre", DS3LocationCategory.WEAPON), - DS3LocationData("PW: Snap Freeze", "Snap Freeze", DS3LocationCategory.SPELL), - DS3LocationData("PW: Floating Chaos", "Floating Chaos", DS3LocationCategory.SPELL), - DS3LocationData("PW: Pyromancer's Parting Flame", "Pyromancer's Parting Flame", DS3LocationCategory.WEAPON), - DS3LocationData("PW: Vilhelm's Helm", "Vilhelm's Helm", DS3LocationCategory.ARMOR), - DS3LocationData("PW: Vilhelm's Armor", "Vilhelm's Armor", DS3LocationCategory.ARMOR), - DS3LocationData("PW: Vilhelm's Gauntlets", "Vilhelm's Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("PW: Vilhelm's Leggings", "Vilhelm's Leggings", DS3LocationCategory.ARMOR), - DS3LocationData("PW: Valorheart", "Valorheart", DS3LocationCategory.WEAPON, + + # DLC + "Painted World of Ariandel (Before Contraption)": [ + DS3LocationData("PW1: Valorheart", "Valorheart", DS3LocationCategory.WEAPON, prominent = True, boss = True), - DS3LocationData("PW: Champion's Bones", "Champion's Bones", DS3LocationCategory.MISC, + DS3LocationData("PW1: Contraption Key", "Contraption Key", DS3LocationCategory.KEY, + prominent = True, progression = True, hostile_npc = True, key = True), # Sir Vilhelm drop + DS3LocationData("PW1: Onyx Blade", "Onyx Blade", DS3LocationCategory.WEAPON, + hostile_npc = True), # Sir Vilhelm drop + DS3LocationData("PW: Chillbite Ring", "Chillbite Ring", DS3LocationCategory.RING, + npc = True), + DS3LocationData("PW1: Rime-blue Moss Clump #1", "Rime-blue Moss Clump x2", DS3LocationCategory.MISC), + DS3LocationData("PW1: Poison Gem", "Poison Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #1", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Follower Javelin", "Follower Javelin", DS3LocationCategory.WEAPON), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #2", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Homeward Bone #1", "Homeward Bone x6", DS3LocationCategory.MISC), + DS3LocationData("PW1: Blessed Gem", "Blessed Gem", DS3LocationCategory.UPGRADE, + hidden = True), # Hidden behind a tower + DS3LocationData("PW1: Captain's Ashes", "Captain's Ashes", DS3LocationCategory.KEY, + progression = True), + DS3LocationData("PW1: Black Firebomb", "Black Firebomb x2", DS3LocationCategory.MISC), + DS3LocationData("PW1: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), + DS3LocationData("PW1: Millwood Greatarrow", "Millwood Greatarrow x5", DS3LocationCategory.MISC), + DS3LocationData("PW1: Millwood Greatbow", "Millwood Greatbow", DS3LocationCategory.WEAPON), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #3", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Rusted Coin #1", "Rusted Coin", DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #4", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Crow Quills", "Crow Quills", DS3LocationCategory.WEAPON, + hidden = True), # Hidden fall + DS3LocationData("PW1: Simple Gem", "Simple Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #5", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Slave Knight Hood", "Slave Knight Hood", DS3LocationCategory.ARMOR), + DS3LocationData("PW1: Slave Knight Armor", "Slave Knight Armor", DS3LocationCategory.ARMOR), + DS3LocationData("PW1: Slave Knight Gauntlets", "Slave Knight Gauntlets", DS3LocationCategory.ARMOR), + DS3LocationData("PW1: Slave Knight Leggings", "Slave Knight Leggings", DS3LocationCategory.ARMOR), + DS3LocationData("PW1: Ember #1", "Ember", DS3LocationCategory.MISC), + DS3LocationData("PW1: Dark Gem", "Dark Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #6", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #7", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Rusted Gold Coin", "Rusted Gold Coin x3", DS3LocationCategory.MISC), + DS3LocationData("PW1: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("PW1: Way of White Corona", "Way of White Corona", DS3LocationCategory.SPELL), + DS3LocationData("PW1: Rusted Coin #2", "Rusted Coin x2", DS3LocationCategory.MISC), + DS3LocationData("PW1: Young White Branch", "Young White Branch", DS3LocationCategory.MISC), + DS3LocationData("PW1: Budding Green Blossom", "Budding Green Blossom x3", DS3LocationCategory.MISC), + DS3LocationData("PW1: Crow Talons", "Crow Talons", DS3LocationCategory.WEAPON), + DS3LocationData("PW1: Blood Gem", "Blood Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("PW1: Hollow Gem", "Hollow Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("PW1: Rime-blue Moss Clump #2", "Rime-blue Moss Clump x4", DS3LocationCategory.MISC), + DS3LocationData("PW1: Follower Sabre", "Follower Sabre", DS3LocationCategory.WEAPON), + DS3LocationData("PW1: Ember #2", "Ember", DS3LocationCategory.MISC), + DS3LocationData("PW1: Snap Freeze", "Snap Freeze", DS3LocationCategory.SPELL, + hidden = True), # Guaranteed drop from normal-looking Tree Woman + DS3LocationData("PW1: Rime-blue Moss Clump #3", "Rime-blue Moss Clump", DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #8", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Ember #3", "Ember", DS3LocationCategory.MISC), + DS3LocationData("PW1: Frozen Weapon", "Frozen Weapon", DS3LocationCategory.SPELL), + DS3LocationData("PW1: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE, + offline = '11,0:50004700::', hidden = True), # Must kill normal-looking Tree Woman + DS3LocationData("PW1: Homeward Bone #2", "Homeward Bone x2", DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #9", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Soul of a Weary Warrior #1", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #10", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Heavy Gem", "Heavy Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("PW1: Large Soul of a Weary Warrior #2", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("PW1: Millwood Battle Axe", "Millwood Battle Axe", DS3LocationCategory.WEAPON), + DS3LocationData("PW1: Ethereal Oak Shield", "Ethereal Oak Shield", DS3LocationCategory.SHIELD), + DS3LocationData("PW1: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("PW1: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("PW1: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("PW1: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("PW1: Twinkling Titanite #3", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("PW1: Large Titanite Shard #3", "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("PW2: Champion's Bones", "Champion's Bones", DS3LocationCategory.MISC, boss = True), - DS3LocationData("PW: Soul of Sister Friede", "Soul of Sister Friede", DS3LocationCategory.BOSS, + ], + "Painted World of Ariandel (After Contraption)": [ + DS3LocationData("PW2: Soul of Sister Friede", "Soul of Sister Friede", DS3LocationCategory.BOSS, prominent = True, boss = True), - DS3LocationData("PW: Chillbite Ring", "Chillbite Ring", DS3LocationCategory.RING), + DS3LocationData("PW2: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE, + boss = True), # One-time drop after Friede Phase 2 + DS3LocationData("PW2: Floating Chaos", "Floating Chaos", DS3LocationCategory.SPELL, + missable = True, hostile_npc = True), # Livid Pyromancer Dunnel drop (requires ember) + DS3LocationData("PW2: Prism Stone", "Prism Stone x10", DS3LocationCategory.MISC), + DS3LocationData("PW2: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("PW2: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("PW2: Follower Shield", "Follower Shield", DS3LocationCategory.SHIELD), + DS3LocationData("PW2: Large Titanite Shard #1", "Large Titanite Shard x2", DS3LocationCategory.UPGRADE), + DS3LocationData("PW2: Quakestone Hammer", "Quakestone Hammer", DS3LocationCategory.WEAPON), + DS3LocationData("PW2: Ember", "Ember", DS3LocationCategory.MISC), + DS3LocationData("PW2: Large Titanite Shard #2", "Large Titanite Shard x2", DS3LocationCategory.UPGRADE), + DS3LocationData("PW2: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("PW2: Soul of a Crestfallen Knight #2", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("PW2: Large Soul of a Crestfallen Knight", "Large Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("PW2: Earth Seeker", "Earth Seeker", DS3LocationCategory.WEAPON), + DS3LocationData("PW2: Follower Torch", "Follower Torch", DS3LocationCategory.SHIELD), + DS3LocationData("PW2: Dung Pie", "Dung Pie x2", DS3LocationCategory.MISC), + DS3LocationData("PW2: Vilhelm's Helm", "Vilhelm's Helm", DS3LocationCategory.ARMOR), + DS3LocationData("PW2: Vilhelm's Armor", "Vilhelm's Armor", DS3LocationCategory.ARMOR), + DS3LocationData("PW2: Vilhelm's Gauntlets", "Vilhelm's Gauntlets", DS3LocationCategory.ARMOR), + DS3LocationData("PW2: Vilhelm's Leggings", "Vilhelm's Leggings", DS3LocationCategory.ARMOR), + DS3LocationData("PW2: Pyromancer's Parting Flame", "Pyromancer's Parting Flame", DS3LocationCategory.WEAPON, + hidden = True), # Behind illusory wall + DS3LocationData("PW2: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC, + hidden = True), # Behind illusory wall + DS3LocationData("PW2: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("PW2: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("PW2: Friede's Great Scythe", "Friede's Great Scythe", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("PW2: Rose of Ariandel", "Rose of Ariandel", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("PW2: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE, + offline = '11,0:50006540::', missable = True, npc = True), # Corvian Settler (quest) + + # Shrine Handmaid after killing Sister Friede + DS3LocationData("PW2: Ordained Hood", "Ordained Hood", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("PW2: Ordained Dress", "Ordained Dress", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("PW2: Ordained Trousers", "Ordained Trousers", DS3LocationCategory.ARMOR, + boss = True, shop = True), ], "Dreg Heap": [ - DS3LocationData("DH: Loincloth", "Loincloth", DS3LocationCategory.ARMOR), + DS3LocationData("DH: Soul of the Demon Prince", "Soul of the Demon Prince", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("DH: Siegbräu", "Siegbräu", DS3LocationCategory.MISC, + missable = True, npc = True), # Lapp (quest or kill) + DS3LocationData("DH: Flame Fan", "Flame Fan", DS3LocationCategory.SPELL, + hostile_npc = True), # Desert Pyromancer Zoey drop + DS3LocationData("DH: Ember #1", "Ember", DS3LocationCategory.MISC), + DS3LocationData("DH: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("DH: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("DH: Aquamarine Dagger", "Aquamarine Dagger", DS3LocationCategory.WEAPON), + DS3LocationData("DH: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE), DS3LocationData("DH: Murky Hand Scythe", "Murky Hand Scythe", DS3LocationCategory.WEAPON), + DS3LocationData("DH: Divine Blessing #1", "Divine Blessing", DS3LocationCategory.MISC), + DS3LocationData("DH: Ring of Steel Protection+3", "Ring of Steel Protection+3", DS3LocationCategory.RING), + DS3LocationData("DH: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("DH: Rusted Coin", "Rusted Coin x2", DS3LocationCategory.MISC), + DS3LocationData("DH: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("DH: Murky Longstaff", "Murky Longstaff", DS3LocationCategory.WEAPON), + DS3LocationData("DH: Ember #2", "Ember", DS3LocationCategory.MISC, + hidden = True), # Behind illusory wall DS3LocationData("DH: Great Soul Dregs", "Great Soul Dregs", DS3LocationCategory.SPELL, - hidden = True), # Behind invisible wall - DS3LocationData("DH: Lothric War Banner", "Lothric War Banner", DS3LocationCategory.WEAPON), + hidden = True), # Behind illusory wall + DS3LocationData("DH: Covetous Silver Serpent Ring+3", "Covetous Silver Serpent Ring+3", DS3LocationCategory.RING, + hidden = True), # Behind illusory wall + DS3LocationData("DH: Titanite Chunk #3", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Homeward Bone #1", "Homeward Bone x3", DS3LocationCategory.MISC), + DS3LocationData("DH: Lightning Urn", "Lightning Urn x4", DS3LocationCategory.MISC), DS3LocationData("DH: Projected Heal", "Projected Heal", DS3LocationCategory.SPELL), - DS3LocationData("DH: Desert Pyromancer Hood", "Desert Pyromancer Hood", DS3LocationCategory.ARMOR), + DS3LocationData("DH: Large Soul of a Weary Warrior #1", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("DH: Lothric War Banner", "Lothric War Banner", DS3LocationCategory.WEAPON), + DS3LocationData("DH: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Black Firebomb", "Black Firebomb x4", DS3LocationCategory.MISC), + DS3LocationData("DH: Titanite Chunk #4", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE), DS3LocationData("DH: Desert Pyromancer Garb", "Desert Pyromancer Garb", DS3LocationCategory.ARMOR), + DS3LocationData("DH: Titanite Chunk #5", "Titanite Chunk x2", DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Giant Door Shield", "Giant Door Shield", DS3LocationCategory.SHIELD), + DS3LocationData("DH: Ember #3", "Ember", DS3LocationCategory.MISC), DS3LocationData("DH: Desert Pyromancer Gloves", "Desert Pyromancer Gloves", DS3LocationCategory.ARMOR), DS3LocationData("DH: Desert Pyromancer Skirt", "Desert Pyromancer Skirt", DS3LocationCategory.ARMOR), - DS3LocationData("DH: Giant Door Shield", "Giant Door Shield", DS3LocationCategory.SHIELD), + DS3LocationData("DH: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Purple Moss Clump", "Purple Moss Clump x4", DS3LocationCategory.MISC), + DS3LocationData("DH: Ring of Favor+3", "Ring of Favor+3", DS3LocationCategory.RING), + DS3LocationData("DH: Titanite Chunk #6", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Large Soul of a Weary Warrior #2", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("DH: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Titanite Chunk #7", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Loincloth", "Loincloth", DS3LocationCategory.ARMOR), + DS3LocationData("DH: Titanite Chunk #8", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Large Soul of a Weary Warrior #3", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), DS3LocationData("DH: Herald Curved Greatsword", "Herald Curved Greatsword", DS3LocationCategory.WEAPON), - DS3LocationData("DH: Flame Fan", "Flame Fan", DS3LocationCategory.SPELL, - hostile_npc = True), # Desert Pyromancer Zoey drop - DS3LocationData("DH: Soul of the Demon Prince", "Soul of the Demon Prince", DS3LocationCategory.BOSS, - prominent = True, boss = True), + DS3LocationData("DH: Homeward Bone #2", "Homeward Bone", DS3LocationCategory.MISC), + DS3LocationData("DH: Prism Stone", "Prism Stone x6", DS3LocationCategory.MISC), + DS3LocationData("DH: Desert Pyromancer Hood", "Desert Pyromancer Hood", DS3LocationCategory.ARMOR), + DS3LocationData("DH: Twinkling Titanite #3", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + hidden = True), # Hidden fall + DS3LocationData("DH: Divine Blessing #2", "Divine Blessing", DS3LocationCategory.MISC), + DS3LocationData("DH: Ember #4", "Ember", DS3LocationCategory.MISC, + hidden = True), # Hidden fall DS3LocationData("DH: Small Envoy Banner", "Small Envoy Banner", DS3LocationCategory.KEY, - boss = True), - DS3LocationData("DH: Ring of Favor+3", "Ring of Favor+3", DS3LocationCategory.RING), - DS3LocationData("DH: Covetous Silver Serpent Ring+3", "Covetous Silver Serpent Ring+3", DS3LocationCategory.RING, - hidden = True), # Behind invisible wall - DS3LocationData("DH: Ring of Steel Protection+3", "Ring of Steel Protection+3", DS3LocationCategory.RING), + progression = True, boss = True), + DS3LocationData("DH: Twinkling Titanite #4", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, + hidden = True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim + DS3LocationData("DH: Twinkling Titanite #5", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, + hidden = True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim + DS3LocationData("DH: Twinkling Titanite #6", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, + hidden = True), # Guaranteed drop from killing normal-looking pilgrim + DS3LocationData("DH: Demon's Scar", "Demon's Scar", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("DH: Seething Chaos", "Seething Chaos", DS3LocationCategory.SPELL, + missable = True, boss = True, shop = True), + + # Stone-humped Hag's shop + DS3LocationData("DH: Splitleaf Greatsword", "Splitleaf Greatsword", DS3LocationCategory.WEAPON, + shop = True), + DS3LocationData("DH: Divine Blessing #3", "Divine Blessing", DS3LocationCategory.MISC, + shop = True), + DS3LocationData("DH: Hidden Blessing", "Hidden Blessing", DS3LocationCategory.MISC, + shop = True), + DS3LocationData("DH: Rusted Gold Coin", "Rusted Gold Coin", DS3LocationCategory.MISC, + shop = True), + DS3LocationData("DH: Ember #5", "Ember", DS3LocationCategory.MISC, + shop = True), ], "Ringed City": [ - DS3LocationData("RC: Ruin Sentinel Helm", "Ruin Sentinel Helm", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Ruin Sentinel Armor", "Ruin Sentinel Armor", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Ruin Sentinel Gauntlets", "Ruin Sentinel Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Ruin Sentinel Leggings", "Ruin Sentinel Leggings", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Black Witch Veil", "Black Witch Veil", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Black Witch Hat", "Black Witch Hat", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Black Witch Garb", "Black Witch Garb", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Black Witch Wrappings", "Black Witch Wrappings", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Black Witch Trousers", "Black Witch Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("RC: White Preacher Head", "White Preacher Head", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Havel's Ring+3", "Havel's Ring+3", DS3LocationCategory.RING, + DS3LocationData("RC: Titanite Slab #1", "Titanite Slab", DS3LocationCategory.UPGRADE, + prominent = True, boss = True), # Halflight drop, only once + DS3LocationData("RC: Soul of Darkeater Midir", "Soul of Darkeater Midir", DS3LocationCategory.BOSS, + prominent = True, boss = True), + DS3LocationData("RC: Sacred Chime of Filianore", "Sacred Chime of Filianore", DS3LocationCategory.WEAPON, + npc = True), + DS3LocationData("RC: Titanite Slab #2", "Titanite Slab", DS3LocationCategory.UPGRADE, + npc = True), + DS3LocationData("RC: Crucifix of the Mad King", "Crucifix of the Mad King", DS3LocationCategory.WEAPON, + hostile_npc = True), # Shira drop + DS3LocationData("RC: Ledo's Great Hammer", "Ledo's Great Hammer", DS3LocationCategory.WEAPON, + hostile_npc = True), # Silver Knight Ledo drop + DS3LocationData("RC: Wolf Ring+3", "Wolf Ring+3", DS3LocationCategory.RING, + hostile_npc = True), # Alva drop + DS3LocationData("RC: Blindfold Mask", "Blindfold Mask", DS3LocationCategory.ARMOR, + hostile_npc = True), # Moaning Knight drop + DS3LocationData("RC: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Ruin Helm", "Ruin Helm", DS3LocationCategory.ARMOR), + DS3LocationData("RC: Ruin Armor", "Ruin Armor", DS3LocationCategory.ARMOR), + DS3LocationData("RC: Ruin Gauntlets", "Ruin Gauntlets", DS3LocationCategory.ARMOR), + DS3LocationData("RC: Ruin Leggings", "Ruin Leggings", DS3LocationCategory.ARMOR), + DS3LocationData("RC: Budding Green Blossom #1", "Budding Green Blossom x2", DS3LocationCategory.MISC), + DS3LocationData("RC: Titanite Chunk #1", "Titanite Chunk x2", DS3LocationCategory.MISC), + DS3LocationData("RC: Ember #1", "Ember", DS3LocationCategory.MISC), + DS3LocationData("RC: Budding Green Blossom #2", "Budding Green Blossom x2", DS3LocationCategory.MISC), + DS3LocationData("RC: Hidden Blessing #1", "Hidden Blessing", DS3LocationCategory.MISC), + DS3LocationData("RC: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("RC: Large Soul of a Weary Warrior #1", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("RC: Ember #2", "Ember", DS3LocationCategory.MISC), + DS3LocationData("RC: Purging Stone", "Purging Stone x2", DS3LocationCategory.MISC), + DS3LocationData("RC: Hollow Gem", "Hollow Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, hidden = True), # Hidden fall + DS3LocationData("RC: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Shira's Crown", "Shira's Crown", DS3LocationCategory.ARMOR, + hidden = True), # Have to return to a cleared area + DS3LocationData("RC: Shira's Armor", "Shira's Armor", DS3LocationCategory.ARMOR, + hidden = True), # Have to return to a cleared area + DS3LocationData("RC: Shira's Gloves", "Shira's Gloves", DS3LocationCategory.ARMOR, + hidden = True), # Have to return to a cleared area + DS3LocationData("RC: Shira's Trousers", "Shira's Trousers", DS3LocationCategory.ARMOR, + hidden = True), # Have to return to a cleared area + DS3LocationData("RC: Mossfruit #1", "Mossfruit x2", DS3LocationCategory.MISC), + DS3LocationData("RC: Large Soul of a Crestfallen Knight #1", "Large Soul of a Crestfallen Knight", DS3LocationCategory.MISC), DS3LocationData("RC: Ringed Knight Spear", "Ringed Knight Spear", DS3LocationCategory.WEAPON), + DS3LocationData("RC: Black Witch Hat", "Black Witch Hat", DS3LocationCategory.ARMOR, + hostile_npc = True), # Alva + DS3LocationData("RC: Black Witch Garb", "Black Witch Garb", DS3LocationCategory.ARMOR, + hostile_npc = True), # Alva + DS3LocationData("RC: Black Witch Wrappings", "Black Witch Wrappings", DS3LocationCategory.ARMOR, + hostile_npc = True), # Alva + DS3LocationData("RC: Black Witch Trousers", "Black Witch Trousers", DS3LocationCategory.ARMOR, + hostile_npc = True), # Alva DS3LocationData("RC: Dragonhead Shield", "Dragonhead Shield", DS3LocationCategory.SHIELD, - hidden = true), # "Show Your Humanity" puzzle + hidden = True), # "Show Your Humanity" puzzle + DS3LocationData("RC: Titanite Chunk #3", "Titanite Chunk", DS3LocationCategory.UPGRADE, + hidden = True), # Hidden fall + DS3LocationData("RC: Mossfruit #2", "Mossfruit x2", DS3LocationCategory.MISC), + DS3LocationData("RC: Large Soul of a Crestfallen Knight #2", "Large Soul of a Crestfallen Knight", DS3LocationCategory.MISC, + hidden = True), # "Show Your Humanity" puzzle + DS3LocationData("RC: Covetous Gold Serpent Ring+3", "Covetous Gold Serpent Ring+3", DS3LocationCategory.RING), + DS3LocationData("RC: Titanite Chunk #4", "Titanite Chunk x2", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Dark Gem", "Dark Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Prism Stone", "Prism Stone x4", DS3LocationCategory.MISC), DS3LocationData("RC: Ringed Knight Straight Sword", "Ringed Knight Straight Sword", DS3LocationCategory.WEAPON), + DS3LocationData("RC: Havel's Ring+3", "Havel's Ring+3", DS3LocationCategory.RING, + hidden = True), # Hidden fall + DS3LocationData("RC: Titanite Chunk #5", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Soul of a Weary Warrior #1", "Soul of a Weary Warrior", DS3LocationCategory.MISC), DS3LocationData("RC: Preacher's Right Arm", "Preacher's Right Arm", DS3LocationCategory.WEAPON), - DS3LocationData("RC: White Birch Bow", "White Birch Bow", DS3LocationCategory.WEAPON), - DS3LocationData("RC: Church Guardian Shiv", "Church Guardian Shiv", DS3LocationCategory.MISC), + DS3LocationData("RC: Rubbish #1", "Rubbish", DS3LocationCategory.MISC), + DS3LocationData("RC: Titanite Chunk #6", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Black Witch Veil", "Black Witch Veil", DS3LocationCategory.ARMOR), + DS3LocationData("RC: Twinkling Titanite #3", "Twinkling Titanite", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Soul of a Crestfallen Knight #2", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("RC: White Preacher Head", "White Preacher Head", DS3LocationCategory.ARMOR), + DS3LocationData("RC: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Titanite Scale #3", "Titanite Scale", DS3LocationCategory.UPGRADE), DS3LocationData("RC: Dragonhead Greatshield", "Dragonhead Greatshield", DS3LocationCategory.SHIELD), + DS3LocationData("RC: Titanite Scale #4", "Titanite Scale x2", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Rubbish #2", "Rubbish", DS3LocationCategory.MISC), + DS3LocationData("RC: Large Soul of a Weary Warrior #2", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("RC: Titanite Scale #5", "Titanite Scale x2", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Titanite Scale #6", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Lightning Gem", "Lightning Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Blessed Gem", "Blessed Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Simple Gem", "Simple Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Large Soul of a Weary Warrior #3", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("RC: Lightning Arrow", "Lightning Arrow", DS3LocationCategory.SPELL), + DS3LocationData("RC: Chloranthy Ring+3", "Chloranthy Ring+3", DS3LocationCategory.RING, + hidden = True), # Hidden fall + DS3LocationData("RC: Ember #3", "Ember", DS3LocationCategory.MISC), + DS3LocationData("RC: Filianore's Spear Ornament", "Filianore's Spear Ornament", DS3LocationCategory.MISC, + offline = '13,0:55100700::'), + DS3LocationData("RC: Antiquated Plain Garb", "Antiquated Plain Garb", DS3LocationCategory.ARMOR), + DS3LocationData("RC: Violet Wrappings", "Violet Wrappings", DS3LocationCategory.ARMOR), + DS3LocationData("RC: Soul of a Weary Warrior #2", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("RC: Twinkling Titanite #4", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Budding Green Blossom #3", "Budding Green Blossom x3", DS3LocationCategory.MISC), + DS3LocationData("RC: Titanite Chunk #7", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Large Soul of a Weary Warrior #4", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("RC: Soul of a Weary Warrior #3", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("RC: Titanite Scale #7", "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Soul of a Crestfallen Knight #3", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("RC: White Birch Bow", "White Birch Bow", DS3LocationCategory.WEAPON), + DS3LocationData("RC: Titanite Chunk #8", "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Young White Branch #1", "Young White Branch", DS3LocationCategory.MISC), + DS3LocationData("RC: Young White Branch #2", "Young White Branch", DS3LocationCategory.MISC), + DS3LocationData("RC: Young White Branch #3", "Young White Branch", DS3LocationCategory.MISC), DS3LocationData("RC: Ringed Knight Paired Greatswords", "Ringed Knight Paired Greatswords", DS3LocationCategory.WEAPON, hidden = True), # Guaranteed drop from a normal-looking Ringed Knight - DS3LocationData("RC: Shira's Crown", "Shira's Crown", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Shira's Armor", "Shira's Armor", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Shira's Gloves", "Shira's Gloves", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Shira's Trousers", "Shira's Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Crucifix of the Mad King", "Crucifix of the Mad King", DS3LocationCategory.WEAPON, - hostile_npc = True), # Shira drop - DS3LocationData("RC: Sacred Chime of Filianore", "Sacred Chime of Filianore", DS3LocationCategory.WEAPON), + DS3LocationData("RC: Hidden Blessing #2", "Hidden Blessing", DS3LocationCategory.MISC, + miniboss = True), # Judicator drop + DS3LocationData("RC: Divine Blessing #1", "Divine Blessing", DS3LocationCategory.MISC, + miniboss = True), # Judicator drop + DS3LocationData("RC: Divine Blessing #2", "Divine Blessing", DS3LocationCategory.MISC, + miniboss = True, hidden = True), # Judicator drop, "Show Your Humanity" puzzle + DS3LocationData("RC: Ring of the Evil Eye+3", "Ring of the Evil Eye+3", DS3LocationCategory.RING, + mimic = True, hidden = True), # Hidden fall DS3LocationData("RC: Iron Dragonslayer Helm", "Iron Dragonslayer Helm", DS3LocationCategory.ARMOR, miniboss = True), DS3LocationData("RC: Iron Dragonslayer Armor", "Iron Dragonslayer Armor", DS3LocationCategory.ARMOR, @@ -824,133 +2606,110 @@ def get_name_to_id() -> dict: miniboss = True), DS3LocationData("RC: Iron Dragonslayer Leggings", "Iron Dragonslayer Leggings", DS3LocationCategory.ARMOR, miniboss = True), - DS3LocationData("RC: Lightning Arrow", "Lightning Arrow", DS3LocationCategory.SPELL), + DS3LocationData("RC: Church Guardian Shiv", "Church Guardian Shiv", DS3LocationCategory.MISC), + DS3LocationData("RC: Spears of the Church", "Spears of the Church", DS3LocationCategory.MISC, + boss = True), # Midir drop DS3LocationData("RC: Ritual Spear Fragment", "Ritual Spear Fragment", DS3LocationCategory.MISC), - DS3LocationData("RC: Antiquated Plain Garb", "Antiquated Plain Garb", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Violet Wrappings", "Violet Wrappings", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Soul of Darkeater Midir", "Soul of Darkeater Midir", DS3LocationCategory.BOSS, + DS3LocationData("RC: Titanite Scale #8", "Titanite Scale", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("RC: Twinkling Titanite #5", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("RC: Titanite Scale #9", "Titanite Scale x2", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("RC: Twinkling Titanite #6", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("RC: Titanite Scale #10", "Titanite Scale", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("RC: Twinkling Titanite #7", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("RC: Soul of Slave Knight Gael", "Soul of Slave Knight Gael", DS3LocationCategory.BOSS, prominent = True, boss = True), - DS3LocationData("RC: Soul of Slave Knight Gael", "Soul of Slave Knight Gael", DS3LocationCategory.BOSS), DS3LocationData("RC: Blood of the Dark Soul", "Blood of the Dark Soul", DS3LocationCategory.KEY), - DS3LocationData("RC: Chloranthy Ring+3", "Chloranthy Ring+3", DS3LocationCategory.RING, - hidden = True), # Hidden fall - DS3LocationData("RC: Covetous Gold Serpent Ring+3", "Covetous Gold Serpent Ring+3", DS3LocationCategory.RING), - DS3LocationData("RC: Ring of the Evil Eye+3", "Ring of the Evil Eye+3", DS3LocationCategory.RING, - mimic = True), - DS3LocationData("RC: Wolf Ring+3", "Wolf Ring+3", DS3LocationCategory.RING, - hostile_npc = True), # Alva drop + DS3LocationData("RC: Titanite Slab #3", "Titanite Slab", DS3LocationCategory.UPGRADE, + hidden = True), # Guaranteed drop from normal-looking Ringed Knight + DS3LocationData("RC: Frayed Blade", "Frayed Blade", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("RC: Old Moonlight", "Old Moonlight", DS3LocationCategory.SPELL, + missable = True, boss = True, shop = True), + DS3LocationData("RC: Gael's Greatsword", "Gael's Greatsword", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("RC: Repeating Crossbow", "Repeating Crossbow", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + + # Lapp + DS3LocationData("RC: Siegbräu", "Siegbräu", DS3LocationCategory.MISC, + missable = True, npc = True), # Lapp (quest) + # Quest or Shrine Handmaiden after death + DS3LocationData("RC: Lapp's Helm", "Lapp's Helm", DS3LocationCategory.ARMOR, + missable = True, npc = True, shop = True), + DS3LocationData("RC: Lapp's Armor", "Lapp's Armor", DS3LocationCategory.ARMOR, + missable = True, npc = True, shop = True), + DS3LocationData("RC: Lapp's Gauntlets", "Lapp's Gauntlets", DS3LocationCategory.ARMOR, + missable = True, npc = True, shop = True), + DS3LocationData("RC: Lapp's Leggings", "Lapp's Leggings", DS3LocationCategory.ARMOR, + missable = True, npc = True, shop = True), ], - # Progressive - "Progressive Items 1": [] + - # Upgrade materials - [DS3LocationData(f"Titanite Shard #{i + 1}", "Titanite Shard", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(26)] + - [DS3LocationData(f"Large Titanite Shard #{i + 1}", "Large Titanite Shard", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(28)] + - [DS3LocationData(f"Titanite Slab #{i + 1}", "Titanite Slab", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Twinkling Titanite #{i + 1}", "Twinkling Titanite", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(15)], - - "Progressive Items 2": [] + - # Items - [DS3LocationData(f"Green Blossom #{i + 1}", "Green Blossom", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(6)] + - [DS3LocationData(f"Firebomb #{i + 1}", "Firebomb", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(4)] + - [DS3LocationData(f"Alluring Skull #{i + 1}", "Alluring Skull", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Undead Hunter Charm #{i + 1}", "Undead Hunter Charm", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Duel Charm #{i + 1}", "Duel Charm", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Throwing Knife #{i + 1}", "Throwing Knife", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Gold Pine Resin #{i + 1}", "Gold Pine Resin", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(1)] + - [DS3LocationData(f"Charcoal Pine Resin #{i + 1}", "Charcoal Pine Resin", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(1)] + - [DS3LocationData(f"Human Pine Resin #{i + 1}", "Human Pine Resin", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Carthus Rouge #{i + 1}", "Carthus Rouge", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(1)] + - [DS3LocationData(f"Pale Pine Resin #{i + 1}", "Pale Pine Resin", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(1)] + - [DS3LocationData(f"Charcoal Pine Bundle #{i + 1}", "Charcoal Pine Bundle", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Rotten Pine Resin #{i + 1}", "Rotten Pine Resin", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Homeward Bone #{i + 1}", "Homeward Bone", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(16)] + - [DS3LocationData(f"Pale Tongue #{i + 1}", "Pale Tongue", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Rusted Coin #{i + 1}", "Rusted Coin", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Rusted Gold Coin #{i + 1}", "Rusted Gold Coin", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Ember #{i + 1}", "Ember", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(45)], - - "Progressive Items 3": [] + - # Souls & Bulk Upgrade Materials - [DS3LocationData(f"Fading Soul #{i + 1}", "Fading Soul", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(5)] + - [DS3LocationData(f"Soul of a Deserted Corpse #{i + 1}", "Soul of a Deserted Corpse", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(5)] + - [DS3LocationData(f"Large Soul of a Deserted Corpse #{i + 1}", "Large Soul of a Deserted Corpse", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(5)] + - [DS3LocationData(f"Soul of an Unknown Traveler #{i + 1}", "Soul of an Unknown Traveler", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(5)] + - [DS3LocationData(f"Large Soul of an Unknown Traveler #{i + 1}", "Large Soul of an Unknown Traveler", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(5)] + - [DS3LocationData(f"Soul of a Nameless Soldier #{i + 1}", "Soul of a Nameless Soldier", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(4)] + - [DS3LocationData(f"Large Soul of a Nameless Soldier #{i + 1}", "Large Soul of a Nameless Soldier", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(4)] + - [DS3LocationData(f"Soul of a Weary Warrior #{i + 1}", "Soul of a Weary Warrior", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(6)] + - [DS3LocationData(f"Soul of a Crestfallen Knight #{i + 1}", "Soul of a Crestfallen Knight", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Titanite Chunk #{i + 1}", "Titanite Chunk", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(22)] + - [DS3LocationData(f"Titanite Scale #{i + 1}", "Titanite Scale", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(29)], - - "Progressive Items 4": [] + - # Gems & Random Consumables - [DS3LocationData(f"Ring of Sacrifice #{i + 1}", "Ring of Sacrifice", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(4)] + - [DS3LocationData(f"Divine Blessing #{i + 1}", "Divine Blessing", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Hidden Blessing #{i + 1}", "Hidden Blessing", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(1)] + - [DS3LocationData(f"Budding Green Blossom #{i + 1}", "Budding Green Blossom", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(5)] + - [DS3LocationData(f"Bloodred Moss Clump #{i + 1}", "Bloodred Moss Clump", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(1)] + - [DS3LocationData(f"Purple Moss Clump #{i + 1}", "Purple Moss Clump", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Blooming Purple Moss Clump #{i + 1}", "Blooming Purple Moss Clump", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(1)] + - [DS3LocationData(f"Purging Stone #{i + 1}", "Purging Stone", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Rime-blue Moss Clump #{i + 1}", "Rime-blue Moss Clump", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Repair Powder #{i + 1}", "Repair Powder", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Kukri #{i + 1}", "Kukri", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Lightning Urn #{i + 1}", "Lightning Urn", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Rubbish #{i + 1}", "Rubbish", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(1)] + - [DS3LocationData(f"Blue Bug Pellet #{i + 1}", "Blue Bug Pellet", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Red Bug Pellet #{i + 1}", "Red Bug Pellet", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Yellow Bug Pellet #{i + 1}", "Yellow Bug Pellet", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Black Bug Pellet #{i + 1}", "Black Bug Pellet", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Heavy Gem #{i + 1}", "Heavy Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Sharp Gem #{i + 1}", "Sharp Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Refined Gem #{i + 1}", "Refined Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Crystal Gem #{i + 1}", "Crystal Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Simple Gem #{i + 1}", "Simple Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Fire Gem #{i + 1}", "Fire Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Chaos Gem #{i + 1}", "Chaos Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Lightning Gem #{i + 1}", "Lightning Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Deep Gem #{i + 1}", "Deep Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Dark Gem #{i + 1}", "Dark Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Poison Gem #{i + 1}", "Poison Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Blood Gem #{i + 1}", "Blood Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(1)] + - [DS3LocationData(f"Raw Gem #{i + 1}", "Raw Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Blessed Gem #{i + 1}", "Blessed Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Hollow Gem #{i + 1}", "Hollow Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Shriving Stone #{i + 1}", "Shriving Stone", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)], - - "Progressive Items DLC": [] + - # Upgrade materials - [DS3LocationData(f"Large Titanite Shard ${i + 1}", "Large Titanite Shard", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Titanite Chunk ${i + 1}", "Titanite Chunk", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(15)] + - [DS3LocationData(f"Titanite Slab ${i + 1}", "Titanite Slab", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Twinkling Titanite ${i + 1}", "Twinkling Titanite", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(5)] + - [DS3LocationData(f"Titanite Scale ${i + 1}", "Titanite Scale", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(11)] + - - - # Items - [DS3LocationData(f"Homeward Bone ${i + 1}", "Homeward Bone", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(6)] + - [DS3LocationData(f"Rusted Coin ${i + 1}", "Rusted Coin", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - [DS3LocationData(f"Ember ${i + 1}", "Ember", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(10)] + - - # Souls - [DS3LocationData(f"Large Soul of an Unknown Traveler ${i + 1}", "Large Soul of an Unknown Traveler", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(9)] + - [DS3LocationData(f"Soul of a Weary Warrior ${i + 1}", "Soul of a Weary Warrior", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(5)] + - [DS3LocationData(f"Large Soul of a Weary Warrior ${i + 1}", "Large Soul of a Weary Warrior", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(6)] + - [DS3LocationData(f"Soul of a Crestfallen Knight ${i + 1}", "Soul of a Crestfallen Knight", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(6)] + - [DS3LocationData(f"Large Soul of a Crestfallen Knight ${i + 1}", "Large Soul of a Crestfallen Knight", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(3)] + - - # Gems - [DS3LocationData(f"Dark Gem ${i + 1}", "Dark Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Blood Gem ${i + 1}", "Blood Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(1)] + - [DS3LocationData(f"Blessed Gem ${i + 1}", "Blessed Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)] + - [DS3LocationData(f"Hollow Gem ${i + 1}", "Hollow Gem", DS3LocationCategory.PROGRESSIVE_ITEM) for i in range(2)], - - "Progressive Items Health": [] + - # Healing - [DS3LocationData(f"Estus Shard #{i + 1}", "Estus Shard", DS3LocationCategory.HEALTH) for i in range(11)] + - [DS3LocationData(f"Undead Bone Shard #{i + 1}", "Undead Bone Shard", DS3LocationCategory.HEALTH) for i in range(10)], + # Unlockable shops. We only bother creating a "region" for these for shops that are locked + # behind keys and always have items available either through the shop or through the NPC's + # ashes. + "Greirat's Shop": [ + DS3LocationData("Greirat: Blue Tearstone Ring", "Blue Tearstone Ring", DS3LocationCategory.RING, + offline = '01,0:50006120::', npc = True), + DS3LocationData("Greirat: Ember #1", "Ember", DS3LocationCategory.MISC, + offline = "99,0:-1:110000,120000,70000110:", shop = True, npc = True), + + # Undead Settlement rewards + DS3LocationData("Greirat: Divine Blessing", "Divine Blessing", DS3LocationCategory.MISC, + offline = '99,0:-1:110000,120000,70000150,70000175:', missable = True, shop = True, npc = True), + DS3LocationData("Greirat: Ember #2", "Ember", DS3LocationCategory.MISC, + offline = '99,0:-1:110000,120000,70000150,70000175:', missable = True, shop = True, npc = True), + + # Irityhll rewards + DS3LocationData("Greirat: Divine Blessing #2", "Divine Blessing", DS3LocationCategory.MISC, + offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), + DS3LocationData("Greirat: Hidden Blessing #1", "Hidden Blessing", DS3LocationCategory.MISC, + offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), + DS3LocationData("Greirat: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE, + offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), + DS3LocationData("Greirat: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), + + # Lothric rewards (from Shrine Handmaid) + DS3LocationData("Greirat: Ember #3", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + offline = '99,0:-1:110000,120000,70000152,70000177:', missable = True, shop = True, npc = True), + ], + "Karla's Shop": [ + DS3LocationData("Karla: Affinity", "Affinity", DS3LocationCategory.SPELL, + shop = True, npc = True), + DS3LocationData("Karla: Dark Edge", "Dark Edge", DS3LocationCategory.SPELL, + shop = True, npc = True), + + # Quelana Pyromancy Tome + DS3LocationData("Karla: Firestorm", "Firestorm", DS3LocationCategory.SPELL, + missable = True, shop = True, npc = True), + DS3LocationData("Karla: Rapport", "Rapport", DS3LocationCategory.SPELL, + missable = True, shop = True, npc = True), + DS3LocationData("Karla: Fire Whip", "Fire Whip", DS3LocationCategory.SPELL, + missable = True, shop = True, npc = True), + + # Grave Warden Pyromancy Tome + DS3LocationData("Karla: Black Flame", "Black Flame", DS3LocationCategory.SPELL, + missable = True, shop = True, npc = True), + DS3LocationData("Karla: Black Fire Orb", "Black Fire Orb", DS3LocationCategory.SPELL, + missable = True, shop = True, npc = True), + + # Drops on death. Missable because the player would have to decide between killing her or + # seeing everything she sells. + DS3LocationData("Karla: Karla's Pointed Hat", "Karla's Pointed Hat", DS3LocationCategory.ARMOR, + offline = '07,0:50006150::', missable = True, npc = True), + DS3LocationData("Karla: Karla's Coat", "Karla's Coat", DS3LocationCategory.ARMOR, + offline = '07,0:50006150::', missable = True, npc = True), + DS3LocationData("Karla: Karla's Gloves", "Karla's Gloves", DS3LocationCategory.ARMOR, + offline = '07,0:50006150::', missable = True, npc = True), + DS3LocationData("Karla: Karla's Trousers", "Karla's Trousers", DS3LocationCategory.ARMOR, + offline = '07,0:50006150::', missable = True, npc = True), + ], } location_name_groups: Dict[str, Set[str]] = { @@ -962,6 +2721,7 @@ def get_name_to_id() -> dict: "Miniboss Rewards": set(), "Mimic Rewards": set(), "Hostile NPC Rewards": set(), + "Small Crystal Lizards": set(), "Keys": set(), "Hidden": set() } @@ -973,15 +2733,17 @@ def get_name_to_id() -> dict: for location_data in location_table: for group_name in location_data.location_groups(): - location_name[group_name].add(group_name) + location_name_groups[group_name].add(location_data.name) # Allow entire locations to be added to location sets. - if not location_name.startswith("Progressive Items"): + if not location_name.endswith(" Shop"): location_name_groups[location_name] = frozenset([ location_data.name for location_data in location_table ]) -location_name_groups["Painted World of Ariandel"] = \ - location_name_groups["Painted World of Ariandel 1"].union(location_name_groups["Painted World of Ariandel 2"]) -del location_name_groups["Painted World of Ariandel 1"] -del location_name_groups["Painted World of Ariandel 2"] +location_name_groups["Painted World of Ariandel"] = ( + location_name_groups["Painted World of Ariandel (Before Contraption)"] + .union(location_name_groups["Painted World of Ariandel (After Contraption)"]) +) +del location_name_groups["Painted World of Ariandel (Before Contraption)"] +del location_name_groups["Painted World of Ariandel (After Contraption)"] diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 9bf94327e78c..b93d8e9582c7 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -1,5 +1,6 @@ # world/dark_souls_3/__init__.py from typing import Dict, Set, List +import re from BaseClasses import MultiWorld, Region, Item, Entrance, Tutorial, ItemClassification from Options import Toggle @@ -88,6 +89,7 @@ def generate_early(self): self.enabled_location_categories.add(DS3LocationCategory.BOSS) if self.multiworld.enable_misc_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.MISC) + self.enabled_location_categories.add(DS3LocationCategory.UPGRADE) if self.multiworld.enable_health_upgrade_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.HEALTH) @@ -117,6 +119,8 @@ def create_regions(self): "Untended Graves", "Archdragon Peak", "Kiln of the First Flame", + "Greirat's Shop", + "Karla's Shop", ]}) # Adds Path of the Dragon as an event item for Archdragon Peak access @@ -127,8 +131,8 @@ def create_regions(self): # Create DLC Regions if self.multiworld.enable_dlc[self.player]: regions.update({region_name: self.create_region(region_name, location_tables[region_name]) for region_name in [ - "Painted World of Ariandel 1", - "Painted World of Ariandel 2", + "Painted World of Ariandel (Before Contraption)", + "Painted World of Ariandel (After Contraption)", "Dreg Heap", "Ringed City", ]}) @@ -150,6 +154,7 @@ def create_connection(from_region: str, to_region: str): create_connection("High Wall of Lothric", "Undead Settlement") create_connection("High Wall of Lothric", "Lothric Castle") + create_connection("High Wall of Lothric", "Greirat's Shop") create_connection("Undead Settlement", "Road of Sacrifices") @@ -166,6 +171,7 @@ def create_connection(from_region: str, to_region: str): create_connection("Irithyll Dungeon", "Archdragon Peak") create_connection("Irithyll Dungeon", "Profaned Capital") + create_connection("Irithyll Dungeon", "Karla's Shop") create_connection("Lothric Castle", "Consumed King's Garden") create_connection("Lothric Castle", "Grand Archives") @@ -174,9 +180,10 @@ def create_connection(from_region: str, to_region: str): # Connect DLC Regions if self.multiworld.enable_dlc[self.player]: - create_connection("Cathedral of the Deep", "Painted World of Ariandel 1") - create_connection("Painted World of Ariandel 1", "Painted World of Ariandel 2") - create_connection("Painted World of Ariandel 2", "Dreg Heap") + create_connection("Cathedral of the Deep", "Painted World of Ariandel (Before Contraption)") + create_connection("Painted World of Ariandel (Before Contraption)", + "Painted World of Ariandel (After Contraption)") + create_connection("Painted World of Ariandel (After Contraption)", "Dreg Heap") create_connection("Dreg Heap", "Ringed City") @@ -187,27 +194,22 @@ def create_region(self, region_name, location_table) -> Region: for location in location_table: if (location.category in self.enabled_location_categories and (not location.npc or self.multiworld.enable_npc_locations[self.player] == Toggle.option_true)): - new_location = DarkSouls3Location( + new_location = DarkSouls3Location.from_data( self.player, - location.name, - location.category, - location.default_item, + location, self.location_name_to_id[location.name], new_region ) else: # Replace non-randomized progression items with events - event_item = self.create_item(location.default_item) + event_item = self.create_item(location.default_item_name) if event_item.classification != ItemClassification.progression: continue - new_location = DarkSouls3Location( + new_location = DarkSouls3Location.from_data( self.player, - location.name, - location.category, - location.default_item, - None, - new_region + location, + parent = new_region ) event_item.code = None new_location.place_locked_item(event_item) @@ -226,14 +228,27 @@ def create_items(self): itempool_by_category = {category: [] for category in self.enabled_location_categories} + # Just used to efficiently deduplicate items + item_set_by_category = {category: set() for category in self.enabled_location_categories} + # Gather all default items on randomized locations num_required_extra_items = 0 for location in self.multiworld.get_locations(self.player): if location.category in itempool_by_category: - if item_dictionary[location.default_item_name].category == DS3ItemCategory.SKIP: + item_category = item_dictionary[location.default_item_name].category + if item_category == DS3ItemCategory.SKIP: num_required_extra_items += 1 - else: + elif item_category == DS3ItemCategory.MISC: itempool_by_category[location.category].append(location.default_item_name) + else: + # For non-miscellaneous non-skip items, make sure there aren't duplicates in the + # item set even if there are multiple in-game locations that provide them. + item_set = item_set_by_category[location.category] + if location.default_item_name in item_set: + num_required_extra_items += 1 + else: + item_set.add(location.default_item_name) + itempool_by_category[location.category].append(location.default_item_name) # Replace each item category with a random sample of items of those types if self.multiworld.pool_type[self.player] == PoolTypeOption.option_various: @@ -277,7 +292,7 @@ def create_random_replacement_list(item_categories: Set[DS3ItemCategory], num_it itempool: List[DarkSouls3Item] = [] for category in self.enabled_location_categories: - itempool += [self.create_item(name) for name in itempool_by_category[category]] + itempool.extend(self.create_item(name) for name in itempool_by_category[category]) # A list of items we can replace removable_items = [item for item in itempool if item.classification != ItemClassification.progression] @@ -318,8 +333,18 @@ def create_random_replacement_list(item_categories: Set[DS3ItemCategory], num_it itempool.append(self.create_item(item_name)) + injectable_items = [ + item for item + in item_dictionary.values() + if item.inject and (not item.is_dlc or dlc_enabled) + ] + number_to_inject = min(num_required_extra_items, len(injectable_items)) + for item in self.multiworld.random.choices(injectable_items, k=number_to_inject): + num_required_extra_items -= 1 + itempool.append(self.create_item(item.name)) + # Extra filler items for locations containing SKIP items - itempool += [self.create_filler() for _ in range(num_required_extra_items)] + itempool.extend(self.create_filler() for _ in range(num_required_extra_items)) # Add items to itempool self.multiworld.itempool += itempool @@ -332,7 +357,6 @@ def create_item(self, name: str) -> Item: DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE, DS3ItemCategory.SPELL, } - data = self.item_name_to_id[name] if name in key_item_names: item_classification = ItemClassification.progression @@ -341,7 +365,13 @@ def create_item(self, name: str) -> Item: else: item_classification = ItemClassification.filler - return DarkSouls3Item(name, item_classification, data, self.player) + data = item_dictionary[name] + return DarkSouls3Item( + name, + item_classification, + self.item_name_to_id[name], + self.player, + data.count) def get_filler_item_name(self) -> str: @@ -350,6 +380,8 @@ def get_filler_item_name(self) -> str: def set_rules(self) -> None: # Define the access rules to the entrances + set_rule(self.multiworld.get_entrance("Go To Firelink Shrine Bell Tower", self.player), + lambda state: state.has("Tower Key", self.player)) set_rule(self.multiworld.get_entrance("Go To Undead Settlement", self.player), lambda state: state.has("Small Lothric Banner", self.player)) set_rule(self.multiworld.get_entrance("Go To Lothric Castle", self.player), @@ -366,6 +398,42 @@ def set_rules(self) -> None: state.has("Cinders of a Lord - Aldrich", self.player) and state.has("Cinders of a Lord - Lothric Prince", self.player)) + ashes = { + "Mortician's Ashes": ["Alluring Skull", "Ember (Mortician)", "Grave Key"], + "Dreamchaser's Ashes": ["Life Ring"], + "Paladin's Ashes": ["Lloyd's Shield Ring"], + "Grave Warden's Ashes": ["Ember (Grave Warden)"], + "Prisoner Chief's Ashes": [ + "Karla's Pointed Hat", + "Karla's Coat", + "Karla's Gloves", + "Karla's Trousers", + ], + "Xanthous Ashes": ["Xanthous Overcoat", "Xanthous Gloves", "Xanthous Trousers"], + "Grave Warden's Ashes": ["Ember (Dragon Chaser)"], + "Easterner's Ashes": [ + "Washing Pole", + "Eastern Helm", + "Eastern Armor", + "Eastern Gauntlets", + "Eastern Leggings", + "Wood Grain Ring", + ], + "Captain's Ashes": [ + "Millwood Knight Helm", + "Millwood Knight Armor", + "Millwood Knight Gauntlets", + "Millwood Knight Leggings", + "Refined Gem", + ] + } + for ash, items in ashes.items(): + for item in items: + location = location_dictionary["FS: " + item] + if location.category in self.enabled_location_categories: + set_rule(self.multiworld.get_location(location.name, self.player), + lambda state, ash=ash: state.has(ash, self.player)) + if self.multiworld.late_basin_of_vows[self.player] == Toggle.option_true: add_rule(self.multiworld.get_entrance("Go To Lothric Castle", self.player), lambda state: state.has("Small Lothric Banner", self.player)) @@ -378,11 +446,11 @@ def set_rules(self) -> None: # If key items are randomized, must have contraption key to enter second half of Ashes DLC # If key items are not randomized, Contraption Key is guaranteed to be accessible before it is needed if self.multiworld.enable_key_locations[self.player] == Toggle.option_true: - add_rule(self.multiworld.get_entrance("Go To Painted World of Ariandel 2", self.player), + add_rule(self.multiworld.get_entrance("Go To Painted World of Ariandel (After Contraption)", self.player), lambda state: state.has("Contraption Key", self.player)) if self.multiworld.late_dlc[self.player] == Toggle.option_true: - add_rule(self.multiworld.get_entrance("Go To Painted World of Ariandel 1", self.player), + add_rule(self.multiworld.get_entrance("Go To Painted World of Ariandel (Before Contraption)", self.player), lambda state: state.has("Small Doll", self.player)) # Define the access rules to some specific locations @@ -398,22 +466,26 @@ def set_rules(self) -> None: lambda state: state.has("Small Lothric Banner", self.player)) if self.multiworld.enable_npc_locations[self.player] == Toggle.option_true: - set_rule(self.multiworld.get_location("HWL: Greirat's Ashes", self.player), - lambda state: state.has("Cell Key", self.player)) - set_rule(self.multiworld.get_location("HWL: Blue Tearstone Ring", self.player), + # Technically the player could lock themselves out of Greirat's shop if they send him to + # Lothric Castle before they have the Grand Archives Key with which to retrieve his + # ashes, but this is so unlikely it's not worth telling the randomizer that the shop is + # contingent on such a lategame item. + set_rule(self.multiworld.get_entrance("Go To Greirat's Shop", self.player), lambda state: state.has("Cell Key", self.player)) - set_rule(self.multiworld.get_location("ID: Karla's Ashes", self.player), - lambda state: state.has("Jailer's Key Ring", self.player)) - set_rule(self.multiworld.get_location("ID: Karla's Pointed Hat", self.player), - lambda state: state.has("Jailer's Key Ring", self.player)) - set_rule(self.multiworld.get_location("ID: Karla's Coat", self.player), - lambda state: state.has("Jailer's Key Ring", self.player)) - set_rule(self.multiworld.get_location("ID: Karla's Gloves", self.player), - lambda state: state.has("Jailer's Key Ring", self.player)) - set_rule(self.multiworld.get_location("ID: Karla's Trousers", self.player), + + set_rule(self.multiworld.get_entrance("Go To Karla's Shop", self.player), lambda state: state.has("Jailer's Key Ring", self.player)) + if self.multiworld.enable_misc_locations[self.player] == Toggle.option_true: + set_rule(self.multiworld.get_location("HWL: Red Eye Orb", self.player), + lambda state: state.has("Lift Chamber Key", self.player)) + for item in ["Leonhard's Garb", "Leonhard's Gauntlets", "Leonhard's Trousers"]: + set_rule(self.multiworld.get_location("AL: " + item, self.player), + lambda state: state.has("Black Eye Orb", self.player)) + if self.multiworld.enable_misc_locations[self.player] == Toggle.option_true: + set_rule(self.multiworld.get_location("AP: Hawkwood's Swordgrass", self.player), + lambda state: state.has("AP: Twinkling Dragon Torso Stone", self.player)) set_rule(self.multiworld.get_location("ID: Prisoner Chief's Ashes", self.player), lambda state: state.has("Jailer's Key Ring", self.player)) @@ -475,15 +547,26 @@ def fill_slot_data(self) -> Dict[str, object]: if self.multiworld.per_slot_randoms[self.player].randint(0, 99) < infusion_percentage: name_to_ds3_code[item.name] += 100 * self.multiworld.per_slot_randoms[self.player].randint(0, 15) - # Create the mandatory lists to generate the player's output file + our_items = { + location.item + for location in self.multiworld.get_filled_locations() + # item.code None is used for events, which we want to skip + if location.item.code is not None and location.item.player == self.player + } + ap_ids_to_ds3_ids: Dict[str, int] = {} + item_counts: Dict[str, int] = {} + for item in our_items: + ap_ids_to_ds3_ids[str(item.code)] = name_to_ds3_code[item.name] + if item.count != 1: item_counts[str(item.code)] = item.count + + # A map from Archipelago's location names to the keys the offline + # randomizer uses to identify locations. + location_names_to_keys: Dict[str, str] = {} for location in self.multiworld.get_filled_locations(): - # Skip events - if location.item.code is None: - continue - - if location.item.player == self.player: - ap_ids_to_ds3_ids[str(location.item.code)] = name_to_ds3_code[location.item.name] + # Skip events and only look at this world's locations + if location.item.code is not None and location.player == self.player and location.offline: + location_names_to_keys[location.name] = location.offline slot_data = { "options": { @@ -509,7 +592,9 @@ def fill_slot_data(self) -> Dict[str, object]: "seed": self.multiworld.seed_name, # to verify the server's multiworld "slot": self.multiworld.player_name[self.player], # to connect to server "base_id": self.base_id, # to merge location and items lists - "apIdsToItemIds": ap_ids_to_ds3_ids + "apIdsToItemIds": ap_ids_to_ds3_ids, + "itemCounts": item_counts, + "locationNamesToKeys": location_names_to_keys, } return slot_data diff --git a/worlds/dark_souls_3/test/TestDarkSouls3.py b/worlds/dark_souls_3/test/TestDarkSouls3.py new file mode 100644 index 000000000000..b491e64ac84e --- /dev/null +++ b/worlds/dark_souls_3/test/TestDarkSouls3.py @@ -0,0 +1,11 @@ +import unittest + +from worlds.dark_souls_3.Items import DarkSouls3Item +from worlds.dark_souls_3.Locations import location_tables + +class DarkSouls3Test(unittest.TestCase): + def testLocationDefaultItems(self): + item_name_to_id = DarkSouls3Item.get_name_to_id() + for locations in location_tables.values(): + for location in locations: + self.assertIn(location.default_item_name, item_name_to_id) diff --git a/worlds/dark_souls_3/test/__init__.py b/worlds/dark_souls_3/test/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/worlds/sm/variaRandomizer/logic/smbool.py b/worlds/sm/variaRandomizer/logic/smbool.py index b7f596cbbb08..99084e4a44f8 100644 --- a/worlds/sm/variaRandomizer/logic/smbool.py +++ b/worlds/sm/variaRandomizer/logic/smbool.py @@ -1,8 +1,4 @@ -def flatten(l): - if type(l) is list: - return [ y for x in l for y in flatten(x) ] - else: - return [ l ] +from Utils import flatten # super metroid boolean class SMBool: From 0bc5cd2c2bc11b0cc1be2d3cf73ebfd7d3f575bd Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 28 Oct 2023 14:59:32 -0700 Subject: [PATCH 024/238] Don't put soul and multiple items in shops --- worlds/dark_souls_3/Items.py | 125 +++++++++++++++++++------------ worlds/dark_souls_3/Locations.py | 26 +++++-- worlds/dark_souls_3/__init__.py | 54 +++++++------ 3 files changed, 123 insertions(+), 82 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 9a8a39403dcf..3167cedc59ec 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -3,7 +3,7 @@ import dataclasses from enum import IntEnum import itertools -from typing import List, NamedTuple, Optional, Self, TypeVar +from typing import ClassVar, List, NamedTuple, Optional, Self, TypeVar from BaseClasses import Item, ItemClassification from Utils import flatten @@ -26,10 +26,16 @@ class DS3ItemCategory(IntEnum): @dataclass class DS3ItemData(): + __item_id: ClassVar[int] = 100000 + """The next item ID to use when creating item data.""" + name: str ds3_code: int category: DS3ItemCategory + ap_code: int = False + """The Archipelago ID for this item.""" + is_dlc: bool = False """Whether this item is only found in one of the two DLC packs.""" @@ -45,6 +51,13 @@ class DS3ItemData(): difference. """ + soul: bool = False + """Whether this is a consumable item that gives souls when used.""" + + def __post_init__(self): + self.ap_code = DS3ItemData.__item_id + DS3ItemData.__item_id += 1 + def counts(self, counts: List[int]) -> Generator[Self]: """Returns an iterable of copies of this item with the given counts.""" yield self @@ -65,22 +78,40 @@ def __eq__(self, other): class DarkSouls3Item(Item): game: str = "Dark Souls III" count: int = 1 + soul: bool = False def __init__( self, name: str, classification: ItemClassification, code: Optional[int], - player: int, - count: Optional[int] = None): + player: int): super().__init__(name, classification, code, player) - self.count = count or 1 @staticmethod - def get_name_to_id() -> dict: - base_id = 100000 - return {item_data.name: id for id, item_data in enumerate(_all_items, base_id)} + def from_data(player: int, data: DS3ItemData) -> Self: + useful_categories = { + DS3ItemCategory.WEAPON_UPGRADE_5, + DS3ItemCategory.WEAPON_UPGRADE_10, + DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE, + DS3ItemCategory.SPELL, + } + + if data.name in key_item_names: + classification = ItemClassification.progression + elif data.category in useful_categories or data.name in {"Estus Shard", "Undead Bone Shard"}: + classification = ItemClassification.useful + else: + classification = ItemClassification.filler + item = DarkSouls3Item( + data.name, + classification, + data.ap_code, + player) + item.count = data.count + item.soul = data.soul + return item key_item_names = { "Small Lothric Banner", @@ -889,26 +920,26 @@ def get_name_to_id() -> dict: DS3ItemData("Twinkling Dragon Torso Stone", 0x40000184, DS3ItemCategory.MISC), DS3ItemData("Fire Keeper Soul", 0x40000186, DS3ItemCategory.MISC), DS3ItemData("Fading Soul", 0x40000190, DS3ItemCategory.MISC), - DS3ItemData("Soul of a Deserted Corpse", 0x40000191, DS3ItemCategory.MISC), - DS3ItemData("Large Soul of a Deserted Corpse", 0x40000192, DS3ItemCategory.MISC), - DS3ItemData("Soul of an Unknown Traveler", 0x40000193, DS3ItemCategory.MISC), - DS3ItemData("Large Soul of an Unknown Traveler", 0x40000194, DS3ItemCategory.MISC), - DS3ItemData("Soul of a Nameless Soldier", 0x40000195, DS3ItemCategory.MISC), - DS3ItemData("Large Soul of a Nameless Soldier", 0x40000196, DS3ItemCategory.MISC), - DS3ItemData("Soul of a Weary Warrior", 0x40000197, DS3ItemCategory.MISC), - DS3ItemData("Large Soul of a Weary Warrior", 0x40000198, DS3ItemCategory.MISC), - DS3ItemData("Soul of a Crestfallen Knight", 0x40000199, DS3ItemCategory.MISC), - DS3ItemData("Large Soul of a Crestfallen Knight", 0x4000019A, DS3ItemCategory.MISC), - DS3ItemData("Soul of a Proud Paladin", 0x4000019B, DS3ItemCategory.MISC), - DS3ItemData("Large Soul of a Proud Paladin", 0x4000019C, DS3ItemCategory.MISC), - DS3ItemData("Soul of an Intrepid Hero", 0x4000019D, DS3ItemCategory.MISC), - DS3ItemData("Large Soul of an Intrepid Hero", 0x4000019E, DS3ItemCategory.MISC), - DS3ItemData("Soul of a Seasoned Warrior", 0x4000019F, DS3ItemCategory.MISC), - DS3ItemData("Large Soul of a Seasoned Warrior", 0x400001A0, DS3ItemCategory.MISC), - DS3ItemData("Soul of an Old Hand", 0x400001A1, DS3ItemCategory.MISC), - DS3ItemData("Soul of a Venerable Old Hand", 0x400001A2, DS3ItemCategory.MISC), - DS3ItemData("Soul of a Champion", 0x400001A3, DS3ItemCategory.MISC), - DS3ItemData("Soul of a Great Champion", 0x400001A4, DS3ItemCategory.MISC), + DS3ItemData("Soul of a Deserted Corpse", 0x40000191, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Large Soul of a Deserted Corpse", 0x40000192, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Soul of an Unknown Traveler", 0x40000193, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Large Soul of an Unknown Traveler", 0x40000194, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Soul of a Nameless Soldier", 0x40000195, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Large Soul of a Nameless Soldier", 0x40000196, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Soul of a Weary Warrior", 0x40000197, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Large Soul of a Weary Warrior", 0x40000198, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Soul of a Crestfallen Knight", 0x40000199, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Large Soul of a Crestfallen Knight", 0x4000019A, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Soul of a Proud Paladin", 0x4000019B, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Large Soul of a Proud Paladin", 0x4000019C, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Soul of an Intrepid Hero", 0x4000019D, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Large Soul of an Intrepid Hero", 0x4000019E, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Soul of a Seasoned Warrior", 0x4000019F, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Large Soul of a Seasoned Warrior", 0x400001A0, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Soul of an Old Hand", 0x400001A1, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Soul of a Venerable Old Hand", 0x400001A2, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Soul of a Champion", 0x400001A3, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Soul of a Great Champion", 0x400001A4, DS3ItemCategory.MISC, soul = True), DS3ItemData("Seed of a Giant Tree", 0x400001B8, DS3ItemCategory.SKIP, inject = True), DS3ItemData("Mossfruit", 0x400001C4, DS3ItemCategory.SKIP).counts([2]), @@ -928,26 +959,26 @@ def get_name_to_id() -> dict: DS3ItemData("Very good! Carving", 0x4000020A, DS3ItemCategory.SKIP), DS3ItemData("I'm sorry Carving", 0x4000020B, DS3ItemCategory.SKIP), DS3ItemData("Help me! Carving", 0x4000020C, DS3ItemCategory.SKIP), - DS3ItemData("Soul of Champion Gundyr", 0x400002C8, DS3ItemCategory.BOSS), - DS3ItemData("Soul of the Dancer", 0x400002CA, DS3ItemCategory.BOSS), - DS3ItemData("Soul of a Crystal Sage", 0x400002CB, DS3ItemCategory.BOSS), - DS3ItemData("Soul of the Blood of the Wolf", 0x400002CD, DS3ItemCategory.BOSS), - DS3ItemData("Soul of Consumed Oceiros", 0x400002CE, DS3ItemCategory.BOSS), - DS3ItemData("Soul of Boreal Valley Vordt", 0x400002CF, DS3ItemCategory.BOSS), - DS3ItemData("Soul of the Old Demon King", 0x400002D0, DS3ItemCategory.BOSS), - DS3ItemData("Soul of Dragonslayer Armour", 0x400002D1, DS3ItemCategory.BOSS), - DS3ItemData("Soul of the Nameless King", 0x400002D2, DS3ItemCategory.BOSS), - DS3ItemData("Soul of Pontiff Sulyvahn", 0x400002D4, DS3ItemCategory.BOSS), - DS3ItemData("Soul of Aldrich", 0x400002D5, DS3ItemCategory.BOSS), - DS3ItemData("Soul of High Lord Wolnir", 0x400002D6, DS3ItemCategory.BOSS), - DS3ItemData("Soul of the Rotted Greatwood", 0x400002D7, DS3ItemCategory.BOSS), - DS3ItemData("Soul of Rosaria", 0x400002D8, DS3ItemCategory.MISC), - DS3ItemData("Soul of the Deacons of the Deep", 0x400002D9, DS3ItemCategory.BOSS), - DS3ItemData("Soul of the Twin Princes", 0x400002DB, DS3ItemCategory.BOSS), - DS3ItemData("Soul of Yhorm the Giant", 0x400002DC, DS3ItemCategory.BOSS), - DS3ItemData("Soul of the Lords", 0x400002DD, DS3ItemCategory.MISC), - DS3ItemData("Soul of a Demon", 0x400002E3, DS3ItemCategory.BOSS), - DS3ItemData("Soul of a Stray Demon", 0x400002E7, DS3ItemCategory.BOSS), + DS3ItemData("Soul of Champion Gundyr", 0x400002C8, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of the Dancer", 0x400002CA, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of a Crystal Sage", 0x400002CB, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of the Blood of the Wolf", 0x400002CD, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of Consumed Oceiros", 0x400002CE, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of Boreal Valley Vordt", 0x400002CF, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of the Old Demon King", 0x400002D0, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of Dragonslayer Armour", 0x400002D1, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of the Nameless King", 0x400002D2, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of Pontiff Sulyvahn", 0x400002D4, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of Aldrich", 0x400002D5, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of High Lord Wolnir", 0x400002D6, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of the Rotted Greatwood", 0x400002D7, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of Rosaria", 0x400002D8, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Soul of the Deacons of the Deep", 0x400002D9, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of the Twin Princes", 0x400002DB, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of Yhorm the Giant", 0x400002DC, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of the Lords", 0x400002DD, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Soul of a Demon", 0x400002E3, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of a Stray Demon", 0x400002E7, DS3ItemCategory.BOSS, soul = True), DS3ItemData("Titanite Shard", 0x400003E8, DS3ItemCategory.MISC).counts([2]), DS3ItemData("Large Titanite Shard", 0x400003E9, DS3ItemCategory.MISC).counts([2, 3]), DS3ItemData("Titanite Chunk", 0x400003EA, DS3ItemCategory.MISC).counts([2, 6]), diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 389d978a82e7..abde80ada05a 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1,5 +1,5 @@ from enum import IntEnum -from typing import Optional, Dict, Set +from typing import Optional, Dict, Self, Set from dataclasses import dataclass from BaseClasses import Location, LocationProgressType, Region @@ -61,6 +61,9 @@ class DS3LocationData: progression or useful items. """ + dlc: bool = False + """Whether this location is only accessible if the DLC is enabled.""" + # TODO: implement this properly ngp: bool = False """Whether this location only contains an item in NG+ and later. @@ -166,7 +169,7 @@ def from_data( player: int, data: DS3LocationData, address: Optional[int] = None, - parent: Optional[Region] = None): + parent: Optional[Region] = None) -> Self: location = DarkSouls3Location( player, data.name, @@ -2660,7 +2663,7 @@ def get_name_to_id() -> dict: offline = "99,0:-1:110000,120000,70000110:", shop = True, npc = True), # Undead Settlement rewards - DS3LocationData("Greirat: Divine Blessing", "Divine Blessing", DS3LocationCategory.MISC, + DS3LocationData("Greirat: Divine Blessing #1", "Divine Blessing", DS3LocationCategory.MISC, offline = '99,0:-1:110000,120000,70000150,70000175:', missable = True, shop = True, npc = True), DS3LocationData("Greirat: Ember #2", "Ember", DS3LocationCategory.MISC, offline = '99,0:-1:110000,120000,70000150,70000175:', missable = True, shop = True, npc = True), @@ -2668,11 +2671,11 @@ def get_name_to_id() -> dict: # Irityhll rewards DS3LocationData("Greirat: Divine Blessing #2", "Divine Blessing", DS3LocationCategory.MISC, offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), - DS3LocationData("Greirat: Hidden Blessing #1", "Hidden Blessing", DS3LocationCategory.MISC, + DS3LocationData("Greirat: Hidden Blessing", "Hidden Blessing", DS3LocationCategory.MISC, offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), - DS3LocationData("Greirat: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE, + DS3LocationData("Greirat: Titanite Scale", "Titanite Scale", DS3LocationCategory.UPGRADE, offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), - DS3LocationData("Greirat: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + DS3LocationData("Greirat: Twinkling Titanite", "Twinkling Titanite", DS3LocationCategory.UPGRADE, offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), # Lothric rewards (from Shrine Handmaid) @@ -2712,6 +2715,17 @@ def get_name_to_id() -> dict: ], } + +for region in [ + "Painted World of Ariandel (Before Contraption)", + "Painted World of Ariandel (After Contraption)", + "Dreg Heap", + "Ringed City", +]: + for location in location_tables[region]: + location.dlc = True + + location_name_groups: Dict[str, Set[str]] = { # We could insert these locations automatically with setdefault(), but we set them up explicitly # instead so we can choose the ordering. diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index b93d8e9582c7..b99654666d22 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -8,8 +8,8 @@ from worlds.AutoWorld import World, WebWorld from worlds.generic.Rules import set_rule, add_rule, add_item_rule -from .Items import DarkSouls3Item, DS3ItemCategory, item_dictionary, key_item_names -from .Locations import DarkSouls3Location, DS3LocationCategory, location_tables, location_dictionary, location_name_groups +from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, item_dictionary, key_item_names +from .Locations import DarkSouls3Location, DS3LocationCategory, DS3LocationData, location_tables, location_dictionary, location_name_groups from .Options import RandomizeWeaponLevelOption, PoolTypeOption, dark_souls_options @@ -51,7 +51,7 @@ class DarkSouls3World(World): base_id = 100000 enabled_location_categories: Set[DS3LocationCategory] required_client_version = (0, 4, 2) - item_name_to_id = DarkSouls3Item.get_name_to_id() + item_name_to_id = {data.name: data.ap_code for data in item_dictionary.values()} location_name_to_id = DarkSouls3Location.get_name_to_id() location_name_groups = location_name_groups item_name_groups = { @@ -350,28 +350,9 @@ def create_random_replacement_list(item_categories: Set[DS3ItemCategory], num_it self.multiworld.itempool += itempool - def create_item(self, name: str) -> Item: - useful_categories = { - DS3ItemCategory.WEAPON_UPGRADE_5, - DS3ItemCategory.WEAPON_UPGRADE_10, - DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE, - DS3ItemCategory.SPELL, - } - - if name in key_item_names: - item_classification = ItemClassification.progression - elif item_dictionary[name].category in useful_categories or name in {"Estus Shard", "Undead Bone Shard"}: - item_classification = ItemClassification.useful - else: - item_classification = ItemClassification.filler - - data = item_dictionary[name] - return DarkSouls3Item( - name, - item_classification, - self.item_name_to_id[name], - self.player, - data.count) + def create_item(self, item: str|DS3ItemData) -> Item: + return DarkSouls3Item.from_data( + self.player, item if isinstance(item, DS3ItemData) else item_dictionary[item]) def get_filler_item_name(self) -> str: @@ -429,9 +410,9 @@ def set_rules(self) -> None: } for ash, items in ashes.items(): for item in items: - location = location_dictionary["FS: " + item] - if location.category in self.enabled_location_categories: - set_rule(self.multiworld.get_location(location.name, self.player), + location = "FS: " + item + if self.__is_location_available(location): + set_rule(self.multiworld.get_location(location, self.player), lambda state, ash=ash: state.has(ash, self.player)) if self.multiworld.late_basin_of_vows[self.player] == Toggle.option_true: @@ -510,6 +491,13 @@ def set_rules(self) -> None: if self.multiworld.enable_weapon_locations[self.player] == Toggle.option_true: set_rule(self.multiworld.get_location("LC: Gotthard Twinswords", self.player), gotthard_corpse_rule) + # Forbid shops from carrying items with multiple counts (the offline randomizer has its own + # logic for choosing how many shop items to sell), and from carring soul items. + for location in location_dictionary.values(): + if location.shop and self.__is_location_available(location): + add_item_rule(self.multiworld.get_location(location.name, self.player), + lambda item: item.count == 1 and not item.soul) + self.multiworld.completion_condition[self.player] = lambda state: \ state.has("Cinders of a Lord - Abyss Watcher", self.player) and \ state.has("Cinders of a Lord - Yhorm the Giant", self.player) and \ @@ -517,6 +505,15 @@ def set_rules(self) -> None: state.has("Cinders of a Lord - Lothric Prince", self.player) + def __is_location_available(self, location: str|DS3LocationData): + """Returns whether the given location is being randomized.""" + data = location if isinstance(location, DS3LocationData) else location_dictionary[location] + return ( + data.category in self.enabled_location_categories and + (not data.dlc or self.multiworld.enable_dlc[self.player] == Toggle.option_true) + ) + + def fill_slot_data(self) -> Dict[str, object]: slot_data: Dict[str, object] = {} @@ -591,7 +588,6 @@ def fill_slot_data(self) -> Dict[str, object]: }, "seed": self.multiworld.seed_name, # to verify the server's multiworld "slot": self.multiworld.player_name[self.player], # to connect to server - "base_id": self.base_id, # to merge location and items lists "apIdsToItemIds": ap_ids_to_ds3_ids, "itemCounts": item_counts, "locationNamesToKeys": location_names_to_keys, From 5363316fc090c129a0e7269df42dd0dc088913fe Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 28 Oct 2023 15:21:37 -0700 Subject: [PATCH 025/238] Add an option to enable whether NG+ items/locations are included --- worlds/dark_souls_3/Locations.py | 10 +++++----- worlds/dark_souls_3/Options.py | 6 ++++++ worlds/dark_souls_3/__init__.py | 21 +++++++++++++++------ 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index abde80ada05a..761acdcd23c8 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -343,15 +343,15 @@ def get_name_to_id() -> dict: shop = True), # Captain's Ashes DS3LocationData("FS: Millwood Knight Helm", "Millwood Knight Helm", DS3LocationCategory.ARMOR, - shop = True), + dlc = True, shop = True), DS3LocationData("FS: Millwood Knight Armor", "Millwood Knight Armor", DS3LocationCategory.ARMOR, - shop = True), + dlc = True, shop = True), DS3LocationData("FS: Millwood Knight Gauntlets", "Millwood Knight Gauntlets", DS3LocationCategory.ARMOR, - shop = True), + dlc = True, shop = True), DS3LocationData("FS: Millwood Knight Leggings", "Millwood Knight Leggings", DS3LocationCategory.ARMOR, - shop = True), + dlc = True, shop = True), DS3LocationData("FS: Refined Gem", "Refined Gem", DS3LocationCategory.UPGRADE, - shop = True), + dlc = True, shop = True), ], "Firelink Shrine Bell Tower": [ # Guarded by Tower Key diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index d305f0ef256e..827bca060674 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -191,6 +191,11 @@ class EnableDLCOption(Toggle): display_name = "Enable DLC" +class EnableNGPOption(Toggle): + """Whether to include items and locations exclusive to NG+ cycles.""" + display_name = "Enable NG+" + + dark_souls_options: typing.Dict[str, Option] = { "enable_weapon_locations": RandomizeWeaponLocations, "enable_shield_locations": RandomizeShieldLocations, @@ -223,4 +228,5 @@ class EnableDLCOption(Toggle): "no_equip_load": NoEquipLoadOption, "death_link": DeathLink, "enable_dlc": EnableDLCOption, + "enable_ngp": EnableNGPOption, } diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index b99654666d22..e06eb27a8292 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -192,8 +192,7 @@ def create_region(self, region_name, location_table) -> Region: new_region = Region(region_name, self.player, self.multiworld) for location in location_table: - if (location.category in self.enabled_location_categories and - (not location.npc or self.multiworld.enable_npc_locations[self.player] == Toggle.option_true)): + if self.__is_location_available(location): new_location = DarkSouls3Location.from_data( self.player, location, @@ -234,7 +233,7 @@ def create_items(self): # Gather all default items on randomized locations num_required_extra_items = 0 for location in self.multiworld.get_locations(self.player): - if location.category in itempool_by_category: + if self.__is_location_available(location.name): item_category = item_dictionary[location.default_item_name].category if item_category == DS3ItemCategory.SKIP: num_required_extra_items += 1 @@ -507,10 +506,19 @@ def set_rules(self) -> None: def __is_location_available(self, location: str|DS3LocationData): """Returns whether the given location is being randomized.""" - data = location if isinstance(location, DS3LocationData) else location_dictionary[location] + if isinstance(location, DS3LocationData): + data = location + elif location in location_dictionary: + data = location_dictionary[location] + else: + # Synthetic locations (like Path of the Dragon) are never considered available. + return False + return ( data.category in self.enabled_location_categories and - (not data.dlc or self.multiworld.enable_dlc[self.player] == Toggle.option_true) + (not data.npc or self.multiworld.enable_npc_locations[self.player] == Toggle.option_true) and + (not data.dlc or self.multiworld.enable_dlc[self.player] == Toggle.option_true) and + (not data.ngp or self.multiworld.enable_ngp[self.player] == Toggle.option_true) ) @@ -584,7 +592,8 @@ def fill_slot_data(self) -> Dict[str, object]: "death_link": self.multiworld.death_link[self.player].value, "no_spell_requirements": self.multiworld.no_spell_requirements[self.player].value, "no_equip_load": self.multiworld.no_equip_load[self.player].value, - "enable_dlc": self.multiworld.enable_dlc[self.player].value + "enable_dlc": self.multiworld.enable_dlc[self.player].value, + "enable_ngp": self.multiworld.enable_ngp[self.player].value, }, "seed": self.multiworld.seed_name, # to verify the server's multiworld "slot": self.multiworld.player_name[self.player], # to connect to server From 055619f382c672595a6fcd6f065fec37d28c70bf Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 28 Oct 2023 16:26:38 -0700 Subject: [PATCH 026/238] 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 --- worlds/dark_souls_3/Items.py | 305 +++++++++++++++++++------------- worlds/dark_souls_3/__init__.py | 21 ++- 2 files changed, 199 insertions(+), 127 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 3167cedc59ec..c4819f47583e 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -23,6 +23,25 @@ class DS3ItemCategory(IntEnum): BOSS = 10 SKIP = 11 +class UsefulIf(IntEnum): + """An enum that indicates when an item should be upgraded to ItemClassification.useful. + + This is used for rings with +x variants that may or may not be the best in class depending on + the player's settings. + """ + + DEFAULT = 0 + """Follows DS3ItemData.classification as written.""" + + BASE = 1 + """Useful only if the DLC and NG+ locations are disabled.""" + + NO_DLC = 2 + """Useful if the DLC is disabled, whether or not NG+ locations are.""" + + NO_NGP = 3 + """Useful if NG+ locations is disabled, whether or not the DLC is.""" + @dataclass class DS3ItemData(): @@ -33,6 +52,9 @@ class DS3ItemData(): ds3_code: int category: DS3ItemCategory + classification: ItemClassification = ItemClassification.filler + """How important this item is to the game progression.""" + ap_code: int = False """The Archipelago ID for this item.""" @@ -54,6 +76,9 @@ class DS3ItemData(): soul: bool = False """Whether this is a consumable item that gives souls when used.""" + useful_if: UsefulIf = UsefulIf.DEFAULT + """Whether and when this item should be marked as "useful".""" + def __post_init__(self): self.ap_code = DS3ItemData.__item_id DS3ItemData.__item_id += 1 @@ -89,59 +114,16 @@ def __init__( super().__init__(name, classification, code, player) @staticmethod - def from_data(player: int, data: DS3ItemData) -> Self: - useful_categories = { - DS3ItemCategory.WEAPON_UPGRADE_5, - DS3ItemCategory.WEAPON_UPGRADE_10, - DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE, - DS3ItemCategory.SPELL, - } - - if data.name in key_item_names: - classification = ItemClassification.progression - elif data.category in useful_categories or data.name in {"Estus Shard", "Undead Bone Shard"}: - classification = ItemClassification.useful - else: - classification = ItemClassification.filler - + def from_data(player: int, data: DS3ItemData, classification = None) -> Self: item = DarkSouls3Item( data.name, - classification, + classification or data.classification, data.ap_code, player) item.count = data.count item.soul = data.soul return item -key_item_names = { - "Small Lothric Banner", - "Basin of Vows", - "Small Doll", - "Storm Ruler", - "Grand Archives Key", - "Cinders of a Lord - Abyss Watcher", - "Cinders of a Lord - Yhorm the Giant", - "Cinders of a Lord - Aldrich", - "Cinders of a Lord - Lothric Prince", - "Mortician's Ashes", - "Dreamchaser's Ashes", - "Paladin's Ashes", - "Grave Warden's Ashes", - "Prisoner Chief's Ashes", - "Xanthus Ashes", - "Dragon Chaser's Ashes", - "Easterner's Ashes", - "Captain's Ashes", - "Cell Key", - "Tower Key", - "Lift Chamber Key", - "Jailbreaker's Key", - "Old Cell Key", - "Jailer's Key Ring", - "Contraption Key", - "Small Envoy Banner" -} - _vanilla_items = flatten([ # Ammunition DS3ItemData("Standard Arrow x12", 0x00061A80, DS3ItemCategory.MISC).counts([12]), @@ -240,7 +222,8 @@ def from_data(player: int, data: DS3ItemData) -> Self: DS3ItemData("Fume Ultra Greatsword", 0x0060E4B0, DS3ItemCategory.WEAPON_UPGRADE_5), DS3ItemData("Old Wolf Curved Sword", 0x00610BC0, DS3ItemCategory.WEAPON_UPGRADE_5, inject = True), # Covenant reward - DS3ItemData("Storm Ruler", 0x006132D0, DS3ItemCategory.KEY), + DS3ItemData("Storm Ruler", 0x006132D0, DS3ItemCategory.KEY, + classification = ItemClassification.progression), DS3ItemData("Hand Axe", 0x006ACFC0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), DS3ItemData("Battle Axe", 0x006AF6D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), DS3ItemData("Deep Battle Axe", 0x006AFA54, DS3ItemCategory.WEAPON_UPGRADE_10), @@ -747,18 +730,26 @@ def from_data(player: int, data: DS3ItemData) -> Self: DS3ItemData("Life Ring+1", 0x20004E21, DS3ItemCategory.RING), DS3ItemData("Life Ring+2", 0x20004E22, DS3ItemCategory.RING), DS3ItemData("Life Ring+3", 0x20004E23, DS3ItemCategory.RING), - DS3ItemData("Chloranthy Ring", 0x20004E2A, DS3ItemCategory.RING), + DS3ItemData("Chloranthy Ring", 0x20004E2A, DS3ItemCategory.RING, + useful_if = UsefulIf.BASE), DS3ItemData("Chloranthy Ring+1", 0x20004E2B, DS3ItemCategory.RING), - DS3ItemData("Chloranthy Ring+2", 0x20004E2C, DS3ItemCategory.RING), - DS3ItemData("Havel's Ring", 0x20004E34, DS3ItemCategory.RING), + DS3ItemData("Chloranthy Ring+2", 0x20004E2C, DS3ItemCategory.RING, + useful_if = UsefulIf.NO_DLC), + DS3ItemData("Havel's Ring", 0x20004E34, DS3ItemCategory.RING, + useful_if = UsefulIf.BASE), DS3ItemData("Havel's Ring+1", 0x20004E35, DS3ItemCategory.RING), - DS3ItemData("Havel's Ring+2", 0x20004E36, DS3ItemCategory.RING), - DS3ItemData("Ring of Favor", 0x20004E3E, DS3ItemCategory.RING), + DS3ItemData("Havel's Ring+2", 0x20004E36, DS3ItemCategory.RING, + useful_if = UsefulIf.NO_DLC), + DS3ItemData("Ring of Favor", 0x20004E3E, DS3ItemCategory.RING, + useful_if = UsefulIf.BASE), DS3ItemData("Ring of Favor+1", 0x20004E3F, DS3ItemCategory.RING), - DS3ItemData("Ring of Favor+2", 0x20004E40, DS3ItemCategory.RING), - DS3ItemData("Ring of Steel Protection", 0x20004E48, DS3ItemCategory.RING), + DS3ItemData("Ring of Favor+2", 0x20004E40, DS3ItemCategory.RING, + useful_if = UsefulIf.NO_DLC), + DS3ItemData("Ring of Steel Protection", 0x20004E48, DS3ItemCategory.RING, + useful_if = UsefulIf.BASE), DS3ItemData("Ring of Steel Protection+1", 0x20004E49, DS3ItemCategory.RING), - DS3ItemData("Ring of Steel Protection+2", 0x20004E4A, DS3ItemCategory.RING), + DS3ItemData("Ring of Steel Protection+2", 0x20004E4A, DS3ItemCategory.RING, + useful_if = UsefulIf.NO_DLC), DS3ItemData("Flame Stoneplate Ring", 0x20004E52, DS3ItemCategory.RING), DS3ItemData("Flame Stoneplate Ring+1", 0x20004E53, DS3ItemCategory.RING), DS3ItemData("Flame Stoneplate Ring+2", 0x20004E54, DS3ItemCategory.RING), @@ -802,9 +793,11 @@ def from_data(player: int, data: DS3ItemData) -> Self: DS3ItemData("Lingering Dragoncrest Ring", 0x20004F2E, DS3ItemCategory.RING), DS3ItemData("Lingering Dragoncrest Ring+1", 0x20004F2F, DS3ItemCategory.RING), DS3ItemData("Lingering Dragoncrest Ring+2", 0x20004F30, DS3ItemCategory.RING), - DS3ItemData("Sage Ring", 0x20004F38, DS3ItemCategory.RING), + DS3ItemData("Sage Ring", 0x20004F38, DS3ItemCategory.RING, + useful_if = UsefulIf.NO_NGP), DS3ItemData("Sage Ring+1", 0x20004F39, DS3ItemCategory.RING), - DS3ItemData("Sage Ring+2", 0x20004F3A, DS3ItemCategory.RING), + DS3ItemData("Sage Ring+2", 0x20004F3A, DS3ItemCategory.RING, + classification = ItemClassification.useful), DS3ItemData("Slumbering Dragoncrest Ring", 0x20004F42, DS3ItemCategory.RING), DS3ItemData("Dusk Crown Ring", 0x20004F4C, DS3ItemCategory.RING), DS3ItemData("Saint's Ring", 0x20004F56, DS3ItemCategory.RING), @@ -816,9 +809,11 @@ def from_data(player: int, data: DS3ItemData) -> Self: DS3ItemData("Covetous Gold Serpent Ring", 0x20004FA6, DS3ItemCategory.RING), DS3ItemData("Covetous Gold Serpent Ring+1", 0x20004FA7, DS3ItemCategory.RING), DS3ItemData("Covetous Gold Serpent Ring+2", 0x20004FA8, DS3ItemCategory.RING), - DS3ItemData("Covetous Silver Serpent Ring", 0x20004FB0, DS3ItemCategory.RING), + DS3ItemData("Covetous Silver Serpent Ring", 0x20004FB0, DS3ItemCategory.RING, + useful_if = UsefulIf.BASE), DS3ItemData("Covetous Silver Serpent Ring+1", 0x20004FB1, DS3ItemCategory.RING), - DS3ItemData("Covetous Silver Serpent Ring+2", 0x20004FB2, DS3ItemCategory.RING), + DS3ItemData("Covetous Silver Serpent Ring+2", 0x20004FB2, DS3ItemCategory.RING, + useful_if = UsefulIf.NO_DLC), DS3ItemData("Sun Princess Ring", 0x20004FBA, DS3ItemCategory.RING), DS3ItemData("Silvercat Ring", 0x20004FC4, DS3ItemCategory.RING), DS3ItemData("Skull Ring", 0x20004FCE, DS3ItemCategory.RING), @@ -832,7 +827,8 @@ def from_data(player: int, data: DS3ItemData) -> Self: DS3ItemData("Fire Clutch Ring", 0x2000501E, DS3ItemCategory.RING), DS3ItemData("Dark Clutch Ring", 0x20005028, DS3ItemCategory.RING), DS3ItemData("Flynn's Ring", 0x2000503C, DS3ItemCategory.RING), - DS3ItemData("Prisoner's Chain", 0x20005046, DS3ItemCategory.RING), + DS3ItemData("Prisoner's Chain", 0x20005046, DS3ItemCategory.RING, + classification = ItemClassification.useful), DS3ItemData("Untrue Dark Ring", 0x20005050, DS3ItemCategory.RING), DS3ItemData("Obscuring Ring", 0x20005064, DS3ItemCategory.RING), DS3ItemData("Ring of the Evil Eye", 0x2000506E, DS3ItemCategory.RING), @@ -842,12 +838,14 @@ def from_data(player: int, data: DS3ItemData) -> Self: DS3ItemData("Farron Ring", 0x20005082, DS3ItemCategory.RING), DS3ItemData("Aldrich's Ruby", 0x2000508C, DS3ItemCategory.RING), DS3ItemData("Aldrich's Sapphire", 0x20005096, DS3ItemCategory.RING), - DS3ItemData("Lloyd's Sword Ring", 0x200050B4, DS3ItemCategory.RING), + DS3ItemData("Lloyd's Sword Ring", 0x200050B4, DS3ItemCategory.RING, + classification = ItemClassification.useful), DS3ItemData("Lloyd's Shield Ring", 0x200050BE, DS3ItemCategory.RING), DS3ItemData("Estus Ring", 0x200050DC, DS3ItemCategory.RING), DS3ItemData("Ashen Estus Ring", 0x200050E6, DS3ItemCategory.RING), DS3ItemData("Horsehoof Ring", 0x200050F0, DS3ItemCategory.RING), - DS3ItemData("Carthus Bloodring", 0x200050FA, DS3ItemCategory.RING), + DS3ItemData("Carthus Bloodring", 0x200050FA, DS3ItemCategory.RING, + classification = ItemClassification.useful), DS3ItemData("Reversal Ring", 0x20005104, DS3ItemCategory.RING), DS3ItemData("Pontiff's Right Eye", 0x2000510E, DS3ItemCategory.RING), DS3ItemData("Pontiff's Left Eye", 0x20005136, DS3ItemCategory.RING), @@ -908,7 +906,7 @@ def from_data(player: int, data: DS3ItemData) -> Self: DS3ItemData("Binoculars", 0x40000173, DS3ItemCategory.MISC), DS3ItemData("Proof of a Concord Kept", 0x40000174, DS3ItemCategory.SKIP), DS3ItemData("Pale Tongue", 0x40000175, DS3ItemCategory.SKIP, - inject = True), # Inject one of these for Leonhard's quest + classification = ItemClassification.useful, inject = True), # Inject one of these for Leonhard's quest DS3ItemData("Vertebra Shackle", 0x40000176, DS3ItemCategory.SKIP, inject = True), # Inject one of these to trade to the crow DS3ItemData("Sunlight Medal", 0x40000177, DS3ItemCategory.SKIP), @@ -959,30 +957,51 @@ def from_data(player: int, data: DS3ItemData) -> Self: DS3ItemData("Very good! Carving", 0x4000020A, DS3ItemCategory.SKIP), DS3ItemData("I'm sorry Carving", 0x4000020B, DS3ItemCategory.SKIP), DS3ItemData("Help me! Carving", 0x4000020C, DS3ItemCategory.SKIP), - DS3ItemData("Soul of Champion Gundyr", 0x400002C8, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of the Dancer", 0x400002CA, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of a Crystal Sage", 0x400002CB, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of the Blood of the Wolf", 0x400002CD, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of Consumed Oceiros", 0x400002CE, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of Boreal Valley Vordt", 0x400002CF, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of the Old Demon King", 0x400002D0, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of Dragonslayer Armour", 0x400002D1, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of the Nameless King", 0x400002D2, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of Pontiff Sulyvahn", 0x400002D4, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of Aldrich", 0x400002D5, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of High Lord Wolnir", 0x400002D6, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of the Rotted Greatwood", 0x400002D7, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of Rosaria", 0x400002D8, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Soul of the Deacons of the Deep", 0x400002D9, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of the Twin Princes", 0x400002DB, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of Yhorm the Giant", 0x400002DC, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of the Lords", 0x400002DD, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Soul of a Demon", 0x400002E3, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of a Stray Demon", 0x400002E7, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of Champion Gundyr", 0x400002C8, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of the Dancer", 0x400002CA, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of a Crystal Sage", 0x400002CB, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of the Blood of the Wolf", 0x400002CD, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of Consumed Oceiros", 0x400002CE, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of Boreal Valley Vordt", 0x400002CF, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of the Old Demon King", 0x400002D0, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of Dragonslayer Armour", 0x400002D1, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of the Nameless King", 0x400002D2, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of Pontiff Sulyvahn", 0x400002D4, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of Aldrich", 0x400002D5, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of High Lord Wolnir", 0x400002D6, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of the Rotted Greatwood", 0x400002D7, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of Rosaria", 0x400002D8, DS3ItemCategory.MISC, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of the Deacons of the Deep", 0x400002D9, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of the Twin Princes", 0x400002DB, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of Yhorm the Giant", 0x400002DC, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of the Lords", 0x400002DD, DS3ItemCategory.MISC, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of a Demon", 0x400002E3, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), + DS3ItemData("Soul of a Stray Demon", 0x400002E7, DS3ItemCategory.BOSS, soul = True, + classification = ItemClassification.useful), DS3ItemData("Titanite Shard", 0x400003E8, DS3ItemCategory.MISC).counts([2]), DS3ItemData("Large Titanite Shard", 0x400003E9, DS3ItemCategory.MISC).counts([2, 3]), DS3ItemData("Titanite Chunk", 0x400003EA, DS3ItemCategory.MISC).counts([2, 6]), - DS3ItemData("Titanite Slab", 0x400003EB, DS3ItemCategory.MISC), + DS3ItemData("Titanite Slab", 0x400003EB, DS3ItemCategory.MISC, + classification = ItemClassification.useful), DS3ItemData("Titanite Scale", 0x400003FC, DS3ItemCategory.MISC).counts([2, 3]), DS3ItemData("Twinkling Titanite", 0x40000406, DS3ItemCategory.MISC).counts([2, 3]), DS3ItemData("Heavy Gem", 0x4000044C, DS3ItemCategory.MISC), @@ -1001,39 +1020,58 @@ def from_data(player: int, data: DS3ItemData) -> Self: DS3ItemData("Blessed Gem", 0x400004CE, DS3ItemCategory.MISC), DS3ItemData("Hollow Gem", 0x400004D8, DS3ItemCategory.MISC), DS3ItemData("Shriving Stone", 0x400004E2, DS3ItemCategory.MISC), - DS3ItemData("Lift Chamber Key", 0x400007D1, DS3ItemCategory.KEY), - DS3ItemData("Small Doll", 0x400007D5, DS3ItemCategory.KEY), - DS3ItemData("Jailbreaker's Key", 0x400007D7, DS3ItemCategory.KEY), - DS3ItemData("Jailer's Key Ring", 0x400007D8, DS3ItemCategory.KEY), + DS3ItemData("Lift Chamber Key", 0x400007D1, DS3ItemCategory.KEY, + classification = ItemClassification.progression), + DS3ItemData("Small Doll", 0x400007D5, DS3ItemCategory.KEY, + classification = ItemClassification.progression), + DS3ItemData("Jailbreaker's Key", 0x400007D7, DS3ItemCategory.KEY, + classification = ItemClassification.progression), + DS3ItemData("Jailer's Key Ring", 0x400007D8, DS3ItemCategory.KEY, + classification = ItemClassification.progression), DS3ItemData("Grave Key", 0x400007D9, DS3ItemCategory.KEY), - DS3ItemData("Cell Key", 0x400007DA, DS3ItemCategory.KEY), + DS3ItemData("Cell Key", 0x400007DA, DS3ItemCategory.KEY, + classification = ItemClassification.progression), DS3ItemData("Dungeon Ground Floor Key", 0x400007DB, DS3ItemCategory.KEY), - DS3ItemData("Old Cell Key", 0x400007DC, DS3ItemCategory.KEY), - DS3ItemData("Grand Archives Key", 0x400007DE, DS3ItemCategory.KEY), - DS3ItemData("Tower Key", 0x400007DF, DS3ItemCategory.KEY), - DS3ItemData("Small Lothric Banner", 0x40000836, DS3ItemCategory.KEY), + DS3ItemData("Old Cell Key", 0x400007DC, DS3ItemCategory.KEY, + classification = ItemClassification.progression), + DS3ItemData("Grand Archives Key", 0x400007DE, DS3ItemCategory.KEY, + classification = ItemClassification.progression), + DS3ItemData("Tower Key", 0x400007DF, DS3ItemCategory.KEY, + classification = ItemClassification.progression), + DS3ItemData("Small Lothric Banner", 0x40000836, DS3ItemCategory.KEY, + classification = ItemClassification.progression), DS3ItemData("Farron Coal", 0x40000837, DS3ItemCategory.MISC), DS3ItemData("Sage's Coal", 0x40000838, DS3ItemCategory.MISC), DS3ItemData("Giant's Coal", 0x40000839, DS3ItemCategory.MISC), DS3ItemData("Profaned Coal", 0x4000083A, DS3ItemCategory.MISC), - DS3ItemData("Mortician's Ashes", 0x4000083B, DS3ItemCategory.MISC), - DS3ItemData("Dreamchaser's Ashes", 0x4000083C, DS3ItemCategory.MISC), - DS3ItemData("Paladin's Ashes", 0x4000083D, DS3ItemCategory.MISC), - DS3ItemData("Grave Warden's Ashes", 0x4000083E, DS3ItemCategory.MISC), + DS3ItemData("Mortician's Ashes", 0x4000083B, DS3ItemCategory.MISC, + classification = ItemClassification.progression), + DS3ItemData("Dreamchaser's Ashes", 0x4000083C, DS3ItemCategory.MISC, + classification = ItemClassification.progression), + DS3ItemData("Paladin's Ashes", 0x4000083D, DS3ItemCategory.MISC, + classification = ItemClassification.progression), + DS3ItemData("Grave Warden's Ashes", 0x4000083E, DS3ItemCategory.MISC, + classification = ItemClassification.progression), DS3ItemData("Greirat's Ashes", 0x4000083F, DS3ItemCategory.MISC), DS3ItemData("Orbeck's Ashes", 0x40000840, DS3ItemCategory.MISC), DS3ItemData("Cornyx's Ashes", 0x40000841, DS3ItemCategory.MISC), DS3ItemData("Karla's Ashes", 0x40000842, DS3ItemCategory.MISC), DS3ItemData("Irina's Ashes", 0x40000843, DS3ItemCategory.MISC), DS3ItemData("Yuria's Ashes", 0x40000844, DS3ItemCategory.MISC), - DS3ItemData("Basin of Vows", 0x40000845, DS3ItemCategory.KEY), - DS3ItemData("Loretta's Bone", 0x40000846, DS3ItemCategory.KEY), + DS3ItemData("Basin of Vows", 0x40000845, DS3ItemCategory.KEY, + classification = ItemClassification.progression), + DS3ItemData("Loretta's Bone", 0x40000846, DS3ItemCategory.KEY, + classification = ItemClassification.useful), DS3ItemData("Braille Divine Tome of Carim", 0x40000847, DS3ItemCategory.MISC), DS3ItemData("Braille Divine Tome of Lothric", 0x40000848, DS3ItemCategory.MISC), - DS3ItemData("Cinders of a Lord - Abyss Watcher", 0x4000084B, DS3ItemCategory.KEY), - DS3ItemData("Cinders of a Lord - Aldrich", 0x4000084C, DS3ItemCategory.KEY), - DS3ItemData("Cinders of a Lord - Yhorm the Giant", 0x4000084D, DS3ItemCategory.KEY), - DS3ItemData("Cinders of a Lord - Lothric Prince", 0x4000084E, DS3ItemCategory.KEY), + DS3ItemData("Cinders of a Lord - Abyss Watcher", 0x4000084B, DS3ItemCategory.KEY, + classification = ItemClassification.progression), + DS3ItemData("Cinders of a Lord - Aldrich", 0x4000084C, DS3ItemCategory.KEY, + classification = ItemClassification.progression), + DS3ItemData("Cinders of a Lord - Yhorm the Giant", 0x4000084D, DS3ItemCategory.KEY, + classification = ItemClassification.progression), + DS3ItemData("Cinders of a Lord - Lothric Prince", 0x4000084E, DS3ItemCategory.KEY, + classification = ItemClassification.progression), DS3ItemData("Great Swamp Pyromancy Tome", 0x4000084F, DS3ItemCategory.MISC), DS3ItemData("Carthus Pyromancy Tome", 0x40000850, DS3ItemCategory.MISC), DS3ItemData("Izalith Pyromancy Tome", 0x40000851, DS3ItemCategory.MISC), @@ -1047,18 +1085,24 @@ def from_data(player: int, data: DS3ItemData) -> Self: DS3ItemData("Eyes of a Fire Keeper", 0x4000085A, DS3ItemCategory.KEY), DS3ItemData("Sword of Avowal", 0x4000085B, DS3ItemCategory.KEY), DS3ItemData("Golden Scroll", 0x4000085C, DS3ItemCategory.MISC), - DS3ItemData("Estus Shard", 0x4000085D, DS3ItemCategory.MISC), + DS3ItemData("Estus Shard", 0x4000085D, DS3ItemCategory.MISC, + classification = ItemClassification.useful), DS3ItemData("Hawkwood's Swordgrass", 0x4000085E, DS3ItemCategory.SKIP), - DS3ItemData("Undead Bone Shard", 0x4000085F, DS3ItemCategory.MISC), + DS3ItemData("Undead Bone Shard", 0x4000085F, DS3ItemCategory.MISC, + classification = ItemClassification.useful), DS3ItemData("Deep Braille Divine Tome", 0x40000860, DS3ItemCategory.MISC), DS3ItemData("Londor Braille Divine Tome", 0x40000861, DS3ItemCategory.MISC), DS3ItemData("Excrement-covered Ashes", 0x40000862, DS3ItemCategory.MISC), - DS3ItemData("Prisoner Chief's Ashes", 0x40000863, DS3ItemCategory.MISC), - DS3ItemData("Xanthous Ashes", 0x40000864, DS3ItemCategory.MISC), + DS3ItemData("Prisoner Chief's Ashes", 0x40000863, DS3ItemCategory.MISC, + classification = ItemClassification.progression), + DS3ItemData("Xanthous Ashes", 0x40000864, DS3ItemCategory.MISC, + classification = ItemClassification.progression), DS3ItemData("Hollow's Ashes", 0x40000865, DS3ItemCategory.MISC), DS3ItemData("Patches' Ashes", 0x40000866, DS3ItemCategory.MISC), - DS3ItemData("Dragon Chaser's Ashes", 0x40000867, DS3ItemCategory.MISC), - DS3ItemData("Easterner's Ashes", 0x40000868, DS3ItemCategory.MISC), + DS3ItemData("Dragon Chaser's Ashes", 0x40000867, DS3ItemCategory.MISC, + classification = ItemClassification.progression), + DS3ItemData("Easterner's Ashes", 0x40000868, DS3ItemCategory.MISC, + classification = ItemClassification.progression), # Spells DS3ItemData("Farron Dart", 0x40124F80, DS3ItemCategory.SPELL), @@ -1080,10 +1124,12 @@ def from_data(player: int, data: DS3ItemData) -> Self: DS3ItemData("Magic Shield", 0x40144B50, DS3ItemCategory.SPELL), DS3ItemData("Great Magic Shield", 0x40144F38, DS3ItemCategory.SPELL), DS3ItemData("Hidden Weapon", 0x40147260, DS3ItemCategory.SPELL), - DS3ItemData("Hidden Body", 0x40147648, DS3ItemCategory.SPELL), + DS3ItemData("Hidden Body", 0x40147648, DS3ItemCategory.SPELL, + classification = ItemClassification.useful), DS3ItemData("Cast Light", 0x40149970, DS3ItemCategory.SPELL), DS3ItemData("Repair", 0x4014A528, DS3ItemCategory.SPELL), - DS3ItemData("Spook", 0x4014A910, DS3ItemCategory.SPELL), + DS3ItemData("Spook", 0x4014A910, DS3ItemCategory.SPELL, + classification = ItemClassification.useful), DS3ItemData("Chameleon", 0x4014ACF8, DS3ItemCategory.SPELL), DS3ItemData("Aural Decoy", 0x4014B0E0, DS3ItemCategory.SPELL), DS3ItemData("White Dragon Breath", 0x4014E790, DS3ItemCategory.SPELL), @@ -1095,7 +1141,8 @@ def from_data(player: int, data: DS3ItemData) -> Self: DS3ItemData("Dark Edge", 0x40189CC8, DS3ItemCategory.SPELL), DS3ItemData("Soul Stream", 0x4018B820, DS3ItemCategory.SPELL), DS3ItemData("Twisted Wall of Light", 0x40193138, DS3ItemCategory.SPELL), - DS3ItemData("Pestilent Mist", 0x401A8CE0, DS3ItemCategory.SPELL), # Originally called "Pestilent Mercury" pre 1.15 + DS3ItemData("Pestilent Mist", 0x401A8CE0, DS3ItemCategory.SPELL, + classification = ItemClassification.useful), # Originally called "Pestilent Mercury" pre 1.15 DS3ItemData("Fireball", 0x40249F00, DS3ItemCategory.SPELL), DS3ItemData("Fire Orb", 0x4024A6D0, DS3ItemCategory.SPELL), DS3ItemData("Firestorm", 0x4024AAB8, DS3ItemCategory.SPELL), @@ -1109,7 +1156,8 @@ def from_data(player: int, data: DS3ItemData) -> Self: DS3ItemData("Iron Flesh", 0x40251430, DS3ItemCategory.SPELL), DS3ItemData("Flash Sweat", 0x40251818, DS3ItemCategory.SPELL), DS3ItemData("Carthus Flame Arc", 0x402527B8, DS3ItemCategory.SPELL), - DS3ItemData("Rapport", 0x40252BA0, DS3ItemCategory.SPELL), + DS3ItemData("Rapport", 0x40252BA0, DS3ItemCategory.SPELL, + classification = ItemClassification.useful), DS3ItemData("Power Within", 0x40253B40, DS3ItemCategory.SPELL), DS3ItemData("Great Chaos Fire Orb", 0x40256250, DS3ItemCategory.SPELL), DS3ItemData("Chaos Storm", 0x40256638, DS3ItemCategory.SPELL), @@ -1127,15 +1175,18 @@ def from_data(player: int, data: DS3ItemData) -> Self: DS3ItemData("Carthus Beacon", 0x40286F90, DS3ItemCategory.SPELL), DS3ItemData("Heal Aid", 0x403540D0, DS3ItemCategory.SPELL), DS3ItemData("Heal", 0x403567E0, DS3ItemCategory.SPELL), - DS3ItemData("Med Heal", 0x40356BC8, DS3ItemCategory.SPELL), + DS3ItemData("Med Heal", 0x40356BC8, DS3ItemCategory.SPELL, + classification = ItemClassification.useful), DS3ItemData("Great Heal", 0x40356FB0, DS3ItemCategory.SPELL), DS3ItemData("Soothing Sunlight", 0x40357398, DS3ItemCategory.SPELL), DS3ItemData("Replenishment", 0x40357780, DS3ItemCategory.SPELL), DS3ItemData("Bountiful Sunlight", 0x40357B68, DS3ItemCategory.SPELL), DS3ItemData("Bountiful Light", 0x40358338, DS3ItemCategory.SPELL), DS3ItemData("Caressing Tears", 0x40358720, DS3ItemCategory.SPELL), - DS3ItemData("Tears of Denial", 0x4035B600, DS3ItemCategory.SPELL), - DS3ItemData("Homeward", 0x4035B9E8, DS3ItemCategory.SPELL), + DS3ItemData("Tears of Denial", 0x4035B600, DS3ItemCategory.SPELL, + classification = ItemClassification.useful), + DS3ItemData("Homeward", 0x4035B9E8, DS3ItemCategory.SPELL, + classification = ItemClassification.useful), DS3ItemData("Force", 0x4035DD10, DS3ItemCategory.SPELL), DS3ItemData("Wrath of the Gods", 0x4035E0F8, DS3ItemCategory.SPELL), DS3ItemData("Emit Force", 0x4035E4E0, DS3ItemCategory.SPELL), @@ -1272,13 +1323,18 @@ def from_data(player: int, data: DS3ItemData) -> Self: DS3ItemData("Spear of the Church", 0x2000276A, DS3ItemCategory.SKIP), # Rings - DS3ItemData("Chloranthy Ring+3", 0x20004E2D, DS3ItemCategory.RING), - DS3ItemData("Havel's Ring+3", 0x20004E37, DS3ItemCategory.RING), - DS3ItemData("Ring of Favor+3", 0x20004E41, DS3ItemCategory.RING), - DS3ItemData("Ring of Steel Protection+3", 0x20004E4B, DS3ItemCategory.RING), + DS3ItemData("Chloranthy Ring+3", 0x20004E2D, DS3ItemCategory.RING, + classification = ItemClassification.useful), + DS3ItemData("Havel's Ring+3", 0x20004E37, DS3ItemCategory.RING, + classification = ItemClassification.useful), + DS3ItemData("Ring of Favor+3", 0x20004E41, DS3ItemCategory.RING, + classification = ItemClassification.useful), + DS3ItemData("Ring of Steel Protection+3", 0x20004E4B, DS3ItemCategory.RING, + classification = ItemClassification.useful), DS3ItemData("Wolf Ring+3", 0x20004EE1, DS3ItemCategory.RING), DS3ItemData("Covetous Gold Serpent Ring+3", 0x20004FA9, DS3ItemCategory.RING), - DS3ItemData("Covetous Silver Serpent Ring+3", 0x20004FB3, DS3ItemCategory.RING), + DS3ItemData("Covetous Silver Serpent Ring+3", 0x20004FB3, DS3ItemCategory.RING, + classification = ItemClassification.useful), DS3ItemData("Ring of the Evil Eye+3", 0x20005071, DS3ItemCategory.RING), DS3ItemData("Chillbite Ring", 0x20005208, DS3ItemCategory.RING), @@ -1292,9 +1348,12 @@ def from_data(player: int, data: DS3ItemData) -> Self: DS3ItemData("Soul of the Demon Prince", 0x400002EA, DS3ItemCategory.BOSS), DS3ItemData("Soul of Darkeater Midir", 0x400002EB, DS3ItemCategory.BOSS), DS3ItemData("Champion's Bones", 0x40000869, DS3ItemCategory.SKIP), - DS3ItemData("Captain's Ashes", 0x4000086A, DS3ItemCategory.MISC), - DS3ItemData("Contraption Key", 0x4000086B, DS3ItemCategory.KEY), - DS3ItemData("Small Envoy Banner", 0x4000086C, DS3ItemCategory.KEY), + DS3ItemData("Captain's Ashes", 0x4000086A, DS3ItemCategory.MISC, + classification = ItemClassification.progression), + DS3ItemData("Contraption Key", 0x4000086B, DS3ItemCategory.KEY, + classification = ItemClassification.progression), + DS3ItemData("Small Envoy Banner", 0x4000086C, DS3ItemCategory.KEY, + classification = ItemClassification.progression), DS3ItemData("Old Woman's Ashes", 0x4000086D, DS3ItemCategory.SKIP), DS3ItemData("Blood of the Dark Soul", 0x4000086E, DS3ItemCategory.SKIP), diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index e06eb27a8292..dc5bdec5481d 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -8,7 +8,7 @@ from worlds.AutoWorld import World, WebWorld from worlds.generic.Rules import set_rule, add_rule, add_item_rule -from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, item_dictionary, key_item_names +from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, UsefulIf, item_dictionary from .Locations import DarkSouls3Location, DS3LocationCategory, DS3LocationData, location_tables, location_dictionary, location_name_groups from .Options import RandomizeWeaponLevelOption, PoolTypeOption, dark_souls_options @@ -294,7 +294,7 @@ def create_random_replacement_list(item_categories: Set[DS3ItemCategory], num_it itempool.extend(self.create_item(name) for name in itempool_by_category[category]) # A list of items we can replace - removable_items = [item for item in itempool if item.classification != ItemClassification.progression] + removable_items = [item for item in itempool if item.classification == ItemClassification.filler] guaranteed_items = self.multiworld.guaranteed_items[self.player].value for item_name in guaranteed_items: @@ -350,8 +350,21 @@ def create_random_replacement_list(item_categories: Set[DS3ItemCategory], num_it def create_item(self, item: str|DS3ItemData) -> Item: - return DarkSouls3Item.from_data( - self.player, item if isinstance(item, DS3ItemData) else item_dictionary[item]) + data = item if isinstance(item, DS3ItemData) else item_dictionary[item] + if ( + data.useful_if == UsefulIf.BASE and + not self.multiworld.enable_dlc[self.player] and + not self.multiworld.enable_ngp[self.player] + ) or ( + data.useful_if == UsefulIf.NO_DLC and + not self.multiworld.enable_dlc[self.player] + ) or ( + data.useful_if == UsefulIf.NO_NGP and + not self.multiworld.enable_ngp[self.player] + ): + progression = ItemProgression.useful + + return DarkSouls3Item.from_data(self.player, data) def get_filler_item_name(self) -> str: From af4fa8bd8300df18170ccc96a0395874497ac322 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 28 Oct 2023 16:44:16 -0700 Subject: [PATCH 027/238] Add more variety to filler items --- worlds/dark_souls_3/Items.py | 117 +++++++++++++++++--------------- worlds/dark_souls_3/__init__.py | 4 +- 2 files changed, 63 insertions(+), 58 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index c4819f47583e..3340804b798d 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -79,6 +79,9 @@ class DS3ItemData(): useful_if: UsefulIf = UsefulIf.DEFAULT """Whether and when this item should be marked as "useful".""" + filler: bool = False + """Whether this is a candidate for a filler item to be added to fill out extra locations.""" + def __post_init__(self): self.ap_code = DS3ItemData.__item_id DS3ItemData.__item_id += 1 @@ -91,6 +94,7 @@ def counts(self, counts: List[int]) -> Generator[Self]: self, name = "{} x{}".format(self.name, count), count = count, + filler = False, # Don't count multiples as filler by default ) def __hash__(self): @@ -126,25 +130,28 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> Self: _vanilla_items = flatten([ # Ammunition - DS3ItemData("Standard Arrow x12", 0x00061A80, DS3ItemCategory.MISC).counts([12]), + DS3ItemData("Standard Arrow", 0x00061A80, DS3ItemCategory.MISC).counts([12]), + DS3ItemData("Standard Arrow x8", 0x00061A80, DS3ItemCategory.MISC, count = 8, filler = True), DS3ItemData("Fire Arrow", 0x00061AE4, DS3ItemCategory.MISC), - DS3ItemData("Poison Arrow x18", 0x00061B48, DS3ItemCategory.MISC).counts([18]), + DS3ItemData("Fire Arrow x8", 0x00061AE4, DS3ItemCategory.MISC, count = 8, filler = True), + DS3ItemData("Poison Arrow", 0x00061B48, DS3ItemCategory.MISC).counts([18]), + DS3ItemData("Poison Arrow x8", 0x00061B48, DS3ItemCategory.MISC, count = 8, filler = True), DS3ItemData("Large Arrow", 0x00061BAC, DS3ItemCategory.MISC), DS3ItemData("Feather Arrow", 0x00061C10, DS3ItemCategory.MISC), - DS3ItemData("Moonlight Arrow x6", 0x00061C74, DS3ItemCategory.MISC).counts([6]), + DS3ItemData("Moonlight Arrow", 0x00061C74, DS3ItemCategory.MISC).counts([6]), DS3ItemData("Wood Arrow", 0x00061CD8, DS3ItemCategory.MISC), DS3ItemData("Dark Arrow", 0x00061D3C, DS3ItemCategory.MISC), - DS3ItemData("Dragonslayer Greatarrow x5", 0x00062250, DS3ItemCategory.MISC).counts([5]), - DS3ItemData("Dragonslayer Lightning Arrow x10", 0x00062318, DS3ItemCategory.MISC).counts([10]), - DS3ItemData("Onislayer Greatarrow x8", 0x0006237C, DS3ItemCategory.MISC).counts([8]), + DS3ItemData("Dragonslayer Greatarrow", 0x00062250, DS3ItemCategory.MISC).counts([5]), + DS3ItemData("Dragonslayer Lightning Arrow", 0x00062318, DS3ItemCategory.MISC).counts([10]), + DS3ItemData("Onislayer Greatarrow", 0x0006237C, DS3ItemCategory.MISC).counts([8]), DS3ItemData("Standard Bolt", 0x00062A20, DS3ItemCategory.MISC), DS3ItemData("Heavy Bolt", 0x00062A84, DS3ItemCategory.MISC), - DS3ItemData("Sniper Bolt x11", 0x00062AE8, DS3ItemCategory.MISC).counts([11]), + DS3ItemData("Sniper Bolt", 0x00062AE8, DS3ItemCategory.MISC).counts([11]), DS3ItemData("Wood Bolt", 0x00062B4C, DS3ItemCategory.MISC), - DS3ItemData("Lightning Bolt x9", 0x00062BB0, DS3ItemCategory.MISC).counts([9]), - DS3ItemData("Lightning Bolt x12", 0x00062BB0, DS3ItemCategory.MISC).counts([12]), + DS3ItemData("Lightning Bolt", 0x00062BB0, DS3ItemCategory.MISC).counts([9]), + DS3ItemData("Lightning Bolt", 0x00062BB0, DS3ItemCategory.MISC).counts([12]), DS3ItemData("Splintering Bolt", 0x00062C14, DS3ItemCategory.MISC), - DS3ItemData("Exploding Bolt x6", 0x00062C78, DS3ItemCategory.MISC).counts([6]), + DS3ItemData("Exploding Bolt", 0x00062C78, DS3ItemCategory.MISC).counts([6]), # Weapons DS3ItemData("Dagger", 0x000F4240, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), @@ -783,7 +790,7 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> Self: DS3ItemData("Wolf Ring+1", 0x20004EDF, DS3ItemCategory.RING), DS3ItemData("Wolf Ring+2", 0x20004EE0, DS3ItemCategory.RING), DS3ItemData("Leo Ring", 0x20004EE8, DS3ItemCategory.RING), - DS3ItemData("Ring of Sacrifice", 0x20004EF2, DS3ItemCategory.RING), + DS3ItemData("Ring of Sacrifice", 0x20004EF2, DS3ItemCategory.RING, filler = True), DS3ItemData("Young Dragon Ring", 0x20004F06, DS3ItemCategory.RING), DS3ItemData("Bellowing Dragoncrest Ring", 0x20004F07, DS3ItemCategory.RING), DS3ItemData("Great Swamp Ring", 0x20004F10, DS3ItemCategory.RING), @@ -856,47 +863,44 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> Self: DS3ItemData("Red Sign Soapstone", 0x40000066, DS3ItemCategory.SKIP), DS3ItemData("Red Eye Orb", 0x40000066, DS3ItemCategory.SKIP), DS3ItemData("Roster of Knights", 0x4000006C, DS3ItemCategory.SKIP), - DS3ItemData("Cracked Red Eye Orb", 0x4000006F, DS3ItemCategory.SKIP), - DS3ItemData("Cracked Red Eye Orb x5", 0x4000006F, DS3ItemCategory.SKIP).counts([5]), + DS3ItemData("Cracked Red Eye Orb", 0x4000006F, DS3ItemCategory.SKIP).counts([5]), DS3ItemData("Black Eye Orb", 0x40000073, DS3ItemCategory.KEY), DS3ItemData("Divine Blessing", 0x400000F0, DS3ItemCategory.MISC), DS3ItemData("Hidden Blessing", 0x400000F1, DS3ItemCategory.MISC), - DS3ItemData("Green Blossom", 0x40000104, DS3ItemCategory.MISC), - DS3ItemData("Green Blossom x2", 0x40000104, DS3ItemCategory.MISC).counts([2]), - DS3ItemData("Green Blossom x3", 0x40000104, DS3ItemCategory.MISC).counts([3]), - DS3ItemData("Green Blossom x4", 0x40000104, DS3ItemCategory.MISC).counts([4]), - DS3ItemData("Budding Green Blossom", 0x40000106, DS3ItemCategory.MISC), - DS3ItemData("Budding Green Blossom x2", 0x40000106, DS3ItemCategory.MISC).counts([2]), - DS3ItemData("Budding Green Blossom x3", 0x40000106, DS3ItemCategory.MISC).counts([3]), - DS3ItemData("Bloodred Moss Clump", 0x4000010E, DS3ItemCategory.MISC), - DS3ItemData("Bloodred Moss Clump x3", 0x4000010E, DS3ItemCategory.MISC), - DS3ItemData("Purple Moss Clump", 0x4000010F, DS3ItemCategory.MISC).counts([2, 3, 4]), + DS3ItemData("Green Blossom", 0x40000104, DS3ItemCategory.MISC, filler = True).counts([2, 3, 4]), + DS3ItemData("Budding Green Blossom", 0x40000106, DS3ItemCategory.MISC).counts([2, 3]), + DS3ItemData("Bloodred Moss Clump", 0x4000010E, DS3ItemCategory.MISC, filler = True).counts([3]), + DS3ItemData("Purple Moss Clump", 0x4000010F, DS3ItemCategory.MISC, filler = True).counts([2, 3, 4]), DS3ItemData("Blooming Purple Moss Clump", 0x40000110, DS3ItemCategory.MISC).counts([3]), DS3ItemData("Purging Stone", 0x40000112, DS3ItemCategory.SKIP).counts([2, 3]), - DS3ItemData("Rime-blue Moss Clump", 0x40000114, DS3ItemCategory.MISC).counts([2, 4]), - DS3ItemData("Repair Powder", 0x40000118, DS3ItemCategory.MISC).counts([2, 3, 4]), + DS3ItemData("Rime-blue Moss Clump", 0x40000114, DS3ItemCategory.MISC, filler = True).counts([2, 4]), + DS3ItemData("Repair Powder", 0x40000118, DS3ItemCategory.MISC, filler = True).counts([2, 3, 4]), DS3ItemData("Kukri", 0x40000122, DS3ItemCategory.MISC).counts([8, 9]), - DS3ItemData("Firebomb", 0x40000124, DS3ItemCategory.MISC).counts([2, 3, 5, 6]), - DS3ItemData("Dung Pie", 0x40000125, DS3ItemCategory.MISC).counts([2, 3, 4]), - DS3ItemData("Alluring Skull", 0x40000126, DS3ItemCategory.MISC).counts([2, 3]), + DS3ItemData("Kukri x5", 0x40000122, DS3ItemCategory.MISC, count = 5, filler = True), + DS3ItemData("Firebomb", 0x40000124, DS3ItemCategory.MISC).counts([3, 5, 6]), + DS3ItemData("Firebomb x2", 0x40000124, DS3ItemCategory.MISC, count = 2, filler = True), + DS3ItemData("Dung Pie", 0x40000125, DS3ItemCategory.MISC).counts([2, 4]), + DS3ItemData("Dung Pie x3", 0x40000125, DS3ItemCategory.MISC, count = 3, filler = True), + DS3ItemData("Alluring Skull", 0x40000126, DS3ItemCategory.MISC, filler = True).counts([2, 3]), DS3ItemData("Undead Hunter Charm", 0x40000128, DS3ItemCategory.MISC).counts([2, 3]), - DS3ItemData("Black Firebomb", 0x40000129, DS3ItemCategory.MISC).counts([2, 3, 4]), + DS3ItemData("Black Firebomb", 0x40000129, DS3ItemCategory.MISC, filler = True).counts([2, 3, 4]), DS3ItemData("Rope Firebomb", 0x4000012B, DS3ItemCategory.MISC), - DS3ItemData("Lightning Urn", 0x4000012C, DS3ItemCategory.MISC).counts([3, 4, 6]), + DS3ItemData("Lightning Urn", 0x4000012C, DS3ItemCategory.MISC, filler = True).counts([3, 4, 6]), DS3ItemData("Rope Black Firebomb", 0x4000012E, DS3ItemCategory.MISC), DS3ItemData("Stalk Dung Pie", 0x4000012F, DS3ItemCategory.MISC).counts([6]), DS3ItemData("Duel Charm", 0x40000130, DS3ItemCategory.MISC).counts([3]), DS3ItemData("Throwing Knife", 0x40000136, DS3ItemCategory.MISC).counts([6, 8]), + DS3ItemData("Throwing Knife x5", 0x40000136, DS3ItemCategory.MISC, count = 5, filler = True), DS3ItemData("Poison Throwing Knife", 0x40000137, DS3ItemCategory.MISC), - DS3ItemData("Charcoal Pine Resin", 0x4000014A, DS3ItemCategory.MISC).counts([2]), - DS3ItemData("Gold Pine Resin", 0x4000014B, DS3ItemCategory.MISC).counts([2]), - DS3ItemData("Human Pine Resin", 0x4000014E, DS3ItemCategory.MISC).counts([2, 4]), - DS3ItemData("Carthus Rouge", 0x4000014F, DS3ItemCategory.MISC).counts([2, 3]), - DS3ItemData("Pale Pine Resin", 0x40000150, DS3ItemCategory.MISC).counts([2]), + DS3ItemData("Charcoal Pine Resin", 0x4000014A, DS3ItemCategory.MISC, filler = True).counts([2]), + DS3ItemData("Gold Pine Resin", 0x4000014B, DS3ItemCategory.MISC, filler = True).counts([2]), + DS3ItemData("Human Pine Resin", 0x4000014E, DS3ItemCategory.MISC, filler = True).counts([2, 4]), + DS3ItemData("Carthus Rouge", 0x4000014F, DS3ItemCategory.MISC, filler = True).counts([2, 3]), + DS3ItemData("Pale Pine Resin", 0x40000150, DS3ItemCategory.MISC, filler = True).counts([2]), DS3ItemData("Charcoal Pine Bundle", 0x40000154, DS3ItemCategory.MISC).counts([2]), DS3ItemData("Gold Pine Bundle", 0x40000155, DS3ItemCategory.MISC).counts([6]), DS3ItemData("Rotten Pine Resin", 0x40000157, DS3ItemCategory.MISC).counts([2, 4]), - DS3ItemData("Homeward Bone", 0x4000015E, DS3ItemCategory.MISC).counts([2, 3, 6]), + DS3ItemData("Homeward Bone", 0x4000015E, DS3ItemCategory.MISC, filler = True).counts([2, 3, 6]), DS3ItemData("Coiled Sword Fragment", 0x4000015F, DS3ItemCategory.MISC), DS3ItemData("Wolf's Blood Swordgrass", 0x4000016E, DS3ItemCategory.SKIP), DS3ItemData("Human Dregs", 0x4000016F, DS3ItemCategory.SKIP), @@ -917,20 +921,20 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> Self: DS3ItemData("Twinkling Dragon Head Stone", 0x40000183, DS3ItemCategory.MISC), DS3ItemData("Twinkling Dragon Torso Stone", 0x40000184, DS3ItemCategory.MISC), DS3ItemData("Fire Keeper Soul", 0x40000186, DS3ItemCategory.MISC), - DS3ItemData("Fading Soul", 0x40000190, DS3ItemCategory.MISC), - DS3ItemData("Soul of a Deserted Corpse", 0x40000191, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Fading Soul", 0x40000190, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Soul of a Deserted Corpse", 0x40000191, DS3ItemCategory.MISC, filler = True, soul = True), DS3ItemData("Large Soul of a Deserted Corpse", 0x40000192, DS3ItemCategory.MISC, soul = True), DS3ItemData("Soul of an Unknown Traveler", 0x40000193, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Large Soul of an Unknown Traveler", 0x40000194, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Large Soul of an Unknown Traveler", 0x40000194, DS3ItemCategory.MISC, filler = True, soul = True), DS3ItemData("Soul of a Nameless Soldier", 0x40000195, DS3ItemCategory.MISC, soul = True), DS3ItemData("Large Soul of a Nameless Soldier", 0x40000196, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Soul of a Weary Warrior", 0x40000197, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Soul of a Weary Warrior", 0x40000197, DS3ItemCategory.MISC, filler = True, soul = True), DS3ItemData("Large Soul of a Weary Warrior", 0x40000198, DS3ItemCategory.MISC, soul = True), DS3ItemData("Soul of a Crestfallen Knight", 0x40000199, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Large Soul of a Crestfallen Knight", 0x4000019A, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Large Soul of a Crestfallen Knight", 0x4000019A, DS3ItemCategory.MISC, filler = True, soul = True), DS3ItemData("Soul of a Proud Paladin", 0x4000019B, DS3ItemCategory.MISC, soul = True), DS3ItemData("Large Soul of a Proud Paladin", 0x4000019C, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Soul of an Intrepid Hero", 0x4000019D, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Soul of an Intrepid Hero", 0x4000019D, DS3ItemCategory.MISC, filler = True, soul = True), DS3ItemData("Large Soul of an Intrepid Hero", 0x4000019E, DS3ItemCategory.MISC, soul = True), DS3ItemData("Soul of a Seasoned Warrior", 0x4000019F, DS3ItemCategory.MISC, soul = True), DS3ItemData("Large Soul of a Seasoned Warrior", 0x400001A0, DS3ItemCategory.MISC, soul = True), @@ -940,18 +944,18 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> Self: DS3ItemData("Soul of a Great Champion", 0x400001A4, DS3ItemCategory.MISC, soul = True), DS3ItemData("Seed of a Giant Tree", 0x400001B8, DS3ItemCategory.SKIP, inject = True), - DS3ItemData("Mossfruit", 0x400001C4, DS3ItemCategory.SKIP).counts([2]), - DS3ItemData("Young White Branch", 0x400001C6, DS3ItemCategory.SKIP), - DS3ItemData("Rusted Coin", 0x400001C7, DS3ItemCategory.MISC).counts([2]), - DS3ItemData("Siegbräu", 0x400001C8, DS3ItemCategory.SKIP), - DS3ItemData("Rusted Gold Coin", 0x400001C9, DS3ItemCategory.MISC).counts([2, 3]), - DS3ItemData("Blue Bug Pellet", 0x400001CA, DS3ItemCategory.SKIP).counts([2]), - DS3ItemData("Red Bug Pellet", 0x400001CB, DS3ItemCategory.SKIP).counts([2, 3]), - DS3ItemData("Yellow Bug Pellet", 0x400001CC, DS3ItemCategory.SKIP).counts([2, 3]), - DS3ItemData("Black Bug Pellet", 0x400001CD, DS3ItemCategory.SKIP).counts([2, 3]), + DS3ItemData("Mossfruit", 0x400001C4, DS3ItemCategory.MISC, filler = True).counts([2]), + DS3ItemData("Young White Branch", 0x400001C6, DS3ItemCategory.MISC), + DS3ItemData("Rusted Coin", 0x400001C7, DS3ItemCategory.MISC, filler = True).counts([2]), + DS3ItemData("Siegbräu", 0x400001C8, DS3ItemCategory.MISC), + DS3ItemData("Rusted Gold Coin", 0x400001C9, DS3ItemCategory.MISC, filler = True).counts([2, 3]), + DS3ItemData("Blue Bug Pellet", 0x400001CA, DS3ItemCategory.MISC, filler = True).counts([2]), + DS3ItemData("Red Bug Pellet", 0x400001CB, DS3ItemCategory.MISC, filler = True).counts([2, 3]), + DS3ItemData("Yellow Bug Pellet", 0x400001CC, DS3ItemCategory.MISC, filler = True).counts([2, 3]), + DS3ItemData("Black Bug Pellet", 0x400001CD, DS3ItemCategory.MISC, filler = True).counts([2, 3]), DS3ItemData("Young White Branch", 0x400001CF, DS3ItemCategory.SKIP), DS3ItemData("Dark Sigil", 0x400001EA, DS3ItemCategory.SKIP), - DS3ItemData("Ember", 0x400001F4, DS3ItemCategory.MISC).counts([2]), + DS3ItemData("Ember", 0x400001F4, DS3ItemCategory.MISC, filler = True).counts([2]), DS3ItemData("Hello Carving", 0x40000208, DS3ItemCategory.SKIP), DS3ItemData("Thank you Carving", 0x40000209, DS3ItemCategory.SKIP), DS3ItemData("Very good! Carving", 0x4000020A, DS3ItemCategory.SKIP), @@ -1343,10 +1347,10 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> Self: DS3ItemData("Filianore's Spear Ornament", 0x4000017B, DS3ItemCategory.SKIP), DS3ItemData("Ritual Spear Fragment", 0x4000028A, DS3ItemCategory.SKIP), DS3ItemData("Divine Spear Fragment", 0x4000028B, DS3ItemCategory.SKIP), - DS3ItemData("Soul of Sister Friede", 0x400002E8, DS3ItemCategory.BOSS), - DS3ItemData("Soul of Slave Knight Gael", 0x400002E9, DS3ItemCategory.BOSS), - DS3ItemData("Soul of the Demon Prince", 0x400002EA, DS3ItemCategory.BOSS), - DS3ItemData("Soul of Darkeater Midir", 0x400002EB, DS3ItemCategory.BOSS), + DS3ItemData("Soul of Sister Friede", 0x400002E8, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of Slave Knight Gael", 0x400002E9, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of the Demon Prince", 0x400002EA, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of Darkeater Midir", 0x400002EB, DS3ItemCategory.BOSS, soul = True), DS3ItemData("Champion's Bones", 0x40000869, DS3ItemCategory.SKIP), DS3ItemData("Captain's Ashes", 0x4000086A, DS3ItemCategory.MISC, classification = ItemClassification.progression), @@ -1455,4 +1459,5 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> Self: _all_items = _vanilla_items + _dlc_items +filler_item_names = [item_data.name for item_data in _all_items if item_data.filler] item_dictionary = {item_data.name: item_data for item_data in _all_items} diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index dc5bdec5481d..92b0e394746c 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -8,7 +8,7 @@ from worlds.AutoWorld import World, WebWorld from worlds.generic.Rules import set_rule, add_rule, add_item_rule -from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, UsefulIf, item_dictionary +from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, UsefulIf, filler_item_names, item_dictionary from .Locations import DarkSouls3Location, DS3LocationCategory, DS3LocationData, location_tables, location_dictionary, location_name_groups from .Options import RandomizeWeaponLevelOption, PoolTypeOption, dark_souls_options @@ -368,7 +368,7 @@ def create_item(self, item: str|DS3ItemData) -> Item: def get_filler_item_name(self) -> str: - return "Soul of an Intrepid Hero" + return self.multiworld.random.choice(filler_item_names) def set_rules(self) -> None: From 1039d7be84c9f36dac276678ff9bc2d47b9c0076 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 28 Oct 2023 21:34:08 -0700 Subject: [PATCH 028/238] Iron out a few bugs and incompatibilities --- worlds/dark_souls_3/Items.py | 10 ++++------ worlds/dark_souls_3/Locations.py | 20 ++++++++++---------- worlds/dark_souls_3/__init__.py | 17 +++++++++-------- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 3340804b798d..74e539b61a50 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -1,9 +1,7 @@ -from collections.abc import Generator from dataclasses import dataclass, field import dataclasses from enum import IntEnum -import itertools -from typing import ClassVar, List, NamedTuple, Optional, Self, TypeVar +from typing import ClassVar, Generator, List, Optional from BaseClasses import Item, ItemClassification from Utils import flatten @@ -86,7 +84,7 @@ def __post_init__(self): self.ap_code = DS3ItemData.__item_id DS3ItemData.__item_id += 1 - def counts(self, counts: List[int]) -> Generator[Self]: + def counts(self, counts: List[int]) -> Generator["DS3ItemData", None, None]: """Returns an iterable of copies of this item with the given counts.""" yield self for count in counts: @@ -118,7 +116,7 @@ def __init__( super().__init__(name, classification, code, player) @staticmethod - def from_data(player: int, data: DS3ItemData, classification = None) -> Self: + def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSouls3Item": item = DarkSouls3Item( data.name, classification or data.classification, @@ -1233,7 +1231,7 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> Self: DS3ItemData("Follower Sabre", 0x003EDDC0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), DS3ItemData("Demon's Scar", 0x003F04D0, DS3ItemCategory.WEAPON_UPGRADE_5), DS3ItemData("Frayed Blade", 0x004D35A0, DS3ItemCategory.WEAPON_UPGRADE_5), - DS3ItemData("Herald Curved Greatsword", 0x006159E0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Harald Curved Greatsword", 0x006159E0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), DS3ItemData("Millwood Battle Axe", 0x006D67D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), DS3ItemData("Earth Seeker", 0x006D8EE0, DS3ItemCategory.WEAPON_UPGRADE_5), DS3ItemData("Quakestone Hammer", 0x007ECCF0, DS3ItemCategory.WEAPON_UPGRADE_5), diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 761acdcd23c8..47dd5c5ee7c0 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1,5 +1,5 @@ from enum import IntEnum -from typing import Optional, Dict, Self, Set +from typing import Optional, Dict, List, Set from dataclasses import dataclass from BaseClasses import Location, LocationProgressType, Region @@ -129,7 +129,7 @@ class DS3LocationData: for an illusory wall or one random mob with a guaranteed drop. """ - def location_groups(self): + def location_groups(self) -> List[str]: """The names of location groups this location should appear in. This is computed from the properties assigned to this location.""" @@ -150,7 +150,7 @@ class DarkSouls3Location(Location): game: str = "Dark Souls III" category: DS3LocationCategory default_item_name: str - offline: Optional[str] + offline: Optional[str] = None def __init__( self, @@ -169,7 +169,7 @@ def from_data( player: int, data: DS3LocationData, address: Optional[int] = None, - parent: Optional[Region] = None) -> Self: + parent: Optional[Region] = None) -> "DarkSouls3Location": location = DarkSouls3Location( player, data.name, @@ -327,7 +327,7 @@ def get_name_to_id() -> dict: shop = True), # Dragon Chaser's Ashes DS3LocationData("FS: Ember (Dragon Chaser)", "Ember", DS3LocationCategory.MISC, - offline = '99,3:-1:110000,70000108:', shop = True), + offline = '99,0:-1:110000,70000108:', shop = True), # Easterner's Ashes DS3LocationData("FS: Washing Pole", "Washing Pole", DS3LocationCategory.WEAPON, shop = True), @@ -1641,9 +1641,9 @@ def get_name_to_id() -> dict: DS3LocationData("AL: Deep Gem", "Deep Gem", DS3LocationCategory.UPGRADE), DS3LocationData("AL: Titanite Scale", "Titanite Scale", DS3LocationCategory.UPGRADE), DS3LocationData("AL: Dragonslayer Greatarrow", "Dragonslayer Greatarrow x5", DS3LocationCategory.MISC, - hidden = True), # Hidden fall + offline = '06,0:53700620::', hidden = True), # Hidden fall DS3LocationData("AL: Dragonslayer Greatbow", "Dragonslayer Greatbow", DS3LocationCategory.WEAPON, - hidden = True), # Hidden fall + offline = '06,0:53700620::', hidden = True), # Hidden fall DS3LocationData("AL: Easterner's Ashes", "Easterner's Ashes", DS3LocationCategory.KEY, progression = True), DS3LocationData("AL: Painting Guardian Hood", "Painting Guardian Hood", DS3LocationCategory.ARMOR, @@ -2243,7 +2243,7 @@ def get_name_to_id() -> dict: # Shrine Handmaid after placing all Cinders of a Lord DS3LocationData("KFF: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE, - hidden = True), + offline = '99,0:-1:9210,110000:', hidden = True), DS3LocationData("KFF: Firelink Helm", "Firelink Helm", DS3LocationCategory.ARMOR, missable = True), DS3LocationData("KFF: Firelink Armor", "Firelink Armor", DS3LocationCategory.ARMOR, @@ -2344,7 +2344,7 @@ def get_name_to_id() -> dict: DS3LocationData("PW1: Large Titanite Shard #3", "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, lizard = True), DS3LocationData("PW2: Champion's Bones", "Champion's Bones", DS3LocationCategory.MISC, - boss = True), + offline = '11,0:50002310::', boss = True), ], "Painted World of Ariandel (After Contraption)": [ DS3LocationData("PW2: Soul of Sister Friede", "Soul of Sister Friede", DS3LocationCategory.BOSS, @@ -2445,7 +2445,7 @@ def get_name_to_id() -> dict: DS3LocationData("DH: Loincloth", "Loincloth", DS3LocationCategory.ARMOR), DS3LocationData("DH: Titanite Chunk #8", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("DH: Large Soul of a Weary Warrior #3", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), - DS3LocationData("DH: Herald Curved Greatsword", "Herald Curved Greatsword", DS3LocationCategory.WEAPON), + DS3LocationData("DH: Harald Curved Greatsword", "Harald Curved Greatsword", DS3LocationCategory.WEAPON), DS3LocationData("DH: Homeward Bone #2", "Homeward Bone", DS3LocationCategory.MISC), DS3LocationData("DH: Prism Stone", "Prism Stone x6", DS3LocationCategory.MISC), DS3LocationData("DH: Desert Pyromancer Hood", "Desert Pyromancer Hood", DS3LocationCategory.ARMOR), diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 92b0e394746c..332b3644f46b 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -1,5 +1,5 @@ # world/dark_souls_3/__init__.py -from typing import Dict, Set, List +from typing import Dict, Set, List, Union import re from BaseClasses import MultiWorld, Region, Item, Entrance, Tutorial, ItemClassification @@ -349,7 +349,7 @@ def create_random_replacement_list(item_categories: Set[DS3ItemCategory], num_it self.multiworld.itempool += itempool - def create_item(self, item: str|DS3ItemData) -> Item: + def create_item(self, item: Union[str, DS3ItemData]) -> Item: data = item if isinstance(item, DS3ItemData) else item_dictionary[item] if ( data.useful_if == UsefulIf.BASE and @@ -517,7 +517,7 @@ def set_rules(self) -> None: state.has("Cinders of a Lord - Lothric Prince", self.player) - def __is_location_available(self, location: str|DS3LocationData): + def __is_location_available(self, location: Union[str, DS3LocationData]): """Returns whether the given location is being randomized.""" if isinstance(location, DS3LocationData): data = location @@ -578,13 +578,14 @@ def fill_slot_data(self) -> Dict[str, object]: ap_ids_to_ds3_ids[str(item.code)] = name_to_ds3_code[item.name] if item.count != 1: item_counts[str(item.code)] = item.count - # A map from Archipelago's location names to the keys the offline + # A map from Archipelago's location IDs to the keys the offline # randomizer uses to identify locations. - location_names_to_keys: Dict[str, str] = {} + location_ids_to_keys: Dict[str, str] = {} for location in self.multiworld.get_filled_locations(): # Skip events and only look at this world's locations - if location.item.code is not None and location.player == self.player and location.offline: - location_names_to_keys[location.name] = location.offline + if (location.address is not None and location.item.code is not None + and location.player == self.player and location.offline): + location_ids_to_keys[location.address] = location.offline slot_data = { "options": { @@ -612,7 +613,7 @@ def fill_slot_data(self) -> Dict[str, object]: "slot": self.multiworld.player_name[self.player], # to connect to server "apIdsToItemIds": ap_ids_to_ds3_ids, "itemCounts": item_counts, - "locationNamesToKeys": location_names_to_keys, + "locationIdsToKeys": location_ids_to_keys, } return slot_data From 6774be8b902aff14ece404350d817545483d04ed Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 28 Oct 2023 23:32:06 -0700 Subject: [PATCH 029/238] Fix more silly bugs --- worlds/dark_souls_3/Items.py | 3 ++- worlds/dark_souls_3/Locations.py | 8 +++---- worlds/dark_souls_3/__init__.py | 37 ++++++++++++++++++-------------- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 74e539b61a50..3f715d5303f0 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -917,7 +917,8 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou DS3ItemData("Rubbish", 0x4000017C, DS3ItemCategory.SKIP), DS3ItemData("Dried Finger", 0x40000181, DS3ItemCategory.SKIP), DS3ItemData("Twinkling Dragon Head Stone", 0x40000183, DS3ItemCategory.MISC), - DS3ItemData("Twinkling Dragon Torso Stone", 0x40000184, DS3ItemCategory.MISC), + DS3ItemData("Twinkling Dragon Torso Stone", 0x40000184, DS3ItemCategory.MISC, + classification = ItemClassification.progression), DS3ItemData("Fire Keeper Soul", 0x40000186, DS3ItemCategory.MISC), DS3ItemData("Fading Soul", 0x40000190, DS3ItemCategory.MISC, soul = True), DS3ItemData("Soul of a Deserted Corpse", 0x40000191, DS3ItemCategory.MISC, filler = True, soul = True), diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 47dd5c5ee7c0..e50b1d257d1a 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1599,7 +1599,7 @@ def get_name_to_id() -> dict: missable = True, boss = True, shop = True), # Siegward drops (kill or quest) - DS3LocationData("PC: Storm Ruler", "Storm Ruler", DS3LocationCategory.WEAPON, + DS3LocationData("PC: Storm Ruler (Siegward)", "Storm Ruler", DS3LocationCategory.WEAPON, offline = '02,0:50006218::', missable = True, npc = True), DS3LocationData("PC: Pierce Shield", "Pierce Shield", DS3LocationCategory.SHIELD, missable = True, npc = True), @@ -2349,8 +2349,8 @@ def get_name_to_id() -> dict: "Painted World of Ariandel (After Contraption)": [ DS3LocationData("PW2: Soul of Sister Friede", "Soul of Sister Friede", DS3LocationCategory.BOSS, prominent = True, boss = True), - DS3LocationData("PW2: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE, - boss = True), # One-time drop after Friede Phase 2 + DS3LocationData("PW2: Titanite Slab (Friede)", "Titanite Slab", DS3LocationCategory.UPGRADE, + offline = '11,0:50004700::', boss = True), # One-time drop after Friede Phase 2 DS3LocationData("PW2: Floating Chaos", "Floating Chaos", DS3LocationCategory.SPELL, missable = True, hostile_npc = True), # Livid Pyromancer Dunnel drop (requires ember) DS3LocationData("PW2: Prism Stone", "Prism Stone x10", DS3LocationCategory.MISC), @@ -2383,7 +2383,7 @@ def get_name_to_id() -> dict: missable = True, boss = True, shop = True), DS3LocationData("PW2: Rose of Ariandel", "Rose of Ariandel", DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), - DS3LocationData("PW2: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE, + DS3LocationData("PW2: Titanite Slab (Corvian)", "Titanite Slab", DS3LocationCategory.UPGRADE, offline = '11,0:50006540::', missable = True, npc = True), # Corvian Settler (quest) # Shrine Handmaid after killing Sister Friede diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 332b3644f46b..65d51b83b1ee 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -232,22 +232,24 @@ def create_items(self): # Gather all default items on randomized locations num_required_extra_items = 0 - for location in self.multiworld.get_locations(self.player): - if self.__is_location_available(location.name): - item_category = item_dictionary[location.default_item_name].category - if item_category == DS3ItemCategory.SKIP: + for location in self.multiworld.get_unfilled_locations(self.player): + if not self.__is_location_available(location.name): + raise Exception("DS3 generation bug: Added an unavailable location.") + + item_category = item_dictionary[location.default_item_name].category + if item_category == DS3ItemCategory.SKIP: + num_required_extra_items += 1 + elif item_category == DS3ItemCategory.MISC: + itempool_by_category[location.category].append(location.default_item_name) + else: + # For non-miscellaneous non-skip items, make sure there aren't duplicates in the + # item set even if there are multiple in-game locations that provide them. + item_set = item_set_by_category[location.category] + if location.default_item_name in item_set: num_required_extra_items += 1 - elif item_category == DS3ItemCategory.MISC: - itempool_by_category[location.category].append(location.default_item_name) else: - # For non-miscellaneous non-skip items, make sure there aren't duplicates in the - # item set even if there are multiple in-game locations that provide them. - item_set = item_set_by_category[location.category] - if location.default_item_name in item_set: - num_required_extra_items += 1 - else: - item_set.add(location.default_item_name) - itempool_by_category[location.category].append(location.default_item_name) + item_set.add(location.default_item_name) + itempool_by_category[location.category].append(location.default_item_name) # Replace each item category with a random sample of items of those types if self.multiworld.pool_type[self.player] == PoolTypeOption.option_various: @@ -478,7 +480,7 @@ def set_rules(self) -> None: if self.multiworld.enable_misc_locations[self.player] == Toggle.option_true: set_rule(self.multiworld.get_location("AP: Hawkwood's Swordgrass", self.player), - lambda state: state.has("AP: Twinkling Dragon Torso Stone", self.player)) + lambda state: state.has("Twinkling Dragon Torso Stone", self.player)) set_rule(self.multiworld.get_location("ID: Prisoner Chief's Ashes", self.player), lambda state: state.has("Jailer's Key Ring", self.player)) @@ -508,7 +510,10 @@ def set_rules(self) -> None: for location in location_dictionary.values(): if location.shop and self.__is_location_available(location): add_item_rule(self.multiworld.get_location(location.name, self.player), - lambda item: item.count == 1 and not item.soul) + lambda item: ( + item.player != self.player or + (item.count == 1 and not item.soul) + )) self.multiworld.completion_condition[self.player] = lambda state: \ state.has("Cinders of a Lord - Abyss Watcher", self.player) and \ From 288526a5d1bc6514190792d619da8268d51560d3 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 28 Oct 2023 23:55:55 -0700 Subject: [PATCH 030/238] Get tests passing --- worlds/dark_souls_3/__init__.py | 10 ++++++---- worlds/dark_souls_3/test/TestDarkSouls3.py | 11 ++++++----- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 65d51b83b1ee..3e74f3848985 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -353,7 +353,8 @@ def create_random_replacement_list(item_categories: Set[DS3ItemCategory], num_it def create_item(self, item: Union[str, DS3ItemData]) -> Item: data = item if isinstance(item, DS3ItemData) else item_dictionary[item] - if ( + classification = None + if self.multiworld and (( data.useful_if == UsefulIf.BASE and not self.multiworld.enable_dlc[self.player] and not self.multiworld.enable_ngp[self.player] @@ -363,10 +364,11 @@ def create_item(self, item: Union[str, DS3ItemData]) -> Item: ) or ( data.useful_if == UsefulIf.NO_NGP and not self.multiworld.enable_ngp[self.player] - ): - progression = ItemProgression.useful + )): + classification = ItemClassification.useful - return DarkSouls3Item.from_data(self.player, data) + return DarkSouls3Item.from_data( + self.player, data, classification=classification) def get_filler_item_name(self) -> str: diff --git a/worlds/dark_souls_3/test/TestDarkSouls3.py b/worlds/dark_souls_3/test/TestDarkSouls3.py index b491e64ac84e..8fba4d7be0a1 100644 --- a/worlds/dark_souls_3/test/TestDarkSouls3.py +++ b/worlds/dark_souls_3/test/TestDarkSouls3.py @@ -1,11 +1,12 @@ -import unittest +from test.TestBase import WorldTestBase -from worlds.dark_souls_3.Items import DarkSouls3Item +from worlds.dark_souls_3.Items import item_dictionary from worlds.dark_souls_3.Locations import location_tables -class DarkSouls3Test(unittest.TestCase): +class DarkSouls3Test(WorldTestBase): + game = "Dark Souls III" + def testLocationDefaultItems(self): - item_name_to_id = DarkSouls3Item.get_name_to_id() for locations in location_tables.values(): for location in locations: - self.assertIn(location.default_item_name, item_name_to_id) + self.assertIn(location.default_item_name, item_dictionary) From 834854f293bfe957fcef4e881dd3c6ef38200ba4 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 29 Oct 2023 13:34:38 -0700 Subject: [PATCH 031/238] Update options to cover new item types Also recategorize some items. --- worlds/dark_souls_3/Items.py | 14 ++- worlds/dark_souls_3/Locations.py | 168 +++++++++++++++++-------------- worlds/dark_souls_3/Options.py | 162 +++++++++++++++++------------ worlds/dark_souls_3/__init__.py | 26 +++-- 4 files changed, 220 insertions(+), 150 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 3f715d5303f0..29a87f317b7f 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -80,6 +80,12 @@ class DS3ItemData(): filler: bool = False """Whether this is a candidate for a filler item to be added to fill out extra locations.""" + force_unique: bool = False + """Whether to ensure only one copy of this item appears in the run. + + This is automatically done for non-MISC items, but may be useful for MISC items in some cases. + """ + def __post_init__(self): self.ap_code = DS3ItemData.__item_id DS3ItemData.__item_id += 1 @@ -907,10 +913,10 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou DS3ItemData("Prism Stone", 0x40000172, DS3ItemCategory.SKIP).counts([4, 6, 10]), DS3ItemData("Binoculars", 0x40000173, DS3ItemCategory.MISC), DS3ItemData("Proof of a Concord Kept", 0x40000174, DS3ItemCategory.SKIP), - DS3ItemData("Pale Tongue", 0x40000175, DS3ItemCategory.SKIP, - classification = ItemClassification.useful, inject = True), # Inject one of these for Leonhard's quest - DS3ItemData("Vertebra Shackle", 0x40000176, DS3ItemCategory.SKIP, - inject = True), # Inject one of these to trade to the crow + DS3ItemData("Pale Tongue", 0x40000175, DS3ItemCategory.MISC, + force_unique = True), # One is needed for Leonhard's quest + DS3ItemData("Vertebra Shackle", 0x40000176, DS3ItemCategory.MISC, + force_unique = True), # Allow one of these to trade to the crow DS3ItemData("Sunlight Medal", 0x40000177, DS3ItemCategory.SKIP), DS3ItemData("Dragon Head Stone", 0x40000179, DS3ItemCategory.MISC), DS3ItemData("Dragon Torso Stone", 0x4000017A, DS3ItemCategory.MISC), diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index e50b1d257d1a..4cc0c8ec4efb 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -18,9 +18,15 @@ class DS3LocationCategory(IntEnum): EVENT = 9 UPGRADE = 10 - """Any upgrade material. + """The original location of any upgrade material. - This includes various forms of titanite as well as infusion gems and shriving stones. + This includes various forms of titanite as well as infusion gems and Shriving Stones. + """ + + UNIQUE = 11 + """The original location of a unique item that's not a key, equipment, spell, or boss soul. + + This includes spellbooks, covenants, multiplayer items, coals, and various quest items. """ @@ -142,6 +148,8 @@ def location_groups(self) -> List[str]: if self.hostile_npc: names.append("Hostile NPC Rewards") if self.lizard: names.append("Small Crystal Lizards") if self.key: names.append("Keys") + if self.category == DS3LocationCategory.UPGRADE: names.append("Upgrade") + if self.category == DS3LocationCategory.MISC: names.append("Miscellaneous") if self.hidden: names.append("Hidden") return names @@ -271,15 +279,15 @@ def get_name_to_id() -> dict: DS3LocationData("FS: Ember #2", "Ember", DS3LocationCategory.MISC), DS3LocationData("FS: Wolf Ring+2", "Wolf Ring+2", DS3LocationCategory.RING, ngp = True), - DS3LocationData("FS: Cracked Red Eye Orb", "Cracked Red Eye Orb x5", DS3LocationCategory.MISC, + DS3LocationData("FS: Cracked Red Eye Orb", "Cracked Red Eye Orb x5", DS3LocationCategory.UNIQUE, missable = True, npc = True), # Leonhard (quest) DS3LocationData("FS: Lift Chamber Key", "Lift Chamber Key", DS3LocationCategory.KEY, - progression = True, npc = True, key = True), # Leonhard (kill or quest, after giving Pale Tongue and lighting Cliff Underside or killing Greatwood) + progression = True, npc = True, key = True), # Leonhard (kill or quest) # Shrine Handmaid shop - DS3LocationData("FS: White Sign Soapstone", "White Sign Soapstone", DS3LocationCategory.MISC, + DS3LocationData("FS: White Sign Soapstone", "White Sign Soapstone", DS3LocationCategory.UNIQUE, shop = True), - DS3LocationData("FS: Dried Finger", "Dried Finger", DS3LocationCategory.MISC, + DS3LocationData("FS: Dried Finger", "Dried Finger", DS3LocationCategory.UNIQUE, shop = True), DS3LocationData("FS: Tower Key", "Tower Key", DS3LocationCategory.KEY, progression = True, shop = True, key = True), @@ -296,7 +304,7 @@ def get_name_to_id() -> dict: shop = True), DS3LocationData("FS: Ember (Mortician)" , "Ember", DS3LocationCategory.MISC, offline = '99,0:-1:110000,70000100:', shop = True), - DS3LocationData("FS: Grave Key", "Grave Key", DS3LocationCategory.MISC, + DS3LocationData("FS: Grave Key", "Grave Key", DS3LocationCategory.KEY, shop = True, key = True), # Dreamchaser's Ashes DS3LocationData("FS: Life Ring", "Life Ring", DS3LocationCategory.RING, @@ -358,7 +366,7 @@ def get_name_to_id() -> dict: DS3LocationData("FSBT: Homeward Bone", "Homeward Bone x3", DS3LocationCategory.MISC), DS3LocationData("FSBT: Estus Ring", "Estus Ring", DS3LocationCategory.RING), DS3LocationData("FSBT: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), - DS3LocationData("FSBT: Fire Keeper Soul", "Fire Keeper Soul", DS3LocationCategory.MISC), + DS3LocationData("FSBT: Fire Keeper Soul", "Fire Keeper Soul", DS3LocationCategory.UNIQUE), DS3LocationData("FSBT: Fire Keeper Robe", "Fire Keeper Robe", DS3LocationCategory.ARMOR), DS3LocationData("FSBT: Fire Keeper Gloves", "Fire Keeper Gloves", DS3LocationCategory.ARMOR), DS3LocationData("FSBT: Fire Keeper Skirt", "Fire Keeper Skirt", DS3LocationCategory.ARMOR), @@ -377,11 +385,11 @@ def get_name_to_id() -> dict: missable = True), DS3LocationData("FSBT: Lucatiel's Mask", "Lucatiel's Mask", DS3LocationCategory.ARMOR, missable = True), - DS3LocationData("FSBT: Very good! Carving", "Very good! Carving", DS3LocationCategory.MISC, + DS3LocationData("FSBT: Very good! Carving", "Very good! Carving", DS3LocationCategory.UNIQUE, missable = True), - DS3LocationData("FSBT: Thank you Carving", "Thank you Carving", DS3LocationCategory.MISC, + DS3LocationData("FSBT: Thank you Carving", "Thank you Carving", DS3LocationCategory.UNIQUE, missable = True), - DS3LocationData("FSBT: I'm sorry Carving", "I'm sorry Carving", DS3LocationCategory.MISC, + DS3LocationData("FSBT: I'm sorry Carving", "I'm sorry Carving", DS3LocationCategory.UNIQUE, missable = True), DS3LocationData("FSBT: Sunlight Shield", "Sunlight Shield", DS3LocationCategory.SHIELD, missable = True), @@ -389,11 +397,11 @@ def get_name_to_id() -> dict: missable = True), DS3LocationData("FSBT: Titanite Scale #1", "Titanite Scale x3", DS3LocationCategory.UPGRADE, missable = True), - DS3LocationData("FSBT: Help me! Carving", "Help me! Carving", DS3LocationCategory.MISC, + DS3LocationData("FSBT: Help me! Carving", "Help me! Carving", DS3LocationCategory.UNIQUE, missable = True), DS3LocationData("FSBT: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE, missable = True), - DS3LocationData("FSBT: Hello Carving", "Hello Carving", DS3LocationCategory.MISC, + DS3LocationData("FSBT: Hello Carving", "Hello Carving", DS3LocationCategory.UNIQUE, missable = True), DS3LocationData("FSBT: Armor of the Sun", "Armor of the Sun", DS3LocationCategory.ARMOR, missable = True), @@ -460,7 +468,7 @@ def get_name_to_id() -> dict: DS3LocationData("HWL: Ember #3", "Ember", DS3LocationCategory.MISC), DS3LocationData("HWL: Large Soul of a Deserted Corpse #3", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC, hidden = True), # Easily missed turnoff - DS3LocationData("HWL: Binoculars", "Binoculars", DS3LocationCategory.MISC), + DS3LocationData("HWL: Binoculars", "Binoculars", DS3LocationCategory.UNIQUE), DS3LocationData("HWL: Ring of Sacrifice", "Ring of Sacrifice", DS3LocationCategory.MISC, hidden = True), # Easily missed turnoff DS3LocationData("HWL: Throwing Knife #2", "Throwing Knife x6", DS3LocationCategory.MISC), @@ -493,7 +501,7 @@ def get_name_to_id() -> dict: # because it requires range and is a crazy thing to do DS3LocationData("HWL: Refined Gem", "Refined Gem", DS3LocationCategory.UPGRADE, miniboss = True), # Red-Eyed Lothric Knight drop - DS3LocationData("HWL: Way of Blue", "Way of Blue", DS3LocationCategory.MISC), + DS3LocationData("HWL: Way of Blue", "Way of Blue", DS3LocationCategory.UNIQUE), DS3LocationData("HWL: Raw Gem", "Raw Gem", DS3LocationCategory.UPGRADE, lizard = True), DS3LocationData("HWL: Red Eye Orb", "Red Eye Orb", DS3LocationCategory.MISC, @@ -506,24 +514,20 @@ def get_name_to_id() -> dict: "Undead Settlement": [ DS3LocationData("US: Soul of the Rotted Greatwood", "Soul of the Rotted Greatwood", DS3LocationCategory.BOSS, prominent = True, boss = True), - DS3LocationData("US: Transposing Kiln", "Transposing Kiln", DS3LocationCategory.MISC, + DS3LocationData("US: Transposing Kiln", "Transposing Kiln", DS3LocationCategory.UNIQUE, boss = True), DS3LocationData("US: Pyromancy Flame", "Pyromancy Flame", DS3LocationCategory.WEAPON, missable = True, npc = True), DS3LocationData("US: Old Sage's Blindfold", "Old Sage's Blindfold", DS3LocationCategory.ARMOR, missable = True, npc = True), DS3LocationData("US: Cornyx's Garb", "Cornyx's Garb", DS3LocationCategory.ARMOR, - missable = True, npc = True), + offline = '02,0:50006141::', missable = True, npc = True), DS3LocationData("US: Cornyx's Wrap", "Cornyx's Wrap", DS3LocationCategory.ARMOR, - missable = True, npc = True), + offline = '02,0:50006141::', missable = True, npc = True), DS3LocationData("US: Cornyx's Skirt", "Cornyx's Skirt", DS3LocationCategory.ARMOR, - missable = True, npc = True), + offline = '02,0:50006141::', missable = True, npc = True), DS3LocationData("US: Tower Key", "Tower Key", DS3LocationCategory.KEY, missable = True, npc = True, key = True), - DS3LocationData("US: Morne's Great Hammer", "Morne's Great Hammer", DS3LocationCategory.WEAPON, - npc = True), # Eygon (kill or quest) - DS3LocationData("US: Moaning Shield", "Moaning Shield", DS3LocationCategory.SHIELD, - npc = True), # Eygon (kill or quest) DS3LocationData("US: Hawk Ring", "Hawk Ring", DS3LocationCategory.RING, npc = True), # Giant archer (kill or quest) DS3LocationData("US: Flynn's Ring", "Flynn's Ring", DS3LocationCategory.RING), @@ -627,9 +631,9 @@ def get_name_to_id() -> dict: miniboss = True), # Boreal Outrider drop DS3LocationData("US: Fire Gem", "Fire Gem", DS3LocationCategory.UPGRADE, miniboss = True), # Fire Demon drop - DS3LocationData("US: Warrior of Sunlight", "Warrior of Sunlight", DS3LocationCategory.MISC, + DS3LocationData("US: Warrior of Sunlight", "Warrior of Sunlight", DS3LocationCategory.UNIQUE, hidden = True), # hidden fall - DS3LocationData("US: Mound-makers", "Mound-makers", DS3LocationCategory.MISC, + DS3LocationData("US: Mound-makers", "Mound-makers", DS3LocationCategory.UNIQUE, missable = True), DS3LocationData("US: Sharp Gem", "Sharp Gem", DS3LocationCategory.UPGRADE, lizard = True), @@ -638,7 +642,7 @@ def get_name_to_id() -> dict: DS3LocationData("US: Siegbräu", "Siegbräu", DS3LocationCategory.MISC, missable = True, npc = True), DS3LocationData("US: Heavy Gem (Hawkwood)", "Heavy Gem", DS3LocationCategory.UPGRADE, - missable = True, npc = True), # Hawkwood (quest, after Greatwood or Sage) + offline = '00,0:50006070::', missable = True, npc = True), # Hawkwood (quest, after Greatwood or Sage) DS3LocationData("US: Hollowslayer Greatsword", "Hollowslayer Greatsword", DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), DS3LocationData("US: Arstor's Spear", "Arstor's Spear", DS3LocationCategory.WEAPON, @@ -661,8 +665,8 @@ def get_name_to_id() -> dict: missable = True, npc = True), DS3LocationData("US: Untrue Dark Ring", "Untrue Dark Ring", DS3LocationCategory.RING, missable = True, npc = True), - DS3LocationData("US: Londor Braille Divine Tome", "Londor Braille Divine Tome", DS3LocationCategory.MISC, - missable = True, npc = True), + DS3LocationData("US: Londor Braille Divine Tome", "Londor Braille Divine Tome", DS3LocationCategory.UNIQUE, + offline = '99,0:-1:40000,110000,70000116:', missable = True, npc = True), DS3LocationData("US: Darkdrift", "Darkdrift", DS3LocationCategory.WEAPON, missable = True, npc = True), # kill her or kill Soul of Cinder @@ -773,7 +777,7 @@ def get_name_to_id() -> dict: DS3LocationData("RS: Conjurator Boots", "Conjurator Boots", DS3LocationCategory.ARMOR), DS3LocationData("RS: Soul of an Unknown Traveler #2", "Soul of an Unknown Traveler", DS3LocationCategory.MISC), DS3LocationData("RS: Green Blossom #2", "Green Blossom x2", DS3LocationCategory.MISC), - DS3LocationData("RS: Great Swamp Pyromancy Tome", "Great Swamp Pyromancy Tome", DS3LocationCategory.MISC), + DS3LocationData("RS: Great Swamp Pyromancy Tome", "Great Swamp Pyromancy Tome", DS3LocationCategory.UNIQUE), DS3LocationData("RS: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC), DS3LocationData("RS: Titanite Shard #3", "Titanite Shard", DS3LocationCategory.MISC), DS3LocationData("RS: Twin Dragon Greatshield", "Twin Dragon Greatshield", DS3LocationCategory.SHIELD), @@ -794,7 +798,7 @@ def get_name_to_id() -> dict: DS3LocationData("RS: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), DS3LocationData("RS: Titanite Shard #4", "Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("RS: Brigand Twindaggers", "Brigand Twindaggers", DS3LocationCategory.WEAPON), - DS3LocationData("RS: Braille Divine Tome of Carim", "Braille Divine Tome of Carim", DS3LocationCategory.MISC, + DS3LocationData("RS: Braille Divine Tome of Carim", "Braille Divine Tome of Carim", DS3LocationCategory.UNIQUE, hidden = True), # Hidden fall DS3LocationData("RS: Ember #2", "Ember", DS3LocationCategory.MISC), DS3LocationData("RS: Sellsword Twinblades", "Sellsword Twinblades", DS3LocationCategory.WEAPON), @@ -810,14 +814,14 @@ def get_name_to_id() -> dict: DS3LocationData("RS: Sellsword Armor", "Sellsword Armor", DS3LocationCategory.ARMOR), DS3LocationData("RS: Sellsword Gauntlet", "Sellsword Gauntlet", DS3LocationCategory.ARMOR), DS3LocationData("RS: Sellsword Trousers", "Sellsword Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Farron Coal", "Farron Coal", DS3LocationCategory.MISC), + DS3LocationData("RS: Farron Coal", "Farron Coal", DS3LocationCategory.UNIQUE), DS3LocationData("RS: Chloranthy Ring+2", "Chloranthy Ring+2", DS3LocationCategory.RING, hidden = True, ngp = True), # Hidden fall DS3LocationData("RS: Lingering Dragoncrest Ring+1", "Lingering Dragoncrest Ring+1", DS3LocationCategory.RING, ngp = True), DS3LocationData("RS: Great Swamp Ring", "Great Swamp Ring", DS3LocationCategory.RING, miniboss = True), # Giant Crab drop - DS3LocationData("RS: Blue Sentinels", "Blue Sentinels", DS3LocationCategory.MISC, + DS3LocationData("RS: Blue Sentinels", "Blue Sentinels", DS3LocationCategory.UNIQUE, missable = True, npc = True), # Horace quest DS3LocationData("RS: Crystal Gem", "Crystal Gem", DS3LocationCategory.UPGRADE), @@ -830,7 +834,7 @@ def get_name_to_id() -> dict: DS3LocationData("RS: Great Soul Arrow", "Great Soul Arrow", DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), DS3LocationData("RS: Heavy Soul Arrow", "Heavy Soul Arrow", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), DS3LocationData("RS: Great Heavy Soul Arrow", "Great Heavy Soul Arrow", DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), DS3LocationData("RS: Magic Weapon", "Magic Weapon", DS3LocationCategory.SPELL, @@ -911,7 +915,7 @@ def get_name_to_id() -> dict: prominent = True, progression = True, boss = True), DS3LocationData("CD: Soul of the Deacons of the Deep", "Soul of the Deacons of the Deep", DS3LocationCategory.BOSS, boss = True), - DS3LocationData("CD: Black Eye Orb", "Black Eye Orb", DS3LocationCategory.MISC, + DS3LocationData("CD: Black Eye Orb", "Black Eye Orb", DS3LocationCategory.UNIQUE, missable = True, npc = True), DS3LocationData("CD: Winged Spear #1", "Winged Spear", DS3LocationCategory.WEAPON, missable = True), # Patches (kill) @@ -996,9 +1000,9 @@ def get_name_to_id() -> dict: missable = True), DS3LocationData("CD: Deep Ring", "Deep Ring", DS3LocationCategory.RING, hidden = True), # Guaranteed drop from a normal-looking Deacon - DS3LocationData("CD: Deep Braille Divine Tome", "Deep Braille Divine Tome", DS3LocationCategory.MISC, + DS3LocationData("CD: Deep Braille Divine Tome", "Deep Braille Divine Tome", DS3LocationCategory.UNIQUE, mimic = True), - DS3LocationData("CD: Red Sign Soapstone", "Red Sign Soapstone", DS3LocationCategory.MISC, + DS3LocationData("CD: Red Sign Soapstone", "Red Sign Soapstone", DS3LocationCategory.UNIQUE, hidden = True), # Guaranteed drop from a normal-looking Corpse-grub DS3LocationData("CD: Aldrich's Sapphire", "Aldrich's Sapphire", DS3LocationCategory.RING, miniboss = True), # Deep Accursed Drop @@ -1012,7 +1016,7 @@ def get_name_to_id() -> dict: lizard = True), DS3LocationData("CD: Twinkling Titanite #4", "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("CD: Rosaria's Fingers", "Rosaria's Fingers", DS3LocationCategory.MISC, + DS3LocationData("CD: Rosaria's Fingers", "Rosaria's Fingers", DS3LocationCategory.UNIQUE, hidden = True), # Hidden fall DS3LocationData("CD: Cleric's Candlestick", "Cleric's Candlestick", DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), @@ -1080,9 +1084,9 @@ def get_name_to_id() -> dict: DS3LocationData("FK: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), DS3LocationData("FK: Repair Powder", "Repair Powder x4", DS3LocationCategory.MISC, hidden = True), # Out-of-the-way hard-to-see cave - DS3LocationData("FK: Golden Scroll", "Golden Scroll", DS3LocationCategory.MISC, + DS3LocationData("FK: Golden Scroll", "Golden Scroll", DS3LocationCategory.UNIQUE, hostile_npc = True), # Out-of-the-way hard-to-see cave - DS3LocationData("FK: Sage's Scroll", "Sage's Scroll", DS3LocationCategory.MISC), + DS3LocationData("FK: Sage's Scroll", "Sage's Scroll", DS3LocationCategory.UNIQUE), DS3LocationData("FK: Dreamchaser's Ashes", "Dreamchaser's Ashes", DS3LocationCategory.KEY, progression = True, hidden = True), # Behind illusory wall DS3LocationData("FK: Titanite Shard #3", "Titanite Shard", DS3LocationCategory.UPGRADE), @@ -1102,7 +1106,7 @@ def get_name_to_id() -> dict: DS3LocationData("FK: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), DS3LocationData("FK: Prism Stone", "Prism Stone x10", DS3LocationCategory.MISC), DS3LocationData("FK: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), - DS3LocationData("FK: Sage's Coal", "Sage's Coal", DS3LocationCategory.MISC), + DS3LocationData("FK: Sage's Coal", "Sage's Coal", DS3LocationCategory.UNIQUE), DS3LocationData("FK: Gold Pine Bundle", "Gold Pine Bundle x6", DS3LocationCategory.MISC), DS3LocationData("FK: Ember #2", "Ember", DS3LocationCategory.MISC), DS3LocationData("FK: Soul of a Nameless Soldier", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), @@ -1142,7 +1146,7 @@ def get_name_to_id() -> dict: lizard = True), DS3LocationData("FK: Soul of a Stray Demon", "Soul of a Stray Demon", DS3LocationCategory.BOSS, miniboss = True), - DS3LocationData("FK: Watchdogs of Farron", "Watchdogs of Farron", DS3LocationCategory.MISC), + DS3LocationData("FK: Watchdogs of Farron", "Watchdogs of Farron", DS3LocationCategory.UNIQUE), DS3LocationData("FK: Hawkwood's Shield", "Hawkwood's Shield", DS3LocationCategory.SHIELD, missable = True, npc = True), # Hawkwood (quest, after Greatwood, Sage, Watchers, and Deacons) DS3LocationData("FK: Havel's Ring", "Havel's Ring", DS3LocationCategory.RING, @@ -1186,7 +1190,7 @@ def get_name_to_id() -> dict: DS3LocationData("CC: Titanite Shard #2", "Titanite Shard x2", DS3LocationCategory.UPGRADE), DS3LocationData("CC: Titanite Shard #3", "Titanite Shard x2", DS3LocationCategory.UPGRADE), DS3LocationData("CC: Ember #3", "Ember", DS3LocationCategory.MISC), - DS3LocationData("CC: Carthus Pyromancy Tome", "Carthus Pyromancy Tome", DS3LocationCategory.MISC, + DS3LocationData("CC: Carthus Pyromancy Tome", "Carthus Pyromancy Tome", DS3LocationCategory.UNIQUE, hidden = True), # Behind illusory wall DS3LocationData("CC: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.MISC), DS3LocationData("CC: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.MISC), @@ -1200,7 +1204,7 @@ def get_name_to_id() -> dict: DS3LocationData("CC: Old Sage's Blindfold", "Old Sage's Blindfold", DS3LocationCategory.ARMOR), DS3LocationData("CC: Witch's Ring", "Witch's Ring", DS3LocationCategory.RING), DS3LocationData("CC: Soul of a Nameless Soldier #2", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), - DS3LocationData("CC: Grave Warden Pyromancy Tome", "Grave Warden Pyromancy Tome", DS3LocationCategory.MISC), + DS3LocationData("CC: Grave Warden Pyromancy Tome", "Grave Warden Pyromancy Tome", DS3LocationCategory.UNIQUE), DS3LocationData("CC: Large Soul of an Unknown Traveler", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), DS3LocationData("CC: Ring of Steel Protection+2", "Ring of Steel Protection+2", DS3LocationCategory.RING, ngp = True), @@ -1257,11 +1261,11 @@ def get_name_to_id() -> dict: DS3LocationData("SL: Ember #1", "Ember", DS3LocationCategory.MISC), DS3LocationData("SL: Chaos Gem #1", "Chaos Gem", DS3LocationCategory.UPGRADE), DS3LocationData("SL: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("SL: Izalith Pyromancy Tome", "Izalith Pyromancy Tome", DS3LocationCategory.MISC), + DS3LocationData("SL: Izalith Pyromancy Tome", "Izalith Pyromancy Tome", DS3LocationCategory.UNIQUE), DS3LocationData("SL: Black Knight Sword", "Black Knight Sword", DS3LocationCategory.WEAPON, hidden = True), # Behind illusory wall DS3LocationData("SL: Ember #3", "Ember", DS3LocationCategory.MISC), - DS3LocationData("SL: Quelana Pyromancy Tome", "Quelana Pyromancy Tome", DS3LocationCategory.MISC), + DS3LocationData("SL: Quelana Pyromancy Tome", "Quelana Pyromancy Tome", DS3LocationCategory.UNIQUE), DS3LocationData("SL: Izalith Staff", "Izalith Staff", DS3LocationCategory.WEAPON, hidden = True), # Behind illusory wall DS3LocationData("SL: White Hair Talisman", "White Hair Talisman", DS3LocationCategory.WEAPON, @@ -1302,12 +1306,13 @@ def get_name_to_id() -> dict: missable = True, boss = True, shop = True), DS3LocationData("SL: Chaos Bed Vestiges", "Chaos Bed Vestiges", DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), - DS3LocationData("SL: Llewellyn Shield", "Llewellyn Shield", DS3LocationCategory.SHIELD, - missable = True, npc = True), # Horace (kill or quest) - # Shrine Handmaid after killing Horace the Hushed + # Horace the Hushed # These are listed here even though you can kill Horace in the Road of Sacrifices because # the player may want to complete his and Anri's quest first. + DS3LocationData("SL: Llewellyn Shield", "Llewellyn Shield", DS3LocationCategory.SHIELD, + npc = True), # kill or quest + # Shrine Handmaiden after killing DS3LocationData("SL: Executioner Helm", "Executioner Helm", DS3LocationCategory.ARMOR, hidden = True, npc = True, shop = True), DS3LocationData("SL: Executioner Armor", "Executioner Armor", DS3LocationCategory.ARMOR, @@ -1377,7 +1382,7 @@ def get_name_to_id() -> dict: DS3LocationData("IBV: Dung Pie #1", "Dung Pie x3", DS3LocationCategory.MISC), DS3LocationData("IBV: Dung Pie #2", "Dung Pie x3", DS3LocationCategory.MISC), # These don't actually guard any single item sales. Maybe we can inject one manually? - DS3LocationData("IBV: Excrement-covered Ashes", "Excrement-covered Ashes", DS3LocationCategory.MISC), + DS3LocationData("IBV: Excrement-covered Ashes", "Excrement-covered Ashes", DS3LocationCategory.UNIQUE), DS3LocationData("IBV: Large Soul of a Nameless Soldier #4", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), DS3LocationData("IBV: Soul of a Weary Warrior #4", "Soul of a Weary Warrior", DS3LocationCategory.MISC), DS3LocationData("IBV: Large Titanite Shard #7", "Large Titanite Shard", DS3LocationCategory.UPGRADE), @@ -1411,7 +1416,7 @@ def get_name_to_id() -> dict: hidden = True), # Guaranteed drop from normal-looking Silver Knight DS3LocationData("IBV: Large Titanite Shard #11", "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, hidden = True), # Guaranteed drop from normal-looking Silver Knight - DS3LocationData("IBV: Roster of Knights", "Roster of Knights", DS3LocationCategory.MISC), + DS3LocationData("IBV: Roster of Knights", "Roster of Knights", DS3LocationCategory.UNIQUE), DS3LocationData("IBV: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True, hidden = True), # Behind illusory wall DS3LocationData("IBV: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, @@ -1466,7 +1471,7 @@ def get_name_to_id() -> dict: missable = True, npc = True), ], "Irithyll Dungeon": [ - DS3LocationData("ID: Titanite Slab", "Titanite Slab", DS3LocationCategory.MISC, + DS3LocationData("ID: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE, missable = True, npc = True), # Siegward (quest) DS3LocationData("ID: Murakumo", "Murakumo", DS3LocationCategory.WEAPON, missable = True, npc = True), # Alva (requires ember) @@ -1491,7 +1496,7 @@ def get_name_to_id() -> dict: DS3LocationData("ID: Dung Pie #1", "Dung Pie x4", DS3LocationCategory.MISC), DS3LocationData("ID: Ember #1", "Ember", DS3LocationCategory.MISC), DS3LocationData("ID: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("ID: Profaned Coal", "Profaned Coal", DS3LocationCategory.MISC), + DS3LocationData("ID: Profaned Coal", "Profaned Coal", DS3LocationCategory.UNIQUE), DS3LocationData("ID: Large Titanite Shard #5", "Large Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("ID: Old Sorcerer Hat", "Old Sorcerer Hat", DS3LocationCategory.ARMOR), DS3LocationData("ID: Old Sorcerer Coat", "Old Sorcerer Coat", DS3LocationCategory.ARMOR), @@ -1511,7 +1516,7 @@ def get_name_to_id() -> dict: key = True), DS3LocationData("ID: Covetous Silver Serpent Ring+1", "Covetous Silver Serpent Ring+1", DS3LocationCategory.RING, ngp = True), - DS3LocationData("ID: Dragon Torso Stone", "Dragon Torso Stone", DS3LocationCategory.MISC), + DS3LocationData("ID: Dragon Torso Stone", "Dragon Torso Stone", DS3LocationCategory.UNIQUE), DS3LocationData("ID: Prisoner Chief's Ashes", "Prisoner Chief's Ashes", DS3LocationCategory.KEY, progression = True), DS3LocationData("ID: Great Magic Shield", "Great Magic Shield", DS3LocationCategory.SPELL, @@ -1547,7 +1552,7 @@ def get_name_to_id() -> dict: boss = True), DS3LocationData("PC: Cinders of a Lord - Yhorm the Giant", "Cinders of a Lord - Yhorm the Giant", DS3LocationCategory.KEY, offline = "07,0:50002170::", prominent = True, progression = True, boss = True), - DS3LocationData("PC: Logan's Scroll", "Logan's Scroll", DS3LocationCategory.MISC, + DS3LocationData("PC: Logan's Scroll", "Logan's Scroll", DS3LocationCategory.UNIQUE, hostile_npc = True), # Sorcerer DS3LocationData("PC: Purging Stone #1", "Purging Stone x3", DS3LocationCategory.MISC), DS3LocationData("PC: Rusted Coin #1", "Rusted Coin x2", DS3LocationCategory.MISC), @@ -1658,7 +1663,7 @@ def get_name_to_id() -> dict: DS3LocationData("AL: Moonlight Arrow", "Moonlight Arrow x6", DS3LocationCategory.MISC), DS3LocationData("AL: Proof of a Concord Kept", "Proof of a Concord Kept", DS3LocationCategory.MISC), DS3LocationData("AL: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), - DS3LocationData("AL: Giant's Coal", "Giant's Coal", DS3LocationCategory.MISC), + DS3LocationData("AL: Giant's Coal", "Giant's Coal", DS3LocationCategory.UNIQUE), DS3LocationData("AL: Havel's Ring+2", "Havel's Ring+2", DS3LocationCategory.RING, ngp = True, hidden = True), # Invisible walkway DS3LocationData("AL: Ring of Favor+1", "Ring of Favor+1", DS3LocationCategory.RING, @@ -1670,7 +1675,7 @@ def get_name_to_id() -> dict: mimic = True), DS3LocationData("AL: Ring of Favor", "Ring of Favor", DS3LocationCategory.RING, miniboss = True, hidden = True), # Sulyvahn's Beast Duo drop, behind illusory wall - DS3LocationData("AL: Blade of the Darkmoon", "Blade of the Darkmoon", DS3LocationCategory.MISC, + DS3LocationData("AL: Blade of the Darkmoon", "Blade of the Darkmoon", DS3LocationCategory.UNIQUE, missable = True, npc = True), # Yorshka (quest or kill) DS3LocationData("AL: Simple Gem", "Simple Gem", DS3LocationCategory.UPGRADE, lizard = True), @@ -1680,10 +1685,10 @@ def get_name_to_id() -> dict: lizard = True), DS3LocationData("AL: Aldrich's Ruby", "Aldrich's Ruby", DS3LocationCategory.RING, miniboss = True), # Deep Accursed drop - DS3LocationData("AL: Aldrich Faithful", "Aldrich Faithful", DS3LocationCategory.MISC, + DS3LocationData("AL: Aldrich Faithful", "Aldrich Faithful", DS3LocationCategory.UNIQUE, hidden = True), # Behind illusory wall DS3LocationData("AL: Budding Green Blossom", "Budding Green Blossom", DS3LocationCategory.MISC, - missable = True, npc = True, shop = True), # sold by Shrine Maiden after helping Sirris and defeating Aldrich + offline = '99,0:-1:110000,70000118:', missable = True, npc = True, shop = True), # sold by Shrine Maiden after helping Sirris and defeating Aldrich DS3LocationData("AL: Bountiful Sunlight", "Bountiful Sunlight", DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), DS3LocationData("AL: Darkmoon Longbow", "Darkmoon Longbow", DS3LocationCategory.WEAPON, @@ -1753,7 +1758,7 @@ def get_name_to_id() -> dict: missable = True, npc = True), DS3LocationData("AL: Silver Mask", "Silver Mask", DS3LocationCategory.ARMOR, missable = True, npc = True), - DS3LocationData("AL: Soul of Rosaria", "Soul of Rosaria", DS3LocationCategory.MISC, + DS3LocationData("AL: Soul of Rosaria", "Soul of Rosaria", DS3LocationCategory.UNIQUE, missable = True, npc = True), ], @@ -1806,7 +1811,7 @@ def get_name_to_id() -> dict: DS3LocationData("LC: Winged Knight Leggings", "Winged Knight Leggings", DS3LocationCategory.ARMOR, hidden = True), # Behind illusory wall DS3LocationData("LC: Rusted Coin", "Rusted Coin x2", DS3LocationCategory.MISC), - DS3LocationData("LC: Braille Divine Tome of Lothric", "Braille Divine Tome of Lothric", DS3LocationCategory.MISC, + DS3LocationData("LC: Braille Divine Tome of Lothric", "Braille Divine Tome of Lothric", DS3LocationCategory.UNIQUE, hidden = True), # Hidden fall DS3LocationData("LC: Red Tearstone Ring", "Red Tearstone Ring", DS3LocationCategory.RING), DS3LocationData("LC: Twinkling Titanite #2", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE), @@ -1857,6 +1862,12 @@ def get_name_to_id() -> dict: DS3LocationData("LC: Dragonslayer Greatshield", "Dragonslayer Greatshield", DS3LocationCategory.SHIELD, missable = True, boss = True, shop = True), + # Eygon of Carim (kill or quest) + DS3LocationData("LC: Morne's Great Hammer", "Morne's Great Hammer", DS3LocationCategory.WEAPON, + npc = True), + DS3LocationData("LC: Moaning Shield", "Moaning Shield", DS3LocationCategory.SHIELD, + npc = True), + # Shrine Handmaid after killing Dancer of the Boreal Valley DS3LocationData("LC: Dancer's Crown", "Dancer's Crown", DS3LocationCategory.ARMOR, boss = True, shop = True), @@ -1973,13 +1984,13 @@ def get_name_to_id() -> dict: ngp = True), DS3LocationData("GA: Divine Blessing", "Divine Blessing", DS3LocationCategory.MISC, hidden = True), # Hidden fall - DS3LocationData("GA: Twinkling Titanite #1", "Twinkling Titanite x3", DS3LocationCategory.MISC, + DS3LocationData("GA: Twinkling Titanite #1", "Twinkling Titanite x3", DS3LocationCategory.UPGRADE, hidden = True), # Hidden fall DS3LocationData("GA: Witch's Locks", "Witch's Locks", DS3LocationCategory.WEAPON, hidden = True), # Switch in darkened room DS3LocationData("GA: Titanite Slab #2", "Titanite Slab", DS3LocationCategory.UPGRADE, hidden = True), # Backtrack after flipping bridge switch - DS3LocationData("GA: Titanite Scale #7", "Titanite Scale x3", DS3LocationCategory.MISC), + DS3LocationData("GA: Titanite Scale #7", "Titanite Scale x3", DS3LocationCategory.UPGRADE), DS3LocationData("GA: Soul Stream", "Soul Stream", DS3LocationCategory.SPELL, hidden = True), # Behind illusory wall DS3LocationData("GA: Scholar Ring", "Scholar Ring", DS3LocationCategory.RING), @@ -1994,7 +2005,7 @@ def get_name_to_id() -> dict: miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop DS3LocationData("GA: Outrider Knight Leggings", "Outrider Knight Leggings", DS3LocationCategory.ARMOR, miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop - DS3LocationData("GA: Crystal Scroll", "Crystal Scroll", DS3LocationCategory.MISC, + DS3LocationData("GA: Crystal Scroll", "Crystal Scroll", DS3LocationCategory.UNIQUE, miniboss = True), # Crystal Sage drop DS3LocationData("GA: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), @@ -2079,7 +2090,7 @@ def get_name_to_id() -> dict: hidden = True), DS3LocationData("UG: Chaos Blade", "Chaos Blade", DS3LocationCategory.WEAPON, hidden = True), - DS3LocationData("UG: Coiled Sword Fragment", "Coiled Sword Fragment", DS3LocationCategory.MISC, + DS3LocationData("UG: Coiled Sword Fragment", "Coiled Sword Fragment", DS3LocationCategory.UNIQUE, boss = True, hidden = True), DS3LocationData("UG: Life Ring+3", "Life Ring+3", DS3LocationCategory.RING, ngp = True, hidden = True), @@ -2121,8 +2132,7 @@ def get_name_to_id() -> dict: hidden = True, boss = True, shop = True), ], "Archdragon Peak": [ - - DS3LocationData("AP: Dragon Head Stone", "Dragon Head Stone", DS3LocationCategory.MISC, + DS3LocationData("AP: Dragon Head Stone", "Dragon Head Stone", DS3LocationCategory.UNIQUE, prominent = True, boss = True), DS3LocationData("AP: Soul of the Nameless King", "Soul of the Nameless King", DS3LocationCategory.BOSS, prominent = True, boss = True), @@ -2194,7 +2204,7 @@ def get_name_to_id() -> dict: miniboss = True), # Wyvern miniboss drop DS3LocationData("AP: Twinkling Titanite #5", "Twinkling Titanite x3", DS3LocationCategory.UPGRADE, miniboss = True), # Wyvern miniboss drop - DS3LocationData("AP: Hawkwood's Swordgrass", "Hawkwood's Swordgrass", DS3LocationCategory.MISC, + DS3LocationData("AP: Hawkwood's Swordgrass", "Hawkwood's Swordgrass", DS3LocationCategory.UNIQUE, hidden = True), DS3LocationData("AP: Storm Curved Sword", "Storm Curved Sword", DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), @@ -2212,7 +2222,7 @@ def get_name_to_id() -> dict: boss = True, shop = True), DS3LocationData("AP: Dragonscale Waistcloth", "Dragonscale Waistcloth", DS3LocationCategory.ARMOR, boss = True, shop = True), - DS3LocationData("AP: Twinkling Dragon Head Stone", "Twinkling Dragon Head Stone", DS3LocationCategory.MISC, + DS3LocationData("AP: Twinkling Dragon Head Stone", "Twinkling Dragon Head Stone", DS3LocationCategory.UNIQUE, missable = True, npc = True), # Hawkwood (quest) # After Oceiros's boss room, only once the Drakeblood summon in AP has been killed @@ -2273,7 +2283,7 @@ def get_name_to_id() -> dict: DS3LocationData("PW1: Onyx Blade", "Onyx Blade", DS3LocationCategory.WEAPON, hostile_npc = True), # Sir Vilhelm drop DS3LocationData("PW: Chillbite Ring", "Chillbite Ring", DS3LocationCategory.RING, - npc = True), + npc = True), # Friede conversation DS3LocationData("PW1: Rime-blue Moss Clump #1", "Rime-blue Moss Clump x2", DS3LocationCategory.MISC), DS3LocationData("PW1: Poison Gem", "Poison Gem", DS3LocationCategory.UPGRADE), DS3LocationData("PW1: Large Soul of an Unknown Traveler #1", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), @@ -2343,7 +2353,7 @@ def get_name_to_id() -> dict: lizard = True), DS3LocationData("PW1: Large Titanite Shard #3", "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("PW2: Champion's Bones", "Champion's Bones", DS3LocationCategory.MISC, + DS3LocationData("PW2: Champion's Bones", "Champion's Bones", DS3LocationCategory.UNIQUE, offline = '11,0:50002310::', boss = True), ], "Painted World of Ariandel (After Contraption)": [ @@ -2485,9 +2495,9 @@ def get_name_to_id() -> dict: DS3LocationData("RC: Soul of Darkeater Midir", "Soul of Darkeater Midir", DS3LocationCategory.BOSS, prominent = True, boss = True), DS3LocationData("RC: Sacred Chime of Filianore", "Sacred Chime of Filianore", DS3LocationCategory.WEAPON, - npc = True), + npc = True), # Shira (kill or quest) DS3LocationData("RC: Titanite Slab #2", "Titanite Slab", DS3LocationCategory.UPGRADE, - npc = True), + npc = True), # Shira (kill or quest) DS3LocationData("RC: Crucifix of the Mad King", "Crucifix of the Mad King", DS3LocationCategory.WEAPON, hostile_npc = True), # Shira drop DS3LocationData("RC: Ledo's Great Hammer", "Ledo's Great Hammer", DS3LocationCategory.WEAPON, @@ -2610,9 +2620,9 @@ def get_name_to_id() -> dict: DS3LocationData("RC: Iron Dragonslayer Leggings", "Iron Dragonslayer Leggings", DS3LocationCategory.ARMOR, miniboss = True), DS3LocationData("RC: Church Guardian Shiv", "Church Guardian Shiv", DS3LocationCategory.MISC), - DS3LocationData("RC: Spears of the Church", "Spears of the Church", DS3LocationCategory.MISC, + DS3LocationData("RC: Spears of the Church", "Spears of the Church", DS3LocationCategory.UNIQUE, boss = True), # Midir drop - DS3LocationData("RC: Ritual Spear Fragment", "Ritual Spear Fragment", DS3LocationCategory.MISC), + DS3LocationData("RC: Ritual Spear Fragment", "Ritual Spear Fragment", DS3LocationCategory.UNIQUE), DS3LocationData("RC: Titanite Scale #8", "Titanite Scale", DS3LocationCategory.UPGRADE, lizard = True), DS3LocationData("RC: Twinkling Titanite #5", "Twinkling Titanite", DS3LocationCategory.UPGRADE, @@ -2737,6 +2747,8 @@ def get_name_to_id() -> dict: "Hostile NPC Rewards": set(), "Small Crystal Lizards": set(), "Keys": set(), + "Upgrade": set(), + "Miscellaneous": set(), "Hidden": set() } @@ -2757,7 +2769,13 @@ def get_name_to_id() -> dict: location_name_groups["Painted World of Ariandel"] = ( location_name_groups["Painted World of Ariandel (Before Contraption)"] - .union(location_name_groups["Painted World of Ariandel (After Contraption)"]) + .union(location_name_groups["Painted World of Ariandel (After Contraption)"]) ) del location_name_groups["Painted World of Ariandel (Before Contraption)"] del location_name_groups["Painted World of Ariandel (After Contraption)"] + +location_name_groups["DLC"] = ( + location_name_groups["Painted World of Ariandel"] + .union(location_name_groups["Dreg Heap"]) + .union(location_name_groups["Ringed City"]) +) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 827bca060674..0b68f7ed240c 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -1,55 +1,90 @@ import typing +from dataclasses import dataclass -from Options import Toggle, DefaultOnToggle, Option, Range, Choice, ItemDict, DeathLink +from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, ItemDict, Option, PerGameCommonOptions, Range, Toggle class RandomizeWeaponLocations(DefaultOnToggle): - """Randomizes weapons (+76 locations)""" + """Randomizes weapons (+101 checks)""" display_name = "Randomize Weapon Locations" class RandomizeShieldLocations(DefaultOnToggle): - """Randomizes shields (+24 locations)""" + """Randomizes shields (+32 checks)""" display_name = "Randomize Shield Locations" class RandomizeArmorLocations(DefaultOnToggle): - """Randomizes armor pieces (+97 locations)""" + """Randomizes armor pieces (+216 checks)""" display_name = "Randomize Armor Locations" class RandomizeRingLocations(DefaultOnToggle): - """Randomizes rings (+49 locations)""" + """Randomizes rings (+64 checks, +101 with NG+ locations)""" display_name = "Randomize Ring Locations" class RandomizeSpellLocations(DefaultOnToggle): - """Randomizes spells (+18 locations)""" + """Randomizes spells (+35 checks)""" display_name = "Randomize Spell Locations" +class RandomizeUpgradeLocations(DefaultOnToggle): + """Randomizes titanite and gems (+220 checks) + + By default, these locations will never include progression items, so they + aren't mandatory checks. You can override this by customizing the + "exclude_locations" field in your YAML config. (For example, + "exclude_locations: []" will allow progression items in every unmissable + location.) + """ + display_name = "Randomize Upgrade Locations" + + class RandomizeKeyLocations(DefaultOnToggle): - """Randomizes items which unlock doors or bypass barriers""" + """Randomizes items which unlock doors or bypass barriers. + + If these aren't randomized, the route through the game will remain unchanged. + """ display_name = "Randomize Key Locations" class RandomizeBossSoulLocations(DefaultOnToggle): - """Randomizes Boss Souls (+18 Locations)""" + """Randomizes boss souls (+22 Locations)""" display_name = "Randomize Boss Soul Locations" -class RandomizeNPCLocations(Toggle): - """Randomizes friendly NPC drops (meaning you will probably have to kill them) (+14 locations)""" +class RandomizeNPCLocations(DefaultOnToggle): + """Randomizes friendly NPC drops and rewards (+34 checks) + + Although all NPC drops will be randomized, progression items will only + appear in drops that aren't possible to lock yourself out of. Progression + items may be available by killing NPCs, but you can always do their quest + instead if you want. + + """ display_name = "Randomize NPC Locations" -class RandomizeMiscLocations(Toggle): - """Randomizes miscellaneous items (ashes, tomes, scrolls, etc.) to the pool. (+36 locations)""" +class RandomizeUniqueLocations(DefaultOnToggle): + """Randomizes unique items (ashes, tomes, scrolls, etc.) (+36 checks)""" + display_name = "Randomize Miscellaneous Locations" + + +class RandomizeMiscLocations(DefaultOnToggle): + """Randomizes miscellaneous items (arrows, firebombs, soul items, etc.) (+388 locations) + + By default, these locations will never include progression items, so they + aren't mandatory checks. You can override this by customizing the + "exclude_locations" field in your YAML config. (For example, + "exclude_locations: []" will allow progression items in every unmissable + location.) + """ display_name = "Randomize Miscellaneous Locations" -class RandomizeHealthLocations(Toggle): - """Randomizes health upgrade items. (+21 locations)""" +class RandomizeHealthLocations(DefaultOnToggle): + """Randomizes health upgrade items. (+21 checks)""" display_name = "Randomize Health Upgrade Locations" @@ -84,14 +119,12 @@ class AutoEquipOption(Toggle): 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.""" + """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 NoWeaponRequirementsOption(Toggle): - """Disable the weapon requirements by removing any movement or damage penalties. - Permitting you to use any weapon early""" + """Disable the weapon requirements by removing any movement or damage penalties, permitting you to use any weapon early.""" display_name = "No Weapon Requirements" @@ -119,12 +152,13 @@ class RandomizeInfusionPercentageOption(Range): 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. + """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""" + Epic: Only weapons that can be upgraded to +5 + """ display_name = "Randomize Weapon Level" option_none = 0 option_all = 1 @@ -173,16 +207,12 @@ class MaxLevelsIn10WeaponPoolOption(Range): class LateBasinOfVowsOption(Toggle): - """This option makes it so the Basin of Vows is still randomized, but guarantees you that you wont have to venture into - Lothric Castle to find your Small Lothric Banner to get out of High Wall of Lothric. So you may find Basin of Vows early, - but you wont have to fight Dancer to find your Small Lothric Banner.""" + """This option makes it so the Basin of Vows is still randomized, but guarantees you that you wont have to venture into Lothric Castle to find your Small Lothric Banner to get out of High Wall of Lothric. So you may find Basin of Vows early, but you wont have to fight Dancer to find your Small Lothric Banner.""" display_name = "Late Basin of Vows" class LateDLCOption(Toggle): - """This option makes it so you are guaranteed to find your Small Doll without having to venture off into the DLC, - effectively putting anything in the DLC in logic after finding both Contraption Key and Small Doll, - and being able to get into Irithyll of the Boreal Valley.""" + """This option makes it so you are guaranteed to find your Small Doll without having to venture off into the DLC, effectively putting anything in the DLC in logic after finding both Contraption Key and Small Doll, and being able to get into Irithyll of the Boreal Valley.""" display_name = "Late DLC" @@ -192,41 +222,49 @@ class EnableDLCOption(Toggle): class EnableNGPOption(Toggle): - """Whether to include items and locations exclusive to NG+ cycles.""" + """Whether to include items and locations exclusive to NG+ cycles""" display_name = "Enable NG+" -dark_souls_options: typing.Dict[str, Option] = { - "enable_weapon_locations": RandomizeWeaponLocations, - "enable_shield_locations": RandomizeShieldLocations, - "enable_armor_locations": RandomizeArmorLocations, - "enable_ring_locations": RandomizeRingLocations, - "enable_spell_locations": RandomizeSpellLocations, - "enable_key_locations": RandomizeKeyLocations, - "enable_boss_locations": RandomizeBossSoulLocations, - "enable_npc_locations": RandomizeNPCLocations, - "enable_misc_locations": RandomizeMiscLocations, - "enable_health_upgrade_locations": RandomizeHealthLocations, - "random_starting_loadout": RandomizeStartingLoadout, - "require_one_handed_starting_weapons": RequireOneHandedStartingWeapons, - "pool_type": PoolTypeOption, - "guaranteed_items": GuaranteedItemsOption, - "auto_equip": AutoEquipOption, - "lock_equip": LockEquipOption, - "no_weapon_requirements": NoWeaponRequirementsOption, - "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, - "late_basin_of_vows": LateBasinOfVowsOption, - "late_dlc": LateDLCOption, - "no_spell_requirements": NoSpellRequirementsOption, - "no_equip_load": NoEquipLoadOption, - "death_link": DeathLink, - "enable_dlc": EnableDLCOption, - "enable_ngp": EnableNGPOption, -} +class DS3ExcludeLocations(ExcludeLocations): + """Prevent these locations from having an important item""" + default = {"Hidden", "Small Crystal Lizards", "Miscellaneous"} + + +@dataclass +class DarkSouls3Options(PerGameCommonOptions): + enable_weapon_locations: RandomizeWeaponLocations + enable_shield_locations: RandomizeShieldLocations + enable_armor_locations: RandomizeArmorLocations + enable_ring_locations: RandomizeRingLocations + enable_spell_locations: RandomizeSpellLocations + enable_upgrade_locations: RandomizeUpgradeLocations + enable_key_locations: RandomizeKeyLocations + enable_boss_locations: RandomizeBossSoulLocations + enable_npc_locations: RandomizeNPCLocations + enable_unique_locations: RandomizeUniqueLocations + enable_misc_locations: RandomizeMiscLocations + enable_health_upgrade_locations: RandomizeHealthLocations + random_starting_loadout: RandomizeStartingLoadout + require_one_handed_starting_weapons: RequireOneHandedStartingWeapons + pool_type: PoolTypeOption + guaranteed_items: GuaranteedItemsOption + auto_equip: AutoEquipOption + lock_equip: LockEquipOption + no_weapon_requirements: NoWeaponRequirementsOption + 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 + late_basin_of_vows: LateBasinOfVowsOption + late_dlc: LateDLCOption + no_spell_requirements: NoSpellRequirementsOption + no_equip_load: NoEquipLoadOption + death_link: DeathLink + enable_dlc: EnableDLCOption + enable_ngp: EnableNGPOption + exclude_locations: DS3ExcludeLocations diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 3e74f3848985..f313e745b4e9 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -10,7 +10,7 @@ from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, UsefulIf, filler_item_names, item_dictionary from .Locations import DarkSouls3Location, DS3LocationCategory, DS3LocationData, location_tables, location_dictionary, location_name_groups -from .Options import RandomizeWeaponLevelOption, PoolTypeOption, dark_souls_options +from .Options import DarkSouls3Options, RandomizeWeaponLevelOption, PoolTypeOption class DarkSouls3Web(WebWorld): @@ -44,7 +44,8 @@ class DarkSouls3World(World): """ game: str = "Dark Souls III" - option_definitions = dark_souls_options + options: DarkSouls3Options + options_dataclass = DarkSouls3Options topology_present: bool = True web = DarkSouls3Web() data_version = 8 @@ -83,10 +84,14 @@ def generate_early(self): self.enabled_location_categories.add(DS3LocationCategory.RING) if self.multiworld.enable_spell_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.SPELL) + if self.multiworld.enable_upgrade_locations[self.player] == Toggle.option_true: + self.enabled_location_categories.add(DS3LocationCategory.UPGRADE) if self.multiworld.enable_key_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.KEY) if self.multiworld.enable_boss_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.BOSS) + if self.multiworld.enable_unique_locations[self.player] == Toggle.option_true: + self.enabled_location_categories.add(DS3LocationCategory.UNIQUE) if self.multiworld.enable_misc_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.MISC) self.enabled_location_categories.add(DS3LocationCategory.UPGRADE) @@ -236,10 +241,10 @@ def create_items(self): if not self.__is_location_available(location.name): raise Exception("DS3 generation bug: Added an unavailable location.") - item_category = item_dictionary[location.default_item_name].category - if item_category == DS3ItemCategory.SKIP: + item = item_dictionary[location.default_item_name] + if item.category == DS3ItemCategory.SKIP: num_required_extra_items += 1 - elif item_category == DS3ItemCategory.MISC: + elif item.category == DS3ItemCategory.MISC or item.force_unique: itempool_by_category[location.category].append(location.default_item_name) else: # For non-miscellaneous non-skip items, make sure there aren't duplicates in the @@ -453,6 +458,8 @@ def set_rules(self) -> None: # Define the access rules to some specific locations set_rule(self.multiworld.get_location("PC: Cinders of a Lord - Yhorm the Giant", self.player), lambda state: state.has("Storm Ruler", self.player)) + set_rule(self.multiworld.get_location("HWL: Red Eye Orb", self.player), + lambda state: state.has("Lift Chamber Key", self.player)) if self.multiworld.enable_ring_locations[self.player] == Toggle.option_true: set_rule(self.multiworld.get_location("ID: Bellowing Dragoncrest Ring", self.player), @@ -472,13 +479,14 @@ def set_rules(self) -> None: set_rule(self.multiworld.get_entrance("Go To Karla's Shop", self.player), lambda state: state.has("Jailer's Key Ring", self.player)) - if self.multiworld.enable_misc_locations[self.player] == Toggle.option_true: - set_rule(self.multiworld.get_location("HWL: Red Eye Orb", self.player), - lambda state: state.has("Lift Chamber Key", self.player)) for item in ["Leonhard's Garb", "Leonhard's Gauntlets", "Leonhard's Trousers"]: set_rule(self.multiworld.get_location("AL: " + item, self.player), lambda state: state.has("Black Eye Orb", self.player)) - + + # You could just kill NPCs for these, but it's more fun to ensure the player can do + # their quests. + set_rule(self.multiworld.get_location("FS: Lift Chamber Key", self.player), + lambda state: state.has("Pale Tongue", self.player)) if self.multiworld.enable_misc_locations[self.player] == Toggle.option_true: set_rule(self.multiworld.get_location("AP: Hawkwood's Swordgrass", self.player), From 2e89c2ba98320c637e342741dfc449cd8cd83b56 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 29 Oct 2023 20:49:36 -0700 Subject: [PATCH 032/238] 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. --- Generate.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Generate.py b/Generate.py index 08fe2b908335..9f66ef9fe463 100644 --- a/Generate.py +++ b/Generate.py @@ -411,19 +411,19 @@ def roll_triggers(weights: dict, triggers: list) -> dict: def handle_option(ret: argparse.Namespace, game_weights: dict, option_key: str, option: type(Options.Option), plando_options: PlandoOptions): - if option_key in game_weights: - try: + try: + if option_key in game_weights: if not option.supports_weighting: player_option = option.from_any(game_weights[option_key]) else: player_option = option.from_any(get_choice(option_key, game_weights)) - setattr(ret, option_key, player_option) - except Exception as e: - raise Exception(f"Error generating option {option_key} in {ret.game}") from e else: - player_option.verify(AutoWorldRegister.world_types[ret.game], ret.name, plando_options) + player_option = option.from_any(option.default) # call the from_any here to support default "random" + setattr(ret, option_key, player_option) + except Exception as e: + raise Exception(f"Error generating option {option_key} in {ret.game}") from e else: - setattr(ret, option_key, option.from_any(option.default)) # call the from_any here to support default "random" + player_option.verify(AutoWorldRegister.world_types[ret.game], ret.name, plando_options) def roll_settings(weights: dict, plando_options: PlandoOptions = PlandoOptions.bosses): From 14f56abed577287bd781478c63edb85b5bd93646 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 30 Oct 2023 00:33:25 -0700 Subject: [PATCH 033/238] Make a few more improvements and fixes --- worlds/dark_souls_3/Items.py | 8 +++++--- worlds/dark_souls_3/Locations.py | 12 +++--------- worlds/dark_souls_3/__init__.py | 5 +++++ 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 29a87f317b7f..2f18bbd3f99b 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -329,7 +329,8 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou DS3ItemData("Sunless Talisman", 0x00CAA300, DS3ItemCategory.WEAPON_UPGRADE_5), DS3ItemData("Saint's Talisman", 0x00CACA10, DS3ItemCategory.WEAPON_UPGRADE_10), DS3ItemData("White Hair Talisman", 0x00CAF120, DS3ItemCategory.WEAPON_UPGRADE_5), - DS3ItemData("Pyromancy Flame", 0x00CC77C0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Pyromancy Flame", 0x00CC77C0, DS3ItemCategory.WEAPON_UPGRADE_10, + classification = ItemClassification.useful), DS3ItemData("Dragonslayer Greatbow", 0x00CF8500, DS3ItemCategory.WEAPON_UPGRADE_5), DS3ItemData("Short Bow", 0x00D5C690, DS3ItemCategory.WEAPON_UPGRADE_10), DS3ItemData("Composite Bow", 0x00D5EDA0, DS3ItemCategory.WEAPON_UPGRADE_10), @@ -828,7 +829,7 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou DS3ItemData("Sun Princess Ring", 0x20004FBA, DS3ItemCategory.RING), DS3ItemData("Silvercat Ring", 0x20004FC4, DS3ItemCategory.RING), DS3ItemData("Skull Ring", 0x20004FCE, DS3ItemCategory.RING), - DS3ItemData("Untrue White Ring", 0x20004FD8, DS3ItemCategory.RING), + DS3ItemData("Untrue White Ring", 0x20004FD8, DS3ItemCategory.SKIP), DS3ItemData("Carthus Milkring", 0x20004FE2, DS3ItemCategory.RING), DS3ItemData("Knight's Ring", 0x20004FEC, DS3ItemCategory.RING), DS3ItemData("Hunter's Ring", 0x20004FF6, DS3ItemCategory.RING), @@ -1089,7 +1090,8 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou DS3ItemData("Sage's Scroll", 0x40000854, DS3ItemCategory.MISC), DS3ItemData("Logan's Scroll", 0x40000855, DS3ItemCategory.MISC), DS3ItemData("Crystal Scroll", 0x40000856, DS3ItemCategory.MISC), - DS3ItemData("Transposing Kiln", 0x40000857, DS3ItemCategory.MISC), + DS3ItemData("Transposing Kiln", 0x40000857, DS3ItemCategory.MISC, + classification = ItemClassification.useful), DS3ItemData("Coiled Sword", 0x40000859, DS3ItemCategory.SKIP), # Useless DS3ItemData("Eyes of a Fire Keeper", 0x4000085A, DS3ItemCategory.KEY), DS3ItemData("Sword of Avowal", 0x4000085B, DS3ItemCategory.KEY), diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 4cc0c8ec4efb..2ff786f11bb0 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -591,7 +591,9 @@ def get_name_to_id() -> dict: DS3LocationData("US: Fire Clutch Ring", "Fire Clutch Ring", DS3LocationCategory.RING), DS3LocationData("US: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), DS3LocationData("US: Firebomb", "Firebomb x6", DS3LocationCategory.MISC), - DS3LocationData("US: Whip", "Whip", DS3LocationCategory.WEAPON), + DS3LocationData("US: Whip", "Whip", DS3LocationCategory.WEAPON, + hidden = True), # In enemy rando, the enemy may not burst through the wall + # and make this room obvious DS3LocationData("US: Great Scythe", "Great Scythe", DS3LocationCategory.WEAPON), DS3LocationData("US: Homeward Bone #3", "Homeward Bone x2", DS3LocationCategory.MISC), DS3LocationData("US: Large Soul of a Deserted Corpse #3", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC), @@ -680,14 +682,6 @@ def get_name_to_id() -> dict: npc = True, shop = True), DS3LocationData("US: Flash Sweat", "Flash Sweat", DS3LocationCategory.SPELL, npc = True, shop = True), - DS3LocationData("US: Pyromancer Crown", "Pyromancer Crown", DS3LocationCategory.ARMOR, - npc = True, shop = True), - DS3LocationData("US: Pyromancer Garb", "Pyromancer Garb", DS3LocationCategory.ARMOR, - npc = True, shop = True), - DS3LocationData("US: Pyromancer Wrap", "Pyromancer Wrap", DS3LocationCategory.ARMOR, - npc = True, shop = True), - DS3LocationData("US: Pyromancer Trousers", "Pyromancer Trousers", DS3LocationCategory.ARMOR, - npc = True, shop = True), # These are missable if you kill Cornyx before giving him the right tomes. DS3LocationData("US: Poison Mist", "Poison Mist", DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index f313e745b4e9..7d9be4fb2d95 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -76,6 +76,8 @@ def __init__(self, multiworld: MultiWorld, player: int): def generate_early(self): if self.multiworld.enable_weapon_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.WEAPON) + # Always make this available early because so many items are useless without it. + self.multiworld.early_items[self.player]['Pyromancy Flame'] = 1 if self.multiworld.enable_shield_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.SHIELD) if self.multiworld.enable_armor_locations[self.player] == Toggle.option_true: @@ -92,8 +94,11 @@ def generate_early(self): self.enabled_location_categories.add(DS3LocationCategory.BOSS) if self.multiworld.enable_unique_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.UNIQUE) + # Make this available early just because it's fun to be able to check boss souls early. + self.multiworld.early_items[self.player]['Transposing Kiln'] = 1 if self.multiworld.enable_misc_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.MISC) + if self.multiworld.enable_upgrade_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.UPGRADE) if self.multiworld.enable_health_upgrade_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.HEALTH) From 4c21a8953d4ff6c6f6ab1a5dc835275084a4562b Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 30 Oct 2023 01:54:22 -0700 Subject: [PATCH 034/238] Randomize Path of the Dragon --- worlds/dark_souls_3/Items.py | 4 ++++ worlds/dark_souls_3/__init__.py | 26 +++++++++++++++++--------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 2f18bbd3f99b..2f9a358774a4 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -1115,6 +1115,10 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou DS3ItemData("Easterner's Ashes", 0x40000868, DS3ItemCategory.MISC, classification = ItemClassification.progression), + # Fake item supported by the offline randomizer for controlling access to Archdragon Peak + DS3ItemData("Path of the Dragon", 0x40002346, DS3ItemCategory.KEY, + classification = ItemClassification.progression), + # Spells DS3ItemData("Farron Dart", 0x40124F80, DS3ItemCategory.SPELL), DS3ItemData("Great Farron Dart", 0x40127690, DS3ItemCategory.SPELL), diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 7d9be4fb2d95..4819cbe3fbc2 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -103,6 +103,9 @@ def generate_early(self): if self.multiworld.enable_health_upgrade_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.HEALTH) + # The offline randomizer's clever code for converting an item into a gesture only works for + # items in the local world. + self.multiworld.local_items[self.player].value.add("Path of the Dragon") def create_regions(self): # Create Vanilla Regions @@ -133,11 +136,6 @@ def create_regions(self): "Karla's Shop", ]}) - # Adds Path of the Dragon as an event item for Archdragon Peak access - potd_location = DarkSouls3Location(self.player, "CKG: Path of the Dragon", DS3LocationCategory.EVENT, "Path of the Dragon", None, regions["Consumed King's Garden"]) - potd_location.place_locked_item(Item("Path of the Dragon", ItemClassification.progression, None, self.player)) - regions["Consumed King's Garden"].locations.append(potd_location) - # Create DLC Regions if self.multiworld.enable_dlc[self.player]: regions.update({region_name: self.create_region(region_name, location_tables[region_name]) for region_name in [ @@ -308,11 +306,15 @@ def create_random_replacement_list(item_categories: Set[DS3ItemCategory], num_it # A list of items we can replace removable_items = [item for item in itempool if item.classification == ItemClassification.filler] - guaranteed_items = self.multiworld.guaranteed_items[self.player].value + guaranteed_items = {"Path of the Dragon": 1} + guaranteed_items.update(self.multiworld.guaranteed_items[self.player].value) + if len(removable_items) == 0 and num_required_extra_items == 0: + raise Exception("Can't add Path of the Dragon to the item pool") + for item_name in guaranteed_items: # Break early just in case nothing is removable (if user is trying to guarantee more # items than the pool can hold, for example) - if len(removable_items) == 0: + if len(removable_items) == 0 and num_required_extra_items == 0: break num_existing_copies = len([item for item in itempool if item.name == item_name]) @@ -322,7 +324,7 @@ def create_random_replacement_list(item_categories: Set[DS3ItemCategory], num_it continue if num_required_extra_items > 0: - # We can just add them instead of using "Soul of an Intrepid Hero" later + # We can just add them instead of using filler later num_required_extra_items -= 1 else: if len(removable_items) == 0: @@ -530,6 +532,12 @@ def set_rules(self) -> None: (item.count == 1 and not item.soul) )) + add_item_rule(self.multiworld.get_location(location.name, self.player), + lambda item: ( + item.player != self.player or + (item.count == 1 and not item.soul) + )) + self.multiworld.completion_condition[self.player] = lambda state: \ state.has("Cinders of a Lord - Abyss Watcher", self.player) and \ state.has("Cinders of a Lord - Yhorm the Giant", self.player) and \ @@ -544,7 +552,7 @@ def __is_location_available(self, location: Union[str, DS3LocationData]): elif location in location_dictionary: data = location_dictionary[location] else: - # Synthetic locations (like Path of the Dragon) are never considered available. + # Synthetic locations are never considered available. return False return ( From 5b90763f306e5e76ccbacaa1dcd31b09e5993cde Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 30 Oct 2023 17:25:12 -0700 Subject: [PATCH 035/238] 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. --- worlds/dark_souls_3/Items.py | 53 ++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 2f9a358774a4..05fbabfec859 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -869,7 +869,8 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou DS3ItemData("Red Eye Orb", 0x40000066, DS3ItemCategory.SKIP), DS3ItemData("Roster of Knights", 0x4000006C, DS3ItemCategory.SKIP), DS3ItemData("Cracked Red Eye Orb", 0x4000006F, DS3ItemCategory.SKIP).counts([5]), - DS3ItemData("Black Eye Orb", 0x40000073, DS3ItemCategory.KEY), + DS3ItemData("Black Eye Orb", 0x40000073, DS3ItemCategory.KEY, + classification = ItemClassification.useful), DS3ItemData("Divine Blessing", 0x400000F0, DS3ItemCategory.MISC), DS3ItemData("Hidden Blessing", 0x400000F1, DS3ItemCategory.MISC), DS3ItemData("Green Blossom", 0x40000104, DS3ItemCategory.MISC, filler = True).counts([2, 3, 4]), @@ -915,6 +916,7 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou DS3ItemData("Binoculars", 0x40000173, DS3ItemCategory.MISC), DS3ItemData("Proof of a Concord Kept", 0x40000174, DS3ItemCategory.SKIP), DS3ItemData("Pale Tongue", 0x40000175, DS3ItemCategory.MISC, + classification = ItemClassification.useful, force_unique = True), # One is needed for Leonhard's quest DS3ItemData("Vertebra Shackle", 0x40000176, DS3ItemCategory.MISC, force_unique = True), # Allow one of these to trade to the crow @@ -1050,10 +1052,14 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou classification = ItemClassification.progression), DS3ItemData("Small Lothric Banner", 0x40000836, DS3ItemCategory.KEY, classification = ItemClassification.progression), - DS3ItemData("Farron Coal", 0x40000837, DS3ItemCategory.MISC), - DS3ItemData("Sage's Coal", 0x40000838, DS3ItemCategory.MISC), - DS3ItemData("Giant's Coal", 0x40000839, DS3ItemCategory.MISC), - DS3ItemData("Profaned Coal", 0x4000083A, DS3ItemCategory.MISC), + DS3ItemData("Farron Coal", 0x40000837, DS3ItemCategory.MISC, + classification = ItemClassification.useful), + DS3ItemData("Sage's Coal", 0x40000838, DS3ItemCategory.MISC, + classification = ItemClassification.useful), + DS3ItemData("Giant's Coal", 0x40000839, DS3ItemCategory.MISC, + classification = ItemClassification.useful), + DS3ItemData("Profaned Coal", 0x4000083A, DS3ItemCategory.MISC, + classification = ItemClassification.useful), DS3ItemData("Mortician's Ashes", 0x4000083B, DS3ItemCategory.MISC, classification = ItemClassification.progression), DS3ItemData("Dreamchaser's Ashes", 0x4000083C, DS3ItemCategory.MISC, @@ -1072,8 +1078,10 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou classification = ItemClassification.progression), DS3ItemData("Loretta's Bone", 0x40000846, DS3ItemCategory.KEY, classification = ItemClassification.useful), - DS3ItemData("Braille Divine Tome of Carim", 0x40000847, DS3ItemCategory.MISC), - DS3ItemData("Braille Divine Tome of Lothric", 0x40000848, DS3ItemCategory.MISC), + DS3ItemData("Braille Divine Tome of Carim", 0x40000847, DS3ItemCategory.MISC, + classification = ItemClassification.useful), + DS3ItemData("Braille Divine Tome of Lothric", 0x40000848, DS3ItemCategory.MISC, + classification = ItemClassification.useful), DS3ItemData("Cinders of a Lord - Abyss Watcher", 0x4000084B, DS3ItemCategory.KEY, classification = ItemClassification.progression), DS3ItemData("Cinders of a Lord - Aldrich", 0x4000084C, DS3ItemCategory.KEY, @@ -1082,20 +1090,31 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou classification = ItemClassification.progression), DS3ItemData("Cinders of a Lord - Lothric Prince", 0x4000084E, DS3ItemCategory.KEY, classification = ItemClassification.progression), - DS3ItemData("Great Swamp Pyromancy Tome", 0x4000084F, DS3ItemCategory.MISC), - DS3ItemData("Carthus Pyromancy Tome", 0x40000850, DS3ItemCategory.MISC), - DS3ItemData("Izalith Pyromancy Tome", 0x40000851, DS3ItemCategory.MISC), - DS3ItemData("Quelana Pyromancy Tome", 0x40000852, DS3ItemCategory.MISC), - DS3ItemData("Grave Warden Pyromancy Tome", 0x40000853, DS3ItemCategory.MISC), - DS3ItemData("Sage's Scroll", 0x40000854, DS3ItemCategory.MISC), - DS3ItemData("Logan's Scroll", 0x40000855, DS3ItemCategory.MISC), - DS3ItemData("Crystal Scroll", 0x40000856, DS3ItemCategory.MISC), + DS3ItemData("Great Swamp Pyromancy Tome", 0x4000084F, DS3ItemCategory.MISC, + classification = ItemClassification.useful), + DS3ItemData("Carthus Pyromancy Tome", 0x40000850, DS3ItemCategory.MISC, + classification = ItemClassification.useful), + DS3ItemData("Izalith Pyromancy Tome", 0x40000851, DS3ItemCategory.MISC, + classification = ItemClassification.useful), + DS3ItemData("Quelana Pyromancy Tome", 0x40000852, DS3ItemCategory.MISC, + classification = ItemClassification.useful), + DS3ItemData("Grave Warden Pyromancy Tome", 0x40000853, DS3ItemCategory.MISC, + classification = ItemClassification.useful), + DS3ItemData("Sage's Scroll", 0x40000854, DS3ItemCategory.MISC, + classification = ItemClassification.useful), + DS3ItemData("Logan's Scroll", 0x40000855, DS3ItemCategory.MISC, + classification = ItemClassification.useful), + DS3ItemData("Crystal Scroll", 0x40000856, DS3ItemCategory.MISC, + classification = ItemClassification.useful), DS3ItemData("Transposing Kiln", 0x40000857, DS3ItemCategory.MISC, classification = ItemClassification.useful), DS3ItemData("Coiled Sword", 0x40000859, DS3ItemCategory.SKIP), # Useless - DS3ItemData("Eyes of a Fire Keeper", 0x4000085A, DS3ItemCategory.KEY), + DS3ItemData("Eyes of a Fire Keeper", 0x4000085A, DS3ItemCategory.KEY, + classification = ItemClassification.useful), # Allow players to do any ending DS3ItemData("Sword of Avowal", 0x4000085B, DS3ItemCategory.KEY), - DS3ItemData("Golden Scroll", 0x4000085C, DS3ItemCategory.MISC), + classification = ItemClassification.useful, + DS3ItemData("Golden Scroll", 0x4000085C, DS3ItemCategory.MISC, + classification = ItemClassification.useful), DS3ItemData("Estus Shard", 0x4000085D, DS3ItemCategory.MISC, classification = ItemClassification.useful), DS3ItemData("Hawkwood's Swordgrass", 0x4000085E, DS3ItemCategory.SKIP), From e08ac9e9d58dde24172169c5f18afbe489a51673 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 30 Oct 2023 17:43:15 -0700 Subject: [PATCH 036/238] Guarantee more NPC quests are completable --- worlds/dark_souls_3/Items.py | 8 ++++---- worlds/dark_souls_3/__init__.py | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 05fbabfec859..57791c489e84 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -1101,11 +1101,11 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou DS3ItemData("Grave Warden Pyromancy Tome", 0x40000853, DS3ItemCategory.MISC, classification = ItemClassification.useful), DS3ItemData("Sage's Scroll", 0x40000854, DS3ItemCategory.MISC, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Logan's Scroll", 0x40000855, DS3ItemCategory.MISC, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Crystal Scroll", 0x40000856, DS3ItemCategory.MISC, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Transposing Kiln", 0x40000857, DS3ItemCategory.MISC, classification = ItemClassification.useful), DS3ItemData("Coiled Sword", 0x40000859, DS3ItemCategory.SKIP), # Useless @@ -1114,7 +1114,7 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou DS3ItemData("Sword of Avowal", 0x4000085B, DS3ItemCategory.KEY), classification = ItemClassification.useful, DS3ItemData("Golden Scroll", 0x4000085C, DS3ItemCategory.MISC, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Estus Shard", 0x4000085D, DS3ItemCategory.MISC, classification = ItemClassification.useful), DS3ItemData("Hawkwood's Swordgrass", 0x4000085E, DS3ItemCategory.SKIP), diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 4819cbe3fbc2..0985fa77fa9f 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -495,12 +495,27 @@ def set_rules(self) -> None: set_rule(self.multiworld.get_location("FS: Lift Chamber Key", self.player), lambda state: state.has("Pale Tongue", self.player)) - if self.multiworld.enable_misc_locations[self.player] == Toggle.option_true: + if self.multiworld.enable_unique_locations[self.player] == Toggle.option_true: set_rule(self.multiworld.get_location("AP: Hawkwood's Swordgrass", self.player), lambda state: state.has("Twinkling Dragon Torso Stone", self.player)) set_rule(self.multiworld.get_location("ID: Prisoner Chief's Ashes", self.player), lambda state: state.has("Jailer's Key Ring", self.player)) + # Make sure that the player can keep Orbeck around by giving him at least one scroll + # before killing Abyss Watchers. + def has_any_scroll(state): + return (state.has("Sage's Scroll", self.player) or + state.has("Golden Scroll", self.player) or + state.has("Logan's Scroll", self.player) or + state.has("Crystal Scroll", self.player)) + if self.multiworld.enable_boss_locations[self.player] == Toggle.option_true: + set_rule(self.multiworld.get_location("FK: Soul of the Blood of the Wolf", self.player), + has_any_scroll) + set_rule(self.multiworld.get_location("FK: Cinders of a Lord - Abyss Watcher", self.player), + has_any_scroll) + set_rule(self.multiworld.get_entrance("Catacombs of Carthus", self.player), + has_any_scroll) + if self.multiworld.enable_boss_locations[self.player] == Toggle.option_true: set_rule(self.multiworld.get_location("PC: Soul of Yhorm the Giant", self.player), lambda state: state.has("Storm Ruler", self.player)) From 8513de4acb8899330c3ef3d65ce991898621476e Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 30 Oct 2023 23:59:15 -0700 Subject: [PATCH 037/238] Fix a syntax error --- worlds/dark_souls_3/Items.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 57791c489e84..4527f285a359 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -1111,8 +1111,8 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou DS3ItemData("Coiled Sword", 0x40000859, DS3ItemCategory.SKIP), # Useless DS3ItemData("Eyes of a Fire Keeper", 0x4000085A, DS3ItemCategory.KEY, classification = ItemClassification.useful), # Allow players to do any ending - DS3ItemData("Sword of Avowal", 0x4000085B, DS3ItemCategory.KEY), - classification = ItemClassification.useful, + DS3ItemData("Sword of Avowal", 0x4000085B, DS3ItemCategory.KEY, + classification = ItemClassification.useful), DS3ItemData("Golden Scroll", 0x4000085C, DS3ItemCategory.MISC, classification = ItemClassification.progression), DS3ItemData("Estus Shard", 0x4000085D, DS3ItemCategory.MISC, From bad85bfa558a05b9db62b51ee55620ae69a933b7 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 31 Oct 2023 00:04:07 -0700 Subject: [PATCH 038/238] Fix rule definition --- worlds/dark_souls_3/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 0985fa77fa9f..bcad994d667b 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -513,7 +513,7 @@ def has_any_scroll(state): has_any_scroll) set_rule(self.multiworld.get_location("FK: Cinders of a Lord - Abyss Watcher", self.player), has_any_scroll) - set_rule(self.multiworld.get_entrance("Catacombs of Carthus", self.player), + set_rule(self.multiworld.get_entrance("Go To Catacombs of Carthus", self.player), has_any_scroll) if self.multiworld.enable_boss_locations[self.player] == Toggle.option_true: From a86d3f322d33ddd10869543b4add6635da73a802 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 31 Oct 2023 19:22:57 -0700 Subject: [PATCH 039/238] Support enemy randomization --- worlds/dark_souls_3/Options.py | 93 +++++++++++++++++++++++++++++++++ worlds/dark_souls_3/__init__.py | 18 +++++-- 2 files changed, 108 insertions(+), 3 deletions(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 0b68f7ed240c..a57f21420169 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -226,6 +226,91 @@ class EnableNGPOption(Toggle): display_name = "Enable NG+" +class RandomizeEnemiesOption(DefaultOnToggle): + """Whether to randomize enemy and boss placements. + + If this is enabled, the Storm Ruler sword is granted immediately upon meeting Yhorm the Giant + instead of being randomized into the world. + """ + display_name = "Randomize Enemies" + + +class RandomizeMimicsWithEnemiesOption(Toggle): + """Whether to 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 Mimcs as well if you enable this. + + This is ignored unless enemies are randomized. + """ + display_name = "Randomize Mimics With Enemies" + + +class RandomizeSmallCrystalLizardsWithEnemiesOption(Toggle): + """Whether to 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): + """Whether to 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 SimpleEarlyBossesOption(DefaultOnToggle): + """Whether to 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): + """Whether to 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 AllChestsAreMimicsOption(Toggle): + """Whether to 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): + """Whether mimics should attack as soon as you get close. + + This is ignored unless enemies are randomized. + """ + display_name = "All Chests Are Mimics" + + class DS3ExcludeLocations(ExcludeLocations): """Prevent these locations from having an important item""" default = {"Hidden", "Small Crystal Lizards", "Miscellaneous"} @@ -267,4 +352,12 @@ class DarkSouls3Options(PerGameCommonOptions): death_link: DeathLink enable_dlc: EnableDLCOption enable_ngp: EnableNGPOption + randomize_enemies: RandomizeEnemiesOption + randomize_mimics_with_enemies: RandomizeMimicsWithEnemiesOption + randomize_small_crystal_lizards_with_enemies: RandomizeSmallCrystalLizardsWithEnemiesOption + reduce_harmless_enemies: ReduceHarmlessEnemiesOption + simple_early_bosses: SimpleEarlyBossesOption + scale_enemies: ScaleEnemiesOption + all_chests_are_mimics: AllChestsAreMimicsOption + impatient_mimics: ImpatientMimicsOption exclude_locations: DS3ExcludeLocations diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index bcad994d667b..64ae8278ac75 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -245,7 +245,10 @@ def create_items(self): raise Exception("DS3 generation bug: Added an unavailable location.") item = item_dictionary[location.default_item_name] - if item.category == DS3ItemCategory.SKIP: + if item.category == DS3ItemCategory.SKIP or ( + self.multiworld.randomize_enemies[self.player] == Toggle.option_true and + item.name == "Storm Ruler" + ): num_required_extra_items += 1 elif item.category == DS3ItemCategory.MISC or item.force_unique: itempool_by_category[location.category].append(location.default_item_name) @@ -463,8 +466,9 @@ def set_rules(self) -> None: lambda state: state.has("Small Doll", self.player)) # Define the access rules to some specific locations - set_rule(self.multiworld.get_location("PC: Cinders of a Lord - Yhorm the Giant", self.player), - lambda state: state.has("Storm Ruler", self.player)) + if self.multiworld.randomize_enemies[self.player] == Toggle.option_false: + set_rule(self.multiworld.get_location("PC: Cinders of a Lord - Yhorm the Giant", self.player), + lambda state: state.has("Storm Ruler", self.player)) set_rule(self.multiworld.get_location("HWL: Red Eye Orb", self.player), lambda state: state.has("Lift Chamber Key", self.player)) @@ -651,6 +655,14 @@ def fill_slot_data(self) -> Dict[str, object]: "no_equip_load": self.multiworld.no_equip_load[self.player].value, "enable_dlc": self.multiworld.enable_dlc[self.player].value, "enable_ngp": self.multiworld.enable_ngp[self.player].value, + "randomize_enemies": self.multiworld.randomize_enemies[self.player].value, + "randomize_mimics_with_enemies": self.multiworld.randomize_mimics_with_enemies[self.player].value, + "randomize_small_crystal_lizards_with_enemies": self.multiworld.randomize_small_crystal_lizards_with_enemies[self.player].value, + "reduce_harmless_enemies": self.multiworld.reduce_harmless_enemies[self.player].value, + "simple_early_bosses": self.multiworld.simple_early_bosses[self.player].value, + "scale_enemies": self.multiworld.scale_enemies[self.player].value, + "all_chests_are_mimics": self.multiworld.all_chests_are_mimics[self.player].value, + "impatient_mimics": self.multiworld.impatient_mimics[self.player].value, }, "seed": self.multiworld.seed_name, # to verify the server's multiworld "slot": self.multiworld.player_name[self.player], # to connect to server From a3a9c5e1cbff9b32fd658b5e198847c3a4072575 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 31 Oct 2023 22:04:13 -0700 Subject: [PATCH 040/238] Support online Yhorm randomization --- worlds/dark_souls_3/Bosses.py | 197 +++++++++++++++++++++ worlds/dark_souls_3/Locations.py | 20 ++- worlds/dark_souls_3/__init__.py | 56 +++++- worlds/dark_souls_3/test/TestDarkSouls3.py | 13 ++ 4 files changed, 270 insertions(+), 16 deletions(-) create mode 100644 worlds/dark_souls_3/Bosses.py diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py new file mode 100644 index 000000000000..bd6cec44aef9 --- /dev/null +++ b/worlds/dark_souls_3/Bosses.py @@ -0,0 +1,197 @@ +# In almost all cases, we leave boss and enemy randomization up to the offline 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 Optional, Set + +@dataclass +class DS3BossInfo: + """The set of locations and regions 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.""" + + region: Optional[str] = None + """The name the region that can't be accessed until the boss is dead, if one exists.""" + + locations: Optional[str] = field(default_factory=set) + """Additional individual locations that can't be accessed until the boss is dead.""" + + +# Note: the offline 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, region = "Firelink Shrine"), + DS3BossInfo("Vordt of the Boreal Valley", 3000800, region = "Undead Settlement", + locations = {"HWL: Soul of Boreal Valley Vordt"}), + DS3BossInfo("Curse-Rotted Greatwood", 3100800, locations = { + "US: Soul of the Rotted Greatwood", + "US: Transposing Kiln", + "US: Wargod Wooden Shield", + }), + DS3BossInfo("Crystal Sage", 3300850, region = "Cathedral of the Deep", locations = { + "RS: Soul of a Crystal Sage", + "RS: Sage's Big Hat", + }), + DS3BossInfo("Deacons of the Deep", 3500800, locations = { + "CD: Soul of the Deacons of the Deep", + "CD: Small Doll", + }), + DS3BossInfo("Abyss Watchers", 3300801, region = "Catacombs of Carthus", locations = { + "FK: Soul of the Blood of the Wolf", + "FK: Cinders of a Lord - Abyss Watchers", + "UG: Hornet Ring", + "FK: Undead Legion Helm", + "FK: Undead Legion Armor", + "FK: Undead Legion Gauntlet", + "FK: Undead Legion Leggings", + "UG: Wolf Knight Helm", + "UG: Wolf Knight Armor", + "UG: Wolf Knight Gauntlet", + "UG: Wolf Knight Leggings", + }), + DS3BossInfo("High Lord Wolnir", 3800800, region = "Irithyll of the Boreal Valley", locations = { + "CC: Soul of High Lord Wolnir", + "CC: Wolnir's Crown", + "CC: Homeward Bone", + "CC: Pontiff's Right Eye", + }), + DS3BossInfo("Pontiff Sulyvahn", 3700850, region = "Anor Londo", locations = { + "IBV: Soul of Ponyiff Sulyvahn", + }), + DS3BossInfo("Old Demon King", 3800830, locations = { + "SL: Soul of the Old Demon King", + }), + DS3BossInfo("Aldrich, Devourer of Men", 3700800, locations = { + "AL: Soul of Aldrich", + "AL: Cinders of a Lord - Aldrich", + "AL: Smough's Helm", + "AL: Smough's Armor", + "AL: Smough's Gauntlets", + "AL: Smough's Leggings", + "AL: Sun Princess Ring", + }), + DS3BossInfo("Dancer of the Boreal Valley", 3000899, region = "Lothric Castle", locations = { + "HWL: Soul of the Dancer", + }), + DS3BossInfo("Dragonslayer Armour", 3010800, region = "Grand Archives", locations = { + "LC: Soul of Dragonslayer Armour", + "LC: Morne's Helm", + "LC: Morne's Armor", + "LC: Morne's Gauntlets", + "LC: Morne's Leggings", + "LC: Titanite Chunk #11", + }), + DS3BossInfo("Consumed King Oceiros", 3000830, region = "Untended Graves", locations = { + "CKG: Soul of Consumed Oceiros", + "CKG: Titanite Scale #2", + "CKG: Titanite Scale #3", + }), + DS3BossInfo("Champion Gundyr", 4000830, locations = { + "UG: Soul of Champion Gundyr", + "UG: Gundyr's Helm", + "UG: Gundyr's Armor", + "UG: Gundyr's Gauntlets", + "UG: Gundyr's Leggings", + "UG: Hornet Ring", + "UG: Chaos Blade", + "UG: Blacksmith Hammer", + "UG: Eyes of a Fire Keeper", + "UG: Coiled Sword Fragment", + "UG: Soul of a Crestfallen Knight #2", + "UG: Life Ring+3", + "UG: Ring of Steel Protection+1", + "UG: Ring of Sacrifice", + "UG: Ring of Sacrifice", + "UG: Ember", + "UG: Wolf Knight Helm", + "UG: Wolf Knight Armor", + "UG: Wolf Knight Gauntlet", + "UG: Wolf Knight Leggings", + }), + # This is a white lie, you can get to a bunch of items in AP before you beat the Wyvern, but + # this saves us from having to split the entire region in two just to mark which specific items + # are before and after. + DS3BossInfo("Ancient Wyvern", 3200800, region = {"Archdragon Peak"}), + DS3BossInfo("King of the Storm", 3200850, locations = { + "AP: Soul of the Nameless King", + "AP: Golden Crown", + "AP: Dragonscale Armor", + "AP: Golden Bracelets", + "AP: Dragonscale Waistcloth", + "AP: Titanite Slab #2", + + }), + DS3BossInfo("Nameless King", 3200851, locations = { + "AP: Soul of the Nameless King", + "AP: Golden Crown", + "AP: Dragonscale Armor", + "AP: Golden Bracelets", + "AP: Dragonscale Waistcloth", + "AP: Dragonslayer Helm", + "AP: Dragonslayer Armor", + "AP: Dragonslayer Gauntlets", + "AP: Dragonslayer Leggings", + }), + DS3BossInfo("Lorian, Elder Prince", 3410830, locations = { + "GA: Soul of the Twin Princes", + "GA: Cinders of a Lord - Twin Princes", + }), + DS3BossInfo("Lothric, Younger Prince", 3410832, locations = { + "GA: Soul of the Twin Princes", + "GA: Cinders of a Lord - Twin Princes", + "GA: Lorian's Helm", + "GA: Lorian's Armor", + "GA: Lorian's Gauntlets", + "GA: Lorian's Leggings", + }), + DS3BossInfo("Champion's Gravetender and Gravetender Greatwolf", 4500860, dlc = True, locations = { + "PW1: Valorheart", + "PW1: Champion's Bones", + }), + DS3BossInfo("Sister Friede", 4500801, dlc = True, region = "Dreg Heap", locations = { + "PW2: Soul of Sister Friede", + "PW2: Titanite Slab (Friede)", + "PW2: Ordained Hood", + "PW2: Ordained Dress", + "PW2: Ordained Trousers", + }), + DS3BossInfo("Blackflame Friede", 5000801, dlc = True, region = "Ringed City", locations = { + "PW2: Soul of Sister Friede", + "PW2: Ordained Hood", + "PW2: Ordained Dress", + "PW2: Ordained Trousers", + }), + DS3BossInfo("Demon Prince", 4500800, dlc = True, region = "Dreg Heap", locations = { + "DH: Soul of the Demon Prince", + "DH: Small Envoy Banner", + }), + DS3BossInfo("Halflight, Spear of the Church", 5100800, dlc = True, region = "Ringed City", locations = { + "RC: Titanite Slab #1", + "RC: Titanite Slab #2", + "RC: Titanite Slab #3", + "RC: Filianore's Spear Ornament", + "RC: Sacred Chime of Filianore", + "RC: Crucifix of the Mad King", + }), + DS3BossInfo("Darkeater Midir", 5100850, dlc = True, locations = { + "RC: Soul of Darkeater Midir", + "RC: Spears of the Church", + }), + DS3BossInfo("Slave Knight Gael 1", 5110801, dlc = True, locations = { + "RC: Soul of Slave Knight Gael", + "RC: Blood of the Dark Soul", + }), + DS3BossInfo("Slave Knight Gael 2", 5110800, dlc = True, locations = { + "RC: Soul of Slave Knight Gael", + "RC: Blood of the Dark Soul", + }), + DS3BossInfo("Soul of Cinder", 4100800), +] diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 2ff786f11bb0..7aa34961dfa8 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -891,10 +891,6 @@ def get_name_to_id() -> dict: # Yuria of Londor for Orbeck's Ashes DS3LocationData("RS: Morion Blade", "Morion Blade", DS3LocationCategory.WEAPON, missable = True, npc = True), - - # Hawkwood after killing Abyss Watchers - DS3LocationData("RS: Farron Ring", "Farron Ring", DS3LocationCategory.RING, - missable = True, npc = True), ], "Cathedral of the Deep": [ DS3LocationData("CD: Herald Helm", "Herald Helm", DS3LocationCategory.ARMOR), @@ -1148,6 +1144,10 @@ def get_name_to_id() -> dict: DS3LocationData("FK: Boulder Heave", "Boulder Heave", DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + # Hawkwood after killing Abyss Watchers + DS3LocationData("RS: Farron Ring", "Farron Ring", DS3LocationCategory.RING, + missable = True, npc = True), + # Shrine Handmaid after killing exiles DS3LocationData("FK: Exile Mask", "Exile Mask", DS3LocationCategory.ARMOR, hidden = True, hostile_npc = True, shop = True), @@ -1873,10 +1873,14 @@ def get_name_to_id() -> dict: boss = True, shop = True), # Shrine Handmaid after killing Dragonslayer Armour (or Eygon of Carim) - DS3LocationData("LC: Morne's Helm", "Morne's Helm", DS3LocationCategory.ARMOR), - DS3LocationData("LC: Morne's Armor", "Morne's Armor", DS3LocationCategory.ARMOR), - DS3LocationData("LC: Morne's Gauntlets", "Morne's Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("LC: Morne's Leggings", "Morne's Leggings", DS3LocationCategory.ARMOR), + DS3LocationData("LC: Morne's Helm", "Morne's Helm", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("LC: Morne's Armor", "Morne's Armor", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("LC: Morne's Gauntlets", "Morne's Gauntlets", DS3LocationCategory.ARMOR, + boss = True, shop = True), + DS3LocationData("LC: Morne's Leggings", "Morne's Leggings", DS3LocationCategory.ARMOR, + boss = True, shop = True), ], "Consumed King's Garden": [ diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 64ae8278ac75..442cb41dbd95 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -1,5 +1,6 @@ # world/dark_souls_3/__init__.py -from typing import Dict, Set, List, Union +import logging +from typing import Dict, Set, List, Optional, TextIO, Union import re from BaseClasses import MultiWorld, Region, Item, Entrance, Tutorial, ItemClassification @@ -8,6 +9,7 @@ from worlds.AutoWorld import World, WebWorld from worlds.generic.Rules import set_rule, add_rule, add_item_rule +from .Bosses import DS3BossInfo, all_bosses from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, UsefulIf, filler_item_names, item_dictionary from .Locations import DarkSouls3Location, DS3LocationCategory, DS3LocationData, location_tables, location_dictionary, location_name_groups from .Options import DarkSouls3Options, RandomizeWeaponLevelOption, PoolTypeOption @@ -64,6 +66,12 @@ class DarkSouls3World(World): } } + yhorm_location: Optional[DS3BossInfo] + """If enemy randomization is enabled, this is the boss who Yhorm the Giant should replace. + + This is used to determine where the Storm Ruler can be placed. + """ + def __init__(self, multiworld: MultiWorld, player: int): super().__init__(multiworld, player) @@ -107,6 +115,25 @@ def generate_early(self): # items in the local world. self.multiworld.local_items[self.player].value.add("Path of the Dragon") + # Randomize Yhorm manually so that we know where to place the Storm Ruler + if self.multiworld.randomize_enemies[self.player] == Toggle.option_true: + self.yhorm_location = self.multiworld.random.choice( + [ + boss for boss in all_bosses if not boss.dlc + ] if self.multiworld.enable_dlc[self.player] else all_bosses + ) + + # If Yhorm is early, make sure the Storm Ruler is easily available to avoid BK + if ( + self.yhorm_location.name == "Iudex Gundyr" or + self.yhorm_location.name == "Vordt of the Boreal Valley" or ( + self.yhorm_location.name == "Dancer of the Boreal Valley" and + self.multiworld.late_basin_of_vows[self.player] == Toggle.option_false + ) + ): + self.multiworld.early_items[self.player]['Storm Ruler'] = 1 + self.multiworld.local_items[self.player].value.add('Storm Ruler') + def create_regions(self): # Create Vanilla Regions regions: Dict[str, Region] = {} @@ -245,10 +272,7 @@ def create_items(self): raise Exception("DS3 generation bug: Added an unavailable location.") item = item_dictionary[location.default_item_name] - if item.category == DS3ItemCategory.SKIP or ( - self.multiworld.randomize_enemies[self.player] == Toggle.option_true and - item.name == "Storm Ruler" - ): + if item.category == DS3ItemCategory.SKIP: num_required_extra_items += 1 elif item.category == DS3ItemCategory.MISC or item.force_unique: itempool_by_category[location.category].append(location.default_item_name) @@ -466,9 +490,6 @@ def set_rules(self) -> None: lambda state: state.has("Small Doll", self.player)) # Define the access rules to some specific locations - if self.multiworld.randomize_enemies[self.player] == Toggle.option_false: - set_rule(self.multiworld.get_location("PC: Cinders of a Lord - Yhorm the Giant", self.player), - lambda state: state.has("Storm Ruler", self.player)) set_rule(self.multiworld.get_location("HWL: Red Eye Orb", self.player), lambda state: state.has("Lift Chamber Key", self.player)) @@ -556,6 +577,19 @@ def has_any_scroll(state): item.player != self.player or (item.count == 1 and not item.soul) )) + + # Make sure the Storm Ruler is available BEFORE Yhorm the Giant + if self.yhorm_location: + if self.yhorm_location.region: + set_rule(self.multiworld.get_entrance("Go To " + self.yhorm_location.region, self.player), + lambda state: state.has("Storm Ruler", self.player)) + for location in self.yhorm_location.locations: + if self.__is_location_available(location): + set_rule(self.multiworld.get_location(location, self.player), + lambda state: state.has("Storm Ruler", self.player)) + else: + set_rule(self.multiworld.get_location("PC: Cinders of a Lord - Yhorm the Giant", self.player), + lambda state: state.has("Storm Ruler", self.player)) self.multiworld.completion_condition[self.player] = lambda state: \ state.has("Cinders of a Lord - Abyss Watcher", self.player) and \ @@ -582,6 +616,11 @@ def __is_location_available(self, location: Union[str, DS3LocationData]): ) + def write_spoiler(self, spoiler_handle: TextIO) -> None: + if self.yhorm_location: + spoiler_handle.write(f"Yhorm takes the place of {self.yhorm_location.name}") + + def fill_slot_data(self) -> Dict[str, object]: slot_data: Dict[str, object] = {} @@ -666,6 +705,7 @@ def fill_slot_data(self) -> Dict[str, object]: }, "seed": self.multiworld.seed_name, # to verify the server's multiworld "slot": self.multiworld.player_name[self.player], # to connect to server + "yhorm": f"{self.yhorm_location.name} {self.yhorm_location.id}" if self.yhorm_location else None, "apIdsToItemIds": ap_ids_to_ds3_ids, "itemCounts": item_counts, "locationIdsToKeys": location_ids_to_keys, diff --git a/worlds/dark_souls_3/test/TestDarkSouls3.py b/worlds/dark_souls_3/test/TestDarkSouls3.py index 8fba4d7be0a1..915c648088f4 100644 --- a/worlds/dark_souls_3/test/TestDarkSouls3.py +++ b/worlds/dark_souls_3/test/TestDarkSouls3.py @@ -2,6 +2,7 @@ from worlds.dark_souls_3.Items import item_dictionary from worlds.dark_souls_3.Locations import location_tables +from worlds.dark_souls_3.Bosses import all_bosses class DarkSouls3Test(WorldTestBase): game = "Dark Souls III" @@ -10,3 +11,15 @@ def testLocationDefaultItems(self): for locations in location_tables.values(): for location in locations: self.assertIn(location.default_item_name, item_dictionary) + + def testBossRegions(self): + all_regions = set(location_tables) + for boss in all_bosses: + if boss.region: + self.assertIn(boss.region, all_regions) + + def testBossLocations(self): + all_locations = {location for locations in location_tables.values() for location in locations)} + for boss in all_bosses: + for location in boss.locations: + self.assertIn(location, all_locations) \ No newline at end of file From a6e49f79969816e90ef7d2cd3e006cf853942380 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 31 Oct 2023 23:25:02 -0700 Subject: [PATCH 041/238] Remove a completed TODO --- worlds/dark_souls_3/Locations.py | 1 - 1 file changed, 1 deletion(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 7aa34961dfa8..6d2fb45be5f0 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -70,7 +70,6 @@ class DS3LocationData: dlc: bool = False """Whether this location is only accessible if the DLC is enabled.""" - # TODO: implement this properly ngp: bool = False """Whether this location only contains an item in NG+ and later. From a74500ca1fa78d4c6f122d0d153ecb50dbcee7a7 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 1 Nov 2023 01:30:34 -0700 Subject: [PATCH 042/238] Fix tests --- worlds/dark_souls_3/Bosses.py | 20 ++++++++++---------- worlds/dark_souls_3/Locations.py | 2 +- worlds/dark_souls_3/__init__.py | 4 ++-- worlds/dark_souls_3/test/TestDarkSouls3.py | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index bd6cec44aef9..08abce62ab6b 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -46,7 +46,7 @@ class DS3BossInfo: }), DS3BossInfo("Abyss Watchers", 3300801, region = "Catacombs of Carthus", locations = { "FK: Soul of the Blood of the Wolf", - "FK: Cinders of a Lord - Abyss Watchers", + "FK: Cinders of a Lord - Abyss Watcher", "UG: Hornet Ring", "FK: Undead Legion Helm", "FK: Undead Legion Armor", @@ -54,7 +54,7 @@ class DS3BossInfo: "FK: Undead Legion Leggings", "UG: Wolf Knight Helm", "UG: Wolf Knight Armor", - "UG: Wolf Knight Gauntlet", + "UG: Wolf Knight Gauntlets", "UG: Wolf Knight Leggings", }), DS3BossInfo("High Lord Wolnir", 3800800, region = "Irithyll of the Boreal Valley", locations = { @@ -64,7 +64,7 @@ class DS3BossInfo: "CC: Pontiff's Right Eye", }), DS3BossInfo("Pontiff Sulyvahn", 3700850, region = "Anor Londo", locations = { - "IBV: Soul of Ponyiff Sulyvahn", + "IBV: Soul of Pontiff Sulyvahn", }), DS3BossInfo("Old Demon King", 3800830, locations = { "SL: Soul of the Old Demon King", @@ -113,13 +113,13 @@ class DS3BossInfo: "UG: Ember", "UG: Wolf Knight Helm", "UG: Wolf Knight Armor", - "UG: Wolf Knight Gauntlet", + "UG: Wolf Knight Gauntlets", "UG: Wolf Knight Leggings", }), # This is a white lie, you can get to a bunch of items in AP before you beat the Wyvern, but # this saves us from having to split the entire region in two just to mark which specific items # are before and after. - DS3BossInfo("Ancient Wyvern", 3200800, region = {"Archdragon Peak"}), + DS3BossInfo("Ancient Wyvern", 3200800, region = "Archdragon Peak"), DS3BossInfo("King of the Storm", 3200850, locations = { "AP: Soul of the Nameless King", "AP: Golden Crown", @@ -142,11 +142,11 @@ class DS3BossInfo: }), DS3BossInfo("Lorian, Elder Prince", 3410830, locations = { "GA: Soul of the Twin Princes", - "GA: Cinders of a Lord - Twin Princes", + "GA: Cinders of a Lord - Lothric Prince", }), DS3BossInfo("Lothric, Younger Prince", 3410832, locations = { "GA: Soul of the Twin Princes", - "GA: Cinders of a Lord - Twin Princes", + "GA: Cinders of a Lord - Lothric Prince", "GA: Lorian's Helm", "GA: Lorian's Armor", "GA: Lorian's Gauntlets", @@ -163,17 +163,17 @@ class DS3BossInfo: "PW2: Ordained Dress", "PW2: Ordained Trousers", }), - DS3BossInfo("Blackflame Friede", 5000801, dlc = True, region = "Ringed City", locations = { + DS3BossInfo("Blackflame Friede", 5000801, dlc = True, region = "Dreg Heap", locations = { "PW2: Soul of Sister Friede", "PW2: Ordained Hood", "PW2: Ordained Dress", "PW2: Ordained Trousers", }), - DS3BossInfo("Demon Prince", 4500800, dlc = True, region = "Dreg Heap", locations = { + DS3BossInfo("Demon Prince", 4500800, dlc = True, region = "Ringed City", locations = { "DH: Soul of the Demon Prince", "DH: Small Envoy Banner", }), - DS3BossInfo("Halflight, Spear of the Church", 5100800, dlc = True, region = "Ringed City", locations = { + DS3BossInfo("Halflight, Spear of the Church", 5100800, dlc = True, locations = { "RC: Titanite Slab #1", "RC: Titanite Slab #2", "RC: Titanite Slab #3", diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 7aa34961dfa8..1eb49c2bc9f1 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -2351,7 +2351,7 @@ def get_name_to_id() -> dict: lizard = True), DS3LocationData("PW1: Large Titanite Shard #3", "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("PW2: Champion's Bones", "Champion's Bones", DS3LocationCategory.UNIQUE, + DS3LocationData("PW1: Champion's Bones", "Champion's Bones", DS3LocationCategory.UNIQUE, offline = '11,0:50002310::', boss = True), ], "Painted World of Ariandel (After Contraption)": [ diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 442cb41dbd95..6d923e2d0cf4 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -120,7 +120,7 @@ def generate_early(self): self.yhorm_location = self.multiworld.random.choice( [ boss for boss in all_bosses if not boss.dlc - ] if self.multiworld.enable_dlc[self.player] else all_bosses + ] if not self.multiworld.enable_dlc[self.player] else all_bosses ) # If Yhorm is early, make sure the Storm Ruler is easily available to avoid BK @@ -581,7 +581,7 @@ def has_any_scroll(state): # Make sure the Storm Ruler is available BEFORE Yhorm the Giant if self.yhorm_location: if self.yhorm_location.region: - set_rule(self.multiworld.get_entrance("Go To " + self.yhorm_location.region, self.player), + set_rule(self.multiworld.get_entrance(f"Go To {self.yhorm_location.region}", self.player), lambda state: state.has("Storm Ruler", self.player)) for location in self.yhorm_location.locations: if self.__is_location_available(location): diff --git a/worlds/dark_souls_3/test/TestDarkSouls3.py b/worlds/dark_souls_3/test/TestDarkSouls3.py index 915c648088f4..a3f9c82f0659 100644 --- a/worlds/dark_souls_3/test/TestDarkSouls3.py +++ b/worlds/dark_souls_3/test/TestDarkSouls3.py @@ -19,7 +19,7 @@ def testBossRegions(self): self.assertIn(boss.region, all_regions) def testBossLocations(self): - all_locations = {location for locations in location_tables.values() for location in locations)} + all_locations = {location.name for locations in location_tables.values() for location in locations} for boss in all_bosses: for location in boss.locations: - self.assertIn(location, all_locations) \ No newline at end of file + self.assertIn(location, all_locations) From aef06e91ec27529f09c3464dc9226b0540499e95 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 1 Nov 2023 01:31:08 -0700 Subject: [PATCH 043/238] Fix force_unique --- worlds/dark_souls_3/__init__.py | 2 +- worlds/dark_souls_3/test/TestDarkSouls3.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 6d923e2d0cf4..dcdbf9ab8bb8 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -274,7 +274,7 @@ def create_items(self): item = item_dictionary[location.default_item_name] if item.category == DS3ItemCategory.SKIP: num_required_extra_items += 1 - elif item.category == DS3ItemCategory.MISC or item.force_unique: + elif item.category == DS3ItemCategory.MISC and not item.force_unique: itempool_by_category[location.category].append(location.default_item_name) else: # For non-miscellaneous non-skip items, make sure there aren't duplicates in the diff --git a/worlds/dark_souls_3/test/TestDarkSouls3.py b/worlds/dark_souls_3/test/TestDarkSouls3.py index a3f9c82f0659..0f3e84e736ff 100644 --- a/worlds/dark_souls_3/test/TestDarkSouls3.py +++ b/worlds/dark_souls_3/test/TestDarkSouls3.py @@ -23,3 +23,7 @@ def testBossLocations(self): for boss in all_bosses: for location in boss.locations: self.assertIn(location, all_locations) + + def testForceUnique(self): + tongues = self.get_items_by_name("Pale Tongue") + self.assertEqual(len(tongues), 1, "There should only be one Pale Tongue in the item pool.") From 7d1eb2cad6c673967615aaae4632389a018d03bf Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 1 Nov 2023 22:52:35 -0700 Subject: [PATCH 044/238] Add an option to smooth out upgrade item progression --- worlds/dark_souls_3/Fill.py | 141 +++++++++++++++++++++++++++++++ worlds/dark_souls_3/Items.py | 23 +++-- worlds/dark_souls_3/Locations.py | 83 ++++++++++-------- worlds/dark_souls_3/Options.py | 36 +++++--- worlds/dark_souls_3/__init__.py | 122 +++++++++++++++++++++----- 5 files changed, 325 insertions(+), 80 deletions(-) create mode 100644 worlds/dark_souls_3/Fill.py diff --git a/worlds/dark_souls_3/Fill.py b/worlds/dark_souls_3/Fill.py new file mode 100644 index 000000000000..c7c743029880 --- /dev/null +++ b/worlds/dark_souls_3/Fill.py @@ -0,0 +1,141 @@ +from typing import List, Optional + +from BaseClasses import ItemClassification, LocationProgressType, MultiWorld + +from .Locations import location_tables + +class Fill: + """A utility class for prefilling items to provide smoother progression.""" + + world: "DarkSouls3World" + """The world that's running this fill.""" + + regions: List[str] + """A list of region names to which prefilled items might be randomized. + + This is roughly in order from earlier to later game, although when the player actually reaches + each region is highly dependent on their seed and settings. This ordering is roughly based on + where upgrade items become available in the base game. + """ + + @property + def multiworld(self) -> MultiWorld: + """The MultiWorld object for the currently generating multiworld.""" + return self.world.multiworld + + @property + def player(self) -> int: + """The ID of the player for which this world is being generated.""" + return self.world.player + + + def __init__(self, world: "DarkSouls3World"): + self.world = world + self.regions = [ + "Cemetery of Ash", + "Firelink Shrine", + "High Wall of Lothric", + "Undead Settlement", + "Road of Sacrifices", + "Farron Keep", + "Cathedral of the Deep", + "Catacombs of Carthus", + "Smouldering Lake", + "Irithyll of the Boreal Valley", + "Irithyll Dungeon", + # The first half of Painted World has one Titanite Slab but mostly Large Titanite Shards, + # much like Irithyll Dungeon. + "Painted World of Ariandel (Before Contraption)", + "Anor Londo", + "Profaned Capital", + # The second half of Painted World has two Titanite Chunks and two Titanite Slabs, which + # puts it on the low end of the post-Lothric Castle areas in terms of rewards. + "Painted World of Ariandel (After Contraption)", + "Lothric Castle", + "Consumed King's Garden", + "Untended Graves", + "Grand Archives", + "Archdragon Peak", + "Kiln of the First Flame", + # Both areas of DLC2 have premium rewards. + "Dreg Heap", + "Ringed City", + ] + + + def fill( + self, + name: str, + start: Optional[str] = None, + through: Optional[str] = None, + count: int = 0, + no_excluded = False) -> None: + """Fills the given item into open locations in the given region. + + This fills open slots from start through through, inclusive, ordered by how good their + rewards are in the base game. If either start or through isn't passed, this fills from the + beginning or through the end of the game, respectively. + + If count is positive, this will place up to that many copies of the item. If it's negative, + this will place all but that many copies with the expectation that the remainder will be + placed in other worlds. If it's 0, this will place all remaining copies in the item pool. + + If there's only one world, negative counts will be treated as None. + + If no_excluded is True, this won't place items into excluded locations. This never places + important items in excluded locations. + """ + + all_items = [ + item for item in self.multiworld.itempool + if item.name == name and not item.location + ] + if count == 0 or count < 0 and len(self.multiworld.worlds) == 1: + self.multiworld.random.shuffle(all_items) + chosen_items = all_items + else: + if count < 0: + count += len(all_items) + if count < 1: return + chosen_items = self.multiworld.random.sample(all_items, k = min(count, len(all_items))) + + if start: assert start in self.regions + if through: assert through in self.regions + region_start = self.regions.index(start) if start else 0 + region_end = self.regions.index(through) + 1 if through else -1 + selected_regions = self.regions[region_start:region_end] + + filler = chosen_items[0].classification == ItemClassification.filler and not no_excluded + possible_locations = [ + location for location in ( + self.multiworld.get_location(location.name, self.player) + for region in selected_regions + for location in location_tables[region] + if ( + self.world.is_location_available(location) and + not location.missable and + not location.conditional + ) + ) + # Don't put important items in excluded locations. + if (filler or location.progress_type != LocationProgressType.EXCLUDED) + and not location.item + ] + + print(f"{name}: {len(chosen_items)} items chosen, {len(possible_locations)} locations available") + + if len(possible_locations) == 0: return + if len(possible_locations) < len(chosen_items): + chosen_items = self.multiworld.random.sample(chosen_items, k = len(possible_locations)) + + locations = self.multiworld.random.sample(possible_locations, k = len(chosen_items)) + for item, location in zip(chosen_items, locations): + location.place_locked_item(item) + + + def save(self): + """Removes all allocated items from the multiworld itempool.""" + self.multiworld.itempool = [ + item for item in self.multiworld.itempool + if not item.location + ] diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 4527f285a359..6a1c33ac8958 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -50,6 +50,9 @@ class DS3ItemData(): ds3_code: int category: DS3ItemCategory + base_name: Optional[str] = None + """The name of the individual item, if this is a multi-item group.""" + classification: ItemClassification = ItemClassification.filler """How important this item is to the game progression.""" @@ -88,6 +91,7 @@ class DS3ItemData(): def __post_init__(self): self.ap_code = DS3ItemData.__item_id + if not self.base_name: self.base_name = self.name DS3ItemData.__item_id += 1 def counts(self, counts: List[int]) -> Generator["DS3ItemData", None, None]: @@ -96,7 +100,8 @@ def counts(self, counts: List[int]) -> Generator["DS3ItemData", None, None]: for count in counts: yield dataclasses.replace( self, - name = "{} x{}".format(self.name, count), + name = "{} x{}".format(self.base_name, count), + base_name = self.base_name, count = count, filler = False, # Don't count multiples as filler by default ) @@ -916,7 +921,7 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou DS3ItemData("Binoculars", 0x40000173, DS3ItemCategory.MISC), DS3ItemData("Proof of a Concord Kept", 0x40000174, DS3ItemCategory.SKIP), DS3ItemData("Pale Tongue", 0x40000175, DS3ItemCategory.MISC, - classification = ItemClassification.useful, + classification = ItemClassification.progression, force_unique = True), # One is needed for Leonhard's quest DS3ItemData("Vertebra Shackle", 0x40000176, DS3ItemCategory.MISC, force_unique = True), # Allow one of these to trade to the crow @@ -929,20 +934,20 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou DS3ItemData("Twinkling Dragon Torso Stone", 0x40000184, DS3ItemCategory.MISC, classification = ItemClassification.progression), DS3ItemData("Fire Keeper Soul", 0x40000186, DS3ItemCategory.MISC), - DS3ItemData("Fading Soul", 0x40000190, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Fading Soul", 0x40000190, DS3ItemCategory.MISC, filler = True, soul = True), DS3ItemData("Soul of a Deserted Corpse", 0x40000191, DS3ItemCategory.MISC, filler = True, soul = True), - DS3ItemData("Large Soul of a Deserted Corpse", 0x40000192, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Soul of an Unknown Traveler", 0x40000193, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Large Soul of a Deserted Corpse", 0x40000192, DS3ItemCategory.MISC, filler = True, soul = True), + DS3ItemData("Soul of an Unknown Traveler", 0x40000193, DS3ItemCategory.MISC, filler = True, soul = True), DS3ItemData("Large Soul of an Unknown Traveler", 0x40000194, DS3ItemCategory.MISC, filler = True, soul = True), - DS3ItemData("Soul of a Nameless Soldier", 0x40000195, DS3ItemCategory.MISC, soul = True), + DS3ItemData("Soul of a Nameless Soldier", 0x40000195, DS3ItemCategory.MISC, filler = True, soul = True), DS3ItemData("Large Soul of a Nameless Soldier", 0x40000196, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Soul of a Weary Warrior", 0x40000197, DS3ItemCategory.MISC, filler = True, soul = True), + DS3ItemData("Soul of a Weary Warrior", 0x40000197, DS3ItemCategory.MISC, soul = True), DS3ItemData("Large Soul of a Weary Warrior", 0x40000198, DS3ItemCategory.MISC, soul = True), DS3ItemData("Soul of a Crestfallen Knight", 0x40000199, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Large Soul of a Crestfallen Knight", 0x4000019A, DS3ItemCategory.MISC, filler = True, soul = True), + DS3ItemData("Large Soul of a Crestfallen Knight", 0x4000019A, DS3ItemCategory.MISC, soul = True), DS3ItemData("Soul of a Proud Paladin", 0x4000019B, DS3ItemCategory.MISC, soul = True), DS3ItemData("Large Soul of a Proud Paladin", 0x4000019C, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Soul of an Intrepid Hero", 0x4000019D, DS3ItemCategory.MISC, filler = True, soul = True), + DS3ItemData("Soul of an Intrepid Hero", 0x4000019D, DS3ItemCategory.MISC, soul = True), DS3ItemData("Large Soul of an Intrepid Hero", 0x4000019E, DS3ItemCategory.MISC, soul = True), DS3ItemData("Soul of a Seasoned Warrior", 0x4000019F, DS3ItemCategory.MISC, soul = True), DS3ItemData("Large Soul of a Seasoned Warrior", 0x400001A0, DS3ItemCategory.MISC, soul = True), diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 1eb49c2bc9f1..eeea15f16aab 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -70,7 +70,6 @@ class DS3LocationData: dlc: bool = False """Whether this location is only accessible if the DLC is enabled.""" - # TODO: implement this properly ngp: bool = False """Whether this location only contains an item in NG+ and later. @@ -122,6 +121,13 @@ class DS3LocationData: shop: bool = False """Whether this location appears in an NPC's shop.""" + conditional: bool = False + """Whether this location is conditional on a progression item. + + This is used to track locations that won't become available until an unknown amount of time into + the run, and as such shouldn't have "similar to the base game" items placed in them. + """ + key: bool = False """Whether this location normally contains a key. @@ -280,9 +286,9 @@ def get_name_to_id() -> dict: DS3LocationData("FS: Wolf Ring+2", "Wolf Ring+2", DS3LocationCategory.RING, ngp = True), DS3LocationData("FS: Cracked Red Eye Orb", "Cracked Red Eye Orb x5", DS3LocationCategory.UNIQUE, - missable = True, npc = True), # Leonhard (quest) + missable = True, npc = True, conditional = True), # Leonhard (quest) DS3LocationData("FS: Lift Chamber Key", "Lift Chamber Key", DS3LocationCategory.KEY, - progression = True, npc = True, key = True), # Leonhard (kill or quest) + progression = True, npc = True, key = True, conditional = True), # Leonhard (kill or quest) # Shrine Handmaid shop DS3LocationData("FS: White Sign Soapstone", "White Sign Soapstone", DS3LocationCategory.UNIQUE, @@ -301,65 +307,65 @@ def get_name_to_id() -> dict: shop = True), # Mortician's Ashes DS3LocationData("FS: Alluring Skull", "Alluring Skull", DS3LocationCategory.MISC, - shop = True), + shop = True, conditional = True), DS3LocationData("FS: Ember (Mortician)" , "Ember", DS3LocationCategory.MISC, - offline = '99,0:-1:110000,70000100:', shop = True), + offline = '99,0:-1:110000,70000100:', shop = True, conditional = True), DS3LocationData("FS: Grave Key", "Grave Key", DS3LocationCategory.KEY, - shop = True, key = True), + shop = True, key = True, conditional = True), # Dreamchaser's Ashes DS3LocationData("FS: Life Ring", "Life Ring", DS3LocationCategory.RING, - shop = True), + shop = True, conditional = True), DS3LocationData("FS: Hidden Blessing #2", "Hidden Blessing", DS3LocationCategory.MISC, - missable = True, shop = True), # only if you say where the ashes were found + missable = True, shop = True, conditional = True), # only if you say where the ashes were found # Paladin's Ashes DS3LocationData("FS: Lloyd's Shield Ring", "Lloyd's Shield Ring", DS3LocationCategory.RING, - shop = True), + shop = True, conditional = True), # Grave Warden's Ashes DS3LocationData("FS: Ember (Grave Warden)", "Ember", DS3LocationCategory.MISC, - offline = '99,0:-1:110000,70000103:', shop = True), + offline = '99,0:-1:110000,70000103:', shop = True, conditional = True), # Prisoner Chief's Ashes DS3LocationData("FS: Karla's Pointed Hat", "Karla's Pointed Hat", DS3LocationCategory.ARMOR, - offline = '99,0:-1:110000,70000105:', shop = True), + offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), DS3LocationData("FS: Karla's Coat", "Karla's Coat", DS3LocationCategory.ARMOR, - offline = '99,0:-1:110000,70000105:', shop = True), + offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), DS3LocationData("FS: Karla's Gloves", "Karla's Gloves", DS3LocationCategory.ARMOR, - offline = '99,0:-1:110000,70000105:', shop = True), + offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), DS3LocationData("FS: Karla's Trousers", "Karla's Trousers", DS3LocationCategory.ARMOR, - offline = '99,0:-1:110000,70000105:', shop = True), + offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), # Xanthous Ashes DS3LocationData("FS: Xanthous Overcoat", "Xanthous Overcoat", DS3LocationCategory.ARMOR, - shop = True), + shop = True, conditional = True), DS3LocationData("FS: Xanthous Gloves", "Xanthous Gloves", DS3LocationCategory.ARMOR, - shop = True), + shop = True, conditional = True), DS3LocationData("FS: Xanthous Trousers", "Xanthous Trousers", DS3LocationCategory.ARMOR, - shop = True), + shop = True, conditional = True), # Dragon Chaser's Ashes DS3LocationData("FS: Ember (Dragon Chaser)", "Ember", DS3LocationCategory.MISC, - offline = '99,0:-1:110000,70000108:', shop = True), + offline = '99,0:-1:110000,70000108:', shop = True, conditional = True), # Easterner's Ashes DS3LocationData("FS: Washing Pole", "Washing Pole", DS3LocationCategory.WEAPON, - shop = True), + shop = True, conditional = True), DS3LocationData("FS: Eastern Helm", "Eastern Helm", DS3LocationCategory.ARMOR, - shop = True), + shop = True, conditional = True), DS3LocationData("FS: Eastern Armor", "Eastern Armor", DS3LocationCategory.ARMOR, - shop = True), + shop = True, conditional = True), DS3LocationData("FS: Eastern Gauntlets", "Eastern Gauntlets", DS3LocationCategory.ARMOR, - shop = True), + shop = True, conditional = True), DS3LocationData("FS: Eastern Leggings", "Eastern Leggings", DS3LocationCategory.ARMOR, - shop = True), + shop = True, conditional = True), DS3LocationData("FS: Wood Grain Ring", "Wood Grain Ring", DS3LocationCategory.RING, - shop = True), + shop = True, conditional = True), # Captain's Ashes DS3LocationData("FS: Millwood Knight Helm", "Millwood Knight Helm", DS3LocationCategory.ARMOR, - dlc = True, shop = True), + dlc = True, shop = True, conditional = True), DS3LocationData("FS: Millwood Knight Armor", "Millwood Knight Armor", DS3LocationCategory.ARMOR, - dlc = True, shop = True), + dlc = True, shop = True, conditional = True), DS3LocationData("FS: Millwood Knight Gauntlets", "Millwood Knight Gauntlets", DS3LocationCategory.ARMOR, - dlc = True, shop = True), + dlc = True, shop = True, conditional = True), DS3LocationData("FS: Millwood Knight Leggings", "Millwood Knight Leggings", DS3LocationCategory.ARMOR, - dlc = True, shop = True), + dlc = True, shop = True, conditional = True), DS3LocationData("FS: Refined Gem", "Refined Gem", DS3LocationCategory.UPGRADE, - dlc = True, shop = True), + dlc = True, shop = True, conditional = True), ], "Firelink Shrine Bell Tower": [ # Guarded by Tower Key @@ -1479,7 +1485,8 @@ def get_name_to_id() -> dict: DS3LocationData("ID: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), DS3LocationData("ID: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("ID: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC), - DS3LocationData("ID: Bellowing Dragoncrest Ring", "Bellowing Dragoncrest Ring", DS3LocationCategory.RING), + DS3LocationData("ID: Bellowing Dragoncrest Ring", "Bellowing Dragoncrest Ring", DS3LocationCategory.RING, + conditional = True), DS3LocationData("ID: Soul of a Weary Warrior #1", "Soul of a Weary Warrior", DS3LocationCategory.MISC), DS3LocationData("ID: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), DS3LocationData("ID: Lightning Bolt", "Lightning Bolt x9", DS3LocationCategory.MISC), @@ -1497,7 +1504,8 @@ def get_name_to_id() -> dict: DS3LocationData("ID: Old Sorcerer Gauntlets", "Old Sorcerer Gauntlets", DS3LocationCategory.ARMOR), DS3LocationData("ID: Old Sorcerer Boots", "Old Sorcerer Boots", DS3LocationCategory.ARMOR), DS3LocationData("ID: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), - DS3LocationData("ID: Covetous Gold Serpent Ring", "Covetous Gold Serpent Ring", DS3LocationCategory.RING), + DS3LocationData("ID: Covetous Gold Serpent Ring", "Covetous Gold Serpent Ring", DS3LocationCategory.RING, + conditional = True), DS3LocationData("ID: Lightning Blade", "Lightning Blade", DS3LocationCategory.SPELL), DS3LocationData("ID: Rusted Coin", "Rusted Coin", DS3LocationCategory.MISC), DS3LocationData("ID: Dusk Crown Ring", "Dusk Crown Ring", DS3LocationCategory.RING), @@ -1721,11 +1729,11 @@ def get_name_to_id() -> dict: # This is listed here even though you can kill Leonhard immediately because we don't want to # make people do that until they have a chance to complete his quest and Sirris's. DS3LocationData("AL: Leonhard's Garb", "Leonhard's Garb", DS3LocationCategory.ARMOR, - hidden = True, npc = True, shop = True), + hidden = True, npc = True, shop = True, conditional = True), DS3LocationData("AL: Leonhard's Gauntlets", "Leonhard's Gauntlets", DS3LocationCategory.ARMOR, - hidden = True, npc = True, shop = True), + hidden = True, npc = True, shop = True, conditional = True), DS3LocationData("AL: Leonhard's Trousers", "Leonhard's Trousers", DS3LocationCategory.ARMOR, - hidden = True, npc = True, shop = True), + hidden = True, npc = True, shop = True, conditional = True), # Shrine Handmaid after killing Alrich, Devourer of Gods DS3LocationData("AL: Smough's Helm", "Smough's Helm", DS3LocationCategory.ARMOR, @@ -1843,9 +1851,10 @@ def get_name_to_id() -> dict: lizard = True), DS3LocationData("LC: Twinkling Titanite #6", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("LC: Gotthard Twinswords", "Gotthard Twinswords", DS3LocationCategory.WEAPON), + DS3LocationData("LC: Gotthard Twinswords", "Gotthard Twinswords", DS3LocationCategory.WEAPON, + conditional = True), DS3LocationData("LC: Grand Archives Key", "Grand Archives Key", DS3LocationCategory.KEY, - prominent = True, progression = True, key = True), + prominent = True, progression = True, key = True, conditional = True), DS3LocationData("LC: Titanite Chunk #11", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("LC: Dancer's Enchanted Swords", "Dancer's Enchanted Swords", DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), @@ -2095,7 +2104,7 @@ def get_name_to_id() -> dict: DS3LocationData("UG: Ring of Steel Protection+1", "Ring of Steel Protection+1", DS3LocationCategory.RING, ngp = True, hidden = True), DS3LocationData("UG: Hornet Ring", "Hornet Ring", DS3LocationCategory.RING, - hidden = True), + hidden = True, conditional = True), DS3LocationData("FS: Gundyr's Halberd", "Gundyr's Halberd", DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), DS3LocationData("FS: Prisoner's Chain", "Prisoner's Chain", DS3LocationCategory.RING, diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index a57f21420169..04d9521381b1 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -29,18 +29,6 @@ class RandomizeSpellLocations(DefaultOnToggle): display_name = "Randomize Spell Locations" -class RandomizeUpgradeLocations(DefaultOnToggle): - """Randomizes titanite and gems (+220 checks) - - By default, these locations will never include progression items, so they - aren't mandatory checks. You can override this by customizing the - "exclude_locations" field in your YAML config. (For example, - "exclude_locations: []" will allow progression items in every unmissable - location.) - """ - display_name = "Randomize Upgrade Locations" - - class RandomizeKeyLocations(DefaultOnToggle): """Randomizes items which unlock doors or bypass barriers. @@ -88,12 +76,32 @@ class RandomizeHealthLocations(DefaultOnToggle): display_name = "Randomize Health Upgrade Locations" +class UpgradeLocationsOption(Choice): + """Where to randomize titanite and gems (220 checks) + + * Not Randomized: All upgrade item locations contain the same items as in the base game. + * Anywhere: Upgrade items are distributed totally randomly throughout the game. + * Similar to Base Game: Upgrade items appear in approximately the same regions they do in the + base game. + + By default, upgrade item locations will never include progression items, so they aren't + mandatory checks. You can override this by customizing the "exclude_locations" field in your + YAML config. (For example, "exclude_locations: []" will allow progression items in every + unmissable location.) + """ + display_name = "Upgrade Locations" + option_not_randomized = 1 + option_anywhere = 2 + option_similar_to_base_game = 3 + default = 3 + + class RandomizeStartingLoadout(DefaultOnToggle): """Randomizes the equipment characters begin with.""" display_name = "Randomize Starting Loadout" -class RequireOneHandedStartingWeapons(Toggle): +class RequireOneHandedStartingWeapons(DefaultOnToggle): """Require starting equipment to be usable one-handed.""" display_name = "Require One-Handed Starting Weapons" @@ -323,13 +331,13 @@ class DarkSouls3Options(PerGameCommonOptions): enable_armor_locations: RandomizeArmorLocations enable_ring_locations: RandomizeRingLocations enable_spell_locations: RandomizeSpellLocations - enable_upgrade_locations: RandomizeUpgradeLocations enable_key_locations: RandomizeKeyLocations enable_boss_locations: RandomizeBossSoulLocations enable_npc_locations: RandomizeNPCLocations enable_unique_locations: RandomizeUniqueLocations enable_misc_locations: RandomizeMiscLocations enable_health_upgrade_locations: RandomizeHealthLocations + upgrade_locations: UpgradeLocationsOption random_starting_loadout: RandomizeStartingLoadout require_one_handed_starting_weapons: RequireOneHandedStartingWeapons pool_type: PoolTypeOption diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index dcdbf9ab8bb8..fd0fb8e1cbb3 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -10,9 +10,10 @@ from worlds.generic.Rules import set_rule, add_rule, add_item_rule from .Bosses import DS3BossInfo, all_bosses +from .Fill import Fill from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, UsefulIf, filler_item_names, item_dictionary from .Locations import DarkSouls3Location, DS3LocationCategory, DS3LocationData, location_tables, location_dictionary, location_name_groups -from .Options import DarkSouls3Options, RandomizeWeaponLevelOption, PoolTypeOption +from .Options import DarkSouls3Options, RandomizeWeaponLevelOption, PoolTypeOption, UpgradeLocationsOption class DarkSouls3Web(WebWorld): @@ -94,7 +95,7 @@ def generate_early(self): self.enabled_location_categories.add(DS3LocationCategory.RING) if self.multiworld.enable_spell_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.SPELL) - if self.multiworld.enable_upgrade_locations[self.player] == Toggle.option_true: + if self.multiworld.upgrade_locations[self.player] != UpgradeLocationsOption.option_not_randomized: self.enabled_location_categories.add(DS3LocationCategory.UPGRADE) if self.multiworld.enable_key_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.KEY) @@ -106,8 +107,6 @@ def generate_early(self): self.multiworld.early_items[self.player]['Transposing Kiln'] = 1 if self.multiworld.enable_misc_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.MISC) - if self.multiworld.enable_upgrade_locations[self.player] == Toggle.option_true: - self.enabled_location_categories.add(DS3LocationCategory.UPGRADE) if self.multiworld.enable_health_upgrade_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.HEALTH) @@ -134,6 +133,16 @@ def generate_early(self): self.multiworld.early_items[self.player]['Storm Ruler'] = 1 self.multiworld.local_items[self.player].value.add('Storm Ruler') + # Mark all items with similar distribution as non-local, so that pre_fill can leave a few to + # be given as multiworld items. + if self.multiworld.upgrade_locations[self.player] == UpgradeLocationsOption.option_similar_to_base_game: + for item in item_dictionary.values(): + # Carefully control the actual weapon upgrade material locations, but be looser with + # gems since they're inherently controlled by coals anyway (which are all local). + if item.base_name in {"Titanite Shard", "Large Titanite Shard", "Titanite Chunk", + "Titanite Slab", "Titanite Scale", "Twinkling Titanite"}: + self.multiworld.non_local_items[self.player].value.add(item.name) + def create_regions(self): # Create Vanilla Regions regions: Dict[str, Region] = {} @@ -227,7 +236,7 @@ def create_region(self, region_name, location_table) -> Region: new_region = Region(region_name, self.player, self.multiworld) for location in location_table: - if self.__is_location_available(location): + if self.is_location_available(location): new_location = DarkSouls3Location.from_data( self.player, location, @@ -268,7 +277,7 @@ def create_items(self): # Gather all default items on randomized locations num_required_extra_items = 0 for location in self.multiworld.get_unfilled_locations(self.player): - if not self.__is_location_available(location.name): + if not self.is_location_available(location.name): raise Exception("DS3 generation bug: Added an unavailable location.") item = item_dictionary[location.default_item_name] @@ -466,7 +475,7 @@ def set_rules(self) -> None: for ash, items in ashes.items(): for item in items: location = "FS: " + item - if self.__is_location_available(location): + if self.is_location_available(location): set_rule(self.multiworld.get_location(location, self.player), lambda state, ash=ash: state.has(ash, self.player)) @@ -565,18 +574,12 @@ def has_any_scroll(state): # Forbid shops from carrying items with multiple counts (the offline randomizer has its own # logic for choosing how many shop items to sell), and from carring soul items. for location in location_dictionary.values(): - if location.shop and self.__is_location_available(location): + if location.shop and self.is_location_available(location): add_item_rule(self.multiworld.get_location(location.name, self.player), lambda item: ( item.player != self.player or (item.count == 1 and not item.soul) )) - - add_item_rule(self.multiworld.get_location(location.name, self.player), - lambda item: ( - item.player != self.player or - (item.count == 1 and not item.soul) - )) # Make sure the Storm Ruler is available BEFORE Yhorm the Giant if self.yhorm_location: @@ -584,7 +587,7 @@ def has_any_scroll(state): set_rule(self.multiworld.get_entrance(f"Go To {self.yhorm_location.region}", self.player), lambda state: state.has("Storm Ruler", self.player)) for location in self.yhorm_location.locations: - if self.__is_location_available(location): + if self.is_location_available(location): set_rule(self.multiworld.get_location(location, self.player), lambda state: state.has("Storm Ruler", self.player)) else: @@ -598,15 +601,12 @@ def has_any_scroll(state): state.has("Cinders of a Lord - Lothric Prince", self.player) - def __is_location_available(self, location: Union[str, DS3LocationData]): + def is_location_available(self, location: Union[str, DS3LocationData]) -> bool: """Returns whether the given location is being randomized.""" if isinstance(location, DS3LocationData): data = location - elif location in location_dictionary: - data = location_dictionary[location] else: - # Synthetic locations are never considered available. - return False + data = location_dictionary[location] return ( data.category in self.enabled_location_categories and @@ -621,6 +621,88 @@ def write_spoiler(self, spoiler_handle: TextIO) -> None: spoiler_handle.write(f"Yhorm takes the place of {self.yhorm_location.name}") + def pre_fill(self) -> None: + fill = Fill(self) + + if self.multiworld.upgrade_locations[self.player] == UpgradeLocationsOption.option_similar_to_base_game: + # Guarantee enough early shards to level a weapon a few times + fill.fill("Titanite Shard", through="High Wall of Lothric", count=6) + fill.fill("Titanite Shard", start="Undead Settlement", through="Catacombs of Carthus") + fill.fill("Titanite Shard x2", start="Farron Keep", through="Catacombs of Carthus", count=-1) + fill.fill("Large Titanite Shard", start="Farron Keep", through="Catacombs of Carthus", count=6) + fill.fill("Large Titanite Shard", start="Smouldering Lake", through="Anor Londo", count=-3) + fill.fill("Large Titanite Shard x2", start="Irithyll of the Boreal Valley", through="Lothric Castle", count=-1) + fill.fill("Large Titanite Shard x3", start="Irithyll of the Boreal Valley", through="Lothric Castle") + fill.fill("Titanite Chunk", start="Smouldering Lake", through="Profaned Capital", count=3) + # There are a whopping twenty chunks available in these areas in the base game. To add a + # bit more variety, we'll guarantee just enough to level one weapon but allow more to be + # added randomly. + fill.fill("Titanite Chunk", start="Painted World of Ariandel (After Contraption)", through="Consumed King's Garden", count=9) + fill.fill("Titanite Chunk", start="Painted World of Ariandel (After Contraption)") + fill.fill("Titanite Chunk x3", start="Painted World of Ariandel (After Contraption)", count=-2) + fill.fill("Titanite Chunk x6", start="Grand Archives") + # In the base game, a slab is available in the first Painted World and in Irithyll + # Dungeon, so we'll be nice and make one available relatively early. + fill.fill("Titanite Slab", start="Irithyll Dungeon", through="Profaned Capital", count=1) + # We'll make another two available in the castle area to match the one in Untended + # Graves and the three in Painted World. + fill.fill("Titanite Slab", start="Painted World of Ariandel (After Contraption)", through="Untended Graves", count=2) + # Drop the rest in the lategame, leaving one as a nice multiworld item. + fill.fill("Titanite Slab", start="Grand Archives", count=-1) + + # Twinkling Titanite and Titanite Scales both have relatively flat distributions until + # the castle. + fill.fill("Twinkling Titanite", start="Farron Keep", through="Cathedral of the Deep", count=6) + fill.fill("Twinkling Titanite", start="Catacombs of Carthus", through="Profaned Capital", + count=(11 if self.multiworld.enable_dlc[self.player] else 8)) + fill.fill("Twinkling Titanite", start="Painted World of Ariandel (After Contraption)", count=-1) + fill.fill("Twinkling Titanite x2", start="Painted World of Ariandel (After Contraption)", count=-1) + fill.fill("Twinkling Titanite x3", start="Painted World of Ariandel (After Contraption)", count=-1) + fill.fill("Titanite Scale", through="High Wall of Lothric", count=1) + fill.fill("Titanite Scale", start="Undead Settlement", through="Cathedral of the Deep", count=2) + fill.fill("Titanite Scale", start="Catacombs of Carthus", through="Profaned Capital", count=4) + fill.fill("Titanite Scale", start="Painted World of Ariandel (After Contraption)") + fill.fill("Titanite Scale x2", start="Painted World of Ariandel (After Contraption)", count=-1) + fill.fill("Titanite Scale x3", start="Painted World of Ariandel (After Contraption)", count=-1) + + # There's not a lot of cost to making coals available early, so we just need to make + # sure they're not available too late. We set the limit approximately one region after + # they appear in the main game so there's a chance that they're a bit tougher to find. + fill.fill("Farron Coal", through="Road of Sacrifices") + fill.fill("Sage's Coal", through="Catacombs of Carthus") + fill.fill("Giant's Coal", through="Painted World of Ariandel (After Contraption)") + fill.fill("Profaned Coal", through="Profaned Capital") + + # Note: unlike other upgrade items, gems that aren't explicitly filled are freely placed + # so they may appear in earlier areas. + + # If there are infused weapons floating around, guarantee a couple early Shriving Stones + # to undo bad infusions. + if self.multiworld.randomize_infusion[self.player]: + fill.fill("Shriving Stone", through="High Wall of Lothric", count=1) + fill.fill("Shriving Stone", start="Undead Settlement", through="Road of Sacrifices", count=1) + + # Guarantee one easily-findable Raw Gem early on for SL1 runs. + fill.fill("Raw Gem", through="High Wall of Lothric", count=1, no_excluded=True) + # Otherwise, provide one of each type of gem before the coal it requires. + fill.fill("Refined Gem", through="Road of Sacrifices", count=1) + fill.fill("Fire Gem", through="Road of Sacrifices", count=1) + fill.fill("Heavy Gem", through="Road of Sacrifices", count=1) + fill.fill("Sharp Gem", through="Road of Sacrifices", count=1) + fill.fill("Poison Gem", through="Road of Sacrifices", count=1) + fill.fill("Crystal Gem", through="Catacombs of Carthus", count=1) + fill.fill("Blessed Gem", through="Catacombs of Carthus", count=1) + fill.fill("Deep Gem", through="Catacombs of Carthus", count=1) + fill.fill("Dark Gem", through="Painted World of Ariandel (After Contraption)", count=1) + fill.fill("Blood Gem", through="Painted World of Ariandel (After Contraption)", count=1) + fill.fill("Hollow Gem", through="Painted World of Ariandel (After Contraption)", count=1) + fill.fill("Lightning Gem", through="Profaned Capital", count=1) + fill.fill("Simple Gem", through="Profaned Capital", count=1) + fill.fill("Chaos Gem", through="Profaned Capital", count=1) + + fill.save() + + def fill_slot_data(self) -> Dict[str, object]: slot_data: Dict[str, object] = {} From 2165a23d864a26fee11f085b2284e4d067fcef75 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 2 Nov 2023 00:01:45 -0700 Subject: [PATCH 045/238] Add helpers for setting location/entrance rules --- worlds/dark_souls_3/Bosses.py | 5 + worlds/dark_souls_3/Fill.py | 2 - worlds/dark_souls_3/Items.py | 2 +- worlds/dark_souls_3/__init__.py | 208 ++++++++++++++------------------ 4 files changed, 98 insertions(+), 119 deletions(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index 08abce62ab6b..00de9bf9c833 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -195,3 +195,8 @@ class DS3BossInfo: }), DS3BossInfo("Soul of Cinder", 4100800), ] + +default_yhorm_location = DS3BossInfo("Yhorm the Giant", 3900800, locations = { + "PC: Soul of Yhorm the Giant", + "PC: Cinders of a Lord - Yhorm the Giant", +}) diff --git a/worlds/dark_souls_3/Fill.py b/worlds/dark_souls_3/Fill.py index c7c743029880..2f8a09605fb5 100644 --- a/worlds/dark_souls_3/Fill.py +++ b/worlds/dark_souls_3/Fill.py @@ -122,8 +122,6 @@ def fill( and not location.item ] - print(f"{name}: {len(chosen_items)} items chosen, {len(possible_locations)} locations available") - if len(possible_locations) == 0: return if len(possible_locations) < len(chosen_items): chosen_items = self.multiworld.random.sample(chosen_items, k = len(possible_locations)) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 6a1c33ac8958..e6c948707f11 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -875,7 +875,7 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou DS3ItemData("Roster of Knights", 0x4000006C, DS3ItemCategory.SKIP), DS3ItemData("Cracked Red Eye Orb", 0x4000006F, DS3ItemCategory.SKIP).counts([5]), DS3ItemData("Black Eye Orb", 0x40000073, DS3ItemCategory.KEY, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Divine Blessing", 0x400000F0, DS3ItemCategory.MISC), DS3ItemData("Hidden Blessing", 0x400000F1, DS3ItemCategory.MISC), DS3ItemData("Green Blossom", 0x40000104, DS3ItemCategory.MISC, filler = True).counts([2, 3, 4]), diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index fd0fb8e1cbb3..514afe47006a 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -7,9 +7,9 @@ from Options import Toggle from worlds.AutoWorld import World, WebWorld -from worlds.generic.Rules import set_rule, add_rule, add_item_rule +from worlds.generic.Rules import CollectionRule, set_rule, add_rule, add_item_rule -from .Bosses import DS3BossInfo, all_bosses +from .Bosses import DS3BossInfo, all_bosses, default_yhorm_location from .Fill import Fill from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, UsefulIf, filler_item_names, item_dictionary from .Locations import DarkSouls3Location, DS3LocationCategory, DS3LocationData, location_tables, location_dictionary, location_name_groups @@ -132,6 +132,8 @@ def generate_early(self): ): self.multiworld.early_items[self.player]['Storm Ruler'] = 1 self.multiworld.local_items[self.player].value.add('Storm Ruler') + else: + self.yhorm_location = default_yhorm_location # Mark all items with similar distribution as non-local, so that pre_fill can leave a few to # be given as multiworld items. @@ -425,23 +427,18 @@ def get_filler_item_name(self) -> str: def set_rules(self) -> None: # Define the access rules to the entrances - set_rule(self.multiworld.get_entrance("Go To Firelink Shrine Bell Tower", self.player), - lambda state: state.has("Tower Key", self.player)) - set_rule(self.multiworld.get_entrance("Go To Undead Settlement", self.player), - lambda state: state.has("Small Lothric Banner", self.player)) - set_rule(self.multiworld.get_entrance("Go To Lothric Castle", self.player), - lambda state: state.has("Basin of Vows", self.player)) - set_rule(self.multiworld.get_entrance("Go To Irithyll of the Boreal Valley", self.player), - lambda state: state.has("Small Doll", self.player)) - set_rule(self.multiworld.get_entrance("Go To Archdragon Peak", self.player), - lambda state: state.has("Path of the Dragon", self.player)) - set_rule(self.multiworld.get_entrance("Go To Grand Archives", self.player), - lambda state: state.has("Grand Archives Key", self.player)) - set_rule(self.multiworld.get_entrance("Go To Kiln of the First Flame", self.player), - lambda state: state.has("Cinders of a Lord - Abyss Watcher", self.player) and - state.has("Cinders of a Lord - Yhorm the Giant", self.player) and - state.has("Cinders of a Lord - Aldrich", self.player) and - state.has("Cinders of a Lord - Lothric Prince", self.player)) + self._set_entrance_rule("Firelink Shrine Bell Tower", "Tower Key") + self._set_entrance_rule("Undead Settlement", "Small Lothric Banner") + self._set_entrance_rule("Lothric Castle", "Basin of Vows") + self._set_entrance_rule("Irithyll of the Boreal Valley", "Small Doll") + self._set_entrance_rule("Archdragon Peak", "Path of the Dragon") + self._set_entrance_rule("Grand Archives", "Grand Archives Key") + self._set_entrance_rule( + "Kiln of the First Flame", + lambda state: state.has("Cinders of a Lord - Abyss Watcher", self.player) and + state.has("Cinders of a Lord - Yhorm the Giant", self.player) and + state.has("Cinders of a Lord - Aldrich", self.player) and + state.has("Cinders of a Lord - Lothric Prince", self.player)) ashes = { "Mortician's Ashes": ["Alluring Skull", "Ember (Mortician)", "Grave Key"], @@ -474,102 +471,62 @@ def set_rules(self) -> None: } for ash, items in ashes.items(): for item in items: - location = "FS: " + item - if self.is_location_available(location): - set_rule(self.multiworld.get_location(location, self.player), - lambda state, ash=ash: state.has(ash, self.player)) + self._set_location_rule("FS: " + item, ash) if self.multiworld.late_basin_of_vows[self.player] == Toggle.option_true: - add_rule(self.multiworld.get_entrance("Go To Lothric Castle", self.player), - lambda state: state.has("Small Lothric Banner", self.player)) + self._set_entrance_rule("Lothric Castle", "Small Lothric Banner") # DLC Access Rules Below if self.multiworld.enable_dlc[self.player]: - set_rule(self.multiworld.get_entrance("Go To Ringed City", self.player), - lambda state: state.has("Small Envoy Banner", self.player)) - - # If key items are randomized, must have contraption key to enter second half of Ashes DLC - # If key items are not randomized, Contraption Key is guaranteed to be accessible before it is needed - if self.multiworld.enable_key_locations[self.player] == Toggle.option_true: - add_rule(self.multiworld.get_entrance("Go To Painted World of Ariandel (After Contraption)", self.player), - lambda state: state.has("Contraption Key", self.player)) + self._set_entrance_rule("Ringed City", "Small Envoy Banner") + self._set_entrance_rule("Painted World of Ariandel (After Contraption)", "Contraption Key") - if self.multiworld.late_dlc[self.player] == Toggle.option_true: - add_rule(self.multiworld.get_entrance("Go To Painted World of Ariandel (Before Contraption)", self.player), - lambda state: state.has("Small Doll", self.player)) + if self.multiworld.late_dlc[self.player]: + self._set_entrance_rule("Painted World of Ariandel (After Contraption)", "Small Doll") # Define the access rules to some specific locations - set_rule(self.multiworld.get_location("HWL: Red Eye Orb", self.player), - lambda state: state.has("Lift Chamber Key", self.player)) - - if self.multiworld.enable_ring_locations[self.player] == Toggle.option_true: - set_rule(self.multiworld.get_location("ID: Bellowing Dragoncrest Ring", self.player), - lambda state: state.has("Jailbreaker's Key", self.player)) - set_rule(self.multiworld.get_location("ID: Covetous Gold Serpent Ring", self.player), - lambda state: state.has("Old Cell Key", self.player)) - set_rule(self.multiworld.get_location("UG: Hornet Ring", self.player), - lambda state: state.has("Small Lothric Banner", self.player)) - - if self.multiworld.enable_npc_locations[self.player] == Toggle.option_true: - # Technically the player could lock themselves out of Greirat's shop if they send him to - # Lothric Castle before they have the Grand Archives Key with which to retrieve his - # ashes, but this is so unlikely it's not worth telling the randomizer that the shop is - # contingent on such a lategame item. - set_rule(self.multiworld.get_entrance("Go To Greirat's Shop", self.player), - lambda state: state.has("Cell Key", self.player)) - - set_rule(self.multiworld.get_entrance("Go To Karla's Shop", self.player), - lambda state: state.has("Jailer's Key Ring", self.player)) - for item in ["Leonhard's Garb", "Leonhard's Gauntlets", "Leonhard's Trousers"]: - set_rule(self.multiworld.get_location("AL: " + item, self.player), - lambda state: state.has("Black Eye Orb", self.player)) - - # You could just kill NPCs for these, but it's more fun to ensure the player can do - # their quests. - set_rule(self.multiworld.get_location("FS: Lift Chamber Key", self.player), - lambda state: state.has("Pale Tongue", self.player)) - - if self.multiworld.enable_unique_locations[self.player] == Toggle.option_true: - set_rule(self.multiworld.get_location("AP: Hawkwood's Swordgrass", self.player), - lambda state: state.has("Twinkling Dragon Torso Stone", self.player)) - set_rule(self.multiworld.get_location("ID: Prisoner Chief's Ashes", self.player), - lambda state: state.has("Jailer's Key Ring", self.player)) - - # Make sure that the player can keep Orbeck around by giving him at least one scroll - # before killing Abyss Watchers. - def has_any_scroll(state): - return (state.has("Sage's Scroll", self.player) or - state.has("Golden Scroll", self.player) or - state.has("Logan's Scroll", self.player) or - state.has("Crystal Scroll", self.player)) - if self.multiworld.enable_boss_locations[self.player] == Toggle.option_true: - set_rule(self.multiworld.get_location("FK: Soul of the Blood of the Wolf", self.player), - has_any_scroll) - set_rule(self.multiworld.get_location("FK: Cinders of a Lord - Abyss Watcher", self.player), - has_any_scroll) - set_rule(self.multiworld.get_entrance("Go To Catacombs of Carthus", self.player), - has_any_scroll) - - if self.multiworld.enable_boss_locations[self.player] == Toggle.option_true: - set_rule(self.multiworld.get_location("PC: Soul of Yhorm the Giant", self.player), - lambda state: state.has("Storm Ruler", self.player)) - set_rule(self.multiworld.get_location("HWL: Soul of the Dancer", self.player), - lambda state: state.has("Basin of Vows", self.player)) - - # Lump Soul of the Dancer in with LC for locations that should not be reachable - # before having access to US. (Prevents requiring getting Basin to fight Dancer to get SLB to go to US) - if self.multiworld.late_basin_of_vows[self.player] == Toggle.option_true: - add_rule(self.multiworld.get_location("HWL: Soul of the Dancer", self.player), - lambda state: state.has("Small Lothric Banner", self.player)) + self._set_location_rule("HWL: Red Eye Orb", "Lift Chamber Key") + self._set_location_rule("ID: Bellowing Dragoncrest Ring", "Jailbreaker's Key") + self._set_location_rule("ID: Covetous Gold Serpent Ring", "Old Cell Key") + self._set_location_rule("UG: Hornet Ring", "Small Lothric Banner") + self._set_entrance_rule("Karla's Shop", "Jailer's Key Ring") + + # The offline randomizer edits events to guarantee that Greirat won't go to Lothric until + # Grand Archives is available, so his shop will always be available one way or another. + self._set_entrance_rule("Greirat's Shop", "Cell Key") + + for item in ["Leonhard's Garb", "Leonhard's Gauntlets", "Leonhard's Trousers"]: + self._set_location_rule("AL: " + item, "Black Eye Orb") + + # You could just kill NPCs for these, but it's more fun to ensure the player can do + # their quests. + self._set_location_rule("FS: Lift Chamber Key", "Pale Tongue") + self._set_location_rule("AP: Hawkwood's Swordgrass", "Twinkling Dragon Torso Stone") + self._set_location_rule("ID: Prisoner Chief's Ashes", "Jailer's Key Ring") + + # Make sure that the player can keep Orbeck around by giving him at least one scroll + # before killing Abyss Watchers. + def has_any_scroll(state): + return (state.has("Sage's Scroll", self.player) or + state.has("Golden Scroll", self.player) or + state.has("Logan's Scroll", self.player) or + state.has("Crystal Scroll", self.player)) + self._set_location_rule("FK: Soul of the Blood of the Wolf", has_any_scroll) + self._set_location_rule("FK: Cinders of a Lord - Abyss Watcher", has_any_scroll) + self._set_entrance_rule("Catacombs of Carthus", has_any_scroll) + + self._set_location_rule("HWL: Soul of the Dancer", "Basin of Vows") + + # Lump Soul of the Dancer in with LC for locations that should not be reachable + # before having access to US. (Prevents requiring getting Basin to fight Dancer to get SLB to go to US) + if self.multiworld.late_basin_of_vows[self.player]: + self._set_location_rule("HWL: Soul of the Dancer", "Small Lothric Banner") gotthard_corpse_rule = lambda state: \ (state.can_reach("AL: Cinders of a Lord - Aldrich", "Location", self.player) and state.can_reach("PC: Cinders of a Lord - Yhorm the Giant", "Location", self.player)) - - set_rule(self.multiworld.get_location("LC: Grand Archives Key", self.player), gotthard_corpse_rule) - - if self.multiworld.enable_weapon_locations[self.player] == Toggle.option_true: - set_rule(self.multiworld.get_location("LC: Gotthard Twinswords", self.player), gotthard_corpse_rule) + self._set_location_rule("LC: Grand Archives Key", gotthard_corpse_rule) + self._set_location_rule("LC: Gotthard Twinswords", gotthard_corpse_rule) # Forbid shops from carrying items with multiple counts (the offline randomizer has its own # logic for choosing how many shop items to sell), and from carring soul items. @@ -582,17 +539,10 @@ def has_any_scroll(state): )) # Make sure the Storm Ruler is available BEFORE Yhorm the Giant - if self.yhorm_location: - if self.yhorm_location.region: - set_rule(self.multiworld.get_entrance(f"Go To {self.yhorm_location.region}", self.player), - lambda state: state.has("Storm Ruler", self.player)) - for location in self.yhorm_location.locations: - if self.is_location_available(location): - set_rule(self.multiworld.get_location(location, self.player), - lambda state: state.has("Storm Ruler", self.player)) - else: - set_rule(self.multiworld.get_location("PC: Cinders of a Lord - Yhorm the Giant", self.player), - lambda state: state.has("Storm Ruler", self.player)) + if self.yhorm_location.region: + self._set_entrance_rule(self.yhorm_location.region, "Storm Ruler") + for location in self.yhorm_location.locations: + self._set_location_rule(location, "Storm Ruler") self.multiworld.completion_condition[self.player] = lambda state: \ state.has("Cinders of a Lord - Abyss Watcher", self.player) and \ @@ -601,6 +551,28 @@ def has_any_scroll(state): state.has("Cinders of a Lord - Lothric Prince", self.player) + def _set_location_rule(self, location: str, rule: Union[CollectionRule, str]) -> None: + """Sets a rule for the given location if it that location is randomized. + + The rule can just be a single item/event name as well as an explicit rule lambda. + """ + if not self.is_location_available(location): return + if isinstance(rule, str): + item = rule + assert item_dictionary[item].classification == ItemClassification.progression + rule = lambda state: state.has(item, self.player) + set_rule(self.multiworld.get_location(location, self.player), rule) + + + def _set_entrance_rule(self, region: str, rule: Union[CollectionRule, str]) -> None: + """Sets a rule for the entrance to the given region.""" + if isinstance(rule, str): + item = rule + assert item_dictionary[item].classification == ItemClassification.progression + rule = lambda state: state.has(item, self.player) + set_rule(self.multiworld.get_entrance("Go To " + region, self.player), rule) + + def is_location_available(self, location: Union[str, DS3LocationData]) -> bool: """Returns whether the given location is being randomized.""" if isinstance(location, DS3LocationData): @@ -617,7 +589,7 @@ def is_location_available(self, location: Union[str, DS3LocationData]) -> bool: def write_spoiler(self, spoiler_handle: TextIO) -> None: - if self.yhorm_location: + if self.yhorm_location != default_yhorm_location: spoiler_handle.write(f"Yhorm takes the place of {self.yhorm_location.name}") @@ -787,7 +759,11 @@ def fill_slot_data(self) -> Dict[str, object]: }, "seed": self.multiworld.seed_name, # to verify the server's multiworld "slot": self.multiworld.player_name[self.player], # to connect to server - "yhorm": f"{self.yhorm_location.name} {self.yhorm_location.id}" if self.yhorm_location else None, + "yhorm": ( + f"{self.yhorm_location.name} {self.yhorm_location.id}" + if self.yhorm_location != default_yhorm_location + else None + ), "apIdsToItemIds": ap_ids_to_ds3_ids, "itemCounts": item_counts, "locationIdsToKeys": location_ids_to_keys, From 3509530c19799ae691e8fdefa84b315851dea8e3 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 2 Nov 2023 02:16:40 -0700 Subject: [PATCH 046/238] Support smoother soul item progression --- worlds/dark_souls_3/Fill.py | 40 +++-- worlds/dark_souls_3/Items.py | 101 +++++------ worlds/dark_souls_3/Locations.py | 292 ++++++++++++++++--------------- worlds/dark_souls_3/Options.py | 35 ++-- worlds/dark_souls_3/__init__.py | 76 ++++++-- 5 files changed, 312 insertions(+), 232 deletions(-) diff --git a/worlds/dark_souls_3/Fill.py b/worlds/dark_souls_3/Fill.py index 2f8a09605fb5..beb659190ca8 100644 --- a/worlds/dark_souls_3/Fill.py +++ b/worlds/dark_souls_3/Fill.py @@ -1,7 +1,8 @@ -from typing import List, Optional +from typing import List, Optional, Set, Union from BaseClasses import ItemClassification, LocationProgressType, MultiWorld +from .Items import item_dictionary from .Locations import location_tables class Fill: @@ -65,7 +66,7 @@ def __init__(self, world: "DarkSouls3World"): def fill( self, - name: str, + name_or_names: Union[str, Set[str]], start: Optional[str] = None, through: Optional[str] = None, count: int = 0, @@ -76,6 +77,9 @@ def fill( rewards are in the base game. If either start or through isn't passed, this fills from the beginning or through the end of the game, respectively. + The name can be a set of names, in which case the items to place are chosen randomly from + among all unplaced items with one of those names. + If count is positive, this will place up to that many copies of the item. If it's negative, this will place all but that many copies with the expectation that the remainder will be placed in other worlds. If it's 0, this will place all remaining copies in the item pool. @@ -86,10 +90,17 @@ def fill( important items in excluded locations. """ - all_items = [ - item for item in self.multiworld.itempool - if item.name == name and not item.location - ] + if isinstance(name_or_names, str): + all_items = [ + item for item in self.multiworld.itempool + if item.name == name_or_names and not item.location + ] + else: + all_items = [ + item for item in self.multiworld.itempool + if item.name in name_or_names and not item.location + ] + if count == 0 or count < 0 and len(self.multiworld.worlds) == 1: self.multiworld.random.shuffle(all_items) chosen_items = all_items @@ -98,6 +109,7 @@ def fill( count += len(all_items) if count < 1: return chosen_items = self.multiworld.random.sample(all_items, k = min(count, len(all_items))) + if len(chosen_items) == 0: return if start: assert start in self.regions if through: assert through in self.regions @@ -105,23 +117,25 @@ def fill( region_end = self.regions.index(through) + 1 if through else -1 selected_regions = self.regions[region_start:region_end] - filler = chosen_items[0].classification == ItemClassification.filler and not no_excluded + # All items are expected to have the same properties, so we choose one arbitrarily + item = chosen_items[0] + filler = item.classification == ItemClassification.filler and not no_excluded possible_locations = [ location for location in ( self.multiworld.get_location(location.name, self.player) for region in selected_regions for location in location_tables[region] if ( - self.world.is_location_available(location) and - not location.missable and - not location.conditional + self.world.is_location_available(location) + and not location.missable + and not location.conditional + and not (location.shop and item.souls) ) ) # Don't put important items in excluded locations. - if (filler or location.progress_type != LocationProgressType.EXCLUDED) - and not location.item + if not location.item + and (filler or location.progress_type != LocationProgressType.EXCLUDED) ] - if len(possible_locations) == 0: return if len(possible_locations) < len(chosen_items): chosen_items = self.multiworld.random.sample(chosen_items, k = len(possible_locations)) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index e6c948707f11..595f96b7c6c8 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -1,7 +1,7 @@ from dataclasses import dataclass, field import dataclasses from enum import IntEnum -from typing import ClassVar, Generator, List, Optional +from typing import ClassVar, Generator, List, Optional, Set from BaseClasses import Item, ItemClassification from Utils import flatten @@ -74,8 +74,8 @@ class DS3ItemData(): difference. """ - soul: bool = False - """Whether this is a consumable item that gives souls when used.""" + souls: Set[int] = None + """If this is a consumable item that gives souls, the number of souls it gives.""" useful_if: UsefulIf = UsefulIf.DEFAULT """Whether and when this item should be marked as "useful".""" @@ -116,7 +116,7 @@ def __eq__(self, other): class DarkSouls3Item(Item): game: str = "Dark Souls III" count: int = 1 - soul: bool = False + souls: Optional[int] = None def __init__( self, @@ -134,7 +134,7 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou data.ap_code, player) item.count = data.count - item.soul = data.soul + item.souls = data.souls return item _vanilla_items = flatten([ @@ -934,27 +934,28 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou DS3ItemData("Twinkling Dragon Torso Stone", 0x40000184, DS3ItemCategory.MISC, classification = ItemClassification.progression), DS3ItemData("Fire Keeper Soul", 0x40000186, DS3ItemCategory.MISC), - DS3ItemData("Fading Soul", 0x40000190, DS3ItemCategory.MISC, filler = True, soul = True), - DS3ItemData("Soul of a Deserted Corpse", 0x40000191, DS3ItemCategory.MISC, filler = True, soul = True), - DS3ItemData("Large Soul of a Deserted Corpse", 0x40000192, DS3ItemCategory.MISC, filler = True, soul = True), - DS3ItemData("Soul of an Unknown Traveler", 0x40000193, DS3ItemCategory.MISC, filler = True, soul = True), - DS3ItemData("Large Soul of an Unknown Traveler", 0x40000194, DS3ItemCategory.MISC, filler = True, soul = True), - DS3ItemData("Soul of a Nameless Soldier", 0x40000195, DS3ItemCategory.MISC, filler = True, soul = True), - DS3ItemData("Large Soul of a Nameless Soldier", 0x40000196, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Soul of a Weary Warrior", 0x40000197, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Large Soul of a Weary Warrior", 0x40000198, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Soul of a Crestfallen Knight", 0x40000199, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Large Soul of a Crestfallen Knight", 0x4000019A, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Soul of a Proud Paladin", 0x4000019B, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Large Soul of a Proud Paladin", 0x4000019C, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Soul of an Intrepid Hero", 0x4000019D, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Large Soul of an Intrepid Hero", 0x4000019E, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Soul of a Seasoned Warrior", 0x4000019F, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Large Soul of a Seasoned Warrior", 0x400001A0, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Soul of an Old Hand", 0x400001A1, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Soul of a Venerable Old Hand", 0x400001A2, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Soul of a Champion", 0x400001A3, DS3ItemCategory.MISC, soul = True), - DS3ItemData("Soul of a Great Champion", 0x400001A4, DS3ItemCategory.MISC, soul = True), + # Allow souls up to 2k in value to be used as filler + DS3ItemData("Fading Soul", 0x40000190, DS3ItemCategory.MISC, filler = True, souls = 50), + DS3ItemData("Soul of a Deserted Corpse", 0x40000191, DS3ItemCategory.MISC, filler = True, souls = 200), + DS3ItemData("Large Soul of a Deserted Corpse", 0x40000192, DS3ItemCategory.MISC, filler = True, souls = 400), + DS3ItemData("Soul of an Unknown Traveler", 0x40000193, DS3ItemCategory.MISC, filler = True, souls = 800), + DS3ItemData("Large Soul of an Unknown Traveler", 0x40000194, DS3ItemCategory.MISC, filler = True, souls = 1000), + DS3ItemData("Soul of a Nameless Soldier", 0x40000195, DS3ItemCategory.MISC, filler = True, souls = 2000), + DS3ItemData("Large Soul of a Nameless Soldier", 0x40000196, DS3ItemCategory.MISC, souls = 3000), + DS3ItemData("Soul of a Weary Warrior", 0x40000197, DS3ItemCategory.MISC, souls = 5000), + DS3ItemData("Large Soul of a Weary Warrior", 0x40000198, DS3ItemCategory.MISC, souls = 8000), + DS3ItemData("Soul of a Crestfallen Knight", 0x40000199, DS3ItemCategory.MISC, souls = 10000), + DS3ItemData("Large Soul of a Crestfallen Knight", 0x4000019A, DS3ItemCategory.MISC, souls = 20000), + DS3ItemData("Soul of a Proud Paladin", 0x4000019B, DS3ItemCategory.MISC, souls = 500), + DS3ItemData("Large Soul of a Proud Paladin", 0x4000019C, DS3ItemCategory.MISC, souls = 1000), + DS3ItemData("Soul of an Intrepid Hero", 0x4000019D, DS3ItemCategory.MISC, souls = 2000), + DS3ItemData("Large Soul of an Intrepid Hero", 0x4000019E, DS3ItemCategory.MISC, souls = 2500), + DS3ItemData("Soul of a Seasoned Warrior", 0x4000019F, DS3ItemCategory.MISC, souls = 5000), + DS3ItemData("Large Soul of a Seasoned Warrior", 0x400001A0, DS3ItemCategory.MISC, souls = 7500), + DS3ItemData("Soul of an Old Hand", 0x400001A1, DS3ItemCategory.MISC, souls = 12500), + DS3ItemData("Soul of a Venerable Old Hand", 0x400001A2, DS3ItemCategory.MISC, souls = 20000), + DS3ItemData("Soul of a Champion", 0x400001A3, DS3ItemCategory.MISC, souls = 25000), + DS3ItemData("Soul of a Great Champion", 0x400001A4, DS3ItemCategory.MISC, souls = 50000), DS3ItemData("Seed of a Giant Tree", 0x400001B8, DS3ItemCategory.SKIP, inject = True), DS3ItemData("Mossfruit", 0x400001C4, DS3ItemCategory.MISC, filler = True).counts([2]), @@ -974,45 +975,45 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou DS3ItemData("Very good! Carving", 0x4000020A, DS3ItemCategory.SKIP), DS3ItemData("I'm sorry Carving", 0x4000020B, DS3ItemCategory.SKIP), DS3ItemData("Help me! Carving", 0x4000020C, DS3ItemCategory.SKIP), - DS3ItemData("Soul of Champion Gundyr", 0x400002C8, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of Champion Gundyr", 0x400002C8, DS3ItemCategory.BOSS, souls = 20000, classification = ItemClassification.useful), - DS3ItemData("Soul of the Dancer", 0x400002CA, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of the Dancer", 0x400002CA, DS3ItemCategory.BOSS, souls = 10000, classification = ItemClassification.useful), - DS3ItemData("Soul of a Crystal Sage", 0x400002CB, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of a Crystal Sage", 0x400002CB, DS3ItemCategory.BOSS, souls = 3000, classification = ItemClassification.useful), - DS3ItemData("Soul of the Blood of the Wolf", 0x400002CD, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of the Blood of the Wolf", 0x400002CD, DS3ItemCategory.BOSS, souls = 20000, classification = ItemClassification.useful), - DS3ItemData("Soul of Consumed Oceiros", 0x400002CE, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of Consumed Oceiros", 0x400002CE, DS3ItemCategory.BOSS, souls = 12000, classification = ItemClassification.useful), - DS3ItemData("Soul of Boreal Valley Vordt", 0x400002CF, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of Boreal Valley Vordt", 0x400002CF, DS3ItemCategory.BOSS, souls = 2000, classification = ItemClassification.useful), - DS3ItemData("Soul of the Old Demon King", 0x400002D0, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of the Old Demon King", 0x400002D0, DS3ItemCategory.BOSS, souls = 10000, classification = ItemClassification.useful), - DS3ItemData("Soul of Dragonslayer Armour", 0x400002D1, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of Dragonslayer Armour", 0x400002D1, DS3ItemCategory.BOSS, souls = 15000, classification = ItemClassification.useful), - DS3ItemData("Soul of the Nameless King", 0x400002D2, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of the Nameless King", 0x400002D2, DS3ItemCategory.BOSS, souls = 16000, classification = ItemClassification.useful), - DS3ItemData("Soul of Pontiff Sulyvahn", 0x400002D4, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of Pontiff Sulyvahn", 0x400002D4, DS3ItemCategory.BOSS, souls = 12000, classification = ItemClassification.useful), - DS3ItemData("Soul of Aldrich", 0x400002D5, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of Aldrich", 0x400002D5, DS3ItemCategory.BOSS, souls = 15000, classification = ItemClassification.useful), - DS3ItemData("Soul of High Lord Wolnir", 0x400002D6, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of High Lord Wolnir", 0x400002D6, DS3ItemCategory.BOSS, souls = 10000, classification = ItemClassification.useful), - DS3ItemData("Soul of the Rotted Greatwood", 0x400002D7, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of the Rotted Greatwood", 0x400002D7, DS3ItemCategory.BOSS, souls = 3000, classification = ItemClassification.useful), - DS3ItemData("Soul of Rosaria", 0x400002D8, DS3ItemCategory.MISC, soul = True, + DS3ItemData("Soul of Rosaria", 0x400002D8, DS3ItemCategory.MISC, souls = 5000, classification = ItemClassification.useful), - DS3ItemData("Soul of the Deacons of the Deep", 0x400002D9, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of the Deacons of the Deep", 0x400002D9, DS3ItemCategory.BOSS, souls = 20000, classification = ItemClassification.useful), - DS3ItemData("Soul of the Twin Princes", 0x400002DB, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of the Twin Princes", 0x400002DB, DS3ItemCategory.BOSS, souls = 20000, classification = ItemClassification.useful), - DS3ItemData("Soul of Yhorm the Giant", 0x400002DC, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of Yhorm the Giant", 0x400002DC, DS3ItemCategory.BOSS, souls = 20000, classification = ItemClassification.useful), - DS3ItemData("Soul of the Lords", 0x400002DD, DS3ItemCategory.MISC, soul = True, + DS3ItemData("Soul of the Lords", 0x400002DD, DS3ItemCategory.MISC, souls = 20000, classification = ItemClassification.useful), - DS3ItemData("Soul of a Demon", 0x400002E3, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of a Demon", 0x400002E3, DS3ItemCategory.BOSS, souls = 20000, classification = ItemClassification.useful), - DS3ItemData("Soul of a Stray Demon", 0x400002E7, DS3ItemCategory.BOSS, soul = True, + DS3ItemData("Soul of a Stray Demon", 0x400002E7, DS3ItemCategory.BOSS, souls = 20000, classification = ItemClassification.useful), DS3ItemData("Titanite Shard", 0x400003E8, DS3ItemCategory.MISC).counts([2]), DS3ItemData("Large Titanite Shard", 0x400003E9, DS3ItemCategory.MISC).counts([2, 3]), @@ -1382,10 +1383,10 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou DS3ItemData("Filianore's Spear Ornament", 0x4000017B, DS3ItemCategory.SKIP), DS3ItemData("Ritual Spear Fragment", 0x4000028A, DS3ItemCategory.SKIP), DS3ItemData("Divine Spear Fragment", 0x4000028B, DS3ItemCategory.SKIP), - DS3ItemData("Soul of Sister Friede", 0x400002E8, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of Slave Knight Gael", 0x400002E9, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of the Demon Prince", 0x400002EA, DS3ItemCategory.BOSS, soul = True), - DS3ItemData("Soul of Darkeater Midir", 0x400002EB, DS3ItemCategory.BOSS, soul = True), + DS3ItemData("Soul of Sister Friede", 0x400002E8, DS3ItemCategory.BOSS, souls = 20000), + DS3ItemData("Soul of Slave Knight Gael", 0x400002E9, DS3ItemCategory.BOSS, souls = 20000), + DS3ItemData("Soul of the Demon Prince", 0x400002EA, DS3ItemCategory.BOSS, souls = 20000), + DS3ItemData("Soul of Darkeater Midir", 0x400002EB, DS3ItemCategory.BOSS, souls = 20000), DS3ItemData("Champion's Bones", 0x40000869, DS3ItemCategory.SKIP), DS3ItemData("Captain's Ashes", 0x4000086A, DS3ItemCategory.MISC, classification = ItemClassification.progression), diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index eeea15f16aab..4680c4017af1 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -12,10 +12,12 @@ class DS3LocationCategory(IntEnum): RING = 3 SPELL = 4 KEY = 5 - BOSS = 6 - MISC = 7 - HEALTH = 8 - EVENT = 9 + MISC = 6 + HEALTH = 7 + EVENT = 8 + + SOUL = 9 + """The original location of a soul item.""" UPGRADE = 10 """The original location of any upgrade material. @@ -155,6 +157,7 @@ def location_groups(self) -> List[str]: if self.lizard: names.append("Small Crystal Lizards") if self.key: names.append("Keys") if self.category == DS3LocationCategory.UPGRADE: names.append("Upgrade") + if self.category == DS3LocationCategory.SOUL: names.append("Soul Items") if self.category == DS3LocationCategory.MISC: names.append("Miscellaneous") if self.hidden: names.append("Hidden") return names @@ -258,10 +261,10 @@ def get_name_to_id() -> dict: location_tables = { "Cemetery of Ash": [ - DS3LocationData("CA: Soul of a Deserted Corpse", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("CA: Soul of a Deserted Corpse", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), DS3LocationData("CA: Firebomb", "Firebomb x5", DS3LocationCategory.MISC), DS3LocationData("CA: Titanite Shard", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("CA: Soul of an Unknown Traveler", "Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("CA: Soul of an Unknown Traveler", "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("CA: Speckled Stoneplate Ring+1", "Speckled Stoneplate Ring+1", DS3LocationCategory.RING, ngp = True), DS3LocationData("CA: Titanite Scale", "Titanite Scale", DS3LocationCategory.UPGRADE, @@ -279,7 +282,7 @@ def get_name_to_id() -> dict: DS3LocationData("FS: Broken Straight Sword", "Broken Straight Sword", DS3LocationCategory.WEAPON), DS3LocationData("FS: Homeward Bone #1", "Homeward Bone", DS3LocationCategory.MISC), DS3LocationData("FS: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("FS: Soul of a Deserted Corpse", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("FS: Soul of a Deserted Corpse", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), DS3LocationData("FS: East-West Shield", "East-West Shield", DS3LocationCategory.SHIELD), DS3LocationData("FS: Homeward Bone #2", "Homeward Bone", DS3LocationCategory.MISC), DS3LocationData("FS: Ember #2", "Ember", DS3LocationCategory.MISC), @@ -431,9 +434,9 @@ def get_name_to_id() -> dict: missable = True), ], "High Wall of Lothric": [ - DS3LocationData("HWL: Soul of Boreal Valley Vordt", "Soul of Boreal Valley Vordt", DS3LocationCategory.BOSS, + DS3LocationData("HWL: Soul of Boreal Valley Vordt", "Soul of Boreal Valley Vordt", DS3LocationCategory.SOUL, prominent = True, boss = True), - DS3LocationData("HWL: Soul of the Dancer", "Soul of the Dancer", DS3LocationCategory.BOSS, + DS3LocationData("HWL: Soul of the Dancer", "Soul of the Dancer", DS3LocationCategory.SOUL, prominent = True, boss = True), DS3LocationData("HWL: Basin of Vows", "Basin of Vows", DS3LocationCategory.KEY, prominent = True, progression = True), @@ -443,13 +446,13 @@ def get_name_to_id() -> dict: hidden = True), # Down an obscured hallway DS3LocationData("HWL: Gold Pine Resin", "Gold Pine Resin x2", DS3LocationCategory.MISC, hidden = True), # Hidden fall - DS3LocationData("HWL: Large Soul of a Deserted Corpse #1", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC), - DS3LocationData("HWL: Soul of a Deserted Corpse #1", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("HWL: Large Soul of a Deserted Corpse #1", "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + DS3LocationData("HWL: Soul of a Deserted Corpse #1", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), DS3LocationData("HWL: Standard Arrow", "Standard Arrow x12", DS3LocationCategory.MISC), DS3LocationData("HWL: Longbow", "Longbow", DS3LocationCategory.WEAPON), DS3LocationData("HWL: Firebomb #1", "Firebomb x3", DS3LocationCategory.MISC), DS3LocationData("HWL: Throwing Knife #1", "Throwing Knife x8", DS3LocationCategory.MISC), - DS3LocationData("HWL: Soul of a Deserted Corpse #2", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("HWL: Soul of a Deserted Corpse #2", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), DS3LocationData("HWL: Club", "Club", DS3LocationCategory.WEAPON), DS3LocationData("HWL: Claymore", "Claymore", DS3LocationCategory.WEAPON), DS3LocationData("HWL: Ember #1", "Ember", DS3LocationCategory.MISC), @@ -462,15 +465,15 @@ def get_name_to_id() -> dict: DS3LocationData("HWL: Cell Key", "Cell Key", DS3LocationCategory.KEY, key = True), DS3LocationData("HWL: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("HWL: Soul of a Deserted Corpse #3", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("HWL: Soul of a Deserted Corpse #3", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), DS3LocationData("HWL: Lucerne", "Lucerne", DS3LocationCategory.WEAPON), DS3LocationData("HWL: Mail Breaker", "Mail Breaker", DS3LocationCategory.WEAPON), DS3LocationData("HWL: Titanite Shard #2", "Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("HWL: Rapier", "Rapier", DS3LocationCategory.WEAPON), DS3LocationData("HWL: Titanite Shard #3", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("HWL: Large Soul of a Deserted Corpse #2", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("HWL: Large Soul of a Deserted Corpse #2", "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), DS3LocationData("HWL: Black Firebomb", "Black Firebomb x3", DS3LocationCategory.MISC), - DS3LocationData("HWL: Soul of a Deserted Corpse #4", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("HWL: Soul of a Deserted Corpse #4", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), DS3LocationData("HWL: Ember #3", "Ember", DS3LocationCategory.MISC), DS3LocationData("HWL: Large Soul of a Deserted Corpse #3", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC, hidden = True), # Easily missed turnoff @@ -478,12 +481,12 @@ def get_name_to_id() -> dict: DS3LocationData("HWL: Ring of Sacrifice", "Ring of Sacrifice", DS3LocationCategory.MISC, hidden = True), # Easily missed turnoff DS3LocationData("HWL: Throwing Knife #2", "Throwing Knife x6", DS3LocationCategory.MISC), - DS3LocationData("HWL: Soul of a Deserted Corpse #5", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("HWL: Soul of a Deserted Corpse #5", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), DS3LocationData("HWL: Green Blossom #2", "Green Blossom x3", DS3LocationCategory.MISC), DS3LocationData("HWL: Broadsword", "Broadsword", DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Soul of a Deserted Corpse #6", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("HWL: Soul of a Deserted Corpse #6", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), DS3LocationData("HWL: Firebomb #4", "Firebomb x3", DS3LocationCategory.MISC), - DS3LocationData("HWL: Soul of a Deserted Corpse #7", "Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("HWL: Soul of a Deserted Corpse #7", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), DS3LocationData("HWL: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), DS3LocationData("HWL: Fleshbite Ring+1", "Fleshbite Ring+1", DS3LocationCategory.RING, hidden = True, ngp = True), # Hidden jump @@ -518,7 +521,7 @@ def get_name_to_id() -> dict: missable = True, boss = True, shop = True), ], "Undead Settlement": [ - DS3LocationData("US: Soul of the Rotted Greatwood", "Soul of the Rotted Greatwood", DS3LocationCategory.BOSS, + DS3LocationData("US: Soul of the Rotted Greatwood", "Soul of the Rotted Greatwood", DS3LocationCategory.SOUL, prominent = True, boss = True), DS3LocationData("US: Transposing Kiln", "Transposing Kiln", DS3LocationCategory.UNIQUE, boss = True), @@ -545,14 +548,14 @@ def get_name_to_id() -> dict: hidden = True), # Hidden fall DS3LocationData("US: Caduceus Round Shield", "Caduceus Round Shield", DS3LocationCategory.SHIELD), DS3LocationData("US: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("US: Soul of an Unknown Traveler #1", "Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("US: Soul of an Unknown Traveler #1", "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("US: Repair Powder", "Repair Powder x2", DS3LocationCategory.MISC), DS3LocationData("US: Homeward Bone #2", "Homeward Bone x2", DS3LocationCategory.MISC), DS3LocationData("US: Titanite Shard #1", "Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("US: Wargod Wooden Shield", "Wargod Wooden Shield", DS3LocationCategory.SHIELD), - DS3LocationData("US: Large Soul of a Deserted Corpse #1", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("US: Large Soul of a Deserted Corpse #1", "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), DS3LocationData("US: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("US: Large Soul of a Deserted Corpse #2", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("US: Large Soul of a Deserted Corpse #2", "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), DS3LocationData("US: Titanite Shard #2", "Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("US: Alluring Skull #2", "Alluring Skull x2", DS3LocationCategory.MISC), DS3LocationData("US: Charcoal Pine Bundle #1", "Charcoal Pine Bundle x2", DS3LocationCategory.MISC), @@ -561,7 +564,7 @@ def get_name_to_id() -> dict: DS3LocationData("US: Cleric Blue Robe", "Cleric Blue Robe", DS3LocationCategory.ARMOR), DS3LocationData("US: Cleric Gloves", "Cleric Gloves", DS3LocationCategory.ARMOR), DS3LocationData("US: Cleric Trousers", "Cleric Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("US: Soul of an Unknown Traveler #2", "Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("US: Soul of an Unknown Traveler #2", "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("US: Charcoal Pine Resin", "Charcoal Pine Resin x2", DS3LocationCategory.MISC), DS3LocationData("US: Loincloth", "Loincloth", DS3LocationCategory.ARMOR), DS3LocationData("US: Bloodbite Ring", "Bloodbite Ring", DS3LocationCategory.RING, @@ -582,7 +585,7 @@ def get_name_to_id() -> dict: DS3LocationData("US: Titanite Shard #6", "Titanite Shard", DS3LocationCategory.UPGRADE, hidden = True), # hidden fall DS3LocationData("US: Hand Axe", "Hand Axe", DS3LocationCategory.WEAPON), - DS3LocationData("US: Soul of an Unknown Traveler #4", "Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("US: Soul of an Unknown Traveler #4", "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("US: Ember #3", "Ember", DS3LocationCategory.MISC), DS3LocationData("US: Mirrah Vest", "Mirrah Vest", DS3LocationCategory.ARMOR, hidden = True), # Hidden fall @@ -602,16 +605,16 @@ def get_name_to_id() -> dict: # and make this room obvious DS3LocationData("US: Great Scythe", "Great Scythe", DS3LocationCategory.WEAPON), DS3LocationData("US: Homeward Bone #3", "Homeward Bone x2", DS3LocationCategory.MISC), - DS3LocationData("US: Large Soul of a Deserted Corpse #3", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("US: Large Soul of a Deserted Corpse #3", "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), DS3LocationData("US: Ember #4", "Ember", DS3LocationCategory.MISC), - DS3LocationData("US: Large Soul of a Deserted Corpse #4", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("US: Large Soul of a Deserted Corpse #4", "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), DS3LocationData("US: Fading Soul #2", "Fading Soul", DS3LocationCategory.MISC), DS3LocationData("US: Young White Branch #1", "Young White Branch", DS3LocationCategory.MISC), DS3LocationData("US: Ember #5", "Ember", DS3LocationCategory.MISC), - DS3LocationData("US: Large Soul of a Deserted Corpse #5", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("US: Large Soul of a Deserted Corpse #5", "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), DS3LocationData("US: Young White Branch #2", "Young White Branch", DS3LocationCategory.MISC), DS3LocationData("US: Reinforced Club", "Reinforced Club", DS3LocationCategory.WEAPON), - DS3LocationData("US: Soul of a Nameless Soldier", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("US: Soul of a Nameless Soldier", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("US: Loretta's Bone", "Loretta's Bone", DS3LocationCategory.KEY), DS3LocationData("US: Northern Helm", "Northern Helm", DS3LocationCategory.ARMOR), DS3LocationData("US: Northern Armor", "Northern Armor", DS3LocationCategory.ARMOR), @@ -624,7 +627,7 @@ def get_name_to_id() -> dict: offline = "02,0:53100740::"), DS3LocationData("US: Small Leather Shield", "Small Leather Shield", DS3LocationCategory.SHIELD), DS3LocationData("US: Pale Tongue", "Pale Tongue", DS3LocationCategory.MISC), - DS3LocationData("US: Large Soul of a Deserted Corpse #6", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC), + DS3LocationData("US: Large Soul of a Deserted Corpse #6", "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), DS3LocationData("US: Kukri", "Kukri x9", DS3LocationCategory.MISC, missable = True), # requires projectile DS3LocationData("US: Life Ring+1", "Life Ring+1", DS3LocationCategory.RING, @@ -746,7 +749,7 @@ def get_name_to_id() -> dict: missable = True, npc = True, shop = True), ], "Road of Sacrifices": [ - DS3LocationData("RS: Soul of a Crystal Sage", "Soul of a Crystal Sage", DS3LocationCategory.BOSS, + DS3LocationData("RS: Soul of a Crystal Sage", "Soul of a Crystal Sage", DS3LocationCategory.SOUL, prominent = True, boss = True), DS3LocationData("RS: Exile Greatsword", "Exile Greatsword", DS3LocationCategory.WEAPON, hostile_npc = True), # Exile Knight #2 drop @@ -764,18 +767,18 @@ def get_name_to_id() -> dict: DS3LocationData("RS: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), DS3LocationData("RS: Ring of Sacrifice", "Ring of Sacrifice", DS3LocationCategory.MISC, hidden = True), # hidden fall - DS3LocationData("RS: Soul of an Unknown Traveler #1", "Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("RS: Soul of an Unknown Traveler #1", "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("RS: Fallen Knight Helm", "Fallen Knight Helm", DS3LocationCategory.ARMOR), DS3LocationData("RS: Fallen Knight Armor", "Fallen Knight Armor", DS3LocationCategory.ARMOR), DS3LocationData("RS: Fallen Knight Gauntlets", "Fallen Knight Gauntlets", DS3LocationCategory.ARMOR), DS3LocationData("RS: Fallen Knight Trousers", "Fallen Knight Trousers", DS3LocationCategory.ARMOR), DS3LocationData("RS: Heretic's Staff", "Heretic's Staff", DS3LocationCategory.WEAPON), - DS3LocationData("RS: Large Soul of an Unknown Traveler", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("RS: Large Soul of an Unknown Traveler", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("RS: Conjurator Hood", "Conjurator Hood", DS3LocationCategory.ARMOR), DS3LocationData("RS: Conjurator Robe", "Conjurator Robe", DS3LocationCategory.ARMOR), DS3LocationData("RS: Conjurator Manchettes", "Conjurator Manchettes", DS3LocationCategory.ARMOR), DS3LocationData("RS: Conjurator Boots", "Conjurator Boots", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Soul of an Unknown Traveler #2", "Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("RS: Soul of an Unknown Traveler #2", "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("RS: Green Blossom #2", "Green Blossom x2", DS3LocationCategory.MISC), DS3LocationData("RS: Great Swamp Pyromancy Tome", "Great Swamp Pyromancy Tome", DS3LocationCategory.UNIQUE), DS3LocationData("RS: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC), @@ -794,7 +797,7 @@ def get_name_to_id() -> dict: DS3LocationData("RS: Grass Crest Shield", "Grass Crest Shield", DS3LocationCategory.SHIELD), DS3LocationData("RS: Ember #1", "Ember", DS3LocationCategory.MISC), DS3LocationData("RS: Blue Bug Pellet", "Blue Bug Pellet x2", DS3LocationCategory.MISC), - DS3LocationData("RS: Soul of an Unknown Traveler #3", "Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("RS: Soul of an Unknown Traveler #3", "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("RS: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), DS3LocationData("RS: Titanite Shard #4", "Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("RS: Brigand Twindaggers", "Brigand Twindaggers", DS3LocationCategory.WEAPON), @@ -909,7 +912,7 @@ def get_name_to_id() -> dict: lizard = True), DS3LocationData("CD: Small Doll", "Small Doll", DS3LocationCategory.KEY, prominent = True, progression = True, boss = True), - DS3LocationData("CD: Soul of the Deacons of the Deep", "Soul of the Deacons of the Deep", DS3LocationCategory.BOSS, + DS3LocationData("CD: Soul of the Deacons of the Deep", "Soul of the Deacons of the Deep", DS3LocationCategory.SOUL, boss = True), DS3LocationData("CD: Black Eye Orb", "Black Eye Orb", DS3LocationCategory.UNIQUE, missable = True, npc = True), @@ -924,7 +927,7 @@ def get_name_to_id() -> dict: DS3LocationData("CD: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), DS3LocationData("CD: Curse Ward Greatshield", "Curse Ward Greatshield", DS3LocationCategory.SHIELD), DS3LocationData("CD: Titanite Shard #2", "Titanite Shard", DS3LocationCategory.MISC), - DS3LocationData("CD: Large Soul of an Unknown Traveler #1", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("CD: Large Soul of an Unknown Traveler #1", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("CD: Paladin's Ashes", "Paladin's Ashes", DS3LocationCategory.KEY, progression = True), DS3LocationData("CD: Arbalest", "Arbalest", DS3LocationCategory.WEAPON, @@ -947,13 +950,13 @@ def get_name_to_id() -> dict: DS3LocationData("CD: Blessed Gem", "Blessed Gem", DS3LocationCategory.UPGRADE, hidden = True), # hidden fall DS3LocationData("CD: Red Bug Pellet #1", "Red Bug Pellet", DS3LocationCategory.MISC), - DS3LocationData("CD: Soul of a Nameless Soldier #1", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("CD: Soul of a Nameless Soldier #1", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("CD: Duel Charm #2", "Duel Charm", DS3LocationCategory.MISC), - DS3LocationData("CD: Large Soul of an Unknown Traveler #2", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("CD: Large Soul of an Unknown Traveler #2", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("CD: Ember #4", "Ember", DS3LocationCategory.MISC), DS3LocationData("CD: Repair Powder", "Repair Powder x3", DS3LocationCategory.MISC), - DS3LocationData("CD: Large Soul of an Unknown Traveler #3", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), - DS3LocationData("CD: Large Soul of an Unknown Traveler #4", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("CD: Large Soul of an Unknown Traveler #3", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("CD: Large Soul of an Unknown Traveler #4", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("CD: Undead Hunter Charm", "Undead Hunter Charm x3", DS3LocationCategory.MISC, hidden = True), # Have to jump from a buttress DS3LocationData("CD: Red Bug Pellet #2", "Red Bug Pellet x3", DS3LocationCategory.MISC), @@ -962,17 +965,17 @@ def get_name_to_id() -> dict: DS3LocationData("CD: Rusted Coin #1", "Rusted Coin x2", DS3LocationCategory.MISC), DS3LocationData("CD: Drang Hammers", "Drang Hammers", DS3LocationCategory.WEAPON), DS3LocationData("CD: Drang Shoes", "Drang Shoes", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Large Soul of an Unknown Traveler #5", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("CD: Large Soul of an Unknown Traveler #5", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("CD: Pale Tongue #2", "Pale Tongue", DS3LocationCategory.MISC), DS3LocationData("CD: Drang Gauntlets", "Drang Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Soul of a Nameless Soldier #2", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("CD: Soul of a Nameless Soldier #2", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("CD: Exploding Bolt", "Exploding Bolt x6", DS3LocationCategory.MISC), DS3LocationData("CD: Lloyd's Sword Ring", "Lloyd's Sword Ring", DS3LocationCategory.RING), - DS3LocationData("CD: Soul of a Nameless Soldier #3", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("CD: Soul of a Nameless Soldier #3", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("CD: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC), DS3LocationData("CD: Deep Gem", "Deep Gem", DS3LocationCategory.UPGRADE), DS3LocationData("CD: Titanite Shard #5", "Titanite Shard", DS3LocationCategory.MISC), - DS3LocationData("CD: Large Soul of an Unknown Traveler #6", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("CD: Large Soul of an Unknown Traveler #6", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), # Before the stairs leading down into the Deacons fight DS3LocationData("CD: Ring of the Evil Eye+1", "Ring of the Evil Eye+1", DS3LocationCategory.RING, ngp = True), @@ -1051,7 +1054,7 @@ def get_name_to_id() -> dict: "Farron Keep": [ DS3LocationData("FK: Lightning Spear", "Lightning Spear", DS3LocationCategory.WEAPON), DS3LocationData("FK: Dragon Crest Shield", "Dragon Crest Shield", DS3LocationCategory.SHIELD), - DS3LocationData("FK: Soul of the Blood of the Wolf", "Soul of the Blood of the Wolf", DS3LocationCategory.BOSS, + DS3LocationData("FK: Soul of the Blood of the Wolf", "Soul of the Blood of the Wolf", DS3LocationCategory.SOUL, boss = True), DS3LocationData("FK: Cinders of a Lord - Abyss Watcher", "Cinders of a Lord - Abyss Watcher", DS3LocationCategory.KEY, offline = "03,0:50002100::", prominent = True, progression = True, boss = True), @@ -1099,14 +1102,14 @@ def get_name_to_id() -> dict: DS3LocationData("FK: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), DS3LocationData("FK: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.HEALTH), DS3LocationData("FK: Titanite Shard #7", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("FK: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("FK: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("FK: Prism Stone", "Prism Stone x10", DS3LocationCategory.MISC), - DS3LocationData("FK: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("FK: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("FK: Sage's Coal", "Sage's Coal", DS3LocationCategory.UNIQUE), DS3LocationData("FK: Gold Pine Bundle", "Gold Pine Bundle x6", DS3LocationCategory.MISC), DS3LocationData("FK: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("FK: Soul of a Nameless Soldier", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), - DS3LocationData("FK: Large Soul of an Unknown Traveler", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("FK: Soul of a Nameless Soldier", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("FK: Large Soul of an Unknown Traveler", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("FK: Greataxe", "Greataxe", DS3LocationCategory.WEAPON), DS3LocationData("FK: Ember #3", "Ember", DS3LocationCategory.MISC), DS3LocationData("FK: Ember #4", "Ember", DS3LocationCategory.MISC), @@ -1140,7 +1143,7 @@ def get_name_to_id() -> dict: lizard = True), DS3LocationData("FK: Twinkling Titanite", "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("FK: Soul of a Stray Demon", "Soul of a Stray Demon", DS3LocationCategory.BOSS, + DS3LocationData("FK: Soul of a Stray Demon", "Soul of a Stray Demon", DS3LocationCategory.SOUL, miniboss = True), DS3LocationData("FK: Watchdogs of Farron", "Watchdogs of Farron", DS3LocationCategory.UNIQUE), DS3LocationData("FK: Hawkwood's Shield", "Hawkwood's Shield", DS3LocationCategory.SHIELD, @@ -1175,11 +1178,11 @@ def get_name_to_id() -> dict: boss = True, shop = True), ], "Catacombs of Carthus": [ - DS3LocationData("CC: Soul of High Lord Wolnir", "Soul of High Lord Wolnir", DS3LocationCategory.BOSS, + DS3LocationData("CC: Soul of High Lord Wolnir", "Soul of High Lord Wolnir", DS3LocationCategory.SOUL, prominent = True, boss = True), DS3LocationData("CC: Carthus Rouge #1", "Carthus Rouge x2", DS3LocationCategory.MISC), DS3LocationData("CC: Sharp Gem", "Sharp Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("CC: Soul of a Nameless Soldier #1", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("CC: Soul of a Nameless Soldier #1", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("CC: Titanite Shard #1", "Titanite Shard x2", DS3LocationCategory.UPGRADE), DS3LocationData("CC: Bloodred Moss Clump", "Bloodred Moss Clump x3", DS3LocationCategory.MISC), DS3LocationData("CC: Carthus Milkring", "Carthus Milkring", DS3LocationCategory.RING), @@ -1195,17 +1198,17 @@ def get_name_to_id() -> dict: DS3LocationData("CC: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.MISC), DS3LocationData("CC: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.MISC), DS3LocationData("CC: Yellow Bug Pellet", "Yellow Bug Pellet x3", DS3LocationCategory.MISC), - DS3LocationData("CC: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("CC: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("CC: Black Bug Pellet", "Black Bug Pellet x2", DS3LocationCategory.MISC), DS3LocationData("CC: Grave Warden's Ashes", "Grave Warden's Ashes", DS3LocationCategory.KEY, progression = True), DS3LocationData("CC: Large Titanite Shard #3", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("CC: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("CC: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("CC: Old Sage's Blindfold", "Old Sage's Blindfold", DS3LocationCategory.ARMOR), DS3LocationData("CC: Witch's Ring", "Witch's Ring", DS3LocationCategory.RING), - DS3LocationData("CC: Soul of a Nameless Soldier #2", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("CC: Soul of a Nameless Soldier #2", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("CC: Grave Warden Pyromancy Tome", "Grave Warden Pyromancy Tome", DS3LocationCategory.UNIQUE), - DS3LocationData("CC: Large Soul of an Unknown Traveler", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("CC: Large Soul of an Unknown Traveler", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("CC: Ring of Steel Protection+2", "Ring of Steel Protection+2", DS3LocationCategory.RING, ngp = True), DS3LocationData("CC: Thunder Stoneplate Ring+1", "Thunder Stoneplate Ring+1", DS3LocationCategory.RING, @@ -1216,7 +1219,7 @@ def get_name_to_id() -> dict: hidden = True), # Skeleton Ball puzzle DS3LocationData("CC: Black Blade", "Black Blade", DS3LocationCategory.WEAPON, mimic = True), - DS3LocationData("CC: Soul of a Demon", "Soul of a Demon", DS3LocationCategory.BOSS, + DS3LocationData("CC: Soul of a Demon", "Soul of a Demon", DS3LocationCategory.SOUL, miniboss = True), DS3LocationData("CC: Twinkling Titanite", "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), @@ -1239,7 +1242,7 @@ def get_name_to_id() -> dict: boss = True, shop = True), ], "Smouldering Lake": [ - DS3LocationData("SL: Soul of the Old Demon King", "Soul of the Old Demon King", DS3LocationCategory.BOSS, + DS3LocationData("SL: Soul of the Old Demon King", "Soul of the Old Demon King", DS3LocationCategory.SOUL, prominent = True, boss = True), DS3LocationData("SL: Fume Ultra Greatsword", "Fume Ultra Greatsword", DS3LocationCategory.WEAPON, @@ -1275,7 +1278,7 @@ def get_name_to_id() -> dict: DS3LocationData("SL: Undead Bone Shard #1", "Undead Bone Shard", DS3LocationCategory.HEALTH), DS3LocationData("SL: Titanite Scale", "Titanite Scale", DS3LocationCategory.UPGRADE), DS3LocationData("SL: Shield of Want", "Shield of Want", DS3LocationCategory.SHIELD), - DS3LocationData("SL: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("SL: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), DS3LocationData("SL: Ember #4", "Ember", DS3LocationCategory.MISC, missable = True), # In lava DS3LocationData("SL: Sacred Flame", "Sacred Flame", DS3LocationCategory.SPELL, @@ -1343,12 +1346,12 @@ def get_name_to_id() -> dict: offline = '02,0:53100100::', missable = True, boss = True, npc = True), ], "Irithyll of the Boreal Valley": [ - DS3LocationData("IBV: Soul of Pontiff Sulyvahn", "Soul of Pontiff Sulyvahn", DS3LocationCategory.BOSS, + DS3LocationData("IBV: Soul of Pontiff Sulyvahn", "Soul of Pontiff Sulyvahn", DS3LocationCategory.SOUL, prominent = True, boss = True), - DS3LocationData("IBV: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("IBV: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("IBV: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("IBV: Soul of a Weary Warrior #1", "Soul of a Weary Warrior", DS3LocationCategory.MISC), - DS3LocationData("IBV: Soul of a Weary Warrior #2", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("IBV: Soul of a Weary Warrior #1", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("IBV: Soul of a Weary Warrior #2", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("IBV: Rime-blue Moss Clump #1", "Rime-blue Moss Clump", DS3LocationCategory.MISC), DS3LocationData("IBV: Witchtree Branch", "Witchtree Branch", DS3LocationCategory.WEAPON, hidden = True), # Behind illusory wall @@ -1358,10 +1361,10 @@ def get_name_to_id() -> dict: DS3LocationData("IBV: Large Titanite Shard #3", "Large Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("IBV: Large Titanite Shard #4", "Large Titanite Shard", DS3LocationCategory.UPGRADE, hidden = True), # Behind illusory wall - DS3LocationData("IBV: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("IBV: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("IBV: Large Titanite Shard #5", "Large Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("IBV: Large Titanite Shard #6", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("IBV: Soul of a Weary Warrior #3", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("IBV: Soul of a Weary Warrior #3", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("IBV: Magic Clutch Ring", "Magic Clutch Ring", DS3LocationCategory.RING, hidden = True), # Behind illusory wall DS3LocationData("IBV: Fading Soul #1", "Fading Soul", DS3LocationCategory.MISC), @@ -1377,22 +1380,22 @@ def get_name_to_id() -> dict: DS3LocationData("IBV: Green Blossom #1", "Green Blossom x3", DS3LocationCategory.MISC), DS3LocationData("IBV: Ring of Sacrifice", "Ring of Sacrifice", DS3LocationCategory.MISC), DS3LocationData("IBV: Great Heal", "Great Heal", DS3LocationCategory.SPELL), - DS3LocationData("IBV: Large Soul of a Nameless Soldier #3", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("IBV: Large Soul of a Nameless Soldier #3", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("IBV: Green Blossom #2", "Green Blossom x3", DS3LocationCategory.MISC), DS3LocationData("IBV: Dung Pie #1", "Dung Pie x3", DS3LocationCategory.MISC), DS3LocationData("IBV: Dung Pie #2", "Dung Pie x3", DS3LocationCategory.MISC), # These don't actually guard any single item sales. Maybe we can inject one manually? DS3LocationData("IBV: Excrement-covered Ashes", "Excrement-covered Ashes", DS3LocationCategory.UNIQUE), - DS3LocationData("IBV: Large Soul of a Nameless Soldier #4", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), - DS3LocationData("IBV: Soul of a Weary Warrior #4", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("IBV: Large Soul of a Nameless Soldier #4", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("IBV: Soul of a Weary Warrior #4", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("IBV: Large Titanite Shard #7", "Large Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("IBV: Blue Bug Pellet #2", "Blue Bug Pellet x2", DS3LocationCategory.MISC), DS3LocationData("IBV: Ember", "Ember", DS3LocationCategory.MISC), DS3LocationData("IBV: Large Titanite Shard #8", "Large Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("IBV: Green Blossom #3", "Green Blossom", DS3LocationCategory.MISC), DS3LocationData("IBV: Lightning Gem", "Lightning Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("IBV: Large Soul of a Nameless Soldier #5", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), - DS3LocationData("IBV: Soul of a Weary Warrior #5", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("IBV: Large Soul of a Nameless Soldier #5", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("IBV: Soul of a Weary Warrior #5", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("IBV: Proof of a Concord Kept", "Proof of a Concord Kept", DS3LocationCategory.MISC), DS3LocationData("IBV: Rusted Gold Coin #2", "Rusted Gold Coin", DS3LocationCategory.MISC, hidden = True), # Hidden fall @@ -1477,23 +1480,23 @@ def get_name_to_id() -> dict: missable = True, npc = True), # Alva (requires ember) DS3LocationData("ID: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("ID: Fading Soul", "Fading Soul", DS3LocationCategory.MISC), - DS3LocationData("ID: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("ID: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("ID: Jailbreaker's Key", "Jailbreaker's Key", DS3LocationCategory.KEY, key = True), DS3LocationData("ID: Pale Pine Resin", "Pale Pine Resin x2", DS3LocationCategory.MISC), DS3LocationData("ID: Simple Gem", "Simple Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("ID: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("ID: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("ID: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("ID: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC), DS3LocationData("ID: Bellowing Dragoncrest Ring", "Bellowing Dragoncrest Ring", DS3LocationCategory.RING, conditional = True), - DS3LocationData("ID: Soul of a Weary Warrior #1", "Soul of a Weary Warrior", DS3LocationCategory.MISC), - DS3LocationData("ID: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("ID: Soul of a Weary Warrior #1", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("ID: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), DS3LocationData("ID: Lightning Bolt", "Lightning Bolt x9", DS3LocationCategory.MISC), DS3LocationData("ID: Large Titanite Shard #3", "Large Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("ID: Profaned Flame", "Profaned Flame", DS3LocationCategory.SPELL), DS3LocationData("ID: Large Titanite Shard #4", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("ID: Soul of a Weary Warrior #2", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("ID: Soul of a Weary Warrior #2", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("ID: Dung Pie #1", "Dung Pie x4", DS3LocationCategory.MISC), DS3LocationData("ID: Ember #1", "Ember", DS3LocationCategory.MISC), DS3LocationData("ID: Ember #2", "Ember", DS3LocationCategory.MISC), @@ -1503,7 +1506,7 @@ def get_name_to_id() -> dict: DS3LocationData("ID: Old Sorcerer Coat", "Old Sorcerer Coat", DS3LocationCategory.ARMOR), DS3LocationData("ID: Old Sorcerer Gauntlets", "Old Sorcerer Gauntlets", DS3LocationCategory.ARMOR), DS3LocationData("ID: Old Sorcerer Boots", "Old Sorcerer Boots", DS3LocationCategory.ARMOR), - DS3LocationData("ID: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("ID: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("ID: Covetous Gold Serpent Ring", "Covetous Gold Serpent Ring", DS3LocationCategory.RING, conditional = True), DS3LocationData("ID: Lightning Blade", "Lightning Blade", DS3LocationCategory.SPELL), @@ -1550,7 +1553,7 @@ def get_name_to_id() -> dict: missable = True, npc = True), ], "Profaned Capital": [ - DS3LocationData("PC: Soul of Yhorm the Giant", "Soul of Yhorm the Giant", DS3LocationCategory.BOSS, + DS3LocationData("PC: Soul of Yhorm the Giant", "Soul of Yhorm the Giant", DS3LocationCategory.SOUL, boss = True), DS3LocationData("PC: Cinders of a Lord - Yhorm the Giant", "Cinders of a Lord - Yhorm the Giant", DS3LocationCategory.KEY, offline = "07,0:50002170::", prominent = True, progression = True, boss = True), @@ -1566,7 +1569,7 @@ def get_name_to_id() -> dict: DS3LocationData("PC: Poison Arrow", "Poison Arrow x18", DS3LocationCategory.MISC), DS3LocationData("PC: Rubbish", "Rubbish", DS3LocationCategory.MISC), DS3LocationData("PC: Onislayer Greatarrow", "Onislayer Greatarrow x8", DS3LocationCategory.MISC), - DS3LocationData("PC: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("PC: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("PC: Rusted Coin #2", "Rusted Coin", DS3LocationCategory.MISC), DS3LocationData("PC: Rusted Coin #3", "Rusted Coin", DS3LocationCategory.MISC), DS3LocationData("PC: Blooming Purple Moss Clump", "Blooming Purple Moss Clump x3", DS3LocationCategory.MISC), @@ -1615,7 +1618,7 @@ def get_name_to_id() -> dict: # match up one-to-one with where the game pops up the region name, but it balances items better # and covers the region that's full of DS1 Anor Londo references. "Anor Londo": [ - DS3LocationData("AL: Soul of Aldrich", "Soul of Aldrich", DS3LocationCategory.BOSS, + DS3LocationData("AL: Soul of Aldrich", "Soul of Aldrich", DS3LocationCategory.SOUL, boss = True), DS3LocationData("AL: Cinders of a Lord - Aldrich", "Cinders of a Lord - Aldrich", DS3LocationCategory.KEY, offline = '06,0:50002130::', prominent = True, progression = True, boss = True), @@ -1639,7 +1642,7 @@ def get_name_to_id() -> dict: DS3LocationData("AL: Ember #1", "Ember", DS3LocationCategory.MISC), DS3LocationData("AL: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("AL: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("AL: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("AL: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("AL: Ember #2", "Ember", DS3LocationCategory.MISC), DS3LocationData("AL: Ember #3", "Ember", DS3LocationCategory.MISC), DS3LocationData("AL: Large Titanite Shard #3", "Large Titanite Shard", DS3LocationCategory.UPGRADE), @@ -1661,10 +1664,10 @@ def get_name_to_id() -> dict: hidden = True), # Invisible walkway DS3LocationData("AL: Painting Guardian Waistcloth", "Painting Guardian Waistcloth", DS3LocationCategory.ARMOR, hidden = True), # Invisible walkway - DS3LocationData("AL: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("AL: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), DS3LocationData("AL: Moonlight Arrow", "Moonlight Arrow x6", DS3LocationCategory.MISC), DS3LocationData("AL: Proof of a Concord Kept", "Proof of a Concord Kept", DS3LocationCategory.MISC), - DS3LocationData("AL: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("AL: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("AL: Giant's Coal", "Giant's Coal", DS3LocationCategory.UNIQUE), DS3LocationData("AL: Havel's Ring+2", "Havel's Ring+2", DS3LocationCategory.RING, ngp = True, hidden = True), # Invisible walkway @@ -1765,7 +1768,7 @@ def get_name_to_id() -> dict: ], "Lothric Castle": [ - DS3LocationData("LC: Soul of Dragonslayer Armour", "Soul of Dragonslayer Armour", DS3LocationCategory.BOSS, + DS3LocationData("LC: Soul of Dragonslayer Armour", "Soul of Dragonslayer Armour", DS3LocationCategory.SOUL, prominent = True, boss = True), DS3LocationData("LC: Sniper Bolt", "Sniper Bolt x11", DS3LocationCategory.MISC), DS3LocationData("LC: Sniper Crossbow", "Sniper Crossbow", DS3LocationCategory.WEAPON), @@ -1778,7 +1781,7 @@ def get_name_to_id() -> dict: hidden = True), # Behind illusory wall DS3LocationData("LC: Titanite Chunk #4", "Titanite Chunk x2", DS3LocationCategory.UPGRADE), DS3LocationData("LC: Refined Gem", "Refined Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("LC: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), DS3LocationData("LC: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), DS3LocationData("LC: Lightning Urn #1", "Lightning Urn x3", DS3LocationCategory.MISC), DS3LocationData("LC: Titanite Chunk #5", "Titanite Chunk", DS3LocationCategory.UPGRADE), @@ -1790,19 +1793,19 @@ def get_name_to_id() -> dict: DS3LocationData("LC: Raw Gem", "Raw Gem", DS3LocationCategory.UPGRADE), DS3LocationData("LC: Black Firebomb", "Black Firebomb x3", DS3LocationCategory.MISC), DS3LocationData("LC: Pale Pine Resin", "Pale Pine Resin", DS3LocationCategory.MISC), - DS3LocationData("LC: Large Soul of a Weary Warrior #1", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("LC: Large Soul of a Weary Warrior #1", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("LC: Sunlight Medal", "Sunlight Medal", DS3LocationCategory.MISC), DS3LocationData("LC: Soul of a Crestfallen Knight #2", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC, hidden = True), # Hidden fall DS3LocationData("LC: Titanite Chunk #8", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("LC: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("LC: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("LC: Knight's Ring", "Knight's Ring", DS3LocationCategory.RING), DS3LocationData("LC: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("LC: Large Soul of a Weary Warrior #2", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("LC: Large Soul of a Weary Warrior #2", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("LC: Ember #3", "Ember", DS3LocationCategory.MISC), DS3LocationData("LC: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.MISC), - DS3LocationData("LC: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("LC: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("LC: Ember #4", "Ember", DS3LocationCategory.MISC), DS3LocationData("LC: Winged Knight Helm", "Winged Knight Helm", DS3LocationCategory.ARMOR, hidden = True), # Behind illusory wall @@ -1817,7 +1820,7 @@ def get_name_to_id() -> dict: hidden = True), # Hidden fall DS3LocationData("LC: Red Tearstone Ring", "Red Tearstone Ring", DS3LocationCategory.RING), DS3LocationData("LC: Twinkling Titanite #2", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Large Soul of a Nameless Soldier #3", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("LC: Large Soul of a Nameless Soldier #3", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("LC: Titanite Scale #3", "Titanite Scale x3", DS3LocationCategory.UPGRADE), DS3LocationData("LC: Titanite Scale #4", "Titanite Scale", DS3LocationCategory.UPGRADE), DS3LocationData("LC: Hood of Prayer", "Hood of Prayer", DS3LocationCategory.ARMOR), @@ -1893,7 +1896,7 @@ def get_name_to_id() -> dict: ], "Consumed King's Garden": [ - DS3LocationData("CKG: Soul of Consumed Oceiros", "Soul of Consumed Oceiros", DS3LocationCategory.BOSS, + DS3LocationData("CKG: Soul of Consumed Oceiros", "Soul of Consumed Oceiros", DS3LocationCategory.SOUL, prominent = True, boss = True), # Could classify this as "hidden" because it's midway down an elevator, but the elevator is # so slow and the midway point is so obvious that it's not actually hard to find. @@ -1909,7 +1912,7 @@ def get_name_to_id() -> dict: DS3LocationData("CKG: Human Pine Resin #1", "Human Pine Resin", DS3LocationCategory.MISC), DS3LocationData("CKG: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("CKG: Titanite Chunk #3", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("CKG: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("CKG: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("CKG: Dark Gem", "Dark Gem", DS3LocationCategory.UPGRADE), DS3LocationData("CKG: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE), DS3LocationData("CKG: Human Pine Resin #2", "Human Pine Resin x2", DS3LocationCategory.MISC), @@ -1932,7 +1935,7 @@ def get_name_to_id() -> dict: # At the bottom of the shortcut elevator right outside the Twin Princes fight. Requires sending the elevator up to the top from the middle, and then riding the lower elevator down. DS3LocationData("GA: Titanite Slab #1", "Titanite Slab", DS3LocationCategory.UPGRADE, hidden = True), # Elevator secret - DS3LocationData("GA: Soul of the Twin Princes", "Soul of the Twin Princes", DS3LocationCategory.BOSS, + DS3LocationData("GA: Soul of the Twin Princes", "Soul of the Twin Princes", DS3LocationCategory.SOUL, boss = True), DS3LocationData("GA: Cinders of a Lord - Lothric Prince", "Cinders of a Lord - Lothric Prince", DS3LocationCategory.KEY, offline = "09,0:50002040::", prominent = True, progression = True, boss = True), @@ -1944,11 +1947,11 @@ def get_name_to_id() -> dict: hostile_npc = True), # Daughter of Crystal Kriemhild drop DS3LocationData("GA: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("GA: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("GA: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), DS3LocationData("GA: Titanite Chunk #3", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("GA: Fleshbite Ring", "Fleshbite Ring", DS3LocationCategory.RING), - DS3LocationData("GA: Soul of a Crestfallen Knight #2", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), - DS3LocationData("GA: Soul of a Nameless Soldier", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("GA: Soul of a Crestfallen Knight #2", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("GA: Soul of a Nameless Soldier", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("GA: Crystal Chime", "Crystal Chime", DS3LocationCategory.WEAPON), DS3LocationData("GA: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE), DS3LocationData("GA: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), @@ -1962,19 +1965,19 @@ def get_name_to_id() -> dict: DS3LocationData("GA: Titanite Scale #5", "Titanite Scale", DS3LocationCategory.UPGRADE, hidden = True), # Hidden by a table DS3LocationData("GA: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Large Soul of a Crestfallen Knight #1", "Large Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("GA: Large Soul of a Crestfallen Knight #1", "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), DS3LocationData("GA: Titanite Chunk #5", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("GA: Titanite Scale #6", "Titanite Scale x3", DS3LocationCategory.UPGRADE, hidden = True), # Hidden fall DS3LocationData("GA: Titanite Chunk #6", "Titanite Chunk", DS3LocationCategory.UPGRADE, hidden = True), # Hidden fall - DS3LocationData("GA: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("GA: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("GA: Titanite Chunk #7", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("GA: Ember", "Ember", DS3LocationCategory.MISC), DS3LocationData("GA: Blessed Gem", "Blessed Gem", DS3LocationCategory.UPGRADE, hidden = True), # Hidden fall DS3LocationData("GA: Titanite Chunk #8", "Titanite Chunk x2", DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Large Soul of a Crestfallen Knight #2", "Large Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("GA: Large Soul of a Crestfallen Knight #2", "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), DS3LocationData("GA: Avelyn", "Avelyn", DS3LocationCategory.WEAPON, hidden = True), # Hidden fall DS3LocationData("GA: Titanite Chunk #9", "Titanite Chunk", DS3LocationCategory.UPGRADE, @@ -2071,7 +2074,7 @@ def get_name_to_id() -> dict: ], # The whole area is behind an illusory wall and thus marked hidden "Untended Graves": [ - DS3LocationData("UG: Soul of Champion Gundyr", "Soul of Champion Gundyr", DS3LocationCategory.BOSS, + DS3LocationData("UG: Soul of Champion Gundyr", "Soul of Champion Gundyr", DS3LocationCategory.SOUL, prominent = True, boss = True, hidden = True), DS3LocationData("UG: Priestess Ring", "Priestess Ring", DS3LocationCategory.RING, hidden = True), @@ -2141,7 +2144,7 @@ def get_name_to_id() -> dict: "Archdragon Peak": [ DS3LocationData("AP: Dragon Head Stone", "Dragon Head Stone", DS3LocationCategory.UNIQUE, prominent = True, boss = True), - DS3LocationData("AP: Soul of the Nameless King", "Soul of the Nameless King", DS3LocationCategory.BOSS, + DS3LocationData("AP: Soul of the Nameless King", "Soul of the Nameless King", DS3LocationCategory.SOUL, prominent = True, boss = True), DS3LocationData("AP: Dragon Tooth", "Dragon Tooth", DS3LocationCategory.WEAPON, hostile_npc = True), # Havel Knight drop @@ -2155,29 +2158,29 @@ def get_name_to_id() -> dict: DS3LocationData("AP: Stalk Dung Pie", "Stalk Dung Pie x6", DS3LocationCategory.MISC), DS3LocationData("AP: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("AP: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Soul of a Weary Warrior #1", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("AP: Soul of a Weary Warrior #1", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("AP: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("AP: Lightning Gem", "Lightning Gem", DS3LocationCategory.UPGRADE), DS3LocationData("AP: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC), - DS3LocationData("AP: Soul of a Nameless Soldier", "Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("AP: Soul of a Nameless Soldier", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("AP: Titanite Chunk #3", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("AP: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("AP: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), - DS3LocationData("AP: Large Soul of a Nameless Soldier", "Large Soul of a Nameless Soldier", DS3LocationCategory.MISC), + DS3LocationData("AP: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("AP: Large Soul of a Nameless Soldier", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), DS3LocationData("AP: Lightning Urn", "Lightning Urn x4", DS3LocationCategory.MISC), DS3LocationData("AP: Lightning Bolt", "Lightning Bolt x12", DS3LocationCategory.MISC), DS3LocationData("AP: Titanite Chunk #4", "Titanite Chunk x2", DS3LocationCategory.UPGRADE), DS3LocationData("AP: Dung Pie", "Dung Pie x3", DS3LocationCategory.MISC), DS3LocationData("AP: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Soul of a Weary Warrior #2", "Soul of a Weary Warrior", DS3LocationCategory.MISC), - DS3LocationData("AP: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("AP: Soul of a Weary Warrior #2", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("AP: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), DS3LocationData("AP: Titanite Chunk #5", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("AP: Ember #2", "Ember", DS3LocationCategory.MISC), DS3LocationData("AP: Thunder Stoneplate Ring", "Thunder Stoneplate Ring", DS3LocationCategory.RING), DS3LocationData("AP: Titanite Scale #3", "Titanite Scale", DS3LocationCategory.UPGRADE), DS3LocationData("AP: Ember #3", "Ember", DS3LocationCategory.MISC), DS3LocationData("AP: Ancient Dragon Greatshield", "Ancient Dragon Greatshield", DS3LocationCategory.SHIELD), - DS3LocationData("AP: Large Soul of a Crestfallen Knight", "Large Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("AP: Large Soul of a Crestfallen Knight", "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), DS3LocationData("AP: Dragon Chaser's Ashes", "Dragon Chaser's Ashes", DS3LocationCategory.KEY, progression = True), DS3LocationData("AP: Ember #4", "Ember", DS3LocationCategory.MISC), @@ -2293,9 +2296,9 @@ def get_name_to_id() -> dict: npc = True), # Friede conversation DS3LocationData("PW1: Rime-blue Moss Clump #1", "Rime-blue Moss Clump x2", DS3LocationCategory.MISC), DS3LocationData("PW1: Poison Gem", "Poison Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #1", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #1", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("PW1: Follower Javelin", "Follower Javelin", DS3LocationCategory.WEAPON), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #2", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #2", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("PW1: Homeward Bone #1", "Homeward Bone x6", DS3LocationCategory.MISC), DS3LocationData("PW1: Blessed Gem", "Blessed Gem", DS3LocationCategory.UPGRADE, hidden = True), # Hidden behind a tower @@ -2305,24 +2308,24 @@ def get_name_to_id() -> dict: DS3LocationData("PW1: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), DS3LocationData("PW1: Millwood Greatarrow", "Millwood Greatarrow x5", DS3LocationCategory.MISC), DS3LocationData("PW1: Millwood Greatbow", "Millwood Greatbow", DS3LocationCategory.WEAPON), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #3", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #3", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("PW1: Rusted Coin #1", "Rusted Coin", DS3LocationCategory.MISC), DS3LocationData("PW1: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #4", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #4", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("PW1: Crow Quills", "Crow Quills", DS3LocationCategory.WEAPON, hidden = True), # Hidden fall DS3LocationData("PW1: Simple Gem", "Simple Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #5", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #5", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("PW1: Slave Knight Hood", "Slave Knight Hood", DS3LocationCategory.ARMOR), DS3LocationData("PW1: Slave Knight Armor", "Slave Knight Armor", DS3LocationCategory.ARMOR), DS3LocationData("PW1: Slave Knight Gauntlets", "Slave Knight Gauntlets", DS3LocationCategory.ARMOR), DS3LocationData("PW1: Slave Knight Leggings", "Slave Knight Leggings", DS3LocationCategory.ARMOR), DS3LocationData("PW1: Ember #1", "Ember", DS3LocationCategory.MISC), DS3LocationData("PW1: Dark Gem", "Dark Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #6", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #7", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #6", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #7", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("PW1: Rusted Gold Coin", "Rusted Gold Coin x3", DS3LocationCategory.MISC), - DS3LocationData("PW1: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("PW1: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), DS3LocationData("PW1: Way of White Corona", "Way of White Corona", DS3LocationCategory.SPELL), DS3LocationData("PW1: Rusted Coin #2", "Rusted Coin x2", DS3LocationCategory.MISC), DS3LocationData("PW1: Young White Branch", "Young White Branch", DS3LocationCategory.MISC), @@ -2336,20 +2339,20 @@ def get_name_to_id() -> dict: DS3LocationData("PW1: Snap Freeze", "Snap Freeze", DS3LocationCategory.SPELL, hidden = True), # Guaranteed drop from normal-looking Tree Woman DS3LocationData("PW1: Rime-blue Moss Clump #3", "Rime-blue Moss Clump", DS3LocationCategory.MISC), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #8", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #8", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("PW1: Ember #3", "Ember", DS3LocationCategory.MISC), DS3LocationData("PW1: Frozen Weapon", "Frozen Weapon", DS3LocationCategory.SPELL), DS3LocationData("PW1: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE, offline = '11,0:50004700::', hidden = True), # Must kill normal-looking Tree Woman DS3LocationData("PW1: Homeward Bone #2", "Homeward Bone x2", DS3LocationCategory.MISC), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #9", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), - DS3LocationData("PW1: Large Soul of a Weary Warrior #1", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #10", "Large Soul of an Unknown Traveler", DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #9", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("PW1: Large Soul of a Weary Warrior #1", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("PW1: Large Soul of an Unknown Traveler #10", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("PW1: Heavy Gem", "Heavy Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("PW1: Large Soul of a Weary Warrior #2", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Soul of a Weary Warrior #2", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("PW1: Millwood Battle Axe", "Millwood Battle Axe", DS3LocationCategory.WEAPON), DS3LocationData("PW1: Ethereal Oak Shield", "Ethereal Oak Shield", DS3LocationCategory.SHIELD), - DS3LocationData("PW1: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("PW1: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("PW1: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), DS3LocationData("PW1: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE, @@ -2364,7 +2367,7 @@ def get_name_to_id() -> dict: offline = '11,0:50002310::', boss = True), ], "Painted World of Ariandel (After Contraption)": [ - DS3LocationData("PW2: Soul of Sister Friede", "Soul of Sister Friede", DS3LocationCategory.BOSS, + DS3LocationData("PW2: Soul of Sister Friede", "Soul of Sister Friede", DS3LocationCategory.SOUL, prominent = True, boss = True), DS3LocationData("PW2: Titanite Slab (Friede)", "Titanite Slab", DS3LocationCategory.UPGRADE, offline = '11,0:50004700::', boss = True), # One-time drop after Friede Phase 2 @@ -2378,9 +2381,9 @@ def get_name_to_id() -> dict: DS3LocationData("PW2: Quakestone Hammer", "Quakestone Hammer", DS3LocationCategory.WEAPON), DS3LocationData("PW2: Ember", "Ember", DS3LocationCategory.MISC), DS3LocationData("PW2: Large Titanite Shard #2", "Large Titanite Shard x2", DS3LocationCategory.UPGRADE), - DS3LocationData("PW2: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), - DS3LocationData("PW2: Soul of a Crestfallen Knight #2", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), - DS3LocationData("PW2: Large Soul of a Crestfallen Knight", "Large Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("PW2: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("PW2: Soul of a Crestfallen Knight #2", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("PW2: Large Soul of a Crestfallen Knight", "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), DS3LocationData("PW2: Earth Seeker", "Earth Seeker", DS3LocationCategory.WEAPON), DS3LocationData("PW2: Follower Torch", "Follower Torch", DS3LocationCategory.SHIELD), DS3LocationData("PW2: Dung Pie", "Dung Pie x2", DS3LocationCategory.MISC), @@ -2412,21 +2415,21 @@ def get_name_to_id() -> dict: boss = True, shop = True), ], "Dreg Heap": [ - DS3LocationData("DH: Soul of the Demon Prince", "Soul of the Demon Prince", DS3LocationCategory.BOSS, + DS3LocationData("DH: Soul of the Demon Prince", "Soul of the Demon Prince", DS3LocationCategory.SOUL, prominent = True, boss = True), DS3LocationData("DH: Siegbräu", "Siegbräu", DS3LocationCategory.MISC, missable = True, npc = True), # Lapp (quest or kill) DS3LocationData("DH: Flame Fan", "Flame Fan", DS3LocationCategory.SPELL, hostile_npc = True), # Desert Pyromancer Zoey drop DS3LocationData("DH: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("DH: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("DH: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("DH: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("DH: Aquamarine Dagger", "Aquamarine Dagger", DS3LocationCategory.WEAPON), DS3LocationData("DH: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE), DS3LocationData("DH: Murky Hand Scythe", "Murky Hand Scythe", DS3LocationCategory.WEAPON), DS3LocationData("DH: Divine Blessing #1", "Divine Blessing", DS3LocationCategory.MISC), DS3LocationData("DH: Ring of Steel Protection+3", "Ring of Steel Protection+3", DS3LocationCategory.RING), - DS3LocationData("DH: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("DH: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), DS3LocationData("DH: Rusted Coin", "Rusted Coin x2", DS3LocationCategory.MISC), DS3LocationData("DH: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("DH: Murky Longstaff", "Murky Longstaff", DS3LocationCategory.WEAPON), @@ -2440,7 +2443,7 @@ def get_name_to_id() -> dict: DS3LocationData("DH: Homeward Bone #1", "Homeward Bone x3", DS3LocationCategory.MISC), DS3LocationData("DH: Lightning Urn", "Lightning Urn x4", DS3LocationCategory.MISC), DS3LocationData("DH: Projected Heal", "Projected Heal", DS3LocationCategory.SPELL), - DS3LocationData("DH: Large Soul of a Weary Warrior #1", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("DH: Large Soul of a Weary Warrior #1", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("DH: Lothric War Banner", "Lothric War Banner", DS3LocationCategory.WEAPON), DS3LocationData("DH: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE), DS3LocationData("DH: Black Firebomb", "Black Firebomb x4", DS3LocationCategory.MISC), @@ -2456,12 +2459,12 @@ def get_name_to_id() -> dict: DS3LocationData("DH: Purple Moss Clump", "Purple Moss Clump x4", DS3LocationCategory.MISC), DS3LocationData("DH: Ring of Favor+3", "Ring of Favor+3", DS3LocationCategory.RING), DS3LocationData("DH: Titanite Chunk #6", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Large Soul of a Weary Warrior #2", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("DH: Large Soul of a Weary Warrior #2", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("DH: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE), DS3LocationData("DH: Titanite Chunk #7", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("DH: Loincloth", "Loincloth", DS3LocationCategory.ARMOR), DS3LocationData("DH: Titanite Chunk #8", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Large Soul of a Weary Warrior #3", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("DH: Large Soul of a Weary Warrior #3", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("DH: Harald Curved Greatsword", "Harald Curved Greatsword", DS3LocationCategory.WEAPON), DS3LocationData("DH: Homeward Bone #2", "Homeward Bone", DS3LocationCategory.MISC), DS3LocationData("DH: Prism Stone", "Prism Stone x6", DS3LocationCategory.MISC), @@ -2499,7 +2502,7 @@ def get_name_to_id() -> dict: "Ringed City": [ DS3LocationData("RC: Titanite Slab #1", "Titanite Slab", DS3LocationCategory.UPGRADE, prominent = True, boss = True), # Halflight drop, only once - DS3LocationData("RC: Soul of Darkeater Midir", "Soul of Darkeater Midir", DS3LocationCategory.BOSS, + DS3LocationData("RC: Soul of Darkeater Midir", "Soul of Darkeater Midir", DS3LocationCategory.SOUL, prominent = True, boss = True), DS3LocationData("RC: Sacred Chime of Filianore", "Sacred Chime of Filianore", DS3LocationCategory.WEAPON, npc = True), # Shira (kill or quest) @@ -2523,8 +2526,8 @@ def get_name_to_id() -> dict: DS3LocationData("RC: Ember #1", "Ember", DS3LocationCategory.MISC), DS3LocationData("RC: Budding Green Blossom #2", "Budding Green Blossom x2", DS3LocationCategory.MISC), DS3LocationData("RC: Hidden Blessing #1", "Hidden Blessing", DS3LocationCategory.MISC), - DS3LocationData("RC: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), - DS3LocationData("RC: Large Soul of a Weary Warrior #1", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("RC: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("RC: Large Soul of a Weary Warrior #1", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("RC: Ember #2", "Ember", DS3LocationCategory.MISC), DS3LocationData("RC: Purging Stone", "Purging Stone x2", DS3LocationCategory.MISC), DS3LocationData("RC: Hollow Gem", "Hollow Gem", DS3LocationCategory.UPGRADE), @@ -2541,7 +2544,7 @@ def get_name_to_id() -> dict: DS3LocationData("RC: Shira's Trousers", "Shira's Trousers", DS3LocationCategory.ARMOR, hidden = True), # Have to return to a cleared area DS3LocationData("RC: Mossfruit #1", "Mossfruit x2", DS3LocationCategory.MISC), - DS3LocationData("RC: Large Soul of a Crestfallen Knight #1", "Large Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("RC: Large Soul of a Crestfallen Knight #1", "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), DS3LocationData("RC: Ringed Knight Spear", "Ringed Knight Spear", DS3LocationCategory.WEAPON), DS3LocationData("RC: Black Witch Hat", "Black Witch Hat", DS3LocationCategory.ARMOR, hostile_npc = True), # Alva @@ -2567,26 +2570,26 @@ def get_name_to_id() -> dict: hidden = True), # Hidden fall DS3LocationData("RC: Titanite Chunk #5", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("RC: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Soul of a Weary Warrior #1", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("RC: Soul of a Weary Warrior #1", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("RC: Preacher's Right Arm", "Preacher's Right Arm", DS3LocationCategory.WEAPON), DS3LocationData("RC: Rubbish #1", "Rubbish", DS3LocationCategory.MISC), DS3LocationData("RC: Titanite Chunk #6", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("RC: Black Witch Veil", "Black Witch Veil", DS3LocationCategory.ARMOR), DS3LocationData("RC: Twinkling Titanite #3", "Twinkling Titanite", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Soul of a Crestfallen Knight #2", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("RC: Soul of a Crestfallen Knight #2", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), DS3LocationData("RC: White Preacher Head", "White Preacher Head", DS3LocationCategory.ARMOR), DS3LocationData("RC: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE), DS3LocationData("RC: Titanite Scale #3", "Titanite Scale", DS3LocationCategory.UPGRADE), DS3LocationData("RC: Dragonhead Greatshield", "Dragonhead Greatshield", DS3LocationCategory.SHIELD), DS3LocationData("RC: Titanite Scale #4", "Titanite Scale x2", DS3LocationCategory.UPGRADE), DS3LocationData("RC: Rubbish #2", "Rubbish", DS3LocationCategory.MISC), - DS3LocationData("RC: Large Soul of a Weary Warrior #2", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("RC: Large Soul of a Weary Warrior #2", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("RC: Titanite Scale #5", "Titanite Scale x2", DS3LocationCategory.UPGRADE), DS3LocationData("RC: Titanite Scale #6", "Titanite Scale", DS3LocationCategory.UPGRADE), DS3LocationData("RC: Lightning Gem", "Lightning Gem", DS3LocationCategory.UPGRADE), DS3LocationData("RC: Blessed Gem", "Blessed Gem", DS3LocationCategory.UPGRADE), DS3LocationData("RC: Simple Gem", "Simple Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Large Soul of a Weary Warrior #3", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("RC: Large Soul of a Weary Warrior #3", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("RC: Lightning Arrow", "Lightning Arrow", DS3LocationCategory.SPELL), DS3LocationData("RC: Chloranthy Ring+3", "Chloranthy Ring+3", DS3LocationCategory.RING, hidden = True), # Hidden fall @@ -2595,14 +2598,14 @@ def get_name_to_id() -> dict: offline = '13,0:55100700::'), DS3LocationData("RC: Antiquated Plain Garb", "Antiquated Plain Garb", DS3LocationCategory.ARMOR), DS3LocationData("RC: Violet Wrappings", "Violet Wrappings", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Soul of a Weary Warrior #2", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("RC: Soul of a Weary Warrior #2", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("RC: Twinkling Titanite #4", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE), DS3LocationData("RC: Budding Green Blossom #3", "Budding Green Blossom x3", DS3LocationCategory.MISC), DS3LocationData("RC: Titanite Chunk #7", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Large Soul of a Weary Warrior #4", "Large Soul of a Weary Warrior", DS3LocationCategory.MISC), - DS3LocationData("RC: Soul of a Weary Warrior #3", "Soul of a Weary Warrior", DS3LocationCategory.MISC), + DS3LocationData("RC: Large Soul of a Weary Warrior #4", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("RC: Soul of a Weary Warrior #3", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), DS3LocationData("RC: Titanite Scale #7", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Soul of a Crestfallen Knight #3", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("RC: Soul of a Crestfallen Knight #3", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), DS3LocationData("RC: White Birch Bow", "White Birch Bow", DS3LocationCategory.WEAPON), DS3LocationData("RC: Titanite Chunk #8", "Titanite Chunk", DS3LocationCategory.UPGRADE), DS3LocationData("RC: Young White Branch #1", "Young White Branch", DS3LocationCategory.MISC), @@ -2642,7 +2645,7 @@ def get_name_to_id() -> dict: lizard = True), DS3LocationData("RC: Twinkling Titanite #7", "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("RC: Soul of Slave Knight Gael", "Soul of Slave Knight Gael", DS3LocationCategory.BOSS, + DS3LocationData("RC: Soul of Slave Knight Gael", "Soul of Slave Knight Gael", DS3LocationCategory.SOUL, prominent = True, boss = True), DS3LocationData("RC: Blood of the Dark Soul", "Blood of the Dark Soul", DS3LocationCategory.KEY), DS3LocationData("RC: Titanite Slab #3", "Titanite Slab", DS3LocationCategory.UPGRADE, @@ -2755,6 +2758,7 @@ def get_name_to_id() -> dict: "Small Crystal Lizards": set(), "Keys": set(), "Upgrade": set(), + "Soul Items": set(), "Miscellaneous": set(), "Hidden": set() } diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 04d9521381b1..ebdd2a4ea648 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -37,11 +37,6 @@ class RandomizeKeyLocations(DefaultOnToggle): display_name = "Randomize Key Locations" -class RandomizeBossSoulLocations(DefaultOnToggle): - """Randomizes boss souls (+22 Locations)""" - display_name = "Randomize Boss Soul Locations" - - class RandomizeNPCLocations(DefaultOnToggle): """Randomizes friendly NPC drops and rewards (+34 checks) @@ -56,11 +51,11 @@ class RandomizeNPCLocations(DefaultOnToggle): class RandomizeUniqueLocations(DefaultOnToggle): """Randomizes unique items (ashes, tomes, scrolls, etc.) (+36 checks)""" - display_name = "Randomize Miscellaneous Locations" + display_name = "Randomize Unique Locations" class RandomizeMiscLocations(DefaultOnToggle): - """Randomizes miscellaneous items (arrows, firebombs, soul items, etc.) (+388 locations) + """Randomizes miscellaneous items (arrows, firebombs, etc.) (222 checks, 288 with NG+) By default, these locations will never include progression items, so they aren't mandatory checks. You can override this by customizing the @@ -76,11 +71,31 @@ class RandomizeHealthLocations(DefaultOnToggle): display_name = "Randomize Health Upgrade Locations" +class SoulLocationsOption(Choice): + """Where to randomize soul items (140 checks, 103 with NG+) + + * Not Randomized: All soul item locations contain the same items as in the base game. + * Anywhere: Soul items are distributed totally randomly throughout the multiworld. + * Similar to Base Game: Soul items appear in approximately the same regions they do in the + base game. + + By default, soul item locations will never include progression items, so they aren't mandatory + checks. You can override this by customizing the "exclude_locations" field in your YAML config. + (For example, "exclude_locations: []" will allow progression items in every unmissable + location.) + """ + display_name = "Soul Locations" + option_not_randomized = 1 + option_anywhere = 2 + option_similar_to_base_game = 3 + default = 3 + + class UpgradeLocationsOption(Choice): """Where to randomize titanite and gems (220 checks) * Not Randomized: All upgrade item locations contain the same items as in the base game. - * Anywhere: Upgrade items are distributed totally randomly throughout the game. + * Anywhere: Upgrade items are distributed totally randomly throughout the multiworld. * Similar to Base Game: Upgrade items appear in approximately the same regions they do in the base game. @@ -321,7 +336,7 @@ class ImpatientMimicsOption(Toggle): class DS3ExcludeLocations(ExcludeLocations): """Prevent these locations from having an important item""" - default = {"Hidden", "Small Crystal Lizards", "Miscellaneous"} + default = {"Hidden", "Small Crystal Lizards", "Upgrade", "Small Souls", "Miscellaneous"} @dataclass @@ -332,11 +347,11 @@ class DarkSouls3Options(PerGameCommonOptions): enable_ring_locations: RandomizeRingLocations enable_spell_locations: RandomizeSpellLocations enable_key_locations: RandomizeKeyLocations - enable_boss_locations: RandomizeBossSoulLocations enable_npc_locations: RandomizeNPCLocations enable_unique_locations: RandomizeUniqueLocations enable_misc_locations: RandomizeMiscLocations enable_health_upgrade_locations: RandomizeHealthLocations + soul_locations: SoulLocationsOption upgrade_locations: UpgradeLocationsOption random_starting_loadout: RandomizeStartingLoadout require_one_handed_starting_weapons: RequireOneHandedStartingWeapons diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 514afe47006a..d3c19cae2cf9 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -13,7 +13,7 @@ from .Fill import Fill from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, UsefulIf, filler_item_names, item_dictionary from .Locations import DarkSouls3Location, DS3LocationCategory, DS3LocationData, location_tables, location_dictionary, location_name_groups -from .Options import DarkSouls3Options, RandomizeWeaponLevelOption, PoolTypeOption, UpgradeLocationsOption +from .Options import DarkSouls3Options, RandomizeWeaponLevelOption, PoolTypeOption, SoulLocationsOption, UpgradeLocationsOption class DarkSouls3Web(WebWorld): @@ -95,12 +95,8 @@ def generate_early(self): self.enabled_location_categories.add(DS3LocationCategory.RING) if self.multiworld.enable_spell_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.SPELL) - if self.multiworld.upgrade_locations[self.player] != UpgradeLocationsOption.option_not_randomized: - self.enabled_location_categories.add(DS3LocationCategory.UPGRADE) if self.multiworld.enable_key_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.KEY) - if self.multiworld.enable_boss_locations[self.player] == Toggle.option_true: - self.enabled_location_categories.add(DS3LocationCategory.BOSS) if self.multiworld.enable_unique_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.UNIQUE) # Make this available early just because it's fun to be able to check boss souls early. @@ -109,6 +105,10 @@ def generate_early(self): self.enabled_location_categories.add(DS3LocationCategory.MISC) if self.multiworld.enable_health_upgrade_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.HEALTH) + if self.multiworld.upgrade_locations[self.player] != UpgradeLocationsOption.option_not_randomized: + self.enabled_location_categories.add(DS3LocationCategory.UPGRADE) + if self.multiworld.soul_locations[self.player] != SoulLocationsOption.option_not_randomized: + self.enabled_location_categories.add(DS3LocationCategory.SOUL) # The offline randomizer's clever code for converting an item into a gesture only works for # items in the local world. @@ -144,6 +144,13 @@ def generate_early(self): if item.base_name in {"Titanite Shard", "Large Titanite Shard", "Titanite Chunk", "Titanite Slab", "Titanite Scale", "Twinkling Titanite"}: self.multiworld.non_local_items[self.player].value.add(item.name) + if self.multiworld.soul_locations[self.player] == SoulLocationsOption.option_similar_to_base_game: + for item in item_dictionary.values(): + if ( + item.souls and item.souls > 50 and + (item.category != DS3ItemCategory.BOSS or item.souls >= 10000) + ): + self.multiworld.non_local_items[self.player].value.add(item.name) def create_regions(self): # Create Vanilla Regions @@ -535,7 +542,7 @@ def has_any_scroll(state): add_item_rule(self.multiworld.get_location(location.name, self.player), lambda item: ( item.player != self.player or - (item.count == 1 and not item.soul) + (item.count == 1 and not item.souls) )) # Make sure the Storm Ruler is available BEFORE Yhorm the Giant @@ -672,6 +679,54 @@ def pre_fill(self) -> None: fill.fill("Simple Gem", through="Profaned Capital", count=1) fill.fill("Chaos Gem", through="Profaned Capital", count=1) + if self.multiworld.soul_locations[self.player] == SoulLocationsOption.option_similar_to_base_game: + # Fading souls are worthless and all over the place anyway, so we don't smooth them. + fill.fill("Soul of a Deserted Corpse", through="High Wall of Lothric") + fill.fill("Large Soul of a Deserted Corpse", start="High Wall of Lothric") + fill.fill("Soul of an Unknown Traveler", through="Road of Sacrifices") + + # Only put items worth 800 to 5k souls in the random pool. Any smaller and it sucks, any + # larger and if we're going to disrupt the XP curve that much it's better to do it with + # a splashy boss soul. + fill.fill("Large Soul of an Unknown Traveler", start="Undead Settlement", through="Road of Sacrifices", count=1) + fill.fill("Large Soul of an Unknown Traveler", start="Farron Keep", + through="Painted World of Ariandel (Before Contraption)", count=-3) + fill.fill("Soul of a Nameless Soldier", start="Undead Settlement", through="Road of Sacrifices", count=1) + fill.fill("Soul of a Nameless Soldier", start="Farron Keep", + through="Painted World of Ariandel (Before Contraption)", count=-3) + fill.fill("Soul of a Nameless Soldier", start="Lothric Castle", through="Kiln of the First Flame", count=1) + fill.fill("Large Soul of a Nameless Soldier", start="Farron Keep", through="Catacombs of Carthus", count=4) + fill.fill("Large Soul of a Nameless Soldier", start="Farron Keep", through="Catacombs of Carthus", count=-5) + fill.fill("Large Soul of a Nameless Soldier", start="Lothric Castle", through="Kiln of the First Flame", count=3) + fill.fill("Soul of a Weary Warrior", start="Irithyll of the Boreal Valley", count=-2) + + fill.fill("Large Soul of a Weary Warrior", start="Irithyll Dungeon", through="Profaned Capital", + count=(5 if self.multiworld.enable_dlc[self.player] else 3)) + fill.fill("Large Soul of a Weary Warrior", start="Painted World of Ariandel (After Contraption)", + through="Kiln of the First Flame", count=3) + fill.fill("Large Soul of a Weary Warrior", start="Dreg Heap") + fill.fill("Soul of a Crestfallen Knight", start="Smouldering Lake", through="Profaned Capital", + count=(4 if self.multiworld.enable_dlc[self.player] else 3)) + fill.fill("Soul of a Crestfallen Knight", start="Painted World of Ariandel (After Contraption)") + fill.fill("Large Soul of a Crestfallen Knight", start="Painted World of Ariandel (After Contraption)", + through="Lothric Castle", count=1) + fill.fill("Large Soul of a Crestfallen Knight", start="Grand Archives") + + # Boss souls are all in a similar general value range, so we shuffle them and gently + # stagger them so that a player doesn't get too many or too few. We leave one left over + # to go into the multiworld and show up whenever. + boss_souls = { + item.name for item in item_dictionary.values() + # Don't smooth boss souls worth less than 10k, it's more fun to let them go wherever. + if item.category == DS3ItemCategory.BOSS and item.souls and item.souls >= 10000 + } + fill.fill(boss_souls, start="Farron Keep", through="Catacombs of Carthus", count=4) + fill.fill(boss_souls, start="Smouldering Lake", through="Profaned Capital", count=4) + fill.fill(boss_souls, start="Painted World of Ariandel (After Contraption)", through="Untended Graves", + count=(5 if self.multiworld.enable_dlc[self.player] else 4)) + fill.fill(boss_souls, start="Grand Archives", through="Ringed City", + count=(5 if self.multiworld.enable_dlc[self.player] else 2)) + fill.save() @@ -729,15 +784,6 @@ def fill_slot_data(self) -> Dict[str, object]: slot_data = { "options": { - "enable_weapon_locations": self.multiworld.enable_weapon_locations[self.player].value, - "enable_shield_locations": self.multiworld.enable_shield_locations[self.player].value, - "enable_armor_locations": self.multiworld.enable_armor_locations[self.player].value, - "enable_ring_locations": self.multiworld.enable_ring_locations[self.player].value, - "enable_spell_locations": self.multiworld.enable_spell_locations[self.player].value, - "enable_key_locations": self.multiworld.enable_key_locations[self.player].value, - "enable_boss_locations": self.multiworld.enable_boss_locations[self.player].value, - "enable_npc_locations": self.multiworld.enable_npc_locations[self.player].value, - "enable_misc_locations": self.multiworld.enable_misc_locations[self.player].value, "random_starting_loadout": self.multiworld.random_starting_loadout[self.player].value, "require_one_handed_starting_weapons": self.multiworld.require_one_handed_starting_weapons[self.player].value, "auto_equip": self.multiworld.auto_equip[self.player].value, From edb90fafd1a369ecbecfeb4b3179ddd6fdd7fb04 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 2 Nov 2023 03:29:49 -0700 Subject: [PATCH 047/238] Fill extra smoothing items into conditional locations as well as other worlds --- worlds/dark_souls_3/Fill.py | 2 +- worlds/dark_souls_3/Items.py | 3 ++ worlds/dark_souls_3/Locations.py | 76 ++++++++++++++++++-------------- worlds/dark_souls_3/__init__.py | 46 ++++++++++++------- 4 files changed, 76 insertions(+), 51 deletions(-) diff --git a/worlds/dark_souls_3/Fill.py b/worlds/dark_souls_3/Fill.py index beb659190ca8..af842957c3d2 100644 --- a/worlds/dark_souls_3/Fill.py +++ b/worlds/dark_souls_3/Fill.py @@ -129,7 +129,7 @@ def fill( self.world.is_location_available(location) and not location.missable and not location.conditional - and not (location.shop and item.souls) + and not (location.shop and (item.count > 1 or item.souls)) ) ) # Don't put important items in excluded locations. diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 595f96b7c6c8..4428e4a54809 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -117,6 +117,7 @@ class DarkSouls3Item(Item): game: str = "Dark Souls III" count: int = 1 souls: Optional[int] = None + base_name: str def __init__( self, @@ -125,6 +126,7 @@ def __init__( code: Optional[int], player: int): super().__init__(name, classification, code, player) + self.base_name = name @staticmethod def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSouls3Item": @@ -135,6 +137,7 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou player) item.count = data.count item.souls = data.souls + item.base_name = data.base_name return item _vanilla_items = flatten([ diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 4680c4017af1..b2c4760afc5a 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -168,6 +168,7 @@ class DarkSouls3Location(Location): category: DS3LocationCategory default_item_name: str offline: Optional[str] = None + conditional: bool = False def __init__( self, @@ -196,6 +197,7 @@ def from_data( parent ) location.offline = data.offline + location.conditional = data.conditional if data.missable: location.progress_type = LocationProgressType.EXCLUDED return location @@ -693,23 +695,23 @@ def get_name_to_id() -> dict: npc = True, shop = True), # These are missable if you kill Cornyx before giving him the right tomes. DS3LocationData("US: Poison Mist", "Poison Mist", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("US: Fire Orb", "Fire Orb", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("US: Profuse Sweat", "Profuse Sweat", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("US: Bursting Fireball", "Bursting Fireball", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("US: Acid Surge", "Acid Surge", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("US: Carthus Flame Arc", "Carthus Flame Arc", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("US: Carthus Beacon", "Carthus Beacon", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("US: Great Chaos Fire Orb", "Great Chaos Fire Orb", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("US: Chaos Storm", "Chaos Storm", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), # Irina of Carim # These aren't in their own location because you don't actually need the Grave Key to access @@ -725,28 +727,28 @@ def get_name_to_id() -> dict: DS3LocationData("US: Homeward", "Homeward", DS3LocationCategory.SPELL, npc = True, shop = True), DS3LocationData("US: Med Heal", "Med Heal", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("US: Tears of Denial", "Tears of Denial", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("US: Force", "Force", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("US: Bountiful Light", "Bountiful Light", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("US: Magic Barrier", "Magic Barrier", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("US: Blessed Weapon", "Blessed Weapon", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), # You can also get these from Karla DS3LocationData("US: Gnaw", "Gnaw", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("US: Deep Protection", "Deep Protection", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("US: Vow of Silence", "Vow of Silence", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("US: Dark Blade", "Dark Blade", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("US: Dead Again", "Dead Again", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), ], "Road of Sacrifices": [ DS3LocationData("RS: Soul of a Crystal Sage", "Soul of a Crystal Sage", DS3LocationCategory.SOUL, @@ -853,31 +855,31 @@ def get_name_to_id() -> dict: DS3LocationData("RS: Farron Flashsword", "Farron Flashsword", DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), DS3LocationData("RS: Pestilent Mist", "Pestilent Mist", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("RS: Great Farron Dart", "Great Farron Dart", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("RS: Farron Hail", "Farron Hail", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("RS: Homing Soulmass", "Homing Soulmass", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("RS: Soul Spear", "Soul Spear", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("RS: Homing Crystal Soulmass", "Homing Crystal Soulmass", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("RS: Crystal Soul Spear", "Crystal Soul Spear", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("RS: Crystal Magic Weapon", "Crystal Magic Weapon", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("RS: Cast Light", "Cast Light", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("RS: Twisted Wall of Light", "Twisted Wall of Light", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("RS: Hidden Weapon", "Hidden Weapon", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("RS: Hidden Body", "Hidden Body", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("RS: Repair", "Repair", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + conditional = True, missable = True, npc = True, shop = True), DS3LocationData("RS: Clandestine Coat", "Clandestine Coat", DS3LocationCategory.ARMOR, missable = True, npc = True, shop = True), # Shrine Handmaid with Orbeck's Ashes + reload DS3LocationData("RS: Young Dragon Ring", "Young Dragon Ring", DS3LocationCategory.RING, @@ -2745,6 +2747,14 @@ def get_name_to_id() -> dict: for location in location_tables[region]: location.dlc = True +for region in [ + "Firelink Shrine Bell Tower", + "Greirat's Shop", + "Karla's Shop" +]: + for location in location_tables[region]: + location.conditional = True + location_name_groups: Dict[str, Set[str]] = { # We could insert these locations automatically with setdefault(), but we set them up explicitly diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index d3c19cae2cf9..3f4c496c0e53 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -135,23 +135,6 @@ def generate_early(self): else: self.yhorm_location = default_yhorm_location - # Mark all items with similar distribution as non-local, so that pre_fill can leave a few to - # be given as multiworld items. - if self.multiworld.upgrade_locations[self.player] == UpgradeLocationsOption.option_similar_to_base_game: - for item in item_dictionary.values(): - # Carefully control the actual weapon upgrade material locations, but be looser with - # gems since they're inherently controlled by coals anyway (which are all local). - if item.base_name in {"Titanite Shard", "Large Titanite Shard", "Titanite Chunk", - "Titanite Slab", "Titanite Scale", "Twinkling Titanite"}: - self.multiworld.non_local_items[self.player].value.add(item.name) - if self.multiworld.soul_locations[self.player] == SoulLocationsOption.option_similar_to_base_game: - for item in item_dictionary.values(): - if ( - item.souls and item.souls > 50 and - (item.category != DS3ItemCategory.BOSS or item.souls >= 10000) - ): - self.multiworld.non_local_items[self.player].value.add(item.name) - def create_regions(self): # Create Vanilla Regions regions: Dict[str, Region] = {} @@ -557,6 +540,35 @@ def has_any_scroll(state): state.has("Cinders of a Lord - Aldrich", self.player) and \ state.has("Cinders of a Lord - Lothric Prince", self.player) + # If smoothing is enabled and there are multiple worlds, set a special rule to forbid the + # remaining items of certain types from in-world locations _except_ those that are small + # unlocks from progression items. This allows exciting items to be unlocked while also + # limiting unlocks to the same pool of items we've already chosen to show up unexpectedly. + if len(self.multiworld.worlds) > 1: + non_local_or_conditional_items = set() + if self.multiworld.upgrade_locations[self.player] == UpgradeLocationsOption.option_similar_to_base_game: + # Carefully control the actual weapon upgrade material locations, but be looser with + # gems since they're inherently controlled by coals anyway (which are all local). + non_local_or_conditional_items.update({ + "Titanite Shard", "Large Titanite Shard", "Titanite Chunk", "Titanite Slab", + "Titanite Scale", "Twinkling Titanite" + }) + if self.multiworld.soul_locations[self.player] == SoulLocationsOption.option_similar_to_base_game: + non_local_or_conditional_items.update( + item.name for item in item_dictionary.values() + if ( + item.souls and item.souls > 50 and + (item.category != DS3ItemCategory.BOSS or item.souls >= 10000) + ) + ) + if len(non_local_or_conditional_items) > 0: + for location in self.multiworld.get_locations(self.player): + if not location.conditional: + add_item_rule(location, lambda item: ( + item.player != self.player or + item.base_name not in non_local_or_conditional_items + )) + def _set_location_rule(self, location: str, rule: Union[CollectionRule, str]) -> None: """Sets a rule for the given location if it that location is randomized. From 52f7a4b3a6c308821c0eec76df68139db12471c8 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 2 Nov 2023 03:46:12 -0700 Subject: [PATCH 048/238] Add health item smoothing --- worlds/dark_souls_3/Options.py | 23 +++++++++++++++++++---- worlds/dark_souls_3/__init__.py | 25 ++++++++++++++++++++----- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index ebdd2a4ea648..bb555f69bc93 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -66,9 +66,24 @@ class RandomizeMiscLocations(DefaultOnToggle): display_name = "Randomize Miscellaneous Locations" -class RandomizeHealthLocations(DefaultOnToggle): - """Randomizes health upgrade items. (+21 checks)""" - display_name = "Randomize Health Upgrade Locations" +class HealthLocationsOption(Choice): + """Where to andomize health upgrade items (21 checks) + + * Not Randomized: All health item locations contain the same items as in the base game. + * Anywhere: Health items are distributed totally randomly throughout the multiworld. + * Similar to Base Game: Health items appear in approximately the same regions they do in the + base game. + + By default, health item locations will never include progression items, so they aren't mandatory + checks. You can override this by customizing the "exclude_locations" field in your YAML config. + (For example, "exclude_locations: []" will allow progression items in every unmissable + location.) + """ + display_name = "Health Upgrade Locations" + option_not_randomized = 1 + option_anywhere = 2 + option_similar_to_base_game = 3 + default = 3 class SoulLocationsOption(Choice): @@ -350,7 +365,7 @@ class DarkSouls3Options(PerGameCommonOptions): enable_npc_locations: RandomizeNPCLocations enable_unique_locations: RandomizeUniqueLocations enable_misc_locations: RandomizeMiscLocations - enable_health_upgrade_locations: RandomizeHealthLocations + health_locations: HealthLocationsOption soul_locations: SoulLocationsOption upgrade_locations: UpgradeLocationsOption random_starting_loadout: RandomizeStartingLoadout diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 3f4c496c0e53..05850ded3e9a 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -13,7 +13,7 @@ from .Fill import Fill from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, UsefulIf, filler_item_names, item_dictionary from .Locations import DarkSouls3Location, DS3LocationCategory, DS3LocationData, location_tables, location_dictionary, location_name_groups -from .Options import DarkSouls3Options, RandomizeWeaponLevelOption, PoolTypeOption, SoulLocationsOption, UpgradeLocationsOption +from .Options import DarkSouls3Options, RandomizeWeaponLevelOption, HealthLocationsOption, PoolTypeOption, SoulLocationsOption, UpgradeLocationsOption class DarkSouls3Web(WebWorld): @@ -103,7 +103,7 @@ def generate_early(self): self.multiworld.early_items[self.player]['Transposing Kiln'] = 1 if self.multiworld.enable_misc_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.MISC) - if self.multiworld.enable_health_upgrade_locations[self.player] == Toggle.option_true: + if self.multiworld.health_locations[self.player] != HealthLocationsOption.option_not_randomized: self.enabled_location_categories.add(DS3LocationCategory.HEALTH) if self.multiworld.upgrade_locations[self.player] != UpgradeLocationsOption.option_not_randomized: self.enabled_location_categories.add(DS3LocationCategory.UPGRADE) @@ -561,6 +561,9 @@ def has_any_scroll(state): (item.category != DS3ItemCategory.BOSS or item.souls >= 10000) ) ) + if self.multiworld.health_locations[self.player] == HealthLocationsOption.option_similar_to_base_game: + non_local_or_conditional_items.update({"Estus Shard", "Undead Bone Shard"}) + if len(non_local_or_conditional_items) > 0: for location in self.multiworld.get_locations(self.player): if not location.conditional: @@ -725,7 +728,7 @@ def pre_fill(self) -> None: fill.fill("Large Soul of a Crestfallen Knight", start="Grand Archives") # Boss souls are all in a similar general value range, so we shuffle them and gently - # stagger them so that a player doesn't get too many or too few. We leave one left over + # stagger them so that a player doesn't get too many or too few. We leave two left over # to go into the multiworld and show up whenever. boss_souls = { item.name for item in item_dictionary.values() @@ -735,9 +738,21 @@ def pre_fill(self) -> None: fill.fill(boss_souls, start="Farron Keep", through="Catacombs of Carthus", count=4) fill.fill(boss_souls, start="Smouldering Lake", through="Profaned Capital", count=4) fill.fill(boss_souls, start="Painted World of Ariandel (After Contraption)", through="Untended Graves", - count=(5 if self.multiworld.enable_dlc[self.player] else 4)) + count=(5 if self.multiworld.enable_dlc[self.player] else 3)) fill.fill(boss_souls, start="Grand Archives", through="Ringed City", - count=(5 if self.multiworld.enable_dlc[self.player] else 2)) + count=(4 if self.multiworld.enable_dlc[self.player] else 2)) + + if self.multiworld.health_locations[self.player] == HealthLocationsOption.option_similar_to_base_game: + # Leave three Estus Shards and three Undead Bone Shards for the multiworld, since + # they're relatively low-risk to just show up anywhere. + fill.fill("Estus Shard", through="Undead Settlement", count=2) + fill.fill("Estus Shard", start="Road of Sacrifices", through="Catacombs of Carthus", count=3) + fill.fill("Estus Shard", start="Catacombs of Carthus", through="Profaned Capital", count=2) + fill.fill("Estus Shard", start="Profaned Capital", count=2) + fill.fill("Undead Bone Shard", start="Undead Settlement", through="Cathedral of the Deep", count=3) + fill.fill("Undead Bone Shard", start="Catacombs of Carthus", + through="Painted World of Ariandel (Before Contraption)", count=2) + fill.fill("Undead Bone Shard", start="Anor Londo", count=2) fill.save() From 1b988da1390204909bd61d50b83cefd9e4caa12b Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 2 Nov 2023 17:46:23 -0700 Subject: [PATCH 049/238] Handle infusions at item generation time --- worlds/dark_souls_3/Items.py | 53 +++++++++++++++++++++++++++++++++ worlds/dark_souls_3/Options.py | 2 ++ worlds/dark_souls_3/__init__.py | 50 ++++++++++++++----------------- 3 files changed, 77 insertions(+), 28 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 4428e4a54809..1ad92cd97428 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -21,6 +21,44 @@ class DS3ItemCategory(IntEnum): BOSS = 10 SKIP = 11 + @property + def is_infusible(self) -> bool: + """Returns whether this category can be infused.""" + return self in [ + DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE, + DS3ItemCategory.SHIELD_INFUSIBLE + ] + + +@dataclass +class Infusion(IntEnum): + """Infusions supported by Dark Souls III. + + The value of each infusion is the number added to the base weapon's ID to get the infused ID. + """ + + HEAVY = 100 + SHARP = 200 + REFINED = 300 + SIMPLE = 400 + CRYSTAL = 500 + FIRE = 600 + CHAOS = 700 + LIGHTNING = 800 + DEEP = 900 + DARK = 1000 + POISON = 1100 + BLOOD = 1200 + RAW = 1300 + BLESSED = 1400 + HOLLOW = 1500 + + @property + def prefix(self): + """The prefix to add to a weapon name with this infusion.""" + return self.name.title() + + class UsefulIf(IntEnum): """An enum that indicates when an item should be upgraded to ItemClassification.useful. @@ -106,6 +144,19 @@ def counts(self, counts: List[int]) -> Generator["DS3ItemData", None, None]: filler = False, # Don't count multiples as filler by default ) + def infuse(self, infusion: Infusion) -> "DS3ItemData": + """Returns this item with the given infusion applied.""" + if not self.category.is_infusible: raise f"{name} is not infusible." + if self.ds3_code % 10000 >= 100: raise f"{name} is already infused." + + return dataclasses.replace( + self, + name = f"{infusion.prefix} {self.name}", + ds3_code = ds3_code + infusion.value, + base_name = self.base_name, + filler = False, + ) + def __hash__(self): return hash((name, count)) @@ -115,6 +166,7 @@ def __eq__(self, other): class DarkSouls3Item(Item): game: str = "Dark Souls III" + ds3_code = int count: int = 1 souls: Optional[int] = None base_name: str @@ -138,6 +190,7 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou item.count = data.count item.souls = data.souls item.base_name = data.base_name + item.ds3_code = data.ds3_code return item _vanilla_items = flatten([ diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index bb555f69bc93..bc963dfce415 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -187,6 +187,8 @@ class RandomizeInfusionPercentageOption(Range): 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): diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 05850ded3e9a..4e4d11709fd0 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -11,7 +11,7 @@ from .Bosses import DS3BossInfo, all_bosses, default_yhorm_location from .Fill import Fill -from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, UsefulIf, filler_item_names, item_dictionary +from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, Infusion, UsefulIf, filler_item_names, item_dictionary from .Locations import DarkSouls3Location, DS3LocationCategory, DS3LocationData, location_tables, location_dictionary, location_name_groups from .Options import DarkSouls3Options, RandomizeWeaponLevelOption, HealthLocationsOption, PoolTypeOption, SoulLocationsOption, UpgradeLocationsOption @@ -407,6 +407,11 @@ def create_item(self, item: Union[str, DS3ItemData]) -> Item: )): classification = ItemClassification.useful + if self.multiworld.randomize_infusion[self.player] and data.category.is_infusible: + infusion_percentage = self.multiworld.randomize_infusion_percentage[self.player] + if self.multiworld.random.randint(0, 99) < infusion_percentage: + data = data.infuse(self.multiworld.random.choice(list(Infusion))) + return DarkSouls3Item.from_data( self.player, data, classification=classification) @@ -760,32 +765,21 @@ def pre_fill(self) -> None: def fill_slot_data(self) -> Dict[str, object]: slot_data: Dict[str, object] = {} - # Depending on the specified option, modify items hexadecimal value to add an upgrade level or infusion - name_to_ds3_code = {item.name: item.ds3_code for item in item_dictionary.values()} - - # Randomize some weapon upgrades - if self.multiworld.randomize_weapon_level[self.player] != RandomizeWeaponLevelOption.option_none: - # if the user made an error and set a min higher than the max we default to the max - max_5 = self.multiworld.max_levels_in_5[self.player] - min_5 = min(self.multiworld.min_levels_in_5[self.player], max_5) - max_10 = self.multiworld.max_levels_in_10[self.player] - min_10 = min(self.multiworld.min_levels_in_10[self.player], max_10) - weapon_level_percentage = self.multiworld.randomize_weapon_level_percentage[self.player] - - for item in item_dictionary.values(): - if self.multiworld.per_slot_randoms[self.player].randint(0, 99) < weapon_level_percentage: - if item.category == DS3ItemCategory.WEAPON_UPGRADE_5: - name_to_ds3_code[item.name] += self.multiworld.per_slot_randoms[self.player].randint(min_5, max_5) - elif item.category in {DS3ItemCategory.WEAPON_UPGRADE_10, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE}: - name_to_ds3_code[item.name] += self.multiworld.per_slot_randoms[self.player].randint(min_10, max_10) - - # Randomize some weapon infusions - if self.multiworld.randomize_infusion[self.player] == Toggle.option_true: - infusion_percentage = self.multiworld.randomize_infusion_percentage[self.player] - for item in item_dictionary.values(): - if item.category in {DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE, DS3ItemCategory.SHIELD_INFUSIBLE}: - if self.multiworld.per_slot_randoms[self.player].randint(0, 99) < infusion_percentage: - name_to_ds3_code[item.name] += 100 * self.multiworld.per_slot_randoms[self.player].randint(0, 15) + # # Randomize some weapon upgrades + # if self.multiworld.randomize_weapon_level[self.player] != RandomizeWeaponLevelOption.option_none: + # # if the user made an error and set a min higher than the max we default to the max + # max_5 = self.multiworld.max_levels_in_5[self.player] + # min_5 = min(self.multiworld.min_levels_in_5[self.player], max_5) + # max_10 = self.multiworld.max_levels_in_10[self.player] + # min_10 = min(self.multiworld.min_levels_in_10[self.player], max_10) + # weapon_level_percentage = self.multiworld.randomize_weapon_level_percentage[self.player] + + # for item in item_dictionary.values(): + # if self.multiworld.per_slot_randoms[self.player].randint(0, 99) < weapon_level_percentage: + # if item.category == DS3ItemCategory.WEAPON_UPGRADE_5: + # name_to_ds3_code[item.name] += self.multiworld.per_slot_randoms[self.player].randint(min_5, max_5) + # elif item.category in {DS3ItemCategory.WEAPON_UPGRADE_10, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE}: + # name_to_ds3_code[item.name] += self.multiworld.per_slot_randoms[self.player].randint(min_10, max_10) our_items = { location.item @@ -797,7 +791,7 @@ def fill_slot_data(self) -> Dict[str, object]: ap_ids_to_ds3_ids: Dict[str, int] = {} item_counts: Dict[str, int] = {} for item in our_items: - ap_ids_to_ds3_ids[str(item.code)] = name_to_ds3_code[item.name] + ap_ids_to_ds3_ids[str(item.code)] = item.ds3_code if item.count != 1: item_counts[str(item.code)] = item.count # A map from Archipelago's location IDs to the keys the offline From c3f9d3b9f77fe3dc47bcb342235c40697d3ce8d6 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 2 Nov 2023 18:08:03 -0700 Subject: [PATCH 050/238] Handle item upgrades at genreation time --- worlds/dark_souls_3/Items.py | 26 +++++++++++++++++++++++++- worlds/dark_souls_3/__init__.py | 33 +++++++++++++++++---------------- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 1ad92cd97428..b0d45b756d0c 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -29,6 +29,16 @@ def is_infusible(self) -> bool: DS3ItemCategory.SHIELD_INFUSIBLE ] + @property + def upgrade_level(self) -> Optional[int]: + """The maximum upgrade level for this category, or None if it's not upgradable.""" + if self == DS3ItemCategory.WEAPON_UPGRADE_5: return 5 + if self in [ + DS3ItemCategory.WEAPON_UPGRADE_10, + DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE + ]: return 10 + return None + @dataclass class Infusion(IntEnum): @@ -152,7 +162,21 @@ def infuse(self, infusion: Infusion) -> "DS3ItemData": return dataclasses.replace( self, name = f"{infusion.prefix} {self.name}", - ds3_code = ds3_code + infusion.value, + ds3_code = self.ds3_code + infusion.value, + base_name = self.base_name, + filler = False, + ) + + def upgrade(self, level: int) -> "DS3ItemData": + """Upgrades this item to the given level.""" + if not self.category.upgrade_level: raise f"{name} is not upgradable." + if level > self.category.upgrade_level: raise f"{name} can't be upgraded to +{level}." + if self.ds3_code % 100 != 0: raise f"{name} is already upgraded." + + return dataclasses.replace( + self, + name = f"{self.name} +{level}", + ds3_code = self.ds3_code + level, base_name = self.base_name, filler = False, ) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 4e4d11709fd0..2287af9607a8 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -407,6 +407,23 @@ def create_item(self, item: Union[str, DS3ItemData]) -> Item: )): classification = ItemClassification.useful + if ( + self.multiworld.randomize_weapon_level[self.player] != RandomizeWeaponLevelOption.option_none + and data.category.upgrade_level + ): + # if the user made an error and set a min higher than the max we default to the max + max_5 = self.multiworld.max_levels_in_5[self.player] + min_5 = min(self.multiworld.min_levels_in_5[self.player], max_5) + max_10 = self.multiworld.max_levels_in_10[self.player] + min_10 = min(self.multiworld.min_levels_in_10[self.player], max_10) + weapon_level_percentage = self.multiworld.randomize_weapon_level_percentage[self.player] + + if self.multiworld.random.randint(0, 99) < weapon_level_percentage: + if data.category.upgrade_level == 5: + data = data.upgrade(self.multiworld.random.randint(min_5, max_5)) + elif data.category.upgrade_level == 10: + data = data.upgrade(self.multiworld.random.randint(min_10, max_10)) + if self.multiworld.randomize_infusion[self.player] and data.category.is_infusible: infusion_percentage = self.multiworld.randomize_infusion_percentage[self.player] if self.multiworld.random.randint(0, 99) < infusion_percentage: @@ -765,22 +782,6 @@ def pre_fill(self) -> None: def fill_slot_data(self) -> Dict[str, object]: slot_data: Dict[str, object] = {} - # # Randomize some weapon upgrades - # if self.multiworld.randomize_weapon_level[self.player] != RandomizeWeaponLevelOption.option_none: - # # if the user made an error and set a min higher than the max we default to the max - # max_5 = self.multiworld.max_levels_in_5[self.player] - # min_5 = min(self.multiworld.min_levels_in_5[self.player], max_5) - # max_10 = self.multiworld.max_levels_in_10[self.player] - # min_10 = min(self.multiworld.min_levels_in_10[self.player], max_10) - # weapon_level_percentage = self.multiworld.randomize_weapon_level_percentage[self.player] - - # for item in item_dictionary.values(): - # if self.multiworld.per_slot_randoms[self.player].randint(0, 99) < weapon_level_percentage: - # if item.category == DS3ItemCategory.WEAPON_UPGRADE_5: - # name_to_ds3_code[item.name] += self.multiworld.per_slot_randoms[self.player].randint(min_5, max_5) - # elif item.category in {DS3ItemCategory.WEAPON_UPGRADE_10, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE}: - # name_to_ds3_code[item.name] += self.multiworld.per_slot_randoms[self.player].randint(min_10, max_10) - our_items = { location.item for location in self.multiworld.get_filled_locations() From 9a22cf06957078fd3c86d980d61f5878c10c2674 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 2 Nov 2023 21:20:29 -0700 Subject: [PATCH 051/238] Fix Grave Warden's Ashes --- worlds/dark_souls_3/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 2287af9607a8..682eb211466c 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -464,7 +464,7 @@ def set_rules(self) -> None: "Karla's Trousers", ], "Xanthous Ashes": ["Xanthous Overcoat", "Xanthous Gloves", "Xanthous Trousers"], - "Grave Warden's Ashes": ["Ember (Dragon Chaser)"], + "Dragon Chaser's Ashes": ["Ember (Dragon Chaser)"], "Easterner's Ashes": [ "Washing Pole", "Eastern Helm", From aba12887dc728d41ab2f3c0f34c4ad694057d13a Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 2 Nov 2023 21:56:33 -0700 Subject: [PATCH 052/238] Don't overwrite old rules --- worlds/dark_souls_3/__init__.py | 80 ++++++++++++++++----------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 682eb211466c..26e25f7fea2a 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -439,13 +439,13 @@ def get_filler_item_name(self) -> str: def set_rules(self) -> None: # Define the access rules to the entrances - self._set_entrance_rule("Firelink Shrine Bell Tower", "Tower Key") - self._set_entrance_rule("Undead Settlement", "Small Lothric Banner") - self._set_entrance_rule("Lothric Castle", "Basin of Vows") - self._set_entrance_rule("Irithyll of the Boreal Valley", "Small Doll") - self._set_entrance_rule("Archdragon Peak", "Path of the Dragon") - self._set_entrance_rule("Grand Archives", "Grand Archives Key") - self._set_entrance_rule( + self._add_entrance_rule("Firelink Shrine Bell Tower", "Tower Key") + self._add_entrance_rule("Undead Settlement", "Small Lothric Banner") + self._add_entrance_rule("Lothric Castle", "Basin of Vows") + self._add_entrance_rule("Irithyll of the Boreal Valley", "Small Doll") + self._add_entrance_rule("Archdragon Peak", "Path of the Dragon") + self._add_entrance_rule("Grand Archives", "Grand Archives Key") + self._add_entrance_rule( "Kiln of the First Flame", lambda state: state.has("Cinders of a Lord - Abyss Watcher", self.player) and state.has("Cinders of a Lord - Yhorm the Giant", self.player) and @@ -483,38 +483,38 @@ def set_rules(self) -> None: } for ash, items in ashes.items(): for item in items: - self._set_location_rule("FS: " + item, ash) + self._add_location_rule("FS: " + item, ash) if self.multiworld.late_basin_of_vows[self.player] == Toggle.option_true: - self._set_entrance_rule("Lothric Castle", "Small Lothric Banner") + self._add_entrance_rule("Lothric Castle", "Small Lothric Banner") # DLC Access Rules Below if self.multiworld.enable_dlc[self.player]: - self._set_entrance_rule("Ringed City", "Small Envoy Banner") - self._set_entrance_rule("Painted World of Ariandel (After Contraption)", "Contraption Key") + self._add_entrance_rule("Ringed City", "Small Envoy Banner") + self._add_entrance_rule("Painted World of Ariandel (After Contraption)", "Contraption Key") if self.multiworld.late_dlc[self.player]: - self._set_entrance_rule("Painted World of Ariandel (After Contraption)", "Small Doll") + self._add_entrance_rule("Painted World of Ariandel (After Contraption)", "Small Doll") # Define the access rules to some specific locations - self._set_location_rule("HWL: Red Eye Orb", "Lift Chamber Key") - self._set_location_rule("ID: Bellowing Dragoncrest Ring", "Jailbreaker's Key") - self._set_location_rule("ID: Covetous Gold Serpent Ring", "Old Cell Key") - self._set_location_rule("UG: Hornet Ring", "Small Lothric Banner") - self._set_entrance_rule("Karla's Shop", "Jailer's Key Ring") + self._add_location_rule("HWL: Red Eye Orb", "Lift Chamber Key") + self._add_location_rule("ID: Bellowing Dragoncrest Ring", "Jailbreaker's Key") + self._add_location_rule("ID: Covetous Gold Serpent Ring", "Old Cell Key") + self._add_location_rule("UG: Hornet Ring", "Small Lothric Banner") + self._add_entrance_rule("Karla's Shop", "Jailer's Key Ring") # The offline randomizer edits events to guarantee that Greirat won't go to Lothric until # Grand Archives is available, so his shop will always be available one way or another. - self._set_entrance_rule("Greirat's Shop", "Cell Key") + self._add_entrance_rule("Greirat's Shop", "Cell Key") for item in ["Leonhard's Garb", "Leonhard's Gauntlets", "Leonhard's Trousers"]: - self._set_location_rule("AL: " + item, "Black Eye Orb") + self._add_location_rule("AL: " + item, "Black Eye Orb") # You could just kill NPCs for these, but it's more fun to ensure the player can do # their quests. - self._set_location_rule("FS: Lift Chamber Key", "Pale Tongue") - self._set_location_rule("AP: Hawkwood's Swordgrass", "Twinkling Dragon Torso Stone") - self._set_location_rule("ID: Prisoner Chief's Ashes", "Jailer's Key Ring") + self._add_location_rule("FS: Lift Chamber Key", "Pale Tongue") + self._add_location_rule("AP: Hawkwood's Swordgrass", "Twinkling Dragon Torso Stone") + self._add_location_rule("ID: Prisoner Chief's Ashes", "Jailer's Key Ring") # Make sure that the player can keep Orbeck around by giving him at least one scroll # before killing Abyss Watchers. @@ -523,22 +523,22 @@ def has_any_scroll(state): state.has("Golden Scroll", self.player) or state.has("Logan's Scroll", self.player) or state.has("Crystal Scroll", self.player)) - self._set_location_rule("FK: Soul of the Blood of the Wolf", has_any_scroll) - self._set_location_rule("FK: Cinders of a Lord - Abyss Watcher", has_any_scroll) - self._set_entrance_rule("Catacombs of Carthus", has_any_scroll) + self._add_location_rule("FK: Soul of the Blood of the Wolf", has_any_scroll) + self._add_location_rule("FK: Cinders of a Lord - Abyss Watcher", has_any_scroll) + self._add_entrance_rule("Catacombs of Carthus", has_any_scroll) - self._set_location_rule("HWL: Soul of the Dancer", "Basin of Vows") + self._add_location_rule("HWL: Soul of the Dancer", "Basin of Vows") # Lump Soul of the Dancer in with LC for locations that should not be reachable # before having access to US. (Prevents requiring getting Basin to fight Dancer to get SLB to go to US) if self.multiworld.late_basin_of_vows[self.player]: - self._set_location_rule("HWL: Soul of the Dancer", "Small Lothric Banner") + self._add_location_rule("HWL: Soul of the Dancer", "Small Lothric Banner") gotthard_corpse_rule = lambda state: \ (state.can_reach("AL: Cinders of a Lord - Aldrich", "Location", self.player) and state.can_reach("PC: Cinders of a Lord - Yhorm the Giant", "Location", self.player)) - self._set_location_rule("LC: Grand Archives Key", gotthard_corpse_rule) - self._set_location_rule("LC: Gotthard Twinswords", gotthard_corpse_rule) + self._add_location_rule("LC: Grand Archives Key", gotthard_corpse_rule) + self._add_location_rule("LC: Gotthard Twinswords", gotthard_corpse_rule) # Forbid shops from carrying items with multiple counts (the offline randomizer has its own # logic for choosing how many shop items to sell), and from carring soul items. @@ -552,9 +552,9 @@ def has_any_scroll(state): # Make sure the Storm Ruler is available BEFORE Yhorm the Giant if self.yhorm_location.region: - self._set_entrance_rule(self.yhorm_location.region, "Storm Ruler") + self._add_entrance_rule(self.yhorm_location.region, "Storm Ruler") for location in self.yhorm_location.locations: - self._set_location_rule(location, "Storm Ruler") + self._add_location_rule(location, "Storm Ruler") self.multiworld.completion_condition[self.player] = lambda state: \ state.has("Cinders of a Lord - Abyss Watcher", self.player) and \ @@ -595,26 +595,24 @@ def has_any_scroll(state): )) - def _set_location_rule(self, location: str, rule: Union[CollectionRule, str]) -> None: + def _add_location_rule(self, location: str, rule: Union[CollectionRule, str]) -> None: """Sets a rule for the given location if it that location is randomized. The rule can just be a single item/event name as well as an explicit rule lambda. """ if not self.is_location_available(location): return if isinstance(rule, str): - item = rule - assert item_dictionary[item].classification == ItemClassification.progression - rule = lambda state: state.has(item, self.player) - set_rule(self.multiworld.get_location(location, self.player), rule) + assert item_dictionary[rule].classification == ItemClassification.progression + rule = lambda state, item=rule: state.has(item, self.player) + add_rule(self.multiworld.get_location(location, self.player), rule) - def _set_entrance_rule(self, region: str, rule: Union[CollectionRule, str]) -> None: + def _add_entrance_rule(self, region: str, rule: Union[CollectionRule, str]) -> None: """Sets a rule for the entrance to the given region.""" if isinstance(rule, str): - item = rule - assert item_dictionary[item].classification == ItemClassification.progression - rule = lambda state: state.has(item, self.player) - set_rule(self.multiworld.get_entrance("Go To " + region, self.player), rule) + assert item_dictionary[rule].classification == ItemClassification.progression + rule = lambda state, item=rule: state.has(item, self.player) + add_rule(self.multiworld.get_entrance("Go To " + region, self.player), rule) def is_location_available(self, location: Union[str, DS3LocationData]) -> bool: From 2aed0223d86ad7155aa1c84766ed5a0193d0fb01 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 2 Nov 2023 23:47:03 -0700 Subject: [PATCH 053/238] Randomize items based on spheres instead of DS3 locations --- worlds/dark_souls_3/Fill.py | 153 --------------- worlds/dark_souls_3/Locations.py | 53 +++++- worlds/dark_souls_3/Options.py | 33 +--- worlds/dark_souls_3/__init__.py | 313 ++++++++++++++----------------- 4 files changed, 196 insertions(+), 356 deletions(-) delete mode 100644 worlds/dark_souls_3/Fill.py diff --git a/worlds/dark_souls_3/Fill.py b/worlds/dark_souls_3/Fill.py deleted file mode 100644 index af842957c3d2..000000000000 --- a/worlds/dark_souls_3/Fill.py +++ /dev/null @@ -1,153 +0,0 @@ -from typing import List, Optional, Set, Union - -from BaseClasses import ItemClassification, LocationProgressType, MultiWorld - -from .Items import item_dictionary -from .Locations import location_tables - -class Fill: - """A utility class for prefilling items to provide smoother progression.""" - - world: "DarkSouls3World" - """The world that's running this fill.""" - - regions: List[str] - """A list of region names to which prefilled items might be randomized. - - This is roughly in order from earlier to later game, although when the player actually reaches - each region is highly dependent on their seed and settings. This ordering is roughly based on - where upgrade items become available in the base game. - """ - - @property - def multiworld(self) -> MultiWorld: - """The MultiWorld object for the currently generating multiworld.""" - return self.world.multiworld - - @property - def player(self) -> int: - """The ID of the player for which this world is being generated.""" - return self.world.player - - - def __init__(self, world: "DarkSouls3World"): - self.world = world - self.regions = [ - "Cemetery of Ash", - "Firelink Shrine", - "High Wall of Lothric", - "Undead Settlement", - "Road of Sacrifices", - "Farron Keep", - "Cathedral of the Deep", - "Catacombs of Carthus", - "Smouldering Lake", - "Irithyll of the Boreal Valley", - "Irithyll Dungeon", - # The first half of Painted World has one Titanite Slab but mostly Large Titanite Shards, - # much like Irithyll Dungeon. - "Painted World of Ariandel (Before Contraption)", - "Anor Londo", - "Profaned Capital", - # The second half of Painted World has two Titanite Chunks and two Titanite Slabs, which - # puts it on the low end of the post-Lothric Castle areas in terms of rewards. - "Painted World of Ariandel (After Contraption)", - "Lothric Castle", - "Consumed King's Garden", - "Untended Graves", - "Grand Archives", - "Archdragon Peak", - "Kiln of the First Flame", - # Both areas of DLC2 have premium rewards. - "Dreg Heap", - "Ringed City", - ] - - - def fill( - self, - name_or_names: Union[str, Set[str]], - start: Optional[str] = None, - through: Optional[str] = None, - count: int = 0, - no_excluded = False) -> None: - """Fills the given item into open locations in the given region. - - This fills open slots from start through through, inclusive, ordered by how good their - rewards are in the base game. If either start or through isn't passed, this fills from the - beginning or through the end of the game, respectively. - - The name can be a set of names, in which case the items to place are chosen randomly from - among all unplaced items with one of those names. - - If count is positive, this will place up to that many copies of the item. If it's negative, - this will place all but that many copies with the expectation that the remainder will be - placed in other worlds. If it's 0, this will place all remaining copies in the item pool. - - If there's only one world, negative counts will be treated as None. - - If no_excluded is True, this won't place items into excluded locations. This never places - important items in excluded locations. - """ - - if isinstance(name_or_names, str): - all_items = [ - item for item in self.multiworld.itempool - if item.name == name_or_names and not item.location - ] - else: - all_items = [ - item for item in self.multiworld.itempool - if item.name in name_or_names and not item.location - ] - - if count == 0 or count < 0 and len(self.multiworld.worlds) == 1: - self.multiworld.random.shuffle(all_items) - chosen_items = all_items - else: - if count < 0: - count += len(all_items) - if count < 1: return - chosen_items = self.multiworld.random.sample(all_items, k = min(count, len(all_items))) - if len(chosen_items) == 0: return - - if start: assert start in self.regions - if through: assert through in self.regions - region_start = self.regions.index(start) if start else 0 - region_end = self.regions.index(through) + 1 if through else -1 - selected_regions = self.regions[region_start:region_end] - - # All items are expected to have the same properties, so we choose one arbitrarily - item = chosen_items[0] - filler = item.classification == ItemClassification.filler and not no_excluded - possible_locations = [ - location for location in ( - self.multiworld.get_location(location.name, self.player) - for region in selected_regions - for location in location_tables[region] - if ( - self.world.is_location_available(location) - and not location.missable - and not location.conditional - and not (location.shop and (item.count > 1 or item.souls)) - ) - ) - # Don't put important items in excluded locations. - if not location.item - and (filler or location.progress_type != LocationProgressType.EXCLUDED) - ] - if len(possible_locations) == 0: return - if len(possible_locations) < len(chosen_items): - chosen_items = self.multiworld.random.sample(chosen_items, k = len(possible_locations)) - - locations = self.multiworld.random.sample(possible_locations, k = len(chosen_items)) - for item, location in zip(chosen_items, locations): - location.place_locked_item(item) - - - def save(self): - """Removes all allocated items from the multiworld itempool.""" - self.multiworld.itempool = [ - item for item in self.multiworld.itempool - if not item.location - ] diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index b2c4760afc5a..98a31fd8c756 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -5,6 +5,44 @@ from BaseClasses import Location, LocationProgressType, Region +# Regions in approximate order of reward, mostly measured by how high-quality the upgrade items are +# in each region. +region_order = [ + "Cemetery of Ash", + "Firelink Shrine", + "High Wall of Lothric", + "Greirat's Shop", + "Undead Settlement", + "Road of Sacrifices", + "Farron Keep", + "Cathedral of the Deep", + "Catacombs of Carthus", + "Smouldering Lake", + "Irithyll of the Boreal Valley", + "Irithyll Dungeon", + "Karla's Shop", + # The first half of Painted World has one Titanite Slab but mostly Large Titanite Shards, + # much like Irithyll Dungeon. + "Painted World of Ariandel (Before Contraption)", + "Anor Londo", + "Profaned Capital", + # The second half of Painted World has two Titanite Chunks and two Titanite Slabs, which + # puts it on the low end of the post-Lothric Castle areas in terms of rewards. + "Painted World of Ariandel (After Contraption)", + "Lothric Castle", + "Consumed King's Garden", + "Untended Graves", + # List this late becaues it contains a Titanite Slab in the base game + "Firelink Shrine Bell Tower", + "Grand Archives", + "Archdragon Peak", + "Kiln of the First Flame", + # Both areas of DLC2 have premium rewards. + "Dreg Heap", + "Ringed City", +] + + class DS3LocationCategory(IntEnum): WEAPON = 0 SHIELD = 1 @@ -45,6 +83,12 @@ class DS3LocationData: category: DS3LocationCategory """The category into which this location falls.""" + region_value: int = 0 + """The relative value of items in this location's region. + + This is used to sort locations when placing items like the base game. + """ + offline: Optional[str] = None """The key in the offline randomizer's Slots table that corresponds to this location. @@ -57,7 +101,7 @@ class DS3LocationData: item name disagrees with the offline randomizer's, this field is used to provide an explicit association instead. """ - + missable: bool = False """Whether this item is possible to permanently lose access to. @@ -169,6 +213,7 @@ class DarkSouls3Location(Location): default_item_name: str offline: Optional[str] = None conditional: bool = False + region_value: int def __init__( self, @@ -198,6 +243,7 @@ def from_data( ) location.offline = data.offline location.conditional = data.conditional + location.region_value = data.region_value if data.missable: location.progress_type = LocationProgressType.EXCLUDED return location @@ -507,9 +553,6 @@ def get_name_to_id() -> dict: hidden = True, miniboss = True), # Only dropped by Pus of Man after transformation DS3LocationData("HWL: Titanite Shard #5", "Titanite Shard", DS3LocationCategory.MISC, hidden = True, miniboss = True), # Only dropped by Pus of Man after transformation - DS3LocationData("HWL: Large Titanite Shard", "Large Titanite Shard", DS3LocationCategory.UPGRADE, - missable = True), # Getting fire-breathing wyvern down to 20% HP. Missable - # because it requires range and is a crazy thing to do DS3LocationData("HWL: Refined Gem", "Refined Gem", DS3LocationCategory.UPGRADE, miniboss = True), # Red-Eyed Lothric Knight drop DS3LocationData("HWL: Way of Blue", "Way of Blue", DS3LocationCategory.UNIQUE), @@ -2737,6 +2780,8 @@ def get_name_to_id() -> dict: ], } +for i, region in enumerate(region_order): + for location in location_tables[region]: location.region_value = i for region in [ "Painted World of Ariandel (Before Contraption)", diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index bc963dfce415..be372a8c1a11 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -66,24 +66,9 @@ class RandomizeMiscLocations(DefaultOnToggle): display_name = "Randomize Miscellaneous Locations" -class HealthLocationsOption(Choice): - """Where to andomize health upgrade items (21 checks) - - * Not Randomized: All health item locations contain the same items as in the base game. - * Anywhere: Health items are distributed totally randomly throughout the multiworld. - * Similar to Base Game: Health items appear in approximately the same regions they do in the - base game. - - By default, health item locations will never include progression items, so they aren't mandatory - checks. You can override this by customizing the "exclude_locations" field in your YAML config. - (For example, "exclude_locations: []" will allow progression items in every unmissable - location.) - """ - display_name = "Health Upgrade Locations" - option_not_randomized = 1 - option_anywhere = 2 - option_similar_to_base_game = 3 - default = 3 +class RandomizeHealthLocations(DefaultOnToggle): + """Whether to andomize health upgrade items (+21 checks)""" + display_name = "Randomize Health Locations" class SoulLocationsOption(Choice): @@ -91,8 +76,7 @@ class SoulLocationsOption(Choice): * Not Randomized: All soul item locations contain the same items as in the base game. * Anywhere: Soul items are distributed totally randomly throughout the multiworld. - * Similar to Base Game: Soul items appear in approximately the same regions they do in the - base game. + * Smooth: Soul items appear in a similar order as in the base game. By default, soul item locations will never include progression items, so they aren't mandatory checks. You can override this by customizing the "exclude_locations" field in your YAML config. @@ -102,7 +86,7 @@ class SoulLocationsOption(Choice): display_name = "Soul Locations" option_not_randomized = 1 option_anywhere = 2 - option_similar_to_base_game = 3 + option_smooth = 3 default = 3 @@ -111,8 +95,7 @@ class UpgradeLocationsOption(Choice): * Not Randomized: All upgrade item locations contain the same items as in the base game. * Anywhere: Upgrade items are distributed totally randomly throughout the multiworld. - * Similar to Base Game: Upgrade items appear in approximately the same regions they do in the - base game. + * Smooth: Upgrade items appear in a similar order as in the base game. By default, upgrade item locations will never include progression items, so they aren't mandatory checks. You can override this by customizing the "exclude_locations" field in your @@ -122,7 +105,7 @@ class UpgradeLocationsOption(Choice): display_name = "Upgrade Locations" option_not_randomized = 1 option_anywhere = 2 - option_similar_to_base_game = 3 + option_smooth = 3 default = 3 @@ -367,7 +350,7 @@ class DarkSouls3Options(PerGameCommonOptions): enable_npc_locations: RandomizeNPCLocations enable_unique_locations: RandomizeUniqueLocations enable_misc_locations: RandomizeMiscLocations - health_locations: HealthLocationsOption + enable_health_locations: RandomizeHealthLocations soul_locations: SoulLocationsOption upgrade_locations: UpgradeLocationsOption random_starting_loadout: RandomizeStartingLoadout diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 26e25f7fea2a..0043c1ebb4c1 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -1,19 +1,19 @@ # world/dark_souls_3/__init__.py +from collections.abc import Sequence import logging from typing import Dict, Set, List, Optional, TextIO, Union import re -from BaseClasses import MultiWorld, Region, Item, Entrance, Tutorial, ItemClassification +from BaseClasses import CollectionState, MultiWorld, Region, Item, Location, LocationProgressType, Entrance, Tutorial, ItemClassification from Options import Toggle from worlds.AutoWorld import World, WebWorld from worlds.generic.Rules import CollectionRule, set_rule, add_rule, add_item_rule from .Bosses import DS3BossInfo, all_bosses, default_yhorm_location -from .Fill import Fill from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, Infusion, UsefulIf, filler_item_names, item_dictionary -from .Locations import DarkSouls3Location, DS3LocationCategory, DS3LocationData, location_tables, location_dictionary, location_name_groups -from .Options import DarkSouls3Options, RandomizeWeaponLevelOption, HealthLocationsOption, PoolTypeOption, SoulLocationsOption, UpgradeLocationsOption +from .Locations import DarkSouls3Location, DS3LocationCategory, DS3LocationData, location_tables, location_dictionary, location_name_groups, region_order +from .Options import DarkSouls3Options, RandomizeWeaponLevelOption, PoolTypeOption, SoulLocationsOption, UpgradeLocationsOption class DarkSouls3Web(WebWorld): @@ -103,7 +103,7 @@ def generate_early(self): self.multiworld.early_items[self.player]['Transposing Kiln'] = 1 if self.multiworld.enable_misc_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.MISC) - if self.multiworld.health_locations[self.player] != HealthLocationsOption.option_not_randomized: + if self.multiworld.enable_health_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.HEALTH) if self.multiworld.upgrade_locations[self.player] != UpgradeLocationsOption.option_not_randomized: self.enabled_location_categories.add(DS3LocationCategory.UPGRADE) @@ -526,6 +526,8 @@ def has_any_scroll(state): self._add_location_rule("FK: Soul of the Blood of the Wolf", has_any_scroll) self._add_location_rule("FK: Cinders of a Lord - Abyss Watcher", has_any_scroll) self._add_entrance_rule("Catacombs of Carthus", has_any_scroll) + # Not really necessary but ensures players can decide which way to go + self._add_entrance_rule("Painted World of Ariandel (After Contraption)", has_any_scroll) self._add_location_rule("HWL: Soul of the Dancer", "Basin of Vows") @@ -533,6 +535,10 @@ def has_any_scroll(state): # before having access to US. (Prevents requiring getting Basin to fight Dancer to get SLB to go to US) if self.multiworld.late_basin_of_vows[self.player]: self._add_location_rule("HWL: Soul of the Dancer", "Small Lothric Banner") + # This isn't really necessary, but it ensures that the game logic knows players will + # want to do Lothric Castle after at least being _able_ to access Catacombs. This is + # useful for smooth item placement. + self._add_location_rule("HWL: Soul of the Dancer", has_any_scroll) gotthard_corpse_rule = lambda state: \ (state.can_reach("AL: Cinders of a Lord - Aldrich", "Location", self.player) and @@ -562,38 +568,6 @@ def has_any_scroll(state): state.has("Cinders of a Lord - Aldrich", self.player) and \ state.has("Cinders of a Lord - Lothric Prince", self.player) - # If smoothing is enabled and there are multiple worlds, set a special rule to forbid the - # remaining items of certain types from in-world locations _except_ those that are small - # unlocks from progression items. This allows exciting items to be unlocked while also - # limiting unlocks to the same pool of items we've already chosen to show up unexpectedly. - if len(self.multiworld.worlds) > 1: - non_local_or_conditional_items = set() - if self.multiworld.upgrade_locations[self.player] == UpgradeLocationsOption.option_similar_to_base_game: - # Carefully control the actual weapon upgrade material locations, but be looser with - # gems since they're inherently controlled by coals anyway (which are all local). - non_local_or_conditional_items.update({ - "Titanite Shard", "Large Titanite Shard", "Titanite Chunk", "Titanite Slab", - "Titanite Scale", "Twinkling Titanite" - }) - if self.multiworld.soul_locations[self.player] == SoulLocationsOption.option_similar_to_base_game: - non_local_or_conditional_items.update( - item.name for item in item_dictionary.values() - if ( - item.souls and item.souls > 50 and - (item.category != DS3ItemCategory.BOSS or item.souls >= 10000) - ) - ) - if self.multiworld.health_locations[self.player] == HealthLocationsOption.option_similar_to_base_game: - non_local_or_conditional_items.update({"Estus Shard", "Undead Bone Shard"}) - - if len(non_local_or_conditional_items) > 0: - for location in self.multiworld.get_locations(self.player): - if not location.conditional: - add_item_rule(location, lambda item: ( - item.player != self.player or - item.base_name not in non_local_or_conditional_items - )) - def _add_location_rule(self, location: str, rule: Union[CollectionRule, str]) -> None: """Sets a rule for the given location if it that location is randomized. @@ -636,145 +610,136 @@ def write_spoiler(self, spoiler_handle: TextIO) -> None: def pre_fill(self) -> None: - fill = Fill(self) - - if self.multiworld.upgrade_locations[self.player] == UpgradeLocationsOption.option_similar_to_base_game: - # Guarantee enough early shards to level a weapon a few times - fill.fill("Titanite Shard", through="High Wall of Lothric", count=6) - fill.fill("Titanite Shard", start="Undead Settlement", through="Catacombs of Carthus") - fill.fill("Titanite Shard x2", start="Farron Keep", through="Catacombs of Carthus", count=-1) - fill.fill("Large Titanite Shard", start="Farron Keep", through="Catacombs of Carthus", count=6) - fill.fill("Large Titanite Shard", start="Smouldering Lake", through="Anor Londo", count=-3) - fill.fill("Large Titanite Shard x2", start="Irithyll of the Boreal Valley", through="Lothric Castle", count=-1) - fill.fill("Large Titanite Shard x3", start="Irithyll of the Boreal Valley", through="Lothric Castle") - fill.fill("Titanite Chunk", start="Smouldering Lake", through="Profaned Capital", count=3) - # There are a whopping twenty chunks available in these areas in the base game. To add a - # bit more variety, we'll guarantee just enough to level one weapon but allow more to be - # added randomly. - fill.fill("Titanite Chunk", start="Painted World of Ariandel (After Contraption)", through="Consumed King's Garden", count=9) - fill.fill("Titanite Chunk", start="Painted World of Ariandel (After Contraption)") - fill.fill("Titanite Chunk x3", start="Painted World of Ariandel (After Contraption)", count=-2) - fill.fill("Titanite Chunk x6", start="Grand Archives") - # In the base game, a slab is available in the first Painted World and in Irithyll - # Dungeon, so we'll be nice and make one available relatively early. - fill.fill("Titanite Slab", start="Irithyll Dungeon", through="Profaned Capital", count=1) - # We'll make another two available in the castle area to match the one in Untended - # Graves and the three in Painted World. - fill.fill("Titanite Slab", start="Painted World of Ariandel (After Contraption)", through="Untended Graves", count=2) - # Drop the rest in the lategame, leaving one as a nice multiworld item. - fill.fill("Titanite Slab", start="Grand Archives", count=-1) - - # Twinkling Titanite and Titanite Scales both have relatively flat distributions until - # the castle. - fill.fill("Twinkling Titanite", start="Farron Keep", through="Cathedral of the Deep", count=6) - fill.fill("Twinkling Titanite", start="Catacombs of Carthus", through="Profaned Capital", - count=(11 if self.multiworld.enable_dlc[self.player] else 8)) - fill.fill("Twinkling Titanite", start="Painted World of Ariandel (After Contraption)", count=-1) - fill.fill("Twinkling Titanite x2", start="Painted World of Ariandel (After Contraption)", count=-1) - fill.fill("Twinkling Titanite x3", start="Painted World of Ariandel (After Contraption)", count=-1) - fill.fill("Titanite Scale", through="High Wall of Lothric", count=1) - fill.fill("Titanite Scale", start="Undead Settlement", through="Cathedral of the Deep", count=2) - fill.fill("Titanite Scale", start="Catacombs of Carthus", through="Profaned Capital", count=4) - fill.fill("Titanite Scale", start="Painted World of Ariandel (After Contraption)") - fill.fill("Titanite Scale x2", start="Painted World of Ariandel (After Contraption)", count=-1) - fill.fill("Titanite Scale x3", start="Painted World of Ariandel (After Contraption)", count=-1) - - # There's not a lot of cost to making coals available early, so we just need to make - # sure they're not available too late. We set the limit approximately one region after - # they appear in the main game so there's a chance that they're a bit tougher to find. - fill.fill("Farron Coal", through="Road of Sacrifices") - fill.fill("Sage's Coal", through="Catacombs of Carthus") - fill.fill("Giant's Coal", through="Painted World of Ariandel (After Contraption)") - fill.fill("Profaned Coal", through="Profaned Capital") - - # Note: unlike other upgrade items, gems that aren't explicitly filled are freely placed - # so they may appear in earlier areas. - - # If there are infused weapons floating around, guarantee a couple early Shriving Stones - # to undo bad infusions. - if self.multiworld.randomize_infusion[self.player]: - fill.fill("Shriving Stone", through="High Wall of Lothric", count=1) - fill.fill("Shriving Stone", start="Undead Settlement", through="Road of Sacrifices", count=1) - - # Guarantee one easily-findable Raw Gem early on for SL1 runs. - fill.fill("Raw Gem", through="High Wall of Lothric", count=1, no_excluded=True) - # Otherwise, provide one of each type of gem before the coal it requires. - fill.fill("Refined Gem", through="Road of Sacrifices", count=1) - fill.fill("Fire Gem", through="Road of Sacrifices", count=1) - fill.fill("Heavy Gem", through="Road of Sacrifices", count=1) - fill.fill("Sharp Gem", through="Road of Sacrifices", count=1) - fill.fill("Poison Gem", through="Road of Sacrifices", count=1) - fill.fill("Crystal Gem", through="Catacombs of Carthus", count=1) - fill.fill("Blessed Gem", through="Catacombs of Carthus", count=1) - fill.fill("Deep Gem", through="Catacombs of Carthus", count=1) - fill.fill("Dark Gem", through="Painted World of Ariandel (After Contraption)", count=1) - fill.fill("Blood Gem", through="Painted World of Ariandel (After Contraption)", count=1) - fill.fill("Hollow Gem", through="Painted World of Ariandel (After Contraption)", count=1) - fill.fill("Lightning Gem", through="Profaned Capital", count=1) - fill.fill("Simple Gem", through="Profaned Capital", count=1) - fill.fill("Chaos Gem", through="Profaned Capital", count=1) - - if self.multiworld.soul_locations[self.player] == SoulLocationsOption.option_similar_to_base_game: - # Fading souls are worthless and all over the place anyway, so we don't smooth them. - fill.fill("Soul of a Deserted Corpse", through="High Wall of Lothric") - fill.fill("Large Soul of a Deserted Corpse", start="High Wall of Lothric") - fill.fill("Soul of an Unknown Traveler", through="Road of Sacrifices") - - # Only put items worth 800 to 5k souls in the random pool. Any smaller and it sucks, any - # larger and if we're going to disrupt the XP curve that much it's better to do it with - # a splashy boss soul. - fill.fill("Large Soul of an Unknown Traveler", start="Undead Settlement", through="Road of Sacrifices", count=1) - fill.fill("Large Soul of an Unknown Traveler", start="Farron Keep", - through="Painted World of Ariandel (Before Contraption)", count=-3) - fill.fill("Soul of a Nameless Soldier", start="Undead Settlement", through="Road of Sacrifices", count=1) - fill.fill("Soul of a Nameless Soldier", start="Farron Keep", - through="Painted World of Ariandel (Before Contraption)", count=-3) - fill.fill("Soul of a Nameless Soldier", start="Lothric Castle", through="Kiln of the First Flame", count=1) - fill.fill("Large Soul of a Nameless Soldier", start="Farron Keep", through="Catacombs of Carthus", count=4) - fill.fill("Large Soul of a Nameless Soldier", start="Farron Keep", through="Catacombs of Carthus", count=-5) - fill.fill("Large Soul of a Nameless Soldier", start="Lothric Castle", through="Kiln of the First Flame", count=3) - fill.fill("Soul of a Weary Warrior", start="Irithyll of the Boreal Valley", count=-2) - - fill.fill("Large Soul of a Weary Warrior", start="Irithyll Dungeon", through="Profaned Capital", - count=(5 if self.multiworld.enable_dlc[self.player] else 3)) - fill.fill("Large Soul of a Weary Warrior", start="Painted World of Ariandel (After Contraption)", - through="Kiln of the First Flame", count=3) - fill.fill("Large Soul of a Weary Warrior", start="Dreg Heap") - fill.fill("Soul of a Crestfallen Knight", start="Smouldering Lake", through="Profaned Capital", - count=(4 if self.multiworld.enable_dlc[self.player] else 3)) - fill.fill("Soul of a Crestfallen Knight", start="Painted World of Ariandel (After Contraption)") - fill.fill("Large Soul of a Crestfallen Knight", start="Painted World of Ariandel (After Contraption)", - through="Lothric Castle", count=1) - fill.fill("Large Soul of a Crestfallen Knight", start="Grand Archives") - - # Boss souls are all in a similar general value range, so we shuffle them and gently - # stagger them so that a player doesn't get too many or too few. We leave two left over - # to go into the multiworld and show up whenever. - boss_souls = { + # If upgrade smoothing is enabled, make sure one raw gem is available early for SL1 players + if self.multiworld.upgrade_locations[self.player] == UpgradeLocationsOption.option_smooth: + candidate_locations = [ + self.multiworld.get_location(location.name, self.player) + for region in ["Cemetery of Ash", "Firelink Shrine", "High Wall of Lothric"] + for location in location_tables[region] + if self.is_location_available(location) + and not location.missable and not location.conditional + ] + location = self.multiworld.random.choice([ + location for location in candidate_locations + if not location.item and location.progress_type != LocationProgressType.EXCLUDED + ]) + raw_gem = next( + item for item in self.multiworld.itempool + if item.player == self.player and item.name == "Raw Gem" + ) + location.place_locked_item(raw_gem) + self.multiworld.itempool.remove(raw_gem) + + + def post_fill(self): + """If item smoothing is enabled, rearrange items so they scale up smoothly through the run. + + This determines the approximate order a given silo of items (say, soul items) show up in the + main game, then rearranges their shuffled placements to match that order. It determines what + should come "earlier" or "later" based on sphere order: earlier spheres get lower-level + items, later spheres get higher-level ones. Within a sphere, items in DS3 are distributed in + region order, and then the best items in a sphere go into the multiworld. + """ + + state: CollectionState = CollectionState(self.multiworld) + unchecked_locations = set(self.multiworld.get_locations()) + locations_by_sphere: List[Set[Location]] = [] + + while len(unchecked_locations) > 0: + sphere_locations = {loc for loc in unchecked_locations if state.can_reach(loc)} + locations_by_sphere.append(self._shuffle(sphere_locations)) + unchecked_locations.difference_update(sphere_locations) + + state.sweep_for_events(key_only=True, locations=unchecked_locations) + for location in sphere_locations: + if location.event: state.collect(location.item, True, location) + + # All items in the base game in approximately the order they appear + all_item_order = [ + item_dictionary[location.default_item_name] + for region in region_order + # Shuffle locations within each region. + for location in self._shuffle(location_tables[region]) + if self.is_location_available(location) + ] + + def smooth_items(names: Set[str], shuffled: Optional[Set[str]] = None) -> None: + """Rearrange all items with a given base name to the order they appear in the base game. + + If a shuffle set is passed, items from that list will also be randomized, but they will + first be shuffled amongst themselves. + """ + + shuffled = shuffled or set() + shuffled_order = self._shuffle(shuffled) + item_order: List[DS3ItemData] = [] + for item in all_item_order: + if item.base_name in names: + item_order.append(item) + elif item.base_name in shuffled: + item_order.append(item_dictionary[shuffled_order.pop(0)]) + + for i, all_locations in enumerate(locations_by_sphere): + locations = [ + loc for loc in all_locations + if loc.item.player == self.player + and not loc.locked + and loc.item.base_name in names + ] + + # Check the game, not the player, because we know how to sort within regions for DS3 + offworld = [loc for loc in locations if loc.game != "Dark Souls III"] + self.multiworld.random.shuffle(offworld) + onworld = sorted((loc for loc in locations if loc.game == "Dark Souls III"), + key=lambda loc: loc.region_value) + + # Give offworld regions the last (best) items within a given sphere + for location in onworld + offworld: + new_item = self._pop_item(location, item_order) + location.item.name = new_item.name + location.item.base_name = new_item.base_name + location.item.ds3_code = new_item.ds3_code + location.item.count = new_item.count + + if self.multiworld.upgrade_locations[self.player] == UpgradeLocationsOption.option_smooth: + smooth_items({ + "Titanite Shard", "Large Titanite Shard", "Titanite Chunk", "Titanite Slab", + "Titanite Scale", "Twinkling Titanite", "Farron Coal", "Sage's Coal", "Giant's Coal", + "Profaned Coal" + }) + + if self.multiworld.soul_locations[self.player] == SoulLocationsOption.option_smooth: + smooth_items({ + item.name for item in item_dictionary.values() + if item.souls and (item.category != DS3ItemCategory.BOSS or item.souls < 10000) + }, shuffled = { + # Larger boss souls are all worth the same general range, so let them appear in any + # order. item.name for item in item_dictionary.values() - # Don't smooth boss souls worth less than 10k, it's more fun to let them go wherever. if item.category == DS3ItemCategory.BOSS and item.souls and item.souls >= 10000 - } - fill.fill(boss_souls, start="Farron Keep", through="Catacombs of Carthus", count=4) - fill.fill(boss_souls, start="Smouldering Lake", through="Profaned Capital", count=4) - fill.fill(boss_souls, start="Painted World of Ariandel (After Contraption)", through="Untended Graves", - count=(5 if self.multiworld.enable_dlc[self.player] else 3)) - fill.fill(boss_souls, start="Grand Archives", through="Ringed City", - count=(4 if self.multiworld.enable_dlc[self.player] else 2)) - - if self.multiworld.health_locations[self.player] == HealthLocationsOption.option_similar_to_base_game: - # Leave three Estus Shards and three Undead Bone Shards for the multiworld, since - # they're relatively low-risk to just show up anywhere. - fill.fill("Estus Shard", through="Undead Settlement", count=2) - fill.fill("Estus Shard", start="Road of Sacrifices", through="Catacombs of Carthus", count=3) - fill.fill("Estus Shard", start="Catacombs of Carthus", through="Profaned Capital", count=2) - fill.fill("Estus Shard", start="Profaned Capital", count=2) - fill.fill("Undead Bone Shard", start="Undead Settlement", through="Cathedral of the Deep", count=3) - fill.fill("Undead Bone Shard", start="Catacombs of Carthus", - through="Painted World of Ariandel (Before Contraption)", count=2) - fill.fill("Undead Bone Shard", start="Anor Londo", count=2) - - fill.save() + }) + + + def _shuffle(self, seq: Sequence) -> Sequence: + """Returns a shuffled copy of a sequence.""" + copy = list(seq) + self.multiworld.random.shuffle(copy) + return copy + + + def _pop_item(self, location: Location, items: List[DS3ItemData]) -> DS3ItemData: + """Returns the next item in items that can be assigned to location.""" + # Non-excluded locations can take any item we throw at them. (More specifically, if they can + # take one item in a group, they can take any other). + if location.progress_type != LocationProgressType.EXCLUDED: return items.pop(0) + + # Excluded locations require filler items. + for i, item in enumerate(items): + if item.classification == ItemClassification.filler: + return items.pop(i) + + # If we can't find a suitable item, give up and assign an unsuitable one. + return items.pop(0) def fill_slot_data(self) -> Dict[str, object]: From b343539f7234850aef8f767d78be02eba9301619 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 3 Nov 2023 00:43:25 -0700 Subject: [PATCH 054/238] Add a smoothing option for weapon upgrades --- worlds/dark_souls_3/Items.py | 55 +++++++++++------------ worlds/dark_souls_3/Options.py | 13 ++++++ worlds/dark_souls_3/__init__.py | 79 ++++++++++++++++++++------------- 3 files changed, 88 insertions(+), 59 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index b0d45b756d0c..69c3da0b7afa 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -1,7 +1,7 @@ from dataclasses import dataclass, field import dataclasses from enum import IntEnum -from typing import ClassVar, Generator, List, Optional, Set +from typing import ClassVar, Generator, List, Optional, Set, Union from BaseClasses import Item, ItemClassification from Utils import flatten @@ -190,32 +190,29 @@ def __eq__(self, other): class DarkSouls3Item(Item): game: str = "Dark Souls III" - ds3_code = int - count: int = 1 - souls: Optional[int] = None + ds3_code: int + count: int + souls: Optional[int] + category: DS3ItemCategory base_name: str + @property + def level(self) -> Union[int, None]: + """This item's upgrade level, if it's a weapon.""" + return self.ds3_code % 100 if self.category.upgrade_level else None + def __init__( self, - name: str, - classification: ItemClassification, - code: Optional[int], - player: int): - super().__init__(name, classification, code, player) - self.base_name = name - - @staticmethod - def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSouls3Item": - item = DarkSouls3Item( - data.name, - classification or data.classification, - data.ap_code, - player) - item.count = data.count - item.souls = data.souls - item.base_name = data.base_name - item.ds3_code = data.ds3_code - return item + player: int, + data: DS3ItemData, + classification = None): + super().__init__(data.name, classification or data.classification, data.ap_code, player) + self.ds3_code = data.ds3_code + self.count = data.count + self.souls = data.souls + self.category = data.category + self.base_name = data.base_name + _vanilla_items = flatten([ # Ammunition @@ -1015,12 +1012,12 @@ def from_data(player: int, data: DS3ItemData, classification = None) -> "DarkSou classification = ItemClassification.progression), DS3ItemData("Fire Keeper Soul", 0x40000186, DS3ItemCategory.MISC), # Allow souls up to 2k in value to be used as filler - DS3ItemData("Fading Soul", 0x40000190, DS3ItemCategory.MISC, filler = True, souls = 50), - DS3ItemData("Soul of a Deserted Corpse", 0x40000191, DS3ItemCategory.MISC, filler = True, souls = 200), - DS3ItemData("Large Soul of a Deserted Corpse", 0x40000192, DS3ItemCategory.MISC, filler = True, souls = 400), - DS3ItemData("Soul of an Unknown Traveler", 0x40000193, DS3ItemCategory.MISC, filler = True, souls = 800), - DS3ItemData("Large Soul of an Unknown Traveler", 0x40000194, DS3ItemCategory.MISC, filler = True, souls = 1000), - DS3ItemData("Soul of a Nameless Soldier", 0x40000195, DS3ItemCategory.MISC, filler = True, souls = 2000), + DS3ItemData("Fading Soul", 0x40000190, DS3ItemCategory.MISC, souls = 50), + DS3ItemData("Soul of a Deserted Corpse", 0x40000191, DS3ItemCategory.MISC, souls = 200), + DS3ItemData("Large Soul of a Deserted Corpse", 0x40000192, DS3ItemCategory.MISC, souls = 400), + DS3ItemData("Soul of an Unknown Traveler", 0x40000193, DS3ItemCategory.MISC, souls = 800), + DS3ItemData("Large Soul of an Unknown Traveler", 0x40000194, DS3ItemCategory.MISC, souls = 1000), + DS3ItemData("Soul of a Nameless Soldier", 0x40000195, DS3ItemCategory.MISC, souls = 2000), DS3ItemData("Large Soul of a Nameless Soldier", 0x40000196, DS3ItemCategory.MISC, souls = 3000), DS3ItemData("Soul of a Weary Warrior", 0x40000197, DS3ItemCategory.MISC, souls = 5000), DS3ItemData("Large Soul of a Weary Warrior", 0x40000198, DS3ItemCategory.MISC, souls = 8000), diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index be372a8c1a11..a7c16ccbbfde 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -109,6 +109,18 @@ class UpgradeLocationsOption(Choice): default = 3 +class UpgradedWeaponLocationsOption(Choice): + """Where to randomize upgraded weapons (if they're enabled) + + * Anywhere: Upgraded weapons are distributed totally randomly throughout the multiworld. + * Smooth: More upgraded weapons appear deeper in the game. + """ + display_name = "Upgraded Weapon Locations" + option_anywhere = 2 + option_smooth = 3 + default = 3 + + class RandomizeStartingLoadout(DefaultOnToggle): """Randomizes the equipment characters begin with.""" display_name = "Randomize Starting Loadout" @@ -353,6 +365,7 @@ class DarkSouls3Options(PerGameCommonOptions): enable_health_locations: RandomizeHealthLocations soul_locations: SoulLocationsOption upgrade_locations: UpgradeLocationsOption + upgraded_weapon_locations: UpgradedWeaponLocationsOption random_starting_loadout: RandomizeStartingLoadout require_one_handed_starting_weapons: RequireOneHandedStartingWeapons pool_type: PoolTypeOption diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 0043c1ebb4c1..68f7590238c6 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -1,6 +1,7 @@ # world/dark_souls_3/__init__.py from collections.abc import Sequence import logging +from collections import defaultdict from typing import Dict, Set, List, Optional, TextIO, Union import re @@ -13,7 +14,7 @@ from .Bosses import DS3BossInfo, all_bosses, default_yhorm_location from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, Infusion, UsefulIf, filler_item_names, item_dictionary from .Locations import DarkSouls3Location, DS3LocationCategory, DS3LocationData, location_tables, location_dictionary, location_name_groups, region_order -from .Options import DarkSouls3Options, RandomizeWeaponLevelOption, PoolTypeOption, SoulLocationsOption, UpgradeLocationsOption +from .Options import DarkSouls3Options, RandomizeWeaponLevelOption, PoolTypeOption, SoulLocationsOption, UpgradeLocationsOption, UpgradedWeaponLocationsOption class DarkSouls3Web(WebWorld): @@ -429,8 +430,7 @@ def create_item(self, item: Union[str, DS3ItemData]) -> Item: if self.multiworld.random.randint(0, 99) < infusion_percentage: data = data.infuse(self.multiworld.random.choice(list(Infusion))) - return DarkSouls3Item.from_data( - self.player, data, classification=classification) + return DarkSouls3Item(self.player, data, classification=classification) def get_filler_item_name(self) -> str: @@ -663,28 +663,21 @@ def post_fill(self): if self.is_location_available(location) ] - def smooth_items(names: Set[str], shuffled: Optional[Set[str]] = None) -> None: - """Rearrange all items with a given base name to the order they appear in the base game. + def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: + """Rearrange all items in item_order to match that order. - If a shuffle set is passed, items from that list will also be randomized, but they will - first be shuffled amongst themselves. + Note: this requires that item_order exactly matches the number of placed items from this + world matching the given names. """ - shuffled = shuffled or set() - shuffled_order = self._shuffle(shuffled) - item_order: List[DS3ItemData] = [] - for item in all_item_order: - if item.base_name in names: - item_order.append(item) - elif item.base_name in shuffled: - item_order.append(item_dictionary[shuffled_order.pop(0)]) + names = {item.name for item in item_order} for i, all_locations in enumerate(locations_by_sphere): locations = [ loc for loc in all_locations if loc.item.player == self.player and not loc.locked - and loc.item.base_name in names + and loc.item.name in names ] # Check the game, not the player, because we know how to sort within regions for DS3 @@ -696,29 +689,55 @@ def smooth_items(names: Set[str], shuffled: Optional[Set[str]] = None) -> None: # Give offworld regions the last (best) items within a given sphere for location in onworld + offworld: new_item = self._pop_item(location, item_order) - location.item.name = new_item.name - location.item.base_name = new_item.base_name - location.item.ds3_code = new_item.ds3_code - location.item.count = new_item.count + if isinstance(new_item, DarkSouls3Item): + location.item = new_item + new_item.location = location + else: + location.item.name = new_item.name + location.item.base_name = new_item.base_name + location.item.ds3_code = new_item.ds3_code + location.item.count = new_item.count if self.multiworld.upgrade_locations[self.player] == UpgradeLocationsOption.option_smooth: - smooth_items({ + base_names = { "Titanite Shard", "Large Titanite Shard", "Titanite Chunk", "Titanite Slab", "Titanite Scale", "Twinkling Titanite", "Farron Coal", "Sage's Coal", "Giant's Coal", "Profaned Coal" - }) + } + smooth_items([item for item in all_item_order if item.base_name in base_names]) if self.multiworld.soul_locations[self.player] == SoulLocationsOption.option_smooth: - smooth_items({ - item.name for item in item_dictionary.values() - if item.souls and (item.category != DS3ItemCategory.BOSS or item.souls < 10000) - }, shuffled = { - # Larger boss souls are all worth the same general range, so let them appear in any - # order. + # Shuffle larger boss sould among themselves because they're all worth 10-20k souls in + # no particular order and that's a lot more interesting than getting them in the same + # order every single run. + shuffled = { item.name for item in item_dictionary.values() if item.category == DS3ItemCategory.BOSS and item.souls and item.souls >= 10000 - }) - + } + shuffled_order = self._shuffle(shuffled) + item_order: List[DS3ItemData] = [] + for item in all_item_order: + if not item.souls: continue + if item.base_name in shuffled: + item_order.append(item_dictionary[shuffled_order.pop(0)]) + else: + item_order.append(item) + + order_names = [item.name for item in item_order] + location_names = [loc.item.name for loc in self.multiworld.get_locations() if loc.item.name in order_names] + + smooth_items(item_order) + + if self.multiworld.upgraded_weapon_locations[self.player] == UpgradedWeaponLocationsOption.option_smooth: + upgraded_weapons = [ + location.item + for location in self.multiworld.get_locations() + if location.item.player == self.player + and location.item.level and location.item.level > 0 + ] + upgraded_weapons.sort(key=lambda item: item.level) + smooth_items(upgraded_weapons) + def _shuffle(self, seq: Sequence) -> Sequence: """Returns a shuffled copy of a sequence.""" From dfe3eaeb676adb58ed9b1b2e58025e73f8574fc0 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 3 Nov 2023 01:02:43 -0700 Subject: [PATCH 055/238] Add rules for crow trades --- worlds/dark_souls_3/Items.py | 33 +++++++++++++++++++++------------ worlds/dark_souls_3/__init__.py | 18 ++++++++++++++++++ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 69c3da0b7afa..c1bc907ce314 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -328,7 +328,8 @@ def __init__( DS3ItemData("Thrall Axe", 0x006C5660, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), DS3ItemData("Dragonslayer Greataxe", 0x006C7D70, DS3ItemCategory.WEAPON_UPGRADE_5), DS3ItemData("Demon's Greataxe", 0x006CA480, DS3ItemCategory.WEAPON_UPGRADE_5), - DS3ItemData("Eleonora", 0x006CCB90, DS3ItemCategory.WEAPON_UPGRADE_5), + DS3ItemData("Eleonora", 0x006CCB90, DS3ItemCategory.WEAPON_UPGRADE_5, + classification = ItemClassification.progression), # Crow trade DS3ItemData("Man Serpent Hatchet", 0x006D19B0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), DS3ItemData("Club", 0x007A1200, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), DS3ItemData("Mace", 0x007A3910, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), @@ -346,7 +347,8 @@ def __init__( DS3ItemData("Pickaxe", 0x007DE290, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), DS3ItemData("Dragon Tooth", 0x007E09A0, DS3ItemCategory.WEAPON_UPGRADE_5), DS3ItemData("Smough's Great Hammer", 0x007E30B0, DS3ItemCategory.WEAPON_UPGRADE_5), - DS3ItemData("Blacksmith Hammer", 0x007E57C0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), + DS3ItemData("Blacksmith Hammer", 0x007E57C0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE, + classification = ItemClassification.progression), # Crow trade DS3ItemData("Morne's Great Hammer", 0x007E7ED0, DS3ItemCategory.WEAPON_UPGRADE_5), DS3ItemData("Spiked Mace", 0x007EA5E0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), DS3ItemData("Spear", 0x00895440, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), @@ -389,7 +391,8 @@ def __init__( DS3ItemData("Talisman", 0x00C72090, DS3ItemCategory.WEAPON_UPGRADE_10), DS3ItemData("Sorcerer's Staff", 0x00C747A0, DS3ItemCategory.WEAPON_UPGRADE_10), DS3ItemData("Storyteller's Staff", 0x00C76EB0, DS3ItemCategory.WEAPON_UPGRADE_10), - DS3ItemData("Mendicant's Staff", 0x00C795C0, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Mendicant's Staff", 0x00C795C0, DS3ItemCategory.WEAPON_UPGRADE_10, + classification = ItemClassification.progression), # Crow trade DS3ItemData("Man-grub's Staff", 0x00C7E3E0, DS3ItemCategory.WEAPON_UPGRADE_5, inject = True), # Covenant reward DS3ItemData("Archdeacon's Great Staff", 0x00C80AF0, DS3ItemCategory.WEAPON_UPGRADE_5, @@ -420,7 +423,8 @@ def __init__( DS3ItemData("Arbalest", 0x00D662D0, DS3ItemCategory.WEAPON_UPGRADE_10), DS3ItemData("Longbow", 0x00D689E0, DS3ItemCategory.WEAPON_UPGRADE_10), DS3ItemData("Dragonrider Bow", 0x00D6B0F0, DS3ItemCategory.WEAPON_UPGRADE_5), - DS3ItemData("Avelyn", 0x00D6FF10, DS3ItemCategory.WEAPON_UPGRADE_10), + DS3ItemData("Avelyn", 0x00D6FF10, DS3ItemCategory.WEAPON_UPGRADE_10, + classification = ItemClassification.progression), # Crow trade DS3ItemData("Knight's Crossbow", 0x00D72620, DS3ItemCategory.WEAPON_UPGRADE_10), DS3ItemData("Heavy Crossbow", 0x00D74D30, DS3ItemCategory.WEAPON_UPGRADE_10), DS3ItemData("Darkmoon Longbow", 0x00D79B50, DS3ItemCategory.WEAPON_UPGRADE_5), @@ -442,7 +446,8 @@ def __init__( DS3ItemData("Buckler", 0x01312D00, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Small Leather Shield", 0x01315410, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Round Shield", 0x0131A230, DS3ItemCategory.SHIELD_INFUSIBLE), - DS3ItemData("Large Leather Shield", 0x0131C940, DS3ItemCategory.SHIELD_INFUSIBLE), + DS3ItemData("Large Leather Shield", 0x0131C940, DS3ItemCategory.SHIELD_INFUSIBLE, + classification = ItemClassification.progression), # Crow trade DS3ItemData("Hawkwood's Shield", 0x01323E70, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Iron Round Shield", 0x01326580, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Wooden Shield", 0x0132DAB0, DS3ItemCategory.SHIELD_INFUSIBLE), @@ -489,7 +494,8 @@ def __init__( DS3ItemData("Lothric Knight Greatshield", 0x014FD890, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Cathedral Knight Greatshield", 0x014FFFA0, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Dragonslayer Greatshield", 0x01504DC0, DS3ItemCategory.SHIELD), - DS3ItemData("Moaning Shield", 0x015074D0, DS3ItemCategory.SHIELD), + DS3ItemData("Moaning Shield", 0x015074D0, DS3ItemCategory.SHIELD, + classification = ItemClassification.progression), # Crow trade DS3ItemData("Yhorm's Greatshield", 0x0150C2F0, DS3ItemCategory.SHIELD), DS3ItemData("Black Iron Greatshield", 0x0150EA00, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Wolf Knight's Greatshield", 0x01511110, DS3ItemCategory.SHIELD, @@ -532,7 +538,8 @@ def __init__( DS3ItemData("Assassin Trousers", 0x115EFF78, DS3ItemCategory.ARMOR), DS3ItemData("Assassin Hood", 0x11607A60, DS3ItemCategory.ARMOR), DS3ItemData("Assassin Armor", 0x11607E48, DS3ItemCategory.ARMOR), - DS3ItemData("Xanthous Crown", 0x116694E0, DS3ItemCategory.ARMOR), + DS3ItemData("Xanthous Crown", 0x116694E0, DS3ItemCategory.ARMOR, + classification = ItemClassification.progression), # Crow trade DS3ItemData("Xanthous Overcoat", 0x116698C8, DS3ItemCategory.ARMOR), DS3ItemData("Xanthous Gloves", 0x11669CB0, DS3ItemCategory.ARMOR), DS3ItemData("Xanthous Trousers", 0x1166A098, DS3ItemCategory.ARMOR), @@ -989,7 +996,8 @@ def __init__( DS3ItemData("Gold Pine Bundle", 0x40000155, DS3ItemCategory.MISC).counts([6]), DS3ItemData("Rotten Pine Resin", 0x40000157, DS3ItemCategory.MISC).counts([2, 4]), DS3ItemData("Homeward Bone", 0x4000015E, DS3ItemCategory.MISC, filler = True).counts([2, 3, 6]), - DS3ItemData("Coiled Sword Fragment", 0x4000015F, DS3ItemCategory.MISC), + DS3ItemData("Coiled Sword Fragment", 0x4000015F, DS3ItemCategory.MISC, + classification = ItemClassification.progression), # Crow trade DS3ItemData("Wolf's Blood Swordgrass", 0x4000016E, DS3ItemCategory.SKIP), DS3ItemData("Human Dregs", 0x4000016F, DS3ItemCategory.SKIP), DS3ItemData("Forked Pale Tongue", 0x40000170, DS3ItemCategory.SKIP), @@ -1001,7 +1009,7 @@ def __init__( classification = ItemClassification.progression, force_unique = True), # One is needed for Leonhard's quest DS3ItemData("Vertebra Shackle", 0x40000176, DS3ItemCategory.MISC, - force_unique = True), # Allow one of these to trade to the crow + classification = ItemClassification.progression, force_unique = True), # Crow trade DS3ItemData("Sunlight Medal", 0x40000177, DS3ItemCategory.SKIP), DS3ItemData("Dragon Head Stone", 0x40000179, DS3ItemCategory.MISC), DS3ItemData("Dragon Torso Stone", 0x4000017A, DS3ItemCategory.MISC), @@ -1034,11 +1042,12 @@ def __init__( DS3ItemData("Soul of a Champion", 0x400001A3, DS3ItemCategory.MISC, souls = 25000), DS3ItemData("Soul of a Great Champion", 0x400001A4, DS3ItemCategory.MISC, souls = 50000), DS3ItemData("Seed of a Giant Tree", 0x400001B8, DS3ItemCategory.SKIP, - inject = True), + classification = ItemClassification.progression, inject = True), # Crow trade DS3ItemData("Mossfruit", 0x400001C4, DS3ItemCategory.MISC, filler = True).counts([2]), DS3ItemData("Young White Branch", 0x400001C6, DS3ItemCategory.MISC), DS3ItemData("Rusted Coin", 0x400001C7, DS3ItemCategory.MISC, filler = True).counts([2]), - DS3ItemData("Siegbräu", 0x400001C8, DS3ItemCategory.MISC), + DS3ItemData("Siegbräu", 0x400001C8, DS3ItemCategory.MISC, + classification = ItemClassification.progression), # Crow trade DS3ItemData("Rusted Gold Coin", 0x400001C9, DS3ItemCategory.MISC, filler = True).counts([2, 3]), DS3ItemData("Blue Bug Pellet", 0x400001CA, DS3ItemCategory.MISC, filler = True).counts([2]), DS3ItemData("Red Bug Pellet", 0x400001CB, DS3ItemCategory.MISC, filler = True).counts([2, 3]), @@ -1160,7 +1169,7 @@ def __init__( DS3ItemData("Basin of Vows", 0x40000845, DS3ItemCategory.KEY, classification = ItemClassification.progression), DS3ItemData("Loretta's Bone", 0x40000846, DS3ItemCategory.KEY, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Braille Divine Tome of Carim", 0x40000847, DS3ItemCategory.MISC, classification = ItemClassification.useful), DS3ItemData("Braille Divine Tome of Lothric", 0x40000848, DS3ItemCategory.MISC, diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 68f7590238c6..505c6d1ab8fb 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -503,6 +503,21 @@ def set_rules(self) -> None: self._add_location_rule("UG: Hornet Ring", "Small Lothric Banner") self._add_entrance_rule("Karla's Shop", "Jailer's Key Ring") + # List crow trades even though they never contain progression items so that the game knows + # what sphere they're in. This is especially useful for item smoothing. + self._add_location_rule("FSBT: Ring of Sacrifice", "Loretta's Bone") + self._add_location_rule("FSBT: Titanite Scale #1", "Avelyn") + self._add_location_rule("FSBT: Titanite Slab", "Coiled Sword Fragment") + self._add_location_rule("FSBT: Iron Leggings", "Seed of a Giant Tree") + self._add_location_rule("FSBT: Armor of the Sun", "Siegbräu") + self._add_location_rule("FSBT: Lucatiel's Mask", "Vertebra Shackle") + self._add_location_rule("FSBT: Lightning Gem", "Xanthous Crown") + self._add_location_rule("FSBT: Sunlight Shield", "Mendicant's Staff") + self._add_location_rule("FSBT: Titanite Scale #2", "Blacksmith Hammer") + self._add_location_rule("FSBT: Twinkling Titanite #3", "Large Leather Shield") + self._add_location_rule("FSBT: Blessed Gem", "Moaning Shield") + self._add_location_rule("FSBT: Hollow Gem", "Eleonora") + # The offline randomizer edits events to guarantee that Greirat won't go to Lothric until # Grand Archives is available, so his shop will always be available one way or another. self._add_entrance_rule("Greirat's Shop", "Cell Key") @@ -648,7 +663,10 @@ def post_fill(self): while len(unchecked_locations) > 0: sphere_locations = {loc for loc in unchecked_locations if state.can_reach(loc)} locations_by_sphere.append(self._shuffle(sphere_locations)) + + old_length = len(unchecked_locations) unchecked_locations.difference_update(sphere_locations) + if len(unchecked_locations) == old_length: break # Unreachable locations state.sweep_for_events(key_only=True, locations=unchecked_locations) for location in sphere_locations: From 0eb6728472aba130d9a5201625c5a665b0b323c1 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 3 Nov 2023 01:16:18 -0700 Subject: [PATCH 056/238] Small fixes --- worlds/dark_souls_3/__init__.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 505c6d1ab8fb..db26b0dd7e61 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -725,7 +725,7 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: smooth_items([item for item in all_item_order if item.base_name in base_names]) if self.multiworld.soul_locations[self.player] == SoulLocationsOption.option_smooth: - # Shuffle larger boss sould among themselves because they're all worth 10-20k souls in + # Shuffle larger boss souls among themselves because they're all worth 10-20k souls in # no particular order and that's a lot more interesting than getting them in the same # order every single run. shuffled = { @@ -740,16 +740,12 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: item_order.append(item_dictionary[shuffled_order.pop(0)]) else: item_order.append(item) - - order_names = [item.name for item in item_order] - location_names = [loc.item.name for loc in self.multiworld.get_locations() if loc.item.name in order_names] - smooth_items(item_order) if self.multiworld.upgraded_weapon_locations[self.player] == UpgradedWeaponLocationsOption.option_smooth: upgraded_weapons = [ location.item - for location in self.multiworld.get_locations() + for location in self.multiworld.get_filled_locations() if location.item.player == self.player and location.item.level and location.item.level > 0 ] @@ -764,7 +760,11 @@ def _shuffle(self, seq: Sequence) -> Sequence: return copy - def _pop_item(self, location: Location, items: List[DS3ItemData]) -> DS3ItemData: + def _pop_item( + self, + location: Location, + items: List[Union[DS3ItemData, DarkSouls3Item]] + ) -> Union[DS3ItemData, DarkSouls3Item]: """Returns the next item in items that can be assigned to location.""" # Non-excluded locations can take any item we throw at them. (More specifically, if they can # take one item in a group, they can take any other). From 588872bdbe19b7b947fda943c4b608e2ffb489ab Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 3 Nov 2023 01:26:23 -0700 Subject: [PATCH 057/238] Fix a few more bugs --- worlds/dark_souls_3/Locations.py | 4 ++-- worlds/dark_souls_3/__init__.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 98a31fd8c756..0d65caaba757 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -201,7 +201,7 @@ def location_groups(self) -> List[str]: if self.lizard: names.append("Small Crystal Lizards") if self.key: names.append("Keys") if self.category == DS3LocationCategory.UPGRADE: names.append("Upgrade") - if self.category == DS3LocationCategory.SOUL: names.append("Soul Items") + if self.category == DS3LocationCategory.SOUL and not self.boss: names.append("Small Souls") if self.category == DS3LocationCategory.MISC: names.append("Miscellaneous") if self.hidden: names.append("Hidden") return names @@ -2813,7 +2813,7 @@ def get_name_to_id() -> dict: "Small Crystal Lizards": set(), "Keys": set(), "Upgrade": set(), - "Soul Items": set(), + "Small Souls": set(), "Miscellaneous": set(), "Hidden": set() } diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index db26b0dd7e61..f573e2463fa8 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -598,6 +598,8 @@ def _add_location_rule(self, location: str, rule: Union[CollectionRule, str]) -> def _add_entrance_rule(self, region: str, rule: Union[CollectionRule, str]) -> None: """Sets a rule for the entrance to the given region.""" + assert region in location_tables + if not any(region == reg.name for reg in self.multiworld.regions): return if isinstance(rule, str): assert item_dictionary[rule].classification == ItemClassification.progression rule = lambda state, item=rule: state.has(item, self.player) From 3ee41c82c89bc4a9bf092499e21c1daa4a6b3104 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 3 Nov 2023 02:28:54 -0700 Subject: [PATCH 058/238] Fix more bugs --- worlds/dark_souls_3/Items.py | 16 +++++----------- worlds/dark_souls_3/__init__.py | 19 ++++++++++--------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index c1bc907ce314..ee40e41618d3 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -156,8 +156,8 @@ def counts(self, counts: List[int]) -> Generator["DS3ItemData", None, None]: def infuse(self, infusion: Infusion) -> "DS3ItemData": """Returns this item with the given infusion applied.""" - if not self.category.is_infusible: raise f"{name} is not infusible." - if self.ds3_code % 10000 >= 100: raise f"{name} is already infused." + if not self.category.is_infusible: raise f"{self.name} is not infusible." + if self.ds3_code % 10000 >= 100: raise f"{self.name} is already infused." return dataclasses.replace( self, @@ -169,9 +169,9 @@ def infuse(self, infusion: Infusion) -> "DS3ItemData": def upgrade(self, level: int) -> "DS3ItemData": """Upgrades this item to the given level.""" - if not self.category.upgrade_level: raise f"{name} is not upgradable." - if level > self.category.upgrade_level: raise f"{name} can't be upgraded to +{level}." - if self.ds3_code % 100 != 0: raise f"{name} is already upgraded." + if not self.category.upgrade_level: raise f"{self.name} is not upgradable." + if level > self.category.upgrade_level: raise f"{self.name} can't be upgraded to +{level}." + if self.ds3_code % 100 != 0: raise f"{self.name} is already upgraded." return dataclasses.replace( self, @@ -181,12 +181,6 @@ def upgrade(self, level: int) -> "DS3ItemData": filler = False, ) - def __hash__(self): - return hash((name, count)) - - def __eq__(self, other): - return self.name == other.name and self.count == other.count - class DarkSouls3Item(Item): game: str = "Dark Souls III" diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index f573e2463fa8..551cdd94692f 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -381,7 +381,7 @@ def create_random_replacement_list(item_categories: Set[DS3ItemCategory], num_it if item.inject and (not item.is_dlc or dlc_enabled) ] number_to_inject = min(num_required_extra_items, len(injectable_items)) - for item in self.multiworld.random.choices(injectable_items, k=number_to_inject): + for item in self.multiworld.random.sample(injectable_items, k=number_to_inject): num_required_extra_items -= 1 itempool.append(self.create_item(item.name)) @@ -683,6 +683,11 @@ def post_fill(self): if self.is_location_available(location) ] + # Full DarkSouls3Items, grouped by name + full_items_by_name = defaultdict(list) + for location in self.multiworld.get_filled_locations(): + full_items_by_name[location.item.name].append(location.item) + def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: """Rearrange all items in item_order to match that order. @@ -709,14 +714,10 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: # Give offworld regions the last (best) items within a given sphere for location in onworld + offworld: new_item = self._pop_item(location, item_order) - if isinstance(new_item, DarkSouls3Item): - location.item = new_item - new_item.location = location - else: - location.item.name = new_item.name - location.item.base_name = new_item.base_name - location.item.ds3_code = new_item.ds3_code - location.item.count = new_item.count + if isinstance(new_item, DS3ItemData): + new_item = full_items_by_name[new_item.name].pop(0) + location.item = new_item + new_item.location = location if self.multiworld.upgrade_locations[self.player] == UpgradeLocationsOption.option_smooth: base_names = { From e32c75261834ff83580050e8aecc15b3ca2e0e00 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 3 Nov 2023 02:43:56 -0700 Subject: [PATCH 059/238] Try to prevent Path of the Dragon from going somewhere it doesn't work --- worlds/dark_souls_3/Locations.py | 89 ++++++++++++++++++-------------- worlds/dark_souls_3/__init__.py | 23 ++++++--- 2 files changed, 66 insertions(+), 46 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 0d65caaba757..4195636c4f5d 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -149,6 +149,12 @@ class DS3LocationData: item drop. NPCs are never considered minibosses, and some normal-looking enemies with guaranteed drops aren't either (these are instead classified as hidden locations).""" + drop: bool = False + """Whether this is an item dropped by a (non-boss) enemy. + + This is automatically set to True if miniboss, mimic, lizard, or hostile_npc is True. + """ + mimic: bool = False """Whether this location is dropped by a mimic.""" @@ -187,6 +193,9 @@ class DS3LocationData: for an illusory wall or one random mob with a guaranteed drop. """ + def __post_init__(self): + if self.miniboss or self.mimic or self.lizard or self.hostile_npc: self.drop = True + def location_groups(self) -> List[str]: """The names of location groups this location should appear in. @@ -320,7 +329,7 @@ def get_name_to_id() -> dict: ], "Firelink Shrine": [ DS3LocationData("FS: Skull Ring", "Skull Ring", DS3LocationCategory.RING, - hidden = True, npc = True), # Ludleth drop, does not permanently die + hidden = True, drop = True, npc = True), # Ludleth drop, does not permanently die DS3LocationData("FS: Uchigatana", "Uchigatana", DS3LocationCategory.WEAPON, hostile_npc = True), # Sword Master drop DS3LocationData("FS: Master's Attire", "Master's Attire", DS3LocationCategory.ARMOR, @@ -339,7 +348,7 @@ def get_name_to_id() -> dict: DS3LocationData("FS: Cracked Red Eye Orb", "Cracked Red Eye Orb x5", DS3LocationCategory.UNIQUE, missable = True, npc = True, conditional = True), # Leonhard (quest) DS3LocationData("FS: Lift Chamber Key", "Lift Chamber Key", DS3LocationCategory.KEY, - progression = True, npc = True, key = True, conditional = True), # Leonhard (kill or quest) + progression = True, npc = True, key = True, drop = True, conditional = True), # Leonhard (kill or quest) # Shrine Handmaid shop DS3LocationData("FS: White Sign Soapstone", "White Sign Soapstone", DS3LocationCategory.UNIQUE, @@ -583,7 +592,7 @@ def get_name_to_id() -> dict: DS3LocationData("US: Tower Key", "Tower Key", DS3LocationCategory.KEY, missable = True, npc = True, key = True), DS3LocationData("US: Hawk Ring", "Hawk Ring", DS3LocationCategory.RING, - npc = True), # Giant archer (kill or quest) + drop = True, npc = True), # Giant archer (kill or quest) DS3LocationData("US: Flynn's Ring", "Flynn's Ring", DS3LocationCategory.RING), DS3LocationData("US: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), DS3LocationData("US: Alluring Skull #1", "Alluring Skull x2", DS3LocationCategory.MISC), @@ -724,7 +733,7 @@ def get_name_to_id() -> dict: DS3LocationData("US: Londor Braille Divine Tome", "Londor Braille Divine Tome", DS3LocationCategory.UNIQUE, offline = '99,0:-1:40000,110000,70000116:', missable = True, npc = True), DS3LocationData("US: Darkdrift", "Darkdrift", DS3LocationCategory.WEAPON, - missable = True, npc = True), # kill her or kill Soul of Cinder + missable = True, drop = True, npc = True), # kill her or kill Soul of Cinder # Cornyx of the Great Swamp # These aren't missable because the Shrine Handmaid will carry them if you kill Cornyx. @@ -805,7 +814,7 @@ def get_name_to_id() -> dict: DS3LocationData("RS: Xanthous Crown", "Xanthous Crown", DS3LocationCategory.WEAPON, missable = True, hostile_npc = True), # Heysel drop DS3LocationData("RS: Butcher Knife", "Butcher Knife", DS3LocationCategory.WEAPON, - hidden = True), # Guaranteed drop from a normal-looking Butcher + drop = True, hidden = True), # Guaranteed drop from a normal-looking Butcher DS3LocationData("RS: Titanite Shard #1", "Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("RS: Titanite Shard #2", "Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("RS: Green Blossom #1", "Green Blossom x4", DS3LocationCategory.MISC), @@ -962,7 +971,7 @@ def get_name_to_id() -> dict: DS3LocationData("CD: Black Eye Orb", "Black Eye Orb", DS3LocationCategory.UNIQUE, missable = True, npc = True), DS3LocationData("CD: Winged Spear #1", "Winged Spear", DS3LocationCategory.WEAPON, - missable = True), # Patches (kill) + drop = True, missable = True), # Patches (kill) DS3LocationData("CD: Spider Shield", "Spider Shield", DS3LocationCategory.SHIELD, hostile_npc = True), # Brigand DS3LocationData("CD: Notched Whip", "Notched Whip", DS3LocationCategory.WEAPON), @@ -1043,11 +1052,11 @@ def get_name_to_id() -> dict: DS3LocationData("CD: Xanthous Crown", "Xanthous Crown", DS3LocationCategory.WEAPON, missable = True), DS3LocationData("CD: Deep Ring", "Deep Ring", DS3LocationCategory.RING, - hidden = True), # Guaranteed drop from a normal-looking Deacon + drop = True, hidden = True), # Guaranteed drop from a normal-looking Deacon DS3LocationData("CD: Deep Braille Divine Tome", "Deep Braille Divine Tome", DS3LocationCategory.UNIQUE, mimic = True), DS3LocationData("CD: Red Sign Soapstone", "Red Sign Soapstone", DS3LocationCategory.UNIQUE, - hidden = True), # Guaranteed drop from a normal-looking Corpse-grub + drop = True, hidden = True), # Guaranteed drop from a normal-looking Corpse-grub DS3LocationData("CD: Aldrich's Sapphire", "Aldrich's Sapphire", DS3LocationCategory.RING, miniboss = True), # Deep Accursed Drop DS3LocationData("CD: Dung Pie", "Dung Pie x4", DS3LocationCategory.MISC, @@ -1094,7 +1103,7 @@ def get_name_to_id() -> dict: DS3LocationData("CD: Hidden Blessing", "Hidden Blessing", DS3LocationCategory.MISC, missable = True, npc = True, shop = True), DS3LocationData("CD: Horsehoof Ring", "Horsehoof Ring", DS3LocationCategory.RING, - missable = True, npc = True, shop = True), # (kill or buy) + missable = True, npc = True, drop = True, shop = True), # (kill or buy) ], "Farron Keep": [ DS3LocationData("FK: Lightning Spear", "Lightning Spear", DS3LocationCategory.WEAPON), @@ -1177,9 +1186,9 @@ def get_name_to_id() -> dict: DS3LocationData("FK: Lingering Dragoncrest Ring", "Lingering Dragoncrest Ring", DS3LocationCategory.RING, miniboss = True), # Great Crab drop DS3LocationData("FK: Pharis's Hat", "Pharis's Hat", DS3LocationCategory.ARMOR, - hidden = True), # Guaranteed drop from a normal-looking Elder Ghru + drop = True, hidden = True), # Guaranteed drop from a normal-looking Elder Ghru DS3LocationData("FK: Black Bow of Pharis", "Black Bow of Pharis", DS3LocationCategory.WEAPON, - hidden = True), # Guaranteed drop from a normal-looking Elder Ghru + drop = True, hidden = True), # Guaranteed drop from a normal-looking Elder Ghru DS3LocationData("FK: Titanite Scale", "Titanite Scale x2", DS3LocationCategory.UPGRADE, miniboss = True), # Ravenous Crystal Lizard drop DS3LocationData("FK: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE), @@ -1359,7 +1368,7 @@ def get_name_to_id() -> dict: # These are listed here even though you can kill Horace in the Road of Sacrifices because # the player may want to complete his and Anri's quest first. DS3LocationData("SL: Llewellyn Shield", "Llewellyn Shield", DS3LocationCategory.SHIELD, - npc = True), # kill or quest + drop = True, npc = True), # kill or quest # Shrine Handmaiden after killing DS3LocationData("SL: Executioner Helm", "Executioner Helm", DS3LocationCategory.ARMOR, hidden = True, npc = True, shop = True), @@ -1457,13 +1466,13 @@ def get_name_to_id() -> dict: DS3LocationData("IBV: Dorhys' Gnawing", "Dorhys' Gnawing", DS3LocationCategory.SPELL, hidden = True), # Behind illusory wall DS3LocationData("IBV: Divine Blessing #2", "Divine Blessing", DS3LocationCategory.MISC, - hidden = True), # Guaranteed drop from normal-looking Silver Knight + drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight DS3LocationData("IBV: Large Titanite Shard #9", "Large Titanite Shard", DS3LocationCategory.UPGRADE, - hidden = True), # Guaranteed drop from normal-looking Silver Knight + drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight DS3LocationData("IBV: Large Titanite Shard #10", "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, - hidden = True), # Guaranteed drop from normal-looking Silver Knight + drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight DS3LocationData("IBV: Large Titanite Shard #11", "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, - hidden = True), # Guaranteed drop from normal-looking Silver Knight + drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight DS3LocationData("IBV: Roster of Knights", "Roster of Knights", DS3LocationCategory.UNIQUE), DS3LocationData("IBV: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True, hidden = True), # Behind illusory wall @@ -1570,7 +1579,7 @@ def get_name_to_id() -> dict: DS3LocationData("ID: Prisoner Chief's Ashes", "Prisoner Chief's Ashes", DS3LocationCategory.KEY, progression = True), DS3LocationData("ID: Great Magic Shield", "Great Magic Shield", DS3LocationCategory.SPELL, - hidden = True), # Guaranteed drop from a normal-looking Corpse-Grub + drop = True, hidden = True), # Guaranteed drop from a normal-looking Corpse-Grub DS3LocationData("ID: Dragonslayer Lightning Arrow", "Dragonslayer Lightning Arrow x10", DS3LocationCategory.MISC, mimic = True), DS3LocationData("ID: Titanite Scale #1", "Titanite Scale x2", DS3LocationCategory.UPGRADE, @@ -1635,7 +1644,7 @@ def get_name_to_id() -> dict: DS3LocationData("PC: Storm Ruler", "Storm Ruler", DS3LocationCategory.KEY), DS3LocationData("PC: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), DS3LocationData("PC: Eleonora", "Eleonora", DS3LocationCategory.WEAPON, - hidden = True), # Guaranteed drop from a normal-looking Monstrosity of Sin + drop = True, hidden = True), # Guaranteed drop from a normal-looking Monstrosity of Sin DS3LocationData("PC: Rusted Gold Coin #2", "Rusted Gold Coin x2", DS3LocationCategory.MISC, mimic = True), DS3LocationData("PC: Court Sorcerer's Staff", "Court Sorcerer's Staff", DS3LocationCategory.WEAPON, @@ -1655,9 +1664,9 @@ def get_name_to_id() -> dict: # Siegward drops (kill or quest) DS3LocationData("PC: Storm Ruler (Siegward)", "Storm Ruler", DS3LocationCategory.WEAPON, - offline = '02,0:50006218::', missable = True, npc = True), + offline = '02,0:50006218::', missable = True, drop = True, npc = True), DS3LocationData("PC: Pierce Shield", "Pierce Shield", DS3LocationCategory.SHIELD, - missable = True, npc = True), + missable = True, drop = True, npc = True), ], # We consider "Anor Londo" to be everything accessible only after killing Pontiff. This doesn't # match up one-to-one with where the game pops up the region name, but it balances items better @@ -1668,9 +1677,9 @@ def get_name_to_id() -> dict: DS3LocationData("AL: Cinders of a Lord - Aldrich", "Cinders of a Lord - Aldrich", DS3LocationCategory.KEY, offline = '06,0:50002130::', prominent = True, progression = True, boss = True), DS3LocationData("AL: Yorshka's Chime", "Yorshka's Chime", DS3LocationCategory.WEAPON, - missable = True, npc = True), # Yorshka (kill), invisible walkway + missable = True, drop = True, npc = True), # Yorshka (kill), invisible walkway DS3LocationData("AL: Drang Twinspears", "Drang Twinspears", DS3LocationCategory.WEAPON, - hidden = True), # Guaranteed drop from a normal-loking knight + drop = True, hidden = True), # Guaranteed drop from a normal-loking knight DS3LocationData("AL: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), DS3LocationData("AL: Painting Guardian's Curved Sword", "Painting Guardian's Curved Sword", DS3LocationCategory.WEAPON, hidden = True), # Invisible walkway @@ -1726,7 +1735,7 @@ def get_name_to_id() -> dict: DS3LocationData("AL: Ring of Favor", "Ring of Favor", DS3LocationCategory.RING, miniboss = True, hidden = True), # Sulyvahn's Beast Duo drop, behind illusory wall DS3LocationData("AL: Blade of the Darkmoon", "Blade of the Darkmoon", DS3LocationCategory.UNIQUE, - missable = True, npc = True), # Yorshka (quest or kill) + missable = True, drop = True, npc = True), # Yorshka (quest or kill) DS3LocationData("AL: Simple Gem", "Simple Gem", DS3LocationCategory.UPGRADE, lizard = True), DS3LocationData("AL: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, @@ -1915,9 +1924,9 @@ def get_name_to_id() -> dict: # Eygon of Carim (kill or quest) DS3LocationData("LC: Morne's Great Hammer", "Morne's Great Hammer", DS3LocationCategory.WEAPON, - npc = True), + drop = True, npc = True), DS3LocationData("LC: Moaning Shield", "Moaning Shield", DS3LocationCategory.SHIELD, - npc = True), + drop = True, npc = True), # Shrine Handmaid after killing Dancer of the Boreal Valley DS3LocationData("LC: Dancer's Crown", "Dancer's Crown", DS3LocationCategory.ARMOR, @@ -1970,7 +1979,7 @@ def get_name_to_id() -> dict: DS3LocationData("CKG: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE), DS3LocationData("CKG: Titanite Scale #3", "Titanite Scale", DS3LocationCategory.UPGRADE), DS3LocationData("CKG: Magic Stoneplate Ring", "Magic Stoneplate Ring", DS3LocationCategory.RING, - hidden = True), # Guaranteed drop from a normal-looking Consumed King's Knight + drop = True, hidden = True), # Guaranteed drop from a normal-looking Consumed King's Knight DS3LocationData("CKG: Moonlight Greatsword", "Moonlight Greatsword", DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), DS3LocationData("CKG: White Dragon Breath", "White Dragon Breath", DS3LocationCategory.SPELL, @@ -2051,7 +2060,7 @@ def get_name_to_id() -> dict: DS3LocationData("GA: Scholar Ring", "Scholar Ring", DS3LocationCategory.RING), DS3LocationData("GA: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), DS3LocationData("GA: Titanite Slab #3", "Titanite Slab", DS3LocationCategory.UPGRADE, - hidden = True), # Guaranteed drop from killing all Winged Knights + drop = True, hidden = True), # Guaranteed drop from killing all Winged Knights DS3LocationData("GA: Outrider Knight Helm", "Outrider Knight Helm", DS3LocationCategory.ARMOR, miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop DS3LocationData("GA: Outrider Knight Armor", "Outrider Knight Armor", DS3LocationCategory.ARMOR, @@ -2382,7 +2391,7 @@ def get_name_to_id() -> dict: DS3LocationData("PW1: Follower Sabre", "Follower Sabre", DS3LocationCategory.WEAPON), DS3LocationData("PW1: Ember #2", "Ember", DS3LocationCategory.MISC), DS3LocationData("PW1: Snap Freeze", "Snap Freeze", DS3LocationCategory.SPELL, - hidden = True), # Guaranteed drop from normal-looking Tree Woman + drop = True, hidden = True), # Guaranteed drop from normal-looking Tree Woman DS3LocationData("PW1: Rime-blue Moss Clump #3", "Rime-blue Moss Clump", DS3LocationCategory.MISC), DS3LocationData("PW1: Large Soul of an Unknown Traveler #8", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), DS3LocationData("PW1: Ember #3", "Ember", DS3LocationCategory.MISC), @@ -2463,7 +2472,7 @@ def get_name_to_id() -> dict: DS3LocationData("DH: Soul of the Demon Prince", "Soul of the Demon Prince", DS3LocationCategory.SOUL, prominent = True, boss = True), DS3LocationData("DH: Siegbräu", "Siegbräu", DS3LocationCategory.MISC, - missable = True, npc = True), # Lapp (quest or kill) + missable = True, drop = True, npc = True), # Lapp (quest or kill) DS3LocationData("DH: Flame Fan", "Flame Fan", DS3LocationCategory.SPELL, hostile_npc = True), # Desert Pyromancer Zoey drop DS3LocationData("DH: Ember #1", "Ember", DS3LocationCategory.MISC), @@ -2522,11 +2531,11 @@ def get_name_to_id() -> dict: DS3LocationData("DH: Small Envoy Banner", "Small Envoy Banner", DS3LocationCategory.KEY, progression = True, boss = True), DS3LocationData("DH: Twinkling Titanite #4", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, - hidden = True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim + drop = True, hidden = True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim DS3LocationData("DH: Twinkling Titanite #5", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, - hidden = True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim + drop = True, hidden = True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim DS3LocationData("DH: Twinkling Titanite #6", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, - hidden = True), # Guaranteed drop from killing normal-looking pilgrim + drop = True, hidden = True), # Guaranteed drop from killing normal-looking pilgrim DS3LocationData("DH: Demon's Scar", "Demon's Scar", DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), DS3LocationData("DH: Seething Chaos", "Seething Chaos", DS3LocationCategory.SPELL, @@ -2550,9 +2559,9 @@ def get_name_to_id() -> dict: DS3LocationData("RC: Soul of Darkeater Midir", "Soul of Darkeater Midir", DS3LocationCategory.SOUL, prominent = True, boss = True), DS3LocationData("RC: Sacred Chime of Filianore", "Sacred Chime of Filianore", DS3LocationCategory.WEAPON, - npc = True), # Shira (kill or quest) + drop = True, npc = True), # Shira (kill or quest) DS3LocationData("RC: Titanite Slab #2", "Titanite Slab", DS3LocationCategory.UPGRADE, - npc = True), # Shira (kill or quest) + drop = True, npc = True), # Shira (kill or quest) DS3LocationData("RC: Crucifix of the Mad King", "Crucifix of the Mad King", DS3LocationCategory.WEAPON, hostile_npc = True), # Shira drop DS3LocationData("RC: Ledo's Great Hammer", "Ledo's Great Hammer", DS3LocationCategory.WEAPON, @@ -2657,7 +2666,7 @@ def get_name_to_id() -> dict: DS3LocationData("RC: Young White Branch #2", "Young White Branch", DS3LocationCategory.MISC), DS3LocationData("RC: Young White Branch #3", "Young White Branch", DS3LocationCategory.MISC), DS3LocationData("RC: Ringed Knight Paired Greatswords", "Ringed Knight Paired Greatswords", DS3LocationCategory.WEAPON, - hidden = True), # Guaranteed drop from a normal-looking Ringed Knight + drop = True, hidden = True), # Guaranteed drop from a normal-looking Ringed Knight DS3LocationData("RC: Hidden Blessing #2", "Hidden Blessing", DS3LocationCategory.MISC, miniboss = True), # Judicator drop DS3LocationData("RC: Divine Blessing #1", "Divine Blessing", DS3LocationCategory.MISC, @@ -2694,7 +2703,7 @@ def get_name_to_id() -> dict: prominent = True, boss = True), DS3LocationData("RC: Blood of the Dark Soul", "Blood of the Dark Soul", DS3LocationCategory.KEY), DS3LocationData("RC: Titanite Slab #3", "Titanite Slab", DS3LocationCategory.UPGRADE, - hidden = True), # Guaranteed drop from normal-looking Ringed Knight + drop = True, hidden = True), # Guaranteed drop from normal-looking Ringed Knight DS3LocationData("RC: Frayed Blade", "Frayed Blade", DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), DS3LocationData("RC: Old Moonlight", "Old Moonlight", DS3LocationCategory.SPELL, @@ -2770,13 +2779,13 @@ def get_name_to_id() -> dict: # Drops on death. Missable because the player would have to decide between killing her or # seeing everything she sells. DS3LocationData("Karla: Karla's Pointed Hat", "Karla's Pointed Hat", DS3LocationCategory.ARMOR, - offline = '07,0:50006150::', missable = True, npc = True), + offline = '07,0:50006150::', missable = True, drop = True, npc = True), DS3LocationData("Karla: Karla's Coat", "Karla's Coat", DS3LocationCategory.ARMOR, - offline = '07,0:50006150::', missable = True, npc = True), + offline = '07,0:50006150::', missable = True, drop = True, npc = True), DS3LocationData("Karla: Karla's Gloves", "Karla's Gloves", DS3LocationCategory.ARMOR, - offline = '07,0:50006150::', missable = True, npc = True), + offline = '07,0:50006150::', missable = True, drop = True, npc = True), DS3LocationData("Karla: Karla's Trousers", "Karla's Trousers", DS3LocationCategory.ARMOR, - offline = '07,0:50006150::', missable = True, npc = True), + offline = '07,0:50006150::', missable = True, drop = True, npc = True), ], } diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 551cdd94692f..b27fcd091528 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -564,12 +564,23 @@ def has_any_scroll(state): # Forbid shops from carrying items with multiple counts (the offline randomizer has its own # logic for choosing how many shop items to sell), and from carring soul items. for location in location_dictionary.values(): - if location.shop and self.is_location_available(location): - add_item_rule(self.multiworld.get_location(location.name, self.player), - lambda item: ( - item.player != self.player or - (item.count == 1 and not item.souls) - )) + if self.is_location_available(location): + if location.shop: + add_item_rule(self.multiworld.get_location(location.name, self.player), + lambda item: ( + item.player != self.player or + (item.count == 1 and not item.souls) + )) + elif location.drop: + # TODO: I'm not sure this is precisely the rule for where this can and can't + # go, but I've seen the offline randomizer reject it as a Ravenous Crystal + # Lizard drop. Should consult thefifthmatt. + add_item_rule(self.multiworld.get_location(location.name, self.player), + lambda item: ( + item.player != self.player or + item.name != "Path of the Dragon" + )) + # Make sure the Storm Ruler is available BEFORE Yhorm the Giant if self.yhorm_location.region: From a95eaf0db70d65a0887154dc4eaae9fa7bd4c509 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 3 Nov 2023 20:42:39 -0700 Subject: [PATCH 060/238] Add the ability to provide enemy presets --- worlds/dark_souls_3/Bosses.py | 4 ++-- worlds/dark_souls_3/Items.py | 18 +++++++++++------ worlds/dark_souls_3/Options.py | 35 +++++++++++++++++++++++++++++++-- worlds/dark_souls_3/__init__.py | 5 +++-- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index 00de9bf9c833..561804803a6e 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -163,13 +163,13 @@ class DS3BossInfo: "PW2: Ordained Dress", "PW2: Ordained Trousers", }), - DS3BossInfo("Blackflame Friede", 5000801, dlc = True, region = "Dreg Heap", locations = { + DS3BossInfo("Blackflame Friede", 4500800, dlc = True, region = "Dreg Heap", locations = { "PW2: Soul of Sister Friede", "PW2: Ordained Hood", "PW2: Ordained Dress", "PW2: Ordained Trousers", }), - DS3BossInfo("Demon Prince", 4500800, dlc = True, region = "Ringed City", locations = { + DS3BossInfo("Demon Prince", 5000801, dlc = True, region = "Ringed City", locations = { "DH: Soul of the Demon Prince", "DH: Small Envoy Banner", }), diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index ee40e41618d3..a3d49c78deb5 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -104,7 +104,7 @@ class DS3ItemData(): classification: ItemClassification = ItemClassification.filler """How important this item is to the game progression.""" - ap_code: int = False + ap_code: int = None """The Archipelago ID for this item.""" is_dlc: bool = False @@ -138,7 +138,7 @@ class DS3ItemData(): """ def __post_init__(self): - self.ap_code = DS3ItemData.__item_id + self.ap_code = self.ap_code or DS3ItemData.__item_id if not self.base_name: self.base_name = self.name DS3ItemData.__item_id += 1 @@ -159,11 +159,14 @@ def infuse(self, infusion: Infusion) -> "DS3ItemData": if not self.category.is_infusible: raise f"{self.name} is not infusible." if self.ds3_code % 10000 >= 100: raise f"{self.name} is already infused." + # We can't change the name or AP code when infusing/upgrading weapons, because they both + # need to match what's in item_name_to_id. We don't want to add every possible + # infusion/upgrade combination to that map because it's way too many items. return dataclasses.replace( self, - name = f"{infusion.prefix} {self.name}", + ap_code = self.ap_code, + name = self.name, ds3_code = self.ds3_code + infusion.value, - base_name = self.base_name, filler = False, ) @@ -173,11 +176,14 @@ def upgrade(self, level: int) -> "DS3ItemData": if level > self.category.upgrade_level: raise f"{self.name} can't be upgraded to +{level}." if self.ds3_code % 100 != 0: raise f"{self.name} is already upgraded." + # We can't change the name or AP code when infusing/upgrading weapons, because they both + # need to match what's in item_name_to_id. We don't want to add every possible + # infusion/upgrade combination to that map because it's way too many items. return dataclasses.replace( self, - name = f"{self.name} +{level}", + ap_code = self.ap_code, + name = self.name, ds3_code = self.ds3_code + level, - base_name = self.base_name, filler = False, ) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index a7c16ccbbfde..39fccaa45087 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -1,7 +1,9 @@ -import typing +from copy import deepcopy from dataclasses import dataclass +import json +import typing -from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, ItemDict, Option, PerGameCommonOptions, Range, Toggle +from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, ItemDict, Option, PerGameCommonOptions, Range, Toggle, VerifyKeys class RandomizeWeaponLocations(DefaultOnToggle): @@ -270,6 +272,34 @@ class RandomizeEnemiesOption(DefaultOnToggle): display_name = "Randomize Enemies" +class RandomEnemyPresetOption(Option[typing.Dict[str, typing.Any]], VerifyKeys): + """The YAML preset for the offline enemy randomizer. + + See the offline randomizer documentation in randomizer\\presets\\README.txt for details. + """ + display_name = "Random Enemy Preset" + supports_weighting = False + default = {} + + valid_keys: ["Description", "RecommendFullRandomization", "RecommendNoEnemyProgression", + "OopsAll", "Boss", "Miniboss", "Basic", "BuffBasicEnemiesAsBosses", + "DontRandomize", "RemoveSource", "Enemies"] + + def __init__(self, value: typing.Dict[str, typing.Any]): + self.value = deepcopy(value) + + def get_option_name(self, value: typing.Dict[str, typing.Any]): + return json.dumps(value) + + @classmethod + def from_any(cls, data: typing.Dict[str, typing.Any]) -> "RandomEnemyPresetOption": + if type(data) == dict: + cls.verify_keys(data) + return cls(data) + else: + raise NotImplementedError(f"Must be a dictionary, got {type(data)}") + + class RandomizeMimicsWithEnemiesOption(Toggle): """Whether to mix Mimics into the main enemy pool. @@ -389,6 +419,7 @@ class DarkSouls3Options(PerGameCommonOptions): enable_dlc: EnableDLCOption enable_ngp: EnableNGPOption randomize_enemies: RandomizeEnemiesOption + random_enemy_preset: RandomEnemyPresetOption randomize_mimics_with_enemies: RandomizeMimicsWithEnemiesOption randomize_small_crystal_lizards_with_enemies: RandomizeSmallCrystalLizardsWithEnemiesOption reduce_harmless_enemies: ReduceHarmlessEnemiesOption diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index b27fcd091528..8a3363a4bc37 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -1,9 +1,8 @@ # world/dark_souls_3/__init__.py from collections.abc import Sequence -import logging from collections import defaultdict +import json from typing import Dict, Set, List, Optional, TextIO, Union -import re from BaseClasses import CollectionState, MultiWorld, Region, Item, Location, LocationProgressType, Entrance, Tutorial, ItemClassification from Options import Toggle @@ -841,6 +840,8 @@ def fill_slot_data(self) -> Dict[str, object]: }, "seed": self.multiworld.seed_name, # to verify the server's multiworld "slot": self.multiworld.player_name[self.player], # to connect to server + # Reserializing here is silly, but it's easier for the offline randomizer. + "random_enemy_preset": json.dumps(self.multiworld.random_enemy_preset[self.player].value), "yhorm": ( f"{self.yhorm_location.name} {self.yhorm_location.id}" if self.yhorm_location != default_yhorm_location From 17ef3acbad041b8053dd12bb58b7c4e80d5e591f Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 4 Nov 2023 19:00:52 -0700 Subject: [PATCH 061/238] Various fixes and features --- worlds/dark_souls_3/Items.py | 15 ++++++++++----- worlds/dark_souls_3/__init__.py | 15 ++++++++++++++- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index a3d49c78deb5..9c620a1bfc58 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -137,6 +137,11 @@ class DS3ItemData(): This is automatically done for non-MISC items, but may be useful for MISC items in some cases. """ + @property + def unique(self): + """Whether this item should be unique, appearing only once in the randomizer.""" + return item.category != DS3ItemCategory.MISC or item.force_unique + def __post_init__(self): self.ap_code = self.ap_code or DS3ItemData.__item_id if not self.base_name: self.base_name = self.name @@ -148,6 +153,7 @@ def counts(self, counts: List[int]) -> Generator["DS3ItemData", None, None]: for count in counts: yield dataclasses.replace( self, + ap_code = None, name = "{} x{}".format(self.base_name, count), base_name = self.base_name, count = count, @@ -164,7 +170,6 @@ def infuse(self, infusion: Infusion) -> "DS3ItemData": # infusion/upgrade combination to that map because it's way too many items. return dataclasses.replace( self, - ap_code = self.ap_code, name = self.name, ds3_code = self.ds3_code + infusion.value, filler = False, @@ -181,7 +186,6 @@ def upgrade(self, level: int) -> "DS3ItemData": # infusion/upgrade combination to that map because it's way too many items. return dataclasses.replace( self, - ap_code = self.ap_code, name = self.name, ds3_code = self.ds3_code + level, filler = False, @@ -1005,9 +1009,9 @@ def __init__( DS3ItemData("Prism Stone", 0x40000172, DS3ItemCategory.SKIP).counts([4, 6, 10]), DS3ItemData("Binoculars", 0x40000173, DS3ItemCategory.MISC), DS3ItemData("Proof of a Concord Kept", 0x40000174, DS3ItemCategory.SKIP), + # One is needed for Leonhard's quest, others are useful for restatting. DS3ItemData("Pale Tongue", 0x40000175, DS3ItemCategory.MISC, - classification = ItemClassification.progression, - force_unique = True), # One is needed for Leonhard's quest + classification = ItemClassification.progression), DS3ItemData("Vertebra Shackle", 0x40000176, DS3ItemCategory.MISC, classification = ItemClassification.progression, force_unique = True), # Crow trade DS3ItemData("Sunlight Medal", 0x40000177, DS3ItemCategory.SKIP), @@ -1200,7 +1204,8 @@ def __init__( classification = ItemClassification.progression), DS3ItemData("Transposing Kiln", 0x40000857, DS3ItemCategory.MISC, classification = ItemClassification.useful), - DS3ItemData("Coiled Sword", 0x40000859, DS3ItemCategory.SKIP), # Useless + DS3ItemData("Coiled Sword", 0x40000859, DS3ItemCategory.KEY, + classification = ItemClassification.progression), DS3ItemData("Eyes of a Fire Keeper", 0x4000085A, DS3ItemCategory.KEY, classification = ItemClassification.useful), # Allow players to do any ending DS3ItemData("Sword of Avowal", 0x4000085B, DS3ItemCategory.KEY, diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 8a3363a4bc37..699a7daa786b 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -97,6 +97,8 @@ def generate_early(self): self.enabled_location_categories.add(DS3LocationCategory.SPELL) if self.multiworld.enable_key_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.KEY) + # No reason to let this be in the multiworld since it's necessary ten minutes into the game + self.multiworld.local_early_items[self.player]['Coiled Sword'] = 1 if self.multiworld.enable_unique_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.UNIQUE) # Make this available early just because it's fun to be able to check boss souls early. @@ -275,7 +277,7 @@ def create_items(self): item = item_dictionary[location.default_item_name] if item.category == DS3ItemCategory.SKIP: num_required_extra_items += 1 - elif item.category == DS3ItemCategory.MISC and not item.force_unique: + elif not item.unique: itempool_by_category[location.category].append(location.default_item_name) else: # For non-miscellaneous non-skip items, make sure there aren't duplicates in the @@ -410,6 +412,9 @@ def create_item(self, item: Union[str, DS3ItemData]) -> Item: if ( self.multiworld.randomize_weapon_level[self.player] != RandomizeWeaponLevelOption.option_none and data.category.upgrade_level + # Because we require the Pyromancy Flame to be available early, don't upgrade it so it + # doesn't get shuffled around by weapon smoothing. + and not data.name == "Pyromancy FLame" ): # if the user made an error and set a min higher than the max we default to the max max_5 = self.multiworld.max_levels_in_5[self.player] @@ -439,6 +444,7 @@ def get_filler_item_name(self) -> str: def set_rules(self) -> None: # Define the access rules to the entrances self._add_entrance_rule("Firelink Shrine Bell Tower", "Tower Key") + self._add_entrance_rule("High Wall of Lothric", "Coiled Sword") self._add_entrance_rule("Undead Settlement", "Small Lothric Banner") self._add_entrance_rule("Lothric Castle", "Basin of Vows") self._add_entrance_rule("Irithyll of the Boreal Valley", "Small Doll") @@ -580,6 +586,11 @@ def has_any_scroll(state): item.name != "Path of the Dragon" )) + # This particular location is bugged, and will drop two copies of whatever item is placed + # there. + if self.is_location_available("US: Young White Branch #2"): + add_item_rule(self.multiworld.get_location("US: Young White Branch #2", self.player), + lambda item: item.player == self.player and not item.unique) # Make sure the Storm Ruler is available BEFORE Yhorm the Giant if self.yhorm_location.region: @@ -829,6 +840,8 @@ def fill_slot_data(self) -> Dict[str, object]: "no_equip_load": self.multiworld.no_equip_load[self.player].value, "enable_dlc": self.multiworld.enable_dlc[self.player].value, "enable_ngp": self.multiworld.enable_ngp[self.player].value, + "smooth_soul_locations": self.multiworld.soul_locations[self.player].value == SoulLocationsOption.option_smooth, + "smooth_upgrade_locations": self.multiworld.upgrade_locations[self.player].value == UpgradeLocationsOption.option_smooth, "randomize_enemies": self.multiworld.randomize_enemies[self.player].value, "randomize_mimics_with_enemies": self.multiworld.randomize_mimics_with_enemies[self.player].value, "randomize_small_crystal_lizards_with_enemies": self.multiworld.randomize_small_crystal_lizards_with_enemies[self.player].value, From 06abc80d401788e5b0e1d6456455a6394b23546a Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 4 Nov 2023 19:58:13 -0700 Subject: [PATCH 062/238] Bug fixes --- worlds/dark_souls_3/Bosses.py | 3 ++- worlds/dark_souls_3/Items.py | 16 ++++------------ worlds/dark_souls_3/Locations.py | 8 ++++++-- worlds/dark_souls_3/__init__.py | 18 +++++++++--------- 4 files changed, 21 insertions(+), 24 deletions(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index 561804803a6e..c3508301544d 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -28,7 +28,8 @@ class DS3BossInfo: # Note: the offline 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, region = "Firelink Shrine"), + DS3BossInfo("Iudex Gundyr", 4000800, region = "Firelink Shrine", + locations = {"CA: Coiled Sword"}), DS3BossInfo("Vordt of the Boreal Valley", 3000800, region = "Undead Settlement", locations = {"HWL: Soul of Boreal Valley Vordt"}), DS3BossInfo("Curse-Rotted Greatwood", 3100800, locations = { diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 9c620a1bfc58..886b1feff1e1 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -140,7 +140,7 @@ class DS3ItemData(): @property def unique(self): """Whether this item should be unique, appearing only once in the randomizer.""" - return item.category != DS3ItemCategory.MISC or item.force_unique + return self.category != DS3ItemCategory.MISC or self.force_unique def __post_init__(self): self.ap_code = self.ap_code or DS3ItemData.__item_id @@ -194,16 +194,12 @@ def upgrade(self, level: int) -> "DS3ItemData": class DarkSouls3Item(Item): game: str = "Dark Souls III" - ds3_code: int - count: int - souls: Optional[int] - category: DS3ItemCategory - base_name: str + data: DS3ItemData @property def level(self) -> Union[int, None]: """This item's upgrade level, if it's a weapon.""" - return self.ds3_code % 100 if self.category.upgrade_level else None + return self.data.ds3_code % 100 if self.data.category.upgrade_level else None def __init__( self, @@ -211,11 +207,7 @@ def __init__( data: DS3ItemData, classification = None): super().__init__(data.name, classification or data.classification, data.ap_code, player) - self.ds3_code = data.ds3_code - self.count = data.count - self.souls = data.souls - self.category = data.category - self.base_name = data.base_name + self.data = data _vanilla_items = flatten([ diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 4195636c4f5d..2381c10c84fc 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -326,6 +326,8 @@ def get_name_to_id() -> dict: ngp = True), DS3LocationData("CA: Titanite Scale", "Titanite Scale", DS3LocationCategory.UPGRADE, miniboss = True), + DS3LocationData("CA: Coiled Sword", "Coiled Sword", DS3LocationCategory.KEY, + prominent = True, progression = True, boss = True), ], "Firelink Shrine": [ DS3LocationData("FS: Skull Ring", "Skull Ring", DS3LocationCategory.RING, @@ -1191,8 +1193,10 @@ def get_name_to_id() -> dict: drop = True, hidden = True), # Guaranteed drop from a normal-looking Elder Ghru DS3LocationData("FK: Titanite Scale", "Titanite Scale x2", DS3LocationCategory.UPGRADE, miniboss = True), # Ravenous Crystal Lizard drop - DS3LocationData("FK: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("FK: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("FK: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE, + lizard = True), DS3LocationData("FK: Heavy Gem", "Heavy Gem", DS3LocationCategory.UPGRADE, lizard = True), DS3LocationData("FK: Twinkling Titanite", "Twinkling Titanite", DS3LocationCategory.UPGRADE, diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 699a7daa786b..f09704a9b22b 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -280,8 +280,8 @@ def create_items(self): elif not item.unique: itempool_by_category[location.category].append(location.default_item_name) else: - # For non-miscellaneous non-skip items, make sure there aren't duplicates in the - # item set even if there are multiple in-game locations that provide them. + # For unique items, make sure there aren't duplicates in the item set even if there + # are multiple in-game locations that provide them. item_set = item_set_by_category[location.category] if location.default_item_name in item_set: num_required_extra_items += 1 @@ -574,7 +574,7 @@ def has_any_scroll(state): add_item_rule(self.multiworld.get_location(location.name, self.player), lambda item: ( item.player != self.player or - (item.count == 1 and not item.souls) + (item.data.count == 1 and not item.data.souls) )) elif location.drop: # TODO: I'm not sure this is precisely the rule for where this can and can't @@ -588,9 +588,9 @@ def has_any_scroll(state): # This particular location is bugged, and will drop two copies of whatever item is placed # there. - if self.is_location_available("US: Young White Branch #2"): - add_item_rule(self.multiworld.get_location("US: Young White Branch #2", self.player), - lambda item: item.player == self.player and not item.unique) + # if self.is_location_available("US: Young White Branch #2"): + # add_item_rule(self.multiworld.get_location("US: Young White Branch #2", self.player), + # lambda item: item.player == self.player and not item.data.unique) # Make sure the Storm Ruler is available BEFORE Yhorm the Giant if self.yhorm_location.region: @@ -704,7 +704,7 @@ def post_fill(self): if self.is_location_available(location) ] - # Full DarkSouls3Items, grouped by name + # All DarkSouls3Items that have been assigned anywhere, grouped by name full_items_by_name = defaultdict(list) for location in self.multiworld.get_filled_locations(): full_items_by_name[location.item.name].append(location.item) @@ -816,8 +816,8 @@ def fill_slot_data(self) -> Dict[str, object]: ap_ids_to_ds3_ids: Dict[str, int] = {} item_counts: Dict[str, int] = {} for item in our_items: - ap_ids_to_ds3_ids[str(item.code)] = item.ds3_code - if item.count != 1: item_counts[str(item.code)] = item.count + ap_ids_to_ds3_ids[str(item.code)] = item.data.ds3_code + if item.data.count != 1: item_counts[str(item.code)] = item.data.count # A map from Archipelago's location IDs to the keys the offline # randomizer uses to identify locations. From 90969758df111565059ab9ffcc034fbf6035627f Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 5 Nov 2023 13:03:24 -0800 Subject: [PATCH 063/238] Better Coiled Sword placement --- worlds/dark_souls_3/__init__.py | 63 +++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index f09704a9b22b..150492ae6094 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -97,8 +97,6 @@ def generate_early(self): self.enabled_location_categories.add(DS3LocationCategory.SPELL) if self.multiworld.enable_key_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.KEY) - # No reason to let this be in the multiworld since it's necessary ten minutes into the game - self.multiworld.local_early_items[self.player]['Coiled Sword'] = 1 if self.multiworld.enable_unique_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.UNIQUE) # Make this available early just because it's fun to be able to check boss souls early. @@ -444,7 +442,6 @@ def get_filler_item_name(self) -> str: def set_rules(self) -> None: # Define the access rules to the entrances self._add_entrance_rule("Firelink Shrine Bell Tower", "Tower Key") - self._add_entrance_rule("High Wall of Lothric", "Coiled Sword") self._add_entrance_rule("Undead Settlement", "Small Lothric Banner") self._add_entrance_rule("Lothric Castle", "Basin of Vows") self._add_entrance_rule("Irithyll of the Boreal Valley", "Small Doll") @@ -588,9 +585,9 @@ def has_any_scroll(state): # This particular location is bugged, and will drop two copies of whatever item is placed # there. - # if self.is_location_available("US: Young White Branch #2"): - # add_item_rule(self.multiworld.get_location("US: Young White Branch #2", self.player), - # lambda item: item.player == self.player and not item.data.unique) + if self.is_location_available("US: Young White Branch #2"): + add_item_rule(self.multiworld.get_location("US: Young White Branch #2", self.player), + lambda item: item.player == self.player and not item.data.unique) # Make sure the Storm Ruler is available BEFORE Yhorm the Giant if self.yhorm_location.region: @@ -648,26 +645,48 @@ def write_spoiler(self, spoiler_handle: TextIO) -> None: def pre_fill(self) -> None: + # Don't place this in the multiworld because it's necessary almost immediately, and don't + # mark it as a blocker for HWL because having a miniscule Sphere 1 screws with progression + # balancing. + self._fill_local_item("Coiled Sword", {"Cemetery of Ash", "Firelink Shrine"}) + # If upgrade smoothing is enabled, make sure one raw gem is available early for SL1 players if self.multiworld.upgrade_locations[self.player] == UpgradeLocationsOption.option_smooth: - candidate_locations = [ - self.multiworld.get_location(location.name, self.player) - for region in ["Cemetery of Ash", "Firelink Shrine", "High Wall of Lothric"] - for location in location_tables[region] - if self.is_location_available(location) - and not location.missable and not location.conditional - ] - location = self.multiworld.random.choice([ - location for location in candidate_locations - if not location.item and location.progress_type != LocationProgressType.EXCLUDED - ]) - raw_gem = next( + self._fill_local_item("Raw Gem", { + "Cemetery of Ash", + "Firelink Shrine", + "High Wall of Lothric" + }) + + + def _fill_local_item(self, name: str, regions: Set[str]) -> None: + """Chooses a valid location for the item with the given name and places it there. + + This always chooses a local location among the given regions. + """ + item = next( + ( item for item in self.multiworld.itempool - if item.player == self.player and item.name == "Raw Gem" - ) - location.place_locked_item(raw_gem) - self.multiworld.itempool.remove(raw_gem) + if item.player == self.player and item.name == name + ), + None + ) + if not item: return + candidate_locations = [ + self.multiworld.get_location(location.name, self.player) + for region in regions + for location in location_tables[region] + if self.is_location_available(location) + and not location.missable and not location.conditional + ] + location = self.multiworld.random.choice([ + location for location in candidate_locations + if not location.item and location.progress_type != LocationProgressType.EXCLUDED + and location.item_rule(item) + ]) + location.place_locked_item(item) + self.multiworld.itempool.remove(item) def post_fill(self): """If item smoothing is enabled, rearrange items so they scale up smoothly through the run. From 9c08a38878ac813d9a2450a49b6c815a31db48d0 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 5 Nov 2023 13:27:25 -0800 Subject: [PATCH 064/238] Structure DarkSouls3Location more like DarkSouls3Item --- worlds/dark_souls_3/Locations.py | 107 +++++-------------------------- worlds/dark_souls_3/__init__.py | 28 ++++---- 2 files changed, 31 insertions(+), 104 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 2381c10c84fc..ae3972afa0fd 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1,5 +1,5 @@ from enum import IntEnum -from typing import Optional, Dict, List, Set +from typing import ClassVar, Optional, Dict, List, Set from dataclasses import dataclass from BaseClasses import Location, LocationProgressType, Region @@ -72,6 +72,9 @@ class DS3LocationCategory(IntEnum): @dataclass class DS3LocationData: + __location_id: ClassVar[int] = 100000 + """The next location ID to use when creating location data.""" + name: str """The name of this location according to Archipelago. @@ -83,6 +86,9 @@ class DS3LocationData: category: DS3LocationCategory """The category into which this location falls.""" + ap_code: int = None + """Archipelago's internal ID for this location (also known as its "address").""" + region_value: int = 0 """The relative value of items in this location's region. @@ -194,6 +200,8 @@ class DS3LocationData: """ def __post_init__(self): + self.ap_code = self.ap_code or DS3LocationData.__location_id + DS3LocationData.__location_id += 1 if self.miniboss or self.mimic or self.lizard or self.hostile_npc: self.drop = True def location_groups(self) -> List[str]: @@ -218,102 +226,17 @@ def location_groups(self) -> List[str]: class DarkSouls3Location(Location): game: str = "Dark Souls III" - category: DS3LocationCategory - default_item_name: str - offline: Optional[str] = None - conditional: bool = False - region_value: int + data: DS3LocationData def __init__( self, - player: int, - name: str, - category: DS3LocationCategory, - default_item_name: str, - address: Optional[int] = None, - parent: Optional[Region] = None): - super().__init__(player, name, address, parent) - self.default_item_name = default_item_name - self.category = category - - @staticmethod - def from_data( player: int, data: DS3LocationData, - address: Optional[int] = None, - parent: Optional[Region] = None) -> "DarkSouls3Location": - location = DarkSouls3Location( - player, - data.name, - data.category, - data.default_item_name, - address, - parent - ) - location.offline = data.offline - location.conditional = data.conditional - location.region_value = data.region_value - if data.missable: - location.progress_type = LocationProgressType.EXCLUDED - return location - - - @staticmethod - def get_name_to_id() -> dict: - base_id = 100000 - table_offset = 150 - - table_order = [ - "Cemetery of Ash", - "Firelink Shrine", - "Firelink Shrine Bell Tower", - "High Wall of Lothric", - "Undead Settlement", - "Road of Sacrifices", - "Cathedral of the Deep", - "Farron Keep", - "Catacombs of Carthus", - "Smouldering Lake", - "Irithyll of the Boreal Valley", - "Irithyll Dungeon", - "Profaned Capital", - "Anor Londo", - "Lothric Castle", - "Consumed King's Garden", - "Grand Archives", - "Untended Graves", - "Archdragon Peak", - "Kiln of the First Flame", - - "Painted World of Ariandel (Before Contraption)", - "Painted World of Ariandel (After Contraption)", - "Dreg Heap", - "Ringed City", - - "Greirat's Shop", - "Karla's Shop", - ] - - if len(location_tables) != len(table_order): - for location in location_tables.keys(): - if location not in table_order: - raise Exception("Location table is missing location {}".format(location)) - for location in table_order: - if location not in location_tables: - raise Exception("Table order is missing location {}".format(location)) - - output = {} - for i, region_name in enumerate(table_order): - if len(location_tables[region_name]) > table_offset: - raise Exception("The location table for {} has {} entries, that is more than {} entries".format( - region_name, - len(location_tables[region_name]), - table_offset, - )) - - output.update({location_data.name: id for id, location_data in enumerate(location_tables[region_name], base_id + (table_offset * i))}) - - return output + event: bool = False, + parent: Optional[Region] = None): + super().__init__(player, data.name, None if event else data.ap_code, parent) + self.data = data + if data.missable: self.progress_type = LocationProgressType.EXCLUDED location_tables = { diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 150492ae6094..f5ea2e19233c 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -56,7 +56,11 @@ class DarkSouls3World(World): enabled_location_categories: Set[DS3LocationCategory] required_client_version = (0, 4, 2) item_name_to_id = {data.name: data.ap_code for data in item_dictionary.values()} - location_name_to_id = DarkSouls3Location.get_name_to_id() + location_name_to_id = { + location.name: location.ap_code + for locations in location_tables.values() + for location in locations + } location_name_groups = location_name_groups item_name_groups = { "Cinders": { @@ -229,7 +233,7 @@ def create_region(self, region_name, location_table) -> Region: for location in location_table: if self.is_location_available(location): - new_location = DarkSouls3Location.from_data( + new_location = DarkSouls3Location( self.player, location, self.location_name_to_id[location.name], @@ -241,7 +245,7 @@ def create_region(self, region_name, location_table) -> Region: if event_item.classification != ItemClassification.progression: continue - new_location = DarkSouls3Location.from_data( + new_location = DarkSouls3Location( self.player, location, parent = new_region @@ -272,20 +276,20 @@ def create_items(self): if not self.is_location_available(location.name): raise Exception("DS3 generation bug: Added an unavailable location.") - item = item_dictionary[location.default_item_name] + item = item_dictionary[location.data.default_item_name] if item.category == DS3ItemCategory.SKIP: num_required_extra_items += 1 elif not item.unique: - itempool_by_category[location.category].append(location.default_item_name) + itempool_by_category[location.data.category].append(location.data.default_item_name) else: # For unique items, make sure there aren't duplicates in the item set even if there # are multiple in-game locations that provide them. - item_set = item_set_by_category[location.category] - if location.default_item_name in item_set: + item_set = item_set_by_category[location.data.category] + if location.data.default_item_name in item_set: num_required_extra_items += 1 else: - item_set.add(location.default_item_name) - itempool_by_category[location.category].append(location.default_item_name) + item_set.add(location.data.default_item_name) + itempool_by_category[location.data.category].append(location.data.default_item_name) # Replace each item category with a random sample of items of those types if self.multiworld.pool_type[self.player] == PoolTypeOption.option_various: @@ -749,7 +753,7 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: offworld = [loc for loc in locations if loc.game != "Dark Souls III"] self.multiworld.random.shuffle(offworld) onworld = sorted((loc for loc in locations if loc.game == "Dark Souls III"), - key=lambda loc: loc.region_value) + key=lambda loc: loc.data.region_value) # Give offworld regions the last (best) items within a given sphere for location in onworld + offworld: @@ -844,8 +848,8 @@ def fill_slot_data(self) -> Dict[str, object]: for location in self.multiworld.get_filled_locations(): # Skip events and only look at this world's locations if (location.address is not None and location.item.code is not None - and location.player == self.player and location.offline): - location_ids_to_keys[location.address] = location.offline + and location.player == self.player and location.data.offline): + location_ids_to_keys[location.address] = location.data.offline slot_data = { "options": { From 1bca41398422b32ecea40655622f2fe669101cfe Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 5 Nov 2023 14:04:24 -0800 Subject: [PATCH 065/238] Add events to make DS3's spheres more even --- worlds/dark_souls_3/Items.py | 8 +++++++- worlds/dark_souls_3/Locations.py | 34 ++++++++++++++++++++++++++------ worlds/dark_souls_3/__init__.py | 19 +++++++++++++++--- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 886b1feff1e1..37abc66e801d 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -95,7 +95,7 @@ class DS3ItemData(): """The next item ID to use when creating item data.""" name: str - ds3_code: int + ds3_code: Optional[int] category: DS3ItemCategory base_name: Optional[str] = None @@ -209,6 +209,12 @@ def __init__( super().__init__(data.name, classification or data.classification, data.ap_code, player) self.data = data + @staticmethod + def event(name: str, player: int) -> "DarkSouls3Item": + data = DS3ItemData(name, None, DS3ItemCategory.SKIP, classification = ItemClassification.progression) + data.ap_code = None + return DarkSouls3Item(player, data) + _vanilla_items = flatten([ # Ammunition diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index ae3972afa0fd..527403cacae6 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -52,7 +52,14 @@ class DS3LocationCategory(IntEnum): KEY = 5 MISC = 6 HEALTH = 7 + EVENT = 8 + """A special location that's achieved as soon as it's accessible. + + These are used to mark major region transitions that aren't otherwise gated by items so that + progression balancing and item smoothing are better able to track how deep in the game regions + are. + """ SOUL = 9 """The original location of a soul item.""" @@ -80,8 +87,11 @@ class DS3LocationData: This needs to be unique within this world.""" - default_item_name: str - """The name of the item that appears by default in this location.""" + default_item_name: Optional[str] + """The name of the item that appears by default in this location. + + This should only ever by None for DS3LocationCategory.EVENT locations. + """ category: DS3LocationCategory """The category into which this location falls.""" @@ -200,8 +210,9 @@ class DS3LocationData: """ def __post_init__(self): - self.ap_code = self.ap_code or DS3LocationData.__location_id - DS3LocationData.__location_id += 1 + if self.category != DS3LocationCategory.EVENT: + self.ap_code = self.ap_code or DS3LocationData.__location_id + DS3LocationData.__location_id += 1 if self.miniboss or self.mimic or self.lizard or self.hostile_npc: self.drop = True def location_groups(self) -> List[str]: @@ -637,6 +648,7 @@ def __init__( missable = True, boss = True, shop = True), DS3LocationData("US: Arstor's Spear", "Arstor's Spear", DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("US -> RS", None, DS3LocationCategory.EVENT), # Yoel/Yuria of Londor DS3LocationData("US: Soul Arrow", "Soul Arrow", DS3LocationCategory.SPELL, @@ -871,6 +883,8 @@ def __init__( missable = True, boss = True, shop = True), DS3LocationData("RS: Wolf Knight's Greatsword", "Wolf Knight's Greatsword", DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("RS -> CD", None, DS3LocationCategory.EVENT), + DS3LocationData("RS -> FK", None, DS3LocationCategory.EVENT), # Shrine Handmaid after killing Crystal Sage DS3LocationData("RS: Sage's Big Hat", "Sage's Big Hat", DS3LocationCategory.ARMOR, @@ -1000,6 +1014,7 @@ def __init__( missable = True, boss = True, shop = True), DS3LocationData("CD: Deep Soul", "Deep Soul", DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + DS3LocationData("CD -> PW1", None, DS3LocationCategory.EVENT), # Longfinger Kirk drops DS3LocationData("CD: Barbed Straight Sword", "Barbed Straight Sword", DS3LocationCategory.WEAPON, @@ -1133,6 +1148,7 @@ def __init__( missable = True, boss = True, shop = True), DS3LocationData("FK: Boulder Heave", "Boulder Heave", DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + DS3LocationData("FK -> CC", None, DS3LocationCategory.EVENT), # Hawkwood after killing Abyss Watchers DS3LocationData("RS: Farron Ring", "Farron Ring", DS3LocationCategory.RING, @@ -1421,6 +1437,8 @@ def __init__( missable = True, boss = True, shop = True), DS3LocationData("IBV: Profaned Greatsword", "Profaned Greatsword", DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("IBV -> AL", None, DS3LocationCategory.EVENT), + DS3LocationData("IBV -> ID", None, DS3LocationCategory.EVENT), # Anri of Astora DS3LocationData("IBV: Anri's Straight Sword", "Anri's Straight Sword", DS3LocationCategory.WEAPON, @@ -1911,6 +1929,7 @@ def __init__( missable = True, boss = True, shop = True), DS3LocationData("CKG: White Dragon Breath", "White Dragon Breath", DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + DS3LocationData("CKG -> UG", None, DS3LocationCategory.EVENT), ], "Grand Archives": [ # At the bottom of the shortcut elevator right outside the Twin Princes fight. Requires sending the elevator up to the top from the middle, and then riding the lower elevator down. @@ -2386,6 +2405,7 @@ def __init__( missable = True, boss = True, shop = True), DS3LocationData("PW2: Titanite Slab (Corvian)", "Titanite Slab", DS3LocationCategory.UPGRADE, offline = '11,0:50006540::', missable = True, npc = True), # Corvian Settler (quest) + DS3LocationData("PW2 -> DH", None, DS3LocationCategory.EVENT), # Shrine Handmaid after killing Sister Friede DS3LocationData("PW2: Ordained Hood", "Ordained Hood", DS3LocationCategory.ARMOR, @@ -2760,13 +2780,15 @@ def __init__( location_dictionary.update({location_data.name: location_data for location_data in location_table}) for location_data in location_table: - for group_name in location_data.location_groups(): - location_name_groups[group_name].add(location_data.name) + if location_data.category != DS3LocationCategory.EVENT: + for group_name in location_data.location_groups(): + location_name_groups[group_name].add(location_data.name) # Allow entire locations to be added to location sets. if not location_name.endswith(" Shop"): location_name_groups[location_name] = frozenset([ location_data.name for location_data in location_table + if location_data.category != DS3LocationCategory.EVENT ]) location_name_groups["Painted World of Ariandel"] = ( diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index f5ea2e19233c..05fb21ccdef2 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -241,7 +241,10 @@ def create_region(self, region_name, location_table) -> Region: ) else: # Replace non-randomized progression items with events - event_item = self.create_item(location.default_item_name) + event_item = ( + self.create_item(location.default_item_name) if location.default_item_name + else DarkSouls3Item.event(location.name, self.player) + ) if event_item.classification != ItemClassification.progression: continue @@ -447,8 +450,15 @@ def set_rules(self) -> None: # Define the access rules to the entrances self._add_entrance_rule("Firelink Shrine Bell Tower", "Tower Key") self._add_entrance_rule("Undead Settlement", "Small Lothric Banner") + self._add_entrance_rule("Road of Sacrifices", "US -> RS") + self._add_entrance_rule("Cathedral of the Deep", "RS -> CD") + self._add_entrance_rule("Farron Keep", "RS -> FK") + self._add_entrance_rule("Catacombs of Carthus", "FK -> CC") + self._add_entrance_rule("Irithyll Dungeon", "IBV -> ID") self._add_entrance_rule("Lothric Castle", "Basin of Vows") + self._add_entrance_rule("Untended Graves", "CKG -> UG") self._add_entrance_rule("Irithyll of the Boreal Valley", "Small Doll") + self._add_entrance_rule("Anor Londo", "IBV -> AL") self._add_entrance_rule("Archdragon Peak", "Path of the Dragon") self._add_entrance_rule("Grand Archives", "Grand Archives Key") self._add_entrance_rule( @@ -496,8 +506,10 @@ def set_rules(self) -> None: # DLC Access Rules Below if self.multiworld.enable_dlc[self.player]: - self._add_entrance_rule("Ringed City", "Small Envoy Banner") + self._add_entrance_rule("Painted World of Ariandel (Before Contraption)", "CD -> PW1") self._add_entrance_rule("Painted World of Ariandel (After Contraption)", "Contraption Key") + self._add_entrance_rule("Dreg Heap", "PW2 -> DH") + self._add_entrance_rule("Ringed City", "Small Envoy Banner") if self.multiworld.late_dlc[self.player]: self._add_entrance_rule("Painted World of Ariandel (After Contraption)", "Small Doll") @@ -623,7 +635,8 @@ def _add_entrance_rule(self, region: str, rule: Union[CollectionRule, str]) -> N assert region in location_tables if not any(region == reg.name for reg in self.multiworld.regions): return if isinstance(rule, str): - assert item_dictionary[rule].classification == ItemClassification.progression + if " -> " not in rule: + assert item_dictionary[rule].classification == ItemClassification.progression rule = lambda state, item=rule: state.has(item, self.player) add_rule(self.multiworld.get_entrance("Go To " + region, self.player), rule) From 0553fbea60d0e3dc1a97207c81ddcc5252f91015 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 10 Nov 2023 00:14:20 -0800 Subject: [PATCH 066/238] Restructure locations to work like items do now --- worlds/dark_souls_3/Locations.py | 6 +++--- worlds/dark_souls_3/__init__.py | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 527403cacae6..2723913d2a21 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -243,8 +243,8 @@ def __init__( self, player: int, data: DS3LocationData, - event: bool = False, - parent: Optional[Region] = None): + parent: Optional[Region] = None, + event: bool = False): super().__init__(player, data.name, None if event else data.ap_code, parent) self.data = data if data.missable: self.progress_type = LocationProgressType.EXCLUDED @@ -1600,7 +1600,7 @@ def __init__( lizard = True), DS3LocationData("PC: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("US: Siegbräu", "Siegbräu", DS3LocationCategory.MISC, + DS3LocationData("PC: Siegbräu", "Siegbräu", DS3LocationCategory.MISC, missable = True, npc = True), DS3LocationData("PC: Yhorm's Great Machete", "Yhorm's Great Machete", DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 05fb21ccdef2..268c2263c675 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -236,7 +236,6 @@ def create_region(self, region_name, location_table) -> Region: new_location = DarkSouls3Location( self.player, location, - self.location_name_to_id[location.name], new_region ) else: @@ -251,7 +250,8 @@ def create_region(self, region_name, location_table) -> Region: new_location = DarkSouls3Location( self.player, location, - parent = new_region + parent = new_region, + event = True, ) event_item.code = None new_location.place_locked_item(event_item) @@ -858,10 +858,10 @@ def fill_slot_data(self) -> Dict[str, object]: # A map from Archipelago's location IDs to the keys the offline # randomizer uses to identify locations. location_ids_to_keys: Dict[str, str] = {} - for location in self.multiworld.get_filled_locations(): + for location in self.multiworld.get_filled_locations(self.player): # Skip events and only look at this world's locations if (location.address is not None and location.item.code is not None - and location.player == self.player and location.data.offline): + and location.data.offline): location_ids_to_keys[location.address] = location.data.offline slot_data = { From 9333537da56513e483e30a0cb3b7a52b49fec632 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 10 Nov 2023 01:47:55 -0800 Subject: [PATCH 067/238] Add rules for more missable locations --- worlds/dark_souls_3/Locations.py | 101 +++++++++++++------------ worlds/dark_souls_3/__init__.py | 124 ++++++++++++++++++++----------- 2 files changed, 134 insertions(+), 91 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 2723913d2a21..a8b25e7f4ee8 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -282,9 +282,9 @@ def __init__( DS3LocationData("FS: Wolf Ring+2", "Wolf Ring+2", DS3LocationCategory.RING, ngp = True), DS3LocationData("FS: Cracked Red Eye Orb", "Cracked Red Eye Orb x5", DS3LocationCategory.UNIQUE, - missable = True, npc = True, conditional = True), # Leonhard (quest) + missable = True, npc = True), # Leonhard (quest) DS3LocationData("FS: Lift Chamber Key", "Lift Chamber Key", DS3LocationCategory.KEY, - progression = True, npc = True, key = True, drop = True, conditional = True), # Leonhard (kill or quest) + missable = True, npc = True, key = True, drop = True, ), # Leonhard (kill or quest) # Shrine Handmaid shop DS3LocationData("FS: White Sign Soapstone", "White Sign Soapstone", DS3LocationCategory.UNIQUE, @@ -312,7 +312,7 @@ def __init__( DS3LocationData("FS: Life Ring", "Life Ring", DS3LocationCategory.RING, shop = True, conditional = True), DS3LocationData("FS: Hidden Blessing #2", "Hidden Blessing", DS3LocationCategory.MISC, - missable = True, shop = True, conditional = True), # only if you say where the ashes were found + missable = True, shop = True), # only if you say where the ashes were found # Paladin's Ashes DS3LocationData("FS: Lloyd's Shield Ring", "Lloyd's Shield Ring", DS3LocationCategory.RING, shop = True, conditional = True), @@ -614,7 +614,7 @@ def __init__( missable = True), # requires projectile DS3LocationData("US: Flame Stoneplate Ring", "Flame Stoneplate Ring", DS3LocationCategory.RING), DS3LocationData("US: Red and White Shield", "Red and White Shield", DS3LocationCategory.SHIELD, - offline = "02,0:53100740::"), + offline = "02,0:53100740::", missable = True), # requires projectile), DS3LocationData("US: Small Leather Shield", "Small Leather Shield", DS3LocationCategory.SHIELD), DS3LocationData("US: Pale Tongue", "Pale Tongue", DS3LocationCategory.MISC), DS3LocationData("US: Large Soul of a Deserted Corpse #6", "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), @@ -684,23 +684,23 @@ def __init__( npc = True, shop = True), # These are missable if you kill Cornyx before giving him the right tomes. DS3LocationData("US: Poison Mist", "Poison Mist", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("US: Fire Orb", "Fire Orb", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("US: Profuse Sweat", "Profuse Sweat", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("US: Bursting Fireball", "Bursting Fireball", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("US: Acid Surge", "Acid Surge", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("US: Carthus Flame Arc", "Carthus Flame Arc", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("US: Carthus Beacon", "Carthus Beacon", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("US: Great Chaos Fire Orb", "Great Chaos Fire Orb", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("US: Chaos Storm", "Chaos Storm", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), # Irina of Carim # These aren't in their own location because you don't actually need the Grave Key to access @@ -716,28 +716,17 @@ def __init__( DS3LocationData("US: Homeward", "Homeward", DS3LocationCategory.SPELL, npc = True, shop = True), DS3LocationData("US: Med Heal", "Med Heal", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("US: Tears of Denial", "Tears of Denial", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("US: Force", "Force", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("US: Bountiful Light", "Bountiful Light", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("US: Magic Barrier", "Magic Barrier", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("US: Blessed Weapon", "Blessed Weapon", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), - # You can also get these from Karla - DS3LocationData("US: Gnaw", "Gnaw", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), - DS3LocationData("US: Deep Protection", "Deep Protection", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), - DS3LocationData("US: Vow of Silence", "Vow of Silence", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), - DS3LocationData("US: Dark Blade", "Dark Blade", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), - DS3LocationData("US: Dead Again", "Dead Again", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), ], "Road of Sacrifices": [ DS3LocationData("RS: Soul of a Crystal Sage", "Soul of a Crystal Sage", DS3LocationCategory.SOUL, @@ -844,31 +833,31 @@ def __init__( DS3LocationData("RS: Farron Flashsword", "Farron Flashsword", DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), DS3LocationData("RS: Pestilent Mist", "Pestilent Mist", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("RS: Great Farron Dart", "Great Farron Dart", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("RS: Farron Hail", "Farron Hail", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("RS: Homing Soulmass", "Homing Soulmass", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("RS: Soul Spear", "Soul Spear", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("RS: Homing Crystal Soulmass", "Homing Crystal Soulmass", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("RS: Crystal Soul Spear", "Crystal Soul Spear", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("RS: Crystal Magic Weapon", "Crystal Magic Weapon", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("RS: Cast Light", "Cast Light", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("RS: Twisted Wall of Light", "Twisted Wall of Light", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("RS: Hidden Weapon", "Hidden Weapon", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("RS: Hidden Body", "Hidden Body", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("RS: Repair", "Repair", DS3LocationCategory.SPELL, - conditional = True, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("RS: Clandestine Coat", "Clandestine Coat", DS3LocationCategory.ARMOR, missable = True, npc = True, shop = True), # Shrine Handmaid with Orbeck's Ashes + reload DS3LocationData("RS: Young Dragon Ring", "Young Dragon Ring", DS3LocationCategory.RING, @@ -879,10 +868,6 @@ def __init__( missable = True, boss = True, shop = True), DS3LocationData("RS: Crystal Hail", "Crystal Hail", DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), - DS3LocationData("RS: Farron Greatsword", "Farron Greatsword", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("RS: Wolf Knight's Greatsword", "Wolf Knight's Greatsword", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), DS3LocationData("RS -> CD", None, DS3LocationCategory.EVENT), DS3LocationData("RS -> FK", None, DS3LocationCategory.EVENT), @@ -1148,6 +1133,10 @@ def __init__( missable = True, boss = True, shop = True), DS3LocationData("FK: Boulder Heave", "Boulder Heave", DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + DS3LocationData("FK: Farron Greatsword", "Farron Greatsword", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), + DS3LocationData("FK: Wolf Knight's Greatsword", "Wolf Knight's Greatsword", DS3LocationCategory.WEAPON, + missable = True, boss = True, shop = True), DS3LocationData("FK -> CC", None, DS3LocationCategory.EVENT), # Hawkwood after killing Abyss Watchers @@ -2108,9 +2097,9 @@ def __init__( ngp = True, hidden = True), DS3LocationData("UG: Hornet Ring", "Hornet Ring", DS3LocationCategory.RING, hidden = True, conditional = True), - DS3LocationData("FS: Gundyr's Halberd", "Gundyr's Halberd", DS3LocationCategory.WEAPON, + DS3LocationData("UG: Gundyr's Halberd", "Gundyr's Halberd", DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), - DS3LocationData("FS: Prisoner's Chain", "Prisoner's Chain", DS3LocationCategory.RING, + DS3LocationData("UG: Prisoner's Chain", "Prisoner's Chain", DS3LocationCategory.RING, missable = True, boss = True, shop = True), # Yuria shop, or Shrine Handmaiden with Hollow's Ashes @@ -2722,6 +2711,20 @@ def __init__( missable = True, shop = True, npc = True), DS3LocationData("Karla: Black Fire Orb", "Black Fire Orb", DS3LocationCategory.SPELL, missable = True, shop = True, npc = True), + + # Deep Braille Divine Tome. This can also be given to Irina but it'll fail her quest + DS3LocationData("Karla: Gnaw", "Gnaw", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("Karla: Deep Protection", "Deep Protection", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + + # Londor Braille Divine Tome. This can also be given to Irina but it'll fail her quest + DS3LocationData("Karla: Vow of Silence", "Vow of Silence", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("Karla: Dark Blade", "Dark Blade", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("Karla: Dead Again", "Dead Again", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), # Drops on death. Missable because the player would have to decide between killing her or # seeing everything she sells. diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 268c2263c675..0a47155bb070 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -468,39 +468,6 @@ def set_rules(self) -> None: state.has("Cinders of a Lord - Aldrich", self.player) and state.has("Cinders of a Lord - Lothric Prince", self.player)) - ashes = { - "Mortician's Ashes": ["Alluring Skull", "Ember (Mortician)", "Grave Key"], - "Dreamchaser's Ashes": ["Life Ring"], - "Paladin's Ashes": ["Lloyd's Shield Ring"], - "Grave Warden's Ashes": ["Ember (Grave Warden)"], - "Prisoner Chief's Ashes": [ - "Karla's Pointed Hat", - "Karla's Coat", - "Karla's Gloves", - "Karla's Trousers", - ], - "Xanthous Ashes": ["Xanthous Overcoat", "Xanthous Gloves", "Xanthous Trousers"], - "Dragon Chaser's Ashes": ["Ember (Dragon Chaser)"], - "Easterner's Ashes": [ - "Washing Pole", - "Eastern Helm", - "Eastern Armor", - "Eastern Gauntlets", - "Eastern Leggings", - "Wood Grain Ring", - ], - "Captain's Ashes": [ - "Millwood Knight Helm", - "Millwood Knight Armor", - "Millwood Knight Gauntlets", - "Millwood Knight Leggings", - "Refined Gem", - ] - } - for ash, items in ashes.items(): - for item in items: - self._add_location_rule("FS: " + item, ash) - if self.multiworld.late_basin_of_vows[self.player] == Toggle.option_true: self._add_entrance_rule("Lothric Castle", "Small Lothric Banner") @@ -521,8 +488,79 @@ def set_rules(self) -> None: self._add_location_rule("UG: Hornet Ring", "Small Lothric Banner") self._add_entrance_rule("Karla's Shop", "Jailer's Key Ring") - # List crow trades even though they never contain progression items so that the game knows - # what sphere they're in. This is especially useful for item smoothing. + # Ashes + self._add_location_rule(["FS: Alluring Skull", "FS: Ember (Mortician)", "FS: Grave Key"], + "Mortician's Ashes") + self._add_location_rule(["FS: Life Ring", "FS: Hidden Blessing #2"], "Dreamchaser's Ashes") + self._add_location_rule("FS: Lloyd's Shield Ring", "Paladin's Ashes") + self._add_location_rule("FS: Ember (Grave Warden)", "Grave Warden's Ashes") + self._add_location_rule([ + "FS: Karla's Pointed Hat", "FS: Karla's Coat", "FS: Karla's Gloves", + "FS: Karla's Trousers" + ], "Prisoner Chief's Ashes") + self._add_location_rule([ + "FS: Xanthous Overcoat", "FS: Xanthous Gloves", "FS: Xanthous Trousers" + ], "Xanthous Ashes") + self._add_location_rule("Ember (Dragon Chaser)", "Dragon Chaser's Ashes") + self._add_location_rule([ + "FS: Washing Pole", "FS: Eastern Helm", "FS: Eastern Armor", "FS: Eastern Gauntlets", + "FS: Eastern Leggings", "FS: Wood Grain Ring", + ], "Easterner's Ashes") + self._add_location_rule([ + "FS: Millwood Knight Helm", "FS: Millwood Knight Armor", + "FS: Millwood Knight Gauntlets", "FS: Millwood Knight Leggings", "FS: Refined Gem", + ], "Captain's Ashes") + + # List missable locations even though they never contain progression items so that the game + # knows what sphere they're in. This is especially useful for item smoothing. We could add + # rules for boss transposition items as well, but then we couldn't freely reorder boss soul + # locations for smoothing. + + self._add_location_rule("FS: Lift Chamber Key", "Pale Tongue") + self._add_location_rule(["AP: Twinkling Dragon Head Stone", "AP: Hawkwood's Swordgrass"], + "Twinkling Dragon Torso Stone") + + # Shop unlocks + self._add_location_rule([ + "US: Poison Mist", "US: Fire Orb", "US: Profuse Sweat", "US: Bursting Fireball" + ], "Great Swamp Pyromancy Tome") + self._add_location_rule(["US: Acid Surge", "US: Carthus Flame Arc", "US: Carthus Beacon"], + "Carthus Pyromancy Tome") + self._add_location_rule(["US: Great Chaos Fire Orb", "US: Chaos Storm"], + "Izalith Pyromancy Tome") + self._add_location_rule(["US: Med Heal", "US: Tears of Denial", "US: Force"], + "Braille Divine Tome of Carim") + self._add_location_rule(["US: Bountiful Light", "US: Magic Barrier", "US: Blessed Weapon"], + "Braille Divine Tome of Lothric") + self._add_location_rule(["RS: Great Farron Dart", "RS: Farron Hail"], "Sage's Scroll") + self._add_location_rule([ + "RS: Cast Light", "RS: Repair", "RS: Hidden Weapon", "RS: Hidden Body", + "RS: Twisted Wall of Light" + ], "Golden Scroll") + self._add_location_rule(["RS: Homing Soulmass", "RS: Soul Spear"], "Logan's Scroll") + self._add_location_rule([ + "RS: Homing Crystal Soulmass", "RS: Crystal Soul Spear", "RS: Crystal Magic Weapon" + ], "Logan's Scroll") + self._add_location_rule([ + "Greirat: Divine Blessing #1", "Greirat: Ember #2", "Greirat: Divine Blessing #2", + "Greirat: Hidden Blessing", "Greirat: Titanite Scale", "Greirat: Twinkling Titanite", + "Greirat: Ember #3" + ], "Loretta's Bone") + self._add_location_rule([ + "Greirat: Divine Blessing #2", "Greirat: Hidden Blessing", "Greirat: Titanite Scale", + "Greirat: Twinkling Titanite", "Greirat: Ember #3" + ], "Small Doll") + self._add_location_rule("Greirat: Ember #3", "Grand Archives Key") + self._add_location_rule(["Karla: Firestorm", "Karla: Rapport", "Karla: Fire Whip"], + "Quelana Pyromancy Tome") + self._add_location_rule(["Karla: Black Flame", "Karla: Black Fire Orb"], + "Grave Warden Pyromancy Tome") + self._add_location_rule(["Karla: Gnaw", "Karla: Deep Protection"], + "Deep Braille Divine Tome") + self._add_location_rule(["Karla: Vow of Silence", "Karla: Dark Blade", "Karla: Dead Again"], + "Londor Braille Divine Tome") + + # Crow items self._add_location_rule("FSBT: Ring of Sacrifice", "Loretta's Bone") self._add_location_rule("FSBT: Titanite Scale #1", "Avelyn") self._add_location_rule("FSBT: Titanite Slab", "Coiled Sword Fragment") @@ -618,16 +656,18 @@ def has_any_scroll(state): state.has("Cinders of a Lord - Lothric Prince", self.player) - def _add_location_rule(self, location: str, rule: Union[CollectionRule, str]) -> None: + def _add_location_rule(self, location: Union[str, List[str]], rule: Union[CollectionRule, str]) -> None: """Sets a rule for the given location if it that location is randomized. The rule can just be a single item/event name as well as an explicit rule lambda. """ - if not self.is_location_available(location): return - if isinstance(rule, str): - assert item_dictionary[rule].classification == ItemClassification.progression - rule = lambda state, item=rule: state.has(item, self.player) - add_rule(self.multiworld.get_location(location, self.player), rule) + locations = location if type(location) is list else [location] + for location in locations: + if not self.is_location_available(location): return + if isinstance(rule, str): + assert item_dictionary[rule].classification == ItemClassification.progression + rule = lambda state, item=rule: state.has(item, self.player) + add_rule(self.multiworld.get_location(location, self.player), rule) def _add_entrance_rule(self, region: str, rule: Union[CollectionRule, str]) -> None: @@ -695,7 +735,7 @@ def _fill_local_item(self, name: str, regions: Set[str]) -> None: for region in regions for location in location_tables[region] if self.is_location_available(location) - and not location.missable and not location.conditional + and not location.missable ] location = self.multiworld.random.choice([ location for location in candidate_locations From c7d9d6cbf6f80a308104ef6ac476864dec513cf4 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 10 Nov 2023 01:49:18 -0800 Subject: [PATCH 068/238] Don't add two Storm Rulers --- worlds/dark_souls_3/Locations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index a8b25e7f4ee8..439a4dbdb35f 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1597,7 +1597,7 @@ def __init__( missable = True, boss = True, shop = True), # Siegward drops (kill or quest) - DS3LocationData("PC: Storm Ruler (Siegward)", "Storm Ruler", DS3LocationCategory.WEAPON, + DS3LocationData("PC: Storm Ruler (Siegward)", "Storm Ruler", DS3LocationCategory.KEY, offline = '02,0:50006218::', missable = True, drop = True, npc = True), DS3LocationData("PC: Pierce Shield", "Pierce Shield", DS3LocationCategory.SHIELD, missable = True, drop = True, npc = True), From b44f574eab5de7b6344684d0552b0a8f7221b2c5 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 10 Nov 2023 01:52:31 -0800 Subject: [PATCH 069/238] Place Hawk Ring in Farron Keep --- worlds/dark_souls_3/Locations.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 439a4dbdb35f..a4abf19e5a99 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -527,8 +527,6 @@ def __init__( offline = '02,0:50006141::', missable = True, npc = True), DS3LocationData("US: Tower Key", "Tower Key", DS3LocationCategory.KEY, missable = True, npc = True, key = True), - DS3LocationData("US: Hawk Ring", "Hawk Ring", DS3LocationCategory.RING, - drop = True, npc = True), # Giant archer (kill or quest) DS3LocationData("US: Flynn's Ring", "Flynn's Ring", DS3LocationCategory.RING), DS3LocationData("US: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), DS3LocationData("US: Alluring Skull #1", "Alluring Skull x2", DS3LocationCategory.MISC), @@ -1137,6 +1135,10 @@ def __init__( missable = True, boss = True, shop = True), DS3LocationData("FK: Wolf Knight's Greatsword", "Wolf Knight's Greatsword", DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FK: Hawk Ring", "Hawk Ring", DS3LocationCategory.RING, + drop = True, npc = True), # Giant archer (kill or quest), here because you + # need to collect all seven White Branch locations + # to get it peacefully DS3LocationData("FK -> CC", None, DS3LocationCategory.EVENT), # Hawkwood after killing Abyss Watchers From d761614acd77a9df80335d97cc728543f0ab6cfa Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 10 Nov 2023 01:53:44 -0800 Subject: [PATCH 070/238] Mark the Grass Crest Shield as useful --- worlds/dark_souls_3/Items.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 37abc66e801d..d2a0e2b4361b 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -483,7 +483,8 @@ def event(name: str, player: int) -> "DarkSouls3Item": DS3ItemData("Crest Shield", 0x01430750, DS3ItemCategory.SHIELD), DS3ItemData("Dragon Crest Shield", 0x01432E60, DS3ItemCategory.SHIELD), DS3ItemData("Spider Shield", 0x01435570, DS3ItemCategory.SHIELD_INFUSIBLE), - DS3ItemData("Grass Crest Shield", 0x01437C80, DS3ItemCategory.SHIELD), + DS3ItemData("Grass Crest Shield", 0x01437C80, DS3ItemCategory.SHIELD, + classification = ItemClassification.useful), DS3ItemData("Sunset Shield", 0x0143A390, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Golden Wing Crest Shield", 0x0143CAA0, DS3ItemCategory.SHIELD), DS3ItemData("Blue Wooden Shield", 0x0143F1B0, DS3ItemCategory.SHIELD_INFUSIBLE), From 0e2623fe84c7bcb43e873dfc920820c8dde730dd Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 10 Nov 2023 01:56:15 -0800 Subject: [PATCH 071/238] Mark new progression items --- worlds/dark_souls_3/Items.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index d2a0e2b4361b..03dcbeef9cbb 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -1174,9 +1174,9 @@ def event(name: str, player: int) -> "DarkSouls3Item": DS3ItemData("Loretta's Bone", 0x40000846, DS3ItemCategory.KEY, classification = ItemClassification.progression), DS3ItemData("Braille Divine Tome of Carim", 0x40000847, DS3ItemCategory.MISC, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Braille Divine Tome of Lothric", 0x40000848, DS3ItemCategory.MISC, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Cinders of a Lord - Abyss Watcher", 0x4000084B, DS3ItemCategory.KEY, classification = ItemClassification.progression), DS3ItemData("Cinders of a Lord - Aldrich", 0x4000084C, DS3ItemCategory.KEY, @@ -1186,15 +1186,15 @@ def event(name: str, player: int) -> "DarkSouls3Item": DS3ItemData("Cinders of a Lord - Lothric Prince", 0x4000084E, DS3ItemCategory.KEY, classification = ItemClassification.progression), DS3ItemData("Great Swamp Pyromancy Tome", 0x4000084F, DS3ItemCategory.MISC, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Carthus Pyromancy Tome", 0x40000850, DS3ItemCategory.MISC, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Izalith Pyromancy Tome", 0x40000851, DS3ItemCategory.MISC, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Quelana Pyromancy Tome", 0x40000852, DS3ItemCategory.MISC, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Grave Warden Pyromancy Tome", 0x40000853, DS3ItemCategory.MISC, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Sage's Scroll", 0x40000854, DS3ItemCategory.MISC, classification = ItemClassification.progression), DS3ItemData("Logan's Scroll", 0x40000855, DS3ItemCategory.MISC, @@ -1216,9 +1216,12 @@ def event(name: str, player: int) -> "DarkSouls3Item": DS3ItemData("Hawkwood's Swordgrass", 0x4000085E, DS3ItemCategory.SKIP), DS3ItemData("Undead Bone Shard", 0x4000085F, DS3ItemCategory.MISC, classification = ItemClassification.useful), - DS3ItemData("Deep Braille Divine Tome", 0x40000860, DS3ItemCategory.MISC), - DS3ItemData("Londor Braille Divine Tome", 0x40000861, DS3ItemCategory.MISC), - DS3ItemData("Excrement-covered Ashes", 0x40000862, DS3ItemCategory.MISC), + DS3ItemData("Deep Braille Divine Tome", 0x40000860, DS3ItemCategory.MISC, + classification = ItemClassification.progression), + DS3ItemData("Londor Braille Divine Tome", 0x40000861, DS3ItemCategory.MISC, + classification = ItemClassification.progression), + DS3ItemData("Excrement-covered Ashes", 0x40000862, DS3ItemCategory.MISC, + classification = ItemClassification.useful), DS3ItemData("Prisoner Chief's Ashes", 0x40000863, DS3ItemCategory.MISC, classification = ItemClassification.progression), DS3ItemData("Xanthous Ashes", 0x40000864, DS3ItemCategory.MISC, From 2870656e89641a29e7009cb8df8bc64b9a5385e3 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 10 Nov 2023 02:08:32 -0800 Subject: [PATCH 072/238] Fix a bug --- worlds/dark_souls_3/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 0a47155bb070..763b23e2c668 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -501,7 +501,7 @@ def set_rules(self) -> None: self._add_location_rule([ "FS: Xanthous Overcoat", "FS: Xanthous Gloves", "FS: Xanthous Trousers" ], "Xanthous Ashes") - self._add_location_rule("Ember (Dragon Chaser)", "Dragon Chaser's Ashes") + self._add_location_rule("FS: Ember (Dragon Chaser)", "Dragon Chaser's Ashes") self._add_location_rule([ "FS: Washing Pole", "FS: Eastern Helm", "FS: Eastern Armor", "FS: Eastern Gauntlets", "FS: Eastern Leggings", "FS: Wood Grain Ring", From b7e94855ca236fa29d32c81b9982205a94910008 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 13 Nov 2023 03:04:41 -0800 Subject: [PATCH 073/238] Support newer better Path of the Dragon code --- worlds/dark_souls_3/Bosses.py | 2 +- worlds/dark_souls_3/Items.py | 2 +- worlds/dark_souls_3/__init__.py | 15 +-------------- 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index c3508301544d..0955f4d101d1 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -32,7 +32,7 @@ class DS3BossInfo: locations = {"CA: Coiled Sword"}), DS3BossInfo("Vordt of the Boreal Valley", 3000800, region = "Undead Settlement", locations = {"HWL: Soul of Boreal Valley Vordt"}), - DS3BossInfo("Curse-Rotted Greatwood", 3100800, locations = { + DS3BossInfo("Curse-rotted Greatwood", 3100800, locations = { "US: Soul of the Rotted Greatwood", "US: Transposing Kiln", "US: Wargod Wooden Shield", diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 03dcbeef9cbb..d65de58453ae 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -1233,7 +1233,7 @@ def event(name: str, player: int) -> "DarkSouls3Item": DS3ItemData("Easterner's Ashes", 0x40000868, DS3ItemCategory.MISC, classification = ItemClassification.progression), - # Fake item supported by the offline randomizer for controlling access to Archdragon Peak + # Fake item for controlling access to Archdragon Peak DS3ItemData("Path of the Dragon", 0x40002346, DS3ItemCategory.KEY, classification = ItemClassification.progression), diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 763b23e2c668..74c74bf770d6 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -114,10 +114,6 @@ def generate_early(self): if self.multiworld.soul_locations[self.player] != SoulLocationsOption.option_not_randomized: self.enabled_location_categories.add(DS3LocationCategory.SOUL) - # The offline randomizer's clever code for converting an item into a gesture only works for - # items in the local world. - self.multiworld.local_items[self.player].value.add("Path of the Dragon") - # Randomize Yhorm manually so that we know where to place the Storm Ruler if self.multiworld.randomize_enemies[self.player] == Toggle.option_true: self.yhorm_location = self.multiworld.random.choice( @@ -627,15 +623,6 @@ def has_any_scroll(state): item.player != self.player or (item.data.count == 1 and not item.data.souls) )) - elif location.drop: - # TODO: I'm not sure this is precisely the rule for where this can and can't - # go, but I've seen the offline randomizer reject it as a Ravenous Crystal - # Lizard drop. Should consult thefifthmatt. - add_item_rule(self.multiworld.get_location(location.name, self.player), - lambda item: ( - item.player != self.player or - item.name != "Path of the Dragon" - )) # This particular location is bugged, and will drop two copies of whatever item is placed # there. @@ -892,7 +879,7 @@ def fill_slot_data(self) -> Dict[str, object]: ap_ids_to_ds3_ids: Dict[str, int] = {} item_counts: Dict[str, int] = {} for item in our_items: - ap_ids_to_ds3_ids[str(item.code)] = item.data.ds3_code + if item.data.ds3_code: ap_ids_to_ds3_ids[str(item.code)] = item.data.ds3_code if item.data.count != 1: item_counts[str(item.code)] = item.data.count # A map from Archipelago's location IDs to the keys the offline From c4a9b13510081538637eb6cbec604a76d6f81c2b Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 28 Nov 2023 21:15:48 -0800 Subject: [PATCH 074/238] Don't lock the player out of Coiled Sword --- worlds/dark_souls_3/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 74c74bf770d6..3e789bfde913 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -723,6 +723,7 @@ def _fill_local_item(self, name: str, regions: Set[str]) -> None: for location in location_tables[region] if self.is_location_available(location) and not location.missable + and not location.conditional ] location = self.multiworld.random.choice([ location for location in candidate_locations From 0be59dee342b64bcde349187a1f5aea8e1f1a2a4 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 29 Nov 2023 21:49:16 -0800 Subject: [PATCH 075/238] Don't create events for missable locations --- worlds/dark_souls_3/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 3e789bfde913..cd44ab848e45 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -235,12 +235,15 @@ def create_region(self, region_name, location_table) -> Region: new_region ) else: - # Replace non-randomized progression items with events + # Replace non-randomized progression items with events if their locations aren't + # missable. Avoiding missable locations prevents issues where, for example, NPC + # locations aren't randomized and so Yhorm is technically defeatable without the + # normal Storm Ruler drop because you can get it from Siegward. event_item = ( self.create_item(location.default_item_name) if location.default_item_name else DarkSouls3Item.event(location.name, self.player) ) - if event_item.classification != ItemClassification.progression: + if location.missable or event_item.classification != ItemClassification.progression: continue new_location = DarkSouls3Location( From 7b2dff8eb51e3101a52c5bcbe1505ab30e403946 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 29 Nov 2023 21:55:00 -0800 Subject: [PATCH 076/238] Don't throw strings --- worlds/dark_souls_3/Items.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index d65de58453ae..5bfc9d7d0f88 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -162,8 +162,8 @@ def counts(self, counts: List[int]) -> Generator["DS3ItemData", None, None]: def infuse(self, infusion: Infusion) -> "DS3ItemData": """Returns this item with the given infusion applied.""" - if not self.category.is_infusible: raise f"{self.name} is not infusible." - if self.ds3_code % 10000 >= 100: raise f"{self.name} is already infused." + if not self.category.is_infusible: raise RuntimeError(f"{self.name} is not infusible.") + if self.ds3_code % 10000 >= 100: raise RuntimeError(f"{self.name} is already infused.") # We can't change the name or AP code when infusing/upgrading weapons, because they both # need to match what's in item_name_to_id. We don't want to add every possible @@ -177,9 +177,10 @@ def infuse(self, infusion: Infusion) -> "DS3ItemData": def upgrade(self, level: int) -> "DS3ItemData": """Upgrades this item to the given level.""" - if not self.category.upgrade_level: raise f"{self.name} is not upgradable." - if level > self.category.upgrade_level: raise f"{self.name} can't be upgraded to +{level}." - if self.ds3_code % 100 != 0: raise f"{self.name} is already upgraded." + if not self.category.upgrade_level: raise RuntimeError(f"{self.name} is not upgradable.") + if level > self.category.upgrade_level: + raise RuntimeError(f"{self.name} can't be upgraded to +{level}.") + if self.ds3_code % 100 != 0: raise RuntimeError(f"{self.name} is already upgraded.") # We can't change the name or AP code when infusing/upgrading weapons, because they both # need to match what's in item_name_to_id. We don't want to add every possible From f8067ededea6699a171e5aefaae7bb1026d47fd0 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 29 Nov 2023 22:21:20 -0800 Subject: [PATCH 077/238] Don't smooth event items --- worlds/dark_souls_3/__init__.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index cd44ab848e45..7783fa8e82cd 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -783,6 +783,15 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: world matching the given names. """ + item_order = [ + item for item in ( + full_items_by_name[item.name].pop(0) if isinstance(item, DS3ItemData) else item + for item in item_order + ) + # Never re-order event items, because they weren't randomized in the first place. + if item.code is not None + ] + names = {item.name for item in item_order} for i, all_locations in enumerate(locations_by_sphere): @@ -802,8 +811,6 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: # Give offworld regions the last (best) items within a given sphere for location in onworld + offworld: new_item = self._pop_item(location, item_order) - if isinstance(new_item, DS3ItemData): - new_item = full_items_by_name[new_item.name].pop(0) location.item = new_item new_item.location = location From b216c2fa5b5fe779820f6ca413767419d4efb0ad Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 29 Nov 2023 22:26:44 -0800 Subject: [PATCH 078/238] Properly categorize Butcher Knife --- worlds/dark_souls_3/Locations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index a4abf19e5a99..8d64f6e78fbf 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -738,7 +738,7 @@ def __init__( DS3LocationData("RS: Xanthous Crown", "Xanthous Crown", DS3LocationCategory.WEAPON, missable = True, hostile_npc = True), # Heysel drop DS3LocationData("RS: Butcher Knife", "Butcher Knife", DS3LocationCategory.WEAPON, - drop = True, hidden = True), # Guaranteed drop from a normal-looking Butcher + hostile_npc = True), # Madwoman DS3LocationData("RS: Titanite Shard #1", "Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("RS: Titanite Shard #2", "Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("RS: Green Blossom #1", "Green Blossom x4", DS3LocationCategory.MISC), From e466b356c70926190dd3334395561dadf0906824 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 29 Nov 2023 23:31:27 -0800 Subject: [PATCH 079/238] Be more careful about placing Yhorm in low-randomization scenarios --- worlds/dark_souls_3/Bosses.py | 19 +++++++++---- worlds/dark_souls_3/Items.py | 2 +- worlds/dark_souls_3/Locations.py | 2 +- worlds/dark_souls_3/__init__.py | 48 ++++++++++++++++++++++++++++---- 4 files changed, 58 insertions(+), 13 deletions(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index 0955f4d101d1..9a6cc35d7d36 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -18,6 +18,13 @@ class DS3BossInfo: 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. + """ + region: Optional[str] = None """The name the region that can't be accessed until the boss is dead, if one exists.""" @@ -28,10 +35,10 @@ class DS3BossInfo: # Note: the offline 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, region = "Firelink Shrine", + DS3BossInfo("Iudex Gundyr", 4000800, before_storm_ruler = True, region = "Firelink Shrine", locations = {"CA: Coiled Sword"}), - DS3BossInfo("Vordt of the Boreal Valley", 3000800, region = "Undead Settlement", - locations = {"HWL: Soul of Boreal Valley Vordt"}), + DS3BossInfo("Vordt of the Boreal Valley", 3000800, before_storm_ruler = True, + region = "Undead Settlement", locations = {"HWL: Soul of Boreal Valley Vordt"}), DS3BossInfo("Curse-rotted Greatwood", 3100800, locations = { "US: Soul of the Rotted Greatwood", "US: Transposing Kiln", @@ -45,7 +52,8 @@ class DS3BossInfo: "CD: Soul of the Deacons of the Deep", "CD: Small Doll", }), - DS3BossInfo("Abyss Watchers", 3300801, region = "Catacombs of Carthus", locations = { + DS3BossInfo("Abyss Watchers", 3300801, before_storm_ruler = True, + region = "Catacombs of Carthus", locations = { "FK: Soul of the Blood of the Wolf", "FK: Cinders of a Lord - Abyss Watcher", "UG: Hornet Ring", @@ -58,7 +66,8 @@ class DS3BossInfo: "UG: Wolf Knight Gauntlets", "UG: Wolf Knight Leggings", }), - DS3BossInfo("High Lord Wolnir", 3800800, region = "Irithyll of the Boreal Valley", locations = { + DS3BossInfo("High Lord Wolnir", 3800800, before_storm_ruler = True, + region = "Irithyll of the Boreal Valley", locations = { "CC: Soul of High Lord Wolnir", "CC: Wolnir's Crown", "CC: Homeward Bone", diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 5bfc9d7d0f88..b27dcfddee55 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -318,7 +318,7 @@ def event(name: str, player: int) -> "DarkSouls3Item": DS3ItemData("Fume Ultra Greatsword", 0x0060E4B0, DS3ItemCategory.WEAPON_UPGRADE_5), DS3ItemData("Old Wolf Curved Sword", 0x00610BC0, DS3ItemCategory.WEAPON_UPGRADE_5, inject = True), # Covenant reward - DS3ItemData("Storm Ruler", 0x006132D0, DS3ItemCategory.KEY, + DS3ItemData("Storm Ruler", 0x006132D0, DS3ItemCategory.WEAPON_UPGRADE_5, classification = ItemClassification.progression), DS3ItemData("Hand Axe", 0x006ACFC0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), DS3ItemData("Battle Axe", 0x006AF6D0, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 8d64f6e78fbf..2cf36ac2da99 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1577,7 +1577,7 @@ def __init__( DS3LocationData("PC: Court Sorcerer Robe", "Court Sorcerer Robe", DS3LocationCategory.ARMOR), DS3LocationData("PC: Court Sorcerer Gloves", "Court Sorcerer Gloves", DS3LocationCategory.ARMOR), DS3LocationData("PC: Court Sorcerer Trousers", "Court Sorcerer Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("PC: Storm Ruler", "Storm Ruler", DS3LocationCategory.KEY), + DS3LocationData("PC: Storm Ruler", "Storm Ruler", DS3LocationCategory.WEAPON), DS3LocationData("PC: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), DS3LocationData("PC: Eleonora", "Eleonora", DS3LocationCategory.WEAPON, drop = True, hidden = True), # Guaranteed drop from a normal-looking Monstrosity of Sin diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 7783fa8e82cd..b9b72f98e1c4 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -114,13 +114,10 @@ def generate_early(self): if self.multiworld.soul_locations[self.player] != SoulLocationsOption.option_not_randomized: self.enabled_location_categories.add(DS3LocationCategory.SOUL) - # Randomize Yhorm manually so that we know where to place the Storm Ruler - if self.multiworld.randomize_enemies[self.player] == Toggle.option_true: + # Randomize Yhorm manually so that we know where to place the Storm Ruler. + if self.multiworld.randomize_enemies[self.player]: self.yhorm_location = self.multiworld.random.choice( - [ - boss for boss in all_bosses if not boss.dlc - ] if not self.multiworld.enable_dlc[self.player] else all_bosses - ) + [boss for boss in all_bosses if self._allow_boss_for_yhorm(boss)]) # If Yhorm is early, make sure the Storm Ruler is easily available to avoid BK if ( @@ -135,6 +132,40 @@ def generate_early(self): else: self.yhorm_location = default_yhorm_location + + def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: + """Returns whether boss is a valid location for Yhorm in this seed.""" + + if not self.multiworld.enable_dlc[self.player] and boss.dlc: return False + + if not self.multiworld.enable_weapon_locations[self.player]: + # If weapons aren't randomized, make sure the player can get to the normal Storm Ruler + # location before they need to get through Yhorm. + if boss.before_storm_ruler: return False + + # If keys also aren't randomized, make sure Yhorm isn't blocking access to the Small + # Doll or it won't be possible to get into Profaned Capital before beating him. + if ( + not self.multiworld.enable_key_locations[self.player] + and boss.name in {"Crystal Sage", "Deacons of the Deep"} + ): + return False + + # There are only a few locations before Iudex Gundyr, and none of them are weapons, so if + # they can't be random don't allow Yhorm in there. + if self.multiworld.pool_type[self.player] == PoolTypeOption.option_various or ( + not self.multiworld.enable_misc_locations[self.player] + and self.multiworld.upgrade_locations[self.player] == + UpgradeLocationsOption.option_not_randomized + and self.multiworld.soul_locations[self.player] == + SoulLocationsOption.option_not_randomized + and boss.name == "Iudex Gundyr" + ): + return False + + return True + + def create_regions(self): # Create Vanilla Regions regions: Dict[str, Region] = {} @@ -692,6 +723,11 @@ def write_spoiler(self, spoiler_handle: TextIO) -> None: def pre_fill(self) -> None: + # Fill this manually so that, if very few slots are available in Cemetery of Ash, this + # doesn't get locked out by bad rolls on the next two fills. + if self.yhorm_location.name == 'Iudex Gundyr': + self._fill_local_item("Storm Ruler", {"Cemetery of Ash"}) + # Don't place this in the multiworld because it's necessary almost immediately, and don't # mark it as a blocker for HWL because having a miniscule Sphere 1 screws with progression # balancing. From eb21802b4c06111b60fdedcf2673f02389f98815 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 29 Nov 2023 23:55:46 -0800 Subject: [PATCH 080/238] Don't try to smooth DLC items with DLC disabled --- worlds/dark_souls_3/__init__.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index b9b72f98e1c4..48be90dcb61e 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -819,13 +819,18 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: world matching the given names. """ + # Convert items to full DarkSouls3Items. item_order = [ item for item in ( - full_items_by_name[item.name].pop(0) if isinstance(item, DS3ItemData) else item + ( + # full_items_by_name won't contain DLC items if the DLC is disabled. + (full_items_by_name[item.name] or [None]).pop(0) + if isinstance(item, DS3ItemData) else item + ) for item in item_order ) # Never re-order event items, because they weren't randomized in the first place. - if item.code is not None + if item and item.code is not None ] names = {item.name for item in item_order} From aa94ec4c4e929a3b2998ba180712499ae058c7d5 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 29 Nov 2023 23:59:10 -0800 Subject: [PATCH 081/238] Fix another Yhorm bug --- worlds/dark_souls_3/__init__.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 48be90dcb61e..3697ffb54467 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -153,13 +153,15 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: # There are only a few locations before Iudex Gundyr, and none of them are weapons, so if # they can't be random don't allow Yhorm in there. - if self.multiworld.pool_type[self.player] == PoolTypeOption.option_various or ( - not self.multiworld.enable_misc_locations[self.player] - and self.multiworld.upgrade_locations[self.player] == - UpgradeLocationsOption.option_not_randomized - and self.multiworld.soul_locations[self.player] == - SoulLocationsOption.option_not_randomized - and boss.name == "Iudex Gundyr" + if boss.name == "Iudex Gundyr" and ( + self.multiworld.pool_type[self.player] == PoolTypeOption.option_various + or ( + not self.multiworld.enable_misc_locations[self.player] + and self.multiworld.upgrade_locations[self.player] == + UpgradeLocationsOption.option_not_randomized + and self.multiworld.soul_locations[self.player] == + SoulLocationsOption.option_not_randomized + ) ): return False From b0e8c9d66c1487d2c08c3a4ad4f90f5e0e8de126 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 30 Nov 2023 00:09:44 -0800 Subject: [PATCH 082/238] Fix upgrade/infusion logic --- worlds/dark_souls_3/Items.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index b27dcfddee55..918dd6837e89 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -95,9 +95,15 @@ class DS3ItemData(): """The next item ID to use when creating item data.""" name: str - ds3_code: Optional[int] + ds3_code: int category: DS3ItemCategory + base_ds3_code: int = None + """If this is an upgradable weapon, the base ID of the weapon it upgrades from. + + Otherwise, or if the weapon isn't upgraded, this is the same as ds3_code. + """ + base_name: Optional[str] = None """The name of the individual item, if this is a multi-item group.""" @@ -145,6 +151,7 @@ def unique(self): def __post_init__(self): self.ap_code = self.ap_code or DS3ItemData.__item_id if not self.base_name: self.base_name = self.name + if not self.base_ds3_code: self.base_ds3_code = self.ds3_code DS3ItemData.__item_id += 1 def counts(self, counts: List[int]) -> Generator["DS3ItemData", None, None]: @@ -163,7 +170,8 @@ def counts(self, counts: List[int]) -> Generator["DS3ItemData", None, None]: def infuse(self, infusion: Infusion) -> "DS3ItemData": """Returns this item with the given infusion applied.""" if not self.category.is_infusible: raise RuntimeError(f"{self.name} is not infusible.") - if self.ds3_code % 10000 >= 100: raise RuntimeError(f"{self.name} is already infused.") + if self.ds3_code - self.base_ds3_code >= 100: + raise RuntimeError(f"{self.name} is already infused.") # We can't change the name or AP code when infusing/upgrading weapons, because they both # need to match what's in item_name_to_id. We don't want to add every possible @@ -180,7 +188,8 @@ def upgrade(self, level: int) -> "DS3ItemData": if not self.category.upgrade_level: raise RuntimeError(f"{self.name} is not upgradable.") if level > self.category.upgrade_level: raise RuntimeError(f"{self.name} can't be upgraded to +{level}.") - if self.ds3_code % 100 != 0: raise RuntimeError(f"{self.name} is already upgraded.") + if (self.ds3_code - self.base_ds3_code) % 100 != 0: + raise RuntimeError(f"{self.name} is already upgraded.") # We can't change the name or AP code when infusing/upgrading weapons, because they both # need to match what's in item_name_to_id. We don't want to add every possible From ac88c50aa86f377bcc018df8ac830430d5ec35ac Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 30 Nov 2023 00:33:02 -0800 Subject: [PATCH 083/238] Remove the PoolType option This distinction is no longer meaningful now that every location in the game of each type is randomized --- worlds/dark_souls_3/Options.py | 11 ------- worlds/dark_souls_3/__init__.py | 58 +++++---------------------------- 2 files changed, 8 insertions(+), 61 deletions(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 39fccaa45087..15b4cacdecdd 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -133,16 +133,6 @@ class RequireOneHandedStartingWeapons(DefaultOnToggle): display_name = "Require One-Handed Starting Weapons" -class PoolTypeOption(Choice): - """Changes which non-progression items you add to the pool - - Shuffle: Items are picked from the locations being randomized - Various: Items are picked from a list of all items in the game, but are the same type of item they replace""" - display_name = "Pool Type" - option_shuffle = 0 - option_various = 1 - - class GuaranteedItemsOption(ItemDict): """Guarantees that the specified items will be in the item pool""" display_name = "Guaranteed Items" @@ -398,7 +388,6 @@ class DarkSouls3Options(PerGameCommonOptions): upgraded_weapon_locations: UpgradedWeaponLocationsOption random_starting_loadout: RandomizeStartingLoadout require_one_handed_starting_weapons: RequireOneHandedStartingWeapons - pool_type: PoolTypeOption guaranteed_items: GuaranteedItemsOption auto_equip: AutoEquipOption lock_equip: LockEquipOption diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 3697ffb54467..e09642340e97 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -13,7 +13,7 @@ from .Bosses import DS3BossInfo, all_bosses, default_yhorm_location from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, Infusion, UsefulIf, filler_item_names, item_dictionary from .Locations import DarkSouls3Location, DS3LocationCategory, DS3LocationData, location_tables, location_dictionary, location_name_groups, region_order -from .Options import DarkSouls3Options, RandomizeWeaponLevelOption, PoolTypeOption, SoulLocationsOption, UpgradeLocationsOption, UpgradedWeaponLocationsOption +from .Options import DarkSouls3Options, RandomizeWeaponLevelOption, SoulLocationsOption, UpgradeLocationsOption, UpgradedWeaponLocationsOption class DarkSouls3Web(WebWorld): @@ -153,15 +153,13 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: # There are only a few locations before Iudex Gundyr, and none of them are weapons, so if # they can't be random don't allow Yhorm in there. - if boss.name == "Iudex Gundyr" and ( - self.multiworld.pool_type[self.player] == PoolTypeOption.option_various - or ( - not self.multiworld.enable_misc_locations[self.player] - and self.multiworld.upgrade_locations[self.player] == - UpgradeLocationsOption.option_not_randomized - and self.multiworld.soul_locations[self.player] == - SoulLocationsOption.option_not_randomized - ) + if ( + boss.name == "Iudex Gundyr" + and not self.multiworld.enable_misc_locations[self.player] + and self.multiworld.upgrade_locations[self.player] == + UpgradeLocationsOption.option_not_randomized + and self.multiworld.soul_locations[self.player] == + SoulLocationsOption.option_not_randomized ): return False @@ -326,46 +324,6 @@ def create_items(self): item_set.add(location.data.default_item_name) itempool_by_category[location.data.category].append(location.data.default_item_name) - # Replace each item category with a random sample of items of those types - if self.multiworld.pool_type[self.player] == PoolTypeOption.option_various: - def create_random_replacement_list(item_categories: Set[DS3ItemCategory], num_items: int): - candidates = [ - item.name for item - in item_dictionary.values() - if (item.category in item_categories and (not item.is_dlc or dlc_enabled)) - ] - return self.multiworld.random.sample(candidates, num_items) - - if DS3LocationCategory.WEAPON in self.enabled_location_categories: - itempool_by_category[DS3LocationCategory.WEAPON] = create_random_replacement_list( - { - DS3ItemCategory.WEAPON_UPGRADE_5, - DS3ItemCategory.WEAPON_UPGRADE_10, - DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE - }, - len(itempool_by_category[DS3LocationCategory.WEAPON]) - ) - if DS3LocationCategory.SHIELD in self.enabled_location_categories: - itempool_by_category[DS3LocationCategory.SHIELD] = create_random_replacement_list( - {DS3ItemCategory.SHIELD, DS3ItemCategory.SHIELD_INFUSIBLE}, - len(itempool_by_category[DS3LocationCategory.SHIELD]) - ) - if DS3LocationCategory.ARMOR in self.enabled_location_categories: - itempool_by_category[DS3LocationCategory.ARMOR] = create_random_replacement_list( - {DS3ItemCategory.ARMOR}, - len(itempool_by_category[DS3LocationCategory.ARMOR]) - ) - if DS3LocationCategory.RING in self.enabled_location_categories: - itempool_by_category[DS3LocationCategory.RING] = create_random_replacement_list( - {DS3ItemCategory.RING}, - len(itempool_by_category[DS3LocationCategory.RING]) - ) - if DS3LocationCategory.SPELL in self.enabled_location_categories: - itempool_by_category[DS3LocationCategory.SPELL] = create_random_replacement_list( - {DS3ItemCategory.SPELL}, - len(itempool_by_category[DS3LocationCategory.SPELL]) - ) - itempool: List[DarkSouls3Item] = [] for category in self.enabled_location_categories: itempool.extend(self.create_item(name) for name in itempool_by_category[category]) From 11571299ca29fa149ca174a92abce6a33b6d9669 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 30 Nov 2023 00:35:49 -0800 Subject: [PATCH 084/238] Categorize HWL: Red Eye Orb as an NPC location --- worlds/dark_souls_3/Locations.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 2cf36ac2da99..ebd76f0a554e 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -503,8 +503,10 @@ def __init__( DS3LocationData("HWL: Way of Blue", "Way of Blue", DS3LocationCategory.UNIQUE), DS3LocationData("HWL: Raw Gem", "Raw Gem", DS3LocationCategory.UPGRADE, lizard = True), + # Categorize this as an NPC item so that it doesn't get randomized if the Lift Chamber Key + # isn't randomized, since in that case it's missable. DS3LocationData("HWL: Red Eye Orb", "Red Eye Orb", DS3LocationCategory.MISC, - miniboss = True), + npc = True, miniboss = True), DS3LocationData("HWL: Vordt's Great Hammer", "Vordt's Great Hammer", DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), DS3LocationData("HWL: Pontiff's Left Eye", "Pontiff's Left Eye", DS3LocationCategory.RING, From 502cf19ee67ce57b4284db4e1ddf727008526986 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 30 Nov 2023 01:13:49 -0800 Subject: [PATCH 085/238] Don't place Storm Ruler on CA: Coiled Sword --- worlds/dark_souls_3/__init__.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index bfd1cb219ae4..4fad8b102b02 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -2,7 +2,7 @@ from collections.abc import Sequence from collections import defaultdict import json -from typing import Dict, Set, List, Optional, TextIO, Union +from typing import Callable, Dict, Set, List, Optional, TextIO, Union from BaseClasses import CollectionState, MultiWorld, Region, Item, Location, LocationProgressType, Entrance, Tutorial, ItemClassification from Options import Toggle @@ -686,7 +686,8 @@ def pre_fill(self) -> None: # Fill this manually so that, if very few slots are available in Cemetery of Ash, this # doesn't get locked out by bad rolls on the next two fills. if self.yhorm_location.name == 'Iudex Gundyr': - self._fill_local_item("Storm Ruler", {"Cemetery of Ash"}) + self._fill_local_item("Storm Ruler", {"Cemetery of Ash"}, + lambda location: location.name != "CA: Coiled Sword") # Don't place this in the multiworld because it's necessary almost immediately, and don't # mark it as a blocker for HWL because having a miniscule Sphere 1 screws with progression @@ -702,10 +703,15 @@ def pre_fill(self) -> None: }) - def _fill_local_item(self, name: str, regions: Set[str]) -> None: + def _fill_local_item( + self, name: str, + regions: Set[str], + additional_condition: Optional[Callable[[DarkSouls3Location], bool]] = None + ) -> None: """Chooses a valid location for the item with the given name and places it there. - This always chooses a local location among the given regions. + This always chooses a local location among the given regions. If additional_condition is + passed, only locations meeting that condition will be considered. """ item = next( ( @@ -723,6 +729,7 @@ def _fill_local_item(self, name: str, regions: Set[str]) -> None: if self.is_location_available(location) and not location.missable and not location.conditional + and (not additional_condition or additional_condition(location)) ] location = self.multiworld.random.choice([ location for location in candidate_locations From cdd8b4895cc637dcbc1d38c6bc94949074851e1f Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 30 Nov 2023 01:17:23 -0800 Subject: [PATCH 086/238] Define flatten() locally to make this APWorld capable --- worlds/dark_souls_3/Items.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index d6ba62de3a99..29449f5f372f 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -1,10 +1,10 @@ from dataclasses import dataclass, field import dataclasses from enum import IntEnum +import types from typing import ClassVar, Generator, List, Optional, Set, Union from BaseClasses import Item, ItemClassification -from Utils import flatten class DS3ItemCategory(IntEnum): @@ -226,6 +226,14 @@ def event(name: str, player: int) -> "DarkSouls3Item": return DarkSouls3Item(player, data) +# TODO: use this from Utils once this is a PR for the main repo and not an APWorld +def flatten(l): + if type(l) is list or type(l) is types.GeneratorType: + return [ y for x in l for y in flatten(x) ] + else: + return [ l ] + + _vanilla_items = flatten([ # Ammunition DS3ItemData("Standard Arrow", 0x00061A80, DS3ItemCategory.MISC).counts([12]), From 9aa635a665b2e77772a562af8655a36a73af8b75 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 30 Nov 2023 01:37:01 -0800 Subject: [PATCH 087/238] Fix some more Leonhard weirdness --- worlds/dark_souls_3/Locations.py | 11 ++++++----- worlds/dark_souls_3/__init__.py | 11 ++++++++++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index ebd76f0a554e..098246b110a3 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1721,14 +1721,15 @@ def __init__( missable = True, npc = True), # Shrine Handmaid after killing Ringfinger Leonhard - # This is listed here even though you can kill Leonhard immediately because we don't want to - # make people do that until they have a chance to complete his quest and Sirris's. + # This is listed here even though you can kill Leonhard immediately because we want the + # logic to assume people will do his full quest. Missable because he can disappear forever + # if you use up all your Pale Tongues. DS3LocationData("AL: Leonhard's Garb", "Leonhard's Garb", DS3LocationCategory.ARMOR, - hidden = True, npc = True, shop = True, conditional = True), + hidden = True, npc = True, shop = True, missable = True), DS3LocationData("AL: Leonhard's Gauntlets", "Leonhard's Gauntlets", DS3LocationCategory.ARMOR, - hidden = True, npc = True, shop = True, conditional = True), + hidden = True, npc = True, shop = True, missable = True), DS3LocationData("AL: Leonhard's Trousers", "Leonhard's Trousers", DS3LocationCategory.ARMOR, - hidden = True, npc = True, shop = True, conditional = True), + hidden = True, npc = True, shop = True, missable = True), # Shrine Handmaid after killing Alrich, Devourer of Gods DS3LocationData("AL: Smough's Helm", "Smough's Helm", DS3LocationCategory.ARMOR, diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 4fad8b102b02..aac0ec67ac48 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -265,6 +265,14 @@ def create_region(self, region_name, location_table) -> Region: location, new_region ) + + # Mark Red Eye Orb as missable if key locations aren't being randomized, because the + # Lift Chamber Key is missable by default. + if ( + not self.multiworld.enable_key_locations[self.player] + and location.name == "HWL: Red Eye Orb" + ): + new_location.progress_type = LocationProgressType.EXCLUDED else: # Replace non-randomized progression items with events if their locations aren't # missable. Avoiding missable locations prevents issues where, for example, NPC @@ -472,7 +480,8 @@ def set_rules(self) -> None: self._add_entrance_rule("Painted World of Ariandel (After Contraption)", "Small Doll") # Define the access rules to some specific locations - self._add_location_rule("HWL: Red Eye Orb", "Lift Chamber Key") + if self.multiworld.enable_key_locations[self.player]: + self._add_location_rule("HWL: Red Eye Orb", "Lift Chamber Key") self._add_location_rule("ID: Bellowing Dragoncrest Ring", "Jailbreaker's Key") self._add_location_rule("ID: Covetous Gold Serpent Ring", "Old Cell Key") self._add_location_rule("UG: Hornet Ring", "Small Lothric Banner") From 360413754eb8a81dbeaeb695cb5627b2f3ec7e4b Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 1 Dec 2023 01:52:16 -0800 Subject: [PATCH 088/238] Fix unique item randomization --- worlds/dark_souls_3/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index aac0ec67ac48..582a3ebd09ee 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -99,6 +99,8 @@ def generate_early(self): self.enabled_location_categories.add(DS3LocationCategory.RING) if self.multiworld.enable_spell_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.SPELL) + if self.multiworld.enable_unique_locations[self.player] == Toggle.option_true: + self.enabled_location_categories.add(DS3LocationCategory.UNIQUE) if self.multiworld.enable_key_locations[self.player] == Toggle.option_true: self.enabled_location_categories.add(DS3LocationCategory.KEY) if self.multiworld.early_banner[self.player] == EarlySmallLothricBanner.option_early_global: @@ -341,6 +343,7 @@ def create_items(self): guaranteed_items = {"Path of the Dragon": 1} guaranteed_items.update(self.multiworld.guaranteed_items[self.player].value) + print(guaranteed_items) if len(removable_items) == 0 and num_required_extra_items == 0: raise Exception("Can't add Path of the Dragon to the item pool") @@ -631,7 +634,7 @@ def has_any_scroll(state): # there. if self.is_location_available("US: Young White Branch #2"): add_item_rule(self.multiworld.get_location("US: Young White Branch #2", self.player), - lambda item: item.player == self.player and not item.data.unique) + lambda item: item.player == self.player and not item.data.unique) # Make sure the Storm Ruler is available BEFORE Yhorm the Giant if self.yhorm_location.region: From 825c44960d65375891f19b5d5b6e47e08a48adb2 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 1 Dec 2023 01:52:30 -0800 Subject: [PATCH 089/238] Don't double Twin Dragon Greatshield --- worlds/dark_souls_3/Items.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 29449f5f372f..2d7886a5cff1 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -521,8 +521,7 @@ def flatten(l): DS3ItemData("Black Iron Greatshield", 0x0150EA00, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Wolf Knight's Greatshield", 0x01511110, DS3ItemCategory.SHIELD, inject = True), # Covenant reward - DS3ItemData("Twin Dragon Greatshield", 0x01513820, DS3ItemCategory.SHIELD_INFUSIBLE, - inject = True), # Covenant reward + DS3ItemData("Twin Dragon Greatshield", 0x01513820, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Greatshield of Glory", 0x01515F30, DS3ItemCategory.SHIELD), DS3ItemData("Curse Ward Greatshield", 0x01518640, DS3ItemCategory.SHIELD), DS3ItemData("Bonewheel Shield", 0x0151AD50, DS3ItemCategory.SHIELD_INFUSIBLE), From d4d5d07df0f8d72ed1c602d6a3f90455cd3cbfd6 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 1 Dec 2023 22:11:10 -0800 Subject: [PATCH 090/238] Remove debugging print --- worlds/dark_souls_3/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 582a3ebd09ee..e9fb6a5dff2e 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -343,7 +343,6 @@ def create_items(self): guaranteed_items = {"Path of the Dragon": 1} guaranteed_items.update(self.multiworld.guaranteed_items[self.player].value) - print(guaranteed_items) if len(removable_items) == 0 and num_required_extra_items == 0: raise Exception("Can't add Path of the Dragon to the item pool") From 1abf6f3c8625229381f178635e9f6042caabe031 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 2 Dec 2023 18:38:40 -0800 Subject: [PATCH 091/238] Don't add double Storm Ruler Also remove now-redundant item sorting by category in create_items. --- worlds/dark_souls_3/__init__.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index e9fb6a5dff2e..d1304ced9849 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -308,12 +308,11 @@ def create_region(self, region_name, location_table) -> Region: def create_items(self): dlc_enabled = self.multiworld.enable_dlc[self.player] == Toggle.option_true - itempool_by_category = {category: [] for category in self.enabled_location_categories} - # Just used to efficiently deduplicate items - item_set_by_category = {category: set() for category in self.enabled_location_categories} + item_set = set() # Gather all default items on randomized locations + itempool: List[DarkSouls3Item] = [] num_required_extra_items = 0 for location in self.multiworld.get_unfilled_locations(self.player): if not self.is_location_available(location.name): @@ -323,20 +322,17 @@ def create_items(self): if item.category == DS3ItemCategory.SKIP: num_required_extra_items += 1 elif not item.unique: - itempool_by_category[location.data.category].append(location.data.default_item_name) + itempool.append(location.data.default_item_name) else: # For unique items, make sure there aren't duplicates in the item set even if there # are multiple in-game locations that provide them. - item_set = item_set_by_category[location.data.category] if location.data.default_item_name in item_set: num_required_extra_items += 1 else: item_set.add(location.data.default_item_name) - itempool_by_category[location.data.category].append(location.data.default_item_name) - - itempool: List[DarkSouls3Item] = [] - for category in self.enabled_location_categories: - itempool.extend(self.create_item(name) for name in itempool_by_category[category]) + if location.data.default_item_name == "Storm Ruler": + print("adding Storm ruler to item_set") + itempool.append(location.data.default_item_name) # A list of items we can replace removable_items = [item for item in itempool if item.classification == ItemClassification.filler] From 54d8d5c172320f64409fb5128443d81d0bc56fcd Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 2 Dec 2023 18:38:40 -0800 Subject: [PATCH 092/238] Don't add double Storm Ruler Also remove now-redundant item sorting by category in create_items. --- worlds/dark_souls_3/__init__.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index e9fb6a5dff2e..ea13f9647228 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -308,12 +308,11 @@ def create_region(self, region_name, location_table) -> Region: def create_items(self): dlc_enabled = self.multiworld.enable_dlc[self.player] == Toggle.option_true - itempool_by_category = {category: [] for category in self.enabled_location_categories} - # Just used to efficiently deduplicate items - item_set_by_category = {category: set() for category in self.enabled_location_categories} + item_set = set() # Gather all default items on randomized locations + itempool: List[DarkSouls3Item] = [] num_required_extra_items = 0 for location in self.multiworld.get_unfilled_locations(self.player): if not self.is_location_available(location.name): @@ -323,20 +322,15 @@ def create_items(self): if item.category == DS3ItemCategory.SKIP: num_required_extra_items += 1 elif not item.unique: - itempool_by_category[location.data.category].append(location.data.default_item_name) + itempool.append(self.create_item(location.data.default_item_name)) else: # For unique items, make sure there aren't duplicates in the item set even if there # are multiple in-game locations that provide them. - item_set = item_set_by_category[location.data.category] if location.data.default_item_name in item_set: num_required_extra_items += 1 else: item_set.add(location.data.default_item_name) - itempool_by_category[location.data.category].append(location.data.default_item_name) - - itempool: List[DarkSouls3Item] = [] - for category in self.enabled_location_categories: - itempool.extend(self.create_item(name) for name in itempool_by_category[category]) + itempool.append(self.create_item(location.data.default_item_name)) # A list of items we can replace removable_items = [item for item in itempool if item.classification == ItemClassification.filler] From 98018b6ece050f6ac2c162eba87b990766972c2c Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 2 Dec 2023 19:13:19 -0800 Subject: [PATCH 093/238] Add a missing dlc_enabled check --- worlds/dark_souls_3/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index ea13f9647228..78bfe73377c6 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -593,7 +593,8 @@ def has_any_scroll(state): self._add_location_rule("FK: Cinders of a Lord - Abyss Watcher", has_any_scroll) self._add_entrance_rule("Catacombs of Carthus", has_any_scroll) # Not really necessary but ensures players can decide which way to go - self._add_entrance_rule("Painted World of Ariandel (After Contraption)", has_any_scroll) + if dlc_enabled: + self._add_entrance_rule("Painted World of Ariandel (After Contraption)", has_any_scroll) self._add_location_rule("HWL: Soul of the Dancer", "Basin of Vows") From 55b0170c59ff391effdc781748ef7f14a0296484 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 2 Dec 2023 20:02:08 -0800 Subject: [PATCH 094/238] Use nicer options syntax --- worlds/dark_souls_3/__init__.py | 153 +++++++++++++++----------------- 1 file changed, 72 insertions(+), 81 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 78bfe73377c6..46d417b7e6ba 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -87,37 +87,37 @@ def __init__(self, multiworld: MultiWorld, player: int): def generate_early(self): - if self.multiworld.enable_weapon_locations[self.player] == Toggle.option_true: + if self.options.enable_weapon_locations: self.enabled_location_categories.add(DS3LocationCategory.WEAPON) # Always make this available early because so many items are useless without it. self.multiworld.early_items[self.player]['Pyromancy Flame'] = 1 - if self.multiworld.enable_shield_locations[self.player] == Toggle.option_true: + if self.options.enable_shield_locations: self.enabled_location_categories.add(DS3LocationCategory.SHIELD) - if self.multiworld.enable_armor_locations[self.player] == Toggle.option_true: + if self.options.enable_armor_locations: self.enabled_location_categories.add(DS3LocationCategory.ARMOR) - if self.multiworld.enable_ring_locations[self.player] == Toggle.option_true: + if self.options.enable_ring_locations: self.enabled_location_categories.add(DS3LocationCategory.RING) - if self.multiworld.enable_spell_locations[self.player] == Toggle.option_true: + if self.options.enable_spell_locations: self.enabled_location_categories.add(DS3LocationCategory.SPELL) - if self.multiworld.enable_unique_locations[self.player] == Toggle.option_true: + if self.options.enable_unique_locations: self.enabled_location_categories.add(DS3LocationCategory.UNIQUE) - if self.multiworld.enable_key_locations[self.player] == Toggle.option_true: + if self.options.enable_key_locations: self.enabled_location_categories.add(DS3LocationCategory.KEY) - if self.multiworld.early_banner[self.player] == EarlySmallLothricBanner.option_early_global: + if self.options.early_banner == "early_global": self.multiworld.early_items[self.player]['Small Lothric Banner'] = 1 - elif self.multiworld.early_banner[self.player] == EarlySmallLothricBanner.option_early_local: + elif self.options.early_banner == "early_local": self.multiworld.local_early_items[self.player]['Small Lothric Banner'] = 1 - if self.multiworld.enable_misc_locations[self.player] == Toggle.option_true: + if self.options.enable_misc_locations: self.enabled_location_categories.add(DS3LocationCategory.MISC) - if self.multiworld.enable_health_locations[self.player] == Toggle.option_true: + if self.options.enable_health_locations: self.enabled_location_categories.add(DS3LocationCategory.HEALTH) - if self.multiworld.upgrade_locations[self.player] != UpgradeLocationsOption.option_not_randomized: + if self.options.upgrade_locations != "not_randomized": self.enabled_location_categories.add(DS3LocationCategory.UPGRADE) - if self.multiworld.soul_locations[self.player] != SoulLocationsOption.option_not_randomized: + if self.options.soul_locations != "not_randomized": self.enabled_location_categories.add(DS3LocationCategory.SOUL) # Randomize Yhorm manually so that we know where to place the Storm Ruler. - if self.multiworld.randomize_enemies[self.player]: + if self.options.randomize_enemies: self.yhorm_location = self.multiworld.random.choice( [boss for boss in all_bosses if self._allow_boss_for_yhorm(boss)]) @@ -126,7 +126,7 @@ def generate_early(self): self.yhorm_location.name == "Iudex Gundyr" or self.yhorm_location.name == "Vordt of the Boreal Valley" or ( self.yhorm_location.name == "Dancer of the Boreal Valley" and - self.multiworld.late_basin_of_vows[self.player] == Toggle.option_false + not self.multiworld.late_basin_of_vows ) ): self.multiworld.early_items[self.player]['Storm Ruler'] = 1 @@ -138,9 +138,9 @@ def generate_early(self): def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: """Returns whether boss is a valid location for Yhorm in this seed.""" - if not self.multiworld.enable_dlc[self.player] and boss.dlc: return False + if not self.options.enable_dlc and boss.dlc: return False - if not self.multiworld.enable_weapon_locations[self.player]: + if not self.options.enable_weapon_locations: # If weapons aren't randomized, make sure the player can get to the normal Storm Ruler # location before they need to get through Yhorm. if boss.before_storm_ruler: return False @@ -148,7 +148,7 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: # If keys also aren't randomized, make sure Yhorm isn't blocking access to the Small # Doll or it won't be possible to get into Profaned Capital before beating him. if ( - not self.multiworld.enable_key_locations[self.player] + not self.options.enable_key_locations and boss.name in {"Crystal Sage", "Deacons of the Deep"} ): return False @@ -157,11 +157,9 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: # they can't be random don't allow Yhorm in there. if ( boss.name == "Iudex Gundyr" - and not self.multiworld.enable_misc_locations[self.player] - and self.multiworld.upgrade_locations[self.player] == - UpgradeLocationsOption.option_not_randomized - and self.multiworld.soul_locations[self.player] == - SoulLocationsOption.option_not_randomized + and not self.options.enable_misc_locations + and self.options.upgrade_locations == "not_randomized" + and self.options.soul_locations == "not_randomized" ): return False @@ -198,7 +196,7 @@ def create_regions(self): ]}) # Create DLC Regions - if self.multiworld.enable_dlc[self.player]: + if self.options.enable_dlc: regions.update({region_name: self.create_region(region_name, location_tables[region_name]) for region_name in [ "Painted World of Ariandel (Before Contraption)", "Painted World of Ariandel (After Contraption)", @@ -248,7 +246,7 @@ def create_connection(from_region: str, to_region: str): create_connection("Consumed King's Garden", "Untended Graves") # Connect DLC Regions - if self.multiworld.enable_dlc[self.player]: + if self.options.enable_dlc: create_connection("Cathedral of the Deep", "Painted World of Ariandel (Before Contraption)") create_connection("Painted World of Ariandel (Before Contraption)", "Painted World of Ariandel (After Contraption)") @@ -270,10 +268,7 @@ def create_region(self, region_name, location_table) -> Region: # Mark Red Eye Orb as missable if key locations aren't being randomized, because the # Lift Chamber Key is missable by default. - if ( - not self.multiworld.enable_key_locations[self.player] - and location.name == "HWL: Red Eye Orb" - ): + if not self.options.enable_key_locations and location.name == "HWL: Red Eye Orb": new_location.progress_type = LocationProgressType.EXCLUDED else: # Replace non-randomized progression items with events if their locations aren't @@ -306,8 +301,6 @@ def create_region(self, region_name, location_table) -> Region: def create_items(self): - dlc_enabled = self.multiworld.enable_dlc[self.player] == Toggle.option_true - # Just used to efficiently deduplicate items item_set = set() @@ -378,7 +371,7 @@ def create_items(self): injectable_items = [ item for item in item_dictionary.values() - if item.inject and (not item.is_dlc or dlc_enabled) + if item.inject and (not item.is_dlc or self.options.enable_dlc) ] number_to_inject = min(num_required_extra_items, len(injectable_items)) for item in self.multiworld.random.sample(injectable_items, k=number_to_inject): @@ -395,21 +388,19 @@ def create_items(self): def create_item(self, item: Union[str, DS3ItemData]) -> Item: data = item if isinstance(item, DS3ItemData) else item_dictionary[item] classification = None - if self.multiworld and (( - data.useful_if == UsefulIf.BASE and - not self.multiworld.enable_dlc[self.player] and - not self.multiworld.enable_ngp[self.player] - ) or ( - data.useful_if == UsefulIf.NO_DLC and - not self.multiworld.enable_dlc[self.player] - ) or ( - data.useful_if == UsefulIf.NO_NGP and - not self.multiworld.enable_ngp[self.player] - )): + if self.multiworld and ( + ( + data.useful_if == UsefulIf.BASE and + not self.options.enable_dlc and + not self.options.enable_ngp + ) + or (data.useful_if == UsefulIf.NO_DLC and not self.options.enable_dlc) + or (data.useful_if == UsefulIf.NO_NGP and not self.options.enable_ngp) + ): classification = ItemClassification.useful if ( - self.multiworld.randomize_weapon_level[self.player] != RandomizeWeaponLevelOption.option_none + self.options.randomize_weapon_level != "none" and data.category.upgrade_level # Because we require the Pyromancy Flame to be available early, don't upgrade it so it # doesn't get shuffled around by weapon smoothing. @@ -420,7 +411,7 @@ def create_item(self, item: Union[str, DS3ItemData]) -> Item: min_5 = min(self.multiworld.min_levels_in_5[self.player], max_5) max_10 = self.multiworld.max_levels_in_10[self.player] min_10 = min(self.multiworld.min_levels_in_10[self.player], max_10) - weapon_level_percentage = self.multiworld.randomize_weapon_level_percentage[self.player] + weapon_level_percentage = self.options.randomize_weapon_level_percentage if self.multiworld.random.randint(0, 99) < weapon_level_percentage: if data.category.upgrade_level == 5: @@ -428,8 +419,8 @@ def create_item(self, item: Union[str, DS3ItemData]) -> Item: elif data.category.upgrade_level == 10: data = data.upgrade(self.multiworld.random.randint(min_10, max_10)) - if self.multiworld.randomize_infusion[self.player] and data.category.is_infusible: - infusion_percentage = self.multiworld.randomize_infusion_percentage[self.player] + if self.options.randomize_infusion and data.category.is_infusible: + infusion_percentage = self.options.randomize_infusion_percentage if self.multiworld.random.randint(0, 99) < infusion_percentage: data = data.infuse(self.multiworld.random.choice(list(Infusion))) @@ -462,21 +453,21 @@ def set_rules(self) -> None: state.has("Cinders of a Lord - Aldrich", self.player) and state.has("Cinders of a Lord - Lothric Prince", self.player)) - if self.multiworld.late_basin_of_vows[self.player] == Toggle.option_true: + if self.options.late_basin_of_vows: self._add_entrance_rule("Lothric Castle", "Small Lothric Banner") # DLC Access Rules Below - if self.multiworld.enable_dlc[self.player]: + if self.options.enable_dlc: self._add_entrance_rule("Painted World of Ariandel (Before Contraption)", "CD -> PW1") self._add_entrance_rule("Painted World of Ariandel (After Contraption)", "Contraption Key") self._add_entrance_rule("Dreg Heap", "PW2 -> DH") self._add_entrance_rule("Ringed City", "Small Envoy Banner") - if self.multiworld.late_dlc[self.player]: + if self.options.late_dlc: self._add_entrance_rule("Painted World of Ariandel (After Contraption)", "Small Doll") # Define the access rules to some specific locations - if self.multiworld.enable_key_locations[self.player]: + if self.options.enable_key_locations: self._add_location_rule("HWL: Red Eye Orb", "Lift Chamber Key") self._add_location_rule("ID: Bellowing Dragoncrest Ring", "Jailbreaker's Key") self._add_location_rule("ID: Covetous Gold Serpent Ring", "Old Cell Key") @@ -593,14 +584,14 @@ def has_any_scroll(state): self._add_location_rule("FK: Cinders of a Lord - Abyss Watcher", has_any_scroll) self._add_entrance_rule("Catacombs of Carthus", has_any_scroll) # Not really necessary but ensures players can decide which way to go - if dlc_enabled: + if self.options.enable_dlc: self._add_entrance_rule("Painted World of Ariandel (After Contraption)", has_any_scroll) self._add_location_rule("HWL: Soul of the Dancer", "Basin of Vows") # Lump Soul of the Dancer in with LC for locations that should not be reachable # before having access to US. (Prevents requiring getting Basin to fight Dancer to get SLB to go to US) - if self.multiworld.late_basin_of_vows[self.player]: + if self.options.late_basin_of_vows: self._add_location_rule("HWL: Soul of the Dancer", "Small Lothric Banner") # This isn't really necessary, but it ensures that the game logic knows players will # want to do Lothric Castle after at least being _able_ to access Catacombs. This is @@ -677,9 +668,9 @@ def is_location_available(self, location: Union[str, DS3LocationData]) -> bool: return ( data.category in self.enabled_location_categories and - (not data.npc or self.multiworld.enable_npc_locations[self.player] == Toggle.option_true) and - (not data.dlc or self.multiworld.enable_dlc[self.player] == Toggle.option_true) and - (not data.ngp or self.multiworld.enable_ngp[self.player] == Toggle.option_true) + (not data.npc or self.options.enable_npc_locations) and + (not data.dlc or self.options.enable_dlc) and + (not data.ngp or self.options.enable_ngp) ) @@ -701,7 +692,7 @@ def pre_fill(self) -> None: self._fill_local_item("Coiled Sword", {"Cemetery of Ash", "Firelink Shrine"}) # If upgrade smoothing is enabled, make sure one raw gem is available early for SL1 players - if self.multiworld.upgrade_locations[self.player] == UpgradeLocationsOption.option_smooth: + if self.options.upgrade_locations == "smooth": self._fill_local_item("Raw Gem", { "Cemetery of Ash", "Firelink Shrine", @@ -828,7 +819,7 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: location.item = new_item new_item.location = location - if self.multiworld.upgrade_locations[self.player] == UpgradeLocationsOption.option_smooth: + if self.options.upgrade_locations == "smooth": base_names = { "Titanite Shard", "Large Titanite Shard", "Titanite Chunk", "Titanite Slab", "Titanite Scale", "Twinkling Titanite", "Farron Coal", "Sage's Coal", "Giant's Coal", @@ -836,7 +827,7 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: } smooth_items([item for item in all_item_order if item.base_name in base_names]) - if self.multiworld.soul_locations[self.player] == SoulLocationsOption.option_smooth: + if self.options.soul_locations == "smooth": # Shuffle larger boss souls among themselves because they're all worth 10-20k souls in # no particular order and that's a lot more interesting than getting them in the same # order every single run. @@ -854,7 +845,7 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: item_order.append(item) smooth_items(item_order) - if self.multiworld.upgraded_weapon_locations[self.player] == UpgradedWeaponLocationsOption.option_smooth: + if self.options.upgraded_weapon_locations == "smooth": upgraded_weapons = [ location.item for location in self.multiworld.get_filled_locations() @@ -918,31 +909,31 @@ def fill_slot_data(self) -> Dict[str, object]: slot_data = { "options": { - "random_starting_loadout": self.multiworld.random_starting_loadout[self.player].value, - "require_one_handed_starting_weapons": self.multiworld.require_one_handed_starting_weapons[self.player].value, - "auto_equip": self.multiworld.auto_equip[self.player].value, - "lock_equip": self.multiworld.lock_equip[self.player].value, - "no_weapon_requirements": self.multiworld.no_weapon_requirements[self.player].value, - "death_link": self.multiworld.death_link[self.player].value, - "no_spell_requirements": self.multiworld.no_spell_requirements[self.player].value, - "no_equip_load": self.multiworld.no_equip_load[self.player].value, - "enable_dlc": self.multiworld.enable_dlc[self.player].value, - "enable_ngp": self.multiworld.enable_ngp[self.player].value, - "smooth_soul_locations": self.multiworld.soul_locations[self.player].value == SoulLocationsOption.option_smooth, - "smooth_upgrade_locations": self.multiworld.upgrade_locations[self.player].value == UpgradeLocationsOption.option_smooth, - "randomize_enemies": self.multiworld.randomize_enemies[self.player].value, - "randomize_mimics_with_enemies": self.multiworld.randomize_mimics_with_enemies[self.player].value, - "randomize_small_crystal_lizards_with_enemies": self.multiworld.randomize_small_crystal_lizards_with_enemies[self.player].value, - "reduce_harmless_enemies": self.multiworld.reduce_harmless_enemies[self.player].value, - "simple_early_bosses": self.multiworld.simple_early_bosses[self.player].value, - "scale_enemies": self.multiworld.scale_enemies[self.player].value, - "all_chests_are_mimics": self.multiworld.all_chests_are_mimics[self.player].value, - "impatient_mimics": self.multiworld.impatient_mimics[self.player].value, + "random_starting_loadout": self.options.random_starting_loadout.value, + "require_one_handed_starting_weapons": self.options.require_one_handed_starting_weapons.value, + "auto_equip": self.options.auto_equip.value, + "lock_equip": self.options.lock_equip.value, + "no_weapon_requirements": self.options.no_weapon_requirements.value, + "death_link": self.options.death_link.value, + "no_spell_requirements": self.options.no_spell_requirements.value, + "no_equip_load": self.options.no_equip_load.value, + "enable_dlc": self.options.enable_dlc.value, + "enable_ngp": self.options.enable_ngp.value, + "smooth_soul_locations": self.options.soul_locations == "smooth", + "smooth_upgrade_locations": self.options.upgrade_locations == "smooth", + "randomize_enemies": self.options.randomize_enemies.value, + "randomize_mimics_with_enemies": self.options.randomize_mimics_with_enemies.value, + "randomize_small_crystal_lizards_with_enemies": self.options.randomize_small_crystal_lizards_with_enemies.value, + "reduce_harmless_enemies": self.options.reduce_harmless_enemies.value, + "simple_early_bosses": self.options.simple_early_bosses.value, + "scale_enemies": self.options.scale_enemies.value, + "all_chests_are_mimics": self.options.all_chests_are_mimics.value, + "impatient_mimics": self.options.impatient_mimics.value, }, "seed": self.multiworld.seed_name, # to verify the server's multiworld "slot": self.multiworld.player_name[self.player], # to connect to server # Reserializing here is silly, but it's easier for the offline randomizer. - "random_enemy_preset": json.dumps(self.multiworld.random_enemy_preset[self.player].value), + "random_enemy_preset": json.dumps(self.options.random_enemy_preset.value), "yhorm": ( f"{self.yhorm_location.name} {self.yhorm_location.id}" if self.yhorm_location != default_yhorm_location From 69daec4deb0461a91f7f598748b4f34e6b57f9d1 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 2 Dec 2023 20:04:46 -0800 Subject: [PATCH 095/238] Bump data_version --- worlds/dark_souls_3/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 46d417b7e6ba..39adce753f7e 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -51,7 +51,7 @@ class DarkSouls3World(World): options_dataclass = DarkSouls3Options topology_present: bool = True web = DarkSouls3Web() - data_version = 8 + data_version = 9 base_id = 100000 enabled_location_categories: Set[DS3LocationCategory] required_client_version = (0, 4, 2) From 904a58dd12fcc4c3ccedc049b43a1a45c747f7b4 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 2 Dec 2023 21:13:14 -0800 Subject: [PATCH 096/238] Mention where Yhorm is in which world --- worlds/dark_souls_3/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 39adce753f7e..137ed42c52fd 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -676,7 +676,9 @@ def is_location_available(self, location: Union[str, DS3LocationData]) -> bool: def write_spoiler(self, spoiler_handle: TextIO) -> None: if self.yhorm_location != default_yhorm_location: - spoiler_handle.write(f"Yhorm takes the place of {self.yhorm_location.name}") + spoiler_handle.write( + f"Yhorm takes the place of {self.yhorm_location.name} in " + + f"{self.multiworld.get_player_name(self.player)}'s world") def pre_fill(self) -> None: From 9bb38a936d1e8cb5cb2cc51fee022d7cb187c03c Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 2 Dec 2023 21:13:58 -0800 Subject: [PATCH 097/238] Better handle excluded events --- worlds/dark_souls_3/Locations.py | 8 ++++++-- worlds/dark_souls_3/__init__.py | 11 +++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 098246b110a3..8f6561e2546e 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -245,9 +245,13 @@ def __init__( data: DS3LocationData, parent: Optional[Region] = None, event: bool = False): - super().__init__(player, data.name, None if event else data.ap_code, parent) + super().__init__( + player, + data.name + (" Obtained" if event else ""), + None if event else data.ap_code, + parent) self.data = data - if data.missable: self.progress_type = LocationProgressType.EXCLUDED + if data.missable and not event: self.progress_type = LocationProgressType.EXCLUDED location_tables = { diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 137ed42c52fd..25ec31a814a9 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -271,16 +271,15 @@ def create_region(self, region_name, location_table) -> Region: if not self.options.enable_key_locations and location.name == "HWL: Red Eye Orb": new_location.progress_type = LocationProgressType.EXCLUDED else: - # Replace non-randomized progression items with events if their locations aren't - # missable. Avoiding missable locations prevents issues where, for example, NPC - # locations aren't randomized and so Yhorm is technically defeatable without the - # normal Storm Ruler drop because you can get it from Siegward. + # Don't allow Siegward's Storm Ruler to mark Yhorm as defeatable. + if location.name == "PC: Storm Ruler (Siegward)": continue + + # Replace non-randomized progression items with events event_item = ( self.create_item(location.default_item_name) if location.default_item_name else DarkSouls3Item.event(location.name, self.player) ) - if location.missable or event_item.classification != ItemClassification.progression: - continue + if event_item.classification != ItemClassification.progression: continue new_location = DarkSouls3Location( self.player, From f088082879c8b4a321a4c0f310e70f6c0fe04871 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 2 Dec 2023 21:27:48 -0800 Subject: [PATCH 098/238] Add a newline to Yhorm location --- worlds/dark_souls_3/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 25ec31a814a9..9424a6462274 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -677,7 +677,7 @@ def write_spoiler(self, spoiler_handle: TextIO) -> None: if self.yhorm_location != default_yhorm_location: spoiler_handle.write( f"Yhorm takes the place of {self.yhorm_location.name} in " + - f"{self.multiworld.get_player_name(self.player)}'s world") + f"{self.multiworld.get_player_name(self.player)}'s world\n") def pre_fill(self) -> None: From c29f6514d90b546d8feeacf9f8b3407d49fdb151 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 2 Dec 2023 21:57:07 -0800 Subject: [PATCH 099/238] Better way of handling excluded unradomized progression locations --- worlds/dark_souls_3/Locations.py | 6 +--- worlds/dark_souls_3/__init__.py | 62 +++++++++++++++++++------------- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 8f6561e2546e..cd557056d656 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -245,11 +245,7 @@ def __init__( data: DS3LocationData, parent: Optional[Region] = None, event: bool = False): - super().__init__( - player, - data.name + (" Obtained" if event else ""), - None if event else data.ap_code, - parent) + super().__init__(player, data.name, None if event else data.ap_code, parent) self.data = data if data.missable and not event: self.progress_type = LocationProgressType.EXCLUDED diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 9424a6462274..96d79e774304 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -153,17 +153,17 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: ): return False - # There are only a few locations before Iudex Gundyr, and none of them are weapons, so if - # they can't be random don't allow Yhorm in there. - if ( - boss.name == "Iudex Gundyr" - and not self.options.enable_misc_locations - and self.options.upgrade_locations == "not_randomized" - and self.options.soul_locations == "not_randomized" - ): - return False - - return True + if boss.name != "Iudex Gundyr": return True + + # Cemetery of Ash has very few locations and all of them are excluded by default, so only + # allow Yhorm as Iudex Gundyr if there's at least one available location. + excluded = self.multiworld.exclude_locations[self.player].value + return any( + self.is_location_available(location) + and location.name not in excluded + and location.name != "CA: Coiled Sword" + for location in location_tables["Cemetery of Ash"] + ) def create_regions(self): @@ -258,6 +258,10 @@ def create_connection(from_region: str, to_region: str): def create_region(self, region_name, location_table) -> Region: new_region = Region(region_name, self.player, self.multiworld) + # Use this to un-exclude event locations so the fill doesn't complain about items behind + # them being unreachable. + excluded = self.multiworld.exclude_locations[self.player].value + for location in location_table: if self.is_location_available(location): new_location = DarkSouls3Location( @@ -289,6 +293,7 @@ def create_region(self, region_name, location_table) -> Region: ) event_item.code = None new_location.place_locked_item(event_item) + if location.name in excluded: excluded.remove(location.name) if region_name == "Menu": add_item_rule(new_location, lambda item: not item.advancement) @@ -685,7 +690,8 @@ def pre_fill(self) -> None: # doesn't get locked out by bad rolls on the next two fills. if self.yhorm_location.name == 'Iudex Gundyr': self._fill_local_item("Storm Ruler", {"Cemetery of Ash"}, - lambda location: location.name != "CA: Coiled Sword") + lambda location: location.name != "CA: Coiled Sword", + mandatory = True) # Don't place this in the multiworld because it's necessary almost immediately, and don't # mark it as a blocker for HWL because having a miniscule Sphere 1 screws with progression @@ -704,12 +710,15 @@ def pre_fill(self) -> None: def _fill_local_item( self, name: str, regions: Set[str], - additional_condition: Optional[Callable[[DarkSouls3Location], bool]] = None + additional_condition: Optional[Callable[[DarkSouls3Location], bool]] = None, + mandatory = False, ) -> None: """Chooses a valid location for the item with the given name and places it there. This always chooses a local location among the given regions. If additional_condition is passed, only locations meeting that condition will be considered. + + If mandatory is True, this will throw an error if the item could not be filled in. """ item = next( ( @@ -721,19 +730,24 @@ def _fill_local_item( if not item: return candidate_locations = [ - self.multiworld.get_location(location.name, self.player) - for region in regions - for location in location_tables[region] - if self.is_location_available(location) - and not location.missable - and not location.conditional - and (not additional_condition or additional_condition(location)) - ] - location = self.multiworld.random.choice([ - location for location in candidate_locations + location for location in ( + self.multiworld.get_location(location.name, self.player) + for region in regions + for location in location_tables[region] + if self.is_location_available(location) + and not location.missable + and not location.conditional + and (not additional_condition or additional_condition(location)) + ) if not location.item and location.progress_type != LocationProgressType.EXCLUDED and location.item_rule(item) - ]) + ] + + if not candidate_locations: + if not mandatory: return + raise Exception(f"No valid locations to place {name}") + + location = self.multiworld.random.choice(candidate_locations) location.place_locked_item(item) self.multiworld.itempool.remove(item) From 5b33e79b4c89d61192e2e2b31faf49fbde6ca57f Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 3 Dec 2023 00:40:02 -0800 Subject: [PATCH 100/238] Fix a squidge of nondeterminism --- worlds/dark_souls_3/__init__.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 96d79e774304..27fa2597bc81 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -689,27 +689,27 @@ def pre_fill(self) -> None: # Fill this manually so that, if very few slots are available in Cemetery of Ash, this # doesn't get locked out by bad rolls on the next two fills. if self.yhorm_location.name == 'Iudex Gundyr': - self._fill_local_item("Storm Ruler", {"Cemetery of Ash"}, + self._fill_local_item("Storm Ruler", ["Cemetery of Ash"], lambda location: location.name != "CA: Coiled Sword", mandatory = True) # Don't place this in the multiworld because it's necessary almost immediately, and don't # mark it as a blocker for HWL because having a miniscule Sphere 1 screws with progression # balancing. - self._fill_local_item("Coiled Sword", {"Cemetery of Ash", "Firelink Shrine"}) + self._fill_local_item("Coiled Sword", ["Cemetery of Ash", "Firelink Shrine"]) # If upgrade smoothing is enabled, make sure one raw gem is available early for SL1 players if self.options.upgrade_locations == "smooth": - self._fill_local_item("Raw Gem", { + self._fill_local_item("Raw Gem", [ "Cemetery of Ash", "Firelink Shrine", "High Wall of Lothric" - }) + ]) def _fill_local_item( self, name: str, - regions: Set[str], + regions: List[str], additional_condition: Optional[Callable[[DarkSouls3Location], bool]] = None, mandatory = False, ) -> None: @@ -767,7 +767,7 @@ def post_fill(self): while len(unchecked_locations) > 0: sphere_locations = {loc for loc in unchecked_locations if state.can_reach(loc)} - locations_by_sphere.append(self._shuffle(sphere_locations)) + locations_by_sphere.append(self._shuffle(sorted(sphere_locations))) old_length = len(unchecked_locations) unchecked_locations.difference_update(sphere_locations) @@ -846,11 +846,11 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: # Shuffle larger boss souls among themselves because they're all worth 10-20k souls in # no particular order and that's a lot more interesting than getting them in the same # order every single run. - shuffled = { + shuffled_order = self._shuffle([ item.name for item in item_dictionary.values() if item.category == DS3ItemCategory.BOSS and item.souls and item.souls >= 10000 - } - shuffled_order = self._shuffle(shuffled) + ]) + shuffled = set(shuffled_order) item_order: List[DS3ItemData] = [] for item in all_item_order: if not item.souls: continue @@ -871,7 +871,7 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: smooth_items(upgraded_weapons) - def _shuffle(self, seq: Sequence) -> Sequence: + def _shuffle(self, seq: Sequence) -> List: """Returns a shuffled copy of a sequence.""" copy = list(seq) self.multiworld.random.shuffle(copy) From 5dd393498842000988b9b59b089c7b6c0cdf41fd Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 3 Dec 2023 00:51:57 -0800 Subject: [PATCH 101/238] Only smooth items from this world --- worlds/dark_souls_3/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 27fa2597bc81..ff4673190c0d 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -786,10 +786,11 @@ def post_fill(self): if self.is_location_available(location) ] - # All DarkSouls3Items that have been assigned anywhere, grouped by name + # All DarkSouls3Items for this world that have been assigned anywhere, grouped by name full_items_by_name = defaultdict(list) for location in self.multiworld.get_filled_locations(): - full_items_by_name[location.item.name].append(location.item) + if location.item.player == self.player: + full_items_by_name[location.item.name].append(location.item) def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: """Rearrange all items in item_order to match that order. @@ -823,8 +824,7 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: ] # Check the game, not the player, because we know how to sort within regions for DS3 - offworld = [loc for loc in locations if loc.game != "Dark Souls III"] - self.multiworld.random.shuffle(offworld) + offworld = self._shuffle(loc for loc in locations if loc.game != "Dark Souls III") onworld = sorted((loc for loc in locations if loc.game == "Dark Souls III"), key=lambda loc: loc.data.region_value) From 417181f33fcc5d7d6d2cd0786df9a91804d54053 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 3 Dec 2023 01:26:25 -0800 Subject: [PATCH 102/238] Don't smooth progression weapons --- worlds/dark_souls_3/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index ff4673190c0d..36410f3d87f2 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -866,6 +866,7 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: for location in self.multiworld.get_filled_locations() if location.item.player == self.player and location.item.level and location.item.level > 0 + and location.item.classification != ItemClassification.progression ] upgraded_weapons.sort(key=lambda item: item.level) smooth_items(upgraded_weapons) From a9622a53075413dec58e889e316e14d4f4ee1dd3 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 4 Dec 2023 19:31:48 -0800 Subject: [PATCH 103/238] Remove a location that doesn't actually exist in-game --- worlds/dark_souls_3/Locations.py | 1 - 1 file changed, 1 deletion(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index cd557056d656..d2ba9601ad47 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1508,7 +1508,6 @@ def __init__( DS3LocationData("ID: Xanthous Ashes", "Xanthous Ashes", DS3LocationCategory.KEY, progression = True), DS3LocationData("ID: Rusted Gold Coin", "Rusted Gold Coin", DS3LocationCategory.MISC), - DS3LocationData("ID: Large Titanite Shard #6", "Large Titanite Shard", DS3LocationCategory.UPGRADE), DS3LocationData("ID: Old Cell Key", "Old Cell Key", DS3LocationCategory.KEY, key = True), DS3LocationData("ID: Covetous Silver Serpent Ring+1", "Covetous Silver Serpent Ring+1", DS3LocationCategory.RING, From 2d0c899104e6802681ac68ee4e5e112a8687118a Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 4 Dec 2023 19:33:45 -0800 Subject: [PATCH 104/238] Classify Power Within as useful --- worlds/dark_souls_3/Items.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 2d7886a5cff1..ac74a8a6e6b0 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -1308,7 +1308,8 @@ def flatten(l): DS3ItemData("Carthus Flame Arc", 0x402527B8, DS3ItemCategory.SPELL), DS3ItemData("Rapport", 0x40252BA0, DS3ItemCategory.SPELL, classification = ItemClassification.useful), - DS3ItemData("Power Within", 0x40253B40, DS3ItemCategory.SPELL), + DS3ItemData("Power Within", 0x40253B40, DS3ItemCategory.SPELL, + classification = ItemClassification.useful), DS3ItemData("Great Chaos Fire Orb", 0x40256250, DS3ItemCategory.SPELL), DS3ItemData("Chaos Storm", 0x40256638, DS3ItemCategory.SPELL), DS3ItemData("Fire Whip", 0x40256A20, DS3ItemCategory.SPELL), From fe75133c3114625e7e47d4e2131bc2ebca1ec3d5 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 30 Nov 2023 18:59:17 -0800 Subject: [PATCH 105/238] Clarify location names --- worlds/dark_souls_3/Bosses.py | 197 +- worlds/dark_souls_3/Items.py | 58 +- worlds/dark_souls_3/Locations.py | 5342 ++++++++++------- worlds/dark_souls_3/__init__.py | 348 +- .../detailed_location_descriptions.py | 94 + worlds/dark_souls_3/docs/en_Dark Souls III.md | 8 +- worlds/dark_souls_3/docs/locations.md | 650 ++ worlds/dark_souls_3/docs/locations_en.md | 2166 +++++++ 8 files changed, 6465 insertions(+), 2398 deletions(-) create mode 100644 worlds/dark_souls_3/detailed_location_descriptions.py create mode 100644 worlds/dark_souls_3/docs/locations.md create mode 100644 worlds/dark_souls_3/docs/locations_en.md diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index 9a6cc35d7d36..aa93480b8556 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -36,42 +36,47 @@ class DS3BossInfo: # of which can be individually replaced by Yhorm. all_bosses = [ DS3BossInfo("Iudex Gundyr", 4000800, before_storm_ruler = True, region = "Firelink Shrine", - locations = {"CA: Coiled Sword"}), + locations = {"CA: Coiled Sword (boss drop)"}), DS3BossInfo("Vordt of the Boreal Valley", 3000800, before_storm_ruler = True, region = "Undead Settlement", locations = {"HWL: Soul of Boreal Valley Vordt"}), DS3BossInfo("Curse-rotted Greatwood", 3100800, locations = { "US: Soul of the Rotted Greatwood", - "US: Transposing Kiln", - "US: Wargod Wooden Shield", + "US: Transposing Kiln (boss drop)", + "US: Wargod Wooden Shield (Pit of Hollows)", + "FS: Hawkwood's Shield (Hawkwood)", }), DS3BossInfo("Crystal Sage", 3300850, region = "Cathedral of the Deep", locations = { "RS: Soul of a Crystal Sage", - "RS: Sage's Big Hat", + "FS: Sage's Big Hat (shop after killing RS boss)", + "FS: Hawkwood's Shield (Hawkwood)", }), DS3BossInfo("Deacons of the Deep", 3500800, locations = { "CD: Soul of the Deacons of the Deep", - "CD: Small Doll", + "CD: Small Doll (boss drop)", + "FS: Hawkwood's Shield (Hawkwood)", }), DS3BossInfo("Abyss Watchers", 3300801, before_storm_ruler = True, region = "Catacombs of Carthus", locations = { "FK: Soul of the Blood of the Wolf", "FK: Cinders of a Lord - Abyss Watcher", - "UG: Hornet Ring", - "FK: Undead Legion Helm", - "FK: Undead Legion Armor", - "FK: Undead Legion Gauntlet", - "FK: Undead Legion Leggings", - "UG: Wolf Knight Helm", - "UG: Wolf Knight Armor", - "UG: Wolf Knight Gauntlets", - "UG: Wolf Knight Leggings", + "UG: Hornet Ring (environs, right of main path)", + "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)", + "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)", + "FS: Farron Ring (Hawkwood)", + "FS: Hawkwood's Shield (Hawkwood)", }), DS3BossInfo("High Lord Wolnir", 3800800, before_storm_ruler = True, region = "Irithyll of the Boreal Valley", locations = { "CC: Soul of High Lord Wolnir", - "CC: Wolnir's Crown", - "CC: Homeward Bone", - "CC: Pontiff's Right Eye", + "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, region = "Anor Londo", locations = { "IBV: Soul of Pontiff Sulyvahn", @@ -82,49 +87,59 @@ class DS3BossInfo: DS3BossInfo("Aldrich, Devourer of Men", 3700800, locations = { "AL: Soul of Aldrich", "AL: Cinders of a Lord - Aldrich", - "AL: Smough's Helm", - "AL: Smough's Armor", - "AL: Smough's Gauntlets", - "AL: Smough's Leggings", - "AL: Sun Princess Ring", + "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, region = "Lothric Castle", 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, region = "Grand Archives", locations = { "LC: Soul of Dragonslayer Armour", - "LC: Morne's Helm", - "LC: Morne's Armor", - "LC: Morne's Gauntlets", - "LC: Morne's Leggings", - "LC: Titanite Chunk #11", + "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, region = "Untended Graves", locations = { "CKG: Soul of Consumed Oceiros", - "CKG: Titanite Scale #2", - "CKG: Titanite Scale #3", + "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", - "UG: Gundyr's Helm", - "UG: Gundyr's Armor", - "UG: Gundyr's Gauntlets", - "UG: Gundyr's Leggings", - "UG: Hornet Ring", - "UG: Chaos Blade", - "UG: Blacksmith Hammer", - "UG: Eyes of a Fire Keeper", - "UG: Coiled Sword Fragment", - "UG: Soul of a Crestfallen Knight #2", - "UG: Life Ring+3", - "UG: Ring of Steel Protection+1", - "UG: Ring of Sacrifice", - "UG: Ring of Sacrifice", - "UG: Ember", - "UG: Wolf Knight Helm", - "UG: Wolf Knight Armor", - "UG: Wolf Knight Gauntlets", - "UG: Wolf Knight Leggings", + "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)", + "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: 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)", }), # This is a white lie, you can get to a bunch of items in AP before you beat the Wyvern, but # this saves us from having to split the entire region in two just to mark which specific items @@ -132,23 +147,29 @@ class DS3BossInfo: DS3BossInfo("Ancient Wyvern", 3200800, region = "Archdragon Peak"), DS3BossInfo("King of the Storm", 3200850, locations = { "AP: Soul of the Nameless King", - "AP: Golden Crown", - "AP: Dragonscale Armor", - "AP: Golden Bracelets", - "AP: Dragonscale Waistcloth", - "AP: Titanite Slab #2", - + "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", - "AP: Golden Crown", - "AP: Dragonscale Armor", - "AP: Golden Bracelets", - "AP: Dragonscale Waistcloth", - "AP: Dragonslayer Helm", - "AP: Dragonslayer Armor", - "AP: Dragonslayer Gauntlets", - "AP: Dragonslayer Leggings", + "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("Lorian, Elder Prince", 3410830, locations = { "GA: Soul of the Twin Princes", @@ -157,51 +178,56 @@ class DS3BossInfo: DS3BossInfo("Lothric, Younger Prince", 3410832, locations = { "GA: Soul of the Twin Princes", "GA: Cinders of a Lord - Lothric Prince", - "GA: Lorian's Helm", - "GA: Lorian's Armor", - "GA: Lorian's Gauntlets", - "GA: Lorian's Leggings", + "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", - "PW1: Champion's Bones", + "PW1: Valorheart (boss drop)", + "PW1: Champion's Bones (boss drop)", }), DS3BossInfo("Sister Friede", 4500801, dlc = True, region = "Dreg Heap", locations = { "PW2: Soul of Sister Friede", - "PW2: Titanite Slab (Friede)", - "PW2: Ordained Hood", - "PW2: Ordained Dress", - "PW2: Ordained Trousers", + "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, region = "Dreg Heap", locations = { "PW2: Soul of Sister Friede", - "PW2: Ordained Hood", - "PW2: Ordained Dress", - "PW2: Ordained Trousers", + "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, region = "Ringed City", locations = { "DH: Soul of the Demon Prince", - "DH: Small Envoy Banner", + "DH: Small Envoy Banner (boss drop)", }), DS3BossInfo("Halflight, Spear of the Church", 5100800, dlc = True, locations = { - "RC: Titanite Slab #1", - "RC: Titanite Slab #2", - "RC: Titanite Slab #3", - "RC: Filianore's Spear Ornament", - "RC: Sacred Chime of Filianore", - "RC: Crucifix of the Mad King", + "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", + "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", + "RC: Blood of the Dark Soul (end boss drop)", }), DS3BossInfo("Slave Knight Gael 2", 5110800, dlc = True, locations = { "RC: Soul of Slave Knight Gael", - "RC: Blood of the Dark Soul", + "RC: Blood of the Dark Soul (end boss drop)", }), DS3BossInfo("Soul of Cinder", 4100800), ] @@ -209,4 +235,5 @@ class DS3BossInfo: 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)", }) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index ac74a8a6e6b0..c1f6d391bb93 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -1082,50 +1082,49 @@ def flatten(l): DS3ItemData("I'm sorry Carving", 0x4000020B, DS3ItemCategory.SKIP), DS3ItemData("Help me! Carving", 0x4000020C, DS3ItemCategory.SKIP), DS3ItemData("Soul of Champion Gundyr", 0x400002C8, DS3ItemCategory.BOSS, souls = 20000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of the Dancer", 0x400002CA, DS3ItemCategory.BOSS, souls = 10000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of a Crystal Sage", 0x400002CB, DS3ItemCategory.BOSS, souls = 3000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of the Blood of the Wolf", 0x400002CD, DS3ItemCategory.BOSS, souls = 20000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of Consumed Oceiros", 0x400002CE, DS3ItemCategory.BOSS, souls = 12000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of Boreal Valley Vordt", 0x400002CF, DS3ItemCategory.BOSS, souls = 2000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of the Old Demon King", 0x400002D0, DS3ItemCategory.BOSS, souls = 10000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of Dragonslayer Armour", 0x400002D1, DS3ItemCategory.BOSS, souls = 15000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of the Nameless King", 0x400002D2, DS3ItemCategory.BOSS, souls = 16000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of Pontiff Sulyvahn", 0x400002D4, DS3ItemCategory.BOSS, souls = 12000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of Aldrich", 0x400002D5, DS3ItemCategory.BOSS, souls = 15000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of High Lord Wolnir", 0x400002D6, DS3ItemCategory.BOSS, souls = 10000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of the Rotted Greatwood", 0x400002D7, DS3ItemCategory.BOSS, souls = 3000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of Rosaria", 0x400002D8, DS3ItemCategory.MISC, souls = 5000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of the Deacons of the Deep", 0x400002D9, DS3ItemCategory.BOSS, souls = 20000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of the Twin Princes", 0x400002DB, DS3ItemCategory.BOSS, souls = 20000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of Yhorm the Giant", 0x400002DC, DS3ItemCategory.BOSS, souls = 20000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of the Lords", 0x400002DD, DS3ItemCategory.MISC, souls = 20000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of a Demon", 0x400002E3, DS3ItemCategory.BOSS, souls = 20000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Soul of a Stray Demon", 0x400002E7, DS3ItemCategory.BOSS, souls = 20000, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Titanite Shard", 0x400003E8, DS3ItemCategory.MISC).counts([2]), DS3ItemData("Large Titanite Shard", 0x400003E9, DS3ItemCategory.MISC).counts([2, 3]), DS3ItemData("Titanite Chunk", 0x400003EA, DS3ItemCategory.MISC).counts([2, 6]), - DS3ItemData("Titanite Slab", 0x400003EB, DS3ItemCategory.MISC, - classification = ItemClassification.useful), + DS3ItemData("Titanite Slab", 0x400003EB, DS3ItemCategory.MISC), DS3ItemData("Titanite Scale", 0x400003FC, DS3ItemCategory.MISC).counts([2, 3]), DS3ItemData("Twinkling Titanite", 0x40000406, DS3ItemCategory.MISC).counts([2, 3]), DS3ItemData("Heavy Gem", 0x4000044C, DS3ItemCategory.MISC), @@ -1280,7 +1279,8 @@ def flatten(l): DS3ItemData("Repair", 0x4014A528, DS3ItemCategory.SPELL), DS3ItemData("Spook", 0x4014A910, DS3ItemCategory.SPELL, classification = ItemClassification.useful), - DS3ItemData("Chameleon", 0x4014ACF8, DS3ItemCategory.SPELL), + DS3ItemData("Chameleon", 0x4014ACF8, DS3ItemCategory.SPELL, + classification = ItemClassification.progression), DS3ItemData("Aural Decoy", 0x4014B0E0, DS3ItemCategory.SPELL), DS3ItemData("White Dragon Breath", 0x4014E790, DS3ItemCategory.SPELL), DS3ItemData("Farron Hail", 0x4014EF60, DS3ItemCategory.SPELL), @@ -1494,10 +1494,14 @@ def flatten(l): DS3ItemData("Filianore's Spear Ornament", 0x4000017B, DS3ItemCategory.SKIP), DS3ItemData("Ritual Spear Fragment", 0x4000028A, DS3ItemCategory.SKIP), DS3ItemData("Divine Spear Fragment", 0x4000028B, DS3ItemCategory.SKIP), - DS3ItemData("Soul of Sister Friede", 0x400002E8, DS3ItemCategory.BOSS, souls = 20000), - DS3ItemData("Soul of Slave Knight Gael", 0x400002E9, DS3ItemCategory.BOSS, souls = 20000), - DS3ItemData("Soul of the Demon Prince", 0x400002EA, DS3ItemCategory.BOSS, souls = 20000), - DS3ItemData("Soul of Darkeater Midir", 0x400002EB, DS3ItemCategory.BOSS, souls = 20000), + DS3ItemData("Soul of Sister Friede", 0x400002E8, DS3ItemCategory.BOSS, souls = 20000, + classification = ItemClassification.progression), + DS3ItemData("Soul of Slave Knight Gael", 0x400002E9, DS3ItemCategory.BOSS, souls = 20000, + classification = ItemClassification.progression), + DS3ItemData("Soul of the Demon Prince", 0x400002EA, DS3ItemCategory.BOSS, souls = 20000, + classification = ItemClassification.progression), + DS3ItemData("Soul of Darkeater Midir", 0x400002EB, DS3ItemCategory.BOSS, souls = 20000, + classification = ItemClassification.progression), DS3ItemData("Champion's Bones", 0x40000869, DS3ItemCategory.SKIP), DS3ItemData("Captain's Ashes", 0x4000086A, DS3ItemCategory.MISC, classification = ItemClassification.progression), diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index d2ba9601ad47..7f019c4afa7e 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -90,7 +90,7 @@ class DS3LocationData: default_item_name: Optional[str] """The name of the item that appears by default in this location. - This should only ever by None for DS3LocationCategory.EVENT locations. + This should only ever be None for DS3LocationCategory.EVENT locations. """ category: DS3LocationCategory @@ -187,7 +187,11 @@ class DS3LocationData: """Whether this location is dropped by a (small) Crystal Lizard.""" shop: bool = False - """Whether this location appears in an NPC's shop.""" + """Whether this location can appear in an NPC's shop. + + Items like Lapp's Set which can appear both in the overworld and in a shop + should still be tagged as shop. + """ conditional: bool = False """Whether this location is conditional on a progression item. @@ -250,2496 +254,3450 @@ def __init__( if data.missable and not event: self.progress_type = LocationProgressType.EXCLUDED +# Naming conventions: +# +# * The regions in item names should match the physical region where the item is +# acquired, even if its logical region is different. For example, Irina's +# inventory appears in the "Undead Settlement" region because she's not +# accessible until there, but it begins with "FS:" because that's where her +# items are purchased. +# +# * Avoid using vanilla enemy placements as landmarks, because these are +# randomized by the enemizer by default. Instead, use generic terms like +# "mob", "boss", and "miniboss". +# +# * Location descriptions don't need to direct the player to the precise spot. +# You can assume the player is broadly familiar with Dark Souls III or willing +# to look at a vanilla guide. Just give a general area to look in or an idea +# of what quest a check is connected to. Terseness is valuable: try to keep +# each location description short enough that the whole line doesn't exceed +# 100 characters. +# +# * Use "[name] drop" for items that require killing an NPC who becomes hostile +# as part of their normal quest, "kill [name]" for items that require killing +# them even when they aren't hostile, and just "[name]" for items that are +# naturally available as part of their quest. location_tables = { "Cemetery of Ash": [ - DS3LocationData("CA: Soul of a Deserted Corpse", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("CA: Firebomb", "Firebomb x5", DS3LocationCategory.MISC), - DS3LocationData("CA: Titanite Shard", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("CA: Soul of an Unknown Traveler", "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("CA: Speckled Stoneplate Ring+1", "Speckled Stoneplate Ring+1", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("CA: Titanite Scale", "Titanite Scale", DS3LocationCategory.UPGRADE, - miniboss = True), - DS3LocationData("CA: Coiled Sword", "Coiled Sword", DS3LocationCategory.KEY, + DS3LocationData("CA: Soul of a Deserted Corpse (right of spawn)", + "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + DS3LocationData("CA: Firebomb (down the cliff edge)", "Firebomb x5", + DS3LocationCategory.MISC), + DS3LocationData("CA: Titanite Shard (jump to coffin)", "Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("CA: Soul of an Unknown Traveler (by miniboss)", + "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("CA: Speckled Stoneplate Ring+1 (by miniboss)", + "Speckled Stoneplate Ring+1", DS3LocationCategory.RING, ngp = True), + DS3LocationData("CA: Titanite Scale (miniboss drop)", "Titanite Scale", + DS3LocationCategory.UPGRADE, miniboss = True), + DS3LocationData("CA: Coiled Sword (boss drop)", "Coiled Sword", DS3LocationCategory.KEY, prominent = True, progression = True, boss = True), ], "Firelink Shrine": [ - DS3LocationData("FS: Skull Ring", "Skull Ring", DS3LocationCategory.RING, - hidden = True, drop = True, npc = True), # Ludleth drop, does not permanently die - DS3LocationData("FS: Uchigatana", "Uchigatana", DS3LocationCategory.WEAPON, - hostile_npc = True), # Sword Master drop - DS3LocationData("FS: Master's Attire", "Master's Attire", DS3LocationCategory.ARMOR, - hostile_npc = True), # Sword Master drop - DS3LocationData("FS: Master's Gloves", "Master's Gloves", DS3LocationCategory.ARMOR, + # Ludleth drop, does not permanently die + DS3LocationData("FS: Skull Ring (kill Ludleth)", "Skull Ring", DS3LocationCategory.RING, + hidden = True, drop = True, npc = True), + + # Sword Master drops + DS3LocationData("FS: Uchigatana (NPC drop)", "Uchigatana", DS3LocationCategory.WEAPON, hostile_npc = True), # Sword Master drop - DS3LocationData("FS: Broken Straight Sword", "Broken Straight Sword", DS3LocationCategory.WEAPON), - DS3LocationData("FS: Homeward Bone #1", "Homeward Bone", DS3LocationCategory.MISC), - DS3LocationData("FS: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("FS: Soul of a Deserted Corpse", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("FS: East-West Shield", "East-West Shield", DS3LocationCategory.SHIELD), - DS3LocationData("FS: Homeward Bone #2", "Homeward Bone", DS3LocationCategory.MISC), - DS3LocationData("FS: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("FS: Wolf Ring+2", "Wolf Ring+2", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("FS: Cracked Red Eye Orb", "Cracked Red Eye Orb x5", DS3LocationCategory.UNIQUE, - missable = True, npc = True), # Leonhard (quest) - DS3LocationData("FS: Lift Chamber Key", "Lift Chamber Key", DS3LocationCategory.KEY, - missable = True, npc = True, key = True, drop = True, ), # Leonhard (kill or quest) + DS3LocationData("FS: Master's Attire (NPC drop)", "Master's Attire", + DS3LocationCategory.ARMOR, hostile_npc = True), + DS3LocationData("FS: Master's Gloves (NPC drop)", "Master's Gloves", + DS3LocationCategory.ARMOR, hostile_npc = True), + + DS3LocationData("FS: Broken Straight Sword (gravestone after boss)", + "Broken Straight Sword", DS3LocationCategory.WEAPON), + DS3LocationData("FS: Homeward Bone (cliff edge after boss)", "Homeward Bone", + DS3LocationCategory.MISC), + DS3LocationData("FS: Ember (path right of Firelink entrance)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("FS: Soul of a Deserted Corpse (bell tower door)", + "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + DS3LocationData("FS: East-West Shield (tree by shrine entrance)", "East-West Shield", DS3LocationCategory.SHIELD), + DS3LocationData("FS: Homeward Bone (path above shrine entrace)", + "Homeward Bone", DS3LocationCategory.MISC), + DS3LocationData("FS: Ember (above shrine entrance)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("FS: Wolf Ring+2 (left of boss room exit)", "Wolf Ring+2", + DS3LocationCategory.RING, ngp = True), + # Leonhard (quest) + DS3LocationData("FS: Cracked Red Eye Orb (Leonhard)", "Cracked Red Eye Orb x5", + DS3LocationCategory.UNIQUE, missable = True, npc = True), + # Leonhard (kill or quest), missable because he can disappear sometimes + DS3LocationData("FS: Lift Chamber Key (Leonhard)", "Lift Chamber Key", + DS3LocationCategory.KEY, missable = True, npc = True, key = True, + drop = True), # Shrine Handmaid shop - DS3LocationData("FS: White Sign Soapstone", "White Sign Soapstone", DS3LocationCategory.UNIQUE, - shop = True), - DS3LocationData("FS: Dried Finger", "Dried Finger", DS3LocationCategory.UNIQUE, + DS3LocationData("FS: White Sign Soapstone (shop)", "White Sign Soapstone", + DS3LocationCategory.UNIQUE, shop = True), + DS3LocationData("FS: Dried Finger (shop)", "Dried Finger", DS3LocationCategory.UNIQUE, shop = True), - DS3LocationData("FS: Tower Key", "Tower Key", DS3LocationCategory.KEY, + DS3LocationData("FS: Tower Key (shop)", "Tower Key", DS3LocationCategory.KEY, progression = True, shop = True, key = True), - DS3LocationData("FS: Ember (Handmaid)", "Ember", DS3LocationCategory.MISC, + DS3LocationData("FS: Ember (shop)", "Ember", DS3LocationCategory.MISC, offline = '99,0:-1:110000:', shop = True), - DS3LocationData("FS: Farron Dart", "Farron Dart", DS3LocationCategory.SPELL, + DS3LocationData("FS: Farron Dart (shop)", "Farron Dart", DS3LocationCategory.SPELL, offline = '99,0:-1:110000:', shop = True), - DS3LocationData("FS: Soul Arrow", "Soul Arrow", DS3LocationCategory.SPELL, + DS3LocationData("FS: Soul Arrow (shop)", "Soul Arrow", DS3LocationCategory.SPELL, offline = '99,0:-1:110000:', shop = True), - DS3LocationData("FS: Heal Aid", "Heal Aid", DS3LocationCategory.SPELL, + DS3LocationData("FS: Heal Aid (shop)", "Heal Aid", DS3LocationCategory.SPELL, shop = True), - # Mortician's Ashes - DS3LocationData("FS: Alluring Skull", "Alluring Skull", DS3LocationCategory.MISC, - shop = True, conditional = True), - DS3LocationData("FS: Ember (Mortician)" , "Ember", DS3LocationCategory.MISC, + DS3LocationData("FS: Alluring Skull (Mortician's Ashes)", "Alluring Skull", + DS3LocationCategory.MISC, shop = True, conditional = True), + DS3LocationData("FS: Ember (Mortician's Ashes)", "Ember", DS3LocationCategory.MISC, offline = '99,0:-1:110000,70000100:', shop = True, conditional = True), - DS3LocationData("FS: Grave Key", "Grave Key", DS3LocationCategory.KEY, + DS3LocationData("FS: Grave Key (Mortician's Ashes)", "Grave Key", DS3LocationCategory.KEY, shop = True, key = True, conditional = True), - # Dreamchaser's Ashes - DS3LocationData("FS: Life Ring", "Life Ring", DS3LocationCategory.RING, - shop = True, conditional = True), - DS3LocationData("FS: Hidden Blessing #2", "Hidden Blessing", DS3LocationCategory.MISC, - missable = True, shop = True), # only if you say where the ashes were found - # Paladin's Ashes - DS3LocationData("FS: Lloyd's Shield Ring", "Lloyd's Shield Ring", DS3LocationCategory.RING, - shop = True, conditional = True), - # Grave Warden's Ashes - DS3LocationData("FS: Ember (Grave Warden)", "Ember", DS3LocationCategory.MISC, + DS3LocationData("FS: Life Ring (Dreamchaser's Ashes)", "Life Ring", + DS3LocationCategory.RING, shop = True, conditional = True), + # Only if you say where the ashes were found + DS3LocationData("FS: Hidden Blessing (Dreamchaser's Ashes)", "Hidden Blessing", + DS3LocationCategory.MISC, missable = True, shop = True), + DS3LocationData("FS: Lloyd's Shield Ring (Paladin's Ashes)", "Lloyd's Shield Ring", + DS3LocationCategory.RING, shop = True, conditional = True), + DS3LocationData("FS: Ember (Grave Warden's Ashes)", "Ember", DS3LocationCategory.MISC, offline = '99,0:-1:110000,70000103:', shop = True, conditional = True), # Prisoner Chief's Ashes - DS3LocationData("FS: Karla's Pointed Hat", "Karla's Pointed Hat", DS3LocationCategory.ARMOR, - offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), - DS3LocationData("FS: Karla's Coat", "Karla's Coat", DS3LocationCategory.ARMOR, - offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), - DS3LocationData("FS: Karla's Gloves", "Karla's Gloves", DS3LocationCategory.ARMOR, - offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), - DS3LocationData("FS: Karla's Trousers", "Karla's Trousers", DS3LocationCategory.ARMOR, - offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), - # Xanthous Ashes - DS3LocationData("FS: Xanthous Overcoat", "Xanthous Overcoat", DS3LocationCategory.ARMOR, + DS3LocationData("FS: Karla's Pointed Hat (Prisoner Chief's Ashes)", "Karla's Pointed Hat", + DS3LocationCategory.ARMOR, offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), - DS3LocationData("FS: Xanthous Gloves", "Xanthous Gloves", DS3LocationCategory.ARMOR, + DS3LocationData("FS: Karla's Coat (Prisoner Chief's Ashes)", "Karla's Coat", + DS3LocationCategory.ARMOR, offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), - DS3LocationData("FS: Xanthous Trousers", "Xanthous Trousers", DS3LocationCategory.ARMOR, + DS3LocationData("FS: Karla's Gloves (Prisoner Chief's Ashes)", "Karla's Gloves", + DS3LocationCategory.ARMOR, offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), - # Dragon Chaser's Ashes - DS3LocationData("FS: Ember (Dragon Chaser)", "Ember", DS3LocationCategory.MISC, + DS3LocationData("FS: Karla's Trousers (Prisoner Chief's Ashes)", + "Karla's Trousers", DS3LocationCategory.ARMOR, + offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), + DS3LocationData("FS: Xanthous Overcoat (Xanthous Ashes)", "Xanthous Overcoat", + DS3LocationCategory.ARMOR, shop = True, conditional = True), + DS3LocationData("FS: Xanthous Gloves (Xanthous Ashes)", "Xanthous Gloves", + DS3LocationCategory.ARMOR, shop = True, conditional = True), + DS3LocationData("FS: Xanthous Trousers (Xanthous Ashes)", "Xanthous Trousers", + DS3LocationCategory.ARMOR, shop = True, conditional = True), + DS3LocationData("FS: Ember (Dragon Chaser's Ashes)", "Ember", DS3LocationCategory.MISC, offline = '99,0:-1:110000,70000108:', shop = True, conditional = True), - # Easterner's Ashes - DS3LocationData("FS: Washing Pole", "Washing Pole", DS3LocationCategory.WEAPON, - shop = True, conditional = True), - DS3LocationData("FS: Eastern Helm", "Eastern Helm", DS3LocationCategory.ARMOR, - shop = True, conditional = True), - DS3LocationData("FS: Eastern Armor", "Eastern Armor", DS3LocationCategory.ARMOR, - shop = True, conditional = True), - DS3LocationData("FS: Eastern Gauntlets", "Eastern Gauntlets", DS3LocationCategory.ARMOR, - shop = True, conditional = True), - DS3LocationData("FS: Eastern Leggings", "Eastern Leggings", DS3LocationCategory.ARMOR, + DS3LocationData("FS: Washing Pole (Easterner's Ashes)", "Washing Pole", + DS3LocationCategory.WEAPON, shop = True, conditional = True), + DS3LocationData("FS: Eastern Helm (Easterner's Ashes)", "Eastern Helm", + DS3LocationCategory.ARMOR, shop = True, conditional = True), + DS3LocationData("FS: Eastern Armor (Easterner's Ashes)", "Eastern Armor", + DS3LocationCategory.ARMOR, shop = True, conditional = True), + DS3LocationData("FS: Eastern Gauntlets (Easterner's Ashes)", "Eastern Gauntlets", + DS3LocationCategory.ARMOR, shop = True, conditional = True), + DS3LocationData("FS: Eastern Leggings (Easterner's Ashes)", "Eastern Leggings", + DS3LocationCategory.ARMOR, shop = True, conditional = True), + DS3LocationData("FS: Wood Grain Ring (Easterner's Ashes)", "Wood Grain Ring", + DS3LocationCategory.RING, shop = True, conditional = True), + DS3LocationData("FS: Millwood Knight Helm (Captain's Ashes)", "Millwood Knight Helm", + DS3LocationCategory.ARMOR, dlc = True, shop = True, conditional = True), + DS3LocationData("FS: Millwood Knight Armor (Captain's Ashes)", "Millwood Knight Armor", + DS3LocationCategory.ARMOR, dlc = True, shop = True, conditional = True), + DS3LocationData("FS: Millwood Knight Gauntlets (Captain's Ashes)", + "Millwood Knight Gauntlets", DS3LocationCategory.ARMOR, dlc = True, shop = True, conditional = True), - DS3LocationData("FS: Wood Grain Ring", "Wood Grain Ring", DS3LocationCategory.RING, + DS3LocationData("FS: Millwood Knight Leggings (Captain's Ashes)", + "Millwood Knight Leggings", DS3LocationCategory.ARMOR, dlc = True, shop = True, conditional = True), - # Captain's Ashes - DS3LocationData("FS: Millwood Knight Helm", "Millwood Knight Helm", DS3LocationCategory.ARMOR, - dlc = True, shop = True, conditional = True), - DS3LocationData("FS: Millwood Knight Armor", "Millwood Knight Armor", DS3LocationCategory.ARMOR, - dlc = True, shop = True, conditional = True), - DS3LocationData("FS: Millwood Knight Gauntlets", "Millwood Knight Gauntlets", DS3LocationCategory.ARMOR, - dlc = True, shop = True, conditional = True), - DS3LocationData("FS: Millwood Knight Leggings", "Millwood Knight Leggings", DS3LocationCategory.ARMOR, - dlc = True, shop = True, conditional = True), - DS3LocationData("FS: Refined Gem", "Refined Gem", DS3LocationCategory.UPGRADE, - dlc = True, shop = True, conditional = True), + DS3LocationData("FS: Refined Gem (Captain's Ashes)", "Refined Gem", + DS3LocationCategory.UPGRADE, dlc = True, shop = True, conditional = True), + + # Ludleth Shop + DS3LocationData("FS: Vordt's Great Hammer (Ludleth for Vordt)", "Vordt's Great Hammer", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Pontiff's Left Eye (Ludleth for Vordt)", "Pontiff's Left Eye", + DS3LocationCategory.RING, missable = True, boss = True, shop = True), + DS3LocationData("FS: Bountiful Sunlight (Ludleth for Rosaria)", "Bountiful Sunlight", + DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + DS3LocationData("FS: Darkmoon Longbow (Ludleth for Aldrich)", "Darkmoon Longbow", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Lifehunt Scythe (Ludleth for Aldrich)", "Lifehunt Scythe", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Hollowslayer Greatsword (Ludleth for Greatwood)", + "Hollowslayer Greatsword", DS3LocationCategory.WEAPON, missable = True, + boss = True, shop = True), + DS3LocationData("FS: Arstor's Spear (Ludleth for Greatwood)", "Arstor's Spear", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Crystal Sage's Rapier (Ludleth for Sage)", "Crystal Sage's Rapier", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Crystal Hail (Ludleth for Sage)", "Crystal Hail", + DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + DS3LocationData("FS: Cleric's Candlestick (Ludleth for Deacons)", "Cleric's Candlestick", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Deep Soul (Ludleth for Deacons)", "Deep Soul", + DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + DS3LocationData("FS: Havel's Ring (Ludleth for Stray Demon)", "Havel's Ring", + DS3LocationCategory.RING, missable = True, boss = True, shop = True), + DS3LocationData("FS: Boulder Heave (Ludleth for Stray Demon)", "Boulder Heave", + DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + DS3LocationData("FS: Farron Greatsword (Ludleth for Abyss Watchers)", "Farron Greatsword", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Wolf Knight's Greatsword (Ludleth for Abyss Watchers)", + "Wolf Knight's Greatsword", DS3LocationCategory.WEAPON, missable = True, + boss = True, shop = True), + DS3LocationData("FS: Wolnir's Holy Sword (Ludleth for Wolnir)", "Wolnir's Holy Sword", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Black Serpent (Ludleth for Wolnir)", "Black Serpent", + DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + DS3LocationData("FS: Demon's Greataxe (Ludleth for Fire Demon)", "Demon's Greataxe", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Demon's Fist (Ludleth for Fire Demon)", "Demon's Fist", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Old King's Great Hammer (Ludleth for Old Demon King)", + "Old King's Great Hammer", DS3LocationCategory.WEAPON, missable = True, + boss = True, shop = True), + DS3LocationData("FS: Chaos Bed Vestiges (Ludleth for Old Demon King)", "Chaos Bed Vestiges", + DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + DS3LocationData("FS: Greatsword of Judgment (Ludleth for Pontiff)", + "Greatsword of Judgment", DS3LocationCategory.WEAPON, missable = True, + boss = True, shop = True), + DS3LocationData("FS: Profaned Greatsword (Ludleth for Pontiff)", "Profaned Greatsword", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Yhorm's Great Machete (Ludleth for Yhorm)", "Yhorm's Great Machete", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Yhorm's Greatshield (Ludleth for Yhorm)", "Yhorm's Greatshield", + DS3LocationCategory.SHIELD, missable = True, boss = True, shop = True), + DS3LocationData("FS: Dancer's Enchanted Swords (Ludleth for Dancer)", + "Dancer's Enchanted Swords", DS3LocationCategory.WEAPON, missable = True, + boss = True, shop = True), + DS3LocationData("FS: Soothing Sunlight (Ludleth for Dancer)", "Soothing Sunlight", + DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + DS3LocationData("FS: Dragonslayer Greataxe (Ludleth for Dragonslayer)", + "Dragonslayer Greataxe", DS3LocationCategory.WEAPON, missable = True, + boss = True, shop = True), + DS3LocationData("FS: Dragonslayer Greatshield (Ludleth for Dragonslayer)", + "Dragonslayer Greatshield", DS3LocationCategory.SHIELD, missable = True, + boss = True, shop = True), + DS3LocationData("FS: Moonlight Greatsword (Ludleth for Oceiros)", "Moonlight Greatsword", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: White Dragon Breath (Ludleth for Oceiros)", "White Dragon Breath", + DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + DS3LocationData("FS: Lorian's Greatsword (Ludleth for Princes)", "Lorian's Greatsword", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Lothric's Holy Sword (Ludleth for Princes)", "Lothric's Holy Sword", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Gundyr's Halberd (Ludleth for Champion)", "Gundyr's Halberd", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Prisoner's Chain (Ludleth for Champion)", "Prisoner's Chain", + DS3LocationCategory.RING, missable = True, boss = True, shop = True), + DS3LocationData("FS: Storm Curved Sword (Ludleth for Nameless)", "Storm Curved Sword", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Dragonslayer Swordspear (Ludleth for Nameless)", + "Dragonslayer Swordspear", DS3LocationCategory.WEAPON, missable = True, + boss = True, shop = True), + DS3LocationData("FS: Lightning Storm (Ludleth for Nameless)", "Lightning Storm", + DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + DS3LocationData("FS: Firelink Greatsword (Ludleth for Cinder)", "Firelink Greatsword", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Sunlight Spear (Ludleth for Cinder)", "Sunlight Spear", + DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + DS3LocationData("FS: Friede's Great Scythe (Ludleth for Friede)", "Friede's Great Scythe", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Rose of Ariandel (Ludleth for Friede)", "Rose of Ariandel", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Demon's Scar (Ludleth for Demon Prince)", "Demon's Scar", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Seething Chaos (Ludleth for Demon Prince)", "Seething Chaos", + DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + DS3LocationData("FS: Frayed Blade (Ludleth for Midir)", "Frayed Blade", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Old Moonlight (Ludleth for Midir)", "Old Moonlight", + DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + DS3LocationData("FS: Gael's Greatsword (Ludleth for Gael)", "Gael's Greatsword", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + DS3LocationData("FS: Repeating Crossbow (Ludleth for Gael)", "Repeating Crossbow", + DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), ], "Firelink Shrine Bell Tower": [ # Guarded by Tower Key - DS3LocationData("FSBT: Homeward Bone", "Homeward Bone x3", DS3LocationCategory.MISC), - DS3LocationData("FSBT: Estus Ring", "Estus Ring", DS3LocationCategory.RING), - DS3LocationData("FSBT: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), - DS3LocationData("FSBT: Fire Keeper Soul", "Fire Keeper Soul", DS3LocationCategory.UNIQUE), - DS3LocationData("FSBT: Fire Keeper Robe", "Fire Keeper Robe", DS3LocationCategory.ARMOR), - DS3LocationData("FSBT: Fire Keeper Gloves", "Fire Keeper Gloves", DS3LocationCategory.ARMOR), - DS3LocationData("FSBT: Fire Keeper Skirt", "Fire Keeper Skirt", DS3LocationCategory.ARMOR), - DS3LocationData("FSBT: Covetous Silver Serpent Ring", "Covetous Silver Serpent Ring", DS3LocationCategory.RING, - hidden = True), # Behind illusory wall - DS3LocationData("FSBT: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), + DS3LocationData("FSBT: Homeward Bone (roof)", "Homeward Bone x3", + DS3LocationCategory.MISC), + DS3LocationData("FSBT: Estus Ring (rafters)", "Estus Ring", DS3LocationCategory.RING), + DS3LocationData("FSBT: Estus Shard (rafters)", "Estus Shard", DS3LocationCategory.HEALTH), + DS3LocationData("FSBT: Fire Keeper Soul (tower top)", "Fire Keeper Soul", + DS3LocationCategory.UNIQUE), + DS3LocationData("FSBT: Fire Keeper Robe (partway down tower)", "Fire Keeper Robe", + DS3LocationCategory.ARMOR), + DS3LocationData("FSBT: Fire Keeper Gloves (partway down tower)", "Fire Keeper Gloves", + DS3LocationCategory.ARMOR), + DS3LocationData("FSBT: Fire Keeper Skirt (partway down tower)", "Fire Keeper Skirt", + DS3LocationCategory.ARMOR), + DS3LocationData("FSBT: Covetous Silver Serpent Ring (illusory wall past rafters)", + "Covetous Silver Serpent Ring", DS3LocationCategory.RING, hidden = True), + DS3LocationData("FSBT: Twinkling Titanite (lizard behind Firelink)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), # Mark all crow trades as missable since no one wants to have to try trading everything just # in case it gives a progression item. - DS3LocationData("FSBT: Iron Bracelets", "Iron Bracelets", DS3LocationCategory.ARMOR, - missable = True), - DS3LocationData("FSBT: Ring of Sacrifice", "Ring of Sacrifice", DS3LocationCategory.MISC, - missable = True), - DS3LocationData("FSBT: Porcine Shield", "Porcine Shield", DS3LocationCategory.SHIELD, - missable = True), - DS3LocationData("FSBT: Lucatiel's Mask", "Lucatiel's Mask", DS3LocationCategory.ARMOR, - missable = True), - DS3LocationData("FSBT: Very good! Carving", "Very good! Carving", DS3LocationCategory.UNIQUE, - missable = True), - DS3LocationData("FSBT: Thank you Carving", "Thank you Carving", DS3LocationCategory.UNIQUE, - missable = True), - DS3LocationData("FSBT: I'm sorry Carving", "I'm sorry Carving", DS3LocationCategory.UNIQUE, - missable = True), - DS3LocationData("FSBT: Sunlight Shield", "Sunlight Shield", DS3LocationCategory.SHIELD, - missable = True), - DS3LocationData("FSBT: Hollow Gem", "Hollow Gem", DS3LocationCategory.UPGRADE, - missable = True), - DS3LocationData("FSBT: Titanite Scale #1", "Titanite Scale x3", DS3LocationCategory.UPGRADE, - missable = True), - DS3LocationData("FSBT: Help me! Carving", "Help me! Carving", DS3LocationCategory.UNIQUE, - missable = True), - DS3LocationData("FSBT: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE, - missable = True), - DS3LocationData("FSBT: Hello Carving", "Hello Carving", DS3LocationCategory.UNIQUE, - missable = True), - DS3LocationData("FSBT: Armor of the Sun", "Armor of the Sun", DS3LocationCategory.ARMOR, - missable = True), - DS3LocationData("FSBT: Large Titanite Shard", "Large Titanite Shard", DS3LocationCategory.UPGRADE, - missable = True), - DS3LocationData("FSBT: Titanite Chunk", "Titanite Chunk", DS3LocationCategory.UPGRADE, - missable = True), - DS3LocationData("FSBT: Iron Helm", "Iron Helm", DS3LocationCategory.ARMOR, - missable = True), - DS3LocationData("FSBT: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - missable = True), - DS3LocationData("FSBT: Iron Leggings", "Iron Leggings", DS3LocationCategory.ARMOR, - missable = True), - DS3LocationData("FSBT: Lightning Gem", "Lightning Gem", DS3LocationCategory.UPGRADE, - missable = True), - DS3LocationData("FSBT: Twinkling Titanite #3", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - missable = True), - DS3LocationData("FSBT: Blessed Gem", "Blessed Gem", DS3LocationCategory.UPGRADE, - missable = True), - DS3LocationData("FSBT: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE, - missable = True), + DS3LocationData("FSBT: Iron Bracelets (crow for Homeward Bone)", "Iron Bracelets", + DS3LocationCategory.ARMOR, missable = True), + DS3LocationData("FSBT: Ring of Sacrifice (crow for Loretta's Bone)", "Ring of Sacrifice", + DS3LocationCategory.MISC, missable = True), + DS3LocationData("FSBT: Porcine Shield (crow for Undead Bone Shard)", "Porcine Shield", + DS3LocationCategory.SHIELD, missable = True), + DS3LocationData("FSBT: Lucatiel's Mask (crow for Vertebra Shackle)", "Lucatiel's Mask", + DS3LocationCategory.ARMOR, missable = True), + DS3LocationData("FSBT: Very good! Carving (crow for Divine Blessing)", + "Very good! Carving", DS3LocationCategory.UNIQUE, missable = True), + DS3LocationData("FSBT: Thank you Carving (crow for Hidden Blessing)", "Thank you Carving", + DS3LocationCategory.UNIQUE, missable = True), + DS3LocationData("FSBT: I'm sorry Carving (crow for Shriving Stone)", "I'm sorry Carving", + DS3LocationCategory.UNIQUE, missable = True), + DS3LocationData("FSBT: Sunlight Shield (crow for Mendicant's Staff)", "Sunlight Shield", + DS3LocationCategory.SHIELD, missable = True), + DS3LocationData("FSBT: Hollow Gem (crow for Eleonora)", "Hollow Gem", + DS3LocationCategory.UPGRADE, missable = True), + DS3LocationData("FSBT: Titanite Scale (crow for Blacksmith Hammer)", "Titanite Scale x3", + DS3LocationCategory.UPGRADE, offline = '99,0:50004330::', missable = True), + DS3LocationData("FSBT: Help me! Carving (crow for any sacred chime)", "Help me! Carving", + DS3LocationCategory.UNIQUE, missable = True), + DS3LocationData("FSBT: Titanite Slab (crow for Coiled Sword Fragment)", "Titanite Slab", + DS3LocationCategory.UPGRADE, missable = True), + DS3LocationData("FSBT: Hello Carving (crow for Alluring Skull)", "Hello Carving", + DS3LocationCategory.UNIQUE, missable = True), + DS3LocationData("FSBT: Armor of the Sun (crow for Siegbräu)", "Armor of the Sun", + DS3LocationCategory.ARMOR, missable = True), + DS3LocationData("FSBT: Large Titanite Shard (crow for Firebomb)", "Large Titanite Shard", + DS3LocationCategory.UPGRADE, missable = True), + DS3LocationData("FSBT: Titanite Chunk (crow for Black Firebomb)", "Titanite Chunk", + DS3LocationCategory.UPGRADE, missable = True), + DS3LocationData("FSBT: Iron Helm (crow for Lightning Urn)", "Iron Helm", + DS3LocationCategory.ARMOR, missable = True), + DS3LocationData("FSBT: Twinkling Titanite (crow for Prism Stone)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE, missable = True), + DS3LocationData("FSBT: Iron Leggings (crow for Seed of a Giant Tree)", "Iron Leggings", + DS3LocationCategory.ARMOR, missable = True), + DS3LocationData("FSBT: Lightning Gem (crow for Xanthous Crown)", "Lightning Gem", + DS3LocationCategory.UPGRADE, missable = True), + DS3LocationData("FSBT: Twinkling Titanite (crow for Large Leather Shield)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE, missable = True), + DS3LocationData("FSBT: Blessed Gem (crow for Moaning Shield)", "Blessed Gem", + DS3LocationCategory.UPGRADE, missable = True), ], "High Wall of Lothric": [ - DS3LocationData("HWL: Soul of Boreal Valley Vordt", "Soul of Boreal Valley Vordt", DS3LocationCategory.SOUL, - prominent = True, boss = True), - DS3LocationData("HWL: Soul of the Dancer", "Soul of the Dancer", DS3LocationCategory.SOUL, + DS3LocationData("HWL: Soul of Boreal Valley Vordt", "Soul of Boreal Valley Vordt", + DS3LocationCategory.SOUL, prominent = True, boss = True), + DS3LocationData("HWL: Soul of the Dancer", "Soul of the Dancer", DS3LocationCategory.SOUL, prominent = True, boss = True), - DS3LocationData("HWL: Basin of Vows", "Basin of Vows", DS3LocationCategory.KEY, - prominent = True, progression = True), - DS3LocationData("HWL: Small Lothric Banner", "Small Lothric Banner", DS3LocationCategory.KEY, - prominent = True, progression = True), - DS3LocationData("HWL: Green Blossom #1", "Green Blossom x2", DS3LocationCategory.MISC, - hidden = True), # Down an obscured hallway - DS3LocationData("HWL: Gold Pine Resin", "Gold Pine Resin x2", DS3LocationCategory.MISC, - hidden = True), # Hidden fall - DS3LocationData("HWL: Large Soul of a Deserted Corpse #1", "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("HWL: Soul of a Deserted Corpse #1", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("HWL: Standard Arrow", "Standard Arrow x12", DS3LocationCategory.MISC), - DS3LocationData("HWL: Longbow", "Longbow", DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Firebomb #1", "Firebomb x3", DS3LocationCategory.MISC), - DS3LocationData("HWL: Throwing Knife #1", "Throwing Knife x8", DS3LocationCategory.MISC), - DS3LocationData("HWL: Soul of a Deserted Corpse #2", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("HWL: Club", "Club", DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Claymore", "Claymore", DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("HWL: Firebomb #2", "Firebomb x2", DS3LocationCategory.MISC, - hidden = True), # In crates and furniture - DS3LocationData("HWL: Titanite Shard #1", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("HWL: Undead Hunter Charm", "Undead Hunter Charm x2", DS3LocationCategory.MISC, - hidden = True), # In a pot - DS3LocationData("HWL: Firebomb #3", "Firebomb x3", DS3LocationCategory.MISC), - DS3LocationData("HWL: Cell Key", "Cell Key", DS3LocationCategory.KEY, - key = True), - DS3LocationData("HWL: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("HWL: Soul of a Deserted Corpse #3", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("HWL: Lucerne", "Lucerne", DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Mail Breaker", "Mail Breaker", DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Titanite Shard #2", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("HWL: Rapier", "Rapier", DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Titanite Shard #3", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("HWL: Large Soul of a Deserted Corpse #2", "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("HWL: Black Firebomb", "Black Firebomb x3", DS3LocationCategory.MISC), - DS3LocationData("HWL: Soul of a Deserted Corpse #4", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("HWL: Ember #3", "Ember", DS3LocationCategory.MISC), - DS3LocationData("HWL: Large Soul of a Deserted Corpse #3", "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC, + DS3LocationData("HWL: Basin of Vows (Emma)", "Basin of Vows", DS3LocationCategory.KEY, + prominent = True, progression = True, conditional = True), + DS3LocationData("HWL: Small Lothric Banner (Emma)", "Small Lothric Banner", + DS3LocationCategory.KEY, prominent = True, progression = True), + DS3LocationData("HWL: Green Blossom (fort walkway, hall behind wheel)", "Green Blossom x2", + DS3LocationCategory.MISC, hidden = True), + DS3LocationData("HWL: Gold Pine Resin (corpse tower, drop)", "Gold Pine Resin x2", + DS3LocationCategory.MISC, hidden = True), + DS3LocationData("HWL: Large Soul of a Deserted Corpse (flame plaza)", + "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + DS3LocationData("HWL: Soul of a Deserted Corpse (by wall tower door)", + "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + DS3LocationData("HWL: Standard Arrow (back tower)", "Standard Arrow x12", + DS3LocationCategory.MISC), + DS3LocationData("HWL: Longbow (back tower)", "Longbow", DS3LocationCategory.WEAPON), + DS3LocationData("HWL: Firebomb (wall tower, beam)", "Firebomb x3", + DS3LocationCategory.MISC), + DS3LocationData("HWL: Throwing Knife (wall tower, path to Greirat)", "Throwing Knife x8", + DS3LocationCategory.MISC), + DS3LocationData("HWL: Soul of a Deserted Corpse (corpse tower, bottom floor)", + "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + DS3LocationData("HWL: Club (flame plaza)", "Club", DS3LocationCategory.WEAPON), + DS3LocationData("HWL: Claymore (flame plaza)", "Claymore", + DS3LocationCategory.WEAPON), + DS3LocationData("HWL: Ember (flame plaza)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("HWL: Firebomb (corpse tower, under table)", "Firebomb x2", + DS3LocationCategory.MISC), + DS3LocationData("HWL: Titanite Shard (wall tower, corner by bonfire)", "Titanite Shard", + DS3LocationCategory.UPGRADE, hidden = True), + DS3LocationData("HWL: Undead Hunter Charm (fort, room off entry, in pot)", + "Undead Hunter Charm x2", DS3LocationCategory.MISC, hidden = True), + DS3LocationData("HWL: Firebomb (top of ladder to fountain)", "Firebomb x3", + DS3LocationCategory.MISC), + DS3LocationData("HWL: Cell Key (fort basement, down stairs)", "Cell Key", + DS3LocationCategory.KEY, key = True), + DS3LocationData("HWL: Ember (fountain #1)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("HWL: Soul of a Deserted Corpse (fort entry, corner)", + "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + DS3LocationData("HWL: Lucerne (promenade, side path)", "Lucerne", + DS3LocationCategory.WEAPON), + DS3LocationData("HWL: Mail Breaker (wall tower, path to Greirat)", "Mail Breaker", + DS3LocationCategory.WEAPON), + DS3LocationData("HWL: Titanite Shard (fort basement, behind crates)", + "Titanite Shard", DS3LocationCategory.UPGRADE, hidden = True), + DS3LocationData("HWL: Rapier (fountain, corner)", "Rapier", DS3LocationCategory.WEAPON), + DS3LocationData("HWL: Titanite Shard (for, room off entry)", + "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("HWL: Large Soul of a Deserted Corpse (fort roof)", + "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + DS3LocationData("HWL: Black Firebomb (small roof over fountain)", "Black Firebomb x3", + DS3LocationCategory.MISC), + DS3LocationData("HWL: Soul of a Deserted Corpse (path to corpse tower)", + "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + DS3LocationData("HWL: Ember (fountain, #2)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("HWL: Large Soul of a Deserted Corpse (platform by fountain)", + "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC, hidden = True), # Easily missed turnoff - DS3LocationData("HWL: Binoculars", "Binoculars", DS3LocationCategory.UNIQUE), - DS3LocationData("HWL: Ring of Sacrifice", "Ring of Sacrifice", DS3LocationCategory.MISC, + DS3LocationData("HWL: Binoculars (corpse tower, upper platform)", "Binoculars", + DS3LocationCategory.UNIQUE), + DS3LocationData("HWL: Ring of Sacrifice (awning by fountain)", + "Ring of Sacrifice", DS3LocationCategory.MISC, hidden = True), # Easily missed turnoff - DS3LocationData("HWL: Throwing Knife #2", "Throwing Knife x6", DS3LocationCategory.MISC), - DS3LocationData("HWL: Soul of a Deserted Corpse #5", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("HWL: Green Blossom #2", "Green Blossom x3", DS3LocationCategory.MISC), - DS3LocationData("HWL: Broadsword", "Broadsword", DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Soul of a Deserted Corpse #6", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("HWL: Firebomb #4", "Firebomb x3", DS3LocationCategory.MISC), - DS3LocationData("HWL: Soul of a Deserted Corpse #7", "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("HWL: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), - DS3LocationData("HWL: Fleshbite Ring+1", "Fleshbite Ring+1", DS3LocationCategory.RING, - hidden = True, ngp = True), # Hidden jump - DS3LocationData("HWL: Ring of the Evil Eye+2", "Ring of the Evil Eye+2", DS3LocationCategory.RING, - hidden = True, ngp = True), # In barrels - DS3LocationData("HWL: Silver Eagle Kite Shield", "Silver Eagle Kite Shield", DS3LocationCategory.SHIELD), - DS3LocationData("HWL: Astora Straight Sword", "Astora Straight Sword", DS3LocationCategory.WEAPON, + DS3LocationData("HWL: Throwing Knife (shortcut, lift top)", "Throwing Knife x6", + DS3LocationCategory.MISC), + DS3LocationData("HWL: Soul of a Deserted Corpse (path to back tower, by lift door)", + "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + DS3LocationData("HWL: Green Blossom (shortcut, by lower lift door)", "Green Blossom x3", + DS3LocationCategory.MISC), + DS3LocationData("HWL: Broadsword (fort, room off entry)", "Broadsword", + DS3LocationCategory.WEAPON), + DS3LocationData("HWL: Soul of a Deserted Corpse (fountain, path to promenade)", + "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + DS3LocationData("HWL: Firebomb (fort roof)", "Firebomb x3", DS3LocationCategory.MISC), + DS3LocationData("HWL: Soul of a Deserted Corpse (wall tower, right of exit)", + "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + DS3LocationData("HWL: Estus Shard (fort basement, on anvil)", "Estus Shard", + DS3LocationCategory.HEALTH), + DS3LocationData("HWL: Fleshbite Ring+1 (fort roof, jump to other roof)", + "Fleshbite Ring+1", DS3LocationCategory.RING, ngp = True, + hidden = True), # Hidden jump + DS3LocationData("HWL: Ring of the Evil Eye+2 (fort basement, far wall)", + "Ring of the Evil Eye+2", DS3LocationCategory.RING, ngp = True, + hidden = True), # In barrels + DS3LocationData("HWL: Silver Eagle Kite Shield (fort mezzanine)", + "Silver Eagle Kite Shield", DS3LocationCategory.SHIELD), + DS3LocationData("HWL: Astora Straight Sword (fort walkway, drop down)", + "Astora Straight Sword", DS3LocationCategory.WEAPON, hidden = True), # Hidden fall - DS3LocationData("HWL: Battle Axe", "Battle Axe", DS3LocationCategory.WEAPON, - offline = '01,0:53000960::', mimic = True), - DS3LocationData("HWL: Ember #4", "Ember", DS3LocationCategory.MISC, - hidden = True, miniboss = True), # Only dropped by Pus of Man after transformation - DS3LocationData("HWL: Titanite Shard #4", "Titanite Shard", DS3LocationCategory.UPGRADE, - hidden = True, miniboss = True), # Only dropped by Pus of Man after transformation - DS3LocationData("HWL: Ember #5", "Ember", DS3LocationCategory.MISC, - hidden = True, miniboss = True), # Only dropped by Pus of Man after transformation - DS3LocationData("HWL: Titanite Shard #5", "Titanite Shard", DS3LocationCategory.MISC, - hidden = True, miniboss = True), # Only dropped by Pus of Man after transformation - DS3LocationData("HWL: Refined Gem", "Refined Gem", DS3LocationCategory.UPGRADE, - miniboss = True), # Red-Eyed Lothric Knight drop - DS3LocationData("HWL: Way of Blue", "Way of Blue", DS3LocationCategory.UNIQUE), - DS3LocationData("HWL: Raw Gem", "Raw Gem", DS3LocationCategory.UPGRADE, - lizard = True), + DS3LocationData("HWL: Battle Axe (flame tower, mimic)", "Battle Axe", + DS3LocationCategory.WEAPON, offline = '01,0:53000960::', mimic = True), + + # Only dropped after transformation + DS3LocationData("HWL: Ember (fort roof, transforming hollow)", "Ember", + DS3LocationCategory.MISC, hidden = True), + DS3LocationData("HWL: Titanite Shard (fort roof, transforming hollow)", + "Titanite Shard", DS3LocationCategory.UPGRADE, hidden = True), + DS3LocationData("HWL: Ember (back tower roof bonfire, transforming hollow)", "Ember", + DS3LocationCategory.MISC, hidden = True), + DS3LocationData("HWL: Titanite Shard (back tower roof bonfire, transforming hollow)", + "Titanite Shard", DS3LocationCategory.MISC, hidden = True), + + DS3LocationData("HWL: Refined Gem (promenade miniboss)", "Refined Gem", + DS3LocationCategory.UPGRADE, miniboss = True), + DS3LocationData("HWL: Way of Blue (Emma)", "Way of Blue", DS3LocationCategory.UNIQUE), # Categorize this as an NPC item so that it doesn't get randomized if the Lift Chamber Key # isn't randomized, since in that case it's missable. - DS3LocationData("HWL: Red Eye Orb", "Red Eye Orb", DS3LocationCategory.MISC, - npc = True, miniboss = True), - DS3LocationData("HWL: Vordt's Great Hammer", "Vordt's Great Hammer", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("HWL: Pontiff's Left Eye", "Pontiff's Left Eye", DS3LocationCategory.RING, - missable = True, boss = True, shop = True), + DS3LocationData("HWL: Red Eye Orb (wall tower, miniboss)", "Red Eye Orb", + DS3LocationCategory.MISC, conditional = True, miniboss = True, npc = True), + DS3LocationData("HWL: Raw Gem (fort roof, lizard)", "Raw Gem", + DS3LocationCategory.UPGRADE, lizard = True), ], "Undead Settlement": [ - DS3LocationData("US: Soul of the Rotted Greatwood", "Soul of the Rotted Greatwood", DS3LocationCategory.SOUL, - prominent = True, boss = True), - DS3LocationData("US: Transposing Kiln", "Transposing Kiln", DS3LocationCategory.UNIQUE, - boss = True), - DS3LocationData("US: Pyromancy Flame", "Pyromancy Flame", DS3LocationCategory.WEAPON, - missable = True, npc = True), - DS3LocationData("US: Old Sage's Blindfold", "Old Sage's Blindfold", DS3LocationCategory.ARMOR, - missable = True, npc = True), - DS3LocationData("US: Cornyx's Garb", "Cornyx's Garb", DS3LocationCategory.ARMOR, - offline = '02,0:50006141::', missable = True, npc = True), - DS3LocationData("US: Cornyx's Wrap", "Cornyx's Wrap", DS3LocationCategory.ARMOR, - offline = '02,0:50006141::', missable = True, npc = True), - DS3LocationData("US: Cornyx's Skirt", "Cornyx's Skirt", DS3LocationCategory.ARMOR, - offline = '02,0:50006141::', missable = True, npc = True), - DS3LocationData("US: Tower Key", "Tower Key", DS3LocationCategory.KEY, + DS3LocationData("US: Soul of the Rotted Greatwood", "Soul of the Rotted Greatwood", + DS3LocationCategory.SOUL, prominent = True, boss = True), + DS3LocationData("US: Transposing Kiln (boss drop)", "Transposing Kiln", + DS3LocationCategory.UNIQUE, boss = True), + # Missable because it's unavailable if you start as a Pyromancer + DS3LocationData("US: Pyromancy Flame (Cornyx)", "Pyromancy Flame", + DS3LocationCategory.WEAPON, missable = True, npc = True), + DS3LocationData("US: Old Sage's Blindfold (kill Cornyx)", "Old Sage's Blindfold", + DS3LocationCategory.ARMOR, npc = True), + DS3LocationData("US: Cornyx's Garb (kill Cornyx)", "Cornyx's Garb", DS3LocationCategory.ARMOR, + offline = '02,0:50006141::', npc = True), + DS3LocationData("US: Cornyx's Wrap (kill Cornyx)", "Cornyx's Wrap", DS3LocationCategory.ARMOR, + offline = '02,0:50006141::', npc = True), + DS3LocationData("US: Cornyx's Skirt (kill Cornyx)", "Cornyx's Skirt", DS3LocationCategory.ARMOR, + offline = '02,0:50006141::', npc = True), + DS3LocationData("US: Tower Key (kill Irina)", "Tower Key", DS3LocationCategory.KEY, missable = True, npc = True, key = True), - DS3LocationData("US: Flynn's Ring", "Flynn's Ring", DS3LocationCategory.RING), - DS3LocationData("US: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), - DS3LocationData("US: Alluring Skull #1", "Alluring Skull x2", DS3LocationCategory.MISC), - DS3LocationData("US: Mortician's Ashes", "Mortician's Ashes", DS3LocationCategory.KEY, - progression = True), - DS3LocationData("US: Homeward Bone #1", "Homeward Bone x2", DS3LocationCategory.MISC, - hidden = True), # Hidden fall - DS3LocationData("US: Caduceus Round Shield", "Caduceus Round Shield", DS3LocationCategory.SHIELD), - DS3LocationData("US: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("US: Soul of an Unknown Traveler #1", "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("US: Repair Powder", "Repair Powder x2", DS3LocationCategory.MISC), - DS3LocationData("US: Homeward Bone #2", "Homeward Bone x2", DS3LocationCategory.MISC), - DS3LocationData("US: Titanite Shard #1", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("US: Wargod Wooden Shield", "Wargod Wooden Shield", DS3LocationCategory.SHIELD), - DS3LocationData("US: Large Soul of a Deserted Corpse #1", "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("US: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("US: Large Soul of a Deserted Corpse #2", "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("US: Titanite Shard #2", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("US: Alluring Skull #2", "Alluring Skull x2", DS3LocationCategory.MISC), - DS3LocationData("US: Charcoal Pine Bundle #1", "Charcoal Pine Bundle x2", DS3LocationCategory.MISC), - DS3LocationData("US: Blue Wooden Shield", "Blue Wooden Shield", DS3LocationCategory.SHIELD), - DS3LocationData("US: Cleric Hat", "Cleric Hat", DS3LocationCategory.ARMOR), - DS3LocationData("US: Cleric Blue Robe", "Cleric Blue Robe", DS3LocationCategory.ARMOR), - DS3LocationData("US: Cleric Gloves", "Cleric Gloves", DS3LocationCategory.ARMOR), - DS3LocationData("US: Cleric Trousers", "Cleric Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("US: Soul of an Unknown Traveler #2", "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("US: Charcoal Pine Resin", "Charcoal Pine Resin x2", DS3LocationCategory.MISC), - DS3LocationData("US: Loincloth", "Loincloth", DS3LocationCategory.ARMOR), - DS3LocationData("US: Bloodbite Ring", "Bloodbite Ring", DS3LocationCategory.RING, - miniboss = True), # Giant Rat drop - DS3LocationData("US: Charcoal Pine Bundle #2", "Charcoal Pine Bundle x2", DS3LocationCategory.MISC), - DS3LocationData("US: Soul of an Unknown Traveler #3", "Soul of an Unknown Traveler", DS3LocationCategory.MISC, - hidden = True), # In crates - DS3LocationData("US: Titanite Shard #3", "Titanite Shard", DS3LocationCategory.MISC), - DS3LocationData("US: Red Hilted Halberd", "Red Hilted Halberd", DS3LocationCategory.WEAPON), - DS3LocationData("US: Rusted Coin", "Rusted Coin x2", DS3LocationCategory.MISC), - DS3LocationData("US: Caestus", "Caestus", DS3LocationCategory.WEAPON), - DS3LocationData("US: Saint's Talisman", "Saint's Talisman", DS3LocationCategory.WEAPON), - DS3LocationData("US: Alluring Skull #3", "Alluring Skull x3", DS3LocationCategory.MISC), - DS3LocationData("US: Large Club", "Large Club", DS3LocationCategory.WEAPON), - DS3LocationData("US: Titanite Shard #4", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("US: Titanite Shard #5", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("US: Fading Soul #1", "Fading Soul", DS3LocationCategory.MISC), - DS3LocationData("US: Titanite Shard #6", "Titanite Shard", DS3LocationCategory.UPGRADE, - hidden = True), # hidden fall - DS3LocationData("US: Hand Axe", "Hand Axe", DS3LocationCategory.WEAPON), - DS3LocationData("US: Soul of an Unknown Traveler #4", "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("US: Ember #3", "Ember", DS3LocationCategory.MISC), - DS3LocationData("US: Mirrah Vest", "Mirrah Vest", DS3LocationCategory.ARMOR, - hidden = True), # Hidden fall - DS3LocationData("US: Mirrah Gloves", "Mirrah Gloves", DS3LocationCategory.ARMOR, - hidden = True), # Hidden fall - DS3LocationData("US: Mirrah Trousers", "Mirrah Trousers", DS3LocationCategory.ARMOR, - hidden = True), # Hidden fall - DS3LocationData("US: Plank Shield", "Plank Shield", DS3LocationCategory.SHIELD), - DS3LocationData("US: Red Bug Pellet", "Red Bug Pellet x2", DS3LocationCategory.MISC), - DS3LocationData("US: Chloranthy Ring", "Chloranthy Ring", DS3LocationCategory.RING, - hidden = True), # Hidden fall - DS3LocationData("US: Fire Clutch Ring", "Fire Clutch Ring", DS3LocationCategory.RING), - DS3LocationData("US: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), - DS3LocationData("US: Firebomb", "Firebomb x6", DS3LocationCategory.MISC), - DS3LocationData("US: Whip", "Whip", DS3LocationCategory.WEAPON, - hidden = True), # In enemy rando, the enemy may not burst through the wall - # and make this room obvious - DS3LocationData("US: Great Scythe", "Great Scythe", DS3LocationCategory.WEAPON), - DS3LocationData("US: Homeward Bone #3", "Homeward Bone x2", DS3LocationCategory.MISC), - DS3LocationData("US: Large Soul of a Deserted Corpse #3", "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("US: Ember #4", "Ember", DS3LocationCategory.MISC), - DS3LocationData("US: Large Soul of a Deserted Corpse #4", "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("US: Fading Soul #2", "Fading Soul", DS3LocationCategory.MISC), - DS3LocationData("US: Young White Branch #1", "Young White Branch", DS3LocationCategory.MISC), - DS3LocationData("US: Ember #5", "Ember", DS3LocationCategory.MISC), - DS3LocationData("US: Large Soul of a Deserted Corpse #5", "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("US: Young White Branch #2", "Young White Branch", DS3LocationCategory.MISC), - DS3LocationData("US: Reinforced Club", "Reinforced Club", DS3LocationCategory.WEAPON), - DS3LocationData("US: Soul of a Nameless Soldier", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("US: Loretta's Bone", "Loretta's Bone", DS3LocationCategory.KEY), - DS3LocationData("US: Northern Helm", "Northern Helm", DS3LocationCategory.ARMOR), - DS3LocationData("US: Northern Armor", "Northern Armor", DS3LocationCategory.ARMOR), - DS3LocationData("US: Northern Gloves", "Northern Gloves", DS3LocationCategory.ARMOR), - DS3LocationData("US: Northern Trousers", "Northern Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("US: Partizan", "Partizan", DS3LocationCategory.WEAPON, - missable = True), # requires projectile - DS3LocationData("US: Flame Stoneplate Ring", "Flame Stoneplate Ring", DS3LocationCategory.RING), - DS3LocationData("US: Red and White Shield", "Red and White Shield", DS3LocationCategory.SHIELD, - offline = "02,0:53100740::", missable = True), # requires projectile), - DS3LocationData("US: Small Leather Shield", "Small Leather Shield", DS3LocationCategory.SHIELD), - DS3LocationData("US: Pale Tongue", "Pale Tongue", DS3LocationCategory.MISC), - DS3LocationData("US: Large Soul of a Deserted Corpse #6", "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("US: Kukri", "Kukri x9", DS3LocationCategory.MISC, + DS3LocationData("US: Flynn's Ring (tower village, rooftop)", "Flynn's Ring", + DS3LocationCategory.RING), + DS3LocationData("US: Undead Bone Shard (by white tree)", "Undead Bone Shard", + DS3LocationCategory.HEALTH), + DS3LocationData("US: Alluring Skull (Foot of the High Wall, behind carriage)", + "Alluring Skull x2", DS3LocationCategory.MISC), + DS3LocationData("US: Mortician's Ashes (graveyard by white tree)", "Mortician's Ashes", + DS3LocationCategory.KEY, progression = True), + DS3LocationData("US: Homeward Bone (tower village, jump from roof)", "Homeward Bone x2", + DS3LocationCategory.MISC, hidden = True), # Hidden fall + DS3LocationData("US: Caduceus Round Shield (right after stable exit)", + "Caduceus Round Shield", DS3LocationCategory.SHIELD), + DS3LocationData("US: Ember (by miniboss before Road of Sacrifices)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("US: Soul of an Unknown Traveler (chasm crypt)", + "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("US: Repair Powder (first building, balcony)", "Repair Powder x2", + DS3LocationCategory.MISC), + DS3LocationData("US: Homeward Bone (stable roof)", "Homeward Bone x2", + DS3LocationCategory.MISC), + DS3LocationData("US: Titanite Shard (side path on the way to Dilapidated Bridge)", + "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("US: Wargod Wooden Shield (Pit of Hollows)", "Wargod Wooden Shield", + DS3LocationCategory.SHIELD), + DS3LocationData("US: Large Soul of a Deserted Corpse (on the way to tower, by well)", + "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + DS3LocationData("US: Ember (bridge on the way to tower)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("US: Large Soul of a Deserted Corpse (stable)", + "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + DS3LocationData("US: Titanite Shard (porch after burning tree)", "Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("US: Alluring Skull (tower village building, upstairs)", + "Alluring Skull x2", DS3LocationCategory.MISC), + DS3LocationData("US: Charcoal Pine Bundle (first building)", "Charcoal Pine Bundle x2", + DS3LocationCategory.MISC), + DS3LocationData("US: Blue Wooden Shield (graveyard by white tree)", "Blue Wooden Shield", + DS3LocationCategory.SHIELD), + DS3LocationData("US: Cleric Hat (graveyard by white tree)", "Cleric Hat", + DS3LocationCategory.ARMOR), + DS3LocationData("US: Cleric Blue Robe (graveyard by white tree)", "Cleric Blue Robe", + DS3LocationCategory.ARMOR), + DS3LocationData("US: Cleric Gloves (graveyard by white tree)", "Cleric Gloves", + DS3LocationCategory.ARMOR), + DS3LocationData("US: Cleric Trousers (graveyard by white tree)", "Cleric Trousers", + DS3LocationCategory.ARMOR), + DS3LocationData("US: Soul of an Unknown Traveler (portcullis by burning tree)", + "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("US: Charcoal Pine Resin (hanging corpse room)", "Charcoal Pine Resin x2", + DS3LocationCategory.MISC), + DS3LocationData("US: Loincloth (by Velka statue)", "Loincloth", DS3LocationCategory.ARMOR), + DS3LocationData("US: Bloodbite Ring (miniboss in sewer)", "Bloodbite Ring", + DS3LocationCategory.RING, miniboss = True), # Giant Rat drop + DS3LocationData("US: Charcoal Pine Bundle (first building)", "Charcoal Pine Bundle x2", + DS3LocationCategory.MISC), + DS3LocationData("US: Soul of an Unknown Traveler (on the way to Dilapidated Bridge, in crates)", + "Soul of an Unknown Traveler", DS3LocationCategory.MISC, hidden = True), + DS3LocationData("US: Titanite Shard (on the way to Dilapidated Bridge, up ladder)", + "Titanite Shard", DS3LocationCategory.MISC), + DS3LocationData("US: Red Hilted Halberd (chasm crypt)", "Red Hilted Halberd", + DS3LocationCategory.WEAPON), + DS3LocationData("US: Rusted Coin (wooden ledge above Dilapidated Bridge)", "Rusted Coin x2", + DS3LocationCategory.MISC), + DS3LocationData("US: Caestus (sewer)", "Caestus", DS3LocationCategory.WEAPON), + DS3LocationData("US: Saint's Talisman (chasm, by ladder)", "Saint's Talisman", + DS3LocationCategory.WEAPON), + DS3LocationData("US: Alluring Skull (on the way to tower, behind building)", + "Alluring Skull x3", DS3LocationCategory.MISC), + DS3LocationData("US: Large Club (tower village, by miniboss)", "Large Club", + DS3LocationCategory.WEAPON), + DS3LocationData("US: Titanite Shard (chasm #1)", "Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("US: Titanite Shard (chasm #2)", "Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("US: Fading Soul (outside stable)", "Fading Soul", + DS3LocationCategory.MISC), + DS3LocationData("US: Titanite Shard (lower path to Cliff Underside)", "Titanite Shard", + DS3LocationCategory.UPGRADE, hidden = True), # hidden fall + DS3LocationData("US: Hand Axe (by Cornyx)", "Hand Axe", DS3LocationCategory.WEAPON), + DS3LocationData("US: Soul of an Unknown Traveler (pillory past stable)", + "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("US: Ember (by stairs to boss)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("US: Mirrah Vest (tower village, jump from roof)", "Mirrah Vest", + DS3LocationCategory.ARMOR, hidden = True), # Hidden fall + DS3LocationData("US: Mirrah Gloves (tower village, jump from roof)", "Mirrah Gloves", + DS3LocationCategory.ARMOR, hidden = True), # Hidden fall + DS3LocationData("US: Mirrah Trousers (tower village, jump from roof)", "Mirrah Trousers", + DS3LocationCategory.ARMOR, hidden = True), # Hidden fall + DS3LocationData("US: Plank Shield (outside stable, by NPC)", "Plank Shield", + DS3LocationCategory.SHIELD), + DS3LocationData("US: Red Bug Pellet (tower village building, basement)", + "Red Bug Pellet x2", DS3LocationCategory.MISC), + DS3LocationData("US: Chloranthy Ring (tower village, jump from roof)", "Chloranthy Ring", + DS3LocationCategory.RING, hidden = True), # Hidden fall + DS3LocationData("US: Fire Clutch Ring (wooden walkway past stable)", "Fire Clutch Ring", + DS3LocationCategory.RING), + DS3LocationData("US: Estus Shard (under burning tree)", "Estus Shard", + DS3LocationCategory.HEALTH), + DS3LocationData("US: Firebomb (stable roof)", "Firebomb x6", DS3LocationCategory.MISC), + # In enemy rando, the enemy may not burst through the wall and make this room obvious + DS3LocationData("US: Whip (on the way to Dilapidated Bridge, behind wooden wall)", + "Whip", DS3LocationCategory.WEAPON, hidden = True), + DS3LocationData("US: Great Scythe (building by white tree, balcony)", "Great Scythe", + DS3LocationCategory.WEAPON), + DS3LocationData("US: Homeward Bone (by Yoel)", "Homeward Bone x2", + DS3LocationCategory.MISC), + DS3LocationData("US: Large Soul of a Deserted Corpse (around corner by Cliff Underside)", + "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL, + hidden = True), # Hidden corner + DS3LocationData("US: Ember (behind burning tree)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("US: Large Soul of a Deserted Corpse (across from Foot of the High Wall)", + "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + DS3LocationData("US: Fading Soul (by white tree)", "Fading Soul", DS3LocationCategory.MISC), + DS3LocationData("US: Young White Branch (by white tree #1)", "Young White Branch", + DS3LocationCategory.MISC), + DS3LocationData("US: Ember (by white tree)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("US: Large Soul of a Deserted Corpse (by white tree)", + "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + DS3LocationData("US: Young White Branch (by white tree #2)", "Young White Branch", + DS3LocationCategory.MISC), + DS3LocationData("US: Reinforced Club (by white tree)", "Reinforced Club", + DS3LocationCategory.WEAPON), + DS3LocationData("US: Soul of a Nameless Soldier (top of tower)", + "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("US: Loretta's Bone (first building, hanging corpse on balcony)", + "Loretta's Bone", DS3LocationCategory.KEY), + DS3LocationData("US: Northern Helm (tower village, hanging corpse)", "Northern Helm", + DS3LocationCategory.ARMOR), + DS3LocationData("US: Northern Armor (tower village, hanging corpse)", "Northern Armor", + DS3LocationCategory.ARMOR), + DS3LocationData("US: Northern Gloves (tower village, hanging corpse)", "Northern Gloves", + DS3LocationCategory.ARMOR), + DS3LocationData("US: Northern Trousers (tower village, hanging corpse)", "Northern Trousers", + DS3LocationCategory.ARMOR), + DS3LocationData("US: Partizan (hanging corpse above Cliff Underside)", "Partizan", + DS3LocationCategory.WEAPON, missable = True), # requires projectile + DS3LocationData("US: Flame Stoneplate Ring (hanging corpse by Mound-Maker transport)", + "Flame Stoneplate Ring", DS3LocationCategory.RING), + DS3LocationData("US: Red and White Shield (chasm, hanging corpse)", "Red and White Shield", + DS3LocationCategory.SHIELD, offline = "02,0:53100740::", missable = True), # requires projectile - DS3LocationData("US: Life Ring+1", "Life Ring+1", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("US: Poisonbite Ring+1", "Poisonbite Ring+1", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("US: Covetous Silver Serpent Ring+2", "Covetous Silver Serpent Ring+2", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("US: Human Pine Resin", "Human Pine Resin x4", DS3LocationCategory.MISC), - DS3LocationData("US: Homeward Bone #4", "Homeward Bone", DS3LocationCategory.MISC), - DS3LocationData("US: Irithyll Straight Sword", "Irithyll Straight Sword", DS3LocationCategory.WEAPON, - miniboss = True), # Boreal Outrider drop - DS3LocationData("US: Fire Gem", "Fire Gem", DS3LocationCategory.UPGRADE, - miniboss = True), # Fire Demon drop - DS3LocationData("US: Warrior of Sunlight", "Warrior of Sunlight", DS3LocationCategory.UNIQUE, + DS3LocationData("US: Small Leather Shield (first building, hanging corpse by entrance)", + "Small Leather Shield", DS3LocationCategory.SHIELD), + DS3LocationData("US: Pale Tongue (tower village, hanging corpse)", "Pale Tongue", + DS3LocationCategory.MISC), + DS3LocationData("US: Large Soul of a Deserted Corpse (hanging corpse room, over stairs)", + "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + DS3LocationData("US: Kukri (hanging corpse above burning tree)", "Kukri x9", + DS3LocationCategory.MISC, missable = True), # requires projectile + DS3LocationData("US: Life Ring+1 (tower on the way to village)", "Life Ring+1", + DS3LocationCategory.RING, ngp = True), + DS3LocationData("US: Poisonbite Ring+1 (graveyard by white tree, near well)", "Poisonbite Ring+1", + DS3LocationCategory.RING, ngp = True), + DS3LocationData("US: Covetous Silver Serpent Ring+2 (tower village, drop down from roof)", + "Covetous Silver Serpent Ring+2", DS3LocationCategory.RING, ngp = True, + hidden = True), # Hidden fall + DS3LocationData("US: Human Pine Resin (tower village building, chest upstairs)", + "Human Pine Resin x4", DS3LocationCategory.MISC), + DS3LocationData("US: Homeward Bone (tower village, right of first drop)", "Homeward Bone", + DS3LocationCategory.MISC), + DS3LocationData("US: Irithyll Straight Sword (miniboss drop, by Road of Sacrifices)", + "Irithyll Straight Sword", DS3LocationCategory.WEAPON, miniboss = True), + DS3LocationData("US: Fire Gem (tower village, miniboss drop)", "Fire Gem", + DS3LocationCategory.UPGRADE, miniboss = True), + DS3LocationData("US: Warrior of Sunlight (hanging corpse room, drop through hole)", + "Warrior of Sunlight", DS3LocationCategory.UNIQUE, hidden = True), # hidden fall - DS3LocationData("US: Mound-makers", "Mound-makers", DS3LocationCategory.UNIQUE, + DS3LocationData("US: Mound-makers (Hodrick)", "Mound-makers", DS3LocationCategory.UNIQUE, missable = True), - DS3LocationData("US: Sharp Gem", "Sharp Gem", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("US: Heavy Gem", "Heavy Gem", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("US: Siegbräu", "Siegbräu", DS3LocationCategory.MISC, + DS3LocationData("US: Sharp Gem (lizard by Dilapidated Bridge)", "Sharp Gem", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("US: Heavy Gem (chasm, lizard)", "Heavy Gem", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("US: Siegbräu (Siegward)", "Siegbräu", DS3LocationCategory.MISC, missable = True, npc = True), - DS3LocationData("US: Heavy Gem (Hawkwood)", "Heavy Gem", DS3LocationCategory.UPGRADE, - offline = '00,0:50006070::', missable = True, npc = True), # Hawkwood (quest, after Greatwood or Sage) - DS3LocationData("US: Hollowslayer Greatsword", "Hollowslayer Greatsword", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("US: Arstor's Spear", "Arstor's Spear", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("US -> RS", None, DS3LocationCategory.EVENT), + DS3LocationData("US: Heavy Gem (Hawkwood)", "Heavy Gem", DS3LocationCategory.UPGRADE, + offline = '00,0:50006070::', missable = True, + npc = True), # Hawkwood (quest, after Greatwood or Sage) + DS3LocationData("US -> RS", None, DS3LocationCategory.EVENT), # Yoel/Yuria of Londor - DS3LocationData("US: Soul Arrow", "Soul Arrow", DS3LocationCategory.SPELL, - offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, shop = True), - DS3LocationData("US: Heavy Soul Arrow", "Heavy Soul Arrow", DS3LocationCategory.SPELL, - offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, shop = True), - DS3LocationData("US: Magic Weapon", "Magic Weapon", DS3LocationCategory.SPELL, - offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, shop = True), - DS3LocationData("US: Magic Shield", "Magic Shield", DS3LocationCategory.SPELL, - offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, shop = True), - DS3LocationData("US: Soul Greatsword", "Soul Greatsword", DS3LocationCategory.SPELL, - offline = '99,0:-1:50000,110000,70000450,70000475:', missable = True, npc = True, shop = True), - DS3LocationData("US: Dark Hand", "Dark Hand", DS3LocationCategory.WEAPON, - missable = True, npc = True), - DS3LocationData("US: Untrue White Ring", "Untrue White Ring", DS3LocationCategory.RING, + DS3LocationData("FS: Soul Arrow (Yoel/Yuria)", "Soul Arrow", DS3LocationCategory.SPELL, + offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, + shop = True), + DS3LocationData("FS: Heavy Soul Arrow (Yoel/Yuria)", "Heavy Soul Arrow", + DS3LocationCategory.SPELL, offline = '99,0:-1:50000,110000,70000116:', + missable = True, npc = True, shop = True), + DS3LocationData("FS: Magic Weapon (Yoel/Yuria)", "Magic Weapon", DS3LocationCategory.SPELL, + offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, + shop = True), + DS3LocationData("FS: Magic Shield (Yoel/Yuria)", "Magic Shield", DS3LocationCategory.SPELL, + offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, + shop = True), + DS3LocationData("FS: Soul Greatsword (Yoel/Yuria)", "Soul Greatsword", + DS3LocationCategory.SPELL, + offline = '99,0:-1:50000,110000,70000450,70000475:', missable = True, + npc = True, shop = True), + DS3LocationData("FS: Dark Hand (Yoel/Yuria)", "Dark Hand", DS3LocationCategory.WEAPON, missable = True, npc = True), - DS3LocationData("US: Untrue Dark Ring", "Untrue Dark Ring", DS3LocationCategory.RING, + DS3LocationData("FS: Untrue White Ring (Yoel/Yuria)", "Untrue White Ring", + DS3LocationCategory.RING, missable = True, npc = True), + DS3LocationData("FS: Untrue Dark Ring (Yoel/Yuria)", "Untrue Dark Ring", + DS3LocationCategory.RING, missable = True, npc = True), + DS3LocationData("FS: Londor Braille Divine Tome (Yoel/Yuria)", "Londor Braille Divine Tome", + DS3LocationCategory.UNIQUE, offline = '99,0:-1:40000,110000,70000116:', missable = True, npc = True), - DS3LocationData("US: Londor Braille Divine Tome", "Londor Braille Divine Tome", DS3LocationCategory.UNIQUE, - offline = '99,0:-1:40000,110000,70000116:', missable = True, npc = True), - DS3LocationData("US: Darkdrift", "Darkdrift", DS3LocationCategory.WEAPON, + DS3LocationData("FS: Darkdrift (Yoel/Yuria)", "Darkdrift", DS3LocationCategory.WEAPON, missable = True, drop = True, npc = True), # kill her or kill Soul of Cinder # Cornyx of the Great Swamp # These aren't missable because the Shrine Handmaid will carry them if you kill Cornyx. - DS3LocationData("US: Fireball", "Fireball", DS3LocationCategory.SPELL, - npc = True, shop = True), - DS3LocationData("US: Fire Surge", "Fire Surge", DS3LocationCategory.SPELL, - npc = True, shop = True), - DS3LocationData("US: Great Combustion", "Great Combustion", DS3LocationCategory.SPELL, + DS3LocationData("FS: Fireball (Cornyx)", "Fireball", DS3LocationCategory.SPELL, npc = True, + shop = True), + DS3LocationData("FS: Fire Surge (Cornyx)", "Fire Surge", DS3LocationCategory.SPELL, npc = True, shop = True), - DS3LocationData("US: Flash Sweat", "Flash Sweat", DS3LocationCategory.SPELL, + DS3LocationData("FS: Great Combustion (Cornyx)", "Great Combustion", + DS3LocationCategory.SPELL, npc = True, shop = True), + DS3LocationData("FS: Flash Sweat (Cornyx)", "Flash Sweat", DS3LocationCategory.SPELL, npc = True, shop = True), # These are missable if you kill Cornyx before giving him the right tomes. - DS3LocationData("US: Poison Mist", "Poison Mist", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("US: Fire Orb", "Fire Orb", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("US: Profuse Sweat", "Profuse Sweat", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("US: Bursting Fireball", "Bursting Fireball", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("US: Acid Surge", "Acid Surge", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("US: Carthus Flame Arc", "Carthus Flame Arc", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("US: Carthus Beacon", "Carthus Beacon", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("US: Great Chaos Fire Orb", "Great Chaos Fire Orb", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("US: Chaos Storm", "Chaos Storm", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + DS3LocationData("FS: Poison Mist (Cornyx for Great Swamp Tome)", "Poison Mist", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Fire Orb (Cornyx for Great Swamp Tome)", "Fire Orb", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Profuse Sweat (Cornyx for Great Swamp Tome)", "Profuse Sweat", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Bursting Fireball (Cornyx for Great Swamp Tome)", "Bursting Fireball", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Acid Surge (Cornyx for Carthus Tome)", "Acid Surge", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Carthus Flame Arc (Cornyx for Carthus Tome)", "Carthus Flame Arc", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Carthus Beacon (Cornyx for Carthus Tome)", "Carthus Beacon", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Great Chaos Fire Orb (Cornyx for Izalith Tome)", + "Great Chaos Fire Orb", DS3LocationCategory.SPELL, missable = True, + npc = True, shop = True), + DS3LocationData("FS: Chaos Storm (Cornyx for Izalith Tome)", "Chaos Storm", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), # Irina of Carim # These aren't in their own location because you don't actually need the Grave Key to access # Irena—you can just fall down the cliff near Eygon. - DS3LocationData("US: Saint's Ring", "Saint's Ring", DS3LocationCategory.RING, - npc = True, shop = True), - DS3LocationData("US: Heal", "Heal", DS3LocationCategory.SPELL, + DS3LocationData("FS: Saint's Ring (Irina)", "Saint's Ring", DS3LocationCategory.RING, npc = True, shop = True), - DS3LocationData("US: Replenishment", "Replenishment", DS3LocationCategory.SPELL, - npc = True, shop = True), - DS3LocationData("US: Caressing Tears", "Caressing Tears", DS3LocationCategory.SPELL, + DS3LocationData("FS: Heal (Irina)", "Heal", DS3LocationCategory.SPELL, npc = True, + shop = True), + DS3LocationData("FS: Replenishment (Irina)", "Replenishment", DS3LocationCategory.SPELL, npc = True, shop = True), - DS3LocationData("US: Homeward", "Homeward", DS3LocationCategory.SPELL, + DS3LocationData("FS: Caressing Tears (Irina)", "Caressing Tears", DS3LocationCategory.SPELL, npc = True, shop = True), - DS3LocationData("US: Med Heal", "Med Heal", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("US: Tears of Denial", "Tears of Denial", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("US: Force", "Force", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("US: Bountiful Light", "Bountiful Light", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("US: Magic Barrier", "Magic Barrier", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("US: Blessed Weapon", "Blessed Weapon", DS3LocationCategory.SPELL, + DS3LocationData("FS: Homeward (Irina)", "Homeward", DS3LocationCategory.SPELL, npc = True, + shop = True), + DS3LocationData("FS: Med Heal (Irina for Tome of Carim)", "Med Heal", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Tears of Denial (Irina for Tome of Carim)", "Tears of Denial", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Force (Irina for Tome of Carim)", "Force", DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Bountiful Light (Irina for Tome of Lothric)", "Bountiful Light", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Magic Barrier (Irina for Tome of Lothric)", "Magic Barrier", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Blessed Weapon (Irina for Tome of Lothric)", "Blessed Weapon", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), ], "Road of Sacrifices": [ - DS3LocationData("RS: Soul of a Crystal Sage", "Soul of a Crystal Sage", DS3LocationCategory.SOUL, - prominent = True, boss = True), - DS3LocationData("RS: Exile Greatsword", "Exile Greatsword", DS3LocationCategory.WEAPON, - hostile_npc = True), # Exile Knight #2 drop - DS3LocationData("RS: Great Club", "Great Club", DS3LocationCategory.WEAPON, - hostile_npc = True), # Exile Knight #1 drop - DS3LocationData("RS: Heysel Pick", "Heysel Pick", DS3LocationCategory.WEAPON, - missable = True, hostile_npc = True), # Heysel drop - DS3LocationData("RS: Xanthous Crown", "Xanthous Crown", DS3LocationCategory.WEAPON, - missable = True, hostile_npc = True), # Heysel drop - DS3LocationData("RS: Butcher Knife", "Butcher Knife", DS3LocationCategory.WEAPON, - hostile_npc = True), # Madwoman - DS3LocationData("RS: Titanite Shard #1", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("RS: Titanite Shard #2", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("RS: Green Blossom #1", "Green Blossom x4", DS3LocationCategory.MISC), - DS3LocationData("RS: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), - DS3LocationData("RS: Ring of Sacrifice", "Ring of Sacrifice", DS3LocationCategory.MISC, - hidden = True), # hidden fall - DS3LocationData("RS: Soul of an Unknown Traveler #1", "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("RS: Fallen Knight Helm", "Fallen Knight Helm", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Fallen Knight Armor", "Fallen Knight Armor", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Fallen Knight Gauntlets", "Fallen Knight Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Fallen Knight Trousers", "Fallen Knight Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Heretic's Staff", "Heretic's Staff", DS3LocationCategory.WEAPON), - DS3LocationData("RS: Large Soul of an Unknown Traveler", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("RS: Conjurator Hood", "Conjurator Hood", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Conjurator Robe", "Conjurator Robe", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Conjurator Manchettes", "Conjurator Manchettes", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Conjurator Boots", "Conjurator Boots", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Soul of an Unknown Traveler #2", "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("RS: Green Blossom #2", "Green Blossom x2", DS3LocationCategory.MISC), - DS3LocationData("RS: Great Swamp Pyromancy Tome", "Great Swamp Pyromancy Tome", DS3LocationCategory.UNIQUE), - DS3LocationData("RS: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC), - DS3LocationData("RS: Titanite Shard #3", "Titanite Shard", DS3LocationCategory.MISC), - DS3LocationData("RS: Twin Dragon Greatshield", "Twin Dragon Greatshield", DS3LocationCategory.SHIELD), - DS3LocationData("RS: Sorcerer Hood", "Sorcerer Hood", DS3LocationCategory.ARMOR, - hidden = True), # Hidden fall - DS3LocationData("RS: Sorcerer Robe", "Sorcerer Robe", DS3LocationCategory.ARMOR, - hidden = True), # Hidden fall - DS3LocationData("RS: Sorcerer Gloves", "Sorcerer Gloves", DS3LocationCategory.ARMOR, - hidden = True), # Hidden fall - DS3LocationData("RS: Sorcerer Trousers", "Sorcerer Trousers", DS3LocationCategory.ARMOR, - hidden = True), # Hidden fall - DS3LocationData("RS: Sage Ring", "Sage Ring", DS3LocationCategory.RING, - hidden = True), # Hidden fall - DS3LocationData("RS: Grass Crest Shield", "Grass Crest Shield", DS3LocationCategory.SHIELD), - DS3LocationData("RS: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("RS: Blue Bug Pellet", "Blue Bug Pellet x2", DS3LocationCategory.MISC), - DS3LocationData("RS: Soul of an Unknown Traveler #3", "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("RS: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), - DS3LocationData("RS: Titanite Shard #4", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("RS: Brigand Twindaggers", "Brigand Twindaggers", DS3LocationCategory.WEAPON), - DS3LocationData("RS: Braille Divine Tome of Carim", "Braille Divine Tome of Carim", DS3LocationCategory.UNIQUE, - hidden = True), # Hidden fall - DS3LocationData("RS: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("RS: Sellsword Twinblades", "Sellsword Twinblades", DS3LocationCategory.WEAPON), - DS3LocationData("RS: Golden Falcon Shield", "Golden Falcon Shield", DS3LocationCategory.SHIELD), - DS3LocationData("RS: Brigand Axe", "Brigand Axe", DS3LocationCategory.WEAPON), - DS3LocationData("RS: Brigand Hood", "Brigand Hood", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Brigand Armor", "Brigand Armor", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Brigand Gauntlets", "Brigand Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Brigand Trousers", "Brigand Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Morne's Ring", "Morne's Ring", DS3LocationCategory.RING, + DS3LocationData("RS: Soul of a Crystal Sage", "Soul of a Crystal Sage", + DS3LocationCategory.SOUL, prominent = True, boss = True), + DS3LocationData("RS: Exile Greatsword (NPC drop by Farron Keep)", "Exile Greatsword", + DS3LocationCategory.WEAPON, hostile_npc = True), # Exile Knight #2 drop + DS3LocationData("RS: Great Club (NPC drop by Farron Keep)", "Great Club", + DS3LocationCategory.WEAPON, hostile_npc = True), # Exile Knight #1 drop + DS3LocationData("RS: Heysel Pick (Heysel drop)", "Heysel Pick", DS3LocationCategory.WEAPON, + missable = True, hostile_npc = True), + DS3LocationData("RS: Xanthous Crown (Heysel drop)", "Xanthous Crown", + DS3LocationCategory.WEAPON, missable = True, hostile_npc = True), + DS3LocationData("RS: Butcher Knife (NPC drop beneath road)", "Butcher Knife", + DS3LocationCategory.WEAPON, hostile_npc = True), # Madwoman + DS3LocationData("RS: Titanite Shard (water by Halfway Fortress)", "Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("RS: Titanite Shard (woods, left of path from Halfway Fortress)", + "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("RS: Green Blossom (by deep water)", "Green Blossom x4", + DS3LocationCategory.MISC), + DS3LocationData("RS: Estus Shard (left of fire behind stronghold left room)", "Estus Shard", + DS3LocationCategory.HEALTH), + DS3LocationData("RS: Ring of Sacrifice (stronghold, drop from right room balcony)", + "Ring of Sacrifice", DS3LocationCategory.MISC, hidden = True), # hidden fall + DS3LocationData("RS: Soul of an Unknown Traveler (drop along wall from Halfway Fortress)", + "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("RS: Fallen Knight Helm (water's edge by Farron Keep)", + "Fallen Knight Helm", DS3LocationCategory.ARMOR), + DS3LocationData("RS: Fallen Knight Armor (water's edge by Farron Keep)", + "Fallen Knight Armor", DS3LocationCategory.ARMOR), + DS3LocationData("RS: Fallen Knight Gauntlets (water's edge by Farron Keep)", + "Fallen Knight Gauntlets", DS3LocationCategory.ARMOR), + DS3LocationData("RS: Fallen Knight Trousers (water's edge by Farron Keep)", + "Fallen Knight Trousers", DS3LocationCategory.ARMOR), + DS3LocationData("RS: Heretic's Staff (stronghold left room)", "Heretic's Staff", + DS3LocationCategory.WEAPON), + DS3LocationData("RS: Large Soul of an Unknown Traveler (left of stairs to Farron Keep)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("RS: Conjurator Hood (deep water)", "Conjurator Hood", + DS3LocationCategory.ARMOR), + DS3LocationData("RS: Conjurator Robe (deep water)", "Conjurator Robe", + DS3LocationCategory.ARMOR), + DS3LocationData("RS: Conjurator Manchettes (deep water)", "Conjurator Manchettes", + DS3LocationCategory.ARMOR), + DS3LocationData("RS: Conjurator Boots (deep water)", "Conjurator Boots", + DS3LocationCategory.ARMOR), + DS3LocationData("RS: Soul of an Unknown Traveler (right of door to stronghold left)", + "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("RS: Green Blossom (water by Crucifixion Woods bonfire)", + "Green Blossom x2", DS3LocationCategory.MISC), + DS3LocationData("RS: Great Swamp Pyromancy Tome (deep water)", "Great Swamp Pyromancy Tome", + DS3LocationCategory.UNIQUE), + DS3LocationData("RS: Homeward Bone (balcony by Farron Keep)", "Homeward Bone x2", + DS3LocationCategory.MISC), + DS3LocationData("RS: Titanite Shard (woods, surrounded by enemies)", "Titanite Shard", + DS3LocationCategory.MISC), + DS3LocationData("RS: Twin Dragon Greatshield (woods by Crucifixion Woods bonfire)", + "Twin Dragon Greatshield", DS3LocationCategory.SHIELD), + DS3LocationData("RS: Sorcerer Hood (water beneath stronghold)", "Sorcerer Hood", + DS3LocationCategory.ARMOR, hidden = True), # Hidden fall + DS3LocationData("RS: Sorcerer Robe (water beneath stronghold)", "Sorcerer Robe", + DS3LocationCategory.ARMOR, hidden = True), # Hidden fall + DS3LocationData("RS: Sorcerer Gloves (water beneath stronghold)", "Sorcerer Gloves", + DS3LocationCategory.ARMOR, hidden = True), # Hidden fall + DS3LocationData("RS: Sorcerer Trousers (water beneath stronghold)", "Sorcerer Trousers", + DS3LocationCategory.ARMOR, hidden = True), # Hidden fall + DS3LocationData("RS: Sage Ring (water beneath stronghold)", "Sage Ring", + DS3LocationCategory.RING, hidden = True), # Hidden fall + DS3LocationData("RS: Grass Crest Shield (water by Crucifixion Woods bonfire)", + "Grass Crest Shield", DS3LocationCategory.SHIELD), + DS3LocationData("RS: Ember (right of fire behind stronghold left room)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("RS: Blue Bug Pellet (broken stairs by Orbeck)", "Blue Bug Pellet x2", + DS3LocationCategory.MISC), + DS3LocationData("RS: Soul of an Unknown Traveler (road, by wagon)", + "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("RS: Shriving Stone (road, by start)", "Shriving Stone", + DS3LocationCategory.UPGRADE), + DS3LocationData("RS: Titanite Shard (road, on bridge after you go under)", + "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("RS: Brigand Twindaggers (beneath road)", "Brigand Twindaggers", + DS3LocationCategory.WEAPON), + DS3LocationData("RS: Braille Divine Tome of Carim (drop from bridge to Halfway Fortress)", + "Braille Divine Tome of Carim", DS3LocationCategory.UNIQUE, hidden = True), # Hidden fall - DS3LocationData("RS: Sellsword Helm", "Sellsword Helm", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Sellsword Armor", "Sellsword Armor", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Sellsword Gauntlet", "Sellsword Gauntlet", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Sellsword Trousers", "Sellsword Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Farron Coal", "Farron Coal", DS3LocationCategory.UNIQUE), - DS3LocationData("RS: Chloranthy Ring+2", "Chloranthy Ring+2", DS3LocationCategory.RING, - hidden = True, ngp = True), # Hidden fall - DS3LocationData("RS: Lingering Dragoncrest Ring+1", "Lingering Dragoncrest Ring+1", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("RS: Great Swamp Ring", "Great Swamp Ring", DS3LocationCategory.RING, + DS3LocationData("RS: Ember (right of Halfway Fortress entrance)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("RS: Sellsword Twinblades (keep perimeter)", "Sellsword Twinblades", + DS3LocationCategory.WEAPON), + DS3LocationData("RS: Golden Falcon Shield (path from stronghold right room to Farron Keep)", + "Golden Falcon Shield", DS3LocationCategory.SHIELD), + DS3LocationData("RS: Brigand Axe (beneath road)", "Brigand Axe", + DS3LocationCategory.WEAPON), + DS3LocationData("RS: Brigand Hood (beneath road)", "Brigand Hood", + DS3LocationCategory.ARMOR), + DS3LocationData("RS: Brigand Armor (beneath road)", "Brigand Armor", + DS3LocationCategory.ARMOR), + DS3LocationData("RS: Brigand Gauntlets (beneath road)", "Brigand Gauntlets", + DS3LocationCategory.ARMOR), + DS3LocationData("RS: Brigand Trousers (beneath road)", "Brigand Trousers", + DS3LocationCategory.ARMOR), + DS3LocationData("RS: Morne's Ring (drop from bridge to Halfway Fortress)", "Morne's Ring", + DS3LocationCategory.RING, hidden = True), # Hidden fall + DS3LocationData("RS: Sellsword Helm (keep perimeter balcony)", "Sellsword Helm", + DS3LocationCategory.ARMOR), + DS3LocationData("RS: Sellsword Armor (keep perimeter balcony)", "Sellsword Armor", + DS3LocationCategory.ARMOR), + DS3LocationData("RS: Sellsword Gauntlet (keep perimeter balcony)", "Sellsword Gauntlet", + DS3LocationCategory.ARMOR), + DS3LocationData("RS: Sellsword Trousers (keep perimeter balcony)", "Sellsword Trousers", + DS3LocationCategory.ARMOR), + DS3LocationData("RS: Farron Coal (keep perimeter)", "Farron Coal", + DS3LocationCategory.UNIQUE), + DS3LocationData("RS: Chloranthy Ring+2 (road, drop across from carriage)", + "Chloranthy Ring+2", DS3LocationCategory.RING, hidden = True, + ngp = True), # Hidden fall + DS3LocationData("RS: Lingering Dragoncrest Ring+1 (water)", "Lingering Dragoncrest Ring+1", + DS3LocationCategory.RING, ngp = True), + DS3LocationData("RS: Great Swamp Ring (miniboss drop, by Farron Keep)", + "Great Swamp Ring", DS3LocationCategory.RING, miniboss = True), # Giant Crab drop - DS3LocationData("RS: Blue Sentinels", "Blue Sentinels", DS3LocationCategory.UNIQUE, + DS3LocationData("RS: Blue Sentinels (Horace)", "Blue Sentinels", DS3LocationCategory.UNIQUE, missable = True, npc = True), # Horace quest - DS3LocationData("RS: Crystal Gem", "Crystal Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("RS: Crystal Gem (stronghold, lizard)", "Crystal Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("RS: Fading Soul (woods by Crucifixion Woods bonfire)", "Fading Soul", + DS3LocationCategory.MISC, offline = '03,0:53300210::'), # Orbeck shop, all missable because he'll disappear if you don't talk to him for too long or # if you don't give him a scroll. - DS3LocationData("RS: Farron Dart", "Farron Dart", DS3LocationCategory.SPELL, - offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), - DS3LocationData("RS: Soul Arrow", "Soul Arrow", DS3LocationCategory.SPELL, - offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), - DS3LocationData("RS: Great Soul Arrow", "Great Soul Arrow", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("RS: Heavy Soul Arrow", "Heavy Soul Arrow", DS3LocationCategory.SPELL, - offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), - DS3LocationData("RS: Great Heavy Soul Arrow", "Great Heavy Soul Arrow", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("RS: Magic Weapon", "Magic Weapon", DS3LocationCategory.SPELL, - offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), - DS3LocationData("RS: Magic Shield", "Magic Shield", DS3LocationCategory.SPELL, - offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), - DS3LocationData("RS: Spook", "Spook", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("RS: Aural Decoy", "Aural Decoy", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("RS: Soul Greatsword", "Soul Greatsword", DS3LocationCategory.SPELL, - offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True), - DS3LocationData("RS: Farron Flashsword", "Farron Flashsword", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("RS: Pestilent Mist", "Pestilent Mist", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("RS: Great Farron Dart", "Great Farron Dart", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("RS: Farron Hail", "Farron Hail", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("RS: Homing Soulmass", "Homing Soulmass", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("RS: Soul Spear", "Soul Spear", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("RS: Homing Crystal Soulmass", "Homing Crystal Soulmass", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("RS: Crystal Soul Spear", "Crystal Soul Spear", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("RS: Crystal Magic Weapon", "Crystal Magic Weapon", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("RS: Cast Light", "Cast Light", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("RS: Twisted Wall of Light", "Twisted Wall of Light", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("RS: Hidden Weapon", "Hidden Weapon", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("RS: Hidden Body", "Hidden Body", DS3LocationCategory.SPELL, + DS3LocationData("FS: Farron Dart (Orbeck)", "Farron Dart", DS3LocationCategory.SPELL, + offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, + shop = True), + DS3LocationData("FS: Soul Arrow (Orbeck)", "Soul Arrow", DS3LocationCategory.SPELL, + offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, + shop = True), + DS3LocationData("FS: Great Soul Arrow (Orbeck)", "Great Soul Arrow", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Heavy Soul Arrow (Orbeck)", "Heavy Soul Arrow", + DS3LocationCategory.SPELL, offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), - DS3LocationData("RS: Repair", "Repair", DS3LocationCategory.SPELL, + DS3LocationData("FS: Great Heavy Soul Arrow (Orbeck)", "Great Heavy Soul Arrow", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Magic Weapon (Orbeck)", "Magic Weapon", DS3LocationCategory.SPELL, + offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, + shop = True), + DS3LocationData("FS: Magic Shield (Orbeck)", "Magic Shield", DS3LocationCategory.SPELL, + offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, + shop = True), + DS3LocationData("FS: Spook (Orbeck)", "Spook", DS3LocationCategory.SPELL, missable = True, + npc = True, shop = True), + DS3LocationData("FS: Aural Decoy (Orbeck)", "Aural Decoy", DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), - DS3LocationData("RS: Clandestine Coat", "Clandestine Coat", DS3LocationCategory.ARMOR, - missable = True, npc = True, shop = True), # Shrine Handmaid with Orbeck's Ashes + reload - DS3LocationData("RS: Young Dragon Ring", "Young Dragon Ring", DS3LocationCategory.RING, + DS3LocationData("FS: Soul Greatsword (Orbeck)", "Soul Greatsword", + DS3LocationCategory.SPELL, offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True), - DS3LocationData("RS: Slumbering Dragoncrest Ring", "Slumbering Dragoncrest Ring", DS3LocationCategory.RING, - missable = True, npc = True), - DS3LocationData("RS: Crystal Sage's Rapier", "Crystal Sage's Rapier", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("RS: Crystal Hail", "Crystal Hail", DS3LocationCategory.SPELL, - missable = True, boss = True, shop = True), - DS3LocationData("RS -> CD", None, DS3LocationCategory.EVENT), - DS3LocationData("RS -> FK", None, DS3LocationCategory.EVENT), + DS3LocationData("FS: Farron Flashsword (Orbeck)", "Farron Flashsword", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Pestilent Mist (Orbeck for any scroll)", "Pestilent Mist", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Great Farron Dart (Orbeck for Sage's Scroll)", "Great Farron Dart", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Farron Hail (Orbeck for Sage's Scroll)", "Farron Hail", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Homing Soulmass (Orbeck for Logan's Scroll)", "Homing Soulmass", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Soul Spear (Orbeck for Logan's Scroll)", "Soul Spear", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Homing Crystal Soulmass (Orbeck for Crystal Scroll)", + "Homing Crystal Soulmass", DS3LocationCategory.SPELL, missable = True, + npc = True, shop = True), + DS3LocationData("FS: Crystal Soul Spear (Orbeck for Crystal Scroll)", "Crystal Soul Spear", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Crystal Magic Weapon (Orbeck for Crystal Scroll)", + "Crystal Magic Weapon", DS3LocationCategory.SPELL, missable = True, + npc = True, shop = True), + DS3LocationData("FS: Cast Light (Orbeck for Golden Scroll)", "Cast Light", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Twisted Wall of Light (Orbeck for Golden Scroll)", + "Twisted Wall of Light", DS3LocationCategory.SPELL, missable = True, + npc = True, shop = True), + DS3LocationData("FS: Hidden Weapon (Orbeck for Golden Scroll)", "Hidden Weapon", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Hidden Body (Orbeck for Golden Scroll)", "Hidden Body", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Repair (Orbeck for Golden Scroll)", "Repair", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Clandestine Coat (shop with Orbeck's Ashes)", "Clandestine Coat", + DS3LocationCategory.ARMOR, missable = True, npc = True, + shop = True), # Shrine Handmaid with Orbeck's Ashes + reload + DS3LocationData("FS: Young Dragon Ring (Orbeck for one scroll and buying three spells)", + "Young Dragon Ring", DS3LocationCategory.RING, missable = True, npc = True), + DS3LocationData("FS: Slumbering Dragoncrest Ring (Orbeck for buying four specific spells)", + "Slumbering Dragoncrest Ring", DS3LocationCategory.RING, missable = True, + npc = True), + DS3LocationData("RS -> CD", None, DS3LocationCategory.EVENT), + DS3LocationData("RS -> FK", None, DS3LocationCategory.EVENT), + + # Shrine Handmaid after killing exiles + DS3LocationData("FS: Exile Mask (shop after killing NPCs in RS)", "Exile Mask", + DS3LocationCategory.ARMOR, hidden = True, hostile_npc = True, shop = True), + DS3LocationData("FS: Exile Armor (shop after killing NPCs in RS)", + "Exile Armor", DS3LocationCategory.ARMOR, hidden = True, + hostile_npc = True, shop = True), + DS3LocationData("FS: Exile Gauntlets (shop after killing NPCs in RS)", + "Exile Gauntlets", DS3LocationCategory.ARMOR, hidden = True, + hostile_npc = True, shop = True), + DS3LocationData("FS: Exile Leggings (shop after killing NPCs in RS)", + "Exile Leggings", DS3LocationCategory.ARMOR, hidden = True, + hostile_npc = True, shop = True), # Shrine Handmaid after killing Crystal Sage - DS3LocationData("RS: Sage's Big Hat", "Sage's Big Hat", DS3LocationCategory.ARMOR, - boss = True, shop = True), + DS3LocationData("FS: Sage's Big Hat (shop after killing RS boss)", + "Sage's Big Hat", DS3LocationCategory.ARMOR, boss = True, shop = True), # Yuria of Londor for Orbeck's Ashes - DS3LocationData("RS: Morion Blade", "Morion Blade", DS3LocationCategory.WEAPON, - missable = True, npc = True), + DS3LocationData("FS: Morion Blade (Yuria for Orbeck's Ashes)", "Morion Blade", + DS3LocationCategory.WEAPON, missable = True, npc = True), ], "Cathedral of the Deep": [ - DS3LocationData("CD: Herald Helm", "Herald Helm", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Herald Armor", "Herald Armor", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Herald Gloves", "Herald Gloves", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Herald Trousers", "Herald Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("CD: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("CD: Small Doll", "Small Doll", DS3LocationCategory.KEY, + DS3LocationData("CD: Herald Helm (path, by fire)", "Herald Helm", + DS3LocationCategory.ARMOR), + DS3LocationData("CD: Herald Armor (path, by fire)", "Herald Armor", + DS3LocationCategory.ARMOR), + DS3LocationData("CD: Herald Gloves (path, by fire)", "Herald Gloves", + DS3LocationCategory.ARMOR), + DS3LocationData("CD: Herald Trousers (path, by fire)", "Herald Trousers", + DS3LocationCategory.ARMOR), + DS3LocationData("CD: Twinkling Titanite (path, lizard #1)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("CD: Twinkling Titanite (path, lizard #2)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("CD: Small Doll (boss drop)", "Small Doll", DS3LocationCategory.KEY, prominent = True, progression = True, boss = True), - DS3LocationData("CD: Soul of the Deacons of the Deep", "Soul of the Deacons of the Deep", DS3LocationCategory.SOUL, - boss = True), - DS3LocationData("CD: Black Eye Orb", "Black Eye Orb", DS3LocationCategory.UNIQUE, - missable = True, npc = True), - DS3LocationData("CD: Winged Spear #1", "Winged Spear", DS3LocationCategory.WEAPON, - drop = True, missable = True), # Patches (kill) - DS3LocationData("CD: Spider Shield", "Spider Shield", DS3LocationCategory.SHIELD, - hostile_npc = True), # Brigand - DS3LocationData("CD: Notched Whip", "Notched Whip", DS3LocationCategory.WEAPON), - DS3LocationData("CD: Titanite Shard #1", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("CD: Astora Greatsword", "Astora Greatsword", DS3LocationCategory.WEAPON), - DS3LocationData("CD: Executioner's Greatsword", "Executioner's Greatsword", DS3LocationCategory.WEAPON), - DS3LocationData("CD: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), - DS3LocationData("CD: Curse Ward Greatshield", "Curse Ward Greatshield", DS3LocationCategory.SHIELD), - DS3LocationData("CD: Titanite Shard #2", "Titanite Shard", DS3LocationCategory.MISC), - DS3LocationData("CD: Large Soul of an Unknown Traveler #1", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("CD: Paladin's Ashes", "Paladin's Ashes", DS3LocationCategory.KEY, - progression = True), - DS3LocationData("CD: Arbalest", "Arbalest", DS3LocationCategory.WEAPON, - hidden = True), # Hidden fall - DS3LocationData("CD: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("CD: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("CD: Poisonbite Ring", "Poisonbite Ring", DS3LocationCategory.RING), - DS3LocationData("CD: Drang Armor", "Drang Armor", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Ember #3", "Ember", DS3LocationCategory.MISC), - DS3LocationData("CD: Duel Charm #1", "Duel Charm x3", DS3LocationCategory.MISC), - DS3LocationData("CD: Seek Guidance", "Seek Guidance", DS3LocationCategory.SPELL), - DS3LocationData("CD: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), - DS3LocationData("CD: Maiden Hood", "Maiden Hood", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Maiden Robe", "Maiden Robe", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Maiden Gloves", "Maiden Gloves", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Maiden Skirt", "Maiden Skirt", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Pale Tongue #1", "Pale Tongue", DS3LocationCategory.MISC, - hidden = True), # hidden fall - DS3LocationData("CD: Fading Soul", "Fading Soul", DS3LocationCategory.MISC), - DS3LocationData("CD: Blessed Gem", "Blessed Gem", DS3LocationCategory.UPGRADE, - hidden = True), # hidden fall - DS3LocationData("CD: Red Bug Pellet #1", "Red Bug Pellet", DS3LocationCategory.MISC), - DS3LocationData("CD: Soul of a Nameless Soldier #1", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("CD: Duel Charm #2", "Duel Charm", DS3LocationCategory.MISC), - DS3LocationData("CD: Large Soul of an Unknown Traveler #2", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("CD: Ember #4", "Ember", DS3LocationCategory.MISC), - DS3LocationData("CD: Repair Powder", "Repair Powder x3", DS3LocationCategory.MISC), - DS3LocationData("CD: Large Soul of an Unknown Traveler #3", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("CD: Large Soul of an Unknown Traveler #4", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("CD: Undead Hunter Charm", "Undead Hunter Charm x3", DS3LocationCategory.MISC, - hidden = True), # Have to jump from a buttress - DS3LocationData("CD: Red Bug Pellet #2", "Red Bug Pellet x3", DS3LocationCategory.MISC), - DS3LocationData("CD: Titanite Shard #3", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("CD: Titanite Shard #4", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("CD: Rusted Coin #1", "Rusted Coin x2", DS3LocationCategory.MISC), - DS3LocationData("CD: Drang Hammers", "Drang Hammers", DS3LocationCategory.WEAPON), - DS3LocationData("CD: Drang Shoes", "Drang Shoes", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Large Soul of an Unknown Traveler #5", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("CD: Pale Tongue #2", "Pale Tongue", DS3LocationCategory.MISC), - DS3LocationData("CD: Drang Gauntlets", "Drang Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("CD: Soul of a Nameless Soldier #2", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("CD: Exploding Bolt", "Exploding Bolt x6", DS3LocationCategory.MISC), - DS3LocationData("CD: Lloyd's Sword Ring", "Lloyd's Sword Ring", DS3LocationCategory.RING), - DS3LocationData("CD: Soul of a Nameless Soldier #3", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("CD: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC), - DS3LocationData("CD: Deep Gem", "Deep Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("CD: Titanite Shard #5", "Titanite Shard", DS3LocationCategory.MISC), - DS3LocationData("CD: Large Soul of an Unknown Traveler #6", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("CD: Soul of the Deacons of the Deep", "Soul of the Deacons of the Deep", + DS3LocationCategory.SOUL, boss = True), + DS3LocationData("CD: Black Eye Orb (Rosaria from Leonhard's quest)", "Black Eye Orb", + DS3LocationCategory.UNIQUE, missable = True, npc = True), + DS3LocationData("CD: Winged Spear (kill Patches)", "Winged Spear", + DS3LocationCategory.WEAPON, drop = True, missable = True), # Patches (kill) + DS3LocationData("CD: Spider Shield (NPC drop on path)", "Spider Shield", + DS3LocationCategory.SHIELD, hostile_npc = True), # Brigand + DS3LocationData("CD: Notched Whip (Cleansing Chapel)", "Notched Whip", + DS3LocationCategory.WEAPON), + DS3LocationData("CD: Titanite Shard (Cleansing Chapel windowsill, by miniboss)", + "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("CD: Astora Greatsword (graveyard, left of entrance)", "Astora Greatsword", + DS3LocationCategory.WEAPON), + DS3LocationData("CD: Executioner's Greatsword (graveyard, far end)", + "Executioner's Greatsword", DS3LocationCategory.WEAPON), + DS3LocationData("CD: Undead Bone Shard (gravestone by white tree)", "Undead Bone Shard", + DS3LocationCategory.HEALTH), + DS3LocationData("CD: Curse Ward Greatshield (by ladder from white tree to moat)", + "Curse Ward Greatshield", DS3LocationCategory.SHIELD), + DS3LocationData("CD: Titanite Shard (moat, far end)", "Titanite Shard", + DS3LocationCategory.MISC), + DS3LocationData("CD: Large Soul of an Unknown Traveler (lower roofs, semicircle balcony)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("CD: Paladin's Ashes (path, guarded by lower NPC)", "Paladin's Ashes", + DS3LocationCategory.KEY, progression = True), + DS3LocationData("CD: Arbalest (upper roofs, end of furthest buttress)", "Arbalest", + DS3LocationCategory.WEAPON), + DS3LocationData("CD: Ember (by back door)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("CD: Ember (side chapel upstairs, up ladder)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("CD: Poisonbite Ring (moat, hall past miniboss)", "Poisonbite Ring", + DS3LocationCategory.RING), + DS3LocationData("CD: Drang Armor (main hall, east)", "Drang Armor", + DS3LocationCategory.ARMOR), + DS3LocationData("CD: Ember (edge of platform before boss)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("CD: Duel Charm (next to Patches in onion armor)", "Duel Charm x3", + DS3LocationCategory.MISC), + DS3LocationData("CD: Seek Guidance (side chapel upstairs)", "Seek Guidance", + DS3LocationCategory.SPELL), + DS3LocationData("CD: Estus Shard (monument outside Cleansing Chapel)", "Estus Shard", + DS3LocationCategory.HEALTH), + DS3LocationData("CD: Maiden Hood (main hall south)", "Maiden Hood", + DS3LocationCategory.ARMOR), + DS3LocationData("CD: Maiden Robe (main hall south)", "Maiden Robe", + DS3LocationCategory.ARMOR), + DS3LocationData("CD: Maiden Gloves (main hall south)", "Maiden Gloves", + DS3LocationCategory.ARMOR), + DS3LocationData("CD: Maiden Skirt (main hall south)", "Maiden Skirt", + DS3LocationCategory.ARMOR), + DS3LocationData("CD: Pale Tongue (upper roofs, outdoors far end)", "Pale Tongue", + DS3LocationCategory.MISC, hidden = True), + DS3LocationData("CD: Fading Soul (graveyard, far end)", "Fading Soul", + DS3LocationCategory.MISC), + DS3LocationData("CD: Blessed Gem (upper roofs, rafters)", "Blessed Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("CD: Red Bug Pellet (right of cathedral front doors)", + "Red Bug Pellet", DS3LocationCategory.MISC), + DS3LocationData("CD: Soul of a Nameless Soldier (main hall south)", + "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("CD: Duel Charm (by first elevator)", "Duel Charm", + DS3LocationCategory.MISC), + DS3LocationData("CD: Large Soul of an Unknown Traveler (main hall south, side path)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("CD: Ember (side chapel, miniboss room)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("CD: Repair Powder (by white tree)", "Repair Powder x3", + DS3LocationCategory.MISC), + DS3LocationData("CD: Large Soul of an Unknown Traveler (by white tree #1)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("CD: Large Soul of an Unknown Traveler (by white tree #2)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("CD: Undead Hunter Charm (lower roofs, up stairs between buttresses", + "Undead Hunter Charm x3", DS3LocationCategory.MISC), + DS3LocationData("CD: Red Bug Pellet (lower roofs, up stairs between buttresses)", + "Red Bug Pellet x3", DS3LocationCategory.MISC), + DS3LocationData("CD: Titanite Shard (outside building by white tree)", + "Titanite Shard", DS3LocationCategory.UPGRADE, + hidden = True), # Easily missable side path + DS3LocationData("CD: Titanite Shard (moat, up a slope)", "Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("CD: Rusted Coin (left of cathedral front doors, behind crates)", + "Rusted Coin x2", DS3LocationCategory.MISC, hidden = True), + DS3LocationData("CD: Drang Hammers (main hall east)", "Drang Hammers", + DS3LocationCategory.WEAPON), + DS3LocationData("CD: Drang Shoes (main hall east)", "Drang Shoes", + DS3LocationCategory.ARMOR), + DS3LocationData("CD: Large Soul of an Unknown Traveler (main hall east)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("CD: Pale Tongue (main hall east)", "Pale Tongue", + DS3LocationCategory.MISC), + DS3LocationData("CD: Drang Gauntlets (main hall east)", "Drang Gauntlets", + DS3LocationCategory.ARMOR), + DS3LocationData("CD: Soul of a Nameless Soldier (lower roofs, side room)", + "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("CD: Exploding Bolt (ledge above main hall south)", "Exploding Bolt x6", + DS3LocationCategory.MISC), + DS3LocationData("CD: Lloyd's Sword Ring (ledge above main hall south)", + "Lloyd's Sword Ring", DS3LocationCategory.RING), + DS3LocationData("CD: Soul of a Nameless Soldier (ledge above main hall south)", + "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("CD: Homeward Bone (outside main hall south door)", "Homeward Bone x2", + DS3LocationCategory.MISC), + DS3LocationData("CD: Deep Gem (down stairs by first elevator)", "Deep Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("CD: Titanite Shard (path, side path by Cathedral of the Deep bonfire)", + "Titanite Shard", DS3LocationCategory.MISC), + DS3LocationData("CD: Large Soul of an Unknown Traveler (path, against outer wall)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), # Before the stairs leading down into the Deacons fight - DS3LocationData("CD: Ring of the Evil Eye+1", "Ring of the Evil Eye+1", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("CD: Ring of Favor+2", "Ring of Favor+2", DS3LocationCategory.RING, - hidden = True, ngp = True), # Hidden fall - DS3LocationData("CD: Crest Shield", "Crest Shield", DS3LocationCategory.SHIELD, - hidden = True), # Hidden fall - DS3LocationData("CD: Young White Branch #1", "Young White Branch", DS3LocationCategory.MISC), - DS3LocationData("CD: Young White Branch #2", "Young White Branch", DS3LocationCategory.MISC), - DS3LocationData("CD: Saint-tree Bellvine", "Saint-tree Bellvine", DS3LocationCategory.WEAPON), - DS3LocationData("CD: Saint Bident", "Saint Bident", DS3LocationCategory.WEAPON), - DS3LocationData("CD: Archdeacon White Crown", "Archdeacon White Crown", DS3LocationCategory.ARMOR, - boss = True, hidden = True), # Have to return to a cleared area - DS3LocationData("CD: Archdeacon Holy Garb", "Archdeacon Holy Garb", DS3LocationCategory.ARMOR, - boss = True, hidden = True), # Have to return to a cleared area - DS3LocationData("CD: Archdeacon Skirt", "Archdeacon Skirt", DS3LocationCategory.ARMOR, - boss = True, hidden = True), # Have to return to a cleared area - DS3LocationData("CD: Heysel Pick", "Heysel Pick", DS3LocationCategory.WEAPON, - missable = True), - DS3LocationData("CD: Xanthous Crown", "Xanthous Crown", DS3LocationCategory.WEAPON, - missable = True), - DS3LocationData("CD: Deep Ring", "Deep Ring", DS3LocationCategory.RING, - drop = True, hidden = True), # Guaranteed drop from a normal-looking Deacon - DS3LocationData("CD: Deep Braille Divine Tome", "Deep Braille Divine Tome", DS3LocationCategory.UNIQUE, - mimic = True), - DS3LocationData("CD: Red Sign Soapstone", "Red Sign Soapstone", DS3LocationCategory.UNIQUE, - drop = True, hidden = True), # Guaranteed drop from a normal-looking Corpse-grub - DS3LocationData("CD: Aldrich's Sapphire", "Aldrich's Sapphire", DS3LocationCategory.RING, - miniboss = True), # Deep Accursed Drop - DS3LocationData("CD: Dung Pie", "Dung Pie x4", DS3LocationCategory.MISC, - miniboss = True), # Giant Slave drop - DS3LocationData("CD: Large Titanite Shard", "Large Titanite Shard", DS3LocationCategory.UPGRADE, - miniboss = True), # Giant Slave drop - DS3LocationData("CD: Titanite Scale", "Titanite Scale", DS3LocationCategory.UPGRADE, + DS3LocationData("CD: Ring of the Evil Eye+1 (by stairs to boss)", "Ring of the Evil Eye+1", + DS3LocationCategory.RING, ngp = True), + DS3LocationData("CD: Ring of Favor+2 (upper roofs, on buttress)", "Ring of Favor+2", + DS3LocationCategory.RING, hidden = True, ngp = True), # Hidden fall + DS3LocationData("CD: Crest Shield (path, drop down by Cathedral of the Deep bonfire)", + "Crest Shield", DS3LocationCategory.SHIELD, hidden = True), # Hidden fall + DS3LocationData("CD: Young White Branch (by white tree #1)", "Young White Branch", + DS3LocationCategory.MISC), + DS3LocationData("CD: Young White Branch (by white tree #2)", "Young White Branch", + DS3LocationCategory.MISC), + DS3LocationData("CD: Saint-tree Bellvine (moat, by water)", "Saint-tree Bellvine", + DS3LocationCategory.WEAPON), + DS3LocationData("CD: Saint Bident (outside main hall south door)", "Saint Bident", + DS3LocationCategory.WEAPON), + # Archdeacon set is hidden because you have to return to a cleared area + DS3LocationData("CD: Archdeacon White Crown (boss room after killing boss)", + "Archdeacon White Crown", DS3LocationCategory.ARMOR, boss = True, + hidden = True), + DS3LocationData("CD: Archdeacon Holy Garb (boss room after killing boss)", + "Archdeacon Holy Garb", DS3LocationCategory.ARMOR, boss = True, + hidden = True), + DS3LocationData("CD: Archdeacon Skirt (boss room after killing boss)", "Archdeacon Skirt", + DS3LocationCategory.ARMOR, boss = True, hidden = True), + # Heysel items may not be missable, but it's not clear what causes them to trigger + DS3LocationData("CD: Heysel Pick (Heysel Corpse-Grub in Rosaria's Bed Chamber)", + "Heysel Pick", DS3LocationCategory.WEAPON, missable = True), + DS3LocationData("CD: Xanthous Crown (Heysel Corpse-Grub in Rosaria's Bed Chamber)", + "Xanthous Crown", DS3LocationCategory.WEAPON, missable = True), + DS3LocationData("CD: Deep Ring (upper roofs, passive mob drop in first tower)", "Deep Ring", + DS3LocationCategory.RING, drop = True, hidden = True), + DS3LocationData("CD: Deep Braille Divine Tome (mimic by side chapel)", + "Deep Braille Divine Tome", DS3LocationCategory.UNIQUE, mimic = True), + DS3LocationData("CD: Red Sign Soapstone (passive mob drop by Rosaria's Bed Chamber)", + "Red Sign Soapstone", DS3LocationCategory.UNIQUE, drop = True, + hidden = True), + DS3LocationData("CD: Aldrich's Sapphire (side chapel, miniboss drop)", "Aldrich's Sapphire", + DS3LocationCategory.RING, miniboss = True), # Deep Accursed Drop + DS3LocationData("CD: Dung Pie (main hall, miniboss drop)", "Dung Pie x4", + DS3LocationCategory.MISC, miniboss = True), # drop from either Giant Slave + DS3LocationData("CD: Large Titanite Shard (main hall, miniboss drop)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE, + miniboss = True), # drop from either Giant Slave + DS3LocationData("CD: Titanite Scale (moat, miniboss drop)", "Titanite Scale", + DS3LocationCategory.UPGRADE, miniboss = True), # Ravenous Crystal Lizard drop - DS3LocationData("CD: Twinkling Titanite #3", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("CD: Twinkling Titanite #4", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("CD: Rosaria's Fingers", "Rosaria's Fingers", DS3LocationCategory.UNIQUE, - hidden = True), # Hidden fall - DS3LocationData("CD: Cleric's Candlestick", "Cleric's Candlestick", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("CD: Deep Soul", "Deep Soul", DS3LocationCategory.SPELL, - missable = True, boss = True, shop = True), - DS3LocationData("CD -> PW1", None, DS3LocationCategory.EVENT), + DS3LocationData("CD: Twinkling Titanite (moat, lizard #1)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("CD: Twinkling Titanite (moat, lizard #2)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("CD: Rosaria's Fingers (Rosaria)", "Rosaria's Fingers", + DS3LocationCategory.UNIQUE, hidden = True), # Hidden fall + DS3LocationData("CD -> PW1", None, DS3LocationCategory.EVENT), # Longfinger Kirk drops - DS3LocationData("CD: Barbed Straight Sword", "Barbed Straight Sword", DS3LocationCategory.WEAPON, - missable = True, hostile_npc = True), - DS3LocationData("CD: Spiked Shield", "Spiked Shield", DS3LocationCategory.SHIELD, - missable = True, hostile_npc = True), + DS3LocationData("CD: Barbed Straight Sword (Kirk drop)", "Barbed Straight Sword", + DS3LocationCategory.WEAPON, missable = True, hostile_npc = True), + DS3LocationData("CD: Spiked Shield (Kirk drop)", "Spiked Shield", + DS3LocationCategory.SHIELD, missable = True, hostile_npc = True), # In Rosaria's Bed Chamber - DS3LocationData("CD: Helm of Thorns", "Helm of Thorns", DS3LocationCategory.ARMOR, - missable = True, hostile_npc = True), - DS3LocationData("CD: Armor of Thorns", "Armor of Thorns", DS3LocationCategory.ARMOR, - missable = True, hostile_npc = True), - DS3LocationData("CD: Gauntlets of Thorns", "Gauntlets of Thorns", DS3LocationCategory.ARMOR, - missable = True, hostile_npc = True), - DS3LocationData("CD: Leggings of Thorns", "Leggings of Thorns", DS3LocationCategory.ARMOR, - missable = True, hostile_npc = True), + DS3LocationData("CD: Helm of Thorns (Rosaria's Bed Chamber after killing Kirk)", + "Helm of Thorns", DS3LocationCategory.ARMOR, missable = True, + hostile_npc = True), + DS3LocationData("CD: Armor of Thorns (Rosaria's Bed Chamber after killing Kirk)", + "Armor of Thorns", DS3LocationCategory.ARMOR, missable = True, + hostile_npc = True), + DS3LocationData("CD: Gauntlets of Thorns (Rosaria's Bed Chamber after killing Kirk)", + "Gauntlets of Thorns", DS3LocationCategory.ARMOR, missable = True, + hostile_npc = True), + DS3LocationData("CD: Leggings of Thorns (Rosaria's Bed Chamber after killing Kirk)", + "Leggings of Thorns", DS3LocationCategory.ARMOR, missable = True, + hostile_npc = True), # Unbreakable Patches - DS3LocationData("CD: Rusted Coin #2", "Rusted Coin", DS3LocationCategory.MISC, - missable = True, npc = True), - DS3LocationData("CD: Rusted Gold Coin", "Rusted Gold Coin", DS3LocationCategory.MISC, - offline = '99,0:50006201::', missable = True, npc = True), # Don't forgive Patches - DS3LocationData("CD: Shotel", "Shotel", DS3LocationCategory.WEAPON, - missable = True, npc = True, shop = True), - DS3LocationData("CD: Ember #5", "Ember", DS3LocationCategory.MISC, - missable = True, npc = True, shop = True), - DS3LocationData("CD: Hidden Blessing", "Hidden Blessing", DS3LocationCategory.MISC, + DS3LocationData("CD: Rusted Coin (don't forgive Patches)", "Rusted Coin", + DS3LocationCategory.MISC, missable = True, npc = True), + DS3LocationData("FS: Rusted Gold Coin (don't forgive Patches)", "Rusted Gold Coin", + DS3LocationCategory.MISC, offline = '99,0:50006201::', missable = True, + npc = True), # Don't forgive Patches + DS3LocationData("CD: Shotel (Patches)", "Shotel", DS3LocationCategory.WEAPON, missable = True, npc = True, shop = True), - DS3LocationData("CD: Horsehoof Ring", "Horsehoof Ring", DS3LocationCategory.RING, + DS3LocationData("CD: Ember (Patches)", "Ember", DS3LocationCategory.MISC, missable = True, + npc = True, shop = True), + DS3LocationData("CD: Hidden Blessing (Patches)", "Hidden Blessing", + DS3LocationCategory.MISC, missable = True, npc = True, shop = True), + DS3LocationData("CD: Horsehoof Ring (Patches)", "Horsehoof Ring", DS3LocationCategory.RING, missable = True, npc = True, drop = True, shop = True), # (kill or buy) ], "Farron Keep": [ - DS3LocationData("FK: Lightning Spear", "Lightning Spear", DS3LocationCategory.WEAPON), - DS3LocationData("FK: Dragon Crest Shield", "Dragon Crest Shield", DS3LocationCategory.SHIELD), - DS3LocationData("FK: Soul of the Blood of the Wolf", "Soul of the Blood of the Wolf", DS3LocationCategory.SOUL, + DS3LocationData("FK: Lightning Spear (upper keep, far side of the wall)", "Lightning Spear", + DS3LocationCategory.WEAPON), + DS3LocationData("FK: Dragon Crest Shield (upper keep, far side of the wall)", + "Dragon Crest Shield", DS3LocationCategory.SHIELD), + DS3LocationData("FK: Soul of the Blood of the Wolf", "Soul of the Blood of the Wolf", + DS3LocationCategory.SOUL, boss = True), + DS3LocationData("FK: Cinders of a Lord - Abyss Watcher", + "Cinders of a Lord - Abyss Watcher", DS3LocationCategory.KEY, + offline = "03,0:50002100::", prominent = True, progression = True, boss = True), - DS3LocationData("FK: Cinders of a Lord - Abyss Watcher", "Cinders of a Lord - Abyss Watcher", DS3LocationCategory.KEY, - offline = "03,0:50002100::", prominent = True, progression = True, boss = True), - DS3LocationData("FK: Manikin Claws", "Manikin Claws", DS3LocationCategory.WEAPON, - missable = True, hostile_npc = True, npc = True), # Londor Pale Shade (if Yoel/Yuria hostile) - DS3LocationData("FK: Purple Moss Clump #1", "Purple Moss Clump x2", DS3LocationCategory.MISC), - DS3LocationData("FK: Purple Moss Clump #2", "Purple Moss Clump x4", DS3LocationCategory.MISC), - DS3LocationData("FK: Greatsword", "Greatsword", DS3LocationCategory.WEAPON), - DS3LocationData("FK: Hollow Gem", "Hollow Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("FK: Fading Soul", "Fading Soul", DS3LocationCategory.MISC), - DS3LocationData("FK: Purple Moss Clump #3", "Purple Moss Clump x3", DS3LocationCategory.MISC), - DS3LocationData("FK: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), - DS3LocationData("FK: Atonement", "Atonement", DS3LocationCategory.SPELL, - hidden = True), # Hidden fall - DS3LocationData("FK: Titanite Shard #1", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("FK: Iron Flesh", "Iron Flesh", DS3LocationCategory.SPELL), - DS3LocationData("FK: Stone Parma", "Stone Parma", DS3LocationCategory.SHIELD), - DS3LocationData("FK: Rotten Pine Resin #1", "Rotten Pine Resin x2", DS3LocationCategory.MISC), - DS3LocationData("FK: Titanite Shard #2", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("FK: Rusted Gold Coin", "Rusted Gold Coin", DS3LocationCategory.MISC, - hidden = True), # Hidden behind a wall - DS3LocationData("FK: Nameless Knight Helm", "Nameless Knight Helm", DS3LocationCategory.ARMOR), - DS3LocationData("FK: Nameless Knight Armor", "Nameless Knight Armor", DS3LocationCategory.ARMOR), - DS3LocationData("FK: Nameless Knight Gauntlets", "Nameless Knight Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("FK: Nameless Knight Leggings", "Nameless Knight Leggings", DS3LocationCategory.ARMOR), - DS3LocationData("FK: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), - DS3LocationData("FK: Repair Powder", "Repair Powder x4", DS3LocationCategory.MISC, - hidden = True), # Out-of-the-way hard-to-see cave - DS3LocationData("FK: Golden Scroll", "Golden Scroll", DS3LocationCategory.UNIQUE, - hostile_npc = True), # Out-of-the-way hard-to-see cave - DS3LocationData("FK: Sage's Scroll", "Sage's Scroll", DS3LocationCategory.UNIQUE), - DS3LocationData("FK: Dreamchaser's Ashes", "Dreamchaser's Ashes", DS3LocationCategory.KEY, - progression = True, hidden = True), # Behind illusory wall - DS3LocationData("FK: Titanite Shard #3", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("FK: Wolf's Blood Swordgrass", "Wolf's Blood Swordgrass", DS3LocationCategory.MISC), - DS3LocationData("FK: Great Magic Weapon", "Great Magic Weapon", DS3LocationCategory.SPELL), - DS3LocationData("FK: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("FK: Titanite Shard #4", "Titanite Shard x2", DS3LocationCategory.UPGRADE), - DS3LocationData("FK: Titanite Shard #5", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("FK: Titanite Shard #6", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("FK: Black Bug Pellet", "Black Bug Pellet x3", DS3LocationCategory.MISC), - DS3LocationData("FK: Rotten Pine Resin #2", "Rotten Pine Resin x4", DS3LocationCategory.MISC), - DS3LocationData("FK: Poison Gem", "Poison Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("FK: Ragged Mask", "Ragged Mask", DS3LocationCategory.ARMOR), - DS3LocationData("FK: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), - DS3LocationData("FK: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.HEALTH), - DS3LocationData("FK: Titanite Shard #7", "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("FK: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("FK: Prism Stone", "Prism Stone x10", DS3LocationCategory.MISC), - DS3LocationData("FK: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("FK: Sage's Coal", "Sage's Coal", DS3LocationCategory.UNIQUE), - DS3LocationData("FK: Gold Pine Bundle", "Gold Pine Bundle x6", DS3LocationCategory.MISC), - DS3LocationData("FK: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("FK: Soul of a Nameless Soldier", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("FK: Large Soul of an Unknown Traveler", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("FK: Greataxe", "Greataxe", DS3LocationCategory.WEAPON), - DS3LocationData("FK: Ember #3", "Ember", DS3LocationCategory.MISC), - DS3LocationData("FK: Ember #4", "Ember", DS3LocationCategory.MISC), - DS3LocationData("FK: Dark Stoneplate Ring+2", "Dark Stoneplate Ring+2", DS3LocationCategory.RING, - hidden = True, ngp = True), # Hidden behind wall - DS3LocationData("FK: Magic Stoneplate Ring+1", "Magic Stoneplate Ring+1", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("FK: Wolf Ring+1", "Wolf Ring+1", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("FK: Antiquated Dress", "Antiquated Dress", DS3LocationCategory.ARMOR, - hostile_npc = True), # Out-of-the-way hard-to-see cave - DS3LocationData("FK: Antiquated Gloves", "Antiquated Gloves", DS3LocationCategory.ARMOR, - hostile_npc = True), # Out-of-the-way hard-to-see cave - DS3LocationData("FK: Antiquated Skirt", "Antiquated Skirt", DS3LocationCategory.ARMOR, - hostile_npc = True), # Out-of-the-way hard-to-see cave - DS3LocationData("FK: Sunlight Talisman", "Sunlight Talisman", DS3LocationCategory.WEAPON), - DS3LocationData("FK: Young White Branch #1", "Young White Branch", DS3LocationCategory.MISC), - DS3LocationData("FK: Young White Branch #2", "Young White Branch", DS3LocationCategory.MISC), - DS3LocationData("FK: Crown of Dusk", "Crown of Dusk", DS3LocationCategory.ARMOR), - DS3LocationData("FK: Lingering Dragoncrest Ring", "Lingering Dragoncrest Ring", DS3LocationCategory.RING, + DS3LocationData("FK: Manikin Claws (Londor Pale Shade drop)", "Manikin Claws", + DS3LocationCategory.WEAPON, missable = True, hostile_npc = True, + npc = True), # Londor Pale Shade (if Yoel/Yuria hostile) + DS3LocationData("FK: Purple Moss Clump (keep ruins, ritual island)", + "Purple Moss Clump x2", DS3LocationCategory.MISC), + DS3LocationData("FK: Purple Moss Clump (ramp directly in front of Farron Keep bonfire)", + "Purple Moss Clump x4", DS3LocationCategory.MISC), + DS3LocationData("FK: Greatsword (ramp by keep ruins ritual island)", "Greatsword", + DS3LocationCategory.WEAPON), + DS3LocationData("FK: Hollow Gem (perimeter, drop down into swamp)", "Hollow Gem", + DS3LocationCategory.UPGRADE, hidden = True), + DS3LocationData("FK: Purple Moss Clump (Farron Keep bonfire, around right corner)", + "Purple Moss Clump x3", DS3LocationCategory.MISC), + DS3LocationData("FK: Undead Bone Shard (pavilion by keep ruins bonfire island)", + "Undead Bone Shard", DS3LocationCategory.HEALTH), + DS3LocationData("FK: Atonement (perimeter, drop down into swamp)", "Atonement", + DS3LocationCategory.SPELL, hidden = True), + DS3LocationData("FK: Titanite Shard (by ladder to keep proper)", "Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Iron Flesh (Farron Keep bonfire, right after exit)", "Iron Flesh", + DS3LocationCategory.SPELL), + DS3LocationData("FK: Stone Parma (near wall by left island)", "Stone Parma", + DS3LocationCategory.SHIELD), + DS3LocationData("FK: Rotten Pine Resin (left island, behind fire)", "Rotten Pine Resin x2", + DS3LocationCategory.MISC), + DS3LocationData("FK: Titanite Shard (between left island and keep ruins)", "Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Rusted Gold Coin (right island, behind wall)", "Rusted Gold Coin", + DS3LocationCategory.MISC, hidden = True), + DS3LocationData("FK: Nameless Knight Helm (next to pillar by right island)", + "Nameless Knight Helm", DS3LocationCategory.ARMOR), + DS3LocationData("FK: Nameless Knight Armor (next to pillar by right island)", + "Nameless Knight Armor", DS3LocationCategory.ARMOR), + DS3LocationData("FK: Nameless Knight Gauntlets (next to pillar by right island)", + "Nameless Knight Gauntlets", DS3LocationCategory.ARMOR), + DS3LocationData("FK: Nameless Knight Leggings (next to pillar by right island)", + "Nameless Knight Leggings", DS3LocationCategory.ARMOR), + DS3LocationData("FK: Shriving Stone (perimeter, just past stone doors)", "Shriving Stone", + DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Repair Powder (outside hidden cave)", "Repair Powder x4", + DS3LocationCategory.MISC, hidden = True), + DS3LocationData("FK: Golden Scroll (hidden cave)", "Golden Scroll", + DS3LocationCategory.UNIQUE, hidden = True), + DS3LocationData("FK: Sage's Scroll (near wall by keep ruins bonfire island)", + "Sage's Scroll", DS3LocationCategory.UNIQUE), + DS3LocationData("FK: Dreamchaser's Ashes (keep proper, illusory wall)", + "Dreamchaser's Ashes", DS3LocationCategory.KEY, progression = True, + hidden = True), + DS3LocationData("FK: Titanite Shard (keep ruins bonfire island, under ramp)", + "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Wolf's Blood Swordgrass (by ladder to keep proper)", + "Wolf's Blood Swordgrass", DS3LocationCategory.MISC), + DS3LocationData("FK: Great Magic Weapon (perimeter, by door to Road of Sacrifices)", + "Great Magic Weapon", DS3LocationCategory.SPELL), + DS3LocationData("FK: Ember (perimeter, path to boss)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("FK: Titanite Shard (swamp by right island)", "Titanite Shard x2", + DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Titanite Shard (by left island stairs)", "Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Titanite Shard (by keep ruins ritual island stairs)", "Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Black Bug Pellet (perimeter, hill by boss door)", + "Black Bug Pellet x3", DS3LocationCategory.MISC), + DS3LocationData("FK: Rotten Pine Resin (outside pavilion by left island)", + "Rotten Pine Resin x4", DS3LocationCategory.MISC), + DS3LocationData("FK: Poison Gem (near wall by keep ruins bridge)", "Poison Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Ragged Mask (Farron Keep bonfire, around left corner)", "Ragged Mask", + DS3LocationCategory.ARMOR), + DS3LocationData("FK: Estus Shard (between Farron Keep bonfire and left island)", + "Estus Shard", DS3LocationCategory.HEALTH), + DS3LocationData("FK: Homeward Bone (right island, behind fire)", "Homeward Bone x2", + DS3LocationCategory.HEALTH), + DS3LocationData("FK: Titanite Shard (Farron Keep bonfire, left after exit)", + "Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("FK: Large Soul of a Nameless Soldier (between right island and pillar)", + "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL, + hidden = True), # Tricky corner to spot + DS3LocationData("FK: Prism Stone (by left island stairs)", "Prism Stone x10", + DS3LocationCategory.MISC), + DS3LocationData("FK: Large Soul of a Nameless Soldier (near wall by right island)", + "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("FK: Sage's Coal (pavilion by left island)", "Sage's Coal", + DS3LocationCategory.UNIQUE), + DS3LocationData("FK: Gold Pine Bundle (by white tree)", "Gold Pine Bundle x6", + DS3LocationCategory.MISC), + DS3LocationData("FK: Ember (by white tree)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("FK: Soul of a Nameless Soldier (by white tree)", "Soul of a Nameless Soldier", + DS3LocationCategory.SOUL), + DS3LocationData("FK: Large Soul of an Unknown Traveler (by white tree)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("FK: Greataxe (upper keep, by miniboss)", "Greataxe", + DS3LocationCategory.WEAPON), + DS3LocationData("FK: Ember (upper keep, by miniboss #1)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("FK: Ember (upper keep, by miniboss #2)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("FK: Dark Stoneplate Ring+2 (keep ruins ritual island, behind wall)", + "Dark Stoneplate Ring+2", DS3LocationCategory.RING, ngp = True, + hidden = True), + DS3LocationData("FK: Magic Stoneplate Ring+1 (between right island and wall)", + "Magic Stoneplate Ring+1", DS3LocationCategory.RING, ngp = True), + DS3LocationData("FK: Wolf Ring+1 (keep ruins bonfire island, outside building)", + "Wolf Ring+1", DS3LocationCategory.RING, ngp = True), + DS3LocationData("FK: Antiquated Dress (hidden cave)", "Antiquated Dress", + DS3LocationCategory.ARMOR, hidden = True), + DS3LocationData("FK: Antiquated Gloves (hidden cave)", "Antiquated Gloves", + DS3LocationCategory.ARMOR, hidden = True), + DS3LocationData("FK: Antiquated Skirt (hidden cave)", "Antiquated Skirt", + DS3LocationCategory.ARMOR, hidden = True), + DS3LocationData("FK: Sunlight Talisman (estus soup island, by ladder to keep proper)", + "Sunlight Talisman", DS3LocationCategory.WEAPON), + DS3LocationData("FK: Young White Branch (by white tree #1)", "Young White Branch", + DS3LocationCategory.MISC), + DS3LocationData("FK: Young White Branch (by white tree #2)", "Young White Branch", + DS3LocationCategory.MISC), + DS3LocationData("FK: Crown of Dusk (by white tree)", "Crown of Dusk", + DS3LocationCategory.ARMOR), + DS3LocationData("FK: Lingering Dragoncrest Ring (by white tree, miniboss drop)", + "Lingering Dragoncrest Ring", DS3LocationCategory.RING, miniboss = True), # Great Crab drop - DS3LocationData("FK: Pharis's Hat", "Pharis's Hat", DS3LocationCategory.ARMOR, - drop = True, hidden = True), # Guaranteed drop from a normal-looking Elder Ghru - DS3LocationData("FK: Black Bow of Pharis", "Black Bow of Pharis", DS3LocationCategory.WEAPON, - drop = True, hidden = True), # Guaranteed drop from a normal-looking Elder Ghru - DS3LocationData("FK: Titanite Scale", "Titanite Scale x2", DS3LocationCategory.UPGRADE, + DS3LocationData("FK: Pharis's Hat (mob drop, around item in corner by keep ruins)", + "Pharis's Hat", DS3LocationCategory.ARMOR, drop = True, hidden = True), + DS3LocationData("FK: Black Bow of Pharis (mob drop, around item in corner by keep ruins)", + "Black Bow of Pharis", DS3LocationCategory.WEAPON, drop = True, + hidden = True), + DS3LocationData("FK: Titanite Scale (perimeter, miniboss drop)", "Titanite Scale x2", + DS3LocationCategory.UPGRADE, miniboss = True), # Ravenous Crystal Lizard drop - DS3LocationData("FK: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("FK: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("FK: Heavy Gem", "Heavy Gem", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("FK: Twinkling Titanite", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("FK: Soul of a Stray Demon", "Soul of a Stray Demon", DS3LocationCategory.SOUL, - miniboss = True), - DS3LocationData("FK: Watchdogs of Farron", "Watchdogs of Farron", DS3LocationCategory.UNIQUE), - DS3LocationData("FK: Hawkwood's Shield", "Hawkwood's Shield", DS3LocationCategory.SHIELD, - missable = True, npc = True), # Hawkwood (quest, after Greatwood, Sage, Watchers, and Deacons) - DS3LocationData("FK: Havel's Ring", "Havel's Ring", DS3LocationCategory.RING, - missable = True, boss = True, shop = True), - DS3LocationData("FK: Boulder Heave", "Boulder Heave", DS3LocationCategory.SPELL, - missable = True, boss = True, shop = True), - DS3LocationData("FK: Farron Greatsword", "Farron Greatsword", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("FK: Wolf Knight's Greatsword", "Wolf Knight's Greatsword", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("FK: Hawk Ring", "Hawk Ring", DS3LocationCategory.RING, + DS3LocationData("FK: Large Titanite Shard (upper keep, lizard #1)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("FK: Large Titanite Shard (upper keep, lizard #2)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("FK: Heavy Gem (uper keep, lizard on stairs)", "Heavy Gem", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("FK: Twinkling Titanite (keep proper, lizardl)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("FK: Soul of a Stray Demon (upper keep, miniboss drop)", + "Soul of a Stray Demon", DS3LocationCategory.SOUL, miniboss = True), + DS3LocationData("FK: Watchdogs of Farron (Old Wolf)", "Watchdogs of Farron", + DS3LocationCategory.UNIQUE), + DS3LocationData("FS: Hawkwood's Shield (Hawkwood)", "Hawkwood's Shield", + DS3LocationCategory.SHIELD, missable = True, + npc = True), # Hawkwood (quest, after Greatwood, Sage, Watchers, and Deacons) + DS3LocationData("US: Hawk Ring (Giant Archer)", "Hawk Ring", DS3LocationCategory.RING, drop = True, npc = True), # Giant archer (kill or quest), here because you # need to collect all seven White Branch locations # to get it peacefully - DS3LocationData("FK -> CC", None, DS3LocationCategory.EVENT), + DS3LocationData("FK -> CC", None, DS3LocationCategory.EVENT), # Hawkwood after killing Abyss Watchers - DS3LocationData("RS: Farron Ring", "Farron Ring", DS3LocationCategory.RING, + DS3LocationData("FS: Farron Ring (Hawkwood)", "Farron Ring", DS3LocationCategory.RING, missable = True, npc = True), - # Shrine Handmaid after killing exiles - DS3LocationData("FK: Exile Mask", "Exile Mask", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True, shop = True), - DS3LocationData("FK: Exile Armor", "Exile Armor", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True, shop = True), - DS3LocationData("FK: Exile Gauntlets", "Exile Gauntlets", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True, shop = True), - DS3LocationData("FK: Exile Leggings", "Exile Leggings", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True, shop = True), - # Shrine Handmaid after killing Abyss Watchers - DS3LocationData("FK: Undead Legion Helm", "Undead Legion Helm", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("FK: Undead Legion Armor", "Undead Legion Armor", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("FK: Undead Legion Gauntlet", "Undead Legion Gauntlet", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("FK: Undead Legion Leggings", "Undead Legion Leggings", DS3LocationCategory.ARMOR, - boss = True, shop = True), + DS3LocationData("FS: Undead Legion Helm (shop after killing FK boss)", + "Undead Legion Helm", DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Undead Legion Armor (shop after killing FK boss)", + "Undead Legion Armor", DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Undead Legion Gauntlet (shop after killing FK boss)", + "Undead Legion Gauntlet", DS3LocationCategory.ARMOR, boss = True, + shop = True), + DS3LocationData("FS: Undead Legion Leggings (shop after killing FK boss)", + "Undead Legion Leggings", DS3LocationCategory.ARMOR, boss = True, + shop = True), + + # Appears after killing Havel Knight in Archdragon Peak + DS3LocationData("FK: Havel's Helm (upper keep, after killing AP belfry roof NPC)", + "Havel's Helm", DS3LocationCategory.ARMOR, hidden = True, + hostile_npc = True), + DS3LocationData("FK: Havel's Armor (upper keep, after killing AP belfry roof NPC)", + "Havel's Armor", DS3LocationCategory.ARMOR, hidden = True, + hostile_npc = True), + DS3LocationData("FK: Havel's Gauntlets (upper keep, after killing AP belfry roof NPC)", + "Havel's Gauntlets", DS3LocationCategory.ARMOR, hidden = True, + hostile_npc = True), + DS3LocationData("FK: Havel's Leggings (upper keep, after killing AP belfry roof NPC)", + "Havel's Leggings", DS3LocationCategory.ARMOR, hidden = True, + hostile_npc = True), ], "Catacombs of Carthus": [ - DS3LocationData("CC: Soul of High Lord Wolnir", "Soul of High Lord Wolnir", DS3LocationCategory.SOUL, - prominent = True, boss = True), - DS3LocationData("CC: Carthus Rouge #1", "Carthus Rouge x2", DS3LocationCategory.MISC), - DS3LocationData("CC: Sharp Gem", "Sharp Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("CC: Soul of a Nameless Soldier #1", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("CC: Titanite Shard #1", "Titanite Shard x2", DS3LocationCategory.UPGRADE), - DS3LocationData("CC: Bloodred Moss Clump", "Bloodred Moss Clump x3", DS3LocationCategory.MISC), - DS3LocationData("CC: Carthus Milkring", "Carthus Milkring", DS3LocationCategory.RING), - DS3LocationData("CC: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("CC: Carthus Rouge #2", "Carthus Rouge x3", DS3LocationCategory.MISC), - DS3LocationData("CC: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("CC: Carthus Bloodring", "Carthus Bloodring", DS3LocationCategory.RING), - DS3LocationData("CC: Titanite Shard #2", "Titanite Shard x2", DS3LocationCategory.UPGRADE), - DS3LocationData("CC: Titanite Shard #3", "Titanite Shard x2", DS3LocationCategory.UPGRADE), - DS3LocationData("CC: Ember #3", "Ember", DS3LocationCategory.MISC), - DS3LocationData("CC: Carthus Pyromancy Tome", "Carthus Pyromancy Tome", DS3LocationCategory.UNIQUE, - hidden = True), # Behind illusory wall - DS3LocationData("CC: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.MISC), - DS3LocationData("CC: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.MISC), - DS3LocationData("CC: Yellow Bug Pellet", "Yellow Bug Pellet x3", DS3LocationCategory.MISC), - DS3LocationData("CC: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("CC: Black Bug Pellet", "Black Bug Pellet x2", DS3LocationCategory.MISC), - DS3LocationData("CC: Grave Warden's Ashes", "Grave Warden's Ashes", DS3LocationCategory.KEY, - progression = True), - DS3LocationData("CC: Large Titanite Shard #3", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("CC: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("CC: Old Sage's Blindfold", "Old Sage's Blindfold", DS3LocationCategory.ARMOR), - DS3LocationData("CC: Witch's Ring", "Witch's Ring", DS3LocationCategory.RING), - DS3LocationData("CC: Soul of a Nameless Soldier #2", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("CC: Grave Warden Pyromancy Tome", "Grave Warden Pyromancy Tome", DS3LocationCategory.UNIQUE), - DS3LocationData("CC: Large Soul of an Unknown Traveler", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("CC: Ring of Steel Protection+2", "Ring of Steel Protection+2", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("CC: Thunder Stoneplate Ring+1", "Thunder Stoneplate Ring+1", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("CC: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH, - hidden = True), # Skeleton Ball puzzle - DS3LocationData("CC: Dark Gem", "Dark Gem", DS3LocationCategory.UPGRADE, + DS3LocationData("CC: Soul of High Lord Wolnir", "Soul of High Lord Wolnir", + DS3LocationCategory.SOUL, prominent = True, boss = True), + DS3LocationData("CC: Carthus Rouge (atrium upper, left after entrance)", + "Carthus Rouge x2", DS3LocationCategory.MISC), + DS3LocationData("CC: Sharp Gem (atrium lower, right before exit)", "Sharp Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("CC: Soul of a Nameless Soldier (atrium lower, down hall)", + "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("CC: Titanite Shard (atrium lower, corner by stairs)", "Titanite Shard x2", + DS3LocationCategory.UPGRADE), + DS3LocationData("CC: Bloodred Moss Clump (atrium lower, down more stairs)", + "Bloodred Moss Clump x3", DS3LocationCategory.MISC), + DS3LocationData("CC: Carthus Milkring (crypt upper, among pots)", "Carthus Milkring", + DS3LocationCategory.RING), + DS3LocationData("CC: Ember (atrium, on long stairway)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("CC: Carthus Rouge (crypt across, corner)", "Carthus Rouge x3", + DS3LocationCategory.MISC), + DS3LocationData("CC: Ember (crypt upper, end of hall past hole)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("CC: Carthus Bloodring (crypt lower, end of side hall)", "Carthus Bloodring", + DS3LocationCategory.RING), + DS3LocationData("CC: Titanite Shard (crypt lower, left of entrance)", "Titanite Shard x2", + DS3LocationCategory.UPGRADE), + DS3LocationData("CC: Titanite Shard (crypt lower, start of side hall)", "Titanite Shard x2", + DS3LocationCategory.UPGRADE), + DS3LocationData("CC: Ember (crypt lower, shortcut to cavern)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("CC: Carthus Pyromancy Tome (atrium lower, jump from bridge)", + "Carthus Pyromancy Tome", DS3LocationCategory.UNIQUE, + hidden = True), # Behind illusory wall or hidden drop + DS3LocationData("CC: Large Titanite Shard (crypt upper, skeleton ball hall)", + "Large Titanite Shard", DS3LocationCategory.MISC), + DS3LocationData("CC: Large Titanite Shard (crypt across, middle hall)", + "Large Titanite Shard", DS3LocationCategory.MISC), + DS3LocationData("CC: Yellow Bug Pellet (cavern, on overlook)", "Yellow Bug Pellet x3", + DS3LocationCategory.MISC), + DS3LocationData("CC: Large Soul of a Nameless Soldier (cavern, before bridge)", + "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("CC: Black Bug Pellet (cavern, before bridge)", "Black Bug Pellet x2", + DS3LocationCategory.MISC), + DS3LocationData("CC: Grave Warden's Ashes (crypt across, corner)", "Grave Warden's Ashes", + DS3LocationCategory.KEY, progression = True), + DS3LocationData("CC: Large Titanite Shard (tomb lower)", "Large Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("CC: Large Soul of a Nameless Soldier (tomb lower)", + "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("CC: Old Sage's Blindfold (tomb, hall before bonfire)", + "Old Sage's Blindfold", DS3LocationCategory.ARMOR), + DS3LocationData("CC: Witch's Ring (tomb, hall before bonfire)", "Witch's Ring", + DS3LocationCategory.RING), + DS3LocationData("CC: Soul of a Nameless Soldier (atrium upper, up more stairs)", + "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("CC: Grave Warden Pyromancy Tome (boss arena)", + "Grave Warden Pyromancy Tome", DS3LocationCategory.UNIQUE), + DS3LocationData("CC: Large Soul of an Unknown Traveler (crypt upper, hall middle)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("CC: Ring of Steel Protection+2 (atrium upper, drop onto pillar)", + "Ring of Steel Protection+2", DS3LocationCategory.RING, ngp = True), + DS3LocationData("CC: Thunder Stoneplate Ring+1 (crypt upper, among pots)", + "Thunder Stoneplate Ring+1", DS3LocationCategory.RING, ngp = True), + DS3LocationData("CC: Undead Bone Shard (crypt upper, skeleton ball drop)", + "Undead Bone Shard", DS3LocationCategory.HEALTH, hidden = True), # Skeleton Ball puzzle - DS3LocationData("CC: Black Blade", "Black Blade", DS3LocationCategory.WEAPON, + DS3LocationData("CC: Dark Gem (crypt lower, skeleton ball drop)", "Dark Gem", + DS3LocationCategory.UPGRADE, hidden = True), # Skeleton Ball puzzle + DS3LocationData("CC: Black Blade (tomb, mimic)", "Black Blade", DS3LocationCategory.WEAPON, mimic = True), - DS3LocationData("CC: Soul of a Demon", "Soul of a Demon", DS3LocationCategory.SOUL, - miniboss = True), - DS3LocationData("CC: Twinkling Titanite", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("CC: Fire Gem", "Fire Gem", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("CC: Homeward Bone", "Homeward Bone", DS3LocationCategory.MISC), - DS3LocationData("CC: Pontiff's Right Eye", "Pontiff's Right Eye", DS3LocationCategory.RING, - miniboss = True), # Sullyvahn's Beast drop, in CC because it doesn't require Small Doll - DS3LocationData("CC: Wolnir's Holy Sword", "Wolnir's Holy Sword", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("CC: Black Serpent", "Black Serpent", DS3LocationCategory.SPELL, - missable = True, boss = True, shop = True), - DS3LocationData("CC: Demon's Greataxe", "Demon's Greataxe", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("CC: Demon's Fist", "Demon's Fist", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), + DS3LocationData("CC: Soul of a Demon (tomb, miniboss drop)", "Soul of a Demon", + DS3LocationCategory.SOUL, miniboss = True), + DS3LocationData("CC: Twinkling Titanite (atrium lower, lizard down more stairs)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("CC: Fire Gem (cavern, lizard)", "Fire Gem", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("CC: Homeward Bone (Irithyll bridge)", "Homeward Bone", + DS3LocationCategory.MISC), + DS3LocationData("CC: Pontiff's Right Eye (Irithyll bridge, miniboss drop)", + "Pontiff's Right Eye", DS3LocationCategory.RING, + miniboss = True), # Sulyvahn's Beast drop # Shrine Handmaid after killing High Lord Wolnir - DS3LocationData("CC: Wolnir's Crown", "Wolnir's Crown", DS3LocationCategory.ARMOR, - boss = True, shop = True), + DS3LocationData("FS: Wolnir's Crown (shop after killing CC boss)", "Wolnir's Crown", + DS3LocationCategory.ARMOR, boss = True, shop = True), ], "Smouldering Lake": [ - DS3LocationData("SL: Soul of the Old Demon King", "Soul of the Old Demon King", DS3LocationCategory.SOUL, - prominent = True, boss = True), - - DS3LocationData("SL: Fume Ultra Greatsword", "Fume Ultra Greatsword", DS3LocationCategory.WEAPON, + DS3LocationData("SL: Soul of the Old Demon King", "Soul of the Old Demon King", + DS3LocationCategory.SOUL, prominent = True, boss = True), + DS3LocationData("SL: Fume Ultra Greatsword (ruins basement, NPC drop)", + "Fume Ultra Greatsword", DS3LocationCategory.WEAPON, hostile_npc = True), # Knight Slayer Tsorig drop - DS3LocationData("SL: Black Iron Greatshield", "Black Iron Greatshield", DS3LocationCategory.SHIELD, + DS3LocationData("SL: Black Iron Greatshield (ruins basement, NPC drop)", + "Black Iron Greatshield", DS3LocationCategory.SHIELD, hostile_npc = True), # Knight Slayer Tsorig drop - DS3LocationData("SL: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Large Titanite Shard #3", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Large Titanite Shard #4", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Large Titanite Shard #5", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Yellow Bug Pellet", "Yellow Bug Pellet x2", DS3LocationCategory.MISC), - DS3LocationData("SL: Large Titanite Shard #6", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Large Titanite Shard #7", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Large Titanite Shard #8", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Speckled Stoneplate Ring", "Speckled Stoneplate Ring", DS3LocationCategory.RING, + DS3LocationData("SL: Large Titanite Shard (ledge by Demon Ruins bonfire)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Large Titanite Shard (lake, by entrance)", "Large Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Large Titanite Shard (lake, straight from entrance)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Large Titanite Shard (lake, by tree #1)", "Large Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Large Titanite Shard (lake, by miniboss)", "Large Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Yellow Bug Pellet (side lake)", "Yellow Bug Pellet x2", + DS3LocationCategory.MISC), + DS3LocationData("SL: Large Titanite Shard (side lake #1)", "Large Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Large Titanite Shard (side lake #2)", "Large Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Large Titanite Shard (lake, by tree #2)", "Large Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Speckled Stoneplate Ring (lake, ballista breaks bricks)", + "Speckled Stoneplate Ring", DS3LocationCategory.RING, hidden = True), # Requires careful ballista shot - DS3LocationData("SL: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC), - DS3LocationData("SL: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("SL: Chaos Gem #1", "Chaos Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("SL: Izalith Pyromancy Tome", "Izalith Pyromancy Tome", DS3LocationCategory.UNIQUE), - DS3LocationData("SL: Black Knight Sword", "Black Knight Sword", DS3LocationCategory.WEAPON, - hidden = True), # Behind illusory wall - DS3LocationData("SL: Ember #3", "Ember", DS3LocationCategory.MISC), - DS3LocationData("SL: Quelana Pyromancy Tome", "Quelana Pyromancy Tome", DS3LocationCategory.UNIQUE), - DS3LocationData("SL: Izalith Staff", "Izalith Staff", DS3LocationCategory.WEAPON, - hidden = True), # Behind illusory wall - DS3LocationData("SL: White Hair Talisman", "White Hair Talisman", DS3LocationCategory.WEAPON, - missable = True), # In lava - DS3LocationData("SL: Toxic Mist", "Toxic Mist", DS3LocationCategory.SPELL, - missable = True), # In lava - DS3LocationData("SL: Undead Bone Shard #1", "Undead Bone Shard", DS3LocationCategory.HEALTH), - DS3LocationData("SL: Titanite Scale", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Shield of Want", "Shield of Want", DS3LocationCategory.SHIELD), - DS3LocationData("SL: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("SL: Ember #4", "Ember", DS3LocationCategory.MISC, + DS3LocationData("SL: Homeward Bone (path to ballista)", "Homeward Bone x2", + DS3LocationCategory.MISC), + DS3LocationData("SL: Ember (ruins main upper, hall end by hole)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("SL: Chaos Gem (lake, far end by mob)", "Chaos Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Ember (ruins main lower, path to antechamber)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("SL: Izalith Pyromancy Tome (antechamber, room near bonfire)", + "Izalith Pyromancy Tome", DS3LocationCategory.UNIQUE), + DS3LocationData("SL: Black Knight Sword (ruins main lower, illusory wall in far hall)", + "Black Knight Sword", DS3LocationCategory.WEAPON, hidden = True), + DS3LocationData("SL: Ember (ruins main upper, just after entrance)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("SL: Quelana Pyromancy Tome (ruins main lower, illusory wall in grey room)", + "Quelana Pyromancy Tome", DS3LocationCategory.UNIQUE, hidden = True), + DS3LocationData("SL: Izalith Staff (ruins basement, second illusory wall behind chest)", + "Izalith Staff", DS3LocationCategory.WEAPON, hidden = True), + DS3LocationData("SL: White Hair Talisman (ruins main lower, in lava)", + "White Hair Talisman", DS3LocationCategory.WEAPON, + missable = True), # This may not even be possible to get without enough fire + # protection gear which the player may not have + DS3LocationData("SL: Toxic Mist (ruins main lower, in lava)", "Toxic Mist", + DS3LocationCategory.SPELL, + missable = True), # This is _probably_ reachable with normal gear, but it + # still sucks and will probably force a death. + DS3LocationData("SL: Undead Bone Shard (ruins main lower, left after stairs)", + "Undead Bone Shard", DS3LocationCategory.HEALTH), + DS3LocationData("SL: Titanite Scale (ruins basement, path to lava)", + "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("SL: Shield of Want (lake, by miniboss)", "Shield of Want", + DS3LocationCategory.SHIELD), + DS3LocationData("SL: Soul of a Crestfallen Knight (ruins basement, above lava)", + "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("SL: Ember (ruins basement, in lava)", "Ember", DS3LocationCategory.MISC, missable = True), # In lava - DS3LocationData("SL: Sacred Flame", "Sacred Flame", DS3LocationCategory.SPELL, - missable = True, hidden = True), # In lava - DS3LocationData("SL: Dragonrider Bow", "Dragonrider Bow", DS3LocationCategory.WEAPON, - hidden = True), # Hidden fall - DS3LocationData("SL: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH, - hidden = True), # Behind illusory wall - DS3LocationData("SL: Bloodbite Ring+1", "Bloodbite Ring+1", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("SL: Flame Stoneplate Ring+2", "Flame Stoneplate Ring+2", DS3LocationCategory.RING, - ngp = True, hidden = True), # Behind illusory wall - DS3LocationData("SL: Large Titanite Shard #9", "Large Titanite Shard x3", DS3LocationCategory.UPGRADE, - hidden = True), # Behind illusory wall - DS3LocationData("SL: Undead Bone Shard #2", "Undead Bone Shard", DS3LocationCategory.HEALTH, - miniboss = True), # Sand Worm drop - DS3LocationData("SL: Lightning Stake", "Lightning Stake", DS3LocationCategory.SPELL, - miniboss = True), # Sand Worm drop - DS3LocationData("SL: Twinkling Titanite", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("SL: Titanite Chunk", "Titanite Chunk", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("SL: Chaos Gem #2", "Chaos Gem", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("SL: Knight Slayer's Ring", "Knight Slayer's Ring", DS3LocationCategory.RING, + DS3LocationData("SL: Sacred Flame (ruins basement, in lava)", "Sacred Flame", + DS3LocationCategory.SPELL, missable = True), # In lava + DS3LocationData("SL: Dragonrider Bow (by ladder from ruins basement to ballista)", + "Dragonrider Bow", DS3LocationCategory.WEAPON, hidden = True), # Hidden fall + DS3LocationData("SL: Estus Shard (antechamber, illusory wall)", "Estus Shard", + DS3LocationCategory.HEALTH, hidden = True), + DS3LocationData("SL: Bloodbite Ring+1 (behind ballista)", "Bloodbite Ring+1", + DS3LocationCategory.RING, ngp = True), + DS3LocationData("SL: Flame Stoneplate Ring+2 (ruins main lower, illusory wall in far hall)", + "Flame Stoneplate Ring+2", DS3LocationCategory.RING, ngp = True, + hidden = True), + DS3LocationData("SL: Large Titanite Shard (ruins basement, illusory wall in upper hall)", + "Large Titanite Shard x3", DS3LocationCategory.UPGRADE, hidden = True), + DS3LocationData("SL: Undead Bone Shard (lake, miniboss drop)", "Undead Bone Shard", + DS3LocationCategory.HEALTH, miniboss = True), # Sand Worm drop + DS3LocationData("SL: Lightning Stake (lake, miniboss drop)", "Lightning Stake", + DS3LocationCategory.SPELL, miniboss = True), # Sand Worm drop + DS3LocationData("SL: Twinkling Titanite (path to side lake, lizard)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("SL: Titanite Chunk (path to side lake, lizard)", "Titanite Chunk", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("SL: Chaos Gem (antechamber, lizard at end of long hall)", + "Chaos Gem", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("SL: Knight Slayer's Ring (ruins basement, NPC drop)", + "Knight Slayer's Ring", DS3LocationCategory.RING, hostile_npc = True), # Knight Slayer Tsorig drop - DS3LocationData("SL: Old King's Great Hammer", "Old King's Great Hammer", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("SL: Chaos Bed Vestiges", "Chaos Bed Vestiges", DS3LocationCategory.SPELL, - missable = True, boss = True, shop = True), # Horace the Hushed # These are listed here even though you can kill Horace in the Road of Sacrifices because # the player may want to complete his and Anri's quest first. - DS3LocationData("SL: Llewellyn Shield", "Llewellyn Shield", DS3LocationCategory.SHIELD, - drop = True, npc = True), # kill or quest - # Shrine Handmaiden after killing - DS3LocationData("SL: Executioner Helm", "Executioner Helm", DS3LocationCategory.ARMOR, - hidden = True, npc = True, shop = True), - DS3LocationData("SL: Executioner Armor", "Executioner Armor", DS3LocationCategory.ARMOR, - hidden = True, npc = True, shop = True), - DS3LocationData("SL: Executioner Gauntlets", "Executioner Gauntlets", DS3LocationCategory.ARMOR, - hidden = True, npc = True, shop = True), - DS3LocationData("SL: Executioner Leggings", "Executioner Leggings", DS3LocationCategory.ARMOR, - hidden = True, npc = True, shop = True), + DS3LocationData("SL: Llewellyn Shield (Horace drop)", "Llewellyn Shield", + DS3LocationCategory.SHIELD, npc = True, hostile_npc = True), + DS3LocationData("FS: Executioner Helm (shop after killing Horace)", "Executioner Helm", + DS3LocationCategory.ARMOR, npc = True, hostile_npc = True, shop = True, + hidden = True), + DS3LocationData("FS: Executioner Armor (shop after killing Horace)", "Executioner Armor", + DS3LocationCategory.ARMOR, npc = True, hostile_npc = True, shop = True, + hidden = True), + DS3LocationData("FS: Executioner Gauntlets (shop after killing Horace)", + "Executioner Gauntlets", DS3LocationCategory.ARMOR, + hostile_npc = True, npc = True, shop = True, hidden = True), + DS3LocationData("FS: Executioner Leggings (shop after killing Horace)", + "Executioner Leggings", DS3LocationCategory.ARMOR, + hostile_npc = True, npc = True, shop = True, hidden = True), # Shrine Handmaid after killing Knight Slayer Tsorig - DS3LocationData("SL: Black Iron Helm", "Black Iron Helm", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True, shop = True), - DS3LocationData("SL: Black Iron Armor", "Black Iron Armor", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True, shop = True), - DS3LocationData("SL: Black Iron Gauntlets", "Black Iron Gauntlets", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True, shop = True), - DS3LocationData("SL: Black Iron Leggings", "Black Iron Leggings", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True, shop = True), + DS3LocationData("FS: Black Iron Helm (shop after killing Tsorig)", "Black Iron Helm", + DS3LocationCategory.ARMOR, hostile_npc = True, shop = True, hidden = True), + DS3LocationData("FS: Black Iron Armor (shop after killing Tsorig)", "Black Iron Armor", + DS3LocationCategory.ARMOR, hostile_npc = True, shop = True, hidden = True), + DS3LocationData("FS: Black Iron Gauntlets (shop after killing Tsorig)", + "Black Iron Gauntlets", DS3LocationCategory.ARMOR, hostile_npc = True, + shop = True, hidden = True), + DS3LocationData("FS: Black Iron Leggings (shop after killing Tsorig)", + "Black Iron Leggings", DS3LocationCategory.ARMOR, hostile_npc = True, + shop = True, hidden = True), # Near Cornyx's cage after killing Old Demon King with Cuculus - DS3LocationData("SL: Spotted Whip", "Spotted Whip", DS3LocationCategory.WEAPON, + DS3LocationData("US: Spotted Whip (by Cornyx's cage after Cuculus quest)", "Spotted Whip", + DS3LocationCategory.WEAPON, missable = True, boss = True, npc = True), + DS3LocationData("US: Cornyx's Garb (by Cornyx's cage after Cuculus quest)", + "Cornyx's Garb", DS3LocationCategory.ARMOR, offline = '02,0:53100100::', + missable = True, boss = True, npc = True), + DS3LocationData("US: Cornyx's Wrap (by Cornyx's cage after Cuculus quest)", "Cornyx's Wrap", + DS3LocationCategory.ARMOR, offline = '02,0:53100100::', missable = True, + boss = True, npc = True), + DS3LocationData("US: Cornyx's Skirt (by Cornyx's cage after Cuculus quest)", + "Cornyx's Skirt", DS3LocationCategory.ARMOR, offline = '02,0:53100100::', missable = True, boss = True, npc = True), - DS3LocationData("SL: Cornyx's Garb", "Cornyx's Garb", DS3LocationCategory.ARMOR, - offline = '02,0:53100100::', missable = True, boss = True, npc = True), - DS3LocationData("SL: Cornyx's Wrap", "Cornyx's Wrap", DS3LocationCategory.ARMOR, - offline = '02,0:53100100::', missable = True, boss = True, npc = True), - DS3LocationData("SL: Cornyx's Skirt", "Cornyx's Skirt", DS3LocationCategory.ARMOR, - offline = '02,0:53100100::', missable = True, boss = True, npc = True), ], "Irithyll of the Boreal Valley": [ - DS3LocationData("IBV: Soul of Pontiff Sulyvahn", "Soul of Pontiff Sulyvahn", DS3LocationCategory.SOUL, - prominent = True, boss = True), - DS3LocationData("IBV: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("IBV: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("IBV: Soul of a Weary Warrior #1", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("IBV: Soul of a Weary Warrior #2", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("IBV: Rime-blue Moss Clump #1", "Rime-blue Moss Clump", DS3LocationCategory.MISC), - DS3LocationData("IBV: Witchtree Branch", "Witchtree Branch", DS3LocationCategory.WEAPON, - hidden = True), # Behind illusory wall - DS3LocationData("IBV: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("IBV: Budding Green Blossom", "Budding Green Blossom", DS3LocationCategory.MISC), - DS3LocationData("IBV: Rime-blue Moss Clump #2", "Rime-blue Moss Clump x2", DS3LocationCategory.MISC), - DS3LocationData("IBV: Large Titanite Shard #3", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("IBV: Large Titanite Shard #4", "Large Titanite Shard", DS3LocationCategory.UPGRADE, - hidden = True), # Behind illusory wall - DS3LocationData("IBV: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("IBV: Large Titanite Shard #5", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("IBV: Large Titanite Shard #6", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("IBV: Soul of a Weary Warrior #3", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("IBV: Magic Clutch Ring", "Magic Clutch Ring", DS3LocationCategory.RING, - hidden = True), # Behind illusory wall - DS3LocationData("IBV: Fading Soul #1", "Fading Soul", DS3LocationCategory.MISC), - DS3LocationData("IBV: Fading Soul #2", "Fading Soul", DS3LocationCategory.MISC), - DS3LocationData("IBV: Homeward Bone", "Homeward Bone x3", DS3LocationCategory.MISC), - DS3LocationData("IBV: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH, - hidden = True), # Hidden behind gravestone - DS3LocationData("IBV: Kukri", "Kukri x8", DS3LocationCategory.MISC), - DS3LocationData("IBV: Rusted Gold Coin #1", "Rusted Gold Coin", DS3LocationCategory.MISC), - DS3LocationData("IBV: Blue Bug Pellet #1", "Blue Bug Pellet x2", DS3LocationCategory.MISC), - DS3LocationData("IBV: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), - DS3LocationData("IBV: Blood Gem", "Blood Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("IBV: Green Blossom #1", "Green Blossom x3", DS3LocationCategory.MISC), - DS3LocationData("IBV: Ring of Sacrifice", "Ring of Sacrifice", DS3LocationCategory.MISC), - DS3LocationData("IBV: Great Heal", "Great Heal", DS3LocationCategory.SPELL), - DS3LocationData("IBV: Large Soul of a Nameless Soldier #3", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("IBV: Green Blossom #2", "Green Blossom x3", DS3LocationCategory.MISC), - DS3LocationData("IBV: Dung Pie #1", "Dung Pie x3", DS3LocationCategory.MISC), - DS3LocationData("IBV: Dung Pie #2", "Dung Pie x3", DS3LocationCategory.MISC), + DS3LocationData("IBV: Soul of Pontiff Sulyvahn", "Soul of Pontiff Sulyvahn", + DS3LocationCategory.SOUL, prominent = True, boss = True), + DS3LocationData("IBV: Large Soul of a Nameless Soldier (central, by bonfire)", + "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("IBV: Large Titanite Shard (ascent, down ladder in last building)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Soul of a Weary Warrior (central, by first fountain)", + "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("IBV: Soul of a Weary Warrior (central, railing by first fountain)", + "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("IBV: Rime-blue Moss Clump (central, by bonfire)", "Rime-blue Moss Clump", + DS3LocationCategory.MISC), + DS3LocationData("IBV: Witchtree Branch (by Dorhys)", "Witchtree Branch", + DS3LocationCategory.WEAPON, hidden = True), # Behind illusory wall + DS3LocationData("IBV: Large Titanite Shard (central, side path after first fountain)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Budding Green Blossom (central, by second fountain)", + "Budding Green Blossom", DS3LocationCategory.MISC), + DS3LocationData("IBV: Rime-blue Moss Clump (central, past second fountain)", + "Rime-blue Moss Clump x2", DS3LocationCategory.MISC), + DS3LocationData("IBV: Large Titanite Shard (central, balcony just before plaza)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Large Titanite Shard (path to Dorhys)", "Large Titanite Shard", + DS3LocationCategory.UPGRADE, hidden = True), # Behind illusory wall + DS3LocationData("IBV: Ring of the Sun's First Born (fall from in front of cathedral)", + "Ring of the Sun's First Born", DS3LocationCategory.RING, + hidden = True), # Hidden fall + DS3LocationData("IBV: Large Soul of a Nameless Soldier (stairs to plaza)", + "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("IBV: Large Titanite Shard (plaza, balcony overlooking ascent)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Large Titanite Shard (plaza, by stairs to church)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Soul of a Weary Warrior (plaza, side room #1)", + "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("IBV: Magic Clutch Ring (plaza, illusory wall)", "Magic Clutch Ring", + DS3LocationCategory.RING, hidden = True), # Behind illusory wall + DS3LocationData("IBV: Fading Soul (descent, cliff edge #1)", "Fading Soul", + DS3LocationCategory.MISC), + DS3LocationData("IBV: Fading Soul (descent, cliff edge #2)", "Fading Soul", + DS3LocationCategory.MISC), + DS3LocationData("IBV: Homeward Bone (descent, before gravestone)", "Homeward Bone x3", + DS3LocationCategory.MISC), + DS3LocationData("IBV: Undead Bone Shard (descent, behind gravestone)", "Undead Bone Shard", + DS3LocationCategory.HEALTH, hidden = True), # Hidden behind gravestone + DS3LocationData("IBV: Kukri (descent, side path)", "Kukri x8", DS3LocationCategory.MISC), + DS3LocationData("IBV: Rusted Gold Coin (descent, side path)", "Rusted Gold Coin", + DS3LocationCategory.MISC), + DS3LocationData("IBV: Blue Bug Pellet (descent, dark room)", "Blue Bug Pellet x2", + DS3LocationCategory.MISC), + DS3LocationData("IBV: Shriving Stone (descent, dark room rafters)", "Shriving Stone", + DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Blood Gem (descent, platform before lake)", "Blood Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Green Blossom (lake, by stairs from descent)", "Green Blossom x3", + DS3LocationCategory.MISC), + DS3LocationData("IBV: Ring of Sacrifice (lake, right of stairs from descent)", + "Ring of Sacrifice", DS3LocationCategory.MISC), + DS3LocationData("IBV: Great Heal (lake, dead Corpse-Grub)", "Great Heal", + DS3LocationCategory.SPELL), + DS3LocationData("IBV: Large Soul of a Nameless Soldier (lake island)", + "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("IBV: Green Blossom (lake wall)", "Green Blossom x3", + DS3LocationCategory.MISC), + DS3LocationData("IBV: Dung Pie (sewer #1)", "Dung Pie x3", DS3LocationCategory.MISC), + DS3LocationData("IBV: Dung Pie (sewer #2)", "Dung Pie x3", DS3LocationCategory.MISC), # These don't actually guard any single item sales. Maybe we can inject one manually? - DS3LocationData("IBV: Excrement-covered Ashes", "Excrement-covered Ashes", DS3LocationCategory.UNIQUE), - DS3LocationData("IBV: Large Soul of a Nameless Soldier #4", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("IBV: Soul of a Weary Warrior #4", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("IBV: Large Titanite Shard #7", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("IBV: Blue Bug Pellet #2", "Blue Bug Pellet x2", DS3LocationCategory.MISC), - DS3LocationData("IBV: Ember", "Ember", DS3LocationCategory.MISC), - DS3LocationData("IBV: Large Titanite Shard #8", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("IBV: Green Blossom #3", "Green Blossom", DS3LocationCategory.MISC), - DS3LocationData("IBV: Lightning Gem", "Lightning Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("IBV: Large Soul of a Nameless Soldier #5", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("IBV: Soul of a Weary Warrior #5", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("IBV: Proof of a Concord Kept", "Proof of a Concord Kept", DS3LocationCategory.MISC), - DS3LocationData("IBV: Rusted Gold Coin #2", "Rusted Gold Coin", DS3LocationCategory.MISC, + DS3LocationData("IBV: Excrement-covered Ashes (sewer, by stairs)", + "Excrement-covered Ashes", DS3LocationCategory.UNIQUE), + DS3LocationData("IBV: Large Soul of a Nameless Soldier (ascent, after great hall)", + "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("IBV: Soul of a Weary Warrior (ascent, by final staircase)", + "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("IBV: Large Titanite Shard (ascent, by elevator door)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Blue Bug Pellet (ascent, in last building)", "Blue Bug Pellet x2", + DS3LocationCategory.MISC), + DS3LocationData("IBV: Ember (shortcut from church to cathedral)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("IBV: Green Blossom (lake, by Distant Manor)", "Green Blossom", + DS3LocationCategory.MISC), + DS3LocationData("IBV: Lightning Gem (plaza center)", "Lightning Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("IBV: Large Soul of a Nameless Soldier (central, by second fountain)", + "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("IBV: Soul of a Weary Warrior (plaza, side room #2)", + "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("IBV: Proof of a Concord Kept (Church of Yorshka altar)", + "Proof of a Concord Kept", DS3LocationCategory.MISC), + DS3LocationData("IBV: Rusted Gold Coin (Distant Manor, down stairs)", "Rusted Gold Coin", + DS3LocationCategory.MISC), + DS3LocationData("IBV: Chloranthy Ring+1 (plaza, behind altar)", "Chloranthy Ring+1", + DS3LocationCategory.RING, ngp = True), + DS3LocationData("IBV: Covetous Gold Serpent Ring+1 (descent, drop after dark room)", + "Covetous Gold Serpent Ring+1", DS3LocationCategory.RING, ngp = True, hidden = True), # Hidden fall - DS3LocationData("IBV: Chloranthy Ring+1", "Chloranthy Ring+1", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("IBV: Covetous Gold Serpent Ring+1", "Covetous Gold Serpent Ring+1", DS3LocationCategory.RING, - ngp = True, hidden = True), # Hidden fall - DS3LocationData("IBV: Wood Grain Ring+2", "Wood Grain Ring+2", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("IBV: Divine Blessing #1", "Divine Blessing", DS3LocationCategory.MISC), - DS3LocationData("IBV: Smough's Great Hammer", "Smough's Great Hammer", DS3LocationCategory.WEAPON), - DS3LocationData("IBV: Yorshka's Spear", "Yorshka's Spear", DS3LocationCategory.WEAPON), - DS3LocationData("IBV: Leo Ring", "Leo Ring", DS3LocationCategory.RING), - DS3LocationData("IBV: Dorhys' Gnawing", "Dorhys' Gnawing", DS3LocationCategory.SPELL, + DS3LocationData("IBV: Wood Grain Ring+2 (ascent, right after great hall)", "Wood Grain Ring+2", + DS3LocationCategory.RING, ngp = True), + DS3LocationData("IBV: Divine Blessing (great hall, chest)", "Divine Blessing", + DS3LocationCategory.MISC), + DS3LocationData("IBV: Smough's Great Hammer (great hall, chest)", + "Smough's Great Hammer", DS3LocationCategory.WEAPON), + DS3LocationData("IBV: Yorshka's Spear (descent, dark room rafers chest)", "Yorshka's Spear", + DS3LocationCategory.WEAPON), + DS3LocationData("IBV: Leo Ring (great hall, chest)", "Leo Ring", + DS3LocationCategory.RING), + DS3LocationData("IBV: Dorhys' Gnawing (Dorhys drop)", "Dorhys' Gnawing", + DS3LocationCategory.SPELL, hidden = True), # Behind illusory wall + DS3LocationData("IBV: Divine Blessing (great hall, mob)", + "Divine Blessing", DS3LocationCategory.MISC, drop = True, + hidden = True), # Guaranteed drop from normal-looking Silver Knight + DS3LocationData("IBV: Large Titanite Shard (great hall, mob)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE, drop = True, + hidden = True), # Guaranteed drop from normal-looking Silver Knight + DS3LocationData("IBV: Large Titanite Shard (great hall, mob)", + "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, drop = True, + hidden = True), # Guaranteed drop from normal-looking Silver Knight + DS3LocationData("IBV: Large Titanite Shard (great hall, mob)", + "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, drop = True, + hidden = True), # Guaranteed drop from normal-looking Silver Knight + DS3LocationData("IBV: Roster of Knights (descent, first landing)", "Roster of Knights", + DS3LocationCategory.UNIQUE), + DS3LocationData("IBV: Twinkling Titanite (descent, lizard behind illusory wall)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True, hidden = True), # Behind illusory wall - DS3LocationData("IBV: Divine Blessing #2", "Divine Blessing", DS3LocationCategory.MISC, - drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight - DS3LocationData("IBV: Large Titanite Shard #9", "Large Titanite Shard", DS3LocationCategory.UPGRADE, - drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight - DS3LocationData("IBV: Large Titanite Shard #10", "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, - drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight - DS3LocationData("IBV: Large Titanite Shard #11", "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, - drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight - DS3LocationData("IBV: Roster of Knights", "Roster of Knights", DS3LocationCategory.UNIQUE), - DS3LocationData("IBV: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True, hidden = True), # Behind illusory wall - DS3LocationData("IBV: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("IBV: Siegbräu", "Siegbräu", DS3LocationCategory.MISC, + DS3LocationData("IBV: Twinkling Titanite (central, lizard before plaza)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("IBV: Siegbräu (Siegward)", "Siegbräu", DS3LocationCategory.MISC, missable = True, npc = True), - DS3LocationData("IBV: Emit Force", "Emit Force", DS3LocationCategory.SPELL, + DS3LocationData("IBV: Emit Force (Siegward)", "Emit Force", DS3LocationCategory.SPELL, missable = True, npc = True), - DS3LocationData("IBV: Sneering Mask", "Sneering Mask", DS3LocationCategory.ARMOR, - missable = True, hostile_npc = True), # Londor Pale Shade (win both invasions) - DS3LocationData("IBV: Pale Shade Robe", "Pale Shade Robe", DS3LocationCategory.ARMOR, - missable = True, hostile_npc = True), # Londor Pale Shade (win both invasions) - DS3LocationData("IBV: Pale Shade Gloves", "Pale Shade Gloves", DS3LocationCategory.ARMOR, - missable = True, hostile_npc = True), # Londor Pale Shade (win both invasions) - DS3LocationData("IBV: Pale Shade Trousers", "Pale Shade Trousers", DS3LocationCategory.ARMOR, - missable = True, hostile_npc = True), # Londor Pale Shade (win both invasions) - DS3LocationData("IBV: Greatsword of Judgment", "Greatsword of Judgment", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("IBV: Profaned Greatsword", "Profaned Greatsword", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("IBV -> AL", None, DS3LocationCategory.EVENT), - DS3LocationData("IBV -> ID", None, DS3LocationCategory.EVENT), + DS3LocationData("IBV -> AL", None, DS3LocationCategory.EVENT), + DS3LocationData("IBV -> ID", None, DS3LocationCategory.EVENT), + + # After winning both Londor Pale Shade invasions + DS3LocationData("FS: Sneering Mask (Yoel's room, kill Londor Pale Shade twice)", + "Sneering Mask", DS3LocationCategory.ARMOR, missable = True, + hostile_npc = True), + DS3LocationData("FS: Pale Shade Robe (Yoel's room, kill Londor Pale Shade twice)", + "Pale Shade Robe", DS3LocationCategory.ARMOR, missable = True, + hostile_npc = True), + DS3LocationData("FS: Pale Shade Gloves (Yoel's room, kill Londor Pale Shade twice)", + "Pale Shade Gloves", DS3LocationCategory.ARMOR, missable = True, + hostile_npc = True), + DS3LocationData("FS: Pale Shade Trousers (Yoel's room, kill Londor Pale Shade twice)", + "Pale Shade Trousers", DS3LocationCategory.ARMOR, missable = True, + hostile_npc = True), # Anri of Astora - DS3LocationData("IBV: Anri's Straight Sword", "Anri's Straight Sword", DS3LocationCategory.WEAPON, - missable = True, npc = True), - DS3LocationData("IBV: Ring of the Evil Eye", "Ring of the Evil Eye", DS3LocationCategory.RING, - missable = True, npc = True), - - # Shrine Handmaid after killing Sulyvahn's Beast Duo - DS3LocationData("IBV: Helm of Favor", "Helm of Favor", DS3LocationCategory.ARMOR, - hidden = True, miniboss = True, shop = True), - DS3LocationData("IBV: Embraced Armor of Favor", "Embraced Armor of Favor", DS3LocationCategory.ARMOR, - hidden = True, miniboss = True, shop = True), - DS3LocationData("IBV: Gauntlets of Favor", "Gauntlets of Favor", DS3LocationCategory.ARMOR, - hidden = True, miniboss = True, shop = True), - DS3LocationData("IBV: Leggings of Favor", "Leggings of Favor", DS3LocationCategory.ARMOR, - hidden = True, miniboss = True, shop = True), - - # Sirris after killing Creighton - DS3LocationData("IBV: Mail Breaker", "Mail Breaker", DS3LocationCategory.WEAPON, - missable = True, npc = True), - DS3LocationData("IBC: Silvercat Ring", "Silvercat Ring", DS3LocationCategory.RING, - missable = True, npc = True), - DS3LocationData("IBV: Dragonslayer's Axe", "Dragonslayer's Axe", DS3LocationCategory.WEAPON, - missable = True, npc = True), - DS3LocationData("IBV: Creighton's Steel Mask", "Creighton's Steel Mask", DS3LocationCategory.ARMOR, - missable = True, npc = True), - DS3LocationData("IBV: Mirrah Chain Mail", "Mirrah Chain Mail", DS3LocationCategory.ARMOR, - missable = True, npc = True), - DS3LocationData("IBV: Mirrah Chain Gloves", "Mirrah Chain Gloves", DS3LocationCategory.ARMOR, - missable = True, npc = True), - DS3LocationData("IBV: Mirrah Chain Leggings", "Mirrah Chain Leggings", DS3LocationCategory.ARMOR, - missable = True, npc = True), + DS3LocationData("IBV: Ring of the Evil Eye (Anri)", "Ring of the Evil Eye", + DS3LocationCategory.RING, missable = True, npc = True), + + # Sirris quest after killing Creighton + DS3LocationData("FS: Mail Breaker (Sirris for killing Creighton)", "Mail Breaker", + DS3LocationCategory.WEAPON, offline = '99,0:50006080::', missable = True, + hostile_npc = True, npc = True), + DS3LocationData("FS: Silvercat Ring (Sirris for killing Creighton)", "Silvercat Ring", + DS3LocationCategory.RING, missable = True, hostile_npc = True, npc = True), + DS3LocationData("IBV: Dragonslayer's Axe (Creighton drop)", "Dragonslayer's Axe", + DS3LocationCategory.WEAPON, missable = True, hostile_npc = True, + npc = True), + DS3LocationData("IBV: Creighton's Steel Mask (bridge after killing Creighton)", + "Creighton's Steel Mask", DS3LocationCategory.ARMOR, missable = True, + hostile_npc = True, npc = True), + DS3LocationData("IBV: Mirrah Chain Mail (bridge after killing Creighton)", + "Mirrah Chain Mail", DS3LocationCategory.ARMOR, missable = True, + hostile_npc = True, npc = True), + DS3LocationData("IBV: Mirrah Chain Gloves (bridge after killing Creighton)", + "Mirrah Chain Gloves", DS3LocationCategory.ARMOR, missable = True, + hostile_npc = True, npc = True), + DS3LocationData("IBV: Mirrah Chain Leggings (bridge after killing Creighton)", + "Mirrah Chain Leggings", DS3LocationCategory.ARMOR, missable = True, + hostile_npc = True, npc = True), ], "Irithyll Dungeon": [ - DS3LocationData("ID: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE, - missable = True, npc = True), # Siegward (quest) - DS3LocationData("ID: Murakumo", "Murakumo", DS3LocationCategory.WEAPON, - missable = True, npc = True), # Alva (requires ember) - DS3LocationData("ID: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("ID: Fading Soul", "Fading Soul", DS3LocationCategory.MISC), - DS3LocationData("ID: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("ID: Jailbreaker's Key", "Jailbreaker's Key", DS3LocationCategory.KEY, - key = True), - DS3LocationData("ID: Pale Pine Resin", "Pale Pine Resin x2", DS3LocationCategory.MISC), - DS3LocationData("ID: Simple Gem", "Simple Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("ID: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("ID: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("ID: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC), - DS3LocationData("ID: Bellowing Dragoncrest Ring", "Bellowing Dragoncrest Ring", DS3LocationCategory.RING, - conditional = True), - DS3LocationData("ID: Soul of a Weary Warrior #1", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("ID: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("ID: Lightning Bolt", "Lightning Bolt x9", DS3LocationCategory.MISC), - DS3LocationData("ID: Large Titanite Shard #3", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("ID: Profaned Flame", "Profaned Flame", DS3LocationCategory.SPELL), - DS3LocationData("ID: Large Titanite Shard #4", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("ID: Soul of a Weary Warrior #2", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("ID: Dung Pie #1", "Dung Pie x4", DS3LocationCategory.MISC), - DS3LocationData("ID: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("ID: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("ID: Profaned Coal", "Profaned Coal", DS3LocationCategory.UNIQUE), - DS3LocationData("ID: Large Titanite Shard #5", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("ID: Old Sorcerer Hat", "Old Sorcerer Hat", DS3LocationCategory.ARMOR), - DS3LocationData("ID: Old Sorcerer Coat", "Old Sorcerer Coat", DS3LocationCategory.ARMOR), - DS3LocationData("ID: Old Sorcerer Gauntlets", "Old Sorcerer Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("ID: Old Sorcerer Boots", "Old Sorcerer Boots", DS3LocationCategory.ARMOR), - DS3LocationData("ID: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("ID: Covetous Gold Serpent Ring", "Covetous Gold Serpent Ring", DS3LocationCategory.RING, - conditional = True), - DS3LocationData("ID: Lightning Blade", "Lightning Blade", DS3LocationCategory.SPELL), - DS3LocationData("ID: Rusted Coin", "Rusted Coin", DS3LocationCategory.MISC), - DS3LocationData("ID: Dusk Crown Ring", "Dusk Crown Ring", DS3LocationCategory.RING), - DS3LocationData("ID: Pickaxe", "Pickaxe", DS3LocationCategory.WEAPON), - DS3LocationData("ID: Xanthous Ashes", "Xanthous Ashes", DS3LocationCategory.KEY, - progression = True), - DS3LocationData("ID: Rusted Gold Coin", "Rusted Gold Coin", DS3LocationCategory.MISC), - DS3LocationData("ID: Old Cell Key", "Old Cell Key", DS3LocationCategory.KEY, - key = True), - DS3LocationData("ID: Covetous Silver Serpent Ring+1", "Covetous Silver Serpent Ring+1", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("ID: Dragon Torso Stone", "Dragon Torso Stone", DS3LocationCategory.UNIQUE), - DS3LocationData("ID: Prisoner Chief's Ashes", "Prisoner Chief's Ashes", DS3LocationCategory.KEY, - progression = True), - DS3LocationData("ID: Great Magic Shield", "Great Magic Shield", DS3LocationCategory.SPELL, - drop = True, hidden = True), # Guaranteed drop from a normal-looking Corpse-Grub - DS3LocationData("ID: Dragonslayer Lightning Arrow", "Dragonslayer Lightning Arrow x10", DS3LocationCategory.MISC, - mimic = True), - DS3LocationData("ID: Titanite Scale #1", "Titanite Scale x2", DS3LocationCategory.UPGRADE, - mimic = True), - DS3LocationData("ID: Dark Clutch Ring", "Dark Clutch Ring", DS3LocationCategory.RING, - mimic = True), - DS3LocationData("ID: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH, - mimic = True), - DS3LocationData("ID: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("ID: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("ID: Dung Pie #2", "Dung Pie x4", DS3LocationCategory.MISC), - DS3LocationData("ID: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE, - miniboss = True), # Giant Slave Drop + DS3LocationData("ID: Titanite Slab (Siegward)", "Titanite Slab", + DS3LocationCategory.UPGRADE, missable = True, npc = True), + DS3LocationData("ID: Murakumo (Alva drop)", "Murakumo", + DS3LocationCategory.WEAPON, missable = True, hostile_npc = True), + DS3LocationData("ID: Large Titanite Shard (B1 near, just past bonfire)", "Large Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("ID: Fading Soul (B1 near, main hall)", "Fading Soul", DS3LocationCategory.MISC), + DS3LocationData("ID: Large Soul of a Nameless Soldier (B2, hall by stairs)", + "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("ID: Jailbreaker's Key (B1 far, cell after gate)", "Jailbreaker's Key", + DS3LocationCategory.KEY, key = True), + DS3LocationData("ID: Pale Pine Resin (B1 far, cell with broken wall)", "Pale Pine Resin x2", + DS3LocationCategory.MISC), + DS3LocationData("ID: Simple Gem (B2 far, cell by stairs)", "Simple Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("ID: Large Soul of a Nameless Soldier (B2 far, by lift)", + "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("ID: Large Titanite Shard (B1 far, rightmost cell)", "Large Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("ID: Homeward Bone (path from B2 to pit)", "Homeward Bone x2", + DS3LocationCategory.MISC), + DS3LocationData("ID: Bellowing Dragoncrest Ring (drop from B1 towards pit)", + "Bellowing Dragoncrest Ring", DS3LocationCategory.RING, conditional = True), + DS3LocationData("ID: Soul of a Weary Warrior (by drop to pit)", "Soul of a Weary Warrior", + DS3LocationCategory.SOUL), + DS3LocationData("ID: Soul of a Crestfallen Knight (balcony above pit)", + "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("ID: Lightning Bolt (awning over pit)", "Lightning Bolt x9", + DS3LocationCategory.MISC), + DS3LocationData("ID: Large Titanite Shard (pit)", "Large Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("ID: Profaned Flame (pit)", "Profaned Flame", DS3LocationCategory.SPELL), + DS3LocationData("ID: Large Titanite Shard (pit)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("ID: Soul of a Weary Warrior (stairs between pit and B3)", + "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("ID: Dung Pie (B3, by path from pit)", "Dung Pie x4", + DS3LocationCategory.MISC), + DS3LocationData("ID: Ember (B3 center)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("ID: Ember (B3 near, by exit)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("ID: Profaned Coal (B3 far, left cell)", "Profaned Coal", + DS3LocationCategory.UNIQUE), + DS3LocationData("ID: Large Titanite Shard (B3 near, right corner)", "Large Titanite Shard", + DS3LocationCategory.UPGRADE), + DS3LocationData("ID: Old Sorcerer Hat (B2 near, middle cell)", "Old Sorcerer Hat", + DS3LocationCategory.ARMOR), + DS3LocationData("ID: Old Sorcerer Coat (B2 near, middle cell)", "Old Sorcerer Coat", + DS3LocationCategory.ARMOR), + DS3LocationData("ID: Old Sorcerer Gauntlets (B2 near, middle cell)", + "Old Sorcerer Gauntlets", DS3LocationCategory.ARMOR), + DS3LocationData("ID: Old Sorcerer Boots (B2 near, middle cell)", "Old Sorcerer Boots", + DS3LocationCategory.ARMOR), + DS3LocationData("ID: Large Soul of a Weary Warrior (just before Profaned Capital)", + "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("ID: Covetous Gold Serpent Ring (Siegward's cell)", + "Covetous Gold Serpent Ring", DS3LocationCategory.RING, conditional = True), + DS3LocationData("ID: Lightning Blade (B3 lift, middle platform)", "Lightning Blade", + DS3LocationCategory.SPELL), + DS3LocationData("ID: Rusted Coin (B1 near, just past bonfire)", "Rusted Coin", + DS3LocationCategory.MISC), + DS3LocationData("ID: Dusk Crown Ring (B3 far, right cell)", "Dusk Crown Ring", + DS3LocationCategory.RING), + DS3LocationData("ID: Pickaxe (path from pit to B3)", "Pickaxe", DS3LocationCategory.WEAPON), + DS3LocationData("ID: Xanthous Ashes (B3 far, right cell)", "Xanthous Ashes", + DS3LocationCategory.KEY, progression = True), + DS3LocationData("ID: Rusted Gold Coin (B1 near, end of hall by door)", "Rusted Gold Coin", + DS3LocationCategory.MISC), + DS3LocationData("ID: Large Titanite Shard (stairs between pit and B3)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("ID: Old Cell Key (stairs between pit and B3)", "Old Cell Key", + DS3LocationCategory.KEY, key = True), + DS3LocationData("ID: Covetous Silver Serpent Ring+1 (pit lift, middle platform)", + "Covetous Silver Serpent Ring+1", DS3LocationCategory.RING, ngp = True), + DS3LocationData("ID: Dragon Torso Stone (B3, outside lift)", "Dragon Torso Stone", + DS3LocationCategory.UNIQUE), + DS3LocationData("ID: Prisoner Chief's Ashes (B2 near, locked cell by stairs)", + "Prisoner Chief's Ashes", DS3LocationCategory.KEY, progression = True), + DS3LocationData("ID: Great Magic Shield (B2 near, mob drop in far left cell)", + "Great Magic Shield", DS3LocationCategory.SPELL,drop = True, + hidden = True), # Guaranteed drop from a normal-looking Corpse-Grub + DS3LocationData("ID: Dragonslayer Lightning Arrow (pit, mimic in hall)", + "Dragonslayer Lightning Arrow x10", DS3LocationCategory.MISC, mimic = True), + DS3LocationData("ID: Titanite Scale (B3 far, mimic in hall)", "Titanite Scale x2", + DS3LocationCategory.UPGRADE, mimic = True), + DS3LocationData("ID: Dark Clutch Ring (stairs between pit and B3, mimic)", + "Dark Clutch Ring", DS3LocationCategory.RING, mimic = True), + DS3LocationData("ID: Estus Shard (mimic on path from B2 to pit)", "Estus Shard", + DS3LocationCategory.HEALTH, mimic = True), + DS3LocationData("ID: Titanite Chunk (balcony above pit, lizard)", "Titanite Chunk", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("ID: Titanite Scale (B2 far, lizard)", "Titanite Scale", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("ID: Dung Pie (pit, miniboss drop)", "Dung Pie x4", + DS3LocationCategory.MISC, miniboss = True), # Giant slave drop + DS3LocationData("ID: Titanite Chunk (pit, miniboss drop", "Titanite Chunk", + DS3LocationCategory.UPGRADE, miniboss = True), # Giant Slave Drop # Alva (requires ember) - DS3LocationData("ID: Alva Helm", "Alva Helm", DS3LocationCategory.ARMOR, - missable = True, npc = True), - DS3LocationData("ID: Alva Armor", "Alva Armor", DS3LocationCategory.ARMOR, - missable = True, npc = True), - DS3LocationData("ID: Alva Gauntlets", "Alva Gauntlets", DS3LocationCategory.ARMOR, - missable = True, npc = True), - DS3LocationData("ID: Alva Leggings", "Alva Leggings", DS3LocationCategory.ARMOR, - missable = True, npc = True), + DS3LocationData("ID: Alva Helm (B3 near, by Karla's cell, after killing Alva)", "Alva Helm", + DS3LocationCategory.ARMOR, missable = True, npc = True), + DS3LocationData("ID: Alva Armor (B3 near, by Karla's cell, after killing Alva)", + "Alva Armor", DS3LocationCategory.ARMOR, missable = True, npc = True), + DS3LocationData("ID: Alva Gauntlets (B3 near, by Karla's cell, after killing Alva)", + "Alva Gauntlets", DS3LocationCategory.ARMOR, missable = True, npc = True), + DS3LocationData("ID: Alva Leggings (B3 near, by Karla's cell, after killing Alva)", + "Alva Leggings", DS3LocationCategory.ARMOR, missable = True, npc = True), ], "Profaned Capital": [ - DS3LocationData("PC: Soul of Yhorm the Giant", "Soul of Yhorm the Giant", DS3LocationCategory.SOUL, + DS3LocationData("PC: Soul of Yhorm the Giant", "Soul of Yhorm the Giant", + DS3LocationCategory.SOUL, boss = True), + DS3LocationData("PC: Cinders of a Lord - Yhorm the Giant", + "Cinders of a Lord - Yhorm the Giant", DS3LocationCategory.KEY, + offline = "07,0:50002170::", prominent = True, progression = True, boss = True), - DS3LocationData("PC: Cinders of a Lord - Yhorm the Giant", "Cinders of a Lord - Yhorm the Giant", DS3LocationCategory.KEY, - offline = "07,0:50002170::", prominent = True, progression = True, boss = True), - DS3LocationData("PC: Logan's Scroll", "Logan's Scroll", DS3LocationCategory.UNIQUE, - hostile_npc = True), # Sorcerer - DS3LocationData("PC: Purging Stone #1", "Purging Stone x3", DS3LocationCategory.MISC), - DS3LocationData("PC: Rusted Coin #1", "Rusted Coin x2", DS3LocationCategory.MISC), - DS3LocationData("PC: Rusted Gold Coin #1", "Rusted Gold Coin", DS3LocationCategory.MISC), - DS3LocationData("PC: Purging Stone #2", "Purging Stone", DS3LocationCategory.MISC), - DS3LocationData("PC: Cursebite Ring", "Cursebite Ring", DS3LocationCategory.RING), - DS3LocationData("PC: Poison Gem", "Poison Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("PC: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), - DS3LocationData("PC: Poison Arrow", "Poison Arrow x18", DS3LocationCategory.MISC), - DS3LocationData("PC: Rubbish", "Rubbish", DS3LocationCategory.MISC), - DS3LocationData("PC: Onislayer Greatarrow", "Onislayer Greatarrow x8", DS3LocationCategory.MISC), - DS3LocationData("PC: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("PC: Rusted Coin #2", "Rusted Coin", DS3LocationCategory.MISC), - DS3LocationData("PC: Rusted Coin #3", "Rusted Coin", DS3LocationCategory.MISC), - DS3LocationData("PC: Blooming Purple Moss Clump", "Blooming Purple Moss Clump x3", DS3LocationCategory.MISC), - DS3LocationData("PC: Wrath of the Gods", "Wrath of the Gods", DS3LocationCategory.SPELL), - DS3LocationData("PC: Onislayer Greatbow", "Onislayer Greatbow", DS3LocationCategory.WEAPON, + DS3LocationData("PC: Logan's Scroll (chapel roof, NPC drop)", "Logan's Scroll", + DS3LocationCategory.UNIQUE, hostile_npc = True), # Sorcerer + DS3LocationData("PC: Purging Stone (chapel ground floor)", "Purging Stone x3", + DS3LocationCategory.MISC), + DS3LocationData("PC: Rusted Coin (tower exterior)", "Rusted Coin x2", + DS3LocationCategory.MISC), + DS3LocationData("PC: Rusted Gold Coin (halls above swamp)", "Rusted Gold Coin", + DS3LocationCategory.MISC), + DS3LocationData("PC: Purging Stone (swamp, by chapel ladder)", "Purging Stone", + DS3LocationCategory.MISC), + DS3LocationData("PC: Cursebite Ring (swamp, below halls)", "Cursebite Ring", + DS3LocationCategory.RING), + DS3LocationData("PC: Poison Gem (swamp, below halls)", "Poison Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("PC: Shriving Stone (swamp, by chapel door)", "Shriving Stone", + DS3LocationCategory.UPGRADE), + DS3LocationData("PC: Poison Arrow (chapel roof)", "Poison Arrow x18", + DS3LocationCategory.MISC), + DS3LocationData("PC: Rubbish (chapel, down stairs from second floor)", "Rubbish", + DS3LocationCategory.MISC), + DS3LocationData("PC: Onislayer Greatarrow (bridge)", "Onislayer Greatarrow x8", + DS3LocationCategory.MISC), + DS3LocationData("PC: Large Soul of a Weary Warrior (bridge, far end)", + "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("PC: Rusted Coin (below bridge #1)", "Rusted Coin", + DS3LocationCategory.MISC), + DS3LocationData("PC: Rusted Coin (below bridge #2)", "Rusted Coin", + DS3LocationCategory.MISC), + DS3LocationData("PC: Blooming Purple Moss Clump (walkway above swamp)", + "Blooming Purple Moss Clump x3", DS3LocationCategory.MISC), + DS3LocationData("PC: Wrath of the Gods (chapel, drop from roof)", "Wrath of the Gods", + DS3LocationCategory.SPELL), + DS3LocationData("PC: Onislayer Greatbow (drop from bridge)", "Onislayer Greatbow", + DS3LocationCategory.WEAPON, hidden = True), # Hidden fall + DS3LocationData("PC: Jailer's Key Ring (hall past chapel)", "Jailer's Key Ring", + DS3LocationCategory.KEY, progression = True, key = True), + DS3LocationData("PC: Ember (palace, far room)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("PC: Flame Stoneplate Ring+1 (chapel, drop from roof towards entrance)", + "Flame Stoneplate Ring+1", DS3LocationCategory.RING, ngp = True, hidden = True), # Hidden fall - DS3LocationData("PC: Jailer's Key Ring", "Jailer's Key Ring", DS3LocationCategory.KEY, - progression = True, key = True), - DS3LocationData("PC: Ember", "Ember", DS3LocationCategory.MISC), - DS3LocationData("PC: Flame Stoneplate Ring+1", "Flame Stoneplate Ring+1", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("PC: Magic Stoneplate Ring+2", "Magic Stoneplate Ring+2", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("PC: Court Sorcerer Hood", "Court Sorcerer Hood", DS3LocationCategory.ARMOR), - DS3LocationData("PC: Court Sorcerer Robe", "Court Sorcerer Robe", DS3LocationCategory.ARMOR), - DS3LocationData("PC: Court Sorcerer Gloves", "Court Sorcerer Gloves", DS3LocationCategory.ARMOR), - DS3LocationData("PC: Court Sorcerer Trousers", "Court Sorcerer Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("PC: Storm Ruler", "Storm Ruler", DS3LocationCategory.WEAPON), - DS3LocationData("PC: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), - DS3LocationData("PC: Eleonora", "Eleonora", DS3LocationCategory.WEAPON, - drop = True, hidden = True), # Guaranteed drop from a normal-looking Monstrosity of Sin - DS3LocationData("PC: Rusted Gold Coin #2", "Rusted Gold Coin x2", DS3LocationCategory.MISC, - mimic = True), - DS3LocationData("PC: Court Sorcerer's Staff", "Court Sorcerer's Staff", DS3LocationCategory.WEAPON, - mimic = True), - DS3LocationData("PC: Greatshield of Glory", "Greatshield of Glory", DS3LocationCategory.SHIELD, - mimic = True), - DS3LocationData("PC: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("PC: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("PC: Siegbräu", "Siegbräu", DS3LocationCategory.MISC, - missable = True, npc = True), - DS3LocationData("PC: Yhorm's Great Machete", "Yhorm's Great Machete", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("PC: Yhorm's Greatshield", "Yhorm's Greatshield", DS3LocationCategory.SHIELD, - missable = True, boss = True, shop = True), + DS3LocationData("PC: Magic Stoneplate Ring+2 (tower base)", "Magic Stoneplate Ring+2", + DS3LocationCategory.RING, ngp = True), + DS3LocationData("PC: Court Sorcerer Hood (chapel, second floor)", "Court Sorcerer Hood", + DS3LocationCategory.ARMOR), + DS3LocationData("PC: Court Sorcerer Robe (chapel, second floor)", "Court Sorcerer Robe", + DS3LocationCategory.ARMOR), + DS3LocationData("PC: Court Sorcerer Gloves (chapel, second floor)", "Court Sorcerer Gloves", + DS3LocationCategory.ARMOR), + DS3LocationData("PC: Court Sorcerer Trousers (chapel, second floor)", + "Court Sorcerer Trousers", DS3LocationCategory.ARMOR), + DS3LocationData("PC: Storm Ruler (boss room)", "Storm Ruler", DS3LocationCategory.WEAPON), + DS3LocationData("PC: Undead Bone Shard (by bonfire)", "Undead Bone Shard", + DS3LocationCategory.HEALTH), + DS3LocationData("PC: Eleonora (chapel ground floor, kill mob)", "Eleonora", + DS3LocationCategory.WEAPON, drop = True, + hidden = True), # Guaranteed drop from a normal-looking Monstrosity of Sin + DS3LocationData("PC: Rusted Gold Coin (palace, mimic in far room)", "Rusted Gold Coin x2", + DS3LocationCategory.MISC, mimic = True), + DS3LocationData("PC: Court Sorcerer's Staff (chapel, mimic on second floor)", + "Court Sorcerer's Staff", DS3LocationCategory.WEAPON, mimic = True), + DS3LocationData("PC: Greatshield of Glory (palace, mimic in far room)", + "Greatshield of Glory", DS3LocationCategory.SHIELD, mimic = True), + DS3LocationData("PC: Twinkling Titanite (halls above swamp, lizard #1)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("PC: Twinkling Titanite (halls above swamp, lizard #1)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("PC: Siegbräu (Siegward after killing boss)", "Siegbräu", + DS3LocationCategory.MISC, missable = True, npc = True), # Siegward drops (kill or quest) - DS3LocationData("PC: Storm Ruler (Siegward)", "Storm Ruler", DS3LocationCategory.KEY, + DS3LocationData("PC: Storm Ruler (Siegward)", "Storm Ruler", DS3LocationCategory.KEY, offline = '02,0:50006218::', missable = True, drop = True, npc = True), - DS3LocationData("PC: Pierce Shield", "Pierce Shield", DS3LocationCategory.SHIELD, + DS3LocationData("PC: Pierce Shield (Siegward)", "Pierce Shield", DS3LocationCategory.SHIELD, missable = True, drop = True, npc = True), ], # We consider "Anor Londo" to be everything accessible only after killing Pontiff. This doesn't # match up one-to-one with where the game pops up the region name, but it balances items better # and covers the region that's full of DS1 Anor Londo references. "Anor Londo": [ - DS3LocationData("AL: Soul of Aldrich", "Soul of Aldrich", DS3LocationCategory.SOUL, + DS3LocationData("AL: Soul of Aldrich", "Soul of Aldrich", DS3LocationCategory.SOUL, boss = True), - DS3LocationData("AL: Cinders of a Lord - Aldrich", "Cinders of a Lord - Aldrich", DS3LocationCategory.KEY, - offline = '06,0:50002130::', prominent = True, progression = True, boss = True), - DS3LocationData("AL: Yorshka's Chime", "Yorshka's Chime", DS3LocationCategory.WEAPON, - missable = True, drop = True, npc = True), # Yorshka (kill), invisible walkway - DS3LocationData("AL: Drang Twinspears", "Drang Twinspears", DS3LocationCategory.WEAPON, - drop = True, hidden = True), # Guaranteed drop from a normal-loking knight - DS3LocationData("AL: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), - DS3LocationData("AL: Painting Guardian's Curved Sword", "Painting Guardian's Curved Sword", DS3LocationCategory.WEAPON, + DS3LocationData("AL: Cinders of a Lord - Aldrich", "Cinders of a Lord - Aldrich", + DS3LocationCategory.KEY, offline = '06,0:50002130::', prominent = True, + progression = True, boss = True), + DS3LocationData("AL: Yorshka's Chime (kill Yorshka)", "Yorshka's Chime", + DS3LocationCategory.WEAPON, missable = True, drop = True, + npc = True), # Hidden walkway, missable because it will break Sirris's quest + DS3LocationData("AL: Drang Twinspears (plaza, NPC drop)", "Drang Twinspears", + DS3LocationCategory.WEAPON, drop = True, hidden = True), + DS3LocationData("AL: Estus Shard (dark cathedral, by left stairs)", "Estus Shard", + DS3LocationCategory.HEALTH), + DS3LocationData("AL: Painting Guardian's Curved Sword (prison tower rafters)", + "Painting Guardian's Curved Sword", DS3LocationCategory.WEAPON, hidden = True), # Invisible walkway - DS3LocationData("AL: Brass Helm", "Brass Helm", DS3LocationCategory.ARMOR, + DS3LocationData("AL: Brass Helm (tomb)", "Brass Helm", DS3LocationCategory.ARMOR, hidden = True), # Behind illusory wall - DS3LocationData("AL: Brass Armor", "Brass Armor", DS3LocationCategory.ARMOR, + DS3LocationData("AL: Brass Armor (tomb)", "Brass Armor", DS3LocationCategory.ARMOR, hidden = True), # Behind illusory wall - DS3LocationData("AL: Brass Gauntlets", "Brass Gauntlets", DS3LocationCategory.ARMOR, + DS3LocationData("AL: Brass Gauntlets (tomb)", "Brass Gauntlets", DS3LocationCategory.ARMOR, hidden = True), # Behind illusory wall - DS3LocationData("AL: Brass Leggings", "Brass Leggings", DS3LocationCategory.ARMOR, + DS3LocationData("AL: Brass Leggings (tomb)", "Brass Leggings", DS3LocationCategory.ARMOR, hidden = True), # Behind illusory wall - DS3LocationData("AL: Human Dregs", "Human Dregs", DS3LocationCategory.MISC, + DS3LocationData("AL: Human Dregs (water reserves)", "Human Dregs", DS3LocationCategory.MISC, hidden = True), # Behind illusory wall - DS3LocationData("AL: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("AL: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("AL: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("AL: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("AL: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("AL: Ember #3", "Ember", DS3LocationCategory.MISC), - DS3LocationData("AL: Large Titanite Shard #3", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("AL: Dark Stoneplate Ring", "Dark Stoneplate Ring", DS3LocationCategory.RING), - DS3LocationData("AL: Large Titanite Shard #4", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("AL: Deep Gem", "Deep Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("AL: Titanite Scale", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("AL: Dragonslayer Greatarrow", "Dragonslayer Greatarrow x5", DS3LocationCategory.MISC, + DS3LocationData("AL: Ember (spiral staircase, bottom)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("AL: Large Titanite Shard (bottom of the furthest buttress)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("AL: Large Titanite Shard (walkway, side path by cathedral)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("AL: Soul of a Weary Warrior (plaza, nearer)", "Soul of a Weary Warrior", + DS3LocationCategory.SOUL), + DS3LocationData("AL: Ember (plaza, right side)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("AL: Ember (plaza, further)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("AL: Large Titanite Shard (right after light cathedral)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("AL: Dark Stoneplate Ring (by dark stairs up from plaza)", + "Dark Stoneplate Ring", DS3LocationCategory.RING), + DS3LocationData("AL: Large Titanite Shard (bottom of the nearest buttress)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("AL: Deep Gem (water reserves)", "Deep Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("AL: Titanite Scale (top of ladder up to buttresses)", "Titanite Scale", + DS3LocationCategory.UPGRADE), + DS3LocationData("AL: Dragonslayer Greatarrow (drop from nearest buttress)", + "Dragonslayer Greatarrow x5", DS3LocationCategory.MISC, offline = '06,0:53700620::', hidden = True), # Hidden fall - DS3LocationData("AL: Dragonslayer Greatbow", "Dragonslayer Greatbow", DS3LocationCategory.WEAPON, + DS3LocationData("AL: Dragonslayer Greatbow (drop from nearest buttress)", + "Dragonslayer Greatbow", DS3LocationCategory.WEAPON, offline = '06,0:53700620::', hidden = True), # Hidden fall - DS3LocationData("AL: Easterner's Ashes", "Easterner's Ashes", DS3LocationCategory.KEY, - progression = True), - DS3LocationData("AL: Painting Guardian Hood", "Painting Guardian Hood", DS3LocationCategory.ARMOR, + DS3LocationData("AL: Easterner's Ashes (below top of furthest buttress)", + "Easterner's Ashes", DS3LocationCategory.KEY, progression = True), + DS3LocationData("AL: Painting Guardian Hood (prison tower, rafters)", + "Painting Guardian Hood", DS3LocationCategory.ARMOR, hidden = True), # Invisible walkway - DS3LocationData("AL: Painting Guardian Gown", "Painting Guardian Gown", DS3LocationCategory.ARMOR, + DS3LocationData("AL: Painting Guardian Gown (prison tower, rafters)", + "Painting Guardian Gown", DS3LocationCategory.ARMOR, hidden = True), # Invisible walkway - DS3LocationData("AL: Painting Guardian Gloves", "Painting Guardian Gloves", DS3LocationCategory.ARMOR, + DS3LocationData("AL: Painting Guardian Gloves (prison tower, rafters)", + "Painting Guardian Gloves", DS3LocationCategory.ARMOR, hidden = True), # Invisible walkway - DS3LocationData("AL: Painting Guardian Waistcloth", "Painting Guardian Waistcloth", DS3LocationCategory.ARMOR, + DS3LocationData("AL: Painting Guardian Waistcloth (prison tower, rafters)", + "Painting Guardian Waistcloth", DS3LocationCategory.ARMOR, hidden = True), # Invisible walkway - DS3LocationData("AL: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("AL: Moonlight Arrow", "Moonlight Arrow x6", DS3LocationCategory.MISC), - DS3LocationData("AL: Proof of a Concord Kept", "Proof of a Concord Kept", DS3LocationCategory.MISC), - DS3LocationData("AL: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("AL: Giant's Coal", "Giant's Coal", DS3LocationCategory.UNIQUE), - DS3LocationData("AL: Havel's Ring+2", "Havel's Ring+2", DS3LocationCategory.RING, - ngp = True, hidden = True), # Invisible walkway - DS3LocationData("AL: Ring of Favor+1", "Ring of Favor+1", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("AL: Sun Princess Ring", "Sun Princess Ring", DS3LocationCategory.RING), - DS3LocationData("AL: Reversal Ring", "Reversal Ring", DS3LocationCategory.RING, - hidden = True), # Behind illusory wall - DS3LocationData("AL: Golden Ritual Spear", "Golden Ritual Spear", DS3LocationCategory.WEAPON, - mimic = True), - DS3LocationData("AL: Ring of Favor", "Ring of Favor", DS3LocationCategory.RING, - miniboss = True, hidden = True), # Sulyvahn's Beast Duo drop, behind illusory wall - DS3LocationData("AL: Blade of the Darkmoon", "Blade of the Darkmoon", DS3LocationCategory.UNIQUE, - missable = True, drop = True, npc = True), # Yorshka (quest or kill) - DS3LocationData("AL: Simple Gem", "Simple Gem", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("AL: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("AL: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("AL: Aldrich's Ruby", "Aldrich's Ruby", DS3LocationCategory.RING, - miniboss = True), # Deep Accursed drop - DS3LocationData("AL: Aldrich Faithful", "Aldrich Faithful", DS3LocationCategory.UNIQUE, - hidden = True), # Behind illusory wall - DS3LocationData("AL: Budding Green Blossom", "Budding Green Blossom", DS3LocationCategory.MISC, - offline = '99,0:-1:110000,70000118:', missable = True, npc = True, shop = True), # sold by Shrine Maiden after helping Sirris and defeating Aldrich - DS3LocationData("AL: Bountiful Sunlight", "Bountiful Sunlight", DS3LocationCategory.SPELL, - missable = True, boss = True, shop = True), - DS3LocationData("AL: Darkmoon Longbow", "Darkmoon Longbow", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("AL: Lifehunt Scythe", "Lifehunt Scythe", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), + DS3LocationData("AL: Soul of a Crestfallen Knight (right of dark cathedral entrance)", + "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("AL: Moonlight Arrow (dark cathedral, up right stairs)", + "Moonlight Arrow x6", DS3LocationCategory.MISC), + DS3LocationData("AL: Proof of a Concord Kept (dark cathedral, up left stairs)", + "Proof of a Concord Kept", DS3LocationCategory.MISC), + DS3LocationData("AL: Large Soul of a Weary Warrior (left of dark cathedral entrance)", + "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("AL: Giant's Coal (by giant near dark cathedral)", "Giant's Coal", + DS3LocationCategory.UNIQUE), + DS3LocationData("AL: Havel's Ring+2 (prison tower, rafters)", "Havel's Ring+2", + DS3LocationCategory.RING, ngp = True, hidden = True), # Invisible walkway + DS3LocationData("AL: Ring of Favor+1 (light cathedral, upstairs)", "Ring of Favor+1", + DS3LocationCategory.RING, ngp = True), + DS3LocationData("AL: Sun Princess Ring (dark cathedral, after boss)", "Sun Princess Ring", + DS3LocationCategory.RING), + DS3LocationData("AL: Reversal Ring (tomb, chest in corner)", "Reversal Ring", + DS3LocationCategory.RING, hidden = True), # Behind illusory wall + DS3LocationData("AL: Golden Ritual Spear (light cathedral, mimic upstairs)", + "Golden Ritual Spear", DS3LocationCategory.WEAPON, mimic = True), + DS3LocationData("AL: Ring of Favor (water reserves, both minibosses)", "Ring of Favor", + DS3LocationCategory.RING, miniboss = True, + hidden = True), # Sulyvahn's Beast Duo drop, behind illusory wall + DS3LocationData("AL: Blade of the Darkmoon (Yorshka with Darkmoon Loyalty)", + "Blade of the Darkmoon", DS3LocationCategory.UNIQUE, missable = True, + drop = True, + npc = True), # Hidden walkway, missable because it will break Sirris's quest + DS3LocationData("AL: Simple Gem (light cathedral, lizard upstairs)", "Simple Gem", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("AL: Twinkling Titanite (lizard after light cathedral #1)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("AL: Twinkling Titanite (lizard after light cathedral #1)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("AL: Aldrich's Ruby (dark cathedral, miniboss)", "Aldrich's Ruby", + DS3LocationCategory.RING, miniboss = True), # Deep Accursed drop + DS3LocationData("AL: Aldrich Faithful (water reserves, talk to McDonnel)", "Aldrich Faithful", + DS3LocationCategory.UNIQUE, hidden = True), # Behind illusory wall + DS3LocationData("AL: Large Titanite Shard ?? (right after light cathedral)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE, + # TODO: Mark this as Area: irithyll_anorlondo in the offline rando and order + # it properly + offline = '06,0:53700480::'), + + DS3LocationData("FS: Budding Green Blossom (shop after Sirris kills Aldrich)", + "Budding Green Blossom", DS3LocationCategory.MISC, + offline = '99,0:-1:110000,70000118:', missable = True, npc = True, + shop = True), # sold by Shrine Maiden after helping Sirris defeat Aldrich # Sirris (quest completion) - DS3LocationData("AL: Sunset Shield", "Sunset Shield", DS3LocationCategory.SHIELD, - missable = True, npc = True), - DS3LocationData("AL: Sunless Talisman", "Sunless Talisman", DS3LocationCategory.WEAPON, - missable = True, npc = True), - DS3LocationData("AL: Sunless Veil", "Sunless Veil", DS3LocationCategory.ARMOR, - missable = True, npc = True, shop = True), - DS3LocationData("AL: Sunless Armor", "Sunless Armor", DS3LocationCategory.ARMOR, - missable = True, npc = True, shop = True), - DS3LocationData("AL: Sunless Gauntlets", "Sunless Gauntlets", DS3LocationCategory.ARMOR, - missable = True, npc = True, shop = True), - DS3LocationData("AL: Sunless Leggings", "Sunless Leggings", DS3LocationCategory.ARMOR, - missable = True, npc = True, shop = True), - # In Pit of Hollows after completion - DS3LocationData("AL: Sunset Helm", "Sunset Helm", DS3LocationCategory.ARMOR, - missable = True, npc = True), - DS3LocationData("AL: Sunset Armor", "Sunset Armor", DS3LocationCategory.ARMOR, - missable = True, npc = True), - DS3LocationData("AL: Sunset Gauntlets", "Sunset Gauntlets", DS3LocationCategory.ARMOR, - missable = True, npc = True), - DS3LocationData("AL: Sunset Leggings", "Sunset Leggings", DS3LocationCategory.ARMOR, - missable = True, npc = True), + DS3LocationData("FS: Sunset Shield (by grave after killing Hodrick w/Sirris)", + "Sunset Shield", DS3LocationCategory.SHIELD, missable = True, + hostile_npc = True, npc = True), + # In Pit of Hollows after killing Hodrick + DS3LocationData("US: Sunset Helm (Pit of Hollows after killing Hodrick w/Sirris)", + "Sunset Helm", DS3LocationCategory.ARMOR, missable = True, + hostile_npc = True, npc = True), + DS3LocationData("US: Sunset Armor (pit of hollows after killing Hodrick w/Sirris)", + "Sunset Armor", DS3LocationCategory.ARMOR, missable = True, + hostile_npc = True, npc = True), + DS3LocationData("US: Sunset Gauntlets (pit of hollows after killing Hodrick w/Sirris)", + "Sunset Gauntlets", DS3LocationCategory.ARMOR, missable = True, + hostile_npc = True, npc = True), + DS3LocationData("US: Sunset Leggings (pit of hollows after killing Hodrick w/Sirris)", + "Sunset Leggings", DS3LocationCategory.ARMOR, missable = True, + hostile_npc = True, npc = True), + + # Shrine Handmaid after killing Sulyvahn's Beast Duo + DS3LocationData("FS: Helm of Favor (shop after killing water reserve minibosses)", + "Helm of Favor", DS3LocationCategory.ARMOR, hidden = True, miniboss = True, + shop = True), + DS3LocationData("FS: Embraced Armor of Favor (shop after killing water reserve minibosses)", + "Embraced Armor of Favor", DS3LocationCategory.ARMOR, hidden = True, + miniboss = True, shop = True), + DS3LocationData("FS: Gauntlets of Favor (shop after killing water reserve minibosses)", + "Gauntlets of Favor", DS3LocationCategory.ARMOR, hidden = True, + miniboss = True, shop = True), + DS3LocationData("FS: Leggings of Favor (shop after killing water reserve minibosses)", + "Leggings of Favor", DS3LocationCategory.ARMOR, hidden = True, + miniboss = True, shop = True), # Anri of Astora - DS3LocationData("AL: Chameleon", "Chameleon", DS3LocationCategory.SPELL, - missable = True, npc = True), + DS3LocationData("AL: Chameleon (tomb after marrying Anri)", "Chameleon", + DS3LocationCategory.SPELL, missable = True, npc = True), + DS3LocationData("AL: Anri's Straight Sword (Anri quest)","Anri's Straight Sword", + DS3LocationCategory.WEAPON, missable = True, npc = True), # Shrine Handmaid after killing Ringfinger Leonhard # This is listed here even though you can kill Leonhard immediately because we want the # logic to assume people will do his full quest. Missable because he can disappear forever # if you use up all your Pale Tongues. - DS3LocationData("AL: Leonhard's Garb", "Leonhard's Garb", DS3LocationCategory.ARMOR, - hidden = True, npc = True, shop = True, missable = True), - DS3LocationData("AL: Leonhard's Gauntlets", "Leonhard's Gauntlets", DS3LocationCategory.ARMOR, - hidden = True, npc = True, shop = True, missable = True), - DS3LocationData("AL: Leonhard's Trousers", "Leonhard's Trousers", DS3LocationCategory.ARMOR, - hidden = True, npc = True, shop = True, missable = True), + DS3LocationData("FS: Leonhard's Garb (shop after killing Leonhard)", + "Leonhard's Garb", DS3LocationCategory.ARMOR, hidden = True, npc = True, + shop = True, missable = True), + DS3LocationData("FS: Leonhard's Gauntlets (shop after killing Leonhard)", + "Leonhard's Gauntlets", DS3LocationCategory.ARMOR, hidden = True, + npc = True, shop = True, missable = True), + DS3LocationData("FS: Leonhard's Trousers (shop after killing Leonhard)", + "Leonhard's Trousers", DS3LocationCategory.ARMOR, hidden = True, npc = True, + shop = True, missable = True), # Shrine Handmaid after killing Alrich, Devourer of Gods - DS3LocationData("AL: Smough's Helm", "Smough's Helm", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("AL: Smough's Armor", "Smough's Armor", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("AL: Smough's Gauntlets", "Smough's Gauntlets", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("AL: Smough's Leggings", "Smough's Leggings", DS3LocationCategory.ARMOR, - boss = True, shop = True), + DS3LocationData("FS: Smough's Helm (shop after killing AL boss)", "Smough's Helm", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Smough's Armor (shop after killing AL boss)", "Smough's Armor", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Smough's Gauntlets (shop after killing AL boss)", "Smough's Gauntlets", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Smough's Leggings (shop after killing AL boss)", "Smough's Leggings", + DS3LocationCategory.ARMOR, boss = True, shop = True), # Shrine Handmaid after killing Anri or completing their quest - DS3LocationData("AL: Elite Knight Helm", "Elite Knight Helm", DS3LocationCategory.ARMOR, - missable = True, npc = True, shop = True), - DS3LocationData("AL: Elite Knight Armor", "Elite Knight Armor", DS3LocationCategory.ARMOR, - missable = True, npc = True, shop = True), - DS3LocationData("AL: Elite Knight Gauntlets", "Elite Knight Gauntlets", DS3LocationCategory.ARMOR, - missable = True, npc = True, shop = True), - DS3LocationData("AL: Elite Knight Leggings", "Elite Knight Leggings", DS3LocationCategory.ARMOR, - missable = True, npc = True, shop = True), + DS3LocationData("FS: Elite Knight Helm (shop after Anri quest)", "Elite Knight Helm", + DS3LocationCategory.ARMOR, missable = True, npc = True, shop = True), + DS3LocationData("FS: Elite Knight Armor (shop after Anri quest)", "Elite Knight Armor", + DS3LocationCategory.ARMOR, missable = True, npc = True, shop = True), + DS3LocationData("FS: Elite Knight Gauntlets (shop after Anri quest)", + "Elite Knight Gauntlets", DS3LocationCategory.ARMOR, missable = True, + npc = True, shop = True), + DS3LocationData("FS: Elite Knight Leggings (shop after Anri quest)", + "Elite Knight Leggings", DS3LocationCategory.ARMOR, missable = True, + npc = True, shop = True), # Ringfinger Leonhard (quest or kill) - DS3LocationData("AL: Crescent Moon Sword", "Crescent Moon Sword", DS3LocationCategory.WEAPON, - missable = True, npc = True), - DS3LocationData("AL: Silver Mask", "Silver Mask", DS3LocationCategory.ARMOR, - missable = True, npc = True), - DS3LocationData("AL: Soul of Rosaria", "Soul of Rosaria", DS3LocationCategory.UNIQUE, - missable = True, npc = True), - + DS3LocationData("AL: Crescent Moon Sword (Leonhard drop)", + "Crescent Moon Sword", DS3LocationCategory.WEAPON, missable = True, + npc = True), + DS3LocationData("AL: Silver Mask (Leonhard drop)", + "Silver Mask", DS3LocationCategory.ARMOR, missable = True, npc = True), + DS3LocationData("AL: Soul of Rosaria (Leonhard drop)", + "Soul of Rosaria", DS3LocationCategory.UNIQUE, missable = True, npc = True), ], "Lothric Castle": [ - DS3LocationData("LC: Soul of Dragonslayer Armour", "Soul of Dragonslayer Armour", DS3LocationCategory.SOUL, - prominent = True, boss = True), - DS3LocationData("LC: Sniper Bolt", "Sniper Bolt x11", DS3LocationCategory.MISC), - DS3LocationData("LC: Sniper Crossbow", "Sniper Crossbow", DS3LocationCategory.WEAPON), - DS3LocationData("LC: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Greatlance", "Greatlance", DS3LocationCategory.WEAPON), - DS3LocationData("LC: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Titanite Chunk #3", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Sacred Bloom Shield", "Sacred Bloom Shield", DS3LocationCategory.SHIELD, + DS3LocationData("LC: Soul of Dragonslayer Armour", "Soul of Dragonslayer Armour", + DS3LocationCategory.SOUL, prominent = True, boss = True), + DS3LocationData("LC: Sniper Bolt (moat, right path end)", "Sniper Bolt x11", + DS3LocationCategory.MISC), + DS3LocationData("LC: Sniper Crossbow (moat, right path end)", "Sniper Crossbow", + DS3LocationCategory.WEAPON), + DS3LocationData("LC: Titanite Scale (dark room, upper balcony)", "Titanite Scale", + DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Titanite Chunk (dark room mid, out door opposite wyvern)", + "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Greatlance (overlooking Dragon Barracks bonfire)", "Greatlance", + DS3LocationCategory.WEAPON), + DS3LocationData("LC: Titanite Chunk (ascent, first balcony)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Titanite Chunk (ascent, turret before barricades)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Sacred Bloom Shield (ascent, behind illusory wall)", + "Sacred Bloom Shield", DS3LocationCategory.SHIELD, hidden = True), # Behind illusory wall - DS3LocationData("LC: Titanite Chunk #4", "Titanite Chunk x2", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Refined Gem", "Refined Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("LC: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), - DS3LocationData("LC: Lightning Urn #1", "Lightning Urn x3", DS3LocationCategory.MISC), - DS3LocationData("LC: Titanite Chunk #5", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Titanite Chunk #6", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Titanite Chunk #7", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Caitha's Chime", "Caitha's Chime", DS3LocationCategory.WEAPON), - DS3LocationData("LC: Lightning Urn #2", "Lightning Urn x6", DS3LocationCategory.MISC), - DS3LocationData("LC: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("LC: Raw Gem", "Raw Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Black Firebomb", "Black Firebomb x3", DS3LocationCategory.MISC), - DS3LocationData("LC: Pale Pine Resin", "Pale Pine Resin", DS3LocationCategory.MISC), - DS3LocationData("LC: Large Soul of a Weary Warrior #1", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("LC: Sunlight Medal", "Sunlight Medal", DS3LocationCategory.MISC), - DS3LocationData("LC: Soul of a Crestfallen Knight #2", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC, + DS3LocationData("LC: Titanite Chunk (ascent, final turret)", "Titanite Chunk x2", + DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Refined Gem (plaza)", "Refined Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Soul of a Crestfallen Knight (by lift bottom)", + "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("LC: Undead Bone Shard (moat, far ledge)", "Undead Bone Shard", + DS3LocationCategory.HEALTH), + DS3LocationData("LC: Lightning Urn (moat, right path, first room)", "Lightning Urn x3", + DS3LocationCategory.MISC), + DS3LocationData("LC: Titanite Chunk (moat #1)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Titanite Chunk (moat #2)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Titanite Chunk (moat, near ledge)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Caitha's Chime (chapel, drop onto roof)", "Caitha's Chime", + DS3LocationCategory.WEAPON), + DS3LocationData("LC: Lightning Urn (plaza)", "Lightning Urn x6", DS3LocationCategory.MISC), + DS3LocationData("LC: Ember (plaza, by gate)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("LC: Raw Gem (plaza left)", "Raw Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Black Firebomb (dark room lower)", "Black Firebomb x3", + DS3LocationCategory.MISC), + DS3LocationData("LC: Pale Pine Resin (dark room upper, by mimic)", "Pale Pine Resin", + DS3LocationCategory.MISC), + DS3LocationData("LC: Large Soul of a Weary Warrior (main hall, by lever)", + "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("LC: Sunlight Medal (by lift top)", "Sunlight Medal", + DS3LocationCategory.MISC), + DS3LocationData("LC: Soul of a Crestfallen Knight (wyvern room, balcony)", + "Soul of a Crestfallen Knight", DS3LocationCategory.MISC, hidden = True), # Hidden fall - DS3LocationData("LC: Titanite Chunk #8", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Large Soul of a Nameless Soldier #1", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("LC: Knight's Ring", "Knight's Ring", DS3LocationCategory.RING), - DS3LocationData("LC: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("LC: Large Soul of a Weary Warrior #2", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("LC: Ember #3", "Ember", DS3LocationCategory.MISC), - DS3LocationData("LC: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.MISC), - DS3LocationData("LC: Large Soul of a Nameless Soldier #2", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("LC: Ember #4", "Ember", DS3LocationCategory.MISC), - DS3LocationData("LC: Winged Knight Helm", "Winged Knight Helm", DS3LocationCategory.ARMOR, - hidden = True), # Behind illusory wall - DS3LocationData("LC: Winged Knight Armor", "Winged Knight Armor", DS3LocationCategory.ARMOR, - hidden = True), # Behind illusory wall - DS3LocationData("LC: Winged Knight Gauntlets", "Winged Knight Gauntlets", DS3LocationCategory.ARMOR, - hidden = True), # Behind illusory wall - DS3LocationData("LC: Winged Knight Leggings", "Winged Knight Leggings", DS3LocationCategory.ARMOR, - hidden = True), # Behind illusory wall - DS3LocationData("LC: Rusted Coin", "Rusted Coin x2", DS3LocationCategory.MISC), - DS3LocationData("LC: Braille Divine Tome of Lothric", "Braille Divine Tome of Lothric", DS3LocationCategory.UNIQUE, + DS3LocationData("LC: Titanite Chunk (altar roof)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Titanite Scale (dark room mid, out door opposite wyvern)", + "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Large Soul of a Nameless Soldier (moat, right path)", + "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("LC: Knight's Ring (altar)", "Knight's Ring", DS3LocationCategory.RING), + DS3LocationData("LC: Ember (main hall, left of stairs)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("LC: Large Soul of a Weary Warrior (ascent, last turret)", + "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("LC: Ember (by Dragon Barracks bonfire)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("LC: Twinkling Titanite (ascent, side room)", "Twinkling Titanite", + DS3LocationCategory.MISC), + DS3LocationData("LC: Large Soul of a Nameless Soldier (dark room mid)", + "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("LC: Ember (plaza center)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("LC: Winged Knight Helm (ascent, behind illusory wall)", + "Winged Knight Helm", DS3LocationCategory.ARMOR, hidden = True), + DS3LocationData("LC: Winged Knight Armor (ascent, behind illusory wall)", + "Winged Knight Armor", DS3LocationCategory.ARMOR, hidden = True), + DS3LocationData("LC: Winged Knight Gauntlets (ascent, behind illusory wall)", + "Winged Knight Gauntlets", DS3LocationCategory.ARMOR, hidden = True), + DS3LocationData("LC: Winged Knight Leggings (ascent, behind illusory wall)", + "Winged Knight Leggings", DS3LocationCategory.ARMOR, hidden = True), + DS3LocationData("LC: Rusted Coin (chapel)", "Rusted Coin x2", DS3LocationCategory.MISC), + DS3LocationData("LC: Braille Divine Tome of Lothric (wyvern room)", + "Braille Divine Tome of Lothric", DS3LocationCategory.UNIQUE, hidden = True), # Hidden fall - DS3LocationData("LC: Red Tearstone Ring", "Red Tearstone Ring", DS3LocationCategory.RING), - DS3LocationData("LC: Twinkling Titanite #2", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Large Soul of a Nameless Soldier #3", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("LC: Titanite Scale #3", "Titanite Scale x3", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Titanite Scale #4", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Hood of Prayer", "Hood of Prayer", DS3LocationCategory.ARMOR), - DS3LocationData("LC: Robe of Prayer", "Robe of Prayer", DS3LocationCategory.ARMOR), - DS3LocationData("LC: Skirt of Prayer", "Skirt of Prayer", DS3LocationCategory.ARMOR), - DS3LocationData("LC: Spirit Tree Crest Shield", "Spirit Tree Crest Shield", DS3LocationCategory.SHIELD), - DS3LocationData("LC: Titanite Scale #5", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Twinkling Titanite #3", "Twinkling Titanite", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Twinkling Titanite #4", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Life Ring+2", "Life Ring+2", DS3LocationCategory.RING, - ngp = True, hidden = True), # Hidden fall - DS3LocationData("LC: Dark Stoneplate Ring+1", "Dark Stoneplate Ring+1", DS3LocationCategory.RING, - ngp = True, hidden = True), # Hidden fall - DS3LocationData("LC: Thunder Stoneplate Ring+2", "Thunder Stoneplate Ring+2", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("LC: Sunlight Straight Sword", "Sunlight Straight Sword", DS3LocationCategory.WEAPON, - mimic = True, hidden = True), # Hidden fall - DS3LocationData("LC: Titanite Scale #6", "Titanite Scale x3", DS3LocationCategory.UPGRADE, - mimic = True), - DS3LocationData("LC: Ember #5", "Ember x2", DS3LocationCategory.MISC, - miniboss = True, hidden = True), # Hidden fall, Pus of Man Wyvern drop - DS3LocationData("LC: Titanite Chunk #9", "Titanite Chunk x2", DS3LocationCategory.UPGRADE, - miniboss = True, hidden = True), # Hidden fall, Pus of Man Wyvern drop - DS3LocationData("LC: Ember #6", "Ember x2", DS3LocationCategory.MISC, - miniboss = True), # Pus of Man Wyvern drop - DS3LocationData("LC: Titanite Chunk #10", "Titanite Chunk x2", DS3LocationCategory.UPGRADE, - miniboss = True), - DS3LocationData("LC: Irithyll Rapier", "Irithyll Rapier", DS3LocationCategory.WEAPON, - miniboss = True), # Boreal Outrider drop - DS3LocationData("LC: Twinkling Titanite #5", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("LC: Twinkling Titanite #6", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("LC: Gotthard Twinswords", "Gotthard Twinswords", DS3LocationCategory.WEAPON, - conditional = True), - DS3LocationData("LC: Grand Archives Key", "Grand Archives Key", DS3LocationCategory.KEY, - prominent = True, progression = True, key = True, conditional = True), - DS3LocationData("LC: Titanite Chunk #11", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Dancer's Enchanted Swords", "Dancer's Enchanted Swords", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("LC: Soothing Sunlight", "Soothing Sunlight", DS3LocationCategory.SPELL, - missable = True, boss = True, shop = True), - DS3LocationData("LC: Dragonslayer Greataxe", "Dragonslayer Greataxe", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("LC: Dragonslayer Greatshield", "Dragonslayer Greatshield", DS3LocationCategory.SHIELD, - missable = True, boss = True, shop = True), + DS3LocationData("LC: Red Tearstone Ring (chapel, drop onto roof)", "Red Tearstone Ring", + DS3LocationCategory.RING), + DS3LocationData("LC: Twinkling Titanite (moat, left side)", "Twinkling Titanite x2", + DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Large Soul of a Nameless Soldier (plaza left, by pillar)", + "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("LC: Titanite Scale (altar)", "Titanite Scale x3", + DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Titanite Scale (chapel, chest)", "Titanite Scale", + DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Hood of Prayer", "Hood of Prayer", + DS3LocationCategory.ARMOR), + DS3LocationData("LC: Robe of Prayer (ascent, chest at beginning)", "Robe of Prayer", + DS3LocationCategory.ARMOR), + DS3LocationData("LC: Skirt of Prayer (ascent, chest at beginning)", "Skirt of Prayer", + DS3LocationCategory.ARMOR), + DS3LocationData("LC: Spirit Tree Crest Shield (basement, chest)", + "Spirit Tree Crest Shield", DS3LocationCategory.SHIELD), + DS3LocationData("LC: Titanite Scale (basement, chest)", "Titanite Scale", + DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Twinkling Titanite (basement, chest #1)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Twinkling Titanite (basement, chest #2)", "Twinkling Titanite x2", + DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Life Ring+2 (dark room mid, out door opposite wyvern, drop down)", + "Life Ring+2", DS3LocationCategory.RING, ngp = True, + hidden = True), # Hidden fall + DS3LocationData("LC: Dark Stoneplate Ring+1 (wyvern room, balcony)", + "Dark Stoneplate Ring+1", DS3LocationCategory.RING, ngp = True, + hidden = True), # Hidden fall + DS3LocationData("LC: Thunder Stoneplate Ring+2 (chapel, drop onto roof)", + "Thunder Stoneplate Ring+2", DS3LocationCategory.RING, ngp = True), + DS3LocationData("LC: Sunlight Straight Sword (wyvern room, mimic)", + "Sunlight Straight Sword", DS3LocationCategory.WEAPON, mimic = True, + hidden = True), # Hidden fall + DS3LocationData("LC: Titanite Scale (dark room, upper, mimic)", "Titanite Scale x3", + DS3LocationCategory.UPGRADE, mimic = True), + DS3LocationData("LC: Ember (wyvern room, wyvern foot mob drop)", "Ember x2", + DS3LocationCategory.MISC, + hidden = True), # Hidden fall, Pus of Man Wyvern drop + DS3LocationData("LC: Titanite Chunk (wyvern room, wyvern foot mob drop)", "Titanite Chunk x2", + DS3LocationCategory.UPGRADE, + hidden = True), # Hidden fall, Pus of Man Wyvern drop + DS3LocationData("LC: Ember (dark room mid, pus of man mob drop)", "Ember x2", + DS3LocationCategory.MISC), # Pus of Man Wyvern drop + DS3LocationData("LC: Titanite Chunk (dark room mid, pus of man mob drop)", + "Titanite Chunk x2", DS3LocationCategory.UPGRADE), + DS3LocationData("LC: Irithyll Rapier (basement, miniboss drop)", "Irithyll Rapier", + DS3LocationCategory.WEAPON, miniboss = True), # Boreal Outrider drop + DS3LocationData("LC: Twinkling Titanite (dark room mid, out door opposite wyvern, lizard)", + "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("LC: Twinkling Titanite (moat, right path, lizard)", + "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("LC: Gotthard Twinswords (by Grand Archives door, after PC and AL bosses)", + "Gotthard Twinswords", DS3LocationCategory.WEAPON, conditional = True), + DS3LocationData("LC: Grand Archives Key (by Grand Archives door, after PC and AL bosses)", + "Grand Archives Key", DS3LocationCategory.KEY, prominent = True, + progression = True, key = True, conditional = True), + DS3LocationData("LC: Titanite Chunk (down stairs after boss)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), # Eygon of Carim (kill or quest) - DS3LocationData("LC: Morne's Great Hammer", "Morne's Great Hammer", DS3LocationCategory.WEAPON, - drop = True, npc = True), - DS3LocationData("LC: Moaning Shield", "Moaning Shield", DS3LocationCategory.SHIELD, - drop = True, npc = True), + DS3LocationData("FS: Morne's Great Hammer (Eygon)", "Morne's Great Hammer", + DS3LocationCategory.WEAPON, npc = True), + DS3LocationData("FS: Moaning Shield (Eygon)", "Moaning Shield", DS3LocationCategory.SHIELD, + npc = True), - # Shrine Handmaid after killing Dancer of the Boreal Valley - DS3LocationData("LC: Dancer's Crown", "Dancer's Crown", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("LC: Dancer's Armor", "Dancer's Armor", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("LC: Dancer's Gauntlets", "Dancer's Gauntlets", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("LC: Dancer's Leggings", "Dancer's Leggings", DS3LocationCategory.ARMOR, - boss = True, shop = True), + # Shrine Handmaid after killing Dragonslayer Armour (or Eygon of Carim) + DS3LocationData("FS: Dancer's Crown (shop after killing LC entry boss)", "Dancer's Crown", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Dancer's Armor (shop after killing LC entry boss)", "Dancer's Armor", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Dancer's Gauntlets (shop after killing LC entry boss)", + "Dancer's Gauntlets", DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Dancer's Leggings (shop after killing LC entry boss)", + "Dancer's Leggings", DS3LocationCategory.ARMOR, boss = True, shop = True), # Shrine Handmaid after killing Dragonslayer Armour (or Eygon of Carim) - DS3LocationData("LC: Morne's Helm", "Morne's Helm", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("LC: Morne's Armor", "Morne's Armor", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("LC: Morne's Gauntlets", "Morne's Gauntlets", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("LC: Morne's Leggings", "Morne's Leggings", DS3LocationCategory.ARMOR, - boss = True, shop = True), + DS3LocationData("FS: Morne's Helm (shop after killing Eygon or LC boss)", "Morne's Helm", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Morne's Armor (shop after killing Eygon or LC boss)", "Morne's Armor", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Morne's Gauntlets (shop after killing Eygon or LC boss)", + "Morne's Gauntlets", DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Morne's Leggings (shop after killing Eygon or LC boss)", + "Morne's Leggings", DS3LocationCategory.ARMOR, boss = True, shop = True), ], "Consumed King's Garden": [ - - DS3LocationData("CKG: Soul of Consumed Oceiros", "Soul of Consumed Oceiros", DS3LocationCategory.SOUL, - prominent = True, boss = True), + DS3LocationData("CKG: Soul of Consumed Oceiros", "Soul of Consumed Oceiros", + DS3LocationCategory.SOUL, prominent = True, boss = True), # Could classify this as "hidden" because it's midway down an elevator, but the elevator is # so slow and the midway point is so obvious that it's not actually hard to find. - DS3LocationData("CKG: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), - DS3LocationData("CKG: Shadow Mask", "Shadow Mask", DS3LocationCategory.ARMOR), - DS3LocationData("CKG: Shadow Garb", "Shadow Garb", DS3LocationCategory.ARMOR), - DS3LocationData("CKG: Shadow Gauntlets", "Shadow Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("CKG: Shadow Leggings", "Shadow Leggings", DS3LocationCategory.ARMOR), - DS3LocationData("CKG: Black Firebomb", "Black Firebomb x2", DS3LocationCategory.MISC), - DS3LocationData("CKG: Claw", "Claw", DS3LocationCategory.WEAPON), - DS3LocationData("CKG: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("CKG: Dragonscale Ring", "Dragonscale Ring", DS3LocationCategory.RING), - DS3LocationData("CKG: Human Pine Resin #1", "Human Pine Resin", DS3LocationCategory.MISC), - DS3LocationData("CKG: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("CKG: Titanite Chunk #3", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("CKG: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("CKG: Dark Gem", "Dark Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("CKG: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("CKG: Human Pine Resin #2", "Human Pine Resin x2", DS3LocationCategory.MISC), - DS3LocationData("CKG: Titanite Chunk #4", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("CKG: Ring of Sacrifice", "Ring of Sacrifice", DS3LocationCategory.MISC), - DS3LocationData("CKG: Wood Grain Ring+1", "Wood Grain Ring+1", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("CKG: Sage Ring+2", "Sage Ring+2", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("CKG: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("CKG: Titanite Scale #3", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("CKG: Magic Stoneplate Ring", "Magic Stoneplate Ring", DS3LocationCategory.RING, - drop = True, hidden = True), # Guaranteed drop from a normal-looking Consumed King's Knight - DS3LocationData("CKG: Moonlight Greatsword", "Moonlight Greatsword", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("CKG: White Dragon Breath", "White Dragon Breath", DS3LocationCategory.SPELL, - missable = True, boss = True, shop = True), - DS3LocationData("CKG -> UG", None, DS3LocationCategory.EVENT), + DS3LocationData("CKG: Estus Shard (balcony)", "Estus Shard", DS3LocationCategory.HEALTH), + DS3LocationData("CKG: Shadow Mask (under center platform)", "Shadow Mask", + DS3LocationCategory.ARMOR), + DS3LocationData("CKG: Shadow Garb (under rotunda)", "Shadow Garb", + DS3LocationCategory.ARMOR), + DS3LocationData("CKG: Shadow Gauntlets (under rotunda)", "Shadow Gauntlets", + DS3LocationCategory.ARMOR), + DS3LocationData("CKG: Shadow Leggings (under rotunda)", "Shadow Leggings", + DS3LocationCategory.ARMOR), + DS3LocationData("CKG: Black Firebomb (under rotunda)", "Black Firebomb x2", + DS3LocationCategory.MISC), + DS3LocationData("CKG: Claw (under rotunda)", "Claw", DS3LocationCategory.WEAPON), + DS3LocationData("CKG: Titanite Chunk (up lone stairway)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("CKG: Dragonscale Ring (shortcut, leave halfway down lift)", + "Dragonscale Ring", DS3LocationCategory.RING), + DS3LocationData("CKG: Human Pine Resin (toxic pool, past rotunda)", "Human Pine Resin", + DS3LocationCategory.MISC), + DS3LocationData("CKG: Titanite Chunk (shortcut)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("CKG: Titanite Chunk (balcony, drop onto rubble)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("CKG: Soul of a Weary Warrior (before first lift)", + "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("CKG: Dark Gem (under lone stairway)", "Dark Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("CKG: Titanite Scale (shortcut)", "Titanite Scale", + DS3LocationCategory.UPGRADE), + DS3LocationData("CKG: Human Pine Resin (by lone stairway bottom)", + "Human Pine Resin x2", DS3LocationCategory.MISC), + DS3LocationData("CKG: Titanite Chunk (right of shortcut lift bottom)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("CKG: Ring of Sacrifice (under balcony)", "Ring of Sacrifice", + DS3LocationCategory.MISC), + DS3LocationData("CKG: Wood Grain Ring+1 (by first elevator bottom)", "Wood Grain Ring+1", + DS3LocationCategory.RING, ngp = True), + DS3LocationData("CKG: Sage Ring+2 (balcony, drop onto rubble, jump back)", "Sage Ring+2", + DS3LocationCategory.RING, ngp = True, hidden = True), + DS3LocationData("CKG: Titanite Scale (tomb, chest #1)", "Titanite Scale", + DS3LocationCategory.UPGRADE), + DS3LocationData("CKG: Titanite Scale (tomb, chest #2)", "Titanite Scale", + DS3LocationCategory.UPGRADE), + DS3LocationData("CKG: Magic Stoneplate Ring (mob drop before boss)", + "Magic Stoneplate Ring", DS3LocationCategory.RING, drop = True, + hidden = True), # Guaranteed drop from a normal-looking Cathedral Knight + DS3LocationData("CKG -> UG", None, DS3LocationCategory.EVENT), + + # After Oceiros's boss room, only once the Drakeblood summon in AP has been killed + DS3LocationData("CKG: Drakeblood Helm (tomb, after killing AP mausoleum NPC)", + "Drakeblood Helm", DS3LocationCategory.ARMOR, hostile_npc = True, + hidden = True), + DS3LocationData("CKG: Drakeblood Armor (tomb, after killing AP mausoleum NPC)", + "Drakeblood Armor", DS3LocationCategory.ARMOR, hostile_npc = True, + hidden = True), + DS3LocationData("CKG: Drakeblood Gauntlets (tomb, after killing AP mausoleum NPC)", + "Drakeblood Gauntlets", DS3LocationCategory.ARMOR, hostile_npc = True, + hidden = True), + DS3LocationData("CKG: Drakeblood Leggings (tomb, after killing AP mausoleum NPC)", + "Drakeblood Leggings", DS3LocationCategory.ARMOR, hostile_npc = True, + hidden = True), ], "Grand Archives": [ - # At the bottom of the shortcut elevator right outside the Twin Princes fight. Requires sending the elevator up to the top from the middle, and then riding the lower elevator down. - DS3LocationData("GA: Titanite Slab #1", "Titanite Slab", DS3LocationCategory.UPGRADE, - hidden = True), # Elevator secret - DS3LocationData("GA: Soul of the Twin Princes", "Soul of the Twin Princes", DS3LocationCategory.SOUL, + DS3LocationData("GA: Titanite Slab (final elevator secret)", "Titanite Slab", + DS3LocationCategory.UPGRADE, hidden = True), + DS3LocationData("GA: Soul of the Twin Princes", "Soul of the Twin Princes", + DS3LocationCategory.SOUL, boss = True), + DS3LocationData("GA: Cinders of a Lord - Lothric Prince", + "Cinders of a Lord - Lothric Prince", DS3LocationCategory.KEY, + offline = "09,0:50002040::", prominent = True, progression = True, boss = True), - DS3LocationData("GA: Cinders of a Lord - Lothric Prince", "Cinders of a Lord - Lothric Prince", DS3LocationCategory.KEY, - offline = "09,0:50002040::", prominent = True, progression = True, boss = True), - DS3LocationData("GA: Onikiri and Ubadachi", "Onikiri and Ubadachi", DS3LocationCategory.WEAPON, + DS3LocationData("GA: Onikiri and Ubadachi (outside 5F, NPC drop)", + "Onikiri and Ubadachi", DS3LocationCategory.WEAPON, hostile_npc = True), # Black Hand Kamui drop - DS3LocationData("GA: Golden Wing Crest Shield", "Golden Wing Crest Shield", DS3LocationCategory.SHIELD, + DS3LocationData("GA: Golden Wing Crest Shield (outside 5F, NPC drop)", + "Golden Wing Crest Shield", DS3LocationCategory.SHIELD, hostile_npc = True), # Lion Knight Albert drop - DS3LocationData("GA: Sage's Crystal Staff", "Sage's Crystal Staff", DS3LocationCategory.WEAPON, + DS3LocationData("GA: Sage's Crystal Staff (outside 5F, NPC drop)", + "Sage's Crystal Staff", DS3LocationCategory.WEAPON, hostile_npc = True), # Daughter of Crystal Kriemhild drop - DS3LocationData("GA: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("GA: Titanite Chunk #3", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Fleshbite Ring", "Fleshbite Ring", DS3LocationCategory.RING), - DS3LocationData("GA: Soul of a Crestfallen Knight #2", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("GA: Soul of a Nameless Soldier", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("GA: Crystal Chime", "Crystal Chime", DS3LocationCategory.WEAPON), - DS3LocationData("GA: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Estus Shard", "Estus Shard", DS3LocationCategory.HEALTH), - DS3LocationData("GA: Homeward Bone", "Homeward Bone x3", DS3LocationCategory.MISC), - DS3LocationData("GA: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE, - hidden = True), # Hidden fall - DS3LocationData("GA: Titanite Chunk #4", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Hollow Gem", "Hollow Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Titanite Scale #3", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Titanite Scale #4", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Titanite Scale #5", "Titanite Scale", DS3LocationCategory.UPGRADE, - hidden = True), # Hidden by a table - DS3LocationData("GA: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Large Soul of a Crestfallen Knight #1", "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("GA: Titanite Chunk #5", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Titanite Scale #6", "Titanite Scale x3", DS3LocationCategory.UPGRADE, - hidden = True), # Hidden fall - DS3LocationData("GA: Titanite Chunk #6", "Titanite Chunk", DS3LocationCategory.UPGRADE, - hidden = True), # Hidden fall - DS3LocationData("GA: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("GA: Titanite Chunk #7", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Ember", "Ember", DS3LocationCategory.MISC), - DS3LocationData("GA: Blessed Gem", "Blessed Gem", DS3LocationCategory.UPGRADE, - hidden = True), # Hidden fall - DS3LocationData("GA: Titanite Chunk #8", "Titanite Chunk x2", DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Large Soul of a Crestfallen Knight #2", "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("GA: Avelyn", "Avelyn", DS3LocationCategory.WEAPON, - hidden = True), # Hidden fall - DS3LocationData("GA: Titanite Chunk #9", "Titanite Chunk", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("GA: Hunter's Ring", "Hunter's Ring", DS3LocationCategory.RING, - hostile_npc = True), # Daughter of Crystal Kriemhild drop - DS3LocationData("GA: Divine Pillars of Light", "Divine Pillars of Light", DS3LocationCategory.SPELL, - hidden = True), # Hidden fall - DS3LocationData("GA: Power Within", "Power Within", DS3LocationCategory.SPELL, + DS3LocationData("GA: Titanite Chunk (1F, up right stairs)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Titanite Chunk (1F, path from wax pool)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Soul of a Crestfallen Knight (1F, loop left after drop)", + "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("GA: Titanite Chunk (1F, balcony)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Fleshbite Ring (up stairs from 4F)", "Fleshbite Ring", + DS3LocationCategory.RING), + DS3LocationData("GA: Soul of a Crestfallen Knight (path to dome)", + "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("GA: Soul of a Nameless Soldier (dark room)", "Soul of a Nameless Soldier", + DS3LocationCategory.SOUL), + DS3LocationData("GA: Crystal Chime (1F, path from wax pool)", "Crystal Chime", + DS3LocationCategory.WEAPON), + DS3LocationData("GA: Titanite Scale (dark room, upstairs)", "Titanite Scale", + DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Estus Shard (dome, far balcony)", "Estus Shard", + DS3LocationCategory.HEALTH), + DS3LocationData("GA: Homeward Bone (2F early balcony)", "Homeward Bone x3", + DS3LocationCategory.MISC), + DS3LocationData("GA: Titanite Scale (2F, titanite scale atop bookshelf)", "Titanite Scale", + DS3LocationCategory.UPGRADE, hidden = True), # Hidden fall + DS3LocationData("GA: Titanite Chunk (2F, by wax pool)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Hollow Gem (rooftops lower, in hall)", "Hollow Gem", + DS3LocationCategory.UPGRADE, hidden = True), # Hidden fall + DS3LocationData("GA: Titanite Scale (3F, corner up stairs)", "Titanite Scale", + DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Titanite Scale (1F, up stairs on bookshelf)", "Titanite Scale", + DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Titanite Scale (3F, by ladder to 2F late)", "Titanite Scale", + DS3LocationCategory.UPGRADE, hidden = True), # Hidden by a table + DS3LocationData("GA: Shriving Stone (2F late, by ladder from 3F)", "Shriving Stone", + DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Large Soul of a Crestfallen Knight (4F, back)", + "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("GA: Titanite Chunk (rooftopps, balcony)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Titanite Scale (rooftops lower, path to 2F)", "Titanite Scale x3", + DS3LocationCategory.UPGRADE, hidden = True), # Hidden fall + DS3LocationData("GA: Titanite Chunk (rooftops lower, ledge by buttress)", "Titanite Chunk", + DS3LocationCategory.UPGRADE, hidden = True), # Hidden fall + DS3LocationData("GA: Soul of a Weary Warrior (rooftops, by lizards)", + "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("GA: Titanite Chunk (rooftops, just before 5F)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Ember (5F, by entrance)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("GA: Blessed Gem (rafters)", "Blessed Gem", DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Titanite Chunk (5F, far balcony)", "Titanite Chunk x2", + DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Large Soul of a Crestfallen Knight (outside 5F)", + "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("GA: Avelyn (1F, drop from 3F onto bookshelves)", "Avelyn", + DS3LocationCategory.WEAPON, hidden = True), # Hidden fall + DS3LocationData("GA: Titanite Chunk (2F, right after dark room)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Hunter's Ring (dome, very top)", "Hunter's Ring", + DS3LocationCategory.RING), + DS3LocationData("GA: Divine Pillars of Light (cage above rafters)", + "Divine Pillars of Light", DS3LocationCategory.SPELL), + DS3LocationData("GA: Power Within (dark room, behind retractable bookshelf)", + "Power Within", DS3LocationCategory.SPELL, hidden = True), # Switch in darkened room - DS3LocationData("GA: Sage Ring+1", "Sage Ring+1", DS3LocationCategory.RING, - ngp = True, hidden = True), # Hidden fall - DS3LocationData("GA: Lingering Dragoncrest Ring+2", "Lingering Dragoncrest Ring+2", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("GA: Divine Blessing", "Divine Blessing", DS3LocationCategory.MISC, - hidden = True), # Hidden fall - DS3LocationData("GA: Twinkling Titanite #1", "Twinkling Titanite x3", DS3LocationCategory.UPGRADE, - hidden = True), # Hidden fall - DS3LocationData("GA: Witch's Locks", "Witch's Locks", DS3LocationCategory.WEAPON, + DS3LocationData("GA: Sage Ring+1 (rafters, second level down)", "Sage Ring+1", + DS3LocationCategory.RING, ngp = True), + DS3LocationData("GA: Lingering Dragoncrest Ring+2 (dome, room behind spire)", + "Lingering Dragoncrest Ring+2", DS3LocationCategory.RING, ngp = True), + DS3LocationData("GA: Divine Blessing (rafters, down lower level ladder)", "Divine Blessing", + DS3LocationCategory.MISC), + DS3LocationData("GA: Twinkling Titanite (rafters, down lower level ladder)", + "Twinkling Titanite x3", DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Witch's Locks (dark room, behind retractable bookshelf)", + "Witch's Locks", DS3LocationCategory.WEAPON, hidden = True), # Switch in darkened room - DS3LocationData("GA: Titanite Slab #2", "Titanite Slab", DS3LocationCategory.UPGRADE, - hidden = True), # Backtrack after flipping bridge switch - DS3LocationData("GA: Titanite Scale #7", "Titanite Scale x3", DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Soul Stream", "Soul Stream", DS3LocationCategory.SPELL, - hidden = True), # Behind illusory wall - DS3LocationData("GA: Scholar Ring", "Scholar Ring", DS3LocationCategory.RING), - DS3LocationData("GA: Undead Bone Shard", "Undead Bone Shard", DS3LocationCategory.HEALTH), - DS3LocationData("GA: Titanite Slab #3", "Titanite Slab", DS3LocationCategory.UPGRADE, - drop = True, hidden = True), # Guaranteed drop from killing all Winged Knights - DS3LocationData("GA: Outrider Knight Helm", "Outrider Knight Helm", DS3LocationCategory.ARMOR, - miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop - DS3LocationData("GA: Outrider Knight Armor", "Outrider Knight Armor", DS3LocationCategory.ARMOR, - miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop - DS3LocationData("GA: Outrider Knight Gauntlets", "Outrider Knight Gauntlets", DS3LocationCategory.ARMOR, + DS3LocationData("GA: Titanite Slab (1F, after pulling 2F switch)", "Titanite Slab", + DS3LocationCategory.UPGRADE, hidden = True), + DS3LocationData("GA: Titanite Scale (5F, chest by exit)", "Titanite Scale x3", + DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Soul Stream (3F, behind illusory wall)", "Soul Stream", + DS3LocationCategory.SPELL, hidden = True), # Behind illusory wall + DS3LocationData("GA: Scholar Ring (2F, between late and early)", "Scholar Ring", + DS3LocationCategory.RING), + DS3LocationData("GA: Undead Bone Shard (5F, by entrance)", "Undead Bone Shard", + DS3LocationCategory.HEALTH), + DS3LocationData("GA: Titanite Slab (dome, kill all mobs)", "Titanite Slab", + DS3LocationCategory.UPGRADE, drop = True, + hidden = True), # Guaranteed drop from killing all Winged Knights + DS3LocationData("GA: Outrider Knight Helm (3F, behind illusory wall, miniboss drop)", + "Outrider Knight Helm", DS3LocationCategory.ARMOR, miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop - DS3LocationData("GA: Outrider Knight Leggings", "Outrider Knight Leggings", DS3LocationCategory.ARMOR, - miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop - DS3LocationData("GA: Crystal Scroll", "Crystal Scroll", DS3LocationCategory.UNIQUE, - miniboss = True), # Crystal Sage drop - DS3LocationData("GA: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("GA: Chaos Gem", "Chaos Gem", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("GA: Twinkling Titanite #3", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("GA: Crystal Gem", "Crystal Gem", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("GA: Twinkling Titanite #4", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("GA: Titanite Scale #8", "Titanite Scale x2", DS3LocationCategory.UPGRADE, - hidden = True, lizard = True), # Hidden fall - DS3LocationData("GA: Twinkling Titanite #5", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("GA: Heavy Gem", "Heavy Gem", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("GA: Twinkling Titanite #6", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("GA: Sharp Gem", "Sharp Gem", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("GA: Twinkling Titanite #7", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("GA: Refined Gem", "Refined Gem", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("GA: Twinkling Titanite #8", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("GA: Lorian's Greatsword", "Lorian's Greatsword", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("GA: Lothric's Holy Sword", "Lothric's Holy Sword", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), + DS3LocationData("GA: Outrider Knight Armor (3F, behind illusory wall, miniboss drop)", + "Outrider Knight Armor", DS3LocationCategory.ARMOR, miniboss = True, + hidden = True), # Behind illusory wall, Outrider Knight drop + DS3LocationData("GA: Outrider Knight Gauntlets (3F, behind illusory wall, miniboss drop)", + "Outrider Knight Gauntlets", DS3LocationCategory.ARMOR, miniboss = True, + hidden = True), # Behind illusory wall, Outrider Knight drop + DS3LocationData("GA: Outrider Knight Leggings (3F, behind illusory wall, miniboss drop)", + "Outrider Knight Leggings", DS3LocationCategory.ARMOR, miniboss = True, + hidden = True), # Behind illusory wall, Outrider Knight drop + DS3LocationData("GA: Crystal Scroll (2F late, miniboss drop)", "Crystal Scroll", + DS3LocationCategory.UNIQUE, miniboss = True), # Crystal Sage drop + DS3LocationData("GA: Twinkling Titanite (dark room, lizard #1)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("GA: Chaos Gem (dark room, lizard)", "Chaos Gem", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("GA: Twinkling Titanite (1F, lizard by drop)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("GA: Crystal Gem (1F, lizard by drop)", "Crystal Gem", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("GA: Twinkling Titanite (2F, lizard by entrance)", "Twinkling Titanite x2", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("GA: Titanite Scale (1F, drop from 2F late onto bookshelves, lizard)", + "Titanite Scale x2", DS3LocationCategory.UPGRADE, lizard = True, + hidden = True), # Hidden fall + DS3LocationData("GA: Twinkling Titanite (rooftops, lizard #1)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("GA: Heavy Gem (rooftops, lizard)", "Heavy Gem", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("GA: Twinkling Titanite (rooftops, lizard #2)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("GA: Sharp Gem (rooftops, lizard)", "Sharp Gem", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("GA: Twinkling Titanite (up stairs from 4F, lizard)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("GA: Refined Gem (up stairs from 4F, lizard)", "Refined Gem", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("GA: Twinkling Titanite (dark room, lizard #2)", "Twinkling Titanite x2", + DS3LocationCategory.UPGRADE, lizard = True), # Shrine Handmaid after killing NPCs - DS3LocationData("GA: Faraam Helm", "Faraam Helm", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True, shop = True), - DS3LocationData("GA: Faraam Armor", "Faraam Armor", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True, shop = True), - DS3LocationData("GA: Faraam Gauntlets", "Faraam Gauntlets", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True, shop = True), - DS3LocationData("GA: Faraam Boots", "Faraam Boots", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True, shop = True), - DS3LocationData("GA: Black Hand Hat", "Black Hand Hat", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True, shop = True), - DS3LocationData("GA: Black Hand Armor", "Black Hand Armor", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True, shop = True), + DS3LocationData("FS: Faraam Helm (shop after killing GA NPC)", "Faraam Helm", + DS3LocationCategory.ARMOR, hidden = True, hostile_npc = True, shop = True), + DS3LocationData("GA: Faraam Armor (shop after killing GA NPC)", "Faraam Armor", + DS3LocationCategory.ARMOR, hidden = True, hostile_npc = True, shop = True), + DS3LocationData("GA: Faraam Gauntlets (shop after killing GA NPC)", "Faraam Gauntlets", + DS3LocationCategory.ARMOR, hidden = True, hostile_npc = True, shop = True), + DS3LocationData("GA: Faraam Boots (shop after killing GA NPC)", "Faraam Boots", + DS3LocationCategory.ARMOR, hidden = True, hostile_npc = True, shop = True), + DS3LocationData("GA: Black Hand Hat (shop after killing GA NPC)", "Black Hand Hat", + DS3LocationCategory.ARMOR, hidden = True, hostile_npc = True, shop = True), + DS3LocationData("GA: Black Hand Armor (shop after killing GA NPC)", "Black Hand Armor", + DS3LocationCategory.ARMOR, hidden = True, hostile_npc = True, shop = True), # Shrine Handmaid after killing Lothric, Younger Prince - DS3LocationData("GA: Lorian's Helm", "Lorian's Helm", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("GA: Lorian's Armor", "Lorian's Armor", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("GA: Lorian's Gauntlets", "Lorian's Gauntlets", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("GA: Lorian's Leggings", "Lorian's Leggings", DS3LocationCategory.ARMOR, - boss = True, shop = True), + DS3LocationData("FS: Lorian's Helm (shop after killing GA boss)", "Lorian's Helm", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Lorian's Armor (shop after killing GA boss)", "Lorian's Armor", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Lorian's Gauntlets (shop after killing GA boss)", "Lorian's Gauntlets", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Lorian's Leggings (shop after killing GA boss)", "Lorian's Leggings", + DS3LocationCategory.ARMOR, boss = True, shop = True), + + # Sirris quest completion + beat Twin Princes + DS3LocationData("FS: Sunless Talisman (Sirris, kill GA boss)", "Sunless Talisman", + DS3LocationCategory.WEAPON, missable = True, npc = True), + DS3LocationData("FS: Sunless Veil (shop, Sirris quest, kill GA boss)", "Sunless Veil", + DS3LocationCategory.ARMOR, missable = True, npc = True, shop = True), + DS3LocationData("FS: Sunless Armor (shop, Sirris quest, kill GA boss)", "Sunless Armor", + DS3LocationCategory.ARMOR, missable = True, npc = True, shop = True), + DS3LocationData("FS: Sunless Gauntlets (shop, Sirris quest, kill GA boss)", + "Sunless Gauntlets", DS3LocationCategory.ARMOR, missable = True, npc = True, + shop = True), + DS3LocationData("FS: Sunless Leggings (shop, Sirris quest, kill GA boss)", + "Sunless Leggings", DS3LocationCategory.ARMOR, missable = True, npc = True, + shop = True), ], - # The whole area is behind an illusory wall and thus marked hidden "Untended Graves": [ - DS3LocationData("UG: Soul of Champion Gundyr", "Soul of Champion Gundyr", DS3LocationCategory.SOUL, - prominent = True, boss = True, hidden = True), - DS3LocationData("UG: Priestess Ring", "Priestess Ring", DS3LocationCategory.RING, - hidden = True), - DS3LocationData("UG: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE, - hidden = True), - DS3LocationData("UG: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE, - hidden = True), - DS3LocationData("UG: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC, - hidden = True), - DS3LocationData("UG: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE, - hidden = True), - DS3LocationData("UG: Ashen Estus Ring", "Ashen Estus Ring", DS3LocationCategory.RING, - hidden = True), - DS3LocationData("UG: Black Knight Glaive", "Black Knight Glaive", DS3LocationCategory.WEAPON, - hidden = True), - DS3LocationData("UG: Hidden Blessing", "Hidden Blessing", DS3LocationCategory.MISC, - hidden = True), - DS3LocationData("UG: Eyes of a Fire Keeper", "Eyes of a Fire Keeper", DS3LocationCategory.KEY, - hidden = True), - DS3LocationData("UG: Soul of a Crestfallen Knight #2", "Soul of a Crestfallen Knight", DS3LocationCategory.MISC, - hidden = True), - DS3LocationData("UG: Blacksmith Hammer", "Blacksmith Hammer", DS3LocationCategory.WEAPON, - hidden = True), - DS3LocationData("UG: Chaos Blade", "Chaos Blade", DS3LocationCategory.WEAPON, - hidden = True), - DS3LocationData("UG: Coiled Sword Fragment", "Coiled Sword Fragment", DS3LocationCategory.UNIQUE, - boss = True, hidden = True), - DS3LocationData("UG: Life Ring+3", "Life Ring+3", DS3LocationCategory.RING, - ngp = True, hidden = True), - DS3LocationData("UG: Ring of Steel Protection+1", "Ring of Steel Protection+1", DS3LocationCategory.RING, - ngp = True, hidden = True), - DS3LocationData("UG: Hornet Ring", "Hornet Ring", DS3LocationCategory.RING, - hidden = True, conditional = True), - DS3LocationData("UG: Gundyr's Halberd", "Gundyr's Halberd", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("UG: Prisoner's Chain", "Prisoner's Chain", DS3LocationCategory.RING, - missable = True, boss = True, shop = True), + DS3LocationData("UG: Soul of Champion Gundyr", "Soul of Champion Gundyr", + DS3LocationCategory.SOUL, prominent = True, boss = True), + DS3LocationData("UG: Priestess Ring (shop)", "Priestess Ring", DS3LocationCategory.RING, + shop = True), + DS3LocationData("UG: Shriving Stone (swamp, by bonfire)", "Shriving Stone", + DS3LocationCategory.UPGRADE), + DS3LocationData("UG: Titanite Chunk (swamp, left path by fountain)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("UG: Soul of a Crestfallen Knight (swamp, center)", + "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("UG: Titanite Chunk (swamp, right path by fountain)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("UG: Ashen Estus Ring (swamp, path opposite bonfire)", "Ashen Estus Ring", + DS3LocationCategory.RING), + DS3LocationData("UG: Black Knight Glaive (boss arena)", "Black Knight Glaive", + DS3LocationCategory.WEAPON), + DS3LocationData("UG: Hidden Blessing (cemetery, behind coffin)", "Hidden Blessing", + DS3LocationCategory.MISC), + DS3LocationData("UG: Eyes of a Fire Keeper (shrine, Irina's room)", "Eyes of a Fire Keeper", + DS3LocationCategory.KEY, hidden = True), # Illusory wall + DS3LocationData("UG: Soul of a Crestfallen Knight (environs, above shrine entrance)", + "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), + DS3LocationData("UG: Blacksmith Hammer (shrine, Andre's room)", "Blacksmith Hammer", + DS3LocationCategory.WEAPON), + DS3LocationData("UG: Chaos Blade (environs, left of shrine)", "Chaos Blade", + DS3LocationCategory.WEAPON), + DS3LocationData("UG: Hornet Ring (environs, right of main path)", + "Hornet Ring", DS3LocationCategory.RING, conditional = True), + DS3LocationData("UG: Coiled Sword Fragment (shrine, dead bonfire)", "Coiled Sword Fragment", + DS3LocationCategory.UNIQUE, boss = True), + DS3LocationData("UG: Life Ring+3 (shrine, behind big throne)", "Life Ring+3", + DS3LocationCategory.RING, ngp = True), + DS3LocationData("UG: Ring of Steel Protection+1 (environs, behind bell tower)", + "Ring of Steel Protection+1", DS3LocationCategory.RING, ngp = True), # Yuria shop, or Shrine Handmaiden with Hollow's Ashes # This is here because this is where the ashes end up if you kill Yoel or Yuria - DS3LocationData("UG: Ring of Sacrifice", "Ring of Sacrifice", DS3LocationCategory.MISC, - offline = '99,0:-1:40000,110000,70000107,70000116:', hidden = True, npc = True, shop = True), + DS3LocationData("FS: Ring of Sacrifice (Yuria shop)", "Ring of Sacrifice", + DS3LocationCategory.MISC, + offline = '99,0:-1:40000,110000,70000107,70000116:', npc = True, + shop = True), # Untended Graves Handmaid - DS3LocationData("UG: Ember", "Ember", DS3LocationCategory.RING, - hidden = True, shop = True), + # All shop items are missable because she can be killed, except Priestess ring because she + # drops it on death anyway. + DS3LocationData("UG: Ember (shop)", "Ember", DS3LocationCategory.RING, shop = True, + missable = True), # Untended Graves Handmaid after killing Abyss Watchers - DS3LocationData("UG: Wolf Knight Helm", "Wolf Knight Helm", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("UG: Wolf Knight Armor", "Wolf Knight Armor", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("UG: Wolf Knight Gauntlets", "Wolf Knight Gauntlets", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("UG: Wolf Knight Leggings", "Wolf Knight Leggings", DS3LocationCategory.ARMOR, - boss = True, shop = True), + DS3LocationData("UG: Wolf Knight Helm (shop after killing FK boss)", "Wolf Knight Helm", + DS3LocationCategory.ARMOR, boss = True, shop = True, conditional = True, + missable = True), + DS3LocationData("UG: Wolf Knight Armor (shop after killing FK boss)", + "Wolf Knight Armor", DS3LocationCategory.ARMOR, boss = True, shop = True, + missable = True), + DS3LocationData("UG: Wolf Knight Gauntlets (shop after killing FK boss)", + "Wolf Knight Gauntlets", DS3LocationCategory.ARMOR, boss = True, + shop = True, missable = True), + DS3LocationData("UG: Wolf Knight Leggings (shop after killing FK boss)", + "Wolf Knight Leggings", DS3LocationCategory.ARMOR, boss = True, shop = True, + missable = True), # Shrine Handmaid after killing Champion Gundyr - DS3LocationData("UG: Gundyr's Helm", "Gundyr's Helm", DS3LocationCategory.ARMOR, - hidden = True, boss = True, shop = True), - DS3LocationData("UG: Gundyr's Armor", "Gundyr's Armor", DS3LocationCategory.ARMOR, - hidden = True, boss = True, shop = True), - DS3LocationData("UG: Gundyr's Gauntlets", "Gundyr's Gauntlets", DS3LocationCategory.ARMOR, - hidden = True, boss = True, shop = True), - DS3LocationData("UG: Gundyr's Leggings", "Gundyr's Leggings", DS3LocationCategory.ARMOR, - hidden = True, boss = True, shop = True), + DS3LocationData("FS: Gundyr's Helm (shop after killing UG boss)", "Gundyr's Helm", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Gundyr's Armor (shop after killing UG boss)", "Gundyr's Armor", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Gundyr's Gauntlets (shop after killing UG boss)", "Gundyr's Gauntlets", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Gundyr's Leggings (shop after killing UG boss)", "Gundyr's Leggings", + DS3LocationCategory.ARMOR, boss = True, shop = True), ], "Archdragon Peak": [ - DS3LocationData("AP: Dragon Head Stone", "Dragon Head Stone", DS3LocationCategory.UNIQUE, - prominent = True, boss = True), - DS3LocationData("AP: Soul of the Nameless King", "Soul of the Nameless King", DS3LocationCategory.SOUL, - prominent = True, boss = True), - DS3LocationData("AP: Dragon Tooth", "Dragon Tooth", DS3LocationCategory.WEAPON, - hostile_npc = True), # Havel Knight drop - DS3LocationData("AP: Havel's Greatshield", "Havel's Greatshield", DS3LocationCategory.SHIELD, - hostile_npc = True), # Havel Knight drop - DS3LocationData("AP: Drakeblood Greatsword", "Drakeblood Greatsword", DS3LocationCategory.WEAPON, - hostile_npc = True, hidden = True), # Drop from a summon who may or may not appear - DS3LocationData("AP: Ricard's Rapier", "Ricard's Rapier", DS3LocationCategory.WEAPON, - hostile_npc = True, hidden = True), # Drop from a summon who may or may not appear - DS3LocationData("AP: Lightning Clutch Ring", "Lightning Clutch Ring", DS3LocationCategory.RING), - DS3LocationData("AP: Stalk Dung Pie", "Stalk Dung Pie x6", DS3LocationCategory.MISC), - DS3LocationData("AP: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Soul of a Weary Warrior #1", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("AP: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Lightning Gem", "Lightning Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC), - DS3LocationData("AP: Soul of a Nameless Soldier", "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("AP: Titanite Chunk #3", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("AP: Large Soul of a Weary Warrior", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("AP: Large Soul of a Nameless Soldier", "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("AP: Lightning Urn", "Lightning Urn x4", DS3LocationCategory.MISC), - DS3LocationData("AP: Lightning Bolt", "Lightning Bolt x12", DS3LocationCategory.MISC), - DS3LocationData("AP: Titanite Chunk #4", "Titanite Chunk x2", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Dung Pie", "Dung Pie x3", DS3LocationCategory.MISC), - DS3LocationData("AP: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Soul of a Weary Warrior #2", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("AP: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("AP: Titanite Chunk #5", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("AP: Thunder Stoneplate Ring", "Thunder Stoneplate Ring", DS3LocationCategory.RING), - DS3LocationData("AP: Titanite Scale #3", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Ember #3", "Ember", DS3LocationCategory.MISC), - DS3LocationData("AP: Ancient Dragon Greatshield", "Ancient Dragon Greatshield", DS3LocationCategory.SHIELD), - DS3LocationData("AP: Large Soul of a Crestfallen Knight", "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("AP: Dragon Chaser's Ashes", "Dragon Chaser's Ashes", DS3LocationCategory.KEY, - progression = True), - DS3LocationData("AP: Ember #4", "Ember", DS3LocationCategory.MISC), - DS3LocationData("AP: Dragonslayer Spear", "Dragonslayer Spear", DS3LocationCategory.WEAPON), - DS3LocationData("AP: Dragonslayer Helm", "Dragonslayer Helm", DS3LocationCategory.ARMOR), - DS3LocationData("AP: Dragonslayer Armor", "Dragonslayer Armor", DS3LocationCategory.ARMOR), - DS3LocationData("AP: Dragonslayer Gauntlets", "Dragonslayer Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("AP: Dragonslayer Leggings", "Dragonslayer Leggings", DS3LocationCategory.ARMOR), - DS3LocationData("AP: Twinkling Titanite #1", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Twinkling Titanite #2", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Titanite Slab #1", "Titanite Slab", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Great Magic Barrier", "Great Magic Barrier", DS3LocationCategory.SPELL, - hidden = True), # Hidden fall - DS3LocationData("AP: Titanite Slab #2", "Titanite Slab", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Ring of Steel Protection", "Ring of Steel Protection", DS3LocationCategory.RING), - DS3LocationData("AP: Havel's Ring+1", "Havel's Ring+1", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("AP: Covetous Gold Serpent Ring+2", "Covetous Gold Serpent Ring+2", DS3LocationCategory.RING, - ngp = True), - DS3LocationData("AP: Titanite Scale #4", "Titanite Scale x3", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Twinkling Titanite #3", "Twinkling Titanite x3", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Twinkling Dragon Torso Stone", "Twinkling Dragon Torso Stone", DS3LocationCategory.MISC, - hidden = True), # Requires gesture - DS3LocationData("AP: Calamity Ring", "Calamity Ring", DS3LocationCategory.RING, + DS3LocationData("AP: Dragon Head Stone (fort, boss drop)", "Dragon Head Stone", + DS3LocationCategory.UNIQUE, prominent = True, boss = True), + DS3LocationData("AP: Soul of the Nameless King", "Soul of the Nameless King", + DS3LocationCategory.SOUL, prominent = True, boss = True), + DS3LocationData("AP: Dragon Tooth (belfry roof, NPC drop)", "Dragon Tooth", + DS3LocationCategory.WEAPON, hostile_npc = True), # Havel Knight drop + DS3LocationData("AP: Havel's Greatshield (belfry roof, NPC drop)", "Havel's Greatshield", + DS3LocationCategory.SHIELD, hostile_npc = True), # Havel Knight drop + DS3LocationData("AP: Drakeblood Greatsword (mausoleum, NPC drop)", "Drakeblood Greatsword", + DS3LocationCategory.WEAPON, hostile_npc = True), + DS3LocationData("AP: Ricard's Rapier (belfry, NPC drop)", "Ricard's Rapier", + DS3LocationCategory.WEAPON, hostile_npc = True), + DS3LocationData("AP: Lightning Clutch Ring (intro, left of boss door)", + "Lightning Clutch Ring", DS3LocationCategory.RING), + DS3LocationData("AP: Stalk Dung Pie (fort overlook)", "Stalk Dung Pie x6", + DS3LocationCategory.MISC), + DS3LocationData("AP: Titanite Chunk (fort, second room balcony)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Titanite Scale (mausoleum, downstairs balcony #1)", + "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Soul of a Weary Warrior (intro, first cliff edge)", + "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("AP: Titanite Chunk (intro, left before archway)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Lightning Gem (intro, side rise)", "Lightning Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Homeward Bone (intro, path to bonfire)", "Homeward Bone x2", + DS3LocationCategory.MISC), + DS3LocationData("AP: Soul of a Nameless Soldier (intro, right before archway)", + "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("AP: Titanite Chunk (intro, archway corner)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Ember (fort overlook #2)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("AP: Large Soul of a Weary Warrior (fort, center)", + "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("AP: Large Soul of a Nameless Soldier (fort, by stairs to first room)", + "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + DS3LocationData("AP: Lightning Urn (fort, left of first room entrance)", + "Lightning Urn x4", DS3LocationCategory.MISC), + DS3LocationData("AP: Lightning Bolt (rotunda)", "Lightning Bolt x12", + DS3LocationCategory.MISC), + DS3LocationData("AP: Titanite Chunk (rotunda)", "Titanite Chunk x2", + DS3LocationCategory.UPGRADE), + # Not 100% sure about this location name, can't find this on any maps + DS3LocationData("AP: Dung Pie (fort, landing after second room)", "Dung Pie x3", + DS3LocationCategory.MISC), + DS3LocationData("AP: Titanite Scale (mausoleum, downstairs balcony #2)", + "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Soul of a Weary Warrior (walkway, building window)", + "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("AP: Soul of a Crestfallen Knight (mausoleum, upstairs)", + "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("AP: Titanite Chunk (intro, behind rock)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Ember (fort overlook #2)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("AP: Thunder Stoneplate Ring (walkway, up ladder)", + "Thunder Stoneplate Ring", DS3LocationCategory.RING), + DS3LocationData("AP: Titanite Scale (mausoleum, upstairs balcony)", "Titanite Scale", + DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Ember (belfry, below bell)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("AP: Ancient Dragon Greatshield (intro, on archway)", + "Ancient Dragon Greatshield", DS3LocationCategory.SHIELD), + DS3LocationData("AP: Large Soul of a Crestfallen Knight (summit, by fountain)", + "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("AP: Dragon Chaser's Ashes (summit, side path)", "Dragon Chaser's Ashes", + DS3LocationCategory.KEY, progression = True), + DS3LocationData("AP: Ember (intro, by bonfire)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("AP: Dragonslayer Spear (gate after mausoleum)", "Dragonslayer Spear", + DS3LocationCategory.WEAPON), + DS3LocationData("AP: Dragonslayer Helm (plaza)", "Dragonslayer Helm", + DS3LocationCategory.ARMOR), + DS3LocationData("AP: Dragonslayer Armor (plaza)", "Dragonslayer Armor", + DS3LocationCategory.ARMOR), + DS3LocationData("AP: Dragonslayer Gauntlets (plaza)", "Dragonslayer Gauntlets", + DS3LocationCategory.ARMOR), + DS3LocationData("AP: Dragonslayer Leggings (plaza)", "Dragonslayer Leggings", + DS3LocationCategory.ARMOR), + DS3LocationData("AP: Twinkling Titanite (fort, end of rafters)", "Twinkling Titanite x2", + DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Twinkling Titanite (fort, down second room balcony ladder)", + "Twinkling Titanite x2", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Titanite Slab (belfry roof)", "Titanite Slab", + DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Great Magic Barrier (drop off belfry roof)", "Great Magic Barrier", + DS3LocationCategory.SPELL, hidden = True), # Hidden fall + DS3LocationData("AP: Titanite Slab (plaza)", "Titanite Slab", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Ring of Steel Protection (fort overlook, beside stairs)", + "Ring of Steel Protection", DS3LocationCategory.RING), + DS3LocationData("AP: Havel's Ring+1 (summit, after building)", "Havel's Ring+1", + DS3LocationCategory.RING, ngp = True), + DS3LocationData("AP: Covetous Gold Serpent Ring+2 (plaza)", "Covetous Gold Serpent Ring+2", + DS3LocationCategory.RING, ngp = True), + DS3LocationData("AP: Titanite Scale (walkway building)", "Titanite Scale x3", + DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Twinkling Titanite (belfry, by ladder to roof)", + "Twinkling Titanite x3", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Twinkling Dragon Torso Stone (summit, gesture at altar)", + "Twinkling Dragon Torso Stone", DS3LocationCategory.MISC, hidden = True), # Requires gesture - DS3LocationData("AP: Twinkling Titanite #4", "Twinkling Titanite x3", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("AP: Titanite Chunk #6", "Titanite Chunk x6", DS3LocationCategory.UPGRADE, - miniboss = True), # Wyvern miniboss drop - DS3LocationData("AP: Titanite Scale #5", "Titanite Scale x3", DS3LocationCategory.UPGRADE, - miniboss = True), # Wyvern miniboss drop - DS3LocationData("AP: Twinkling Titanite #5", "Twinkling Titanite x3", DS3LocationCategory.UPGRADE, - miniboss = True), # Wyvern miniboss drop - DS3LocationData("AP: Hawkwood's Swordgrass", "Hawkwood's Swordgrass", DS3LocationCategory.UNIQUE, + DS3LocationData("AP: Calamity Ring (mausoleum, gesture at altar)", "Calamity Ring", + DS3LocationCategory.RING, hidden = True), # Requires gesture + DS3LocationData("AP: Twinkling Titanite (walkway building, lizard)", + "Twinkling Titanite x3", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("AP: Titanite Chunk (walkway, miniboss drop)", "Titanite Chunk x6", + DS3LocationCategory.UPGRADE, miniboss = True), # Wyvern miniboss drop + DS3LocationData("AP: Titanite Scale (walkway, miniboss drop)", "Titanite Scale x3", + DS3LocationCategory.UPGRADE, miniboss = True), # Wyvern miniboss drop + DS3LocationData("AP: Twinkling Titanite (walkway, miniboss drop)", "Twinkling Titanite x3", + DS3LocationCategory.UPGRADE, miniboss = True), # Wyvern miniboss drop + DS3LocationData("FS: Hawkwood's Swordgrass (Andre after gesture in AP summit)", + "Hawkwood's Swordgrass", DS3LocationCategory.UNIQUE, conditional = True, hidden = True), - DS3LocationData("AP: Storm Curved Sword", "Storm Curved Sword", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("AP: Dragonslayer Swordspear", "Dragonslayer Swordspear", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("AP: Lightning Storm", "Lightning Storm", DS3LocationCategory.SPELL, - missable = True, boss = True, shop = True), # Shrine Handmaid after killing Nameless King - DS3LocationData("AP: Golden Crown", "Golden Crown", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("AP: Dragonscale Armor", "Dragonscale Armor", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("AP: Golden Bracelets", "Golden Bracelets", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("AP: Dragonscale Waistcloth", "Dragonscale Waistcloth", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("AP: Twinkling Dragon Head Stone", "Twinkling Dragon Head Stone", DS3LocationCategory.UNIQUE, - missable = True, npc = True), # Hawkwood (quest) - - # After Oceiros's boss room, only once the Drakeblood summon in AP has been killed - DS3LocationData("AP: Drakeblood Helm", "Drakeblood Helm", DS3LocationCategory.ARMOR, - missable = True, hostile_npc = True), - DS3LocationData("AP: Drakeblood Armor", "Drakeblood Armor", DS3LocationCategory.ARMOR, - missable = True, hostile_npc = True), - DS3LocationData("AP: Drakeblood Gauntlets", "Drakeblood Gauntlets", DS3LocationCategory.ARMOR, - missable = True, hostile_npc = True), - DS3LocationData("AP: Drakeblood Leggings", "Drakeblood Leggings", DS3LocationCategory.ARMOR, - missable = True, hostile_npc = True), - - # Appears by Stray Demon after killing Havel Knight - DS3LocationData("AP: Havel's Helm", "Havel's Helm", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True), - DS3LocationData("AP: Havel's Armor", "Havel's Armor", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True), - DS3LocationData("AP: Havel's Gauntlets", "Havel's Gauntlets", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True), - DS3LocationData("AP: Havel's Leggings", "Havel's Leggings", DS3LocationCategory.ARMOR, - hidden = True, hostile_npc = True), + DS3LocationData("FS: Golden Crown (shop after killing AP boss)", "Golden Crown", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Dragonscale Armor (shop after killing AP boss)", "Dragonscale Armor", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Golden Bracelets (shop after killing AP boss)", "Golden Bracelets", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Dragonscale Waistcloth (shop after killing AP boss)", + "Dragonscale Waistcloth", DS3LocationCategory.ARMOR, boss = True, + shop = True), + DS3LocationData("FK: Twinkling Dragon Head Stone (Hawkwood drop)", + "Twinkling Dragon Head Stone", DS3LocationCategory.UNIQUE, missable = True, + npc = True), # Hawkwood (quest) ], "Kiln of the First Flame": [ - DS3LocationData("KFF: Firelink Greatsword", "Firelink Greatsword", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("KFF: Sunlight Spear", "Sunlight Spear", DS3LocationCategory.SPELL, - missable = True, boss = True, shop = True), + DS3LocationData("KFF: Soul of the Lords", "Soul of the Lords", DS3LocationCategory.SOUL, + boss = True), # Shrine Handmaid after placing all Cinders of a Lord - DS3LocationData("KFF: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE, - offline = '99,0:-1:9210,110000:', hidden = True), - DS3LocationData("KFF: Firelink Helm", "Firelink Helm", DS3LocationCategory.ARMOR, - missable = True), - DS3LocationData("KFF: Firelink Armor", "Firelink Armor", DS3LocationCategory.ARMOR, - missable = True), - DS3LocationData("KFF: Firelink Gauntlets", "Firelink Gauntlets", DS3LocationCategory.ARMOR, - missable = True), - DS3LocationData("KFF: Firelink Leggings", "Firelink Leggings", DS3LocationCategory.ARMOR, - missable = True), + DS3LocationData("FS: Titanite Slab (shop after placing all Cinders)", "Titanite Slab", + DS3LocationCategory.UPGRADE, offline = '99,0:-1:9210,110000:', + hidden = True), + DS3LocationData("FS: Firelink Helm (shop after placing all Cinders)", "Firelink Helm", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Firelink Armor (shop after placing all Cinders)", "Firelink Armor", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Firelink Gauntlets (shop after placing all Cinders)", + "Firelink Gauntlets", DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Firelink Leggings (shop after placing all Cinders)", + "Firelink Leggings", DS3LocationCategory.ARMOR, boss = True, shop = True), # Yuria (quest, after Soul of Cinder) - DS3LocationData("KFF: Billed Mask", "Billed Mask", DS3LocationCategory.ARMOR, - missable = True, npc = True), - DS3LocationData("KFF: Black Dress", "Black Dress", DS3LocationCategory.ARMOR, - missable = True, npc = True), - DS3LocationData("KFF: Black Gauntlets", "Black Gauntlets", DS3LocationCategory.ARMOR, - missable = True, npc = True), - DS3LocationData("KFF: Black Leggings", "Black Leggings", DS3LocationCategory.ARMOR, - missable = True, npc = True), + DS3LocationData("FS: Billed Mask (Yuria after killing KFF boss)", "Billed Mask", + DS3LocationCategory.ARMOR, missable = True, npc = True), + DS3LocationData("FS: Black Dress (Yuria after killing KFF boss)", "Black Dress", + DS3LocationCategory.ARMOR, missable = True, npc = True), + DS3LocationData("FS: Black Gauntlets (Yuria after killing KFF boss)", "Black Gauntlets", + DS3LocationCategory.ARMOR, missable = True, npc = True), + DS3LocationData("FS: Black Leggings (Yuria after killing KFF boss)", "Black Leggings", + DS3LocationCategory.ARMOR, missable = True, npc = True), ], # DLC "Painted World of Ariandel (Before Contraption)": [ - DS3LocationData("PW1: Valorheart", "Valorheart", DS3LocationCategory.WEAPON, - prominent = True, boss = True), - DS3LocationData("PW1: Contraption Key", "Contraption Key", DS3LocationCategory.KEY, - prominent = True, progression = True, hostile_npc = True, key = True), # Sir Vilhelm drop - DS3LocationData("PW1: Onyx Blade", "Onyx Blade", DS3LocationCategory.WEAPON, - hostile_npc = True), # Sir Vilhelm drop - DS3LocationData("PW: Chillbite Ring", "Chillbite Ring", DS3LocationCategory.RING, - npc = True), # Friede conversation - DS3LocationData("PW1: Rime-blue Moss Clump #1", "Rime-blue Moss Clump x2", DS3LocationCategory.MISC), - DS3LocationData("PW1: Poison Gem", "Poison Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #1", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Follower Javelin", "Follower Javelin", DS3LocationCategory.WEAPON), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #2", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Homeward Bone #1", "Homeward Bone x6", DS3LocationCategory.MISC), - DS3LocationData("PW1: Blessed Gem", "Blessed Gem", DS3LocationCategory.UPGRADE, - hidden = True), # Hidden behind a tower - DS3LocationData("PW1: Captain's Ashes", "Captain's Ashes", DS3LocationCategory.KEY, - progression = True), - DS3LocationData("PW1: Black Firebomb", "Black Firebomb x2", DS3LocationCategory.MISC), - DS3LocationData("PW1: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), - DS3LocationData("PW1: Millwood Greatarrow", "Millwood Greatarrow x5", DS3LocationCategory.MISC), - DS3LocationData("PW1: Millwood Greatbow", "Millwood Greatbow", DS3LocationCategory.WEAPON), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #3", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Rusted Coin #1", "Rusted Coin", DS3LocationCategory.MISC), - DS3LocationData("PW1: Large Titanite Shard #1", "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #4", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Crow Quills", "Crow Quills", DS3LocationCategory.WEAPON, - hidden = True), # Hidden fall - DS3LocationData("PW1: Simple Gem", "Simple Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #5", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Slave Knight Hood", "Slave Knight Hood", DS3LocationCategory.ARMOR), - DS3LocationData("PW1: Slave Knight Armor", "Slave Knight Armor", DS3LocationCategory.ARMOR), - DS3LocationData("PW1: Slave Knight Gauntlets", "Slave Knight Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("PW1: Slave Knight Leggings", "Slave Knight Leggings", DS3LocationCategory.ARMOR), - DS3LocationData("PW1: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("PW1: Dark Gem", "Dark Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #6", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #7", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Rusted Gold Coin", "Rusted Gold Coin x3", DS3LocationCategory.MISC), - DS3LocationData("PW1: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Way of White Corona", "Way of White Corona", DS3LocationCategory.SPELL), - DS3LocationData("PW1: Rusted Coin #2", "Rusted Coin x2", DS3LocationCategory.MISC), - DS3LocationData("PW1: Young White Branch", "Young White Branch", DS3LocationCategory.MISC), - DS3LocationData("PW1: Budding Green Blossom", "Budding Green Blossom x3", DS3LocationCategory.MISC), - DS3LocationData("PW1: Crow Talons", "Crow Talons", DS3LocationCategory.WEAPON), - DS3LocationData("PW1: Blood Gem", "Blood Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("PW1: Hollow Gem", "Hollow Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("PW1: Rime-blue Moss Clump #2", "Rime-blue Moss Clump x4", DS3LocationCategory.MISC), - DS3LocationData("PW1: Follower Sabre", "Follower Sabre", DS3LocationCategory.WEAPON), - DS3LocationData("PW1: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("PW1: Snap Freeze", "Snap Freeze", DS3LocationCategory.SPELL, - drop = True, hidden = True), # Guaranteed drop from normal-looking Tree Woman - DS3LocationData("PW1: Rime-blue Moss Clump #3", "Rime-blue Moss Clump", DS3LocationCategory.MISC), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #8", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Ember #3", "Ember", DS3LocationCategory.MISC), - DS3LocationData("PW1: Frozen Weapon", "Frozen Weapon", DS3LocationCategory.SPELL), - DS3LocationData("PW1: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE, - offline = '11,0:50004700::', hidden = True), # Must kill normal-looking Tree Woman - DS3LocationData("PW1: Homeward Bone #2", "Homeward Bone x2", DS3LocationCategory.MISC), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #9", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Large Soul of a Weary Warrior #1", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Large Soul of an Unknown Traveler #10", "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Heavy Gem", "Heavy Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("PW1: Large Soul of a Weary Warrior #2", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Millwood Battle Axe", "Millwood Battle Axe", DS3LocationCategory.WEAPON), - DS3LocationData("PW1: Ethereal Oak Shield", "Ethereal Oak Shield", DS3LocationCategory.SHIELD), - DS3LocationData("PW1: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("PW1: Large Titanite Shard #2", "Large Titanite Shard", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("PW1: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("PW1: Twinkling Titanite #3", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("PW1: Large Titanite Shard #3", "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("PW1: Champion's Bones", "Champion's Bones", DS3LocationCategory.UNIQUE, - offline = '11,0:50002310::', boss = True), + DS3LocationData("PW1: Valorheart (boss drop)", "Valorheart", + DS3LocationCategory.WEAPON, prominent = True, boss = True), + DS3LocationData("PW1: Contraption Key (library, NPC drop)", "Contraption Key", + DS3LocationCategory.KEY, prominent = True, progression = True, + hostile_npc = True, key = True), # Sir Vilhelm drop + DS3LocationData("PW1: Onyx Blade (library, NPC drop)", "Onyx Blade", + DS3LocationCategory.WEAPON, hostile_npc = True), # Sir Vilhelm drop + DS3LocationData("PW1: Chillbite Ring (Friede)", "Chillbite Ring", + DS3LocationCategory.RING, npc = True), # Friede conversation + DS3LocationData("PW1: Rime-blue Moss Clump (snowfield upper, starting cave)", + "Rime-blue Moss Clump x2", DS3LocationCategory.MISC), + DS3LocationData("PW1: Poison Gem (snowfield upper, forward from bonfire)", "Poison Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("PW1: Large Soul of an Unknown Traveler (snowfield lower, path back up)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("PW1: Follower Javelin (snowfield lower, path back up)", "Follower Javelin", + DS3LocationCategory.WEAPON), + DS3LocationData("PW1: Large Soul of an Unknown Traveler (snowfield lower, path to village)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("PW1: Homeward Bone (snowfield village, outcropping)", "Homeward Bone x6", + DS3LocationCategory.MISC), + DS3LocationData("PW1: Blessed Gem (snowfield, behind tower)", "Blessed Gem", + DS3LocationCategory.UPGRADE, hidden = True), # Hidden behind a tower + DS3LocationData("PW1: Captain's Ashes (snowfield tower, 6F)", "Captain's Ashes", + DS3LocationCategory.KEY, progression = True), + DS3LocationData("PW1: Black Firebomb (snowfield lower, path to bridge)", + "Black Firebomb x2", DS3LocationCategory.MISC), + DS3LocationData("PW1: Shriving Stone (below bridge near)", "Shriving Stone", + DS3LocationCategory.UPGRADE), + DS3LocationData("PW1: Millwood Greatarrow (snowfield village, loop back to lower)", + "Millwood Greatarrow x5", DS3LocationCategory.MISC), + DS3LocationData("PW1: Millwood Greatbow (snowfield village, loop back to lower)", + "Millwood Greatbow", DS3LocationCategory.WEAPON), + DS3LocationData("PW1: Large Soul of an Unknown Traveler (snowfield upper)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("PW1: Rusted Coin (snowfield lower, straight from fall)", "Rusted Coin", + DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Titanite Shard (snowfield lower, left from fall)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE), + DS3LocationData("PW1: Large Soul of an Unknown Traveler (settlement courtyard, cliff)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("PW1: Crow Quills (settlement loop, jump into courtyard)", "Crow Quills", + DS3LocationCategory.WEAPON, hidden = True), # Hidden fall + DS3LocationData("PW1: Simple Gem (settlement, lowest level, behind gate)", "Simple Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("PW1: Large Soul of an Unknown Traveler (settlement, by ladder to bonfire)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("PW1: Slave Knight Hood (settlement roofs, drop by ladder)", + "Slave Knight Hood", DS3LocationCategory.ARMOR), + DS3LocationData("PW1: Slave Knight Armor (settlement roofs, drop by ladder)", + "Slave Knight Armor", DS3LocationCategory.ARMOR), + DS3LocationData("PW1: Slave Knight Gauntlets (settlement roofs, drop by ladder)", + "Slave Knight Gauntlets", DS3LocationCategory.ARMOR), + DS3LocationData("PW1: Slave Knight Leggings (settlement roofs, drop by ladder)", + "Slave Knight Leggings", DS3LocationCategory.ARMOR), + DS3LocationData("PW1: Ember (settlement main, left building after bridge)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("PW1: Dark Gem (settlement back, egg building)", "Dark Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("PW1: Large Soul of an Unknown Traveler (settlement roofs, balcony)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("PW1: Large Soul of an Unknown Traveler (settlement loop, by bonfire)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("PW1: Rusted Gold Coin (settlement roofs, roof near second ladder)", + "Rusted Gold Coin x3", DS3LocationCategory.MISC), + DS3LocationData("PW1: Soul of a Crestfallen Knight (settlement hall, rafters)", + "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("PW1: Way of White Corona (settlement hall, by altar)", + "Way of White Corona", DS3LocationCategory.SPELL), + DS3LocationData("PW1: Rusted Coin (right of library)", "Rusted Coin x2", + DS3LocationCategory.MISC), + DS3LocationData("PW1: Young White Branch (right of library)", "Young White Branch", + DS3LocationCategory.MISC), + DS3LocationData("PW1: Budding Green Blossom (settlement courtyard, ledge)", + "Budding Green Blossom x3", DS3LocationCategory.MISC), + DS3LocationData("PW1: Crow Talons (settlement roofs, near bonfire)", "Crow Talons", + DS3LocationCategory.WEAPON), + DS3LocationData("PW1: Hollow Gem (beside chapel)", "Hollow Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("PW1: Rime-blue Moss Clump (below bridge far)", "Rime-blue Moss Clump x4", + DS3LocationCategory.MISC), + DS3LocationData("PW1: Follower Sabre (roots above depths)", "Follower Sabre", + DS3LocationCategory.WEAPON), + DS3LocationData("PW1: Ember (roots above depths)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("PW1: Snap Freeze (depths, far end, mob drop)", "Snap Freeze", + DS3LocationCategory.SPELL, drop = True, + hidden = True), # Guaranteed drop from normal-looking Tree Woman + DS3LocationData("PW1: Rime-blue Moss Clump (snowfield upper, overhang)", + "Rime-blue Moss Clump", DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Soul of an Unknown Traveler (snowfield lower, by cliff)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("PW1: Ember (settlement, building near bonfire)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("PW1: Frozen Weapon (snowfield lower, path to bonfire)", "Frozen Weapon", + DS3LocationCategory.SPELL), + DS3LocationData("PW1: Titanite Slab (depths, up secret ladder)", "Titanite Slab", + DS3LocationCategory.UPGRADE, offline = '11,0:50004700::', + hidden = True), # Must kill normal-looking Tree Woman + DS3LocationData("PW1: Homeward Bone (depths, up hill)", "Homeward Bone x2", + DS3LocationCategory.MISC), + DS3LocationData("PW1: Large Soul of an Unknown Traveler (below snowfield village overhang)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("PW1: Large Soul of a Weary Warrior (settlement hall roof)", + "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("PW1: Large Soul of an Unknown Traveler (settlement back)", + "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + DS3LocationData("PW1: Heavy Gem (snowfield village)", "Heavy Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("PW1: Large Soul of a Weary Warrior (snowfield tower, 6F)", + "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("PW1: Millwood Battle Axe (snowfield tower, 5F)", "Millwood Battle Axe", + DS3LocationCategory.WEAPON), + DS3LocationData("PW1: Ethereal Oak Shield (snowfield tower, 3F)", "Ethereal Oak Shield", + DS3LocationCategory.SHIELD), + DS3LocationData("PW1: Soul of a Weary Warrior (snowfield tower, 1F)", + "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("PW1: Twinkling Titanite (snowfield tower, 3F lizard)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("PW1: Large Titanite Shard (lizard under bridge near)", + "Large Titanite Shard", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("PW1: Twinkling Titanite (roots, lizard)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("PW1: Twinkling Titanite (settlement roofs, lizard before hall)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("PW1: Large Titanite Shard (settlement loop, lizard)", + "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("PW1: Champion's Bones (boss drop)", "Champion's Bones", + DS3LocationCategory.UNIQUE, offline = '11,0:50002310::', boss = True), ], "Painted World of Ariandel (After Contraption)": [ DS3LocationData("PW2: Soul of Sister Friede", "Soul of Sister Friede", DS3LocationCategory.SOUL, prominent = True, boss = True), - DS3LocationData("PW2: Titanite Slab (Friede)", "Titanite Slab", DS3LocationCategory.UPGRADE, - offline = '11,0:50004700::', boss = True), # One-time drop after Friede Phase 2 - DS3LocationData("PW2: Floating Chaos", "Floating Chaos", DS3LocationCategory.SPELL, - missable = True, hostile_npc = True), # Livid Pyromancer Dunnel drop (requires ember) - DS3LocationData("PW2: Prism Stone", "Prism Stone x10", DS3LocationCategory.MISC), - DS3LocationData("PW2: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("PW2: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("PW2: Follower Shield", "Follower Shield", DS3LocationCategory.SHIELD), - DS3LocationData("PW2: Large Titanite Shard #1", "Large Titanite Shard x2", DS3LocationCategory.UPGRADE), - DS3LocationData("PW2: Quakestone Hammer", "Quakestone Hammer", DS3LocationCategory.WEAPON), - DS3LocationData("PW2: Ember", "Ember", DS3LocationCategory.MISC), - DS3LocationData("PW2: Large Titanite Shard #2", "Large Titanite Shard x2", DS3LocationCategory.UPGRADE), - DS3LocationData("PW2: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("PW2: Soul of a Crestfallen Knight #2", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("PW2: Large Soul of a Crestfallen Knight", "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("PW2: Earth Seeker", "Earth Seeker", DS3LocationCategory.WEAPON), - DS3LocationData("PW2: Follower Torch", "Follower Torch", DS3LocationCategory.SHIELD), - DS3LocationData("PW2: Dung Pie", "Dung Pie x2", DS3LocationCategory.MISC), - DS3LocationData("PW2: Vilhelm's Helm", "Vilhelm's Helm", DS3LocationCategory.ARMOR), - DS3LocationData("PW2: Vilhelm's Armor", "Vilhelm's Armor", DS3LocationCategory.ARMOR), - DS3LocationData("PW2: Vilhelm's Gauntlets", "Vilhelm's Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("PW2: Vilhelm's Leggings", "Vilhelm's Leggings", DS3LocationCategory.ARMOR), - DS3LocationData("PW2: Pyromancer's Parting Flame", "Pyromancer's Parting Flame", DS3LocationCategory.WEAPON, + DS3LocationData("PW2: Titanite Slab (boss drop)", "Titanite Slab", + DS3LocationCategory.UPGRADE, offline = '11,0:50004700::', + boss = True), # One-time drop after Friede Phase 2 + DS3LocationData("PW2: Floating Chaos (Dunnel drop)", "Floating Chaos", + DS3LocationCategory.SPELL, hostile_npc = True, + hidden = True), # Livid Pyromancer Dunnel drop (requires ember) + DS3LocationData("PW2: Prism Stone (pass, tree by beginning)", "Prism Stone x10", + DS3LocationCategory.MISC), + DS3LocationData("PW2: Titanite Chunk (pass, cliff overlooking bonfire)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("PW2: Titanite Chunk (pass, by kickable tree)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("PW2: Follower Shield (pass, far cliffside)", "Follower Shield", + DS3LocationCategory.SHIELD), + DS3LocationData("PW2: Large Titanite Shard (pass, just before B1)", + "Large Titanite Shard x2", DS3LocationCategory.UPGRADE), + DS3LocationData("PW2: Quakestone Hammer (pass, side path near B1)", "Quakestone Hammer", + DS3LocationCategory.WEAPON), + DS3LocationData("PW2: Ember (pass, central alcove)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("PW2: Large Titanite Shard (pass, far side path)", + "Large Titanite Shard x2", DS3LocationCategory.UPGRADE), + DS3LocationData("PW2: Soul of a Crestfallen Knight (pit edge #1)", + "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("PW2: Soul of a Crestfallen Knight (pit edge #2)", + "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("PW2: Large Soul of a Crestfallen Knight (pit, by tree)", + "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("PW2: Earth Seeker (pit cave)", "Earth Seeker", DS3LocationCategory.WEAPON), + DS3LocationData("PW2: Follower Torch (pass, far side path)", "Follower Torch", + DS3LocationCategory.SHIELD), + DS3LocationData("PW2: Dung Pie (B1)", "Dung Pie x2", DS3LocationCategory.MISC), + DS3LocationData("PW2: Vilhelm's Helm", "Vilhelm's Helm", + DS3LocationCategory.ARMOR), + DS3LocationData("PW2: Vilhelm's Armor (B2, along wall)", "Vilhelm's Armor", + DS3LocationCategory.ARMOR), + DS3LocationData("PW2: Vilhelm's Gauntlets (B2, along wall)", "Vilhelm's Gauntlets", + DS3LocationCategory.ARMOR), + DS3LocationData("PW2: Vilhelm's Leggings (B2, along wall)", "Vilhelm's Leggings", + DS3LocationCategory.ARMOR), + DS3LocationData("PW2: Pyromancer's Parting Flame (rotunda)", + "Pyromancer's Parting Flame", DS3LocationCategory.WEAPON, hidden = True), # Behind illusory wall - DS3LocationData("PW2: Homeward Bone", "Homeward Bone x2", DS3LocationCategory.MISC, + DS3LocationData("PW2: Homeward Bone (rotunda)", "Homeward Bone x2", + DS3LocationCategory.MISC, hidden = True), # Behind illusory wall - DS3LocationData("PW2: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("PW2: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("PW2: Friede's Great Scythe", "Friede's Great Scythe", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("PW2: Rose of Ariandel", "Rose of Ariandel", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("PW2: Titanite Slab (Corvian)", "Titanite Slab", DS3LocationCategory.UPGRADE, - offline = '11,0:50006540::', missable = True, npc = True), # Corvian Settler (quest) - DS3LocationData("PW2 -> DH", None, DS3LocationCategory.EVENT), + DS3LocationData("PW2: Twinkling Titanite (B3, lizard #1)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("PW2: Twinkling Titanite (B3, lizard #2)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("PW2: Blood Gem (B2, center)", "Blood Gem", DS3LocationCategory.UPGRADE, + # TODO: Mark this as Area: ariandel_vilhelm in the offline rando and reorder + offline = '11,0:54500480::'), + DS3LocationData("PW2 -> DH", None, DS3LocationCategory.EVENT), + + # Corvian Settler after killing Friede + DS3LocationData("PW1: Titanite Slab (Corvian)", "Titanite Slab", + DS3LocationCategory.UPGRADE, missable = True, + npc = True), # Shrine Handmaid after killing Sister Friede - DS3LocationData("PW2: Ordained Hood", "Ordained Hood", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("PW2: Ordained Dress", "Ordained Dress", DS3LocationCategory.ARMOR, - boss = True, shop = True), - DS3LocationData("PW2: Ordained Trousers", "Ordained Trousers", DS3LocationCategory.ARMOR, - boss = True, shop = True), + DS3LocationData("FS: Ordained Hood (shop after killing PW2 boss)", "Ordained Hood", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Ordained Dress (shop after killing PW2 boss)", "Ordained Dress", + DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Ordained Trousers (shop after killing PW2 boss)", "Ordained Trousers", + DS3LocationCategory.ARMOR, boss = True, shop = True), ], "Dreg Heap": [ - DS3LocationData("DH: Soul of the Demon Prince", "Soul of the Demon Prince", DS3LocationCategory.SOUL, - prominent = True, boss = True), - DS3LocationData("DH: Siegbräu", "Siegbräu", DS3LocationCategory.MISC, + DS3LocationData("DH: Soul of the Demon Prince", "Soul of the Demon Prince", + DS3LocationCategory.SOUL, prominent = True, boss = True), + DS3LocationData("DH: Siegbräu (Lapp)", "Siegbräu", DS3LocationCategory.MISC, missable = True, drop = True, npc = True), # Lapp (quest or kill) - DS3LocationData("DH: Flame Fan", "Flame Fan", DS3LocationCategory.SPELL, + DS3LocationData("DH: Flame Fan (swamp upper, NPC drop)", "Flame Fan", + DS3LocationCategory.SPELL, hostile_npc = True), # Desert Pyromancer Zoey drop - DS3LocationData("DH: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("DH: Soul of a Weary Warrior", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("DH: Titanite Chunk #1", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Aquamarine Dagger", "Aquamarine Dagger", DS3LocationCategory.WEAPON), - DS3LocationData("DH: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Murky Hand Scythe", "Murky Hand Scythe", DS3LocationCategory.WEAPON), - DS3LocationData("DH: Divine Blessing #1", "Divine Blessing", DS3LocationCategory.MISC), - DS3LocationData("DH: Ring of Steel Protection+3", "Ring of Steel Protection+3", DS3LocationCategory.RING), - DS3LocationData("DH: Soul of a Crestfallen Knight", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("DH: Rusted Coin", "Rusted Coin x2", DS3LocationCategory.MISC), - DS3LocationData("DH: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Murky Longstaff", "Murky Longstaff", DS3LocationCategory.WEAPON), - DS3LocationData("DH: Ember #2", "Ember", DS3LocationCategory.MISC, - hidden = True), # Behind illusory wall - DS3LocationData("DH: Great Soul Dregs", "Great Soul Dregs", DS3LocationCategory.SPELL, - hidden = True), # Behind illusory wall - DS3LocationData("DH: Covetous Silver Serpent Ring+3", "Covetous Silver Serpent Ring+3", DS3LocationCategory.RING, + DS3LocationData("DH: Ember (castle, behind spire)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("DH: Soul of a Weary Warrior (castle overhang)", "Soul of a Weary Warrior", + DS3LocationCategory.SOUL), + DS3LocationData("DH: Titanite Chunk (castle, up stairs)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Aquamarine Dagger (castle, up stairs)", "Aquamarine Dagger", + DS3LocationCategory.WEAPON), + DS3LocationData("DH: Twinkling Titanite (library, chandelier)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Murky Hand Scythe (library, behind bookshelves)", "Murky Hand Scythe", + DS3LocationCategory.WEAPON), + DS3LocationData("DH: Divine Blessing (library, after drop)", "Divine Blessing", + DS3LocationCategory.MISC), + DS3LocationData("DH: Ring of Steel Protection+3 (ledge before church)", + "Ring of Steel Protection+3", DS3LocationCategory.RING), + DS3LocationData("DH: Soul of a Crestfallen Knight (church, altar)", + "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("DH: Rusted Coin (behind fountain after church)", "Rusted Coin x2", + DS3LocationCategory.MISC), + DS3LocationData("DH: Titanite Chunk (pantry, first room)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Murky Longstaff (pantry, last room)", "Murky Longstaff", + DS3LocationCategory.WEAPON), + DS3LocationData("DH: Ember (pantry, behind crates just before upstairs)", "Ember", + DS3LocationCategory.MISC, hidden = True), # Behind illusory wall + DS3LocationData("DH: Great Soul Dregs (pantry upstairs)", "Great Soul Dregs", + DS3LocationCategory.SPELL, hidden = True), # Behind illusory wall + DS3LocationData("DH: Covetous Silver Serpent Ring+3 (pantry upstairs, drop down)", + "Covetous Silver Serpent Ring+3", DS3LocationCategory.RING, hidden = True), # Behind illusory wall - DS3LocationData("DH: Titanite Chunk #3", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Homeward Bone #1", "Homeward Bone x3", DS3LocationCategory.MISC), - DS3LocationData("DH: Lightning Urn", "Lightning Urn x4", DS3LocationCategory.MISC), - DS3LocationData("DH: Projected Heal", "Projected Heal", DS3LocationCategory.SPELL), - DS3LocationData("DH: Large Soul of a Weary Warrior #1", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("DH: Lothric War Banner", "Lothric War Banner", DS3LocationCategory.WEAPON), - DS3LocationData("DH: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Black Firebomb", "Black Firebomb x4", DS3LocationCategory.MISC), - DS3LocationData("DH: Titanite Chunk #4", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Desert Pyromancer Garb", "Desert Pyromancer Garb", DS3LocationCategory.ARMOR), - DS3LocationData("DH: Titanite Chunk #5", "Titanite Chunk x2", DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Giant Door Shield", "Giant Door Shield", DS3LocationCategory.SHIELD), - DS3LocationData("DH: Ember #3", "Ember", DS3LocationCategory.MISC), - DS3LocationData("DH: Desert Pyromancer Gloves", "Desert Pyromancer Gloves", DS3LocationCategory.ARMOR), - DS3LocationData("DH: Desert Pyromancer Skirt", "Desert Pyromancer Skirt", DS3LocationCategory.ARMOR), - DS3LocationData("DH: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Purple Moss Clump", "Purple Moss Clump x4", DS3LocationCategory.MISC), - DS3LocationData("DH: Ring of Favor+3", "Ring of Favor+3", DS3LocationCategory.RING), - DS3LocationData("DH: Titanite Chunk #6", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Large Soul of a Weary Warrior #2", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("DH: Titanite Slab", "Titanite Slab", DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Titanite Chunk #7", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Loincloth", "Loincloth", DS3LocationCategory.ARMOR), - DS3LocationData("DH: Titanite Chunk #8", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Large Soul of a Weary Warrior #3", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("DH: Harald Curved Greatsword", "Harald Curved Greatsword", DS3LocationCategory.WEAPON), - DS3LocationData("DH: Homeward Bone #2", "Homeward Bone", DS3LocationCategory.MISC), - DS3LocationData("DH: Prism Stone", "Prism Stone x6", DS3LocationCategory.MISC), - DS3LocationData("DH: Desert Pyromancer Hood", "Desert Pyromancer Hood", DS3LocationCategory.ARMOR), - DS3LocationData("DH: Twinkling Titanite #3", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + DS3LocationData("DH: Titanite Chunk (path from church, by pillar)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Homeward Bone (end of path from church)", "Homeward Bone x3", + DS3LocationCategory.MISC), + DS3LocationData("DH: Lightning Urn (wall outside church)", "Lightning Urn x4", + DS3LocationCategory.MISC), + DS3LocationData("DH: Projected Heal (parapets balcony)", "Projected Heal", + DS3LocationCategory.SPELL), + DS3LocationData("DH: Large Soul of a Weary Warrior (parapets, hall)", + "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("DH: Lothric War Banner (parapets, end of hall)", "Lothric War Banner", + DS3LocationCategory.WEAPON), + DS3LocationData("DH: Titanite Scale (library, back of room)", "Titanite Scale", + DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Black Firebomb (ruins, up windmill from bonfire)", "Black Firebomb x4", + DS3LocationCategory.MISC), + DS3LocationData("DH: Titanite Chunk (ruins, path from bonfire)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Twinkling Titanite (ruins, root near bonfire)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Desert Pyromancer Garb (ruins, by shack near cliff)", + "Desert Pyromancer Garb", DS3LocationCategory.ARMOR), + DS3LocationData("DH: Titanite Chunk (ruins, by far shack)", "Titanite Chunk x2", + DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Giant Door Shield (ruins, path below far shack)", + "Giant Door Shield", DS3LocationCategory.SHIELD), + DS3LocationData("DH: Ember (ruins, alcove before swamp)", "Ember", + DS3LocationCategory.MISC), + DS3LocationData("DH: Desert Pyromancer Gloves (swamp, far right)", + "Desert Pyromancer Gloves", DS3LocationCategory.ARMOR), + DS3LocationData("DH: Desert Pyromancer Skirt (swamp right, by roots)", + "Desert Pyromancer Skirt", DS3LocationCategory.ARMOR), + DS3LocationData("DH: Titanite Scale (swamp upper, drop and jump into tower)", + "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Purple Moss Clump (swamp shack)", "Purple Moss Clump x4", + DS3LocationCategory.MISC), + DS3LocationData("DH: Ring of Favor+3 (swamp right, up root)", "Ring of Favor+3", + DS3LocationCategory.RING), + DS3LocationData("DH: Titanite Chunk (swamp right, drop partway up root)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Large Soul of a Weary Warrior (swamp, under overhang)", + "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("DH: Titanite Slab (swamp, path under overhang)", "Titanite Slab", + DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Titanite Chunk (swamp, along buildings)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Loincloth (swamp, left edge)", "Loincloth", + DS3LocationCategory.ARMOR), + DS3LocationData("DH: Titanite Chunk (swamp, path to upper)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("DH: Large Soul of a Weary Warrior (swamp center)", + "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("DH: Harald Curved Greatsword (swamp left, under root)", + "Harald Curved Greatsword", DS3LocationCategory.WEAPON), + DS3LocationData("DH: Homeward Bone (swamp left, on root)", "Homeward Bone", + DS3LocationCategory.MISC), + DS3LocationData("DH: Prism Stone (swamp upper, tunnel start)", "Prism Stone x6", + DS3LocationCategory.MISC), + DS3LocationData("DH: Desert Pyromancer Hood (swamp upper, tunnel end)", + "Desert Pyromancer Hood", DS3LocationCategory.ARMOR), + DS3LocationData("DH: Twinkling Titanite (swamp upper, drop onto root)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE, hidden = True), # Hidden fall - DS3LocationData("DH: Divine Blessing #2", "Divine Blessing", DS3LocationCategory.MISC), - DS3LocationData("DH: Ember #4", "Ember", DS3LocationCategory.MISC, + DS3LocationData("DH: Divine Blessing (swamp upper, building roof)", "Divine Blessing", + DS3LocationCategory.MISC), + DS3LocationData("DH: Ember (ruins, alcove on cliff)", "Ember", DS3LocationCategory.MISC, hidden = True), # Hidden fall - DS3LocationData("DH: Small Envoy Banner", "Small Envoy Banner", DS3LocationCategory.KEY, - progression = True, boss = True), - DS3LocationData("DH: Twinkling Titanite #4", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, - drop = True, hidden = True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim - DS3LocationData("DH: Twinkling Titanite #5", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, - drop = True, hidden = True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim - DS3LocationData("DH: Twinkling Titanite #6", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, - drop = True, hidden = True), # Guaranteed drop from killing normal-looking pilgrim - DS3LocationData("DH: Demon's Scar", "Demon's Scar", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("DH: Seething Chaos", "Seething Chaos", DS3LocationCategory.SPELL, - missable = True, boss = True, shop = True), + DS3LocationData("DH: Small Envoy Banner (boss drop)", "Small Envoy Banner", + DS3LocationCategory.KEY, progression = True, boss = True), + DS3LocationData("DH: Twinkling Titanite (ruins, alcove on cliff, mob drop)", + "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, drop = True, + hidden = True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim + DS3LocationData("DH: Twinkling Titanite (swamp upper, mob drop on roof)", + "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, drop = True, + hidden = True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim + DS3LocationData("DH: Twinkling Titanite (path after church, mob drop)", + "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, drop = True, + hidden = True), # Guaranteed drop from killing normal-looking pilgrim # Stone-humped Hag's shop - DS3LocationData("DH: Splitleaf Greatsword", "Splitleaf Greatsword", DS3LocationCategory.WEAPON, - shop = True), - DS3LocationData("DH: Divine Blessing #3", "Divine Blessing", DS3LocationCategory.MISC, - shop = True), - DS3LocationData("DH: Hidden Blessing", "Hidden Blessing", DS3LocationCategory.MISC, + DS3LocationData("DH: Splitleaf Greatsword (shop)", "Splitleaf Greatsword", + DS3LocationCategory.WEAPON, shop = True), + DS3LocationData("DH: Divine Blessing (shop)", "Divine Blessing", DS3LocationCategory.MISC, shop = True), - DS3LocationData("DH: Rusted Gold Coin", "Rusted Gold Coin", DS3LocationCategory.MISC, + DS3LocationData("DH: Hidden Blessing (shop)", "Hidden Blessing", DS3LocationCategory.MISC, shop = True), - DS3LocationData("DH: Ember #5", "Ember", DS3LocationCategory.MISC, + DS3LocationData("DH: Rusted Gold Coin (shop)", "Rusted Gold Coin", DS3LocationCategory.MISC, shop = True), + DS3LocationData("DH: Ember (shop)", "Ember", DS3LocationCategory.MISC, shop = True), ], "Ringed City": [ - DS3LocationData("RC: Titanite Slab #1", "Titanite Slab", DS3LocationCategory.UPGRADE, - prominent = True, boss = True), # Halflight drop, only once - DS3LocationData("RC: Soul of Darkeater Midir", "Soul of Darkeater Midir", DS3LocationCategory.SOUL, - prominent = True, boss = True), - DS3LocationData("RC: Sacred Chime of Filianore", "Sacred Chime of Filianore", DS3LocationCategory.WEAPON, - drop = True, npc = True), # Shira (kill or quest) - DS3LocationData("RC: Titanite Slab #2", "Titanite Slab", DS3LocationCategory.UPGRADE, - drop = True, npc = True), # Shira (kill or quest) - DS3LocationData("RC: Crucifix of the Mad King", "Crucifix of the Mad King", DS3LocationCategory.WEAPON, + DS3LocationData("RC: Titanite Slab (mid boss drop)", "Titanite Slab", + DS3LocationCategory.UPGRADE, prominent = True, + boss = True), # Halflight drop, only once + DS3LocationData("RC: Filianore's Spear Ornament (mid boss drop)", + "Filianore's Spear Ornament", DS3LocationCategory.MISC), + DS3LocationData("RC: Soul of Darkeater Midir", "Soul of Darkeater Midir", + DS3LocationCategory.SOUL, prominent = True, boss = True), + DS3LocationData("RC: Sacred Chime of Filianore (ashes, NPC drop)", + "Sacred Chime of Filianore", DS3LocationCategory.WEAPON, + hostile_npc = True), # Shira (kill or quest) + DS3LocationData("RC: Titanite Slab (ashes, NPC drop)", "Titanite Slab", + DS3LocationCategory.UPGRADE, hostile_npc = True), # Shira (kill or quest) + DS3LocationData("RC: Crucifix of the Mad King (ashes, NPC drop)", + "Crucifix of the Mad King", DS3LocationCategory.WEAPON, hostile_npc = True), # Shira drop - DS3LocationData("RC: Ledo's Great Hammer", "Ledo's Great Hammer", DS3LocationCategory.WEAPON, + DS3LocationData("RC: Ledo's Great Hammer (streets high, opposite building, NPC drop)", + "Ledo's Great Hammer", DS3LocationCategory.WEAPON, hostile_npc = True), # Silver Knight Ledo drop - DS3LocationData("RC: Wolf Ring+3", "Wolf Ring+3", DS3LocationCategory.RING, + DS3LocationData("RC: Wolf Ring+3 (street gardens, NPC drop)", "Wolf Ring+3", DS3LocationCategory.RING, hostile_npc = True), # Alva drop - DS3LocationData("RC: Blindfold Mask", "Blindfold Mask", DS3LocationCategory.ARMOR, - hostile_npc = True), # Moaning Knight drop - DS3LocationData("RC: Titanite Scale #1", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Ruin Helm", "Ruin Helm", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Ruin Armor", "Ruin Armor", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Ruin Gauntlets", "Ruin Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Ruin Leggings", "Ruin Leggings", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Budding Green Blossom #1", "Budding Green Blossom x2", DS3LocationCategory.MISC), - DS3LocationData("RC: Titanite Chunk #1", "Titanite Chunk x2", DS3LocationCategory.MISC), - DS3LocationData("RC: Ember #1", "Ember", DS3LocationCategory.MISC), - DS3LocationData("RC: Budding Green Blossom #2", "Budding Green Blossom x2", DS3LocationCategory.MISC), - DS3LocationData("RC: Hidden Blessing #1", "Hidden Blessing", DS3LocationCategory.MISC), - DS3LocationData("RC: Soul of a Crestfallen Knight #1", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("RC: Large Soul of a Weary Warrior #1", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("RC: Ember #2", "Ember", DS3LocationCategory.MISC), - DS3LocationData("RC: Purging Stone", "Purging Stone x2", DS3LocationCategory.MISC), - DS3LocationData("RC: Hollow Gem", "Hollow Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Titanite Chunk #2", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Twinkling Titanite #1", "Twinkling Titanite", DS3LocationCategory.UPGRADE, + DS3LocationData("RC: Blindfold Mask (grave, NPC drop)", "Blindfold Mask", + DS3LocationCategory.ARMOR, hostile_npc = True), # Moaning Knight drop + DS3LocationData("RC: Titanite Scale (wall top, behind spawn)", "Titanite Scale", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Ruin Helm (wall top, under stairs to bonfire)", "Ruin Helm", + DS3LocationCategory.ARMOR), + DS3LocationData("RC: Ruin Armor (wall top, under stairs to bonfire)", "Ruin Armor", + DS3LocationCategory.ARMOR), + DS3LocationData("RC: Ruin Gauntlets (wall top, under stairs to bonfire)", "Ruin Gauntlets", + DS3LocationCategory.ARMOR), + DS3LocationData("RC: Ruin Leggings (wall top, under stairs to bonfire)", "Ruin Leggings", + DS3LocationCategory.ARMOR), + DS3LocationData("RC: Budding Green Blossom (wall top, in flower cluster)", + "Budding Green Blossom x2", DS3LocationCategory.MISC), + DS3LocationData("RC: Titanite Chunk (wall top, among graves)", "Titanite Chunk x2", + DS3LocationCategory.MISC), + DS3LocationData("RC: Ember (wall top, by statue)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("RC: Budding Green Blossom (wall top, flowers by stairs)", + "Budding Green Blossom x2", DS3LocationCategory.MISC), + DS3LocationData("RC: Hidden Blessing (wall top, tomb under platform)", "Hidden Blessing", + DS3LocationCategory.MISC, hidden = True), # hidden fall + DS3LocationData("RC: Soul of a Crestfallen Knight (wall top, under drop)", + "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL, + hidden = True), # hidden fall + DS3LocationData("RC: Large Soul of a Weary Warrior (wall top, right of small tomb)", + "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("RC: Ember (wall upper, balcony)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("RC: Purging Stone (wall top, by door to upper)", "Purging Stone x2", + DS3LocationCategory.MISC), + DS3LocationData("RC: Hollow Gem (wall upper, path to tower)", "Hollow Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Titanite Chunk (wall upper, courtyard alcove)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Twinkling Titanite (wall tower, jump from chandelier)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE, hidden = True), # Hidden fall - DS3LocationData("RC: Shriving Stone", "Shriving Stone", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Shira's Crown", "Shira's Crown", DS3LocationCategory.ARMOR, + DS3LocationData("RC: Shriving Stone (wall tower, bottom floor center)", "Shriving Stone", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Shira's Crown (Shira's room after killing ashes NPC)", "Shira's Crown", + DS3LocationCategory.ARMOR, hidden = True), # Have to return to a cleared area - DS3LocationData("RC: Shira's Armor", "Shira's Armor", DS3LocationCategory.ARMOR, + DS3LocationData("RC: Shira's Armor (Shira's room after killing ashes NPC)", "Shira's Armor", + DS3LocationCategory.ARMOR, hidden = True), # Have to return to a cleared area - DS3LocationData("RC: Shira's Gloves", "Shira's Gloves", DS3LocationCategory.ARMOR, + DS3LocationData("RC: Shira's Gloves (Shira's room after killing ashes NPC)", + "Shira's Gloves", DS3LocationCategory.ARMOR, hidden = True), # Have to return to a cleared area - DS3LocationData("RC: Shira's Trousers", "Shira's Trousers", DS3LocationCategory.ARMOR, + DS3LocationData("RC: Shira's Trousers (Shira's room after killing ashes NPC)", + "Shira's Trousers", DS3LocationCategory.ARMOR, hidden = True), # Have to return to a cleared area - DS3LocationData("RC: Mossfruit #1", "Mossfruit x2", DS3LocationCategory.MISC), - DS3LocationData("RC: Large Soul of a Crestfallen Knight #1", "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("RC: Ringed Knight Spear", "Ringed Knight Spear", DS3LocationCategory.WEAPON), - DS3LocationData("RC: Black Witch Hat", "Black Witch Hat", DS3LocationCategory.ARMOR, - hostile_npc = True), # Alva - DS3LocationData("RC: Black Witch Garb", "Black Witch Garb", DS3LocationCategory.ARMOR, - hostile_npc = True), # Alva - DS3LocationData("RC: Black Witch Wrappings", "Black Witch Wrappings", DS3LocationCategory.ARMOR, - hostile_npc = True), # Alva - DS3LocationData("RC: Black Witch Trousers", "Black Witch Trousers", DS3LocationCategory.ARMOR, - hostile_npc = True), # Alva - DS3LocationData("RC: Dragonhead Shield", "Dragonhead Shield", DS3LocationCategory.SHIELD, + DS3LocationData("RC: Mossfruit (streets near left, path to garden)", "Mossfruit x2", + DS3LocationCategory.MISC), + DS3LocationData("RC: Large Soul of a Crestfallen Knight (streets, far stairs)", + "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("RC: Ringed Knight Spear (streets, down far right hall)", + "Ringed Knight Spear", DS3LocationCategory.WEAPON), + DS3LocationData("RC: Black Witch Hat (streets garden)", "Black Witch Hat", + DS3LocationCategory.ARMOR, hostile_npc = True), # Alva + DS3LocationData("RC: Black Witch Garb (streets garden)", "Black Witch Garb", + DS3LocationCategory.ARMOR, hostile_npc = True), # Alva + DS3LocationData("RC: Black Witch Wrappings (streets garden)", "Black Witch Wrappings", + DS3LocationCategory.ARMOR, hostile_npc = True), # Alva + DS3LocationData("RC: Black Witch Trousers (streets garden)", "Black Witch Trousers", + DS3LocationCategory.ARMOR, hostile_npc = True), # Alva + DS3LocationData("RC: Dragonhead Shield (streets monument, across bridge)", + "Dragonhead Shield", DS3LocationCategory.SHIELD, hidden = True), # "Show Your Humanity" puzzle - DS3LocationData("RC: Titanite Chunk #3", "Titanite Chunk", DS3LocationCategory.UPGRADE, - hidden = True), # Hidden fall - DS3LocationData("RC: Mossfruit #2", "Mossfruit x2", DS3LocationCategory.MISC), - DS3LocationData("RC: Large Soul of a Crestfallen Knight #2", "Large Soul of a Crestfallen Knight", DS3LocationCategory.MISC, + DS3LocationData("RC: Titanite Chunk (streets, near left drop)", "Titanite Chunk", + DS3LocationCategory.UPGRADE, hidden = True), # Hidden fall + DS3LocationData("RC: Mossfruit (streets, far left alcove)", "Mossfruit x2", + DS3LocationCategory.MISC), + DS3LocationData("RC: Large Soul of a Crestfallen Knight (streets monument, across bridge)", + "Large Soul of a Crestfallen Knight", DS3LocationCategory.MISC, hidden = True), # "Show Your Humanity" puzzle - DS3LocationData("RC: Covetous Gold Serpent Ring+3", "Covetous Gold Serpent Ring+3", DS3LocationCategory.RING), - DS3LocationData("RC: Titanite Chunk #4", "Titanite Chunk x2", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Dark Gem", "Dark Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Prism Stone", "Prism Stone x4", DS3LocationCategory.MISC), - DS3LocationData("RC: Ringed Knight Straight Sword", "Ringed Knight Straight Sword", DS3LocationCategory.WEAPON), - DS3LocationData("RC: Havel's Ring+3", "Havel's Ring+3", DS3LocationCategory.RING, + DS3LocationData("RC: Covetous Gold Serpent Ring+3 (streets, by Lapp)", + "Covetous Gold Serpent Ring+3", DS3LocationCategory.RING), + DS3LocationData("RC: Titanite Chunk (streets high, building opposite)", "Titanite Chunk x2", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Dark Gem (swamp near, by stairs)", "Dark Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Prism Stone (swamp near, path to bonfire)", "Prism Stone x4", + DS3LocationCategory.MISC), + DS3LocationData("RC: Ringed Knight Straight Sword (swamp near, pillar by bonfire)", + "Ringed Knight Straight Sword", DS3LocationCategory.WEAPON), + DS3LocationData("RC: Havel's Ring+3 (streets high, drop from building opposite)", + "Havel's Ring+3", DS3LocationCategory.RING, hidden = True), # Hidden fall + DS3LocationData("RC: Titanite Chunk (swamp near left, opposite ladder)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Twinkling Titanite (swamp near left)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Soul of a Weary Warrior (swamp center)", "Soul of a Weary Warrior", + DS3LocationCategory.SOUL), + DS3LocationData("RC: Preacher's Right Arm (swamp near right, by crystal)", + "Preacher's Right Arm", DS3LocationCategory.WEAPON), + DS3LocationData("RC: Rubbish (swamp far, by crystal)", "Rubbish", DS3LocationCategory.MISC), + DS3LocationData("RC: Titanite Chunk (swamp near right, by sinking church)", + "Titanite Chunk", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Black Witch Veil (swamp near right, by sinking church)", + "Black Witch Veil", DS3LocationCategory.ARMOR), + DS3LocationData("RC: Twinkling Titanite (swamp near right, on sinking church)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Soul of a Crestfallen Knight (swamp near left, by ladder)", + "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("RC: White Preacher Head (swamp near, ground near bonfire exit)", + "White Preacher Head", DS3LocationCategory.ARMOR), + DS3LocationData("RC: Titanite Scale (swamp far, by miniboss)", "Titanite Scale", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Titanite Scale (upper cliff, path under bridge)", "Titanite Scale", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Dragonhead Greatshield (upper cluff, under bridge)", + "Dragonhead Greatshield", DS3LocationCategory.SHIELD), + DS3LocationData("RC: Titanite Scale (upper cliff, first alcove)", "Titanite Scale x2", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Rubbish (upper cliff, middle)", "Rubbish", DS3LocationCategory.MISC), + DS3LocationData("RC: Large Soul of a Weary Warrior (upper cliff, end)", + "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("RC: Titanite Scale (upper cliff, lower path)", "Titanite Scale x2", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Titanite Scale (lower cliff, bridge)", "Titanite Scale", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Lightning Gem (grave, room after first drop)", "Lightning Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Blessed Gem (grave, down lowest stairs)", "Blessed Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Simple Gem (grave, up stairs after first drop)", "Simple Gem", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Large Soul of a Weary Warrior (wall lower, past two illusory walls)", + "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL, hidden = True), + DS3LocationData("RC: Lightning Arrow (wall lower, past three illusory walls)", + "Lightning Arrow", DS3LocationCategory.SPELL), + DS3LocationData("RC: Chloranthy Ring+3 (wall hidden, drop onto statue)", + "Chloranthy Ring+3", DS3LocationCategory.RING, hidden = True), # Hidden fall - DS3LocationData("RC: Titanite Chunk #5", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Twinkling Titanite #2", "Twinkling Titanite", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Soul of a Weary Warrior #1", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("RC: Preacher's Right Arm", "Preacher's Right Arm", DS3LocationCategory.WEAPON), - DS3LocationData("RC: Rubbish #1", "Rubbish", DS3LocationCategory.MISC), - DS3LocationData("RC: Titanite Chunk #6", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Black Witch Veil", "Black Witch Veil", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Twinkling Titanite #3", "Twinkling Titanite", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Soul of a Crestfallen Knight #2", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("RC: White Preacher Head", "White Preacher Head", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Titanite Scale #2", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Titanite Scale #3", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Dragonhead Greatshield", "Dragonhead Greatshield", DS3LocationCategory.SHIELD), - DS3LocationData("RC: Titanite Scale #4", "Titanite Scale x2", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Rubbish #2", "Rubbish", DS3LocationCategory.MISC), - DS3LocationData("RC: Large Soul of a Weary Warrior #2", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("RC: Titanite Scale #5", "Titanite Scale x2", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Titanite Scale #6", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Lightning Gem", "Lightning Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Blessed Gem", "Blessed Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Simple Gem", "Simple Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Large Soul of a Weary Warrior #3", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("RC: Lightning Arrow", "Lightning Arrow", DS3LocationCategory.SPELL), - DS3LocationData("RC: Chloranthy Ring+3", "Chloranthy Ring+3", DS3LocationCategory.RING, - hidden = True), # Hidden fall - DS3LocationData("RC: Ember #3", "Ember", DS3LocationCategory.MISC), - DS3LocationData("RC: Filianore's Spear Ornament", "Filianore's Spear Ornament", DS3LocationCategory.MISC, - offline = '13,0:55100700::'), - DS3LocationData("RC: Antiquated Plain Garb", "Antiquated Plain Garb", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Violet Wrappings", "Violet Wrappings", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Soul of a Weary Warrior #2", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("RC: Twinkling Titanite #4", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Budding Green Blossom #3", "Budding Green Blossom x3", DS3LocationCategory.MISC), - DS3LocationData("RC: Titanite Chunk #7", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Large Soul of a Weary Warrior #4", "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("RC: Soul of a Weary Warrior #3", "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("RC: Titanite Scale #7", "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Soul of a Crestfallen Knight #3", "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("RC: White Birch Bow", "White Birch Bow", DS3LocationCategory.WEAPON), - DS3LocationData("RC: Titanite Chunk #8", "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Young White Branch #1", "Young White Branch", DS3LocationCategory.MISC), - DS3LocationData("RC: Young White Branch #2", "Young White Branch", DS3LocationCategory.MISC), - DS3LocationData("RC: Young White Branch #3", "Young White Branch", DS3LocationCategory.MISC), - DS3LocationData("RC: Ringed Knight Paired Greatswords", "Ringed Knight Paired Greatswords", DS3LocationCategory.WEAPON, - drop = True, hidden = True), # Guaranteed drop from a normal-looking Ringed Knight - DS3LocationData("RC: Hidden Blessing #2", "Hidden Blessing", DS3LocationCategory.MISC, - miniboss = True), # Judicator drop - DS3LocationData("RC: Divine Blessing #1", "Divine Blessing", DS3LocationCategory.MISC, - miniboss = True), # Judicator drop - DS3LocationData("RC: Divine Blessing #2", "Divine Blessing", DS3LocationCategory.MISC, - miniboss = True, hidden = True), # Judicator drop, "Show Your Humanity" puzzle - DS3LocationData("RC: Ring of the Evil Eye+3", "Ring of the Evil Eye+3", DS3LocationCategory.RING, - mimic = True, hidden = True), # Hidden fall - DS3LocationData("RC: Iron Dragonslayer Helm", "Iron Dragonslayer Helm", DS3LocationCategory.ARMOR, - miniboss = True), - DS3LocationData("RC: Iron Dragonslayer Armor", "Iron Dragonslayer Armor", DS3LocationCategory.ARMOR, - miniboss = True), - DS3LocationData("RC: Iron Dragonslayer Gauntlets", "Iron Dragonslayer Gauntlets", DS3LocationCategory.ARMOR, - miniboss = True), - DS3LocationData("RC: Iron Dragonslayer Leggings", "Iron Dragonslayer Leggings", DS3LocationCategory.ARMOR, - miniboss = True), - DS3LocationData("RC: Church Guardian Shiv", "Church Guardian Shiv", DS3LocationCategory.MISC), - DS3LocationData("RC: Spears of the Church", "Spears of the Church", DS3LocationCategory.UNIQUE, - boss = True), # Midir drop - DS3LocationData("RC: Ritual Spear Fragment", "Ritual Spear Fragment", DS3LocationCategory.UNIQUE), - DS3LocationData("RC: Titanite Scale #8", "Titanite Scale", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("RC: Twinkling Titanite #5", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("RC: Titanite Scale #9", "Titanite Scale x2", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("RC: Twinkling Titanite #6", "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("RC: Titanite Scale #10", "Titanite Scale", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("RC: Twinkling Titanite #7", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - lizard = True), - DS3LocationData("RC: Soul of Slave Knight Gael", "Soul of Slave Knight Gael", DS3LocationCategory.SOUL, - prominent = True, boss = True), - DS3LocationData("RC: Blood of the Dark Soul", "Blood of the Dark Soul", DS3LocationCategory.KEY), - DS3LocationData("RC: Titanite Slab #3", "Titanite Slab", DS3LocationCategory.UPGRADE, - drop = True, hidden = True), # Guaranteed drop from normal-looking Ringed Knight - DS3LocationData("RC: Frayed Blade", "Frayed Blade", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("RC: Old Moonlight", "Old Moonlight", DS3LocationCategory.SPELL, - missable = True, boss = True, shop = True), - DS3LocationData("RC: Gael's Greatsword", "Gael's Greatsword", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), - DS3LocationData("RC: Repeating Crossbow", "Repeating Crossbow", DS3LocationCategory.WEAPON, - missable = True, boss = True, shop = True), + DS3LocationData("RC: Ember (wall hidden, statue room)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("RC: Filianore's Spear Ornament (wall hidden, by ladder)", + "Filianore's Spear Ornament", DS3LocationCategory.MISC), + DS3LocationData("RC: Antiquated Plain Garb (wall hidden, before boss)", + "Antiquated Plain Garb", DS3LocationCategory.ARMOR), + DS3LocationData("RC: Violet Wrappings (wall hidden, before boss)", "Violet Wrappings", + DS3LocationCategory.ARMOR), + DS3LocationData("RC: Soul of a Weary Warrior (upper cliff, by first alcove)", + "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("RC: Twinkling Titanite (church path, left of boss door)", + "Twinkling Titanite x2", DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Budding Green Blossom (church path)", "Budding Green Blossom x3", + DS3LocationCategory.MISC), + DS3LocationData("RC: Titanite Chunk (swamp center, along edge)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Large Soul of a Weary Warrior (swamp center)", + "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("RC: Soul of a Weary Warrior (swamp right, by sunken church)", + "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + DS3LocationData("RC: Titanite Scale (swamp far, by miniboss)", "Titanite Scale", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Soul of a Crestfallen Knight (swamp far, behind crystal)", + "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + DS3LocationData("RC: White Birch Bow (swamp far left, up hill)", "White Birch Bow", + DS3LocationCategory.WEAPON), + DS3LocationData("RC: Titanite Chunk (swamp far left, up hill)", "Titanite Chunk", + DS3LocationCategory.UPGRADE), + DS3LocationData("RC: Young White Branch (swamp far left, by white tree)", + "Young White Branch", DS3LocationCategory.MISC), + DS3LocationData("RC: Young White Branch (swamp far left, by white tree)", + "Young White Branch", DS3LocationCategory.MISC), + DS3LocationData("RC: Young White Branch (swamp far left, by white tree)", + "Young White Branch", DS3LocationCategory.MISC), + DS3LocationData("RC: Ringed Knight Paired Greatswords (church path, mob drop)", + "Ringed Knight Paired Greatswords", DS3LocationCategory.WEAPON, drop = True, + hidden = True), # Guaranteed drop from a normal-looking Ringed Knight + DS3LocationData("RC: Hidden Blessing (swamp center, mob drop)", "Hidden Blessing", + DS3LocationCategory.MISC, drop = True, + hidden = True), # Guaranteed drop from Judicator + DS3LocationData("RC: Divine Blessing (wall top, mob drop)", "Divine Blessing", + DS3LocationCategory.MISC, drop = True, + hidden = True), # Guaranteed drop from Judicator + DS3LocationData("RC: Divine Blessing (streets monument, mob drop)", "Divine Blessing", + DS3LocationCategory.MISC, drop = True, + hidden = True), # Guaranteed drop from Judicator, "Show Your Humanity" puzzle + DS3LocationData("RC: Ring of the Evil Eye+3 (grave, mimic)", "Ring of the Evil Eye+3", + DS3LocationCategory.RING, mimic = True), + DS3LocationData("RC: Iron Dragonslayer Helm (swamp far, miniboss drop)", + "Iron Dragonslayer Helm", DS3LocationCategory.ARMOR, miniboss = True), + DS3LocationData("RC: Iron Dragonslayer Armor (swamp far, miniboss drop)", + "Iron Dragonslayer Armor", DS3LocationCategory.ARMOR, miniboss = True), + DS3LocationData("RC: Iron Dragonslayer Gauntlets (swamp far, miniboss drop)", + "Iron Dragonslayer Gauntlets", DS3LocationCategory.ARMOR, miniboss = True), + DS3LocationData("RC: Iron Dragonslayer Leggings (swamp far, miniboss drop)", + "Iron Dragonslayer Leggings", DS3LocationCategory.ARMOR, miniboss = True), + DS3LocationData("RC: Church Guardian Shiv (swamp far left, in building)", + "Church Guardian Shiv", DS3LocationCategory.MISC), + DS3LocationData("RC: Spears of the Church (hidden boss drop)", "Spears of the Church", + DS3LocationCategory.UNIQUE, boss = True), # Midir drop + DS3LocationData("RC: Ritual Spear Fragment (church path)", "Ritual Spear Fragment", + DS3LocationCategory.UNIQUE), + DS3LocationData("RC: Titanite Scale (grave, lizard after first drop)", "Titanite Scale", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("RC: Twinkling Titanite (grave, lizard after first drop)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("RC: Titanite Scale (wall lower, lizard)", "Titanite Scale x2", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("RC: Twinkling Titanite (streets high, lizard)", "Twinkling Titanite x2", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("RC: Titanite Scale (wall top, lizard on side path)", "Titanite Scale", + DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("RC: Twinkling Titanite (wall top, lizard on side path)", + "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("RC: Soul of Slave Knight Gael", "Soul of Slave Knight Gael", + DS3LocationCategory.SOUL, prominent = True, boss = True), + DS3LocationData("RC: Blood of the Dark Soul (end boss drop)", "Blood of the Dark Soul", + DS3LocationCategory.KEY), + DS3LocationData("RC: Titanite Slab (ashes, mob drop)", "Titanite Slab", + DS3LocationCategory.UPGRADE, drop = True, + hidden = True), # Guaranteed drop from normal-looking Ringed Knight # Lapp - DS3LocationData("RC: Siegbräu", "Siegbräu", DS3LocationCategory.MISC, + DS3LocationData("RC: Siegbräu (Lapp)", "Siegbräu", DS3LocationCategory.MISC, missable = True, npc = True), # Lapp (quest) # Quest or Shrine Handmaiden after death - DS3LocationData("RC: Lapp's Helm", "Lapp's Helm", DS3LocationCategory.ARMOR, - missable = True, npc = True, shop = True), - DS3LocationData("RC: Lapp's Armor", "Lapp's Armor", DS3LocationCategory.ARMOR, - missable = True, npc = True, shop = True), - DS3LocationData("RC: Lapp's Gauntlets", "Lapp's Gauntlets", DS3LocationCategory.ARMOR, - missable = True, npc = True, shop = True), - DS3LocationData("RC: Lapp's Leggings", "Lapp's Leggings", DS3LocationCategory.ARMOR, - missable = True, npc = True, shop = True), + DS3LocationData("RC: Lapp's Helm (Lapp)", "Lapp's Helm", DS3LocationCategory.ARMOR, + npc = True, shop = True), + DS3LocationData("RC: Lapp's Armor (Lapp)", "Lapp's Armor", DS3LocationCategory.ARMOR, + npc = True, shop = True), + DS3LocationData("RC: Lapp's Gauntlets (Lapp)", "Lapp's Gauntlets", + DS3LocationCategory.ARMOR, npc = True, shop = True), + DS3LocationData("RC: Lapp's Leggings (Lapp)", "Lapp's Leggings", DS3LocationCategory.ARMOR, + npc = True, shop = True), ], # Unlockable shops. We only bother creating a "region" for these for shops that are locked # behind keys and always have items available either through the shop or through the NPC's # ashes. "Greirat's Shop": [ - DS3LocationData("Greirat: Blue Tearstone Ring", "Blue Tearstone Ring", DS3LocationCategory.RING, - offline = '01,0:50006120::', npc = True), - DS3LocationData("Greirat: Ember #1", "Ember", DS3LocationCategory.MISC, + DS3LocationData("FS: Blue Tearstone Ring (Greirat)", "Blue Tearstone Ring", + DS3LocationCategory.RING, offline = '01,0:50006120::', npc = True), + DS3LocationData("FS: Ember (Greirat)", "Ember", DS3LocationCategory.MISC, offline = "99,0:-1:110000,120000,70000110:", shop = True, npc = True), # Undead Settlement rewards - DS3LocationData("Greirat: Divine Blessing #1", "Divine Blessing", DS3LocationCategory.MISC, - offline = '99,0:-1:110000,120000,70000150,70000175:', missable = True, shop = True, npc = True), - DS3LocationData("Greirat: Ember #2", "Ember", DS3LocationCategory.MISC, - offline = '99,0:-1:110000,120000,70000150,70000175:', missable = True, shop = True, npc = True), + DS3LocationData("FS: Divine Blessing (Greirat from US)", "Divine Blessing", + DS3LocationCategory.MISC, + offline = '99,0:-1:110000,120000,70000150,70000175:', missable = True, + shop = True, npc = True), + DS3LocationData("FS: Ember (Greirat from US)", "Ember", DS3LocationCategory.MISC, + offline = '99,0:-1:110000,120000,70000150,70000175:', missable = True, + shop = True, npc = True), # Irityhll rewards - DS3LocationData("Greirat: Divine Blessing #2", "Divine Blessing", DS3LocationCategory.MISC, - offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), - DS3LocationData("Greirat: Hidden Blessing", "Hidden Blessing", DS3LocationCategory.MISC, - offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), - DS3LocationData("Greirat: Titanite Scale", "Titanite Scale", DS3LocationCategory.UPGRADE, - offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), - DS3LocationData("Greirat: Twinkling Titanite", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), + DS3LocationData("FS: Divine Blessing (Greirat from IBV)", "Divine Blessing", + DS3LocationCategory.MISC, + offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, + shop = True, npc = True), + DS3LocationData("FS: Hidden Blessing (Greirat from IBV)", "Hidden Blessing", + DS3LocationCategory.MISC, + offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, + shop = True, npc = True), + DS3LocationData("FS: Titanite Scale (Greirat from IBV)", "Titanite Scale", + DS3LocationCategory.UPGRADE, + offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, + shop = True, npc = True), + DS3LocationData("FS: Twinkling Titanite (Greirat from IBV)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE, + offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, + shop = True, npc = True), # Lothric rewards (from Shrine Handmaid) - DS3LocationData("Greirat: Ember #3", "Twinkling Titanite", DS3LocationCategory.UPGRADE, - offline = '99,0:-1:110000,120000,70000152,70000177:', missable = True, shop = True, npc = True), + DS3LocationData("FS: Ember (shop for Greirat's Ashes)", "Twinkling Titanite", + DS3LocationCategory.UPGRADE, + offline = '99,0:-1:110000,120000,70000152,70000177:', missable = True, + shop = True, npc = True), ], "Karla's Shop": [ - DS3LocationData("Karla: Affinity", "Affinity", DS3LocationCategory.SPELL, + DS3LocationData("FS: Affinity (Karla)", "Affinity", DS3LocationCategory.SPELL, shop = True, npc = True), - DS3LocationData("Karla: Dark Edge", "Dark Edge", DS3LocationCategory.SPELL, + DS3LocationData("FS: Dark Edge (Karla)", "Dark Edge", DS3LocationCategory.SPELL, shop = True, npc = True), # Quelana Pyromancy Tome - DS3LocationData("Karla: Firestorm", "Firestorm", DS3LocationCategory.SPELL, - missable = True, shop = True, npc = True), - DS3LocationData("Karla: Rapport", "Rapport", DS3LocationCategory.SPELL, - missable = True, shop = True, npc = True), - DS3LocationData("Karla: Fire Whip", "Fire Whip", DS3LocationCategory.SPELL, - missable = True, shop = True, npc = True), + DS3LocationData("FS: Firestorm (Karla for Quelana Tome)", "Firestorm", + DS3LocationCategory.SPELL, missable = True, shop = True, npc = True), + DS3LocationData("FS: Rapport (Karla for Quelana Tome)", "Rapport", + DS3LocationCategory.SPELL, missable = True, shop = True, npc = True), + DS3LocationData("FS: Fire Whip (Karla for Quelana Tome)", "Fire Whip", + DS3LocationCategory.SPELL, missable = True, shop = True, npc = True), # Grave Warden Pyromancy Tome - DS3LocationData("Karla: Black Flame", "Black Flame", DS3LocationCategory.SPELL, - missable = True, shop = True, npc = True), - DS3LocationData("Karla: Black Fire Orb", "Black Fire Orb", DS3LocationCategory.SPELL, - missable = True, shop = True, npc = True), + DS3LocationData("FS: Black Flame (Karla for Grave Warden Tome)", "Black Flame", + DS3LocationCategory.SPELL, missable = True, shop = True, npc = True), + DS3LocationData("FS: Black Fire Orb (Karla for Grave Warden Tome)", "Black Fire Orb", + DS3LocationCategory.SPELL, missable = True, shop = True, npc = True), # Deep Braille Divine Tome. This can also be given to Irina but it'll fail her quest - DS3LocationData("Karla: Gnaw", "Gnaw", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("Karla: Deep Protection", "Deep Protection", DS3LocationCategory.SPELL, + DS3LocationData("FS: Gnaw (Karla for Deep Braille Tome)", "Gnaw", DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Deep Protection (Karla for Deep Braille Tome)", "Deep Protection", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), # Londor Braille Divine Tome. This can also be given to Irina but it'll fail her quest - DS3LocationData("Karla: Vow of Silence", "Vow of Silence", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("Karla: Dark Blade", "Dark Blade", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), - DS3LocationData("Karla: Dead Again", "Dead Again", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + DS3LocationData("FS: Vow of Silence (Karla for Londor Tome)", "Vow of Silence", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Dark Blade (Karla for Londor Tome)", "Dark Blade", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Dead Again (Karla for Londor Tome)", "Dead Again", + DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), # Drops on death. Missable because the player would have to decide between killing her or # seeing everything she sells. - DS3LocationData("Karla: Karla's Pointed Hat", "Karla's Pointed Hat", DS3LocationCategory.ARMOR, - offline = '07,0:50006150::', missable = True, drop = True, npc = True), - DS3LocationData("Karla: Karla's Coat", "Karla's Coat", DS3LocationCategory.ARMOR, - offline = '07,0:50006150::', missable = True, drop = True, npc = True), - DS3LocationData("Karla: Karla's Gloves", "Karla's Gloves", DS3LocationCategory.ARMOR, - offline = '07,0:50006150::', missable = True, drop = True, npc = True), - DS3LocationData("Karla: Karla's Trousers", "Karla's Trousers", DS3LocationCategory.ARMOR, + DS3LocationData("FS: Karla's Pointed Hat (kill Karla)", "Karla's Pointed Hat", + DS3LocationCategory.ARMOR, offline = '07,0:50006150::', missable = True, + drop = True, npc = True), + DS3LocationData("FS: Karla's Coat (kill Karla)", "Karla's Coat", DS3LocationCategory.ARMOR, offline = '07,0:50006150::', missable = True, drop = True, npc = True), + DS3LocationData("FS: Karla's Gloves (kill Karla)", "Karla's Gloves", + DS3LocationCategory.ARMOR, offline = '07,0:50006150::', missable = True, + drop = True, npc = True), + DS3LocationData("FS: Karla's Trousers (kill Karla)", "Karla's Trousers", + DS3LocationCategory.ARMOR, offline = '07,0:50006150::', missable = True, + drop = True, npc = True), ], } diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 36410f3d87f2..3f27543bbab2 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -272,7 +272,10 @@ def create_region(self, region_name, location_table) -> Region: # Mark Red Eye Orb as missable if key locations aren't being randomized, because the # Lift Chamber Key is missable by default. - if not self.options.enable_key_locations and location.name == "HWL: Red Eye Orb": + if ( + not self.options.enable_key_locations + and location.name == "HWL: Red Eye Orb (wall tower, miniboss)" + ): new_location.progress_type = LocationProgressType.EXCLUDED else: # Don't allow Siegward's Storm Ruler to mark Yhorm as defeatable. @@ -472,110 +475,226 @@ def set_rules(self) -> None: # Define the access rules to some specific locations if self.options.enable_key_locations: - self._add_location_rule("HWL: Red Eye Orb", "Lift Chamber Key") - self._add_location_rule("ID: Bellowing Dragoncrest Ring", "Jailbreaker's Key") - self._add_location_rule("ID: Covetous Gold Serpent Ring", "Old Cell Key") - self._add_location_rule("UG: Hornet Ring", "Small Lothric Banner") + self._add_location_rule("HWL: Red Eye Orb (wall tower, miniboss)", + "Lift Chamber Key") + self._add_location_rule("ID: Bellowing Dragoncrest Ring (drop from B1 towards pit)", + "Jailbreaker's Key") + self._add_location_rule("ID: Covetous Gold Serpent Ring (Siegward's cell)", "Old Cell Key") + self._add_location_rule("UG: Hornet Ring (environs, right of main path)", + "Small Lothric Banner") self._add_entrance_rule("Karla's Shop", "Jailer's Key Ring") # Ashes - self._add_location_rule(["FS: Alluring Skull", "FS: Ember (Mortician)", "FS: Grave Key"], - "Mortician's Ashes") - self._add_location_rule(["FS: Life Ring", "FS: Hidden Blessing #2"], "Dreamchaser's Ashes") - self._add_location_rule("FS: Lloyd's Shield Ring", "Paladin's Ashes") - self._add_location_rule("FS: Ember (Grave Warden)", "Grave Warden's Ashes") - self._add_location_rule([ - "FS: Karla's Pointed Hat", "FS: Karla's Coat", "FS: Karla's Gloves", - "FS: Karla's Trousers" - ], "Prisoner Chief's Ashes") - self._add_location_rule([ - "FS: Xanthous Overcoat", "FS: Xanthous Gloves", "FS: Xanthous Trousers" - ], "Xanthous Ashes") - self._add_location_rule("FS: Ember (Dragon Chaser)", "Dragon Chaser's Ashes") - self._add_location_rule([ - "FS: Washing Pole", "FS: Eastern Helm", "FS: Eastern Armor", "FS: Eastern Gauntlets", - "FS: Eastern Leggings", "FS: Wood Grain Ring", - ], "Easterner's Ashes") - self._add_location_rule([ - "FS: Millwood Knight Helm", "FS: Millwood Knight Armor", - "FS: Millwood Knight Gauntlets", "FS: Millwood Knight Leggings", "FS: Refined Gem", - ], "Captain's Ashes") + ashes = { + "Mortician's Ashes": ["Alluring Skull", "Ember", "Grave Key"], + "Dreamchaser's Ashes": ["Life Ring", "Hidden Blessing"], + "Paladin's Ashes": ["Lloyd's Shield Ring"], + "Grave Warden's Ashes": ["Ember"], + "Prisoner Chief's Ashes": [ + "Karla's Pointed Hat", "Karla's Coat", "Karla's Gloves", "Karla's Trousers" + ], + "Xanthous Ashes": ["Xanthous Overcoat", "Xanthous Gloves", "Xanthous Trousers"], + "Dragon Chaser's Ashes": ["Ember"], + "Easterner's Ashes": [ + "Washing Pole", "Eastern Helm", "Eastern Armor", "Eastern Gauntlets", + "Eastern Leggings", "Wood Grain Ring", + ], + "Captain's Ashes": [ + "Millwood Knight Helm", "Millwood Knight Armor", "Millwood Knight Gauntlets", + "Millwood Knight Leggings", "Refined Gem", + ] + } + for (ash, items) in ashes.items(): + self._add_location_rule([f"FS: {item} ({ash})" for item in items], ash) + + # Soul transposition + transpositions = [ + ( + "Soul of Boreal Valley Vordt", "Vordt", + ["Vordt's Great Hammer", "Pontiff's Left Eye"] + ), + ("Soul of Rosaria", "Rosaria", ["Bountiful Sunlight"]), + ("Soul of Aldrich", "Aldrich", ["Darkmoon Longbow", "Lifehunt Scythe"]), + ( + "Soul of the Rotted Greatwood", "Greatwood", + ["Hollowslayer Greatsword", "Arstor's Spear"] + ), + ("Soul of a Crystal Sage", "Sage", ["Crystal Sage's Rapier", "Crystal Hail"]), + ("Soul of the Deacons of the Deep", "Deacons", ["Cleric's Candlestick", "Deep Soul"]), + ("Soul of a Stray Demon", "Stray Demon", ["Havel's Ring", "Boulder Heave"]), + ( + "Soul of the Blood of the Wolf", "Abyss Watchers", + ["Farron Greatsword", "Wolf Knight's Greatsword"] + ), + ("Soul of High Lord Wolnir", "Wolnir", ["Wolnir's Holy Sword", "Black Serpent"]), + ("Soul of a Demon", "Fire Demon", ["Demon's Greataxe", "Demon's Fist"]), + ( + "Soul of the Old Demon King", "Old Demon King", + ["Old King's Great Hammer", "Chaos Bed Vestiges"] + ), + ( + "Soul of Pontiff Sulyvahn", "Pontiff", + ["Greatsword of Judgment", "Profaned Greatsword"] + ), + ("Soul of Yhorm the Giant", "Yhorm", ["Yhorm's Great Machete", "Yhorm's Greatshield"]), + ("Soul of the Dancer", "Dancer", ["Dancer's Enchanted Swords", "Soothing Sunlight"]), + ( + "Soul of Dragonslayer Armour", "Dragonslayer", + ["Dragonslayer Greataxe", "Dragonslayer Greatshield"] + ), + ( + "Soul of Consumed Oceiros", "Oceiros", + ["Moonlight Greatsword", "White Dragon Breath"] + ), + ( + "Soul of the Twin Princes", "Princes", + ["Lorian's Greatsword", "Lothric's Holy Sword"] + ), + ("Soul of Champion Gundyr", "Champion", ["Gundyr's Halberd", "Prisoner's Chain"]), + ( + "Soul of the Nameless King", "Nameless", + ["Storm Curved Sword", "Dragonslayer Swordspear", "Lightning Storm"] + ), + ("Soul of the Lords", "Cinder", ["Firelink Greatsword", "Sunlight Spear"]), + ("Soul of Sister Friede", "Friede", ["Friede's Great Scythe", "Rose of Ariandel"]), + ("Soul of the Demon Prince", "Demon Prince", ["Demon's Scar", "Seething Chaos"]), + ("Soul of Darkeater Midir", "Midir", ["Frayed Blade", "Old Moonlight"]), + ("Soul of Slave Knight Gael", "Gael", ["Gael's Greatsword", "Repeating Crossbow"]), + ] + for (soul, soul_name, items) in transpositions: + self._add_location_rule([ + f"FS: {item} (Ludleth for {soul_name})" for item in items + ], soul) # List missable locations even though they never contain progression items so that the game # knows what sphere they're in. This is especially useful for item smoothing. We could add # rules for boss transposition items as well, but then we couldn't freely reorder boss soul # locations for smoothing. - self._add_location_rule("FS: Lift Chamber Key", "Pale Tongue") - self._add_location_rule(["AP: Twinkling Dragon Head Stone", "AP: Hawkwood's Swordgrass"], - "Twinkling Dragon Torso Stone") + self._add_location_rule("FS: Lift Chamber Key (Leonhard)", "Pale Tongue") + self._add_location_rule([ + "FK: Twinkling Dragon Head Stone (Hawkwood drop)", + "FS: Hawkwood's Swordgrass (Andre after gesture in AP summit)" + ], "Twinkling Dragon Torso Stone") # Shop unlocks + shop_unlocks = { + "Cornyx": [ + ( + "Great Swamp Pyromancy Tome", "Great Swamp Tome", + ["Poison Mist", "Fire Orb", "Profuse Sweat", "Bursting Fireball"] + ), + ( + "Carthus Pyromancy Tome", "Carthus Tome", + ["Acid Surge", "Carthus Flame Arc", "Carthus Beacon"] + ), + ("Izalith Pyromancy Tome", "Izalith Tome", ["Great Chaos Fire Orb", "Chaos Storm"]), + ], + "Irina": [ + ( + "Braille Divine Tome of Carim", "Tome of Carim", + ["Med Heal", "Tears of Denial", "Force"] + ), + ( + "Braille Divine Tome of Lothric", "Tome of Lothric", + ["Bountiful Light", "Magic Barrier", "Blessed Weapon"] + ), + ], + "Orbeck": [ + ("Sage's Scroll", "Sage's Scroll", ["Great Farron Dart", "Farron Hail"]), + ( + "Golden Scroll", "Golden Scroll", + [ + "Cast Light", "Repair", "Hidden Weapon", "Hidden Body", + "Twisted Wall of Light" + ], + ), + ("Logan's Scroll", "Logan's Scroll", ["Homing Soulmass", "Soul Spear"]), + ( + "Crystal Scroll", "Crystal Scroll", + ["Homing Crystal Soulmass", "Crystal Soul Spear", "Crystal Magic Weapon"] + ), + ], + "Karla": [ + ("Quelana Pyromancy Tome", "Quelana Tome", ["Firestorm", "Rapport", "Fire Whip"]), + ( + "Grave Warden Pyromancy Tome", "Grave Warden Tome", + ["Black Flame", "Black Fire Orb"] + ), + ("Deep Braille Divine Tome", "Deep Braille Tome", ["Gnaw", "Deep Protection"]), + ( + "Londor Braille Divine Tome", "Londor Tome", + ["Vow of Silence", "Dark Blade", "Dead Again"] + ), + ], + } + for (shop, unlocks) in shop_unlocks.items(): + for (key, key_name, items) in unlocks: + self._add_location_rule( + [f"FS: {item} ({shop} for {key_name})" for item in items], key) + self._add_location_rule([ - "US: Poison Mist", "US: Fire Orb", "US: Profuse Sweat", "US: Bursting Fireball" - ], "Great Swamp Pyromancy Tome") - self._add_location_rule(["US: Acid Surge", "US: Carthus Flame Arc", "US: Carthus Beacon"], - "Carthus Pyromancy Tome") - self._add_location_rule(["US: Great Chaos Fire Orb", "US: Chaos Storm"], - "Izalith Pyromancy Tome") - self._add_location_rule(["US: Med Heal", "US: Tears of Denial", "US: Force"], - "Braille Divine Tome of Carim") - self._add_location_rule(["US: Bountiful Light", "US: Magic Barrier", "US: Blessed Weapon"], - "Braille Divine Tome of Lothric") - self._add_location_rule(["RS: Great Farron Dart", "RS: Farron Hail"], "Sage's Scroll") - self._add_location_rule([ - "RS: Cast Light", "RS: Repair", "RS: Hidden Weapon", "RS: Hidden Body", - "RS: Twisted Wall of Light" - ], "Golden Scroll") - self._add_location_rule(["RS: Homing Soulmass", "RS: Soul Spear"], "Logan's Scroll") - self._add_location_rule([ - "RS: Homing Crystal Soulmass", "RS: Crystal Soul Spear", "RS: Crystal Magic Weapon" - ], "Logan's Scroll") - self._add_location_rule([ - "Greirat: Divine Blessing #1", "Greirat: Ember #2", "Greirat: Divine Blessing #2", - "Greirat: Hidden Blessing", "Greirat: Titanite Scale", "Greirat: Twinkling Titanite", - "Greirat: Ember #3" - ], "Loretta's Bone") + "FS: Divine Blessing (Greirat from US)", + "FS: Ember (Greirat from US)", + ], lambda state: state.can_reach("Go To Undead Settlement", "Entrance", self.player)) self._add_location_rule([ - "Greirat: Divine Blessing #2", "Greirat: Hidden Blessing", "Greirat: Titanite Scale", - "Greirat: Twinkling Titanite", "Greirat: Ember #3" - ], "Small Doll") - self._add_location_rule("Greirat: Ember #3", "Grand Archives Key") - self._add_location_rule(["Karla: Firestorm", "Karla: Rapport", "Karla: Fire Whip"], - "Quelana Pyromancy Tome") - self._add_location_rule(["Karla: Black Flame", "Karla: Black Fire Orb"], - "Grave Warden Pyromancy Tome") - self._add_location_rule(["Karla: Gnaw", "Karla: Deep Protection"], - "Deep Braille Divine Tome") - self._add_location_rule(["Karla: Vow of Silence", "Karla: Dark Blade", "Karla: Dead Again"], - "Londor Braille Divine Tome") + "FS: Divine Blessing (Greirat from IBV)", + "FS: Hidden Blessing (Greirat from IBV)", + "FS: Titanite Scale (Greirat from IBV)", + "FS: Twinkling Titanite (Greirat from IBV)", + "FS: Ember (shop for Greirat's Ashes)" + ], lambda state: state.can_reach( + "Go To Irithyll of the Boreal Valley", + "Entrance", + self.player + )) + self._add_location_rule( + "FS: Ember (shop for Greirat's Ashes)", + lambda state: state.can_reach("Go To Grand Archives", "Entrance", self.player) + ) # Crow items - self._add_location_rule("FSBT: Ring of Sacrifice", "Loretta's Bone") - self._add_location_rule("FSBT: Titanite Scale #1", "Avelyn") - self._add_location_rule("FSBT: Titanite Slab", "Coiled Sword Fragment") - self._add_location_rule("FSBT: Iron Leggings", "Seed of a Giant Tree") - self._add_location_rule("FSBT: Armor of the Sun", "Siegbräu") - self._add_location_rule("FSBT: Lucatiel's Mask", "Vertebra Shackle") - self._add_location_rule("FSBT: Lightning Gem", "Xanthous Crown") - self._add_location_rule("FSBT: Sunlight Shield", "Mendicant's Staff") - self._add_location_rule("FSBT: Titanite Scale #2", "Blacksmith Hammer") - self._add_location_rule("FSBT: Twinkling Titanite #3", "Large Leather Shield") - self._add_location_rule("FSBT: Blessed Gem", "Moaning Shield") - self._add_location_rule("FSBT: Hollow Gem", "Eleonora") + crow = { + "Loretta's Bone": "Ring of Sacrifice", + # "Avelyn": "Titanite Scale", # Missing from offline randomizer + "Coiled Sword Fragment": "Titanite Slab", + "Seed of a Giant Tree": "Iron Leggings", + "Siegbräu": "Armor of the Sun", + "Vertebra Shackle": "Lucatiel's Mask", + "Xanthous Crown": "Lightning Gem", + "Mendicant's Staff": "Sunlight Shield", + "Blacksmith Hammer": "Titanite Scale", + "Large Leather Shield": "Twinkling Titanite", + "Moaning Shield": "Blessed Gem", + "Eleonora": "Hollow Gem", + } + for (given, received) in crow.items(): + self._add_location_rule(f"FSBT: {received} (crow for {given})", given) # The offline randomizer edits events to guarantee that Greirat won't go to Lothric until # Grand Archives is available, so his shop will always be available one way or another. self._add_entrance_rule("Greirat's Shop", "Cell Key") - for item in ["Leonhard's Garb", "Leonhard's Gauntlets", "Leonhard's Trousers"]: - self._add_location_rule("AL: " + item, "Black Eye Orb") + self._add_location_rule([ + f"FS: {item} (shop after killing Leonhard)" + for item in ["Leonhard's Garb", "Leonhard's Gauntlets", "Leonhard's Trousers"] + ], "Black Eye Orb") # You could just kill NPCs for these, but it's more fun to ensure the player can do # their quests. - self._add_location_rule("FS: Lift Chamber Key", "Pale Tongue") - self._add_location_rule("AP: Hawkwood's Swordgrass", "Twinkling Dragon Torso Stone") - self._add_location_rule("ID: Prisoner Chief's Ashes", "Jailer's Key Ring") + self._add_location_rule("HWL: Basin of Vows (Emma)", "Small Doll") + self._add_location_rule( + "ID: Prisoner Chief's Ashes (B2 near, locked cell by stairs)", + "Jailer's Key Ring" + ) + self._add_location_rule([ + "US: Old Sage's Blindfold (kill Cornyx)", "US: Cornyx's Garb (kill Cornyx)", + "US: Cornyx's Wrap (kill Cornyx)", "US: Cornyx's Skirt (kill Cornyx)" + ], lambda state: ( + state.has("Great Swamp Pyromancy Tome", self.player) + and state.has("Carthus Pyromancy Tome", self.player) + and state.has("Izalith Pyromancy Tome", self.player) + )) # Make sure that the player can keep Orbeck around by giving him at least one scroll # before killing Abyss Watchers. @@ -602,11 +721,53 @@ def has_any_scroll(state): # useful for smooth item placement. self._add_location_rule("HWL: Soul of the Dancer", has_any_scroll) - gotthard_corpse_rule = lambda state: \ - (state.can_reach("AL: Cinders of a Lord - Aldrich", "Location", self.player) and - state.can_reach("PC: Cinders of a Lord - Yhorm the Giant", "Location", self.player)) - self._add_location_rule("LC: Grand Archives Key", gotthard_corpse_rule) - self._add_location_rule("LC: Gotthard Twinswords", gotthard_corpse_rule) + self._add_location_rule([ + "LC: Grand Archives Key (by Grand Archives door, after PC and AL bosses)", + "LC: Gotthard Twinswords (by Grand Archives door, after PC and AL bosses)" + ], lambda state: ( + state.can_reach("AL: Cinders of a Lord - Aldrich", "Location", self.player) and + state.can_reach("PC: Cinders of a Lord - Yhorm the Giant", "Location", self.player) + )) + + self._add_location_rule([ + "FS: Morne's Great Hammer (Eygon)", + "FS: Moaning Shield (Eygon)" + ], lambda state: ( + state.can_reach("LC: Soul of Dragonslayer Armour", "Location", self.player) and + state.can_reach("FK: Soul of the Blood of the Wolf", "Location", self.player) + )) + + self._add_location_rule([ + "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)", + ], lambda state: state.can_reach( + "AP: Drakeblood Greatsword (mausoleum, NPC drop)", + "Location", + self.player + )) + + self._add_location_rule([ + "FK: Havel's Helm (upper keep, after killing AP belfry roof NPC)", + "FK: Havel's Armor (upper keep, after killing AP belfry roof NPC)", + "FK: Havel's Gauntlets (upper keep, after killing AP belfry roof NPC)", + "FK: Havel's Leggings (upper keep, after killing AP belfry roof NPC)", + ], lambda state: state.can_reach( + "AP: Dragon Tooth (belfry roof, NPC drop)", + "Location", + self.player + )) + + self._add_location_rule([ + "RC: Dragonhead Shield (streets monument, across bridge)", + "RC: Large Soul of a Crestfallen Knight (streets monument, across bridge)", + "RC: Divine Blessing (streets monument, mob drop)", + "RC: Lapp's Helm (Lapp)", + "RC: Lapp's Armor (Lapp)", + "RC: Lapp's Gauntlets (Lapp)", + "RC: Lapp's Leggings (Lapp)", + ], "Chameleon") # Forbid shops from carrying items with multiple counts (the offline randomizer has its own # logic for choosing how many shop items to sell), and from carring soul items. @@ -621,9 +782,12 @@ def has_any_scroll(state): # This particular location is bugged, and will drop two copies of whatever item is placed # there. - if self.is_location_available("US: Young White Branch #2"): - add_item_rule(self.multiworld.get_location("US: Young White Branch #2", self.player), - lambda item: item.player == self.player and not item.data.unique) + if self.is_location_available("US: Young White Branch (by white tree #2)"): + loc = self.multiworld.get_location( + "US: Young White Branch (by white tree #2)", + self.player + ) + add_item_rule(loc, lambda item: item.player == self.player and not item.data.unique) # Make sure the Storm Ruler is available BEFORE Yhorm the Giant if self.yhorm_location.region: @@ -689,8 +853,8 @@ def pre_fill(self) -> None: # Fill this manually so that, if very few slots are available in Cemetery of Ash, this # doesn't get locked out by bad rolls on the next two fills. if self.yhorm_location.name == 'Iudex Gundyr': - self._fill_local_item("Storm Ruler", ["Cemetery of Ash"], - lambda location: location.name != "CA: Coiled Sword", + self._fill_local_item("Storm Ruler", {"Cemetery of Ash"}, + lambda location: location.name != "CA: Coiled Sword (boss drop)", mandatory = True) # Don't place this in the multiworld because it's necessary almost immediately, and don't diff --git a/worlds/dark_souls_3/detailed_location_descriptions.py b/worlds/dark_souls_3/detailed_location_descriptions.py new file mode 100644 index 000000000000..23355ac2f460 --- /dev/null +++ b/worlds/dark_souls_3/detailed_location_descriptions.py @@ -0,0 +1,94 @@ +# python -m worlds.dark_souls_3.detailed_location_descriptions \ +# worlds/dark_souls_3/detailed_location_descriptions.py + +from collections import defaultdict +import html +import os +import re +import requests +import yaml + +from .Locations import location_dictionary + + +location_re = re.compile(r'^([A-Z0-9]+): (.*?)(?:$| \()') + +if __name__ == '__main__': + # TODO: update this to the main branch of the main randomizer once Archipelago support is merged + url = 'https://raw.githubusercontent.com/nex3/SoulsRandomizers/archipelago-server/dist/Base/annotations.txt' + response = requests.get(url) + if response.status_code != 200: + raise Exception(f"Got {response.status_code} when downloading offline randomizer locations") + annotations = yaml.load(response.text, Loader=yaml.Loader) + + offline_to_archi_regions = { + area['Name']: area['Archipelago'] + for area in annotations['Areas'] + } + + descriptions_by_key = {slot['Key']: slot['Text'] for slot in annotations['Slots']} + + # A map from (region, item name) pairs to all the descriptions that match those pairs. + descriptions_by_location = defaultdict(list) + + # A map from item names to all the descriptions for those item names. + descriptions_by_item = defaultdict(list) + + for slot in annotations['Slots']: + region = offline_to_archi_regions[slot['Area']] + for item in slot['DebugText']: + name = item.split(" - ")[0] + descriptions_by_location[(region, name)].append(slot['Text']) + descriptions_by_item[name].append(slot['Text']) + original_descriptions_by_location = dict(descriptions_by_location) + + + location_names_to_descriptions = {} + for location in location_dictionary.values(): + if location.ap_code is None: continue + if location.offline: + location_names_to_descriptions[location.name] = descriptions_by_key[location.offline] + continue + + match = location_re.match(location.name) + if not match: + raise Exception(f'Location name "{location.name}" doesn\'t match expected format.') + + item_candidates = descriptions_by_item[match[2]] + if len(item_candidates) == 1: + location_names_to_descriptions[location.name] = item_candidates[0] + continue + + key = (match[1], match[2]) + if key not in descriptions_by_location: + raise Exception(f'No offline randomizer location found matching "{match[1]}: {match[2]}".') + + candidates = descriptions_by_location[key] + if len(candidates) == 0: + raise Exception( + f'There are only {len(original_descriptions_by_location[key])} locations in the ' + + f'offline randomizer matching "{match[1]}: {match[2]}", but there are more in ' + + 'Archipelago.' + ) + + location_names_to_descriptions[location.name] = candidates.pop(0) + + table = "\n" + for (name, description) in sorted( + location_names_to_descriptions.items(), + key = lambda pair: pair[0] + ): + table += f"\n" + table += "
Location nameDetailed description
{html.escape(name)}{html.escape(description)}
\n" + + with open(os.path.join(os.path.dirname(__file__), 'docs/locations_en.md'), 'r+') as f: + original = f.read() + start_flag = "\n" + start = original.index(start_flag) + len(start_flag) + end = original.index("") + + f.seek(0) + f.write(original[:start] + table + original[end:]) + f.truncate() + + print("Updated docs/locations_en.md!") diff --git a/worlds/dark_souls_3/docs/en_Dark Souls III.md b/worlds/dark_souls_3/docs/en_Dark Souls III.md index e844925df1ea..ecae2e52b3be 100644 --- a/worlds/dark_souls_3/docs/en_Dark Souls III.md +++ b/worlds/dark_souls_3/docs/en_Dark Souls III.md @@ -23,6 +23,10 @@ The goal is to find the four "Cinders of a Lord" items randomized into the multi Practically anything can be found in other worlds including pieces of armor, upgraded weapons, key items, consumables, spells, upgrade materials, etc... -## What does another world's item look like in Dark Souls III? +## What do Dark Souls III location names mean? -In Dark Souls III, items which are sent to other worlds appear as Prism Stones. +Location names have to pack a lot of information into very little space. To better understand them, +check out the [location guide], which explains all the names used in locations and provides more +detailed descriptions for each individual location. + +[location guide]: /tutorial/Dark Souls III/locations/en diff --git a/worlds/dark_souls_3/docs/locations.md b/worlds/dark_souls_3/docs/locations.md new file mode 100644 index 000000000000..159b9d25192b --- /dev/null +++ b/worlds/dark_souls_3/docs/locations.md @@ -0,0 +1,650 @@ +# Dark Souls III Locations + +All locations begin with an abbreviation indicating their general region. Most +locations have a set of landmarks that are used in location names to keep them +short. + +* **FS:** Firelink Shrine +* **FSBT:** Firelink Shrine belltower +* **HWL:** [High Wall of Lothric](#high-wall-of-lothric) +* **US:** [Undead Settlement](#undead-settlement) +* **RS:** [Road of Sacrifices](#road-of-sacrifices) +* **CD:** [Cathedral of the Deep](#cathedral-of-the-deep) +* **FK:** [Farron Keep](#farron-keep) +* **CC:** [Catacombs of Carthus](#catacombs-of-carthus) +* **SL:** [Smouldering Lake](#smouldering-lake) +* **IBV:** [Irithyll of the Boreal Valley](#irithyll-of-the-boreal-valley) +* **ID:** [Irithyll Dungeon](#irithyll-dungeon) +* **PC:** [Profaned Capital](#profaned-capital) +* **AL:** [Anor Londo](#anor-londo) +* **LC:** [Lothric Castle](#lothric-castle) +* **CKG:** [Consumed King's Garden](#consumed-kings-garden) +* **GA:** [Grand Archives](#grand-archives) +* **UG:** [Untended Graves](#untended-graves) +* **AP:** [Archdragon Peak](#archdragon-peak) +* **PW1:** [Painted World of Ariandel (Before Contraption)](#painted-world-of-ariandel-before-contraption) +* **PW2:** [Painted World of Ariandel (After Contraption)](#painted-world-of-ariandel-after-contraption) +* **DH:** [Dreg Heap](#dreg-heap) +* **RC:** [Ringed City](#ringed-city) + +General notes: + +* "Lizard" always refers to a small crystal lizard. + +* "Miniboss" are large enemies that don't respawn after being killed and usually + drop some sort of treasure, such as Boreal Outrider Knights and Ravenous + Crystal Lizards. They usually don't have boss bars, but a few of them do. + +* NPC quest items are always in the first location you can get them _without_ + killing the NPC or ending the quest early. + +## High Wall of Lothric + +* **Back tower:** The tower _behind_ the High Wall of Lothric bonfire, past the + path to the shortcut elevator. + +* **Corpse tower:** The first tower after the High Wall of Lothric bonfire, with + a dead Wyvern on top of it. + +* **Fire tower:** The second tower after the High Wall of Lothric bonfire, where + a living Wyvern lands and breathes fire at you. + +* **Flame plaza:** The open area with many items where the Wyvern breathes fire. + +* **Wall tower:** The third tower after the High Wall of Lothric bonfire, with + the Tower on the Wall bonfire. + +* **Fort:** The large building after the Tower on the Wall bonfire, with the + transforming hollow on top. + + * "Entry": The first room you enter after descending the ladder from the roof. + + * "Walkway": The top floor of the tall room, with a path around the edge + hidden by a large wheel. + + * "Mezzanine": The middle floor of the tall room, with a chest. + + * "Ground": The bottom floor of the tall room, with an anvil and many mobs. + +* **Fountain:** The large fountain with many dead knights around it, where the + Winged Knight patrols in vanilla. + +* **Shortcut:** The unlockable path between the promenade and the High Wall of + Lothric bonfire, including both the elevator and the area at its base. + +* **Promenade:** The long, wide path between the two boss arenas. + +## Undead Settlement + +* **Burning tree:** The tree near the beginning of the region, with the + Cathedral Evangelist in front of it in vanilla. + +* **Hanging corpse room:** The dark room to the left of the burning tree with + many hanging corpses inside, on the way to the Dilapidated Bridge bonfire. + +* **Stable:** The building complex across the bridge to the right of the burning + tree. + +* **White tree:** The birch tree by the Dilapidated Bridge bonfire, where the + giant shoots arrows. + +* **Sewer:** The underground passage between the + +* **Chasm:** The chasm underneath the bridge on the way to the tower. It's + possible to get into the chasm without a key by dropping down next to Eygon of + Carim with a full health bar. + +* **Tower:** The tower at the end of the region with the giant archer at the + top. + +* **Tower village:** The village reachable from the tower, where the Fire Giant + patrols in vanilla. + +## Road of Sacrifices + +The area after the Crystal Sage is considered part of the Cathedral of the Deep +region. + +* **Road:** The path from the Road of Sacrifices bonfire to the Halfway Fortress + bonfire. + +* **Woods:** The wooded area on land, after the Halfway Fortress bonfire and + surrounding the Crucifixion Woods bonfire. + +* **Water:** The watery area, covered in crabs in vanilla. + +* **Deep water:** The area in the water near the ladder to Farron Keep, where + your walking is slowed. + +* **Stronghold:** The stone building complex on the way to Crystal Sage. + + * "Left room" is the room whose entrance is near the Crucifixion Woods + bonfire. + + * "Right room" is the room up the stairs closer to Farron Keep. + +* **Keep perimiter:** The building with the Black Knight and the locked door to + the Farron Keep Perimeter bonfire. + +## Cathedral of the Deep + +* **Path:** The path from Road of Sacrifices to the cathedral proper. + +* **Moat:** The circular path around the base of the area in front of the + cathedral, with the Ravenous Crystal Lizard in vanilla. Only the lowest part + actually has any water. + +* **Graveyard:** The area with respawning enemies up the hill from the Cleansing + Chapel bonfire. + +* **White tree:** The birch tree below the front doors of the chapel and across + the moat from the graveyard, where the giant shoots arrows if he's still + alive. + +* **Lower roofs:** The roofs, flying buttresses, and associated areas to the + right of the front door, which must be traversed before entering the + cathedral. + +* **Upper roofs:** The roofs, flying buttresses, and rafters leading to the + Rosaria's Bedchamber bonfire. + +* **Main hall:** The central and largest room in the cathedral, with the muck + that slows your movement. Divided into the south (with the sleeping giant in + vanilla) and east (with many items) wings, with north pointing towards the + door to the boss. + +* **Side chapel:** The room with rows of pews and the patrolling Cathedral + Knight in vanilla, to the side of the main hall. + +## Farron Keep + +* **Left island:** The large island with the ritual flame, to the left as you + leave the Farron Keep bonfire. + +* **Right island:** The large island with the ritual flame, to the right as you + leave the Farron Keep bonfire. + +* **Hidden cave:** A small cave in the far corner of the map, closest to the + right island. Near a bunch of basilisks in vanilla. + +* **Keep ruins:** The two islands with the Keep Ruins bonfire (bonfire island) + and one of the three ritual fires (ritual island). + +* **White tree**: The birch tree by the ramp down from the keep ruins bonfire + island, where the giant shoots arrows if he's still alive. + +* **Keep proper:** The building with the Old Wolf of Farron bonfire. + +* **Upper keep:** The area on top of the keep proper, reachable from the + elevator from the Old Wolf of Farron bonfire. + +* **Perimeter:** The area from near the Farron Keep Perimeter bonfire, including + the stony section and the path to the boss. + +## Catacombs of Carthus + +All the area up to the Small Doll wall into Irithyll is considered part of the +Catacombs of Carthus region. + +* **Atrium:** The large open area you first enter and the rooms attached to it. + + * "Upper" is the floor you begin on. + * "Lower" is the floor down the short stairs but at the top of the long + stairway that the skeleton ball rolls down. + +* **Crypt:** The enclosed area at the bottom of the long stairway that the + skeleton ball rolls down. + + * "Upper" is the floor the long stairway leads to that also contains the + Catacombs of Carthus bonfire. + * "Lower" is the floor with rats and bonewheels in vanilla. + * "Across" is the area reached by going up a different set of stairs from + downstairs. + +* **Cavern:** The even larger open area past the crypt with the rope bridge to + the boss arena. + +* **Tomb:** The area on the way to Smouldering Lake, reachable by cutting down + the rope bridge and climbing down it. + +* **Irithyll Bridge:** The outdoor bridge leading to Irithyll of the Boreal + Valley. + +## Smouldering Lake + +* **Lake:** The watery area you enter initially, where you get shot at by the + ballista. + +* **Side lake:** The small lake accessible via a passage from the larger one, in + which you face Horace the Hushed as part of his quest. + +* **Ruins main:** The area you first enter after the Demon Ruins bonfire. + + * "Upper" is the floor you begin on. + * "Lower" is the floor down the stairs from upper. + +* **Antechamber:** The area up a different flight of stairs from ruins main + lower, with the Old King's Antechamber bonfire. + +* **Ruins basement:** The area further down from ruins main lower, with a many + basilisks and Knight Slayer Tsorig in vanilla. + +## Irithyll of the Boreal Valley + +This region starts _after_ the Small Doll wall and ends with Pontiff Sulyvahn. +Everything after that, including the contents of Sulyvahn's cathedral is +considered part of Anor Londo. + +* **Central:** The beginning of the region, from the Central Irithyll bonfire up + to the plaza. + +* **Dorhys:** The sobbing mob (a Cathedral Evangelist in vanilla) behind the + locked door opening onto central. Accessed through an illusory railing by the + crystal lizard just before the plaza. + +* **Plaza:** The area in front of and below the cathedral, with a locked door up + to it and a locked elevator to the ascent. + +* **Descent:** The path from the Church of Yorshka bonfire down to the lake. + +* **Lake:** The open watery area outside the room with the Distant Manor + bonfire. + +* **Sewer:** The room between the lake and the beginning of the ascent, filled + with Sewer Centipedes in vanilla. + +* **Ascent:** The path up from the lake to the cathedral, through several + buildings and some open stairs. + +* **Great hall:** The building along the ascent with a large picture of + Gwynevere and several Silver Knights in vanilla. + +## Irithyll Dungeon + +In Irithyll Dungeon locations, "left" and "right" are always oriented facing +from the "near" side of the floor to the "far" side. + +* **B1:** The floor on which the player enters the dungeon, with the Irithyll + Dungeon bonfire. + + * "Near" is the side of the dungeon with the bonfire. + * "Far" is the opposite side. + +* **B2:** The floor directly below B1, which can be reached by going down the + stairs or dropping. + + * "Near" is the same side of the dungeon as the bonfire. + * "Far" is the opposite side. + +* **Pit:** The large room with the Giant Slave and many Rats in vanilla. + +* **Pit lift:** The elevator from the pit up to B1 near, right to the Irithyll + Dungeon bonfire. + +* **B3:** The lowest floor, with Karla's cell, a lift back to B2, and the exit + onwards to Profaned Capital. + + * "Near" is the side with Karla's cell and the the path from the pit. + * "Far" is the opposite side with the mimic. + +* **B3 lift:** The elevator from B3 (near where you can use Path of the Dragon + to go to Archdragon Peak) up to B2 far. + +## Profaned Capital + +* **Tower:** The tower that contains the Profaned Capital bonfire. + +* **Swamp:** The pool of toxic liquid accessible by falling down out of the + lower floor of the tower, going into the corridor to the left, and falling + down a hole. + +* **Chapel:** The building in the swamp, with Monstrosities of Sin in it in + vanilla. + +* **Bridge:** The long bridge from the tower into the palace. + +* **Palace:** The large building carved into the wall of the cavern, full of + chalices and broken pillars. + +## Anor Londo + +This region includes everything after Sulyvahn's cathedral, including its upper +story. + +* **Light cathedral:** The cathedral in which you fight Pontiff Sulyvahn in + vanilla. + +* **Plaza:** The wide open area filled with dead Giant Slaves and a couple live + ones in vanilla. + +* **Walkway:** The path above the plaza leading to the second floor of the light + cathedral, with Deacons in vanilla. + +* **Buttresses:** The flying buttresses that you have to climb to get to the + spiral staircase. "Near" and "far" are relative to the light cathedral, so the + nearest buttress is the one that leads back to the walkway. + +* **Tomb:** The area past the illusory wall just before the spiral staircase, in + which you marry Anri during Yoel and Yuria's quest. + +* **Dark cathedral:** The darkened cathedral just before the Aldrich fight in + vanilla. + +## Lothric Castle + +This region covers everything up the ladder from the Dancer of the Boreal Valley +bonfire up to the door into Grand Archives, except the area to the left of the +ladder which is part of Consumed King's Garden. + +* **Lift:** The elevator from the room straight after the Dancer of the Boreal + Valley bonfire up to just before the boss fight. + +* **Ascent:** The set of stairways and turrets leading from the Lothric Castle + bonfire to the Dragon Barracks bonfire. + +* **Barracks:** The large building with two fire-breathing wyverns across from + the Dragon Barracks bonfire. + +* **Moat:** The ditch beneath the bridge leading to the barracks. + + * The "right path" leads to the right as you face the barracks, around and + above the stairs up to the Dragon Barracks bonfire. + +* **Plaza:** The open area in the center of the barracks, where the two wyverns + breathe fire. + + * "Left" is the enclosed area on the left as you're coming from the Dragon + Barracks bonfire, with the stairs down to the basement. + +* **Basement:** The room beneath plaza left, with the Boreal Outrider in + vanilla. + +* **Dark room:** The large darkened room on the right of the barracks as you're + coming from the Dragon Barracks bonfire, with firebomb-throwing Hollows in + vanilla. + + * "Lower" is the bottom floor that you enter onto from the plaza. + * "Upper" is the top floor with the door to the main hall. + * "Mid" is the middle floor accessible by climbing a ladder from lower or + going down stairs from upper. + +* **Main hall:** The central room of the barracks, behind the gate. + +* **Chapel:** The building to the right just before the stairs to the boss, with + a locked elevator to Grand Archives. + +* **Wyvern room:** The room where you can fight the Pus of Man infecting the + left wyvern, accessible by dropping down to the left of the stairs to the + boss. + +* **Altar:** The building containing the Altar of Sunlight, accessible by + climbing up a ladder onto a roof around the corner from the stairs to the + boss. + +## Consumed King's Garden + +This region covers everything to the left of the ladder up from the Dancer of +the Boreal Valley bonfire up to the illusory wall into Untended Graves. + +* **Balcony:** The walkway accessible by getting off the first elevator halfway + down. + +* **Rotunda:** The building in the center of the toxic pool, with a Cathedral + Knight on it in vanilla. + +* **Lone stairway:** A set of stairs leading nowhere in the far left of the main + area as you enter from the first elevator. + +* **Shortcut:** The path from the locked door into Lothric Castle, through the + room filled with thralls in vanilla, and down a lift. + +* **Tomb:** The area after the boss room. + +## Grand Archives + +* **1F:** The first floor of the Grand Archives, including the first wax pool. + +* **Dark room:** The unlit room on 1F to the right of the wax pool. + +* **2F:** The second floor of the grand archives. It's split into two sections + that are separated by retractable bookshelves. + + * "Early" is the first part you reach and has an outdoor balcony with a ladder + to 3F and a wax pool up a short set of stairs. + * "Late" is the part you can only reach by climbing down from F3, where you + encounter the teleporting miniboss for the final time. + +* **3F:** The third floor of the grand archives, where you encounter the + teleporting miniboss for the second time. Includes the area with a hidden room + with another miniboss. + +* **4F:** The topmost and most well-lit section of bookshelves, overlooking the + rest of the archives. + +* **Rooftops:** The outer rooftop area between 4F and 5F, with Gargoyles in + vanilla. + + * "Lower" is the balcony you can reach by dropping off the rooftops, as well + as the further rooftops leading down to the 2F early balcony. + +* **5F:** The topmost floor of the archives interior, accessible from the + rooftops, with a ladder down to 4F. + +* **Dome:** The domed roof of the Grand Archives, with Ascended Winged Knights + in vanilla. + +* **Rafters:** The narrow walkways above the Grand Archives, accessible by + dropping down from the dome. + +## Untended Graves + +* **Swamp:** The watery area immediately after the Untended graves bonfire, up + to the cemetery. + +* **Cemetery:** The area past where the Cemetery of Ash bonfire would be, up to + the boss arena. + +* **Environs:** The area after the boss and outside the abandoned Firelink + Shrine. + +* **Shrine:** The area inside the abandoned Firelink Shrine. + +## Archdragon Peak + +"Gesture" always means the Path of the Dragon gesture. + +* **Intro:** The first section, from where you warp in from Irithyll Dungeon up + to the first boss fight. + + * "Archway": The large stone archway in front of the boss door. + +* **Fort:** The arena where you fight Ancient Wyvern in vanilla. + + * "Overlook": The area down the stairs from where the Ancient Wyvern first + lands in vanilla, overlooking the fog. + + * "Rotunda": The top of the spiral staircase building, to the left before the + bridge with the chain-axe Man-Serpent in vanilla. + +* **Mausoleum:** The building with the Dragon-Kin Mausoleum bonfire, where + you're warped after the first boss fight. + +* **Walkway:** The path from the mausoleum to the belfry, looking out over + clouds. + + * "Building": The building along the walkway, just before the wyvern in + vanilla. + +* **Belfry:** The building with the Great Belfry bonfire, including the room + with the summoner. + +* **Plaza:** The arena that appears after you defeat Nameless King in vanilla. + +* **Summit:** The path up from the belfry to the final altar at the top of the + mountain. + +## Painted World of Ariandel (Before Contraption) + +This region covers the Ashes of Ariandel DLC up to the point where you must use +the Contraption Key to ascend to the second level of the building and first meet +the painter. + +* **Snowfield:** The area around the Snowfield bonfire, + + * "Upper": The area immediately after the Snowfield bonfire, before the + collapsing overhang, with the Followers in vanilla. + + * "Lower": The snowy tree-filled area after the collapsing overhang, with the + Wolves in vanilla. + + * "Village": The area with broken-down buildings and Millwood Knights in + vanilla. + + * "Tower": The tower by the village, with Millwood Knights in Vanilla. + +* **Bridge:** The rope bridge to the chapel. + + * "Near": The side of the bridge by the Rope Bridge Cave bonfire. + + * "Far": The side of the bridge by the Ariandel Chapel bonfire. + +* **Chapel:** The building with the Ariandel Chapel bonfire and Lady Friede. + +* **Depths:** The area reachable by cutting down the bridge and descending on + the far side, with the Depths of the Painting bonfire. + +* **Settlement:** The area reachable by cutting down the bridge and descending + on the near side, with the Corvian Settlement bonfire. Everything after the + slide down the hill is considered part of the settlement. + + * "Courtyard": The area in front of the settlement, immediately after the + slide. + + * "Main": The main road of the settlement leading up to the locked gate to the + library. Also includes the buildings that are immediately accessible from + this road. + + * "Loop": A side path that loops left from the main road and goes up and + behind the building with the bonfire. + + * "Back": The back alley of the settlement, accessible by dropping down to the + right of the locked gate to the library. Also includes the buildings that + are immediately accessible from this alley. + + * "Roofs": The village rooftops, first accessible by climbing a ladder from + the back alley. Also includes the buildings and items that are first + accessible from the roofs. + + * "Hall": The largest building in the settlement, with two Corvian Knights in + vanilla. + +* **Library:** The building where you use the contraption key, where Vilhelm + appears in vanilla. + +## Painted World of Ariandel (After Contraption) + +This region covers the Ashes of Ariandel DLC past the point where you must use +the Contraption Key to ascend to the second level of the building and first meet +the painter, including the basement beneath the chapel. + +* **Pass:** The mountainous area past the Snowy Mountain Pass bonfire. + +* **Pit:** The area with a large tree and numerous Millwood Knights in vanilla, + reached by a collapsing overhang in the pass. + +* **B1:** The floor immediately below the chapel, first accessible from the + pass. Filled with Giant Flies in vanilla. + +* **B2:** The floor below B1, with lots of fly eggs. Filled with even more Giant + Flies than B1 in vanilla. + +* **B3:** The floor below B2, accessible through an illusory wall. + +* **Rotunda:** The round arena out in the open, accessible by platforming down + tree roots from B3. + +## Dreg Heap + +* **Shop:** Items sold by the Stone-Humped Hag by The Dreg Heap bonfire. + +* **Castle:** The building with The Dreg Heap bonfire, up to the large fall into + the library. + +* **Library:** The building with the stained glass window that you fall into + from the castle. + +* **Church:** The building below and to the right of the library, which the + pillar falls into to make a bridge. + +* **Pantry:** The set of rooms entered through a door near the fountain just + past the church, with boxes and barrels. + + * "Upstairs": The room with an open side, accessible through an illusory wall + in the furthest pantry room. + +* **Parapets:** The area with balconies and Overgrown Lothric Knights in + vanilla, accessible by taking the pillar bridge from the church, following + that path to the end, and dropping down to the right. + +* **Ruins:** The area around the Earthen Peak Ruins bonfire, up to the swamp. + +* **Swamp:** The area in and above the poisonous water, up to the point the + branches deposit you back on the ruins. + + * "Left": Left as you enter from the ruins, towards the cliff edge. + + * "Right": Right as you enter from the ruins, towards higher ground. + + * "Upper": The path up and over the swamp towards the Within Earthen Peak + Ruins bonfire. + +## Ringed City + +The "mid boss", "end boss", and "hidden boss" are the bosses who take the place +of Halflight, Gael, and Midir, respectively. + +* **Wall:** The large wall in which you spawn when you first enter the area, + with the Mausoleum Lookout bonfire. + + * "Top": The open-air top of the wall, where you first spawn in. + + * "Upper": The upper area of the wall, with the Ringed Inner Wall bonfire. + + * "Tower": The tiered tower leading down from the upper area to the stairs. + + * "Lower": The lower rooms of the wall, accessible from the lower cliff, with + an elevator back to upper. + + * "Hidden": The hidden floor accessible from the elevator from lower to upper, + from which you can reach Midir in vanilla. + +* **Streets:** The streets and skyways of the city proper. "Left" and "right" + are relative to the main staircase as you head down towards the swamp, "near" + and "far" are relative to Shira's chamber at the top of the stairs. + + * "Garden": The flower-filled back alley accessible from the left side of the + nearest bridge over the stairs. + + * "High": The higher areas in the far left where you can find the Locust + Preacher, accessible from a long ladder in the swamp. + + * "Monument": The area around the purging monument, which can only be accessed + by solving the "Show Your Humanity" puzzle. + +* **Swamp:** The wet area past the city streets. "Left and "right" are relative + to heading out from the Ringed City Streets bonfire, and "near" and "far" are + relative to that bonfire as well. + +* **Upper cliff:** The cliffside path leading from the swamp into the shared + grave, where Midir breathes fire. + +* **Grave:** The cylindrical chamber with spiral stairs around the edges, + connecting the two cliffs, containing the Shared Grave bonfire. + +* **Lower cliff:** The cliffside path leading out of the grave to the lower + wall. + +* **Church path:** The sunlit path from the lower cliff up to the Church of + Filianore where you fight Halflight in vanilla. + +* **Ashes:** The final area, where you fight Gael in vanilla. diff --git a/worlds/dark_souls_3/docs/locations_en.md b/worlds/dark_souls_3/docs/locations_en.md new file mode 100644 index 000000000000..10c3b78cd9fd --- /dev/null +++ b/worlds/dark_souls_3/docs/locations_en.md @@ -0,0 +1,2166 @@ +# Dark Souls III Locations + +## Understanding Location Names + +All locations begin with an abbreviation indicating their general region. Most +locations have a set of landmarks that are used in location names to keep them +short. + +* **FS:** Firelink Shrine +* **FSBT:** Firelink Shrine belltower +* **HWL:** [High Wall of Lothric](#high-wall-of-lothric) +* **US:** [Undead Settlement](#undead-settlement) +* **RS:** [Road of Sacrifices](#road-of-sacrifices) +* **CD:** [Cathedral of the Deep](#cathedral-of-the-deep) +* **FK:** [Farron Keep](#farron-keep) +* **CC:** [Catacombs of Carthus](#catacombs-of-carthus) +* **SL:** [Smouldering Lake](#smouldering-lake) +* **IBV:** [Irithyll of the Boreal Valley](#irithyll-of-the-boreal-valley) +* **ID:** [Irithyll Dungeon](#irithyll-dungeon) +* **PC:** [Profaned Capital](#profaned-capital) +* **AL:** [Anor Londo](#anor-londo) +* **LC:** [Lothric Castle](#lothric-castle) +* **CKG:** [Consumed King's Garden](#consumed-kings-garden) +* **GA:** [Grand Archives](#grand-archives) +* **UG:** [Untended Graves](#untended-graves) +* **AP:** [Archdragon Peak](#archdragon-peak) +* **PW1:** [Painted World of Ariandel (Before Contraption)](#painted-world-of-ariandel-%28before-contraption%29) +* **PW2:** [Painted World of Ariandel (After Contraption)](#painted-world-of-ariandel-%28after-contraption%29) +* **DH:** [Dreg Heap](#dreg-heap) +* **RC:** [Ringed City](#ringed-city) + +General notes: + +* "Lizard" always refers to a small crystal lizard. + +* "Miniboss" are large enemies that don't respawn after being killed and usually + drop some sort of treasure, such as Boreal Outrider Knights and Ravenous + Crystal Lizards. They usually don't have boss bars, but a few of them do. + +* NPC quest items are always in the first location you can get them _without_ + killing the NPC or ending the quest early. + +### High Wall of Lothric + +* **Back tower:** The tower _behind_ the High Wall of Lothric bonfire, past the + path to the shortcut elevator. + +* **Corpse tower:** The first tower after the High Wall of Lothric bonfire, with + a dead Wyvern on top of it. + +* **Fire tower:** The second tower after the High Wall of Lothric bonfire, where + a living Wyvern lands and breathes fire at you. + +* **Flame plaza:** The open area with many items where the Wyvern breathes fire. + +* **Wall tower:** The third tower after the High Wall of Lothric bonfire, with + the Tower on the Wall bonfire. + +* **Fort:** The large building after the Tower on the Wall bonfire, with the + transforming hollow on top. + + * "Entry": The first room you enter after descending the ladder from the roof. + + * "Walkway": The top floor of the tall room, with a path around the edge + hidden by a large wheel. + + * "Mezzanine": The middle floor of the tall room, with a chest. + + * "Ground": The bottom floor of the tall room, with an anvil and many mobs. + +* **Fountain:** The large fountain with many dead knights around it, where the + Winged Knight patrols in vanilla. + +* **Shortcut:** The unlockable path between the promenade and the High Wall of + Lothric bonfire, including both the elevator and the area at its base. + +* **Promenade:** The long, wide path between the two boss arenas. + +### Undead Settlement + +* **Burning tree:** The tree near the beginning of the region, with the + Cathedral Evangelist in front of it in vanilla. + +* **Hanging corpse room:** The dark room to the left of the burning tree with + many hanging corpses inside, on the way to the Dilapidated Bridge bonfire. + +* **Stable:** The building complex across the bridge to the right of the burning + tree. + +* **White tree:** The birch tree by the Dilapidated Bridge bonfire, where the + giant shoots arrows. + +* **Sewer:** The underground passage between the + +* **Chasm:** The chasm underneath the bridge on the way to the tower. It's + possible to get into the chasm without a key by dropping down next to Eygon of + Carim with a full health bar. + +* **Tower:** The tower at the end of the region with the giant archer at the + top. + +* **Tower village:** The village reachable from the tower, where the Fire Giant + patrols in vanilla. + +### Road of Sacrifices + +The area after the Crystal Sage is considered part of the Cathedral of the Deep +region. + +* **Road:** The path from the Road of Sacrifices bonfire to the Halfway Fortress + bonfire. + +* **Woods:** The wooded area on land, after the Halfway Fortress bonfire and + surrounding the Crucifixion Woods bonfire. + +* **Water:** The watery area, covered in crabs in vanilla. + +* **Deep water:** The area in the water near the ladder to Farron Keep, where + your walking is slowed. + +* **Stronghold:** The stone building complex on the way to Crystal Sage. + + * "Left room" is the room whose entrance is near the Crucifixion Woods + bonfire. + + * "Right room" is the room up the stairs closer to Farron Keep. + +* **Keep perimiter:** The building with the Black Knight and the locked door to + the Farron Keep Perimeter bonfire. + +### Cathedral of the Deep + +* **Path:** The path from Road of Sacrifices to the cathedral proper. + +* **Moat:** The circular path around the base of the area in front of the + cathedral, with the Ravenous Crystal Lizard in vanilla. Only the lowest part + actually has any water. + +* **Graveyard:** The area with respawning enemies up the hill from the Cleansing + Chapel bonfire. + +* **White tree:** The birch tree below the front doors of the chapel and across + the moat from the graveyard, where the giant shoots arrows if he's still + alive. + +* **Lower roofs:** The roofs, flying buttresses, and associated areas to the + right of the front door, which must be traversed before entering the + cathedral. + +* **Upper roofs:** The roofs, flying buttresses, and rafters leading to the + Rosaria's Bedchamber bonfire. + +* **Main hall:** The central and largest room in the cathedral, with the muck + that slows your movement. Divided into the south (with the sleeping giant in + vanilla) and east (with many items) wings, with north pointing towards the + door to the boss. + +* **Side chapel:** The room with rows of pews and the patrolling Cathedral + Knight in vanilla, to the side of the main hall. + +### Farron Keep + +* **Left island:** The large island with the ritual flame, to the left as you + leave the Farron Keep bonfire. + +* **Right island:** The large island with the ritual flame, to the right as you + leave the Farron Keep bonfire. + +* **Hidden cave:** A small cave in the far corner of the map, closest to the + right island. Near a bunch of basilisks in vanilla. + +* **Keep ruins:** The two islands with the Keep Ruins bonfire (bonfire island) + and one of the three ritual fires (ritual island). + +* **White tree**: The birch tree by the ramp down from the keep ruins bonfire + island, where the giant shoots arrows if he's still alive. + +* **Keep proper:** The building with the Old Wolf of Farron bonfire. + +* **Upper keep:** The area on top of the keep proper, reachable from the + elevator from the Old Wolf of Farron bonfire. + +* **Perimeter:** The area from near the Farron Keep Perimeter bonfire, including + the stony section and the path to the boss. + +### Catacombs of Carthus + +All the area up to the Small Doll wall into Irithyll is considered part of the +Catacombs of Carthus region. + +* **Atrium:** The large open area you first enter and the rooms attached to it. + + * "Upper" is the floor you begin on. + * "Lower" is the floor down the short stairs but at the top of the long + stairway that the skeleton ball rolls down. + +* **Crypt:** The enclosed area at the bottom of the long stairway that the + skeleton ball rolls down. + + * "Upper" is the floor the long stairway leads to that also contains the + Catacombs of Carthus bonfire. + * "Lower" is the floor with rats and bonewheels in vanilla. + * "Across" is the area reached by going up a different set of stairs from + downstairs. + +* **Cavern:** The even larger open area past the crypt with the rope bridge to + the boss arena. + +* **Tomb:** The area on the way to Smouldering Lake, reachable by cutting down + the rope bridge and climbing down it. + +* **Irithyll Bridge:** The outdoor bridge leading to Irithyll of the Boreal + Valley. + +### Smouldering Lake + +* **Lake:** The watery area you enter initially, where you get shot at by the + ballista. + +* **Side lake:** The small lake accessible via a passage from the larger one, in + which you face Horace the Hushed as part of his quest. + +* **Ruins main:** The area you first enter after the Demon Ruins bonfire. + + * "Upper" is the floor you begin on. + * "Lower" is the floor down the stairs from upper. + +* **Antechamber:** The area up a different flight of stairs from ruins main + lower, with the Old King's Antechamber bonfire. + +* **Ruins basement:** The area further down from ruins main lower, with a many + basilisks and Knight Slayer Tsorig in vanilla. + +### Irithyll of the Boreal Valley + +This region starts _after_ the Small Doll wall and ends with Pontiff Sulyvahn. +Everything after that, including the contents of Sulyvahn's cathedral is +considered part of Anor Londo. + +* **Central:** The beginning of the region, from the Central Irithyll bonfire up + to the plaza. + +* **Dorhys:** The sobbing mob (a Cathedral Evangelist in vanilla) behind the + locked door opening onto central. Accessed through an illusory railing by the + crystal lizard just before the plaza. + +* **Plaza:** The area in front of and below the cathedral, with a locked door up + to it and a locked elevator to the ascent. + +* **Descent:** The path from the Church of Yorshka bonfire down to the lake. + +* **Lake:** The open watery area outside the room with the Distant Manor + bonfire. + +* **Sewer:** The room between the lake and the beginning of the ascent, filled + with Sewer Centipedes in vanilla. + +* **Ascent:** The path up from the lake to the cathedral, through several + buildings and some open stairs. + +* **Great hall:** The building along the ascent with a large picture of + Gwynevere and several Silver Knights in vanilla. + +### Irithyll Dungeon + +In Irithyll Dungeon locations, "left" and "right" are always oriented facing +from the "near" side of the floor to the "far" side. + +* **B1:** The floor on which the player enters the dungeon, with the Irithyll + Dungeon bonfire. + + * "Near" is the side of the dungeon with the bonfire. + * "Far" is the opposite side. + +* **B2:** The floor directly below B1, which can be reached by going down the + stairs or dropping. + + * "Near" is the same side of the dungeon as the bonfire. + * "Far" is the opposite side. + +* **Pit:** The large room with the Giant Slave and many Rats in vanilla. + +* **Pit lift:** The elevator from the pit up to B1 near, right to the Irithyll + Dungeon bonfire. + +* **B3:** The lowest floor, with Karla's cell, a lift back to B2, and the exit + onwards to Profaned Capital. + + * "Near" is the side with Karla's cell and the the path from the pit. + * "Far" is the opposite side with the mimic. + +* **B3 lift:** The elevator from B3 (near where you can use Path of the Dragon + to go to Archdragon Peak) up to B2 far. + +### Profaned Capital + +* **Tower:** The tower that contains the Profaned Capital bonfire. + +* **Swamp:** The pool of toxic liquid accessible by falling down out of the + lower floor of the tower, going into the corridor to the left, and falling + down a hole. + +* **Chapel:** The building in the swamp, with Monstrosities of Sin in it in + vanilla. + +* **Bridge:** The long bridge from the tower into the palace. + +* **Palace:** The large building carved into the wall of the cavern, full of + chalices and broken pillars. + +### Anor Londo + +This region includes everything after Sulyvahn's cathedral, including its upper +story. + +* **Light cathedral:** The cathedral in which you fight Pontiff Sulyvahn in + vanilla. + +* **Plaza:** The wide open area filled with dead Giant Slaves and a couple live + ones in vanilla. + +* **Walkway:** The path above the plaza leading to the second floor of the light + cathedral, with Deacons in vanilla. + +* **Buttresses:** The flying buttresses that you have to climb to get to the + spiral staircase. "Near" and "far" are relative to the light cathedral, so the + nearest buttress is the one that leads back to the walkway. + +* **Tomb:** The area past the illusory wall just before the spiral staircase, in + which you marry Anri during Yoel and Yuria's quest. + +* **Dark cathedral:** The darkened cathedral just before the Aldrich fight in + vanilla. + +### Lothric Castle + +This region covers everything up the ladder from the Dancer of the Boreal Valley +bonfire up to the door into Grand Archives, except the area to the left of the +ladder which is part of Consumed King's Garden. + +* **Lift:** The elevator from the room straight after the Dancer of the Boreal + Valley bonfire up to just before the boss fight. + +* **Ascent:** The set of stairways and turrets leading from the Lothric Castle + bonfire to the Dragon Barracks bonfire. + +* **Barracks:** The large building with two fire-breathing wyverns across from + the Dragon Barracks bonfire. + +* **Moat:** The ditch beneath the bridge leading to the barracks. + + * The "right path" leads to the right as you face the barracks, around and + above the stairs up to the Dragon Barracks bonfire. + +* **Plaza:** The open area in the center of the barracks, where the two wyverns + breathe fire. + + * "Left" is the enclosed area on the left as you're coming from the Dragon + Barracks bonfire, with the stairs down to the basement. + +* **Basement:** The room beneath plaza left, with the Boreal Outrider in + vanilla. + +* **Dark room:** The large darkened room on the right of the barracks as you're + coming from the Dragon Barracks bonfire, with firebomb-throwing Hollows in + vanilla. + + * "Lower" is the bottom floor that you enter onto from the plaza. + * "Upper" is the top floor with the door to the main hall. + * "Mid" is the middle floor accessible by climbing a ladder from lower or + going down stairs from upper. + +* **Main hall:** The central room of the barracks, behind the gate. + +* **Chapel:** The building to the right just before the stairs to the boss, with + a locked elevator to Grand Archives. + +* **Wyvern room:** The room where you can fight the Pus of Man infecting the + left wyvern, accessible by dropping down to the left of the stairs to the + boss. + +* **Altar:** The building containing the Altar of Sunlight, accessible by + climbing up a ladder onto a roof around the corner from the stairs to the + boss. + +### Consumed King's Garden + +This region covers everything to the left of the ladder up from the Dancer of +the Boreal Valley bonfire up to the illusory wall into Untended Graves. + +* **Balcony:** The walkway accessible by getting off the first elevator halfway + down. + +* **Rotunda:** The building in the center of the toxic pool, with a Cathedral + Knight on it in vanilla. + +* **Lone stairway:** A set of stairs leading nowhere in the far left of the main + area as you enter from the first elevator. + +* **Shortcut:** The path from the locked door into Lothric Castle, through the + room filled with thralls in vanilla, and down a lift. + +* **Tomb:** The area after the boss room. + +### Grand Archives + +* **1F:** The first floor of the Grand Archives, including the first wax pool. + +* **Dark room:** The unlit room on 1F to the right of the wax pool. + +* **2F:** The second floor of the grand archives. It's split into two sections + that are separated by retractable bookshelves. + + * "Early" is the first part you reach and has an outdoor balcony with a ladder + to 3F and a wax pool up a short set of stairs. + * "Late" is the part you can only reach by climbing down from F3, where you + encounter the teleporting miniboss for the final time. + +* **3F:** The third floor of the grand archives, where you encounter the + teleporting miniboss for the second time. Includes the area with a hidden room + with another miniboss. + +* **4F:** The topmost and most well-lit section of bookshelves, overlooking the + rest of the archives. + +* **Rooftops:** The outer rooftop area between 4F and 5F, with Gargoyles in + vanilla. + + * "Lower" is the balcony you can reach by dropping off the rooftops, as well + as the further rooftops leading down to the 2F early balcony. + +* **5F:** The topmost floor of the archives interior, accessible from the + rooftops, with a ladder down to 4F. + +* **Dome:** The domed roof of the Grand Archives, with Ascended Winged Knights + in vanilla. + +* **Rafters:** The narrow walkways above the Grand Archives, accessible by + dropping down from the dome. + +### Untended Graves + +* **Swamp:** The watery area immediately after the Untended graves bonfire, up + to the cemetery. + +* **Cemetery:** The area past where the Cemetery of Ash bonfire would be, up to + the boss arena. + +* **Environs:** The area after the boss and outside the abandoned Firelink + Shrine. + +* **Shrine:** The area inside the abandoned Firelink Shrine. + +### Archdragon Peak + +"Gesture" always means the Path of the Dragon gesture. + +* **Intro:** The first section, from where you warp in from Irithyll Dungeon up + to the first boss fight. + + * "Archway": The large stone archway in front of the boss door. + +* **Fort:** The arena where you fight Ancient Wyvern in vanilla. + + * "Overlook": The area down the stairs from where the Ancient Wyvern first + lands in vanilla, overlooking the fog. + + * "Rotunda": The top of the spiral staircase building, to the left before the + bridge with the chain-axe Man-Serpent in vanilla. + +* **Mausoleum:** The building with the Dragon-Kin Mausoleum bonfire, where + you're warped after the first boss fight. + +* **Walkway:** The path from the mausoleum to the belfry, looking out over + clouds. + + * "Building": The building along the walkway, just before the wyvern in + vanilla. + +* **Belfry:** The building with the Great Belfry bonfire, including the room + with the summoner. + +* **Plaza:** The arena that appears after you defeat Nameless King in vanilla. + +* **Summit:** The path up from the belfry to the final altar at the top of the + mountain. + +### Painted World of Ariandel (Before Contraption) + +This region covers the Ashes of Ariandel DLC up to the point where you must use +the Contraption Key to ascend to the second level of the building and first meet +the painter. + +* **Snowfield:** The area around the Snowfield bonfire, + + * "Upper": The area immediately after the Snowfield bonfire, before the + collapsing overhang, with the Followers in vanilla. + + * "Lower": The snowy tree-filled area after the collapsing overhang, with the + Wolves in vanilla. + + * "Village": The area with broken-down buildings and Millwood Knights in + vanilla. + + * "Tower": The tower by the village, with Millwood Knights in Vanilla. + +* **Bridge:** The rope bridge to the chapel. + + * "Near": The side of the bridge by the Rope Bridge Cave bonfire. + + * "Far": The side of the bridge by the Ariandel Chapel bonfire. + +* **Chapel:** The building with the Ariandel Chapel bonfire and Lady Friede. + +* **Depths:** The area reachable by cutting down the bridge and descending on + the far side, with the Depths of the Painting bonfire. + +* **Settlement:** The area reachable by cutting down the bridge and descending + on the near side, with the Corvian Settlement bonfire. Everything after the + slide down the hill is considered part of the settlement. + + * "Courtyard": The area in front of the settlement, immediately after the + slide. + + * "Main": The main road of the settlement leading up to the locked gate to the + library. Also includes the buildings that are immediately accessible from + this road. + + * "Loop": A side path that loops left from the main road and goes up and + behind the building with the bonfire. + + * "Back": The back alley of the settlement, accessible by dropping down to the + right of the locked gate to the library. Also includes the buildings that + are immediately accessible from this alley. + + * "Roofs": The village rooftops, first accessible by climbing a ladder from + the back alley. Also includes the buildings and items that are first + accessible from the roofs. + + * "Hall": The largest building in the settlement, with two Corvian Knights in + vanilla. + +* **Library:** The building where you use the contraption key, where Vilhelm + appears in vanilla. + +### Painted World of Ariandel (After Contraption) + +This region covers the Ashes of Ariandel DLC past the point where you must use +the Contraption Key to ascend to the second level of the building and first meet +the painter, including the basement beneath the chapel. + +* **Pass:** The mountainous area past the Snowy Mountain Pass bonfire. + +* **Pit:** The area with a large tree and numerous Millwood Knights in vanilla, + reached by a collapsing overhang in the pass. + +* **B1:** The floor immediately below the chapel, first accessible from the + pass. Filled with Giant Flies in vanilla. + +* **B2:** The floor below B1, with lots of fly eggs. Filled with even more Giant + Flies than B1 in vanilla. + +* **B3:** The floor below B2, accessible through an illusory wall. + +* **Rotunda:** The round arena out in the open, accessible by platforming down + tree roots from B3. + +### Dreg Heap + +* **Shop:** Items sold by the Stone-Humped Hag by The Dreg Heap bonfire. + +* **Castle:** The building with The Dreg Heap bonfire, up to the large fall into + the library. + +* **Library:** The building with the stained glass window that you fall into + from the castle. + +* **Church:** The building below and to the right of the library, which the + pillar falls into to make a bridge. + +* **Pantry:** The set of rooms entered through a door near the fountain just + past the church, with boxes and barrels. + + * "Upstairs": The room with an open side, accessible through an illusory wall + in the furthest pantry room. + +* **Parapets:** The area with balconies and Overgrown Lothric Knights in + vanilla, accessible by taking the pillar bridge from the church, following + that path to the end, and dropping down to the right. + +* **Ruins:** The area around the Earthen Peak Ruins bonfire, up to the swamp. + +* **Swamp:** The area in and above the poisonous water, up to the point the + branches deposit you back on the ruins. + + * "Left": Left as you enter from the ruins, towards the cliff edge. + + * "Right": Right as you enter from the ruins, towards higher ground. + + * "Upper": The path up and over the swamp towards the Within Earthen Peak + Ruins bonfire. + +### Ringed City + +The "mid boss", "end boss", and "hidden boss" are the bosses who take the place +of Halflight, Gael, and Midir, respectively. + +* **Wall:** The large wall in which you spawn when you first enter the area, + with the Mausoleum Lookout bonfire. + + * "Top": The open-air top of the wall, where you first spawn in. + + * "Upper": The upper area of the wall, with the Ringed Inner Wall bonfire. + + * "Tower": The tiered tower leading down from the upper area to the stairs. + + * "Lower": The lower rooms of the wall, accessible from the lower cliff, with + an elevator back to upper. + + * "Hidden": The hidden floor accessible from the elevator from lower to upper, + from which you can reach Midir in vanilla. + +* **Streets:** The streets and skyways of the city proper. "Left" and "right" + are relative to the main staircase as you head down towards the swamp, "near" + and "far" are relative to Shira's chamber at the top of the stairs. + + * "Garden": The flower-filled back alley accessible from the left side of the + nearest bridge over the stairs. + + * "High": The higher areas in the far left where you can find the Locust + Preacher, accessible from a long ladder in the swamp. + + * "Monument": The area around the purging monument, which can only be accessed + by solving the "Show Your Humanity" puzzle. + +* **Swamp:** The wet area past the city streets. "Left and "right" are relative + to heading out from the Ringed City Streets bonfire, and "near" and "far" are + relative to that bonfire as well. + +* **Upper cliff:** The cliffside path leading from the swamp into the shared + grave, where Midir breathes fire. + +* **Grave:** The cylindrical chamber with spiral stairs around the edges, + connecting the two cliffs, containing the Shared Grave bonfire. + +* **Lower cliff:** The cliffside path leading out of the grave to the lower + wall. + +* **Church path:** The sunlit path from the lower cliff up to the Church of + Filianore where you fight Halflight in vanilla. + +* **Ashes:** The final area, where you fight Gael in vanilla. + +## Detailed Location Descriptions + +These location decsriptions were originally written by [Matt Gruen] for [the +offline _Dark Souls III_ randomizer]. + +[Matt Gruen]: https://thefifthmatt.com/ +[the offline _Dark Souls III_ randomizer]: https://www.nexusmods.com/darksouls3/mods/361 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Location nameDetailed description
AL: Aldrich Faithful (water reserves, talk to McDonnel)Given by Archdeacon McDonnel in Water Reserves.
AL: Aldrich's Ruby (dark cathedral, miniboss)Dropped by the Deep Accursed who drops down when you open the Anor Londo Cathedral shortcut
AL: Anri's Straight Sword (Anri quest)Dropped by Anri of Astora upon death or completing quest. In the Darkmoon Tomb with Lord of Hollows route, or given by Ludleth if summoned to defeat Aldrich.
AL: Blade of the Darkmoon (Yorshka with Darkmoon Loyalty)Given by Yorshka after learning the Darkmoon Loyalty gesture from Sirris, or by killing her
AL: Brass Armor (tomb)Behind the illusory statue in the hallway leading to the Darkmoon Tomb
AL: Brass Gauntlets (tomb)Behind the illusory statue in the hallway leading to the Darkmoon Tomb
AL: Brass Helm (tomb)Behind the illusory statue in the hallway leading to the Darkmoon Tomb
AL: Brass Leggings (tomb)Behind the illusory statue in the hallway leading to the Darkmoon Tomb
AL: Chameleon (tomb after marrying Anri)Dropped by the Stone-humped Hag assassin after Anri reaches the Church of Yorshka, either in the church or after marrying Anri
AL: Cinders of a Lord - AldrichDropped by Aldrich
AL: Crescent Moon Sword (Leonhard drop)Drop by Ringfinger Leonhard upon death. Includes Soul of Rosaria if invaded in Anor Londo.
AL: Dark Stoneplate Ring (by dark stairs up from plaza)After the Pontiff fight, in the dark hallways to the left of the area with the Giant Slaves
AL: Deep Gem (water reserves)In the open in the Water Reserves
AL: Dragonslayer Greatarrow (drop from nearest buttress)Dropping down from about halfway down the flying buttress closest to the entrance to the Darkmoon Tomb
AL: Dragonslayer Greatbow (drop from nearest buttress)Dropping down from about halfway down the flying buttress closest to the entrance to the Darkmoon Tomb
AL: Drang Twinspears (plaza, NPC drop)Dropped by Drang Twinspears-wielding knight on the stairs leading up to the Anor Londo Silver Knights
AL: Easterner's Ashes (below top of furthest buttress)Dropping down from the rightmost flying buttress, or the rightmost set of stairs
AL: Ember (plaza, further)After the Pontiff fight, in the middle of the area with the Giant Slaves
AL: Ember (plaza, right side)After the Pontiff fight, next to one of the Giant Slaves on the right side
AL: Ember (spiral staircase, bottom)Next to the lever that summons the rotating Anor Londo stairs at the bottom
AL: Estus Shard (dark cathedral, by left stairs)In a chest on the floor of the Anor Londo cathedral
AL: Giant's Coal (by giant near dark cathedral)On the Giant Blacksmith's corpse in Anor Londo
AL: Golden Ritual Spear (light cathedral, mimic upstairs)Drop from a mimic in the higher levels of Pontiff's cathedral, accessible from the Deacons after the Pontiff fight
AL: Havel's Ring+2 (prison tower, rafters)On the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Human Dregs (water reserves)In the open in the Water Reserves
AL: Large Soul of a Weary Warrior (left of dark cathedral entrance)In front of the Anor Londo cathedral, slightly to the left
AL: Large Titanite Shard (bottom of the furthest buttress)At the base of the rightmost flying buttress leading up to Anor Londo
AL: Large Titanite Shard (bottom of the nearest buttress)On the tower leading back from Anor Londo to the shortcut to Irithyll, down the flying buttress closest to the Darkmoon Tomb entrance.
AL: Large Titanite Shard (right after light cathedral)After the Pontiff fight, on the balcony to the right of the area with the Giant Slaves
AL: Large Titanite Shard (walkway, side path by cathedral)After the Pontiff fight, going back from the Deacons area to the original cathedral, before a dropdown
AL: Large Titanite Shard ?? (right after light cathedral)After Pontiff's cathedral, hugging the wall to the right
AL: Moonlight Arrow (dark cathedral, up right stairs)In the Anor Londo cathedral, up the stairs on the right side
AL: Painting Guardian Gloves (prison tower, rafters)On the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Painting Guardian Gown (prison tower, rafters)On the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Painting Guardian Hood (prison tower, rafters)On the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Painting Guardian Waistcloth (prison tower, rafters)On the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Painting Guardian's Curved Sword (prison tower rafters)On the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Proof of a Concord Kept (dark cathedral, up left stairs)In the Anor Londo cathedral, halfway down the stairs on the left side next to some Deacons
AL: Reversal Ring (tomb, chest in corner)In a chest in Darkmoon Tomb
AL: Ring of Favor (water reserves, both minibosses)Dropped after killing both of Sulyvahn's Beasts in the Water Reserves
AL: Ring of Favor+1 (light cathedral, upstairs)In the higher levels of Pontiff's cathedral, accessible from the Deacons after the Pontiff fight
AL: Silver Mask (Leonhard drop)Drop by Ringfinger Leonhard upon death. Includes Soul of Rosaria if invaded in Anor Londo.
AL: Simple Gem (light cathedral, lizard upstairs)Dropped by a Crystal Lizard in the higher levels of Pontiff's cathedral, accessible from the Deacons after the Pontiff fight
AL: Soul of AldrichDropped by Aldrich
AL: Soul of Rosaria (Leonhard drop)Drop by Ringfinger Leonhard upon death. Includes Soul of Rosaria if invaded in Anor Londo.
AL: Soul of a Crestfallen Knight (right of dark cathedral entrance)To the right of the Anor Londo cathedral entrance, past the red-eyed Silver Knight
AL: Soul of a Weary Warrior (plaza, nearer)After the Pontiff fight, in the middle of the area with the Giant Slaves
AL: Sun Princess Ring (dark cathedral, after boss)In the Anor Londo cathedral after defeating Aldrich, up the elevators in Gwynevere's Chamber
AL: Titanite Scale (top of ladder up to buttresses)On the platform after the stairs leading up to Anor Londo from the Water Reserves building
AL: Twinkling Titanite (lizard after light cathedral #1)Dropped a Crystal Lizard straight after the Pontiff fight
AL: Yorshka's Chime (kill Yorshka)Dropped by Yorshka upon death.
AP: Ancient Dragon Greatshield (intro, on archway)After the Archdragon Peak bonfire, on top of the arch in front of the Ancient Wyvern fight
AP: Calamity Ring (mausoleum, gesture at altar)Received using Path of the Dragon at the Altar by the Mausoleum bonfire
AP: Covetous Gold Serpent Ring+2 (plaza)In the Nameless King boss arena after he is defeated
AP: Dragon Chaser's Ashes (summit, side path)In the run-up to the Dragon Altar after the Belfry bonfire, in a side path to the left side
AP: Dragon Head Stone (fort, boss drop)Dropped by Ancient Wyvern
AP: Dragon Tooth (belfry roof, NPC drop)Dropped from any of the Havel Knights
AP: Dragonslayer Armor (plaza)In the Nameless King boss arena after he is defeated
AP: Dragonslayer Gauntlets (plaza)In the Nameless King boss arena after he is defeated
AP: Dragonslayer Helm (plaza)In the Nameless King boss arena after he is defeated
AP: Dragonslayer Leggings (plaza)In the Nameless King boss arena after he is defeated
AP: Dragonslayer Spear (gate after mausoleum)In the gate connecting the Dragon-Kin Mausoleum area to the bridge where the Nameless King fight takes place
AP: Drakeblood Greatsword (mausoleum, NPC drop)Dropped by the Drakeblood Knight summoned by the Serpent-Man Summoner
AP: Dung Pie (fort, landing after second room)On a landing going up the stairs from the Ancient Wyvern to the chainaxe Man-Serpent area
AP: Ember (belfry, below bell)From the right of where Ancient Wyvern first lands
AP: Ember (fort overlook #2)From the right of where Ancient Wyvern first lands
AP: Ember (intro, by bonfire)In the area below the bell lever, either dropping down near the lever or going down the stairs from the open fountain area after the Belfry bonfire
AP: Great Magic Barrier (drop off belfry roof)Dropping down to the left from the area with the Havel Knight and the dead Wyvern
AP: Havel's Greatshield (belfry roof, NPC drop)Dropped from any of the Havel Knights
AP: Havel's Ring+1 (summit, after building)Just past the building with all of the Man-Serpents on the way to the Dragon Altar, on the left side
AP: Homeward Bone (intro, path to bonfire)From the start of the area, along the left path leading to the first bonfire
AP: Large Soul of a Crestfallen Knight (summit, by fountain)In the middle of the open fountain area after the Belfry bonfire
AP: Large Soul of a Nameless Soldier (fort, by stairs to first room)to the left of where the Ancient Wyvern lands
AP: Large Soul of a Weary Warrior (fort, center)Where the Ancient Wyvern lands
AP: Lightning Bolt (rotunda)On top of the ruined dome found going up spiral stairs to the left before the bridge with the chainaxe Man-Serpent
AP: Lightning Clutch Ring (intro, left of boss door)To the left of gate leading to Ancient Wyvern, past the Rock Lizard
AP: Lightning Gem (intro, side rise)From the start of the area, up a ledge in between two forked paths toward the first bonfire
AP: Lightning Urn (fort, left of first room entrance)On the path to the left of where the Ancient Wyvern lands, left of the building entrance
AP: Ricard's Rapier (belfry, NPC drop)Dropped by the Richard Champion summoned by the Serpent-Man Summoner
AP: Ring of Steel Protection (fort overlook, beside stairs)To the right of the area where the Ancient Wyvern lands, dropping down onto the ledge
AP: Soul of a Crestfallen Knight (mausoleum, upstairs)From the Mausoleum bonfire, up the second set of stairs to the right
AP: Soul of a Nameless Soldier (intro, right before archway)From the Archdragon Peak bonfire, going right before the arch before Ancient Wyvern
AP: Soul of a Weary Warrior (intro, first cliff edge)At the very start of the area on the left cliff edge
AP: Soul of a Weary Warrior (walkway, building window)On the way to the Belfry bonfire after the sagging wooden bridge, on a ledge visible in a room with a Crystal Lizard, accessible by a tricky jump or just going around the other side
AP: Soul of the Nameless KingDropped by Nameless King
AP: Stalk Dung Pie (fort overlook)From the right of where Ancient Wyvern first lands
AP: Thunder Stoneplate Ring (walkway, up ladder)After the long hallway after the Mausoleum bonfire, before the rope bridge, up the long ladder
AP: Titanite Chunk (fort, second room balcony)After going left of where Ancient Wyvern lands and left again, rather than going up the stairs to the right, go to the open area to the left
AP: Titanite Chunk (intro, archway corner)From the Archdragon Peak bonfire, under the arch, immediately to the right
AP: Titanite Chunk (intro, behind rock)Almost at the Archdragon Peak bonfire, behind a rock in the area with many Man-Serpents
AP: Titanite Chunk (intro, left before archway)After the Archdragon Peak bonfire, going left before the arch before Ancient Wyvern
AP: Titanite Chunk (rotunda)On top of the ruined dome found going up spiral stairs to the left before the bridge with the chainaxe Man-Serpent
AP: Titanite Chunk (walkway, miniboss drop)Dropped by the second Ancient Wyvern patrolling the path up to the Belfry
AP: Titanite Scale (mausoleum, downstairs balcony #1)From the Mausoleum bonfire, up the stairs to the left, past the Rock Lizard
AP: Titanite Scale (mausoleum, downstairs balcony #2)From the Mausoleum bonfire, up the stairs to the left, past the Rock Lizard
AP: Titanite Scale (mausoleum, upstairs balcony)From the Mausoleum bonfire, up the first stairs to the right, going around toward the Man-Serpent Summoner, on the balcony on the side
AP: Titanite Scale (walkway building)In a chest after the sagging wooden bridge on the way to the Belfry, in the building with the Crystal Lizard
AP: Titanite Scale (walkway, miniboss drop)Dropped by the second Ancient Wyvern patrolling the path up to the Belfry
AP: Titanite Slab (belfry roof)Next to the Havel Knight by the dead Wyvern
AP: Titanite Slab (plaza)In the Nameless King boss arena after he is defeated
AP: Twinkling Dragon Torso Stone (summit, gesture at altar)Received using Path of the Dragon at the Altar after the Belfry bonfire. Hawkwood also uses the gesture there when summoned.
AP: Twinkling Titanite (belfry, by ladder to roof)In the chest before the ladder climbing up to the Havel Knight
AP: Twinkling Titanite (fort, down second room balcony ladder)After going left of where Ancient Wyvern lands and left again, rather than going up the stairs to the right, go to the open area to the left and then down the ladder
AP: Twinkling Titanite (fort, end of rafters)Dropping down to the left of the Mausoleum bonfire, all the way down the wooden rafters
AP: Twinkling Titanite (walkway building, lizard)Dropped by Crystal Lizard in the building after the sagging wooden bridge toward the Belfry
AP: Twinkling Titanite (walkway, miniboss drop)Dropped by the second Ancient Wyvern patrolling the path up to the Belfry
CA: Coiled Sword (boss drop)Dropped by Iudex Gundyr
CA: Firebomb (down the cliff edge)Along the cliff edge before the Iudex Gundyr fight, to the right
CA: Soul of a Deserted Corpse (right of spawn)At the very start of the game
CA: Soul of an Unknown Traveler (by miniboss)In the area with the Ravenous Crystal Lizard
CA: Speckled Stoneplate Ring+1 (by miniboss)In the area with the Ravenous Crystal Lizard, along the right wall
CA: Titanite Scale (miniboss drop)Dropped by Ravenous Crystal Lizard
CA: Titanite Shard (jump to coffin)Making a jump to a coffin after the Cemetery of Ash bonfire
CC: Black Blade (tomb, mimic)Dropped by the mimic before Smouldering Lake
CC: Black Bug Pellet (cavern, before bridge)In the area where many many skeletons are before the bridge you can cut
CC: Bloodred Moss Clump (atrium lower, down more stairs)To the left before going down the main stairwell in the Catacombs, past the skeleton ambush and where Anri is standing, near the Crystal Lizard
CC: Carthus Bloodring (crypt lower, end of side hall)At the very end of the Bonewheel Skeleton area
CC: Carthus Milkring (crypt upper, among pots)After the first Skeleton Ball, in the hallway alcove with the many dark-exploding pots
CC: Carthus Pyromancy Tome (atrium lower, jump from bridge)Down the hallway to the right before going down the main stairwell in the Catacombs and through an illusory wall on the left, or making a difficult dropdown from the top-level platform
CC: Carthus Rouge (atrium upper, left after entrance)To the right after first entering the Catacombs
CC: Carthus Rouge (crypt across, corner)Making a difficult jump between the hallway after the first Skeleton Ball and the area at the same level on the opposite side, or going up the stairs from the main hall
CC: Dark Gem (crypt lower, skeleton ball drop)Dropped by second Skeleton Ball after killing its sorcerer skeleton
CC: Ember (atrium, on long stairway)On the main stairwell in Catacombs
CC: Ember (crypt lower, shortcut to cavern)In the short hallway with the level shortcut where Knight Slayer Tsorig invades
CC: Ember (crypt upper, end of hall past hole)Going right from the Catacombs bonfire, down the hall to the left, then to the right. After a hole that drops down into the Bonewheel Skeleton area.
CC: Fire Gem (cavern, lizard)Dropped by a Crystal Lizard found between the Catacombs main halls and the ledge overlooking the bridge you can cut down
CC: Grave Warden Pyromancy Tome (boss arena)In Wolnir's arena, or in the back left of the room containing his bonfire if not picked up in the arena
CC: Grave Warden's Ashes (crypt across, corner)From the Catacombs bonfire, down the stairs into the main hall and up the stairs to the other side, on the far left side. Stairwell past the illusory wall is most direct.
CC: Homeward Bone (Irithyll bridge)Found right before the wall blocking access to Irithyll
CC: Large Soul of a Nameless Soldier (cavern, before bridge)In the area where many many skeletons are before the bridge you can cut
CC: Large Soul of a Nameless Soldier (tomb lower)Down the ramp from the Fire Demon, where all the skeletons are
CC: Large Soul of an Unknown Traveler (crypt upper, hall middle)Going right from the Catacombs bonfire, then down the long hallway after the hallway to the left
CC: Large Titanite Shard (crypt across, middle hall)From the Catacombs bonfire, down the stairs into the main hall and up the stairs to the other side, in a middle hallway
CC: Large Titanite Shard (crypt upper, skeleton ball hall)Going right from the Catacombs bonfire, to the end of the hallway where second Skeleton Ball rolls
CC: Large Titanite Shard (tomb lower)Down the ramp from the Fire Demon, where all the skeletons are
CC: Old Sage's Blindfold (tomb, hall before bonfire)Down the ramp from the Fire Demon, straight down the hallway past the room with the Abandoned Tomb bonfire
CC: Pontiff's Right Eye (Irithyll bridge, miniboss drop)Dropped by killing Sulyvahn's Beast on the bridge to Irithyll or in the lake below
CC: Ring of Steel Protection+2 (atrium upper, drop onto pillar)From the first bridge in Catacombs where the first skeletons are encountered, parallel to the long stairwell, walk off onto a pillar on the left side.
CC: Sharp Gem (atrium lower, right before exit)Down the hallway to the right before going down the main stairwell in the Catacombs
CC: Soul of High Lord WolnirDropped by High Lord Wolnir
CC: Soul of a Demon (tomb, miniboss drop)Dropped by the Fire Demon before Smouldering Lake
CC: Soul of a Nameless Soldier (atrium lower, down hall)All the way down the hallway to the right before going down the main stairwell in the Catacombs
CC: Soul of a Nameless Soldier (atrium upper, up more stairs)From the room before the Catacombs main stairwell, up the two ramps and to the end of the long hallway crossing the room
CC: Thunder Stoneplate Ring+1 (crypt upper, among pots)After the first Skeleton Ball, in the hallway alcove with the many dark-exploding pots, behind one of the pillars
CC: Titanite Shard (atrium lower, corner by stairs)To the left before going down the main stairwell in the Catacombs, behind the pensive Carthus Cursed Sword Skeleton
CC: Titanite Shard (crypt lower, left of entrance)In the main hall after the Catacombs bonfire, down the stairs and to the left
CC: Titanite Shard (crypt lower, start of side hall)In the Bonewheel Skeleton area, on the left side under a Writhing Flesh
CC: Twinkling Titanite (atrium lower, lizard down more stairs)Dropped by a Crystal Lizard found to the left before going down the main stairwell in the Catacombs, past the skeleton ambush and past where Anri is standing
CC: Undead Bone Shard (crypt upper, skeleton ball drop)Dropped by first Skeleton Ball after killing its sorcerer skeleton
CC: Witch's Ring (tomb, hall before bonfire)Down the ramp from the Fire Demon, straight down the hallway past the room with the Abandoned Tomb bonfire
CC: Yellow Bug Pellet (cavern, on overlook)To the right of the Carthus Curved Sword Skeleton overlooking the pit Horace falls into
CD: Aldrich's Sapphire (side chapel, miniboss drop)Dropped by the Deep Accursed
CD: Arbalest (upper roofs, end of furthest buttress)Before the rafters on the way to Rosaria, up a flying buttress, past a halberd-wielding Large Hollow Soldier to the right, and down another flying buttress to the right
CD: Archdeacon Holy Garb (boss room after killing boss)Near the Deacons of the Deep bonfire, found after resting at it
CD: Archdeacon Skirt (boss room after killing boss)Near the Deacons of the Deep bonfire, found after resting at it
CD: Archdeacon White Crown (boss room after killing boss)Near the Deacons of the Deep bonfire, found after resting at it
CD: Armor of Thorns (Rosaria's Bed Chamber after killing Kirk)Found in Rosaria's Bed Chamber after killing Longfinger Kirk
CD: Astora Greatsword (graveyard, left of entrance)Down one of the side paths to the left in the Reanimated Corpse area
CD: Barbed Straight Sword (Kirk drop)Dropped by Longfinger Kirk when he invades in the cathedral central room
CD: Black Eye Orb (Rosaria from Leonhard's quest)On Rosaria's corpse after joining Rosaria's Fingers, exhausing Leonhard's dialogue there and reaching the Profaned Capital bonfire.
CD: Blessed Gem (upper roofs, rafters)In the rafters leading to Rosaria, guarded by a Cathedral Knight to the right
CD: Crest Shield (path, drop down by Cathedral of the Deep bonfire)On a grave near the Cathedral of the Deep bonfire, accessed by dropping down to the right
CD: Curse Ward Greatshield (by ladder from white tree to moat)Taking a right after the Infested Corpse graveyard, before the shortcut ladder down to the Ravenous Crystal Lizard area
CD: Deep Braille Divine Tome (mimic by side chapel)Dropped by the Mimic before the room with the patrolling Cathedral Knight and Deep Accursed
CD: Deep Gem (down stairs by first elevator)Coming from the room where you first see deacons, go down instead of continuing to the main cathedral room. Guarded by a pensive Cathedral Evangelist.
CD: Deep Ring (upper roofs, passive mob drop in first tower)Dropped by the passive Deacon on the way to Rosaria
CD: Drang Armor (main hall, east)In the Giant Slave muck pit leading up to Deacons
CD: Drang Gauntlets (main hall east)In the Giant Slave muck pit leading up to Deacons
CD: Drang Hammers (main hall east)In the Giant Slave muck pit leading up to Deacons, underneath the stairwell
CD: Drang Shoes (main hall east)In the Giant Slave muck pit leading up to Deacons
CD: Duel Charm (by first elevator)After opening the cathedral's backdoor, where the Deacon enemies are first seen, under a fountain that spouts poison
CD: Duel Charm (next to Patches in onion armor)To the right of the bridge leading to Rosaria, from the Deacons side. Patches will lower the bridge if you try to cross from this side.
CD: Dung Pie (main hall, miniboss drop)Dropped by either Giant Slave
CD: Ember (Patches)Sold by Patches in Firelink Shrine
CD: Ember (by back door)Past the pair of Grave Wardens and the Cathedral backdoor against a wall, guarded by a greataxe-wielding Large Hollow Soldier
CD: Ember (edge of platform before boss)On the edge of the chapel before Deacons overlooking the Giant Slaves
CD: Ember (side chapel upstairs, up ladder)Up a ladder and past the Cathedral Evangelist from the top level of the room with the patrolling Cathedral Knight and Deep Accursed
CD: Ember (side chapel, miniboss room)In the room with the Deep Accursed
CD: Estus Shard (monument outside Cleansing Chapel)Right outside of the Cleansing Chapel. Requires killing praying hollows.
CD: Executioner's Greatsword (graveyard, far end)In an open area down one of the side paths to the left in the Reanimated Corpse area
CD: Exploding Bolt (ledge above main hall south)On the ledge where the Giant Slave slams his arms down
CD: Fading Soul (graveyard, far end)In an open area down one of the side paths to the left in the Reanimated Corpse area, next to the Executioner's Greatsword
CD: Gauntlets of Thorns (Rosaria's Bed Chamber after killing Kirk)Found in Rosaria's Bed Chamber after killing Longfinger Kirk
CD: Helm of Thorns (Rosaria's Bed Chamber after killing Kirk)Found in Rosaria's Bed Chamber after killing Longfinger Kirk
CD: Herald Armor (path, by fire)Guarded by the Cathedral Evangelist after the Crystal Sage fight
CD: Herald Gloves (path, by fire)Guarded by the Cathedral Evangelist after the Crystal Sage fight
CD: Herald Helm (path, by fire)Guarded by the Cathedral Evangelist after the Crystal Sage fight
CD: Herald Trousers (path, by fire)Guarded by the Cathedral Evangelist after the Crystal Sage fight
CD: Heysel Pick (Heysel Corpse-Grub in Rosaria's Bed Chamber)Dropped by the Heysel Corpse-grub in Rosaria's Bed Chamber
CD: Hidden Blessing (Patches)Sold by Patches after Greirat pillages Lothric Castle, telling Patches, and Patches returning
CD: Homeward Bone (outside main hall south door)Past the cathedral doors guarded by the Giant Slave opposite to the Deacons fight
CD: Horsehoof Ring (Patches)Sold or dropped by Patches after he mentions Greirat
CD: Large Soul of an Unknown Traveler (by white tree #1)In the graveyard with the White Birch and Infested Corpses
CD: Large Soul of an Unknown Traveler (by white tree #2)In the graveyard with the White Birch and Infested Corpses
CD: Large Soul of an Unknown Traveler (lower roofs, semicircle balcony)On the cathedral roof after climbing up the flying buttresses, on the edge of the semicircle platform balcony
CD: Large Soul of an Unknown Traveler (main hall east)In the Giant Slave muck pit leading up to Deacons
CD: Large Soul of an Unknown Traveler (main hall south, side path)Down a side path with poison-spouting fountains in the main cathedral room, accessible from the Cleansing Chapel shortcut, patrolled by a Cathedral Knight
CD: Large Soul of an Unknown Traveler (path, against outer wall)From the Cathedral of the Deep bonfire after the Brigand, against the wall in the area with the dogs and crossbowmen
CD: Large Titanite Shard (main hall, miniboss drop)Dropped by either Giant Slave
CD: Leggings of Thorns (Rosaria's Bed Chamber after killing Kirk)Found in Rosaria's Bed Chamber after killing Longfinger Kirk
CD: Lloyd's Sword Ring (ledge above main hall south)On the ledge where the Giant Slave slams his arms down
CD: Maiden Gloves (main hall south)In the muck pit with the Giant Slave that can attack with his arms
CD: Maiden Hood (main hall south)In the muck pit with the Giant Slave that can attack with his arms
CD: Maiden Robe (main hall south)In the muck pit with the Giant Slave that can attack with his arms
CD: Maiden Skirt (main hall south)In the muck pit with the Giant Slave that can attack with his arms
CD: Notched Whip (Cleansing Chapel)In a corner of the Cleansing Chapel
CD: Paladin's Ashes (path, guarded by lower NPC)At the very start of the area, guarded by the Fallen Knight
CD: Pale Tongue (main hall east)In the Giant Slave muck pit leading up to Deacons
CD: Pale Tongue (upper roofs, outdoors far end)Before the rafters on the way to Rosaria, up a flying buttress and straight right, passing a halberd-wielding Large Hollow Soldier
CD: Poisonbite Ring (moat, hall past miniboss)In the pit with the Infested Corpse, accessible from the Ravenous Crystal Lizard area or from dropping down near the second Cleansing Chapel shortcut
CD: Red Bug Pellet (lower roofs, up stairs between buttresses)In the area after the cathedral roof against the wall of the cathedral, down the path from the Cathedral Evangelist.
CD: Red Bug Pellet (right of cathedral front doors)Up the stairs past the Infested Corpse graveyard and the left, toward the roof path to the right of the cathedral doors
CD: Red Sign Soapstone (passive mob drop by Rosaria's Bed Chamber)Dropped by passive Corpse-grub against the wall near the entrance to Rosaria's Bed Chamber
CD: Repair Powder (by white tree)In the graveyard with the White Birch and Infested Corpses
CD: Ring of Favor+2 (upper roofs, on buttress)Before the rafters on the way to Rosaria, up a flying buttress, behind a greataxe-wielding Large Hollow Soldier to the left
CD: Ring of the Evil Eye+1 (by stairs to boss)Before the stairs leading down into the Deacons fight
CD: Rosaria's Fingers (Rosaria)Given by Rosaria.
CD: Rusted Coin (don't forgive Patches)Given by Patches after not forgiving him after he lowers the bridge in Cathedral of the Deep.
CD: Rusted Coin (left of cathedral front doors, behind crates)Up the stairs past the Infested Corpse graveyard and to the left, hidden behind some crates to the left of the cathedral door
CD: Saint Bident (outside main hall south door)Past the cathedral doors guarded by the Giant Slave opposite to the Deacons fight
CD: Saint-tree Bellvine (moat, by water)In the Infested Corpse moat beneath the Cathedral
CD: Seek Guidance (side chapel upstairs)Above the room with the patrolling Cathedral Knight and Deep Accursed, below a writhing flesh on the ceiling.
CD: Shotel (Patches)Sold by Patches
CD: Small Doll (boss drop)Dropped by Deacons of the Deep
CD: Soul of a Nameless Soldier (ledge above main hall south)On the ledge where the Giant Slave slams his arms down
CD: Soul of a Nameless Soldier (lower roofs, side room)Coming from the cathedral roof, past the three crossbowmen to the path patrolled by the halberd-wielding Large Hollow Soldier, in a room to the left with many thralls.
CD: Soul of a Nameless Soldier (main hall south)In the muck pit with the Giant Slave that can attack with his arms
CD: Soul of the Deacons of the DeepDropped by Deacons of the Deep
CD: Spider Shield (NPC drop on path)Dropped by the brigand at the start of Cathedral of the Deep
CD: Spiked Shield (Kirk drop)Dropped by Longfinger Kirk when he invades in the cathedral central room
CD: Titanite Scale (moat, miniboss drop)Dropped by the Ravenous Crystal Lizard outside of the Cathedral
CD: Titanite Shard (Cleansing Chapel windowsill, by miniboss)On the ledge dropping back down into Cleansing Chapel from the area with the Ravenous Crystal Lizard
CD: Titanite Shard (moat, far end)Behind the cathedral near the Infested Corpse moat, going from the Ravenous Crystal Lizard
CD: Titanite Shard (moat, up a slope)Up one of the slopes in the Ravenous Crystal Lizard area
CD: Titanite Shard (outside building by white tree)Past the Infested Corpse graveyard to the left, hidden along the left wall of the building with the shortcut ladder and Curse Ward Greatshield
CD: Titanite Shard (path, side path by Cathedral of the Deep bonfire)Up a path to the left after the Cathedral of the Deep bonfire, after the Fallen Knight and before the Brigand
CD: Twinkling Titanite (moat, lizard #1)Dropped by the Crystal Lizard behind the cathedral near the Infested Corpse moat, going from the Ravenous Crystal Lizard
CD: Twinkling Titanite (moat, lizard #2)Dropped by the Crystal Lizard under the cathedral near the Infested Corpse moat, going from the Ravenous Crystal Lizard
CD: Twinkling Titanite (path, lizard #1)Dropped by the first Crystal Lizard after the Crystal Sage fight
CD: Twinkling Titanite (path, lizard #2)Dropped by the second Crystal Lizard after the Crystal Sage fight
CD: Undead Bone Shard (gravestone by white tree)In the graveyard with the Infested Corpses, on a coffin partly hanging off of the ledge
CD: Undead Hunter Charm (lower roofs, up stairs between buttressesIn the area after the cathedral roof guarded by a Cathedral Evangelist. Can be jumped to from a flying buttress or by going around and back
CD: Winged Spear (kill Patches)Dropped by Patches when killed in his own armor.
CD: Xanthous Crown (Heysel Corpse-Grub in Rosaria's Bed Chamber)Dropped by the Heysel Corpse-grub in Rosaria's Bed Chamber
CD: Young White Branch (by white tree #1)By the White Birch tree in the Infested Corpse graveyard
CD: Young White Branch (by white tree #2)By the White Birch tree in the Infested Corpse graveyard
CKG: Black Firebomb (under rotunda)Under the platform in the middle of the garden, in the toxic pool
CKG: Claw (under rotunda)Under the platform in the middle of the garden, in the toxic pool
CKG: Dark Gem (under lone stairway)Following the left wall, behind the standalone set of stairs
CKG: Dragonscale Ring (shortcut, leave halfway down lift)From the middle level of the second elevator, toward the Oceiros boss fight
CKG: Drakeblood Armor (tomb, after killing AP mausoleum NPC)On the Drakeblood Knight after Oceiros fight, after defeating the Drakeblood Knight from the Serpent-Man Summoner
CKG: Drakeblood Gauntlets (tomb, after killing AP mausoleum NPC)On the Drakeblood Knight after Oceiros fight, after defeating the Drakeblood Knight from the Serpent-Man Summoner
CKG: Drakeblood Helm (tomb, after killing AP mausoleum NPC)On the Drakeblood Knight after Oceiros fight, after defeating the Drakeblood Knight from the Serpent-Man Summoner
CKG: Drakeblood Leggings (tomb, after killing AP mausoleum NPC)On the Drakeblood Knight after Oceiros fight, after defeating the Drakeblood Knight from the Serpent-Man Summoner
CKG: Estus Shard (balcony)From the middle level of the first Consumed King's Gardens elevator, out the balcony and to the right
CKG: Human Pine Resin (by lone stairway bottom)On the right side of the garden, following the wall past the entrance to the shortcut elevator building, in a toxic pool
CKG: Human Pine Resin (toxic pool, past rotunda)In between two platforms near the middle of the garden, by a tree in a toxic pool
CKG: Magic Stoneplate Ring (mob drop before boss)Dropped by the Cathedral Knight closest to the Oceiros fog gate
CKG: Ring of Sacrifice (under balcony)Along the right wall of the garden, next to the first elevator building
CKG: Sage Ring+2 (balcony, drop onto rubble, jump back)From the middle platform of the first elevator in the target, going out and dropping off to the left, and then running off onto the ruined arch behind.
CKG: Shadow Garb (under rotunda)Under the platform in the middle of the garden, in the toxic pool
CKG: Shadow Gauntlets (under rotunda)Under the platform in the middle of the garden, in the toxic pool
CKG: Shadow Leggings (under rotunda)Under the platform in the middle of the garden, in the toxic pool
CKG: Shadow Mask (under center platform)Under the platform in the middle of the garden, in the toxic pool
CKG: Soul of Consumed OceirosDropped by Consumed King Oceiros
CKG: Soul of a Weary Warrior (before first lift)On the path leading to the first elevator from Lothric Castle
CKG: Titanite Chunk (balcony, drop onto rubble)From the middle platform of the first elevator, dropping down to the left
CKG: Titanite Chunk (right of shortcut lift bottom)On the right side of the garden, following the wall past the entrance to the shortcut elevator building, all the way to the end
CKG: Titanite Chunk (shortcut)Right inside of the shortcut door leading to Oceiros from Lothric/Dancer bonfire
CKG: Titanite Chunk (up lone stairway)Following the left wall of the garden, in and up the standalone set of stairs
CKG: Titanite Scale (shortcut)In the room leading to the Oceiros shortcut elevator from Lothric/Dancer, in the first floor alcove.
CKG: Titanite Scale (tomb, chest #1)Chest after Oceiros fight
CKG: Titanite Scale (tomb, chest #2)Chest after Oceiros fight
CKG: Wood Grain Ring+1 (by first elevator bottom)Behind the first elevator going down into the garden, in the toxic pool
DH: Aquamarine Dagger (castle, up stairs)Up the second flight of stairs to the left of the starting area with the murkmen, before the long drop
DH: Black Firebomb (ruins, up windmill from bonfire)To the left of the Earthen Peak Ruins bonfire, past the ruined windmill, next to many Poisonhorn bugs.
DH: Covetous Silver Serpent Ring+3 (pantry upstairs, drop down)After exiting the building with the Lothric Knights where the front crumbles, to the last room of the building to the right, up stairs past an illusory wall to the left, then dropping down after exiting the building from the last room.
DH: Desert Pyromancer Garb (ruins, by shack near cliff)Behind a shack near the edge of the cliff of the area targeted by the second angel.
DH: Desert Pyromancer Gloves (swamp, far right)After dropping down in the poison swamp area, against the wall straight to the right.
DH: Desert Pyromancer Hood (swamp upper, tunnel end)At the end of the tunnel with Desert Pyromancy Zoey, to the right of the final branches.
DH: Desert Pyromancer Skirt (swamp right, by roots)In the poison swamp, against a tree guarded by a few Poisonhorn bugs in the front right.
DH: Divine Blessing (library, after drop)After the dropdown where an angel first targets you, behind you
DH: Divine Blessing (shop)Sold by Stone-humped Hag, or in her ashes
DH: Divine Blessing (swamp upper, building roof)On a rooftop of one of the buildings bordering the poison swamp. Can be reached by dropping down from the final tree branch and accessing the roof to the right.
DH: Ember (castle, behind spire)At the start of the area, behind a spire to the right of first drop down
DH: Ember (pantry, behind crates just before upstairs)After exiting the building with the Lothric Knights where the front crumbles, to the last room end of the building to the right, up stairs past an illusory wall to the left, in the second-to-last room of the sequence, behind some crates to the left.
DH: Ember (ruins, alcove before swamp)In an alcove providing cover from the second angel's projectiles, before dropping down in the poison swamp area.
DH: Ember (ruins, alcove on cliff)In the area with the pilgrim responsible for the second angel, below the Within Earthen Peak Ruins bonfire. Can be accessed by dropping down from a cliff edge, dropping down to the right of the bonfire.
DH: Ember (shop)Sold by Stone-humped Hag, or in her ashes
DH: Flame Fan (swamp upper, NPC drop)Dropped by Desert Pyromancer Zoey
DH: Giant Door Shield (ruins, path below far shack)Descending down a path from the edge of the cliff of the area targeted by the second angel, to the very end of the cliff.
DH: Great Soul Dregs (pantry upstairs)After exiting the building with the Lothric Knights where the front crumbles, to the last room of the building to the right, up stairs past an illusory wall to the left, then all the way to the end of the last room.
DH: Harald Curved Greatsword (swamp left, under root)In the back leftmost area of the poison swamp, underneath the tree branch leading up and out, guarded by a stationary Harald Legion Knight.
DH: Hidden Blessing (shop)Sold by Stone-humped Hag, or in her ashes
DH: Homeward Bone (end of path from church)Immediately before dropping into the area with the Earthen Peak Ruins bonfire, next to Gael's flag.
DH: Homeward Bone (swamp left, on root)All the way to the end of a short path in the back leftmost area of the poison swamp, where you can plunge attack the stationary Harald Legion Knight.
DH: Large Soul of a Weary Warrior (parapets, hall)After crossing the spire bridge that crashes into the building with the Lothric Knights, past Lapp's initial location, dropping down behind the murkman and dropping down again, in a corner to the left.
DH: Large Soul of a Weary Warrior (swamp center)In the middle of the poison swamp.
DH: Large Soul of a Weary Warrior (swamp, under overhang)In the cavern adjacent to the poison swamp, surrounded by a few Poisonhorn bugs.
DH: Lightning Urn (wall outside church)After the dropdown where an angel first targets you, against the wall on the left.
DH: Loincloth (swamp, left edge)In the leftmost edge of the poison swamp after dropping down, guarded by 6 Poisonhorn bugs.
DH: Lothric War Banner (parapets, end of hall)After crossing the spire bridge that crashes into the building with the Lothric Knights, past Lapp's initial location, dropping down behind the murkman and dropping down again, at the end of the hallway to the right.
DH: Murky Hand Scythe (library, behind bookshelves)After the first long drop into the building which looks like Grand Archives, to the left up the bookshelf stairs and behind the bookshelves
DH: Murky Longstaff (pantry, last room)After exiting the building with the Lothric Knights where the front crumbles, in the third furthest room in the building to the right.
DH: Prism Stone (swamp upper, tunnel start)Near the start of the tunnel with Desert Pyromancer Zoey.
DH: Projected Heal (parapets balcony)After crossing the spire bridge that crashes into the building with the Lothric Knights, past Lapp's initial location, dropping down behind the murkman, against a wall in the area with the Lothric War Banner Knight and many murkmen.
DH: Purple Moss Clump (swamp shack)In the ruined shack with Poisonhorn bugs straight ahead of the dropdown into the poison swamp area.
DH: Ring of Favor+3 (swamp right, up root)Up the long branch close to the dropdown into the poison swamp area, in front of the cavern.
DH: Ring of Steel Protection+3 (ledge before church)After the dropdown where an angel first targets you, on an exposed edge to the left. Difficult to get without killing the angel.
DH: Rusted Coin (behind fountain after church)After exiting the building with the Lothric Knights where the front crumbles, behind the fountain on the right side.
DH: Rusted Gold Coin (shop)Sold by Stone-humped Hag, or in her ashes
DH: Siegbräu (Lapp)Given by Lapp after collecting the Titanite Slab in Earthen Peak Ruins, or left after Demon Princes fight, or dropped upon death if not given.
DH: Small Envoy Banner (boss drop)Found in the small room after beating Demon Prince.
DH: Soul of a Crestfallen Knight (church, altar)In the building where the front crumbles, guarded by the two Lothric Knights at the front of the chapel.
DH: Soul of a Weary Warrior (castle overhang)The bait item at the start of the area which falls down with you into the ruined building below.
DH: Soul of the Demon PrinceDropped by Demon Prince
DH: Splitleaf Greatsword (shop)Sold by Stone-humped Hag, or in her ashes
DH: Titanite Chunk (castle, up stairs)Up first flight of stairs to the left of the starting area with the murkmen, before the long drop
DH: Titanite Chunk (pantry, first room)After exiting the building with the Lothric Knights where the front crumbles, on a ledge in the first room of the building to the right.
DH: Titanite Chunk (path from church, by pillar)Before dropping into the area with the Earthen Peak Ruins bonfire, behind a pillar in front of a murkman pool.
DH: Titanite Chunk (ruins, by far shack)In front of a shack at the far edge of the cliff of the area targeted by the second angel. There is a shortcut dropdown to the left of the building.
DH: Titanite Chunk (ruins, path from bonfire)At the Earthen Peak Ruins bonfire, straight a bit then all the way left, near the edge of the cliff in the area targeted by the second angel.
DH: Titanite Chunk (swamp right, drop partway up root)Partway up the long branch close to the dropdown into the poison swamp area, in front of the cavern, dropping down to a branch to the left.
DH: Titanite Chunk (swamp, along buildings)After dropping down into the poison swamp, along the buildings on the left side.
DH: Titanite Chunk (swamp, path to upper)Partway up the branch that leads out of the poison swamp, on a very exposed branch jutting out to the left.
DH: Titanite Scale (library, back of room)After the first long drop into the building which looks like Grand Archives, behind you at the back of the room
DH: Titanite Scale (swamp upper, drop and jump into tower)At the very end of the last tree branch before dropping down toward the Within Earthen Peak Ruins bonfire, drop down to the left instead. Make a jump into the interior of the overturned tower to the left.
DH: Titanite Slab (swamp, path under overhang)Deep within the cavern adjacent to the poison swamp, to the back and then left. Alternatively, given by Lapp after exhausting dialogue near the bonfire and dying, or left after he moves on, or dropped upon death if not given.
DH: Twinkling Titanite (library, chandelier)After the first long drop into the building which looks like Grand Archives, straight ahead hanging from a chandelier on the ground
DH: Twinkling Titanite (path after church, mob drop)Dropped the pilgrim responsible for the first angel encountered, below the spire bridge that forms by crashing into the building.
DH: Twinkling Titanite (ruins, alcove on cliff, mob drop)Dropped by the pilgrim responsible for the second angel, below the Within Earthen Peak Ruins bonfire. Can be accessed by dropping down from a cliff edge, or dropping down to the right of the bonfire.
DH: Twinkling Titanite (ruins, root near bonfire)Treasure visible straight ahead of the Earthen Peak Ruins bonfire on a branch. Can be accessed by following the right wall from the bonfire until a point of access onto the branch is found.
DH: Twinkling Titanite (swamp upper, drop onto root)On the final tree branches before dropping down toward the Within Earthen Peak Ruins bonfire, drop down on a smaller branch to the right. This loops back to the original branch.
DH: Twinkling Titanite (swamp upper, mob drop on roof)Dropped by the pilgrim responsible for the third angel in the swamp. Rather than heading left into the tunnel with Desert Pyromancy Zoey, go right onto a shack roof. Drop down onto a tree branch at the end, then drop down to another roof.
FK: Antiquated Dress (hidden cave)In a chest in the cave found along the keep wall in the basilisk area, with the Elizabeth corpse
FK: Antiquated Gloves (hidden cave)In a chest in the cave found along the keep wall in the basilisk area, with the Elizabeth corpse
FK: Antiquated Skirt (hidden cave)In a chest in the cave found along the keep wall in the basilisk area, with the Elizabeth corpse
FK: Atonement (perimeter, drop down into swamp)Dropping down from the Farron Keep Perimeter building, to the right past the bonfire, before the stairs going up
FK: Black Bow of Pharis (mob drop, around item in corner by keep ruins)Dropped the Elder Ghru on the left side of the group of three to the left of the Keep Ruins bonfire, as approached from the ritual fire.
FK: Black Bug Pellet (perimeter, hill by boss door)On the small hill to the right of the Abyss Watchers entrance, guarded by a spear-wielding Ghru Grunt
FK: Cinders of a Lord - Abyss WatcherDropped by Abyss Watchers
FK: Crown of Dusk (by white tree)Near the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Dark Stoneplate Ring+2 (keep ruins ritual island, behind wall)Hidden behind the right wall of the ritual fire before Keep Ruins
FK: Dragon Crest Shield (upper keep, far side of the wall)Up the elevator from Old Wolf of Farron bonfire, and dropping down to Crystal Lizard area, in the open.
FK: Dreamchaser's Ashes (keep proper, illusory wall)Near the Old Wolf of Farron bonfire, behind an illusory wall near the Crystal Lizard
FK: Ember (by white tree)Near the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Ember (perimeter, path to boss)Guarded by a spear-wielding Ghru Grunt to the right of the main path leading up to Abyss Watchers
FK: Ember (upper keep, by miniboss #1)Guarded by Stray Demon, up from the Old Wolf of Farron bonfire
FK: Ember (upper keep, by miniboss #2)Guarded by Stray Demon, up from the Old Wolf of Farron bonfire
FK: Estus Shard (between Farron Keep bonfire and left island)Straight ahead from the Farron Keep bonfire to the ritual fire stairs, guarded by a slug
FK: Gold Pine Bundle (by white tree)Near the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Golden Scroll (hidden cave)In a cave found along the keep wall in the basilisk area, with the Elizabeth corpse
FK: Great Magic Weapon (perimeter, by door to Road of Sacrifices)Next to the shortcut leading from Farron Keep Perimeter back into Crucifixion Woods, past the Ravenous Crystal Lizard
FK: Greataxe (upper keep, by miniboss)Guarded by Stray Demon, up from the Old Wolf of Farron bonfire
FK: Greatsword (ramp by keep ruins ritual island)In the middle of the swamp, on the pair of long ramps furthest from the Farron Keep bonfire, going out forward and slightly right from the bonfire.
FK: Havel's Armor (upper keep, after killing AP belfry roof NPC)Appears by Stray Demon, up from the Old Wolf of Farron bonfire, after the Havel Knight guarding the Titanite Slab in Archdragon Peak has been killed
FK: Havel's Gauntlets (upper keep, after killing AP belfry roof NPC)Appears by Stray Demon, up from the Old Wolf of Farron bonfire, after the Havel Knight guarding the Titanite Slab in Archdragon Peak has been killed
FK: Havel's Helm (upper keep, after killing AP belfry roof NPC)Appears by Stray Demon, up from the Old Wolf of Farron bonfire, after the Havel Knight guarding the Titanite Slab in Archdragon Peak has been killed
FK: Havel's Leggings (upper keep, after killing AP belfry roof NPC)Appears by Stray Demon, up from the Old Wolf of Farron bonfire, after the Havel Knight guarding the Titanite Slab in Archdragon Peak has been killed
FK: Heavy Gem (uper keep, lizard on stairs)Dropped by the Crystal Lizard that scurries up the stairs in the area dropping down from near Stray Demon, up from Old Wolf of Farron bonfire
FK: Hollow Gem (perimeter, drop down into swamp)Dropping down from the Farron Keep Perimeter building, to the right past the bonfire, before the stairs going up
FK: Homeward Bone (right island, behind fire)Behind the ritual fire with stairs guarded by Elder Ghrus/basilisks
FK: Iron Flesh (Farron Keep bonfire, right after exit)In the open in the swamp, heading straight right from Farron Keep bonfire
FK: Large Soul of a Nameless Soldier (between right island and pillar)Hidden in a corner to the right of the stairs leading up to the ritual fire from the basilisk area
FK: Large Soul of a Nameless Soldier (near wall by right island)To the left of the stairs leading up to the ritual fire from the Basilisk area, by the keep wall
FK: Large Soul of an Unknown Traveler (by white tree)On a tree close to the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Large Titanite Shard (upper keep, lizard #1)Dropped by the closer Crystal Lizard in the area dropping down from near Stray Demon, up from Old Wolf of Farron bonfire
FK: Large Titanite Shard (upper keep, lizard #2)Dropped by the farther Crystal Lizard in the area dropping down from near Stray Demon, up from Old Wolf of Farron bonfire
FK: Lightning Spear (upper keep, far side of the wall)Up the elevator from Old Wolf of Farron bonfire, and dropping down to Crystal Lizard area, in the open.
FK: Lingering Dragoncrest Ring (by white tree, miniboss drop)Dropped by the Greater Crab patrolling the birch tree where the Giant shoots arrows
FK: Magic Stoneplate Ring+1 (between right island and wall)Behind a tree in the basilisk area, heading directly right from Farron Keep bonfire
FK: Manikin Claws (Londor Pale Shade drop)Dropped by Londor Pale Shade when he invades near the basilisks, if Yoel or Yuria have been betrayed
FK: Nameless Knight Armor (next to pillar by right island)From the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill
FK: Nameless Knight Gauntlets (next to pillar by right island)From the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill
FK: Nameless Knight Helm (next to pillar by right island)From the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill
FK: Nameless Knight Leggings (next to pillar by right island)From the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill
FK: Pharis's Hat (mob drop, around item in corner by keep ruins)Dropped the Elder Ghru in the back of the group of three to the left of the Keep Ruins bonfire, as approached from the ritual fire.
FK: Poison Gem (near wall by keep ruins bridge)From the left of the bridge leading from the ritual fire to the Keep Ruins bonfire, guarded by the three Elder Ghru
FK: Prism Stone (by left island stairs)On an island to the left of the stairs leading up to the ritual fire straight ahead of the Farron Keep bonfire
FK: Purple Moss Clump (Farron Keep bonfire, around right corner)Along the inner wall of the keep, making an immediate right from Farron Keep bonfire
FK: Purple Moss Clump (keep ruins, ritual island)Close to the ritual fire before the Keep Ruins bonfire
FK: Purple Moss Clump (ramp directly in front of Farron Keep bonfire)In the middle of the swamp, on the pair of long ramps closest to the Farron Keep bonfire, going out forward and slightly right from the bonfire.
FK: Ragged Mask (Farron Keep bonfire, around left corner)Along the inner wall of the keep, making an immediate left from Farron Keep bonfire, guarded by slugs
FK: Repair Powder (outside hidden cave)Along the keep wall in the basilisk area, outside of the cave with the Elizabeth corpse and Golden Scroll
FK: Rotten Pine Resin (left island, behind fire)In the area behind the ritual fire which is straight ahead of the Farron Keep bonfire
FK: Rotten Pine Resin (outside pavilion by left island)From the Farron Keep bonfire straight ahead to the pavillion guarded by the Darkwraith, just to the left of the ritual fire stairs
FK: Rusted Gold Coin (right island, behind wall)Hidden behind the right wall of the ritual fire with stairs guarded by Elder Ghrus/basilisks
FK: Sage's Coal (pavilion by left island)In the pavillion guarded by a Darkwraith, straight ahead from the Farron Keep bonfire to the left of the ritual fire stairs
FK: Sage's Scroll (near wall by keep ruins bonfire island)Along the keep inner wall, heading left from the stone doors past the crab area, surrounded by many Ghru enemies
FK: Shriving Stone (perimeter, just past stone doors)Past the stone doors, on the path leading up to Abyss Watchers by the Corvians
FK: Soul of a Nameless Soldier (by white tree)Near the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Soul of a Stray Demon (upper keep, miniboss drop)Dropped by Stray Demon on the bridge above Farron Keep
FK: Soul of the Blood of the WolfDropped by Abyss Watchers
FK: Stone Parma (near wall by left island)Along the inner wall of the keep, making an left from Farron Keep bonfire but before the area with the Darkwraith, guarded by a slug
FK: Sunlight Talisman (estus soup island, by ladder to keep proper)By the pot of estus soup to the left of the stairs leading up to Old Wolf of Farron
FK: Titanite Scale (perimeter, miniboss drop)Dropped by Ravenous Crystal Lizard near the shortcut from Farron Keep back to Road of Sacrifices
FK: Titanite Shard (Farron Keep bonfire, left after exit)Along the inner wall of the keep, making an left from Farron Keep bonfire, by the second group of four slugs
FK: Titanite Shard (between left island and keep ruins)In the swamp area with the Ghru Leaper between the Keep Ruins ritual fire and ritual fire straight ahead of Farron Keep bonfire, opposite from the keep wall
FK: Titanite Shard (by keep ruins ritual island stairs)By the stairs leading up to the Keep Ruins ritual fire from the middle of the swamp
FK: Titanite Shard (by ladder to keep proper)In the swamp area close to the foot of the ladder leading to Old Wolf of Farron bonfire
FK: Titanite Shard (by left island stairs)In front of the stairs leading up to the ritual fire straight ahead of the Farron Keep bonfire
FK: Titanite Shard (keep ruins bonfire island, under ramp)Under the ramp leading down from the Keep Ruins bonfire
FK: Titanite Shard (swamp by right island)Behind a tree patrolled by an Elder Ghru close to the ritual fire stairs
FK: Twinkling Dragon Head Stone (Hawkwood drop)Dropped by Hawkwood after killing him in the Abyss Watchers arena, after running up to the altar in Archdragon Peak. Twinkling Dragon Torso Stone needs to be acquired first.
FK: Twinkling Titanite (keep proper, lizardl)Dropped by the Crystal Lizard on the balcony behind the Old Wolf of Farron bonfire
FK: Undead Bone Shard (pavilion by keep ruins bonfire island)In a standalone pavillion down the ramp from Keep Ruins bonfire and to the right
FK: Watchdogs of Farron (Old Wolf)Given by Old Wolf of Farron.
FK: Wolf Ring+1 (keep ruins bonfire island, outside building)To the right of the building with the Keep Ruins bonfire, when approached from the ritual fire
FK: Wolf's Blood Swordgrass (by ladder to keep proper)To the left of the ladder leading up to the Old Wolf of Farron bonfire
FK: Young White Branch (by white tree #1)Near the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Young White Branch (by white tree #2)Near the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FS: Acid Surge (Cornyx for Carthus Tome)Sold by Cornyx after giving him the Carthus Pyromancy Tome
FS: Affinity (Karla)Sold by Karla after recruiting her, or in her ashes
FS: Alluring Skull (Mortician's Ashes)Sold by Handmaid after giving Mortician's Ashes
FS: Arstor's Spear (Ludleth for Greatwood)Boss weapon for Curse-Rotted Greatwood
FS: Aural Decoy (Orbeck)Sold by Orbeck
FS: Billed Mask (Yuria after killing KFF boss)Dropped by Yuria upon death or quest completion.
FS: Black Dress (Yuria after killing KFF boss)Dropped by Yuria upon death or quest completion.
FS: Black Fire Orb (Karla for Grave Warden Tome)Sold by Karla after giving her the Grave Warden Pyromancy Tome
FS: Black Flame (Karla for Grave Warden Tome)Sold by Karla after giving her the Grave Warden Pyromancy Tome
FS: Black Gauntlets (Yuria after killing KFF boss)Dropped by Yuria upon death or quest completion.
FS: Black Iron Armor (shop after killing Tsorig)Sold by Handmaid after killing Knight Slayer Tsorig in Smouldering Lake
FS: Black Iron Gauntlets (shop after killing Tsorig)Sold by Handmaid after killing Knight Slayer Tsorig in Smouldering Lake
FS: Black Iron Helm (shop after killing Tsorig)Sold by Handmaid after killing Knight Slayer Tsorig in Smouldering Lake
FS: Black Iron Leggings (shop after killing Tsorig)Sold by Handmaid after killing Knight Slayer Tsorig in Smouldering Lake
FS: Black Leggings (Yuria after killing KFF boss)Dropped by Yuria upon death or quest completion.
FS: Black Serpent (Ludleth for Wolnir)Boss weapon for High Lord Wolnir
FS: Blessed Weapon (Irina for Tome of Lothric)Sold by Irina after giving her the Braille Divine Tome of Lothric
FS: Blue Tearstone Ring (Greirat)Given by Greirat upon rescuing him from the High Wall cell
FS: Boulder Heave (Ludleth for Stray Demon)Boss weapon for Stray Demon
FS: Bountiful Light (Irina for Tome of Lothric)Sold by Irina after giving her the Braille Divine Tome of Lothric
FS: Bountiful Sunlight (Ludleth for Rosaria)Boss weapon for Rosaria, available after Leonhard is killed
FS: Broken Straight Sword (gravestone after boss)Near the grave after Iudex Gundyr fight
FS: Budding Green Blossom (shop after Sirris kills Aldrich)Sold by Handmaid after receiving Silvercat Ring item lot from Sirris and defeating Aldrich
FS: Bursting Fireball (Cornyx for Great Swamp Tome)Sold by Cornyx after giving him the Great Swamp Pyromancy Tome
FS: Caressing Tears (Irina)Sold by Irina after recruiting her, or in her ashes
FS: Carthus Beacon (Cornyx for Carthus Tome)Sold by Cornyx after giving him the Carthus Pyromancy Tome
FS: Carthus Flame Arc (Cornyx for Carthus Tome)Sold by Cornyx after giving him the Carthus Pyromancy Tome
FS: Cast Light (Orbeck for Golden Scroll)Sold by Orbeck after giving him the Golden Scroll
FS: Chaos Bed Vestiges (Ludleth for Old Demon King)Boss weapon for Old Demon King
FS: Chaos Storm (Cornyx for Izalith Tome)Sold by Cornyx after giving him Izalith Pyromancy Tome
FS: Clandestine Coat (shop with Orbeck's Ashes)Sold by Handmaid after giving Orbeck's Ashes and reloading
FS: Cleric's Candlestick (Ludleth for Deacons)Boss weapon for Deacons of the Deep
FS: Cracked Red Eye Orb (Leonhard)Given by Ringfinger Leonhard in Firelink Shrine after reaching Tower on the Wall bonfire
FS: Crystal Hail (Ludleth for Sage)Boss weapon for Crystal Sage
FS: Crystal Magic Weapon (Orbeck for Crystal Scroll)Sold by Orbeck after giving him the Crystal Scroll
FS: Crystal Sage's Rapier (Ludleth for Sage)Boss weapon for Crystal Sage
FS: Crystal Soul Spear (Orbeck for Crystal Scroll)Sold by Orbeck after giving him the Crystal Scroll
FS: Dancer's Armor (shop after killing LC entry boss)Sold by Handmaid after defeating Dancer of the Boreal Valley
FS: Dancer's Crown (shop after killing LC entry boss)Sold by Handmaid after defeating Dancer of the Boreal Valley
FS: Dancer's Enchanted Swords (Ludleth for Dancer)Boss weapon for Dancer of the Boreal Valley
FS: Dancer's Gauntlets (shop after killing LC entry boss)Sold by Handmaid after defeating Dancer of the Boreal Valley
FS: Dancer's Leggings (shop after killing LC entry boss)Sold by Handmaid after defeating Dancer of the Boreal Valley
FS: Dark Blade (Karla for Londor Tome)Sold by Irina or Karla after giving one the Londor Braille Divine Tome
FS: Dark Edge (Karla)Sold by Karla after recruiting her, or in her ashes
FS: Dark Hand (Yoel/Yuria)Sold by Yuria
FS: Darkdrift (Yoel/Yuria)Dropped by Yuria upon death or quest completion.
FS: Darkmoon Longbow (Ludleth for Aldrich)Boss weapon for Aldrich
FS: Dead Again (Karla for Londor Tome)Sold by Irina or Karla after giving one the Londor Braille Divine Tome
FS: Deep Protection (Karla for Deep Braille Tome)Sold by Irina or Karla after giving one the Deep Braille Divine Tome
FS: Deep Soul (Ludleth for Deacons)Boss weapon for Deacons of the Deep
FS: Demon's Fist (Ludleth for Fire Demon)Boss weapon for Fire Demon
FS: Demon's Greataxe (Ludleth for Fire Demon)Boss weapon for Fire Demon
FS: Demon's Scar (Ludleth for Demon Prince)Boss weapon for Demon Prince
FS: Divine Blessing (Greirat from IBV)Sold by Greirat after pillaging Irithyll
FS: Divine Blessing (Greirat from US)Sold by Greirat after pillaging Undead Settlement
FS: Dragonscale Armor (shop after killing AP boss)Sold by Handmaid after defeating Nameless King
FS: Dragonscale Waistcloth (shop after killing AP boss)Sold by Handmaid after defeating Nameless King
FS: Dragonslayer Greataxe (Ludleth for Dragonslayer)Boss weapon for Dragonslayer Armour
FS: Dragonslayer Greatshield (Ludleth for Dragonslayer)Boss weapon for Dragonslayer Armour
FS: Dragonslayer Swordspear (Ludleth for Nameless)Boss weapon for Nameless King
FS: Dried Finger (shop)Sold by both Shrine Handmaid and Untended Graves Handmaid
FS: East-West Shield (tree by shrine entrance)In a tree to the left of the Firelink Shrine entrance
FS: Eastern Armor (Easterner's Ashes)Sold by Handmaid after giving Easterner's Ashes
FS: Eastern Gauntlets (Easterner's Ashes)Sold by Handmaid after giving Easterner's Ashes
FS: Eastern Helm (Easterner's Ashes)Sold by Handmaid after giving Easterner's Ashes
FS: Eastern Leggings (Easterner's Ashes)Sold by Handmaid after giving Easterner's Ashes
FS: Elite Knight Armor (shop after Anri quest)Sold by Handmaid after completing Anri's questline or killing Anri
FS: Elite Knight Gauntlets (shop after Anri quest)Sold by Handmaid after completing Anri's questline or killing Anri
FS: Elite Knight Helm (shop after Anri quest)Sold by Handmaid after completing Anri's questline or killing Anri
FS: Elite Knight Leggings (shop after Anri quest)Sold by Handmaid after completing Anri's questline or killing Anri
FS: Ember (Dragon Chaser's Ashes)Sold by Handmaid after giving Dragon Chaser's Ashes
FS: Ember (Grave Warden's Ashes)Sold by Handmaid after giving Grave Warden's Ashes
FS: Ember (Greirat from US)Sold by Greirat after pillaging Undead Settlement
FS: Ember (Greirat)Sold by Greirat after recruiting him, or in his ashes
FS: Ember (Mortician's Ashes)Sold by Handmaid after giving Mortician's Ashes
FS: Ember (above shrine entrance)Above the Firelink Shrine entrance, up stairs/slope from either left or right of the entrance
FS: Ember (path right of Firelink entrance)On a cliffside to the right of the main path leading up to Firelink Shrine, guarded by a dog
FS: Ember (shop for Greirat's Ashes)Sold by Handmaid after Greirat pillages Lothric Castle and handing in ashes
FS: Ember (shop)Sold by Handmaid
FS: Embraced Armor of Favor (shop after killing water reserve minibosses)Sold by Handmaid after killing Sulyvahn's Beasts in Water Reserve
FS: Executioner Armor (shop after killing Horace)Sold by Handmaid after killing Horace the Hushed
FS: Executioner Gauntlets (shop after killing Horace)Sold by Handmaid after killing Horace the Hushed
FS: Executioner Helm (shop after killing Horace)Sold by Handmaid after killing Horace the Hushed
FS: Executioner Leggings (shop after killing Horace)Sold by Handmaid after killing Horace the Hushed
FS: Exile Armor (shop after killing NPCs in RS)Sold by Handmaid after killing the exiles just before Farron Keep
FS: Exile Gauntlets (shop after killing NPCs in RS)Sold by Handmaid after killing the exiles just before Farron Keep
FS: Exile Leggings (shop after killing NPCs in RS)Sold by Handmaid after killing the exiles just before Farron Keep
FS: Exile Mask (shop after killing NPCs in RS)Sold by Handmaid after killing the exiles just before Farron Keep
FS: Faraam Helm (shop after killing GA NPC)Sold by Handmaid after killing Lion Knight Albert
FS: Farron Dart (Orbeck)Sold by Orbeck
FS: Farron Dart (shop)Sold by Handmaid
FS: Farron Flashsword (Orbeck)Sold by Orbeck
FS: Farron Greatsword (Ludleth for Abyss Watchers)Boss weapon for Abyss Watchers
FS: Farron Hail (Orbeck for Sage's Scroll)Sold by Orbeck after giving him the Sage's Scroll
FS: Farron Ring (Hawkwood)Given by Hawkwood, or dropped upon death, after defeating Abyss Watchers.
FS: Fire Orb (Cornyx for Great Swamp Tome)Sold by Cornyx after giving him the Great Swamp Pyromancy Tome
FS: Fire Surge (Cornyx)Sold by Cornyx after recruiting him, or in his ashes
FS: Fire Whip (Karla for Quelana Tome)Sold by Karla after giving her the Quelana Pyromancy Tome
FS: Fireball (Cornyx)Sold by Cornyx after recruiting him, or in his ashes
FS: Firelink Armor (shop after placing all Cinders)Sold by Handmaid after defeating Soul of Cinder
FS: Firelink Gauntlets (shop after placing all Cinders)Sold by Handmaid after defeating Soul of Cinder
FS: Firelink Greatsword (Ludleth for Cinder)Boss weapon for Soul of Cinder
FS: Firelink Helm (shop after placing all Cinders)Sold by Handmaid after defeating Soul of Cinder
FS: Firelink Leggings (shop after placing all Cinders)Sold by Handmaid after defeating Soul of Cinder
FS: Firestorm (Karla for Quelana Tome)Sold by Karla after giving her the Quelana Pyromancy Tome
FS: Flash Sweat (Cornyx)Sold by Cornyx after recruiting him, or in his ashes
FS: Force (Irina for Tome of Carim)Sold by Irina after giving her the Braille Divine Tome of Carim
FS: Frayed Blade (Ludleth for Midir)Boss weapon for Darkeater Midir
FS: Friede's Great Scythe (Ludleth for Friede)Boss weapon for Sister Friede
FS: Gael's Greatsword (Ludleth for Gael)Boss weapon for Slave Knight Gael
FS: Gauntlets of Favor (shop after killing water reserve minibosses)Sold by Handmaid after killing Sulyvahn's Beasts in Water Reserve
FS: Gnaw (Karla for Deep Braille Tome)Sold by Irina or Karla after giving one the Deep Braille Divine Tome
FS: Golden Bracelets (shop after killing AP boss)Sold by Handmaid after defeating Nameless King
FS: Golden Crown (shop after killing AP boss)Sold by Handmaid after defeating Nameless King
FS: Grave Key (Mortician's Ashes)Sold by Handmaid after giving Mortician's Ashes
FS: Great Chaos Fire Orb (Cornyx for Izalith Tome)Sold by Cornyx after giving him Izalith Pyromancy Tome
FS: Great Combustion (Cornyx)Sold by Cornyx after recruiting him, or in his ashes
FS: Great Farron Dart (Orbeck for Sage's Scroll)Sold by Orbeck after giving him the Sage's Scroll
FS: Great Heavy Soul Arrow (Orbeck)Sold by Orbeck
FS: Great Soul Arrow (Orbeck)Sold by Orbeck
FS: Greatsword of Judgment (Ludleth for Pontiff)Boss weapon for Pontiff Sulyvahn
FS: Gundyr's Armor (shop after killing UG boss)Sold by Handmaid after defeating Champion Gundyr
FS: Gundyr's Gauntlets (shop after killing UG boss)Sold by Handmaid after defeating Champion Gundyr
FS: Gundyr's Halberd (Ludleth for Champion)Boss weapon for Champion Gundyr
FS: Gundyr's Helm (shop after killing UG boss)Sold by Handmaid after defeating Champion Gundyr
FS: Gundyr's Leggings (shop after killing UG boss)Sold by Handmaid after defeating Champion Gundyr
FS: Havel's Ring (Ludleth for Stray Demon)Boss weapon for Stray Demon
FS: Hawkwood's Shield (Hawkwood)Left by Hawkwood after defeating Abyss Watchers, Curse-Rotted Greatwood, Deacons of the Deep, and Crystal Sage
FS: Hawkwood's Swordgrass (Andre after gesture in AP summit)Given by Andre after praying at the Dragon Altar in Archdragon Peak, after acquiring Twinkling Dragon Torso Stone.
FS: Heal (Irina)Sold by Irina after recruiting her, or in her ashes
FS: Heal Aid (shop)Sold by Handmaid
FS: Heavy Soul Arrow (Orbeck)Sold by Orbeck
FS: Heavy Soul Arrow (Yoel/Yuria)Sold by Yoel/Yuria
FS: Helm of Favor (shop after killing water reserve minibosses)Sold by Handmaid after killing Sulyvahn's Beasts in Water Reserve
FS: Hidden Blessing (Dreamchaser's Ashes)Sold by Greirat after pillaging Irithyll
FS: Hidden Blessing (Greirat from IBV)Sold by Greirat after pillaging Irithyll
FS: Hidden Body (Orbeck for Golden Scroll)Sold by Orbeck after giving him the Golden Scroll
FS: Hidden Weapon (Orbeck for Golden Scroll)Sold by Orbeck after giving him the Golden Scroll
FS: Hollowslayer Greatsword (Ludleth for Greatwood)Boss weapon for Curse-Rotted Greatwood
FS: Homeward (Irina)Sold by Irina after recruiting her, or in her ashes
FS: Homeward Bone (cliff edge after boss)Along the cliff edge straight ahead of the Iudex Gundyr fight
FS: Homeward Bone (path above shrine entrace)To the right of the Firelink Shrine entrance, up a slope and before the ledge on top of a coffin
FS: Homing Crystal Soulmass (Orbeck for Crystal Scroll)Sold by Orbeck after giving him the Crystal Scroll
FS: Homing Soulmass (Orbeck for Logan's Scroll)Sold by Orbeck after giving him Logan's Scroll
FS: Karla's Coat (Prisoner Chief's Ashes)Sold by Handmaid after giving Prisoner Chief's Ashes
FS: Karla's Coat (kill Karla)Dropped from Karla upon death
FS: Karla's Gloves (Prisoner Chief's Ashes)Sold by Handmaid after giving Prisoner Chief's Ashes
FS: Karla's Gloves (kill Karla)Dropped from Karla upon death
FS: Karla's Pointed Hat (Prisoner Chief's Ashes)Sold by Handmaid after giving Prisoner Chief's Ashes
FS: Karla's Pointed Hat (kill Karla)Dropped from Karla upon death
FS: Karla's Trousers (Prisoner Chief's Ashes)Sold by Handmaid after giving Prisoner Chief's Ashes
FS: Karla's Trousers (kill Karla)Dropped from Karla upon death
FS: Leggings of Favor (shop after killing water reserve minibosses)Sold by Handmaid after killing Sulyvahn's Beasts in Water Reserve
FS: Leonhard's Garb (shop after killing Leonhard)Sold by Handmaid after killing Leonhard
FS: Leonhard's Gauntlets (shop after killing Leonhard)Sold by Handmaid after killing Leonhard
FS: Leonhard's Trousers (shop after killing Leonhard)Sold by Handmaid after killing Leonhard
FS: Life Ring (Dreamchaser's Ashes)Sold by Handmaid after giving Dreamchaser's Ashes
FS: Lifehunt Scythe (Ludleth for Aldrich)Boss weapon for Aldrich
FS: Lift Chamber Key (Leonhard)Given by Ringfinger Leonhard after acquiring a Pale Tongue.
FS: Lightning Storm (Ludleth for Nameless)Boss weapon for Nameless King
FS: Lloyd's Shield Ring (Paladin's Ashes)Sold by Handmaid after giving Paladin's Ashes
FS: Londor Braille Divine Tome (Yoel/Yuria)Sold by Yuria
FS: Lorian's Armor (shop after killing GA boss)Sold by Handmaid after defeating Lothric, Younger Prince
FS: Lorian's Gauntlets (shop after killing GA boss)Sold by Handmaid after defeating Lothric, Younger Prince
FS: Lorian's Greatsword (Ludleth for Princes)Boss weapon for Twin Princes
FS: Lorian's Helm (shop after killing GA boss)Sold by Handmaid after defeating Lothric, Younger Prince
FS: Lorian's Leggings (shop after killing GA boss)Sold by Handmaid after defeating Lothric, Younger Prince
FS: Lothric's Holy Sword (Ludleth for Princes)Boss weapon for Twin Princes
FS: Magic Barrier (Irina for Tome of Lothric)Sold by Irina after giving her the Braille Divine Tome of Lothric
FS: Magic Shield (Orbeck)Sold by Orbeck
FS: Magic Shield (Yoel/Yuria)Sold by Yoel/Yuria
FS: Magic Weapon (Orbeck)Sold by Orbeck
FS: Magic Weapon (Yoel/Yuria)Sold by Yoel/Yuria
FS: Mail Breaker (Sirris for killing Creighton)Given by Sirris talking to her in Firelink Shrine after invading and vanquishing Creighton.
FS: Master's Attire (NPC drop)Dropped by Sword Master
FS: Master's Gloves (NPC drop)Dropped by Sword Master
FS: Med Heal (Irina for Tome of Carim)Sold by Irina after giving her the Braille Divine Tome of Carim
FS: Millwood Knight Armor (Captain's Ashes)Sold by Handmaid after giving Captain's Ashes
FS: Millwood Knight Gauntlets (Captain's Ashes)Sold by Handmaid after giving Captain's Ashes
FS: Millwood Knight Helm (Captain's Ashes)Sold by Handmaid after giving Captain's Ashes
FS: Millwood Knight Leggings (Captain's Ashes)Sold by Handmaid after giving Captain's Ashes
FS: Moaning Shield (Eygon)Dropped by Eygon of Carim
FS: Moonlight Greatsword (Ludleth for Oceiros)Boss weapon for Oceiros, the Consumed King
FS: Morion Blade (Yuria for Orbeck's Ashes)Given by Yuria after giving Orbeck's Ashes after she asks you to assassinate him, after he moves to Firelink Shrine. Can be done without killing Orbeck, by completing his questline.
FS: Morne's Armor (shop after killing Eygon or LC boss)Sold by Handmaid after killing Eygon of Carim or defeating Dragonslayer Armour
FS: Morne's Gauntlets (shop after killing Eygon or LC boss)Sold by Handmaid after killing Eygon of Carim or defeating Dragonslayer Armour
FS: Morne's Great Hammer (Eygon)Dropped by Eygon of Carim
FS: Morne's Helm (shop after killing Eygon or LC boss)Sold by Handmaid after killing Eygon of Carim or defeating Dragonslayer Armour
FS: Morne's Leggings (shop after killing Eygon or LC boss)Sold by Handmaid after killing Eygon of Carim or defeating Dragonslayer Armour
FS: Old King's Great Hammer (Ludleth for Old Demon King)Boss weapon for Old Demon King
FS: Old Moonlight (Ludleth for Midir)Boss weapon for Darkeater Midir
FS: Ordained Dress (shop after killing PW2 boss)Sold by Handmaid after defeating Sister Friede
FS: Ordained Hood (shop after killing PW2 boss)Sold by Handmaid after defeating Sister Friede
FS: Ordained Trousers (shop after killing PW2 boss)Sold by Handmaid after defeating Sister Friede
FS: Pale Shade Gloves (Yoel's room, kill Londor Pale Shade twice)In Yoel/Yuria's area after defeating both Londor Pale Shade invasions
FS: Pale Shade Robe (Yoel's room, kill Londor Pale Shade twice)In Yoel/Yuria's area after defeating both Londor Pale Shade invasions
FS: Pale Shade Trousers (Yoel's room, kill Londor Pale Shade twice)In Yoel/Yuria's area after defeating both Londor Pale Shade invasions
FS: Pestilent Mist (Orbeck for any scroll)Sold by Orbeck after giving him any scroll
FS: Poison Mist (Cornyx for Great Swamp Tome)Sold by Cornyx after giving him the Great Swamp Pyromancy Tome
FS: Pontiff's Left Eye (Ludleth for Vordt)Boss weapon for Vordt of the Boreal Valley
FS: Prisoner's Chain (Ludleth for Champion)Boss weapon for Champion Gundyr
FS: Profaned Greatsword (Ludleth for Pontiff)Boss weapon for Pontiff Sulyvahn
FS: Profuse Sweat (Cornyx for Great Swamp Tome)Sold by Cornyx after giving him the Great Swamp Pyromancy Tome
FS: Rapport (Karla for Quelana Tome)Sold by Karla after giving her the Quelana Pyromancy Tome
FS: Refined Gem (Captain's Ashes)Sold by Handmaid after giving Captain's Ashes
FS: Repair (Orbeck for Golden Scroll)Sold by Orbeck after giving him the Golden Scroll
FS: Repeating Crossbow (Ludleth for Gael)Boss weapon for Slave Knight Gael
FS: Replenishment (Irina)Sold by Irina after recruiting her, or in her ashes
FS: Ring of Sacrifice (Yuria shop)Sold by Yuria, or by Handmaid after giving Hollow's Ashes
FS: Rose of Ariandel (Ludleth for Friede)Boss weapon for Sister Friede
FS: Rusted Gold Coin (don't forgive Patches)Given by Patches after not forgiving him after he locks you in the Bell Tower.
FS: Sage's Big Hat (shop after killing RS boss)Sold by Handmaid after defeating Crystal Sage
FS: Saint's Ring (Irina)Sold by Irina after recruiting her, or in her ashes
FS: Seething Chaos (Ludleth for Demon Prince)Boss weapon for Demon Prince
FS: Silvercat Ring (Sirris for killing Creighton)Given by Sirris talking to her in Firelink Shrine after invading and vanquishing Creighton.
FS: Skull Ring (kill Ludleth)Dropped by Ludleth upon death, including after placing all cinders. Note that if killed before giving Transposing Kiln, transposition is not possible.
FS: Slumbering Dragoncrest Ring (Orbeck for buying four specific spells)Given by Orbeck after purchasing the shop items corresponding to Aural Decoy, Farron Flashsword, Spook (starting items), and Pestlient Mist (after giving one scroll).
FS: Smough's Armor (shop after killing AL boss)Sold by Handmaid after defeating Alrich, Devourer of Gods
FS: Smough's Gauntlets (shop after killing AL boss)Sold by Handmaid after defeating Alrich, Devourer of Gods
FS: Smough's Helm (shop after killing AL boss)Sold by Handmaid after defeating Alrich, Devourer of Gods
FS: Smough's Leggings (shop after killing AL boss)Sold by Handmaid after defeating Alrich, Devourer of Gods
FS: Sneering Mask (Yoel's room, kill Londor Pale Shade twice)In Yoel/Yuria's area after defeating both Londor Pale Shade invasions
FS: Soothing Sunlight (Ludleth for Dancer)Boss weapon for Dancer of the Boreal Valley
FS: Soul Arrow (Orbeck)Sold by Orbeck
FS: Soul Arrow (Yoel/Yuria)Sold by Yoel/Yuria
FS: Soul Arrow (shop)Sold by Handmaid
FS: Soul Greatsword (Orbeck)Sold by Orbeck
FS: Soul Greatsword (Yoel/Yuria)Sold by Yoel/Yuria after using Draw Out True Strength
FS: Soul Spear (Orbeck for Logan's Scroll)Sold by Orbeck after giving him Logan's Scroll
FS: Soul of a Deserted Corpse (bell tower door)Next to the door requiring the Tower Key
FS: Spook (Orbeck)Sold by Orbeck
FS: Storm Curved Sword (Ludleth for Nameless)Boss weapon for Nameless King
FS: Sunless Armor (shop, Sirris quest, kill GA boss)Sold by Handmaid after completing Sirris' questline
FS: Sunless Gauntlets (shop, Sirris quest, kill GA boss)Sold by Handmaid after completing Sirris' questline
FS: Sunless Leggings (shop, Sirris quest, kill GA boss)Sold by Handmaid after completing Sirris' questline
FS: Sunless Talisman (Sirris, kill GA boss)Dropped by Sirris on death or quest completion.
FS: Sunless Veil (shop, Sirris quest, kill GA boss)Sold by Handmaid after completing Sirris' questline
FS: Sunlight Spear (Ludleth for Cinder)Boss weapon for Soul of Cinder
FS: Sunset Shield (by grave after killing Hodrick w/Sirris)Left by Sirris upon quest completion.
FS: Tears of Denial (Irina for Tome of Carim)Sold by Irina after giving her the Braille Divine Tome of Carim
FS: Titanite Scale (Greirat from IBV)Sold by Greirat after pillaging Irithyll
FS: Titanite Slab (shop after placing all Cinders)Sold by Handmaid after placing all Cinders of a Lord on their thrones
FS: Tower Key (shop)Sold by both Shrine Handmaid and Untended Graves Handmaid
FS: Twinkling Titanite (Greirat from IBV)Sold by Greirat after pillaging Irithyll
FS: Twisted Wall of Light (Orbeck for Golden Scroll)Sold by Orbeck after giving him the Golden Scroll
FS: Uchigatana (NPC drop)Dropped by Sword Master
FS: Undead Legion Armor (shop after killing FK boss)Sold by Handmaid after defeating Abyss Watchers
FS: Undead Legion Gauntlet (shop after killing FK boss)Sold by Handmaid after defeating Abyss Watchers
FS: Undead Legion Helm (shop after killing FK boss)Sold by Handmaid after defeating Abyss Watchers
FS: Undead Legion Leggings (shop after killing FK boss)Sold by Handmaid after defeating Abyss Watchers
FS: Untrue Dark Ring (Yoel/Yuria)Sold by Yuria
FS: Untrue White Ring (Yoel/Yuria)Sold by Yuria
FS: Vordt's Great Hammer (Ludleth for Vordt)Boss weapon for Vordt of the Boreal Valley
FS: Vow of Silence (Karla for Londor Tome)Sold by Irina or Karla after giving one the Londor Braille Divine Tome
FS: Washing Pole (Easterner's Ashes)Sold by Handmaid after giving Easterner's Ashes
FS: White Dragon Breath (Ludleth for Oceiros)Boss weapon for Oceiros, the Consumed King
FS: White Sign Soapstone (shop)Sold by both Shrine Handmaid and Untended Graves Handmaid
FS: Wolf Knight's Greatsword (Ludleth for Abyss Watchers)Boss weapon for Abyss Watchers
FS: Wolf Ring+2 (left of boss room exit)After Iudex Gundyr on the left
FS: Wolnir's Crown (shop after killing CC boss)Sold by Handmaid after defeating High Lord Wolnir
FS: Wolnir's Holy Sword (Ludleth for Wolnir)Boss weapon for High Lord Wolnir
FS: Wood Grain Ring (Easterner's Ashes)Sold by Handmaid after giving Easterner's Ashes
FS: Xanthous Gloves (Xanthous Ashes)Sold by Handmaid after giving Xanthous Ashes
FS: Xanthous Overcoat (Xanthous Ashes)Sold by Handmaid after giving Xanthous Ashes
FS: Xanthous Trousers (Xanthous Ashes)Sold by Handmaid after giving Xanthous Ashes
FS: Yhorm's Great Machete (Ludleth for Yhorm)Boss weapon for Yhorm the Giant
FS: Yhorm's Greatshield (Ludleth for Yhorm)Boss weapon for Yhorm the Giant
FS: Young Dragon Ring (Orbeck for one scroll and buying three spells)Given by Orbeck after purchasing four sorceries from him, and giving him one scroll, as a non-sorcerer.
FSBT: Armor of the Sun (crow for Siegbräu)Trade Siegbrau with crow
FSBT: Blessed Gem (crow for Moaning Shield)Trade Moaning Shield with crow
FSBT: Covetous Silver Serpent Ring (illusory wall past rafters)From the Firelink Shrine roof, past the rafters and an illusory wall
FSBT: Estus Ring (rafters)Dropping down from the Bell Tower to where Irina eventually resides
FSBT: Estus Shard (rafters)In the Firelink Shrine rafters, accessible from the roof
FSBT: Fire Keeper Gloves (partway down tower)Dropping down to the left after entering the Bell Tower. Align with the center of the closest floor tile row and run off the edge at full speed, aiming slightly left.
FSBT: Fire Keeper Robe (partway down tower)Dropping down to the left after entering the Bell Tower. Align with the center of the closest floor tile row and run off the edge at full speed, aiming slightly left.
FSBT: Fire Keeper Skirt (partway down tower)Dropping down to the left after entering the Bell Tower. Align with the center of the closest floor tile row and run off the edge at full speed, aiming slightly left.
FSBT: Fire Keeper Soul (tower top)At the top of the Bell Tower
FSBT: Hello Carving (crow for Alluring Skull)Trade Alluring Skull with crow
FSBT: Help me! Carving (crow for any sacred chime)Trade any Sacred Chime with crow
FSBT: Hollow Gem (crow for Eleonora)Trade Eleonora with crow
FSBT: Homeward Bone (roof)On Firelink Shrine roof
FSBT: I'm sorry Carving (crow for Shriving Stone)Trade Shriving Stone with crow
FSBT: Iron Bracelets (crow for Homeward Bone)Trade Homeward Bone with crow
FSBT: Iron Helm (crow for Lightning Urn)Trade Lightning Urn with crow
FSBT: Iron Leggings (crow for Seed of a Giant Tree)Trade Seed of a Giant Tree with crow
FSBT: Large Titanite Shard (crow for Firebomb)Trade Firebomb or Rope Firebomb with crow
FSBT: Lightning Gem (crow for Xanthous Crown)Trade Xanthous Crown with crow
FSBT: Lucatiel's Mask (crow for Vertebra Shackle)Trade Vertebra Shackle with crow
FSBT: Porcine Shield (crow for Undead Bone Shard)Trade Undead Bone Shard with crow
FSBT: Ring of Sacrifice (crow for Loretta's Bone)Trade Loretta's Bone with crow
FSBT: Sunlight Shield (crow for Mendicant's Staff)Trade Mendicant's Staff with crow
FSBT: Thank you Carving (crow for Hidden Blessing)Trade Hidden Blessing with crow
FSBT: Titanite Chunk (crow for Black Firebomb)Trade Black Firebomb or Rope Black Firebomb with crow
FSBT: Titanite Scale (crow for Blacksmith Hammer)Trade Blacksmith Hammer with crow
FSBT: Titanite Slab (crow for Coiled Sword Fragment)Trade Coiled Sword Fragment with crow
FSBT: Twinkling Titanite (crow for Large Leather Shield)Trade Large Leather Shield with crow
FSBT: Twinkling Titanite (crow for Prism Stone)Trade Prism Stone with crow
FSBT: Twinkling Titanite (lizard behind Firelink)Dropped by the Crystal Lizard behind Firelink Shrine. Can be accessed with tree jump by going all the way around the roof, left of the entrance to the rafters, or alternatively dropping down from the Bell Tower.
FSBT: Very good! Carving (crow for Divine Blessing)Trade Divine Blessing with crow
GA: Avelyn (1F, drop from 3F onto bookshelves)On top of a bookshelf on the Archive first floor, accessible by going halfway up the stairs to the third floor, dropping down past the Grand Archives Scholar, and then dropping down again
GA: Black Hand Armor (shop after killing GA NPC)Sold by Handmaid after killing Black Hand Kumai
GA: Black Hand Hat (shop after killing GA NPC)Sold by Handmaid after killing Black Hand Kumai
GA: Blessed Gem (rafters)On the rafters high above the Archives, can be accessed by dropping down from the Winged Knight roof area
GA: Chaos Gem (dark room, lizard)Dropped by a Crystal Lizard on the Archives first floor in the dark room past the large wax pool
GA: Cinders of a Lord - Lothric PrinceDropped by Twin Princes
GA: Crystal Chime (1F, path from wax pool)On the Archives first floor, in the room with the Lothric Knight, to the right
GA: Crystal Gem (1F, lizard by drop)Dropped by the Crystal Lizard on the Archives first floor along the left wall
GA: Crystal Scroll (2F late, miniboss drop)Dropped by the Grand Archives Crystal Sage
GA: Divine Blessing (rafters, down lower level ladder)In a chest reachable after dropping down from the Archives rafters and down a ladder near the Corpse-grub
GA: Divine Pillars of Light (cage above rafters)In a cage above the rafters high above the Archives, can be accessed by dropping down from the Winged Knight roof area
GA: Ember (5F, by entrance)On a balcony high in the Archives overlooking the area with the Grand Archives Scholars with a shortcut ladder, on the opposite side from the wax pool
GA: Estus Shard (dome, far balcony)On the Archives roof near the three Winged Knights, in a side area overlooking the ocean.
GA: Faraam Armor (shop after killing GA NPC)Sold by Handmaid after killing Lion Knight Albert
GA: Faraam Boots (shop after killing GA NPC)Sold by Handmaid after killing Lion Knight Albert
GA: Faraam Gauntlets (shop after killing GA NPC)Sold by Handmaid after killing Lion Knight Albert
GA: Fleshbite Ring (up stairs from 4F)From the first shortcut elevator with the movable bookshelf, past the Scholars right before going outside onto the roof, in an alcove to the right with many Clawed Curse bookshelves
GA: Golden Wing Crest Shield (outside 5F, NPC drop)Dropped by Lion Knight Albert before the stairs leading up to Twin Princes
GA: Heavy Gem (rooftops, lizard)Dropped by one of the pair of Crystal Lizards, on the right side, found going up a slope past the gargoyle on the Archives roof
GA: Hollow Gem (rooftops lower, in hall)Going onto the roof and down the first ladder, dropping down on either side from the ledge facing the ocean, in a tunnel underneath the ledge
GA: Homeward Bone (2F early balcony)On the Archives second floor, on the balcony with the ladder going up to the Crystal Sage
GA: Hunter's Ring (dome, very top)At the top of the ladder in roof the area with the Winged Knights
GA: Large Soul of a Crestfallen Knight (4F, back)In the back of a Clawed Curse-heavy corridor of bookshelves, in the area with the Grand Archives Scholars and dropdown ladder, after the first shortcut elevator with the movable bookshelf
GA: Large Soul of a Crestfallen Knight (outside 5F)In the middle of the area with the three human NPCs attacking you, before the Grand Archives bonfire shortcut elevator
GA: Lingering Dragoncrest Ring+2 (dome, room behind spire)Near the tower with the Winged Knights, up the stairs on the opposite side from the ladder leading up to the Hunter's Ring
GA: Onikiri and Ubadachi (outside 5F, NPC drop)Dropped by Black Hand Kamui before the stairs leading up to Twin Princes
GA: Outrider Knight Armor (3F, behind illusory wall, miniboss drop)Dropped by an Outrider Knight past the Crystal Sage's third floor location and an illusory wall
GA: Outrider Knight Gauntlets (3F, behind illusory wall, miniboss drop)Dropped by an Outrider Knight past the Crystal Sage's third floor location and an illusory wall
GA: Outrider Knight Helm (3F, behind illusory wall, miniboss drop)Dropped by an Outrider Knight past the Crystal Sage's third floor location and an illusory wall
GA: Outrider Knight Leggings (3F, behind illusory wall, miniboss drop)Dropped by an Outrider Knight past the Crystal Sage's third floor location and an illusory wall
GA: Power Within (dark room, behind retractable bookshelf)Behind a bookshelf in the dark room with the Crystal Lizards, moved by a lever in the same room
GA: Refined Gem (up stairs from 4F, lizard)Dropped by a Crystal Lizard found heading from the first elevator shortcut with the movable bookshelf, on the right side up the stairs before exiting to the roof
GA: Sage Ring+1 (rafters, second level down)On the rafters high above the Grand Archives, dropping down from the cage to the high rafters to the rafters below with the Corpse-grub
GA: Sage's Crystal Staff (outside 5F, NPC drop)Dropped by Daughter of Crystal Kriemhild before the stairs leading up to Twin Princes
GA: Scholar Ring (2F, between late and early)On the corpse of a sitting Archives Scholar between two bookshelves, accessible by activating a lever before crossing the bridge that is the Crystal Sage's final location
GA: Sharp Gem (rooftops, lizard)Dropped by one of the pair of Crystal Lizards, on the left side, found going up a slope past the gargoyle on the Archives roof
GA: Shriving Stone (2F late, by ladder from 3F)Going from the Crystal Sage's location on the third floor to its location on the bridge, after descending the ladder
GA: Soul Stream (3F, behind illusory wall)Past the Crystal Sage's third floor location, an illusory wall, and an Outrider Knight, on the corpse of a sitting Archives Scholar
GA: Soul of a Crestfallen Knight (1F, loop left after drop)On the Archives first floor, hugging the left wall, on a ledge that loops back around to the left wall
GA: Soul of a Crestfallen Knight (path to dome)On balcony of the building with the second shortcut elevator down to the bonfire, accessible by going up the spiral stairs to the left
GA: Soul of a Nameless Soldier (dark room)On the Archives first floor, after the wax pool, against a Clawed Curse bookshelf
GA: Soul of a Weary Warrior (rooftops, by lizards)On the Archives roof, going up the first rooftop slope where a Gargoyle always attacks you
GA: Soul of the Twin PrincesDropped by Twin Princes
GA: Titanite Chunk (1F, balcony)On the Archives first floor, on balcony overlooking the entrance opposite from the Grand Archives Scholars wax pool
GA: Titanite Chunk (1F, path from wax pool)On the Archives first floor, toward the Lothric Knight, turning right to a ledge leading back to the entrance area
GA: Titanite Chunk (1F, up right stairs)Going right after entering the Archives entrance and up the short flight of stairs
GA: Titanite Chunk (2F, by wax pool)Up the stairs from the Archives second floor on the right side from the entrance, in a corner near the small wax pool
GA: Titanite Chunk (2F, right after dark room)Exiting from the dark room with the Crystal Lizards on the first floor onto the second floor main room, then taking an immediate right
GA: Titanite Chunk (5F, far balcony)On a balcony outside where Lothric Knight stands on the top floor of the Archives, accessing by going right from the final wax pool or by dropping down from the gargoyle area
GA: Titanite Chunk (rooftopps, balcony)Going onto the roof and down the first ladder, all the way down the ledge facing the ocean to the right
GA: Titanite Chunk (rooftops lower, ledge by buttress)Going onto the roof and down the first ladder, dropping down on either side from the ledge facing the ocean, on a roof ledge to the right
GA: Titanite Chunk (rooftops, just before 5F)On the Archives roof, after a short dropdown, in the small area where the two Gargoyles attack you
GA: Titanite Scale (1F, drop from 2F late onto bookshelves, lizard)Dropped by a Crystal Lizard on first floor bookshelves. Can be acessed by dropping down to the left at the end of the bridge which is the Crystal Sage's final location
GA: Titanite Scale (1F, up stairs on bookshelf)On the Archives first floor, up a movable set of stairs near the large wax pool, on top of a bookshelf
GA: Titanite Scale (2F, titanite scale atop bookshelf)On top of a bookshelf on the Archive second floor, accessible by going halfway up the stairs to the third floor and dropping down near a Grand Archives Scholar
GA: Titanite Scale (3F, by ladder to 2F late)Going from the Crystal Sage's location on the third floor to its location on the bridge, on the left side of the ladder you descend, behind a table
GA: Titanite Scale (3F, corner up stairs)From the Grand Archives third floor up past the thralls, in a corner with bookshelves to the left
GA: Titanite Scale (5F, chest by exit)In a chest after the first elevator shortcut with the movable bookshelf, in the area with the Grand Archives Scholars, to the left of the stairwell leading up to the roof
GA: Titanite Scale (dark room, upstairs)Right after going up the stairs to the Archives second floor, on the left guarded by a Grand Archives Scholar and a sequence of Clawed Curse bookshelves
GA: Titanite Scale (rooftops lower, path to 2F)Going onto the roof and down the first ladder, dropping down on either side from the ledge facing the ocean, then going past the corvians all the way to the left and making a jump
GA: Titanite Slab (1F, after pulling 2F switch)In a chest on the Archives first floor, behind a bookshelf moved by pulling a lever in the middle of the second floor between two cursed bookshelves
GA: Titanite Slab (dome, kill all mobs)Dropped by killing all three Winged Knights on top of the Archives
GA: Titanite Slab (final elevator secret)At the bottom of the shortcut elevator right outside the Twin Princes fight. Requires sending the elevator up to the top from the middle, and then riding the lower elevator down.
GA: Twinkling Titanite (1F, lizard by drop)Dropped by the Crystal Lizard on the Archives first floor along the left wall
GA: Twinkling Titanite (2F, lizard by entrance)Dropped by the Crystal Lizard on the Archives second floor, going toward the stairs/balcony
GA: Twinkling Titanite (dark room, lizard #1)Dropped by a Crystal Lizard on the Archives first floor in the dark room past the large wax pool
GA: Twinkling Titanite (dark room, lizard #2)Dropped by a Crystal Lizard on the Archives first floor in the dark room past the large wax pool
GA: Twinkling Titanite (rafters, down lower level ladder)In a chest reachable after dropping down from the Archives rafters and down a ladder near the Corpse-grub
GA: Twinkling Titanite (rooftops, lizard #1)Dropped by one of the pair of Crystal Lizards, on the right side, found going up a slope past the gargoyle on the Archives roof
GA: Twinkling Titanite (rooftops, lizard #2)Dropped by one of the pair of Crystal Lizards, on the left side, found going up a slope past the gargoyle on the Archives roof
GA: Twinkling Titanite (up stairs from 4F, lizard)Dropped by a Crystal Lizard found heading from the first elevator shortcut with the movable bookshelf, on the right side up the stairs before exiting to the roof
GA: Undead Bone Shard (5F, by entrance)On the corpse of a sitting Archives Scholar on a balcony high in the Archives overlooking the area with the Grand Archives Scholars with a shortcut ladder, near the final wax pool
GA: Witch's Locks (dark room, behind retractable bookshelf)Behind a bookshelf in the dark room with the Crystal Lizards, moved by a lever in the same room
HWL: Astora Straight Sword (fort walkway, drop down)In the building with the Pus of Man on the roof, past the Lothric Knight down a hallway obscured by a wooden wheel, dropping down past the edge
HWL: Basin of Vows (Emma)Dropped by Emma upon killing her. This is possible to do at any time
HWL: Battle Axe (flame tower, mimic)Dropped by mimic in the building guarded by the fire-breathing wyvern
HWL: Binoculars (corpse tower, upper platform)In the area with the dead wyvern, at the top of a set of stairs past a Hollow Soldier
HWL: Black Firebomb (small roof over fountain)After roof with Pus of Man, on the edge of another rooftop to the left where you can drop down into Winged Knight area
HWL: Broadsword (fort, room off entry)In the building with the Pus of Man on the roof, past the Lothric Knight in an alcove to the left
HWL: Cell Key (fort basement, down stairs)In the basement of the building with Pus of Man on the roof, down the stairs guarded by a dog
HWL: Claymore (flame plaza)In the area where the wyvern breathes fire, farthest away from the door
HWL: Club (flame plaza)In the area where the wyvern breathes fire, in the open
HWL: Ember (back tower roof bonfire, transforming hollow)Dropped by the Pus of Man on the tower to the right of the High Wall bonfire after transformation
HWL: Ember (flame plaza)In the area where the wyvern breathes fire, in the open
HWL: Ember (fort roof, transforming hollow)Dropped by the Pus of Man on the roof after the Tower on the Wall bonfire after transformation
HWL: Ember (fountain #1)In the area with the Winged Knight
HWL: Ember (fountain, #2)In the area with the Winged Knight
HWL: Estus Shard (fort basement, on anvil)In the basement of the building with the Pus of Man on the roof, on the blacksmith anvil
HWL: Firebomb (corpse tower, under table)In the building near the dead wyvern, behind a table near the ladder you descend
HWL: Firebomb (fort roof)Next to the Pus of Man on the roof
HWL: Firebomb (top of ladder to fountain)By the long ladder leading down to the area with the Winged Knight
HWL: Firebomb (wall tower, beam)In the building with the Tower on the Wall bonfire, on a wooden beam overhanging the lower levels
HWL: Fleshbite Ring+1 (fort roof, jump to other roof)Jumping from the roof with the Pus of Man to a nearby building with a fenced roof
HWL: Gold Pine Resin (corpse tower, drop)Dropping past the dead wyvern, down the left path from the High Wall bonfire
HWL: Green Blossom (fort walkway, hall behind wheel)In the building with the Pus of Man on the roof, past the Lothric Knight down a hallway obscured by a wooden wheel
HWL: Green Blossom (shortcut, by lower lift door)In the courtyard at the bottom of the shortcut elevator
HWL: Large Soul of a Deserted Corpse (flame plaza)In the area where the wyvern breathes fire, behind one of the praying statues
HWL: Large Soul of a Deserted Corpse (fort roof)On the edge of the roof with the Pus of Man
HWL: Large Soul of a Deserted Corpse (platform by fountain)Coming from the elevator shortcut, on a side path to the left (toward Winged Knight area)
HWL: Longbow (back tower)Down the path from the right of the High Wall bonfire, where the Pus of Man and crossbowman are
HWL: Lucerne (promenade, side path)On one of the side paths from the main path connecting Dancer and Vordt fights, patrolled by a Lothric Knight
HWL: Mail Breaker (wall tower, path to Greirat)In the basement of the building with the Tower on the Wall bonfire on the roof, before Greirat's cell
HWL: Rapier (fountain, corner)In a corner in the area with the Winged Knight
HWL: Raw Gem (fort roof, lizard)Dropped by the Crystal Lizard on the rooftop after the Tower on the Wall bonfire
HWL: Red Eye Orb (wall tower, miniboss)Dropped by the Darkwraith past the Lift Chamber Key
HWL: Refined Gem (promenade miniboss)Dropped by the red-eyed Lothric Knight to the left of the Dancer's room entrance
HWL: Ring of Sacrifice (awning by fountain)Coming from the elevator shortcut, on a side path to the left (toward Winged Knight area), jumping onto a wooden support
HWL: Ring of the Evil Eye+2 (fort basement, far wall)In the basement of the building with the Pus of Man on the roof, on the far wall past the stairwell, behind some barrels
HWL: Silver Eagle Kite Shield (fort mezzanine)In the chest on the balcony overlooking the basement of the building with the Pus of Man on the roof
HWL: Small Lothric Banner (Emma)Given by Emma, or dropped upon death
HWL: Soul of Boreal Valley VordtDropped by Vordt of the Boreal Valley
HWL: Soul of a Deserted Corpse (by wall tower door)Right before the entrance to the building with the Tower on the Wall bonfire
HWL: Soul of a Deserted Corpse (corpse tower, bottom floor)Down the ladder of the building near the dead wyvern, on the way to the living wyvern
HWL: Soul of a Deserted Corpse (fort entry, corner)In the corner of the room with a Lothric Knight, with the Pus of Man on the roof
HWL: Soul of a Deserted Corpse (fountain, path to promenade)In between the Winged Knight area and the Dancer/Vordt corridor
HWL: Soul of a Deserted Corpse (path to back tower, by lift door)Where the Greataxe Hollow Soldier patrols outside of the elevator shortcut entrance
HWL: Soul of a Deserted Corpse (path to corpse tower)At the very start, heading left from the High Wall bonfire
HWL: Soul of a Deserted Corpse (wall tower, right of exit)Exiting the building with the Tower on the Wall bonfire on the roof, immediately to the right
HWL: Soul of the DancerDropped by Dancer of the Boreal Valley
HWL: Standard Arrow (back tower)Down the path from the right of the High Wall bonfire, where the Pus of Man and crossbowman are
HWL: Throwing Knife (shortcut, lift top)At the top of the elevator shortcut, opposite from the one-way door
HWL: Throwing Knife (wall tower, path to Greirat)In the basement of the building with the Tower on the Wall bonfire, in the room with the explosive barrels
HWL: Titanite Shard (back tower roof bonfire, transforming hollow)Dropped by the Pus of Man on the tower to the right of the High Wall bonfire after transformation
HWL: Titanite Shard (for, room off entry)In the building with the Pus of Man on the roof, in a room to the left and up the short stairs
HWL: Titanite Shard (fort basement, behind crates)Behind some wooden crates in the basement of the building with the Pus of Man on the roof
HWL: Titanite Shard (fort roof, transforming hollow)Dropped by the Pus of Man on the roof after the Tower on the Wall bonfire after transformation
HWL: Titanite Shard (wall tower, corner by bonfire)On the balcony with the Tower on the Wall bonfire
HWL: Undead Hunter Charm (fort, room off entry, in pot)In the building with the Pus of Man on the roof, in a room to the left, in a pot you have to break
HWL: Way of Blue (Emma)Given by Emma or dropped upon death.
IBV: Blood Gem (descent, platform before lake)In front of the tree in the courtyard before going down the stairs to the lake leading to the Distant Manor bonfire
IBV: Blue Bug Pellet (ascent, in last building)In the final building before Pontiff's cathedral, coming from the sewer, on the first floor
IBV: Blue Bug Pellet (descent, dark room)In the dark area with the Irithyllian slaves, to the left of the staircase
IBV: Budding Green Blossom (central, by second fountain)Next to the fountain up the stairs from the Central Irithyll bonfire
IBV: Chloranthy Ring+1 (plaza, behind altar)In the area before and below Pontiff's cathedral, behind the central structure
IBV: Covetous Gold Serpent Ring+1 (descent, drop after dark room)After the dark area with the Irithyllian slaves, drop down to the right
IBV: Creighton's Steel Mask (bridge after killing Creighton)Following Sirris' questline, found on the bridge to Irithyll after being invaded by Creighton the Wanderer in the graveyard after the Church of Yorshka.
IBV: Divine Blessing (great hall, chest)In a chest up the stairs in the room with the Silver Knight staring at the painting
IBV: Divine Blessing (great hall, mob)One-time drop from the Silver Knight staring at the painting in Irithyll
IBV: Dorhys' Gnawing (Dorhys drop)Dropped by Cathedral Evangelist Dorhys, past an illusory railing past the Central Irithyll Fire Witches and to the left
IBV: Dragonslayer's Axe (Creighton drop)Following Sirris' questline, dropped by Creighton the Wanderer when he invades in the graveyard after the Church of Yorshka.
IBV: Dung Pie (sewer #1)In the area with the sewer centipedes
IBV: Dung Pie (sewer #2)In the area with the sewer centipedes
IBV: Ember (shortcut from church to cathedral)After the gate shortcut from Church of Yorshka to Pontiff's cathedral
IBV: Emit Force (Siegward)Given by Siegward meeting him in the Irithyll kitchen after the Sewer Centipedes.
IBV: Excrement-covered Ashes (sewer, by stairs)In the area with the sewer centipedes, before going up the stairs to the kitchen
IBV: Fading Soul (descent, cliff edge #1)In the graveyard down the stairs from the Church of Yorshka, at the cliff edge
IBV: Fading Soul (descent, cliff edge #2)In the graveyard down the stairs from the Church of Yorshka, at the cliff edge
IBV: Great Heal (lake, dead Corpse-Grub)On the Corpse-grub at the edge of the lake leading to the Distant Manor bonfire
IBV: Green Blossom (lake wall)On the wall of the lake leading to the Distant Manor bonfire
IBV: Green Blossom (lake, by Distant Manor)In the lake close to the Distant Manor bonfire
IBV: Green Blossom (lake, by stairs from descent)Going down the stairs into the lake leading to the Distant Manor bonfire
IBV: Homeward Bone (descent, before gravestone)In the graveyard down the stairs from the Church of Yorshka, in front of the grave with the Corvian
IBV: Kukri (descent, side path)Down the stairs from the graveyard after Church of Yorshka, before the group of dogs in the left path
IBV: Large Soul of a Nameless Soldier (ascent, after great hall)By the tree near the stairs from the sewer leading up to Pontiff's cathedral, where the first dogs attack you
IBV: Large Soul of a Nameless Soldier (central, by bonfire)By the Central Irithyll bonfire
IBV: Large Soul of a Nameless Soldier (central, by second fountain)Next to the fountain up the stairs from the Central Irithyll bonfire
IBV: Large Soul of a Nameless Soldier (lake island)On an island in the lake leading to the Distant Manor bonfire
IBV: Large Soul of a Nameless Soldier (stairs to plaza)On the path from Central Irithyll bonfire, before making the left toward Church of Yorshka
IBV: Large Titanite Shard (ascent, by elevator door)On the path from the sewer leading up to Pontiff's cathedral, to the right of the statue surrounded by dogs
IBV: Large Titanite Shard (ascent, down ladder in last building)Outside the final building before Pontiff's cathedral, coming from the sewer, dropping down to the left before the entrance
IBV: Large Titanite Shard (central, balcony just before plaza)From the Central Irithyll bonfire, on the balcony with the second Fire Witch.
IBV: Large Titanite Shard (central, side path after first fountain)Up the stairs from the Central Irithyll bonfire, on a railing to the right
IBV: Large Titanite Shard (great hall, mob)After Pontiff's cathedral, hugging the wall to the right
IBV: Large Titanite Shard (path to Dorhys)Before the area with Cathedral Evangelist Dorhys, past an illusory railing past the Central Irithyll Fire Witches
IBV: Large Titanite Shard (plaza, balcony overlooking ascent)On the path from Central Irithyll bonfire, instead of going left toward the Church of Yorshka, going right, on the balcony
IBV: Large Titanite Shard (plaza, by stairs to church)To the left of the stairs leading up to the Church of Yorshka from Central Irithyll
IBV: Leo Ring (great hall, chest)In a chest up the stairs in the room with the Silver Knight staring at the painting
IBV: Lightning Gem (plaza center)In the area before and below Pontiff's cathedral, in the center guarded by the enemies
IBV: Magic Clutch Ring (plaza, illusory wall)In the area before and below Pontiff's cathedral, behind an illusory wall to the right
IBV: Mirrah Chain Gloves (bridge after killing Creighton)Following Sirris' questline, found on the bridge to Irithyll after being invaded by Creighton the Wanderer in the graveyard after the Church of Yorshka.
IBV: Mirrah Chain Leggings (bridge after killing Creighton)Following Sirris' questline, found on the bridge to Irithyll after being invaded by Creighton the Wanderer in the graveyard after the Church of Yorshka.
IBV: Mirrah Chain Mail (bridge after killing Creighton)Following Sirris' questline, found on the bridge to Irithyll after being invaded by Creighton the Wanderer in the graveyard after the Church of Yorshka.
IBV: Proof of a Concord Kept (Church of Yorshka altar)At the altar in the Church of Yorshka
IBV: Rime-blue Moss Clump (central, by bonfire)By the Central Irithyll bonfire
IBV: Rime-blue Moss Clump (central, past second fountain)From the Central Irithyll bonfire, to the left before the first Fire Witch.
IBV: Ring of Sacrifice (lake, right of stairs from descent)Near the sewer centipede at the start of the lake leading to the Distant Manor bonfire
IBV: Ring of the Evil Eye (Anri)Given by Anri of Astora in the Church of Yorshka, or if told of Horace's whereabouts in the Catacombs
IBV: Ring of the Sun's First Born (fall from in front of cathedral)Dropping down from in front of Pontiff Sulyvahn's church toward the Church of Yorshka
IBV: Roster of Knights (descent, first landing)On the landing going down the stairs from Church of Yorshka to the graveyard
IBV: Rusted Gold Coin (Distant Manor, down stairs)Dropping down after the first set of stairs leading from Distant Manor bonfire
IBV: Rusted Gold Coin (descent, side path)Down the stairs from the graveyard after Church of Yorshka, guarded by the group of dogs in the left path
IBV: Shriving Stone (descent, dark room rafters)On the rafters in the dark area with the Irithyllian slaves
IBV: Siegbräu (Siegward)Given by Siegward meeting him in the Irithyll kitchen after the Sewer Centipedes.
IBV: Smough's Great Hammer (great hall, chest)In a chest up the stairs in the room with the Silver Knight staring at the painting
IBV: Soul of Pontiff SulyvahnDropped by Pontiff Sulyvahn
IBV: Soul of a Weary Warrior (ascent, by final staircase)Toward the end of the path from the sewer leading up to Pontiff's cathedral, to the left of the final staircase
IBV: Soul of a Weary Warrior (central, by first fountain)By the Central Irithyll bonfire
IBV: Soul of a Weary Warrior (central, railing by first fountain)On the railing overlooking the Central Irithyll bonfire, at the very start
IBV: Soul of a Weary Warrior (plaza, side room #1)Dropping down from the path from Church of Yorshka to Pontiff, guarded by the pensive Fire Witch
IBV: Soul of a Weary Warrior (plaza, side room #2)In the path from Church of Yorshka to Pontiff's cathedral, at the broken ledge you can drop down onto the Fire Witch
IBV: Twinkling Titanite (central, lizard before plaza)Dropped by a Crystal Lizard past the Central Irithyll Fire Witches and to the left
IBV: Twinkling Titanite (descent, lizard behind illusory wall)Dropped by a Crystal Lizard behind an illusory wall before going down the stairs to the lake leading to the Distant Manor bonfire
IBV: Undead Bone Shard (descent, behind gravestone)In the graveyard down the stairs from the Church of Yorshka, behind the grave with the Corvian
IBV: Witchtree Branch (by Dorhys)In the area with Cathedral Evangelist Dorhys, past an illusory railing past the Central Irithyll Fire Witches
IBV: Wood Grain Ring+2 (ascent, right after great hall)Leaving the building with the Silver Knight staring at the painting, instead of going left up the stairs, go right
IBV: Yorshka's Spear (descent, dark room rafers chest)In a chest in the rafters of the dark area with the Irithyllian slaves
ID: Alva Armor (B3 near, by Karla's cell, after killing Alva)In the main Jailer cell block on the floor close to Karla's cell, if the invading Alva is killed
ID: Alva Gauntlets (B3 near, by Karla's cell, after killing Alva)In the main Jailer cell block on the floor close to Karla's cell, if the invading Alva is killed
ID: Alva Helm (B3 near, by Karla's cell, after killing Alva)In the main Jailer cell block on the floor close to Karla's cell, if the invading Alva is killed
ID: Alva Leggings (B3 near, by Karla's cell, after killing Alva)In the main Jailer cell block on the floor close to Karla's cell, if the invading Alva is killed
ID: Bellowing Dragoncrest Ring (drop from B1 towards pit)Dropping down from the Jailbreaker's Key shortcut at the end of the top corridor on the bonfire side in Irithyll Dungeon
ID: Covetous Gold Serpent Ring (Siegward's cell)In the Old Cell where Siegward is rescued
ID: Covetous Silver Serpent Ring+1 (pit lift, middle platform)On one of the platforms in elevator shaft of the shortcut elevator from the Giant Slave area to the Irithyll Dungeon bonfire
ID: Dark Clutch Ring (stairs between pit and B3, mimic)Dropped by the mimic found going past the Giant Slave to the sewer with the rats and the basilisks, up the first flight of stairs, on the left side
ID: Dragon Torso Stone (B3, outside lift)On the balcony corpse in the Path of the Dragon pose
ID: Dragonslayer Lightning Arrow (pit, mimic in hall)Dropped by the mimic in the side corridor from where the Giant Slave is standing, before the long ladder
ID: Dung Pie (B3, by path from pit)In the room with the Giant Hound Rats
ID: Dung Pie (pit, miniboss drop)Drop from the Giant Slave
ID: Dusk Crown Ring (B3 far, right cell)In the cell in the main Jailer cell block to the left of the Profaned Capital exit
ID: Ember (B3 center)At the center pillar in the main Jailer cell block
ID: Ember (B3 near, by exit)In the main Jailer cell block, on the left side coming from the Profaned Capital
ID: Estus Shard (mimic on path from B2 to pit)Dropped by the mimic in the room after the outside area of Irithyll Dungeon overlooking Profaned Capital
ID: Fading Soul (B1 near, main hall)On the top corridor on the bonfire side in Irithyll Dungeon, close to the first Jailer
ID: Great Magic Shield (B2 near, mob drop in far left cell)One-time drop from the Infested Corpse in the bottom corridor on the bonfire side of Irithyll Dungeon, in the closest cell
ID: Homeward Bone (path from B2 to pit)In the part of Irithyll Dungeon overlooking the Profaned Capital, after exiting the last jail cell corridor
ID: Jailbreaker's Key (B1 far, cell after gate)In the cell of the top corridor opposite to the bonfire in Irithyll Dungeon
ID: Large Soul of a Nameless Soldier (B2 far, by lift)Taking the elevator up from the area you can use Path of the Dragon, before the one-way door
ID: Large Soul of a Nameless Soldier (B2, hall by stairs)At the end of the bottom corridor on the bonfire side in Irithyll Dungeon
ID: Large Soul of a Weary Warrior (just before Profaned Capital)In the open area before the bridge leading into Profaned Capital from Irithyll Dungeon
ID: Large Titanite Shard (B1 far, rightmost cell)In a cell on the far end of the top corridor opposite to the bonfire in Irithyll Dungeon, nearby the Jailer
ID: Large Titanite Shard (B1 near, just past bonfire)In the second cell on the right after Irithyll Dungeon bonfire
ID: Large Titanite Shard (B3 near, right corner)On the floor where the Giant Slave is standing
ID: Large Titanite Shard (pit)On the floor where the Giant Slave is standing
ID: Large Titanite Shard (stairs between pit and B3)In the main Jailer cell block, to the left of the hallway leading to the Path of the Dragon area
ID: Lightning Blade (B3 lift, middle platform)On the middle platform riding the elevator up from the Path of the Dragon area
ID: Lightning Bolt (awning over pit)On the wooden overhangs above the Giant Slave. Can be reached by dropping down after climbing the long ladder around the area where the Giant stands.
ID: Murakumo (Alva drop)Dropped by Alva, Seeker of the Spurned when he invades in the cliffside path to Irithyll Dungeon
ID: Old Cell Key (stairs between pit and B3)In a chest found going past the Giant Slave to the sewer with the rats and the basilisks, up the stairs to the end, on the right side
ID: Old Sorcerer Boots (B2 near, middle cell)In one of the cells on the bottom corridor on the bonfire side in Irithyll Dungeon, close to the bonfire, with many Infested Corpses
ID: Old Sorcerer Coat (B2 near, middle cell)In one of the cells on the bottom corridor on the bonfire side in Irithyll Dungeon, close to the bonfire, with many Infested Corpses
ID: Old Sorcerer Gauntlets (B2 near, middle cell)In one of the cells on the bottom corridor on the bonfire side in Irithyll Dungeon, close to the bonfire, with many Infested Corpses
ID: Old Sorcerer Hat (B2 near, middle cell)In one of the cells on the bottom corridor on the bonfire side in Irithyll Dungeon, close to the bonfire, with many Infested Corpses
ID: Pale Pine Resin (B1 far, cell with broken wall)In the jail cell with the broken wall in the top corridor opposite to the bonfire in Irithyll Dungeon, near the passive Wretch on the wall
ID: Pickaxe (path from pit to B3)Passing by the Giant Slave, before the tunnel with the rats and basilisks
ID: Prisoner Chief's Ashes (B2 near, locked cell by stairs)In the cell at the far end of the bottom corridor on the bonfire side in Irithyll Dungeon
ID: Profaned Coal (B3 far, left cell)In the room with the Wretches next to the main Jailer cell block, guarded by a Wretch
ID: Profaned Flame (pit)On the floor where the Giant Slave is standing
ID: Rusted Coin (B1 near, just past bonfire)In the first cell on the left from the Irithyll dungeon bonfire
ID: Rusted Gold Coin (B1 near, end of hall by door)In the third cell on the right from the Irithyll Dungeon bonfire
ID: Simple Gem (B2 far, cell by stairs)In the cell near the bottom corridor opposite to the bonfire in Irithyll Dungeon, adjacent to the room with three Jailers and Cage Spiders
ID: Soul of a Crestfallen Knight (balcony above pit)Under whether the Giant Slave is resting his head
ID: Soul of a Weary Warrior (by drop to pit)At the end of the room with many peasant hollows after the Estus Shard minic
ID: Soul of a Weary Warrior (stairs between pit and B3)Going past the Giant Slave to the sewer with the rats and the basilisks, up the first flight of stairs
ID: Titanite Chunk (balcony above pit, lizard)Dropped by the Crystal Lizard where the Giant Slave is resting his head
ID: Titanite Chunk (pit, miniboss dropDrop from the Giant Slave
ID: Titanite Scale (B2 far, lizard)Dropped by the Crystal Lizard on the bottom corridor opposite from the bonfire in Irithyll Dungeon where a Wretch attacks you
ID: Titanite Scale (B3 far, mimic in hall)Dropped by the mimic in the main Jailer cell block
ID: Titanite Slab (Siegward)Given by Siegward after unlocking Old Cell or on quest completion
ID: Xanthous Ashes (B3 far, right cell)In the cell in the main Jailer cell block to the left of the Profaned Capital exit
KFF: Soul of the LordsDropped by Soul of Cinder
LC: Black Firebomb (dark room lower)In the room with the firebomb-throwing hollows, against the wall on the lowest level
LC: Braille Divine Tome of Lothric (wyvern room)In the room next to the second Pus of Man wyvern
LC: Caitha's Chime (chapel, drop onto roof)Dropping down from the chapel balcony where the Red Tearstone Ring is found, and then dropping down again towards the Lothric knights
LC: Dark Stoneplate Ring+1 (wyvern room, balcony)Through the room next to the second Pus of Man wyvern, on the balcony outside
LC: Ember (by Dragon Barracks bonfire)Near the Dragon Barracks bonfire
LC: Ember (dark room mid, pus of man mob drop)Dropped by the first Pus of Man wyvern
LC: Ember (main hall, left of stairs)To the left of the stairs past the Dragon Barracks grate
LC: Ember (plaza center)In the area where the Pus of Man wyverns breathe fire
LC: Ember (plaza, by gate)On the railing near the area where the Pus of Man wyverns breathe fire, before the gate
LC: Ember (wyvern room, wyvern foot mob drop)Dropped by the second Pus of Man wyvern
LC: Gotthard Twinswords (by Grand Archives door, after PC and AL bosses)Before the door to the Grand Archives after Aldrich and Yhorm are killed
LC: Grand Archives Key (by Grand Archives door, after PC and AL bosses)Before the door to the Grand Archives after Aldrich and Yhorm are killed
LC: Greatlance (overlooking Dragon Barracks bonfire)Guarded by a pensive Lothric Knight after the Dragon Barracks bonfire and continuing up the stairs
LC: Hood of PrayerIn a chest right after the Lothric Castle bonfire
LC: Irithyll Rapier (basement, miniboss drop)Dropped by the Boreal Outrider Knight in the basement
LC: Knight's Ring (altar)Climbing the ladder to the rooftop outside the Dragonslayer Armour fight, past the Large Hollow Soldier, down into the room with the tables
LC: Large Soul of a Nameless Soldier (dark room mid)In the room with the firebomb-throwing hollows, up the ladder
LC: Large Soul of a Nameless Soldier (moat, right path)Found on the ledge after dropping into the area with the Pus of Man transforming hollows and making the entire loop
LC: Large Soul of a Nameless Soldier (plaza left, by pillar)In the building to the left of the area where the Pus of Man wyverns breathe fire, against a pillar
LC: Large Soul of a Weary Warrior (ascent, last turret)Rather than going up the stairs to the Dragon Barracks bonfire, continue straight down the stairs and forwards
LC: Large Soul of a Weary Warrior (main hall, by lever)On a ledge to the right of the lever opening the grate
LC: Life Ring+2 (dark room mid, out door opposite wyvern, drop down)Past the room with the firebomb-throwing hollows and Pus of Man wyvern, around to the front, dropping down past where the Titanite Chunk is
LC: Lightning Urn (moat, right path, first room)Starting the loop from where the Pus of Man hollows transform, behind some crates in the first room
LC: Lightning Urn (plaza)In the area where the Pus of Man wyverns breathe fire
LC: Pale Pine Resin (dark room upper, by mimic)In the room with the firebomb-throwing hollows, next to the mimic in the far back left
LC: Raw Gem (plaza left)On a balcony to the left of the area where the Pus of Man wyverns breathe fire, where the Hollow Soldier throws Undead Hunter Charms
LC: Red Tearstone Ring (chapel, drop onto roof)From the chapel to the right of the Dragonslayer Armour fight, on the balcony to the left
LC: Refined Gem (plaza)In the area where the Pus of Man wyverns breathe fire
LC: Robe of Prayer (ascent, chest at beginning)In a chest right after the Lothric Castle bonfire
LC: Rusted Coin (chapel)In the chapel to the right of the Dragonslayer Armour fight
LC: Sacred Bloom Shield (ascent, behind illusory wall)Up the ladder where the Winged Knight is waiting, past an illusory wall
LC: Skirt of Prayer (ascent, chest at beginning)In a chest right after the Lothric Castle bonfire
LC: Sniper Bolt (moat, right path end)Hanging from the arch passed under on the way to the Dragon Barracks bonfire. Can be accessed by dropping into the area with the Pus of Man transforming hollows and making the entire loop, but going left at the end
LC: Sniper Crossbow (moat, right path end)Hanging from the arch passed under on the way to the Dragon Barracks bonfire. Can be accessed by dropping into the area with the Pus of Man transforming hollows and making the entire loop, but going left at the end
LC: Soul of Dragonslayer ArmourDropped by Dragonslayer Armour
LC: Soul of a Crestfallen Knight (by lift bottom)Guarded by a buffed Lothric Knight straight from the Dancer bonfire
LC: Soul of a Crestfallen Knight (wyvern room, balcony)On a ledge accessible after the second Pus of Man wyvern is defeated
LC: Spirit Tree Crest Shield (basement, chest)In a chest in the basement with the Outrider Knight
LC: Sunlight Medal (by lift top)Next to the shortcut elevator outside of the Dragonslayer Armour fight that goes down to the start of the area
LC: Sunlight Straight Sword (wyvern room, mimic)Dropped by the mimic in the room next to the second Pus of Man wyvern
LC: Thunder Stoneplate Ring+2 (chapel, drop onto roof)Dropping down from the chapel balcony where the Red Tearstone Ring is found, out on the edge
LC: Titanite Chunk (altar roof)Climbing the ladder to the rooftop outside the Dragonslayer Armour fight, overlooking the tree
LC: Titanite Chunk (ascent, final turret)Rather than going up the stairs to the Dragon Barracks bonfire, continue straight down the stairs, then right
LC: Titanite Chunk (ascent, first balcony)Right after the Lothric Castle bonfire, out on the balcony
LC: Titanite Chunk (ascent, turret before barricades)From the Lothric Castle bonfire, up the stairs, straight, and then down the stairs behind the barricade
LC: Titanite Chunk (dark room mid, out door opposite wyvern)From the room with the firebomb-throwing hollows, past the Pus of Man Wyvern and back around the front, before the Crystal Lizard
LC: Titanite Chunk (dark room mid, pus of man mob drop)Dropped by the first Pus of Man wyvern
LC: Titanite Chunk (down stairs after boss)Down the stairs to the right after Dragonslayer Armour
LC: Titanite Chunk (moat #1)In the center of the area where the Pus of Man hollows transform
LC: Titanite Chunk (moat #2)In the center of the area where the Pus of Man hollows transform
LC: Titanite Chunk (moat, near ledge)Dropping down from the bridge where the Pus of Man wyverns breathe fire on the near side to the bonfire
LC: Titanite Chunk (wyvern room, wyvern foot mob drop)Dropped by the second Pus of Man wyvern
LC: Titanite Scale (altar)In a chest climbing the ladder to the rooftop outside the Dragonslayer Armour fight, continuing the loop past the Red-Eyed Lothric Knight
LC: Titanite Scale (basement, chest)In a chest in the basement with the Outrider Knight
LC: Titanite Scale (chapel, chest)In a chest in the chapel to the right of the Dragonslayer Armour fight
LC: Titanite Scale (dark room mid, out door opposite wyvern)Passing through the room with the firebomb-throwing hollows and the Pus of Man wyvern around to the front, overlooking the area where the wyverns breathe fire
LC: Titanite Scale (dark room, upper balcony)In the room with the firebomb-throwing hollows, at the very top on a balcony to the right
LC: Titanite Scale (dark room, upper, mimic)Dropped by the crawling mimic at the top of the room with the firebomb-throwing hollows
LC: Twinkling Titanite (ascent, side room)In the room where the Winged Knight drops down
LC: Twinkling Titanite (basement, chest #1)In a chest in the basement with the Outrider Knight
LC: Twinkling Titanite (basement, chest #2)In a chest in the basement with the Outrider Knight
LC: Twinkling Titanite (dark room mid, out door opposite wyvern, lizard)Dropped by the Crystal Lizard after the room with the firebomb-throwing hollows around the front
LC: Twinkling Titanite (moat, left side)Behind one of the Pus of Man transforming hollows, to the left of the bridge to the wyvern fire-breathing area
LC: Twinkling Titanite (moat, right path, lizard)Dropped by the Crystal Lizard near the thieves after dropping down to the area with the Pus of Man transforming hollows
LC: Undead Bone Shard (moat, far ledge)Dropping down from the bridge where the Pus of Man wyverns breathe fire on the far side from the bonfire
LC: Winged Knight Armor (ascent, behind illusory wall)In the area where the Winged Knight drops down, up the ladder and past the illusory wall
LC: Winged Knight Gauntlets (ascent, behind illusory wall)In the area where the Winged Knight drops down, up the ladder and past the illusory wall
LC: Winged Knight Helm (ascent, behind illusory wall)In the area where the Winged Knight drops down, up the ladder and past the illusory wall
LC: Winged Knight Leggings (ascent, behind illusory wall)In the area where the Winged Knight drops down, up the ladder and past the illusory wall
PC: Blooming Purple Moss Clump (walkway above swamp)At the right end of the plank before dropping down into the Profaned Capital toxic pool
PC: Cinders of a Lord - Yhorm the GiantDropped by Yhorm the Giant
PC: Court Sorcerer Gloves (chapel, second floor)On the second floor of the Monstrosity of Sin building in front of the Monstrosity of Sin
PC: Court Sorcerer Hood (chapel, second floor)On the second floor of the Monstrosity of Sin building in front of the Monstrosity of Sin
PC: Court Sorcerer Robe (chapel, second floor)On the second floor of the Monstrosity of Sin building in front of the Monstrosity of Sin
PC: Court Sorcerer Trousers (chapel, second floor)On the second floor of the Monstrosity of Sin building in front of the Monstrosity of Sin
PC: Court Sorcerer's Staff (chapel, mimic on second floor)Dropped by the mimic on the second floor of the Monstrosity of Sin building
PC: Cursebite Ring (swamp, below halls)In the inner cave of the Profaned Capital toxic pool
PC: Eleonora (chapel ground floor, kill mob)Dropped by the Monstrosity of Sin on the first floor, furthest away from the door
PC: Ember (palace, far room)To the right of the Profaned Flame, in the room with the many Jailers looking at the mimics
PC: Flame Stoneplate Ring+1 (chapel, drop from roof towards entrance)Dropping down from the roof connected to the second floor of the Monstrosity of Sin building, above the main entrance to the building
PC: Greatshield of Glory (palace, mimic in far room)Dropped by the left mimic surrounded by the Jailers to the right of the Profaned Flame
PC: Jailer's Key Ring (hall past chapel)Past the Profaned Capital Court Sorcerer, in the corridor overlooking the Irithyll Dungeon Giant Slave area
PC: Large Soul of a Weary Warrior (bridge, far end)On the way from the Profaned Capital bonfire toward the Profaned Flame, crossing the bridge without dropping down
PC: Logan's Scroll (chapel roof, NPC drop)Dropped by the court sorcerer above the toxic pool
PC: Magic Stoneplate Ring+2 (tower base)At the base of the Profaned Capital structure, going all the way around the outside wall clockwise
PC: Onislayer Greatarrow (bridge)Item on the bridge descending from the Profaned Capital bonfire into the Profaned Flame building
PC: Onislayer Greatbow (drop from bridge)From the bridge leading from the Profaned Capital bonfire to Yhorm, onto the ruined pillars shortcut to the right, behind you after the first dropdown.
PC: Pierce Shield (Siegward)Dropped by Siegward upon death or quest completion, and sold by Patches while Siegward is in the well.
PC: Poison Arrow (chapel roof)At the far end of the roof with the Court Sorcerer
PC: Poison Gem (swamp, below halls)In the inner cave of the Profaned Capital toxic pool
PC: Purging Stone (chapel ground floor)At the back of the room with the three Monstrosities of Sin on the first floor
PC: Purging Stone (swamp, by chapel ladder)In the middle of the Profaned Capital toxic pool, near the ladder to the Court Sorcerer
PC: Rubbish (chapel, down stairs from second floor)Hanging corpse visible from Profaned Capital accessible from the second floor of the building with the Monstrosities of Sin, in the back right
PC: Rusted Coin (below bridge #1)Among the rubble before the steps leading up to the Profaned Flame
PC: Rusted Coin (below bridge #2)Among the rubble before the steps leading up to the Profaned Flame
PC: Rusted Coin (tower exterior)Treasure visible on a ledge in the Profaned Capital bonfire. Can be accessed by climbing a ladder outside the main structure.
PC: Rusted Gold Coin (halls above swamp)In the corridors leading to the Profaned Capital toxic pool
PC: Rusted Gold Coin (palace, mimic in far room)Dropped by the right mimic surrounded by the Jailers to the right of the Profaned Flame
PC: Shriving Stone (swamp, by chapel door)At the far end of the Profaned Capital toxic pool, to the left of the door leading to the Monstrosities of Sin
PC: Siegbräu (Siegward after killing boss)Given by Siegward after helping him defeat Yhorm the Giant. You must talk to him before Emma teleports you.
PC: Soul of Yhorm the GiantDropped by Yhorm the Giant
PC: Storm Ruler (Siegward)Dropped by Siegward upon death or quest completion.
PC: Storm Ruler (boss room)To the right of Yhorm's throne
PC: Twinkling Titanite (halls above swamp, lizard #1)Dropped by the second Crystal Lizard in the corridors before the Profaned Capital toxic pool
PC: Undead Bone Shard (by bonfire)On the corpse of Laddersmith Gilligan next to the Profaned Capital bonfire
PC: Wrath of the Gods (chapel, drop from roof)Dropping down from the roof of the Monstrosity of Sin building where the Court Sorcerer is
PW1: Black Firebomb (snowfield lower, path to bridge)Dropping down after the first snow overhang and following the wall on the left, past the rotting bed descending toward the second bonfire
PW1: Blessed Gem (snowfield, behind tower)Behind the Millwood Knight tower in the first area, approach from the right side
PW1: Budding Green Blossom (settlement courtyard, ledge)After sliding down the slope on the way to Corvian Settlement, dropping down hugging the left wall
PW1: Captain's Ashes (snowfield tower, 6F)At the very top of the Millwood Knight tower after climbing up the second ladder
PW1: Champion's Bones (boss drop)Dropped by Champion's Gravetender
PW1: Chillbite Ring (Friede)Given by Sister Friede while she is sitting in the Ariandel Chapel, or on the stool after she moves.
PW1: Contraption Key (library, NPC drop)Dropped by Sir Vilhelm
PW1: Crow Quills (settlement loop, jump into courtyard)Crossing the bridge after Corvian Settlement bonfire, follow the left edge past another bridge until a dropdown point looping back to the bonfire. Go right and jump past some barrels onto the central platform.
PW1: Crow Talons (settlement roofs, near bonfire)After climbing the ladder onto Corvian Settlement rooftops, dropping down on a bridge to the left, into the building, then looping around onto its roof.
PW1: Dark Gem (settlement back, egg building)Dropping down to the right of the gate guarded by a Corvian Knight in Corvian Settlement, inside of the last building on the right
PW1: Ember (roots above depths)In the tree branch area after climbing down the rope bridge, hugging a right wall past a Follower Javelin wielder
PW1: Ember (settlement main, left building after bridge)Crossing the bridge after Corvian Settlement bonfire, in the building to the left.
PW1: Ember (settlement, building near bonfire)In the first building in Corvian Settlement next to the bonfire building
PW1: Ethereal Oak Shield (snowfield tower, 3F)In the Millwood Knight tower on a Millwood Knight corpse, after climbing the first ladder, then going down the staircase
PW1: Follower Javelin (snowfield lower, path back up)Dropping down after the first snow overhang, follow the right wall around and up a slope, past the Followers
PW1: Follower Sabre (roots above depths)On a tree branch after climbing down the rope bridge. Rather than hugging a right wall toward a Follower Javelin wielder, drop off to the left.
PW1: Frozen Weapon (snowfield lower, path to bonfire)Dropping down after the first snow overhang, in the rotting bed along the left side
PW1: Heavy Gem (snowfield village)Before the Millwood Knight tower, on the far side of one of the ruined walls targeted by the archer
PW1: Hollow Gem (beside chapel)To the right of the entrance to the Ariandel
PW1: Homeward Bone (depths, up hill)In the Depths of the Painting, up a hill next to the giant crabs.
PW1: Homeward Bone (snowfield village, outcropping)Dropping down after the first snow overhang and following the cliff on the right, making a sharp right after a ruined wall segment before approaching the Millwood Knight tower
PW1: Large Soul of a Weary Warrior (settlement hall roof)On top of the chapel with the Corvian Knight to the left of Vilhelm's building
PW1: Large Soul of a Weary Warrior (snowfield tower, 6F)At the very top of the Millwood Knight tower after climbing up the second ladder, on a Millwood Knight corpse
PW1: Large Soul of an Unknown Traveler (below snowfield village overhang)Up the slope to the left of the Millwood Knight tower, dropping down after a snow overhang, then several more ledges.
PW1: Large Soul of an Unknown Traveler (settlement back)In Corvian Settlement, on the ground before the ladder climbing onto the rooftops
PW1: Large Soul of an Unknown Traveler (settlement courtyard, cliff)After sliding down the slope on the way to Corvian Settlement, on a cliff to the right and behind
PW1: Large Soul of an Unknown Traveler (settlement loop, by bonfire)Crossing the bridge after Corvian Settlement bonfire, follow the left edge past another bridge until a dropdown point looping back to the bonfire. On the corpse in a hole in the wall leading back to the bonfire.
PW1: Large Soul of an Unknown Traveler (settlement roofs, balcony)After climbing the ladder onto Corvian Settlement rooftops, dropping down on a bridge to the left, on the other side of the bridge.
PW1: Large Soul of an Unknown Traveler (settlement, by ladder to bonfire)To the right of the ladder leading up to Corvian Settlement bonfire.
PW1: Large Soul of an Unknown Traveler (snowfield lower, by cliff)Dropping down after the first snow overhang, between the forest and the cliff edge, before where the large wolf drops down
PW1: Large Soul of an Unknown Traveler (snowfield lower, path back up)Dropping down after the first snow overhang, follow the right wall around and up a slope, past the Followers
PW1: Large Soul of an Unknown Traveler (snowfield lower, path to village)Dropping down after the first snow overhang and following the cliff on the right, on a tree past where the large wolf jumps down
PW1: Large Soul of an Unknown Traveler (snowfield upper)Going straight after the first bonfire, to the left of the caving snow overhand
PW1: Large Titanite Shard (lizard under bridge near)Dropped by a Crystal Lizard after the Rope Bridge Cave on the way to Corvian Settlement
PW1: Large Titanite Shard (settlement loop, lizard)Crossing the bridge after Corvian Settlement bonfire, follow the left edge past another bridge until a dropdown point looping back to the bonfire. Hug the bonfire building's outer wall along the right side.
PW1: Large Titanite Shard (snowfield lower, left from fall)Dropping down after the first snow overhang, guarded by a Tree Woman overlooking the rotting bed along the left wall
PW1: Millwood Battle Axe (snowfield tower, 5F)In the Milkwood Knight tower, either dropping down from rafters after climbing the second ladder or making a risky jump
PW1: Millwood Greatarrow (snowfield village, loop back to lower)Dropping down after the first snow overhang and following the cliff on the right, making the full loop around, up the slope leading towards where the large wolf drops down
PW1: Millwood Greatbow (snowfield village, loop back to lower)Dropping down after the first snow overhang and following the cliff on the right, making the full loop around, up the slope leading towards where the large wolf drops down
PW1: Onyx Blade (library, NPC drop)Dropped by Sir Vilhelm
PW1: Poison Gem (snowfield upper, forward from bonfire)Following the left wall from the start, guarded by a Giant Fly
PW1: Rime-blue Moss Clump (below bridge far)In a small alcove to the right after climbing down the rope bridge
PW1: Rime-blue Moss Clump (snowfield upper, overhang)On the first snow overhang at the start. It drops down at the same time you do.
PW1: Rime-blue Moss Clump (snowfield upper, starting cave)In the starting cave
PW1: Rusted Coin (right of library)To the right of Vilhelm's building
PW1: Rusted Coin (snowfield lower, straight from fall)Dropping down after the first snow overhang, shortly straight ahead
PW1: Rusted Gold Coin (settlement roofs, roof near second ladder)After climbing the second ladder on the Corvian Settlement rooftops, immediately dropping off the bridge to the right, on a rooftop
PW1: Shriving Stone (below bridge near)After the Rope Bridge Cave bonfire, dropping down before the bridge, following the ledge all the way to the right
PW1: Simple Gem (settlement, lowest level, behind gate)Crossing the bridge after Corvian Settlement bonfire, follow the left edge until a bridge, then drop down on the right side. Guarded by a Sewer Centipede.
PW1: Slave Knight Armor (settlement roofs, drop by ladder)In Corvian Settlement, rather than climbing up a ladder leading to a bridge to the roof of the chapel with the Corvian Knight, dropping down a hole to the left of the ladder into the building below.
PW1: Slave Knight Gauntlets (settlement roofs, drop by ladder)In Corvian Settlement, rather than climbing up a ladder leading to a bridge to the roof of the chapel with the Corvian Knight, dropping down a hole to the left of the ladder into the building below.
PW1: Slave Knight Hood (settlement roofs, drop by ladder)In Corvian Settlement, rather than climbing up a ladder leading to a bridge to the roof of the chapel with the Corvian Knight, dropping down a hole to the left of the ladder into the building below.
PW1: Slave Knight Leggings (settlement roofs, drop by ladder)In Corvian Settlement, rather than climbing up a ladder leading to a bridge to the roof of the chapel with the Corvian Knight, dropping down a hole to the left of the ladder into the building below.
PW1: Snap Freeze (depths, far end, mob drop)In the Depths of the Painting, past the giant crabs, guarded by a special Tree Woman. Killing her drops down a very long nearby ladder.
PW1: Soul of a Crestfallen Knight (settlement hall, rafters)In the rafters of the chapel with the Corvian Knight to the left of Vilhelm's building. Can drop down from the windows exposed to the roof.
PW1: Soul of a Weary Warrior (snowfield tower, 1F)At the bottom of the Millwood Knight tower on a Millwood Knight corpse
PW1: Titanite Slab (Corvian)Given by the Corvian NPC in the building next to Corvian Settlement bonfire.
PW1: Titanite Slab (depths, up secret ladder)One-time drop after killing Father Ariandel and Friede (phase 2) for the first time.
PW1: Twinkling Titanite (roots, lizard)Dropped by a Crystal Lizard in the tree branch area after climbing down the rope bridge, before the ledge with the Follower Javelin wielder
PW1: Twinkling Titanite (settlement roofs, lizard before hall)Dropped by a Crystal Lizard on a bridge in Corvian Settlement before the rooftop of the chapel with the Corvian Knight inside.
PW1: Twinkling Titanite (snowfield tower, 3F lizard)Dropped by a Crystal Lizard in the Millwood Knight tower, climbing up the first ladder and descending the stairs down
PW1: Valorheart (boss drop)Dropped by Champion's Gravetender
PW1: Way of White Corona (settlement hall, by altar)In the chapel with the Corvian Knight to the left of Vilhelm's building, in front of the altar.
PW1: Young White Branch (right of library)To the right of Vilhelm's building
PW2: Blood Gem (B2, center)On the lower level of the Ariandel Chapel basement, in the middle
PW2: Dung Pie (B1)On the higher level of the Ariandel Chapel basement, on a wooden beam overlooking the lower level
PW2: Earth Seeker (pit cave)In the area after Snowy Mountain Pass with the giant tree and Earth Seeker Millwood Knight, in the cave
PW2: Ember (pass, central alcove)After the Snowy Mountain Pass bonfire, going left of the bell stuck in the ground, in a small alcove along the left wall
PW2: Floating Chaos (Dunnel drop)Dropped by Livid Pyromancer Dunnel when he invades while embered, whether boss is defeated or not. On the second level of Priscilla's building above the Gravetender fight, accessed from the lowest level of the Ariandel Chapel basement, past an illusory wall nearly straight left of the mechanism that moves the statue, then carefully dropping down tree branches.
PW2: Follower Shield (pass, far cliffside)After the Snowy Mountain Pass bonfire, going left of the bell stuck in the ground, on the cliff ledge past the open area, to the left
PW2: Follower Torch (pass, far side path)On the way to the Ariandel Chapel basement, where the first wolf enemies reappear, going all the way down the slope on the edge of the map. Guarded by a Follower
PW2: Homeward Bone (rotunda)On the second level of Priscilla's building above the Gravetender fight. Can be accessed from the lowest level of the Ariandel Chapel basement, past an illusory wall nearly straight left of the mechanism that moves the statue, then carefully dropping down tree branches.
PW2: Large Soul of a Crestfallen Knight (pit, by tree)In the area after Snowy Mountain Pass with the giant tree and Earth Seeker Millwood Knight, by the tree
PW2: Large Titanite Shard (pass, far side path)On the way to the Ariandel Chapel basement, where the first wolf enemies reappear, going partway down the slope on the edge of the map
PW2: Large Titanite Shard (pass, just before B1)On the way to Ariandel Chapel basement, past the Millwood Knights and before the first rotten tree that can be knocked down
PW2: Prism Stone (pass, tree by beginning)Up the slope and to the left after the Snowy Mountain Pass, straight ahead by a tree
PW2: Pyromancer's Parting Flame (rotunda)On the second level of Priscilla's building above the Gravetender fight. Can be accessed from the lowest level of the Ariandel Chapel basement, past an illusory wall nearly straight left of the mechanism that moves the statue, then carefully dropping down tree branches.
PW2: Quakestone Hammer (pass, side path near B1)On the way to Ariandel Chapel basement, rather than going right past the two Millwood Knights, go left, guarded by a very strong Millwood Knight
PW2: Soul of Sister FriedeDropped by Sister Friede
PW2: Soul of a Crestfallen Knight (pit edge #1)In the area after Snowy Mountain Pass with the giant tree and Earth Seeker Millwood Knight, along the edge
PW2: Soul of a Crestfallen Knight (pit edge #2)In the area after Snowy Mountain Pass with the giant tree and Earth Seeker Millwood Knight, along the edge
PW2: Titanite Chunk (pass, by kickable tree)After the Snowy Mountain Pass bonfire, on a ledge to the right of the slope with the bell stuck in the ground, behind a tree
PW2: Titanite Chunk (pass, cliff overlooking bonfire)On a cliff overlooking the Snowy Mountain Pass bonfire. Requires following the left wall
PW2: Titanite Slab (boss drop)One-time drop after killing Father Ariandel and Friede (phase 2) for the first time.
PW2: Twinkling Titanite (B3, lizard #1)Dropped by a Crystal Lizard past an illusory wall nearly straight left of the mechanism that moves the statue in the lowest level of the Ariandel Chapel basement
PW2: Twinkling Titanite (B3, lizard #2)Dropped by a Crystal Lizard past an illusory wall nearly straight left of the mechanism that moves the statue in the lowest level of the Ariandel Chapel basement
PW2: Vilhelm's Armor (B2, along wall)On the lower level of the Ariandel Chapel basement, along a wall to the left of the contraption that turns the statue
PW2: Vilhelm's Gauntlets (B2, along wall)On the lower level of the Ariandel Chapel basement, along a wall to the left of the contraption that turns the statue
PW2: Vilhelm's HelmOn the lower level of the Ariandel Chapel basement, along a wall to the left of the contraption that turns the statue
PW2: Vilhelm's Leggings (B2, along wall)On the lower level of the Ariandel Chapel basement, along a wall to the left of the contraption that turns the statue
RC: Antiquated Plain Garb (wall hidden, before boss)In the chapel before the Midir fight in the Ringed Inner Wall building.
RC: Black Witch Garb (streets garden)Guarded by Alva (invades whether embered or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight.
RC: Black Witch Hat (streets garden)Guarded by Alva (invades whether embered or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight.
RC: Black Witch Trousers (streets garden)Guarded by Alva (invades whether embered or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight.
RC: Black Witch Veil (swamp near right, by sinking church)To the left of the submerged building with 4 Ringed Knights, near a spear-wielding knight.
RC: Black Witch Wrappings (streets garden)Guarded by Alva (invades whether embered or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight.
RC: Blessed Gem (grave, down lowest stairs)In Shared Grave, after dropping down near Gael's flag and dropping down again, behind you. Or from the bonfire, go back through the side tunnel with the skeletons and down the stairs after that.
RC: Blindfold Mask (grave, NPC drop)Dropped by Moaning Knight (invades whether embered or not, or boss defeated or not) in Shared Grave.
RC: Blood of the Dark Soul (end boss drop)Dropped by Slave Knight Gael
RC: Budding Green Blossom (church path)On the way to the Halflight building.
RC: Budding Green Blossom (wall top, flowers by stairs)In a patch of flowers to the right of the stairs leading up to the first Judicator along the left wall of the courtyard are Mausoleum Lookout.
RC: Budding Green Blossom (wall top, in flower cluster)Along the left wall of the courtyard after Mausoleum Lookout, in a patch of flowers.
RC: Chloranthy Ring+3 (wall hidden, drop onto statue)From the mid level of the Ringed Inner Wall elevator that leads to the Midir fight, dropping back down toward the way to Filianore, onto a platform with a Gwyn statue. Try to land on the platform rather than the statue.
RC: Church Guardian Shiv (swamp far left, in building)Inside of the building at the remote end of the muck pit surrounded by praying Hollow Clerics.
RC: Covetous Gold Serpent Ring+3 (streets, by Lapp)Going up the very long ladder from the muck pit, then up some stairs, to the left, and across the bridge, in a building past the Ringed Knights. Also where Lapp can be found to tell him of the Purging Monument.
RC: Crucifix of the Mad King (ashes, NPC drop)Dropped by Shira, who invades you (ember not required) in the far-future version of her room
RC: Dark Gem (swamp near, by stairs)In the middle of the muck pit, close to the long stairs.
RC: Divine Blessing (streets monument, mob drop)Dropped by the Judicator near the Purging Monument area. Requires solving "Show Your Humanity" puzzle.
RC: Divine Blessing (wall top, mob drop)Dropped by the Judicator after the Mausoleum Lookup bonfire.
RC: Dragonhead Greatshield (upper cluff, under bridge)Down a slope to the right of the bridge where Midir first assaults you, past a sword-wielding Ringed Knight, under the bridge.
RC: Dragonhead Shield (streets monument, across bridge)Found in Purging Monument area, across the bridge from the monument. Requires solving "Show Your Humanity" puzzle.
RC: Ember (wall hidden, statue room)From the mid level of the Ringed Inner Wall elevator that leads to the Midir fight, in the room with the illusory statue.
RC: Ember (wall top, by statue)Along the left wall of the courtyard after Mausoleum Lookout, in front of a tall monument.
RC: Ember (wall upper, balcony)On the balcony attached to the room with the Ringed Inner Wall bonfire.
RC: Filianore's Spear Ornament (mid boss drop)Dropped by Halflight, Spear of the Church
RC: Filianore's Spear Ornament (wall hidden, by ladder)Next the ladder leading down to the chapel before the Midir fight in the Ringed Inner Wall building.
RC: Havel's Ring+3 (streets high, drop from building opposite)Dropping down from the building where Silver Knight Ledo invades. The building is up the very long ladder from the muck pit, down the path all the way to the right.
RC: Hidden Blessing (swamp center, mob drop)Dropped by Judicator patrolling the muck pit.
RC: Hidden Blessing (wall top, tomb under platform)In a tomb underneath the platform with the first Judicator, accessed by approaching from Mausoleum Lookout bonfire.
RC: Hollow Gem (wall upper, path to tower)Heading down the cursed stairs after Ringed Inner Wall bonfire and another short flight of stairs, hanging on a balcony.
RC: Iron Dragonslayer Armor (swamp far, miniboss drop)Dropped by Dragonslayer Armour at the far end of the muck pit.
RC: Iron Dragonslayer Gauntlets (swamp far, miniboss drop)Dropped by Dragonslayer Armour at the far end of the muck pit.
RC: Iron Dragonslayer Helm (swamp far, miniboss drop)Dropped by Dragonslayer Armour at the far end of the muck pit.
RC: Iron Dragonslayer Leggings (swamp far, miniboss drop)Dropped by Dragonslayer Armour at the far end of the muck pit.
RC: Lapp's Armor (Lapp)Left at Lapp's final location in Shared Grave after his quest is complete, or sold by Shrine Handmaid upon killing Lapp.
RC: Lapp's Gauntlets (Lapp)Left at Lapp's final location in Shared Grave after his quest is complete, or sold by Shrine Handmaid upon killing Lapp.
RC: Lapp's Helm (Lapp)Left at Lapp's final location in Shared Grave after his quest is complete, or sold by Shrine Handmaid upon killing Lapp.
RC: Lapp's Leggings (Lapp)Left at Lapp's final location in Shared Grave after his quest is complete, or sold by Shrine Handmaid upon killing Lapp.
RC: Large Soul of a Crestfallen Knight (streets monument, across bridge)Found in Purging Monument area, on the other side of the bridge leading to the monument. Requires solving "Show Your Humanity" puzzle.
RC: Large Soul of a Crestfallen Knight (streets, far stairs)Toward the bottom of the stairs leading down to the muck pit.
RC: Large Soul of a Weary Warrior (swamp center)In the muck pit approaching where the Judicator patrols from the stairs.
RC: Large Soul of a Weary Warrior (upper cliff, end)Toward the end of the upper path attacked Midir's fire-breathing.
RC: Large Soul of a Weary Warrior (wall lower, past two illusory walls)In the Ringed Inner Wall building coming from Shared Grave, past two illusory walls on the right side of the ascending stairs.
RC: Large Soul of a Weary Warrior (wall top, right of small tomb)In the open toward the end of the courtyard after the Mausoleum Lookout bonfire, on the right side of the small tomb.
RC: Ledo's Great Hammer (streets high, opposite building, NPC drop)Dropped by Silver Knight Ledo (invades whether embered or not, or boss defeated or not) in the building down the path to the right after climbing the very long ladder from the muck area.
RC: Lightning Arrow (wall lower, past three illusory walls)In the Ringed Inner Wall building coming from Shared Grave, past three illusory walls on the right side of the ascending stairs.
RC: Lightning Gem (grave, room after first drop)In Shared Grave, in the first room encountered after falling down from the crumbling stairs and continuing upward.
RC: Mossfruit (streets near left, path to garden)Partway down the stairs from Shira, across the bridge.
RC: Mossfruit (streets, far left alcove)Near the bottom of the stairs before the muck pit, in an alcove to the left.
RC: Preacher's Right Arm (swamp near right, by crystal)In the muck pit behind a crystal-covered structure, close to the Ringed City Streets shortcut entrance.
RC: Prism Stone (swamp near, path to bonfire)On the balcony of the path leading up to Ringed City Streets bonfire from the muck pit.
RC: Purging Stone (wall top, by door to upper)At the end of the path from Mausoleum Lookup to Ringed Inner Wall, just outside the door.
RC: Ring of the Evil Eye+3 (grave, mimic)Dropped by mimic in Shared Grave. In one of the rooms after dropping down near Gael's flag and then dropping down again.
RC: Ringed Knight Paired Greatswords (church path, mob drop)Dropped by Ringed Knight with paired greatswords before Filianore building.
RC: Ringed Knight Spear (streets, down far right hall)In a courtyard guarded by a spear-wielding Ringed Knight. Can be accessed from a hallway filled with cursed clerics on the right side going down the long stairs, or by climbing up the long ladder from the muck pit and dropping down past the Locust Preacher.
RC: Ringed Knight Straight Sword (swamp near, pillar by bonfire)On a monument next to the Ringed City Streets building. Can be easily accessed after unlocking the shortcut by following the left wall inside and then outside the building.
RC: Ritual Spear Fragment (church path)To the right of the Paired Greatswords Ringed Knight on the way to Halflight.
RC: Rubbish (swamp far, by crystal)In the remote end of the muck pit, next to a massive crystal structure between a giant tree and the building with praying Hollow Clerics, guarded by several Locust Preachers.
RC: Rubbish (upper cliff, middle)In the middle of the upper path attacked Midir's fire-breathing, after the first alcove.
RC: Ruin Armor (wall top, under stairs to bonfire)Underneath the stairs leading down from Mausoleum Lookout.
RC: Ruin Gauntlets (wall top, under stairs to bonfire)Underneath the stairs leading down from Mausoleum Lookout.
RC: Ruin Helm (wall top, under stairs to bonfire)Underneath the stairs leading down from Mausoleum Lookout.
RC: Ruin Leggings (wall top, under stairs to bonfire)Underneath the stairs leading down from Mausoleum Lookout.
RC: Sacred Chime of Filianore (ashes, NPC drop)Given by Shira after accepting her request to kill Midir, or dropped by her in post-Filianore Ringed City.
RC: Shira's Armor (Shira's room after killing ashes NPC)Found in Shira's room in Ringed City after killing her in post-Filianore Ringed City.
RC: Shira's Crown (Shira's room after killing ashes NPC)Found in Shira's room in Ringed City after killing her in post-Filianore Ringed City.
RC: Shira's Gloves (Shira's room after killing ashes NPC)Found in Shira's room in Ringed City after killing her in post-Filianore Ringed City.
RC: Shira's Trousers (Shira's room after killing ashes NPC)Found in Shira's room in Ringed City after killing her in post-Filianore Ringed City.
RC: Shriving Stone (wall tower, bottom floor center)In the cylindrical building before the long stairs with many Harald Legion Knights, in the center structure on the first floor.
RC: Siegbräu (Lapp)Given by Lapp within the Ringed Inner Wall.
RC: Simple Gem (grave, up stairs after first drop)In Shared Grave, following the path after falling down from the crumbling stairs and continuing upward.
RC: Soul of Darkeater MidirDropped by Darkeater Midir
RC: Soul of Slave Knight GaelDropped by Slave Knight Gael
RC: Soul of a Crestfallen Knight (swamp far, behind crystal)Behind a crystal structure at the far end of the muck pit, close to the building with the praying Hollow Clerics before Dragonslayer Armour.
RC: Soul of a Crestfallen Knight (swamp near left, by ladder)In the muck pit behind all of the Hollow Clerics near the very long ladder.
RC: Soul of a Crestfallen Knight (wall top, under drop)After dropping down onto the side path on the right side of the Mausoleum Lookout courtyard to where the Crystal Lizard is, behind you.
RC: Soul of a Weary Warrior (swamp center)In the middle of the muck pit where the Judicator is patrolling.
RC: Soul of a Weary Warrior (swamp right, by sunken church)In between where the Judicator patrols in the muck pit and the submerged building with the 4 Ringed Knights. Provides some shelter from his arrows.
RC: Soul of a Weary Warrior (upper cliff, by first alcove)In front of the first alcove providing shelter from Midir's fire-breathing on the way to Shared Grave.
RC: Spears of the Church (hidden boss drop)Dropped by Darkeater Midir
RC: Titanite Chunk (streets high, building opposite)Down a path past the room where Silver Knight Ledo invades. The building is up the very long ladder from the muck pit, down the path all the way to the right.
RC: Titanite Chunk (streets, near left drop)Near the top of the stairs by Shira, dropping down in an alcove to the left.
RC: Titanite Chunk (swamp center, along edge)Along the edge of the muck pit close to where the Judicator patrols.
RC: Titanite Chunk (swamp far left, up hill)Up a hill at the edge of the muck pit with the Hollow Clerics.
RC: Titanite Chunk (swamp near left, opposite ladder)At the edge of the muck pit, on the opposite side of the wall from the very long ladder.
RC: Titanite Chunk (swamp near right, by sinking church)At the very edge of the muck pit, to the left of the submerged building with 4 Ringed Knights.
RC: Titanite Chunk (wall top, among graves)Along the right edge of the courtyard after Mausoleum Lookout in a cluster of graves.
RC: Titanite Chunk (wall upper, courtyard alcove)In the courtyard where the first Ringed Knight is seen, along the right wall into an alcove.
RC: Titanite Scale (grave, lizard after first drop)In the area at the far end of the muck pit with the Dragonslayer Armour.
RC: Titanite Scale (lower cliff, bridge)On the final bridge where Midir attacks before you knock him off.
RC: Titanite Scale (swamp far, by miniboss)In the area at the far end of the muck pit with the Dragonslayer Armour.
RC: Titanite Scale (upper cliff, first alcove)In the first alcove providing shelter from Midir's fire-breathing on the way to Shared Grave.
RC: Titanite Scale (upper cliff, lower path)After dropping down from the upper path attacked by Midir's fire-breathing to the lower path.
RC: Titanite Scale (upper cliff, path under bridge)Partway down a slope to the right of the bridge where Midir first assaults you.
RC: Titanite Scale (wall lower, lizard)Dropped by the Crystal Lizard right after the crumbling stairs in Shared Grave.
RC: Titanite Scale (wall top, behind spawn)Behind you at the very start of the level.
RC: Titanite Scale (wall top, lizard on side path)Dropped by the Crystal Lizard on the stairs going up from Shared Grave to Ringed Inner Wall elevator.
RC: Titanite Slab (ashes, NPC drop)Given by Shira after defeating Midir, or dropped by her in post-Filianore Ringed City.
RC: Titanite Slab (ashes, mob drop)Dropped by the Ringed Knight wandering around near Gael's arena
RC: Titanite Slab (mid boss drop)Dropped by Halflight, Spear of the Church
RC: Twinkling Titanite (church path, left of boss door)Dropping down to the left of the door leading to Halflight.
RC: Twinkling Titanite (grave, lizard after first drop)Dropped by the Crystal Lizard right after the crumbling stairs in Shared Grave.
RC: Twinkling Titanite (streets high, lizard)Dropped by the Crystal Lizard which runs across the bridge after climbing the very long ladder up from the muck pit.
RC: Twinkling Titanite (swamp near left)At the left edge of the muck pit coming from the stairs, guarded by a Preacher Locust.
RC: Twinkling Titanite (swamp near right, on sinking church)Following the sloped roof of the submerged building with the 4 Ringed Knights, along the back wall
RC: Twinkling Titanite (wall top, lizard on side path)Dropped by the first Crystal Lizard on the side path on the right side of the Mausoleum Lookout courtyard
RC: Twinkling Titanite (wall tower, jump from chandelier)In the cylindrical building before the long stairs with many Harald Legion Knights. Carefully drop down to the chandelier in the center, then jump to the second floor. The item is on a ledge.
RC: Violet Wrappings (wall hidden, before boss)In the chapel before the Midir fight in the Ringed Inner Wall building.
RC: White Birch Bow (swamp far left, up hill)Up a hill at the edge of the muck pit with the Hollow Clerics.
RC: White Preacher Head (swamp near, ground near bonfire exit)Past the balcony to the right of the Ringed City Streets bonfire room entrance. Can be accessed by dropping down straight after from the bonfire, then around to the left.
RC: Wolf Ring+3 (street gardens, NPC drop)Dropped by Alva (invades whether embered or not, or boss defeated or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight.
RC: Young White Branch (swamp far left, by white tree)Next to a small birch tree at the edge of the muck pit, between the hill with the aggressive Hollow Clerics and the building with the praying Hollow Clerics outside.
RS: Blue Bug Pellet (broken stairs by Orbeck)On the broken stairs leading down from Orbeck's area, on the opposite side from Orbeck
RS: Blue Sentinels (Horace)Given by Horace the Hushed by first "talking" to him, or upon death.
RS: Braille Divine Tome of Carim (drop from bridge to Halfway Fortress)Dropping down before the bridge leading up to Halfway Fortress from Road of Sacrifices, guarded by the maggot belly dog
RS: Brigand Armor (beneath road)In the middle of the path where the Madwoman waits in Road of Sacrifices
RS: Brigand Axe (beneath road)At the start of the path leading down to the Madwoman in Road of Sacrifices
RS: Brigand Gauntlets (beneath road)In the middle of the path where the Madwoman waits in Road of Sacrifices
RS: Brigand Hood (beneath road)In the middle of the path where the Madwoman waits in Road of Sacrifices
RS: Brigand Trousers (beneath road)In the middle of the path where the Madwoman waits in Road of Sacrifices
RS: Brigand Twindaggers (beneath road)At the end of the path guarded by the Madwoman in Road of Sacrifices
RS: Butcher Knife (NPC drop beneath road)Dropped by the Butcher Knife-wielding madwoman near the start of Road of Sacrifices
RS: Chloranthy Ring+2 (road, drop across from carriage)Found dropping down from the first Storyteller Corvian on the left side rather than the right side. You can then further drop down to where the madwoman is, after healing.
RS: Conjurator Boots (deep water)In the deep water part of the Crucifixion Woods crab area, between a large tree and the keep wall
RS: Conjurator Hood (deep water)In the deep water part of the Crucifixion Woods crab area, between a large tree and the keep wall
RS: Conjurator Manchettes (deep water)In the deep water part of the Crucifixion Woods crab area, between a large tree and the keep wall
RS: Conjurator Robe (deep water)In the deep water part of the Crucifixion Woods crab area, between a large tree and the keep wall
RS: Crystal Gem (stronghold, lizard)Dropped by the Crystal Lizard in the building before Crystal Sage
RS: Ember (right of Halfway Fortress entrance)On the ledge with the Corvian with the Storyteller Staff, to the right of the Halfway Fortress entrance
RS: Ember (right of fire behind stronghold left room)Behind the building before Crystal Sage, approached from Crucifixion Woods bonfire. Can drop down on left side or go under bridge on right side
RS: Estus Shard (left of fire behind stronghold left room)Behind the building leading to Crystal Sage, approached from Crucifixion Woods bonfire. Can drop down on left side of go under bridge on right side
RS: Exile Greatsword (NPC drop by Farron Keep)Dropped by the greatsword-wielding Exile Knight before the ladder down to Farron Keep
RS: Fading Soul (woods by Crucifixion Woods bonfire)Dropping down from the Crucifixion Woods bonfire toward the Halfway Fortress, guarded by dogs
RS: Fallen Knight Armor (water's edge by Farron Keep)On the edge of the water surrounding the building where you descend into Farron Keep
RS: Fallen Knight Gauntlets (water's edge by Farron Keep)On the edge of the water surrounding the building where you descend into Farron Keep
RS: Fallen Knight Helm (water's edge by Farron Keep)On the edge of the water surrounding the building where you descend into Farron Keep
RS: Fallen Knight Trousers (water's edge by Farron Keep)On the edge of the water surrounding the building where you descend into Farron Keep
RS: Farron Coal (keep perimeter)At the end of the Farron Keep Perimeter building on Crucifixion Woods side, behind the Black Knight
RS: Golden Falcon Shield (path from stronghold right room to Farron Keep)Halfway up the stairs to the sorcerer in the building before Crystal Sage, entering from the stairs leading up from the crab area, go straight and follow the path down
RS: Grass Crest Shield (water by Crucifixion Woods bonfire)Dropping down into the crab area from Crucifixion Woods, on the other side of a tree from the greater crab
RS: Great Club (NPC drop by Farron Keep)Dropped by the club-wielding Exile Knight before the ladder down to Farron Keep
RS: Great Swamp Pyromancy Tome (deep water)In the deep water part of the Crucifixion Woods crab area, between a large tree and the keep wall
RS: Great Swamp Ring (miniboss drop, by Farron Keep)Dropped by Greater Crab in Crucifixion Woods close to the Farron Keep outer wall
RS: Green Blossom (by deep water)In the Crucifixion Woods crab area out in the open, close to the edge of the deep water area
RS: Green Blossom (water by Crucifixion Woods bonfire)In the Crucifixion Woods crab area close to the Crucifixion Woods bonfire, along the left wall of the water area, to the right of the entrance to the building before Crystal Sage
RS: Heretic's Staff (stronghold left room)In the building before Crystal Sage, entering from near Cruficixion Woods, in a corner under the first stairwell and balcony
RS: Heysel Pick (Heysel drop)Dropped by Heysel when she invades in Road of Sacrifices
RS: Homeward Bone (balcony by Farron Keep)At the far end of the building where you descend into Farron Keep, by the balcony
RS: Large Soul of an Unknown Traveler (left of stairs to Farron Keep)In the area before you descend into Farron Keep, before the stairs to the far left
RS: Lingering Dragoncrest Ring+1 (water)On a tree by the greater crab near the Crucifixion Woods bonfire, after the Grass Crest Shield tree
RS: Morne's Ring (drop from bridge to Halfway Fortress)Dropping down before the bridge leading up to Halfway Fortress from Road of Sacrifices, guarded by the maggot belly dog
RS: Ring of Sacrifice (stronghold, drop from right room balcony)Drop down from the platform behind the sorcerer in the building before Crystal Sage, entering from the stairs leading up from the crab area
RS: Sage Ring (water beneath stronghold)In an alcove under the building before Crystal Sage, guarded by a Lycanthrope, accessible from the swamp or from dropping down
RS: Sellsword Armor (keep perimeter balcony)In the Farron Keep Perimeter building on Crucifixion Woods side, on the balcony on the right side overlooking the Black Knight
RS: Sellsword Gauntlet (keep perimeter balcony)In the Farron Keep Perimeter building on Crucifixion Woods side, on the balcony on the right side overlooking the Black Knight
RS: Sellsword Helm (keep perimeter balcony)In the Farron Keep Perimeter building on Crucifixion Woods side, on the balcony on the right side overlooking the Black Knight
RS: Sellsword Trousers (keep perimeter balcony)In the Farron Keep Perimeter building on Crucifixion Woods side, on the balcony on the right side overlooking the Black Knight
RS: Sellsword Twinblades (keep perimeter)In the Farron Keep Perimeter building on Crucifixion Woods side, behind and to the right of the Black Knight
RS: Shriving Stone (road, by start)Dropping down to the left of the first Corvian enemy in Road of Sacrifices
RS: Sorcerer Gloves (water beneath stronghold)In an alcove under the building before Crystal Sage, guarded by a Lycanthrope, accessible from the swamp or from dropping down
RS: Sorcerer Hood (water beneath stronghold)In an alcove under the building before Crystal Sage, guarded by a Lycanthrope, accessible from the swamp or from dropping down
RS: Sorcerer Robe (water beneath stronghold)In an alcove under the building before Crystal Sage, guarded by a Lycanthrope, accessible from the swamp or from dropping down
RS: Sorcerer Trousers (water beneath stronghold)In an alcove under the building before Crystal Sage, guarded by a Lycanthrope, accessible from the swamp or from dropping down
RS: Soul of a Crystal SageDropped by Crystal Sage
RS: Soul of an Unknown Traveler (drop along wall from Halfway Fortress)From Halfway Fortress, hug the right wall and drop down twice on the way to the crab area
RS: Soul of an Unknown Traveler (right of door to stronghold left)Out in the open to the right of the building before Crystal Sage, as entered from Crufixion Woods bonfire
RS: Soul of an Unknown Traveler (road, by wagon)To the right of the overturned wagon descending from the Road of Sacrifices bonfire
RS: Titanite Shard (road, on bridge after you go under)Crossing the bridge you go under after the first Road of Sacrifices bonfire, after a sleeping Corvian and another Corvian guarding the pickup
RS: Titanite Shard (water by Halfway Fortress)Dropping down into the Crucifixion Woods crab area right after Halfway Fortress, on the left wall heading toward the Black Knight building, guarded by dog
RS: Titanite Shard (woods, left of path from Halfway Fortress)Hugging the left wall from Halfway Fortress to Crystal Sage, behind you after the first dropdown
RS: Titanite Shard (woods, surrounded by enemies)Hugging the left wall from Halfway Fortress to the Crystal Sage bonfire, after a dropdown surrounded by seven Poisonhorn bugs
RS: Twin Dragon Greatshield (woods by Crucifixion Woods bonfire)In the middle of the area with the Poisonhorn bugs and Lycanthrope Hunters, following the wall where the bugs guard a Titanite Shard
RS: Xanthous Crown (Heysel drop)Dropped by Heysel when she invades in Road of Sacrifices
SL: Black Iron Greatshield (ruins basement, NPC drop)Dropped by Knight Slayer Tsorig in Smouldering Lake
SL: Black Knight Sword (ruins main lower, illusory wall in far hall)On the far exit of the Demon Ruins main hall, past an illusory wall, guarded by a Black Knight
SL: Bloodbite Ring+1 (behind ballista)Behind the ballista, overlooking Smouldering Lake
SL: Chaos Gem (antechamber, lizard at end of long hall)Dropped by the Crystal Lizard found from the Antechamber bonfire, toward the Demon Cleric and to the right, then all the way down
SL: Chaos Gem (lake, far end by mob)In Smouldering Lake along the wall underneath the balista, all the way to the left past two crabs
SL: Dragonrider Bow (by ladder from ruins basement to ballista)After climbing up the ladder after the Black Knight in Demon Ruins, falling back down to a ledge
SL: Ember (ruins basement, in lava)In the lava pit under the Black Knight, by Knight Slayer Tsorig
SL: Ember (ruins main lower, path to antechamber)Going down the stairs from the Antechamber bonfire, to the right, at the end of the short hallway to the next right
SL: Ember (ruins main upper, hall end by hole)In the Demon Ruins, hugging the right wall from the Demon Ruins bonfire, or making a jump from the illusory hall corridor from Antechamber bonfire
SL: Ember (ruins main upper, just after entrance)Behind the first Demon Cleric from the Demon Ruins bonfire
SL: Estus Shard (antechamber, illusory wall)Behind an illusory wall and Smouldering Writhing Flesh-filled corridor from Antechamber bonfire
SL: Flame Stoneplate Ring+2 (ruins main lower, illusory wall in far hall)On the far exit of the Demon Ruins main hall, past an illusory wall, past the Black Knight, hidden in a corner
SL: Fume Ultra Greatsword (ruins basement, NPC drop)Dropped by Knight Slayer Tsorig in Smouldering Lake
SL: Homeward Bone (path to ballista)In the area targeted by the ballista after the long ladder guarded by the Black Knight, before the Bonewheel Skeletons
SL: Izalith Pyromancy Tome (antechamber, room near bonfire)In the room straight down from the Antechamber bonfire, past a Demon Cleric, surrounded by many Ghrus.
SL: Izalith Staff (ruins basement, second illusory wall behind chest)Past an illusory wall to the left of the Large Hound Rat in Demon Ruins, and then past another illusory wall, before the basilisk area
SL: Knight Slayer's Ring (ruins basement, NPC drop)Dropped by Knight Slayer Tsorig after invading in the Catacombs
SL: Large Titanite Shard (lake, by entrance)In the middle of Smouldering Lake, close to the Abandoned Tomb
SL: Large Titanite Shard (lake, by miniboss)In the middle of Smouldering Lake, under the Carthus Sandworm
SL: Large Titanite Shard (lake, by tree #1)In the middle of Smouldering Lake, by a tree before the hallway to the pit
SL: Large Titanite Shard (lake, by tree #2)In the middle of Smouldering Lake, by a tree before the hallway to the pit
SL: Large Titanite Shard (lake, straight from entrance)In the middle of Smouldering Lake, in between Abandoned Tomb and Demon Ruins
SL: Large Titanite Shard (ledge by Demon Ruins bonfire)On a corpse hanging off the ledge outside the Demon Ruins bonfire
SL: Large Titanite Shard (ruins basement, illusory wall in upper hall)In a chest past an illusory wall to the left of the Large Hound Rat in Demon Ruins, before the basilisk area
SL: Large Titanite Shard (side lake #1)In the Smouldering Lake pit where Horace can be found, following the right wall from Abandoned Tomb
SL: Large Titanite Shard (side lake #2)In the Smouldering Lake pit where Horace can be found, following the right wall from Abandoned Tomb
SL: Lightning Stake (lake, miniboss drop)Dropped by the giant Carthus Sandworm
SL: Llewellyn Shield (Horace drop)Dropped by Horace the Hushed upon death or quest completion.
SL: Quelana Pyromancy Tome (ruins main lower, illusory wall in grey room)At the far end of the Demon Ruins main hall to the right, where the rats are, then another right and past the illusory wall
SL: Sacred Flame (ruins basement, in lava)In the lava pit under the Black Knight, by Knight Slayer Tsorig
SL: Shield of Want (lake, by miniboss)In the middle of Smouldering Lake, under the Carthus Sandworm
SL: Soul of a Crestfallen Knight (ruins basement, above lava)Next to the Black Knight in Demon Ruins
SL: Soul of the Old Demon KingDropped by Old Demon King in Smouldering Lake
SL: Speckled Stoneplate Ring (lake, ballista breaks bricks)Behind a destructible wall in Smouldering Lake which the ballista has to destroy
SL: Titanite Chunk (path to side lake, lizard)Dropped by the second Crystal Lizard in the cave leading to the pit where Horace can be found in Smouldering Lake
SL: Titanite Scale (ruins basement, path to lava)In the area with Basilisks on the way to the ballista
SL: Toxic Mist (ruins main lower, in lava)At the far end of the Demon Ruins main hall to the right, where the rats are, then another right and past the illusory wall, in the middle of the lava pit.
SL: Twinkling Titanite (path to side lake, lizard)Dropped by the first Crystal Lizard in the cave leading to the pit where Horace can be found in Smouldering Lake
SL: Undead Bone Shard (lake, miniboss drop)Dropped by the giant Carthus Sandworm
SL: Undead Bone Shard (ruins main lower, left after stairs)In the close end of the Demon Ruins main hall, right below a Smouldering Writhing Flesh
SL: White Hair Talisman (ruins main lower, in lava)At the far end of the Demon Ruins main hall to the right, where the rats are, then another right and past the illusory wall, at the far end of the lava pit.
SL: Yellow Bug Pellet (side lake)In the Smouldering Lake pit where Horace can be found, following the right wall from Abandoned Tomb
UG: Ashen Estus Ring (swamp, path opposite bonfire)In the coffin similar to your initial spawn location, guarded by Corvians
UG: Black Knight Glaive (boss arena)In the Champion Gundyr boss area
UG: Blacksmith Hammer (shrine, Andre's room)Where Andre sits in Firelink Shrine
UG: Chaos Blade (environs, left of shrine)Where Sword Master is in Firelink Shrine
UG: Coiled Sword Fragment (shrine, dead bonfire)In the dead Firelink Shrine bonfire
UG: Ember (shop)Sold by Untended Graves Handmaid
UG: Eyes of a Fire Keeper (shrine, Irina's room)Behind an illusory wall, in the same location Irina sits in Firelink Shrine
UG: Hidden Blessing (cemetery, behind coffin)Behind the coffin that had a Titanite Shard in Cemetary of Ash
UG: Hornet Ring (environs, right of main path)On a cliffside to the right of the main path leading up to dark Firelink Shrine, after Abyss Watchers is defeated.
UG: Life Ring+3 (shrine, behind big throne)Behind Prince Lothric's throne
UG: Priestess Ring (shop)Sold or dropped by Untended Graves Handmaid. Killing her is not recommended
UG: Ring of Steel Protection+1 (environs, behind bell tower)Behind Bell Tower to the right
UG: Shriving Stone (swamp, by bonfire)At the very start of the area
UG: Soul of Champion GundyrDropped by Champion Gundyr
UG: Soul of a Crestfallen Knight (environs, above shrine entrance)Above the Firelink Shrine entrance, up stairs/slope from either left or right of the entrance
UG: Soul of a Crestfallen Knight (swamp, center)Close to where Ashen Estus Flask was in Cemetary of Ash
UG: Titanite Chunk (swamp, left path by fountain)In a path to the left of where Ashen Estus Flask was in Cemetary of Ash
UG: Titanite Chunk (swamp, right path by fountain)In a path to the right of where Ashen Estus Flask was in Cemetary of Ash
UG: Wolf Knight Armor (shop after killing FK boss)Sold by Untended Graves Handmaid after defeating Abyss Watchers
UG: Wolf Knight Gauntlets (shop after killing FK boss)Sold by Untended Graves Handmaid after defeating Abyss Watchers
UG: Wolf Knight Helm (shop after killing FK boss)Sold by Untended Graves Handmaid after defeating Abyss Watchers
UG: Wolf Knight Leggings (shop after killing FK boss)Sold by Untended Graves Handmaid after defeating Abyss Watchers
US: Alluring Skull (Foot of the High Wall, behind carriage)Guarded by two dogs after the Foot of the High Wall bonfire
US: Alluring Skull (on the way to tower, behind building)After the ravine bridge leading to Eygon and the Giant's tower, wrapping around the building to the right.
US: Alluring Skull (tower village building, upstairs)Up the stairs of the building with Cage Spiders after the Fire Demon, before the dogs
US: Bloodbite Ring (miniboss in sewer)Dropped by the large rat in the sewers with grave access
US: Blue Wooden Shield (graveyard by white tree)After Dilapidated Bridge bonfire, in the back of the Giant's arrow area. Guarded by a flamberge-wielding thrall.
US: Caduceus Round Shield (right after stable exit)After exiting the building across the bridge to the right of the first Undead Settlement building, to the left
US: Caestus (sewer)In the tunnel with the Giant Hound Rat and Grave Key door, from the ravine bridge toward Dilapidated Bridge bonfire
US: Charcoal Pine Bundle (first building)On the bottom floor of the first building
US: Charcoal Pine Resin (hanging corpse room)In the building after the burning tree and Cathedral Evangelist, in the room with the many hanging corpses
US: Chloranthy Ring (tower village, jump from roof)At the end of the Fire Demon loop, in the tower where you have to drop down after the roof
US: Cleric Blue Robe (graveyard by white tree)After Dilapidated Bridge bonfire, in the back of the Giant's arrow area. Guarded by a flamberge-wielding thrall.
US: Cleric Gloves (graveyard by white tree)After Dilapidated Bridge bonfire, in the back of the Giant's arrow area. Guarded by a flamberge-wielding thrall.
US: Cleric Hat (graveyard by white tree)After Dilapidated Bridge bonfire, in the back of the Giant's arrow area. Guarded by a flamberge-wielding thrall.
US: Cleric Trousers (graveyard by white tree)After Dilapidated Bridge bonfire, in the back of the Giant's arrow area. Guarded by a flamberge-wielding thrall.
US: Cornyx's Garb (by Cornyx's cage after Cuculus quest)Appears next to Cornyx's cage after defeating Old Demon King with Cuculus surviving
US: Cornyx's Garb (kill Cornyx)Dropped by Cornyx
US: Cornyx's Skirt (by Cornyx's cage after Cuculus quest)Appears next to Cornyx's cage after defeating Old Demon King with Cuculus surviving
US: Cornyx's Skirt (kill Cornyx)Dropped by Cornyx
US: Cornyx's Wrap (by Cornyx's cage after Cuculus quest)Appears next to Cornyx's cage after defeating Old Demon King with Cuculus surviving
US: Cornyx's Wrap (kill Cornyx)Dropped by Cornyx
US: Covetous Silver Serpent Ring+2 (tower village, drop down from roof)At the back of a roof near the end of the Fire Demon loop, dropping down past where Flynn's Ring is
US: Ember (behind burning tree)Behind the burning tree with the Cathedral Evangelist
US: Ember (bridge on the way to tower)On the ravine bridge leading toward Eygon and the Giant's tower
US: Ember (by miniboss before Road of Sacrifices)In the room with the Outrider Knight
US: Ember (by stairs to boss)Next to the stairs leading up to Curse-Rotted Greatwood fight, near a tree guarded by a dog
US: Ember (by white tree)Near the Birch Tree where giant shoots arrows
US: Estus Shard (under burning tree)In front of the burning tree guarded by the Cathedral Evangelist
US: Fading Soul (by white tree)Near the Birch Tree where giant shoots arrows
US: Fading Soul (outside stable)In the thrall area to the right of the bridge to the right of the burning tree with the Cathedral Evangelist
US: Fire Clutch Ring (wooden walkway past stable)From the area bombarded by firebombs above the Cliff Underside bonfire
US: Fire Gem (tower village, miniboss drop)Dropped by the Fire Demon you fight with Siegward
US: Firebomb (stable roof)In the thrall area across the bridge from the first Undead Settlement building, on a rooftop overlooking the Cliff Underside area.
US: Flame Stoneplate Ring (hanging corpse by Mound-Maker transport)On a hanging corpse in the area with the Pit of Hollows cage manservant, after the thrall area, overlooking the entrance to the Giant's tower.
US: Flynn's Ring (tower village, rooftop)On the roof toward the end of the Fire Demon loop, past the Cathedral Evangelists
US: Great Scythe (building by white tree, balcony)On the balcony of the building before Curse-Rotted Greatwood, coming from Dilapidated Bridge bonfire
US: Hand Axe (by Cornyx)Next to Cornyx's cell
US: Hawk Ring (Giant Archer)Dropped by Giant, either by killing him or collecting all of the birch tree items locations in the base game.
US: Heavy Gem (Hawkwood)Given or dropped by Hawkwood after defeating Curse-Rotted Greatwood or Crystal Sage
US: Heavy Gem (chasm, lizard)Drop by Crystal Lizard in ravine accessible by Grave Key or dropping down near Eygon.
US: Homeward Bone (by Yoel)In the thrall area across the bridge from the first Undead Settlement building, on a roof overlooking the ravine bridge.
US: Homeward Bone (stable roof)At the end of the loop from the Siegward Demon fight, after dropping down from the roof onto the tower with Chloranthy Ring, to the right of the tower entrance
US: Homeward Bone (tower village, jump from roof)Given by Holy Knight Hodrick before fighting Curse-Rotted Greatwood, or on his corpse in the Pit of Hollows.
US: Homeward Bone (tower village, right of first drop)Under Foot of the High Wall bonfire, around where Yoel can be first met
US: Human Pine Resin (tower village building, chest upstairs)In a chest after Fire Demon. Cage Spiders activate open opening it.
US: Irithyll Straight Sword (miniboss drop, by Road of Sacrifices)Dropped by the Boreal Outright Knight before Road of Sacrifices
US: Kukri (hanging corpse above burning tree)Hanging corpse high above the burning tree with the Cathedral Evangelist. Must be shot down with an arrow or projective.
US: Large Club (tower village, by miniboss)In the Fire Demon area
US: Large Soul of a Deserted Corpse (across from Foot of the High Wall)On the opposite tower from the Foot of the High Wall bonfire
US: Large Soul of a Deserted Corpse (around corner by Cliff Underside)After going up the stairs from Curse-Rotted Greatwood to Cliff Underside area, on a cliff edge to the right
US: Large Soul of a Deserted Corpse (by white tree)Near the Birch Tree where giant shoots arrows
US: Large Soul of a Deserted Corpse (hanging corpse room, over stairs)On a hanging corpse in the building after the burning tree. Can be knocked down by dropping onto the stairs through the broken railing.
US: Large Soul of a Deserted Corpse (on the way to tower, by well)After the ravine bridge leading toward Eygon and the Giant's tower, next to the well to the right
US: Large Soul of a Deserted Corpse (stable)In the building with stables across the bridge and to the right from the first Undead Settlement building
US: Life Ring+1 (tower on the way to village)On the wooden rafters near where Siegward is waiting for Fire Demon
US: Loincloth (by Velka statue)Next to the Velka statue. Requires Grave Key or dropping down near Eygon and backtracking through the skeleton area.
US: Loretta's Bone (first building, hanging corpse on balcony)On a hanging corpse after the first building, can be knocked down by rolling into it
US: Mirrah Gloves (tower village, jump from roof)At the end of the Fire Demon loop, in the tower where you have to drop down after the roof
US: Mirrah Trousers (tower village, jump from roof)At the end of the Fire Demon loop, in the tower where you have to drop down after the roof
US: Mirrah Vest (tower village, jump from roof)At the end of the Fire Demon loop, in the tower where you have to drop down after the roof
US: Mortician's Ashes (graveyard by white tree)In the area past the Dilapidated Bridge bonfire, where the Giant is shooting arrows, at the close end of the graveyard
US: Mound-makers (Hodrick)Given by Hodrick if accessing the Pit of Hollows before fighting Curse-Rotted Greatwood, or dropped after invading him with Sirris.
US: Northern Armor (tower village, hanging corpse)Hanging corpse in the Fire Demon fight area, can be knocked down by rolling into it
US: Northern Gloves (tower village, hanging corpse)Hanging corpse in the Fire Demon fight area, can be knocked down by rolling into it
US: Northern Helm (tower village, hanging corpse)Hanging corpse in the Fire Demon fight area, can be knocked down by rolling into it
US: Northern Trousers (tower village, hanging corpse)Hanging corpse in the Fire Demon fight area, can be knocked down by rolling into it
US: Old Sage's Blindfold (kill Cornyx)Dropped by Cornyx
US: Pale Tongue (tower village, hanging corpse)Hanging corpse in the Fire Demon fight area, can be knocked down by rolling into it
US: Partizan (hanging corpse above Cliff Underside)On a hanging corpse on the path from Cliff Underside to Cornyx's cage. Must be shot down with an arrow or projective.
US: Plank Shield (outside stable, by NPC)In the thrall area across the bridge from the first Undead Settlement building, on a cliff edge overlooking the ravine bridge.
US: Poisonbite Ring+1 (graveyard by white tree, near well)Behind the well in the back of area where the Giant shoots arrows, nearby where the flamerge-wielding thrall drops down.
US: Pyromancy Flame (Cornyx)Given by Cornyx in Firelink Shrine or dropped.
US: Red Bug Pellet (tower village building, basement)On the floor of the building after the Fire Demon encounter
US: Red Hilted Halberd (chasm crypt)In the skeleton area accessible from Grave Key or dropping down from near Eygon
US: Red and White Shield (chasm, hanging corpse)On a hanging corpse in the ravine accessible with the Grave Key or dropping down near Eygon, to the entrance of Irina's prison. Must be shot down with an arrow or projective.
US: Reinforced Club (by white tree)Near the Birch Tree where giant shoots arrows
US: Repair Powder (first building, balcony)On the balcony of the first Undead Settlement building
US: Rusted Coin (wooden ledge above Dilapidated Bridge)On a wooden ledge near the Dilapidated Bridge bonfire. Must be jumped to from near Cathedral Evangelist enemy
US: Saint's Talisman (chasm, by ladder)From the ravine accessible via Grave Key or dropping near Eygon, before ladder leading up to Irina of Carim
US: Sharp Gem (lizard by Dilapidated Bridge)Drop by Crystal Lizard near Dilapidated Bridge bonfire.
US: Siegbräu (Siegward)Given by Siegward after helping him defeat the Fire Demon.
US: Small Leather Shield (first building, hanging corpse by entrance)Hanging corpse in the first building, to the right of the entrance
US: Soul of a Nameless Soldier (top of tower)At the top of the tower where Giant shoots arrows
US: Soul of an Unknown Traveler (chasm crypt)In the skeleton area accessible Grave Key or dropping down from near Eygon
US: Soul of an Unknown Traveler (on the way to Dilapidated Bridge, in crates)After exiting the building after the burning tree on the way to the Dilapidated Bridge bonfire. Hidden behind some crates between two buildings on the right.
US: Soul of an Unknown Traveler (pillory past stable)In the area bombarded by firebombs above the Cliff Underside bonfire
US: Soul of an Unknown Traveler (portcullis by burning tree)Behind a grate to the left of the burning tree and Cathedral Evangelist
US: Soul of the Rotted GreatwoodDropped by Curse Rotted Greatwood
US: Spotted Whip (by Cornyx's cage after Cuculus quest)Appears next to Cornyx's cage after defeating Old Demon King with Cuculus surviving
US: Sunset Armor (pit of hollows after killing Hodrick w/Sirris)Found in Pit of Hollows after completing Sirris' questline.
US: Sunset Gauntlets (pit of hollows after killing Hodrick w/Sirris)Found in Pit of Hollows after completing Sirris' questline.
US: Sunset Helm (Pit of Hollows after killing Hodrick w/Sirris)Found in Pit of Hollows after completing Sirris' questline.
US: Sunset Leggings (pit of hollows after killing Hodrick w/Sirris)Found in Pit of Hollows after completing Sirris' questline.
US: Titanite Shard (chasm #1)In the ravine accessible from Grave Key or dropping down from near Eygon
US: Titanite Shard (chasm #2)In the ravine accessible from Grave Key or dropping down from near Eygon
US: Titanite Shard (lower path to Cliff Underside)At the end of the cliffside path next to Cliff Underside bonfire, guarded by a Hollow Peasant wielding a four-pronged plow.
US: Titanite Shard (on the way to Dilapidated Bridge, up ladder)Next to the Cathedral Evangelist close to the Dilapidated Bridge bonfire
US: Titanite Shard (porch after burning tree)In front of the building after the burning tree and Cathedral Evangelist
US: Titanite Shard (side path on the way to Dilapidated Bridge)On a side path to the right of the Cathedral Evangelist before the Dilapidated Bridge bonfire
US: Tower Key (kill Irina)Dropped by Irina of Carim
US: Transposing Kiln (boss drop)Dropped by Curse Rotted Greatwood
US: Undead Bone Shard (by white tree)In the area past the Dilapidated Bridge bonfire, where the Giant is shooting arrows, jumping to the floating platform on the right
US: Wargod Wooden Shield (Pit of Hollows)In the Pit of Hollows
US: Warrior of Sunlight (hanging corpse room, drop through hole)Dropping through a hole in the floor in the first building after the burning tree.
US: Whip (on the way to Dilapidated Bridge, behind wooden wall)In one of the houses between building after the burning tree and the Dilapidated Bridge bonfire
US: Young White Branch (by white tree #1)Near the Birch Tree where giant shoots arrows
US: Young White Branch (by white tree #2)Near the Birch Tree where giant shoots arrows
+ From c11ca5c1dde1dfaa7f8337610f3b0606ea42cdf5 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 29 Dec 2023 23:49:31 -0800 Subject: [PATCH 106/238] Fix location requirements --- worlds/dark_souls_3/__init__.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 3f27543bbab2..71e77e002313 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -742,22 +742,14 @@ def has_any_scroll(state): "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)", - ], lambda state: state.can_reach( - "AP: Drakeblood Greatsword (mausoleum, NPC drop)", - "Location", - self.player - )) + ], lambda state: state.can_reach("Go To Archdragon Peak", "Entrance", self.player)) self._add_location_rule([ "FK: Havel's Helm (upper keep, after killing AP belfry roof NPC)", "FK: Havel's Armor (upper keep, after killing AP belfry roof NPC)", "FK: Havel's Gauntlets (upper keep, after killing AP belfry roof NPC)", "FK: Havel's Leggings (upper keep, after killing AP belfry roof NPC)", - ], lambda state: state.can_reach( - "AP: Dragon Tooth (belfry roof, NPC drop)", - "Location", - self.player - )) + ], lambda state: state.can_reach("Go To Archdragon Peak", "Entrance", self.player)) self._add_location_rule([ "RC: Dragonhead Shield (streets monument, across bridge)", From edf476c2bd4ca7f58a97270e0fd71995854e225d Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 29 Dec 2023 23:52:28 -0800 Subject: [PATCH 107/238] Clean up randomization options --- worlds/dark_souls_3/Bosses.py | 4 +- worlds/dark_souls_3/Items.py | 469 ++-- worlds/dark_souls_3/Locations.py | 4030 +++++++++++++----------------- worlds/dark_souls_3/Options.py | 180 +- worlds/dark_souls_3/__init__.py | 149 +- 5 files changed, 2136 insertions(+), 2696 deletions(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index aa93480b8556..a14b8e0921d4 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -59,7 +59,7 @@ class DS3BossInfo: region = "Catacombs of Carthus", locations = { "FK: Soul of the Blood of the Wolf", "FK: Cinders of a Lord - Abyss Watcher", - "UG: Hornet Ring (environs, right of main path)", + "UG: Hornet Ring (environs, right of main path after killing FK boss)", "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)", @@ -126,7 +126,7 @@ class DS3BossInfo: "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)", + "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)", diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index c1f6d391bb93..5b01f705e4c3 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -17,9 +17,11 @@ class DS3ItemCategory(IntEnum): RING = 6 SPELL = 7 MISC = 8 - KEY = 9 + UNIQUE = 9 BOSS = 10 - SKIP = 11 + SOUL = 11 + UPGRADE = 12 + HEALING = 13 @property def is_infusible(self) -> bool: @@ -137,6 +139,9 @@ class DS3ItemData(): filler: bool = False """Whether this is a candidate for a filler item to be added to fill out extra locations.""" + skip: bool = False + """Whether to omit this item from randomization and replace it with filler or unique items.""" + force_unique: bool = False """Whether to ensure only one copy of this item appears in the run. @@ -221,7 +226,8 @@ def __init__( @staticmethod def event(name: str, player: int) -> "DarkSouls3Item": - data = DS3ItemData(name, None, DS3ItemCategory.SKIP, classification = ItemClassification.progression) + data = DS3ItemData(name, None, DS3ItemCategory.MISC, + skip = True, classification = ItemClassification.progression) data.ap_code = None return DarkSouls3Item(player, data) @@ -836,15 +842,15 @@ def flatten(l): DS3ItemData("Karla's Trousers", 0x15E6AA78, DS3ItemCategory.ARMOR), # Covenants - DS3ItemData("Blade of the Darkmoon", 0x20002710, DS3ItemCategory.SKIP), - DS3ItemData("Watchdogs of Farron", 0x20002724, DS3ItemCategory.SKIP), - DS3ItemData("Aldrich Faithful", 0x2000272E, DS3ItemCategory.SKIP), - DS3ItemData("Warrior of Sunlight", 0x20002738, DS3ItemCategory.SKIP), - DS3ItemData("Mound-makers", 0x20002742, DS3ItemCategory.SKIP), - DS3ItemData("Way of Blue", 0x2000274C, DS3ItemCategory.SKIP), - DS3ItemData("Blue Sentinels", 0x20002756, DS3ItemCategory.SKIP), - DS3ItemData("Rosaria's Fingers", 0x20002760, DS3ItemCategory.SKIP), - DS3ItemData("Spears of the Church", 0x2000276A, DS3ItemCategory.SKIP), + DS3ItemData("Blade of the Darkmoon", 0x20002710, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Watchdogs of Farron", 0x20002724, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Aldrich Faithful", 0x2000272E, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Warrior of Sunlight", 0x20002738, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Mound-makers", 0x20002742, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Way of Blue", 0x2000274C, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Blue Sentinels", 0x20002756, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Rosaria's Fingers", 0x20002760, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Spears of the Church", 0x2000276A, DS3ItemCategory.UNIQUE, skip = True), # Rings DS3ItemData("Life Ring", 0x20004E20, DS3ItemCategory.RING), @@ -938,7 +944,7 @@ def flatten(l): DS3ItemData("Sun Princess Ring", 0x20004FBA, DS3ItemCategory.RING), DS3ItemData("Silvercat Ring", 0x20004FC4, DS3ItemCategory.RING), DS3ItemData("Skull Ring", 0x20004FCE, DS3ItemCategory.RING), - DS3ItemData("Untrue White Ring", 0x20004FD8, DS3ItemCategory.SKIP), + DS3ItemData("Untrue White Ring", 0x20004FD8, DS3ItemCategory.RING, skip = True), DS3ItemData("Carthus Milkring", 0x20004FE2, DS3ItemCategory.RING), DS3ItemData("Knight's Ring", 0x20004FEC, DS3ItemCategory.RING), DS3ItemData("Hunter's Ring", 0x20004FF6, DS3ItemCategory.RING), @@ -973,12 +979,12 @@ def flatten(l): DS3ItemData("Dragonscale Ring", 0x2000515E, DS3ItemCategory.RING), # Items - DS3ItemData("White Sign Soapstone", 0x40000064, DS3ItemCategory.SKIP), - DS3ItemData("Red Sign Soapstone", 0x40000066, DS3ItemCategory.SKIP), - DS3ItemData("Red Eye Orb", 0x40000066, DS3ItemCategory.SKIP), - DS3ItemData("Roster of Knights", 0x4000006C, DS3ItemCategory.SKIP), - DS3ItemData("Cracked Red Eye Orb", 0x4000006F, DS3ItemCategory.SKIP).counts([5]), - DS3ItemData("Black Eye Orb", 0x40000073, DS3ItemCategory.KEY, + DS3ItemData("White Sign Soapstone", 0x40000064, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Red Sign Soapstone", 0x40000066, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Red Eye Orb", 0x40000066, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Roster of Knights", 0x4000006C, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Cracked Red Eye Orb", 0x4000006F, DS3ItemCategory.MISC, skip = True).counts([5]), + DS3ItemData("Black Eye Orb", 0x40000073, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), DS3ItemData("Divine Blessing", 0x400000F0, DS3ItemCategory.MISC), DS3ItemData("Hidden Blessing", 0x400000F1, DS3ItemCategory.MISC), @@ -987,7 +993,7 @@ def flatten(l): DS3ItemData("Bloodred Moss Clump", 0x4000010E, DS3ItemCategory.MISC, filler = True).counts([3]), DS3ItemData("Purple Moss Clump", 0x4000010F, DS3ItemCategory.MISC, filler = True).counts([2, 3, 4]), DS3ItemData("Blooming Purple Moss Clump", 0x40000110, DS3ItemCategory.MISC).counts([3]), - DS3ItemData("Purging Stone", 0x40000112, DS3ItemCategory.SKIP).counts([2, 3]), + DS3ItemData("Purging Stone", 0x40000112, DS3ItemCategory.MISC, skip = True).counts([2, 3]), DS3ItemData("Rime-blue Moss Clump", 0x40000114, DS3ItemCategory.MISC, filler = True).counts([2, 4]), DS3ItemData("Repair Powder", 0x40000118, DS3ItemCategory.MISC, filler = True).counts([2, 3, 4]), DS3ItemData("Kukri", 0x40000122, DS3ItemCategory.MISC).counts([8, 9]), @@ -1016,52 +1022,52 @@ def flatten(l): DS3ItemData("Gold Pine Bundle", 0x40000155, DS3ItemCategory.MISC).counts([6]), DS3ItemData("Rotten Pine Resin", 0x40000157, DS3ItemCategory.MISC).counts([2, 4]), DS3ItemData("Homeward Bone", 0x4000015E, DS3ItemCategory.MISC, filler = True).counts([2, 3, 6]), - DS3ItemData("Coiled Sword Fragment", 0x4000015F, DS3ItemCategory.MISC, + DS3ItemData("Coiled Sword Fragment", 0x4000015F, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), # Crow trade - DS3ItemData("Wolf's Blood Swordgrass", 0x4000016E, DS3ItemCategory.SKIP), - DS3ItemData("Human Dregs", 0x4000016F, DS3ItemCategory.SKIP), - DS3ItemData("Forked Pale Tongue", 0x40000170, DS3ItemCategory.SKIP), - DS3ItemData("Proof of a Concord Well Kept", 0x40000171, DS3ItemCategory.SKIP), - DS3ItemData("Prism Stone", 0x40000172, DS3ItemCategory.SKIP).counts([4, 6, 10]), + DS3ItemData("Wolf's Blood Swordgrass", 0x4000016E, DS3ItemCategory.MISC, skip = True), + DS3ItemData("Human Dregs", 0x4000016F, DS3ItemCategory.MISC, skip = True), + DS3ItemData("Forked Pale Tongue", 0x40000170, DS3ItemCategory.MISC, skip = True), + DS3ItemData("Proof of a Concord Well Kept", 0x40000171, DS3ItemCategory.MISC, skip = True), + DS3ItemData("Prism Stone", 0x40000172, DS3ItemCategory.MISC, skip = True).counts([4, 6, 10]), DS3ItemData("Binoculars", 0x40000173, DS3ItemCategory.MISC), - DS3ItemData("Proof of a Concord Kept", 0x40000174, DS3ItemCategory.SKIP), + DS3ItemData("Proof of a Concord Kept", 0x40000174, DS3ItemCategory.MISC, skip = True), # One is needed for Leonhard's quest, others are useful for restatting. DS3ItemData("Pale Tongue", 0x40000175, DS3ItemCategory.MISC, classification = ItemClassification.progression), DS3ItemData("Vertebra Shackle", 0x40000176, DS3ItemCategory.MISC, classification = ItemClassification.progression, force_unique = True), # Crow trade - DS3ItemData("Sunlight Medal", 0x40000177, DS3ItemCategory.SKIP), - DS3ItemData("Dragon Head Stone", 0x40000179, DS3ItemCategory.MISC), - DS3ItemData("Dragon Torso Stone", 0x4000017A, DS3ItemCategory.MISC), - DS3ItemData("Rubbish", 0x4000017C, DS3ItemCategory.SKIP), - DS3ItemData("Dried Finger", 0x40000181, DS3ItemCategory.SKIP), - DS3ItemData("Twinkling Dragon Head Stone", 0x40000183, DS3ItemCategory.MISC), - DS3ItemData("Twinkling Dragon Torso Stone", 0x40000184, DS3ItemCategory.MISC, - classification = ItemClassification.progression), - DS3ItemData("Fire Keeper Soul", 0x40000186, DS3ItemCategory.MISC), + DS3ItemData("Sunlight Medal", 0x40000177, DS3ItemCategory.MISC, skip = True), + DS3ItemData("Dragon Head Stone", 0x40000179, DS3ItemCategory.UNIQUE), + DS3ItemData("Dragon Torso Stone", 0x4000017A, DS3ItemCategory.UNIQUE), + DS3ItemData("Rubbish", 0x4000017C, DS3ItemCategory.MISC, skip = True), + DS3ItemData("Dried Finger", 0x40000181, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Twinkling Dragon Head Stone", 0x40000183, DS3ItemCategory.UNIQUE), + DS3ItemData("Twinkling Dragon Torso Stone", 0x40000184, DS3ItemCategory.UNIQUE, + classification = ItemClassification.progression), + DS3ItemData("Fire Keeper Soul", 0x40000186, DS3ItemCategory.UNIQUE), # Allow souls up to 2k in value to be used as filler - DS3ItemData("Fading Soul", 0x40000190, DS3ItemCategory.MISC, souls = 50), - DS3ItemData("Soul of a Deserted Corpse", 0x40000191, DS3ItemCategory.MISC, souls = 200), - DS3ItemData("Large Soul of a Deserted Corpse", 0x40000192, DS3ItemCategory.MISC, souls = 400), - DS3ItemData("Soul of an Unknown Traveler", 0x40000193, DS3ItemCategory.MISC, souls = 800), - DS3ItemData("Large Soul of an Unknown Traveler", 0x40000194, DS3ItemCategory.MISC, souls = 1000), - DS3ItemData("Soul of a Nameless Soldier", 0x40000195, DS3ItemCategory.MISC, souls = 2000), - DS3ItemData("Large Soul of a Nameless Soldier", 0x40000196, DS3ItemCategory.MISC, souls = 3000), - DS3ItemData("Soul of a Weary Warrior", 0x40000197, DS3ItemCategory.MISC, souls = 5000), - DS3ItemData("Large Soul of a Weary Warrior", 0x40000198, DS3ItemCategory.MISC, souls = 8000), - DS3ItemData("Soul of a Crestfallen Knight", 0x40000199, DS3ItemCategory.MISC, souls = 10000), - DS3ItemData("Large Soul of a Crestfallen Knight", 0x4000019A, DS3ItemCategory.MISC, souls = 20000), - DS3ItemData("Soul of a Proud Paladin", 0x4000019B, DS3ItemCategory.MISC, souls = 500), - DS3ItemData("Large Soul of a Proud Paladin", 0x4000019C, DS3ItemCategory.MISC, souls = 1000), - DS3ItemData("Soul of an Intrepid Hero", 0x4000019D, DS3ItemCategory.MISC, souls = 2000), - DS3ItemData("Large Soul of an Intrepid Hero", 0x4000019E, DS3ItemCategory.MISC, souls = 2500), - DS3ItemData("Soul of a Seasoned Warrior", 0x4000019F, DS3ItemCategory.MISC, souls = 5000), - DS3ItemData("Large Soul of a Seasoned Warrior", 0x400001A0, DS3ItemCategory.MISC, souls = 7500), - DS3ItemData("Soul of an Old Hand", 0x400001A1, DS3ItemCategory.MISC, souls = 12500), - DS3ItemData("Soul of a Venerable Old Hand", 0x400001A2, DS3ItemCategory.MISC, souls = 20000), - DS3ItemData("Soul of a Champion", 0x400001A3, DS3ItemCategory.MISC, souls = 25000), - DS3ItemData("Soul of a Great Champion", 0x400001A4, DS3ItemCategory.MISC, souls = 50000), - DS3ItemData("Seed of a Giant Tree", 0x400001B8, DS3ItemCategory.SKIP, + DS3ItemData("Fading Soul", 0x40000190, DS3ItemCategory.SOUL, souls = 50), + DS3ItemData("Soul of a Deserted Corpse", 0x40000191, DS3ItemCategory.SOUL, souls = 200), + DS3ItemData("Large Soul of a Deserted Corpse", 0x40000192, DS3ItemCategory.SOUL, souls = 400), + DS3ItemData("Soul of an Unknown Traveler", 0x40000193, DS3ItemCategory.SOUL, souls = 800), + DS3ItemData("Large Soul of an Unknown Traveler", 0x40000194, DS3ItemCategory.SOUL, souls = 1000), + DS3ItemData("Soul of a Nameless Soldier", 0x40000195, DS3ItemCategory.SOUL, souls = 2000), + DS3ItemData("Large Soul of a Nameless Soldier", 0x40000196, DS3ItemCategory.SOUL, souls = 3000), + DS3ItemData("Soul of a Weary Warrior", 0x40000197, DS3ItemCategory.SOUL, souls = 5000), + DS3ItemData("Large Soul of a Weary Warrior", 0x40000198, DS3ItemCategory.SOUL, souls = 8000), + DS3ItemData("Soul of a Crestfallen Knight", 0x40000199, DS3ItemCategory.SOUL, souls = 10000), + DS3ItemData("Large Soul of a Crestfallen Knight", 0x4000019A, DS3ItemCategory.SOUL, souls = 20000), + DS3ItemData("Soul of a Proud Paladin", 0x4000019B, DS3ItemCategory.SOUL, souls = 500), + DS3ItemData("Large Soul of a Proud Paladin", 0x4000019C, DS3ItemCategory.SOUL, souls = 1000), + DS3ItemData("Soul of an Intrepid Hero", 0x4000019D, DS3ItemCategory.SOUL, souls = 2000), + DS3ItemData("Large Soul of an Intrepid Hero", 0x4000019E, DS3ItemCategory.SOUL, souls = 2500), + DS3ItemData("Soul of a Seasoned Warrior", 0x4000019F, DS3ItemCategory.SOUL, souls = 5000), + DS3ItemData("Large Soul of a Seasoned Warrior", 0x400001A0, DS3ItemCategory.SOUL, souls = 7500), + DS3ItemData("Soul of an Old Hand", 0x400001A1, DS3ItemCategory.SOUL, souls = 12500), + DS3ItemData("Soul of a Venerable Old Hand", 0x400001A2, DS3ItemCategory.SOUL, souls = 20000), + DS3ItemData("Soul of a Champion", 0x400001A3, DS3ItemCategory.SOUL, souls = 25000), + DS3ItemData("Soul of a Great Champion", 0x400001A4, DS3ItemCategory.SOUL, souls = 50000), + DS3ItemData("Seed of a Giant Tree", 0x400001B8, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression, inject = True), # Crow trade DS3ItemData("Mossfruit", 0x400001C4, DS3ItemCategory.MISC, filler = True).counts([2]), DS3ItemData("Young White Branch", 0x400001C6, DS3ItemCategory.MISC), @@ -1073,14 +1079,14 @@ def flatten(l): DS3ItemData("Red Bug Pellet", 0x400001CB, DS3ItemCategory.MISC, filler = True).counts([2, 3]), DS3ItemData("Yellow Bug Pellet", 0x400001CC, DS3ItemCategory.MISC, filler = True).counts([2, 3]), DS3ItemData("Black Bug Pellet", 0x400001CD, DS3ItemCategory.MISC, filler = True).counts([2, 3]), - DS3ItemData("Young White Branch", 0x400001CF, DS3ItemCategory.SKIP), - DS3ItemData("Dark Sigil", 0x400001EA, DS3ItemCategory.SKIP), + DS3ItemData("Young White Branch", 0x400001CF, DS3ItemCategory.MISC, skip = True), + DS3ItemData("Dark Sigil", 0x400001EA, DS3ItemCategory.MISC, skip = True), DS3ItemData("Ember", 0x400001F4, DS3ItemCategory.MISC, filler = True).counts([2]), - DS3ItemData("Hello Carving", 0x40000208, DS3ItemCategory.SKIP), - DS3ItemData("Thank you Carving", 0x40000209, DS3ItemCategory.SKIP), - DS3ItemData("Very good! Carving", 0x4000020A, DS3ItemCategory.SKIP), - DS3ItemData("I'm sorry Carving", 0x4000020B, DS3ItemCategory.SKIP), - DS3ItemData("Help me! Carving", 0x4000020C, DS3ItemCategory.SKIP), + DS3ItemData("Hello Carving", 0x40000208, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Thank you Carving", 0x40000209, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Very good! Carving", 0x4000020A, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("I'm sorry Carving", 0x4000020B, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Help me! Carving", 0x4000020C, DS3ItemCategory.UNIQUE, skip = True), DS3ItemData("Soul of Champion Gundyr", 0x400002C8, DS3ItemCategory.BOSS, souls = 20000, classification = ItemClassification.progression), DS3ItemData("Soul of the Dancer", 0x400002CA, DS3ItemCategory.BOSS, souls = 10000, @@ -1107,7 +1113,7 @@ def flatten(l): classification = ItemClassification.progression), DS3ItemData("Soul of the Rotted Greatwood", 0x400002D7, DS3ItemCategory.BOSS, souls = 3000, classification = ItemClassification.progression), - DS3ItemData("Soul of Rosaria", 0x400002D8, DS3ItemCategory.MISC, souls = 5000, + DS3ItemData("Soul of Rosaria", 0x400002D8, DS3ItemCategory.BOSS, souls = 5000, classification = ItemClassification.progression), DS3ItemData("Soul of the Deacons of the Deep", 0x400002D9, DS3ItemCategory.BOSS, souls = 20000, classification = ItemClassification.progression), @@ -1115,142 +1121,143 @@ def flatten(l): classification = ItemClassification.progression), DS3ItemData("Soul of Yhorm the Giant", 0x400002DC, DS3ItemCategory.BOSS, souls = 20000, classification = ItemClassification.progression), - DS3ItemData("Soul of the Lords", 0x400002DD, DS3ItemCategory.MISC, souls = 20000, + DS3ItemData("Soul of the Lords", 0x400002DD, DS3ItemCategory.BOSS, souls = 20000, classification = ItemClassification.progression), DS3ItemData("Soul of a Demon", 0x400002E3, DS3ItemCategory.BOSS, souls = 20000, classification = ItemClassification.progression), DS3ItemData("Soul of a Stray Demon", 0x400002E7, DS3ItemCategory.BOSS, souls = 20000, classification = ItemClassification.progression), - DS3ItemData("Titanite Shard", 0x400003E8, DS3ItemCategory.MISC).counts([2]), - DS3ItemData("Large Titanite Shard", 0x400003E9, DS3ItemCategory.MISC).counts([2, 3]), - DS3ItemData("Titanite Chunk", 0x400003EA, DS3ItemCategory.MISC).counts([2, 6]), - DS3ItemData("Titanite Slab", 0x400003EB, DS3ItemCategory.MISC), - DS3ItemData("Titanite Scale", 0x400003FC, DS3ItemCategory.MISC).counts([2, 3]), - DS3ItemData("Twinkling Titanite", 0x40000406, DS3ItemCategory.MISC).counts([2, 3]), - DS3ItemData("Heavy Gem", 0x4000044C, DS3ItemCategory.MISC), - DS3ItemData("Sharp Gem", 0x40000456, DS3ItemCategory.MISC), - DS3ItemData("Refined Gem", 0x40000460, DS3ItemCategory.MISC), - DS3ItemData("Crystal Gem", 0x4000046A, DS3ItemCategory.MISC), - DS3ItemData("Simple Gem", 0x40000474, DS3ItemCategory.MISC), - DS3ItemData("Fire Gem", 0x4000047E, DS3ItemCategory.MISC), - DS3ItemData("Chaos Gem", 0x40000488, DS3ItemCategory.MISC), - DS3ItemData("Lightning Gem", 0x40000492, DS3ItemCategory.MISC), - DS3ItemData("Deep Gem", 0x4000049C, DS3ItemCategory.MISC), - DS3ItemData("Dark Gem", 0x400004A6, DS3ItemCategory.MISC), - DS3ItemData("Poison Gem", 0x400004B0, DS3ItemCategory.MISC), - DS3ItemData("Blood Gem", 0x400004BA, DS3ItemCategory.MISC), - DS3ItemData("Raw Gem", 0x400004C4, DS3ItemCategory.MISC), - DS3ItemData("Blessed Gem", 0x400004CE, DS3ItemCategory.MISC), - DS3ItemData("Hollow Gem", 0x400004D8, DS3ItemCategory.MISC), - DS3ItemData("Shriving Stone", 0x400004E2, DS3ItemCategory.MISC), - DS3ItemData("Lift Chamber Key", 0x400007D1, DS3ItemCategory.KEY, - classification = ItemClassification.progression), - DS3ItemData("Small Doll", 0x400007D5, DS3ItemCategory.KEY, - classification = ItemClassification.progression), - DS3ItemData("Jailbreaker's Key", 0x400007D7, DS3ItemCategory.KEY, - classification = ItemClassification.progression), - DS3ItemData("Jailer's Key Ring", 0x400007D8, DS3ItemCategory.KEY, - classification = ItemClassification.progression), - DS3ItemData("Grave Key", 0x400007D9, DS3ItemCategory.KEY), - DS3ItemData("Cell Key", 0x400007DA, DS3ItemCategory.KEY, - classification = ItemClassification.progression), - DS3ItemData("Dungeon Ground Floor Key", 0x400007DB, DS3ItemCategory.KEY), - DS3ItemData("Old Cell Key", 0x400007DC, DS3ItemCategory.KEY, - classification = ItemClassification.progression), - DS3ItemData("Grand Archives Key", 0x400007DE, DS3ItemCategory.KEY, - classification = ItemClassification.progression), - DS3ItemData("Tower Key", 0x400007DF, DS3ItemCategory.KEY, - classification = ItemClassification.progression), - DS3ItemData("Small Lothric Banner", 0x40000836, DS3ItemCategory.KEY, - classification = ItemClassification.progression), - DS3ItemData("Farron Coal", 0x40000837, DS3ItemCategory.MISC, + DS3ItemData("Titanite Shard", 0x400003E8, DS3ItemCategory.UPGRADE).counts([2]), + DS3ItemData("Large Titanite Shard", 0x400003E9, DS3ItemCategory.UPGRADE).counts([2, 3]), + DS3ItemData("Titanite Chunk", 0x400003EA, DS3ItemCategory.UPGRADE).counts([2, 6]), + DS3ItemData("Titanite Slab", 0x400003EB, DS3ItemCategory.UPGRADE, + classification = ItemClassification.useful), + DS3ItemData("Titanite Scale", 0x400003FC, DS3ItemCategory.UPGRADE).counts([2, 3]), + DS3ItemData("Twinkling Titanite", 0x40000406, DS3ItemCategory.UPGRADE).counts([2, 3]), + DS3ItemData("Heavy Gem", 0x4000044C, DS3ItemCategory.UPGRADE), + DS3ItemData("Sharp Gem", 0x40000456, DS3ItemCategory.UPGRADE), + DS3ItemData("Refined Gem", 0x40000460, DS3ItemCategory.UPGRADE), + DS3ItemData("Crystal Gem", 0x4000046A, DS3ItemCategory.UPGRADE), + DS3ItemData("Simple Gem", 0x40000474, DS3ItemCategory.UPGRADE), + DS3ItemData("Fire Gem", 0x4000047E, DS3ItemCategory.UPGRADE), + DS3ItemData("Chaos Gem", 0x40000488, DS3ItemCategory.UPGRADE), + DS3ItemData("Lightning Gem", 0x40000492, DS3ItemCategory.UPGRADE), + DS3ItemData("Deep Gem", 0x4000049C, DS3ItemCategory.UPGRADE), + DS3ItemData("Dark Gem", 0x400004A6, DS3ItemCategory.UPGRADE), + DS3ItemData("Poison Gem", 0x400004B0, DS3ItemCategory.UPGRADE), + DS3ItemData("Blood Gem", 0x400004BA, DS3ItemCategory.UPGRADE), + DS3ItemData("Raw Gem", 0x400004C4, DS3ItemCategory.UPGRADE), + DS3ItemData("Blessed Gem", 0x400004CE, DS3ItemCategory.UPGRADE), + DS3ItemData("Hollow Gem", 0x400004D8, DS3ItemCategory.UPGRADE), + DS3ItemData("Shriving Stone", 0x400004E2, DS3ItemCategory.UPGRADE), + DS3ItemData("Lift Chamber Key", 0x400007D1, DS3ItemCategory.UNIQUE, + classification = ItemClassification.progression), + DS3ItemData("Small Doll", 0x400007D5, DS3ItemCategory.UNIQUE, + classification = ItemClassification.progression), + DS3ItemData("Jailbreaker's Key", 0x400007D7, DS3ItemCategory.UNIQUE, + classification = ItemClassification.progression), + DS3ItemData("Jailer's Key Ring", 0x400007D8, DS3ItemCategory.UNIQUE, + classification = ItemClassification.progression), + DS3ItemData("Grave Key", 0x400007D9, DS3ItemCategory.UNIQUE), + DS3ItemData("Cell Key", 0x400007DA, DS3ItemCategory.UNIQUE, + classification = ItemClassification.progression), + DS3ItemData("Dungeon Ground Floor Key", 0x400007DB, DS3ItemCategory.UNIQUE), + DS3ItemData("Old Cell Key", 0x400007DC, DS3ItemCategory.UNIQUE, + classification = ItemClassification.progression), + DS3ItemData("Grand Archives Key", 0x400007DE, DS3ItemCategory.UNIQUE, + classification = ItemClassification.progression), + DS3ItemData("Tower Key", 0x400007DF, DS3ItemCategory.UNIQUE, + classification = ItemClassification.progression), + DS3ItemData("Small Lothric Banner", 0x40000836, DS3ItemCategory.UNIQUE, + classification = ItemClassification.progression), + DS3ItemData("Farron Coal", 0x40000837, DS3ItemCategory.UNIQUE, classification = ItemClassification.useful), - DS3ItemData("Sage's Coal", 0x40000838, DS3ItemCategory.MISC, + DS3ItemData("Sage's Coal", 0x40000838, DS3ItemCategory.UNIQUE, classification = ItemClassification.useful), - DS3ItemData("Giant's Coal", 0x40000839, DS3ItemCategory.MISC, + DS3ItemData("Giant's Coal", 0x40000839, DS3ItemCategory.UNIQUE, classification = ItemClassification.useful), - DS3ItemData("Profaned Coal", 0x4000083A, DS3ItemCategory.MISC, + DS3ItemData("Profaned Coal", 0x4000083A, DS3ItemCategory.UNIQUE, classification = ItemClassification.useful), - DS3ItemData("Mortician's Ashes", 0x4000083B, DS3ItemCategory.MISC, + DS3ItemData("Mortician's Ashes", 0x4000083B, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Dreamchaser's Ashes", 0x4000083C, DS3ItemCategory.MISC, + DS3ItemData("Dreamchaser's Ashes", 0x4000083C, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Paladin's Ashes", 0x4000083D, DS3ItemCategory.MISC, + DS3ItemData("Paladin's Ashes", 0x4000083D, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Grave Warden's Ashes", 0x4000083E, DS3ItemCategory.MISC, + DS3ItemData("Grave Warden's Ashes", 0x4000083E, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Greirat's Ashes", 0x4000083F, DS3ItemCategory.MISC), - DS3ItemData("Orbeck's Ashes", 0x40000840, DS3ItemCategory.MISC), - DS3ItemData("Cornyx's Ashes", 0x40000841, DS3ItemCategory.MISC), - DS3ItemData("Karla's Ashes", 0x40000842, DS3ItemCategory.MISC), - DS3ItemData("Irina's Ashes", 0x40000843, DS3ItemCategory.MISC), - DS3ItemData("Yuria's Ashes", 0x40000844, DS3ItemCategory.MISC), - DS3ItemData("Basin of Vows", 0x40000845, DS3ItemCategory.KEY, + DS3ItemData("Greirat's Ashes", 0x4000083F, DS3ItemCategory.UNIQUE), + DS3ItemData("Orbeck's Ashes", 0x40000840, DS3ItemCategory.UNIQUE), + DS3ItemData("Cornyx's Ashes", 0x40000841, DS3ItemCategory.UNIQUE), + DS3ItemData("Karla's Ashes", 0x40000842, DS3ItemCategory.UNIQUE), + DS3ItemData("Irina's Ashes", 0x40000843, DS3ItemCategory.UNIQUE), + DS3ItemData("Yuria's Ashes", 0x40000844, DS3ItemCategory.UNIQUE), + DS3ItemData("Basin of Vows", 0x40000845, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Loretta's Bone", 0x40000846, DS3ItemCategory.KEY, + DS3ItemData("Loretta's Bone", 0x40000846, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Braille Divine Tome of Carim", 0x40000847, DS3ItemCategory.MISC, + DS3ItemData("Braille Divine Tome of Carim", 0x40000847, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Braille Divine Tome of Lothric", 0x40000848, DS3ItemCategory.MISC, + DS3ItemData("Braille Divine Tome of Lothric", 0x40000848, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Cinders of a Lord - Abyss Watcher", 0x4000084B, DS3ItemCategory.KEY, + DS3ItemData("Cinders of a Lord - Abyss Watcher", 0x4000084B, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Cinders of a Lord - Aldrich", 0x4000084C, DS3ItemCategory.KEY, + DS3ItemData("Cinders of a Lord - Aldrich", 0x4000084C, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Cinders of a Lord - Yhorm the Giant", 0x4000084D, DS3ItemCategory.KEY, + DS3ItemData("Cinders of a Lord - Yhorm the Giant", 0x4000084D, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Cinders of a Lord - Lothric Prince", 0x4000084E, DS3ItemCategory.KEY, + DS3ItemData("Cinders of a Lord - Lothric Prince", 0x4000084E, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Great Swamp Pyromancy Tome", 0x4000084F, DS3ItemCategory.MISC, + DS3ItemData("Great Swamp Pyromancy Tome", 0x4000084F, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Carthus Pyromancy Tome", 0x40000850, DS3ItemCategory.MISC, + DS3ItemData("Carthus Pyromancy Tome", 0x40000850, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Izalith Pyromancy Tome", 0x40000851, DS3ItemCategory.MISC, + DS3ItemData("Izalith Pyromancy Tome", 0x40000851, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Quelana Pyromancy Tome", 0x40000852, DS3ItemCategory.MISC, + DS3ItemData("Quelana Pyromancy Tome", 0x40000852, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Grave Warden Pyromancy Tome", 0x40000853, DS3ItemCategory.MISC, + DS3ItemData("Grave Warden Pyromancy Tome", 0x40000853, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Sage's Scroll", 0x40000854, DS3ItemCategory.MISC, + DS3ItemData("Sage's Scroll", 0x40000854, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Logan's Scroll", 0x40000855, DS3ItemCategory.MISC, + DS3ItemData("Logan's Scroll", 0x40000855, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Crystal Scroll", 0x40000856, DS3ItemCategory.MISC, + DS3ItemData("Crystal Scroll", 0x40000856, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Transposing Kiln", 0x40000857, DS3ItemCategory.MISC, + DS3ItemData("Transposing Kiln", 0x40000857, DS3ItemCategory.UNIQUE, classification = ItemClassification.useful), - DS3ItemData("Coiled Sword", 0x40000859, DS3ItemCategory.KEY, + DS3ItemData("Coiled Sword", 0x40000859, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Eyes of a Fire Keeper", 0x4000085A, DS3ItemCategory.KEY, + DS3ItemData("Eyes of a Fire Keeper", 0x4000085A, DS3ItemCategory.UNIQUE, classification = ItemClassification.useful), # Allow players to do any ending - DS3ItemData("Sword of Avowal", 0x4000085B, DS3ItemCategory.KEY, + DS3ItemData("Sword of Avowal", 0x4000085B, DS3ItemCategory.UNIQUE, classification = ItemClassification.useful), - DS3ItemData("Golden Scroll", 0x4000085C, DS3ItemCategory.MISC, + DS3ItemData("Golden Scroll", 0x4000085C, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Estus Shard", 0x4000085D, DS3ItemCategory.MISC, + DS3ItemData("Estus Shard", 0x4000085D, DS3ItemCategory.HEALING, classification = ItemClassification.useful), - DS3ItemData("Hawkwood's Swordgrass", 0x4000085E, DS3ItemCategory.SKIP), - DS3ItemData("Undead Bone Shard", 0x4000085F, DS3ItemCategory.MISC, + DS3ItemData("Hawkwood's Swordgrass", 0x4000085E, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Undead Bone Shard", 0x4000085F, DS3ItemCategory.HEALING, classification = ItemClassification.useful), - DS3ItemData("Deep Braille Divine Tome", 0x40000860, DS3ItemCategory.MISC, + DS3ItemData("Deep Braille Divine Tome", 0x40000860, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Londor Braille Divine Tome", 0x40000861, DS3ItemCategory.MISC, + DS3ItemData("Londor Braille Divine Tome", 0x40000861, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Excrement-covered Ashes", 0x40000862, DS3ItemCategory.MISC, + DS3ItemData("Excrement-covered Ashes", 0x40000862, DS3ItemCategory.UNIQUE, classification = ItemClassification.useful), - DS3ItemData("Prisoner Chief's Ashes", 0x40000863, DS3ItemCategory.MISC, + DS3ItemData("Prisoner Chief's Ashes", 0x40000863, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Xanthous Ashes", 0x40000864, DS3ItemCategory.MISC, + DS3ItemData("Xanthous Ashes", 0x40000864, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Hollow's Ashes", 0x40000865, DS3ItemCategory.MISC), - DS3ItemData("Patches' Ashes", 0x40000866, DS3ItemCategory.MISC), - DS3ItemData("Dragon Chaser's Ashes", 0x40000867, DS3ItemCategory.MISC, + DS3ItemData("Hollow's Ashes", 0x40000865, DS3ItemCategory.UNIQUE), + DS3ItemData("Patches' Ashes", 0x40000866, DS3ItemCategory.UNIQUE), + DS3ItemData("Dragon Chaser's Ashes", 0x40000867, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Easterner's Ashes", 0x40000868, DS3ItemCategory.MISC, + DS3ItemData("Easterner's Ashes", 0x40000868, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), # Fake item for controlling access to Archdragon Peak - DS3ItemData("Path of the Dragon", 0x40002346, DS3ItemCategory.KEY, + DS3ItemData("Path of the Dragon", 0x40002346, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), # Spells @@ -1369,7 +1376,7 @@ def flatten(l): _dlc_items = flatten([ # Ammunition - DS3ItemData("Millwood Greatarrow", 0x000623E0, DS3ItemCategory.SKIP).counts([5]), + DS3ItemData("Millwood Greatarrow", 0x000623E0, DS3ItemCategory.MISC).counts([5]), # Weapons DS3ItemData("Aquamarine Dagger", 0x00116520, DS3ItemCategory.WEAPON_UPGRADE_5), @@ -1471,7 +1478,7 @@ def flatten(l): DS3ItemData("Blindfold Mask", 0x15095E20, DS3ItemCategory.ARMOR), # Covenants - DS3ItemData("Spear of the Church", 0x2000276A, DS3ItemCategory.SKIP), + DS3ItemData("Spear of the Church", 0x2000276A, DS3ItemCategory.UNIQUE, skip = True), # Rings DS3ItemData("Chloranthy Ring+3", 0x20004E2D, DS3ItemCategory.RING, @@ -1491,9 +1498,9 @@ def flatten(l): # Items DS3ItemData("Church Guardian Shiv", 0x4000013B, DS3ItemCategory.MISC), - DS3ItemData("Filianore's Spear Ornament", 0x4000017B, DS3ItemCategory.SKIP), - DS3ItemData("Ritual Spear Fragment", 0x4000028A, DS3ItemCategory.SKIP), - DS3ItemData("Divine Spear Fragment", 0x4000028B, DS3ItemCategory.SKIP), + DS3ItemData("Filianore's Spear Ornament", 0x4000017B, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Ritual Spear Fragment", 0x4000028A, DS3ItemCategory.UNIQUE, skip = True), + DS3ItemData("Divine Spear Fragment", 0x4000028B, DS3ItemCategory.UNIQUE, skip = True), DS3ItemData("Soul of Sister Friede", 0x400002E8, DS3ItemCategory.BOSS, souls = 20000, classification = ItemClassification.progression), DS3ItemData("Soul of Slave Knight Gael", 0x400002E9, DS3ItemCategory.BOSS, souls = 20000, @@ -1502,15 +1509,15 @@ def flatten(l): classification = ItemClassification.progression), DS3ItemData("Soul of Darkeater Midir", 0x400002EB, DS3ItemCategory.BOSS, souls = 20000, classification = ItemClassification.progression), - DS3ItemData("Champion's Bones", 0x40000869, DS3ItemCategory.SKIP), + DS3ItemData("Champion's Bones", 0x40000869, DS3ItemCategory.UNIQUE, skip = True), DS3ItemData("Captain's Ashes", 0x4000086A, DS3ItemCategory.MISC, classification = ItemClassification.progression), - DS3ItemData("Contraption Key", 0x4000086B, DS3ItemCategory.KEY, + DS3ItemData("Contraption Key", 0x4000086B, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Small Envoy Banner", 0x4000086C, DS3ItemCategory.KEY, + DS3ItemData("Small Envoy Banner", 0x4000086C, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - DS3ItemData("Old Woman's Ashes", 0x4000086D, DS3ItemCategory.SKIP), - DS3ItemData("Blood of the Dark Soul", 0x4000086E, DS3ItemCategory.SKIP), + DS3ItemData("Old Woman's Ashes", 0x4000086D, DS3ItemCategory.UNIQUE), + DS3ItemData("Blood of the Dark Soul", 0x4000086E, DS3ItemCategory.UNIQUE, skip = True), # Spells DS3ItemData("Frozen Weapon", 0x401408E8, DS3ItemCategory.SPELL), @@ -1532,80 +1539,80 @@ def flatten(l): # in-game and can't be picked up without modifications _cut_content_items = [ # Weapons - DS3ItemData("Blood-stained Short Sword", 0x00100590, DS3ItemCategory.SKIP), - DS3ItemData("Missionary's Axe", 0x006C2F50, DS3ItemCategory.SKIP), - DS3ItemData("Dragon King Greataxe", 0x006D40C0, DS3ItemCategory.SKIP), - DS3ItemData("Four Knights Hammer", 0x007D4650, DS3ItemCategory.SKIP), - DS3ItemData("Hammer of the Great Tree", 0x007D9470, DS3ItemCategory.SKIP), - DS3ItemData("Lothric's Scythe", 0x009A4430, DS3ItemCategory.SKIP), - DS3ItemData("Ancient Dragon Halberd", 0x009A6B40, DS3ItemCategory.SKIP), - DS3ItemData("Scythe of Want", 0x009A9250, DS3ItemCategory.SKIP), - DS3ItemData("Sacred Beast Catalyst", 0x00C8A730, DS3ItemCategory.SKIP), - DS3ItemData("Deep Pyromancy Flame", 0x00CC9ED0, DS3ItemCategory.SKIP), # Duplicate? - DS3ItemData("Flickering Pyromancy Flame", 0x00CD3B10, DS3ItemCategory.SKIP), - DS3ItemData("Strong Pyromancy Flame", 0x00CD6220, DS3ItemCategory.SKIP), - DS3ItemData("Deep Pyromancy Flame", 0x00CDFE60, DS3ItemCategory.SKIP), # Duplicate? - DS3ItemData("Pitch-Dark Pyromancy Flame", 0x00CE2570, DS3ItemCategory.SKIP), - DS3ItemData("Dancer's Short Bow", 0x00D77440, DS3ItemCategory.SKIP), - DS3ItemData("Shield Crossbow", 0x00D81080, DS3ItemCategory.SKIP), - DS3ItemData("Golden Dual Swords", 0x00F55C80, DS3ItemCategory.SKIP), - DS3ItemData("Channeler's Trident", 0x008C8890, DS3ItemCategory.SKIP), + DS3ItemData("Blood-stained Short Sword", 0x00100590, DS3ItemCategory.UNIQUE), + DS3ItemData("Missionary's Axe", 0x006C2F50, DS3ItemCategory.UNIQUE), + DS3ItemData("Dragon King Greataxe", 0x006D40C0, DS3ItemCategory.UNIQUE), + DS3ItemData("Four Knights Hammer", 0x007D4650, DS3ItemCategory.UNIQUE), + DS3ItemData("Hammer of the Great Tree", 0x007D9470, DS3ItemCategory.UNIQUE), + DS3ItemData("Lothric's Scythe", 0x009A4430, DS3ItemCategory.UNIQUE), + DS3ItemData("Ancient Dragon Halberd", 0x009A6B40, DS3ItemCategory.UNIQUE), + DS3ItemData("Scythe of Want", 0x009A9250, DS3ItemCategory.UNIQUE), + DS3ItemData("Sacred Beast Catalyst", 0x00C8A730, DS3ItemCategory.UNIQUE), + DS3ItemData("Deep Pyromancy Flame", 0x00CC9ED0, DS3ItemCategory.UNIQUE), # Duplicate? + DS3ItemData("Flickering Pyromancy Flame", 0x00CD3B10, DS3ItemCategory.UNIQUE), + DS3ItemData("Strong Pyromancy Flame", 0x00CD6220, DS3ItemCategory.UNIQUE), + DS3ItemData("Deep Pyromancy Flame", 0x00CDFE60, DS3ItemCategory.UNIQUE), # Duplicate? + DS3ItemData("Pitch-Dark Pyromancy Flame", 0x00CE2570, DS3ItemCategory.UNIQUE), + DS3ItemData("Dancer's Short Bow", 0x00D77440, DS3ItemCategory.UNIQUE), + DS3ItemData("Shield Crossbow", 0x00D81080, DS3ItemCategory.UNIQUE), + DS3ItemData("Golden Dual Swords", 0x00F55C80, DS3ItemCategory.UNIQUE), + DS3ItemData("Channeler's Trident", 0x008C8890, DS3ItemCategory.UNIQUE), # Shields - DS3ItemData("Cleric's Parma", 0x013524A0, DS3ItemCategory.SKIP), - DS3ItemData("Prince's Shield", 0x01421CF0, DS3ItemCategory.SKIP), + DS3ItemData("Cleric's Parma", 0x013524A0, DS3ItemCategory.UNIQUE), + DS3ItemData("Prince's Shield", 0x01421CF0, DS3ItemCategory.UNIQUE), # Armor - DS3ItemData("Dingy Maiden's Overcoat", 0x11DA9048, DS3ItemCategory.SKIP), - DS3ItemData("Grotto Hat", 0x11F78A40, DS3ItemCategory.SKIP), - DS3ItemData("Grotto Robe", 0x11F78E28, DS3ItemCategory.SKIP), - DS3ItemData("Grotto Wrap", 0x11F79210, DS3ItemCategory.SKIP), - DS3ItemData("Grotto Trousers", 0x11F795F8, DS3ItemCategory.SKIP), - DS3ItemData("Soldier's Gauntlets", 0x126261D0, DS3ItemCategory.SKIP), - DS3ItemData("Soldier's Hood", 0x1263E0A0, DS3ItemCategory.SKIP), - DS3ItemData("Elder's Robe", 0x129024A8, DS3ItemCategory.SKIP), - DS3ItemData("Saint's Veil", 0x12A70420, DS3ItemCategory.SKIP), - DS3ItemData("Saint's Dress", 0x12A70808, DS3ItemCategory.SKIP), - DS3ItemData("Footman's Hood", 0x12AEA540, DS3ItemCategory.SKIP), - DS3ItemData("Footman's Overcoat", 0x12AEA928, DS3ItemCategory.SKIP), - DS3ItemData("Footman's Bracelets", 0x12AEAD10, DS3ItemCategory.SKIP), - DS3ItemData("Footman's Trousers", 0x12AEB0F8, DS3ItemCategory.SKIP), - DS3ItemData("Scholar's Shed Skin", 0x12E40D20, DS3ItemCategory.SKIP), - DS3ItemData("Man Serpent's Mask", 0x138BE5E0, DS3ItemCategory.SKIP), - DS3ItemData("Man Serpent's Robe", 0x138BE9C8, DS3ItemCategory.SKIP), - DS3ItemData("Old Monarch's Crown", 0x13DFD240, DS3ItemCategory.SKIP), - DS3ItemData("Old Monarch's Robe", 0x13DFD628, DS3ItemCategory.SKIP), - DS3ItemData("Frigid Valley Mask", 0x13FE56C0, DS3ItemCategory.SKIP), - DS3ItemData("Dingy Hood", 0x140D9900, DS3ItemCategory.SKIP), - DS3ItemData("Hexer's Hood", 0x15A995C0, DS3ItemCategory.SKIP), - DS3ItemData("Hexer's Robes", 0x15A999A8, DS3ItemCategory.SKIP), - DS3ItemData("Hexer's Gloves", 0x15A99D90, DS3ItemCategory.SKIP), - DS3ItemData("Hexer's Boots", 0x15A9A178, DS3ItemCategory.SKIP), - DS3ItemData("Varangian Helm", 0x15C81A40, DS3ItemCategory.SKIP), - DS3ItemData("Varangian Armor", 0x15C81E28, DS3ItemCategory.SKIP), - DS3ItemData("Varangian Cuffs", 0x15C82210, DS3ItemCategory.SKIP), - DS3ItemData("Varangian Leggings", 0x15C825F8, DS3ItemCategory.SKIP), + DS3ItemData("Dingy Maiden's Overcoat", 0x11DA9048, DS3ItemCategory.UNIQUE), + DS3ItemData("Grotto Hat", 0x11F78A40, DS3ItemCategory.UNIQUE), + DS3ItemData("Grotto Robe", 0x11F78E28, DS3ItemCategory.UNIQUE), + DS3ItemData("Grotto Wrap", 0x11F79210, DS3ItemCategory.UNIQUE), + DS3ItemData("Grotto Trousers", 0x11F795F8, DS3ItemCategory.UNIQUE), + DS3ItemData("Soldier's Gauntlets", 0x126261D0, DS3ItemCategory.UNIQUE), + DS3ItemData("Soldier's Hood", 0x1263E0A0, DS3ItemCategory.UNIQUE), + DS3ItemData("Elder's Robe", 0x129024A8, DS3ItemCategory.UNIQUE), + DS3ItemData("Saint's Veil", 0x12A70420, DS3ItemCategory.UNIQUE), + DS3ItemData("Saint's Dress", 0x12A70808, DS3ItemCategory.UNIQUE), + DS3ItemData("Footman's Hood", 0x12AEA540, DS3ItemCategory.UNIQUE), + DS3ItemData("Footman's Overcoat", 0x12AEA928, DS3ItemCategory.UNIQUE), + DS3ItemData("Footman's Bracelets", 0x12AEAD10, DS3ItemCategory.UNIQUE), + DS3ItemData("Footman's Trousers", 0x12AEB0F8, DS3ItemCategory.UNIQUE), + DS3ItemData("Scholar's Shed Skin", 0x12E40D20, DS3ItemCategory.UNIQUE), + DS3ItemData("Man Serpent's Mask", 0x138BE5E0, DS3ItemCategory.UNIQUE), + DS3ItemData("Man Serpent's Robe", 0x138BE9C8, DS3ItemCategory.UNIQUE), + DS3ItemData("Old Monarch's Crown", 0x13DFD240, DS3ItemCategory.UNIQUE), + DS3ItemData("Old Monarch's Robe", 0x13DFD628, DS3ItemCategory.UNIQUE), + DS3ItemData("Frigid Valley Mask", 0x13FE56C0, DS3ItemCategory.UNIQUE), + DS3ItemData("Dingy Hood", 0x140D9900, DS3ItemCategory.UNIQUE), + DS3ItemData("Hexer's Hood", 0x15A995C0, DS3ItemCategory.UNIQUE), + DS3ItemData("Hexer's Robes", 0x15A999A8, DS3ItemCategory.UNIQUE), + DS3ItemData("Hexer's Gloves", 0x15A99D90, DS3ItemCategory.UNIQUE), + DS3ItemData("Hexer's Boots", 0x15A9A178, DS3ItemCategory.UNIQUE), + DS3ItemData("Varangian Helm", 0x15C81A40, DS3ItemCategory.UNIQUE), + DS3ItemData("Varangian Armor", 0x15C81E28, DS3ItemCategory.UNIQUE), + DS3ItemData("Varangian Cuffs", 0x15C82210, DS3ItemCategory.UNIQUE), + DS3ItemData("Varangian Leggings", 0x15C825F8, DS3ItemCategory.UNIQUE), # Rings - DS3ItemData("Rare Ring of Sacrifice", 0x20004EFC, DS3ItemCategory.SKIP), - DS3ItemData("Baneful Bird Ring", 0x20005032, DS3ItemCategory.SKIP), - DS3ItemData("Darkmoon Blade Covenant Ring", 0x20004F7E, DS3ItemCategory.SKIP), - DS3ItemData("Yorgh's Ring", 0x2000505A, DS3ItemCategory.SKIP), - DS3ItemData("Ring of Hiding", 0x200050D2, DS3ItemCategory.SKIP), - DS3ItemData("Ring of Sustained Toughness", 0x20005118, DS3ItemCategory.SKIP), - DS3ItemData("Ring of Sustained Energy", 0x20005122, DS3ItemCategory.SKIP), - DS3ItemData("Ring of Sustained Magic", 0x2000512C, DS3ItemCategory.SKIP), - DS3ItemData("Ring of Sustained Essence", 0x20005140, DS3ItemCategory.SKIP), - DS3ItemData("Ring of Sustained Might", 0x2000514A, DS3ItemCategory.SKIP), - DS3ItemData("Ring of Sustained Fortune", 0x20005154, DS3ItemCategory.SKIP), + DS3ItemData("Rare Ring of Sacrifice", 0x20004EFC, DS3ItemCategory.UNIQUE), + DS3ItemData("Baneful Bird Ring", 0x20005032, DS3ItemCategory.UNIQUE), + DS3ItemData("Darkmoon Blade Covenant Ring", 0x20004F7E, DS3ItemCategory.UNIQUE), + DS3ItemData("Yorgh's Ring", 0x2000505A, DS3ItemCategory.UNIQUE), + DS3ItemData("Ring of Hiding", 0x200050D2, DS3ItemCategory.UNIQUE), + DS3ItemData("Ring of Sustained Toughness", 0x20005118, DS3ItemCategory.UNIQUE), + DS3ItemData("Ring of Sustained Energy", 0x20005122, DS3ItemCategory.UNIQUE), + DS3ItemData("Ring of Sustained Magic", 0x2000512C, DS3ItemCategory.UNIQUE), + DS3ItemData("Ring of Sustained Essence", 0x20005140, DS3ItemCategory.UNIQUE), + DS3ItemData("Ring of Sustained Might", 0x2000514A, DS3ItemCategory.UNIQUE), + DS3ItemData("Ring of Sustained Fortune", 0x20005154, DS3ItemCategory.UNIQUE), # Items - DS3ItemData("Soul of a Wicked Spirit", 0x400002C9, DS3ItemCategory.SKIP), + DS3ItemData("Soul of a Wicked Spirit", 0x400002C9, DS3ItemCategory.UNIQUE), # Spells - DS3ItemData("Dark Orb", 0x4027AC40, DS3ItemCategory.SKIP), - DS3ItemData("Morbid Temptation", 0x40359AA8, DS3ItemCategory.SKIP), - DS3ItemData("Dorris Swarm", 0x40393870, DS3ItemCategory.SKIP), + DS3ItemData("Dark Orb", 0x4027AC40, DS3ItemCategory.UNIQUE), + DS3ItemData("Morbid Temptation", 0x40359AA8, DS3ItemCategory.UNIQUE), + DS3ItemData("Dorris Swarm", 0x40393870, DS3ItemCategory.UNIQUE), ] item_descriptions = { diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 7f019c4afa7e..e1ae61dd0226 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -2,7 +2,8 @@ from typing import ClassVar, Optional, Dict, List, Set from dataclasses import dataclass -from BaseClasses import Location, LocationProgressType, Region +from BaseClasses import ItemClassification, Location, LocationProgressType, Region +from .Items import DS3ItemCategory, item_dictionary # Regions in approximate order of reward, mostly measured by how high-quality the upgrade items are @@ -43,40 +44,6 @@ ] -class DS3LocationCategory(IntEnum): - WEAPON = 0 - SHIELD = 1 - ARMOR = 2 - RING = 3 - SPELL = 4 - KEY = 5 - MISC = 6 - HEALTH = 7 - - EVENT = 8 - """A special location that's achieved as soon as it's accessible. - - These are used to mark major region transitions that aren't otherwise gated by items so that - progression balancing and item smoothing are better able to track how deep in the game regions - are. - """ - - SOUL = 9 - """The original location of a soul item.""" - - UPGRADE = 10 - """The original location of any upgrade material. - - This includes various forms of titanite as well as infusion gems and Shriving Stones. - """ - - UNIQUE = 11 - """The original location of a unique item that's not a key, equipment, spell, or boss soul. - - This includes spellbooks, covenants, multiplayer items, coals, and various quest items. - """ - - @dataclass class DS3LocationData: __location_id: ClassVar[int] = 100000 @@ -84,17 +51,17 @@ class DS3LocationData: name: str """The name of this location according to Archipelago. - + This needs to be unique within this world.""" default_item_name: Optional[str] """The name of the item that appears by default in this location. - - This should only ever be None for DS3LocationCategory.EVENT locations. - """ - category: DS3LocationCategory - """The category into which this location falls.""" + If this is None, that indicates that this location is an "event" that's + automatically considered accessed as soon as it's available. Events are used + to indicate major game transitions that aren't otherwise gated by items so + that progression balancing and item smoothing is more accurate for DS3. + """ ap_code: int = None """Archipelago's internal ID for this location (also known as its "address").""" @@ -104,7 +71,7 @@ class DS3LocationData: This is used to sort locations when placing items like the base game. """ - + offline: Optional[str] = None """The key in the offline randomizer's Slots table that corresponds to this location. @@ -167,7 +134,7 @@ class DS3LocationData: drop: bool = False """Whether this is an item dropped by a (non-boss) enemy. - + This is automatically set to True if miniboss, mimic, lizard, or hostile_npc is True. """ @@ -200,12 +167,6 @@ class DS3LocationData: the run, and as such shouldn't have "similar to the base game" items placed in them. """ - key: bool = False - """Whether this location normally contains a key. - - This is a literal key, not just a key item or a progression item. - """ - hidden: bool = False """Whether this location is particularly tricky to find. @@ -213,8 +174,13 @@ class DS3LocationData: for an illusory wall or one random mob with a guaranteed drop. """ + @property + def is_event(self) -> bool: + """Whether this location represents an event rather than a specific item pickup.""" + return self.default_item_name is None + def __post_init__(self): - if self.category != DS3LocationCategory.EVENT: + if not self.is_event: self.ap_code = self.ap_code or DS3LocationData.__location_id DS3LocationData.__location_id += 1 if self.miniboss or self.mimic or self.lizard or self.hostile_npc: self.drop = True @@ -223,6 +189,9 @@ def location_groups(self) -> List[str]: """The names of location groups this location should appear in. This is computed from the properties assigned to this location.""" + # Events aren't part of any location groups. + if self.is_event: return + names = [] if self.prominent: names.append("Prominent") if self.progression: names.append("Progression") @@ -230,12 +199,30 @@ def location_groups(self) -> List[str]: if self.miniboss: names.append("Miniboss Rewards") if self.mimic: names.append("Mimic Rewards") if self.hostile_npc: names.append("Hostile NPC Rewards") + if self.npc: names.append("Friendly NPC Rewards") if self.lizard: names.append("Small Crystal Lizards") - if self.key: names.append("Keys") - if self.category == DS3LocationCategory.UPGRADE: names.append("Upgrade") - if self.category == DS3LocationCategory.SOUL and not self.boss: names.append("Small Souls") - if self.category == DS3LocationCategory.MISC: names.append("Miscellaneous") if self.hidden: names.append("Hidden") + + default_item = item_dictionary[self.default_item_name] + names.append({ + DS3ItemCategory.WEAPON_UPGRADE_5: "Weapons", + DS3ItemCategory.WEAPON_UPGRADE_10: "Weapons", + DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE: "Weapons", + DS3ItemCategory.SHIELD: "Shields", + DS3ItemCategory.SHIELD_INFUSIBLE: "Shields", + DS3ItemCategory.ARMOR: "Armor", + DS3ItemCategory.RING: "Rings", + DS3ItemCategory.SPELL: "Spells", + DS3ItemCategory.MISC: "Miscellaneous", + DS3ItemCategory.UNIQUE: "Unique", + DS3ItemCategory.BOSS: "Boss Souls", + DS3ItemCategory.SOUL: "Small Souls", + DS3ItemCategory.UPGRADE: "Upgrade", + DS3ItemCategory.HEALING: "Healing", + }[default_item.category]) + if default_item.classification == ItemClassification.progression: + names.append("Progression") + return names @@ -247,7 +234,7 @@ def __init__( self, player: int, data: DS3LocationData, - parent: Optional[Region] = None, + parent: Optional[Region] = None, event: bool = False): super().__init__(player, data.name, None if event else data.ap_code, parent) self.data = data @@ -280,3333 +267,2683 @@ def __init__( location_tables = { "Cemetery of Ash": [ DS3LocationData("CA: Soul of a Deserted Corpse (right of spawn)", - "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("CA: Firebomb (down the cliff edge)", "Firebomb x5", - DS3LocationCategory.MISC), - DS3LocationData("CA: Titanite Shard (jump to coffin)", "Titanite Shard", - DS3LocationCategory.UPGRADE), + "Soul of a Deserted Corpse"), + DS3LocationData("CA: Firebomb (down the cliff edge)", "Firebomb x5"), + DS3LocationData("CA: Titanite Shard (jump to coffin)", "Titanite Shard"), DS3LocationData("CA: Soul of an Unknown Traveler (by miniboss)", - "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + "Soul of an Unknown Traveler"), DS3LocationData("CA: Speckled Stoneplate Ring+1 (by miniboss)", - "Speckled Stoneplate Ring+1", DS3LocationCategory.RING, ngp = True), - DS3LocationData("CA: Titanite Scale (miniboss drop)", "Titanite Scale", - DS3LocationCategory.UPGRADE, miniboss = True), - DS3LocationData("CA: Coiled Sword (boss drop)", "Coiled Sword", DS3LocationCategory.KEY, - prominent = True, progression = True, boss = True), + "Speckled Stoneplate Ring+1", ngp = True), + DS3LocationData("CA: Titanite Scale (miniboss drop)", "Titanite Scale", miniboss = True), + DS3LocationData("CA: Coiled Sword (boss drop)", "Coiled Sword", prominent = True, + progression = True, boss = True), ], "Firelink Shrine": [ # Ludleth drop, does not permanently die - DS3LocationData("FS: Skull Ring (kill Ludleth)", "Skull Ring", DS3LocationCategory.RING, - hidden = True, drop = True, npc = True), + DS3LocationData("FS: Skull Ring (kill Ludleth)", "Skull Ring", hidden = True, drop = True, + npc = True), # Sword Master drops - DS3LocationData("FS: Uchigatana (NPC drop)", "Uchigatana", DS3LocationCategory.WEAPON, - hostile_npc = True), # Sword Master drop - DS3LocationData("FS: Master's Attire (NPC drop)", "Master's Attire", - DS3LocationCategory.ARMOR, hostile_npc = True), - DS3LocationData("FS: Master's Gloves (NPC drop)", "Master's Gloves", - DS3LocationCategory.ARMOR, hostile_npc = True), + DS3LocationData("FS: Uchigatana (NPC drop)", "Uchigatana", hostile_npc = True), + DS3LocationData("FS: Master's Attire (NPC drop)", "Master's Attire", hostile_npc = True), + DS3LocationData("FS: Master's Gloves (NPC drop)", "Master's Gloves", hostile_npc = True), DS3LocationData("FS: Broken Straight Sword (gravestone after boss)", - "Broken Straight Sword", DS3LocationCategory.WEAPON), - DS3LocationData("FS: Homeward Bone (cliff edge after boss)", "Homeward Bone", - DS3LocationCategory.MISC), - DS3LocationData("FS: Ember (path right of Firelink entrance)", "Ember", - DS3LocationCategory.MISC), + "Broken Straight Sword"), + DS3LocationData("FS: Homeward Bone (cliff edge after boss)", "Homeward Bone"), + DS3LocationData("FS: Ember (path right of Firelink entrance)", "Ember"), DS3LocationData("FS: Soul of a Deserted Corpse (bell tower door)", - "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("FS: East-West Shield (tree by shrine entrance)", "East-West Shield", DS3LocationCategory.SHIELD), - DS3LocationData("FS: Homeward Bone (path above shrine entrace)", - "Homeward Bone", DS3LocationCategory.MISC), - DS3LocationData("FS: Ember (above shrine entrance)", "Ember", DS3LocationCategory.MISC), - DS3LocationData("FS: Wolf Ring+2 (left of boss room exit)", "Wolf Ring+2", - DS3LocationCategory.RING, ngp = True), + "Soul of a Deserted Corpse"), + DS3LocationData("FS: East-West Shield (tree by shrine entrance)", "East-West Shield"), + DS3LocationData("FS: Homeward Bone (path above shrine entrace)", "Homeward Bone"), + DS3LocationData("FS: Ember (above shrine entrance)", "Ember"), + DS3LocationData("FS: Wolf Ring+2 (left of boss room exit)", "Wolf Ring+2", ngp = True), # Leonhard (quest) DS3LocationData("FS: Cracked Red Eye Orb (Leonhard)", "Cracked Red Eye Orb x5", - DS3LocationCategory.UNIQUE, missable = True, npc = True), + missable = True, npc = True), # Leonhard (kill or quest), missable because he can disappear sometimes - DS3LocationData("FS: Lift Chamber Key (Leonhard)", "Lift Chamber Key", - DS3LocationCategory.KEY, missable = True, npc = True, key = True, - drop = True), + DS3LocationData("FS: Lift Chamber Key (Leonhard)", "Lift Chamber Key", missable = True, + npc = True, drop = True), # Shrine Handmaid shop - DS3LocationData("FS: White Sign Soapstone (shop)", "White Sign Soapstone", - DS3LocationCategory.UNIQUE, shop = True), - DS3LocationData("FS: Dried Finger (shop)", "Dried Finger", DS3LocationCategory.UNIQUE, + DS3LocationData("FS: White Sign Soapstone (shop)", "White Sign Soapstone", shop = True), + DS3LocationData("FS: Dried Finger (shop)", "Dried Finger", shop = True), + DS3LocationData("FS: Tower Key (shop)", "Tower Key", progression = True, shop = True), + DS3LocationData("FS: Ember (shop)", "Ember", offline = '99,0:-1:110000:', shop = True), + DS3LocationData("FS: Farron Dart (shop)", "Farron Dart", offline = '99,0:-1:110000:', shop = True), - DS3LocationData("FS: Tower Key (shop)", "Tower Key", DS3LocationCategory.KEY, - progression = True, shop = True, key = True), - DS3LocationData("FS: Ember (shop)", "Ember", DS3LocationCategory.MISC, - offline = '99,0:-1:110000:', shop = True), - DS3LocationData("FS: Farron Dart (shop)", "Farron Dart", DS3LocationCategory.SPELL, - offline = '99,0:-1:110000:', shop = True), - DS3LocationData("FS: Soul Arrow (shop)", "Soul Arrow", DS3LocationCategory.SPELL, - offline = '99,0:-1:110000:', shop = True), - DS3LocationData("FS: Heal Aid (shop)", "Heal Aid", DS3LocationCategory.SPELL, + DS3LocationData("FS: Soul Arrow (shop)", "Soul Arrow", offline = '99,0:-1:110000:', shop = True), - DS3LocationData("FS: Alluring Skull (Mortician's Ashes)", "Alluring Skull", - DS3LocationCategory.MISC, shop = True, conditional = True), - DS3LocationData("FS: Ember (Mortician's Ashes)", "Ember", DS3LocationCategory.MISC, + DS3LocationData("FS: Heal Aid (shop)", "Heal Aid", shop = True), + DS3LocationData("FS: Alluring Skull (Mortician's Ashes)", "Alluring Skull", shop = True, + conditional = True), + DS3LocationData("FS: Ember (Mortician's Ashes)", "Ember", offline = '99,0:-1:110000,70000100:', shop = True, conditional = True), - DS3LocationData("FS: Grave Key (Mortician's Ashes)", "Grave Key", DS3LocationCategory.KEY, - shop = True, key = True, conditional = True), - DS3LocationData("FS: Life Ring (Dreamchaser's Ashes)", "Life Ring", - DS3LocationCategory.RING, shop = True, conditional = True), + DS3LocationData("FS: Grave Key (Mortician's Ashes)", "Grave Key", shop = True, + conditional = True), + DS3LocationData("FS: Life Ring (Dreamchaser's Ashes)", "Life Ring", shop = True, + conditional = True), # Only if you say where the ashes were found DS3LocationData("FS: Hidden Blessing (Dreamchaser's Ashes)", "Hidden Blessing", - DS3LocationCategory.MISC, missable = True, shop = True), + missable = True, shop = True), DS3LocationData("FS: Lloyd's Shield Ring (Paladin's Ashes)", "Lloyd's Shield Ring", - DS3LocationCategory.RING, shop = True, conditional = True), - DS3LocationData("FS: Ember (Grave Warden's Ashes)", "Ember", DS3LocationCategory.MISC, + shop = True, conditional = True), + DS3LocationData("FS: Ember (Grave Warden's Ashes)", "Ember", offline = '99,0:-1:110000,70000103:', shop = True, conditional = True), # Prisoner Chief's Ashes DS3LocationData("FS: Karla's Pointed Hat (Prisoner Chief's Ashes)", "Karla's Pointed Hat", - DS3LocationCategory.ARMOR, offline = '99,0:-1:110000,70000105:', - shop = True, conditional = True), + offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), DS3LocationData("FS: Karla's Coat (Prisoner Chief's Ashes)", "Karla's Coat", - DS3LocationCategory.ARMOR, offline = '99,0:-1:110000,70000105:', - shop = True, conditional = True), + offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), DS3LocationData("FS: Karla's Gloves (Prisoner Chief's Ashes)", "Karla's Gloves", - DS3LocationCategory.ARMOR, offline = '99,0:-1:110000,70000105:', - shop = True, conditional = True), - DS3LocationData("FS: Karla's Trousers (Prisoner Chief's Ashes)", - "Karla's Trousers", DS3LocationCategory.ARMOR, offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), - DS3LocationData("FS: Xanthous Overcoat (Xanthous Ashes)", "Xanthous Overcoat", - DS3LocationCategory.ARMOR, shop = True, conditional = True), - DS3LocationData("FS: Xanthous Gloves (Xanthous Ashes)", "Xanthous Gloves", - DS3LocationCategory.ARMOR, shop = True, conditional = True), - DS3LocationData("FS: Xanthous Trousers (Xanthous Ashes)", "Xanthous Trousers", - DS3LocationCategory.ARMOR, shop = True, conditional = True), - DS3LocationData("FS: Ember (Dragon Chaser's Ashes)", "Ember", DS3LocationCategory.MISC, + DS3LocationData("FS: Karla's Trousers (Prisoner Chief's Ashes)", "Karla's Trousers", + offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), + DS3LocationData("FS: Xanthous Overcoat (Xanthous Ashes)", "Xanthous Overcoat", shop = True, + conditional = True), + DS3LocationData("FS: Xanthous Gloves (Xanthous Ashes)", "Xanthous Gloves", shop = True, + conditional = True), + DS3LocationData("FS: Xanthous Trousers (Xanthous Ashes)", "Xanthous Trousers", shop = True, + conditional = True), + DS3LocationData("FS: Ember (Dragon Chaser's Ashes)", "Ember", offline = '99,0:-1:110000,70000108:', shop = True, conditional = True), - DS3LocationData("FS: Washing Pole (Easterner's Ashes)", "Washing Pole", - DS3LocationCategory.WEAPON, shop = True, conditional = True), - DS3LocationData("FS: Eastern Helm (Easterner's Ashes)", "Eastern Helm", - DS3LocationCategory.ARMOR, shop = True, conditional = True), - DS3LocationData("FS: Eastern Armor (Easterner's Ashes)", "Eastern Armor", - DS3LocationCategory.ARMOR, shop = True, conditional = True), + DS3LocationData("FS: Washing Pole (Easterner's Ashes)", "Washing Pole", shop = True, + conditional = True), + DS3LocationData("FS: Eastern Helm (Easterner's Ashes)", "Eastern Helm", shop = True, + conditional = True), + DS3LocationData("FS: Eastern Armor (Easterner's Ashes)", "Eastern Armor", shop = True, + conditional = True), DS3LocationData("FS: Eastern Gauntlets (Easterner's Ashes)", "Eastern Gauntlets", - DS3LocationCategory.ARMOR, shop = True, conditional = True), - DS3LocationData("FS: Eastern Leggings (Easterner's Ashes)", "Eastern Leggings", - DS3LocationCategory.ARMOR, shop = True, conditional = True), - DS3LocationData("FS: Wood Grain Ring (Easterner's Ashes)", "Wood Grain Ring", - DS3LocationCategory.RING, shop = True, conditional = True), + shop = True, conditional = True), + DS3LocationData("FS: Eastern Leggings (Easterner's Ashes)", "Eastern Leggings", shop = True, + conditional = True), + DS3LocationData("FS: Wood Grain Ring (Easterner's Ashes)", "Wood Grain Ring", shop = True, + conditional = True), DS3LocationData("FS: Millwood Knight Helm (Captain's Ashes)", "Millwood Knight Helm", - DS3LocationCategory.ARMOR, dlc = True, shop = True, conditional = True), + dlc = True, shop = True, conditional = True), DS3LocationData("FS: Millwood Knight Armor (Captain's Ashes)", "Millwood Knight Armor", - DS3LocationCategory.ARMOR, dlc = True, shop = True, conditional = True), + dlc = True, shop = True, conditional = True), DS3LocationData("FS: Millwood Knight Gauntlets (Captain's Ashes)", - "Millwood Knight Gauntlets", DS3LocationCategory.ARMOR, dlc = True, - shop = True, conditional = True), + "Millwood Knight Gauntlets", dlc = True, shop = True, conditional = True), DS3LocationData("FS: Millwood Knight Leggings (Captain's Ashes)", - "Millwood Knight Leggings", DS3LocationCategory.ARMOR, dlc = True, - shop = True, conditional = True), - DS3LocationData("FS: Refined Gem (Captain's Ashes)", "Refined Gem", - DS3LocationCategory.UPGRADE, dlc = True, shop = True, conditional = True), + "Millwood Knight Leggings", dlc = True, shop = True, conditional = True), + DS3LocationData("FS: Refined Gem (Captain's Ashes)", "Refined Gem", dlc = True, shop = True, + conditional = True), # Ludleth Shop DS3LocationData("FS: Vordt's Great Hammer (Ludleth for Vordt)", "Vordt's Great Hammer", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Pontiff's Left Eye (Ludleth for Vordt)", "Pontiff's Left Eye", - DS3LocationCategory.RING, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Bountiful Sunlight (Ludleth for Rosaria)", "Bountiful Sunlight", - DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Darkmoon Longbow (Ludleth for Aldrich)", "Darkmoon Longbow", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Lifehunt Scythe (Ludleth for Aldrich)", "Lifehunt Scythe", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Hollowslayer Greatsword (Ludleth for Greatwood)", - "Hollowslayer Greatsword", DS3LocationCategory.WEAPON, missable = True, - boss = True, shop = True), + "Hollowslayer Greatsword", missable = True, boss = True, shop = True), DS3LocationData("FS: Arstor's Spear (Ludleth for Greatwood)", "Arstor's Spear", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Crystal Sage's Rapier (Ludleth for Sage)", "Crystal Sage's Rapier", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), - DS3LocationData("FS: Crystal Hail (Ludleth for Sage)", "Crystal Hail", - DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), + DS3LocationData("FS: Crystal Hail (Ludleth for Sage)", "Crystal Hail", missable = True, + boss = True, shop = True), DS3LocationData("FS: Cleric's Candlestick (Ludleth for Deacons)", "Cleric's Candlestick", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), - DS3LocationData("FS: Deep Soul (Ludleth for Deacons)", "Deep Soul", - DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), + DS3LocationData("FS: Deep Soul (Ludleth for Deacons)", "Deep Soul", missable = True, + boss = True, shop = True), DS3LocationData("FS: Havel's Ring (Ludleth for Stray Demon)", "Havel's Ring", - DS3LocationCategory.RING, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Boulder Heave (Ludleth for Stray Demon)", "Boulder Heave", - DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Farron Greatsword (Ludleth for Abyss Watchers)", "Farron Greatsword", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Wolf Knight's Greatsword (Ludleth for Abyss Watchers)", - "Wolf Knight's Greatsword", DS3LocationCategory.WEAPON, missable = True, - boss = True, shop = True), + "Wolf Knight's Greatsword", missable = True, boss = True, shop = True), DS3LocationData("FS: Wolnir's Holy Sword (Ludleth for Wolnir)", "Wolnir's Holy Sword", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), - DS3LocationData("FS: Black Serpent (Ludleth for Wolnir)", "Black Serpent", - DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), + DS3LocationData("FS: Black Serpent (Ludleth for Wolnir)", "Black Serpent", missable = True, + boss = True, shop = True), DS3LocationData("FS: Demon's Greataxe (Ludleth for Fire Demon)", "Demon's Greataxe", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Demon's Fist (Ludleth for Fire Demon)", "Demon's Fist", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Old King's Great Hammer (Ludleth for Old Demon King)", - "Old King's Great Hammer", DS3LocationCategory.WEAPON, missable = True, - boss = True, shop = True), + "Old King's Great Hammer", missable = True, boss = True, shop = True), DS3LocationData("FS: Chaos Bed Vestiges (Ludleth for Old Demon King)", "Chaos Bed Vestiges", - DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Greatsword of Judgment (Ludleth for Pontiff)", - "Greatsword of Judgment", DS3LocationCategory.WEAPON, missable = True, - boss = True, shop = True), + "Greatsword of Judgment", missable = True, boss = True, shop = True), DS3LocationData("FS: Profaned Greatsword (Ludleth for Pontiff)", "Profaned Greatsword", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Yhorm's Great Machete (Ludleth for Yhorm)", "Yhorm's Great Machete", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Yhorm's Greatshield (Ludleth for Yhorm)", "Yhorm's Greatshield", - DS3LocationCategory.SHIELD, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Dancer's Enchanted Swords (Ludleth for Dancer)", - "Dancer's Enchanted Swords", DS3LocationCategory.WEAPON, missable = True, - boss = True, shop = True), + "Dancer's Enchanted Swords", missable = True, boss = True, shop = True), DS3LocationData("FS: Soothing Sunlight (Ludleth for Dancer)", "Soothing Sunlight", - DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Dragonslayer Greataxe (Ludleth for Dragonslayer)", - "Dragonslayer Greataxe", DS3LocationCategory.WEAPON, missable = True, - boss = True, shop = True), + "Dragonslayer Greataxe", missable = True, boss = True, shop = True), DS3LocationData("FS: Dragonslayer Greatshield (Ludleth for Dragonslayer)", - "Dragonslayer Greatshield", DS3LocationCategory.SHIELD, missable = True, - boss = True, shop = True), + "Dragonslayer Greatshield", missable = True, boss = True, shop = True), DS3LocationData("FS: Moonlight Greatsword (Ludleth for Oceiros)", "Moonlight Greatsword", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: White Dragon Breath (Ludleth for Oceiros)", "White Dragon Breath", - DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Lorian's Greatsword (Ludleth for Princes)", "Lorian's Greatsword", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Lothric's Holy Sword (Ludleth for Princes)", "Lothric's Holy Sword", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Gundyr's Halberd (Ludleth for Champion)", "Gundyr's Halberd", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Prisoner's Chain (Ludleth for Champion)", "Prisoner's Chain", - DS3LocationCategory.RING, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Storm Curved Sword (Ludleth for Nameless)", "Storm Curved Sword", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Dragonslayer Swordspear (Ludleth for Nameless)", - "Dragonslayer Swordspear", DS3LocationCategory.WEAPON, missable = True, - boss = True, shop = True), + "Dragonslayer Swordspear", missable = True, boss = True, shop = True), DS3LocationData("FS: Lightning Storm (Ludleth for Nameless)", "Lightning Storm", - DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Firelink Greatsword (Ludleth for Cinder)", "Firelink Greatsword", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Sunlight Spear (Ludleth for Cinder)", "Sunlight Spear", - DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Friede's Great Scythe (Ludleth for Friede)", "Friede's Great Scythe", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Rose of Ariandel (Ludleth for Friede)", "Rose of Ariandel", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Demon's Scar (Ludleth for Demon Prince)", "Demon's Scar", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Seething Chaos (Ludleth for Demon Prince)", "Seething Chaos", - DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), - DS3LocationData("FS: Frayed Blade (Ludleth for Midir)", "Frayed Blade", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), - DS3LocationData("FS: Old Moonlight (Ludleth for Midir)", "Old Moonlight", - DS3LocationCategory.SPELL, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), + DS3LocationData("FS: Frayed Blade (Ludleth for Midir)", "Frayed Blade", missable = True, + boss = True, shop = True), + DS3LocationData("FS: Old Moonlight (Ludleth for Midir)", "Old Moonlight", missable = True, + boss = True, shop = True), DS3LocationData("FS: Gael's Greatsword (Ludleth for Gael)", "Gael's Greatsword", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), DS3LocationData("FS: Repeating Crossbow (Ludleth for Gael)", "Repeating Crossbow", - DS3LocationCategory.WEAPON, missable = True, boss = True, shop = True), + missable = True, boss = True, shop = True), ], "Firelink Shrine Bell Tower": [ # Guarded by Tower Key - DS3LocationData("FSBT: Homeward Bone (roof)", "Homeward Bone x3", - DS3LocationCategory.MISC), - DS3LocationData("FSBT: Estus Ring (rafters)", "Estus Ring", DS3LocationCategory.RING), - DS3LocationData("FSBT: Estus Shard (rafters)", "Estus Shard", DS3LocationCategory.HEALTH), - DS3LocationData("FSBT: Fire Keeper Soul (tower top)", "Fire Keeper Soul", - DS3LocationCategory.UNIQUE), - DS3LocationData("FSBT: Fire Keeper Robe (partway down tower)", "Fire Keeper Robe", - DS3LocationCategory.ARMOR), - DS3LocationData("FSBT: Fire Keeper Gloves (partway down tower)", "Fire Keeper Gloves", - DS3LocationCategory.ARMOR), - DS3LocationData("FSBT: Fire Keeper Skirt (partway down tower)", "Fire Keeper Skirt", - DS3LocationCategory.ARMOR), + DS3LocationData("FSBT: Homeward Bone (roof)", "Homeward Bone x3"), + DS3LocationData("FSBT: Estus Ring (rafters)", "Estus Ring"), + DS3LocationData("FSBT: Estus Shard (rafters)", "Estus Shard"), + DS3LocationData("FSBT: Fire Keeper Soul (tower top)", "Fire Keeper Soul"), + DS3LocationData("FSBT: Fire Keeper Robe (partway down tower)", "Fire Keeper Robe"), + DS3LocationData("FSBT: Fire Keeper Gloves (partway down tower)", "Fire Keeper Gloves"), + DS3LocationData("FSBT: Fire Keeper Skirt (partway down tower)", "Fire Keeper Skirt"), DS3LocationData("FSBT: Covetous Silver Serpent Ring (illusory wall past rafters)", - "Covetous Silver Serpent Ring", DS3LocationCategory.RING, hidden = True), + "Covetous Silver Serpent Ring", hidden = True), DS3LocationData("FSBT: Twinkling Titanite (lizard behind Firelink)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + "Twinkling Titanite", lizard = True), # Mark all crow trades as missable since no one wants to have to try trading everything just # in case it gives a progression item. DS3LocationData("FSBT: Iron Bracelets (crow for Homeward Bone)", "Iron Bracelets", - DS3LocationCategory.ARMOR, missable = True), + missable = True), DS3LocationData("FSBT: Ring of Sacrifice (crow for Loretta's Bone)", "Ring of Sacrifice", - DS3LocationCategory.MISC, missable = True), + missable = True), DS3LocationData("FSBT: Porcine Shield (crow for Undead Bone Shard)", "Porcine Shield", - DS3LocationCategory.SHIELD, missable = True), + missable = True), DS3LocationData("FSBT: Lucatiel's Mask (crow for Vertebra Shackle)", "Lucatiel's Mask", - DS3LocationCategory.ARMOR, missable = True), + missable = True), DS3LocationData("FSBT: Very good! Carving (crow for Divine Blessing)", - "Very good! Carving", DS3LocationCategory.UNIQUE, missable = True), + "Very good! Carving", missable = True), DS3LocationData("FSBT: Thank you Carving (crow for Hidden Blessing)", "Thank you Carving", - DS3LocationCategory.UNIQUE, missable = True), + missable = True), DS3LocationData("FSBT: I'm sorry Carving (crow for Shriving Stone)", "I'm sorry Carving", - DS3LocationCategory.UNIQUE, missable = True), + missable = True), DS3LocationData("FSBT: Sunlight Shield (crow for Mendicant's Staff)", "Sunlight Shield", - DS3LocationCategory.SHIELD, missable = True), + missable = True), DS3LocationData("FSBT: Hollow Gem (crow for Eleonora)", "Hollow Gem", - DS3LocationCategory.UPGRADE, missable = True), + missable = True), DS3LocationData("FSBT: Titanite Scale (crow for Blacksmith Hammer)", "Titanite Scale x3", - DS3LocationCategory.UPGRADE, offline = '99,0:50004330::', missable = True), + offline = '99,0:50004330::', missable = True), DS3LocationData("FSBT: Help me! Carving (crow for any sacred chime)", "Help me! Carving", - DS3LocationCategory.UNIQUE, missable = True), + missable = True), DS3LocationData("FSBT: Titanite Slab (crow for Coiled Sword Fragment)", "Titanite Slab", - DS3LocationCategory.UPGRADE, missable = True), + missable = True), DS3LocationData("FSBT: Hello Carving (crow for Alluring Skull)", "Hello Carving", - DS3LocationCategory.UNIQUE, missable = True), + missable = True), DS3LocationData("FSBT: Armor of the Sun (crow for Siegbräu)", "Armor of the Sun", - DS3LocationCategory.ARMOR, missable = True), + missable = True), DS3LocationData("FSBT: Large Titanite Shard (crow for Firebomb)", "Large Titanite Shard", - DS3LocationCategory.UPGRADE, missable = True), + missable = True), DS3LocationData("FSBT: Titanite Chunk (crow for Black Firebomb)", "Titanite Chunk", - DS3LocationCategory.UPGRADE, missable = True), - DS3LocationData("FSBT: Iron Helm (crow for Lightning Urn)", "Iron Helm", - DS3LocationCategory.ARMOR, missable = True), + missable = True), + DS3LocationData("FSBT: Iron Helm (crow for Lightning Urn)", "Iron Helm", missable = True), DS3LocationData("FSBT: Twinkling Titanite (crow for Prism Stone)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE, missable = True), + missable = True), DS3LocationData("FSBT: Iron Leggings (crow for Seed of a Giant Tree)", "Iron Leggings", - DS3LocationCategory.ARMOR, missable = True), + missable = True), DS3LocationData("FSBT: Lightning Gem (crow for Xanthous Crown)", "Lightning Gem", - DS3LocationCategory.UPGRADE, missable = True), + missable = True), DS3LocationData("FSBT: Twinkling Titanite (crow for Large Leather Shield)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE, missable = True), + "Twinkling Titanite", missable = True), DS3LocationData("FSBT: Blessed Gem (crow for Moaning Shield)", "Blessed Gem", - DS3LocationCategory.UPGRADE, missable = True), + missable = True), ], "High Wall of Lothric": [ DS3LocationData("HWL: Soul of Boreal Valley Vordt", "Soul of Boreal Valley Vordt", - DS3LocationCategory.SOUL, prominent = True, boss = True), - DS3LocationData("HWL: Soul of the Dancer", "Soul of the Dancer", DS3LocationCategory.SOUL, prominent = True, boss = True), - DS3LocationData("HWL: Basin of Vows (Emma)", "Basin of Vows", DS3LocationCategory.KEY, - prominent = True, progression = True, conditional = True), + DS3LocationData("HWL: Soul of the Dancer", "Soul of the Dancer", prominent = True, + boss = True), + DS3LocationData("HWL: Basin of Vows (Emma)", "Basin of Vows", prominent = True, + progression = True, conditional = True), DS3LocationData("HWL: Small Lothric Banner (Emma)", "Small Lothric Banner", - DS3LocationCategory.KEY, prominent = True, progression = True), + prominent = True, progression = True), DS3LocationData("HWL: Green Blossom (fort walkway, hall behind wheel)", "Green Blossom x2", - DS3LocationCategory.MISC, hidden = True), + hidden = True), DS3LocationData("HWL: Gold Pine Resin (corpse tower, drop)", "Gold Pine Resin x2", - DS3LocationCategory.MISC, hidden = True), + hidden = True), DS3LocationData("HWL: Large Soul of a Deserted Corpse (flame plaza)", - "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + "Large Soul of a Deserted Corpse"), DS3LocationData("HWL: Soul of a Deserted Corpse (by wall tower door)", - "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("HWL: Standard Arrow (back tower)", "Standard Arrow x12", - DS3LocationCategory.MISC), - DS3LocationData("HWL: Longbow (back tower)", "Longbow", DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Firebomb (wall tower, beam)", "Firebomb x3", - DS3LocationCategory.MISC), - DS3LocationData("HWL: Throwing Knife (wall tower, path to Greirat)", "Throwing Knife x8", - DS3LocationCategory.MISC), + "Soul of a Deserted Corpse"), + DS3LocationData("HWL: Standard Arrow (back tower)", "Standard Arrow x12"), + DS3LocationData("HWL: Longbow (back tower)", "Longbow"), + DS3LocationData("HWL: Firebomb (wall tower, beam)", "Firebomb x3"), + DS3LocationData("HWL: Throwing Knife (wall tower, path to Greirat)", "Throwing Knife x8"), DS3LocationData("HWL: Soul of a Deserted Corpse (corpse tower, bottom floor)", - "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("HWL: Club (flame plaza)", "Club", DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Claymore (flame plaza)", "Claymore", - DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Ember (flame plaza)", "Ember", DS3LocationCategory.MISC), - DS3LocationData("HWL: Firebomb (corpse tower, under table)", "Firebomb x2", - DS3LocationCategory.MISC), + "Soul of a Deserted Corpse"), + DS3LocationData("HWL: Club (flame plaza)", "Club"), + DS3LocationData("HWL: Claymore (flame plaza)", "Claymore"), + DS3LocationData("HWL: Ember (flame plaza)", "Ember"), + DS3LocationData("HWL: Firebomb (corpse tower, under table)", "Firebomb x2"), DS3LocationData("HWL: Titanite Shard (wall tower, corner by bonfire)", "Titanite Shard", - DS3LocationCategory.UPGRADE, hidden = True), + hidden = True), DS3LocationData("HWL: Undead Hunter Charm (fort, room off entry, in pot)", - "Undead Hunter Charm x2", DS3LocationCategory.MISC, hidden = True), - DS3LocationData("HWL: Firebomb (top of ladder to fountain)", "Firebomb x3", - DS3LocationCategory.MISC), - DS3LocationData("HWL: Cell Key (fort basement, down stairs)", "Cell Key", - DS3LocationCategory.KEY, key = True), - DS3LocationData("HWL: Ember (fountain #1)", "Ember", DS3LocationCategory.MISC), + "Undead Hunter Charm x2", hidden = True), + DS3LocationData("HWL: Firebomb (top of ladder to fountain)", "Firebomb x3"), + DS3LocationData("HWL: Cell Key (fort basement, down stairs)", "Cell Key"), + DS3LocationData("HWL: Ember (fountain #1)", "Ember"), DS3LocationData("HWL: Soul of a Deserted Corpse (fort entry, corner)", - "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("HWL: Lucerne (promenade, side path)", "Lucerne", - DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Mail Breaker (wall tower, path to Greirat)", "Mail Breaker", - DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Titanite Shard (fort basement, behind crates)", - "Titanite Shard", DS3LocationCategory.UPGRADE, hidden = True), - DS3LocationData("HWL: Rapier (fountain, corner)", "Rapier", DS3LocationCategory.WEAPON), - DS3LocationData("HWL: Titanite Shard (for, room off entry)", - "Titanite Shard", DS3LocationCategory.UPGRADE), + "Soul of a Deserted Corpse"), + DS3LocationData("HWL: Lucerne (promenade, side path)", "Lucerne"), + DS3LocationData("HWL: Mail Breaker (wall tower, path to Greirat)", "Mail Breaker"), + DS3LocationData("HWL: Titanite Shard (fort basement, behind crates)", "Titanite Shard", + hidden = True), + DS3LocationData("HWL: Rapier (fountain, corner)", "Rapier"), + DS3LocationData("HWL: Titanite Shard (for, room off entry)", "Titanite Shard"), DS3LocationData("HWL: Large Soul of a Deserted Corpse (fort roof)", - "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("HWL: Black Firebomb (small roof over fountain)", "Black Firebomb x3", - DS3LocationCategory.MISC), + "Large Soul of a Deserted Corpse"), + DS3LocationData("HWL: Black Firebomb (small roof over fountain)", "Black Firebomb x3"), DS3LocationData("HWL: Soul of a Deserted Corpse (path to corpse tower)", - "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("HWL: Ember (fountain, #2)", "Ember", DS3LocationCategory.MISC), + "Soul of a Deserted Corpse"), + DS3LocationData("HWL: Ember (fountain, #2)", "Ember"), DS3LocationData("HWL: Large Soul of a Deserted Corpse (platform by fountain)", - "Large Soul of a Deserted Corpse", DS3LocationCategory.MISC, - hidden = True), # Easily missed turnoff - DS3LocationData("HWL: Binoculars (corpse tower, upper platform)", "Binoculars", - DS3LocationCategory.UNIQUE), + "Large Soul of a Deserted Corpse", hidden = True), # Easily missed turnoff + DS3LocationData("HWL: Binoculars (corpse tower, upper platform)", "Binoculars"), DS3LocationData("HWL: Ring of Sacrifice (awning by fountain)", - "Ring of Sacrifice", DS3LocationCategory.MISC, - hidden = True), # Easily missed turnoff - DS3LocationData("HWL: Throwing Knife (shortcut, lift top)", "Throwing Knife x6", - DS3LocationCategory.MISC), + "Ring of Sacrifice", hidden = True), # Easily missed turnoff + DS3LocationData("HWL: Throwing Knife (shortcut, lift top)", "Throwing Knife x6"), DS3LocationData("HWL: Soul of a Deserted Corpse (path to back tower, by lift door)", - "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("HWL: Green Blossom (shortcut, by lower lift door)", "Green Blossom x3", - DS3LocationCategory.MISC), - DS3LocationData("HWL: Broadsword (fort, room off entry)", "Broadsword", - DS3LocationCategory.WEAPON), + "Soul of a Deserted Corpse"), + DS3LocationData("HWL: Green Blossom (shortcut, by lower lift door)", "Green Blossom x3"), + DS3LocationData("HWL: Broadsword (fort, room off entry)", "Broadsword"), DS3LocationData("HWL: Soul of a Deserted Corpse (fountain, path to promenade)", - "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("HWL: Firebomb (fort roof)", "Firebomb x3", DS3LocationCategory.MISC), + "Soul of a Deserted Corpse"), + DS3LocationData("HWL: Firebomb (fort roof)", "Firebomb x3"), DS3LocationData("HWL: Soul of a Deserted Corpse (wall tower, right of exit)", - "Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("HWL: Estus Shard (fort basement, on anvil)", "Estus Shard", - DS3LocationCategory.HEALTH), + "Soul of a Deserted Corpse"), + DS3LocationData("HWL: Estus Shard (fort basement, on anvil)", "Estus Shard"), DS3LocationData("HWL: Fleshbite Ring+1 (fort roof, jump to other roof)", - "Fleshbite Ring+1", DS3LocationCategory.RING, ngp = True, - hidden = True), # Hidden jump + "Fleshbite Ring+1", ngp = True, hidden = True), # Hidden jump DS3LocationData("HWL: Ring of the Evil Eye+2 (fort basement, far wall)", - "Ring of the Evil Eye+2", DS3LocationCategory.RING, ngp = True, - hidden = True), # In barrels + "Ring of the Evil Eye+2", ngp = True, hidden = True), # In barrels DS3LocationData("HWL: Silver Eagle Kite Shield (fort mezzanine)", - "Silver Eagle Kite Shield", DS3LocationCategory.SHIELD), + "Silver Eagle Kite Shield"), DS3LocationData("HWL: Astora Straight Sword (fort walkway, drop down)", - "Astora Straight Sword", DS3LocationCategory.WEAPON, - hidden = True), # Hidden fall + "Astora Straight Sword", hidden = True), # Hidden fall DS3LocationData("HWL: Battle Axe (flame tower, mimic)", "Battle Axe", - DS3LocationCategory.WEAPON, offline = '01,0:53000960::', mimic = True), + offline = '01,0:53000960::', mimic = True), - # Only dropped after transformation - DS3LocationData("HWL: Ember (fort roof, transforming hollow)", "Ember", - DS3LocationCategory.MISC, hidden = True), - DS3LocationData("HWL: Titanite Shard (fort roof, transforming hollow)", - "Titanite Shard", DS3LocationCategory.UPGRADE, hidden = True), + # Only dropped after transformation + DS3LocationData("HWL: Ember (fort roof, transforming hollow)", "Ember", hidden = True), + DS3LocationData("HWL: Titanite Shard (fort roof, transforming hollow)", "Titanite Shard", + hidden = True), DS3LocationData("HWL: Ember (back tower roof bonfire, transforming hollow)", "Ember", - DS3LocationCategory.MISC, hidden = True), + hidden = True), DS3LocationData("HWL: Titanite Shard (back tower roof bonfire, transforming hollow)", - "Titanite Shard", DS3LocationCategory.MISC, hidden = True), + "Titanite Shard", hidden = True), - DS3LocationData("HWL: Refined Gem (promenade miniboss)", "Refined Gem", - DS3LocationCategory.UPGRADE, miniboss = True), - DS3LocationData("HWL: Way of Blue (Emma)", "Way of Blue", DS3LocationCategory.UNIQUE), + DS3LocationData("HWL: Refined Gem (promenade miniboss)", "Refined Gem", miniboss = True), + DS3LocationData("HWL: Way of Blue (Emma)", "Way of Blue"), # Categorize this as an NPC item so that it doesn't get randomized if the Lift Chamber Key # isn't randomized, since in that case it's missable. DS3LocationData("HWL: Red Eye Orb (wall tower, miniboss)", "Red Eye Orb", - DS3LocationCategory.MISC, conditional = True, miniboss = True, npc = True), - DS3LocationData("HWL: Raw Gem (fort roof, lizard)", "Raw Gem", - DS3LocationCategory.UPGRADE, lizard = True), + conditional = True, miniboss = True, npc = True), + DS3LocationData("HWL: Raw Gem (fort roof, lizard)", "Raw Gem", lizard = True), ], "Undead Settlement": [ DS3LocationData("US: Soul of the Rotted Greatwood", "Soul of the Rotted Greatwood", - DS3LocationCategory.SOUL, prominent = True, boss = True), - DS3LocationData("US: Transposing Kiln (boss drop)", "Transposing Kiln", - DS3LocationCategory.UNIQUE, boss = True), + prominent = True, boss = True), + DS3LocationData("US: Transposing Kiln (boss drop)", "Transposing Kiln", boss = True), # Missable because it's unavailable if you start as a Pyromancer - DS3LocationData("US: Pyromancy Flame (Cornyx)", "Pyromancy Flame", - DS3LocationCategory.WEAPON, missable = True, npc = True), + DS3LocationData("US: Pyromancy Flame (Cornyx)", "Pyromancy Flame", missable = True, + npc = True), DS3LocationData("US: Old Sage's Blindfold (kill Cornyx)", "Old Sage's Blindfold", - DS3LocationCategory.ARMOR, npc = True), - DS3LocationData("US: Cornyx's Garb (kill Cornyx)", "Cornyx's Garb", DS3LocationCategory.ARMOR, + npc = True), + DS3LocationData("US: Cornyx's Garb (kill Cornyx)", "Cornyx's Garb", offline = '02,0:50006141::', npc = True), - DS3LocationData("US: Cornyx's Wrap (kill Cornyx)", "Cornyx's Wrap", DS3LocationCategory.ARMOR, + DS3LocationData("US: Cornyx's Wrap (kill Cornyx)", "Cornyx's Wrap", offline = '02,0:50006141::', npc = True), - DS3LocationData("US: Cornyx's Skirt (kill Cornyx)", "Cornyx's Skirt", DS3LocationCategory.ARMOR, + DS3LocationData("US: Cornyx's Skirt (kill Cornyx)", "Cornyx's Skirt", offline = '02,0:50006141::', npc = True), - DS3LocationData("US: Tower Key (kill Irina)", "Tower Key", DS3LocationCategory.KEY, - missable = True, npc = True, key = True), - DS3LocationData("US: Flynn's Ring (tower village, rooftop)", "Flynn's Ring", - DS3LocationCategory.RING), - DS3LocationData("US: Undead Bone Shard (by white tree)", "Undead Bone Shard", - DS3LocationCategory.HEALTH), + DS3LocationData("US: Tower Key (kill Irina)", "Tower Key", missable = True, npc = True), + DS3LocationData("US: Flynn's Ring (tower village, rooftop)", "Flynn's Ring"), + DS3LocationData("US: Undead Bone Shard (by white tree)", "Undead Bone Shard"), DS3LocationData("US: Alluring Skull (Foot of the High Wall, behind carriage)", - "Alluring Skull x2", DS3LocationCategory.MISC), + "Alluring Skull x2"), DS3LocationData("US: Mortician's Ashes (graveyard by white tree)", "Mortician's Ashes", - DS3LocationCategory.KEY, progression = True), + progression = True), DS3LocationData("US: Homeward Bone (tower village, jump from roof)", "Homeward Bone x2", - DS3LocationCategory.MISC, hidden = True), # Hidden fall + hidden = True), # Hidden fall DS3LocationData("US: Caduceus Round Shield (right after stable exit)", - "Caduceus Round Shield", DS3LocationCategory.SHIELD), - DS3LocationData("US: Ember (by miniboss before Road of Sacrifices)", "Ember", - DS3LocationCategory.MISC), + "Caduceus Round Shield"), + DS3LocationData("US: Ember (by miniboss before Road of Sacrifices)", "Ember"), DS3LocationData("US: Soul of an Unknown Traveler (chasm crypt)", - "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("US: Repair Powder (first building, balcony)", "Repair Powder x2", - DS3LocationCategory.MISC), - DS3LocationData("US: Homeward Bone (stable roof)", "Homeward Bone x2", - DS3LocationCategory.MISC), + "Soul of an Unknown Traveler"), + DS3LocationData("US: Repair Powder (first building, balcony)", "Repair Powder x2"), + DS3LocationData("US: Homeward Bone (stable roof)", "Homeward Bone x2"), DS3LocationData("US: Titanite Shard (side path on the way to Dilapidated Bridge)", - "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("US: Wargod Wooden Shield (Pit of Hollows)", "Wargod Wooden Shield", - DS3LocationCategory.SHIELD), + "Titanite Shard"), + DS3LocationData("US: Wargod Wooden Shield (Pit of Hollows)", "Wargod Wooden Shield"), DS3LocationData("US: Large Soul of a Deserted Corpse (on the way to tower, by well)", - "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("US: Ember (bridge on the way to tower)", "Ember", - DS3LocationCategory.MISC), + "Large Soul of a Deserted Corpse"), + DS3LocationData("US: Ember (bridge on the way to tower)", "Ember"), DS3LocationData("US: Large Soul of a Deserted Corpse (stable)", - "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("US: Titanite Shard (porch after burning tree)", "Titanite Shard", - DS3LocationCategory.UPGRADE), + "Large Soul of a Deserted Corpse"), + DS3LocationData("US: Titanite Shard (porch after burning tree)", "Titanite Shard"), DS3LocationData("US: Alluring Skull (tower village building, upstairs)", - "Alluring Skull x2", DS3LocationCategory.MISC), - DS3LocationData("US: Charcoal Pine Bundle (first building)", "Charcoal Pine Bundle x2", - DS3LocationCategory.MISC), - DS3LocationData("US: Blue Wooden Shield (graveyard by white tree)", "Blue Wooden Shield", - DS3LocationCategory.SHIELD), - DS3LocationData("US: Cleric Hat (graveyard by white tree)", "Cleric Hat", - DS3LocationCategory.ARMOR), - DS3LocationData("US: Cleric Blue Robe (graveyard by white tree)", "Cleric Blue Robe", - DS3LocationCategory.ARMOR), - DS3LocationData("US: Cleric Gloves (graveyard by white tree)", "Cleric Gloves", - DS3LocationCategory.ARMOR), - DS3LocationData("US: Cleric Trousers (graveyard by white tree)", "Cleric Trousers", - DS3LocationCategory.ARMOR), + "Alluring Skull x2"), + DS3LocationData("US: Charcoal Pine Bundle (first building)", "Charcoal Pine Bundle x2"), + DS3LocationData("US: Blue Wooden Shield (graveyard by white tree)", "Blue Wooden Shield"), + DS3LocationData("US: Cleric Hat (graveyard by white tree)", "Cleric Hat"), + DS3LocationData("US: Cleric Blue Robe (graveyard by white tree)", "Cleric Blue Robe"), + DS3LocationData("US: Cleric Gloves (graveyard by white tree)", "Cleric Gloves"), + DS3LocationData("US: Cleric Trousers (graveyard by white tree)", "Cleric Trousers"), DS3LocationData("US: Soul of an Unknown Traveler (portcullis by burning tree)", - "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("US: Charcoal Pine Resin (hanging corpse room)", "Charcoal Pine Resin x2", - DS3LocationCategory.MISC), - DS3LocationData("US: Loincloth (by Velka statue)", "Loincloth", DS3LocationCategory.ARMOR), + "Soul of an Unknown Traveler"), + DS3LocationData("US: Charcoal Pine Resin (hanging corpse room)", "Charcoal Pine Resin x2"), + DS3LocationData("US: Loincloth (by Velka statue)", "Loincloth"), DS3LocationData("US: Bloodbite Ring (miniboss in sewer)", "Bloodbite Ring", - DS3LocationCategory.RING, miniboss = True), # Giant Rat drop - DS3LocationData("US: Charcoal Pine Bundle (first building)", "Charcoal Pine Bundle x2", - DS3LocationCategory.MISC), + miniboss = True), # Giant Rat drop + DS3LocationData("US: Charcoal Pine Bundle (first building)", "Charcoal Pine Bundle x2"), DS3LocationData("US: Soul of an Unknown Traveler (on the way to Dilapidated Bridge, in crates)", - "Soul of an Unknown Traveler", DS3LocationCategory.MISC, hidden = True), + "Soul of an Unknown Traveler", hidden = True), DS3LocationData("US: Titanite Shard (on the way to Dilapidated Bridge, up ladder)", - "Titanite Shard", DS3LocationCategory.MISC), - DS3LocationData("US: Red Hilted Halberd (chasm crypt)", "Red Hilted Halberd", - DS3LocationCategory.WEAPON), - DS3LocationData("US: Rusted Coin (wooden ledge above Dilapidated Bridge)", "Rusted Coin x2", - DS3LocationCategory.MISC), - DS3LocationData("US: Caestus (sewer)", "Caestus", DS3LocationCategory.WEAPON), - DS3LocationData("US: Saint's Talisman (chasm, by ladder)", "Saint's Talisman", - DS3LocationCategory.WEAPON), + "Titanite Shard"), + DS3LocationData("US: Red Hilted Halberd (chasm crypt)", "Red Hilted Halberd"), + DS3LocationData("US: Rusted Coin (wooden ledge above Dilapidated Bridge)", + "Rusted Coin x2"), + DS3LocationData("US: Caestus (sewer)", "Caestus"), + DS3LocationData("US: Saint's Talisman (chasm, by ladder)", "Saint's Talisman"), DS3LocationData("US: Alluring Skull (on the way to tower, behind building)", - "Alluring Skull x3", DS3LocationCategory.MISC), - DS3LocationData("US: Large Club (tower village, by miniboss)", "Large Club", - DS3LocationCategory.WEAPON), - DS3LocationData("US: Titanite Shard (chasm #1)", "Titanite Shard", - DS3LocationCategory.UPGRADE), - DS3LocationData("US: Titanite Shard (chasm #2)", "Titanite Shard", - DS3LocationCategory.UPGRADE), - DS3LocationData("US: Fading Soul (outside stable)", "Fading Soul", - DS3LocationCategory.MISC), + "Alluring Skull x3"), + DS3LocationData("US: Large Club (tower village, by miniboss)", "Large Club"), + DS3LocationData("US: Titanite Shard (chasm #1)", "Titanite Shard"), + DS3LocationData("US: Titanite Shard (chasm #2)", "Titanite Shard"), + DS3LocationData("US: Fading Soul (outside stable)", "Fading Soul"), DS3LocationData("US: Titanite Shard (lower path to Cliff Underside)", "Titanite Shard", - DS3LocationCategory.UPGRADE, hidden = True), # hidden fall - DS3LocationData("US: Hand Axe (by Cornyx)", "Hand Axe", DS3LocationCategory.WEAPON), + hidden = True), # hidden fall + DS3LocationData("US: Hand Axe (by Cornyx)", "Hand Axe"), DS3LocationData("US: Soul of an Unknown Traveler (pillory past stable)", - "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("US: Ember (by stairs to boss)", "Ember", DS3LocationCategory.MISC), + "Soul of an Unknown Traveler"), + DS3LocationData("US: Ember (by stairs to boss)", "Ember"), DS3LocationData("US: Mirrah Vest (tower village, jump from roof)", "Mirrah Vest", - DS3LocationCategory.ARMOR, hidden = True), # Hidden fall + hidden = True), # Hidden fall DS3LocationData("US: Mirrah Gloves (tower village, jump from roof)", "Mirrah Gloves", - DS3LocationCategory.ARMOR, hidden = True), # Hidden fall + hidden = True), # Hidden fall DS3LocationData("US: Mirrah Trousers (tower village, jump from roof)", "Mirrah Trousers", - DS3LocationCategory.ARMOR, hidden = True), # Hidden fall - DS3LocationData("US: Plank Shield (outside stable, by NPC)", "Plank Shield", - DS3LocationCategory.SHIELD), + hidden = True), # Hidden fall + DS3LocationData("US: Plank Shield (outside stable, by NPC)", "Plank Shield"), DS3LocationData("US: Red Bug Pellet (tower village building, basement)", - "Red Bug Pellet x2", DS3LocationCategory.MISC), + "Red Bug Pellet x2"), DS3LocationData("US: Chloranthy Ring (tower village, jump from roof)", "Chloranthy Ring", - DS3LocationCategory.RING, hidden = True), # Hidden fall - DS3LocationData("US: Fire Clutch Ring (wooden walkway past stable)", "Fire Clutch Ring", - DS3LocationCategory.RING), - DS3LocationData("US: Estus Shard (under burning tree)", "Estus Shard", - DS3LocationCategory.HEALTH), - DS3LocationData("US: Firebomb (stable roof)", "Firebomb x6", DS3LocationCategory.MISC), + hidden = True), # Hidden fall + DS3LocationData("US: Fire Clutch Ring (wooden walkway past stable)", "Fire Clutch Ring"), + DS3LocationData("US: Estus Shard (under burning tree)", "Estus Shard"), + DS3LocationData("US: Firebomb (stable roof)", "Firebomb x6"), # In enemy rando, the enemy may not burst through the wall and make this room obvious DS3LocationData("US: Whip (on the way to Dilapidated Bridge, behind wooden wall)", - "Whip", DS3LocationCategory.WEAPON, hidden = True), - DS3LocationData("US: Great Scythe (building by white tree, balcony)", "Great Scythe", - DS3LocationCategory.WEAPON), - DS3LocationData("US: Homeward Bone (by Yoel)", "Homeward Bone x2", - DS3LocationCategory.MISC), + "Whip", hidden = True), + DS3LocationData("US: Great Scythe (building by white tree, balcony)", "Great Scythe"), + DS3LocationData("US: Homeward Bone (by Yoel)", "Homeward Bone x2"), DS3LocationData("US: Large Soul of a Deserted Corpse (around corner by Cliff Underside)", - "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL, - hidden = True), # Hidden corner - DS3LocationData("US: Ember (behind burning tree)", "Ember", DS3LocationCategory.MISC), + "Large Soul of a Deserted Corpse", hidden = True), # Hidden corner + DS3LocationData("US: Ember (behind burning tree)", "Ember"), DS3LocationData("US: Large Soul of a Deserted Corpse (across from Foot of the High Wall)", - "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("US: Fading Soul (by white tree)", "Fading Soul", DS3LocationCategory.MISC), - DS3LocationData("US: Young White Branch (by white tree #1)", "Young White Branch", - DS3LocationCategory.MISC), - DS3LocationData("US: Ember (by white tree)", "Ember", DS3LocationCategory.MISC), + "Large Soul of a Deserted Corpse"), + DS3LocationData("US: Fading Soul (by white tree)", "Fading Soul"), + DS3LocationData("US: Young White Branch (by white tree #1)", "Young White Branch"), + DS3LocationData("US: Ember (by white tree)", "Ember"), DS3LocationData("US: Large Soul of a Deserted Corpse (by white tree)", - "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), - DS3LocationData("US: Young White Branch (by white tree #2)", "Young White Branch", - DS3LocationCategory.MISC), - DS3LocationData("US: Reinforced Club (by white tree)", "Reinforced Club", - DS3LocationCategory.WEAPON), + "Large Soul of a Deserted Corpse"), + DS3LocationData("US: Young White Branch (by white tree #2)", "Young White Branch"), + DS3LocationData("US: Reinforced Club (by white tree)", "Reinforced Club"), DS3LocationData("US: Soul of a Nameless Soldier (top of tower)", - "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + "Soul of a Nameless Soldier"), DS3LocationData("US: Loretta's Bone (first building, hanging corpse on balcony)", - "Loretta's Bone", DS3LocationCategory.KEY), - DS3LocationData("US: Northern Helm (tower village, hanging corpse)", "Northern Helm", - DS3LocationCategory.ARMOR), - DS3LocationData("US: Northern Armor (tower village, hanging corpse)", "Northern Armor", - DS3LocationCategory.ARMOR), - DS3LocationData("US: Northern Gloves (tower village, hanging corpse)", "Northern Gloves", - DS3LocationCategory.ARMOR), - DS3LocationData("US: Northern Trousers (tower village, hanging corpse)", "Northern Trousers", - DS3LocationCategory.ARMOR), + "Loretta's Bone"), + DS3LocationData("US: Northern Helm (tower village, hanging corpse)", "Northern Helm"), + DS3LocationData("US: Northern Armor (tower village, hanging corpse)", "Northern Armor"), + DS3LocationData("US: Northern Gloves (tower village, hanging corpse)", "Northern Gloves"), + DS3LocationData("US: Northern Trousers (tower village, hanging corpse)", + "Northern Trousers"), DS3LocationData("US: Partizan (hanging corpse above Cliff Underside)", "Partizan", - DS3LocationCategory.WEAPON, missable = True), # requires projectile + missable = True), # requires projectile DS3LocationData("US: Flame Stoneplate Ring (hanging corpse by Mound-Maker transport)", - "Flame Stoneplate Ring", DS3LocationCategory.RING), + "Flame Stoneplate Ring"), DS3LocationData("US: Red and White Shield (chasm, hanging corpse)", "Red and White Shield", - DS3LocationCategory.SHIELD, offline = "02,0:53100740::", - missable = True), # requires projectile + offline = "02,0:53100740::", missable = True), # requires projectile DS3LocationData("US: Small Leather Shield (first building, hanging corpse by entrance)", - "Small Leather Shield", DS3LocationCategory.SHIELD), - DS3LocationData("US: Pale Tongue (tower village, hanging corpse)", "Pale Tongue", - DS3LocationCategory.MISC), + "Small Leather Shield"), + DS3LocationData("US: Pale Tongue (tower village, hanging corpse)", "Pale Tongue"), DS3LocationData("US: Large Soul of a Deserted Corpse (hanging corpse room, over stairs)", - "Large Soul of a Deserted Corpse", DS3LocationCategory.SOUL), + "Large Soul of a Deserted Corpse"), DS3LocationData("US: Kukri (hanging corpse above burning tree)", "Kukri x9", - DS3LocationCategory.MISC, missable = True), # requires projectile - DS3LocationData("US: Life Ring+1 (tower on the way to village)", "Life Ring+1", - DS3LocationCategory.RING, ngp = True), - DS3LocationData("US: Poisonbite Ring+1 (graveyard by white tree, near well)", "Poisonbite Ring+1", - DS3LocationCategory.RING, ngp = True), + missable = True), # requires projectile + DS3LocationData("US: Life Ring+1 (tower on the way to village)", "Life Ring+1", ngp = True), + DS3LocationData("US: Poisonbite Ring+1 (graveyard by white tree, near well)", + "Poisonbite Ring+1", ngp = True), DS3LocationData("US: Covetous Silver Serpent Ring+2 (tower village, drop down from roof)", - "Covetous Silver Serpent Ring+2", DS3LocationCategory.RING, ngp = True, - hidden = True), # Hidden fall + "Covetous Silver Serpent Ring+2", ngp = True, hidden = True), # Hidden fall DS3LocationData("US: Human Pine Resin (tower village building, chest upstairs)", - "Human Pine Resin x4", DS3LocationCategory.MISC), - DS3LocationData("US: Homeward Bone (tower village, right of first drop)", "Homeward Bone", - DS3LocationCategory.MISC), + "Human Pine Resin x4"), + DS3LocationData("US: Homeward Bone (tower village, right of first drop)", "Homeward Bone"), DS3LocationData("US: Irithyll Straight Sword (miniboss drop, by Road of Sacrifices)", - "Irithyll Straight Sword", DS3LocationCategory.WEAPON, miniboss = True), - DS3LocationData("US: Fire Gem (tower village, miniboss drop)", "Fire Gem", - DS3LocationCategory.UPGRADE, miniboss = True), + "Irithyll Straight Sword", miniboss = True), + DS3LocationData("US: Fire Gem (tower village, miniboss drop)", "Fire Gem", miniboss = True), DS3LocationData("US: Warrior of Sunlight (hanging corpse room, drop through hole)", - "Warrior of Sunlight", DS3LocationCategory.UNIQUE, - hidden = True), # hidden fall - DS3LocationData("US: Mound-makers (Hodrick)", "Mound-makers", DS3LocationCategory.UNIQUE, - missable = True), - DS3LocationData("US: Sharp Gem (lizard by Dilapidated Bridge)", "Sharp Gem", - DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("US: Heavy Gem (chasm, lizard)", "Heavy Gem", - DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("US: Siegbräu (Siegward)", "Siegbräu", DS3LocationCategory.MISC, - missable = True, npc = True), - DS3LocationData("US: Heavy Gem (Hawkwood)", "Heavy Gem", DS3LocationCategory.UPGRADE, - offline = '00,0:50006070::', missable = True, - npc = True), # Hawkwood (quest, after Greatwood or Sage) - DS3LocationData("US -> RS", None, DS3LocationCategory.EVENT), + "Warrior of Sunlight", hidden = True), # hidden fall + DS3LocationData("US: Mound-makers (Hodrick)", "Mound-makers", missable = True), + DS3LocationData("US: Sharp Gem (lizard by Dilapidated Bridge)", "Sharp Gem", lizard = True), + DS3LocationData("US: Heavy Gem (chasm, lizard)", "Heavy Gem", lizard = True), + DS3LocationData("US: Siegbräu (Siegward)", "Siegbräu", missable = True, npc = True), + DS3LocationData("US: Heavy Gem (Hawkwood)", "Heavy Gem", offline = '00,0:50006070::', + missable = True, npc = True), # Hawkwood (quest, after Greatwood or Sage) + DS3LocationData("US -> RS", None), # Yoel/Yuria of Londor - DS3LocationData("FS: Soul Arrow (Yoel/Yuria)", "Soul Arrow", DS3LocationCategory.SPELL, + DS3LocationData("FS: Soul Arrow (Yoel/Yuria)", "Soul Arrow", offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, shop = True), DS3LocationData("FS: Heavy Soul Arrow (Yoel/Yuria)", "Heavy Soul Arrow", - DS3LocationCategory.SPELL, offline = '99,0:-1:50000,110000,70000116:', + offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, shop = True), - DS3LocationData("FS: Magic Weapon (Yoel/Yuria)", "Magic Weapon", DS3LocationCategory.SPELL, + DS3LocationData("FS: Magic Weapon (Yoel/Yuria)", "Magic Weapon", offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, shop = True), - DS3LocationData("FS: Magic Shield (Yoel/Yuria)", "Magic Shield", DS3LocationCategory.SPELL, + DS3LocationData("FS: Magic Shield (Yoel/Yuria)", "Magic Shield", offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, shop = True), DS3LocationData("FS: Soul Greatsword (Yoel/Yuria)", "Soul Greatsword", - DS3LocationCategory.SPELL, offline = '99,0:-1:50000,110000,70000450,70000475:', missable = True, npc = True, shop = True), - DS3LocationData("FS: Dark Hand (Yoel/Yuria)", "Dark Hand", DS3LocationCategory.WEAPON, - missable = True, npc = True), - DS3LocationData("FS: Untrue White Ring (Yoel/Yuria)", "Untrue White Ring", - DS3LocationCategory.RING, missable = True, npc = True), - DS3LocationData("FS: Untrue Dark Ring (Yoel/Yuria)", "Untrue Dark Ring", - DS3LocationCategory.RING, missable = True, npc = True), + DS3LocationData("FS: Dark Hand (Yoel/Yuria)", "Dark Hand", missable = True, npc = True), + DS3LocationData("FS: Untrue White Ring (Yoel/Yuria)", "Untrue White Ring", missable = True, + npc = True), + DS3LocationData("FS: Untrue Dark Ring (Yoel/Yuria)", "Untrue Dark Ring", missable = True, + npc = True), DS3LocationData("FS: Londor Braille Divine Tome (Yoel/Yuria)", "Londor Braille Divine Tome", - DS3LocationCategory.UNIQUE, offline = '99,0:-1:40000,110000,70000116:', - missable = True, npc = True), - DS3LocationData("FS: Darkdrift (Yoel/Yuria)", "Darkdrift", DS3LocationCategory.WEAPON, - missable = True, drop = True, npc = True), # kill her or kill Soul of Cinder + offline = '99,0:-1:40000,110000,70000116:', missable = True, npc = True), + DS3LocationData("FS: Darkdrift (Yoel/Yuria)", "Darkdrift", missable = True, drop = True, + npc = True), # kill her or kill Soul of Cinder # Cornyx of the Great Swamp # These aren't missable because the Shrine Handmaid will carry them if you kill Cornyx. - DS3LocationData("FS: Fireball (Cornyx)", "Fireball", DS3LocationCategory.SPELL, npc = True, + DS3LocationData("FS: Fireball (Cornyx)", "Fireball", npc = True, shop = True), + DS3LocationData("FS: Fire Surge (Cornyx)", "Fire Surge", npc = True, shop = True), + DS3LocationData("FS: Great Combustion (Cornyx)", "Great Combustion", npc = True, shop = True), - DS3LocationData("FS: Fire Surge (Cornyx)", "Fire Surge", DS3LocationCategory.SPELL, - npc = True, shop = True), - DS3LocationData("FS: Great Combustion (Cornyx)", "Great Combustion", - DS3LocationCategory.SPELL, npc = True, shop = True), - DS3LocationData("FS: Flash Sweat (Cornyx)", "Flash Sweat", DS3LocationCategory.SPELL, - npc = True, shop = True), + DS3LocationData("FS: Flash Sweat (Cornyx)", "Flash Sweat", npc = True, shop = True), # These are missable if you kill Cornyx before giving him the right tomes. DS3LocationData("FS: Poison Mist (Cornyx for Great Swamp Tome)", "Poison Mist", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), - DS3LocationData("FS: Fire Orb (Cornyx for Great Swamp Tome)", "Fire Orb", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), + DS3LocationData("FS: Fire Orb (Cornyx for Great Swamp Tome)", "Fire Orb", missable = True, + npc = True, shop = True), DS3LocationData("FS: Profuse Sweat (Cornyx for Great Swamp Tome)", "Profuse Sweat", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("FS: Bursting Fireball (Cornyx for Great Swamp Tome)", "Bursting Fireball", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), - DS3LocationData("FS: Acid Surge (Cornyx for Carthus Tome)", "Acid Surge", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), + DS3LocationData("FS: Acid Surge (Cornyx for Carthus Tome)", "Acid Surge", missable = True, + npc = True, shop = True), DS3LocationData("FS: Carthus Flame Arc (Cornyx for Carthus Tome)", "Carthus Flame Arc", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("FS: Carthus Beacon (Cornyx for Carthus Tome)", "Carthus Beacon", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("FS: Great Chaos Fire Orb (Cornyx for Izalith Tome)", - "Great Chaos Fire Orb", DS3LocationCategory.SPELL, missable = True, + "Great Chaos Fire Orb", missable = True, npc = True, shop = True), + DS3LocationData("FS: Chaos Storm (Cornyx for Izalith Tome)", "Chaos Storm", missable = True, npc = True, shop = True), - DS3LocationData("FS: Chaos Storm (Cornyx for Izalith Tome)", "Chaos Storm", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), # Irina of Carim # These aren't in their own location because you don't actually need the Grave Key to access # Irena—you can just fall down the cliff near Eygon. - DS3LocationData("FS: Saint's Ring (Irina)", "Saint's Ring", DS3LocationCategory.RING, - npc = True, shop = True), - DS3LocationData("FS: Heal (Irina)", "Heal", DS3LocationCategory.SPELL, npc = True, - shop = True), - DS3LocationData("FS: Replenishment (Irina)", "Replenishment", DS3LocationCategory.SPELL, + DS3LocationData("FS: Saint's Ring (Irina)", "Saint's Ring", npc = True, shop = True), + DS3LocationData("FS: Heal (Irina)", "Heal", npc = True, shop = True), + DS3LocationData("FS: Replenishment (Irina)", "Replenishment", npc = True, shop = True), + DS3LocationData("FS: Caressing Tears (Irina)", "Caressing Tears", npc = True, shop = True), + DS3LocationData("FS: Homeward (Irina)", "Homeward", npc = True, shop = True), + DS3LocationData("FS: Med Heal (Irina for Tome of Carim)", "Med Heal", missable = True, npc = True, shop = True), - DS3LocationData("FS: Caressing Tears (Irina)", "Caressing Tears", DS3LocationCategory.SPELL, - npc = True, shop = True), - DS3LocationData("FS: Homeward (Irina)", "Homeward", DS3LocationCategory.SPELL, npc = True, - shop = True), - DS3LocationData("FS: Med Heal (Irina for Tome of Carim)", "Med Heal", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), DS3LocationData("FS: Tears of Denial (Irina for Tome of Carim)", "Tears of Denial", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), - DS3LocationData("FS: Force (Irina for Tome of Carim)", "Force", DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Force (Irina for Tome of Carim)", "Force", missable = True, npc = True, + shop = True), DS3LocationData("FS: Bountiful Light (Irina for Tome of Lothric)", "Bountiful Light", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("FS: Magic Barrier (Irina for Tome of Lothric)", "Magic Barrier", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("FS: Blessed Weapon (Irina for Tome of Lothric)", "Blessed Weapon", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), ], "Road of Sacrifices": [ - DS3LocationData("RS: Soul of a Crystal Sage", "Soul of a Crystal Sage", - DS3LocationCategory.SOUL, prominent = True, boss = True), + DS3LocationData("RS: Soul of a Crystal Sage", "Soul of a Crystal Sage", prominent = True, + boss = True), DS3LocationData("RS: Exile Greatsword (NPC drop by Farron Keep)", "Exile Greatsword", - DS3LocationCategory.WEAPON, hostile_npc = True), # Exile Knight #2 drop + hostile_npc = True), # Exile Knight #2 drop DS3LocationData("RS: Great Club (NPC drop by Farron Keep)", "Great Club", - DS3LocationCategory.WEAPON, hostile_npc = True), # Exile Knight #1 drop - DS3LocationData("RS: Heysel Pick (Heysel drop)", "Heysel Pick", DS3LocationCategory.WEAPON, - missable = True, hostile_npc = True), - DS3LocationData("RS: Xanthous Crown (Heysel drop)", "Xanthous Crown", - DS3LocationCategory.WEAPON, missable = True, hostile_npc = True), + hostile_npc = True), # Exile Knight #1 drop + DS3LocationData("RS: Heysel Pick (Heysel drop)", "Heysel Pick", missable = True, + hostile_npc = True), + DS3LocationData("RS: Xanthous Crown (Heysel drop)", "Xanthous Crown", missable = True, + hostile_npc = True), DS3LocationData("RS: Butcher Knife (NPC drop beneath road)", "Butcher Knife", - DS3LocationCategory.WEAPON, hostile_npc = True), # Madwoman - DS3LocationData("RS: Titanite Shard (water by Halfway Fortress)", "Titanite Shard", - DS3LocationCategory.UPGRADE), + hostile_npc = True), # Madwoman + DS3LocationData("RS: Titanite Shard (water by Halfway Fortress)", "Titanite Shard"), DS3LocationData("RS: Titanite Shard (woods, left of path from Halfway Fortress)", - "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("RS: Green Blossom (by deep water)", "Green Blossom x4", - DS3LocationCategory.MISC), - DS3LocationData("RS: Estus Shard (left of fire behind stronghold left room)", "Estus Shard", - DS3LocationCategory.HEALTH), + "Titanite Shard"), + DS3LocationData("RS: Green Blossom (by deep water)", "Green Blossom x4"), + DS3LocationData("RS: Estus Shard (left of fire behind stronghold left room)", + "Estus Shard"), DS3LocationData("RS: Ring of Sacrifice (stronghold, drop from right room balcony)", - "Ring of Sacrifice", DS3LocationCategory.MISC, hidden = True), # hidden fall + "Ring of Sacrifice", hidden = True), # hidden fall DS3LocationData("RS: Soul of an Unknown Traveler (drop along wall from Halfway Fortress)", - "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + "Soul of an Unknown Traveler"), DS3LocationData("RS: Fallen Knight Helm (water's edge by Farron Keep)", - "Fallen Knight Helm", DS3LocationCategory.ARMOR), + "Fallen Knight Helm"), DS3LocationData("RS: Fallen Knight Armor (water's edge by Farron Keep)", - "Fallen Knight Armor", DS3LocationCategory.ARMOR), + "Fallen Knight Armor"), DS3LocationData("RS: Fallen Knight Gauntlets (water's edge by Farron Keep)", - "Fallen Knight Gauntlets", DS3LocationCategory.ARMOR), + "Fallen Knight Gauntlets"), DS3LocationData("RS: Fallen Knight Trousers (water's edge by Farron Keep)", - "Fallen Knight Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("RS: Heretic's Staff (stronghold left room)", "Heretic's Staff", - DS3LocationCategory.WEAPON), + "Fallen Knight Trousers"), + DS3LocationData("RS: Heretic's Staff (stronghold left room)", "Heretic's Staff"), DS3LocationData("RS: Large Soul of an Unknown Traveler (left of stairs to Farron Keep)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("RS: Conjurator Hood (deep water)", "Conjurator Hood", - DS3LocationCategory.ARMOR), - DS3LocationData("RS: Conjurator Robe (deep water)", "Conjurator Robe", - DS3LocationCategory.ARMOR), - DS3LocationData("RS: Conjurator Manchettes (deep water)", "Conjurator Manchettes", - DS3LocationCategory.ARMOR), - DS3LocationData("RS: Conjurator Boots (deep water)", "Conjurator Boots", - DS3LocationCategory.ARMOR), + "Large Soul of an Unknown Traveler"), + DS3LocationData("RS: Conjurator Hood (deep water)", "Conjurator Hood"), + DS3LocationData("RS: Conjurator Robe (deep water)", "Conjurator Robe"), + DS3LocationData("RS: Conjurator Manchettes (deep water)", "Conjurator Manchettes"), + DS3LocationData("RS: Conjurator Boots (deep water)", "Conjurator Boots"), DS3LocationData("RS: Soul of an Unknown Traveler (right of door to stronghold left)", - "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + "Soul of an Unknown Traveler"), DS3LocationData("RS: Green Blossom (water by Crucifixion Woods bonfire)", - "Green Blossom x2", DS3LocationCategory.MISC), - DS3LocationData("RS: Great Swamp Pyromancy Tome (deep water)", "Great Swamp Pyromancy Tome", - DS3LocationCategory.UNIQUE), - DS3LocationData("RS: Homeward Bone (balcony by Farron Keep)", "Homeward Bone x2", - DS3LocationCategory.MISC), - DS3LocationData("RS: Titanite Shard (woods, surrounded by enemies)", "Titanite Shard", - DS3LocationCategory.MISC), + "Green Blossom x2"), + DS3LocationData("RS: Great Swamp Pyromancy Tome (deep water)", + "Great Swamp Pyromancy Tome"), + DS3LocationData("RS: Homeward Bone (balcony by Farron Keep)", "Homeward Bone x2"), + DS3LocationData("RS: Titanite Shard (woods, surrounded by enemies)", "Titanite Shard"), DS3LocationData("RS: Twin Dragon Greatshield (woods by Crucifixion Woods bonfire)", - "Twin Dragon Greatshield", DS3LocationCategory.SHIELD), + "Twin Dragon Greatshield"), DS3LocationData("RS: Sorcerer Hood (water beneath stronghold)", "Sorcerer Hood", - DS3LocationCategory.ARMOR, hidden = True), # Hidden fall + hidden = True), # Hidden fall DS3LocationData("RS: Sorcerer Robe (water beneath stronghold)", "Sorcerer Robe", - DS3LocationCategory.ARMOR, hidden = True), # Hidden fall + hidden = True), # Hidden fall DS3LocationData("RS: Sorcerer Gloves (water beneath stronghold)", "Sorcerer Gloves", - DS3LocationCategory.ARMOR, hidden = True), # Hidden fall + hidden = True), # Hidden fall DS3LocationData("RS: Sorcerer Trousers (water beneath stronghold)", "Sorcerer Trousers", - DS3LocationCategory.ARMOR, hidden = True), # Hidden fall + hidden = True), # Hidden fall DS3LocationData("RS: Sage Ring (water beneath stronghold)", "Sage Ring", - DS3LocationCategory.RING, hidden = True), # Hidden fall + hidden = True), # Hidden fall DS3LocationData("RS: Grass Crest Shield (water by Crucifixion Woods bonfire)", - "Grass Crest Shield", DS3LocationCategory.SHIELD), - DS3LocationData("RS: Ember (right of fire behind stronghold left room)", "Ember", - DS3LocationCategory.MISC), - DS3LocationData("RS: Blue Bug Pellet (broken stairs by Orbeck)", "Blue Bug Pellet x2", - DS3LocationCategory.MISC), + "Grass Crest Shield"), + DS3LocationData("RS: Ember (right of fire behind stronghold left room)", "Ember"), + DS3LocationData("RS: Blue Bug Pellet (broken stairs by Orbeck)", "Blue Bug Pellet x2"), DS3LocationData("RS: Soul of an Unknown Traveler (road, by wagon)", - "Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("RS: Shriving Stone (road, by start)", "Shriving Stone", - DS3LocationCategory.UPGRADE), + "Soul of an Unknown Traveler"), + DS3LocationData("RS: Shriving Stone (road, by start)", "Shriving Stone"), DS3LocationData("RS: Titanite Shard (road, on bridge after you go under)", - "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("RS: Brigand Twindaggers (beneath road)", "Brigand Twindaggers", - DS3LocationCategory.WEAPON), + "Titanite Shard"), + DS3LocationData("RS: Brigand Twindaggers (beneath road)", "Brigand Twindaggers"), DS3LocationData("RS: Braille Divine Tome of Carim (drop from bridge to Halfway Fortress)", - "Braille Divine Tome of Carim", DS3LocationCategory.UNIQUE, - hidden = True), # Hidden fall - DS3LocationData("RS: Ember (right of Halfway Fortress entrance)", "Ember", - DS3LocationCategory.MISC), - DS3LocationData("RS: Sellsword Twinblades (keep perimeter)", "Sellsword Twinblades", - DS3LocationCategory.WEAPON), + "Braille Divine Tome of Carim", hidden = True), # Hidden fall + DS3LocationData("RS: Ember (right of Halfway Fortress entrance)", "Ember"), + DS3LocationData("RS: Sellsword Twinblades (keep perimeter)", "Sellsword Twinblades"), DS3LocationData("RS: Golden Falcon Shield (path from stronghold right room to Farron Keep)", - "Golden Falcon Shield", DS3LocationCategory.SHIELD), - DS3LocationData("RS: Brigand Axe (beneath road)", "Brigand Axe", - DS3LocationCategory.WEAPON), - DS3LocationData("RS: Brigand Hood (beneath road)", "Brigand Hood", - DS3LocationCategory.ARMOR), - DS3LocationData("RS: Brigand Armor (beneath road)", "Brigand Armor", - DS3LocationCategory.ARMOR), - DS3LocationData("RS: Brigand Gauntlets (beneath road)", "Brigand Gauntlets", - DS3LocationCategory.ARMOR), - DS3LocationData("RS: Brigand Trousers (beneath road)", "Brigand Trousers", - DS3LocationCategory.ARMOR), + "Golden Falcon Shield"), + DS3LocationData("RS: Brigand Axe (beneath road)", "Brigand Axe"), + DS3LocationData("RS: Brigand Hood (beneath road)", "Brigand Hood"), + DS3LocationData("RS: Brigand Armor (beneath road)", "Brigand Armor"), + DS3LocationData("RS: Brigand Gauntlets (beneath road)", "Brigand Gauntlets"), + DS3LocationData("RS: Brigand Trousers (beneath road)", "Brigand Trousers"), DS3LocationData("RS: Morne's Ring (drop from bridge to Halfway Fortress)", "Morne's Ring", - DS3LocationCategory.RING, hidden = True), # Hidden fall - DS3LocationData("RS: Sellsword Helm (keep perimeter balcony)", "Sellsword Helm", - DS3LocationCategory.ARMOR), - DS3LocationData("RS: Sellsword Armor (keep perimeter balcony)", "Sellsword Armor", - DS3LocationCategory.ARMOR), - DS3LocationData("RS: Sellsword Gauntlet (keep perimeter balcony)", "Sellsword Gauntlet", - DS3LocationCategory.ARMOR), - DS3LocationData("RS: Sellsword Trousers (keep perimeter balcony)", "Sellsword Trousers", - DS3LocationCategory.ARMOR), - DS3LocationData("RS: Farron Coal (keep perimeter)", "Farron Coal", - DS3LocationCategory.UNIQUE), + hidden = True), # Hidden fall + DS3LocationData("RS: Sellsword Helm (keep perimeter balcony)", "Sellsword Helm"), + DS3LocationData("RS: Sellsword Armor (keep perimeter balcony)", "Sellsword Armor"), + DS3LocationData("RS: Sellsword Gauntlet (keep perimeter balcony)", "Sellsword Gauntlet"), + DS3LocationData("RS: Sellsword Trousers (keep perimeter balcony)", "Sellsword Trousers"), + DS3LocationData("RS: Farron Coal (keep perimeter)", "Farron Coal"), DS3LocationData("RS: Chloranthy Ring+2 (road, drop across from carriage)", - "Chloranthy Ring+2", DS3LocationCategory.RING, hidden = True, - ngp = True), # Hidden fall + "Chloranthy Ring+2", hidden = True, ngp = True), # Hidden fall DS3LocationData("RS: Lingering Dragoncrest Ring+1 (water)", "Lingering Dragoncrest Ring+1", - DS3LocationCategory.RING, ngp = True), + ngp = True), DS3LocationData("RS: Great Swamp Ring (miniboss drop, by Farron Keep)", - "Great Swamp Ring", DS3LocationCategory.RING, - miniboss = True), # Giant Crab drop - DS3LocationData("RS: Blue Sentinels (Horace)", "Blue Sentinels", DS3LocationCategory.UNIQUE, + "Great Swamp Ring", miniboss = True), # Giant Crab drop + DS3LocationData("RS: Blue Sentinels (Horace)", "Blue Sentinels", missable = True, npc = True), # Horace quest - DS3LocationData("RS: Crystal Gem (stronghold, lizard)", "Crystal Gem", - DS3LocationCategory.UPGRADE), + DS3LocationData("RS: Crystal Gem (stronghold, lizard)", "Crystal Gem"), DS3LocationData("RS: Fading Soul (woods by Crucifixion Woods bonfire)", "Fading Soul", - DS3LocationCategory.MISC, offline = '03,0:53300210::'), + offline = '03,0:53300210::'), # Orbeck shop, all missable because he'll disappear if you don't talk to him for too long or # if you don't give him a scroll. - DS3LocationData("FS: Farron Dart (Orbeck)", "Farron Dart", DS3LocationCategory.SPELL, + DS3LocationData("FS: Farron Dart (Orbeck)", "Farron Dart", offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), - DS3LocationData("FS: Soul Arrow (Orbeck)", "Soul Arrow", DS3LocationCategory.SPELL, + DS3LocationData("FS: Soul Arrow (Orbeck)", "Soul Arrow", offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), - DS3LocationData("FS: Great Soul Arrow (Orbeck)", "Great Soul Arrow", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + DS3LocationData("FS: Great Soul Arrow (Orbeck)", "Great Soul Arrow", missable = True, + npc = True, shop = True), DS3LocationData("FS: Heavy Soul Arrow (Orbeck)", "Heavy Soul Arrow", - DS3LocationCategory.SPELL, offline = '99,0:-1:110000,130100,70000111:', - missable = True, npc = True, shop = True), + offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, + shop = True), DS3LocationData("FS: Great Heavy Soul Arrow (Orbeck)", "Great Heavy Soul Arrow", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), - DS3LocationData("FS: Magic Weapon (Orbeck)", "Magic Weapon", DS3LocationCategory.SPELL, + missable = True, npc = True, shop = True), + DS3LocationData("FS: Magic Weapon (Orbeck)", "Magic Weapon", offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), - DS3LocationData("FS: Magic Shield (Orbeck)", "Magic Shield", DS3LocationCategory.SPELL, + DS3LocationData("FS: Magic Shield (Orbeck)", "Magic Shield", offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), - DS3LocationData("FS: Spook (Orbeck)", "Spook", DS3LocationCategory.SPELL, missable = True, - npc = True, shop = True), - DS3LocationData("FS: Aural Decoy (Orbeck)", "Aural Decoy", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + DS3LocationData("FS: Spook (Orbeck)", "Spook", missable = True, npc = True, shop = True), + DS3LocationData("FS: Aural Decoy (Orbeck)", "Aural Decoy", missable = True, npc = True, + shop = True), DS3LocationData("FS: Soul Greatsword (Orbeck)", "Soul Greatsword", - DS3LocationCategory.SPELL, offline = '99,0:-1:110000,130100,70000111:', - missable = True, npc = True), - DS3LocationData("FS: Farron Flashsword (Orbeck)", "Farron Flashsword", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True), + DS3LocationData("FS: Farron Flashsword (Orbeck)", "Farron Flashsword", missable = True, + npc = True, shop = True), DS3LocationData("FS: Pestilent Mist (Orbeck for any scroll)", "Pestilent Mist", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("FS: Great Farron Dart (Orbeck for Sage's Scroll)", "Great Farron Dart", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("FS: Farron Hail (Orbeck for Sage's Scroll)", "Farron Hail", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("FS: Homing Soulmass (Orbeck for Logan's Scroll)", "Homing Soulmass", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("FS: Soul Spear (Orbeck for Logan's Scroll)", "Soul Spear", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("FS: Homing Crystal Soulmass (Orbeck for Crystal Scroll)", - "Homing Crystal Soulmass", DS3LocationCategory.SPELL, missable = True, - npc = True, shop = True), + "Homing Crystal Soulmass", missable = True, npc = True, shop = True), DS3LocationData("FS: Crystal Soul Spear (Orbeck for Crystal Scroll)", "Crystal Soul Spear", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("FS: Crystal Magic Weapon (Orbeck for Crystal Scroll)", - "Crystal Magic Weapon", DS3LocationCategory.SPELL, missable = True, + "Crystal Magic Weapon", missable = True, npc = True, shop = True), + DS3LocationData("FS: Cast Light (Orbeck for Golden Scroll)", "Cast Light", missable = True, npc = True, shop = True), - DS3LocationData("FS: Cast Light (Orbeck for Golden Scroll)", "Cast Light", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), DS3LocationData("FS: Twisted Wall of Light (Orbeck for Golden Scroll)", - "Twisted Wall of Light", DS3LocationCategory.SPELL, missable = True, - npc = True, shop = True), + "Twisted Wall of Light", missable = True, npc = True, shop = True), DS3LocationData("FS: Hidden Weapon (Orbeck for Golden Scroll)", "Hidden Weapon", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("FS: Hidden Body (Orbeck for Golden Scroll)", "Hidden Body", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), - DS3LocationData("FS: Repair (Orbeck for Golden Scroll)", "Repair", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), + DS3LocationData("FS: Repair (Orbeck for Golden Scroll)", "Repair", missable = True, + npc = True, shop = True), DS3LocationData("FS: Clandestine Coat (shop with Orbeck's Ashes)", "Clandestine Coat", - DS3LocationCategory.ARMOR, missable = True, npc = True, + missable = True, npc = True, shop = True), # Shrine Handmaid with Orbeck's Ashes + reload DS3LocationData("FS: Young Dragon Ring (Orbeck for one scroll and buying three spells)", - "Young Dragon Ring", DS3LocationCategory.RING, missable = True, npc = True), + "Young Dragon Ring", missable = True, npc = True), DS3LocationData("FS: Slumbering Dragoncrest Ring (Orbeck for buying four specific spells)", - "Slumbering Dragoncrest Ring", DS3LocationCategory.RING, missable = True, - npc = True), - DS3LocationData("RS -> CD", None, DS3LocationCategory.EVENT), - DS3LocationData("RS -> FK", None, DS3LocationCategory.EVENT), + "Slumbering Dragoncrest Ring", missable = True, npc = True), + DS3LocationData("RS -> CD", None), + DS3LocationData("RS -> FK", None), # Shrine Handmaid after killing exiles DS3LocationData("FS: Exile Mask (shop after killing NPCs in RS)", "Exile Mask", - DS3LocationCategory.ARMOR, hidden = True, hostile_npc = True, shop = True), - DS3LocationData("FS: Exile Armor (shop after killing NPCs in RS)", - "Exile Armor", DS3LocationCategory.ARMOR, hidden = True, - hostile_npc = True, shop = True), - DS3LocationData("FS: Exile Gauntlets (shop after killing NPCs in RS)", - "Exile Gauntlets", DS3LocationCategory.ARMOR, hidden = True, - hostile_npc = True, shop = True), - DS3LocationData("FS: Exile Leggings (shop after killing NPCs in RS)", - "Exile Leggings", DS3LocationCategory.ARMOR, hidden = True, - hostile_npc = True, shop = True), + hostile_npc = True, shop = True, hidden = True), + DS3LocationData("FS: Exile Armor (shop after killing NPCs in RS)", "Exile Armor", + hostile_npc = True, shop = True, hidden = True), + DS3LocationData("FS: Exile Gauntlets (shop after killing NPCs in RS)", "Exile Gauntlets", + hostile_npc = True, shop = True, hidden = True), + DS3LocationData("FS: Exile Leggings (shop after killing NPCs in RS)", "Exile Leggings", + hostile_npc = True, shop = True, hidden = True), # Shrine Handmaid after killing Crystal Sage - DS3LocationData("FS: Sage's Big Hat (shop after killing RS boss)", - "Sage's Big Hat", DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Sage's Big Hat (shop after killing RS boss)", "Sage's Big Hat", + boss = True, shop = True), # Yuria of Londor for Orbeck's Ashes DS3LocationData("FS: Morion Blade (Yuria for Orbeck's Ashes)", "Morion Blade", - DS3LocationCategory.WEAPON, missable = True, npc = True), + missable = True, npc = True), ], "Cathedral of the Deep": [ - DS3LocationData("CD: Herald Helm (path, by fire)", "Herald Helm", - DS3LocationCategory.ARMOR), - DS3LocationData("CD: Herald Armor (path, by fire)", "Herald Armor", - DS3LocationCategory.ARMOR), - DS3LocationData("CD: Herald Gloves (path, by fire)", "Herald Gloves", - DS3LocationCategory.ARMOR), - DS3LocationData("CD: Herald Trousers (path, by fire)", "Herald Trousers", - DS3LocationCategory.ARMOR), + DS3LocationData("CD: Herald Helm (path, by fire)", "Herald Helm"), + DS3LocationData("CD: Herald Armor (path, by fire)", "Herald Armor"), + DS3LocationData("CD: Herald Gloves (path, by fire)", "Herald Gloves"), + DS3LocationData("CD: Herald Trousers (path, by fire)", "Herald Trousers"), DS3LocationData("CD: Twinkling Titanite (path, lizard #1)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), DS3LocationData("CD: Twinkling Titanite (path, lizard #2)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("CD: Small Doll (boss drop)", "Small Doll", DS3LocationCategory.KEY, - prominent = True, progression = True, boss = True), + lizard = True), + DS3LocationData("CD: Small Doll (boss drop)", "Small Doll", prominent = True, + progression = True, boss = True), DS3LocationData("CD: Soul of the Deacons of the Deep", "Soul of the Deacons of the Deep", - DS3LocationCategory.SOUL, boss = True), + boss = True), DS3LocationData("CD: Black Eye Orb (Rosaria from Leonhard's quest)", "Black Eye Orb", - DS3LocationCategory.UNIQUE, missable = True, npc = True), - DS3LocationData("CD: Winged Spear (kill Patches)", "Winged Spear", - DS3LocationCategory.WEAPON, drop = True, missable = True), # Patches (kill) + missable = True, npc = True), + DS3LocationData("CD: Winged Spear (kill Patches)", "Winged Spear", drop = True, + missable = True), # Patches (kill) DS3LocationData("CD: Spider Shield (NPC drop on path)", "Spider Shield", - DS3LocationCategory.SHIELD, hostile_npc = True), # Brigand - DS3LocationData("CD: Notched Whip (Cleansing Chapel)", "Notched Whip", - DS3LocationCategory.WEAPON), + hostile_npc = True), # Brigand + DS3LocationData("CD: Notched Whip (Cleansing Chapel)", "Notched Whip"), DS3LocationData("CD: Titanite Shard (Cleansing Chapel windowsill, by miniboss)", - "Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("CD: Astora Greatsword (graveyard, left of entrance)", "Astora Greatsword", - DS3LocationCategory.WEAPON), + "Titanite Shard"), + DS3LocationData("CD: Astora Greatsword (graveyard, left of entrance)", "Astora Greatsword"), DS3LocationData("CD: Executioner's Greatsword (graveyard, far end)", - "Executioner's Greatsword", DS3LocationCategory.WEAPON), - DS3LocationData("CD: Undead Bone Shard (gravestone by white tree)", "Undead Bone Shard", - DS3LocationCategory.HEALTH), + "Executioner's Greatsword"), + DS3LocationData("CD: Undead Bone Shard (gravestone by white tree)", "Undead Bone Shard"), DS3LocationData("CD: Curse Ward Greatshield (by ladder from white tree to moat)", - "Curse Ward Greatshield", DS3LocationCategory.SHIELD), - DS3LocationData("CD: Titanite Shard (moat, far end)", "Titanite Shard", - DS3LocationCategory.MISC), + "Curse Ward Greatshield"), + DS3LocationData("CD: Titanite Shard (moat, far end)", "Titanite Shard"), DS3LocationData("CD: Large Soul of an Unknown Traveler (lower roofs, semicircle balcony)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + "Large Soul of an Unknown Traveler"), DS3LocationData("CD: Paladin's Ashes (path, guarded by lower NPC)", "Paladin's Ashes", - DS3LocationCategory.KEY, progression = True), - DS3LocationData("CD: Arbalest (upper roofs, end of furthest buttress)", "Arbalest", - DS3LocationCategory.WEAPON), - DS3LocationData("CD: Ember (by back door)", "Ember", DS3LocationCategory.MISC), - DS3LocationData("CD: Ember (side chapel upstairs, up ladder)", "Ember", - DS3LocationCategory.MISC), - DS3LocationData("CD: Poisonbite Ring (moat, hall past miniboss)", "Poisonbite Ring", - DS3LocationCategory.RING), - DS3LocationData("CD: Drang Armor (main hall, east)", "Drang Armor", - DS3LocationCategory.ARMOR), - DS3LocationData("CD: Ember (edge of platform before boss)", "Ember", - DS3LocationCategory.MISC), - DS3LocationData("CD: Duel Charm (next to Patches in onion armor)", "Duel Charm x3", - DS3LocationCategory.MISC), - DS3LocationData("CD: Seek Guidance (side chapel upstairs)", "Seek Guidance", - DS3LocationCategory.SPELL), - DS3LocationData("CD: Estus Shard (monument outside Cleansing Chapel)", "Estus Shard", - DS3LocationCategory.HEALTH), - DS3LocationData("CD: Maiden Hood (main hall south)", "Maiden Hood", - DS3LocationCategory.ARMOR), - DS3LocationData("CD: Maiden Robe (main hall south)", "Maiden Robe", - DS3LocationCategory.ARMOR), - DS3LocationData("CD: Maiden Gloves (main hall south)", "Maiden Gloves", - DS3LocationCategory.ARMOR), - DS3LocationData("CD: Maiden Skirt (main hall south)", "Maiden Skirt", - DS3LocationCategory.ARMOR), - DS3LocationData("CD: Pale Tongue (upper roofs, outdoors far end)", "Pale Tongue", - DS3LocationCategory.MISC, hidden = True), - DS3LocationData("CD: Fading Soul (graveyard, far end)", "Fading Soul", - DS3LocationCategory.MISC), - DS3LocationData("CD: Blessed Gem (upper roofs, rafters)", "Blessed Gem", - DS3LocationCategory.UPGRADE), - DS3LocationData("CD: Red Bug Pellet (right of cathedral front doors)", - "Red Bug Pellet", DS3LocationCategory.MISC), + progression = True), + DS3LocationData("CD: Arbalest (upper roofs, end of furthest buttress)", "Arbalest"), + DS3LocationData("CD: Ember (by back door)", "Ember"), + DS3LocationData("CD: Ember (side chapel upstairs, up ladder)", "Ember"), + DS3LocationData("CD: Poisonbite Ring (moat, hall past miniboss)", "Poisonbite Ring"), + DS3LocationData("CD: Drang Armor (main hall, east)", "Drang Armor"), + DS3LocationData("CD: Ember (edge of platform before boss)", "Ember"), + DS3LocationData("CD: Duel Charm (next to Patches in onion armor)", "Duel Charm x3"), + DS3LocationData("CD: Seek Guidance (side chapel upstairs)", "Seek Guidance"), + DS3LocationData("CD: Estus Shard (monument outside Cleansing Chapel)", "Estus Shard"), + DS3LocationData("CD: Maiden Hood (main hall south)", "Maiden Hood"), + DS3LocationData("CD: Maiden Robe (main hall south)", "Maiden Robe"), + DS3LocationData("CD: Maiden Gloves (main hall south)", "Maiden Gloves"), + DS3LocationData("CD: Maiden Skirt (main hall south)", "Maiden Skirt"), + DS3LocationData("CD: Pale Tongue (upper roofs, outdoors far end)", "Pale Tongue"), + DS3LocationData("CD: Fading Soul (graveyard, far end)", "Fading Soul"), + DS3LocationData("CD: Blessed Gem (upper roofs, rafters)", "Blessed Gem"), + DS3LocationData("CD: Red Bug Pellet (right of cathedral front doors)", "Red Bug Pellet"), DS3LocationData("CD: Soul of a Nameless Soldier (main hall south)", - "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("CD: Duel Charm (by first elevator)", "Duel Charm", - DS3LocationCategory.MISC), + "Soul of a Nameless Soldier"), + DS3LocationData("CD: Duel Charm (by first elevator)", "Duel Charm"), DS3LocationData("CD: Large Soul of an Unknown Traveler (main hall south, side path)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("CD: Ember (side chapel, miniboss room)", "Ember", - DS3LocationCategory.MISC), - DS3LocationData("CD: Repair Powder (by white tree)", "Repair Powder x3", - DS3LocationCategory.MISC), + "Large Soul of an Unknown Traveler"), + DS3LocationData("CD: Ember (side chapel, miniboss room)", "Ember"), + DS3LocationData("CD: Repair Powder (by white tree)", "Repair Powder x3"), DS3LocationData("CD: Large Soul of an Unknown Traveler (by white tree #1)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + "Large Soul of an Unknown Traveler"), DS3LocationData("CD: Large Soul of an Unknown Traveler (by white tree #2)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + "Large Soul of an Unknown Traveler"), DS3LocationData("CD: Undead Hunter Charm (lower roofs, up stairs between buttresses", - "Undead Hunter Charm x3", DS3LocationCategory.MISC), + "Undead Hunter Charm x3"), DS3LocationData("CD: Red Bug Pellet (lower roofs, up stairs between buttresses)", - "Red Bug Pellet x3", DS3LocationCategory.MISC), - DS3LocationData("CD: Titanite Shard (outside building by white tree)", - "Titanite Shard", DS3LocationCategory.UPGRADE, + "Red Bug Pellet x3"), + DS3LocationData("CD: Titanite Shard (outside building by white tree)", "Titanite Shard", hidden = True), # Easily missable side path - DS3LocationData("CD: Titanite Shard (moat, up a slope)", "Titanite Shard", - DS3LocationCategory.UPGRADE), + DS3LocationData("CD: Titanite Shard (moat, up a slope)", "Titanite Shard"), DS3LocationData("CD: Rusted Coin (left of cathedral front doors, behind crates)", - "Rusted Coin x2", DS3LocationCategory.MISC, hidden = True), - DS3LocationData("CD: Drang Hammers (main hall east)", "Drang Hammers", - DS3LocationCategory.WEAPON), - DS3LocationData("CD: Drang Shoes (main hall east)", "Drang Shoes", - DS3LocationCategory.ARMOR), + "Rusted Coin x2", hidden = True), + DS3LocationData("CD: Drang Hammers (main hall east)", "Drang Hammers"), + DS3LocationData("CD: Drang Shoes (main hall east)", "Drang Shoes"), DS3LocationData("CD: Large Soul of an Unknown Traveler (main hall east)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("CD: Pale Tongue (main hall east)", "Pale Tongue", - DS3LocationCategory.MISC), - DS3LocationData("CD: Drang Gauntlets (main hall east)", "Drang Gauntlets", - DS3LocationCategory.ARMOR), + "Large Soul of an Unknown Traveler"), + DS3LocationData("CD: Pale Tongue (main hall east)", "Pale Tongue"), + DS3LocationData("CD: Drang Gauntlets (main hall east)", "Drang Gauntlets"), DS3LocationData("CD: Soul of a Nameless Soldier (lower roofs, side room)", - "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("CD: Exploding Bolt (ledge above main hall south)", "Exploding Bolt x6", - DS3LocationCategory.MISC), + "Soul of a Nameless Soldier"), + DS3LocationData("CD: Exploding Bolt (ledge above main hall south)", "Exploding Bolt x6"), DS3LocationData("CD: Lloyd's Sword Ring (ledge above main hall south)", - "Lloyd's Sword Ring", DS3LocationCategory.RING), + "Lloyd's Sword Ring"), DS3LocationData("CD: Soul of a Nameless Soldier (ledge above main hall south)", - "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("CD: Homeward Bone (outside main hall south door)", "Homeward Bone x2", - DS3LocationCategory.MISC), - DS3LocationData("CD: Deep Gem (down stairs by first elevator)", "Deep Gem", - DS3LocationCategory.UPGRADE), + "Soul of a Nameless Soldier"), + DS3LocationData("CD: Homeward Bone (outside main hall south door)", "Homeward Bone x2"), + DS3LocationData("CD: Deep Gem (down stairs by first elevator)", "Deep Gem"), DS3LocationData("CD: Titanite Shard (path, side path by Cathedral of the Deep bonfire)", - "Titanite Shard", DS3LocationCategory.MISC), + "Titanite Shard"), DS3LocationData("CD: Large Soul of an Unknown Traveler (path, against outer wall)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + "Large Soul of an Unknown Traveler"), # Before the stairs leading down into the Deacons fight DS3LocationData("CD: Ring of the Evil Eye+1 (by stairs to boss)", "Ring of the Evil Eye+1", - DS3LocationCategory.RING, ngp = True), + ngp = True), DS3LocationData("CD: Ring of Favor+2 (upper roofs, on buttress)", "Ring of Favor+2", - DS3LocationCategory.RING, hidden = True, ngp = True), # Hidden fall + hidden = True, ngp = True), # Hidden fall DS3LocationData("CD: Crest Shield (path, drop down by Cathedral of the Deep bonfire)", - "Crest Shield", DS3LocationCategory.SHIELD, hidden = True), # Hidden fall - DS3LocationData("CD: Young White Branch (by white tree #1)", "Young White Branch", - DS3LocationCategory.MISC), - DS3LocationData("CD: Young White Branch (by white tree #2)", "Young White Branch", - DS3LocationCategory.MISC), - DS3LocationData("CD: Saint-tree Bellvine (moat, by water)", "Saint-tree Bellvine", - DS3LocationCategory.WEAPON), - DS3LocationData("CD: Saint Bident (outside main hall south door)", "Saint Bident", - DS3LocationCategory.WEAPON), + "Crest Shield", hidden = True), # Hidden fall + DS3LocationData("CD: Young White Branch (by white tree #1)", "Young White Branch"), + DS3LocationData("CD: Young White Branch (by white tree #2)", "Young White Branch"), + DS3LocationData("CD: Saint-tree Bellvine (moat, by water)", "Saint-tree Bellvine"), + DS3LocationData("CD: Saint Bident (outside main hall south door)", "Saint Bident"), # Archdeacon set is hidden because you have to return to a cleared area DS3LocationData("CD: Archdeacon White Crown (boss room after killing boss)", - "Archdeacon White Crown", DS3LocationCategory.ARMOR, boss = True, - hidden = True), + "Archdeacon White Crown", boss = True, hidden = True), DS3LocationData("CD: Archdeacon Holy Garb (boss room after killing boss)", - "Archdeacon Holy Garb", DS3LocationCategory.ARMOR, boss = True, - hidden = True), + "Archdeacon Holy Garb", boss = True, hidden = True), DS3LocationData("CD: Archdeacon Skirt (boss room after killing boss)", "Archdeacon Skirt", - DS3LocationCategory.ARMOR, boss = True, hidden = True), + boss = True, hidden = True), # Heysel items may not be missable, but it's not clear what causes them to trigger DS3LocationData("CD: Heysel Pick (Heysel Corpse-Grub in Rosaria's Bed Chamber)", - "Heysel Pick", DS3LocationCategory.WEAPON, missable = True), + "Heysel Pick", missable = True), DS3LocationData("CD: Xanthous Crown (Heysel Corpse-Grub in Rosaria's Bed Chamber)", - "Xanthous Crown", DS3LocationCategory.WEAPON, missable = True), + "Xanthous Crown", missable = True), DS3LocationData("CD: Deep Ring (upper roofs, passive mob drop in first tower)", "Deep Ring", - DS3LocationCategory.RING, drop = True, hidden = True), + drop = True, hidden = True), DS3LocationData("CD: Deep Braille Divine Tome (mimic by side chapel)", - "Deep Braille Divine Tome", DS3LocationCategory.UNIQUE, mimic = True), + "Deep Braille Divine Tome", mimic = True), DS3LocationData("CD: Red Sign Soapstone (passive mob drop by Rosaria's Bed Chamber)", - "Red Sign Soapstone", DS3LocationCategory.UNIQUE, drop = True, - hidden = True), + "Red Sign Soapstone", drop = True, hidden = True), DS3LocationData("CD: Aldrich's Sapphire (side chapel, miniboss drop)", "Aldrich's Sapphire", - DS3LocationCategory.RING, miniboss = True), # Deep Accursed Drop + miniboss = True), # Deep Accursed Drop DS3LocationData("CD: Dung Pie (main hall, miniboss drop)", "Dung Pie x4", - DS3LocationCategory.MISC, miniboss = True), # drop from either Giant Slave - DS3LocationData("CD: Large Titanite Shard (main hall, miniboss drop)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE, miniboss = True), # drop from either Giant Slave + DS3LocationData("CD: Large Titanite Shard (main hall, miniboss drop)", + "Large Titanite Shard", miniboss = True), # drop from either Giant Slave DS3LocationData("CD: Titanite Scale (moat, miniboss drop)", "Titanite Scale", - DS3LocationCategory.UPGRADE, miniboss = True), # Ravenous Crystal Lizard drop DS3LocationData("CD: Twinkling Titanite (moat, lizard #1)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), DS3LocationData("CD: Twinkling Titanite (moat, lizard #2)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), DS3LocationData("CD: Rosaria's Fingers (Rosaria)", "Rosaria's Fingers", - DS3LocationCategory.UNIQUE, hidden = True), # Hidden fall - DS3LocationData("CD -> PW1", None, DS3LocationCategory.EVENT), + hidden = True), # Hidden fall + DS3LocationData("CD -> PW1", None), # Longfinger Kirk drops DS3LocationData("CD: Barbed Straight Sword (Kirk drop)", "Barbed Straight Sword", - DS3LocationCategory.WEAPON, missable = True, hostile_npc = True), - DS3LocationData("CD: Spiked Shield (Kirk drop)", "Spiked Shield", - DS3LocationCategory.SHIELD, missable = True, hostile_npc = True), + missable = True, hostile_npc = True), + DS3LocationData("CD: Spiked Shield (Kirk drop)", "Spiked Shield", missable = True, + hostile_npc = True), # In Rosaria's Bed Chamber DS3LocationData("CD: Helm of Thorns (Rosaria's Bed Chamber after killing Kirk)", - "Helm of Thorns", DS3LocationCategory.ARMOR, missable = True, - hostile_npc = True), + "Helm of Thorns", missable = True, hostile_npc = True), DS3LocationData("CD: Armor of Thorns (Rosaria's Bed Chamber after killing Kirk)", - "Armor of Thorns", DS3LocationCategory.ARMOR, missable = True, - hostile_npc = True), + "Armor of Thorns", missable = True, hostile_npc = True), DS3LocationData("CD: Gauntlets of Thorns (Rosaria's Bed Chamber after killing Kirk)", - "Gauntlets of Thorns", DS3LocationCategory.ARMOR, missable = True, - hostile_npc = True), + "Gauntlets of Thorns", missable = True, hostile_npc = True), DS3LocationData("CD: Leggings of Thorns (Rosaria's Bed Chamber after killing Kirk)", - "Leggings of Thorns", DS3LocationCategory.ARMOR, missable = True, - hostile_npc = True), + "Leggings of Thorns", missable = True, hostile_npc = True), # Unbreakable Patches DS3LocationData("CD: Rusted Coin (don't forgive Patches)", "Rusted Coin", - DS3LocationCategory.MISC, missable = True, npc = True), + missable = True, npc = True), DS3LocationData("FS: Rusted Gold Coin (don't forgive Patches)", "Rusted Gold Coin", - DS3LocationCategory.MISC, offline = '99,0:50006201::', missable = True, + offline = '99,0:50006201::', missable = True, npc = True), # Don't forgive Patches - DS3LocationData("CD: Shotel (Patches)", "Shotel", DS3LocationCategory.WEAPON, - missable = True, npc = True, shop = True), - DS3LocationData("CD: Ember (Patches)", "Ember", DS3LocationCategory.MISC, missable = True, + DS3LocationData("CD: Shotel (Patches)", "Shotel", missable = True, npc = True, shop = True), + DS3LocationData("CD: Ember (Patches)", "Ember", missable = True, npc = True, shop = True), + DS3LocationData("CD: Hidden Blessing (Patches)", "Hidden Blessing", missable = True, npc = True, shop = True), - DS3LocationData("CD: Hidden Blessing (Patches)", "Hidden Blessing", - DS3LocationCategory.MISC, missable = True, npc = True, shop = True), - DS3LocationData("CD: Horsehoof Ring (Patches)", "Horsehoof Ring", DS3LocationCategory.RING, - missable = True, npc = True, drop = True, shop = True), # (kill or buy) + DS3LocationData("CD: Horsehoof Ring (Patches)", "Horsehoof Ring", missable = True, + npc = True, drop = True, shop = True), # (kill or buy) ], "Farron Keep": [ - DS3LocationData("FK: Lightning Spear (upper keep, far side of the wall)", "Lightning Spear", - DS3LocationCategory.WEAPON), + DS3LocationData("FK: Lightning Spear (upper keep, far side of the wall)", + "Lightning Spear"), DS3LocationData("FK: Dragon Crest Shield (upper keep, far side of the wall)", - "Dragon Crest Shield", DS3LocationCategory.SHIELD), + "Dragon Crest Shield"), DS3LocationData("FK: Soul of the Blood of the Wolf", "Soul of the Blood of the Wolf", - DS3LocationCategory.SOUL, boss = True), + boss = True), DS3LocationData("FK: Cinders of a Lord - Abyss Watcher", - "Cinders of a Lord - Abyss Watcher", DS3LocationCategory.KEY, + "Cinders of a Lord - Abyss Watcher", offline = "03,0:50002100::", prominent = True, progression = True, boss = True), DS3LocationData("FK: Manikin Claws (Londor Pale Shade drop)", "Manikin Claws", - DS3LocationCategory.WEAPON, missable = True, hostile_npc = True, + missable = True, hostile_npc = True, npc = True), # Londor Pale Shade (if Yoel/Yuria hostile) DS3LocationData("FK: Purple Moss Clump (keep ruins, ritual island)", - "Purple Moss Clump x2", DS3LocationCategory.MISC), + "Purple Moss Clump x2"), DS3LocationData("FK: Purple Moss Clump (ramp directly in front of Farron Keep bonfire)", - "Purple Moss Clump x4", DS3LocationCategory.MISC), - DS3LocationData("FK: Greatsword (ramp by keep ruins ritual island)", "Greatsword", - DS3LocationCategory.WEAPON), + "Purple Moss Clump x4"), + DS3LocationData("FK: Greatsword (ramp by keep ruins ritual island)", "Greatsword"), DS3LocationData("FK: Hollow Gem (perimeter, drop down into swamp)", "Hollow Gem", - DS3LocationCategory.UPGRADE, hidden = True), + hidden = True), DS3LocationData("FK: Purple Moss Clump (Farron Keep bonfire, around right corner)", - "Purple Moss Clump x3", DS3LocationCategory.MISC), + "Purple Moss Clump x3"), DS3LocationData("FK: Undead Bone Shard (pavilion by keep ruins bonfire island)", - "Undead Bone Shard", DS3LocationCategory.HEALTH), + "Undead Bone Shard"), DS3LocationData("FK: Atonement (perimeter, drop down into swamp)", "Atonement", - DS3LocationCategory.SPELL, hidden = True), - DS3LocationData("FK: Titanite Shard (by ladder to keep proper)", "Titanite Shard", - DS3LocationCategory.UPGRADE), - DS3LocationData("FK: Iron Flesh (Farron Keep bonfire, right after exit)", "Iron Flesh", - DS3LocationCategory.SPELL), - DS3LocationData("FK: Stone Parma (near wall by left island)", "Stone Parma", - DS3LocationCategory.SHIELD), - DS3LocationData("FK: Rotten Pine Resin (left island, behind fire)", "Rotten Pine Resin x2", - DS3LocationCategory.MISC), - DS3LocationData("FK: Titanite Shard (between left island and keep ruins)", "Titanite Shard", - DS3LocationCategory.UPGRADE), + hidden = True), + DS3LocationData("FK: Titanite Shard (by ladder to keep proper)", "Titanite Shard"), + DS3LocationData("FK: Iron Flesh (Farron Keep bonfire, right after exit)", "Iron Flesh"), + DS3LocationData("FK: Stone Parma (near wall by left island)", "Stone Parma"), + DS3LocationData("FK: Rotten Pine Resin (left island, behind fire)", "Rotten Pine Resin x2"), + DS3LocationData("FK: Titanite Shard (between left island and keep ruins)", "Titanite Shard"), DS3LocationData("FK: Rusted Gold Coin (right island, behind wall)", "Rusted Gold Coin", - DS3LocationCategory.MISC, hidden = True), + hidden = True), DS3LocationData("FK: Nameless Knight Helm (next to pillar by right island)", - "Nameless Knight Helm", DS3LocationCategory.ARMOR), + "Nameless Knight Helm"), DS3LocationData("FK: Nameless Knight Armor (next to pillar by right island)", - "Nameless Knight Armor", DS3LocationCategory.ARMOR), + "Nameless Knight Armor"), DS3LocationData("FK: Nameless Knight Gauntlets (next to pillar by right island)", - "Nameless Knight Gauntlets", DS3LocationCategory.ARMOR), + "Nameless Knight Gauntlets"), DS3LocationData("FK: Nameless Knight Leggings (next to pillar by right island)", - "Nameless Knight Leggings", DS3LocationCategory.ARMOR), - DS3LocationData("FK: Shriving Stone (perimeter, just past stone doors)", "Shriving Stone", - DS3LocationCategory.UPGRADE), + "Nameless Knight Leggings"), + DS3LocationData("FK: Shriving Stone (perimeter, just past stone doors)", "Shriving Stone"), DS3LocationData("FK: Repair Powder (outside hidden cave)", "Repair Powder x4", - DS3LocationCategory.MISC, hidden = True), - DS3LocationData("FK: Golden Scroll (hidden cave)", "Golden Scroll", - DS3LocationCategory.UNIQUE, hidden = True), + hidden = True), + DS3LocationData("FK: Golden Scroll (hidden cave)", "Golden Scroll", hidden = True), DS3LocationData("FK: Sage's Scroll (near wall by keep ruins bonfire island)", - "Sage's Scroll", DS3LocationCategory.UNIQUE), + "Sage's Scroll"), DS3LocationData("FK: Dreamchaser's Ashes (keep proper, illusory wall)", - "Dreamchaser's Ashes", DS3LocationCategory.KEY, progression = True, - hidden = True), + "Dreamchaser's Ashes", progression = True, hidden = True), DS3LocationData("FK: Titanite Shard (keep ruins bonfire island, under ramp)", - "Titanite Shard", DS3LocationCategory.UPGRADE), + "Titanite Shard"), DS3LocationData("FK: Wolf's Blood Swordgrass (by ladder to keep proper)", - "Wolf's Blood Swordgrass", DS3LocationCategory.MISC), + "Wolf's Blood Swordgrass"), DS3LocationData("FK: Great Magic Weapon (perimeter, by door to Road of Sacrifices)", - "Great Magic Weapon", DS3LocationCategory.SPELL), - DS3LocationData("FK: Ember (perimeter, path to boss)", "Ember", DS3LocationCategory.MISC), - DS3LocationData("FK: Titanite Shard (swamp by right island)", "Titanite Shard x2", - DS3LocationCategory.UPGRADE), - DS3LocationData("FK: Titanite Shard (by left island stairs)", "Titanite Shard", - DS3LocationCategory.UPGRADE), - DS3LocationData("FK: Titanite Shard (by keep ruins ritual island stairs)", "Titanite Shard", - DS3LocationCategory.UPGRADE), + "Great Magic Weapon"), + DS3LocationData("FK: Ember (perimeter, path to boss)", "Ember"), + DS3LocationData("FK: Titanite Shard (swamp by right island)", "Titanite Shard x2"), + DS3LocationData("FK: Titanite Shard (by left island stairs)", "Titanite Shard"), + DS3LocationData("FK: Titanite Shard (by keep ruins ritual island stairs)", "Titanite Shard"), DS3LocationData("FK: Black Bug Pellet (perimeter, hill by boss door)", - "Black Bug Pellet x3", DS3LocationCategory.MISC), + "Black Bug Pellet x3"), DS3LocationData("FK: Rotten Pine Resin (outside pavilion by left island)", - "Rotten Pine Resin x4", DS3LocationCategory.MISC), - DS3LocationData("FK: Poison Gem (near wall by keep ruins bridge)", "Poison Gem", - DS3LocationCategory.UPGRADE), - DS3LocationData("FK: Ragged Mask (Farron Keep bonfire, around left corner)", "Ragged Mask", - DS3LocationCategory.ARMOR), + "Rotten Pine Resin x4"), + DS3LocationData("FK: Poison Gem (near wall by keep ruins bridge)", "Poison Gem"), + DS3LocationData("FK: Ragged Mask (Farron Keep bonfire, around left corner)", "Ragged Mask"), DS3LocationData("FK: Estus Shard (between Farron Keep bonfire and left island)", - "Estus Shard", DS3LocationCategory.HEALTH), - DS3LocationData("FK: Homeward Bone (right island, behind fire)", "Homeward Bone x2", - DS3LocationCategory.HEALTH), + "Estus Shard"), + DS3LocationData("FK: Homeward Bone (right island, behind fire)", "Homeward Bone x2"), DS3LocationData("FK: Titanite Shard (Farron Keep bonfire, left after exit)", - "Titanite Shard", DS3LocationCategory.UPGRADE), + "Titanite Shard"), DS3LocationData("FK: Large Soul of a Nameless Soldier (between right island and pillar)", - "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL, - hidden = True), # Tricky corner to spot - DS3LocationData("FK: Prism Stone (by left island stairs)", "Prism Stone x10", - DS3LocationCategory.MISC), + "Large Soul of a Nameless Soldier", hidden = True), # Tricky corner to spot + DS3LocationData("FK: Prism Stone (by left island stairs)", "Prism Stone x10"), DS3LocationData("FK: Large Soul of a Nameless Soldier (near wall by right island)", - "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("FK: Sage's Coal (pavilion by left island)", "Sage's Coal", - DS3LocationCategory.UNIQUE), - DS3LocationData("FK: Gold Pine Bundle (by white tree)", "Gold Pine Bundle x6", - DS3LocationCategory.MISC), - DS3LocationData("FK: Ember (by white tree)", "Ember", DS3LocationCategory.MISC), - DS3LocationData("FK: Soul of a Nameless Soldier (by white tree)", "Soul of a Nameless Soldier", - DS3LocationCategory.SOUL), + "Large Soul of a Nameless Soldier"), + DS3LocationData("FK: Sage's Coal (pavilion by left island)", "Sage's Coal"), + DS3LocationData("FK: Gold Pine Bundle (by white tree)", "Gold Pine Bundle x6"), + DS3LocationData("FK: Ember (by white tree)", "Ember"), + DS3LocationData("FK: Soul of a Nameless Soldier (by white tree)", "Soul of a Nameless Soldier"), DS3LocationData("FK: Large Soul of an Unknown Traveler (by white tree)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("FK: Greataxe (upper keep, by miniboss)", "Greataxe", - DS3LocationCategory.WEAPON), - DS3LocationData("FK: Ember (upper keep, by miniboss #1)", "Ember", - DS3LocationCategory.MISC), - DS3LocationData("FK: Ember (upper keep, by miniboss #2)", "Ember", - DS3LocationCategory.MISC), + "Large Soul of an Unknown Traveler"), + DS3LocationData("FK: Greataxe (upper keep, by miniboss)", "Greataxe"), + DS3LocationData("FK: Ember (upper keep, by miniboss #1)", "Ember"), + DS3LocationData("FK: Ember (upper keep, by miniboss #2)", "Ember"), DS3LocationData("FK: Dark Stoneplate Ring+2 (keep ruins ritual island, behind wall)", - "Dark Stoneplate Ring+2", DS3LocationCategory.RING, ngp = True, - hidden = True), + "Dark Stoneplate Ring+2", ngp = True, hidden = True), DS3LocationData("FK: Magic Stoneplate Ring+1 (between right island and wall)", - "Magic Stoneplate Ring+1", DS3LocationCategory.RING, ngp = True), + "Magic Stoneplate Ring+1", ngp = True), DS3LocationData("FK: Wolf Ring+1 (keep ruins bonfire island, outside building)", - "Wolf Ring+1", DS3LocationCategory.RING, ngp = True), - DS3LocationData("FK: Antiquated Dress (hidden cave)", "Antiquated Dress", - DS3LocationCategory.ARMOR, hidden = True), - DS3LocationData("FK: Antiquated Gloves (hidden cave)", "Antiquated Gloves", - DS3LocationCategory.ARMOR, hidden = True), - DS3LocationData("FK: Antiquated Skirt (hidden cave)", "Antiquated Skirt", - DS3LocationCategory.ARMOR, hidden = True), + "Wolf Ring+1", ngp = True), + DS3LocationData("FK: Antiquated Dress (hidden cave)", "Antiquated Dress", hidden = True), + DS3LocationData("FK: Antiquated Gloves (hidden cave)", "Antiquated Gloves", hidden = True), + DS3LocationData("FK: Antiquated Skirt (hidden cave)", "Antiquated Skirt", hidden = True), DS3LocationData("FK: Sunlight Talisman (estus soup island, by ladder to keep proper)", - "Sunlight Talisman", DS3LocationCategory.WEAPON), - DS3LocationData("FK: Young White Branch (by white tree #1)", "Young White Branch", - DS3LocationCategory.MISC), - DS3LocationData("FK: Young White Branch (by white tree #2)", "Young White Branch", - DS3LocationCategory.MISC), - DS3LocationData("FK: Crown of Dusk (by white tree)", "Crown of Dusk", - DS3LocationCategory.ARMOR), + "Sunlight Talisman"), + DS3LocationData("FK: Young White Branch (by white tree #1)", "Young White Branch"), + DS3LocationData("FK: Young White Branch (by white tree #2)", "Young White Branch"), + DS3LocationData("FK: Crown of Dusk (by white tree)", "Crown of Dusk"), DS3LocationData("FK: Lingering Dragoncrest Ring (by white tree, miniboss drop)", - "Lingering Dragoncrest Ring", DS3LocationCategory.RING, - miniboss = True), # Great Crab drop + "Lingering Dragoncrest Ring", miniboss = True), # Great Crab drop DS3LocationData("FK: Pharis's Hat (mob drop, around item in corner by keep ruins)", - "Pharis's Hat", DS3LocationCategory.ARMOR, drop = True, hidden = True), + "Pharis's Hat", drop = True, hidden = True), DS3LocationData("FK: Black Bow of Pharis (mob drop, around item in corner by keep ruins)", - "Black Bow of Pharis", DS3LocationCategory.WEAPON, drop = True, - hidden = True), + "Black Bow of Pharis", drop = True, hidden = True), DS3LocationData("FK: Titanite Scale (perimeter, miniboss drop)", "Titanite Scale x2", - DS3LocationCategory.UPGRADE, miniboss = True), # Ravenous Crystal Lizard drop - DS3LocationData("FK: Large Titanite Shard (upper keep, lizard #1)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("FK: Large Titanite Shard (upper keep, lizard #2)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("FK: Heavy Gem (uper keep, lizard on stairs)", "Heavy Gem", - DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("FK: Twinkling Titanite (keep proper, lizardl)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + DS3LocationData("FK: Large Titanite Shard (upper keep, lizard #1)", "Large Titanite Shard", + lizard = True), + DS3LocationData("FK: Large Titanite Shard (upper keep, lizard #2)", "Large Titanite Shard", + lizard = True), + DS3LocationData("FK: Heavy Gem (uper keep, lizard on stairs)", "Heavy Gem", lizard = True), + DS3LocationData("FK: Twinkling Titanite (keep proper, lizard)", "Twinkling Titanite", + lizard = True), DS3LocationData("FK: Soul of a Stray Demon (upper keep, miniboss drop)", - "Soul of a Stray Demon", DS3LocationCategory.SOUL, miniboss = True), - DS3LocationData("FK: Watchdogs of Farron (Old Wolf)", "Watchdogs of Farron", - DS3LocationCategory.UNIQUE), - DS3LocationData("FS: Hawkwood's Shield (Hawkwood)", "Hawkwood's Shield", - DS3LocationCategory.SHIELD, missable = True, + "Soul of a Stray Demon", miniboss = True), + DS3LocationData("FK: Watchdogs of Farron (Old Wolf)", "Watchdogs of Farron"), + DS3LocationData("FS: Hawkwood's Shield (Hawkwood)", "Hawkwood's Shield", missable = True, npc = True), # Hawkwood (quest, after Greatwood, Sage, Watchers, and Deacons) - DS3LocationData("US: Hawk Ring (Giant Archer)", "Hawk Ring", DS3LocationCategory.RING, - drop = True, npc = True), # Giant archer (kill or quest), here because you - # need to collect all seven White Branch locations - # to get it peacefully - DS3LocationData("FK -> CC", None, DS3LocationCategory.EVENT), + DS3LocationData("US: Hawk Ring (Giant Archer)", "Hawk Ring", drop = True, + npc = True), # Giant archer (kill or quest), here because you need to + # collect all seven White Branch locations to get it peacefully + DS3LocationData("FK -> CC", None), # Hawkwood after killing Abyss Watchers - DS3LocationData("FS: Farron Ring (Hawkwood)", "Farron Ring", DS3LocationCategory.RING, + DS3LocationData("FS: Farron Ring (Hawkwood)", "Farron Ring", missable = True, npc = True), # Shrine Handmaid after killing Abyss Watchers - DS3LocationData("FS: Undead Legion Helm (shop after killing FK boss)", - "Undead Legion Helm", DS3LocationCategory.ARMOR, boss = True, shop = True), + DS3LocationData("FS: Undead Legion Helm (shop after killing FK boss)", "Undead Legion Helm", + boss = True, shop = True), DS3LocationData("FS: Undead Legion Armor (shop after killing FK boss)", - "Undead Legion Armor", DS3LocationCategory.ARMOR, boss = True, shop = True), + "Undead Legion Armor", boss = True, shop = True), DS3LocationData("FS: Undead Legion Gauntlet (shop after killing FK boss)", - "Undead Legion Gauntlet", DS3LocationCategory.ARMOR, boss = True, - shop = True), + "Undead Legion Gauntlet", boss = True, shop = True), DS3LocationData("FS: Undead Legion Leggings (shop after killing FK boss)", - "Undead Legion Leggings", DS3LocationCategory.ARMOR, boss = True, - shop = True), + "Undead Legion Leggings", boss = True, shop = True), # Appears after killing Havel Knight in Archdragon Peak DS3LocationData("FK: Havel's Helm (upper keep, after killing AP belfry roof NPC)", - "Havel's Helm", DS3LocationCategory.ARMOR, hidden = True, - hostile_npc = True), + "Havel's Helm", hidden = True, hostile_npc = True), DS3LocationData("FK: Havel's Armor (upper keep, after killing AP belfry roof NPC)", - "Havel's Armor", DS3LocationCategory.ARMOR, hidden = True, - hostile_npc = True), + "Havel's Armor", hidden = True, hostile_npc = True), DS3LocationData("FK: Havel's Gauntlets (upper keep, after killing AP belfry roof NPC)", - "Havel's Gauntlets", DS3LocationCategory.ARMOR, hidden = True, - hostile_npc = True), + "Havel's Gauntlets", hidden = True, hostile_npc = True), DS3LocationData("FK: Havel's Leggings (upper keep, after killing AP belfry roof NPC)", - "Havel's Leggings", DS3LocationCategory.ARMOR, hidden = True, - hostile_npc = True), + "Havel's Leggings", hidden = True, hostile_npc = True), ], "Catacombs of Carthus": [ DS3LocationData("CC: Soul of High Lord Wolnir", "Soul of High Lord Wolnir", - DS3LocationCategory.SOUL, prominent = True, boss = True), + prominent = True, boss = True), DS3LocationData("CC: Carthus Rouge (atrium upper, left after entrance)", - "Carthus Rouge x2", DS3LocationCategory.MISC), - DS3LocationData("CC: Sharp Gem (atrium lower, right before exit)", "Sharp Gem", - DS3LocationCategory.UPGRADE), + "Carthus Rouge x2"), + DS3LocationData("CC: Sharp Gem (atrium lower, right before exit)", "Sharp Gem"), DS3LocationData("CC: Soul of a Nameless Soldier (atrium lower, down hall)", - "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("CC: Titanite Shard (atrium lower, corner by stairs)", "Titanite Shard x2", - DS3LocationCategory.UPGRADE), + "Soul of a Nameless Soldier"), + DS3LocationData("CC: Titanite Shard (atrium lower, corner by stairs)", "Titanite Shard x2"), DS3LocationData("CC: Bloodred Moss Clump (atrium lower, down more stairs)", - "Bloodred Moss Clump x3", DS3LocationCategory.MISC), - DS3LocationData("CC: Carthus Milkring (crypt upper, among pots)", "Carthus Milkring", - DS3LocationCategory.RING), - DS3LocationData("CC: Ember (atrium, on long stairway)", "Ember", DS3LocationCategory.MISC), - DS3LocationData("CC: Carthus Rouge (crypt across, corner)", "Carthus Rouge x3", - DS3LocationCategory.MISC), - DS3LocationData("CC: Ember (crypt upper, end of hall past hole)", "Ember", - DS3LocationCategory.MISC), - DS3LocationData("CC: Carthus Bloodring (crypt lower, end of side hall)", "Carthus Bloodring", - DS3LocationCategory.RING), - DS3LocationData("CC: Titanite Shard (crypt lower, left of entrance)", "Titanite Shard x2", - DS3LocationCategory.UPGRADE), - DS3LocationData("CC: Titanite Shard (crypt lower, start of side hall)", "Titanite Shard x2", - DS3LocationCategory.UPGRADE), - DS3LocationData("CC: Ember (crypt lower, shortcut to cavern)", "Ember", - DS3LocationCategory.MISC), + "Bloodred Moss Clump x3"), + DS3LocationData("CC: Carthus Milkring (crypt upper, among pots)", "Carthus Milkring"), + DS3LocationData("CC: Ember (atrium, on long stairway)", "Ember"), + DS3LocationData("CC: Carthus Rouge (crypt across, corner)", "Carthus Rouge x3"), + DS3LocationData("CC: Ember (crypt upper, end of hall past hole)", "Ember"), + DS3LocationData("CC: Carthus Bloodring (crypt lower, end of side hall)", "Carthus Bloodring"), + DS3LocationData("CC: Titanite Shard (crypt lower, left of entrance)", "Titanite Shard x2"), + DS3LocationData("CC: Titanite Shard (crypt lower, start of side hall)", "Titanite Shard x2"), + DS3LocationData("CC: Ember (crypt lower, shortcut to cavern)", "Ember"), DS3LocationData("CC: Carthus Pyromancy Tome (atrium lower, jump from bridge)", - "Carthus Pyromancy Tome", DS3LocationCategory.UNIQUE, + "Carthus Pyromancy Tome", hidden = True), # Behind illusory wall or hidden drop DS3LocationData("CC: Large Titanite Shard (crypt upper, skeleton ball hall)", - "Large Titanite Shard", DS3LocationCategory.MISC), + "Large Titanite Shard"), DS3LocationData("CC: Large Titanite Shard (crypt across, middle hall)", - "Large Titanite Shard", DS3LocationCategory.MISC), - DS3LocationData("CC: Yellow Bug Pellet (cavern, on overlook)", "Yellow Bug Pellet x3", - DS3LocationCategory.MISC), + "Large Titanite Shard"), + DS3LocationData("CC: Yellow Bug Pellet (cavern, on overlook)", "Yellow Bug Pellet x3"), DS3LocationData("CC: Large Soul of a Nameless Soldier (cavern, before bridge)", - "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("CC: Black Bug Pellet (cavern, before bridge)", "Black Bug Pellet x2", - DS3LocationCategory.MISC), + "Large Soul of a Nameless Soldier"), + DS3LocationData("CC: Black Bug Pellet (cavern, before bridge)", "Black Bug Pellet x2"), DS3LocationData("CC: Grave Warden's Ashes (crypt across, corner)", "Grave Warden's Ashes", - DS3LocationCategory.KEY, progression = True), - DS3LocationData("CC: Large Titanite Shard (tomb lower)", "Large Titanite Shard", - DS3LocationCategory.UPGRADE), + progression = True), + DS3LocationData("CC: Large Titanite Shard (tomb lower)", "Large Titanite Shard"), DS3LocationData("CC: Large Soul of a Nameless Soldier (tomb lower)", - "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + "Large Soul of a Nameless Soldier"), DS3LocationData("CC: Old Sage's Blindfold (tomb, hall before bonfire)", - "Old Sage's Blindfold", DS3LocationCategory.ARMOR), - DS3LocationData("CC: Witch's Ring (tomb, hall before bonfire)", "Witch's Ring", - DS3LocationCategory.RING), + "Old Sage's Blindfold"), + DS3LocationData("CC: Witch's Ring (tomb, hall before bonfire)", "Witch's Ring"), DS3LocationData("CC: Soul of a Nameless Soldier (atrium upper, up more stairs)", - "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + "Soul of a Nameless Soldier"), DS3LocationData("CC: Grave Warden Pyromancy Tome (boss arena)", - "Grave Warden Pyromancy Tome", DS3LocationCategory.UNIQUE), + "Grave Warden Pyromancy Tome"), DS3LocationData("CC: Large Soul of an Unknown Traveler (crypt upper, hall middle)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + "Large Soul of an Unknown Traveler"), DS3LocationData("CC: Ring of Steel Protection+2 (atrium upper, drop onto pillar)", - "Ring of Steel Protection+2", DS3LocationCategory.RING, ngp = True), + "Ring of Steel Protection+2", ngp = True), DS3LocationData("CC: Thunder Stoneplate Ring+1 (crypt upper, among pots)", - "Thunder Stoneplate Ring+1", DS3LocationCategory.RING, ngp = True), + "Thunder Stoneplate Ring+1", ngp = True), DS3LocationData("CC: Undead Bone Shard (crypt upper, skeleton ball drop)", - "Undead Bone Shard", DS3LocationCategory.HEALTH, - hidden = True), # Skeleton Ball puzzle + "Undead Bone Shard", hidden = True), # Skeleton Ball puzzle DS3LocationData("CC: Dark Gem (crypt lower, skeleton ball drop)", "Dark Gem", - DS3LocationCategory.UPGRADE, hidden = True), # Skeleton Ball puzzle - DS3LocationData("CC: Black Blade (tomb, mimic)", "Black Blade", DS3LocationCategory.WEAPON, - mimic = True), + hidden = True), # Skeleton Ball puzzle + DS3LocationData("CC: Black Blade (tomb, mimic)", "Black Blade", mimic = True), DS3LocationData("CC: Soul of a Demon (tomb, miniboss drop)", "Soul of a Demon", - DS3LocationCategory.SOUL, miniboss = True), + miniboss = True), DS3LocationData("CC: Twinkling Titanite (atrium lower, lizard down more stairs)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("CC: Fire Gem (cavern, lizard)", "Fire Gem", - DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("CC: Homeward Bone (Irithyll bridge)", "Homeward Bone", - DS3LocationCategory.MISC), + "Twinkling Titanite", lizard = True), + DS3LocationData("CC: Fire Gem (cavern, lizard)", "Fire Gem", lizard = True), + DS3LocationData("CC: Homeward Bone (Irithyll bridge)", "Homeward Bone"), DS3LocationData("CC: Pontiff's Right Eye (Irithyll bridge, miniboss drop)", - "Pontiff's Right Eye", DS3LocationCategory.RING, - miniboss = True), # Sulyvahn's Beast drop + "Pontiff's Right Eye", miniboss = True), # Sulyvahn's Beast drop # Shrine Handmaid after killing High Lord Wolnir DS3LocationData("FS: Wolnir's Crown (shop after killing CC boss)", "Wolnir's Crown", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), ], "Smouldering Lake": [ DS3LocationData("SL: Soul of the Old Demon King", "Soul of the Old Demon King", - DS3LocationCategory.SOUL, prominent = True, boss = True), + prominent = True, boss = True), DS3LocationData("SL: Fume Ultra Greatsword (ruins basement, NPC drop)", - "Fume Ultra Greatsword", DS3LocationCategory.WEAPON, - hostile_npc = True), # Knight Slayer Tsorig drop + "Fume Ultra Greatsword", hostile_npc = True), # Knight Slayer Tsorig drop DS3LocationData("SL: Black Iron Greatshield (ruins basement, NPC drop)", - "Black Iron Greatshield", DS3LocationCategory.SHIELD, - hostile_npc = True), # Knight Slayer Tsorig drop + "Black Iron Greatshield", hostile_npc = True), # Knight Slayer Tsorig drop DS3LocationData("SL: Large Titanite Shard (ledge by Demon Ruins bonfire)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Large Titanite Shard (lake, by entrance)", "Large Titanite Shard", - DS3LocationCategory.UPGRADE), + "Large Titanite Shard"), + DS3LocationData("SL: Large Titanite Shard (lake, by entrance)", "Large Titanite Shard"), DS3LocationData("SL: Large Titanite Shard (lake, straight from entrance)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Large Titanite Shard (lake, by tree #1)", "Large Titanite Shard", - DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Large Titanite Shard (lake, by miniboss)", "Large Titanite Shard", - DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Yellow Bug Pellet (side lake)", "Yellow Bug Pellet x2", - DS3LocationCategory.MISC), - DS3LocationData("SL: Large Titanite Shard (side lake #1)", "Large Titanite Shard", - DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Large Titanite Shard (side lake #2)", "Large Titanite Shard", - DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Large Titanite Shard (lake, by tree #2)", "Large Titanite Shard", - DS3LocationCategory.UPGRADE), + "Large Titanite Shard"), + DS3LocationData("SL: Large Titanite Shard (lake, by tree #1)", "Large Titanite Shard"), + DS3LocationData("SL: Large Titanite Shard (lake, by miniboss)", "Large Titanite Shard"), + DS3LocationData("SL: Yellow Bug Pellet (side lake)", "Yellow Bug Pellet x2"), + DS3LocationData("SL: Large Titanite Shard (side lake #1)", "Large Titanite Shard"), + DS3LocationData("SL: Large Titanite Shard (side lake #2)", "Large Titanite Shard"), + DS3LocationData("SL: Large Titanite Shard (lake, by tree #2)", "Large Titanite Shard"), DS3LocationData("SL: Speckled Stoneplate Ring (lake, ballista breaks bricks)", - "Speckled Stoneplate Ring", DS3LocationCategory.RING, - hidden = True), # Requires careful ballista shot - DS3LocationData("SL: Homeward Bone (path to ballista)", "Homeward Bone x2", - DS3LocationCategory.MISC), - DS3LocationData("SL: Ember (ruins main upper, hall end by hole)", "Ember", - DS3LocationCategory.MISC), - DS3LocationData("SL: Chaos Gem (lake, far end by mob)", "Chaos Gem", - DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Ember (ruins main lower, path to antechamber)", "Ember", - DS3LocationCategory.MISC), + "Speckled Stoneplate Ring", hidden = True), # Requires careful ballista shot + DS3LocationData("SL: Homeward Bone (path to ballista)", "Homeward Bone x2"), + DS3LocationData("SL: Ember (ruins main upper, hall end by hole)", "Ember"), + DS3LocationData("SL: Chaos Gem (lake, far end by mob)", "Chaos Gem"), + DS3LocationData("SL: Ember (ruins main lower, path to antechamber)", "Ember"), DS3LocationData("SL: Izalith Pyromancy Tome (antechamber, room near bonfire)", - "Izalith Pyromancy Tome", DS3LocationCategory.UNIQUE), + "Izalith Pyromancy Tome"), DS3LocationData("SL: Black Knight Sword (ruins main lower, illusory wall in far hall)", - "Black Knight Sword", DS3LocationCategory.WEAPON, hidden = True), - DS3LocationData("SL: Ember (ruins main upper, just after entrance)", "Ember", - DS3LocationCategory.MISC), + "Black Knight Sword", hidden = True), + DS3LocationData("SL: Ember (ruins main upper, just after entrance)", "Ember"), DS3LocationData("SL: Quelana Pyromancy Tome (ruins main lower, illusory wall in grey room)", - "Quelana Pyromancy Tome", DS3LocationCategory.UNIQUE, hidden = True), + "Quelana Pyromancy Tome", hidden = True), DS3LocationData("SL: Izalith Staff (ruins basement, second illusory wall behind chest)", - "Izalith Staff", DS3LocationCategory.WEAPON, hidden = True), + "Izalith Staff", hidden = True), DS3LocationData("SL: White Hair Talisman (ruins main lower, in lava)", - "White Hair Talisman", DS3LocationCategory.WEAPON, + "White Hair Talisman", missable = True), # This may not even be possible to get without enough fire # protection gear which the player may not have DS3LocationData("SL: Toxic Mist (ruins main lower, in lava)", "Toxic Mist", - DS3LocationCategory.SPELL, missable = True), # This is _probably_ reachable with normal gear, but it # still sucks and will probably force a death. DS3LocationData("SL: Undead Bone Shard (ruins main lower, left after stairs)", - "Undead Bone Shard", DS3LocationCategory.HEALTH), - DS3LocationData("SL: Titanite Scale (ruins basement, path to lava)", - "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("SL: Shield of Want (lake, by miniboss)", "Shield of Want", - DS3LocationCategory.SHIELD), + "Undead Bone Shard"), + DS3LocationData("SL: Titanite Scale (ruins basement, path to lava)", "Titanite Scale"), + DS3LocationData("SL: Shield of Want (lake, by miniboss)", "Shield of Want"), DS3LocationData("SL: Soul of a Crestfallen Knight (ruins basement, above lava)", - "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("SL: Ember (ruins basement, in lava)", "Ember", DS3LocationCategory.MISC, - missable = True), # In lava + "Soul of a Crestfallen Knight"), + + # Lava items are missable because they require a complex set of armor, rings, spells, and + # undead bone shards to reliably access without dying. + DS3LocationData("SL: Ember (ruins basement, in lava)", "Ember", missable = True), # In lava DS3LocationData("SL: Sacred Flame (ruins basement, in lava)", "Sacred Flame", - DS3LocationCategory.SPELL, missable = True), # In lava + missable = True), # In lava + DS3LocationData("SL: Dragonrider Bow (by ladder from ruins basement to ballista)", - "Dragonrider Bow", DS3LocationCategory.WEAPON, hidden = True), # Hidden fall + "Dragonrider Bow", hidden = True), # Hidden fall DS3LocationData("SL: Estus Shard (antechamber, illusory wall)", "Estus Shard", - DS3LocationCategory.HEALTH, hidden = True), - DS3LocationData("SL: Bloodbite Ring+1 (behind ballista)", "Bloodbite Ring+1", - DS3LocationCategory.RING, ngp = True), - DS3LocationData("SL: Flame Stoneplate Ring+2 (ruins main lower, illusory wall in far hall)", - "Flame Stoneplate Ring+2", DS3LocationCategory.RING, ngp = True, hidden = True), + DS3LocationData("SL: Bloodbite Ring+1 (behind ballista)", "Bloodbite Ring+1", ngp = True), + DS3LocationData("SL: Flame Stoneplate Ring+2 (ruins main lower, illusory wall in far hall)", + "Flame Stoneplate Ring+2", ngp = True, hidden = True), DS3LocationData("SL: Large Titanite Shard (ruins basement, illusory wall in upper hall)", - "Large Titanite Shard x3", DS3LocationCategory.UPGRADE, hidden = True), + "Large Titanite Shard x3", hidden = True), DS3LocationData("SL: Undead Bone Shard (lake, miniboss drop)", "Undead Bone Shard", - DS3LocationCategory.HEALTH, miniboss = True), # Sand Worm drop + miniboss = True), # Sand Worm drop DS3LocationData("SL: Lightning Stake (lake, miniboss drop)", "Lightning Stake", - DS3LocationCategory.SPELL, miniboss = True), # Sand Worm drop - DS3LocationData("SL: Twinkling Titanite (path to side lake, lizard)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + miniboss = True), # Sand Worm drop + DS3LocationData("SL: Twinkling Titanite (path to side lake, lizard)", "Twinkling Titanite", + lizard = True), DS3LocationData("SL: Titanite Chunk (path to side lake, lizard)", "Titanite Chunk", - DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("SL: Chaos Gem (antechamber, lizard at end of long hall)", - "Chaos Gem", DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), + DS3LocationData("SL: Chaos Gem (antechamber, lizard at end of long hall)", "Chaos Gem", + lizard = True), DS3LocationData("SL: Knight Slayer's Ring (ruins basement, NPC drop)", - "Knight Slayer's Ring", DS3LocationCategory.RING, - hostile_npc = True), # Knight Slayer Tsorig drop + "Knight Slayer's Ring", hostile_npc = True), # Knight Slayer Tsorig drop # Horace the Hushed # These are listed here even though you can kill Horace in the Road of Sacrifices because # the player may want to complete his and Anri's quest first. - DS3LocationData("SL: Llewellyn Shield (Horace drop)", "Llewellyn Shield", - DS3LocationCategory.SHIELD, npc = True, hostile_npc = True), + DS3LocationData("SL: Llewellyn Shield (Horace drop)", "Llewellyn Shield", npc = True, + hostile_npc = True), DS3LocationData("FS: Executioner Helm (shop after killing Horace)", "Executioner Helm", - DS3LocationCategory.ARMOR, npc = True, hostile_npc = True, shop = True, - hidden = True), + npc = True, hostile_npc = True, shop = True, hidden = True), DS3LocationData("FS: Executioner Armor (shop after killing Horace)", "Executioner Armor", - DS3LocationCategory.ARMOR, npc = True, hostile_npc = True, shop = True, - hidden = True), + npc = True, hostile_npc = True, shop = True, hidden = True), DS3LocationData("FS: Executioner Gauntlets (shop after killing Horace)", - "Executioner Gauntlets", DS3LocationCategory.ARMOR, - hostile_npc = True, npc = True, shop = True, hidden = True), + "Executioner Gauntlets", hostile_npc = True, npc = True, shop = True, + hidden = True), DS3LocationData("FS: Executioner Leggings (shop after killing Horace)", - "Executioner Leggings", DS3LocationCategory.ARMOR, - hostile_npc = True, npc = True, shop = True, hidden = True), + "Executioner Leggings", hostile_npc = True, npc = True, shop = True, + hidden = True), # Shrine Handmaid after killing Knight Slayer Tsorig DS3LocationData("FS: Black Iron Helm (shop after killing Tsorig)", "Black Iron Helm", - DS3LocationCategory.ARMOR, hostile_npc = True, shop = True, hidden = True), + hostile_npc = True, shop = True, hidden = True), DS3LocationData("FS: Black Iron Armor (shop after killing Tsorig)", "Black Iron Armor", - DS3LocationCategory.ARMOR, hostile_npc = True, shop = True, hidden = True), + hostile_npc = True, shop = True, hidden = True), DS3LocationData("FS: Black Iron Gauntlets (shop after killing Tsorig)", - "Black Iron Gauntlets", DS3LocationCategory.ARMOR, hostile_npc = True, - shop = True, hidden = True), + "Black Iron Gauntlets", hostile_npc = True, shop = True, hidden = True), DS3LocationData("FS: Black Iron Leggings (shop after killing Tsorig)", - "Black Iron Leggings", DS3LocationCategory.ARMOR, hostile_npc = True, - shop = True, hidden = True), + "Black Iron Leggings", hostile_npc = True, shop = True, hidden = True), # Near Cornyx's cage after killing Old Demon King with Cuculus DS3LocationData("US: Spotted Whip (by Cornyx's cage after Cuculus quest)", "Spotted Whip", - DS3LocationCategory.WEAPON, missable = True, boss = True, npc = True), - DS3LocationData("US: Cornyx's Garb (by Cornyx's cage after Cuculus quest)", - "Cornyx's Garb", DS3LocationCategory.ARMOR, offline = '02,0:53100100::', missable = True, boss = True, npc = True), + DS3LocationData("US: Cornyx's Garb (by Cornyx's cage after Cuculus quest)", + "Cornyx's Garb", offline = '02,0:53100100::', missable = True, boss = True, + npc = True), DS3LocationData("US: Cornyx's Wrap (by Cornyx's cage after Cuculus quest)", "Cornyx's Wrap", - DS3LocationCategory.ARMOR, offline = '02,0:53100100::', missable = True, - boss = True, npc = True), + offline = '02,0:53100100::', missable = True, boss = True, npc = True), DS3LocationData("US: Cornyx's Skirt (by Cornyx's cage after Cuculus quest)", - "Cornyx's Skirt", DS3LocationCategory.ARMOR, offline = '02,0:53100100::', - missable = True, boss = True, npc = True), + "Cornyx's Skirt", offline = '02,0:53100100::', missable = True, boss = True, + npc = True), ], "Irithyll of the Boreal Valley": [ DS3LocationData("IBV: Soul of Pontiff Sulyvahn", "Soul of Pontiff Sulyvahn", - DS3LocationCategory.SOUL, prominent = True, boss = True), + prominent = True, boss = True), DS3LocationData("IBV: Large Soul of a Nameless Soldier (central, by bonfire)", - "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + "Large Soul of a Nameless Soldier"), DS3LocationData("IBV: Large Titanite Shard (ascent, down ladder in last building)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE), + "Large Titanite Shard"), DS3LocationData("IBV: Soul of a Weary Warrior (central, by first fountain)", - "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + "Soul of a Weary Warrior"), DS3LocationData("IBV: Soul of a Weary Warrior (central, railing by first fountain)", - "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("IBV: Rime-blue Moss Clump (central, by bonfire)", "Rime-blue Moss Clump", - DS3LocationCategory.MISC), + "Soul of a Weary Warrior"), + DS3LocationData("IBV: Rime-blue Moss Clump (central, by bonfire)", "Rime-blue Moss Clump"), DS3LocationData("IBV: Witchtree Branch (by Dorhys)", "Witchtree Branch", - DS3LocationCategory.WEAPON, hidden = True), # Behind illusory wall + hidden = True), # Behind illusory wall DS3LocationData("IBV: Large Titanite Shard (central, side path after first fountain)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE), + "Large Titanite Shard"), DS3LocationData("IBV: Budding Green Blossom (central, by second fountain)", - "Budding Green Blossom", DS3LocationCategory.MISC), + "Budding Green Blossom"), DS3LocationData("IBV: Rime-blue Moss Clump (central, past second fountain)", - "Rime-blue Moss Clump x2", DS3LocationCategory.MISC), + "Rime-blue Moss Clump x2"), DS3LocationData("IBV: Large Titanite Shard (central, balcony just before plaza)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE), + "Large Titanite Shard"), DS3LocationData("IBV: Large Titanite Shard (path to Dorhys)", "Large Titanite Shard", - DS3LocationCategory.UPGRADE, hidden = True), # Behind illusory wall + hidden = True), # Behind illusory wall DS3LocationData("IBV: Ring of the Sun's First Born (fall from in front of cathedral)", - "Ring of the Sun's First Born", DS3LocationCategory.RING, + "Ring of the Sun's First Born", hidden = True), # Hidden fall DS3LocationData("IBV: Large Soul of a Nameless Soldier (stairs to plaza)", - "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + "Large Soul of a Nameless Soldier"), DS3LocationData("IBV: Large Titanite Shard (plaza, balcony overlooking ascent)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE), + "Large Titanite Shard"), DS3LocationData("IBV: Large Titanite Shard (plaza, by stairs to church)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE), + "Large Titanite Shard"), DS3LocationData("IBV: Soul of a Weary Warrior (plaza, side room #1)", - "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + "Soul of a Weary Warrior"), DS3LocationData("IBV: Magic Clutch Ring (plaza, illusory wall)", "Magic Clutch Ring", - DS3LocationCategory.RING, hidden = True), # Behind illusory wall - DS3LocationData("IBV: Fading Soul (descent, cliff edge #1)", "Fading Soul", - DS3LocationCategory.MISC), - DS3LocationData("IBV: Fading Soul (descent, cliff edge #2)", "Fading Soul", - DS3LocationCategory.MISC), - DS3LocationData("IBV: Homeward Bone (descent, before gravestone)", "Homeward Bone x3", - DS3LocationCategory.MISC), + hidden = True), # Behind illusory wall + DS3LocationData("IBV: Fading Soul (descent, cliff edge #1)", "Fading Soul"), + DS3LocationData("IBV: Fading Soul (descent, cliff edge #2)", "Fading Soul"), + DS3LocationData("IBV: Homeward Bone (descent, before gravestone)", "Homeward Bone x3"), DS3LocationData("IBV: Undead Bone Shard (descent, behind gravestone)", "Undead Bone Shard", - DS3LocationCategory.HEALTH, hidden = True), # Hidden behind gravestone - DS3LocationData("IBV: Kukri (descent, side path)", "Kukri x8", DS3LocationCategory.MISC), - DS3LocationData("IBV: Rusted Gold Coin (descent, side path)", "Rusted Gold Coin", - DS3LocationCategory.MISC), - DS3LocationData("IBV: Blue Bug Pellet (descent, dark room)", "Blue Bug Pellet x2", - DS3LocationCategory.MISC), - DS3LocationData("IBV: Shriving Stone (descent, dark room rafters)", "Shriving Stone", - DS3LocationCategory.UPGRADE), - DS3LocationData("IBV: Blood Gem (descent, platform before lake)", "Blood Gem", - DS3LocationCategory.UPGRADE), - DS3LocationData("IBV: Green Blossom (lake, by stairs from descent)", "Green Blossom x3", - DS3LocationCategory.MISC), + hidden = True), # Hidden behind gravestone + DS3LocationData("IBV: Kukri (descent, side path)", "Kukri x8"), + DS3LocationData("IBV: Rusted Gold Coin (descent, side path)", "Rusted Gold Coin"), + DS3LocationData("IBV: Blue Bug Pellet (descent, dark room)", "Blue Bug Pellet x2"), + DS3LocationData("IBV: Shriving Stone (descent, dark room rafters)", "Shriving Stone"), + DS3LocationData("IBV: Blood Gem (descent, platform before lake)", "Blood Gem"), + DS3LocationData("IBV: Green Blossom (lake, by stairs from descent)", "Green Blossom x3"), DS3LocationData("IBV: Ring of Sacrifice (lake, right of stairs from descent)", - "Ring of Sacrifice", DS3LocationCategory.MISC), - DS3LocationData("IBV: Great Heal (lake, dead Corpse-Grub)", "Great Heal", - DS3LocationCategory.SPELL), + "Ring of Sacrifice"), + DS3LocationData("IBV: Great Heal (lake, dead Corpse-Grub)", "Great Heal"), DS3LocationData("IBV: Large Soul of a Nameless Soldier (lake island)", - "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("IBV: Green Blossom (lake wall)", "Green Blossom x3", - DS3LocationCategory.MISC), - DS3LocationData("IBV: Dung Pie (sewer #1)", "Dung Pie x3", DS3LocationCategory.MISC), - DS3LocationData("IBV: Dung Pie (sewer #2)", "Dung Pie x3", DS3LocationCategory.MISC), + "Large Soul of a Nameless Soldier"), + DS3LocationData("IBV: Green Blossom (lake wall)", "Green Blossom x3"), + DS3LocationData("IBV: Dung Pie (sewer #1)", "Dung Pie x3"), + DS3LocationData("IBV: Dung Pie (sewer #2)", "Dung Pie x3"), # These don't actually guard any single item sales. Maybe we can inject one manually? DS3LocationData("IBV: Excrement-covered Ashes (sewer, by stairs)", - "Excrement-covered Ashes", DS3LocationCategory.UNIQUE), + "Excrement-covered Ashes"), DS3LocationData("IBV: Large Soul of a Nameless Soldier (ascent, after great hall)", - "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + "Large Soul of a Nameless Soldier"), DS3LocationData("IBV: Soul of a Weary Warrior (ascent, by final staircase)", - "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + "Soul of a Weary Warrior"), DS3LocationData("IBV: Large Titanite Shard (ascent, by elevator door)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("IBV: Blue Bug Pellet (ascent, in last building)", "Blue Bug Pellet x2", - DS3LocationCategory.MISC), - DS3LocationData("IBV: Ember (shortcut from church to cathedral)", "Ember", - DS3LocationCategory.MISC), - DS3LocationData("IBV: Green Blossom (lake, by Distant Manor)", "Green Blossom", - DS3LocationCategory.MISC), - DS3LocationData("IBV: Lightning Gem (plaza center)", "Lightning Gem", - DS3LocationCategory.UPGRADE), + "Large Titanite Shard"), + DS3LocationData("IBV: Blue Bug Pellet (ascent, in last building)", "Blue Bug Pellet x2"), + DS3LocationData("IBV: Ember (shortcut from church to cathedral)", "Ember"), + DS3LocationData("IBV: Green Blossom (lake, by Distant Manor)", "Green Blossom"), + DS3LocationData("IBV: Lightning Gem (plaza center)", "Lightning Gem"), DS3LocationData("IBV: Large Soul of a Nameless Soldier (central, by second fountain)", - "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + "Large Soul of a Nameless Soldier"), DS3LocationData("IBV: Soul of a Weary Warrior (plaza, side room #2)", - "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + "Soul of a Weary Warrior"), DS3LocationData("IBV: Proof of a Concord Kept (Church of Yorshka altar)", - "Proof of a Concord Kept", DS3LocationCategory.MISC), - DS3LocationData("IBV: Rusted Gold Coin (Distant Manor, down stairs)", "Rusted Gold Coin", - DS3LocationCategory.MISC), + "Proof of a Concord Kept"), + DS3LocationData("IBV: Rusted Gold Coin (Distant Manor, down stairs)", "Rusted Gold Coin"), DS3LocationData("IBV: Chloranthy Ring+1 (plaza, behind altar)", "Chloranthy Ring+1", - DS3LocationCategory.RING, ngp = True), + ngp = True), DS3LocationData("IBV: Covetous Gold Serpent Ring+1 (descent, drop after dark room)", - "Covetous Gold Serpent Ring+1", DS3LocationCategory.RING, ngp = True, - hidden = True), # Hidden fall + "Covetous Gold Serpent Ring+1", ngp = True, hidden = True), # Hidden fall DS3LocationData("IBV: Wood Grain Ring+2 (ascent, right after great hall)", "Wood Grain Ring+2", - DS3LocationCategory.RING, ngp = True), - DS3LocationData("IBV: Divine Blessing (great hall, chest)", "Divine Blessing", - DS3LocationCategory.MISC), + ngp = True), + DS3LocationData("IBV: Divine Blessing (great hall, chest)", "Divine Blessing"), DS3LocationData("IBV: Smough's Great Hammer (great hall, chest)", - "Smough's Great Hammer", DS3LocationCategory.WEAPON), - DS3LocationData("IBV: Yorshka's Spear (descent, dark room rafers chest)", "Yorshka's Spear", - DS3LocationCategory.WEAPON), - DS3LocationData("IBV: Leo Ring (great hall, chest)", "Leo Ring", - DS3LocationCategory.RING), + "Smough's Great Hammer"), + DS3LocationData("IBV: Yorshka's Spear (descent, dark room rafers chest)", "Yorshka's Spear"), + DS3LocationData("IBV: Leo Ring (great hall, chest)", "Leo Ring"), DS3LocationData("IBV: Dorhys' Gnawing (Dorhys drop)", "Dorhys' Gnawing", - DS3LocationCategory.SPELL, hidden = True), # Behind illusory wall + hidden = True), # Behind illusory wall DS3LocationData("IBV: Divine Blessing (great hall, mob)", - "Divine Blessing", DS3LocationCategory.MISC, drop = True, + "Divine Blessing", drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight DS3LocationData("IBV: Large Titanite Shard (great hall, mob)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE, drop = True, + "Large Titanite Shard", drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight DS3LocationData("IBV: Large Titanite Shard (great hall, mob)", - "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, drop = True, + "Large Titanite Shard x2", drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight DS3LocationData("IBV: Large Titanite Shard (great hall, mob)", - "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, drop = True, + "Large Titanite Shard x2", drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight - DS3LocationData("IBV: Roster of Knights (descent, first landing)", "Roster of Knights", - DS3LocationCategory.UNIQUE), + DS3LocationData("IBV: Roster of Knights (descent, first landing)", "Roster of Knights"), DS3LocationData("IBV: Twinkling Titanite (descent, lizard behind illusory wall)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True, - hidden = True), # Behind illusory wall + "Twinkling Titanite", lizard = True, hidden = True), # Behind illusory wall DS3LocationData("IBV: Twinkling Titanite (central, lizard before plaza)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("IBV: Siegbräu (Siegward)", "Siegbräu", DS3LocationCategory.MISC, - missable = True, npc = True), - DS3LocationData("IBV: Emit Force (Siegward)", "Emit Force", DS3LocationCategory.SPELL, - missable = True, npc = True), - DS3LocationData("IBV -> AL", None, DS3LocationCategory.EVENT), - DS3LocationData("IBV -> ID", None, DS3LocationCategory.EVENT), + "Twinkling Titanite", lizard = True), + DS3LocationData("IBV: Siegbräu (Siegward)", "Siegbräu", missable = True, npc = True), + DS3LocationData("IBV: Emit Force (Siegward)", "Emit Force", missable = True, npc = True), + DS3LocationData("IBV -> AL", None), + DS3LocationData("IBV -> ID", None), # After winning both Londor Pale Shade invasions DS3LocationData("FS: Sneering Mask (Yoel's room, kill Londor Pale Shade twice)", - "Sneering Mask", DS3LocationCategory.ARMOR, missable = True, - hostile_npc = True), + "Sneering Mask", missable = True, hostile_npc = True), DS3LocationData("FS: Pale Shade Robe (Yoel's room, kill Londor Pale Shade twice)", - "Pale Shade Robe", DS3LocationCategory.ARMOR, missable = True, - hostile_npc = True), + "Pale Shade Robe", missable = True, hostile_npc = True), DS3LocationData("FS: Pale Shade Gloves (Yoel's room, kill Londor Pale Shade twice)", - "Pale Shade Gloves", DS3LocationCategory.ARMOR, missable = True, - hostile_npc = True), + "Pale Shade Gloves", missable = True, hostile_npc = True), DS3LocationData("FS: Pale Shade Trousers (Yoel's room, kill Londor Pale Shade twice)", - "Pale Shade Trousers", DS3LocationCategory.ARMOR, missable = True, - hostile_npc = True), + "Pale Shade Trousers", missable = True, hostile_npc = True), # Anri of Astora - DS3LocationData("IBV: Ring of the Evil Eye (Anri)", "Ring of the Evil Eye", - DS3LocationCategory.RING, missable = True, npc = True), + DS3LocationData("IBV: Ring of the Evil Eye (Anri)", "Ring of the Evil Eye", missable = True, + npc = True), # Sirris quest after killing Creighton DS3LocationData("FS: Mail Breaker (Sirris for killing Creighton)", "Mail Breaker", - DS3LocationCategory.WEAPON, offline = '99,0:50006080::', missable = True, - hostile_npc = True, npc = True), + offline = '99,0:50006080::', missable = True, hostile_npc = True, + npc = True), DS3LocationData("FS: Silvercat Ring (Sirris for killing Creighton)", "Silvercat Ring", - DS3LocationCategory.RING, missable = True, hostile_npc = True, npc = True), + missable = True, hostile_npc = True, npc = True), DS3LocationData("IBV: Dragonslayer's Axe (Creighton drop)", "Dragonslayer's Axe", - DS3LocationCategory.WEAPON, missable = True, hostile_npc = True, - npc = True), + missable = True, hostile_npc = True, npc = True), DS3LocationData("IBV: Creighton's Steel Mask (bridge after killing Creighton)", - "Creighton's Steel Mask", DS3LocationCategory.ARMOR, missable = True, - hostile_npc = True, npc = True), + "Creighton's Steel Mask", missable = True, hostile_npc = True, npc = True), DS3LocationData("IBV: Mirrah Chain Mail (bridge after killing Creighton)", - "Mirrah Chain Mail", DS3LocationCategory.ARMOR, missable = True, - hostile_npc = True, npc = True), + "Mirrah Chain Mail", missable = True, hostile_npc = True, npc = True), DS3LocationData("IBV: Mirrah Chain Gloves (bridge after killing Creighton)", - "Mirrah Chain Gloves", DS3LocationCategory.ARMOR, missable = True, - hostile_npc = True, npc = True), + "Mirrah Chain Gloves", missable = True, hostile_npc = True, npc = True), DS3LocationData("IBV: Mirrah Chain Leggings (bridge after killing Creighton)", - "Mirrah Chain Leggings", DS3LocationCategory.ARMOR, missable = True, - hostile_npc = True, npc = True), + "Mirrah Chain Leggings", missable = True, hostile_npc = True, npc = True), ], "Irithyll Dungeon": [ - DS3LocationData("ID: Titanite Slab (Siegward)", "Titanite Slab", - DS3LocationCategory.UPGRADE, missable = True, npc = True), - DS3LocationData("ID: Murakumo (Alva drop)", "Murakumo", - DS3LocationCategory.WEAPON, missable = True, hostile_npc = True), - DS3LocationData("ID: Large Titanite Shard (B1 near, just past bonfire)", "Large Titanite Shard", - DS3LocationCategory.UPGRADE), - DS3LocationData("ID: Fading Soul (B1 near, main hall)", "Fading Soul", DS3LocationCategory.MISC), + DS3LocationData("ID: Titanite Slab (Siegward)", "Titanite Slab", missable = True, + npc = True), + DS3LocationData("ID: Murakumo (Alva drop)", "Murakumo", missable = True, + hostile_npc = True), + DS3LocationData("ID: Large Titanite Shard (B1 near, just past bonfire)", + "Large Titanite Shard"), + DS3LocationData("ID: Fading Soul (B1 near, main hall)", "Fading Soul"), DS3LocationData("ID: Large Soul of a Nameless Soldier (B2, hall by stairs)", - "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("ID: Jailbreaker's Key (B1 far, cell after gate)", "Jailbreaker's Key", - DS3LocationCategory.KEY, key = True), - DS3LocationData("ID: Pale Pine Resin (B1 far, cell with broken wall)", "Pale Pine Resin x2", - DS3LocationCategory.MISC), - DS3LocationData("ID: Simple Gem (B2 far, cell by stairs)", "Simple Gem", - DS3LocationCategory.UPGRADE), + "Large Soul of a Nameless Soldier"), + DS3LocationData("ID: Jailbreaker's Key (B1 far, cell after gate)", "Jailbreaker's Key"), + DS3LocationData("ID: Pale Pine Resin (B1 far, cell with broken wall)", + "Pale Pine Resin x2"), + DS3LocationData("ID: Simple Gem (B2 far, cell by stairs)", "Simple Gem"), DS3LocationData("ID: Large Soul of a Nameless Soldier (B2 far, by lift)", - "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("ID: Large Titanite Shard (B1 far, rightmost cell)", "Large Titanite Shard", - DS3LocationCategory.UPGRADE), - DS3LocationData("ID: Homeward Bone (path from B2 to pit)", "Homeward Bone x2", - DS3LocationCategory.MISC), + "Large Soul of a Nameless Soldier"), + DS3LocationData("ID: Large Titanite Shard (B1 far, rightmost cell)", + "Large Titanite Shard"), + DS3LocationData("ID: Homeward Bone (path from B2 to pit)", "Homeward Bone x2"), DS3LocationData("ID: Bellowing Dragoncrest Ring (drop from B1 towards pit)", - "Bellowing Dragoncrest Ring", DS3LocationCategory.RING, conditional = True), - DS3LocationData("ID: Soul of a Weary Warrior (by drop to pit)", "Soul of a Weary Warrior", - DS3LocationCategory.SOUL), + "Bellowing Dragoncrest Ring", conditional = True), + DS3LocationData("ID: Soul of a Weary Warrior (by drop to pit)", "Soul of a Weary Warrior"), DS3LocationData("ID: Soul of a Crestfallen Knight (balcony above pit)", - "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("ID: Lightning Bolt (awning over pit)", "Lightning Bolt x9", - DS3LocationCategory.MISC), - DS3LocationData("ID: Large Titanite Shard (pit)", "Large Titanite Shard", - DS3LocationCategory.UPGRADE), - DS3LocationData("ID: Profaned Flame (pit)", "Profaned Flame", DS3LocationCategory.SPELL), - DS3LocationData("ID: Large Titanite Shard (pit)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE), + "Soul of a Crestfallen Knight"), + DS3LocationData("ID: Lightning Bolt (awning over pit)", "Lightning Bolt x9"), + DS3LocationData("ID: Large Titanite Shard (pit)", "Large Titanite Shard"), + DS3LocationData("ID: Profaned Flame (pit)", "Profaned Flame"), + DS3LocationData("ID: Large Titanite Shard (pit)", "Large Titanite Shard"), DS3LocationData("ID: Soul of a Weary Warrior (stairs between pit and B3)", - "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("ID: Dung Pie (B3, by path from pit)", "Dung Pie x4", - DS3LocationCategory.MISC), - DS3LocationData("ID: Ember (B3 center)", "Ember", DS3LocationCategory.MISC), - DS3LocationData("ID: Ember (B3 near, by exit)", "Ember", DS3LocationCategory.MISC), - DS3LocationData("ID: Profaned Coal (B3 far, left cell)", "Profaned Coal", - DS3LocationCategory.UNIQUE), - DS3LocationData("ID: Large Titanite Shard (B3 near, right corner)", "Large Titanite Shard", - DS3LocationCategory.UPGRADE), - DS3LocationData("ID: Old Sorcerer Hat (B2 near, middle cell)", "Old Sorcerer Hat", - DS3LocationCategory.ARMOR), - DS3LocationData("ID: Old Sorcerer Coat (B2 near, middle cell)", "Old Sorcerer Coat", - DS3LocationCategory.ARMOR), + "Soul of a Weary Warrior"), + DS3LocationData("ID: Dung Pie (B3, by path from pit)", "Dung Pie x4"), + DS3LocationData("ID: Ember (B3 center)", "Ember"), + DS3LocationData("ID: Ember (B3 near, by exit)", "Ember"), + DS3LocationData("ID: Profaned Coal (B3 far, left cell)", "Profaned Coal"), + DS3LocationData("ID: Large Titanite Shard (B3 near, right corner)", "Large Titanite Shard"), + DS3LocationData("ID: Old Sorcerer Hat (B2 near, middle cell)", "Old Sorcerer Hat"), + DS3LocationData("ID: Old Sorcerer Coat (B2 near, middle cell)", "Old Sorcerer Coat"), DS3LocationData("ID: Old Sorcerer Gauntlets (B2 near, middle cell)", - "Old Sorcerer Gauntlets", DS3LocationCategory.ARMOR), - DS3LocationData("ID: Old Sorcerer Boots (B2 near, middle cell)", "Old Sorcerer Boots", - DS3LocationCategory.ARMOR), + "Old Sorcerer Gauntlets"), + DS3LocationData("ID: Old Sorcerer Boots (B2 near, middle cell)", "Old Sorcerer Boots"), DS3LocationData("ID: Large Soul of a Weary Warrior (just before Profaned Capital)", - "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + "Large Soul of a Weary Warrior"), DS3LocationData("ID: Covetous Gold Serpent Ring (Siegward's cell)", - "Covetous Gold Serpent Ring", DS3LocationCategory.RING, conditional = True), - DS3LocationData("ID: Lightning Blade (B3 lift, middle platform)", "Lightning Blade", - DS3LocationCategory.SPELL), - DS3LocationData("ID: Rusted Coin (B1 near, just past bonfire)", "Rusted Coin", - DS3LocationCategory.MISC), - DS3LocationData("ID: Dusk Crown Ring (B3 far, right cell)", "Dusk Crown Ring", - DS3LocationCategory.RING), - DS3LocationData("ID: Pickaxe (path from pit to B3)", "Pickaxe", DS3LocationCategory.WEAPON), + "Covetous Gold Serpent Ring", conditional = True), + DS3LocationData("ID: Lightning Blade (B3 lift, middle platform)", "Lightning Blade"), + DS3LocationData("ID: Rusted Coin (B1 near, just past bonfire)", "Rusted Coin"), + DS3LocationData("ID: Dusk Crown Ring (B3 far, right cell)", "Dusk Crown Ring"), + DS3LocationData("ID: Pickaxe (path from pit to B3)", "Pickaxe"), DS3LocationData("ID: Xanthous Ashes (B3 far, right cell)", "Xanthous Ashes", - DS3LocationCategory.KEY, progression = True), - DS3LocationData("ID: Rusted Gold Coin (B1 near, end of hall by door)", "Rusted Gold Coin", - DS3LocationCategory.MISC), + progression = True), + DS3LocationData("ID: Rusted Gold Coin (B1 near, end of hall by door)", "Rusted Gold Coin"), DS3LocationData("ID: Large Titanite Shard (stairs between pit and B3)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("ID: Old Cell Key (stairs between pit and B3)", "Old Cell Key", - DS3LocationCategory.KEY, key = True), + "Large Titanite Shard"), + DS3LocationData("ID: Old Cell Key (stairs between pit and B3)", "Old Cell Key"), DS3LocationData("ID: Covetous Silver Serpent Ring+1 (pit lift, middle platform)", - "Covetous Silver Serpent Ring+1", DS3LocationCategory.RING, ngp = True), - DS3LocationData("ID: Dragon Torso Stone (B3, outside lift)", "Dragon Torso Stone", - DS3LocationCategory.UNIQUE), + "Covetous Silver Serpent Ring+1", ngp = True), + DS3LocationData("ID: Dragon Torso Stone (B3, outside lift)", "Dragon Torso Stone"), DS3LocationData("ID: Prisoner Chief's Ashes (B2 near, locked cell by stairs)", - "Prisoner Chief's Ashes", DS3LocationCategory.KEY, progression = True), + "Prisoner Chief's Ashes", progression = True), DS3LocationData("ID: Great Magic Shield (B2 near, mob drop in far left cell)", - "Great Magic Shield", DS3LocationCategory.SPELL,drop = True, + "Great Magic Shield", drop = True, hidden = True), # Guaranteed drop from a normal-looking Corpse-Grub DS3LocationData("ID: Dragonslayer Lightning Arrow (pit, mimic in hall)", - "Dragonslayer Lightning Arrow x10", DS3LocationCategory.MISC, mimic = True), + "Dragonslayer Lightning Arrow x10", mimic = True), DS3LocationData("ID: Titanite Scale (B3 far, mimic in hall)", "Titanite Scale x2", - DS3LocationCategory.UPGRADE, mimic = True), + mimic = True), DS3LocationData("ID: Dark Clutch Ring (stairs between pit and B3, mimic)", - "Dark Clutch Ring", DS3LocationCategory.RING, mimic = True), + "Dark Clutch Ring", mimic = True), DS3LocationData("ID: Estus Shard (mimic on path from B2 to pit)", "Estus Shard", - DS3LocationCategory.HEALTH, mimic = True), + mimic = True), DS3LocationData("ID: Titanite Chunk (balcony above pit, lizard)", "Titanite Chunk", - DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("ID: Titanite Scale (B2 far, lizard)", "Titanite Scale", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), + DS3LocationData("ID: Titanite Scale (B2 far, lizard)", "Titanite Scale", lizard = True), DS3LocationData("ID: Dung Pie (pit, miniboss drop)", "Dung Pie x4", - DS3LocationCategory.MISC, miniboss = True), # Giant slave drop + miniboss = True), # Giant slave drop DS3LocationData("ID: Titanite Chunk (pit, miniboss drop", "Titanite Chunk", - DS3LocationCategory.UPGRADE, miniboss = True), # Giant Slave Drop + miniboss = True), # Giant Slave Drop # Alva (requires ember) DS3LocationData("ID: Alva Helm (B3 near, by Karla's cell, after killing Alva)", "Alva Helm", - DS3LocationCategory.ARMOR, missable = True, npc = True), + missable = True, npc = True), DS3LocationData("ID: Alva Armor (B3 near, by Karla's cell, after killing Alva)", - "Alva Armor", DS3LocationCategory.ARMOR, missable = True, npc = True), + "Alva Armor", missable = True, npc = True), DS3LocationData("ID: Alva Gauntlets (B3 near, by Karla's cell, after killing Alva)", - "Alva Gauntlets", DS3LocationCategory.ARMOR, missable = True, npc = True), + "Alva Gauntlets", missable = True, npc = True), DS3LocationData("ID: Alva Leggings (B3 near, by Karla's cell, after killing Alva)", - "Alva Leggings", DS3LocationCategory.ARMOR, missable = True, npc = True), + "Alva Leggings", missable = True, npc = True), ], "Profaned Capital": [ - DS3LocationData("PC: Soul of Yhorm the Giant", "Soul of Yhorm the Giant", - DS3LocationCategory.SOUL, boss = True), + DS3LocationData("PC: Soul of Yhorm the Giant", "Soul of Yhorm the Giant", boss = True), DS3LocationData("PC: Cinders of a Lord - Yhorm the Giant", - "Cinders of a Lord - Yhorm the Giant", DS3LocationCategory.KEY, - offline = "07,0:50002170::", prominent = True, progression = True, - boss = True), + "Cinders of a Lord - Yhorm the Giant", offline = "07,0:50002170::", + prominent = True, progression = True, boss = True), DS3LocationData("PC: Logan's Scroll (chapel roof, NPC drop)", "Logan's Scroll", - DS3LocationCategory.UNIQUE, hostile_npc = True), # Sorcerer - DS3LocationData("PC: Purging Stone (chapel ground floor)", "Purging Stone x3", - DS3LocationCategory.MISC), - DS3LocationData("PC: Rusted Coin (tower exterior)", "Rusted Coin x2", - DS3LocationCategory.MISC), - DS3LocationData("PC: Rusted Gold Coin (halls above swamp)", "Rusted Gold Coin", - DS3LocationCategory.MISC), - DS3LocationData("PC: Purging Stone (swamp, by chapel ladder)", "Purging Stone", - DS3LocationCategory.MISC), - DS3LocationData("PC: Cursebite Ring (swamp, below halls)", "Cursebite Ring", - DS3LocationCategory.RING), - DS3LocationData("PC: Poison Gem (swamp, below halls)", "Poison Gem", - DS3LocationCategory.UPGRADE), - DS3LocationData("PC: Shriving Stone (swamp, by chapel door)", "Shriving Stone", - DS3LocationCategory.UPGRADE), - DS3LocationData("PC: Poison Arrow (chapel roof)", "Poison Arrow x18", - DS3LocationCategory.MISC), - DS3LocationData("PC: Rubbish (chapel, down stairs from second floor)", "Rubbish", - DS3LocationCategory.MISC), - DS3LocationData("PC: Onislayer Greatarrow (bridge)", "Onislayer Greatarrow x8", - DS3LocationCategory.MISC), + hostile_npc = True), # Sorcerer + DS3LocationData("PC: Purging Stone (chapel ground floor)", "Purging Stone x3"), + DS3LocationData("PC: Rusted Coin (tower exterior)", "Rusted Coin x2"), + DS3LocationData("PC: Rusted Gold Coin (halls above swamp)", "Rusted Gold Coin"), + DS3LocationData("PC: Purging Stone (swamp, by chapel ladder)", "Purging Stone"), + DS3LocationData("PC: Cursebite Ring (swamp, below halls)", "Cursebite Ring"), + DS3LocationData("PC: Poison Gem (swamp, below halls)", "Poison Gem"), + DS3LocationData("PC: Shriving Stone (swamp, by chapel door)", "Shriving Stone"), + DS3LocationData("PC: Poison Arrow (chapel roof)", "Poison Arrow x18"), + DS3LocationData("PC: Rubbish (chapel, down stairs from second floor)", "Rubbish"), + DS3LocationData("PC: Onislayer Greatarrow (bridge)", "Onislayer Greatarrow x8"), DS3LocationData("PC: Large Soul of a Weary Warrior (bridge, far end)", - "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("PC: Rusted Coin (below bridge #1)", "Rusted Coin", - DS3LocationCategory.MISC), - DS3LocationData("PC: Rusted Coin (below bridge #2)", "Rusted Coin", - DS3LocationCategory.MISC), + "Large Soul of a Weary Warrior"), + DS3LocationData("PC: Rusted Coin (below bridge #1)", "Rusted Coin"), + DS3LocationData("PC: Rusted Coin (below bridge #2)", "Rusted Coin"), DS3LocationData("PC: Blooming Purple Moss Clump (walkway above swamp)", - "Blooming Purple Moss Clump x3", DS3LocationCategory.MISC), - DS3LocationData("PC: Wrath of the Gods (chapel, drop from roof)", "Wrath of the Gods", - DS3LocationCategory.SPELL), + "Blooming Purple Moss Clump x3"), + DS3LocationData("PC: Wrath of the Gods (chapel, drop from roof)", "Wrath of the Gods"), DS3LocationData("PC: Onislayer Greatbow (drop from bridge)", "Onislayer Greatbow", - DS3LocationCategory.WEAPON, hidden = True), # Hidden fall + hidden = True), # Hidden fall DS3LocationData("PC: Jailer's Key Ring (hall past chapel)", "Jailer's Key Ring", - DS3LocationCategory.KEY, progression = True, key = True), - DS3LocationData("PC: Ember (palace, far room)", "Ember", DS3LocationCategory.MISC), + progression = True), + DS3LocationData("PC: Ember (palace, far room)", "Ember"), DS3LocationData("PC: Flame Stoneplate Ring+1 (chapel, drop from roof towards entrance)", - "Flame Stoneplate Ring+1", DS3LocationCategory.RING, ngp = True, - hidden = True), # Hidden fall + "Flame Stoneplate Ring+1", ngp = True, hidden = True), # Hidden fall DS3LocationData("PC: Magic Stoneplate Ring+2 (tower base)", "Magic Stoneplate Ring+2", - DS3LocationCategory.RING, ngp = True), - DS3LocationData("PC: Court Sorcerer Hood (chapel, second floor)", "Court Sorcerer Hood", - DS3LocationCategory.ARMOR), - DS3LocationData("PC: Court Sorcerer Robe (chapel, second floor)", "Court Sorcerer Robe", - DS3LocationCategory.ARMOR), - DS3LocationData("PC: Court Sorcerer Gloves (chapel, second floor)", "Court Sorcerer Gloves", - DS3LocationCategory.ARMOR), + ngp = True), + DS3LocationData("PC: Court Sorcerer Hood (chapel, second floor)", "Court Sorcerer Hood"), + DS3LocationData("PC: Court Sorcerer Robe (chapel, second floor)", "Court Sorcerer Robe"), + DS3LocationData("PC: Court Sorcerer Gloves (chapel, second floor)", "Court Sorcerer Gloves"), DS3LocationData("PC: Court Sorcerer Trousers (chapel, second floor)", - "Court Sorcerer Trousers", DS3LocationCategory.ARMOR), - DS3LocationData("PC: Storm Ruler (boss room)", "Storm Ruler", DS3LocationCategory.WEAPON), - DS3LocationData("PC: Undead Bone Shard (by bonfire)", "Undead Bone Shard", - DS3LocationCategory.HEALTH), + "Court Sorcerer Trousers"), + DS3LocationData("PC: Storm Ruler (boss room)", "Storm Ruler"), + DS3LocationData("PC: Undead Bone Shard (by bonfire)", "Undead Bone Shard"), DS3LocationData("PC: Eleonora (chapel ground floor, kill mob)", "Eleonora", - DS3LocationCategory.WEAPON, drop = True, + drop = True, hidden = True), # Guaranteed drop from a normal-looking Monstrosity of Sin DS3LocationData("PC: Rusted Gold Coin (palace, mimic in far room)", "Rusted Gold Coin x2", - DS3LocationCategory.MISC, mimic = True), + mimic = True), DS3LocationData("PC: Court Sorcerer's Staff (chapel, mimic on second floor)", - "Court Sorcerer's Staff", DS3LocationCategory.WEAPON, mimic = True), + "Court Sorcerer's Staff", mimic = True), DS3LocationData("PC: Greatshield of Glory (palace, mimic in far room)", - "Greatshield of Glory", DS3LocationCategory.SHIELD, mimic = True), + "Greatshield of Glory", mimic = True), DS3LocationData("PC: Twinkling Titanite (halls above swamp, lizard #1)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + "Twinkling Titanite", lizard = True), DS3LocationData("PC: Twinkling Titanite (halls above swamp, lizard #1)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + "Twinkling Titanite", lizard = True), DS3LocationData("PC: Siegbräu (Siegward after killing boss)", "Siegbräu", - DS3LocationCategory.MISC, missable = True, npc = True), + missable = True, npc = True), # Siegward drops (kill or quest) - DS3LocationData("PC: Storm Ruler (Siegward)", "Storm Ruler", DS3LocationCategory.KEY, - offline = '02,0:50006218::', missable = True, drop = True, npc = True), - DS3LocationData("PC: Pierce Shield (Siegward)", "Pierce Shield", DS3LocationCategory.SHIELD, + DS3LocationData("PC: Storm Ruler (Siegward)", "Storm Ruler", offline = '02,0:50006218::', missable = True, drop = True, npc = True), + DS3LocationData("PC: Pierce Shield (Siegward)", "Pierce Shield", missable = True, + drop = True, npc = True), ], # We consider "Anor Londo" to be everything accessible only after killing Pontiff. This doesn't # match up one-to-one with where the game pops up the region name, but it balances items better # and covers the region that's full of DS1 Anor Londo references. "Anor Londo": [ - DS3LocationData("AL: Soul of Aldrich", "Soul of Aldrich", DS3LocationCategory.SOUL, - boss = True), + DS3LocationData("AL: Soul of Aldrich", "Soul of Aldrich", boss = True), DS3LocationData("AL: Cinders of a Lord - Aldrich", "Cinders of a Lord - Aldrich", - DS3LocationCategory.KEY, offline = '06,0:50002130::', prominent = True, - progression = True, boss = True), - DS3LocationData("AL: Yorshka's Chime (kill Yorshka)", "Yorshka's Chime", - DS3LocationCategory.WEAPON, missable = True, drop = True, + offline = '06,0:50002130::', prominent = True, progression = True, + boss = True), + DS3LocationData("AL: Yorshka's Chime (kill Yorshka)", "Yorshka's Chime", missable = True, + drop = True, npc = True), # Hidden walkway, missable because it will break Sirris's quest - DS3LocationData("AL: Drang Twinspears (plaza, NPC drop)", "Drang Twinspears", - DS3LocationCategory.WEAPON, drop = True, hidden = True), - DS3LocationData("AL: Estus Shard (dark cathedral, by left stairs)", "Estus Shard", - DS3LocationCategory.HEALTH), + DS3LocationData("AL: Drang Twinspears (plaza, NPC drop)", "Drang Twinspears", drop = True, + hidden = True), + DS3LocationData("AL: Estus Shard (dark cathedral, by left stairs)", "Estus Shard"), DS3LocationData("AL: Painting Guardian's Curved Sword (prison tower rafters)", - "Painting Guardian's Curved Sword", DS3LocationCategory.WEAPON, - hidden = True), # Invisible walkway - DS3LocationData("AL: Brass Helm (tomb)", "Brass Helm", DS3LocationCategory.ARMOR, + "Painting Guardian's Curved Sword", hidden = True), # Invisible walkway + DS3LocationData("AL: Brass Helm (tomb)", "Brass Helm", hidden = True), # Behind illusory wall - DS3LocationData("AL: Brass Armor (tomb)", "Brass Armor", DS3LocationCategory.ARMOR, + DS3LocationData("AL: Brass Armor (tomb)", "Brass Armor", hidden = True), # Behind illusory wall - DS3LocationData("AL: Brass Gauntlets (tomb)", "Brass Gauntlets", DS3LocationCategory.ARMOR, + DS3LocationData("AL: Brass Gauntlets (tomb)", "Brass Gauntlets", hidden = True), # Behind illusory wall - DS3LocationData("AL: Brass Leggings (tomb)", "Brass Leggings", DS3LocationCategory.ARMOR, + DS3LocationData("AL: Brass Leggings (tomb)", "Brass Leggings", hidden = True), # Behind illusory wall - DS3LocationData("AL: Human Dregs (water reserves)", "Human Dregs", DS3LocationCategory.MISC, + DS3LocationData("AL: Human Dregs (water reserves)", "Human Dregs", hidden = True), # Behind illusory wall - DS3LocationData("AL: Ember (spiral staircase, bottom)", "Ember", DS3LocationCategory.MISC), + DS3LocationData("AL: Ember (spiral staircase, bottom)", "Ember"), DS3LocationData("AL: Large Titanite Shard (bottom of the furthest buttress)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE), + "Large Titanite Shard"), DS3LocationData("AL: Large Titanite Shard (walkway, side path by cathedral)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("AL: Soul of a Weary Warrior (plaza, nearer)", "Soul of a Weary Warrior", - DS3LocationCategory.SOUL), - DS3LocationData("AL: Ember (plaza, right side)", "Ember", DS3LocationCategory.MISC), - DS3LocationData("AL: Ember (plaza, further)", "Ember", DS3LocationCategory.MISC), + "Large Titanite Shard"), + DS3LocationData("AL: Soul of a Weary Warrior (plaza, nearer)", "Soul of a Weary Warrior"), + DS3LocationData("AL: Ember (plaza, right side)", "Ember"), + DS3LocationData("AL: Ember (plaza, further)", "Ember"), DS3LocationData("AL: Large Titanite Shard (right after light cathedral)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE), + "Large Titanite Shard"), DS3LocationData("AL: Dark Stoneplate Ring (by dark stairs up from plaza)", - "Dark Stoneplate Ring", DS3LocationCategory.RING), + "Dark Stoneplate Ring"), DS3LocationData("AL: Large Titanite Shard (bottom of the nearest buttress)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE), - DS3LocationData("AL: Deep Gem (water reserves)", "Deep Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("AL: Titanite Scale (top of ladder up to buttresses)", "Titanite Scale", - DS3LocationCategory.UPGRADE), + "Large Titanite Shard"), + DS3LocationData("AL: Deep Gem (water reserves)", "Deep Gem"), + DS3LocationData("AL: Titanite Scale (top of ladder up to buttresses)", "Titanite Scale"), DS3LocationData("AL: Dragonslayer Greatarrow (drop from nearest buttress)", - "Dragonslayer Greatarrow x5", DS3LocationCategory.MISC, - offline = '06,0:53700620::', hidden = True), # Hidden fall + "Dragonslayer Greatarrow x5", offline = '06,0:53700620::', + hidden = True), # Hidden fall DS3LocationData("AL: Dragonslayer Greatbow (drop from nearest buttress)", - "Dragonslayer Greatbow", DS3LocationCategory.WEAPON, - offline = '06,0:53700620::', hidden = True), # Hidden fall + "Dragonslayer Greatbow", offline = '06,0:53700620::', + hidden = True), # Hidden fall DS3LocationData("AL: Easterner's Ashes (below top of furthest buttress)", - "Easterner's Ashes", DS3LocationCategory.KEY, progression = True), + "Easterner's Ashes", progression = True), DS3LocationData("AL: Painting Guardian Hood (prison tower, rafters)", - "Painting Guardian Hood", DS3LocationCategory.ARMOR, - hidden = True), # Invisible walkway + "Painting Guardian Hood", hidden = True), # Invisible walkway DS3LocationData("AL: Painting Guardian Gown (prison tower, rafters)", - "Painting Guardian Gown", DS3LocationCategory.ARMOR, - hidden = True), # Invisible walkway + "Painting Guardian Gown", hidden = True), # Invisible walkway DS3LocationData("AL: Painting Guardian Gloves (prison tower, rafters)", - "Painting Guardian Gloves", DS3LocationCategory.ARMOR, - hidden = True), # Invisible walkway + "Painting Guardian Gloves", hidden = True), # Invisible walkway DS3LocationData("AL: Painting Guardian Waistcloth (prison tower, rafters)", - "Painting Guardian Waistcloth", DS3LocationCategory.ARMOR, - hidden = True), # Invisible walkway + "Painting Guardian Waistcloth", hidden = True), # Invisible walkway DS3LocationData("AL: Soul of a Crestfallen Knight (right of dark cathedral entrance)", - "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + "Soul of a Crestfallen Knight"), DS3LocationData("AL: Moonlight Arrow (dark cathedral, up right stairs)", - "Moonlight Arrow x6", DS3LocationCategory.MISC), + "Moonlight Arrow x6"), DS3LocationData("AL: Proof of a Concord Kept (dark cathedral, up left stairs)", - "Proof of a Concord Kept", DS3LocationCategory.MISC), + "Proof of a Concord Kept"), DS3LocationData("AL: Large Soul of a Weary Warrior (left of dark cathedral entrance)", - "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("AL: Giant's Coal (by giant near dark cathedral)", "Giant's Coal", - DS3LocationCategory.UNIQUE), - DS3LocationData("AL: Havel's Ring+2 (prison tower, rafters)", "Havel's Ring+2", - DS3LocationCategory.RING, ngp = True, hidden = True), # Invisible walkway + "Large Soul of a Weary Warrior"), + DS3LocationData("AL: Giant's Coal (by giant near dark cathedral)", "Giant's Coal"), + DS3LocationData("AL: Havel's Ring+2 (prison tower, rafters)", "Havel's Ring+2", ngp = True, + hidden = True), # Invisible walkway DS3LocationData("AL: Ring of Favor+1 (light cathedral, upstairs)", "Ring of Favor+1", - DS3LocationCategory.RING, ngp = True), - DS3LocationData("AL: Sun Princess Ring (dark cathedral, after boss)", "Sun Princess Ring", - DS3LocationCategory.RING), + ngp = True), + DS3LocationData("AL: Sun Princess Ring (dark cathedral, after boss)", "Sun Princess Ring"), DS3LocationData("AL: Reversal Ring (tomb, chest in corner)", "Reversal Ring", - DS3LocationCategory.RING, hidden = True), # Behind illusory wall + hidden = True), # Behind illusory wall DS3LocationData("AL: Golden Ritual Spear (light cathedral, mimic upstairs)", - "Golden Ritual Spear", DS3LocationCategory.WEAPON, mimic = True), + "Golden Ritual Spear", mimic = True), DS3LocationData("AL: Ring of Favor (water reserves, both minibosses)", "Ring of Favor", - DS3LocationCategory.RING, miniboss = True, + miniboss = True, hidden = True), # Sulyvahn's Beast Duo drop, behind illusory wall DS3LocationData("AL: Blade of the Darkmoon (Yorshka with Darkmoon Loyalty)", - "Blade of the Darkmoon", DS3LocationCategory.UNIQUE, missable = True, - drop = True, + "Blade of the Darkmoon", missable = True, drop = True, npc = True), # Hidden walkway, missable because it will break Sirris's quest DS3LocationData("AL: Simple Gem (light cathedral, lizard upstairs)", "Simple Gem", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), DS3LocationData("AL: Twinkling Titanite (lizard after light cathedral #1)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + "Twinkling Titanite", lizard = True), DS3LocationData("AL: Twinkling Titanite (lizard after light cathedral #1)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + "Twinkling Titanite", lizard = True), DS3LocationData("AL: Aldrich's Ruby (dark cathedral, miniboss)", "Aldrich's Ruby", - DS3LocationCategory.RING, miniboss = True), # Deep Accursed drop + miniboss = True), # Deep Accursed drop DS3LocationData("AL: Aldrich Faithful (water reserves, talk to McDonnel)", "Aldrich Faithful", - DS3LocationCategory.UNIQUE, hidden = True), # Behind illusory wall + hidden = True), # Behind illusory wall DS3LocationData("AL: Large Titanite Shard ?? (right after light cathedral)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE, + "Large Titanite Shard", # TODO: Mark this as Area: irithyll_anorlondo in the offline rando and order # it properly offline = '06,0:53700480::'), DS3LocationData("FS: Budding Green Blossom (shop after Sirris kills Aldrich)", - "Budding Green Blossom", DS3LocationCategory.MISC, + "Budding Green Blossom", offline = '99,0:-1:110000,70000118:', missable = True, npc = True, shop = True), # sold by Shrine Maiden after helping Sirris defeat Aldrich # Sirris (quest completion) DS3LocationData("FS: Sunset Shield (by grave after killing Hodrick w/Sirris)", - "Sunset Shield", DS3LocationCategory.SHIELD, missable = True, - hostile_npc = True, npc = True), + "Sunset Shield", missable = True, hostile_npc = True, npc = True), # In Pit of Hollows after killing Hodrick DS3LocationData("US: Sunset Helm (Pit of Hollows after killing Hodrick w/Sirris)", - "Sunset Helm", DS3LocationCategory.ARMOR, missable = True, - hostile_npc = True, npc = True), + "Sunset Helm", missable = True, hostile_npc = True, npc = True), DS3LocationData("US: Sunset Armor (pit of hollows after killing Hodrick w/Sirris)", - "Sunset Armor", DS3LocationCategory.ARMOR, missable = True, - hostile_npc = True, npc = True), + "Sunset Armor", missable = True, hostile_npc = True, npc = True), DS3LocationData("US: Sunset Gauntlets (pit of hollows after killing Hodrick w/Sirris)", - "Sunset Gauntlets", DS3LocationCategory.ARMOR, missable = True, - hostile_npc = True, npc = True), + "Sunset Gauntlets", missable = True, hostile_npc = True, npc = True), DS3LocationData("US: Sunset Leggings (pit of hollows after killing Hodrick w/Sirris)", - "Sunset Leggings", DS3LocationCategory.ARMOR, missable = True, - hostile_npc = True, npc = True), + "Sunset Leggings", missable = True, hostile_npc = True, npc = True), # Shrine Handmaid after killing Sulyvahn's Beast Duo DS3LocationData("FS: Helm of Favor (shop after killing water reserve minibosses)", - "Helm of Favor", DS3LocationCategory.ARMOR, hidden = True, miniboss = True, - shop = True), + "Helm of Favor", hidden = True, miniboss = True, shop = True), DS3LocationData("FS: Embraced Armor of Favor (shop after killing water reserve minibosses)", - "Embraced Armor of Favor", DS3LocationCategory.ARMOR, hidden = True, - miniboss = True, shop = True), + "Embraced Armor of Favor", hidden = True, miniboss = True, shop = True), DS3LocationData("FS: Gauntlets of Favor (shop after killing water reserve minibosses)", - "Gauntlets of Favor", DS3LocationCategory.ARMOR, hidden = True, - miniboss = True, shop = True), + "Gauntlets of Favor", hidden = True, miniboss = True, shop = True), DS3LocationData("FS: Leggings of Favor (shop after killing water reserve minibosses)", - "Leggings of Favor", DS3LocationCategory.ARMOR, hidden = True, - miniboss = True, shop = True), + "Leggings of Favor", hidden = True, miniboss = True, shop = True), # Anri of Astora - DS3LocationData("AL: Chameleon (tomb after marrying Anri)", "Chameleon", - DS3LocationCategory.SPELL, missable = True, npc = True), + DS3LocationData("AL: Chameleon (tomb after marrying Anri)", "Chameleon", missable = True, + npc = True), DS3LocationData("AL: Anri's Straight Sword (Anri quest)","Anri's Straight Sword", - DS3LocationCategory.WEAPON, missable = True, npc = True), + missable = True, npc = True), # Shrine Handmaid after killing Ringfinger Leonhard # This is listed here even though you can kill Leonhard immediately because we want the # logic to assume people will do his full quest. Missable because he can disappear forever # if you use up all your Pale Tongues. DS3LocationData("FS: Leonhard's Garb (shop after killing Leonhard)", - "Leonhard's Garb", DS3LocationCategory.ARMOR, hidden = True, npc = True, - shop = True, missable = True), + "Leonhard's Garb", hidden = True, npc = True, shop = True, missable = True), DS3LocationData("FS: Leonhard's Gauntlets (shop after killing Leonhard)", - "Leonhard's Gauntlets", DS3LocationCategory.ARMOR, hidden = True, - npc = True, shop = True, missable = True), + "Leonhard's Gauntlets", hidden = True, npc = True, shop = True, + missable = True), DS3LocationData("FS: Leonhard's Trousers (shop after killing Leonhard)", - "Leonhard's Trousers", DS3LocationCategory.ARMOR, hidden = True, npc = True, - shop = True, missable = True), + "Leonhard's Trousers", hidden = True, npc = True, shop = True, + missable = True), # Shrine Handmaid after killing Alrich, Devourer of Gods DS3LocationData("FS: Smough's Helm (shop after killing AL boss)", "Smough's Helm", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Smough's Armor (shop after killing AL boss)", "Smough's Armor", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Smough's Gauntlets (shop after killing AL boss)", "Smough's Gauntlets", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Smough's Leggings (shop after killing AL boss)", "Smough's Leggings", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), # Shrine Handmaid after killing Anri or completing their quest DS3LocationData("FS: Elite Knight Helm (shop after Anri quest)", "Elite Knight Helm", - DS3LocationCategory.ARMOR, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("FS: Elite Knight Armor (shop after Anri quest)", "Elite Knight Armor", - DS3LocationCategory.ARMOR, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("FS: Elite Knight Gauntlets (shop after Anri quest)", - "Elite Knight Gauntlets", DS3LocationCategory.ARMOR, missable = True, - npc = True, shop = True), + "Elite Knight Gauntlets", missable = True, npc = True, shop = True), DS3LocationData("FS: Elite Knight Leggings (shop after Anri quest)", - "Elite Knight Leggings", DS3LocationCategory.ARMOR, missable = True, - npc = True, shop = True), + "Elite Knight Leggings", missable = True, npc = True, shop = True), # Ringfinger Leonhard (quest or kill) - DS3LocationData("AL: Crescent Moon Sword (Leonhard drop)", - "Crescent Moon Sword", DS3LocationCategory.WEAPON, missable = True, + DS3LocationData("AL: Crescent Moon Sword (Leonhard drop)", "Crescent Moon Sword", + missable = True, npc = True), + DS3LocationData("AL: Silver Mask (Leonhard drop)", "Silver Mask", missable = True, + npc = True), + DS3LocationData("AL: Soul of Rosaria (Leonhard drop)", "Soul of Rosaria", missable = True, npc = True), - DS3LocationData("AL: Silver Mask (Leonhard drop)", - "Silver Mask", DS3LocationCategory.ARMOR, missable = True, npc = True), - DS3LocationData("AL: Soul of Rosaria (Leonhard drop)", - "Soul of Rosaria", DS3LocationCategory.UNIQUE, missable = True, npc = True), ], "Lothric Castle": [ DS3LocationData("LC: Soul of Dragonslayer Armour", "Soul of Dragonslayer Armour", - DS3LocationCategory.SOUL, prominent = True, boss = True), - DS3LocationData("LC: Sniper Bolt (moat, right path end)", "Sniper Bolt x11", - DS3LocationCategory.MISC), - DS3LocationData("LC: Sniper Crossbow (moat, right path end)", "Sniper Crossbow", - DS3LocationCategory.WEAPON), - DS3LocationData("LC: Titanite Scale (dark room, upper balcony)", "Titanite Scale", - DS3LocationCategory.UPGRADE), + prominent = True, boss = True), + DS3LocationData("LC: Sniper Bolt (moat, right path end)", "Sniper Bolt x11"), + DS3LocationData("LC: Sniper Crossbow (moat, right path end)", "Sniper Crossbow"), + DS3LocationData("LC: Titanite Scale (dark room, upper balcony)", "Titanite Scale"), DS3LocationData("LC: Titanite Chunk (dark room mid, out door opposite wyvern)", - "Titanite Chunk", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Greatlance (overlooking Dragon Barracks bonfire)", "Greatlance", - DS3LocationCategory.WEAPON), - DS3LocationData("LC: Titanite Chunk (ascent, first balcony)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Titanite Chunk (ascent, turret before barricades)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), + "Titanite Chunk"), + DS3LocationData("LC: Greatlance (overlooking Dragon Barracks bonfire)", "Greatlance"), + DS3LocationData("LC: Titanite Chunk (ascent, first balcony)", "Titanite Chunk"), + DS3LocationData("LC: Titanite Chunk (ascent, turret before barricades)", "Titanite Chunk"), DS3LocationData("LC: Sacred Bloom Shield (ascent, behind illusory wall)", - "Sacred Bloom Shield", DS3LocationCategory.SHIELD, - hidden = True), # Behind illusory wall - DS3LocationData("LC: Titanite Chunk (ascent, final turret)", "Titanite Chunk x2", - DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Refined Gem (plaza)", "Refined Gem", DS3LocationCategory.UPGRADE), + "Sacred Bloom Shield", hidden = True), # Behind illusory wall + DS3LocationData("LC: Titanite Chunk (ascent, final turret)", "Titanite Chunk x2"), + DS3LocationData("LC: Refined Gem (plaza)", "Refined Gem"), DS3LocationData("LC: Soul of a Crestfallen Knight (by lift bottom)", - "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("LC: Undead Bone Shard (moat, far ledge)", "Undead Bone Shard", - DS3LocationCategory.HEALTH), - DS3LocationData("LC: Lightning Urn (moat, right path, first room)", "Lightning Urn x3", - DS3LocationCategory.MISC), - DS3LocationData("LC: Titanite Chunk (moat #1)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Titanite Chunk (moat #2)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Titanite Chunk (moat, near ledge)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Caitha's Chime (chapel, drop onto roof)", "Caitha's Chime", - DS3LocationCategory.WEAPON), - DS3LocationData("LC: Lightning Urn (plaza)", "Lightning Urn x6", DS3LocationCategory.MISC), - DS3LocationData("LC: Ember (plaza, by gate)", "Ember", DS3LocationCategory.MISC), - DS3LocationData("LC: Raw Gem (plaza left)", "Raw Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Black Firebomb (dark room lower)", "Black Firebomb x3", - DS3LocationCategory.MISC), - DS3LocationData("LC: Pale Pine Resin (dark room upper, by mimic)", "Pale Pine Resin", - DS3LocationCategory.MISC), + "Soul of a Crestfallen Knight"), + DS3LocationData("LC: Undead Bone Shard (moat, far ledge)", "Undead Bone Shard"), + DS3LocationData("LC: Lightning Urn (moat, right path, first room)", "Lightning Urn x3"), + DS3LocationData("LC: Titanite Chunk (moat #1)", "Titanite Chunk"), + DS3LocationData("LC: Titanite Chunk (moat #2)", "Titanite Chunk"), + DS3LocationData("LC: Titanite Chunk (moat, near ledge)", "Titanite Chunk"), + DS3LocationData("LC: Caitha's Chime (chapel, drop onto roof)", "Caitha's Chime"), + DS3LocationData("LC: Lightning Urn (plaza)", "Lightning Urn x6"), + DS3LocationData("LC: Ember (plaza, by gate)", "Ember"), + DS3LocationData("LC: Raw Gem (plaza left)", "Raw Gem"), + DS3LocationData("LC: Black Firebomb (dark room lower)", "Black Firebomb x3"), + DS3LocationData("LC: Pale Pine Resin (dark room upper, by mimic)", "Pale Pine Resin"), DS3LocationData("LC: Large Soul of a Weary Warrior (main hall, by lever)", - "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("LC: Sunlight Medal (by lift top)", "Sunlight Medal", - DS3LocationCategory.MISC), + "Large Soul of a Weary Warrior"), + DS3LocationData("LC: Sunlight Medal (by lift top)", "Sunlight Medal"), DS3LocationData("LC: Soul of a Crestfallen Knight (wyvern room, balcony)", - "Soul of a Crestfallen Knight", DS3LocationCategory.MISC, - hidden = True), # Hidden fall - DS3LocationData("LC: Titanite Chunk (altar roof)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), + "Soul of a Crestfallen Knight", hidden = True), # Hidden fall + DS3LocationData("LC: Titanite Chunk (altar roof)", "Titanite Chunk"), DS3LocationData("LC: Titanite Scale (dark room mid, out door opposite wyvern)", - "Titanite Scale", DS3LocationCategory.UPGRADE), + "Titanite Scale"), DS3LocationData("LC: Large Soul of a Nameless Soldier (moat, right path)", - "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("LC: Knight's Ring (altar)", "Knight's Ring", DS3LocationCategory.RING), - DS3LocationData("LC: Ember (main hall, left of stairs)", "Ember", DS3LocationCategory.MISC), + "Large Soul of a Nameless Soldier"), + DS3LocationData("LC: Knight's Ring (altar)", "Knight's Ring"), + DS3LocationData("LC: Ember (main hall, left of stairs)", "Ember"), DS3LocationData("LC: Large Soul of a Weary Warrior (ascent, last turret)", - "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("LC: Ember (by Dragon Barracks bonfire)", "Ember", - DS3LocationCategory.MISC), - DS3LocationData("LC: Twinkling Titanite (ascent, side room)", "Twinkling Titanite", - DS3LocationCategory.MISC), + "Large Soul of a Weary Warrior"), + DS3LocationData("LC: Ember (by Dragon Barracks bonfire)", "Ember"), + DS3LocationData("LC: Twinkling Titanite (ascent, side room)", "Twinkling Titanite"), DS3LocationData("LC: Large Soul of a Nameless Soldier (dark room mid)", - "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("LC: Ember (plaza center)", "Ember", DS3LocationCategory.MISC), + "Large Soul of a Nameless Soldier"), + DS3LocationData("LC: Ember (plaza center)", "Ember"), DS3LocationData("LC: Winged Knight Helm (ascent, behind illusory wall)", - "Winged Knight Helm", DS3LocationCategory.ARMOR, hidden = True), + "Winged Knight Helm", hidden = True), DS3LocationData("LC: Winged Knight Armor (ascent, behind illusory wall)", - "Winged Knight Armor", DS3LocationCategory.ARMOR, hidden = True), + "Winged Knight Armor", hidden = True), DS3LocationData("LC: Winged Knight Gauntlets (ascent, behind illusory wall)", - "Winged Knight Gauntlets", DS3LocationCategory.ARMOR, hidden = True), + "Winged Knight Gauntlets", hidden = True), DS3LocationData("LC: Winged Knight Leggings (ascent, behind illusory wall)", - "Winged Knight Leggings", DS3LocationCategory.ARMOR, hidden = True), - DS3LocationData("LC: Rusted Coin (chapel)", "Rusted Coin x2", DS3LocationCategory.MISC), + "Winged Knight Leggings", hidden = True), + DS3LocationData("LC: Rusted Coin (chapel)", "Rusted Coin x2"), DS3LocationData("LC: Braille Divine Tome of Lothric (wyvern room)", - "Braille Divine Tome of Lothric", DS3LocationCategory.UNIQUE, - hidden = True), # Hidden fall - DS3LocationData("LC: Red Tearstone Ring (chapel, drop onto roof)", "Red Tearstone Ring", - DS3LocationCategory.RING), - DS3LocationData("LC: Twinkling Titanite (moat, left side)", "Twinkling Titanite x2", - DS3LocationCategory.UPGRADE), + "Braille Divine Tome of Lothric", hidden = True), # Hidden fall + DS3LocationData("LC: Red Tearstone Ring (chapel, drop onto roof)", "Red Tearstone Ring"), + DS3LocationData("LC: Twinkling Titanite (moat, left side)", "Twinkling Titanite x2"), DS3LocationData("LC: Large Soul of a Nameless Soldier (plaza left, by pillar)", - "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("LC: Titanite Scale (altar)", "Titanite Scale x3", - DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Titanite Scale (chapel, chest)", "Titanite Scale", - DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Hood of Prayer", "Hood of Prayer", - DS3LocationCategory.ARMOR), - DS3LocationData("LC: Robe of Prayer (ascent, chest at beginning)", "Robe of Prayer", - DS3LocationCategory.ARMOR), - DS3LocationData("LC: Skirt of Prayer (ascent, chest at beginning)", "Skirt of Prayer", - DS3LocationCategory.ARMOR), + "Large Soul of a Nameless Soldier"), + DS3LocationData("LC: Titanite Scale (altar)", "Titanite Scale x3"), + DS3LocationData("LC: Titanite Scale (chapel, chest)", "Titanite Scale"), + DS3LocationData("LC: Hood of Prayer", "Hood of Prayer"), + DS3LocationData("LC: Robe of Prayer (ascent, chest at beginning)", "Robe of Prayer"), + DS3LocationData("LC: Skirt of Prayer (ascent, chest at beginning)", "Skirt of Prayer"), DS3LocationData("LC: Spirit Tree Crest Shield (basement, chest)", - "Spirit Tree Crest Shield", DS3LocationCategory.SHIELD), - DS3LocationData("LC: Titanite Scale (basement, chest)", "Titanite Scale", - DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Twinkling Titanite (basement, chest #1)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE), - DS3LocationData("LC: Twinkling Titanite (basement, chest #2)", "Twinkling Titanite x2", - DS3LocationCategory.UPGRADE), + "Spirit Tree Crest Shield"), + DS3LocationData("LC: Titanite Scale (basement, chest)", "Titanite Scale"), + DS3LocationData("LC: Twinkling Titanite (basement, chest #1)", "Twinkling Titanite"), + DS3LocationData("LC: Twinkling Titanite (basement, chest #2)", "Twinkling Titanite x2"), DS3LocationData("LC: Life Ring+2 (dark room mid, out door opposite wyvern, drop down)", - "Life Ring+2", DS3LocationCategory.RING, ngp = True, - hidden = True), # Hidden fall + "Life Ring+2", ngp = True, hidden = True), # Hidden fall DS3LocationData("LC: Dark Stoneplate Ring+1 (wyvern room, balcony)", - "Dark Stoneplate Ring+1", DS3LocationCategory.RING, ngp = True, - hidden = True), # Hidden fall + "Dark Stoneplate Ring+1", ngp = True, hidden = True), # Hidden fall DS3LocationData("LC: Thunder Stoneplate Ring+2 (chapel, drop onto roof)", - "Thunder Stoneplate Ring+2", DS3LocationCategory.RING, ngp = True), + "Thunder Stoneplate Ring+2", ngp = True), DS3LocationData("LC: Sunlight Straight Sword (wyvern room, mimic)", - "Sunlight Straight Sword", DS3LocationCategory.WEAPON, mimic = True, - hidden = True), # Hidden fall + "Sunlight Straight Sword", mimic = True, hidden = True), # Hidden fall DS3LocationData("LC: Titanite Scale (dark room, upper, mimic)", "Titanite Scale x3", - DS3LocationCategory.UPGRADE, mimic = True), + mimic = True), DS3LocationData("LC: Ember (wyvern room, wyvern foot mob drop)", "Ember x2", - DS3LocationCategory.MISC, - hidden = True), # Hidden fall, Pus of Man Wyvern drop + drop = True, hidden = True), # Hidden fall, Pus of Man Wyvern drop DS3LocationData("LC: Titanite Chunk (wyvern room, wyvern foot mob drop)", "Titanite Chunk x2", - DS3LocationCategory.UPGRADE, - hidden = True), # Hidden fall, Pus of Man Wyvern drop + drop = True, hidden = True), # Hidden fall, Pus of Man Wyvern drop DS3LocationData("LC: Ember (dark room mid, pus of man mob drop)", "Ember x2", - DS3LocationCategory.MISC), # Pus of Man Wyvern drop + drop = True), # Pus of Man Wyvern drop DS3LocationData("LC: Titanite Chunk (dark room mid, pus of man mob drop)", - "Titanite Chunk x2", DS3LocationCategory.UPGRADE), + "Titanite Chunk x2"), DS3LocationData("LC: Irithyll Rapier (basement, miniboss drop)", "Irithyll Rapier", - DS3LocationCategory.WEAPON, miniboss = True), # Boreal Outrider drop + miniboss = True), # Boreal Outrider drop DS3LocationData("LC: Twinkling Titanite (dark room mid, out door opposite wyvern, lizard)", - "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, lizard = True), + "Twinkling Titanite x2", lizard = True), DS3LocationData("LC: Twinkling Titanite (moat, right path, lizard)", - "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, lizard = True), + "Twinkling Titanite x2", lizard = True), DS3LocationData("LC: Gotthard Twinswords (by Grand Archives door, after PC and AL bosses)", - "Gotthard Twinswords", DS3LocationCategory.WEAPON, conditional = True), + "Gotthard Twinswords", conditional = True), DS3LocationData("LC: Grand Archives Key (by Grand Archives door, after PC and AL bosses)", - "Grand Archives Key", DS3LocationCategory.KEY, prominent = True, - progression = True, key = True, conditional = True), - DS3LocationData("LC: Titanite Chunk (down stairs after boss)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), + "Grand Archives Key", prominent = True, progression = True, + conditional = True), + DS3LocationData("LC: Titanite Chunk (down stairs after boss)", "Titanite Chunk"), # Eygon of Carim (kill or quest) - DS3LocationData("FS: Morne's Great Hammer (Eygon)", "Morne's Great Hammer", - DS3LocationCategory.WEAPON, npc = True), - DS3LocationData("FS: Moaning Shield (Eygon)", "Moaning Shield", DS3LocationCategory.SHIELD, - npc = True), + DS3LocationData("FS: Morne's Great Hammer (Eygon)", "Morne's Great Hammer", npc = True), + DS3LocationData("FS: Moaning Shield (Eygon)", "Moaning Shield", npc = True), # Shrine Handmaid after killing Dragonslayer Armour (or Eygon of Carim) DS3LocationData("FS: Dancer's Crown (shop after killing LC entry boss)", "Dancer's Crown", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Dancer's Armor (shop after killing LC entry boss)", "Dancer's Armor", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Dancer's Gauntlets (shop after killing LC entry boss)", - "Dancer's Gauntlets", DS3LocationCategory.ARMOR, boss = True, shop = True), + "Dancer's Gauntlets", boss = True, shop = True), DS3LocationData("FS: Dancer's Leggings (shop after killing LC entry boss)", - "Dancer's Leggings", DS3LocationCategory.ARMOR, boss = True, shop = True), + "Dancer's Leggings", boss = True, shop = True), # Shrine Handmaid after killing Dragonslayer Armour (or Eygon of Carim) DS3LocationData("FS: Morne's Helm (shop after killing Eygon or LC boss)", "Morne's Helm", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Morne's Armor (shop after killing Eygon or LC boss)", "Morne's Armor", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Morne's Gauntlets (shop after killing Eygon or LC boss)", - "Morne's Gauntlets", DS3LocationCategory.ARMOR, boss = True, shop = True), + "Morne's Gauntlets", boss = True, shop = True), DS3LocationData("FS: Morne's Leggings (shop after killing Eygon or LC boss)", - "Morne's Leggings", DS3LocationCategory.ARMOR, boss = True, shop = True), + "Morne's Leggings", boss = True, shop = True), ], "Consumed King's Garden": [ DS3LocationData("CKG: Soul of Consumed Oceiros", "Soul of Consumed Oceiros", - DS3LocationCategory.SOUL, prominent = True, boss = True), + prominent = True, boss = True), # Could classify this as "hidden" because it's midway down an elevator, but the elevator is # so slow and the midway point is so obvious that it's not actually hard to find. - DS3LocationData("CKG: Estus Shard (balcony)", "Estus Shard", DS3LocationCategory.HEALTH), - DS3LocationData("CKG: Shadow Mask (under center platform)", "Shadow Mask", - DS3LocationCategory.ARMOR), - DS3LocationData("CKG: Shadow Garb (under rotunda)", "Shadow Garb", - DS3LocationCategory.ARMOR), - DS3LocationData("CKG: Shadow Gauntlets (under rotunda)", "Shadow Gauntlets", - DS3LocationCategory.ARMOR), - DS3LocationData("CKG: Shadow Leggings (under rotunda)", "Shadow Leggings", - DS3LocationCategory.ARMOR), - DS3LocationData("CKG: Black Firebomb (under rotunda)", "Black Firebomb x2", - DS3LocationCategory.MISC), - DS3LocationData("CKG: Claw (under rotunda)", "Claw", DS3LocationCategory.WEAPON), - DS3LocationData("CKG: Titanite Chunk (up lone stairway)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), + DS3LocationData("CKG: Estus Shard (balcony)", "Estus Shard"), + DS3LocationData("CKG: Shadow Mask (under center platform)", "Shadow Mask"), + DS3LocationData("CKG: Shadow Garb (under rotunda)", "Shadow Garb"), + DS3LocationData("CKG: Shadow Gauntlets (under rotunda)", "Shadow Gauntlets"), + DS3LocationData("CKG: Shadow Leggings (under rotunda)", "Shadow Leggings"), + DS3LocationData("CKG: Black Firebomb (under rotunda)", "Black Firebomb x2"), + DS3LocationData("CKG: Claw (under rotunda)", "Claw"), + DS3LocationData("CKG: Titanite Chunk (up lone stairway)", "Titanite Chunk"), DS3LocationData("CKG: Dragonscale Ring (shortcut, leave halfway down lift)", - "Dragonscale Ring", DS3LocationCategory.RING), - DS3LocationData("CKG: Human Pine Resin (toxic pool, past rotunda)", "Human Pine Resin", - DS3LocationCategory.MISC), - DS3LocationData("CKG: Titanite Chunk (shortcut)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("CKG: Titanite Chunk (balcony, drop onto rubble)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), + "Dragonscale Ring"), + DS3LocationData("CKG: Human Pine Resin (toxic pool, past rotunda)", "Human Pine Resin"), + DS3LocationData("CKG: Titanite Chunk (shortcut)", "Titanite Chunk"), + DS3LocationData("CKG: Titanite Chunk (balcony, drop onto rubble)", "Titanite Chunk"), DS3LocationData("CKG: Soul of a Weary Warrior (before first lift)", - "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("CKG: Dark Gem (under lone stairway)", "Dark Gem", - DS3LocationCategory.UPGRADE), - DS3LocationData("CKG: Titanite Scale (shortcut)", "Titanite Scale", - DS3LocationCategory.UPGRADE), + "Soul of a Weary Warrior"), + DS3LocationData("CKG: Dark Gem (under lone stairway)", "Dark Gem"), + DS3LocationData("CKG: Titanite Scale (shortcut)", "Titanite Scale"), DS3LocationData("CKG: Human Pine Resin (by lone stairway bottom)", - "Human Pine Resin x2", DS3LocationCategory.MISC), - DS3LocationData("CKG: Titanite Chunk (right of shortcut lift bottom)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("CKG: Ring of Sacrifice (under balcony)", "Ring of Sacrifice", - DS3LocationCategory.MISC), + "Human Pine Resin x2"), + DS3LocationData("CKG: Titanite Chunk (right of shortcut lift bottom)", "Titanite Chunk"), + DS3LocationData("CKG: Ring of Sacrifice (under balcony)", "Ring of Sacrifice"), DS3LocationData("CKG: Wood Grain Ring+1 (by first elevator bottom)", "Wood Grain Ring+1", - DS3LocationCategory.RING, ngp = True), + ngp = True), DS3LocationData("CKG: Sage Ring+2 (balcony, drop onto rubble, jump back)", "Sage Ring+2", - DS3LocationCategory.RING, ngp = True, hidden = True), - DS3LocationData("CKG: Titanite Scale (tomb, chest #1)", "Titanite Scale", - DS3LocationCategory.UPGRADE), - DS3LocationData("CKG: Titanite Scale (tomb, chest #2)", "Titanite Scale", - DS3LocationCategory.UPGRADE), + ngp = True, hidden = True), + DS3LocationData("CKG: Titanite Scale (tomb, chest #1)", "Titanite Scale"), + DS3LocationData("CKG: Titanite Scale (tomb, chest #2)", "Titanite Scale"), DS3LocationData("CKG: Magic Stoneplate Ring (mob drop before boss)", - "Magic Stoneplate Ring", DS3LocationCategory.RING, drop = True, + "Magic Stoneplate Ring", drop = True, hidden = True), # Guaranteed drop from a normal-looking Cathedral Knight - DS3LocationData("CKG -> UG", None, DS3LocationCategory.EVENT), + DS3LocationData("CKG -> UG", None), # After Oceiros's boss room, only once the Drakeblood summon in AP has been killed DS3LocationData("CKG: Drakeblood Helm (tomb, after killing AP mausoleum NPC)", - "Drakeblood Helm", DS3LocationCategory.ARMOR, hostile_npc = True, - hidden = True), + "Drakeblood Helm", hostile_npc = True, hidden = True), DS3LocationData("CKG: Drakeblood Armor (tomb, after killing AP mausoleum NPC)", - "Drakeblood Armor", DS3LocationCategory.ARMOR, hostile_npc = True, - hidden = True), + "Drakeblood Armor", hostile_npc = True, hidden = True), DS3LocationData("CKG: Drakeblood Gauntlets (tomb, after killing AP mausoleum NPC)", - "Drakeblood Gauntlets", DS3LocationCategory.ARMOR, hostile_npc = True, - hidden = True), + "Drakeblood Gauntlets", hostile_npc = True, hidden = True), DS3LocationData("CKG: Drakeblood Leggings (tomb, after killing AP mausoleum NPC)", - "Drakeblood Leggings", DS3LocationCategory.ARMOR, hostile_npc = True, - hidden = True), + "Drakeblood Leggings", hostile_npc = True, hidden = True), ], "Grand Archives": [ DS3LocationData("GA: Titanite Slab (final elevator secret)", "Titanite Slab", - DS3LocationCategory.UPGRADE, hidden = True), - DS3LocationData("GA: Soul of the Twin Princes", "Soul of the Twin Princes", - DS3LocationCategory.SOUL, boss = True), + hidden = True), + DS3LocationData("GA: Soul of the Twin Princes", "Soul of the Twin Princes", boss = True), DS3LocationData("GA: Cinders of a Lord - Lothric Prince", - "Cinders of a Lord - Lothric Prince", DS3LocationCategory.KEY, + "Cinders of a Lord - Lothric Prince", offline = "09,0:50002040::", prominent = True, progression = True, boss = True), - DS3LocationData("GA: Onikiri and Ubadachi (outside 5F, NPC drop)", - "Onikiri and Ubadachi", DS3LocationCategory.WEAPON, + DS3LocationData("GA: Onikiri and Ubadachi (outside 5F, NPC drop)", "Onikiri and Ubadachi", hostile_npc = True), # Black Hand Kamui drop DS3LocationData("GA: Golden Wing Crest Shield (outside 5F, NPC drop)", - "Golden Wing Crest Shield", DS3LocationCategory.SHIELD, + "Golden Wing Crest Shield", hostile_npc = True), # Lion Knight Albert drop DS3LocationData("GA: Sage's Crystal Staff (outside 5F, NPC drop)", - "Sage's Crystal Staff", DS3LocationCategory.WEAPON, + "Sage's Crystal Staff", hostile_npc = True), # Daughter of Crystal Kriemhild drop - DS3LocationData("GA: Titanite Chunk (1F, up right stairs)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Titanite Chunk (1F, path from wax pool)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), + DS3LocationData("GA: Titanite Chunk (1F, up right stairs)", "Titanite Chunk"), + DS3LocationData("GA: Titanite Chunk (1F, path from wax pool)", "Titanite Chunk"), DS3LocationData("GA: Soul of a Crestfallen Knight (1F, loop left after drop)", - "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("GA: Titanite Chunk (1F, balcony)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Fleshbite Ring (up stairs from 4F)", "Fleshbite Ring", - DS3LocationCategory.RING), + "Soul of a Crestfallen Knight"), + DS3LocationData("GA: Titanite Chunk (1F, balcony)", "Titanite Chunk"), + DS3LocationData("GA: Fleshbite Ring (up stairs from 4F)", "Fleshbite Ring"), DS3LocationData("GA: Soul of a Crestfallen Knight (path to dome)", - "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("GA: Soul of a Nameless Soldier (dark room)", "Soul of a Nameless Soldier", - DS3LocationCategory.SOUL), - DS3LocationData("GA: Crystal Chime (1F, path from wax pool)", "Crystal Chime", - DS3LocationCategory.WEAPON), - DS3LocationData("GA: Titanite Scale (dark room, upstairs)", "Titanite Scale", - DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Estus Shard (dome, far balcony)", "Estus Shard", - DS3LocationCategory.HEALTH), - DS3LocationData("GA: Homeward Bone (2F early balcony)", "Homeward Bone x3", - DS3LocationCategory.MISC), + "Soul of a Crestfallen Knight"), + DS3LocationData("GA: Soul of a Nameless Soldier (dark room)", "Soul of a Nameless Soldier"), + DS3LocationData("GA: Crystal Chime (1F, path from wax pool)", "Crystal Chime"), + DS3LocationData("GA: Titanite Scale (dark room, upstairs)", "Titanite Scale"), + DS3LocationData("GA: Estus Shard (dome, far balcony)", "Estus Shard"), + DS3LocationData("GA: Homeward Bone (2F early balcony)", "Homeward Bone x3"), DS3LocationData("GA: Titanite Scale (2F, titanite scale atop bookshelf)", "Titanite Scale", - DS3LocationCategory.UPGRADE, hidden = True), # Hidden fall - DS3LocationData("GA: Titanite Chunk (2F, by wax pool)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), + hidden = True), # Hidden fall + DS3LocationData("GA: Titanite Chunk (2F, by wax pool)", "Titanite Chunk"), DS3LocationData("GA: Hollow Gem (rooftops lower, in hall)", "Hollow Gem", - DS3LocationCategory.UPGRADE, hidden = True), # Hidden fall - DS3LocationData("GA: Titanite Scale (3F, corner up stairs)", "Titanite Scale", - DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Titanite Scale (1F, up stairs on bookshelf)", "Titanite Scale", - DS3LocationCategory.UPGRADE), + hidden = True), # Hidden fall + DS3LocationData("GA: Titanite Scale (3F, corner up stairs)", "Titanite Scale"), + DS3LocationData("GA: Titanite Scale (1F, up stairs on bookshelf)", "Titanite Scale"), DS3LocationData("GA: Titanite Scale (3F, by ladder to 2F late)", "Titanite Scale", - DS3LocationCategory.UPGRADE, hidden = True), # Hidden by a table - DS3LocationData("GA: Shriving Stone (2F late, by ladder from 3F)", "Shriving Stone", - DS3LocationCategory.UPGRADE), + hidden = True), # Hidden by a table + DS3LocationData("GA: Shriving Stone (2F late, by ladder from 3F)", "Shriving Stone"), DS3LocationData("GA: Large Soul of a Crestfallen Knight (4F, back)", - "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("GA: Titanite Chunk (rooftopps, balcony)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), + "Large Soul of a Crestfallen Knight"), + DS3LocationData("GA: Titanite Chunk (rooftopps, balcony)", "Titanite Chunk"), DS3LocationData("GA: Titanite Scale (rooftops lower, path to 2F)", "Titanite Scale x3", - DS3LocationCategory.UPGRADE, hidden = True), # Hidden fall + hidden = True), # Hidden fall DS3LocationData("GA: Titanite Chunk (rooftops lower, ledge by buttress)", "Titanite Chunk", - DS3LocationCategory.UPGRADE, hidden = True), # Hidden fall + hidden = True), # Hidden fall DS3LocationData("GA: Soul of a Weary Warrior (rooftops, by lizards)", - "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("GA: Titanite Chunk (rooftops, just before 5F)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Ember (5F, by entrance)", "Ember", DS3LocationCategory.MISC), - DS3LocationData("GA: Blessed Gem (rafters)", "Blessed Gem", DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Titanite Chunk (5F, far balcony)", "Titanite Chunk x2", - DS3LocationCategory.UPGRADE), + "Soul of a Weary Warrior"), + DS3LocationData("GA: Titanite Chunk (rooftops, just before 5F)", "Titanite Chunk"), + DS3LocationData("GA: Ember (5F, by entrance)", "Ember"), + DS3LocationData("GA: Blessed Gem (rafters)", "Blessed Gem"), + DS3LocationData("GA: Titanite Chunk (5F, far balcony)", "Titanite Chunk x2"), DS3LocationData("GA: Large Soul of a Crestfallen Knight (outside 5F)", - "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + "Large Soul of a Crestfallen Knight"), DS3LocationData("GA: Avelyn (1F, drop from 3F onto bookshelves)", "Avelyn", - DS3LocationCategory.WEAPON, hidden = True), # Hidden fall - DS3LocationData("GA: Titanite Chunk (2F, right after dark room)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("GA: Hunter's Ring (dome, very top)", "Hunter's Ring", - DS3LocationCategory.RING), + hidden = True), # Hidden fall + DS3LocationData("GA: Titanite Chunk (2F, right after dark room)", "Titanite Chunk"), + DS3LocationData("GA: Hunter's Ring (dome, very top)", "Hunter's Ring"), DS3LocationData("GA: Divine Pillars of Light (cage above rafters)", - "Divine Pillars of Light", DS3LocationCategory.SPELL), + "Divine Pillars of Light"), DS3LocationData("GA: Power Within (dark room, behind retractable bookshelf)", - "Power Within", DS3LocationCategory.SPELL, - hidden = True), # Switch in darkened room - DS3LocationData("GA: Sage Ring+1 (rafters, second level down)", "Sage Ring+1", - DS3LocationCategory.RING, ngp = True), + "Power Within", hidden = True), # Switch in darkened room + DS3LocationData("GA: Sage Ring+1 (rafters, second level down)", "Sage Ring+1", ngp = True), DS3LocationData("GA: Lingering Dragoncrest Ring+2 (dome, room behind spire)", - "Lingering Dragoncrest Ring+2", DS3LocationCategory.RING, ngp = True), - DS3LocationData("GA: Divine Blessing (rafters, down lower level ladder)", "Divine Blessing", - DS3LocationCategory.MISC), + "Lingering Dragoncrest Ring+2", ngp = True), + DS3LocationData("GA: Divine Blessing (rafters, down lower level ladder)", + "Divine Blessing"), DS3LocationData("GA: Twinkling Titanite (rafters, down lower level ladder)", - "Twinkling Titanite x3", DS3LocationCategory.UPGRADE), + "Twinkling Titanite x3"), DS3LocationData("GA: Witch's Locks (dark room, behind retractable bookshelf)", - "Witch's Locks", DS3LocationCategory.WEAPON, - hidden = True), # Switch in darkened room + "Witch's Locks", hidden = True), # Switch in darkened room DS3LocationData("GA: Titanite Slab (1F, after pulling 2F switch)", "Titanite Slab", - DS3LocationCategory.UPGRADE, hidden = True), - DS3LocationData("GA: Titanite Scale (5F, chest by exit)", "Titanite Scale x3", - DS3LocationCategory.UPGRADE), + hidden = True), + DS3LocationData("GA: Titanite Scale (5F, chest by exit)", "Titanite Scale x3"), DS3LocationData("GA: Soul Stream (3F, behind illusory wall)", "Soul Stream", - DS3LocationCategory.SPELL, hidden = True), # Behind illusory wall - DS3LocationData("GA: Scholar Ring (2F, between late and early)", "Scholar Ring", - DS3LocationCategory.RING), - DS3LocationData("GA: Undead Bone Shard (5F, by entrance)", "Undead Bone Shard", - DS3LocationCategory.HEALTH), + hidden = True), # Behind illusory wall + DS3LocationData("GA: Scholar Ring (2F, between late and early)", "Scholar Ring"), + DS3LocationData("GA: Undead Bone Shard (5F, by entrance)", "Undead Bone Shard"), DS3LocationData("GA: Titanite Slab (dome, kill all mobs)", "Titanite Slab", - DS3LocationCategory.UPGRADE, drop = True, + drop = True, hidden = True), # Guaranteed drop from killing all Winged Knights DS3LocationData("GA: Outrider Knight Helm (3F, behind illusory wall, miniboss drop)", - "Outrider Knight Helm", DS3LocationCategory.ARMOR, - miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop + "Outrider Knight Helm", miniboss = True, + hidden = True), # Behind illusory wall, Outrider Knight drop DS3LocationData("GA: Outrider Knight Armor (3F, behind illusory wall, miniboss drop)", - "Outrider Knight Armor", DS3LocationCategory.ARMOR, miniboss = True, + "Outrider Knight Armor", miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop DS3LocationData("GA: Outrider Knight Gauntlets (3F, behind illusory wall, miniboss drop)", - "Outrider Knight Gauntlets", DS3LocationCategory.ARMOR, miniboss = True, + "Outrider Knight Gauntlets", miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop DS3LocationData("GA: Outrider Knight Leggings (3F, behind illusory wall, miniboss drop)", - "Outrider Knight Leggings", DS3LocationCategory.ARMOR, miniboss = True, + "Outrider Knight Leggings", miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop DS3LocationData("GA: Crystal Scroll (2F late, miniboss drop)", "Crystal Scroll", - DS3LocationCategory.UNIQUE, miniboss = True), # Crystal Sage drop + miniboss = True), # Crystal Sage drop DS3LocationData("GA: Twinkling Titanite (dark room, lizard #1)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("GA: Chaos Gem (dark room, lizard)", "Chaos Gem", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), + DS3LocationData("GA: Chaos Gem (dark room, lizard)", "Chaos Gem", lizard = True), DS3LocationData("GA: Twinkling Titanite (1F, lizard by drop)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("GA: Crystal Gem (1F, lizard by drop)", "Crystal Gem", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), + DS3LocationData("GA: Crystal Gem (1F, lizard by drop)", "Crystal Gem", lizard = True), DS3LocationData("GA: Twinkling Titanite (2F, lizard by entrance)", "Twinkling Titanite x2", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), DS3LocationData("GA: Titanite Scale (1F, drop from 2F late onto bookshelves, lizard)", - "Titanite Scale x2", DS3LocationCategory.UPGRADE, lizard = True, - hidden = True), # Hidden fall + "Titanite Scale x2", lizard = True, hidden = True), # Hidden fall DS3LocationData("GA: Twinkling Titanite (rooftops, lizard #1)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("GA: Heavy Gem (rooftops, lizard)", "Heavy Gem", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), + DS3LocationData("GA: Heavy Gem (rooftops, lizard)", "Heavy Gem", lizard = True), DS3LocationData("GA: Twinkling Titanite (rooftops, lizard #2)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("GA: Sharp Gem (rooftops, lizard)", "Sharp Gem", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), + DS3LocationData("GA: Sharp Gem (rooftops, lizard)", "Sharp Gem", lizard = True), DS3LocationData("GA: Twinkling Titanite (up stairs from 4F, lizard)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), DS3LocationData("GA: Refined Gem (up stairs from 4F, lizard)", "Refined Gem", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), DS3LocationData("GA: Twinkling Titanite (dark room, lizard #2)", "Twinkling Titanite x2", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), # Shrine Handmaid after killing NPCs DS3LocationData("FS: Faraam Helm (shop after killing GA NPC)", "Faraam Helm", - DS3LocationCategory.ARMOR, hidden = True, hostile_npc = True, shop = True), + hidden = True, hostile_npc = True, shop = True), DS3LocationData("GA: Faraam Armor (shop after killing GA NPC)", "Faraam Armor", - DS3LocationCategory.ARMOR, hidden = True, hostile_npc = True, shop = True), + hidden = True, hostile_npc = True, shop = True), DS3LocationData("GA: Faraam Gauntlets (shop after killing GA NPC)", "Faraam Gauntlets", - DS3LocationCategory.ARMOR, hidden = True, hostile_npc = True, shop = True), + hidden = True, hostile_npc = True, shop = True), DS3LocationData("GA: Faraam Boots (shop after killing GA NPC)", "Faraam Boots", - DS3LocationCategory.ARMOR, hidden = True, hostile_npc = True, shop = True), + hidden = True, hostile_npc = True, shop = True), DS3LocationData("GA: Black Hand Hat (shop after killing GA NPC)", "Black Hand Hat", - DS3LocationCategory.ARMOR, hidden = True, hostile_npc = True, shop = True), + hidden = True, hostile_npc = True, shop = True), DS3LocationData("GA: Black Hand Armor (shop after killing GA NPC)", "Black Hand Armor", - DS3LocationCategory.ARMOR, hidden = True, hostile_npc = True, shop = True), + hidden = True, hostile_npc = True, shop = True), # Shrine Handmaid after killing Lothric, Younger Prince DS3LocationData("FS: Lorian's Helm (shop after killing GA boss)", "Lorian's Helm", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Lorian's Armor (shop after killing GA boss)", "Lorian's Armor", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Lorian's Gauntlets (shop after killing GA boss)", "Lorian's Gauntlets", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Lorian's Leggings (shop after killing GA boss)", "Lorian's Leggings", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), # Sirris quest completion + beat Twin Princes DS3LocationData("FS: Sunless Talisman (Sirris, kill GA boss)", "Sunless Talisman", - DS3LocationCategory.WEAPON, missable = True, npc = True), + missable = True, npc = True), DS3LocationData("FS: Sunless Veil (shop, Sirris quest, kill GA boss)", "Sunless Veil", - DS3LocationCategory.ARMOR, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("FS: Sunless Armor (shop, Sirris quest, kill GA boss)", "Sunless Armor", - DS3LocationCategory.ARMOR, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), DS3LocationData("FS: Sunless Gauntlets (shop, Sirris quest, kill GA boss)", - "Sunless Gauntlets", DS3LocationCategory.ARMOR, missable = True, npc = True, - shop = True), + "Sunless Gauntlets", missable = True, npc = True, shop = True), DS3LocationData("FS: Sunless Leggings (shop, Sirris quest, kill GA boss)", - "Sunless Leggings", DS3LocationCategory.ARMOR, missable = True, npc = True, - shop = True), + "Sunless Leggings", missable = True, npc = True, shop = True), ], "Untended Graves": [ - DS3LocationData("UG: Soul of Champion Gundyr", "Soul of Champion Gundyr", - DS3LocationCategory.SOUL, prominent = True, boss = True), - DS3LocationData("UG: Priestess Ring (shop)", "Priestess Ring", DS3LocationCategory.RING, - shop = True), - DS3LocationData("UG: Shriving Stone (swamp, by bonfire)", "Shriving Stone", - DS3LocationCategory.UPGRADE), - DS3LocationData("UG: Titanite Chunk (swamp, left path by fountain)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), + DS3LocationData("UG: Soul of Champion Gundyr", "Soul of Champion Gundyr", prominent = True, + boss = True), + DS3LocationData("UG: Priestess Ring (shop)", "Priestess Ring", shop = True), + DS3LocationData("UG: Shriving Stone (swamp, by bonfire)", "Shriving Stone"), + DS3LocationData("UG: Titanite Chunk (swamp, left path by fountain)", "Titanite Chunk"), DS3LocationData("UG: Soul of a Crestfallen Knight (swamp, center)", - "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), - DS3LocationData("UG: Titanite Chunk (swamp, right path by fountain)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("UG: Ashen Estus Ring (swamp, path opposite bonfire)", "Ashen Estus Ring", - DS3LocationCategory.RING), - DS3LocationData("UG: Black Knight Glaive (boss arena)", "Black Knight Glaive", - DS3LocationCategory.WEAPON), - DS3LocationData("UG: Hidden Blessing (cemetery, behind coffin)", "Hidden Blessing", - DS3LocationCategory.MISC), + "Soul of a Crestfallen Knight"), + DS3LocationData("UG: Titanite Chunk (swamp, right path by fountain)", "Titanite Chunk"), + DS3LocationData("UG: Ashen Estus Ring (swamp, path opposite bonfire)", "Ashen Estus Ring"), + DS3LocationData("UG: Black Knight Glaive (boss arena)", "Black Knight Glaive"), + DS3LocationData("UG: Hidden Blessing (cemetery, behind coffin)", "Hidden Blessing"), DS3LocationData("UG: Eyes of a Fire Keeper (shrine, Irina's room)", "Eyes of a Fire Keeper", - DS3LocationCategory.KEY, hidden = True), # Illusory wall + hidden = True), # Illusory wall DS3LocationData("UG: Soul of a Crestfallen Knight (environs, above shrine entrance)", - "Soul of a Crestfallen Knight", DS3LocationCategory.MISC), - DS3LocationData("UG: Blacksmith Hammer (shrine, Andre's room)", "Blacksmith Hammer", - DS3LocationCategory.WEAPON), - DS3LocationData("UG: Chaos Blade (environs, left of shrine)", "Chaos Blade", - DS3LocationCategory.WEAPON), - DS3LocationData("UG: Hornet Ring (environs, right of main path)", - "Hornet Ring", DS3LocationCategory.RING, conditional = True), + "Soul of a Crestfallen Knight"), + DS3LocationData("UG: Blacksmith Hammer (shrine, Andre's room)", "Blacksmith Hammer"), + DS3LocationData("UG: Chaos Blade (environs, left of shrine)", "Chaos Blade"), + DS3LocationData("UG: Hornet Ring (environs, right of main path after killing FK boss)", + "Hornet Ring", conditional = True), DS3LocationData("UG: Coiled Sword Fragment (shrine, dead bonfire)", "Coiled Sword Fragment", - DS3LocationCategory.UNIQUE, boss = True), - DS3LocationData("UG: Life Ring+3 (shrine, behind big throne)", "Life Ring+3", - DS3LocationCategory.RING, ngp = True), + boss = True), + DS3LocationData("UG: Life Ring+3 (shrine, behind big throne)", "Life Ring+3", ngp = True), DS3LocationData("UG: Ring of Steel Protection+1 (environs, behind bell tower)", - "Ring of Steel Protection+1", DS3LocationCategory.RING, ngp = True), + "Ring of Steel Protection+1", ngp = True), # Yuria shop, or Shrine Handmaiden with Hollow's Ashes # This is here because this is where the ashes end up if you kill Yoel or Yuria DS3LocationData("FS: Ring of Sacrifice (Yuria shop)", "Ring of Sacrifice", - DS3LocationCategory.MISC, offline = '99,0:-1:40000,110000,70000107,70000116:', npc = True, shop = True), # Untended Graves Handmaid # All shop items are missable because she can be killed, except Priestess ring because she # drops it on death anyway. - DS3LocationData("UG: Ember (shop)", "Ember", DS3LocationCategory.RING, shop = True, - missable = True), + DS3LocationData("UG: Ember (shop)", "Ember", shop = True, missable = True), # Untended Graves Handmaid after killing Abyss Watchers DS3LocationData("UG: Wolf Knight Helm (shop after killing FK boss)", "Wolf Knight Helm", - DS3LocationCategory.ARMOR, boss = True, shop = True, conditional = True, + boss = True, shop = True, conditional = True, missable = True), DS3LocationData("UG: Wolf Knight Armor (shop after killing FK boss)", - "Wolf Knight Armor", DS3LocationCategory.ARMOR, boss = True, shop = True, - missable = True), + "Wolf Knight Armor", boss = True, shop = True, missable = True), DS3LocationData("UG: Wolf Knight Gauntlets (shop after killing FK boss)", - "Wolf Knight Gauntlets", DS3LocationCategory.ARMOR, boss = True, - shop = True, missable = True), + "Wolf Knight Gauntlets", boss = True, shop = True, missable = True), DS3LocationData("UG: Wolf Knight Leggings (shop after killing FK boss)", - "Wolf Knight Leggings", DS3LocationCategory.ARMOR, boss = True, shop = True, - missable = True), + "Wolf Knight Leggings", boss = True, shop = True, missable = True), # Shrine Handmaid after killing Champion Gundyr DS3LocationData("FS: Gundyr's Helm (shop after killing UG boss)", "Gundyr's Helm", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Gundyr's Armor (shop after killing UG boss)", "Gundyr's Armor", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Gundyr's Gauntlets (shop after killing UG boss)", "Gundyr's Gauntlets", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Gundyr's Leggings (shop after killing UG boss)", "Gundyr's Leggings", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), ], "Archdragon Peak": [ DS3LocationData("AP: Dragon Head Stone (fort, boss drop)", "Dragon Head Stone", - DS3LocationCategory.UNIQUE, prominent = True, boss = True), + prominent = True, boss = True), DS3LocationData("AP: Soul of the Nameless King", "Soul of the Nameless King", - DS3LocationCategory.SOUL, prominent = True, boss = True), + prominent = True, boss = True), DS3LocationData("AP: Dragon Tooth (belfry roof, NPC drop)", "Dragon Tooth", - DS3LocationCategory.WEAPON, hostile_npc = True), # Havel Knight drop + hostile_npc = True), # Havel Knight drop DS3LocationData("AP: Havel's Greatshield (belfry roof, NPC drop)", "Havel's Greatshield", - DS3LocationCategory.SHIELD, hostile_npc = True), # Havel Knight drop + hostile_npc = True), # Havel Knight drop DS3LocationData("AP: Drakeblood Greatsword (mausoleum, NPC drop)", "Drakeblood Greatsword", - DS3LocationCategory.WEAPON, hostile_npc = True), + hostile_npc = True), DS3LocationData("AP: Ricard's Rapier (belfry, NPC drop)", "Ricard's Rapier", - DS3LocationCategory.WEAPON, hostile_npc = True), + hostile_npc = True), DS3LocationData("AP: Lightning Clutch Ring (intro, left of boss door)", - "Lightning Clutch Ring", DS3LocationCategory.RING), - DS3LocationData("AP: Stalk Dung Pie (fort overlook)", "Stalk Dung Pie x6", - DS3LocationCategory.MISC), - DS3LocationData("AP: Titanite Chunk (fort, second room balcony)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), + "Lightning Clutch Ring"), + DS3LocationData("AP: Stalk Dung Pie (fort overlook)", "Stalk Dung Pie x6"), + DS3LocationData("AP: Titanite Chunk (fort, second room balcony)", "Titanite Chunk"), DS3LocationData("AP: Titanite Scale (mausoleum, downstairs balcony #1)", - "Titanite Scale", DS3LocationCategory.UPGRADE), + "Titanite Scale"), DS3LocationData("AP: Soul of a Weary Warrior (intro, first cliff edge)", - "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("AP: Titanite Chunk (intro, left before archway)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Lightning Gem (intro, side rise)", "Lightning Gem", - DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Homeward Bone (intro, path to bonfire)", "Homeward Bone x2", - DS3LocationCategory.MISC), + "Soul of a Weary Warrior"), + DS3LocationData("AP: Titanite Chunk (intro, left before archway)", "Titanite Chunk"), + DS3LocationData("AP: Lightning Gem (intro, side rise)", "Lightning Gem"), + DS3LocationData("AP: Homeward Bone (intro, path to bonfire)", "Homeward Bone x2"), DS3LocationData("AP: Soul of a Nameless Soldier (intro, right before archway)", - "Soul of a Nameless Soldier", DS3LocationCategory.SOUL), - DS3LocationData("AP: Titanite Chunk (intro, archway corner)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Ember (fort overlook #2)", "Ember", DS3LocationCategory.MISC), + "Soul of a Nameless Soldier"), + DS3LocationData("AP: Titanite Chunk (intro, archway corner)", "Titanite Chunk"), + DS3LocationData("AP: Ember (fort overlook #2)", "Ember"), DS3LocationData("AP: Large Soul of a Weary Warrior (fort, center)", - "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + "Large Soul of a Weary Warrior"), DS3LocationData("AP: Large Soul of a Nameless Soldier (fort, by stairs to first room)", - "Large Soul of a Nameless Soldier", DS3LocationCategory.SOUL), + "Large Soul of a Nameless Soldier"), DS3LocationData("AP: Lightning Urn (fort, left of first room entrance)", - "Lightning Urn x4", DS3LocationCategory.MISC), - DS3LocationData("AP: Lightning Bolt (rotunda)", "Lightning Bolt x12", - DS3LocationCategory.MISC), - DS3LocationData("AP: Titanite Chunk (rotunda)", "Titanite Chunk x2", - DS3LocationCategory.UPGRADE), + "Lightning Urn x4"), + DS3LocationData("AP: Lightning Bolt (rotunda)", "Lightning Bolt x12"), + DS3LocationData("AP: Titanite Chunk (rotunda)", "Titanite Chunk x2"), # Not 100% sure about this location name, can't find this on any maps - DS3LocationData("AP: Dung Pie (fort, landing after second room)", "Dung Pie x3", - DS3LocationCategory.MISC), - DS3LocationData("AP: Titanite Scale (mausoleum, downstairs balcony #2)", - "Titanite Scale", DS3LocationCategory.UPGRADE), + DS3LocationData("AP: Dung Pie (fort, landing after second room)", "Dung Pie x3"), + DS3LocationData("AP: Titanite Scale (mausoleum, downstairs balcony #2)", "Titanite Scale"), DS3LocationData("AP: Soul of a Weary Warrior (walkway, building window)", - "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + "Soul of a Weary Warrior"), DS3LocationData("AP: Soul of a Crestfallen Knight (mausoleum, upstairs)", - "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("AP: Titanite Chunk (intro, behind rock)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Ember (fort overlook #2)", "Ember", - DS3LocationCategory.MISC), + "Soul of a Crestfallen Knight"), + DS3LocationData("AP: Titanite Chunk (intro, behind rock)", "Titanite Chunk"), + DS3LocationData("AP: Ember (fort overlook #2)", "Ember"), DS3LocationData("AP: Thunder Stoneplate Ring (walkway, up ladder)", - "Thunder Stoneplate Ring", DS3LocationCategory.RING), - DS3LocationData("AP: Titanite Scale (mausoleum, upstairs balcony)", "Titanite Scale", - DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Ember (belfry, below bell)", "Ember", DS3LocationCategory.MISC), + "Thunder Stoneplate Ring"), + DS3LocationData("AP: Titanite Scale (mausoleum, upstairs balcony)", "Titanite Scale"), + DS3LocationData("AP: Ember (belfry, below bell)", "Ember"), DS3LocationData("AP: Ancient Dragon Greatshield (intro, on archway)", - "Ancient Dragon Greatshield", DS3LocationCategory.SHIELD), + "Ancient Dragon Greatshield"), DS3LocationData("AP: Large Soul of a Crestfallen Knight (summit, by fountain)", - "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + "Large Soul of a Crestfallen Knight"), DS3LocationData("AP: Dragon Chaser's Ashes (summit, side path)", "Dragon Chaser's Ashes", - DS3LocationCategory.KEY, progression = True), - DS3LocationData("AP: Ember (intro, by bonfire)", "Ember", DS3LocationCategory.MISC), - DS3LocationData("AP: Dragonslayer Spear (gate after mausoleum)", "Dragonslayer Spear", - DS3LocationCategory.WEAPON), - DS3LocationData("AP: Dragonslayer Helm (plaza)", "Dragonslayer Helm", - DS3LocationCategory.ARMOR), - DS3LocationData("AP: Dragonslayer Armor (plaza)", "Dragonslayer Armor", - DS3LocationCategory.ARMOR), - DS3LocationData("AP: Dragonslayer Gauntlets (plaza)", "Dragonslayer Gauntlets", - DS3LocationCategory.ARMOR), - DS3LocationData("AP: Dragonslayer Leggings (plaza)", "Dragonslayer Leggings", - DS3LocationCategory.ARMOR), - DS3LocationData("AP: Twinkling Titanite (fort, end of rafters)", "Twinkling Titanite x2", - DS3LocationCategory.UPGRADE), + progression = True), + DS3LocationData("AP: Ember (intro, by bonfire)", "Ember"), + DS3LocationData("AP: Dragonslayer Spear (gate after mausoleum)", "Dragonslayer Spear"), + DS3LocationData("AP: Dragonslayer Helm (plaza)", "Dragonslayer Helm"), + DS3LocationData("AP: Dragonslayer Armor (plaza)", "Dragonslayer Armor"), + DS3LocationData("AP: Dragonslayer Gauntlets (plaza)", "Dragonslayer Gauntlets"), + DS3LocationData("AP: Dragonslayer Leggings (plaza)", "Dragonslayer Leggings"), + DS3LocationData("AP: Twinkling Titanite (fort, end of rafters)", "Twinkling Titanite x2"), DS3LocationData("AP: Twinkling Titanite (fort, down second room balcony ladder)", - "Twinkling Titanite x2", DS3LocationCategory.UPGRADE), - DS3LocationData("AP: Titanite Slab (belfry roof)", "Titanite Slab", - DS3LocationCategory.UPGRADE), + "Twinkling Titanite x2"), + DS3LocationData("AP: Titanite Slab (belfry roof)", "Titanite Slab"), DS3LocationData("AP: Great Magic Barrier (drop off belfry roof)", "Great Magic Barrier", - DS3LocationCategory.SPELL, hidden = True), # Hidden fall - DS3LocationData("AP: Titanite Slab (plaza)", "Titanite Slab", DS3LocationCategory.UPGRADE), + hidden = True), # Hidden fall + DS3LocationData("AP: Titanite Slab (plaza)", "Titanite Slab"), DS3LocationData("AP: Ring of Steel Protection (fort overlook, beside stairs)", - "Ring of Steel Protection", DS3LocationCategory.RING), + "Ring of Steel Protection"), DS3LocationData("AP: Havel's Ring+1 (summit, after building)", "Havel's Ring+1", - DS3LocationCategory.RING, ngp = True), + ngp = True), DS3LocationData("AP: Covetous Gold Serpent Ring+2 (plaza)", "Covetous Gold Serpent Ring+2", - DS3LocationCategory.RING, ngp = True), - DS3LocationData("AP: Titanite Scale (walkway building)", "Titanite Scale x3", - DS3LocationCategory.UPGRADE), + ngp = True), + DS3LocationData("AP: Titanite Scale (walkway building)", "Titanite Scale x3"), DS3LocationData("AP: Twinkling Titanite (belfry, by ladder to roof)", - "Twinkling Titanite x3", DS3LocationCategory.UPGRADE), + "Twinkling Titanite x3"), DS3LocationData("AP: Twinkling Dragon Torso Stone (summit, gesture at altar)", - "Twinkling Dragon Torso Stone", DS3LocationCategory.MISC, - hidden = True), # Requires gesture + "Twinkling Dragon Torso Stone", hidden = True), # Requires gesture DS3LocationData("AP: Calamity Ring (mausoleum, gesture at altar)", "Calamity Ring", - DS3LocationCategory.RING, hidden = True), # Requires gesture + hidden = True), # Requires gesture DS3LocationData("AP: Twinkling Titanite (walkway building, lizard)", - "Twinkling Titanite x3", DS3LocationCategory.UPGRADE, lizard = True), + "Twinkling Titanite x3", lizard = True), DS3LocationData("AP: Titanite Chunk (walkway, miniboss drop)", "Titanite Chunk x6", - DS3LocationCategory.UPGRADE, miniboss = True), # Wyvern miniboss drop + miniboss = True), # Wyvern miniboss drop DS3LocationData("AP: Titanite Scale (walkway, miniboss drop)", "Titanite Scale x3", - DS3LocationCategory.UPGRADE, miniboss = True), # Wyvern miniboss drop + miniboss = True), # Wyvern miniboss drop DS3LocationData("AP: Twinkling Titanite (walkway, miniboss drop)", "Twinkling Titanite x3", - DS3LocationCategory.UPGRADE, miniboss = True), # Wyvern miniboss drop + miniboss = True), # Wyvern miniboss drop DS3LocationData("FS: Hawkwood's Swordgrass (Andre after gesture in AP summit)", - "Hawkwood's Swordgrass", DS3LocationCategory.UNIQUE, conditional = True, - hidden = True), + "Hawkwood's Swordgrass", conditional = True, hidden = True), # Shrine Handmaid after killing Nameless King DS3LocationData("FS: Golden Crown (shop after killing AP boss)", "Golden Crown", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Dragonscale Armor (shop after killing AP boss)", "Dragonscale Armor", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Golden Bracelets (shop after killing AP boss)", "Golden Bracelets", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Dragonscale Waistcloth (shop after killing AP boss)", - "Dragonscale Waistcloth", DS3LocationCategory.ARMOR, boss = True, - shop = True), + "Dragonscale Waistcloth", boss = True, shop = True), DS3LocationData("FK: Twinkling Dragon Head Stone (Hawkwood drop)", - "Twinkling Dragon Head Stone", DS3LocationCategory.UNIQUE, missable = True, + "Twinkling Dragon Head Stone", missable = True, npc = True), # Hawkwood (quest) ], "Kiln of the First Flame": [ - DS3LocationData("KFF: Soul of the Lords", "Soul of the Lords", DS3LocationCategory.SOUL, - boss = True), + DS3LocationData("KFF: Soul of the Lords", "Soul of the Lords", boss = True), # Shrine Handmaid after placing all Cinders of a Lord DS3LocationData("FS: Titanite Slab (shop after placing all Cinders)", "Titanite Slab", - DS3LocationCategory.UPGRADE, offline = '99,0:-1:9210,110000:', - hidden = True), + offline = '99,0:-1:9210,110000:', hidden = True), DS3LocationData("FS: Firelink Helm (shop after placing all Cinders)", "Firelink Helm", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Firelink Armor (shop after placing all Cinders)", "Firelink Armor", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Firelink Gauntlets (shop after placing all Cinders)", - "Firelink Gauntlets", DS3LocationCategory.ARMOR, boss = True, shop = True), + "Firelink Gauntlets", boss = True, shop = True), DS3LocationData("FS: Firelink Leggings (shop after placing all Cinders)", - "Firelink Leggings", DS3LocationCategory.ARMOR, boss = True, shop = True), + "Firelink Leggings", boss = True, shop = True), # Yuria (quest, after Soul of Cinder) DS3LocationData("FS: Billed Mask (Yuria after killing KFF boss)", "Billed Mask", - DS3LocationCategory.ARMOR, missable = True, npc = True), + missable = True, npc = True), DS3LocationData("FS: Black Dress (Yuria after killing KFF boss)", "Black Dress", - DS3LocationCategory.ARMOR, missable = True, npc = True), + missable = True, npc = True), DS3LocationData("FS: Black Gauntlets (Yuria after killing KFF boss)", "Black Gauntlets", - DS3LocationCategory.ARMOR, missable = True, npc = True), + missable = True, npc = True), DS3LocationData("FS: Black Leggings (Yuria after killing KFF boss)", "Black Leggings", - DS3LocationCategory.ARMOR, missable = True, npc = True), + missable = True, npc = True), ], # DLC "Painted World of Ariandel (Before Contraption)": [ - DS3LocationData("PW1: Valorheart (boss drop)", "Valorheart", - DS3LocationCategory.WEAPON, prominent = True, boss = True), + DS3LocationData("PW1: Valorheart (boss drop)", "Valorheart", prominent = True, boss = True), DS3LocationData("PW1: Contraption Key (library, NPC drop)", "Contraption Key", - DS3LocationCategory.KEY, prominent = True, progression = True, - hostile_npc = True, key = True), # Sir Vilhelm drop + prominent = True, progression = True, + hostile_npc = True), # Sir Vilhelm drop DS3LocationData("PW1: Onyx Blade (library, NPC drop)", "Onyx Blade", - DS3LocationCategory.WEAPON, hostile_npc = True), # Sir Vilhelm drop + hostile_npc = True), # Sir Vilhelm drop DS3LocationData("PW1: Chillbite Ring (Friede)", "Chillbite Ring", - DS3LocationCategory.RING, npc = True), # Friede conversation + npc = True), # Friede conversation DS3LocationData("PW1: Rime-blue Moss Clump (snowfield upper, starting cave)", - "Rime-blue Moss Clump x2", DS3LocationCategory.MISC), - DS3LocationData("PW1: Poison Gem (snowfield upper, forward from bonfire)", "Poison Gem", - DS3LocationCategory.UPGRADE), + "Rime-blue Moss Clump x2"), + DS3LocationData("PW1: Poison Gem (snowfield upper, forward from bonfire)", "Poison Gem"), DS3LocationData("PW1: Large Soul of an Unknown Traveler (snowfield lower, path back up)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Follower Javelin (snowfield lower, path back up)", "Follower Javelin", - DS3LocationCategory.WEAPON), + "Large Soul of an Unknown Traveler"), + DS3LocationData("PW1: Follower Javelin (snowfield lower, path back up)", "Follower Javelin"), DS3LocationData("PW1: Large Soul of an Unknown Traveler (snowfield lower, path to village)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Homeward Bone (snowfield village, outcropping)", "Homeward Bone x6", - DS3LocationCategory.MISC), + "Large Soul of an Unknown Traveler"), + DS3LocationData("PW1: Homeward Bone (snowfield village, outcropping)", "Homeward Bone x6"), DS3LocationData("PW1: Blessed Gem (snowfield, behind tower)", "Blessed Gem", - DS3LocationCategory.UPGRADE, hidden = True), # Hidden behind a tower + hidden = True), # Hidden behind a tower DS3LocationData("PW1: Captain's Ashes (snowfield tower, 6F)", "Captain's Ashes", - DS3LocationCategory.KEY, progression = True), + progression = True), DS3LocationData("PW1: Black Firebomb (snowfield lower, path to bridge)", - "Black Firebomb x2", DS3LocationCategory.MISC), - DS3LocationData("PW1: Shriving Stone (below bridge near)", "Shriving Stone", - DS3LocationCategory.UPGRADE), + "Black Firebomb x2"), + DS3LocationData("PW1: Shriving Stone (below bridge near)", "Shriving Stone"), DS3LocationData("PW1: Millwood Greatarrow (snowfield village, loop back to lower)", - "Millwood Greatarrow x5", DS3LocationCategory.MISC), + "Millwood Greatarrow x5"), DS3LocationData("PW1: Millwood Greatbow (snowfield village, loop back to lower)", - "Millwood Greatbow", DS3LocationCategory.WEAPON), + "Millwood Greatbow"), DS3LocationData("PW1: Large Soul of an Unknown Traveler (snowfield upper)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Rusted Coin (snowfield lower, straight from fall)", "Rusted Coin", - DS3LocationCategory.MISC), + "Large Soul of an Unknown Traveler"), + DS3LocationData("PW1: Rusted Coin (snowfield lower, straight from fall)", "Rusted Coin"), DS3LocationData("PW1: Large Titanite Shard (snowfield lower, left from fall)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE), + "Large Titanite Shard"), DS3LocationData("PW1: Large Soul of an Unknown Traveler (settlement courtyard, cliff)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + "Large Soul of an Unknown Traveler"), DS3LocationData("PW1: Crow Quills (settlement loop, jump into courtyard)", "Crow Quills", - DS3LocationCategory.WEAPON, hidden = True), # Hidden fall - DS3LocationData("PW1: Simple Gem (settlement, lowest level, behind gate)", "Simple Gem", - DS3LocationCategory.UPGRADE), + hidden = True), # Hidden fall + DS3LocationData("PW1: Simple Gem (settlement, lowest level, behind gate)", "Simple Gem"), DS3LocationData("PW1: Large Soul of an Unknown Traveler (settlement, by ladder to bonfire)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + "Large Soul of an Unknown Traveler"), DS3LocationData("PW1: Slave Knight Hood (settlement roofs, drop by ladder)", - "Slave Knight Hood", DS3LocationCategory.ARMOR), + "Slave Knight Hood"), DS3LocationData("PW1: Slave Knight Armor (settlement roofs, drop by ladder)", - "Slave Knight Armor", DS3LocationCategory.ARMOR), + "Slave Knight Armor"), DS3LocationData("PW1: Slave Knight Gauntlets (settlement roofs, drop by ladder)", - "Slave Knight Gauntlets", DS3LocationCategory.ARMOR), + "Slave Knight Gauntlets"), DS3LocationData("PW1: Slave Knight Leggings (settlement roofs, drop by ladder)", - "Slave Knight Leggings", DS3LocationCategory.ARMOR), - DS3LocationData("PW1: Ember (settlement main, left building after bridge)", "Ember", - DS3LocationCategory.MISC), - DS3LocationData("PW1: Dark Gem (settlement back, egg building)", "Dark Gem", - DS3LocationCategory.UPGRADE), + "Slave Knight Leggings"), + DS3LocationData("PW1: Ember (settlement main, left building after bridge)", "Ember"), + DS3LocationData("PW1: Dark Gem (settlement back, egg building)", "Dark Gem"), DS3LocationData("PW1: Large Soul of an Unknown Traveler (settlement roofs, balcony)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + "Large Soul of an Unknown Traveler"), DS3LocationData("PW1: Large Soul of an Unknown Traveler (settlement loop, by bonfire)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + "Large Soul of an Unknown Traveler"), DS3LocationData("PW1: Rusted Gold Coin (settlement roofs, roof near second ladder)", - "Rusted Gold Coin x3", DS3LocationCategory.MISC), + "Rusted Gold Coin x3"), DS3LocationData("PW1: Soul of a Crestfallen Knight (settlement hall, rafters)", - "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + "Soul of a Crestfallen Knight"), DS3LocationData("PW1: Way of White Corona (settlement hall, by altar)", - "Way of White Corona", DS3LocationCategory.SPELL), - DS3LocationData("PW1: Rusted Coin (right of library)", "Rusted Coin x2", - DS3LocationCategory.MISC), - DS3LocationData("PW1: Young White Branch (right of library)", "Young White Branch", - DS3LocationCategory.MISC), + "Way of White Corona"), + DS3LocationData("PW1: Rusted Coin (right of library)", "Rusted Coin x2"), + DS3LocationData("PW1: Young White Branch (right of library)", "Young White Branch"), DS3LocationData("PW1: Budding Green Blossom (settlement courtyard, ledge)", - "Budding Green Blossom x3", DS3LocationCategory.MISC), - DS3LocationData("PW1: Crow Talons (settlement roofs, near bonfire)", "Crow Talons", - DS3LocationCategory.WEAPON), - DS3LocationData("PW1: Hollow Gem (beside chapel)", "Hollow Gem", - DS3LocationCategory.UPGRADE), - DS3LocationData("PW1: Rime-blue Moss Clump (below bridge far)", "Rime-blue Moss Clump x4", - DS3LocationCategory.MISC), - DS3LocationData("PW1: Follower Sabre (roots above depths)", "Follower Sabre", - DS3LocationCategory.WEAPON), - DS3LocationData("PW1: Ember (roots above depths)", "Ember", DS3LocationCategory.MISC), - DS3LocationData("PW1: Snap Freeze (depths, far end, mob drop)", "Snap Freeze", - DS3LocationCategory.SPELL, drop = True, + "Budding Green Blossom x3"), + DS3LocationData("PW1: Crow Talons (settlement roofs, near bonfire)", "Crow Talons"), + DS3LocationData("PW1: Hollow Gem (beside chapel)", "Hollow Gem"), + DS3LocationData("PW1: Rime-blue Moss Clump (below bridge far)", "Rime-blue Moss Clump x4"), + DS3LocationData("PW1: Follower Sabre (roots above depths)", "Follower Sabre"), + DS3LocationData("PW1: Ember (roots above depths)", "Ember"), + DS3LocationData("PW1: Snap Freeze (depths, far end, mob drop)", "Snap Freeze", drop = True, hidden = True), # Guaranteed drop from normal-looking Tree Woman DS3LocationData("PW1: Rime-blue Moss Clump (snowfield upper, overhang)", - "Rime-blue Moss Clump", DS3LocationCategory.MISC), + "Rime-blue Moss Clump"), DS3LocationData("PW1: Large Soul of an Unknown Traveler (snowfield lower, by cliff)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Ember (settlement, building near bonfire)", "Ember", - DS3LocationCategory.MISC), - DS3LocationData("PW1: Frozen Weapon (snowfield lower, path to bonfire)", "Frozen Weapon", - DS3LocationCategory.SPELL), + "Large Soul of an Unknown Traveler"), + DS3LocationData("PW1: Ember (settlement, building near bonfire)", "Ember"), + DS3LocationData("PW1: Frozen Weapon (snowfield lower, path to bonfire)", "Frozen Weapon"), DS3LocationData("PW1: Titanite Slab (depths, up secret ladder)", "Titanite Slab", - DS3LocationCategory.UPGRADE, offline = '11,0:50004700::', + offline = '11,0:50004700::', hidden = True), # Must kill normal-looking Tree Woman - DS3LocationData("PW1: Homeward Bone (depths, up hill)", "Homeward Bone x2", - DS3LocationCategory.MISC), + DS3LocationData("PW1: Homeward Bone (depths, up hill)", "Homeward Bone x2"), DS3LocationData("PW1: Large Soul of an Unknown Traveler (below snowfield village overhang)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), + "Large Soul of an Unknown Traveler"), DS3LocationData("PW1: Large Soul of a Weary Warrior (settlement hall roof)", - "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + "Large Soul of a Weary Warrior"), DS3LocationData("PW1: Large Soul of an Unknown Traveler (settlement back)", - "Large Soul of an Unknown Traveler", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Heavy Gem (snowfield village)", "Heavy Gem", - DS3LocationCategory.UPGRADE), + "Large Soul of an Unknown Traveler"), + DS3LocationData("PW1: Heavy Gem (snowfield village)", "Heavy Gem"), DS3LocationData("PW1: Large Soul of a Weary Warrior (snowfield tower, 6F)", - "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("PW1: Millwood Battle Axe (snowfield tower, 5F)", "Millwood Battle Axe", - DS3LocationCategory.WEAPON), - DS3LocationData("PW1: Ethereal Oak Shield (snowfield tower, 3F)", "Ethereal Oak Shield", - DS3LocationCategory.SHIELD), + "Large Soul of a Weary Warrior"), + DS3LocationData("PW1: Millwood Battle Axe (snowfield tower, 5F)", "Millwood Battle Axe"), + DS3LocationData("PW1: Ethereal Oak Shield (snowfield tower, 3F)", "Ethereal Oak Shield"), DS3LocationData("PW1: Soul of a Weary Warrior (snowfield tower, 1F)", - "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + "Soul of a Weary Warrior"), DS3LocationData("PW1: Twinkling Titanite (snowfield tower, 3F lizard)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + "Twinkling Titanite", lizard = True), DS3LocationData("PW1: Large Titanite Shard (lizard under bridge near)", - "Large Titanite Shard", DS3LocationCategory.UPGRADE, lizard = True), + "Large Titanite Shard", lizard = True), DS3LocationData("PW1: Twinkling Titanite (roots, lizard)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), DS3LocationData("PW1: Twinkling Titanite (settlement roofs, lizard before hall)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + "Twinkling Titanite", lizard = True), DS3LocationData("PW1: Large Titanite Shard (settlement loop, lizard)", - "Large Titanite Shard x2", DS3LocationCategory.UPGRADE, lizard = True), + "Large Titanite Shard x2", lizard = True), DS3LocationData("PW1: Champion's Bones (boss drop)", "Champion's Bones", - DS3LocationCategory.UNIQUE, offline = '11,0:50002310::', boss = True), + offline = '11,0:50002310::', boss = True), ], "Painted World of Ariandel (After Contraption)": [ - DS3LocationData("PW2: Soul of Sister Friede", "Soul of Sister Friede", DS3LocationCategory.SOUL, - prominent = True, boss = True), + DS3LocationData("PW2: Soul of Sister Friede", "Soul of Sister Friede", prominent = True, + boss = True), DS3LocationData("PW2: Titanite Slab (boss drop)", "Titanite Slab", - DS3LocationCategory.UPGRADE, offline = '11,0:50004700::', + offline = '11,0:50004700::', boss = True), # One-time drop after Friede Phase 2 - DS3LocationData("PW2: Floating Chaos (Dunnel drop)", "Floating Chaos", - DS3LocationCategory.SPELL, hostile_npc = True, + DS3LocationData("PW2: Floating Chaos (Dunnel drop)", "Floating Chaos", hostile_npc = True, hidden = True), # Livid Pyromancer Dunnel drop (requires ember) - DS3LocationData("PW2: Prism Stone (pass, tree by beginning)", "Prism Stone x10", - DS3LocationCategory.MISC), - DS3LocationData("PW2: Titanite Chunk (pass, cliff overlooking bonfire)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("PW2: Titanite Chunk (pass, by kickable tree)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("PW2: Follower Shield (pass, far cliffside)", "Follower Shield", - DS3LocationCategory.SHIELD), + DS3LocationData("PW2: Prism Stone (pass, tree by beginning)", "Prism Stone x10"), + DS3LocationData("PW2: Titanite Chunk (pass, cliff overlooking bonfire)", "Titanite Chunk"), + DS3LocationData("PW2: Titanite Chunk (pass, by kickable tree)", "Titanite Chunk"), + DS3LocationData("PW2: Follower Shield (pass, far cliffside)", "Follower Shield"), DS3LocationData("PW2: Large Titanite Shard (pass, just before B1)", - "Large Titanite Shard x2", DS3LocationCategory.UPGRADE), - DS3LocationData("PW2: Quakestone Hammer (pass, side path near B1)", "Quakestone Hammer", - DS3LocationCategory.WEAPON), - DS3LocationData("PW2: Ember (pass, central alcove)", "Ember", DS3LocationCategory.MISC), + "Large Titanite Shard x2"), + DS3LocationData("PW2: Quakestone Hammer (pass, side path near B1)", "Quakestone Hammer"), + DS3LocationData("PW2: Ember (pass, central alcove)", "Ember"), DS3LocationData("PW2: Large Titanite Shard (pass, far side path)", - "Large Titanite Shard x2", DS3LocationCategory.UPGRADE), + "Large Titanite Shard x2"), DS3LocationData("PW2: Soul of a Crestfallen Knight (pit edge #1)", - "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + "Soul of a Crestfallen Knight"), DS3LocationData("PW2: Soul of a Crestfallen Knight (pit edge #2)", - "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + "Soul of a Crestfallen Knight"), DS3LocationData("PW2: Large Soul of a Crestfallen Knight (pit, by tree)", - "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("PW2: Earth Seeker (pit cave)", "Earth Seeker", DS3LocationCategory.WEAPON), - DS3LocationData("PW2: Follower Torch (pass, far side path)", "Follower Torch", - DS3LocationCategory.SHIELD), - DS3LocationData("PW2: Dung Pie (B1)", "Dung Pie x2", DS3LocationCategory.MISC), - DS3LocationData("PW2: Vilhelm's Helm", "Vilhelm's Helm", - DS3LocationCategory.ARMOR), - DS3LocationData("PW2: Vilhelm's Armor (B2, along wall)", "Vilhelm's Armor", - DS3LocationCategory.ARMOR), - DS3LocationData("PW2: Vilhelm's Gauntlets (B2, along wall)", "Vilhelm's Gauntlets", - DS3LocationCategory.ARMOR), - DS3LocationData("PW2: Vilhelm's Leggings (B2, along wall)", "Vilhelm's Leggings", - DS3LocationCategory.ARMOR), + "Large Soul of a Crestfallen Knight"), + DS3LocationData("PW2: Earth Seeker (pit cave)", "Earth Seeker"), + DS3LocationData("PW2: Follower Torch (pass, far side path)", "Follower Torch"), + DS3LocationData("PW2: Dung Pie (B1)", "Dung Pie x2"), + DS3LocationData("PW2: Vilhelm's Helm", "Vilhelm's Helm"), + DS3LocationData("PW2: Vilhelm's Armor (B2, along wall)", "Vilhelm's Armor"), + DS3LocationData("PW2: Vilhelm's Gauntlets (B2, along wall)", "Vilhelm's Gauntlets"), + DS3LocationData("PW2: Vilhelm's Leggings (B2, along wall)", "Vilhelm's Leggings"), DS3LocationData("PW2: Pyromancer's Parting Flame (rotunda)", - "Pyromancer's Parting Flame", DS3LocationCategory.WEAPON, - hidden = True), # Behind illusory wall + "Pyromancer's Parting Flame", hidden = True), # Behind illusory wall DS3LocationData("PW2: Homeward Bone (rotunda)", "Homeward Bone x2", - DS3LocationCategory.MISC, hidden = True), # Behind illusory wall DS3LocationData("PW2: Twinkling Titanite (B3, lizard #1)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), DS3LocationData("PW2: Twinkling Titanite (B3, lizard #2)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE, lizard = True), - DS3LocationData("PW2: Blood Gem (B2, center)", "Blood Gem", DS3LocationCategory.UPGRADE, + lizard = True), + DS3LocationData("PW2: Blood Gem (B2, center)", "Blood Gem", # TODO: Mark this as Area: ariandel_vilhelm in the offline rando and reorder offline = '11,0:54500480::'), - DS3LocationData("PW2 -> DH", None, DS3LocationCategory.EVENT), + DS3LocationData("PW2 -> DH", None), # Corvian Settler after killing Friede - DS3LocationData("PW1: Titanite Slab (Corvian)", "Titanite Slab", - DS3LocationCategory.UPGRADE, missable = True, + DS3LocationData("PW1: Titanite Slab (Corvian)", "Titanite Slab", missable = True, npc = True), # Shrine Handmaid after killing Sister Friede DS3LocationData("FS: Ordained Hood (shop after killing PW2 boss)", "Ordained Hood", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Ordained Dress (shop after killing PW2 boss)", "Ordained Dress", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), DS3LocationData("FS: Ordained Trousers (shop after killing PW2 boss)", "Ordained Trousers", - DS3LocationCategory.ARMOR, boss = True, shop = True), + boss = True, shop = True), ], "Dreg Heap": [ DS3LocationData("DH: Soul of the Demon Prince", "Soul of the Demon Prince", - DS3LocationCategory.SOUL, prominent = True, boss = True), - DS3LocationData("DH: Siegbräu (Lapp)", "Siegbräu", DS3LocationCategory.MISC, - missable = True, drop = True, npc = True), # Lapp (quest or kill) + prominent = True, boss = True), + DS3LocationData("DH: Siegbräu (Lapp)", "Siegbräu", missable = True, drop = True, + npc = True), # Lapp (quest or kill) DS3LocationData("DH: Flame Fan (swamp upper, NPC drop)", "Flame Fan", - DS3LocationCategory.SPELL, hostile_npc = True), # Desert Pyromancer Zoey drop - DS3LocationData("DH: Ember (castle, behind spire)", "Ember", DS3LocationCategory.MISC), - DS3LocationData("DH: Soul of a Weary Warrior (castle overhang)", "Soul of a Weary Warrior", - DS3LocationCategory.SOUL), - DS3LocationData("DH: Titanite Chunk (castle, up stairs)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Aquamarine Dagger (castle, up stairs)", "Aquamarine Dagger", - DS3LocationCategory.WEAPON), - DS3LocationData("DH: Twinkling Titanite (library, chandelier)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Murky Hand Scythe (library, behind bookshelves)", "Murky Hand Scythe", - DS3LocationCategory.WEAPON), - DS3LocationData("DH: Divine Blessing (library, after drop)", "Divine Blessing", - DS3LocationCategory.MISC), + DS3LocationData("DH: Ember (castle, behind spire)", "Ember"), + DS3LocationData("DH: Soul of a Weary Warrior (castle overhang)", "Soul of a Weary Warrior"), + DS3LocationData("DH: Titanite Chunk (castle, up stairs)", "Titanite Chunk"), + DS3LocationData("DH: Aquamarine Dagger (castle, up stairs)", "Aquamarine Dagger"), + DS3LocationData("DH: Twinkling Titanite (library, chandelier)", "Twinkling Titanite"), + DS3LocationData("DH: Murky Hand Scythe (library, behind bookshelves)", "Murky Hand Scythe"), + DS3LocationData("DH: Divine Blessing (library, after drop)", "Divine Blessing"), DS3LocationData("DH: Ring of Steel Protection+3 (ledge before church)", - "Ring of Steel Protection+3", DS3LocationCategory.RING), + "Ring of Steel Protection+3"), DS3LocationData("DH: Soul of a Crestfallen Knight (church, altar)", - "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("DH: Rusted Coin (behind fountain after church)", "Rusted Coin x2", - DS3LocationCategory.MISC), - DS3LocationData("DH: Titanite Chunk (pantry, first room)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Murky Longstaff (pantry, last room)", "Murky Longstaff", - DS3LocationCategory.WEAPON), + "Soul of a Crestfallen Knight"), + DS3LocationData("DH: Rusted Coin (behind fountain after church)", "Rusted Coin x2"), + DS3LocationData("DH: Titanite Chunk (pantry, first room)", "Titanite Chunk"), + DS3LocationData("DH: Murky Longstaff (pantry, last room)", "Murky Longstaff"), DS3LocationData("DH: Ember (pantry, behind crates just before upstairs)", "Ember", - DS3LocationCategory.MISC, hidden = True), # Behind illusory wall + hidden = True), # Behind illusory wall DS3LocationData("DH: Great Soul Dregs (pantry upstairs)", "Great Soul Dregs", - DS3LocationCategory.SPELL, hidden = True), # Behind illusory wall - DS3LocationData("DH: Covetous Silver Serpent Ring+3 (pantry upstairs, drop down)", - "Covetous Silver Serpent Ring+3", DS3LocationCategory.RING, hidden = True), # Behind illusory wall - DS3LocationData("DH: Titanite Chunk (path from church, by pillar)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Homeward Bone (end of path from church)", "Homeward Bone x3", - DS3LocationCategory.MISC), - DS3LocationData("DH: Lightning Urn (wall outside church)", "Lightning Urn x4", - DS3LocationCategory.MISC), - DS3LocationData("DH: Projected Heal (parapets balcony)", "Projected Heal", - DS3LocationCategory.SPELL), + DS3LocationData("DH: Covetous Silver Serpent Ring+3 (pantry upstairs, drop down)", + "Covetous Silver Serpent Ring+3", hidden = True), # Behind illusory wall + DS3LocationData("DH: Titanite Chunk (path from church, by pillar)", "Titanite Chunk"), + DS3LocationData("DH: Homeward Bone (end of path from church)", "Homeward Bone x3"), + DS3LocationData("DH: Lightning Urn (wall outside church)", "Lightning Urn x4"), + DS3LocationData("DH: Projected Heal (parapets balcony)", "Projected Heal"), DS3LocationData("DH: Large Soul of a Weary Warrior (parapets, hall)", - "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("DH: Lothric War Banner (parapets, end of hall)", "Lothric War Banner", - DS3LocationCategory.WEAPON), - DS3LocationData("DH: Titanite Scale (library, back of room)", "Titanite Scale", - DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Black Firebomb (ruins, up windmill from bonfire)", "Black Firebomb x4", - DS3LocationCategory.MISC), - DS3LocationData("DH: Titanite Chunk (ruins, path from bonfire)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Twinkling Titanite (ruins, root near bonfire)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE), + "Large Soul of a Weary Warrior"), + DS3LocationData("DH: Lothric War Banner (parapets, end of hall)", "Lothric War Banner"), + DS3LocationData("DH: Titanite Scale (library, back of room)", "Titanite Scale"), + DS3LocationData("DH: Black Firebomb (ruins, up windmill from bonfire)", "Black Firebomb x4"), + DS3LocationData("DH: Titanite Chunk (ruins, path from bonfire)", "Titanite Chunk"), + DS3LocationData("DH: Twinkling Titanite (ruins, root near bonfire)", "Twinkling Titanite"), DS3LocationData("DH: Desert Pyromancer Garb (ruins, by shack near cliff)", - "Desert Pyromancer Garb", DS3LocationCategory.ARMOR), - DS3LocationData("DH: Titanite Chunk (ruins, by far shack)", "Titanite Chunk x2", - DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Giant Door Shield (ruins, path below far shack)", - "Giant Door Shield", DS3LocationCategory.SHIELD), - DS3LocationData("DH: Ember (ruins, alcove before swamp)", "Ember", - DS3LocationCategory.MISC), + "Desert Pyromancer Garb"), + DS3LocationData("DH: Titanite Chunk (ruins, by far shack)", "Titanite Chunk x2"), + DS3LocationData("DH: Giant Door Shield (ruins, path below far shack)", "Giant Door Shield"), + DS3LocationData("DH: Ember (ruins, alcove before swamp)", "Ember"), DS3LocationData("DH: Desert Pyromancer Gloves (swamp, far right)", - "Desert Pyromancer Gloves", DS3LocationCategory.ARMOR), + "Desert Pyromancer Gloves"), DS3LocationData("DH: Desert Pyromancer Skirt (swamp right, by roots)", - "Desert Pyromancer Skirt", DS3LocationCategory.ARMOR), + "Desert Pyromancer Skirt"), DS3LocationData("DH: Titanite Scale (swamp upper, drop and jump into tower)", - "Titanite Scale", DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Purple Moss Clump (swamp shack)", "Purple Moss Clump x4", - DS3LocationCategory.MISC), - DS3LocationData("DH: Ring of Favor+3 (swamp right, up root)", "Ring of Favor+3", - DS3LocationCategory.RING), - DS3LocationData("DH: Titanite Chunk (swamp right, drop partway up root)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), + "Titanite Scale"), + DS3LocationData("DH: Purple Moss Clump (swamp shack)", "Purple Moss Clump x4"), + DS3LocationData("DH: Ring of Favor+3 (swamp right, up root)", "Ring of Favor+3"), + DS3LocationData("DH: Titanite Chunk (swamp right, drop partway up root)", "Titanite Chunk"), DS3LocationData("DH: Large Soul of a Weary Warrior (swamp, under overhang)", - "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("DH: Titanite Slab (swamp, path under overhang)", "Titanite Slab", - DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Titanite Chunk (swamp, along buildings)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("DH: Loincloth (swamp, left edge)", "Loincloth", - DS3LocationCategory.ARMOR), - DS3LocationData("DH: Titanite Chunk (swamp, path to upper)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), + "Large Soul of a Weary Warrior"), + DS3LocationData("DH: Titanite Slab (swamp, path under overhang)", "Titanite Slab"), + DS3LocationData("DH: Titanite Chunk (swamp, along buildings)", "Titanite Chunk"), + DS3LocationData("DH: Loincloth (swamp, left edge)", "Loincloth"), + DS3LocationData("DH: Titanite Chunk (swamp, path to upper)", "Titanite Chunk"), DS3LocationData("DH: Large Soul of a Weary Warrior (swamp center)", - "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + "Large Soul of a Weary Warrior"), DS3LocationData("DH: Harald Curved Greatsword (swamp left, under root)", - "Harald Curved Greatsword", DS3LocationCategory.WEAPON), - DS3LocationData("DH: Homeward Bone (swamp left, on root)", "Homeward Bone", - DS3LocationCategory.MISC), - DS3LocationData("DH: Prism Stone (swamp upper, tunnel start)", "Prism Stone x6", - DS3LocationCategory.MISC), + "Harald Curved Greatsword"), + DS3LocationData("DH: Homeward Bone (swamp left, on root)", "Homeward Bone"), + DS3LocationData("DH: Prism Stone (swamp upper, tunnel start)", "Prism Stone x6"), DS3LocationData("DH: Desert Pyromancer Hood (swamp upper, tunnel end)", - "Desert Pyromancer Hood", DS3LocationCategory.ARMOR), + "Desert Pyromancer Hood"), DS3LocationData("DH: Twinkling Titanite (swamp upper, drop onto root)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE, - hidden = True), # Hidden fall - DS3LocationData("DH: Divine Blessing (swamp upper, building roof)", "Divine Blessing", - DS3LocationCategory.MISC), - DS3LocationData("DH: Ember (ruins, alcove on cliff)", "Ember", DS3LocationCategory.MISC, - hidden = True), # Hidden fall + "Twinkling Titanite", hidden = True), # Hidden fall + DS3LocationData("DH: Divine Blessing (swamp upper, building roof)", "Divine Blessing"), + DS3LocationData("DH: Ember (ruins, alcove on cliff)", "Ember", hidden = True), # Hidden fall DS3LocationData("DH: Small Envoy Banner (boss drop)", "Small Envoy Banner", - DS3LocationCategory.KEY, progression = True, boss = True), + progression = True, boss = True), DS3LocationData("DH: Twinkling Titanite (ruins, alcove on cliff, mob drop)", - "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, drop = True, + "Twinkling Titanite x2", drop = True, hidden = True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim DS3LocationData("DH: Twinkling Titanite (swamp upper, mob drop on roof)", - "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, drop = True, + "Twinkling Titanite x2", drop = True, hidden = True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim DS3LocationData("DH: Twinkling Titanite (path after church, mob drop)", - "Twinkling Titanite x2", DS3LocationCategory.UPGRADE, drop = True, + "Twinkling Titanite x2", drop = True, hidden = True), # Guaranteed drop from killing normal-looking pilgrim # Stone-humped Hag's shop - DS3LocationData("DH: Splitleaf Greatsword (shop)", "Splitleaf Greatsword", - DS3LocationCategory.WEAPON, shop = True), - DS3LocationData("DH: Divine Blessing (shop)", "Divine Blessing", DS3LocationCategory.MISC, - shop = True), - DS3LocationData("DH: Hidden Blessing (shop)", "Hidden Blessing", DS3LocationCategory.MISC, - shop = True), - DS3LocationData("DH: Rusted Gold Coin (shop)", "Rusted Gold Coin", DS3LocationCategory.MISC, - shop = True), - DS3LocationData("DH: Ember (shop)", "Ember", DS3LocationCategory.MISC, shop = True), + DS3LocationData("DH: Splitleaf Greatsword (shop)", "Splitleaf Greatsword", shop = True), + DS3LocationData("DH: Divine Blessing (shop)", "Divine Blessing", shop = True), + DS3LocationData("DH: Hidden Blessing (shop)", "Hidden Blessing", shop = True), + DS3LocationData("DH: Rusted Gold Coin (shop)", "Rusted Gold Coin", shop = True), + DS3LocationData("DH: Ember (shop)", "Ember", shop = True), ], "Ringed City": [ DS3LocationData("RC: Titanite Slab (mid boss drop)", "Titanite Slab", - DS3LocationCategory.UPGRADE, prominent = True, - boss = True), # Halflight drop, only once + prominent = True, boss = True), # Halflight drop, only once DS3LocationData("RC: Filianore's Spear Ornament (mid boss drop)", - "Filianore's Spear Ornament", DS3LocationCategory.MISC), - DS3LocationData("RC: Soul of Darkeater Midir", "Soul of Darkeater Midir", - DS3LocationCategory.SOUL, prominent = True, boss = True), + "Filianore's Spear Ornament"), + DS3LocationData("RC: Soul of Darkeater Midir", "Soul of Darkeater Midir", prominent = True, + boss = True), DS3LocationData("RC: Sacred Chime of Filianore (ashes, NPC drop)", - "Sacred Chime of Filianore", DS3LocationCategory.WEAPON, + "Sacred Chime of Filianore", hostile_npc = True), # Shira (kill or quest) DS3LocationData("RC: Titanite Slab (ashes, NPC drop)", "Titanite Slab", - DS3LocationCategory.UPGRADE, hostile_npc = True), # Shira (kill or quest) + hostile_npc = True), # Shira (kill or quest) DS3LocationData("RC: Crucifix of the Mad King (ashes, NPC drop)", - "Crucifix of the Mad King", DS3LocationCategory.WEAPON, - hostile_npc = True), # Shira drop + "Crucifix of the Mad King", hostile_npc = True), # Shira drop DS3LocationData("RC: Ledo's Great Hammer (streets high, opposite building, NPC drop)", - "Ledo's Great Hammer", DS3LocationCategory.WEAPON, - hostile_npc = True), # Silver Knight Ledo drop - DS3LocationData("RC: Wolf Ring+3 (street gardens, NPC drop)", "Wolf Ring+3", DS3LocationCategory.RING, + "Ledo's Great Hammer", hostile_npc = True), # Silver Knight Ledo drop + DS3LocationData("RC: Wolf Ring+3 (street gardens, NPC drop)", "Wolf Ring+3", hostile_npc = True), # Alva drop DS3LocationData("RC: Blindfold Mask (grave, NPC drop)", "Blindfold Mask", - DS3LocationCategory.ARMOR, hostile_npc = True), # Moaning Knight drop - DS3LocationData("RC: Titanite Scale (wall top, behind spawn)", "Titanite Scale", - DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Ruin Helm (wall top, under stairs to bonfire)", "Ruin Helm", - DS3LocationCategory.ARMOR), - DS3LocationData("RC: Ruin Armor (wall top, under stairs to bonfire)", "Ruin Armor", - DS3LocationCategory.ARMOR), - DS3LocationData("RC: Ruin Gauntlets (wall top, under stairs to bonfire)", "Ruin Gauntlets", - DS3LocationCategory.ARMOR), - DS3LocationData("RC: Ruin Leggings (wall top, under stairs to bonfire)", "Ruin Leggings", - DS3LocationCategory.ARMOR), + hostile_npc = True), # Moaning Knight drop + DS3LocationData("RC: Titanite Scale (wall top, behind spawn)", "Titanite Scale"), + DS3LocationData("RC: Ruin Helm (wall top, under stairs to bonfire)", "Ruin Helm"), + DS3LocationData("RC: Ruin Armor (wall top, under stairs to bonfire)", "Ruin Armor"), + DS3LocationData("RC: Ruin Gauntlets (wall top, under stairs to bonfire)", "Ruin Gauntlets"), + DS3LocationData("RC: Ruin Leggings (wall top, under stairs to bonfire)", "Ruin Leggings"), DS3LocationData("RC: Budding Green Blossom (wall top, in flower cluster)", - "Budding Green Blossom x2", DS3LocationCategory.MISC), - DS3LocationData("RC: Titanite Chunk (wall top, among graves)", "Titanite Chunk x2", - DS3LocationCategory.MISC), - DS3LocationData("RC: Ember (wall top, by statue)", "Ember", DS3LocationCategory.MISC), + "Budding Green Blossom x2"), + DS3LocationData("RC: Titanite Chunk (wall top, among graves)", "Titanite Chunk x2"), + DS3LocationData("RC: Ember (wall top, by statue)", "Ember"), DS3LocationData("RC: Budding Green Blossom (wall top, flowers by stairs)", - "Budding Green Blossom x2", DS3LocationCategory.MISC), + "Budding Green Blossom x2"), DS3LocationData("RC: Hidden Blessing (wall top, tomb under platform)", "Hidden Blessing", - DS3LocationCategory.MISC, hidden = True), # hidden fall - DS3LocationData("RC: Soul of a Crestfallen Knight (wall top, under drop)", - "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL, hidden = True), # hidden fall + DS3LocationData("RC: Soul of a Crestfallen Knight (wall top, under drop)", + "Soul of a Crestfallen Knight", hidden = True), # hidden fall DS3LocationData("RC: Large Soul of a Weary Warrior (wall top, right of small tomb)", - "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("RC: Ember (wall upper, balcony)", "Ember", DS3LocationCategory.MISC), - DS3LocationData("RC: Purging Stone (wall top, by door to upper)", "Purging Stone x2", - DS3LocationCategory.MISC), - DS3LocationData("RC: Hollow Gem (wall upper, path to tower)", "Hollow Gem", - DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Titanite Chunk (wall upper, courtyard alcove)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), + "Large Soul of a Weary Warrior"), + DS3LocationData("RC: Ember (wall upper, balcony)", "Ember"), + DS3LocationData("RC: Purging Stone (wall top, by door to upper)", "Purging Stone x2"), + DS3LocationData("RC: Hollow Gem (wall upper, path to tower)", "Hollow Gem"), + DS3LocationData("RC: Titanite Chunk (wall upper, courtyard alcove)", "Titanite Chunk"), DS3LocationData("RC: Twinkling Titanite (wall tower, jump from chandelier)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE, - hidden = True), # Hidden fall - DS3LocationData("RC: Shriving Stone (wall tower, bottom floor center)", "Shriving Stone", - DS3LocationCategory.UPGRADE), + "Twinkling Titanite", hidden = True), # Hidden fall + DS3LocationData("RC: Shriving Stone (wall tower, bottom floor center)", "Shriving Stone"), DS3LocationData("RC: Shira's Crown (Shira's room after killing ashes NPC)", "Shira's Crown", - DS3LocationCategory.ARMOR, hidden = True), # Have to return to a cleared area DS3LocationData("RC: Shira's Armor (Shira's room after killing ashes NPC)", "Shira's Armor", - DS3LocationCategory.ARMOR, hidden = True), # Have to return to a cleared area DS3LocationData("RC: Shira's Gloves (Shira's room after killing ashes NPC)", - "Shira's Gloves", DS3LocationCategory.ARMOR, - hidden = True), # Have to return to a cleared area + "Shira's Gloves", hidden = True), # Have to return to a cleared area DS3LocationData("RC: Shira's Trousers (Shira's room after killing ashes NPC)", - "Shira's Trousers", DS3LocationCategory.ARMOR, - hidden = True), # Have to return to a cleared area - DS3LocationData("RC: Mossfruit (streets near left, path to garden)", "Mossfruit x2", - DS3LocationCategory.MISC), + "Shira's Trousers", hidden = True), # Have to return to a cleared area + DS3LocationData("RC: Mossfruit (streets near left, path to garden)", "Mossfruit x2"), DS3LocationData("RC: Large Soul of a Crestfallen Knight (streets, far stairs)", - "Large Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + "Large Soul of a Crestfallen Knight"), DS3LocationData("RC: Ringed Knight Spear (streets, down far right hall)", - "Ringed Knight Spear", DS3LocationCategory.WEAPON), + "Ringed Knight Spear"), DS3LocationData("RC: Black Witch Hat (streets garden)", "Black Witch Hat", - DS3LocationCategory.ARMOR, hostile_npc = True), # Alva + hostile_npc = True), # Alva DS3LocationData("RC: Black Witch Garb (streets garden)", "Black Witch Garb", - DS3LocationCategory.ARMOR, hostile_npc = True), # Alva + hostile_npc = True), # Alva DS3LocationData("RC: Black Witch Wrappings (streets garden)", "Black Witch Wrappings", - DS3LocationCategory.ARMOR, hostile_npc = True), # Alva + hostile_npc = True), # Alva DS3LocationData("RC: Black Witch Trousers (streets garden)", "Black Witch Trousers", - DS3LocationCategory.ARMOR, hostile_npc = True), # Alva + hostile_npc = True), # Alva DS3LocationData("RC: Dragonhead Shield (streets monument, across bridge)", - "Dragonhead Shield", DS3LocationCategory.SHIELD, - hidden = True), # "Show Your Humanity" puzzle + "Dragonhead Shield", hidden = True), # "Show Your Humanity" puzzle DS3LocationData("RC: Titanite Chunk (streets, near left drop)", "Titanite Chunk", - DS3LocationCategory.UPGRADE, hidden = True), # Hidden fall - DS3LocationData("RC: Mossfruit (streets, far left alcove)", "Mossfruit x2", - DS3LocationCategory.MISC), + hidden = True), # Hidden fall + DS3LocationData("RC: Mossfruit (streets, far left alcove)", "Mossfruit x2"), DS3LocationData("RC: Large Soul of a Crestfallen Knight (streets monument, across bridge)", - "Large Soul of a Crestfallen Knight", DS3LocationCategory.MISC, + "Large Soul of a Crestfallen Knight", hidden = True), # "Show Your Humanity" puzzle DS3LocationData("RC: Covetous Gold Serpent Ring+3 (streets, by Lapp)", - "Covetous Gold Serpent Ring+3", DS3LocationCategory.RING), - DS3LocationData("RC: Titanite Chunk (streets high, building opposite)", "Titanite Chunk x2", - DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Dark Gem (swamp near, by stairs)", "Dark Gem", - DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Prism Stone (swamp near, path to bonfire)", "Prism Stone x4", - DS3LocationCategory.MISC), + "Covetous Gold Serpent Ring+3"), + DS3LocationData("RC: Titanite Chunk (streets high, building opposite)", "Titanite Chunk x2"), + DS3LocationData("RC: Dark Gem (swamp near, by stairs)", "Dark Gem"), + DS3LocationData("RC: Prism Stone (swamp near, path to bonfire)", "Prism Stone x4"), DS3LocationData("RC: Ringed Knight Straight Sword (swamp near, pillar by bonfire)", - "Ringed Knight Straight Sword", DS3LocationCategory.WEAPON), + "Ringed Knight Straight Sword"), DS3LocationData("RC: Havel's Ring+3 (streets high, drop from building opposite)", - "Havel's Ring+3", DS3LocationCategory.RING, hidden = True), # Hidden fall - DS3LocationData("RC: Titanite Chunk (swamp near left, opposite ladder)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Twinkling Titanite (swamp near left)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Soul of a Weary Warrior (swamp center)", "Soul of a Weary Warrior", - DS3LocationCategory.SOUL), + "Havel's Ring+3", hidden = True), # Hidden fall + DS3LocationData("RC: Titanite Chunk (swamp near left, opposite ladder)", "Titanite Chunk"), + DS3LocationData("RC: Twinkling Titanite (swamp near left)", "Twinkling Titanite"), + DS3LocationData("RC: Soul of a Weary Warrior (swamp center)", "Soul of a Weary Warrior"), DS3LocationData("RC: Preacher's Right Arm (swamp near right, by crystal)", - "Preacher's Right Arm", DS3LocationCategory.WEAPON), - DS3LocationData("RC: Rubbish (swamp far, by crystal)", "Rubbish", DS3LocationCategory.MISC), + "Preacher's Right Arm"), + DS3LocationData("RC: Rubbish (swamp far, by crystal)", "Rubbish"), DS3LocationData("RC: Titanite Chunk (swamp near right, by sinking church)", - "Titanite Chunk", DS3LocationCategory.UPGRADE), + "Titanite Chunk"), DS3LocationData("RC: Black Witch Veil (swamp near right, by sinking church)", - "Black Witch Veil", DS3LocationCategory.ARMOR), + "Black Witch Veil"), DS3LocationData("RC: Twinkling Titanite (swamp near right, on sinking church)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE), + "Twinkling Titanite"), DS3LocationData("RC: Soul of a Crestfallen Knight (swamp near left, by ladder)", - "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), + "Soul of a Crestfallen Knight"), DS3LocationData("RC: White Preacher Head (swamp near, ground near bonfire exit)", - "White Preacher Head", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Titanite Scale (swamp far, by miniboss)", "Titanite Scale", - DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Titanite Scale (upper cliff, path under bridge)", "Titanite Scale", - DS3LocationCategory.UPGRADE), + "White Preacher Head"), + DS3LocationData("RC: Titanite Scale (swamp far, by miniboss)", "Titanite Scale"), + DS3LocationData("RC: Titanite Scale (upper cliff, path under bridge)", "Titanite Scale"), DS3LocationData("RC: Dragonhead Greatshield (upper cluff, under bridge)", - "Dragonhead Greatshield", DS3LocationCategory.SHIELD), - DS3LocationData("RC: Titanite Scale (upper cliff, first alcove)", "Titanite Scale x2", - DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Rubbish (upper cliff, middle)", "Rubbish", DS3LocationCategory.MISC), + "Dragonhead Greatshield"), + DS3LocationData("RC: Titanite Scale (upper cliff, first alcove)", "Titanite Scale x2"), + DS3LocationData("RC: Rubbish (upper cliff, middle)", "Rubbish"), DS3LocationData("RC: Large Soul of a Weary Warrior (upper cliff, end)", - "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("RC: Titanite Scale (upper cliff, lower path)", "Titanite Scale x2", - DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Titanite Scale (lower cliff, bridge)", "Titanite Scale", - DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Lightning Gem (grave, room after first drop)", "Lightning Gem", - DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Blessed Gem (grave, down lowest stairs)", "Blessed Gem", - DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Simple Gem (grave, up stairs after first drop)", "Simple Gem", - DS3LocationCategory.UPGRADE), + "Large Soul of a Weary Warrior"), + DS3LocationData("RC: Titanite Scale (upper cliff, lower path)", "Titanite Scale x2"), + DS3LocationData("RC: Titanite Scale (lower cliff, bridge)", "Titanite Scale"), + DS3LocationData("RC: Lightning Gem (grave, room after first drop)", "Lightning Gem"), + DS3LocationData("RC: Blessed Gem (grave, down lowest stairs)", "Blessed Gem"), + DS3LocationData("RC: Simple Gem (grave, up stairs after first drop)", "Simple Gem"), DS3LocationData("RC: Large Soul of a Weary Warrior (wall lower, past two illusory walls)", - "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL, hidden = True), + "Large Soul of a Weary Warrior", hidden = True), DS3LocationData("RC: Lightning Arrow (wall lower, past three illusory walls)", - "Lightning Arrow", DS3LocationCategory.SPELL), + "Lightning Arrow"), DS3LocationData("RC: Chloranthy Ring+3 (wall hidden, drop onto statue)", - "Chloranthy Ring+3", DS3LocationCategory.RING, - hidden = True), # Hidden fall - DS3LocationData("RC: Ember (wall hidden, statue room)", "Ember", DS3LocationCategory.MISC), + "Chloranthy Ring+3", hidden = True), # Hidden fall + DS3LocationData("RC: Ember (wall hidden, statue room)", "Ember"), DS3LocationData("RC: Filianore's Spear Ornament (wall hidden, by ladder)", - "Filianore's Spear Ornament", DS3LocationCategory.MISC), + "Filianore's Spear Ornament"), DS3LocationData("RC: Antiquated Plain Garb (wall hidden, before boss)", - "Antiquated Plain Garb", DS3LocationCategory.ARMOR), - DS3LocationData("RC: Violet Wrappings (wall hidden, before boss)", "Violet Wrappings", - DS3LocationCategory.ARMOR), + "Antiquated Plain Garb"), + DS3LocationData("RC: Violet Wrappings (wall hidden, before boss)", "Violet Wrappings"), DS3LocationData("RC: Soul of a Weary Warrior (upper cliff, by first alcove)", - "Soul of a Weary Warrior", DS3LocationCategory.SOUL), + "Soul of a Weary Warrior"), DS3LocationData("RC: Twinkling Titanite (church path, left of boss door)", - "Twinkling Titanite x2", DS3LocationCategory.UPGRADE), - DS3LocationData("RC: Budding Green Blossom (church path)", "Budding Green Blossom x3", - DS3LocationCategory.MISC), - DS3LocationData("RC: Titanite Chunk (swamp center, along edge)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), + "Twinkling Titanite x2"), + DS3LocationData("RC: Budding Green Blossom (church path)", "Budding Green Blossom x3"), + DS3LocationData("RC: Titanite Chunk (swamp center, along edge)", "Titanite Chunk"), DS3LocationData("RC: Large Soul of a Weary Warrior (swamp center)", - "Large Soul of a Weary Warrior", DS3LocationCategory.SOUL), + "Large Soul of a Weary Warrior"), DS3LocationData("RC: Soul of a Weary Warrior (swamp right, by sunken church)", - "Soul of a Weary Warrior", DS3LocationCategory.SOUL), - DS3LocationData("RC: Titanite Scale (swamp far, by miniboss)", "Titanite Scale", - DS3LocationCategory.UPGRADE), + "Soul of a Weary Warrior"), + DS3LocationData("RC: Titanite Scale (swamp far, by miniboss)", "Titanite Scale"), DS3LocationData("RC: Soul of a Crestfallen Knight (swamp far, behind crystal)", - "Soul of a Crestfallen Knight", DS3LocationCategory.SOUL), - DS3LocationData("RC: White Birch Bow (swamp far left, up hill)", "White Birch Bow", - DS3LocationCategory.WEAPON), - DS3LocationData("RC: Titanite Chunk (swamp far left, up hill)", "Titanite Chunk", - DS3LocationCategory.UPGRADE), + "Soul of a Crestfallen Knight"), + DS3LocationData("RC: White Birch Bow (swamp far left, up hill)", "White Birch Bow"), + DS3LocationData("RC: Titanite Chunk (swamp far left, up hill)", "Titanite Chunk"), DS3LocationData("RC: Young White Branch (swamp far left, by white tree)", - "Young White Branch", DS3LocationCategory.MISC), + "Young White Branch"), DS3LocationData("RC: Young White Branch (swamp far left, by white tree)", - "Young White Branch", DS3LocationCategory.MISC), + "Young White Branch"), DS3LocationData("RC: Young White Branch (swamp far left, by white tree)", - "Young White Branch", DS3LocationCategory.MISC), + "Young White Branch"), DS3LocationData("RC: Ringed Knight Paired Greatswords (church path, mob drop)", - "Ringed Knight Paired Greatswords", DS3LocationCategory.WEAPON, drop = True, + "Ringed Knight Paired Greatswords", drop = True, hidden = True), # Guaranteed drop from a normal-looking Ringed Knight DS3LocationData("RC: Hidden Blessing (swamp center, mob drop)", "Hidden Blessing", - DS3LocationCategory.MISC, drop = True, - hidden = True), # Guaranteed drop from Judicator + drop = True, hidden = True), # Guaranteed drop from Judicator DS3LocationData("RC: Divine Blessing (wall top, mob drop)", "Divine Blessing", - DS3LocationCategory.MISC, drop = True, - hidden = True), # Guaranteed drop from Judicator + drop = True, hidden = True), # Guaranteed drop from Judicator DS3LocationData("RC: Divine Blessing (streets monument, mob drop)", "Divine Blessing", - DS3LocationCategory.MISC, drop = True, + drop = True, hidden = True), # Guaranteed drop from Judicator, "Show Your Humanity" puzzle DS3LocationData("RC: Ring of the Evil Eye+3 (grave, mimic)", "Ring of the Evil Eye+3", - DS3LocationCategory.RING, mimic = True), + mimic = True), DS3LocationData("RC: Iron Dragonslayer Helm (swamp far, miniboss drop)", - "Iron Dragonslayer Helm", DS3LocationCategory.ARMOR, miniboss = True), + "Iron Dragonslayer Helm", miniboss = True), DS3LocationData("RC: Iron Dragonslayer Armor (swamp far, miniboss drop)", - "Iron Dragonslayer Armor", DS3LocationCategory.ARMOR, miniboss = True), + "Iron Dragonslayer Armor", miniboss = True), DS3LocationData("RC: Iron Dragonslayer Gauntlets (swamp far, miniboss drop)", - "Iron Dragonslayer Gauntlets", DS3LocationCategory.ARMOR, miniboss = True), + "Iron Dragonslayer Gauntlets", miniboss = True), DS3LocationData("RC: Iron Dragonslayer Leggings (swamp far, miniboss drop)", - "Iron Dragonslayer Leggings", DS3LocationCategory.ARMOR, miniboss = True), + "Iron Dragonslayer Leggings", miniboss = True), DS3LocationData("RC: Church Guardian Shiv (swamp far left, in building)", - "Church Guardian Shiv", DS3LocationCategory.MISC), + "Church Guardian Shiv"), DS3LocationData("RC: Spears of the Church (hidden boss drop)", "Spears of the Church", - DS3LocationCategory.UNIQUE, boss = True), # Midir drop - DS3LocationData("RC: Ritual Spear Fragment (church path)", "Ritual Spear Fragment", - DS3LocationCategory.UNIQUE), + boss = True), # Midir drop + DS3LocationData("RC: Ritual Spear Fragment (church path)", "Ritual Spear Fragment"), DS3LocationData("RC: Titanite Scale (grave, lizard after first drop)", "Titanite Scale", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), DS3LocationData("RC: Twinkling Titanite (grave, lizard after first drop)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + "Twinkling Titanite", lizard = True), DS3LocationData("RC: Titanite Scale (wall lower, lizard)", "Titanite Scale x2", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), DS3LocationData("RC: Twinkling Titanite (streets high, lizard)", "Twinkling Titanite x2", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), DS3LocationData("RC: Titanite Scale (wall top, lizard on side path)", "Titanite Scale", - DS3LocationCategory.UPGRADE, lizard = True), + lizard = True), DS3LocationData("RC: Twinkling Titanite (wall top, lizard on side path)", - "Twinkling Titanite", DS3LocationCategory.UPGRADE, lizard = True), + "Twinkling Titanite", lizard = True), DS3LocationData("RC: Soul of Slave Knight Gael", "Soul of Slave Knight Gael", - DS3LocationCategory.SOUL, prominent = True, boss = True), - DS3LocationData("RC: Blood of the Dark Soul (end boss drop)", "Blood of the Dark Soul", - DS3LocationCategory.KEY), + prominent = True, boss = True), + DS3LocationData("RC: Blood of the Dark Soul (end boss drop)", "Blood of the Dark Soul"), DS3LocationData("RC: Titanite Slab (ashes, mob drop)", "Titanite Slab", - DS3LocationCategory.UPGRADE, drop = True, + drop = True, hidden = True), # Guaranteed drop from normal-looking Ringed Knight - # Lapp - DS3LocationData("RC: Siegbräu (Lapp)", "Siegbräu", DS3LocationCategory.MISC, - missable = True, npc = True), # Lapp (quest) + # Lapp + DS3LocationData("RC: Siegbräu (Lapp)", "Siegbräu", missable = True, + npc = True), # Lapp (quest) # Quest or Shrine Handmaiden after death - DS3LocationData("RC: Lapp's Helm (Lapp)", "Lapp's Helm", DS3LocationCategory.ARMOR, - npc = True, shop = True), - DS3LocationData("RC: Lapp's Armor (Lapp)", "Lapp's Armor", DS3LocationCategory.ARMOR, - npc = True, shop = True), - DS3LocationData("RC: Lapp's Gauntlets (Lapp)", "Lapp's Gauntlets", - DS3LocationCategory.ARMOR, npc = True, shop = True), - DS3LocationData("RC: Lapp's Leggings (Lapp)", "Lapp's Leggings", DS3LocationCategory.ARMOR, - npc = True, shop = True), + DS3LocationData("RC: Lapp's Helm (Lapp)", "Lapp's Helm", npc = True, shop = True), + DS3LocationData("RC: Lapp's Armor (Lapp)", "Lapp's Armor", npc = True, shop = True), + DS3LocationData("RC: Lapp's Gauntlets (Lapp)", "Lapp's Gauntlets", npc = True, shop = True), + DS3LocationData("RC: Lapp's Leggings (Lapp)", "Lapp's Leggings", npc = True, shop = True), ], # Unlockable shops. We only bother creating a "region" for these for shops that are locked @@ -3614,90 +2951,79 @@ def __init__( # ashes. "Greirat's Shop": [ DS3LocationData("FS: Blue Tearstone Ring (Greirat)", "Blue Tearstone Ring", - DS3LocationCategory.RING, offline = '01,0:50006120::', npc = True), - DS3LocationData("FS: Ember (Greirat)", "Ember", DS3LocationCategory.MISC, - offline = "99,0:-1:110000,120000,70000110:", shop = True, npc = True), + offline = '01,0:50006120::', npc = True), + DS3LocationData("FS: Ember (Greirat)", "Ember", offline = "99,0:-1:110000,120000,70000110:", + shop = True, npc = True), # Undead Settlement rewards DS3LocationData("FS: Divine Blessing (Greirat from US)", "Divine Blessing", - DS3LocationCategory.MISC, offline = '99,0:-1:110000,120000,70000150,70000175:', missable = True, shop = True, npc = True), - DS3LocationData("FS: Ember (Greirat from US)", "Ember", DS3LocationCategory.MISC, + DS3LocationData("FS: Ember (Greirat from US)", "Ember", offline = '99,0:-1:110000,120000,70000150,70000175:', missable = True, shop = True, npc = True), # Irityhll rewards DS3LocationData("FS: Divine Blessing (Greirat from IBV)", "Divine Blessing", - DS3LocationCategory.MISC, offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), DS3LocationData("FS: Hidden Blessing (Greirat from IBV)", "Hidden Blessing", - DS3LocationCategory.MISC, offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), DS3LocationData("FS: Titanite Scale (Greirat from IBV)", "Titanite Scale", - DS3LocationCategory.UPGRADE, offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), DS3LocationData("FS: Twinkling Titanite (Greirat from IBV)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE, offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), # Lothric rewards (from Shrine Handmaid) DS3LocationData("FS: Ember (shop for Greirat's Ashes)", "Twinkling Titanite", - DS3LocationCategory.UPGRADE, offline = '99,0:-1:110000,120000,70000152,70000177:', missable = True, shop = True, npc = True), ], "Karla's Shop": [ - DS3LocationData("FS: Affinity (Karla)", "Affinity", DS3LocationCategory.SPELL, - shop = True, npc = True), - DS3LocationData("FS: Dark Edge (Karla)", "Dark Edge", DS3LocationCategory.SPELL, - shop = True, npc = True), + DS3LocationData("FS: Affinity (Karla)", "Affinity", shop = True, npc = True), + DS3LocationData("FS: Dark Edge (Karla)", "Dark Edge", shop = True, npc = True), # Quelana Pyromancy Tome - DS3LocationData("FS: Firestorm (Karla for Quelana Tome)", "Firestorm", - DS3LocationCategory.SPELL, missable = True, shop = True, npc = True), - DS3LocationData("FS: Rapport (Karla for Quelana Tome)", "Rapport", - DS3LocationCategory.SPELL, missable = True, shop = True, npc = True), - DS3LocationData("FS: Fire Whip (Karla for Quelana Tome)", "Fire Whip", - DS3LocationCategory.SPELL, missable = True, shop = True, npc = True), + DS3LocationData("FS: Firestorm (Karla for Quelana Tome)", "Firestorm", missable = True, + shop = True, npc = True), + DS3LocationData("FS: Rapport (Karla for Quelana Tome)", "Rapport", missable = True, + shop = True, npc = True), + DS3LocationData("FS: Fire Whip (Karla for Quelana Tome)", "Fire Whip", missable = True, + shop = True, npc = True), # Grave Warden Pyromancy Tome DS3LocationData("FS: Black Flame (Karla for Grave Warden Tome)", "Black Flame", - DS3LocationCategory.SPELL, missable = True, shop = True, npc = True), + missable = True, shop = True, npc = True), DS3LocationData("FS: Black Fire Orb (Karla for Grave Warden Tome)", "Black Fire Orb", - DS3LocationCategory.SPELL, missable = True, shop = True, npc = True), + missable = True, shop = True, npc = True), # Deep Braille Divine Tome. This can also be given to Irina but it'll fail her quest - DS3LocationData("FS: Gnaw (Karla for Deep Braille Tome)", "Gnaw", DS3LocationCategory.SPELL, - missable = True, npc = True, shop = True), + DS3LocationData("FS: Gnaw (Karla for Deep Braille Tome)", "Gnaw", missable = True, + npc = True, shop = True), DS3LocationData("FS: Deep Protection (Karla for Deep Braille Tome)", "Deep Protection", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), + missable = True, npc = True, shop = True), # Londor Braille Divine Tome. This can also be given to Irina but it'll fail her quest DS3LocationData("FS: Vow of Silence (Karla for Londor Tome)", "Vow of Silence", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), - DS3LocationData("FS: Dark Blade (Karla for Londor Tome)", "Dark Blade", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), - DS3LocationData("FS: Dead Again (Karla for Londor Tome)", "Dead Again", - DS3LocationCategory.SPELL, missable = True, npc = True, shop = True), - + missable = True, npc = True, shop = True), + DS3LocationData("FS: Dark Blade (Karla for Londor Tome)", "Dark Blade", missable = True, + npc = True, shop = True), + DS3LocationData("FS: Dead Again (Karla for Londor Tome)", "Dead Again", missable = True, + npc = True, shop = True), + # Drops on death. Missable because the player would have to decide between killing her or # seeing everything she sells. DS3LocationData("FS: Karla's Pointed Hat (kill Karla)", "Karla's Pointed Hat", - DS3LocationCategory.ARMOR, offline = '07,0:50006150::', missable = True, - drop = True, npc = True), - DS3LocationData("FS: Karla's Coat (kill Karla)", "Karla's Coat", DS3LocationCategory.ARMOR, + offline = '07,0:50006150::', missable = True, drop = True, npc = True), + DS3LocationData("FS: Karla's Coat (kill Karla)", "Karla's Coat", offline = '07,0:50006150::', missable = True, drop = True, npc = True), DS3LocationData("FS: Karla's Gloves (kill Karla)", "Karla's Gloves", - DS3LocationCategory.ARMOR, offline = '07,0:50006150::', missable = True, - drop = True, npc = True), + offline = '07,0:50006150::', missable = True, drop = True, npc = True), DS3LocationData("FS: Karla's Trousers (kill Karla)", "Karla's Trousers", - DS3LocationCategory.ARMOR, offline = '07,0:50006150::', missable = True, - drop = True, npc = True), + offline = '07,0:50006150::', missable = True, drop = True, npc = True), ], } @@ -3731,12 +3057,52 @@ def __init__( "Miniboss Rewards": set(), "Mimic Rewards": set(), "Hostile NPC Rewards": set(), + "Friendly NPC Rewards": set(), "Small Crystal Lizards": set(), - "Keys": set(), "Upgrade": set(), "Small Souls": set(), + "Boss Souls": set(), + "Unique": set(), + "Healing": set(), "Miscellaneous": set(), - "Hidden": set() + "Hidden": set(), + "Weapons": set(), + "Shields": set(), + "Armor": set(), + "Rings": set(), + "Spells": set(), +} + + +location_descriptions = { + "Prominent": "A small number of locations that are in very obvious locations. Mostly boss " + \ + "drops. Ideal for setting as priority locations.", + "Progression": "Locations that contain items in vanilla which unlock other locations.", + "Boss Rewards": "Boss drops. Does not include soul transfusions or shop items.", + "Miniboss Rewards": "Miniboss drops. Only includes enemies considered minibosses by the " + \ + "enemy randomizer.", + "Mimic Rewards": "Drops from enemies that are mimics in vanilla.", + "Hostile NPC Rewards": "Drops from NPCs that are hostile to you. This includes scripted " + \ + "invaders and initially-friendly NPCs that must be fought as part of their quest.", + "Friendly NPC Rewards": "Items given by friendly NPCs as part of their quests or from " + \ + "non-violent interaction.", + "Upgrade": "Locations that contain upgrade items in vanilla, including titanite, gems, and " + \ + "Shriving Stones.", + "Small Souls": "Locations that contain soul items in vanilla, not including boss souls.", + "Boss Souls": "Locations that contain boss souls in vanilla, as well as Soul of Rosaria.", + "Unique": "Locations that contain items in vanilla that are unique per NG cycle, such as " + \ + "scrolls, keys, ashes, and so on. Doesn't cover equipment, spells, or souls.", + "Healing": "Locations that contain Undead Bone Shards and Estus Shards in vanilla.", + "Miscellaneous": "Locations that contain generic stackable items in vanilla, such as arrows, " + + "firebombs, buffs, and so on.", + "Hidden": "Locations that are particularly difficult to find, such as behind illusory " + \ + "walls, down hidden drops, and so on. Does not include large locations like Untended " + \ + "Graves or Archdragon Peak.", + "Weapons": "Locations that contain weapons in vanilla.", + "Shields": "Locations that contain shields in vanilla.", + "Armor": "Locations that contain armor in vanilla.", + "Rings": "Locations that contain rings in vanilla.", + "Spells": "Locations that contain spells in vanilla.", } @@ -3745,7 +3111,7 @@ def __init__( location_dictionary.update({location_data.name: location_data for location_data in location_table}) for location_data in location_table: - if location_data.category != DS3LocationCategory.EVENT: + if not location_data.is_event: for group_name in location_data.location_groups(): location_name_groups[group_name].add(location_data.name) @@ -3753,7 +3119,7 @@ def __init__( if not location_name.endswith(" Shop"): location_name_groups[location_name] = frozenset([ location_data.name for location_data in location_table - if location_data.category != DS3LocationCategory.EVENT + if not location_data.is_event ]) location_name_groups["Painted World of Ariandel"] = ( diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 0fffdee66fc5..4d767c843e92 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -6,121 +6,165 @@ from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, ItemDict, Option, PerGameCommonOptions, Range, Toggle, VerifyKeys +class ExcludedLocationsOption(Choice): + """Which items can be placed in excluded locations in DS3. + + * Unnecessary: Excluded locations can't have progression items, but they can + have useful items. + * Unimportant: Neither progression items nor useful items can be placed in + excluded locations. + * Unrandomized: 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. + """ + option_unnecessary = 1 + option_unimportant = 2 + option_unrandomized = 3 + default = 2 + + class RandomizeWeaponLocations(DefaultOnToggle): - """Randomizes weapons (+101 checks)""" + + """DEPRECATED (use "Excluded Locations" options instead) + + Setting this to false is now equivalent to adding "Weapons" to the "Exclude + Locations" option. It does _not_ cause the locations not be randomized + unless "Excluded Locations" is also set to "Original Items". + """ display_name = "Randomize Weapon Locations" class RandomizeShieldLocations(DefaultOnToggle): - """Randomizes shields (+32 checks)""" + """DEPRECATED (use "Excluded Locations" options instead) + + Setting this to false is now equivalent to adding "Shields" to the "Exclude + Locations" option. It does _not_ cause the locations not be randomized + unless "Excluded Locations" is also set to "Original Items". + """ display_name = "Randomize Shield Locations" class RandomizeArmorLocations(DefaultOnToggle): - """Randomizes armor pieces (+216 checks)""" + """DEPRECATED (use "Excluded Locations" options instead) + + Setting this to false is now equivalent to adding "Armor" to the "Exclude + Locations" option. It does _not_ cause the locations not be randomized + unless "Excluded Locations" is also set to "Original Items". + """ display_name = "Randomize Armor Locations" class RandomizeRingLocations(DefaultOnToggle): - """Randomizes rings (+64 checks, +101 with NG+ locations)""" + """DEPRECATED (use "Excluded Locations" options instead) + + Setting this to false is now equivalent to adding "Rings" to the "Exclude + Locations" option. It does _not_ cause the locations not be randomized + unless "Excluded Locations" is also set to "Original Items". + """ display_name = "Randomize Ring Locations" class RandomizeSpellLocations(DefaultOnToggle): - """Randomizes spells (+35 checks)""" + """DEPRECATED (use "Excluded Locations" options instead) + + Setting this to false is now equivalent to adding "Spells" to the "Exclude + Locations" option. It does _not_ cause the locations not be randomized + unless "Excluded Locations" is also set to "Original Items". + """ display_name = "Randomize Spell Locations" class RandomizeKeyLocations(DefaultOnToggle): - """Randomizes items which unlock doors or bypass barriers. + """DEPRECATED (use "Excluded Locations" options instead) - If these aren't randomized, the route through the game will remain unchanged. + Setting this to false is now equivalent to adding "Progression" to the + "Exclude Locations" option. It does _not_ cause the locations not be + randomized unless "Excluded Locations" is also set to "Original Items". """ display_name = "Randomize Key Locations" -class RandomizeNPCLocations(DefaultOnToggle): - """Randomizes friendly NPC drops and rewards (+34 checks) - - Although all NPC drops will be randomized, progression items will only - appear in drops that aren't possible to lock yourself out of. Progression - items may be available by killing NPCs, but you can always do their quest - instead if you want. +class RandomizeBossSoulLocations(DefaultOnToggle): + """DEPRECATED (use "Excluded Locations" options instead) + Setting this to false is now equivalent to adding "Boss Souls" to the + "Exclude Locations" option. It does _not_ cause the locations not be + randomized unless "Excluded Locations" is also set to "Original Items". """ - display_name = "Randomize NPC Locations" + display_name = "Randomize Key Locations" -class RandomizeUniqueLocations(DefaultOnToggle): - """Randomizes unique items (ashes, tomes, scrolls, etc.) (+36 checks)""" - display_name = "Randomize Unique Locations" +class RandomizeNPCLocations(DefaultOnToggle): + """DEPRECATED (use "Excluded Locations" options instead) + + Setting this to false is now equivalent to adding "Friendly NPC Rewards" to + the "Exclude Locations" option. It does _not_ cause the locations not be + randomized unless "Excluded Locations" is also set to "Original Items". + """ + display_name = "Randomize NPC Locations" class RandomizeMiscLocations(DefaultOnToggle): - """Randomizes miscellaneous items (arrows, firebombs, etc.) (222 checks, 288 with NG+) + """DEPRECATED (use "Excluded Locations" options instead) - By default, these locations will never include progression items, so they - aren't mandatory checks. You can override this by customizing the - "exclude_locations" field in your YAML config. (For example, - "exclude_locations: []" will allow progression items in every unmissable - location.) + Setting this to false is now equivalent to adding "Unique" to the "Exclude + Locations" option. It does _not_ cause the locations not be randomized + unless "Excluded Locations" is also set to "Original Items". """ display_name = "Randomize Miscellaneous Locations" class RandomizeHealthLocations(DefaultOnToggle): - """Whether to andomize health upgrade items (+21 checks)""" - display_name = "Randomize Health Locations" + """DEPRECATED (use "Excluded Locations" options instead) + Setting this to false is now equivalent to adding "Healing" to the "Exclude + Locations" option. It does _not_ cause the locations not be randomized + unless "Excluded Locations" is also set to "Original Items". + """ + display_name = "Randomize Health Locations" -class SoulLocationsOption(Choice): - """Where to randomize soul items (140 checks, 103 with NG+) - * Not Randomized: All soul item locations contain the same items as in the base game. - * Anywhere: Soul items are distributed totally randomly throughout the multiworld. - * Smooth: Soul items appear in a similar order as in the base game. +class RandomizeProgressiveLocationsOption(DefaultOnToggle): + """DEPRECATED (use "Excluded Locations" options instead) - By default, soul item locations will never include progression items, so they aren't mandatory - checks. You can override this by customizing the "exclude_locations" field in your YAML config. - (For example, "exclude_locations: []" will allow progression items in every unmissable - location.) + Setting this to false is now equivalent to adding "Miscellaneous" to the + "Exclude Locations" option. It does _not_ cause the locations not be + randomized unless "Excluded Locations" is also set to "Original Items". """ - display_name = "Soul Locations" - option_not_randomized = 1 - option_anywhere = 2 - option_smooth = 3 - default = 3 + display_name = "Randomize Progressive Locations" -class UpgradeLocationsOption(Choice): - """Where to randomize titanite and gems (220 checks) +class SmoothSoulItemsOption(DefaultOnToggle): + """Whether to 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" + - * Not Randomized: All upgrade item locations contain the same items as in the base game. - * Anywhere: Upgrade items are distributed totally randomly throughout the multiworld. - * Smooth: Upgrade items appear in a similar order as in the base game. +class SmoothUpgradeItemsOption(DefaultOnToggle): + """Whether to distribute upgrade items in a similar order as the base game. - By default, upgrade item locations will never include progression items, so they aren't - mandatory checks. You can override this by customizing the "exclude_locations" field in your - YAML config. (For example, "exclude_locations: []" will allow progression items in every - unmissable location.) + 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 = "Upgrade Locations" - option_not_randomized = 1 - option_anywhere = 2 - option_smooth = 3 - default = 3 + display_name = "Smooth Upgrade Items" -class UpgradedWeaponLocationsOption(Choice): - """Where to randomize upgraded weapons (if they're enabled) +class SmoothUpgradedWeaponsOption(DefaultOnToggle): + """Whether to distribute upgraded weapons in a similar order as the base game. - * Anywhere: Upgraded weapons are distributed totally randomly throughout the multiworld. - * Smooth: More upgraded weapons appear deeper in the 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 = "Upgraded Weapon Locations" - option_anywhere = 2 - option_smooth = 3 - default = 3 + display_name = "Smooth Upgraded Weapons" class RandomizeStartingLoadout(DefaultOnToggle): @@ -383,19 +427,21 @@ class DS3ExcludeLocations(ExcludeLocations): @dataclass class DarkSouls3Options(PerGameCommonOptions): + excluded_locations: ExcludedLocationsOption enable_weapon_locations: RandomizeWeaponLocations enable_shield_locations: RandomizeShieldLocations enable_armor_locations: RandomizeArmorLocations enable_ring_locations: RandomizeRingLocations enable_spell_locations: RandomizeSpellLocations enable_key_locations: RandomizeKeyLocations + enable_boss_locations: RandomizeBossSoulLocations enable_npc_locations: RandomizeNPCLocations - enable_unique_locations: RandomizeUniqueLocations enable_misc_locations: RandomizeMiscLocations - enable_health_locations: RandomizeHealthLocations - soul_locations: SoulLocationsOption - upgrade_locations: UpgradeLocationsOption - upgraded_weapon_locations: UpgradedWeaponLocationsOption + enable_health_upgrade_locations: RandomizeHealthLocations + enable_progressive_locations: RandomizeProgressiveLocationsOption + smooth_soul_items: SmoothSoulItemsOption + smooth_upgrade_items: SmoothUpgradeItemsOption + smooth_upgraded_weapons: SmoothUpgradedWeaponsOption random_starting_loadout: RandomizeStartingLoadout require_one_handed_starting_weapons: RequireOneHandedStartingWeapons guaranteed_items: GuaranteedItemsOption diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 71e77e002313..787e2251b1cf 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -12,8 +12,8 @@ from .Bosses import DS3BossInfo, all_bosses, default_yhorm_location from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, Infusion, UsefulIf, filler_item_names, item_dictionary -from .Locations import DarkSouls3Location, DS3LocationCategory, DS3LocationData, location_tables, location_dictionary, location_name_groups, region_order -from .Options import DarkSouls3Options, EarlySmallLothricBanner, RandomizeWeaponLevelOption, SoulLocationsOption, UpgradeLocationsOption, UpgradedWeaponLocationsOption +from .Locations import DarkSouls3Location, DS3LocationData, location_tables, location_descriptions, location_dictionary, location_name_groups, region_order +from .Options import DarkSouls3Options, EarlySmallLothricBanner class DarkSouls3Web(WebWorld): @@ -53,7 +53,6 @@ class DarkSouls3World(World): web = DarkSouls3Web() data_version = 9 base_id = 100000 - enabled_location_categories: Set[DS3LocationCategory] required_client_version = (0, 4, 2) item_name_to_id = {data.name: data.ap_code for data in item_dictionary.values()} location_name_to_id = { @@ -70,6 +69,7 @@ class DarkSouls3World(World): "Cinders of a Lord - Lothric Prince" } } + location_descriptions = location_descriptions yhorm_location: Optional[DS3BossInfo] """If enemy randomization is enabled, this is the boss who Yhorm the Giant should replace. @@ -87,34 +87,22 @@ def __init__(self, multiworld: MultiWorld, player: int): def generate_early(self): - if self.options.enable_weapon_locations: - self.enabled_location_categories.add(DS3LocationCategory.WEAPON) - # Always make this available early because so many items are useless without it. - self.multiworld.early_items[self.player]['Pyromancy Flame'] = 1 - if self.options.enable_shield_locations: - self.enabled_location_categories.add(DS3LocationCategory.SHIELD) - if self.options.enable_armor_locations: - self.enabled_location_categories.add(DS3LocationCategory.ARMOR) - if self.options.enable_ring_locations: - self.enabled_location_categories.add(DS3LocationCategory.RING) - if self.options.enable_spell_locations: - self.enabled_location_categories.add(DS3LocationCategory.SPELL) - if self.options.enable_unique_locations: - self.enabled_location_categories.add(DS3LocationCategory.UNIQUE) - if self.options.enable_key_locations: - self.enabled_location_categories.add(DS3LocationCategory.KEY) - if self.options.early_banner == "early_global": - self.multiworld.early_items[self.player]['Small Lothric Banner'] = 1 - elif self.options.early_banner == "early_local": - self.multiworld.local_early_items[self.player]['Small Lothric Banner'] = 1 - if self.options.enable_misc_locations: - self.enabled_location_categories.add(DS3LocationCategory.MISC) - if self.options.enable_health_locations: - self.enabled_location_categories.add(DS3LocationCategory.HEALTH) - if self.options.upgrade_locations != "not_randomized": - self.enabled_location_categories.add(DS3LocationCategory.UPGRADE) - if self.options.soul_locations != "not_randomized": - self.enabled_location_categories.add(DS3LocationCategory.SOUL) + if not self.options.enable_weapon_locations: + self._exclude_location_group("Weapons") + if not self.options.enable_shield_locations: + self._exclude_location_group("Shields") + if not self.options.enable_armor_locations: + self._exclude_location_group("Armor") + if not self.options.enable_ring_locations: + self._exclude_location_group("Rings") + if not self.options.enable_spell_locations: + self._exclude_location_group("Spells") + if not self.options.enable_key_locations: + self._exclude_location_group("Progression") + if not self.options.enable_misc_locations: + self._exclude_location_group("Unique") + if not self.options.enable_health_upgrade_locations: + self._exclude_location_group("Healing") # Randomize Yhorm manually so that we know where to place the Storm Ruler. if self.options.randomize_enemies: @@ -135,20 +123,25 @@ def generate_early(self): self.yhorm_location = default_yhorm_location + def _exclude_location_group(self, name: str): + """Adds all the locations in the given location group to the set of excluded locations.""" + self.options.exclude_locations.value.update(location_name_groups[name]) + + def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: """Returns whether boss is a valid location for Yhorm in this seed.""" if not self.options.enable_dlc and boss.dlc: return False - if not self.options.enable_weapon_locations: - # If weapons aren't randomized, make sure the player can get to the normal Storm Ruler - # location before they need to get through Yhorm. + if not self.is_location_available("PC: Storm Ruler (boss room)"): + # If the Storm Ruler isn't randomized, make sure the player can get to the normal Storm + # Ruler location before they need to get through Yhorm. if boss.before_storm_ruler: return False - # If keys also aren't randomized, make sure Yhorm isn't blocking access to the Small - # Doll or it won't be possible to get into Profaned Capital before beating him. + # If the Small Doll also wasn't randomized, make sure Yhorm isn't blocking access to it + # or it won't be possible to get into Profaned Capital before beating him. if ( - not self.options.enable_key_locations + not self.is_location_available("CD: Small Doll (boss drop)") and boss.name in {"Crystal Sage", "Deacons of the Deep"} ): return False @@ -157,7 +150,7 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: # Cemetery of Ash has very few locations and all of them are excluded by default, so only # allow Yhorm as Iudex Gundyr if there's at least one available location. - excluded = self.multiworld.exclude_locations[self.player].value + excluded = self.options.exclude_locations.value return any( self.is_location_available(location) and location.name not in excluded @@ -260,7 +253,7 @@ def create_region(self, region_name, location_table) -> Region: # Use this to un-exclude event locations so the fill doesn't complain about items behind # them being unreachable. - excluded = self.multiworld.exclude_locations[self.player].value + excluded = self.options.exclude_locations.value for location in location_table: if self.is_location_available(location): @@ -273,7 +266,7 @@ def create_region(self, region_name, location_table) -> Region: # Mark Red Eye Orb as missable if key locations aren't being randomized, because the # Lift Chamber Key is missable by default. if ( - not self.options.enable_key_locations + not self.is_location_available("FS: Lift Chamber Key (Leonhard)") and location.name == "HWL: Red Eye Orb (wall tower, miniboss)" ): new_location.progress_type = LocationProgressType.EXCLUDED @@ -319,7 +312,7 @@ def create_items(self): raise Exception("DS3 generation bug: Added an unavailable location.") item = item_dictionary[location.data.default_item_name] - if item.category == DS3ItemCategory.SKIP: + if item.skip: num_required_extra_items += 1 elif not item.unique: itempool.append(self.create_item(location.data.default_item_name)) @@ -336,7 +329,7 @@ def create_items(self): removable_items = [item for item in itempool if item.classification == ItemClassification.filler] guaranteed_items = {"Path of the Dragon": 1} - guaranteed_items.update(self.multiworld.guaranteed_items[self.player].value) + guaranteed_items.update(self.options.guaranteed_items) if len(removable_items) == 0 and num_required_extra_items == 0: raise Exception("Can't add Path of the Dragon to the item pool") @@ -385,13 +378,14 @@ def create_items(self): num_required_extra_items -= 1 itempool.append(self.create_item(item.name)) - # Extra filler items for locations containing SKIP items + # Extra filler items for locations containing skip items itempool.extend(self.create_filler() for _ in range(num_required_extra_items)) # Add items to itempool self.multiworld.itempool += itempool + def create_item(self, item: Union[str, DS3ItemData]) -> Item: data = item if isinstance(item, DS3ItemData) else item_dictionary[item] classification = None @@ -414,10 +408,10 @@ def create_item(self, item: Union[str, DS3ItemData]) -> Item: and not data.name == "Pyromancy FLame" ): # if the user made an error and set a min higher than the max we default to the max - max_5 = self.multiworld.max_levels_in_5[self.player] - min_5 = min(self.multiworld.min_levels_in_5[self.player], max_5) - max_10 = self.multiworld.max_levels_in_10[self.player] - min_10 = min(self.multiworld.min_levels_in_10[self.player], max_10) + max_5 = self.options.max_levels_in_5 + min_5 = min(self.options.min_levels_in_5, max_5) + max_10 = self.options.max_levels_in_10 + min_10 = min(self.options.min_levels_in_10, max_10) weapon_level_percentage = self.options.randomize_weapon_level_percentage if self.multiworld.random.randint(0, 99) < weapon_level_percentage: @@ -474,14 +468,16 @@ def set_rules(self) -> None: self._add_entrance_rule("Painted World of Ariandel (After Contraption)", "Small Doll") # Define the access rules to some specific locations - if self.options.enable_key_locations: + if self.is_location_available("FS: Lift Chamber Key (Leonhard)"): self._add_location_rule("HWL: Red Eye Orb (wall tower, miniboss)", "Lift Chamber Key") self._add_location_rule("ID: Bellowing Dragoncrest Ring (drop from B1 towards pit)", "Jailbreaker's Key") self._add_location_rule("ID: Covetous Gold Serpent Ring (Siegward's cell)", "Old Cell Key") - self._add_location_rule("UG: Hornet Ring (environs, right of main path)", - "Small Lothric Banner") + self._add_location_rule( + "UG: Hornet Ring (environs, right of main path after killing FK boss)", + "Small Lothric Banner" + ) self._add_entrance_rule("Karla's Shop", "Jailer's Key Ring") # Ashes @@ -767,10 +763,10 @@ def has_any_scroll(state): if self.is_location_available(location): if location.shop: add_item_rule(self.multiworld.get_location(location.name, self.player), - lambda item: ( - item.player != self.player or - (item.data.count == 1 and not item.data.souls) - )) + lambda item: ( + item.player != self.player or + (item.data.count == 1 and not item.data.souls) + )) # This particular location is bugged, and will drop two copies of whatever item is placed # there. @@ -793,6 +789,26 @@ def has_any_scroll(state): state.has("Cinders of a Lord - Aldrich", self.player) and \ state.has("Cinders of a Lord - Lothric Prince", self.player) + if self.options.excluded_locations == "unnecessary": + for location in self.options.exclude_locations: + add_item_rule(self.multiworld.get_location(location, self.player), + lambda item: item.classification != ItemClassification.progression) + self.options.exclude_locations.value.clear() + + + randomized_items = { + item.name for item in self.multiworld.itempool + if item.player == self.player + } + # Always make this available early because so many items are useless without it. + if 'Pyromancy Flame' in randomized_items: + self.multiworld.early_items[self.player]['Pyromancy Flame'] = 1 + if 'Small Lothric Banner' in randomized_items: + if self.options.early_banner == "early_global": + self.multiworld.early_items[self.player]['Small Lothric Banner'] = 1 + elif self.options.early_banner == "early_local": + self.multiworld.local_early_items[self.player]['Small Lothric Banner'] = 1 + def _add_location_rule(self, location: Union[str, List[str]], rule: Union[CollectionRule, str]) -> None: """Sets a rule for the given location if it that location is randomized. @@ -827,10 +843,13 @@ def is_location_available(self, location: Union[str, DS3LocationData]) -> bool: data = location_dictionary[location] return ( - data.category in self.enabled_location_categories and - (not data.npc or self.options.enable_npc_locations) and - (not data.dlc or self.options.enable_dlc) and - (not data.ngp or self.options.enable_ngp) + not data.is_event + and (not data.dlc or self.options.enable_dlc) + and (not data.ngp or self.options.enable_ngp) + and not ( + self.options.excluded_locations == "unrandomized" + and data.name in self.options.exclude_locations + ) ) @@ -855,7 +874,7 @@ def pre_fill(self) -> None: self._fill_local_item("Coiled Sword", ["Cemetery of Ash", "Firelink Shrine"]) # If upgrade smoothing is enabled, make sure one raw gem is available early for SL1 players - if self.options.upgrade_locations == "smooth": + if self.options.smooth_upgrade_items: self._fill_local_item("Raw Gem", [ "Cemetery of Ash", "Firelink Shrine", @@ -990,7 +1009,7 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: location.item = new_item new_item.location = location - if self.options.upgrade_locations == "smooth": + if self.options.smooth_upgrade_items: base_names = { "Titanite Shard", "Large Titanite Shard", "Titanite Chunk", "Titanite Slab", "Titanite Scale", "Twinkling Titanite", "Farron Coal", "Sage's Coal", "Giant's Coal", @@ -998,7 +1017,9 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: } smooth_items([item for item in all_item_order if item.base_name in base_names]) - if self.options.soul_locations == "smooth": + if self.options.smooth_soul_items: + # TODO: don't smooth boss souls since they're now progression items :( + # Shuffle larger boss souls among themselves because they're all worth 10-20k souls in # no particular order and that's a lot more interesting than getting them in the same # order every single run. @@ -1016,7 +1037,7 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: item_order.append(item) smooth_items(item_order) - if self.options.upgraded_weapon_locations == "smooth": + if self.options.smooth_upgraded_weapons: upgraded_weapons = [ location.item for location in self.multiworld.get_filled_locations() @@ -1091,8 +1112,8 @@ def fill_slot_data(self) -> Dict[str, object]: "no_equip_load": self.options.no_equip_load.value, "enable_dlc": self.options.enable_dlc.value, "enable_ngp": self.options.enable_ngp.value, - "smooth_soul_locations": self.options.soul_locations == "smooth", - "smooth_upgrade_locations": self.options.upgrade_locations == "smooth", + "smooth_soul_locations": self.options.smooth_soul_items, + "smooth_upgrade_locations": self.options.smooth_upgrade_items, "randomize_enemies": self.options.randomize_enemies.value, "randomize_mimics_with_enemies": self.options.randomize_mimics_with_enemies.value, "randomize_small_crystal_lizards_with_enemies": self.options.randomize_small_crystal_lizards_with_enemies.value, From 8786768b2ab06fffb7a274e43e0fb674a875426a Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 30 Dec 2023 00:03:32 -0800 Subject: [PATCH 108/238] Properly name Coiled Sword location --- worlds/dark_souls_3/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 787e2251b1cf..4fc71375d8c3 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -154,7 +154,7 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: return any( self.is_location_available(location) and location.name not in excluded - and location.name != "CA: Coiled Sword" + and location.name != "CA: Coiled Sword (boss drop)" for location in location_tables["Cemetery of Ash"] ) From 3ec651a6317827ee5a9f2afdf860156ec56d4f00 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 30 Dec 2023 00:46:28 -0800 Subject: [PATCH 109/238] Add an option for configuring how missable items are handled --- worlds/dark_souls_3/Locations.py | 1 - worlds/dark_souls_3/Options.py | 21 +++++++++++++ worlds/dark_souls_3/__init__.py | 52 ++++++++++++++------------------ 3 files changed, 44 insertions(+), 30 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index e1ae61dd0226..8adccd074f74 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -238,7 +238,6 @@ def __init__( event: bool = False): super().__init__(player, data.name, None if event else data.ap_code, parent) self.data = data - if data.missable and not event: self.progress_type = LocationProgressType.EXCLUDED # Naming conventions: diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 4d767c843e92..c6d16587b104 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -24,6 +24,26 @@ class ExcludedLocationsOption(Choice): option_unimportant = 2 option_unrandomized = 3 default = 2 + + +class MissableLocationsOption(Choice): + """Which items can be placed in locations that can be permanently missed. + + * Unnecessary: Missable locations can't have progression items, but they can + have useful items. + * Unimportant: Neither progression items nor useful items can be placed in + missablek locations. + * Unrandomized: 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. + """ + option_unnecessary = 1 + option_unimportant = 2 + option_unrandomized = 3 + default = 2 class RandomizeWeaponLocations(DefaultOnToggle): @@ -428,6 +448,7 @@ class DS3ExcludeLocations(ExcludeLocations): @dataclass class DarkSouls3Options(PerGameCommonOptions): excluded_locations: ExcludedLocationsOption + missable_locations: MissableLocationsOption enable_weapon_locations: RandomizeWeaponLocations enable_shield_locations: RandomizeShieldLocations enable_armor_locations: RandomizeArmorLocations diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 4fc71375d8c3..da71f65688fa 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -257,15 +257,12 @@ def create_region(self, region_name, location_table) -> Region: for location in location_table: if self.is_location_available(location): - new_location = DarkSouls3Location( - self.player, - location, - new_region - ) - - # Mark Red Eye Orb as missable if key locations aren't being randomized, because the - # Lift Chamber Key is missable by default. + new_location = DarkSouls3Location(self.player, location, new_region) if ( + location.missable and self.options.missable_locations == "unimportant" + ) or ( + # Mark Red Eye Orb as missable if Lift Chamber Key isn't randomized, because + # the latter is missable by default. not self.is_location_available("FS: Lift Chamber Key (Leonhard)") and location.name == "HWL: Red Eye Orb (wall tower, miniboss)" ): @@ -789,12 +786,19 @@ def has_any_scroll(state): state.has("Cinders of a Lord - Aldrich", self.player) and \ state.has("Cinders of a Lord - Lothric Prince", self.player) - if self.options.excluded_locations == "unnecessary": - for location in self.options.exclude_locations: + unnecessary_locations = ( + self.options.exclude_locations.value + if self.options.excluded_locations == "unnecessary" + else set() + ).union( + {location for location in self.multiworld.get_locations() if location.missable} + if self.options.missable_locations == "unnecessary" + else set() + ) + for location in unnecessary_locations: + if self.is_location_available(location): add_item_rule(self.multiworld.get_location(location, self.player), lambda item: item.classification != ItemClassification.progression) - self.options.exclude_locations.value.clear() - randomized_items = { item.name for item in self.multiworld.itempool @@ -850,6 +854,10 @@ def is_location_available(self, location: Union[str, DS3LocationData]) -> bool: self.options.excluded_locations == "unrandomized" and data.name in self.options.exclude_locations ) + and not ( + self.options.missable_locations == "unrandomized" + and data.missable + ) ) @@ -1018,24 +1026,10 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: smooth_items([item for item in all_item_order if item.base_name in base_names]) if self.options.smooth_soul_items: - # TODO: don't smooth boss souls since they're now progression items :( - - # Shuffle larger boss souls among themselves because they're all worth 10-20k souls in - # no particular order and that's a lot more interesting than getting them in the same - # order every single run. - shuffled_order = self._shuffle([ - item.name for item in item_dictionary.values() - if item.category == DS3ItemCategory.BOSS and item.souls and item.souls >= 10000 + smooth_items([ + item for item in all_item_order + if item.souls and item.classification != ItemClassification.progression ]) - shuffled = set(shuffled_order) - item_order: List[DS3ItemData] = [] - for item in all_item_order: - if not item.souls: continue - if item.base_name in shuffled: - item_order.append(item_dictionary[shuffled_order.pop(0)]) - else: - item_order.append(item) - smooth_items(item_order) if self.options.smooth_upgraded_weapons: upgraded_weapons = [ From 362d95babddfecfd097f189aab78a5c0da063313 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 4 Jan 2024 01:05:31 -0800 Subject: [PATCH 110/238] Fix some bugs from location name updates --- worlds/dark_souls_3/Locations.py | 4 ++-- worlds/dark_souls_3/Options.py | 2 ++ worlds/dark_souls_3/__init__.py | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 8adccd074f74..dd1c48bc4aa3 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1084,7 +1084,7 @@ def __init__( "Large Soul of an Unknown Traveler"), DS3LocationData("CD: Large Soul of an Unknown Traveler (by white tree #2)", "Large Soul of an Unknown Traveler"), - DS3LocationData("CD: Undead Hunter Charm (lower roofs, up stairs between buttresses", + DS3LocationData("CD: Undead Hunter Charm (lower roofs, up stairs between buttresses)", "Undead Hunter Charm x3"), DS3LocationData("CD: Red Bug Pellet (lower roofs, up stairs between buttresses)", "Red Bug Pellet x3"), @@ -1729,7 +1729,7 @@ def __init__( DS3LocationData("ID: Titanite Scale (B2 far, lizard)", "Titanite Scale", lizard = True), DS3LocationData("ID: Dung Pie (pit, miniboss drop)", "Dung Pie x4", miniboss = True), # Giant slave drop - DS3LocationData("ID: Titanite Chunk (pit, miniboss drop", "Titanite Chunk", + DS3LocationData("ID: Titanite Chunk (pit, miniboss drop)", "Titanite Chunk", miniboss = True), # Giant Slave Drop # Alva (requires ember) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index c6d16587b104..4e1b6ac04b03 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -20,6 +20,7 @@ class ExcludedLocationsOption(Choice): 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" option_unnecessary = 1 option_unimportant = 2 option_unrandomized = 3 @@ -40,6 +41,7 @@ class MissableLocationsOption(Choice): 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" option_unnecessary = 1 option_unimportant = 2 option_unrandomized = 3 diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index d05f7cc45adc..fc2c2063718d 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -1106,8 +1106,8 @@ def fill_slot_data(self) -> Dict[str, object]: "no_equip_load": self.options.no_equip_load.value, "enable_dlc": self.options.enable_dlc.value, "enable_ngp": self.options.enable_ngp.value, - "smooth_soul_locations": self.options.smooth_soul_items, - "smooth_upgrade_locations": self.options.smooth_upgrade_items, + "smooth_soul_locations": self.options.smooth_soul_items.value, + "smooth_upgrade_locations": self.options.smooth_upgrade_items.value, "randomize_enemies": self.options.randomize_enemies.value, "randomize_mimics_with_enemies": self.options.randomize_mimics_with_enemies.value, "randomize_small_crystal_lizards_with_enemies": self.options.randomize_small_crystal_lizards_with_enemies.value, From 56833eda665a16741dcdd402c5610201b9e5faab Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 4 Jan 2024 01:37:16 -0800 Subject: [PATCH 111/238] Fix location guide link --- worlds/dark_souls_3/docs/en_Dark Souls III.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/docs/en_Dark Souls III.md b/worlds/dark_souls_3/docs/en_Dark Souls III.md index ecae2e52b3be..b74f3db5534d 100644 --- a/worlds/dark_souls_3/docs/en_Dark Souls III.md +++ b/worlds/dark_souls_3/docs/en_Dark Souls III.md @@ -29,4 +29,4 @@ Location names have to pack a lot of information into very little space. To bett check out the [location guide], which explains all the names used in locations and provides more detailed descriptions for each individual location. -[location guide]: /tutorial/Dark Souls III/locations/en +[location guide]: /tutorial/Dark%20Souls%20III/locations/en From 7a6639c71e9b17cc91e0497ee080a1f1d2670840 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 4 Jan 2024 01:43:31 -0800 Subject: [PATCH 112/238] Fix a couple locations that were busted offline --- worlds/dark_souls_3/Locations.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index dd1c48bc4aa3..4e8a2ec2ee38 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1833,12 +1833,14 @@ def __init__( DS3LocationData("AL: Ember (spiral staircase, bottom)", "Ember"), DS3LocationData("AL: Large Titanite Shard (bottom of the furthest buttress)", "Large Titanite Shard"), + DS3LocationData("AL: Large Titanite Shard (right after light cathedral)", + "Large Titanite Shard"), DS3LocationData("AL: Large Titanite Shard (walkway, side path by cathedral)", "Large Titanite Shard"), DS3LocationData("AL: Soul of a Weary Warrior (plaza, nearer)", "Soul of a Weary Warrior"), DS3LocationData("AL: Ember (plaza, right side)", "Ember"), DS3LocationData("AL: Ember (plaza, further)", "Ember"), - DS3LocationData("AL: Large Titanite Shard (right after light cathedral)", + DS3LocationData("AL: Large Titanite Shard (after light cathedral)", "Large Titanite Shard"), DS3LocationData("AL: Dark Stoneplate Ring (by dark stairs up from plaza)", "Dark Stoneplate Ring"), @@ -1896,11 +1898,6 @@ def __init__( miniboss = True), # Deep Accursed drop DS3LocationData("AL: Aldrich Faithful (water reserves, talk to McDonnel)", "Aldrich Faithful", hidden = True), # Behind illusory wall - DS3LocationData("AL: Large Titanite Shard ?? (right after light cathedral)", - "Large Titanite Shard", - # TODO: Mark this as Area: irithyll_anorlondo in the offline rando and order - # it properly - offline = '06,0:53700480::'), DS3LocationData("FS: Budding Green Blossom (shop after Sirris kills Aldrich)", "Budding Green Blossom", @@ -2633,6 +2630,7 @@ def __init__( DS3LocationData("PW2: Vilhelm's Armor (B2, along wall)", "Vilhelm's Armor"), DS3LocationData("PW2: Vilhelm's Gauntlets (B2, along wall)", "Vilhelm's Gauntlets"), DS3LocationData("PW2: Vilhelm's Leggings (B2, along wall)", "Vilhelm's Leggings"), + DS3LocationData("PW2: Blood Gem (B2, center)", "Blood Gem"), DS3LocationData("PW2: Pyromancer's Parting Flame (rotunda)", "Pyromancer's Parting Flame", hidden = True), # Behind illusory wall DS3LocationData("PW2: Homeward Bone (rotunda)", "Homeward Bone x2", @@ -2641,9 +2639,6 @@ def __init__( lizard = True), DS3LocationData("PW2: Twinkling Titanite (B3, lizard #2)", "Twinkling Titanite", lizard = True), - DS3LocationData("PW2: Blood Gem (B2, center)", "Blood Gem", - # TODO: Mark this as Area: ariandel_vilhelm in the offline rando and reorder - offline = '11,0:54500480::'), DS3LocationData("PW2 -> DH", None), # Corvian Settler after killing Friede From 3d3fcfae54f04e854c90859e329190e7b9ff55f9 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 4 Jan 2024 01:51:48 -0800 Subject: [PATCH 113/238] Update detailed location descriptions --- .../detailed_location_descriptions.py | 9 ++++--- worlds/dark_souls_3/docs/locations_en.md | 26 +++++++++---------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/worlds/dark_souls_3/detailed_location_descriptions.py b/worlds/dark_souls_3/detailed_location_descriptions.py index b1d4bfffbaaf..13879f742b0f 100644 --- a/worlds/dark_souls_3/detailed_location_descriptions.py +++ b/worlds/dark_souls_3/detailed_location_descriptions.py @@ -43,7 +43,9 @@ name = item.split(" - ")[0] descriptions_by_location[(region, name)].append(slot['Text']) descriptions_by_item[name].append(slot['Text']) - original_descriptions_by_location = dict(descriptions_by_location) + counts_by_location = { + location: len(descriptions) for (location, descriptions) in descriptions_by_location.items() + } location_names_to_descriptions = {} @@ -69,9 +71,8 @@ candidates = descriptions_by_location[key] if len(candidates) == 0: raise Exception( - f'There are only {len(original_descriptions_by_location[key])} locations in the ' + - f'offline randomizer matching "{match[1]}: {match[2]}", but there are more in ' + - 'Archipelago.' + f'There are only {counts_by_location[key]} locations in the offline randomizer ' + + f'matching "{match[1]}: {match[2]}", but there are more in Archipelago.' ) location_names_to_descriptions[location.name] = candidates.pop(0) diff --git a/worlds/dark_souls_3/docs/locations_en.md b/worlds/dark_souls_3/docs/locations_en.md index 10c3b78cd9fd..bf4f3865558d 100644 --- a/worlds/dark_souls_3/docs/locations_en.md +++ b/worlds/dark_souls_3/docs/locations_en.md @@ -689,11 +689,11 @@ offline _Dark Souls III_ randomizer]. AL: Havel's Ring+2 (prison tower, rafters)On the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka AL: Human Dregs (water reserves)In the open in the Water Reserves AL: Large Soul of a Weary Warrior (left of dark cathedral entrance)In front of the Anor Londo cathedral, slightly to the left +AL: Large Titanite Shard (after light cathedral)After the Pontiff fight, on the balcony to the right of the area with the Giant Slaves AL: Large Titanite Shard (bottom of the furthest buttress)At the base of the rightmost flying buttress leading up to Anor Londo AL: Large Titanite Shard (bottom of the nearest buttress)On the tower leading back from Anor Londo to the shortcut to Irithyll, down the flying buttress closest to the Darkmoon Tomb entrance. -AL: Large Titanite Shard (right after light cathedral)After the Pontiff fight, on the balcony to the right of the area with the Giant Slaves +AL: Large Titanite Shard (right after light cathedral)After Pontiff's cathedral, hugging the wall to the right AL: Large Titanite Shard (walkway, side path by cathedral)After the Pontiff fight, going back from the Deacons area to the original cathedral, before a dropdown -AL: Large Titanite Shard ?? (right after light cathedral)After Pontiff's cathedral, hugging the wall to the right AL: Moonlight Arrow (dark cathedral, up right stairs)In the Anor Londo cathedral, up the stairs on the right side AL: Painting Guardian Gloves (prison tower, rafters)On the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka AL: Painting Guardian Gown (prison tower, rafters)On the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka @@ -904,7 +904,7 @@ offline _Dark Souls III_ randomizer]. CD: Twinkling Titanite (path, lizard #1)Dropped by the first Crystal Lizard after the Crystal Sage fight CD: Twinkling Titanite (path, lizard #2)Dropped by the second Crystal Lizard after the Crystal Sage fight CD: Undead Bone Shard (gravestone by white tree)In the graveyard with the Infested Corpses, on a coffin partly hanging off of the ledge -CD: Undead Hunter Charm (lower roofs, up stairs between buttressesIn the area after the cathedral roof guarded by a Cathedral Evangelist. Can be jumped to from a flying buttress or by going around and back +CD: Undead Hunter Charm (lower roofs, up stairs between buttresses)In the area after the cathedral roof guarded by a Cathedral Evangelist. Can be jumped to from a flying buttress or by going around and back CD: Winged Spear (kill Patches)Dropped by Patches when killed in his own armor. CD: Xanthous Crown (Heysel Corpse-Grub in Rosaria's Bed Chamber)Dropped by the Heysel Corpse-grub in Rosaria's Bed Chamber CD: Young White Branch (by white tree #1)By the White Birch tree in the Infested Corpse graveyard @@ -974,7 +974,7 @@ offline _Dark Souls III_ randomizer]. DH: Ring of Steel Protection+3 (ledge before church)After the dropdown where an angel first targets you, on an exposed edge to the left. Difficult to get without killing the angel. DH: Rusted Coin (behind fountain after church)After exiting the building with the Lothric Knights where the front crumbles, behind the fountain on the right side. DH: Rusted Gold Coin (shop)Sold by Stone-humped Hag, or in her ashes -DH: Siegbräu (Lapp)Given by Lapp after collecting the Titanite Slab in Earthen Peak Ruins, or left after Demon Princes fight, or dropped upon death if not given. +DH: Siegbräu (Lapp)Given by Lapp after collecting the Titanite Slab in Earthen Peak Ruins, or left after Demon Princes fight, or dropped upon death if not given. DH: Small Envoy Banner (boss drop)Found in the small room after beating Demon Prince. DH: Soul of a Crestfallen Knight (church, altar)In the building where the front crumbles, guarded by the two Lothric Knights at the front of the chapel. DH: Soul of a Weary Warrior (castle overhang)The bait item at the start of the area which falls down with you into the ruined building below. @@ -1067,7 +1067,7 @@ offline _Dark Souls III_ randomizer]. FK: Titanite Shard (keep ruins bonfire island, under ramp)Under the ramp leading down from the Keep Ruins bonfire FK: Titanite Shard (swamp by right island)Behind a tree patrolled by an Elder Ghru close to the ritual fire stairs FK: Twinkling Dragon Head Stone (Hawkwood drop)Dropped by Hawkwood after killing him in the Abyss Watchers arena, after running up to the altar in Archdragon Peak. Twinkling Dragon Torso Stone needs to be acquired first. -FK: Twinkling Titanite (keep proper, lizardl)Dropped by the Crystal Lizard on the balcony behind the Old Wolf of Farron bonfire +FK: Twinkling Titanite (keep proper, lizard)Dropped by the Crystal Lizard on the balcony behind the Old Wolf of Farron bonfire FK: Undead Bone Shard (pavilion by keep ruins bonfire island)In a standalone pavillion down the ramp from Keep Ruins bonfire and to the right FK: Watchdogs of Farron (Old Wolf)Given by Old Wolf of Farron. FK: Wolf Ring+1 (keep ruins bonfire island, outside building)To the right of the building with the Keep Ruins bonfire, when approached from the ritual fire @@ -1342,7 +1342,7 @@ offline _Dark Souls III_ randomizer]. FS: Yhorm's Great Machete (Ludleth for Yhorm)Boss weapon for Yhorm the Giant FS: Yhorm's Greatshield (Ludleth for Yhorm)Boss weapon for Yhorm the Giant FS: Young Dragon Ring (Orbeck for one scroll and buying three spells)Given by Orbeck after purchasing four sorceries from him, and giving him one scroll, as a non-sorcerer. -FSBT: Armor of the Sun (crow for Siegbräu)Trade Siegbrau with crow +FSBT: Armor of the Sun (crow for Siegbräu)Trade Siegbrau with crow FSBT: Blessed Gem (crow for Moaning Shield)Trade Moaning Shield with crow FSBT: Covetous Silver Serpent Ring (illusory wall past rafters)From the Firelink Shrine roof, past the rafters and an illusory wall FSBT: Estus Ring (rafters)Dropping down from the Bell Tower to where Irina eventually resides @@ -1535,7 +1535,7 @@ offline _Dark Souls III_ randomizer]. IBV: Large Titanite Shard (ascent, down ladder in last building)Outside the final building before Pontiff's cathedral, coming from the sewer, dropping down to the left before the entrance IBV: Large Titanite Shard (central, balcony just before plaza)From the Central Irithyll bonfire, on the balcony with the second Fire Witch. IBV: Large Titanite Shard (central, side path after first fountain)Up the stairs from the Central Irithyll bonfire, on a railing to the right -IBV: Large Titanite Shard (great hall, mob)After Pontiff's cathedral, hugging the wall to the right +IBV: Large Titanite Shard (great hall, mob)One-time drop from the Silver Knight staring at the painting in Irithyll IBV: Large Titanite Shard (path to Dorhys)Before the area with Cathedral Evangelist Dorhys, past an illusory railing past the Central Irithyll Fire Witches IBV: Large Titanite Shard (plaza, balcony overlooking ascent)On the path from Central Irithyll bonfire, instead of going left toward the Church of Yorshka, going right, on the balcony IBV: Large Titanite Shard (plaza, by stairs to church)To the left of the stairs leading up to the Church of Yorshka from Central Irithyll @@ -1555,7 +1555,7 @@ offline _Dark Souls III_ randomizer]. IBV: Rusted Gold Coin (Distant Manor, down stairs)Dropping down after the first set of stairs leading from Distant Manor bonfire IBV: Rusted Gold Coin (descent, side path)Down the stairs from the graveyard after Church of Yorshka, guarded by the group of dogs in the left path IBV: Shriving Stone (descent, dark room rafters)On the rafters in the dark area with the Irithyllian slaves -IBV: Siegbräu (Siegward)Given by Siegward meeting him in the Irithyll kitchen after the Sewer Centipedes. +IBV: Siegbräu (Siegward)Given by Siegward meeting him in the Irithyll kitchen after the Sewer Centipedes. IBV: Smough's Great Hammer (great hall, chest)In a chest up the stairs in the room with the Silver Knight staring at the painting IBV: Soul of Pontiff SulyvahnDropped by Pontiff Sulyvahn IBV: Soul of a Weary Warrior (ascent, by final staircase)Toward the end of the path from the sewer leading up to Pontiff's cathedral, to the left of the final staircase @@ -1617,7 +1617,7 @@ offline _Dark Souls III_ randomizer]. ID: Soul of a Weary Warrior (by drop to pit)At the end of the room with many peasant hollows after the Estus Shard minic ID: Soul of a Weary Warrior (stairs between pit and B3)Going past the Giant Slave to the sewer with the rats and the basilisks, up the first flight of stairs ID: Titanite Chunk (balcony above pit, lizard)Dropped by the Crystal Lizard where the Giant Slave is resting his head -ID: Titanite Chunk (pit, miniboss dropDrop from the Giant Slave +ID: Titanite Chunk (pit, miniboss drop)Drop from the Giant Slave ID: Titanite Scale (B2 far, lizard)Dropped by the Crystal Lizard on the bottom corridor opposite from the bonfire in Irithyll Dungeon where a Wretch attacks you ID: Titanite Scale (B3 far, mimic in hall)Dropped by the mimic in the main Jailer cell block ID: Titanite Slab (Siegward)Given by Siegward after unlocking Old Cell or on quest completion @@ -1722,7 +1722,7 @@ offline _Dark Souls III_ randomizer]. PC: Rusted Gold Coin (halls above swamp)In the corridors leading to the Profaned Capital toxic pool PC: Rusted Gold Coin (palace, mimic in far room)Dropped by the right mimic surrounded by the Jailers to the right of the Profaned Flame PC: Shriving Stone (swamp, by chapel door)At the far end of the Profaned Capital toxic pool, to the left of the door leading to the Monstrosities of Sin -PC: Siegbräu (Siegward after killing boss)Given by Siegward after helping him defeat Yhorm the Giant. You must talk to him before Emma teleports you. +PC: Siegbräu (Siegward after killing boss)Given by Siegward after helping him defeat Yhorm the Giant. You must talk to him before Emma teleports you. PC: Soul of Yhorm the GiantDropped by Yhorm the Giant PC: Storm Ruler (Siegward)Dropped by Siegward upon death or quest completion. PC: Storm Ruler (boss room)To the right of Yhorm's throne @@ -1888,7 +1888,7 @@ offline _Dark Souls III_ randomizer]. RC: Shira's Gloves (Shira's room after killing ashes NPC)Found in Shira's room in Ringed City after killing her in post-Filianore Ringed City. RC: Shira's Trousers (Shira's room after killing ashes NPC)Found in Shira's room in Ringed City after killing her in post-Filianore Ringed City. RC: Shriving Stone (wall tower, bottom floor center)In the cylindrical building before the long stairs with many Harald Legion Knights, in the center structure on the first floor. -RC: Siegbräu (Lapp)Given by Lapp within the Ringed Inner Wall. +RC: Siegbräu (Lapp)Given by Lapp within the Ringed Inner Wall. RC: Simple Gem (grave, up stairs after first drop)In Shared Grave, following the path after falling down from the crumbling stairs and continuing upward. RC: Soul of Darkeater MidirDropped by Darkeater Midir RC: Soul of Slave Knight GaelDropped by Slave Knight Gael @@ -2042,7 +2042,7 @@ offline _Dark Souls III_ randomizer]. UG: Ember (shop)Sold by Untended Graves Handmaid UG: Eyes of a Fire Keeper (shrine, Irina's room)Behind an illusory wall, in the same location Irina sits in Firelink Shrine UG: Hidden Blessing (cemetery, behind coffin)Behind the coffin that had a Titanite Shard in Cemetary of Ash -UG: Hornet Ring (environs, right of main path)On a cliffside to the right of the main path leading up to dark Firelink Shrine, after Abyss Watchers is defeated. +UG: Hornet Ring (environs, right of main path after killing FK boss)On a cliffside to the right of the main path leading up to dark Firelink Shrine, after Abyss Watchers is defeated. UG: Life Ring+3 (shrine, behind big throne)Behind Prince Lothric's throne UG: Priestess Ring (shop)Sold or dropped by Untended Graves Handmaid. Killing her is not recommended UG: Ring of Steel Protection+1 (environs, behind bell tower)Behind Bell Tower to the right @@ -2135,7 +2135,7 @@ offline _Dark Souls III_ randomizer]. US: Rusted Coin (wooden ledge above Dilapidated Bridge)On a wooden ledge near the Dilapidated Bridge bonfire. Must be jumped to from near Cathedral Evangelist enemy US: Saint's Talisman (chasm, by ladder)From the ravine accessible via Grave Key or dropping near Eygon, before ladder leading up to Irina of Carim US: Sharp Gem (lizard by Dilapidated Bridge)Drop by Crystal Lizard near Dilapidated Bridge bonfire. -US: Siegbräu (Siegward)Given by Siegward after helping him defeat the Fire Demon. +US: Siegbräu (Siegward)Given by Siegward after helping him defeat the Fire Demon. US: Small Leather Shield (first building, hanging corpse by entrance)Hanging corpse in the first building, to the right of the entrance US: Soul of a Nameless Soldier (top of tower)At the top of the tower where Giant shoots arrows US: Soul of an Unknown Traveler (chasm crypt)In the skeleton area accessible Grave Key or dropping down from near Eygon From d4b108dfb8a838e488e355e6a189b9e7563391b1 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 4 Jan 2024 18:17:47 -0800 Subject: [PATCH 114/238] Fix some bugs when generating for a multiworld --- worlds/dark_souls_3/Items.py | 3 ++- worlds/dark_souls_3/Locations.py | 16 ++++++++-------- worlds/dark_souls_3/Options.py | 1 - worlds/dark_souls_3/__init__.py | 9 +++++++-- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 5b01f705e4c3..4ea6bd5a6fc6 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -418,7 +418,8 @@ def flatten(l): DS3ItemData("Sorcerer's Staff", 0x00C747A0, DS3ItemCategory.WEAPON_UPGRADE_10), DS3ItemData("Storyteller's Staff", 0x00C76EB0, DS3ItemCategory.WEAPON_UPGRADE_10), DS3ItemData("Mendicant's Staff", 0x00C795C0, DS3ItemCategory.WEAPON_UPGRADE_10, - classification = ItemClassification.progression), # Crow trade + classification = ItemClassification.progression, # Crow trade + inject = True), # This is just a random drop normally but we need it in-logic DS3ItemData("Man-grub's Staff", 0x00C7E3E0, DS3ItemCategory.WEAPON_UPGRADE_5, inject = True), # Covenant reward DS3ItemData("Archdeacon's Great Staff", 0x00C80AF0, DS3ItemCategory.WEAPON_UPGRADE_5, diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 4e8a2ec2ee38..7649b38c092a 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -451,21 +451,21 @@ def __init__( DS3LocationData("FS: Sunlight Spear (Ludleth for Cinder)", "Sunlight Spear", missable = True, boss = True, shop = True), DS3LocationData("FS: Friede's Great Scythe (Ludleth for Friede)", "Friede's Great Scythe", - missable = True, boss = True, shop = True), + missable = True, dlc = True, boss = True, shop = True), DS3LocationData("FS: Rose of Ariandel (Ludleth for Friede)", "Rose of Ariandel", - missable = True, boss = True, shop = True), + missable = True, dlc = True, boss = True, shop = True), DS3LocationData("FS: Demon's Scar (Ludleth for Demon Prince)", "Demon's Scar", - missable = True, boss = True, shop = True), + missable = True, dlc = True, boss = True, shop = True), DS3LocationData("FS: Seething Chaos (Ludleth for Demon Prince)", "Seething Chaos", - missable = True, boss = True, shop = True), + missable = True, dlc = True, boss = True, shop = True), DS3LocationData("FS: Frayed Blade (Ludleth for Midir)", "Frayed Blade", missable = True, - boss = True, shop = True), + dlc = True, boss = True, shop = True), DS3LocationData("FS: Old Moonlight (Ludleth for Midir)", "Old Moonlight", missable = True, - boss = True, shop = True), + dlc = True, boss = True, shop = True), DS3LocationData("FS: Gael's Greatsword (Ludleth for Gael)", "Gael's Greatsword", - missable = True, boss = True, shop = True), + missable = True, dlc = True, boss = True, shop = True), DS3LocationData("FS: Repeating Crossbow (Ludleth for Gael)", "Repeating Crossbow", - missable = True, boss = True, shop = True), + missable = True, dlc = True, boss = True, shop = True), ], "Firelink Shrine Bell Tower": [ # Guarded by Tower Key diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 4e1b6ac04b03..14d221e931b1 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -49,7 +49,6 @@ class MissableLocationsOption(Choice): class RandomizeWeaponLocations(DefaultOnToggle): - """DEPRECATED (use "Excluded Locations" options instead) Setting this to false is now equivalent to adding "Weapons" to the "Exclude diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index fc2c2063718d..a762e639b3d1 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -653,7 +653,8 @@ def set_rules(self) -> None: "Coiled Sword Fragment": "Titanite Slab", "Seed of a Giant Tree": "Iron Leggings", "Siegbräu": "Armor of the Sun", - "Vertebra Shackle": "Lucatiel's Mask", + # Offline randomizer can't randomize Hodrick's drop yet + # "Vertebra Shackle": "Lucatiel's Mask", "Xanthous Crown": "Lightning Gem", "Mendicant's Staff": "Sunlight Shield", "Blacksmith Hammer": "Titanite Scale", @@ -791,7 +792,11 @@ def has_any_scroll(state): if self.options.excluded_locations == "unnecessary" else set() ).union( - {location for location in self.multiworld.get_locations() if location.missable} + { + location.name + for location in self.multiworld.get_locations() + if location.player == self.player and location.data.missable + } if self.options.missable_locations == "unnecessary" else set() ) From 13ffa157b36cbf2434472f662f0c0b67b6e46525 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 4 Jan 2024 19:19:31 -0800 Subject: [PATCH 115/238] Inject Large Leather Shield --- worlds/dark_souls_3/Items.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 4ea6bd5a6fc6..90347b60afe3 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -474,7 +474,8 @@ def flatten(l): DS3ItemData("Small Leather Shield", 0x01315410, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Round Shield", 0x0131A230, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Large Leather Shield", 0x0131C940, DS3ItemCategory.SHIELD_INFUSIBLE, - classification = ItemClassification.progression), # Crow trade + classification = ItemClassification.progression, # Crow trade + inject = True), # This is a shop/infinite drop item but we need it in logic DS3ItemData("Hawkwood's Shield", 0x01323E70, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Iron Round Shield", 0x01326580, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Wooden Shield", 0x0132DAB0, DS3ItemCategory.SHIELD_INFUSIBLE), From 818ace27b00046874d894330d284f43b5e76c9b4 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 5 Jan 2024 02:09:17 -0800 Subject: [PATCH 116/238] Fix a few location issues --- worlds/dark_souls_3/Locations.py | 21 +- worlds/dark_souls_3/docs/locations.md | 650 -------------------------- 2 files changed, 10 insertions(+), 661 deletions(-) delete mode 100644 worlds/dark_souls_3/docs/locations.md diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 7649b38c092a..83191af4ba55 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -559,22 +559,22 @@ def __init__( DS3LocationData("HWL: Undead Hunter Charm (fort, room off entry, in pot)", "Undead Hunter Charm x2", hidden = True), DS3LocationData("HWL: Firebomb (top of ladder to fountain)", "Firebomb x3"), - DS3LocationData("HWL: Cell Key (fort basement, down stairs)", "Cell Key"), + DS3LocationData("HWL: Cell Key (fort ground, down stairs)", "Cell Key"), DS3LocationData("HWL: Ember (fountain #1)", "Ember"), DS3LocationData("HWL: Soul of a Deserted Corpse (fort entry, corner)", "Soul of a Deserted Corpse"), DS3LocationData("HWL: Lucerne (promenade, side path)", "Lucerne"), DS3LocationData("HWL: Mail Breaker (wall tower, path to Greirat)", "Mail Breaker"), - DS3LocationData("HWL: Titanite Shard (fort basement, behind crates)", "Titanite Shard", + DS3LocationData("HWL: Titanite Shard (fort ground behind crates)", "Titanite Shard", hidden = True), DS3LocationData("HWL: Rapier (fountain, corner)", "Rapier"), - DS3LocationData("HWL: Titanite Shard (for, room off entry)", "Titanite Shard"), + DS3LocationData("HWL: Titanite Shard (fort, room off entry)", "Titanite Shard"), DS3LocationData("HWL: Large Soul of a Deserted Corpse (fort roof)", "Large Soul of a Deserted Corpse"), DS3LocationData("HWL: Black Firebomb (small roof over fountain)", "Black Firebomb x3"), DS3LocationData("HWL: Soul of a Deserted Corpse (path to corpse tower)", "Soul of a Deserted Corpse"), - DS3LocationData("HWL: Ember (fountain, #2)", "Ember"), + DS3LocationData("HWL: Ember (fountain #2)", "Ember"), DS3LocationData("HWL: Large Soul of a Deserted Corpse (platform by fountain)", "Large Soul of a Deserted Corpse", hidden = True), # Easily missed turnoff DS3LocationData("HWL: Binoculars (corpse tower, upper platform)", "Binoculars"), @@ -583,17 +583,17 @@ def __init__( DS3LocationData("HWL: Throwing Knife (shortcut, lift top)", "Throwing Knife x6"), DS3LocationData("HWL: Soul of a Deserted Corpse (path to back tower, by lift door)", "Soul of a Deserted Corpse"), - DS3LocationData("HWL: Green Blossom (shortcut, by lower lift door)", "Green Blossom x3"), - DS3LocationData("HWL: Broadsword (fort, room off entry)", "Broadsword"), + DS3LocationData("HWL: Green Blossom (shortcut, lower courtyard)", "Green Blossom x3"), + DS3LocationData("HWL: Broadsword (fort, room off walkway)", "Broadsword"), DS3LocationData("HWL: Soul of a Deserted Corpse (fountain, path to promenade)", "Soul of a Deserted Corpse"), DS3LocationData("HWL: Firebomb (fort roof)", "Firebomb x3"), DS3LocationData("HWL: Soul of a Deserted Corpse (wall tower, right of exit)", "Soul of a Deserted Corpse"), - DS3LocationData("HWL: Estus Shard (fort basement, on anvil)", "Estus Shard"), + DS3LocationData("HWL: Estus Shard (fort ground, on anvil)", "Estus Shard"), DS3LocationData("HWL: Fleshbite Ring+1 (fort roof, jump to other roof)", "Fleshbite Ring+1", ngp = True, hidden = True), # Hidden jump - DS3LocationData("HWL: Ring of the Evil Eye+2 (fort basement, far wall)", + DS3LocationData("HWL: Ring of the Evil Eye+2 (fort ground, far wall)", "Ring of the Evil Eye+2", ngp = True, hidden = True), # In barrels DS3LocationData("HWL: Silver Eagle Kite Shield (fort mezzanine)", "Silver Eagle Kite Shield"), @@ -606,10 +606,9 @@ def __init__( DS3LocationData("HWL: Ember (fort roof, transforming hollow)", "Ember", hidden = True), DS3LocationData("HWL: Titanite Shard (fort roof, transforming hollow)", "Titanite Shard", hidden = True), - DS3LocationData("HWL: Ember (back tower roof bonfire, transforming hollow)", "Ember", + DS3LocationData("HWL: Ember (back tower, transforming hollow)", "Ember", hidden = True), + DS3LocationData("HWL: Titanite Shard (back tower, transforming hollow)", "Titanite Shard", hidden = True), - DS3LocationData("HWL: Titanite Shard (back tower roof bonfire, transforming hollow)", - "Titanite Shard", hidden = True), DS3LocationData("HWL: Refined Gem (promenade miniboss)", "Refined Gem", miniboss = True), DS3LocationData("HWL: Way of Blue (Emma)", "Way of Blue"), diff --git a/worlds/dark_souls_3/docs/locations.md b/worlds/dark_souls_3/docs/locations.md deleted file mode 100644 index 159b9d25192b..000000000000 --- a/worlds/dark_souls_3/docs/locations.md +++ /dev/null @@ -1,650 +0,0 @@ -# Dark Souls III Locations - -All locations begin with an abbreviation indicating their general region. Most -locations have a set of landmarks that are used in location names to keep them -short. - -* **FS:** Firelink Shrine -* **FSBT:** Firelink Shrine belltower -* **HWL:** [High Wall of Lothric](#high-wall-of-lothric) -* **US:** [Undead Settlement](#undead-settlement) -* **RS:** [Road of Sacrifices](#road-of-sacrifices) -* **CD:** [Cathedral of the Deep](#cathedral-of-the-deep) -* **FK:** [Farron Keep](#farron-keep) -* **CC:** [Catacombs of Carthus](#catacombs-of-carthus) -* **SL:** [Smouldering Lake](#smouldering-lake) -* **IBV:** [Irithyll of the Boreal Valley](#irithyll-of-the-boreal-valley) -* **ID:** [Irithyll Dungeon](#irithyll-dungeon) -* **PC:** [Profaned Capital](#profaned-capital) -* **AL:** [Anor Londo](#anor-londo) -* **LC:** [Lothric Castle](#lothric-castle) -* **CKG:** [Consumed King's Garden](#consumed-kings-garden) -* **GA:** [Grand Archives](#grand-archives) -* **UG:** [Untended Graves](#untended-graves) -* **AP:** [Archdragon Peak](#archdragon-peak) -* **PW1:** [Painted World of Ariandel (Before Contraption)](#painted-world-of-ariandel-before-contraption) -* **PW2:** [Painted World of Ariandel (After Contraption)](#painted-world-of-ariandel-after-contraption) -* **DH:** [Dreg Heap](#dreg-heap) -* **RC:** [Ringed City](#ringed-city) - -General notes: - -* "Lizard" always refers to a small crystal lizard. - -* "Miniboss" are large enemies that don't respawn after being killed and usually - drop some sort of treasure, such as Boreal Outrider Knights and Ravenous - Crystal Lizards. They usually don't have boss bars, but a few of them do. - -* NPC quest items are always in the first location you can get them _without_ - killing the NPC or ending the quest early. - -## High Wall of Lothric - -* **Back tower:** The tower _behind_ the High Wall of Lothric bonfire, past the - path to the shortcut elevator. - -* **Corpse tower:** The first tower after the High Wall of Lothric bonfire, with - a dead Wyvern on top of it. - -* **Fire tower:** The second tower after the High Wall of Lothric bonfire, where - a living Wyvern lands and breathes fire at you. - -* **Flame plaza:** The open area with many items where the Wyvern breathes fire. - -* **Wall tower:** The third tower after the High Wall of Lothric bonfire, with - the Tower on the Wall bonfire. - -* **Fort:** The large building after the Tower on the Wall bonfire, with the - transforming hollow on top. - - * "Entry": The first room you enter after descending the ladder from the roof. - - * "Walkway": The top floor of the tall room, with a path around the edge - hidden by a large wheel. - - * "Mezzanine": The middle floor of the tall room, with a chest. - - * "Ground": The bottom floor of the tall room, with an anvil and many mobs. - -* **Fountain:** The large fountain with many dead knights around it, where the - Winged Knight patrols in vanilla. - -* **Shortcut:** The unlockable path between the promenade and the High Wall of - Lothric bonfire, including both the elevator and the area at its base. - -* **Promenade:** The long, wide path between the two boss arenas. - -## Undead Settlement - -* **Burning tree:** The tree near the beginning of the region, with the - Cathedral Evangelist in front of it in vanilla. - -* **Hanging corpse room:** The dark room to the left of the burning tree with - many hanging corpses inside, on the way to the Dilapidated Bridge bonfire. - -* **Stable:** The building complex across the bridge to the right of the burning - tree. - -* **White tree:** The birch tree by the Dilapidated Bridge bonfire, where the - giant shoots arrows. - -* **Sewer:** The underground passage between the - -* **Chasm:** The chasm underneath the bridge on the way to the tower. It's - possible to get into the chasm without a key by dropping down next to Eygon of - Carim with a full health bar. - -* **Tower:** The tower at the end of the region with the giant archer at the - top. - -* **Tower village:** The village reachable from the tower, where the Fire Giant - patrols in vanilla. - -## Road of Sacrifices - -The area after the Crystal Sage is considered part of the Cathedral of the Deep -region. - -* **Road:** The path from the Road of Sacrifices bonfire to the Halfway Fortress - bonfire. - -* **Woods:** The wooded area on land, after the Halfway Fortress bonfire and - surrounding the Crucifixion Woods bonfire. - -* **Water:** The watery area, covered in crabs in vanilla. - -* **Deep water:** The area in the water near the ladder to Farron Keep, where - your walking is slowed. - -* **Stronghold:** The stone building complex on the way to Crystal Sage. - - * "Left room" is the room whose entrance is near the Crucifixion Woods - bonfire. - - * "Right room" is the room up the stairs closer to Farron Keep. - -* **Keep perimiter:** The building with the Black Knight and the locked door to - the Farron Keep Perimeter bonfire. - -## Cathedral of the Deep - -* **Path:** The path from Road of Sacrifices to the cathedral proper. - -* **Moat:** The circular path around the base of the area in front of the - cathedral, with the Ravenous Crystal Lizard in vanilla. Only the lowest part - actually has any water. - -* **Graveyard:** The area with respawning enemies up the hill from the Cleansing - Chapel bonfire. - -* **White tree:** The birch tree below the front doors of the chapel and across - the moat from the graveyard, where the giant shoots arrows if he's still - alive. - -* **Lower roofs:** The roofs, flying buttresses, and associated areas to the - right of the front door, which must be traversed before entering the - cathedral. - -* **Upper roofs:** The roofs, flying buttresses, and rafters leading to the - Rosaria's Bedchamber bonfire. - -* **Main hall:** The central and largest room in the cathedral, with the muck - that slows your movement. Divided into the south (with the sleeping giant in - vanilla) and east (with many items) wings, with north pointing towards the - door to the boss. - -* **Side chapel:** The room with rows of pews and the patrolling Cathedral - Knight in vanilla, to the side of the main hall. - -## Farron Keep - -* **Left island:** The large island with the ritual flame, to the left as you - leave the Farron Keep bonfire. - -* **Right island:** The large island with the ritual flame, to the right as you - leave the Farron Keep bonfire. - -* **Hidden cave:** A small cave in the far corner of the map, closest to the - right island. Near a bunch of basilisks in vanilla. - -* **Keep ruins:** The two islands with the Keep Ruins bonfire (bonfire island) - and one of the three ritual fires (ritual island). - -* **White tree**: The birch tree by the ramp down from the keep ruins bonfire - island, where the giant shoots arrows if he's still alive. - -* **Keep proper:** The building with the Old Wolf of Farron bonfire. - -* **Upper keep:** The area on top of the keep proper, reachable from the - elevator from the Old Wolf of Farron bonfire. - -* **Perimeter:** The area from near the Farron Keep Perimeter bonfire, including - the stony section and the path to the boss. - -## Catacombs of Carthus - -All the area up to the Small Doll wall into Irithyll is considered part of the -Catacombs of Carthus region. - -* **Atrium:** The large open area you first enter and the rooms attached to it. - - * "Upper" is the floor you begin on. - * "Lower" is the floor down the short stairs but at the top of the long - stairway that the skeleton ball rolls down. - -* **Crypt:** The enclosed area at the bottom of the long stairway that the - skeleton ball rolls down. - - * "Upper" is the floor the long stairway leads to that also contains the - Catacombs of Carthus bonfire. - * "Lower" is the floor with rats and bonewheels in vanilla. - * "Across" is the area reached by going up a different set of stairs from - downstairs. - -* **Cavern:** The even larger open area past the crypt with the rope bridge to - the boss arena. - -* **Tomb:** The area on the way to Smouldering Lake, reachable by cutting down - the rope bridge and climbing down it. - -* **Irithyll Bridge:** The outdoor bridge leading to Irithyll of the Boreal - Valley. - -## Smouldering Lake - -* **Lake:** The watery area you enter initially, where you get shot at by the - ballista. - -* **Side lake:** The small lake accessible via a passage from the larger one, in - which you face Horace the Hushed as part of his quest. - -* **Ruins main:** The area you first enter after the Demon Ruins bonfire. - - * "Upper" is the floor you begin on. - * "Lower" is the floor down the stairs from upper. - -* **Antechamber:** The area up a different flight of stairs from ruins main - lower, with the Old King's Antechamber bonfire. - -* **Ruins basement:** The area further down from ruins main lower, with a many - basilisks and Knight Slayer Tsorig in vanilla. - -## Irithyll of the Boreal Valley - -This region starts _after_ the Small Doll wall and ends with Pontiff Sulyvahn. -Everything after that, including the contents of Sulyvahn's cathedral is -considered part of Anor Londo. - -* **Central:** The beginning of the region, from the Central Irithyll bonfire up - to the plaza. - -* **Dorhys:** The sobbing mob (a Cathedral Evangelist in vanilla) behind the - locked door opening onto central. Accessed through an illusory railing by the - crystal lizard just before the plaza. - -* **Plaza:** The area in front of and below the cathedral, with a locked door up - to it and a locked elevator to the ascent. - -* **Descent:** The path from the Church of Yorshka bonfire down to the lake. - -* **Lake:** The open watery area outside the room with the Distant Manor - bonfire. - -* **Sewer:** The room between the lake and the beginning of the ascent, filled - with Sewer Centipedes in vanilla. - -* **Ascent:** The path up from the lake to the cathedral, through several - buildings and some open stairs. - -* **Great hall:** The building along the ascent with a large picture of - Gwynevere and several Silver Knights in vanilla. - -## Irithyll Dungeon - -In Irithyll Dungeon locations, "left" and "right" are always oriented facing -from the "near" side of the floor to the "far" side. - -* **B1:** The floor on which the player enters the dungeon, with the Irithyll - Dungeon bonfire. - - * "Near" is the side of the dungeon with the bonfire. - * "Far" is the opposite side. - -* **B2:** The floor directly below B1, which can be reached by going down the - stairs or dropping. - - * "Near" is the same side of the dungeon as the bonfire. - * "Far" is the opposite side. - -* **Pit:** The large room with the Giant Slave and many Rats in vanilla. - -* **Pit lift:** The elevator from the pit up to B1 near, right to the Irithyll - Dungeon bonfire. - -* **B3:** The lowest floor, with Karla's cell, a lift back to B2, and the exit - onwards to Profaned Capital. - - * "Near" is the side with Karla's cell and the the path from the pit. - * "Far" is the opposite side with the mimic. - -* **B3 lift:** The elevator from B3 (near where you can use Path of the Dragon - to go to Archdragon Peak) up to B2 far. - -## Profaned Capital - -* **Tower:** The tower that contains the Profaned Capital bonfire. - -* **Swamp:** The pool of toxic liquid accessible by falling down out of the - lower floor of the tower, going into the corridor to the left, and falling - down a hole. - -* **Chapel:** The building in the swamp, with Monstrosities of Sin in it in - vanilla. - -* **Bridge:** The long bridge from the tower into the palace. - -* **Palace:** The large building carved into the wall of the cavern, full of - chalices and broken pillars. - -## Anor Londo - -This region includes everything after Sulyvahn's cathedral, including its upper -story. - -* **Light cathedral:** The cathedral in which you fight Pontiff Sulyvahn in - vanilla. - -* **Plaza:** The wide open area filled with dead Giant Slaves and a couple live - ones in vanilla. - -* **Walkway:** The path above the plaza leading to the second floor of the light - cathedral, with Deacons in vanilla. - -* **Buttresses:** The flying buttresses that you have to climb to get to the - spiral staircase. "Near" and "far" are relative to the light cathedral, so the - nearest buttress is the one that leads back to the walkway. - -* **Tomb:** The area past the illusory wall just before the spiral staircase, in - which you marry Anri during Yoel and Yuria's quest. - -* **Dark cathedral:** The darkened cathedral just before the Aldrich fight in - vanilla. - -## Lothric Castle - -This region covers everything up the ladder from the Dancer of the Boreal Valley -bonfire up to the door into Grand Archives, except the area to the left of the -ladder which is part of Consumed King's Garden. - -* **Lift:** The elevator from the room straight after the Dancer of the Boreal - Valley bonfire up to just before the boss fight. - -* **Ascent:** The set of stairways and turrets leading from the Lothric Castle - bonfire to the Dragon Barracks bonfire. - -* **Barracks:** The large building with two fire-breathing wyverns across from - the Dragon Barracks bonfire. - -* **Moat:** The ditch beneath the bridge leading to the barracks. - - * The "right path" leads to the right as you face the barracks, around and - above the stairs up to the Dragon Barracks bonfire. - -* **Plaza:** The open area in the center of the barracks, where the two wyverns - breathe fire. - - * "Left" is the enclosed area on the left as you're coming from the Dragon - Barracks bonfire, with the stairs down to the basement. - -* **Basement:** The room beneath plaza left, with the Boreal Outrider in - vanilla. - -* **Dark room:** The large darkened room on the right of the barracks as you're - coming from the Dragon Barracks bonfire, with firebomb-throwing Hollows in - vanilla. - - * "Lower" is the bottom floor that you enter onto from the plaza. - * "Upper" is the top floor with the door to the main hall. - * "Mid" is the middle floor accessible by climbing a ladder from lower or - going down stairs from upper. - -* **Main hall:** The central room of the barracks, behind the gate. - -* **Chapel:** The building to the right just before the stairs to the boss, with - a locked elevator to Grand Archives. - -* **Wyvern room:** The room where you can fight the Pus of Man infecting the - left wyvern, accessible by dropping down to the left of the stairs to the - boss. - -* **Altar:** The building containing the Altar of Sunlight, accessible by - climbing up a ladder onto a roof around the corner from the stairs to the - boss. - -## Consumed King's Garden - -This region covers everything to the left of the ladder up from the Dancer of -the Boreal Valley bonfire up to the illusory wall into Untended Graves. - -* **Balcony:** The walkway accessible by getting off the first elevator halfway - down. - -* **Rotunda:** The building in the center of the toxic pool, with a Cathedral - Knight on it in vanilla. - -* **Lone stairway:** A set of stairs leading nowhere in the far left of the main - area as you enter from the first elevator. - -* **Shortcut:** The path from the locked door into Lothric Castle, through the - room filled with thralls in vanilla, and down a lift. - -* **Tomb:** The area after the boss room. - -## Grand Archives - -* **1F:** The first floor of the Grand Archives, including the first wax pool. - -* **Dark room:** The unlit room on 1F to the right of the wax pool. - -* **2F:** The second floor of the grand archives. It's split into two sections - that are separated by retractable bookshelves. - - * "Early" is the first part you reach and has an outdoor balcony with a ladder - to 3F and a wax pool up a short set of stairs. - * "Late" is the part you can only reach by climbing down from F3, where you - encounter the teleporting miniboss for the final time. - -* **3F:** The third floor of the grand archives, where you encounter the - teleporting miniboss for the second time. Includes the area with a hidden room - with another miniboss. - -* **4F:** The topmost and most well-lit section of bookshelves, overlooking the - rest of the archives. - -* **Rooftops:** The outer rooftop area between 4F and 5F, with Gargoyles in - vanilla. - - * "Lower" is the balcony you can reach by dropping off the rooftops, as well - as the further rooftops leading down to the 2F early balcony. - -* **5F:** The topmost floor of the archives interior, accessible from the - rooftops, with a ladder down to 4F. - -* **Dome:** The domed roof of the Grand Archives, with Ascended Winged Knights - in vanilla. - -* **Rafters:** The narrow walkways above the Grand Archives, accessible by - dropping down from the dome. - -## Untended Graves - -* **Swamp:** The watery area immediately after the Untended graves bonfire, up - to the cemetery. - -* **Cemetery:** The area past where the Cemetery of Ash bonfire would be, up to - the boss arena. - -* **Environs:** The area after the boss and outside the abandoned Firelink - Shrine. - -* **Shrine:** The area inside the abandoned Firelink Shrine. - -## Archdragon Peak - -"Gesture" always means the Path of the Dragon gesture. - -* **Intro:** The first section, from where you warp in from Irithyll Dungeon up - to the first boss fight. - - * "Archway": The large stone archway in front of the boss door. - -* **Fort:** The arena where you fight Ancient Wyvern in vanilla. - - * "Overlook": The area down the stairs from where the Ancient Wyvern first - lands in vanilla, overlooking the fog. - - * "Rotunda": The top of the spiral staircase building, to the left before the - bridge with the chain-axe Man-Serpent in vanilla. - -* **Mausoleum:** The building with the Dragon-Kin Mausoleum bonfire, where - you're warped after the first boss fight. - -* **Walkway:** The path from the mausoleum to the belfry, looking out over - clouds. - - * "Building": The building along the walkway, just before the wyvern in - vanilla. - -* **Belfry:** The building with the Great Belfry bonfire, including the room - with the summoner. - -* **Plaza:** The arena that appears after you defeat Nameless King in vanilla. - -* **Summit:** The path up from the belfry to the final altar at the top of the - mountain. - -## Painted World of Ariandel (Before Contraption) - -This region covers the Ashes of Ariandel DLC up to the point where you must use -the Contraption Key to ascend to the second level of the building and first meet -the painter. - -* **Snowfield:** The area around the Snowfield bonfire, - - * "Upper": The area immediately after the Snowfield bonfire, before the - collapsing overhang, with the Followers in vanilla. - - * "Lower": The snowy tree-filled area after the collapsing overhang, with the - Wolves in vanilla. - - * "Village": The area with broken-down buildings and Millwood Knights in - vanilla. - - * "Tower": The tower by the village, with Millwood Knights in Vanilla. - -* **Bridge:** The rope bridge to the chapel. - - * "Near": The side of the bridge by the Rope Bridge Cave bonfire. - - * "Far": The side of the bridge by the Ariandel Chapel bonfire. - -* **Chapel:** The building with the Ariandel Chapel bonfire and Lady Friede. - -* **Depths:** The area reachable by cutting down the bridge and descending on - the far side, with the Depths of the Painting bonfire. - -* **Settlement:** The area reachable by cutting down the bridge and descending - on the near side, with the Corvian Settlement bonfire. Everything after the - slide down the hill is considered part of the settlement. - - * "Courtyard": The area in front of the settlement, immediately after the - slide. - - * "Main": The main road of the settlement leading up to the locked gate to the - library. Also includes the buildings that are immediately accessible from - this road. - - * "Loop": A side path that loops left from the main road and goes up and - behind the building with the bonfire. - - * "Back": The back alley of the settlement, accessible by dropping down to the - right of the locked gate to the library. Also includes the buildings that - are immediately accessible from this alley. - - * "Roofs": The village rooftops, first accessible by climbing a ladder from - the back alley. Also includes the buildings and items that are first - accessible from the roofs. - - * "Hall": The largest building in the settlement, with two Corvian Knights in - vanilla. - -* **Library:** The building where you use the contraption key, where Vilhelm - appears in vanilla. - -## Painted World of Ariandel (After Contraption) - -This region covers the Ashes of Ariandel DLC past the point where you must use -the Contraption Key to ascend to the second level of the building and first meet -the painter, including the basement beneath the chapel. - -* **Pass:** The mountainous area past the Snowy Mountain Pass bonfire. - -* **Pit:** The area with a large tree and numerous Millwood Knights in vanilla, - reached by a collapsing overhang in the pass. - -* **B1:** The floor immediately below the chapel, first accessible from the - pass. Filled with Giant Flies in vanilla. - -* **B2:** The floor below B1, with lots of fly eggs. Filled with even more Giant - Flies than B1 in vanilla. - -* **B3:** The floor below B2, accessible through an illusory wall. - -* **Rotunda:** The round arena out in the open, accessible by platforming down - tree roots from B3. - -## Dreg Heap - -* **Shop:** Items sold by the Stone-Humped Hag by The Dreg Heap bonfire. - -* **Castle:** The building with The Dreg Heap bonfire, up to the large fall into - the library. - -* **Library:** The building with the stained glass window that you fall into - from the castle. - -* **Church:** The building below and to the right of the library, which the - pillar falls into to make a bridge. - -* **Pantry:** The set of rooms entered through a door near the fountain just - past the church, with boxes and barrels. - - * "Upstairs": The room with an open side, accessible through an illusory wall - in the furthest pantry room. - -* **Parapets:** The area with balconies and Overgrown Lothric Knights in - vanilla, accessible by taking the pillar bridge from the church, following - that path to the end, and dropping down to the right. - -* **Ruins:** The area around the Earthen Peak Ruins bonfire, up to the swamp. - -* **Swamp:** The area in and above the poisonous water, up to the point the - branches deposit you back on the ruins. - - * "Left": Left as you enter from the ruins, towards the cliff edge. - - * "Right": Right as you enter from the ruins, towards higher ground. - - * "Upper": The path up and over the swamp towards the Within Earthen Peak - Ruins bonfire. - -## Ringed City - -The "mid boss", "end boss", and "hidden boss" are the bosses who take the place -of Halflight, Gael, and Midir, respectively. - -* **Wall:** The large wall in which you spawn when you first enter the area, - with the Mausoleum Lookout bonfire. - - * "Top": The open-air top of the wall, where you first spawn in. - - * "Upper": The upper area of the wall, with the Ringed Inner Wall bonfire. - - * "Tower": The tiered tower leading down from the upper area to the stairs. - - * "Lower": The lower rooms of the wall, accessible from the lower cliff, with - an elevator back to upper. - - * "Hidden": The hidden floor accessible from the elevator from lower to upper, - from which you can reach Midir in vanilla. - -* **Streets:** The streets and skyways of the city proper. "Left" and "right" - are relative to the main staircase as you head down towards the swamp, "near" - and "far" are relative to Shira's chamber at the top of the stairs. - - * "Garden": The flower-filled back alley accessible from the left side of the - nearest bridge over the stairs. - - * "High": The higher areas in the far left where you can find the Locust - Preacher, accessible from a long ladder in the swamp. - - * "Monument": The area around the purging monument, which can only be accessed - by solving the "Show Your Humanity" puzzle. - -* **Swamp:** The wet area past the city streets. "Left and "right" are relative - to heading out from the Ringed City Streets bonfire, and "near" and "far" are - relative to that bonfire as well. - -* **Upper cliff:** The cliffside path leading from the swamp into the shared - grave, where Midir breathes fire. - -* **Grave:** The cylindrical chamber with spiral stairs around the edges, - connecting the two cliffs, containing the Shared Grave bonfire. - -* **Lower cliff:** The cliffside path leading out of the grave to the lower - wall. - -* **Church path:** The sunlit path from the lower cliff up to the Church of - Filianore where you fight Halflight in vanilla. - -* **Ashes:** The final area, where you fight Gael in vanilla. From f87880356e491d27c669ef9aa0f55b5e0a8ef2d2 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 6 Jan 2024 20:17:01 -0800 Subject: [PATCH 117/238] Don't allow progression_skip_balancing for unnecessary locs --- worlds/dark_souls_3/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index a762e639b3d1..9651fcd535a8 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -803,7 +803,10 @@ def has_any_scroll(state): for location in unnecessary_locations: if self.is_location_available(location): add_item_rule(self.multiworld.get_location(location, self.player), - lambda item: item.classification != ItemClassification.progression) + lambda item: item.classification not in { + ItemClassification.progression, + ItemClassification.progression_skip_balancing + }) randomized_items = { item.name for item in self.multiworld.itempool From a447251ef083027aee2f2a9e6c3643a2a2a90676 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 8 Jan 2024 16:20:14 -0800 Subject: [PATCH 118/238] Update some location info --- worlds/dark_souls_3/Bosses.py | 14 ++- worlds/dark_souls_3/Locations.py | 91 +++++++++---------- worlds/dark_souls_3/docs/locations_en.md | 110 ++++++++++++----------- 3 files changed, 112 insertions(+), 103 deletions(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index a14b8e0921d4..945c5703fdda 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -44,6 +44,16 @@ class DS3BossInfo: "US: Transposing Kiln (boss drop)", "US: Wargod Wooden Shield (Pit of Hollows)", "FS: Hawkwood's Shield (Hawkwood)", + "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, region = "Cathedral of the Deep", locations = { "RS: Soul of a Crystal Sage", @@ -171,11 +181,11 @@ class DS3BossInfo: "AP: Dragonslayer Gauntlets (plaza)", "AP: Dragonslayer Leggings (plaza)", }), - DS3BossInfo("Lorian, Elder Prince", 3410830, locations = { + DS3BossInfo("Lothric, Younger Prince", 3410830, locations = { "GA: Soul of the Twin Princes", "GA: Cinders of a Lord - Lothric Prince", }), - DS3BossInfo("Lothric, Younger Prince", 3410832, locations = { + 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)", diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 83191af4ba55..c4f8c48ed4cb 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -470,7 +470,7 @@ def __init__( "Firelink Shrine Bell Tower": [ # Guarded by Tower Key DS3LocationData("FSBT: Homeward Bone (roof)", "Homeward Bone x3"), - DS3LocationData("FSBT: Estus Ring (rafters)", "Estus Ring"), + DS3LocationData("FSBT: Estus Ring (tower base)", "Estus Ring"), DS3LocationData("FSBT: Estus Shard (rafters)", "Estus Shard"), DS3LocationData("FSBT: Fire Keeper Soul (tower top)", "Fire Keeper Soul"), DS3LocationData("FSBT: Fire Keeper Robe (partway down tower)", "Fire Keeper Robe"), @@ -636,21 +636,19 @@ def __init__( DS3LocationData("US: Tower Key (kill Irina)", "Tower Key", missable = True, npc = True), DS3LocationData("US: Flynn's Ring (tower village, rooftop)", "Flynn's Ring"), DS3LocationData("US: Undead Bone Shard (by white tree)", "Undead Bone Shard"), - DS3LocationData("US: Alluring Skull (Foot of the High Wall, behind carriage)", - "Alluring Skull x2"), + DS3LocationData("US: Alluring Skull (foot, behind carriage)", "Alluring Skull x2"), DS3LocationData("US: Mortician's Ashes (graveyard by white tree)", "Mortician's Ashes", progression = True), - DS3LocationData("US: Homeward Bone (tower village, jump from roof)", "Homeward Bone x2", - hidden = True), # Hidden fall + DS3LocationData("US: Homeward Bone (???)", "Homeward Bone x2"), # Hidden fall DS3LocationData("US: Caduceus Round Shield (right after stable exit)", "Caduceus Round Shield"), - DS3LocationData("US: Ember (by miniboss before Road of Sacrifices)", "Ember"), + DS3LocationData("US: Ember (tower basement, miniboss)", "Ember"), DS3LocationData("US: Soul of an Unknown Traveler (chasm crypt)", "Soul of an Unknown Traveler"), DS3LocationData("US: Repair Powder (first building, balcony)", "Repair Powder x2"), - DS3LocationData("US: Homeward Bone (stable roof)", "Homeward Bone x2"), - DS3LocationData("US: Titanite Shard (side path on the way to Dilapidated Bridge)", - "Titanite Shard"), + DS3LocationData("US: Homeward Bone (tower village, jump from roof)", "Homeward Bone x2", + hidden = True), # Hidden fall + DS3LocationData("US: Titanite Shard (back alley, side path)", "Titanite Shard"), DS3LocationData("US: Wargod Wooden Shield (Pit of Hollows)", "Wargod Wooden Shield"), DS3LocationData("US: Large Soul of a Deserted Corpse (on the way to tower, by well)", "Large Soul of a Deserted Corpse"), @@ -673,13 +671,11 @@ def __init__( DS3LocationData("US: Bloodbite Ring (miniboss in sewer)", "Bloodbite Ring", miniboss = True), # Giant Rat drop DS3LocationData("US: Charcoal Pine Bundle (first building)", "Charcoal Pine Bundle x2"), - DS3LocationData("US: Soul of an Unknown Traveler (on the way to Dilapidated Bridge, in crates)", + DS3LocationData("US: Soul of an Unknown Traveler (back alley, past crates)", "Soul of an Unknown Traveler", hidden = True), - DS3LocationData("US: Titanite Shard (on the way to Dilapidated Bridge, up ladder)", - "Titanite Shard"), + DS3LocationData("US: Titanite Shard (back alley, up ladder)", "Titanite Shard"), DS3LocationData("US: Red Hilted Halberd (chasm crypt)", "Red Hilted Halberd"), - DS3LocationData("US: Rusted Coin (wooden ledge above Dilapidated Bridge)", - "Rusted Coin x2"), + DS3LocationData("US: Rusted Coin (awning above Dilapidated Bridge)", "Rusted Coin x2"), DS3LocationData("US: Caestus (sewer)", "Caestus"), DS3LocationData("US: Saint's Talisman (chasm, by ladder)", "Saint's Talisman"), DS3LocationData("US: Alluring Skull (on the way to tower, behind building)", @@ -709,10 +705,9 @@ def __init__( DS3LocationData("US: Estus Shard (under burning tree)", "Estus Shard"), DS3LocationData("US: Firebomb (stable roof)", "Firebomb x6"), # In enemy rando, the enemy may not burst through the wall and make this room obvious - DS3LocationData("US: Whip (on the way to Dilapidated Bridge, behind wooden wall)", - "Whip", hidden = True), + DS3LocationData("US: Whip (back alley, behind wooden wall)", "Whip", hidden = True), DS3LocationData("US: Great Scythe (building by white tree, balcony)", "Great Scythe"), - DS3LocationData("US: Homeward Bone (by Yoel)", "Homeward Bone x2"), + DS3LocationData("US: Homeward Bone (stable roof)", "Homeward Bone x2"), DS3LocationData("US: Large Soul of a Deserted Corpse (around corner by Cliff Underside)", "Large Soul of a Deserted Corpse", hidden = True), # Hidden corner DS3LocationData("US: Ember (behind burning tree)", "Ember"), @@ -754,7 +749,7 @@ def __init__( "Covetous Silver Serpent Ring+2", ngp = True, hidden = True), # Hidden fall DS3LocationData("US: Human Pine Resin (tower village building, chest upstairs)", "Human Pine Resin x4"), - DS3LocationData("US: Homeward Bone (tower village, right of first drop)", "Homeward Bone"), + DS3LocationData("US: Homeward Bone (foot, drop overloop)", "Homeward Bone"), DS3LocationData("US: Irithyll Straight Sword (miniboss drop, by Road of Sacrifices)", "Irithyll Straight Sword", miniboss = True), DS3LocationData("US: Fire Gem (tower village, miniboss drop)", "Fire Gem", miniboss = True), @@ -882,8 +877,7 @@ def __init__( DS3LocationData("RS: Conjurator Boots (deep water)", "Conjurator Boots"), DS3LocationData("RS: Soul of an Unknown Traveler (right of door to stronghold left)", "Soul of an Unknown Traveler"), - DS3LocationData("RS: Green Blossom (water by Crucifixion Woods bonfire)", - "Green Blossom x2"), + DS3LocationData("RS: Green Blossom (water beneath stronghold)", "Green Blossom x2"), DS3LocationData("RS: Great Swamp Pyromancy Tome (deep water)", "Great Swamp Pyromancy Tome"), DS3LocationData("RS: Homeward Bone (balcony by Farron Keep)", "Homeward Bone x2"), @@ -1142,10 +1136,6 @@ def __init__( "Red Sign Soapstone", drop = True, hidden = True), DS3LocationData("CD: Aldrich's Sapphire (side chapel, miniboss drop)", "Aldrich's Sapphire", miniboss = True), # Deep Accursed Drop - DS3LocationData("CD: Dung Pie (main hall, miniboss drop)", "Dung Pie x4", - miniboss = True), # drop from either Giant Slave - DS3LocationData("CD: Large Titanite Shard (main hall, miniboss drop)", - "Large Titanite Shard", miniboss = True), # drop from either Giant Slave DS3LocationData("CD: Titanite Scale (moat, miniboss drop)", "Titanite Scale", miniboss = True), # Ravenous Crystal Lizard drop DS3LocationData("CD: Twinkling Titanite (moat, lizard #1)", "Twinkling Titanite", @@ -1218,13 +1208,13 @@ def __init__( DS3LocationData("FK: Titanite Shard (between left island and keep ruins)", "Titanite Shard"), DS3LocationData("FK: Rusted Gold Coin (right island, behind wall)", "Rusted Gold Coin", hidden = True), - DS3LocationData("FK: Nameless Knight Helm (next to pillar by right island)", + DS3LocationData("FK: Nameless Knight Helm (corner of keep and right island)", "Nameless Knight Helm"), - DS3LocationData("FK: Nameless Knight Armor (next to pillar by right island)", + DS3LocationData("FK: Nameless Knight Armor (corner of keep and right island)", "Nameless Knight Armor"), - DS3LocationData("FK: Nameless Knight Gauntlets (next to pillar by right island)", + DS3LocationData("FK: Nameless Knight Gauntlets (corner of keep and right island)", "Nameless Knight Gauntlets"), - DS3LocationData("FK: Nameless Knight Leggings (next to pillar by right island)", + DS3LocationData("FK: Nameless Knight Leggings (corner of keep and right island)", "Nameless Knight Leggings"), DS3LocationData("FK: Shriving Stone (perimeter, just past stone doors)", "Shriving Stone"), DS3LocationData("FK: Repair Powder (outside hidden cave)", "Repair Powder x4", @@ -1255,7 +1245,7 @@ def __init__( DS3LocationData("FK: Homeward Bone (right island, behind fire)", "Homeward Bone x2"), DS3LocationData("FK: Titanite Shard (Farron Keep bonfire, left after exit)", "Titanite Shard"), - DS3LocationData("FK: Large Soul of a Nameless Soldier (between right island and pillar)", + DS3LocationData("FK: Large Soul of a Nameless Soldier (corner of keep and right island)", "Large Soul of a Nameless Soldier", hidden = True), # Tricky corner to spot DS3LocationData("FK: Prism Stone (by left island stairs)", "Prism Stone x10"), DS3LocationData("FK: Large Soul of a Nameless Soldier (near wall by right island)", @@ -1285,17 +1275,17 @@ def __init__( DS3LocationData("FK: Crown of Dusk (by white tree)", "Crown of Dusk"), DS3LocationData("FK: Lingering Dragoncrest Ring (by white tree, miniboss drop)", "Lingering Dragoncrest Ring", miniboss = True), # Great Crab drop - DS3LocationData("FK: Pharis's Hat (mob drop, around item in corner by keep ruins)", - "Pharis's Hat", drop = True, hidden = True), - DS3LocationData("FK: Black Bow of Pharis (mob drop, around item in corner by keep ruins)", - "Black Bow of Pharis", drop = True, hidden = True), + DS3LocationData("FK: Pharis's Hat (miniboss drop, by keep ruins near wall)", + "Pharis's Hat", miniboss = True), # Elder Ghru drop + DS3LocationData("FK: Black Bow of Pharis (miniboss drop, by keep ruins near wall)", + "Black Bow of Pharis", miniboss = True), # Elder Ghru drop DS3LocationData("FK: Titanite Scale (perimeter, miniboss drop)", "Titanite Scale x2", miniboss = True), # Ravenous Crystal Lizard drop - DS3LocationData("FK: Large Titanite Shard (upper keep, lizard #1)", "Large Titanite Shard", - lizard = True), - DS3LocationData("FK: Large Titanite Shard (upper keep, lizard #2)", "Large Titanite Shard", - lizard = True), - DS3LocationData("FK: Heavy Gem (uper keep, lizard on stairs)", "Heavy Gem", lizard = True), + DS3LocationData("FK: Large Titanite Shard (upper keep, lizard in open)", + "Large Titanite Shard", lizard = True), + DS3LocationData("FK: Large Titanite Shard (upper keep, lizard by wyvern)", + "Large Titanite Shard", lizard = True), + DS3LocationData("FK: Heavy Gem (upper keep, lizard on stairs)", "Heavy Gem", lizard = True), DS3LocationData("FK: Twinkling Titanite (keep proper, lizard)", "Twinkling Titanite", lizard = True), DS3LocationData("FK: Soul of a Stray Demon (upper keep, miniboss drop)", @@ -1390,8 +1380,8 @@ def __init__( DS3LocationData("CC: Twinkling Titanite (atrium lower, lizard down more stairs)", "Twinkling Titanite", lizard = True), DS3LocationData("CC: Fire Gem (cavern, lizard)", "Fire Gem", lizard = True), - DS3LocationData("CC: Homeward Bone (Irithyll bridge)", "Homeward Bone"), - DS3LocationData("CC: Pontiff's Right Eye (Irithyll bridge, miniboss drop)", + DS3LocationData("CC: Homeward Bone (bridge)", "Homeward Bone"), + DS3LocationData("CC: Pontiff's Right Eye (bridge, miniboss drop)", "Pontiff's Right Eye", miniboss = True), # Sulyvahn's Beast drop # Shrine Handmaid after killing High Lord Wolnir @@ -1544,7 +1534,7 @@ def __init__( "Large Titanite Shard"), DS3LocationData("IBV: Large Titanite Shard (plaza, by stairs to church)", "Large Titanite Shard"), - DS3LocationData("IBV: Soul of a Weary Warrior (plaza, side room #1)", + DS3LocationData("IBV: Soul of a Weary Warrior (plaza, side room lower)", "Soul of a Weary Warrior"), DS3LocationData("IBV: Magic Clutch Ring (plaza, illusory wall)", "Magic Clutch Ring", hidden = True), # Behind illusory wall @@ -1582,7 +1572,7 @@ def __init__( DS3LocationData("IBV: Lightning Gem (plaza center)", "Lightning Gem"), DS3LocationData("IBV: Large Soul of a Nameless Soldier (central, by second fountain)", "Large Soul of a Nameless Soldier"), - DS3LocationData("IBV: Soul of a Weary Warrior (plaza, side room #2)", + DS3LocationData("IBV: Soul of a Weary Warrior (plaza, side room upper)", "Soul of a Weary Warrior"), DS3LocationData("IBV: Proof of a Concord Kept (Church of Yorshka altar)", "Proof of a Concord Kept"), @@ -1685,7 +1675,7 @@ def __init__( "Soul of a Weary Warrior"), DS3LocationData("ID: Dung Pie (B3, by path from pit)", "Dung Pie x4"), DS3LocationData("ID: Ember (B3 center)", "Ember"), - DS3LocationData("ID: Ember (B3 near, by exit)", "Ember"), + DS3LocationData("ID: Ember (B3 far right)", "Ember"), DS3LocationData("ID: Profaned Coal (B3 far, left cell)", "Profaned Coal"), DS3LocationData("ID: Large Titanite Shard (B3 near, right corner)", "Large Titanite Shard"), DS3LocationData("ID: Old Sorcerer Hat (B2 near, middle cell)", "Old Sorcerer Hat"), @@ -1898,10 +1888,11 @@ def __init__( DS3LocationData("AL: Aldrich Faithful (water reserves, talk to McDonnel)", "Aldrich Faithful", hidden = True), # Behind illusory wall - DS3LocationData("FS: Budding Green Blossom (shop after Sirris kills Aldrich)", + DS3LocationData("FS: Budding Green Blossom (shop killing Creighton and AL boss)", "Budding Green Blossom", offline = '99,0:-1:110000,70000118:', missable = True, npc = True, - shop = True), # sold by Shrine Maiden after helping Sirris defeat Aldrich + shop = True), # sold by Shrine Maiden after killing Aldrich and helping + # Sirris defeat Creighton # Sirris (quest completion) DS3LocationData("FS: Sunset Shield (by grave after killing Hodrick w/Sirris)", @@ -2156,7 +2147,9 @@ def __init__( offline = "09,0:50002040::", prominent = True, progression = True, boss = True), DS3LocationData("GA: Onikiri and Ubadachi (outside 5F, NPC drop)", "Onikiri and Ubadachi", - hostile_npc = True), # Black Hand Kamui drop + hostile_npc = True, # Black Hand Kamui drop + missable = True), # This is placed at the location the NPC gets randomized + # to, which makes it hard to include in logic. DS3LocationData("GA: Golden Wing Crest Shield (outside 5F, NPC drop)", "Golden Wing Crest Shield", hostile_npc = True), # Lion Knight Albert drop @@ -2512,7 +2505,7 @@ def __init__( hidden = True), # Hidden behind a tower DS3LocationData("PW1: Captain's Ashes (snowfield tower, 6F)", "Captain's Ashes", progression = True), - DS3LocationData("PW1: Black Firebomb (snowfield lower, path to bridge)", + DS3LocationData("PW1: Black Firebomb (snowfield lower, path to bonfire)", "Black Firebomb x2"), DS3LocationData("PW1: Shriving Stone (below bridge near)", "Shriving Stone"), DS3LocationData("PW1: Millwood Greatarrow (snowfield village, loop back to lower)", @@ -2567,7 +2560,7 @@ def __init__( DS3LocationData("PW1: Large Soul of an Unknown Traveler (snowfield lower, by cliff)", "Large Soul of an Unknown Traveler"), DS3LocationData("PW1: Ember (settlement, building near bonfire)", "Ember"), - DS3LocationData("PW1: Frozen Weapon (snowfield lower, path to bonfire)", "Frozen Weapon"), + DS3LocationData("PW1: Frozen Weapon (snowfield lower, egg zone)", "Frozen Weapon"), DS3LocationData("PW1: Titanite Slab (depths, up secret ladder)", "Titanite Slab", offline = '11,0:50004700::', hidden = True), # Must kill normal-looking Tree Woman @@ -2841,7 +2834,7 @@ def __init__( "White Preacher Head"), DS3LocationData("RC: Titanite Scale (swamp far, by miniboss)", "Titanite Scale"), DS3LocationData("RC: Titanite Scale (upper cliff, path under bridge)", "Titanite Scale"), - DS3LocationData("RC: Dragonhead Greatshield (upper cluff, under bridge)", + DS3LocationData("RC: Dragonhead Greatshield (upper cliff, under bridge)", "Dragonhead Greatshield"), DS3LocationData("RC: Titanite Scale (upper cliff, first alcove)", "Titanite Scale x2"), DS3LocationData("RC: Rubbish (upper cliff, middle)", "Rubbish"), diff --git a/worlds/dark_souls_3/docs/locations_en.md b/worlds/dark_souls_3/docs/locations_en.md index bf4f3865558d..529a9abb8e7b 100644 --- a/worlds/dark_souls_3/docs/locations_en.md +++ b/worlds/dark_souls_3/docs/locations_en.md @@ -78,12 +78,18 @@ General notes: ### Undead Settlement +* **Foot:** The area where you first appear, around the Foot of the High Wall + bonfire. + * **Burning tree:** The tree near the beginning of the region, with the Cathedral Evangelist in front of it in vanilla. * **Hanging corpse room:** The dark room to the left of the burning tree with many hanging corpses inside, on the way to the Dilapidated Bridge bonfire. +* **Back alley:** The path between buildings leading to the Dilapidated Bridge + bonfire. + * **Stable:** The building complex across the bridge to the right of the burning tree. @@ -169,8 +175,10 @@ region. * **Hidden cave:** A small cave in the far corner of the map, closest to the right island. Near a bunch of basilisks in vanilla. -* **Keep ruins:** The two islands with the Keep Ruins bonfire (bonfire island) - and one of the three ritual fires (ritual island). +* **Keep ruins:** The following two islands: + + * "Bonfire island": The island with the Keep Ruins bonfire. + * "Ritual island": The island with one of the three ritual fires. * **White tree**: The birch tree by the ramp down from the keep ruins bonfire island, where the giant shoots arrows if he's still alive. @@ -791,7 +799,7 @@ offline _Dark Souls III_ randomizer]. CC: Fire Gem (cavern, lizard)Dropped by a Crystal Lizard found between the Catacombs main halls and the ledge overlooking the bridge you can cut down CC: Grave Warden Pyromancy Tome (boss arena)In Wolnir's arena, or in the back left of the room containing his bonfire if not picked up in the arena CC: Grave Warden's Ashes (crypt across, corner)From the Catacombs bonfire, down the stairs into the main hall and up the stairs to the other side, on the far left side. Stairwell past the illusory wall is most direct. -CC: Homeward Bone (Irithyll bridge)Found right before the wall blocking access to Irithyll +CC: Homeward Bone (bridge)Found right before the wall blocking access to Irithyll CC: Large Soul of a Nameless Soldier (cavern, before bridge)In the area where many many skeletons are before the bridge you can cut CC: Large Soul of a Nameless Soldier (tomb lower)Down the ramp from the Fire Demon, where all the skeletons are CC: Large Soul of an Unknown Traveler (crypt upper, hall middle)Going right from the Catacombs bonfire, then down the long hallway after the hallway to the left @@ -799,7 +807,7 @@ offline _Dark Souls III_ randomizer]. CC: Large Titanite Shard (crypt upper, skeleton ball hall)Going right from the Catacombs bonfire, to the end of the hallway where second Skeleton Ball rolls CC: Large Titanite Shard (tomb lower)Down the ramp from the Fire Demon, where all the skeletons are CC: Old Sage's Blindfold (tomb, hall before bonfire)Down the ramp from the Fire Demon, straight down the hallway past the room with the Abandoned Tomb bonfire -CC: Pontiff's Right Eye (Irithyll bridge, miniboss drop)Dropped by killing Sulyvahn's Beast on the bridge to Irithyll or in the lake below +CC: Pontiff's Right Eye (bridge, miniboss drop)Dropped by killing Sulyvahn's Beast on the bridge to Irithyll or in the lake below CC: Ring of Steel Protection+2 (atrium upper, drop onto pillar)From the first bridge in Catacombs where the first skeletons are encountered, parallel to the long stairwell, walk off onto a pillar on the left side. CC: Sharp Gem (atrium lower, right before exit)Down the hallway to the right before going down the main stairwell in the Catacombs CC: Soul of High Lord WolnirDropped by High Lord Wolnir @@ -835,7 +843,6 @@ offline _Dark Souls III_ randomizer]. CD: Drang Shoes (main hall east)In the Giant Slave muck pit leading up to Deacons CD: Duel Charm (by first elevator)After opening the cathedral's backdoor, where the Deacon enemies are first seen, under a fountain that spouts poison CD: Duel Charm (next to Patches in onion armor)To the right of the bridge leading to Rosaria, from the Deacons side. Patches will lower the bridge if you try to cross from this side. -CD: Dung Pie (main hall, miniboss drop)Dropped by either Giant Slave CD: Ember (Patches)Sold by Patches in Firelink Shrine CD: Ember (by back door)Past the pair of Grave Wardens and the Cathedral backdoor against a wall, guarded by a greataxe-wielding Large Hollow Soldier CD: Ember (edge of platform before boss)On the edge of the chapel before Deacons overlooking the Giant Slaves @@ -861,7 +868,6 @@ offline _Dark Souls III_ randomizer]. CD: Large Soul of an Unknown Traveler (main hall east)In the Giant Slave muck pit leading up to Deacons CD: Large Soul of an Unknown Traveler (main hall south, side path)Down a side path with poison-spouting fountains in the main cathedral room, accessible from the Cleansing Chapel shortcut, patrolled by a Cathedral Knight CD: Large Soul of an Unknown Traveler (path, against outer wall)From the Cathedral of the Deep bonfire after the Brigand, against the wall in the area with the dogs and crossbowmen -CD: Large Titanite Shard (main hall, miniboss drop)Dropped by either Giant Slave CD: Leggings of Thorns (Rosaria's Bed Chamber after killing Kirk)Found in Rosaria's Bed Chamber after killing Longfinger Kirk CD: Lloyd's Sword Ring (ledge above main hall south)On the ledge where the Giant Slave slams his arms down CD: Maiden Gloves (main hall south)In the muck pit with the Giant Slave that can attack with his arms @@ -974,7 +980,7 @@ offline _Dark Souls III_ randomizer]. DH: Ring of Steel Protection+3 (ledge before church)After the dropdown where an angel first targets you, on an exposed edge to the left. Difficult to get without killing the angel. DH: Rusted Coin (behind fountain after church)After exiting the building with the Lothric Knights where the front crumbles, behind the fountain on the right side. DH: Rusted Gold Coin (shop)Sold by Stone-humped Hag, or in her ashes -DH: Siegbräu (Lapp)Given by Lapp after collecting the Titanite Slab in Earthen Peak Ruins, or left after Demon Princes fight, or dropped upon death if not given. +DH: Siegbräu (Lapp)Given by Lapp after collecting the Titanite Slab in Earthen Peak Ruins, or left after Demon Princes fight, or dropped upon death if not given. DH: Small Envoy Banner (boss drop)Found in the small room after beating Demon Prince. DH: Soul of a Crestfallen Knight (church, altar)In the building where the front crumbles, guarded by the two Lothric Knights at the front of the chapel. DH: Soul of a Weary Warrior (castle overhang)The bait item at the start of the area which falls down with you into the ruined building below. @@ -1001,7 +1007,7 @@ offline _Dark Souls III_ randomizer]. FK: Antiquated Gloves (hidden cave)In a chest in the cave found along the keep wall in the basilisk area, with the Elizabeth corpse FK: Antiquated Skirt (hidden cave)In a chest in the cave found along the keep wall in the basilisk area, with the Elizabeth corpse FK: Atonement (perimeter, drop down into swamp)Dropping down from the Farron Keep Perimeter building, to the right past the bonfire, before the stairs going up -FK: Black Bow of Pharis (mob drop, around item in corner by keep ruins)Dropped the Elder Ghru on the left side of the group of three to the left of the Keep Ruins bonfire, as approached from the ritual fire. +FK: Black Bow of Pharis (miniboss drop, by keep ruins near wall)Dropped the Elder Ghru on the left side of the group of three to the left of the Keep Ruins bonfire, as approached from the ritual fire. FK: Black Bug Pellet (perimeter, hill by boss door)On the small hill to the right of the Abyss Watchers entrance, guarded by a spear-wielding Ghru Grunt FK: Cinders of a Lord - Abyss WatcherDropped by Abyss Watchers FK: Crown of Dusk (by white tree)Near the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows @@ -1022,24 +1028,24 @@ offline _Dark Souls III_ randomizer]. FK: Havel's Gauntlets (upper keep, after killing AP belfry roof NPC)Appears by Stray Demon, up from the Old Wolf of Farron bonfire, after the Havel Knight guarding the Titanite Slab in Archdragon Peak has been killed FK: Havel's Helm (upper keep, after killing AP belfry roof NPC)Appears by Stray Demon, up from the Old Wolf of Farron bonfire, after the Havel Knight guarding the Titanite Slab in Archdragon Peak has been killed FK: Havel's Leggings (upper keep, after killing AP belfry roof NPC)Appears by Stray Demon, up from the Old Wolf of Farron bonfire, after the Havel Knight guarding the Titanite Slab in Archdragon Peak has been killed -FK: Heavy Gem (uper keep, lizard on stairs)Dropped by the Crystal Lizard that scurries up the stairs in the area dropping down from near Stray Demon, up from Old Wolf of Farron bonfire +FK: Heavy Gem (upper keep, lizard on stairs)Dropped by the Crystal Lizard that scurries up the stairs in the area dropping down from near Stray Demon, up from Old Wolf of Farron bonfire FK: Hollow Gem (perimeter, drop down into swamp)Dropping down from the Farron Keep Perimeter building, to the right past the bonfire, before the stairs going up FK: Homeward Bone (right island, behind fire)Behind the ritual fire with stairs guarded by Elder Ghrus/basilisks FK: Iron Flesh (Farron Keep bonfire, right after exit)In the open in the swamp, heading straight right from Farron Keep bonfire -FK: Large Soul of a Nameless Soldier (between right island and pillar)Hidden in a corner to the right of the stairs leading up to the ritual fire from the basilisk area +FK: Large Soul of a Nameless Soldier (corner of keep and right island)Hidden in a corner to the right of the stairs leading up to the ritual fire from the basilisk area FK: Large Soul of a Nameless Soldier (near wall by right island)To the left of the stairs leading up to the ritual fire from the Basilisk area, by the keep wall FK: Large Soul of an Unknown Traveler (by white tree)On a tree close to the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows -FK: Large Titanite Shard (upper keep, lizard #1)Dropped by the closer Crystal Lizard in the area dropping down from near Stray Demon, up from Old Wolf of Farron bonfire -FK: Large Titanite Shard (upper keep, lizard #2)Dropped by the farther Crystal Lizard in the area dropping down from near Stray Demon, up from Old Wolf of Farron bonfire +FK: Large Titanite Shard (upper keep, lizard by wyvern)Dropped by the farther Crystal Lizard in the area dropping down from near Stray Demon, up from Old Wolf of Farron bonfire +FK: Large Titanite Shard (upper keep, lizard in open)Dropped by the closer Crystal Lizard in the area dropping down from near Stray Demon, up from Old Wolf of Farron bonfire FK: Lightning Spear (upper keep, far side of the wall)Up the elevator from Old Wolf of Farron bonfire, and dropping down to Crystal Lizard area, in the open. FK: Lingering Dragoncrest Ring (by white tree, miniboss drop)Dropped by the Greater Crab patrolling the birch tree where the Giant shoots arrows FK: Magic Stoneplate Ring+1 (between right island and wall)Behind a tree in the basilisk area, heading directly right from Farron Keep bonfire FK: Manikin Claws (Londor Pale Shade drop)Dropped by Londor Pale Shade when he invades near the basilisks, if Yoel or Yuria have been betrayed -FK: Nameless Knight Armor (next to pillar by right island)From the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill -FK: Nameless Knight Gauntlets (next to pillar by right island)From the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill -FK: Nameless Knight Helm (next to pillar by right island)From the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill -FK: Nameless Knight Leggings (next to pillar by right island)From the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill -FK: Pharis's Hat (mob drop, around item in corner by keep ruins)Dropped the Elder Ghru in the back of the group of three to the left of the Keep Ruins bonfire, as approached from the ritual fire. +FK: Nameless Knight Armor (corner of keep and right island)From the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill +FK: Nameless Knight Gauntlets (corner of keep and right island)From the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill +FK: Nameless Knight Helm (corner of keep and right island)From the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill +FK: Nameless Knight Leggings (corner of keep and right island)From the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill +FK: Pharis's Hat (miniboss drop, by keep ruins near wall)Dropped the Elder Ghru in the back of the group of three to the left of the Keep Ruins bonfire, as approached from the ritual fire. FK: Poison Gem (near wall by keep ruins bridge)From the left of the bridge leading from the ritual fire to the Keep Ruins bonfire, guarded by the three Elder Ghru FK: Prism Stone (by left island stairs)On an island to the left of the stairs leading up to the ritual fire straight ahead of the Farron Keep bonfire FK: Purple Moss Clump (Farron Keep bonfire, around right corner)Along the inner wall of the keep, making an immediate right from Farron Keep bonfire @@ -1096,7 +1102,7 @@ offline _Dark Souls III_ randomizer]. FS: Bountiful Light (Irina for Tome of Lothric)Sold by Irina after giving her the Braille Divine Tome of Lothric FS: Bountiful Sunlight (Ludleth for Rosaria)Boss weapon for Rosaria, available after Leonhard is killed FS: Broken Straight Sword (gravestone after boss)Near the grave after Iudex Gundyr fight -FS: Budding Green Blossom (shop after Sirris kills Aldrich)Sold by Handmaid after receiving Silvercat Ring item lot from Sirris and defeating Aldrich +FS: Budding Green Blossom (shop killing Creighton and AL boss)Sold by Handmaid after receiving Silvercat Ring item lot from Sirris and defeating Aldrich FS: Bursting Fireball (Cornyx for Great Swamp Tome)Sold by Cornyx after giving him the Great Swamp Pyromancy Tome FS: Caressing Tears (Irina)Sold by Irina after recruiting her, or in her ashes FS: Carthus Beacon (Cornyx for Carthus Tome)Sold by Cornyx after giving him the Carthus Pyromancy Tome @@ -1342,10 +1348,10 @@ offline _Dark Souls III_ randomizer]. FS: Yhorm's Great Machete (Ludleth for Yhorm)Boss weapon for Yhorm the Giant FS: Yhorm's Greatshield (Ludleth for Yhorm)Boss weapon for Yhorm the Giant FS: Young Dragon Ring (Orbeck for one scroll and buying three spells)Given by Orbeck after purchasing four sorceries from him, and giving him one scroll, as a non-sorcerer. -FSBT: Armor of the Sun (crow for Siegbräu)Trade Siegbrau with crow +FSBT: Armor of the Sun (crow for Siegbräu)Trade Siegbrau with crow FSBT: Blessed Gem (crow for Moaning Shield)Trade Moaning Shield with crow FSBT: Covetous Silver Serpent Ring (illusory wall past rafters)From the Firelink Shrine roof, past the rafters and an illusory wall -FSBT: Estus Ring (rafters)Dropping down from the Bell Tower to where Irina eventually resides +FSBT: Estus Ring (tower base)Dropping down from the Bell Tower to where Irina eventually resides FSBT: Estus Shard (rafters)In the Firelink Shrine rafters, accessible from the roof FSBT: Fire Keeper Gloves (partway down tower)Dropping down to the left after entering the Bell Tower. Align with the center of the closest floor tile row and run off the edge at full speed, aiming slightly left. FSBT: Fire Keeper Robe (partway down tower)Dropping down to the left after entering the Bell Tower. Align with the center of the closest floor tile row and run off the edge at full speed, aiming slightly left. @@ -1451,16 +1457,16 @@ offline _Dark Souls III_ randomizer]. HWL: Battle Axe (flame tower, mimic)Dropped by mimic in the building guarded by the fire-breathing wyvern HWL: Binoculars (corpse tower, upper platform)In the area with the dead wyvern, at the top of a set of stairs past a Hollow Soldier HWL: Black Firebomb (small roof over fountain)After roof with Pus of Man, on the edge of another rooftop to the left where you can drop down into Winged Knight area -HWL: Broadsword (fort, room off entry)In the building with the Pus of Man on the roof, past the Lothric Knight in an alcove to the left -HWL: Cell Key (fort basement, down stairs)In the basement of the building with Pus of Man on the roof, down the stairs guarded by a dog +HWL: Broadsword (fort, room off walkway)In the building with the Pus of Man on the roof, past the Lothric Knight in an alcove to the left +HWL: Cell Key (fort ground, down stairs)In the basement of the building with Pus of Man on the roof, down the stairs guarded by a dog HWL: Claymore (flame plaza)In the area where the wyvern breathes fire, farthest away from the door HWL: Club (flame plaza)In the area where the wyvern breathes fire, in the open -HWL: Ember (back tower roof bonfire, transforming hollow)Dropped by the Pus of Man on the tower to the right of the High Wall bonfire after transformation +HWL: Ember (back tower, transforming hollow)Dropped by the Pus of Man on the tower to the right of the High Wall bonfire after transformation HWL: Ember (flame plaza)In the area where the wyvern breathes fire, in the open HWL: Ember (fort roof, transforming hollow)Dropped by the Pus of Man on the roof after the Tower on the Wall bonfire after transformation HWL: Ember (fountain #1)In the area with the Winged Knight -HWL: Ember (fountain, #2)In the area with the Winged Knight -HWL: Estus Shard (fort basement, on anvil)In the basement of the building with the Pus of Man on the roof, on the blacksmith anvil +HWL: Ember (fountain #2)In the area with the Winged Knight +HWL: Estus Shard (fort ground, on anvil)In the basement of the building with the Pus of Man on the roof, on the blacksmith anvil HWL: Firebomb (corpse tower, under table)In the building near the dead wyvern, behind a table near the ladder you descend HWL: Firebomb (fort roof)Next to the Pus of Man on the roof HWL: Firebomb (top of ladder to fountain)By the long ladder leading down to the area with the Winged Knight @@ -1468,7 +1474,7 @@ offline _Dark Souls III_ randomizer]. HWL: Fleshbite Ring+1 (fort roof, jump to other roof)Jumping from the roof with the Pus of Man to a nearby building with a fenced roof HWL: Gold Pine Resin (corpse tower, drop)Dropping past the dead wyvern, down the left path from the High Wall bonfire HWL: Green Blossom (fort walkway, hall behind wheel)In the building with the Pus of Man on the roof, past the Lothric Knight down a hallway obscured by a wooden wheel -HWL: Green Blossom (shortcut, by lower lift door)In the courtyard at the bottom of the shortcut elevator +HWL: Green Blossom (shortcut, lower courtyard)In the courtyard at the bottom of the shortcut elevator HWL: Large Soul of a Deserted Corpse (flame plaza)In the area where the wyvern breathes fire, behind one of the praying statues HWL: Large Soul of a Deserted Corpse (fort roof)On the edge of the roof with the Pus of Man HWL: Large Soul of a Deserted Corpse (platform by fountain)Coming from the elevator shortcut, on a side path to the left (toward Winged Knight area) @@ -1480,7 +1486,7 @@ offline _Dark Souls III_ randomizer]. HWL: Red Eye Orb (wall tower, miniboss)Dropped by the Darkwraith past the Lift Chamber Key HWL: Refined Gem (promenade miniboss)Dropped by the red-eyed Lothric Knight to the left of the Dancer's room entrance HWL: Ring of Sacrifice (awning by fountain)Coming from the elevator shortcut, on a side path to the left (toward Winged Knight area), jumping onto a wooden support -HWL: Ring of the Evil Eye+2 (fort basement, far wall)In the basement of the building with the Pus of Man on the roof, on the far wall past the stairwell, behind some barrels +HWL: Ring of the Evil Eye+2 (fort ground, far wall)In the basement of the building with the Pus of Man on the roof, on the far wall past the stairwell, behind some barrels HWL: Silver Eagle Kite Shield (fort mezzanine)In the chest on the balcony overlooking the basement of the building with the Pus of Man on the roof HWL: Small Lothric Banner (Emma)Given by Emma, or dropped upon death HWL: Soul of Boreal Valley VordtDropped by Vordt of the Boreal Valley @@ -1495,10 +1501,10 @@ offline _Dark Souls III_ randomizer]. HWL: Standard Arrow (back tower)Down the path from the right of the High Wall bonfire, where the Pus of Man and crossbowman are HWL: Throwing Knife (shortcut, lift top)At the top of the elevator shortcut, opposite from the one-way door HWL: Throwing Knife (wall tower, path to Greirat)In the basement of the building with the Tower on the Wall bonfire, in the room with the explosive barrels -HWL: Titanite Shard (back tower roof bonfire, transforming hollow)Dropped by the Pus of Man on the tower to the right of the High Wall bonfire after transformation -HWL: Titanite Shard (for, room off entry)In the building with the Pus of Man on the roof, in a room to the left and up the short stairs -HWL: Titanite Shard (fort basement, behind crates)Behind some wooden crates in the basement of the building with the Pus of Man on the roof +HWL: Titanite Shard (back tower, transforming hollow)Dropped by the Pus of Man on the tower to the right of the High Wall bonfire after transformation +HWL: Titanite Shard (fort ground behind crates)Behind some wooden crates in the basement of the building with the Pus of Man on the roof HWL: Titanite Shard (fort roof, transforming hollow)Dropped by the Pus of Man on the roof after the Tower on the Wall bonfire after transformation +HWL: Titanite Shard (fort, room off entry)In the building with the Pus of Man on the roof, in a room to the left and up the short stairs HWL: Titanite Shard (wall tower, corner by bonfire)On the balcony with the Tower on the Wall bonfire HWL: Undead Hunter Charm (fort, room off entry, in pot)In the building with the Pus of Man on the roof, in a room to the left, in a pot you have to break HWL: Way of Blue (Emma)Given by Emma or dropped upon death. @@ -1555,14 +1561,14 @@ offline _Dark Souls III_ randomizer]. IBV: Rusted Gold Coin (Distant Manor, down stairs)Dropping down after the first set of stairs leading from Distant Manor bonfire IBV: Rusted Gold Coin (descent, side path)Down the stairs from the graveyard after Church of Yorshka, guarded by the group of dogs in the left path IBV: Shriving Stone (descent, dark room rafters)On the rafters in the dark area with the Irithyllian slaves -IBV: Siegbräu (Siegward)Given by Siegward meeting him in the Irithyll kitchen after the Sewer Centipedes. +IBV: Siegbräu (Siegward)Given by Siegward meeting him in the Irithyll kitchen after the Sewer Centipedes. IBV: Smough's Great Hammer (great hall, chest)In a chest up the stairs in the room with the Silver Knight staring at the painting IBV: Soul of Pontiff SulyvahnDropped by Pontiff Sulyvahn IBV: Soul of a Weary Warrior (ascent, by final staircase)Toward the end of the path from the sewer leading up to Pontiff's cathedral, to the left of the final staircase IBV: Soul of a Weary Warrior (central, by first fountain)By the Central Irithyll bonfire IBV: Soul of a Weary Warrior (central, railing by first fountain)On the railing overlooking the Central Irithyll bonfire, at the very start -IBV: Soul of a Weary Warrior (plaza, side room #1)Dropping down from the path from Church of Yorshka to Pontiff, guarded by the pensive Fire Witch -IBV: Soul of a Weary Warrior (plaza, side room #2)In the path from Church of Yorshka to Pontiff's cathedral, at the broken ledge you can drop down onto the Fire Witch +IBV: Soul of a Weary Warrior (plaza, side room lower)Dropping down from the path from Church of Yorshka to Pontiff, guarded by the pensive Fire Witch +IBV: Soul of a Weary Warrior (plaza, side room upper)In the path from Church of Yorshka to Pontiff's cathedral, at the broken ledge you can drop down onto the Fire Witch IBV: Twinkling Titanite (central, lizard before plaza)Dropped by a Crystal Lizard past the Central Irithyll Fire Witches and to the left IBV: Twinkling Titanite (descent, lizard behind illusory wall)Dropped by a Crystal Lizard behind an illusory wall before going down the stairs to the lake leading to the Distant Manor bonfire IBV: Undead Bone Shard (descent, behind gravestone)In the graveyard down the stairs from the Church of Yorshka, behind the grave with the Corvian @@ -1583,7 +1589,7 @@ offline _Dark Souls III_ randomizer]. ID: Dung Pie (pit, miniboss drop)Drop from the Giant Slave ID: Dusk Crown Ring (B3 far, right cell)In the cell in the main Jailer cell block to the left of the Profaned Capital exit ID: Ember (B3 center)At the center pillar in the main Jailer cell block -ID: Ember (B3 near, by exit)In the main Jailer cell block, on the left side coming from the Profaned Capital +ID: Ember (B3 far right)In the main Jailer cell block, on the left side coming from the Profaned Capital ID: Estus Shard (mimic on path from B2 to pit)Dropped by the mimic in the room after the outside area of Irithyll Dungeon overlooking Profaned Capital ID: Fading Soul (B1 near, main hall)On the top corridor on the bonfire side in Irithyll Dungeon, close to the first Jailer ID: Great Magic Shield (B2 near, mob drop in far left cell)One-time drop from the Infested Corpse in the bottom corridor on the bonfire side of Irithyll Dungeon, in the closest cell @@ -1722,14 +1728,14 @@ offline _Dark Souls III_ randomizer]. PC: Rusted Gold Coin (halls above swamp)In the corridors leading to the Profaned Capital toxic pool PC: Rusted Gold Coin (palace, mimic in far room)Dropped by the right mimic surrounded by the Jailers to the right of the Profaned Flame PC: Shriving Stone (swamp, by chapel door)At the far end of the Profaned Capital toxic pool, to the left of the door leading to the Monstrosities of Sin -PC: Siegbräu (Siegward after killing boss)Given by Siegward after helping him defeat Yhorm the Giant. You must talk to him before Emma teleports you. +PC: Siegbräu (Siegward after killing boss)Given by Siegward after helping him defeat Yhorm the Giant. You must talk to him before Emma teleports you. PC: Soul of Yhorm the GiantDropped by Yhorm the Giant PC: Storm Ruler (Siegward)Dropped by Siegward upon death or quest completion. PC: Storm Ruler (boss room)To the right of Yhorm's throne PC: Twinkling Titanite (halls above swamp, lizard #1)Dropped by the second Crystal Lizard in the corridors before the Profaned Capital toxic pool PC: Undead Bone Shard (by bonfire)On the corpse of Laddersmith Gilligan next to the Profaned Capital bonfire PC: Wrath of the Gods (chapel, drop from roof)Dropping down from the roof of the Monstrosity of Sin building where the Court Sorcerer is -PW1: Black Firebomb (snowfield lower, path to bridge)Dropping down after the first snow overhang and following the wall on the left, past the rotting bed descending toward the second bonfire +PW1: Black Firebomb (snowfield lower, path to bonfire)Dropping down after the first snow overhang and following the wall on the left, past the rotting bed descending toward the second bonfire PW1: Blessed Gem (snowfield, behind tower)Behind the Millwood Knight tower in the first area, approach from the right side PW1: Budding Green Blossom (settlement courtyard, ledge)After sliding down the slope on the way to Corvian Settlement, dropping down hugging the left wall PW1: Captain's Ashes (snowfield tower, 6F)At the very top of the Millwood Knight tower after climbing up the second ladder @@ -1745,7 +1751,7 @@ offline _Dark Souls III_ randomizer]. PW1: Ethereal Oak Shield (snowfield tower, 3F)In the Millwood Knight tower on a Millwood Knight corpse, after climbing the first ladder, then going down the staircase PW1: Follower Javelin (snowfield lower, path back up)Dropping down after the first snow overhang, follow the right wall around and up a slope, past the Followers PW1: Follower Sabre (roots above depths)On a tree branch after climbing down the rope bridge. Rather than hugging a right wall toward a Follower Javelin wielder, drop off to the left. -PW1: Frozen Weapon (snowfield lower, path to bonfire)Dropping down after the first snow overhang, in the rotting bed along the left side +PW1: Frozen Weapon (snowfield lower, egg zone)Dropping down after the first snow overhang, in the rotting bed along the left side PW1: Heavy Gem (snowfield village)Before the Millwood Knight tower, on the far side of one of the ruined walls targeted by the archer PW1: Hollow Gem (beside chapel)To the right of the entrance to the Ariandel PW1: Homeward Bone (depths, up hill)In the Depths of the Painting, up a hill next to the giant crabs. @@ -1838,7 +1844,7 @@ offline _Dark Souls III_ randomizer]. RC: Dark Gem (swamp near, by stairs)In the middle of the muck pit, close to the long stairs. RC: Divine Blessing (streets monument, mob drop)Dropped by the Judicator near the Purging Monument area. Requires solving "Show Your Humanity" puzzle. RC: Divine Blessing (wall top, mob drop)Dropped by the Judicator after the Mausoleum Lookup bonfire. -RC: Dragonhead Greatshield (upper cluff, under bridge)Down a slope to the right of the bridge where Midir first assaults you, past a sword-wielding Ringed Knight, under the bridge. +RC: Dragonhead Greatshield (upper cliff, under bridge)Down a slope to the right of the bridge where Midir first assaults you, past a sword-wielding Ringed Knight, under the bridge. RC: Dragonhead Shield (streets monument, across bridge)Found in Purging Monument area, across the bridge from the monument. Requires solving "Show Your Humanity" puzzle. RC: Ember (wall hidden, statue room)From the mid level of the Ringed Inner Wall elevator that leads to the Midir fight, in the room with the illusory statue. RC: Ember (wall top, by statue)Along the left wall of the courtyard after Mausoleum Lookout, in front of a tall monument. @@ -1888,7 +1894,7 @@ offline _Dark Souls III_ randomizer]. RC: Shira's Gloves (Shira's room after killing ashes NPC)Found in Shira's room in Ringed City after killing her in post-Filianore Ringed City. RC: Shira's Trousers (Shira's room after killing ashes NPC)Found in Shira's room in Ringed City after killing her in post-Filianore Ringed City. RC: Shriving Stone (wall tower, bottom floor center)In the cylindrical building before the long stairs with many Harald Legion Knights, in the center structure on the first floor. -RC: Siegbräu (Lapp)Given by Lapp within the Ringed Inner Wall. +RC: Siegbräu (Lapp)Given by Lapp within the Ringed Inner Wall. RC: Simple Gem (grave, up stairs after first drop)In Shared Grave, following the path after falling down from the crumbling stairs and continuing upward. RC: Soul of Darkeater MidirDropped by Darkeater Midir RC: Soul of Slave Knight GaelDropped by Slave Knight Gael @@ -1963,7 +1969,7 @@ offline _Dark Souls III_ randomizer]. RS: Great Swamp Pyromancy Tome (deep water)In the deep water part of the Crucifixion Woods crab area, between a large tree and the keep wall RS: Great Swamp Ring (miniboss drop, by Farron Keep)Dropped by Greater Crab in Crucifixion Woods close to the Farron Keep outer wall RS: Green Blossom (by deep water)In the Crucifixion Woods crab area out in the open, close to the edge of the deep water area -RS: Green Blossom (water by Crucifixion Woods bonfire)In the Crucifixion Woods crab area close to the Crucifixion Woods bonfire, along the left wall of the water area, to the right of the entrance to the building before Crystal Sage +RS: Green Blossom (water beneath stronghold)In the Crucifixion Woods crab area close to the Crucifixion Woods bonfire, along the left wall of the water area, to the right of the entrance to the building before Crystal Sage RS: Heretic's Staff (stronghold left room)In the building before Crystal Sage, entering from near Cruficixion Woods, in a corner under the first stairwell and balcony RS: Heysel Pick (Heysel drop)Dropped by Heysel when she invades in Road of Sacrifices RS: Homeward Bone (balcony by Farron Keep)At the far end of the building where you descend into Farron Keep, by the balcony @@ -2056,7 +2062,7 @@ offline _Dark Souls III_ randomizer]. UG: Wolf Knight Gauntlets (shop after killing FK boss)Sold by Untended Graves Handmaid after defeating Abyss Watchers UG: Wolf Knight Helm (shop after killing FK boss)Sold by Untended Graves Handmaid after defeating Abyss Watchers UG: Wolf Knight Leggings (shop after killing FK boss)Sold by Untended Graves Handmaid after defeating Abyss Watchers -US: Alluring Skull (Foot of the High Wall, behind carriage)Guarded by two dogs after the Foot of the High Wall bonfire +US: Alluring Skull (foot, behind carriage)Guarded by two dogs after the Foot of the High Wall bonfire US: Alluring Skull (on the way to tower, behind building)After the ravine bridge leading to Eygon and the Giant's tower, wrapping around the building to the right. US: Alluring Skull (tower village building, upstairs)Up the stairs of the building with Cage Spiders after the Fire Demon, before the dogs US: Bloodbite Ring (miniboss in sewer)Dropped by the large rat in the sewers with grave access @@ -2079,9 +2085,9 @@ offline _Dark Souls III_ randomizer]. US: Covetous Silver Serpent Ring+2 (tower village, drop down from roof)At the back of a roof near the end of the Fire Demon loop, dropping down past where Flynn's Ring is US: Ember (behind burning tree)Behind the burning tree with the Cathedral Evangelist US: Ember (bridge on the way to tower)On the ravine bridge leading toward Eygon and the Giant's tower -US: Ember (by miniboss before Road of Sacrifices)In the room with the Outrider Knight US: Ember (by stairs to boss)Next to the stairs leading up to Curse-Rotted Greatwood fight, near a tree guarded by a dog US: Ember (by white tree)Near the Birch Tree where giant shoots arrows +US: Ember (tower basement, miniboss)In the room with the Outrider Knight US: Estus Shard (under burning tree)In front of the burning tree guarded by the Cathedral Evangelist US: Fading Soul (by white tree)Near the Birch Tree where giant shoots arrows US: Fading Soul (outside stable)In the thrall area to the right of the bridge to the right of the burning tree with the Cathedral Evangelist @@ -2095,10 +2101,10 @@ offline _Dark Souls III_ randomizer]. US: Hawk Ring (Giant Archer)Dropped by Giant, either by killing him or collecting all of the birch tree items locations in the base game. US: Heavy Gem (Hawkwood)Given or dropped by Hawkwood after defeating Curse-Rotted Greatwood or Crystal Sage US: Heavy Gem (chasm, lizard)Drop by Crystal Lizard in ravine accessible by Grave Key or dropping down near Eygon. -US: Homeward Bone (by Yoel)In the thrall area across the bridge from the first Undead Settlement building, on a roof overlooking the ravine bridge. -US: Homeward Bone (stable roof)At the end of the loop from the Siegward Demon fight, after dropping down from the roof onto the tower with Chloranthy Ring, to the right of the tower entrance -US: Homeward Bone (tower village, jump from roof)Given by Holy Knight Hodrick before fighting Curse-Rotted Greatwood, or on his corpse in the Pit of Hollows. -US: Homeward Bone (tower village, right of first drop)Under Foot of the High Wall bonfire, around where Yoel can be first met +US: Homeward Bone (???)Given by Holy Knight Hodrick before fighting Curse-Rotted Greatwood, or on his corpse in the Pit of Hollows. +US: Homeward Bone (foot, drop overloop)Under Foot of the High Wall bonfire, around where Yoel can be first met +US: Homeward Bone (stable roof)In the thrall area across the bridge from the first Undead Settlement building, on a roof overlooking the ravine bridge. +US: Homeward Bone (tower village, jump from roof)At the end of the loop from the Siegward Demon fight, after dropping down from the roof onto the tower with Chloranthy Ring, to the right of the tower entrance US: Human Pine Resin (tower village building, chest upstairs)In a chest after Fire Demon. Cage Spiders activate open opening it. US: Irithyll Straight Sword (miniboss drop, by Road of Sacrifices)Dropped by the Boreal Outright Knight before Road of Sacrifices US: Kukri (hanging corpse above burning tree)Hanging corpse high above the burning tree with the Cathedral Evangelist. Must be shot down with an arrow or projective. @@ -2132,14 +2138,14 @@ offline _Dark Souls III_ randomizer]. US: Red and White Shield (chasm, hanging corpse)On a hanging corpse in the ravine accessible with the Grave Key or dropping down near Eygon, to the entrance of Irina's prison. Must be shot down with an arrow or projective. US: Reinforced Club (by white tree)Near the Birch Tree where giant shoots arrows US: Repair Powder (first building, balcony)On the balcony of the first Undead Settlement building -US: Rusted Coin (wooden ledge above Dilapidated Bridge)On a wooden ledge near the Dilapidated Bridge bonfire. Must be jumped to from near Cathedral Evangelist enemy +US: Rusted Coin (awning above Dilapidated Bridge)On a wooden ledge near the Dilapidated Bridge bonfire. Must be jumped to from near Cathedral Evangelist enemy US: Saint's Talisman (chasm, by ladder)From the ravine accessible via Grave Key or dropping near Eygon, before ladder leading up to Irina of Carim US: Sharp Gem (lizard by Dilapidated Bridge)Drop by Crystal Lizard near Dilapidated Bridge bonfire. -US: Siegbräu (Siegward)Given by Siegward after helping him defeat the Fire Demon. +US: Siegbräu (Siegward)Given by Siegward after helping him defeat the Fire Demon. US: Small Leather Shield (first building, hanging corpse by entrance)Hanging corpse in the first building, to the right of the entrance US: Soul of a Nameless Soldier (top of tower)At the top of the tower where Giant shoots arrows +US: Soul of an Unknown Traveler (back alley, past crates)After exiting the building after the burning tree on the way to the Dilapidated Bridge bonfire. Hidden behind some crates between two buildings on the right. US: Soul of an Unknown Traveler (chasm crypt)In the skeleton area accessible Grave Key or dropping down from near Eygon -US: Soul of an Unknown Traveler (on the way to Dilapidated Bridge, in crates)After exiting the building after the burning tree on the way to the Dilapidated Bridge bonfire. Hidden behind some crates between two buildings on the right. US: Soul of an Unknown Traveler (pillory past stable)In the area bombarded by firebombs above the Cliff Underside bonfire US: Soul of an Unknown Traveler (portcullis by burning tree)Behind a grate to the left of the burning tree and Cathedral Evangelist US: Soul of the Rotted GreatwoodDropped by Curse Rotted Greatwood @@ -2148,18 +2154,18 @@ offline _Dark Souls III_ randomizer]. US: Sunset Gauntlets (pit of hollows after killing Hodrick w/Sirris)Found in Pit of Hollows after completing Sirris' questline. US: Sunset Helm (Pit of Hollows after killing Hodrick w/Sirris)Found in Pit of Hollows after completing Sirris' questline. US: Sunset Leggings (pit of hollows after killing Hodrick w/Sirris)Found in Pit of Hollows after completing Sirris' questline. +US: Titanite Shard (back alley, side path)On a side path to the right of the Cathedral Evangelist before the Dilapidated Bridge bonfire +US: Titanite Shard (back alley, up ladder)Next to the Cathedral Evangelist close to the Dilapidated Bridge bonfire US: Titanite Shard (chasm #1)In the ravine accessible from Grave Key or dropping down from near Eygon US: Titanite Shard (chasm #2)In the ravine accessible from Grave Key or dropping down from near Eygon US: Titanite Shard (lower path to Cliff Underside)At the end of the cliffside path next to Cliff Underside bonfire, guarded by a Hollow Peasant wielding a four-pronged plow. -US: Titanite Shard (on the way to Dilapidated Bridge, up ladder)Next to the Cathedral Evangelist close to the Dilapidated Bridge bonfire US: Titanite Shard (porch after burning tree)In front of the building after the burning tree and Cathedral Evangelist -US: Titanite Shard (side path on the way to Dilapidated Bridge)On a side path to the right of the Cathedral Evangelist before the Dilapidated Bridge bonfire US: Tower Key (kill Irina)Dropped by Irina of Carim US: Transposing Kiln (boss drop)Dropped by Curse Rotted Greatwood US: Undead Bone Shard (by white tree)In the area past the Dilapidated Bridge bonfire, where the Giant is shooting arrows, jumping to the floating platform on the right US: Wargod Wooden Shield (Pit of Hollows)In the Pit of Hollows US: Warrior of Sunlight (hanging corpse room, drop through hole)Dropping through a hole in the floor in the first building after the burning tree. -US: Whip (on the way to Dilapidated Bridge, behind wooden wall)In one of the houses between building after the burning tree and the Dilapidated Bridge bonfire +US: Whip (back alley, behind wooden wall)In one of the houses between building after the burning tree and the Dilapidated Bridge bonfire US: Young White Branch (by white tree #1)Near the Birch Tree where giant shoots arrows US: Young White Branch (by white tree #2)Near the Birch Tree where giant shoots arrows From ceb92a6e3d16273f9e37026e71968a9810b0a14a Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 8 Jan 2024 16:23:40 -0800 Subject: [PATCH 119/238] Don't uniquify the wrong items --- worlds/dark_souls_3/Items.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 90347b60afe3..33c9237b51ee 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -151,7 +151,10 @@ class DS3ItemData(): @property def unique(self): """Whether this item should be unique, appearing only once in the randomizer.""" - return self.category != DS3ItemCategory.MISC or self.force_unique + return self.force_unique or self.category not in { + DS3ItemCategory.MISC, DS3ItemCategory.SOUL, DS3ItemCategory.UPGRADE, + DS3ItemCategory.HEALING, + } def __post_init__(self): self.ap_code = self.ap_code or DS3ItemData.__item_id From f415dc83e662132d6ded5b6671089f90b9005895 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 8 Jan 2024 18:16:19 -0800 Subject: [PATCH 120/238] Fix some more location issues --- worlds/dark_souls_3/Locations.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index c4f8c48ed4cb..efe31cb6d250 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1576,7 +1576,8 @@ def __init__( "Soul of a Weary Warrior"), DS3LocationData("IBV: Proof of a Concord Kept (Church of Yorshka altar)", "Proof of a Concord Kept"), - DS3LocationData("IBV: Rusted Gold Coin (Distant Manor, down stairs)", "Rusted Gold Coin"), + DS3LocationData("IBV: Rusted Gold Coin (Distant Manor, drop after stairs)", + "Rusted Gold Coin"), DS3LocationData("IBV: Chloranthy Ring+1 (plaza, behind altar)", "Chloranthy Ring+1", ngp = True), DS3LocationData("IBV: Covetous Gold Serpent Ring+1 (descent, drop after dark room)", @@ -1607,6 +1608,8 @@ def __init__( "Twinkling Titanite", lizard = True, hidden = True), # Behind illusory wall DS3LocationData("IBV: Twinkling Titanite (central, lizard before plaza)", "Twinkling Titanite", lizard = True), + DS3LocationData("IBV: Large Titanite Shard (Distant Manor, under overhang)", + "Large Titanite Shard"), DS3LocationData("IBV: Siegbräu (Siegward)", "Siegbräu", missable = True, npc = True), DS3LocationData("IBV: Emit Force (Siegward)", "Emit Force", missable = True, npc = True), DS3LocationData("IBV -> AL", None), @@ -1648,7 +1651,7 @@ def __init__( npc = True), DS3LocationData("ID: Murakumo (Alva drop)", "Murakumo", missable = True, hostile_npc = True), - DS3LocationData("ID: Large Titanite Shard (B1 near, just past bonfire)", + DS3LocationData("ID: Large Titanite Shard (B1 near, second cell on right)", "Large Titanite Shard"), DS3LocationData("ID: Fading Soul (B1 near, main hall)", "Fading Soul"), DS3LocationData("ID: Large Soul of a Nameless Soldier (B2, hall by stairs)", @@ -1688,12 +1691,14 @@ def __init__( DS3LocationData("ID: Covetous Gold Serpent Ring (Siegward's cell)", "Covetous Gold Serpent Ring", conditional = True), DS3LocationData("ID: Lightning Blade (B3 lift, middle platform)", "Lightning Blade"), - DS3LocationData("ID: Rusted Coin (B1 near, just past bonfire)", "Rusted Coin"), + DS3LocationData("ID: Rusted Coin (B1 near, first cell on left)", "Rusted Coin"), DS3LocationData("ID: Dusk Crown Ring (B3 far, right cell)", "Dusk Crown Ring"), DS3LocationData("ID: Pickaxe (path from pit to B3)", "Pickaxe"), DS3LocationData("ID: Xanthous Ashes (B3 far, right cell)", "Xanthous Ashes", progression = True), - DS3LocationData("ID: Rusted Gold Coin (B1 near, end of hall by door)", "Rusted Gold Coin"), + DS3LocationData("ID: Large Titanite Shard (B1 near, by door)", "Large Titanite Shard"), + DS3LocationData("ID: Rusted Gold Coin (after bonfire, last cell on right)", + "Rusted Gold Coin"), DS3LocationData("ID: Large Titanite Shard (stairs between pit and B3)", "Large Titanite Shard"), DS3LocationData("ID: Old Cell Key (stairs between pit and B3)", "Old Cell Key"), From 2bf1a68ee85ba60cd84b4306e7b36608e745f88d Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 8 Jan 2024 18:23:16 -0800 Subject: [PATCH 121/238] More location fixes --- worlds/dark_souls_3/Locations.py | 33 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index efe31cb6d250..24a252f7a9c8 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -639,15 +639,16 @@ def __init__( DS3LocationData("US: Alluring Skull (foot, behind carriage)", "Alluring Skull x2"), DS3LocationData("US: Mortician's Ashes (graveyard by white tree)", "Mortician's Ashes", progression = True), - DS3LocationData("US: Homeward Bone (???)", "Homeward Bone x2"), # Hidden fall + DS3LocationData("US: Homeward Bone (tower village, jump from roof)", "Homeward Bone x2", + offline = '02,0:53100040::', hidden = True), # Hidden fall DS3LocationData("US: Caduceus Round Shield (right after stable exit)", "Caduceus Round Shield"), DS3LocationData("US: Ember (tower basement, miniboss)", "Ember"), DS3LocationData("US: Soul of an Unknown Traveler (chasm crypt)", "Soul of an Unknown Traveler"), DS3LocationData("US: Repair Powder (first building, balcony)", "Repair Powder x2"), - DS3LocationData("US: Homeward Bone (tower village, jump from roof)", "Homeward Bone x2", - hidden = True), # Hidden fall + DS3LocationData("US: Homeward Bone (stable roof)", "Homeward Bone x2", + offline = '02,0:53100090::'), DS3LocationData("US: Titanite Shard (back alley, side path)", "Titanite Shard"), DS3LocationData("US: Wargod Wooden Shield (Pit of Hollows)", "Wargod Wooden Shield"), DS3LocationData("US: Large Soul of a Deserted Corpse (on the way to tower, by well)", @@ -707,7 +708,8 @@ def __init__( # In enemy rando, the enemy may not burst through the wall and make this room obvious DS3LocationData("US: Whip (back alley, behind wooden wall)", "Whip", hidden = True), DS3LocationData("US: Great Scythe (building by white tree, balcony)", "Great Scythe"), - DS3LocationData("US: Homeward Bone (stable roof)", "Homeward Bone x2"), + DS3LocationData("US: Homeward Bone (foot, drop overloop)", "Homeward Bone", + offline = '02,0:53100540::'), DS3LocationData("US: Large Soul of a Deserted Corpse (around corner by Cliff Underside)", "Large Soul of a Deserted Corpse", hidden = True), # Hidden corner DS3LocationData("US: Ember (behind burning tree)", "Ember"), @@ -749,7 +751,8 @@ def __init__( "Covetous Silver Serpent Ring+2", ngp = True, hidden = True), # Hidden fall DS3LocationData("US: Human Pine Resin (tower village building, chest upstairs)", "Human Pine Resin x4"), - DS3LocationData("US: Homeward Bone (foot, drop overloop)", "Homeward Bone"), + DS3LocationData("US: Homeward Bone (tower village, right at start)", "Homeward Bone", + offline = '02,0:53100540::'), DS3LocationData("US: Irithyll Straight Sword (miniboss drop, by Road of Sacrifices)", "Irithyll Straight Sword", miniboss = True), DS3LocationData("US: Fire Gem (tower village, miniboss drop)", "Fire Gem", miniboss = True), @@ -1591,16 +1594,16 @@ def __init__( DS3LocationData("IBV: Leo Ring (great hall, chest)", "Leo Ring"), DS3LocationData("IBV: Dorhys' Gnawing (Dorhys drop)", "Dorhys' Gnawing", hidden = True), # Behind illusory wall - DS3LocationData("IBV: Divine Blessing (great hall, mob)", + DS3LocationData("IBV: Divine Blessing (great hall, mob drop)", "Divine Blessing", drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight - DS3LocationData("IBV: Large Titanite Shard (great hall, mob)", + DS3LocationData("IBV: Large Titanite Shard (great hall, main floor mob drop)", "Large Titanite Shard", drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight - DS3LocationData("IBV: Large Titanite Shard (great hall, mob)", + DS3LocationData("IBV: Large Titanite Shard (great hall, upstairs mob drop #1)", "Large Titanite Shard x2", drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight - DS3LocationData("IBV: Large Titanite Shard (great hall, mob)", + DS3LocationData("IBV: Large Titanite Shard (great hall, upstairs mob drop #2)", "Large Titanite Shard x2", drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight DS3LocationData("IBV: Roster of Knights (descent, first landing)", "Roster of Knights"), @@ -1651,7 +1654,7 @@ def __init__( npc = True), DS3LocationData("ID: Murakumo (Alva drop)", "Murakumo", missable = True, hostile_npc = True), - DS3LocationData("ID: Large Titanite Shard (B1 near, second cell on right)", + DS3LocationData("ID: Large Titanite Shard (after bonfire, second cell on right)", "Large Titanite Shard"), DS3LocationData("ID: Fading Soul (B1 near, main hall)", "Fading Soul"), DS3LocationData("ID: Large Soul of a Nameless Soldier (B2, hall by stairs)", @@ -1691,7 +1694,7 @@ def __init__( DS3LocationData("ID: Covetous Gold Serpent Ring (Siegward's cell)", "Covetous Gold Serpent Ring", conditional = True), DS3LocationData("ID: Lightning Blade (B3 lift, middle platform)", "Lightning Blade"), - DS3LocationData("ID: Rusted Coin (B1 near, first cell on left)", "Rusted Coin"), + DS3LocationData("ID: Rusted Coin (after bonfire, first cell on left)", "Rusted Coin"), DS3LocationData("ID: Dusk Crown Ring (B3 far, right cell)", "Dusk Crown Ring"), DS3LocationData("ID: Pickaxe (path from pit to B3)", "Pickaxe"), DS3LocationData("ID: Xanthous Ashes (B3 far, right cell)", "Xanthous Ashes", @@ -1787,7 +1790,7 @@ def __init__( "Greatshield of Glory", mimic = True), DS3LocationData("PC: Twinkling Titanite (halls above swamp, lizard #1)", "Twinkling Titanite", lizard = True), - DS3LocationData("PC: Twinkling Titanite (halls above swamp, lizard #1)", + DS3LocationData("PC: Twinkling Titanite (halls above swamp, lizard #2)", "Twinkling Titanite", lizard = True), DS3LocationData("PC: Siegbräu (Siegward after killing boss)", "Siegbräu", missable = True, npc = True), @@ -1886,7 +1889,7 @@ def __init__( lizard = True), DS3LocationData("AL: Twinkling Titanite (lizard after light cathedral #1)", "Twinkling Titanite", lizard = True), - DS3LocationData("AL: Twinkling Titanite (lizard after light cathedral #1)", + DS3LocationData("AL: Twinkling Titanite (lizard after light cathedral #2)", "Twinkling Titanite", lizard = True), DS3LocationData("AL: Aldrich's Ruby (dark cathedral, miniboss)", "Aldrich's Ruby", miniboss = True), # Deep Accursed drop @@ -2567,7 +2570,7 @@ def __init__( DS3LocationData("PW1: Ember (settlement, building near bonfire)", "Ember"), DS3LocationData("PW1: Frozen Weapon (snowfield lower, egg zone)", "Frozen Weapon"), DS3LocationData("PW1: Titanite Slab (depths, up secret ladder)", "Titanite Slab", - offline = '11,0:50004700::', + offline = '11,0:54500640::', hidden = True), # Must kill normal-looking Tree Woman DS3LocationData("PW1: Homeward Bone (depths, up hill)", "Homeward Bone x2"), DS3LocationData("PW1: Large Soul of an Unknown Traveler (below snowfield village overhang)", @@ -2593,8 +2596,6 @@ def __init__( "Twinkling Titanite", lizard = True), DS3LocationData("PW1: Large Titanite Shard (settlement loop, lizard)", "Large Titanite Shard x2", lizard = True), - DS3LocationData("PW1: Champion's Bones (boss drop)", "Champion's Bones", - offline = '11,0:50002310::', boss = True), ], "Painted World of Ariandel (After Contraption)": [ DS3LocationData("PW2: Soul of Sister Friede", "Soul of Sister Friede", prominent = True, From a0976eb5812076063239677127d07e3ab24e3f69 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 8 Jan 2024 18:44:41 -0800 Subject: [PATCH 122/238] Use hyphens instead of parens for location descriptions --- worlds/dark_souls_3/Bosses.py | 244 +- worlds/dark_souls_3/Locations.py | 2962 ++++++++--------- worlds/dark_souls_3/__init__.py | 106 +- .../detailed_location_descriptions.py | 2 +- worlds/dark_souls_3/docs/locations_en.md | 2944 ++++++++-------- 5 files changed, 3131 insertions(+), 3127 deletions(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index 945c5703fdda..0c15ea4de976 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -36,57 +36,57 @@ class DS3BossInfo: # of which can be individually replaced by Yhorm. all_bosses = [ DS3BossInfo("Iudex Gundyr", 4000800, before_storm_ruler = True, region = "Firelink Shrine", - locations = {"CA: Coiled Sword (boss drop)"}), + locations = {"CA: Coiled Sword - boss drop"}), DS3BossInfo("Vordt of the Boreal Valley", 3000800, before_storm_ruler = True, region = "Undead Settlement", 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 (Hawkwood)", - "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)", + "US: Transposing Kiln - boss drop", + "US: Wargod Wooden Shield - Pit of Hollows", + "FS: Hawkwood's Shield - Hawkwood", + "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, region = "Cathedral of the Deep", locations = { "RS: Soul of a Crystal Sage", - "FS: Sage's Big Hat (shop after killing RS boss)", - "FS: Hawkwood's Shield (Hawkwood)", + "FS: Sage's Big Hat - shop after killing RS boss", + "FS: Hawkwood's Shield - Hawkwood", }), DS3BossInfo("Deacons of the Deep", 3500800, locations = { "CD: Soul of the Deacons of the Deep", - "CD: Small Doll (boss drop)", - "FS: Hawkwood's Shield (Hawkwood)", + "CD: Small Doll - boss drop", + "FS: Hawkwood's Shield - Hawkwood", }), DS3BossInfo("Abyss Watchers", 3300801, before_storm_ruler = True, region = "Catacombs of Carthus", locations = { "FK: Soul of the Blood of the Wolf", "FK: Cinders of a Lord - Abyss Watcher", - "UG: Hornet Ring (environs, right of main path after killing FK boss)", - "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)", - "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)", - "FS: Farron Ring (Hawkwood)", - "FS: Hawkwood's Shield (Hawkwood)", + "UG: Hornet Ring - environs, right of main path after killing FK boss", + "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", + "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", + "FS: Farron Ring - Hawkwood", + "FS: Hawkwood's Shield - Hawkwood", }), DS3BossInfo("High Lord Wolnir", 3800800, before_storm_ruler = True, region = "Irithyll of the Boreal Valley", 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)", + "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, region = "Anor Londo", locations = { "IBV: Soul of Pontiff Sulyvahn", @@ -97,59 +97,59 @@ class DS3BossInfo: DS3BossInfo("Aldrich, Devourer of Men", 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)", + "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, region = "Lothric Castle", 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)", + "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, region = "Grand Archives", 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)", + "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, region = "Untended Graves", 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)", + "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: 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)", + "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: 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", }), # This is a white lie, you can get to a bunch of items in AP before you beat the Wyvern, but # this saves us from having to split the entire region in two just to mark which specific items @@ -157,29 +157,29 @@ class DS3BossInfo: DS3BossInfo("Ancient Wyvern", 3200800, region = "Archdragon Peak"), 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)", + "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)", + "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", @@ -188,56 +188,56 @@ class DS3BossInfo: 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)", + "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)", - "PW1: Champion's Bones (boss drop)", + "PW1: Valorheart - boss drop", + "PW1: Champion's Bones - boss drop", }), DS3BossInfo("Sister Friede", 4500801, dlc = True, region = "Dreg Heap", 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)", + "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, region = "Dreg Heap", 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)", + "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, region = "Ringed City", locations = { "DH: Soul of the Demon Prince", - "DH: Small Envoy Banner (boss drop)", + "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)", + "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)", + "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)", + "RC: Blood of the Dark Soul - end boss drop", }), DS3BossInfo("Slave Knight Gael 2", 5110800, dlc = True, locations = { "RC: Soul of Slave Knight Gael", - "RC: Blood of the Dark Soul (end boss drop)", + "RC: Blood of the Dark Soul - end boss drop", }), DS3BossInfo("Soul of Cinder", 4100800), ] @@ -245,5 +245,5 @@ class DS3BossInfo: 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)", + "PC: Siegbräu - Siegward after killing boss", }) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 24a252f7a9c8..35e8b3a2b3ea 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -265,266 +265,266 @@ def __init__( # naturally available as part of their quest. location_tables = { "Cemetery of Ash": [ - DS3LocationData("CA: Soul of a Deserted Corpse (right of spawn)", + DS3LocationData("CA: Soul of a Deserted Corpse - right of spawn", "Soul of a Deserted Corpse"), - DS3LocationData("CA: Firebomb (down the cliff edge)", "Firebomb x5"), - DS3LocationData("CA: Titanite Shard (jump to coffin)", "Titanite Shard"), - DS3LocationData("CA: Soul of an Unknown Traveler (by miniboss)", + DS3LocationData("CA: Firebomb - down the cliff edge", "Firebomb x5"), + DS3LocationData("CA: Titanite Shard - jump to coffin", "Titanite Shard"), + DS3LocationData("CA: Soul of an Unknown Traveler - by miniboss", "Soul of an Unknown Traveler"), - DS3LocationData("CA: Speckled Stoneplate Ring+1 (by miniboss)", + DS3LocationData("CA: Speckled Stoneplate Ring+1 - by miniboss", "Speckled Stoneplate Ring+1", ngp = True), - DS3LocationData("CA: Titanite Scale (miniboss drop)", "Titanite Scale", miniboss = True), - DS3LocationData("CA: Coiled Sword (boss drop)", "Coiled Sword", prominent = True, + DS3LocationData("CA: Titanite Scale - miniboss drop", "Titanite Scale", miniboss = True), + DS3LocationData("CA: Coiled Sword - boss drop", "Coiled Sword", prominent = True, progression = True, boss = True), ], "Firelink Shrine": [ # Ludleth drop, does not permanently die - DS3LocationData("FS: Skull Ring (kill Ludleth)", "Skull Ring", hidden = True, drop = True, + DS3LocationData("FS: Skull Ring - kill Ludleth", "Skull Ring", hidden = True, drop = True, npc = True), # Sword Master drops - DS3LocationData("FS: Uchigatana (NPC drop)", "Uchigatana", hostile_npc = True), - DS3LocationData("FS: Master's Attire (NPC drop)", "Master's Attire", hostile_npc = True), - DS3LocationData("FS: Master's Gloves (NPC drop)", "Master's Gloves", hostile_npc = True), + DS3LocationData("FS: Uchigatana - NPC drop", "Uchigatana", hostile_npc = True), + DS3LocationData("FS: Master's Attire - NPC drop", "Master's Attire", hostile_npc = True), + DS3LocationData("FS: Master's Gloves - NPC drop", "Master's Gloves", hostile_npc = True), - DS3LocationData("FS: Broken Straight Sword (gravestone after boss)", + DS3LocationData("FS: Broken Straight Sword - gravestone after boss", "Broken Straight Sword"), - DS3LocationData("FS: Homeward Bone (cliff edge after boss)", "Homeward Bone"), - DS3LocationData("FS: Ember (path right of Firelink entrance)", "Ember"), - DS3LocationData("FS: Soul of a Deserted Corpse (bell tower door)", + DS3LocationData("FS: Homeward Bone - cliff edge after boss", "Homeward Bone"), + DS3LocationData("FS: Ember - path right of Firelink entrance", "Ember"), + DS3LocationData("FS: Soul of a Deserted Corpse - bell tower door", "Soul of a Deserted Corpse"), - DS3LocationData("FS: East-West Shield (tree by shrine entrance)", "East-West Shield"), - DS3LocationData("FS: Homeward Bone (path above shrine entrace)", "Homeward Bone"), - DS3LocationData("FS: Ember (above shrine entrance)", "Ember"), - DS3LocationData("FS: Wolf Ring+2 (left of boss room exit)", "Wolf Ring+2", ngp = True), + DS3LocationData("FS: East-West Shield - tree by shrine entrance", "East-West Shield"), + DS3LocationData("FS: Homeward Bone - path above shrine entrace", "Homeward Bone"), + DS3LocationData("FS: Ember - above shrine entrance", "Ember"), + DS3LocationData("FS: Wolf Ring+2 - left of boss room exit", "Wolf Ring+2", ngp = True), # Leonhard (quest) - DS3LocationData("FS: Cracked Red Eye Orb (Leonhard)", "Cracked Red Eye Orb x5", + DS3LocationData("FS: Cracked Red Eye Orb - Leonhard", "Cracked Red Eye Orb x5", missable = True, npc = True), # Leonhard (kill or quest), missable because he can disappear sometimes - DS3LocationData("FS: Lift Chamber Key (Leonhard)", "Lift Chamber Key", missable = True, + DS3LocationData("FS: Lift Chamber Key - Leonhard", "Lift Chamber Key", missable = True, npc = True, drop = True), # Shrine Handmaid shop - DS3LocationData("FS: White Sign Soapstone (shop)", "White Sign Soapstone", shop = True), - DS3LocationData("FS: Dried Finger (shop)", "Dried Finger", shop = True), - DS3LocationData("FS: Tower Key (shop)", "Tower Key", progression = True, shop = True), - DS3LocationData("FS: Ember (shop)", "Ember", offline = '99,0:-1:110000:', shop = True), - DS3LocationData("FS: Farron Dart (shop)", "Farron Dart", offline = '99,0:-1:110000:', + DS3LocationData("FS: White Sign Soapstone - shop", "White Sign Soapstone", shop = True), + DS3LocationData("FS: Dried Finger - shop", "Dried Finger", shop = True), + DS3LocationData("FS: Tower Key - shop", "Tower Key", progression = True, shop = True), + DS3LocationData("FS: Ember - shop", "Ember", offline = '99,0:-1:110000:', shop = True), + DS3LocationData("FS: Farron Dart - shop", "Farron Dart", offline = '99,0:-1:110000:', shop = True), - DS3LocationData("FS: Soul Arrow (shop)", "Soul Arrow", offline = '99,0:-1:110000:', + DS3LocationData("FS: Soul Arrow - shop", "Soul Arrow", offline = '99,0:-1:110000:', shop = True), - DS3LocationData("FS: Heal Aid (shop)", "Heal Aid", shop = True), - DS3LocationData("FS: Alluring Skull (Mortician's Ashes)", "Alluring Skull", shop = True, + DS3LocationData("FS: Heal Aid - shop", "Heal Aid", shop = True), + DS3LocationData("FS: Alluring Skull - Mortician's Ashes", "Alluring Skull", shop = True, conditional = True), - DS3LocationData("FS: Ember (Mortician's Ashes)", "Ember", + DS3LocationData("FS: Ember - Mortician's Ashes", "Ember", offline = '99,0:-1:110000,70000100:', shop = True, conditional = True), - DS3LocationData("FS: Grave Key (Mortician's Ashes)", "Grave Key", shop = True, + DS3LocationData("FS: Grave Key - Mortician's Ashes", "Grave Key", shop = True, conditional = True), - DS3LocationData("FS: Life Ring (Dreamchaser's Ashes)", "Life Ring", shop = True, + DS3LocationData("FS: Life Ring - Dreamchaser's Ashes", "Life Ring", shop = True, conditional = True), # Only if you say where the ashes were found - DS3LocationData("FS: Hidden Blessing (Dreamchaser's Ashes)", "Hidden Blessing", + DS3LocationData("FS: Hidden Blessing - Dreamchaser's Ashes", "Hidden Blessing", missable = True, shop = True), - DS3LocationData("FS: Lloyd's Shield Ring (Paladin's Ashes)", "Lloyd's Shield Ring", + DS3LocationData("FS: Lloyd's Shield Ring - Paladin's Ashes", "Lloyd's Shield Ring", shop = True, conditional = True), - DS3LocationData("FS: Ember (Grave Warden's Ashes)", "Ember", + DS3LocationData("FS: Ember - Grave Warden's Ashes", "Ember", offline = '99,0:-1:110000,70000103:', shop = True, conditional = True), # Prisoner Chief's Ashes - DS3LocationData("FS: Karla's Pointed Hat (Prisoner Chief's Ashes)", "Karla's Pointed Hat", + DS3LocationData("FS: Karla's Pointed Hat - Prisoner Chief's Ashes", "Karla's Pointed Hat", offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), - DS3LocationData("FS: Karla's Coat (Prisoner Chief's Ashes)", "Karla's Coat", + DS3LocationData("FS: Karla's Coat - Prisoner Chief's Ashes", "Karla's Coat", offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), - DS3LocationData("FS: Karla's Gloves (Prisoner Chief's Ashes)", "Karla's Gloves", + DS3LocationData("FS: Karla's Gloves - Prisoner Chief's Ashes", "Karla's Gloves", offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), - DS3LocationData("FS: Karla's Trousers (Prisoner Chief's Ashes)", "Karla's Trousers", + DS3LocationData("FS: Karla's Trousers - Prisoner Chief's Ashes", "Karla's Trousers", offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), - DS3LocationData("FS: Xanthous Overcoat (Xanthous Ashes)", "Xanthous Overcoat", shop = True, + DS3LocationData("FS: Xanthous Overcoat - Xanthous Ashes", "Xanthous Overcoat", shop = True, conditional = True), - DS3LocationData("FS: Xanthous Gloves (Xanthous Ashes)", "Xanthous Gloves", shop = True, + DS3LocationData("FS: Xanthous Gloves - Xanthous Ashes", "Xanthous Gloves", shop = True, conditional = True), - DS3LocationData("FS: Xanthous Trousers (Xanthous Ashes)", "Xanthous Trousers", shop = True, + DS3LocationData("FS: Xanthous Trousers - Xanthous Ashes", "Xanthous Trousers", shop = True, conditional = True), - DS3LocationData("FS: Ember (Dragon Chaser's Ashes)", "Ember", + DS3LocationData("FS: Ember - Dragon Chaser's Ashes", "Ember", offline = '99,0:-1:110000,70000108:', shop = True, conditional = True), - DS3LocationData("FS: Washing Pole (Easterner's Ashes)", "Washing Pole", shop = True, + DS3LocationData("FS: Washing Pole - Easterner's Ashes", "Washing Pole", shop = True, conditional = True), - DS3LocationData("FS: Eastern Helm (Easterner's Ashes)", "Eastern Helm", shop = True, + DS3LocationData("FS: Eastern Helm - Easterner's Ashes", "Eastern Helm", shop = True, conditional = True), - DS3LocationData("FS: Eastern Armor (Easterner's Ashes)", "Eastern Armor", shop = True, + DS3LocationData("FS: Eastern Armor - Easterner's Ashes", "Eastern Armor", shop = True, conditional = True), - DS3LocationData("FS: Eastern Gauntlets (Easterner's Ashes)", "Eastern Gauntlets", + DS3LocationData("FS: Eastern Gauntlets - Easterner's Ashes", "Eastern Gauntlets", shop = True, conditional = True), - DS3LocationData("FS: Eastern Leggings (Easterner's Ashes)", "Eastern Leggings", shop = True, + DS3LocationData("FS: Eastern Leggings - Easterner's Ashes", "Eastern Leggings", shop = True, conditional = True), - DS3LocationData("FS: Wood Grain Ring (Easterner's Ashes)", "Wood Grain Ring", shop = True, + DS3LocationData("FS: Wood Grain Ring - Easterner's Ashes", "Wood Grain Ring", shop = True, conditional = True), - DS3LocationData("FS: Millwood Knight Helm (Captain's Ashes)", "Millwood Knight Helm", + DS3LocationData("FS: Millwood Knight Helm - Captain's Ashes", "Millwood Knight Helm", dlc = True, shop = True, conditional = True), - DS3LocationData("FS: Millwood Knight Armor (Captain's Ashes)", "Millwood Knight Armor", + DS3LocationData("FS: Millwood Knight Armor - Captain's Ashes", "Millwood Knight Armor", dlc = True, shop = True, conditional = True), - DS3LocationData("FS: Millwood Knight Gauntlets (Captain's Ashes)", + DS3LocationData("FS: Millwood Knight Gauntlets - Captain's Ashes", "Millwood Knight Gauntlets", dlc = True, shop = True, conditional = True), - DS3LocationData("FS: Millwood Knight Leggings (Captain's Ashes)", + DS3LocationData("FS: Millwood Knight Leggings - Captain's Ashes", "Millwood Knight Leggings", dlc = True, shop = True, conditional = True), - DS3LocationData("FS: Refined Gem (Captain's Ashes)", "Refined Gem", dlc = True, shop = True, + DS3LocationData("FS: Refined Gem - Captain's Ashes", "Refined Gem", dlc = True, shop = True, conditional = True), # Ludleth Shop - DS3LocationData("FS: Vordt's Great Hammer (Ludleth for Vordt)", "Vordt's Great Hammer", + DS3LocationData("FS: Vordt's Great Hammer - Ludleth for Vordt", "Vordt's Great Hammer", missable = True, boss = True, shop = True), - DS3LocationData("FS: Pontiff's Left Eye (Ludleth for Vordt)", "Pontiff's Left Eye", + DS3LocationData("FS: Pontiff's Left Eye - Ludleth for Vordt", "Pontiff's Left Eye", missable = True, boss = True, shop = True), - DS3LocationData("FS: Bountiful Sunlight (Ludleth for Rosaria)", "Bountiful Sunlight", + DS3LocationData("FS: Bountiful Sunlight - Ludleth for Rosaria", "Bountiful Sunlight", missable = True, boss = True, shop = True), - DS3LocationData("FS: Darkmoon Longbow (Ludleth for Aldrich)", "Darkmoon Longbow", + DS3LocationData("FS: Darkmoon Longbow - Ludleth for Aldrich", "Darkmoon Longbow", missable = True, boss = True, shop = True), - DS3LocationData("FS: Lifehunt Scythe (Ludleth for Aldrich)", "Lifehunt Scythe", + DS3LocationData("FS: Lifehunt Scythe - Ludleth for Aldrich", "Lifehunt Scythe", missable = True, boss = True, shop = True), - DS3LocationData("FS: Hollowslayer Greatsword (Ludleth for Greatwood)", + DS3LocationData("FS: Hollowslayer Greatsword - Ludleth for Greatwood", "Hollowslayer Greatsword", missable = True, boss = True, shop = True), - DS3LocationData("FS: Arstor's Spear (Ludleth for Greatwood)", "Arstor's Spear", + DS3LocationData("FS: Arstor's Spear - Ludleth for Greatwood", "Arstor's Spear", missable = True, boss = True, shop = True), - DS3LocationData("FS: Crystal Sage's Rapier (Ludleth for Sage)", "Crystal Sage's Rapier", + DS3LocationData("FS: Crystal Sage's Rapier - Ludleth for Sage", "Crystal Sage's Rapier", missable = True, boss = True, shop = True), - DS3LocationData("FS: Crystal Hail (Ludleth for Sage)", "Crystal Hail", missable = True, + DS3LocationData("FS: Crystal Hail - Ludleth for Sage", "Crystal Hail", missable = True, boss = True, shop = True), - DS3LocationData("FS: Cleric's Candlestick (Ludleth for Deacons)", "Cleric's Candlestick", + DS3LocationData("FS: Cleric's Candlestick - Ludleth for Deacons", "Cleric's Candlestick", missable = True, boss = True, shop = True), - DS3LocationData("FS: Deep Soul (Ludleth for Deacons)", "Deep Soul", missable = True, + DS3LocationData("FS: Deep Soul - Ludleth for Deacons", "Deep Soul", missable = True, boss = True, shop = True), - DS3LocationData("FS: Havel's Ring (Ludleth for Stray Demon)", "Havel's Ring", + DS3LocationData("FS: Havel's Ring - Ludleth for Stray Demon", "Havel's Ring", missable = True, boss = True, shop = True), - DS3LocationData("FS: Boulder Heave (Ludleth for Stray Demon)", "Boulder Heave", + DS3LocationData("FS: Boulder Heave - Ludleth for Stray Demon", "Boulder Heave", missable = True, boss = True, shop = True), - DS3LocationData("FS: Farron Greatsword (Ludleth for Abyss Watchers)", "Farron Greatsword", + DS3LocationData("FS: Farron Greatsword - Ludleth for Abyss Watchers", "Farron Greatsword", missable = True, boss = True, shop = True), - DS3LocationData("FS: Wolf Knight's Greatsword (Ludleth for Abyss Watchers)", + DS3LocationData("FS: Wolf Knight's Greatsword - Ludleth for Abyss Watchers", "Wolf Knight's Greatsword", missable = True, boss = True, shop = True), - DS3LocationData("FS: Wolnir's Holy Sword (Ludleth for Wolnir)", "Wolnir's Holy Sword", + DS3LocationData("FS: Wolnir's Holy Sword - Ludleth for Wolnir", "Wolnir's Holy Sword", missable = True, boss = True, shop = True), - DS3LocationData("FS: Black Serpent (Ludleth for Wolnir)", "Black Serpent", missable = True, + DS3LocationData("FS: Black Serpent - Ludleth for Wolnir", "Black Serpent", missable = True, boss = True, shop = True), - DS3LocationData("FS: Demon's Greataxe (Ludleth for Fire Demon)", "Demon's Greataxe", + DS3LocationData("FS: Demon's Greataxe - Ludleth for Fire Demon", "Demon's Greataxe", missable = True, boss = True, shop = True), - DS3LocationData("FS: Demon's Fist (Ludleth for Fire Demon)", "Demon's Fist", + DS3LocationData("FS: Demon's Fist - Ludleth for Fire Demon", "Demon's Fist", missable = True, boss = True, shop = True), - DS3LocationData("FS: Old King's Great Hammer (Ludleth for Old Demon King)", + DS3LocationData("FS: Old King's Great Hammer - Ludleth for Old Demon King", "Old King's Great Hammer", missable = True, boss = True, shop = True), - DS3LocationData("FS: Chaos Bed Vestiges (Ludleth for Old Demon King)", "Chaos Bed Vestiges", + DS3LocationData("FS: Chaos Bed Vestiges - Ludleth for Old Demon King", "Chaos Bed Vestiges", missable = True, boss = True, shop = True), - DS3LocationData("FS: Greatsword of Judgment (Ludleth for Pontiff)", + DS3LocationData("FS: Greatsword of Judgment - Ludleth for Pontiff", "Greatsword of Judgment", missable = True, boss = True, shop = True), - DS3LocationData("FS: Profaned Greatsword (Ludleth for Pontiff)", "Profaned Greatsword", + DS3LocationData("FS: Profaned Greatsword - Ludleth for Pontiff", "Profaned Greatsword", missable = True, boss = True, shop = True), - DS3LocationData("FS: Yhorm's Great Machete (Ludleth for Yhorm)", "Yhorm's Great Machete", + DS3LocationData("FS: Yhorm's Great Machete - Ludleth for Yhorm", "Yhorm's Great Machete", missable = True, boss = True, shop = True), - DS3LocationData("FS: Yhorm's Greatshield (Ludleth for Yhorm)", "Yhorm's Greatshield", + DS3LocationData("FS: Yhorm's Greatshield - Ludleth for Yhorm", "Yhorm's Greatshield", missable = True, boss = True, shop = True), - DS3LocationData("FS: Dancer's Enchanted Swords (Ludleth for Dancer)", + DS3LocationData("FS: Dancer's Enchanted Swords - Ludleth for Dancer", "Dancer's Enchanted Swords", missable = True, boss = True, shop = True), - DS3LocationData("FS: Soothing Sunlight (Ludleth for Dancer)", "Soothing Sunlight", + DS3LocationData("FS: Soothing Sunlight - Ludleth for Dancer", "Soothing Sunlight", missable = True, boss = True, shop = True), - DS3LocationData("FS: Dragonslayer Greataxe (Ludleth for Dragonslayer)", + DS3LocationData("FS: Dragonslayer Greataxe - Ludleth for Dragonslayer", "Dragonslayer Greataxe", missable = True, boss = True, shop = True), - DS3LocationData("FS: Dragonslayer Greatshield (Ludleth for Dragonslayer)", + DS3LocationData("FS: Dragonslayer Greatshield - Ludleth for Dragonslayer", "Dragonslayer Greatshield", missable = True, boss = True, shop = True), - DS3LocationData("FS: Moonlight Greatsword (Ludleth for Oceiros)", "Moonlight Greatsword", + DS3LocationData("FS: Moonlight Greatsword - Ludleth for Oceiros", "Moonlight Greatsword", missable = True, boss = True, shop = True), - DS3LocationData("FS: White Dragon Breath (Ludleth for Oceiros)", "White Dragon Breath", + DS3LocationData("FS: White Dragon Breath - Ludleth for Oceiros", "White Dragon Breath", missable = True, boss = True, shop = True), - DS3LocationData("FS: Lorian's Greatsword (Ludleth for Princes)", "Lorian's Greatsword", + DS3LocationData("FS: Lorian's Greatsword - Ludleth for Princes", "Lorian's Greatsword", missable = True, boss = True, shop = True), - DS3LocationData("FS: Lothric's Holy Sword (Ludleth for Princes)", "Lothric's Holy Sword", + DS3LocationData("FS: Lothric's Holy Sword - Ludleth for Princes", "Lothric's Holy Sword", missable = True, boss = True, shop = True), - DS3LocationData("FS: Gundyr's Halberd (Ludleth for Champion)", "Gundyr's Halberd", + DS3LocationData("FS: Gundyr's Halberd - Ludleth for Champion", "Gundyr's Halberd", missable = True, boss = True, shop = True), - DS3LocationData("FS: Prisoner's Chain (Ludleth for Champion)", "Prisoner's Chain", + DS3LocationData("FS: Prisoner's Chain - Ludleth for Champion", "Prisoner's Chain", missable = True, boss = True, shop = True), - DS3LocationData("FS: Storm Curved Sword (Ludleth for Nameless)", "Storm Curved Sword", + DS3LocationData("FS: Storm Curved Sword - Ludleth for Nameless", "Storm Curved Sword", missable = True, boss = True, shop = True), - DS3LocationData("FS: Dragonslayer Swordspear (Ludleth for Nameless)", + DS3LocationData("FS: Dragonslayer Swordspear - Ludleth for Nameless", "Dragonslayer Swordspear", missable = True, boss = True, shop = True), - DS3LocationData("FS: Lightning Storm (Ludleth for Nameless)", "Lightning Storm", + DS3LocationData("FS: Lightning Storm - Ludleth for Nameless", "Lightning Storm", missable = True, boss = True, shop = True), - DS3LocationData("FS: Firelink Greatsword (Ludleth for Cinder)", "Firelink Greatsword", + DS3LocationData("FS: Firelink Greatsword - Ludleth for Cinder", "Firelink Greatsword", missable = True, boss = True, shop = True), - DS3LocationData("FS: Sunlight Spear (Ludleth for Cinder)", "Sunlight Spear", + DS3LocationData("FS: Sunlight Spear - Ludleth for Cinder", "Sunlight Spear", missable = True, boss = True, shop = True), - DS3LocationData("FS: Friede's Great Scythe (Ludleth for Friede)", "Friede's Great Scythe", + DS3LocationData("FS: Friede's Great Scythe - Ludleth for Friede", "Friede's Great Scythe", missable = True, dlc = True, boss = True, shop = True), - DS3LocationData("FS: Rose of Ariandel (Ludleth for Friede)", "Rose of Ariandel", + DS3LocationData("FS: Rose of Ariandel - Ludleth for Friede", "Rose of Ariandel", missable = True, dlc = True, boss = True, shop = True), - DS3LocationData("FS: Demon's Scar (Ludleth for Demon Prince)", "Demon's Scar", + DS3LocationData("FS: Demon's Scar - Ludleth for Demon Prince", "Demon's Scar", missable = True, dlc = True, boss = True, shop = True), - DS3LocationData("FS: Seething Chaos (Ludleth for Demon Prince)", "Seething Chaos", + DS3LocationData("FS: Seething Chaos - Ludleth for Demon Prince", "Seething Chaos", missable = True, dlc = True, boss = True, shop = True), - DS3LocationData("FS: Frayed Blade (Ludleth for Midir)", "Frayed Blade", missable = True, + DS3LocationData("FS: Frayed Blade - Ludleth for Midir", "Frayed Blade", missable = True, dlc = True, boss = True, shop = True), - DS3LocationData("FS: Old Moonlight (Ludleth for Midir)", "Old Moonlight", missable = True, + DS3LocationData("FS: Old Moonlight - Ludleth for Midir", "Old Moonlight", missable = True, dlc = True, boss = True, shop = True), - DS3LocationData("FS: Gael's Greatsword (Ludleth for Gael)", "Gael's Greatsword", + DS3LocationData("FS: Gael's Greatsword - Ludleth for Gael", "Gael's Greatsword", missable = True, dlc = True, boss = True, shop = True), - DS3LocationData("FS: Repeating Crossbow (Ludleth for Gael)", "Repeating Crossbow", + DS3LocationData("FS: Repeating Crossbow - Ludleth for Gael", "Repeating Crossbow", missable = True, dlc = True, boss = True, shop = True), ], "Firelink Shrine Bell Tower": [ # Guarded by Tower Key - DS3LocationData("FSBT: Homeward Bone (roof)", "Homeward Bone x3"), - DS3LocationData("FSBT: Estus Ring (tower base)", "Estus Ring"), - DS3LocationData("FSBT: Estus Shard (rafters)", "Estus Shard"), - DS3LocationData("FSBT: Fire Keeper Soul (tower top)", "Fire Keeper Soul"), - DS3LocationData("FSBT: Fire Keeper Robe (partway down tower)", "Fire Keeper Robe"), - DS3LocationData("FSBT: Fire Keeper Gloves (partway down tower)", "Fire Keeper Gloves"), - DS3LocationData("FSBT: Fire Keeper Skirt (partway down tower)", "Fire Keeper Skirt"), - DS3LocationData("FSBT: Covetous Silver Serpent Ring (illusory wall past rafters)", + DS3LocationData("FSBT: Homeward Bone - roof", "Homeward Bone x3"), + DS3LocationData("FSBT: Estus Ring - tower base", "Estus Ring"), + DS3LocationData("FSBT: Estus Shard - rafters", "Estus Shard"), + DS3LocationData("FSBT: Fire Keeper Soul - tower top", "Fire Keeper Soul"), + DS3LocationData("FSBT: Fire Keeper Robe - partway down tower", "Fire Keeper Robe"), + DS3LocationData("FSBT: Fire Keeper Gloves - partway down tower", "Fire Keeper Gloves"), + DS3LocationData("FSBT: Fire Keeper Skirt - partway down tower", "Fire Keeper Skirt"), + DS3LocationData("FSBT: Covetous Silver Serpent Ring - illusory wall past rafters", "Covetous Silver Serpent Ring", hidden = True), - DS3LocationData("FSBT: Twinkling Titanite (lizard behind Firelink)", + DS3LocationData("FSBT: Twinkling Titanite - lizard behind Firelink", "Twinkling Titanite", lizard = True), # Mark all crow trades as missable since no one wants to have to try trading everything just # in case it gives a progression item. - DS3LocationData("FSBT: Iron Bracelets (crow for Homeward Bone)", "Iron Bracelets", + DS3LocationData("FSBT: Iron Bracelets - crow for Homeward Bone", "Iron Bracelets", missable = True), - DS3LocationData("FSBT: Ring of Sacrifice (crow for Loretta's Bone)", "Ring of Sacrifice", + DS3LocationData("FSBT: Ring of Sacrifice - crow for Loretta's Bone", "Ring of Sacrifice", missable = True), - DS3LocationData("FSBT: Porcine Shield (crow for Undead Bone Shard)", "Porcine Shield", + DS3LocationData("FSBT: Porcine Shield - crow for Undead Bone Shard", "Porcine Shield", missable = True), - DS3LocationData("FSBT: Lucatiel's Mask (crow for Vertebra Shackle)", "Lucatiel's Mask", + DS3LocationData("FSBT: Lucatiel's Mask - crow for Vertebra Shackle", "Lucatiel's Mask", missable = True), - DS3LocationData("FSBT: Very good! Carving (crow for Divine Blessing)", + DS3LocationData("FSBT: Very good! Carving - crow for Divine Blessing", "Very good! Carving", missable = True), - DS3LocationData("FSBT: Thank you Carving (crow for Hidden Blessing)", "Thank you Carving", + DS3LocationData("FSBT: Thank you Carving - crow for Hidden Blessing", "Thank you Carving", missable = True), - DS3LocationData("FSBT: I'm sorry Carving (crow for Shriving Stone)", "I'm sorry Carving", + DS3LocationData("FSBT: I'm sorry Carving - crow for Shriving Stone", "I'm sorry Carving", missable = True), - DS3LocationData("FSBT: Sunlight Shield (crow for Mendicant's Staff)", "Sunlight Shield", + DS3LocationData("FSBT: Sunlight Shield - crow for Mendicant's Staff", "Sunlight Shield", missable = True), - DS3LocationData("FSBT: Hollow Gem (crow for Eleonora)", "Hollow Gem", + DS3LocationData("FSBT: Hollow Gem - crow for Eleonora", "Hollow Gem", missable = True), - DS3LocationData("FSBT: Titanite Scale (crow for Blacksmith Hammer)", "Titanite Scale x3", + DS3LocationData("FSBT: Titanite Scale - crow for Blacksmith Hammer", "Titanite Scale x3", offline = '99,0:50004330::', missable = True), - DS3LocationData("FSBT: Help me! Carving (crow for any sacred chime)", "Help me! Carving", + DS3LocationData("FSBT: Help me! Carving - crow for any sacred chime", "Help me! Carving", missable = True), - DS3LocationData("FSBT: Titanite Slab (crow for Coiled Sword Fragment)", "Titanite Slab", + DS3LocationData("FSBT: Titanite Slab - crow for Coiled Sword Fragment", "Titanite Slab", missable = True), - DS3LocationData("FSBT: Hello Carving (crow for Alluring Skull)", "Hello Carving", + DS3LocationData("FSBT: Hello Carving - crow for Alluring Skull", "Hello Carving", missable = True), - DS3LocationData("FSBT: Armor of the Sun (crow for Siegbräu)", "Armor of the Sun", + DS3LocationData("FSBT: Armor of the Sun - crow for Siegbräu", "Armor of the Sun", missable = True), - DS3LocationData("FSBT: Large Titanite Shard (crow for Firebomb)", "Large Titanite Shard", + DS3LocationData("FSBT: Large Titanite Shard - crow for Firebomb", "Large Titanite Shard", missable = True), - DS3LocationData("FSBT: Titanite Chunk (crow for Black Firebomb)", "Titanite Chunk", + DS3LocationData("FSBT: Titanite Chunk - crow for Black Firebomb", "Titanite Chunk", missable = True), - DS3LocationData("FSBT: Iron Helm (crow for Lightning Urn)", "Iron Helm", missable = True), - DS3LocationData("FSBT: Twinkling Titanite (crow for Prism Stone)", "Twinkling Titanite", + DS3LocationData("FSBT: Iron Helm - crow for Lightning Urn", "Iron Helm", missable = True), + DS3LocationData("FSBT: Twinkling Titanite - crow for Prism Stone", "Twinkling Titanite", missable = True), - DS3LocationData("FSBT: Iron Leggings (crow for Seed of a Giant Tree)", "Iron Leggings", + DS3LocationData("FSBT: Iron Leggings - crow for Seed of a Giant Tree", "Iron Leggings", missable = True), - DS3LocationData("FSBT: Lightning Gem (crow for Xanthous Crown)", "Lightning Gem", + DS3LocationData("FSBT: Lightning Gem - crow for Xanthous Crown", "Lightning Gem", missable = True), - DS3LocationData("FSBT: Twinkling Titanite (crow for Large Leather Shield)", + DS3LocationData("FSBT: Twinkling Titanite - crow for Large Leather Shield", "Twinkling Titanite", missable = True), - DS3LocationData("FSBT: Blessed Gem (crow for Moaning Shield)", "Blessed Gem", + DS3LocationData("FSBT: Blessed Gem - crow for Moaning Shield", "Blessed Gem", missable = True), ], "High Wall of Lothric": [ @@ -532,655 +532,655 @@ def __init__( prominent = True, boss = True), DS3LocationData("HWL: Soul of the Dancer", "Soul of the Dancer", prominent = True, boss = True), - DS3LocationData("HWL: Basin of Vows (Emma)", "Basin of Vows", prominent = True, + DS3LocationData("HWL: Basin of Vows - Emma", "Basin of Vows", prominent = True, progression = True, conditional = True), - DS3LocationData("HWL: Small Lothric Banner (Emma)", "Small Lothric Banner", + DS3LocationData("HWL: Small Lothric Banner - Emma", "Small Lothric Banner", prominent = True, progression = True), - DS3LocationData("HWL: Green Blossom (fort walkway, hall behind wheel)", "Green Blossom x2", + DS3LocationData("HWL: Green Blossom - fort walkway, hall behind wheel", "Green Blossom x2", hidden = True), - DS3LocationData("HWL: Gold Pine Resin (corpse tower, drop)", "Gold Pine Resin x2", + DS3LocationData("HWL: Gold Pine Resin - corpse tower, drop", "Gold Pine Resin x2", hidden = True), - DS3LocationData("HWL: Large Soul of a Deserted Corpse (flame plaza)", + DS3LocationData("HWL: Large Soul of a Deserted Corpse - flame plaza", "Large Soul of a Deserted Corpse"), - DS3LocationData("HWL: Soul of a Deserted Corpse (by wall tower door)", + DS3LocationData("HWL: Soul of a Deserted Corpse - by wall tower door", "Soul of a Deserted Corpse"), - DS3LocationData("HWL: Standard Arrow (back tower)", "Standard Arrow x12"), - DS3LocationData("HWL: Longbow (back tower)", "Longbow"), - DS3LocationData("HWL: Firebomb (wall tower, beam)", "Firebomb x3"), - DS3LocationData("HWL: Throwing Knife (wall tower, path to Greirat)", "Throwing Knife x8"), - DS3LocationData("HWL: Soul of a Deserted Corpse (corpse tower, bottom floor)", + DS3LocationData("HWL: Standard Arrow - back tower", "Standard Arrow x12"), + DS3LocationData("HWL: Longbow - back tower", "Longbow"), + DS3LocationData("HWL: Firebomb - wall tower, beam", "Firebomb x3"), + DS3LocationData("HWL: Throwing Knife - wall tower, path to Greirat", "Throwing Knife x8"), + DS3LocationData("HWL: Soul of a Deserted Corpse - corpse tower, bottom floor", "Soul of a Deserted Corpse"), - DS3LocationData("HWL: Club (flame plaza)", "Club"), - DS3LocationData("HWL: Claymore (flame plaza)", "Claymore"), - DS3LocationData("HWL: Ember (flame plaza)", "Ember"), - DS3LocationData("HWL: Firebomb (corpse tower, under table)", "Firebomb x2"), - DS3LocationData("HWL: Titanite Shard (wall tower, corner by bonfire)", "Titanite Shard", + DS3LocationData("HWL: Club - flame plaza", "Club"), + DS3LocationData("HWL: Claymore - flame plaza", "Claymore"), + DS3LocationData("HWL: Ember - flame plaza", "Ember"), + DS3LocationData("HWL: Firebomb - corpse tower, under table", "Firebomb x2"), + DS3LocationData("HWL: Titanite Shard - wall tower, corner by bonfire", "Titanite Shard", hidden = True), - DS3LocationData("HWL: Undead Hunter Charm (fort, room off entry, in pot)", + DS3LocationData("HWL: Undead Hunter Charm - fort, room off entry, in pot", "Undead Hunter Charm x2", hidden = True), - DS3LocationData("HWL: Firebomb (top of ladder to fountain)", "Firebomb x3"), - DS3LocationData("HWL: Cell Key (fort ground, down stairs)", "Cell Key"), - DS3LocationData("HWL: Ember (fountain #1)", "Ember"), - DS3LocationData("HWL: Soul of a Deserted Corpse (fort entry, corner)", + DS3LocationData("HWL: Firebomb - top of ladder to fountain", "Firebomb x3"), + DS3LocationData("HWL: Cell Key - fort ground, down stairs", "Cell Key"), + DS3LocationData("HWL: Ember - fountain #1", "Ember"), + DS3LocationData("HWL: Soul of a Deserted Corpse - fort entry, corner", "Soul of a Deserted Corpse"), - DS3LocationData("HWL: Lucerne (promenade, side path)", "Lucerne"), - DS3LocationData("HWL: Mail Breaker (wall tower, path to Greirat)", "Mail Breaker"), - DS3LocationData("HWL: Titanite Shard (fort ground behind crates)", "Titanite Shard", + DS3LocationData("HWL: Lucerne - promenade, side path", "Lucerne"), + DS3LocationData("HWL: Mail Breaker - wall tower, path to Greirat", "Mail Breaker"), + DS3LocationData("HWL: Titanite Shard - fort ground behind crates", "Titanite Shard", hidden = True), - DS3LocationData("HWL: Rapier (fountain, corner)", "Rapier"), - DS3LocationData("HWL: Titanite Shard (fort, room off entry)", "Titanite Shard"), - DS3LocationData("HWL: Large Soul of a Deserted Corpse (fort roof)", + DS3LocationData("HWL: Rapier - fountain, corner", "Rapier"), + DS3LocationData("HWL: Titanite Shard - fort, room off entry", "Titanite Shard"), + DS3LocationData("HWL: Large Soul of a Deserted Corpse - fort roof", "Large Soul of a Deserted Corpse"), - DS3LocationData("HWL: Black Firebomb (small roof over fountain)", "Black Firebomb x3"), - DS3LocationData("HWL: Soul of a Deserted Corpse (path to corpse tower)", + DS3LocationData("HWL: Black Firebomb - small roof over fountain", "Black Firebomb x3"), + DS3LocationData("HWL: Soul of a Deserted Corpse - path to corpse tower", "Soul of a Deserted Corpse"), - DS3LocationData("HWL: Ember (fountain #2)", "Ember"), - DS3LocationData("HWL: Large Soul of a Deserted Corpse (platform by fountain)", + DS3LocationData("HWL: Ember - fountain #2", "Ember"), + DS3LocationData("HWL: Large Soul of a Deserted Corpse - platform by fountain", "Large Soul of a Deserted Corpse", hidden = True), # Easily missed turnoff - DS3LocationData("HWL: Binoculars (corpse tower, upper platform)", "Binoculars"), - DS3LocationData("HWL: Ring of Sacrifice (awning by fountain)", + DS3LocationData("HWL: Binoculars - corpse tower, upper platform", "Binoculars"), + DS3LocationData("HWL: Ring of Sacrifice - awning by fountain", "Ring of Sacrifice", hidden = True), # Easily missed turnoff - DS3LocationData("HWL: Throwing Knife (shortcut, lift top)", "Throwing Knife x6"), - DS3LocationData("HWL: Soul of a Deserted Corpse (path to back tower, by lift door)", + DS3LocationData("HWL: Throwing Knife - shortcut, lift top", "Throwing Knife x6"), + DS3LocationData("HWL: Soul of a Deserted Corpse - path to back tower, by lift door", "Soul of a Deserted Corpse"), - DS3LocationData("HWL: Green Blossom (shortcut, lower courtyard)", "Green Blossom x3"), - DS3LocationData("HWL: Broadsword (fort, room off walkway)", "Broadsword"), - DS3LocationData("HWL: Soul of a Deserted Corpse (fountain, path to promenade)", + DS3LocationData("HWL: Green Blossom - shortcut, lower courtyard", "Green Blossom x3"), + DS3LocationData("HWL: Broadsword - fort, room off walkway", "Broadsword"), + DS3LocationData("HWL: Soul of a Deserted Corpse - fountain, path to promenade", "Soul of a Deserted Corpse"), - DS3LocationData("HWL: Firebomb (fort roof)", "Firebomb x3"), - DS3LocationData("HWL: Soul of a Deserted Corpse (wall tower, right of exit)", + DS3LocationData("HWL: Firebomb - fort roof", "Firebomb x3"), + DS3LocationData("HWL: Soul of a Deserted Corpse - wall tower, right of exit", "Soul of a Deserted Corpse"), - DS3LocationData("HWL: Estus Shard (fort ground, on anvil)", "Estus Shard"), - DS3LocationData("HWL: Fleshbite Ring+1 (fort roof, jump to other roof)", + DS3LocationData("HWL: Estus Shard - fort ground, on anvil", "Estus Shard"), + DS3LocationData("HWL: Fleshbite Ring+1 - fort roof, jump to other roof", "Fleshbite Ring+1", ngp = True, hidden = True), # Hidden jump - DS3LocationData("HWL: Ring of the Evil Eye+2 (fort ground, far wall)", + DS3LocationData("HWL: Ring of the Evil Eye+2 - fort ground, far wall", "Ring of the Evil Eye+2", ngp = True, hidden = True), # In barrels - DS3LocationData("HWL: Silver Eagle Kite Shield (fort mezzanine)", + DS3LocationData("HWL: Silver Eagle Kite Shield - fort mezzanine", "Silver Eagle Kite Shield"), - DS3LocationData("HWL: Astora Straight Sword (fort walkway, drop down)", + DS3LocationData("HWL: Astora Straight Sword - fort walkway, drop down", "Astora Straight Sword", hidden = True), # Hidden fall - DS3LocationData("HWL: Battle Axe (flame tower, mimic)", "Battle Axe", + DS3LocationData("HWL: Battle Axe - flame tower, mimic", "Battle Axe", offline = '01,0:53000960::', mimic = True), # Only dropped after transformation - DS3LocationData("HWL: Ember (fort roof, transforming hollow)", "Ember", hidden = True), - DS3LocationData("HWL: Titanite Shard (fort roof, transforming hollow)", "Titanite Shard", + DS3LocationData("HWL: Ember - fort roof, transforming hollow", "Ember", hidden = True), + DS3LocationData("HWL: Titanite Shard - fort roof, transforming hollow", "Titanite Shard", hidden = True), - DS3LocationData("HWL: Ember (back tower, transforming hollow)", "Ember", hidden = True), - DS3LocationData("HWL: Titanite Shard (back tower, transforming hollow)", "Titanite Shard", + DS3LocationData("HWL: Ember - back tower, transforming hollow", "Ember", hidden = True), + DS3LocationData("HWL: Titanite Shard - back tower, transforming hollow", "Titanite Shard", hidden = True), - DS3LocationData("HWL: Refined Gem (promenade miniboss)", "Refined Gem", miniboss = True), - DS3LocationData("HWL: Way of Blue (Emma)", "Way of Blue"), + DS3LocationData("HWL: Refined Gem - promenade miniboss", "Refined Gem", miniboss = True), + DS3LocationData("HWL: Way of Blue - Emma", "Way of Blue"), # Categorize this as an NPC item so that it doesn't get randomized if the Lift Chamber Key # isn't randomized, since in that case it's missable. - DS3LocationData("HWL: Red Eye Orb (wall tower, miniboss)", "Red Eye Orb", + DS3LocationData("HWL: Red Eye Orb - wall tower, miniboss", "Red Eye Orb", conditional = True, miniboss = True, npc = True), - DS3LocationData("HWL: Raw Gem (fort roof, lizard)", "Raw Gem", lizard = True), + DS3LocationData("HWL: Raw Gem - fort roof, lizard", "Raw Gem", lizard = True), ], "Undead Settlement": [ DS3LocationData("US: Soul of the Rotted Greatwood", "Soul of the Rotted Greatwood", prominent = True, boss = True), - DS3LocationData("US: Transposing Kiln (boss drop)", "Transposing Kiln", boss = True), + DS3LocationData("US: Transposing Kiln - boss drop", "Transposing Kiln", boss = True), # Missable because it's unavailable if you start as a Pyromancer - DS3LocationData("US: Pyromancy Flame (Cornyx)", "Pyromancy Flame", missable = True, + DS3LocationData("US: Pyromancy Flame - Cornyx", "Pyromancy Flame", missable = True, npc = True), - DS3LocationData("US: Old Sage's Blindfold (kill Cornyx)", "Old Sage's Blindfold", + DS3LocationData("US: Old Sage's Blindfold - kill Cornyx", "Old Sage's Blindfold", npc = True), - DS3LocationData("US: Cornyx's Garb (kill Cornyx)", "Cornyx's Garb", + DS3LocationData("US: Cornyx's Garb - kill Cornyx", "Cornyx's Garb", offline = '02,0:50006141::', npc = True), - DS3LocationData("US: Cornyx's Wrap (kill Cornyx)", "Cornyx's Wrap", + DS3LocationData("US: Cornyx's Wrap - kill Cornyx", "Cornyx's Wrap", offline = '02,0:50006141::', npc = True), - DS3LocationData("US: Cornyx's Skirt (kill Cornyx)", "Cornyx's Skirt", + DS3LocationData("US: Cornyx's Skirt - kill Cornyx", "Cornyx's Skirt", offline = '02,0:50006141::', npc = True), - DS3LocationData("US: Tower Key (kill Irina)", "Tower Key", missable = True, npc = True), - DS3LocationData("US: Flynn's Ring (tower village, rooftop)", "Flynn's Ring"), - DS3LocationData("US: Undead Bone Shard (by white tree)", "Undead Bone Shard"), - DS3LocationData("US: Alluring Skull (foot, behind carriage)", "Alluring Skull x2"), - DS3LocationData("US: Mortician's Ashes (graveyard by white tree)", "Mortician's Ashes", + DS3LocationData("US: Tower Key - kill Irina", "Tower Key", missable = True, npc = True), + DS3LocationData("US: Flynn's Ring - tower village, rooftop", "Flynn's Ring"), + DS3LocationData("US: Undead Bone Shard - by white tree", "Undead Bone Shard"), + DS3LocationData("US: Alluring Skull - foot, behind carriage", "Alluring Skull x2"), + DS3LocationData("US: Mortician's Ashes - graveyard by white tree", "Mortician's Ashes", progression = True), - DS3LocationData("US: Homeward Bone (tower village, jump from roof)", "Homeward Bone x2", + DS3LocationData("US: Homeward Bone - tower village, jump from roof", "Homeward Bone x2", offline = '02,0:53100040::', hidden = True), # Hidden fall - DS3LocationData("US: Caduceus Round Shield (right after stable exit)", + DS3LocationData("US: Caduceus Round Shield - right after stable exit", "Caduceus Round Shield"), - DS3LocationData("US: Ember (tower basement, miniboss)", "Ember"), - DS3LocationData("US: Soul of an Unknown Traveler (chasm crypt)", + DS3LocationData("US: Ember - tower basement, miniboss", "Ember"), + DS3LocationData("US: Soul of an Unknown Traveler - chasm crypt", "Soul of an Unknown Traveler"), - DS3LocationData("US: Repair Powder (first building, balcony)", "Repair Powder x2"), - DS3LocationData("US: Homeward Bone (stable roof)", "Homeward Bone x2", + DS3LocationData("US: Repair Powder - first building, balcony", "Repair Powder x2"), + DS3LocationData("US: Homeward Bone - stable roof", "Homeward Bone x2", offline = '02,0:53100090::'), - DS3LocationData("US: Titanite Shard (back alley, side path)", "Titanite Shard"), - DS3LocationData("US: Wargod Wooden Shield (Pit of Hollows)", "Wargod Wooden Shield"), - DS3LocationData("US: Large Soul of a Deserted Corpse (on the way to tower, by well)", + DS3LocationData("US: Titanite Shard - back alley, side path", "Titanite Shard"), + DS3LocationData("US: Wargod Wooden Shield - Pit of Hollows", "Wargod Wooden Shield"), + DS3LocationData("US: Large Soul of a Deserted Corpse - on the way to tower, by well", "Large Soul of a Deserted Corpse"), - DS3LocationData("US: Ember (bridge on the way to tower)", "Ember"), - DS3LocationData("US: Large Soul of a Deserted Corpse (stable)", + DS3LocationData("US: Ember - bridge on the way to tower", "Ember"), + DS3LocationData("US: Large Soul of a Deserted Corpse - stable", "Large Soul of a Deserted Corpse"), - DS3LocationData("US: Titanite Shard (porch after burning tree)", "Titanite Shard"), - DS3LocationData("US: Alluring Skull (tower village building, upstairs)", + DS3LocationData("US: Titanite Shard - porch after burning tree", "Titanite Shard"), + DS3LocationData("US: Alluring Skull - tower village building, upstairs", "Alluring Skull x2"), - DS3LocationData("US: Charcoal Pine Bundle (first building)", "Charcoal Pine Bundle x2"), - DS3LocationData("US: Blue Wooden Shield (graveyard by white tree)", "Blue Wooden Shield"), - DS3LocationData("US: Cleric Hat (graveyard by white tree)", "Cleric Hat"), - DS3LocationData("US: Cleric Blue Robe (graveyard by white tree)", "Cleric Blue Robe"), - DS3LocationData("US: Cleric Gloves (graveyard by white tree)", "Cleric Gloves"), - DS3LocationData("US: Cleric Trousers (graveyard by white tree)", "Cleric Trousers"), - DS3LocationData("US: Soul of an Unknown Traveler (portcullis by burning tree)", + DS3LocationData("US: Charcoal Pine Bundle - first building", "Charcoal Pine Bundle x2"), + DS3LocationData("US: Blue Wooden Shield - graveyard by white tree", "Blue Wooden Shield"), + DS3LocationData("US: Cleric Hat - graveyard by white tree", "Cleric Hat"), + DS3LocationData("US: Cleric Blue Robe - graveyard by white tree", "Cleric Blue Robe"), + DS3LocationData("US: Cleric Gloves - graveyard by white tree", "Cleric Gloves"), + DS3LocationData("US: Cleric Trousers - graveyard by white tree", "Cleric Trousers"), + DS3LocationData("US: Soul of an Unknown Traveler - portcullis by burning tree", "Soul of an Unknown Traveler"), - DS3LocationData("US: Charcoal Pine Resin (hanging corpse room)", "Charcoal Pine Resin x2"), - DS3LocationData("US: Loincloth (by Velka statue)", "Loincloth"), - DS3LocationData("US: Bloodbite Ring (miniboss in sewer)", "Bloodbite Ring", + DS3LocationData("US: Charcoal Pine Resin - hanging corpse room", "Charcoal Pine Resin x2"), + DS3LocationData("US: Loincloth - by Velka statue", "Loincloth"), + DS3LocationData("US: Bloodbite Ring - miniboss in sewer", "Bloodbite Ring", miniboss = True), # Giant Rat drop - DS3LocationData("US: Charcoal Pine Bundle (first building)", "Charcoal Pine Bundle x2"), - DS3LocationData("US: Soul of an Unknown Traveler (back alley, past crates)", + DS3LocationData("US: Charcoal Pine Bundle - first building", "Charcoal Pine Bundle x2"), + DS3LocationData("US: Soul of an Unknown Traveler - back alley, past crates", "Soul of an Unknown Traveler", hidden = True), - DS3LocationData("US: Titanite Shard (back alley, up ladder)", "Titanite Shard"), - DS3LocationData("US: Red Hilted Halberd (chasm crypt)", "Red Hilted Halberd"), - DS3LocationData("US: Rusted Coin (awning above Dilapidated Bridge)", "Rusted Coin x2"), - DS3LocationData("US: Caestus (sewer)", "Caestus"), - DS3LocationData("US: Saint's Talisman (chasm, by ladder)", "Saint's Talisman"), - DS3LocationData("US: Alluring Skull (on the way to tower, behind building)", + DS3LocationData("US: Titanite Shard - back alley, up ladder", "Titanite Shard"), + DS3LocationData("US: Red Hilted Halberd - chasm crypt", "Red Hilted Halberd"), + DS3LocationData("US: Rusted Coin - awning above Dilapidated Bridge", "Rusted Coin x2"), + DS3LocationData("US: Caestus - sewer", "Caestus"), + DS3LocationData("US: Saint's Talisman - chasm, by ladder", "Saint's Talisman"), + DS3LocationData("US: Alluring Skull - on the way to tower, behind building", "Alluring Skull x3"), - DS3LocationData("US: Large Club (tower village, by miniboss)", "Large Club"), - DS3LocationData("US: Titanite Shard (chasm #1)", "Titanite Shard"), - DS3LocationData("US: Titanite Shard (chasm #2)", "Titanite Shard"), - DS3LocationData("US: Fading Soul (outside stable)", "Fading Soul"), - DS3LocationData("US: Titanite Shard (lower path to Cliff Underside)", "Titanite Shard", + DS3LocationData("US: Large Club - tower village, by miniboss", "Large Club"), + DS3LocationData("US: Titanite Shard - chasm #1", "Titanite Shard"), + DS3LocationData("US: Titanite Shard - chasm #2", "Titanite Shard"), + DS3LocationData("US: Fading Soul - outside stable", "Fading Soul"), + DS3LocationData("US: Titanite Shard - lower path to Cliff Underside", "Titanite Shard", hidden = True), # hidden fall - DS3LocationData("US: Hand Axe (by Cornyx)", "Hand Axe"), - DS3LocationData("US: Soul of an Unknown Traveler (pillory past stable)", + DS3LocationData("US: Hand Axe - by Cornyx", "Hand Axe"), + DS3LocationData("US: Soul of an Unknown Traveler - pillory past stable", "Soul of an Unknown Traveler"), - DS3LocationData("US: Ember (by stairs to boss)", "Ember"), - DS3LocationData("US: Mirrah Vest (tower village, jump from roof)", "Mirrah Vest", + DS3LocationData("US: Ember - by stairs to boss", "Ember"), + DS3LocationData("US: Mirrah Vest - tower village, jump from roof", "Mirrah Vest", hidden = True), # Hidden fall - DS3LocationData("US: Mirrah Gloves (tower village, jump from roof)", "Mirrah Gloves", + DS3LocationData("US: Mirrah Gloves - tower village, jump from roof", "Mirrah Gloves", hidden = True), # Hidden fall - DS3LocationData("US: Mirrah Trousers (tower village, jump from roof)", "Mirrah Trousers", + DS3LocationData("US: Mirrah Trousers - tower village, jump from roof", "Mirrah Trousers", hidden = True), # Hidden fall - DS3LocationData("US: Plank Shield (outside stable, by NPC)", "Plank Shield"), - DS3LocationData("US: Red Bug Pellet (tower village building, basement)", + DS3LocationData("US: Plank Shield - outside stable, by NPC", "Plank Shield"), + DS3LocationData("US: Red Bug Pellet - tower village building, basement", "Red Bug Pellet x2"), - DS3LocationData("US: Chloranthy Ring (tower village, jump from roof)", "Chloranthy Ring", + DS3LocationData("US: Chloranthy Ring - tower village, jump from roof", "Chloranthy Ring", hidden = True), # Hidden fall - DS3LocationData("US: Fire Clutch Ring (wooden walkway past stable)", "Fire Clutch Ring"), - DS3LocationData("US: Estus Shard (under burning tree)", "Estus Shard"), - DS3LocationData("US: Firebomb (stable roof)", "Firebomb x6"), + DS3LocationData("US: Fire Clutch Ring - wooden walkway past stable", "Fire Clutch Ring"), + DS3LocationData("US: Estus Shard - under burning tree", "Estus Shard"), + DS3LocationData("US: Firebomb - stable roof", "Firebomb x6"), # In enemy rando, the enemy may not burst through the wall and make this room obvious - DS3LocationData("US: Whip (back alley, behind wooden wall)", "Whip", hidden = True), - DS3LocationData("US: Great Scythe (building by white tree, balcony)", "Great Scythe"), - DS3LocationData("US: Homeward Bone (foot, drop overloop)", "Homeward Bone", + DS3LocationData("US: Whip - back alley, behind wooden wall", "Whip", hidden = True), + DS3LocationData("US: Great Scythe - building by white tree, balcony", "Great Scythe"), + DS3LocationData("US: Homeward Bone - foot, drop overloop", "Homeward Bone", offline = '02,0:53100540::'), - DS3LocationData("US: Large Soul of a Deserted Corpse (around corner by Cliff Underside)", + DS3LocationData("US: Large Soul of a Deserted Corpse - around corner by Cliff Underside", "Large Soul of a Deserted Corpse", hidden = True), # Hidden corner - DS3LocationData("US: Ember (behind burning tree)", "Ember"), - DS3LocationData("US: Large Soul of a Deserted Corpse (across from Foot of the High Wall)", + DS3LocationData("US: Ember - behind burning tree", "Ember"), + DS3LocationData("US: Large Soul of a Deserted Corpse - across from Foot of the High Wall", "Large Soul of a Deserted Corpse"), - DS3LocationData("US: Fading Soul (by white tree)", "Fading Soul"), - DS3LocationData("US: Young White Branch (by white tree #1)", "Young White Branch"), - DS3LocationData("US: Ember (by white tree)", "Ember"), - DS3LocationData("US: Large Soul of a Deserted Corpse (by white tree)", + DS3LocationData("US: Fading Soul - by white tree", "Fading Soul"), + DS3LocationData("US: Young White Branch - by white tree #1", "Young White Branch"), + DS3LocationData("US: Ember - by white tree", "Ember"), + DS3LocationData("US: Large Soul of a Deserted Corpse - by white tree", "Large Soul of a Deserted Corpse"), - DS3LocationData("US: Young White Branch (by white tree #2)", "Young White Branch"), - DS3LocationData("US: Reinforced Club (by white tree)", "Reinforced Club"), - DS3LocationData("US: Soul of a Nameless Soldier (top of tower)", + DS3LocationData("US: Young White Branch - by white tree #2", "Young White Branch"), + DS3LocationData("US: Reinforced Club - by white tree", "Reinforced Club"), + DS3LocationData("US: Soul of a Nameless Soldier - top of tower", "Soul of a Nameless Soldier"), - DS3LocationData("US: Loretta's Bone (first building, hanging corpse on balcony)", + DS3LocationData("US: Loretta's Bone - first building, hanging corpse on balcony", "Loretta's Bone"), - DS3LocationData("US: Northern Helm (tower village, hanging corpse)", "Northern Helm"), - DS3LocationData("US: Northern Armor (tower village, hanging corpse)", "Northern Armor"), - DS3LocationData("US: Northern Gloves (tower village, hanging corpse)", "Northern Gloves"), - DS3LocationData("US: Northern Trousers (tower village, hanging corpse)", + DS3LocationData("US: Northern Helm - tower village, hanging corpse", "Northern Helm"), + DS3LocationData("US: Northern Armor - tower village, hanging corpse", "Northern Armor"), + DS3LocationData("US: Northern Gloves - tower village, hanging corpse", "Northern Gloves"), + DS3LocationData("US: Northern Trousers - tower village, hanging corpse", "Northern Trousers"), - DS3LocationData("US: Partizan (hanging corpse above Cliff Underside)", "Partizan", + DS3LocationData("US: Partizan - hanging corpse above Cliff Underside", "Partizan", missable = True), # requires projectile - DS3LocationData("US: Flame Stoneplate Ring (hanging corpse by Mound-Maker transport)", + DS3LocationData("US: Flame Stoneplate Ring - hanging corpse by Mound-Maker transport", "Flame Stoneplate Ring"), - DS3LocationData("US: Red and White Shield (chasm, hanging corpse)", "Red and White Shield", + DS3LocationData("US: Red and White Shield - chasm, hanging corpse", "Red and White Shield", offline = "02,0:53100740::", missable = True), # requires projectile - DS3LocationData("US: Small Leather Shield (first building, hanging corpse by entrance)", + DS3LocationData("US: Small Leather Shield - first building, hanging corpse by entrance", "Small Leather Shield"), - DS3LocationData("US: Pale Tongue (tower village, hanging corpse)", "Pale Tongue"), - DS3LocationData("US: Large Soul of a Deserted Corpse (hanging corpse room, over stairs)", + DS3LocationData("US: Pale Tongue - tower village, hanging corpse", "Pale Tongue"), + DS3LocationData("US: Large Soul of a Deserted Corpse - hanging corpse room, over stairs", "Large Soul of a Deserted Corpse"), - DS3LocationData("US: Kukri (hanging corpse above burning tree)", "Kukri x9", + DS3LocationData("US: Kukri - hanging corpse above burning tree", "Kukri x9", missable = True), # requires projectile - DS3LocationData("US: Life Ring+1 (tower on the way to village)", "Life Ring+1", ngp = True), - DS3LocationData("US: Poisonbite Ring+1 (graveyard by white tree, near well)", + DS3LocationData("US: Life Ring+1 - tower on the way to village", "Life Ring+1", ngp = True), + DS3LocationData("US: Poisonbite Ring+1 - graveyard by white tree, near well", "Poisonbite Ring+1", ngp = True), - DS3LocationData("US: Covetous Silver Serpent Ring+2 (tower village, drop down from roof)", + DS3LocationData("US: Covetous Silver Serpent Ring+2 - tower village, drop down from roof", "Covetous Silver Serpent Ring+2", ngp = True, hidden = True), # Hidden fall - DS3LocationData("US: Human Pine Resin (tower village building, chest upstairs)", + DS3LocationData("US: Human Pine Resin - tower village building, chest upstairs", "Human Pine Resin x4"), - DS3LocationData("US: Homeward Bone (tower village, right at start)", "Homeward Bone", + DS3LocationData("US: Homeward Bone - tower village, right at start", "Homeward Bone", offline = '02,0:53100540::'), - DS3LocationData("US: Irithyll Straight Sword (miniboss drop, by Road of Sacrifices)", + DS3LocationData("US: Irithyll Straight Sword - miniboss drop, by Road of Sacrifices", "Irithyll Straight Sword", miniboss = True), - DS3LocationData("US: Fire Gem (tower village, miniboss drop)", "Fire Gem", miniboss = True), - DS3LocationData("US: Warrior of Sunlight (hanging corpse room, drop through hole)", + DS3LocationData("US: Fire Gem - tower village, miniboss drop", "Fire Gem", miniboss = True), + DS3LocationData("US: Warrior of Sunlight - hanging corpse room, drop through hole", "Warrior of Sunlight", hidden = True), # hidden fall - DS3LocationData("US: Mound-makers (Hodrick)", "Mound-makers", missable = True), - DS3LocationData("US: Sharp Gem (lizard by Dilapidated Bridge)", "Sharp Gem", lizard = True), - DS3LocationData("US: Heavy Gem (chasm, lizard)", "Heavy Gem", lizard = True), - DS3LocationData("US: Siegbräu (Siegward)", "Siegbräu", missable = True, npc = True), - DS3LocationData("US: Heavy Gem (Hawkwood)", "Heavy Gem", offline = '00,0:50006070::', + DS3LocationData("US: Mound-makers - Hodrick", "Mound-makers", missable = True), + DS3LocationData("US: Sharp Gem - lizard by Dilapidated Bridge", "Sharp Gem", lizard = True), + DS3LocationData("US: Heavy Gem - chasm, lizard", "Heavy Gem", lizard = True), + DS3LocationData("US: Siegbräu - Siegward", "Siegbräu", missable = True, npc = True), + DS3LocationData("US: Heavy Gem - Hawkwood", "Heavy Gem", offline = '00,0:50006070::', missable = True, npc = True), # Hawkwood (quest, after Greatwood or Sage) DS3LocationData("US -> RS", None), # Yoel/Yuria of Londor - DS3LocationData("FS: Soul Arrow (Yoel/Yuria)", "Soul Arrow", + DS3LocationData("FS: Soul Arrow - Yoel/Yuria", "Soul Arrow", offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, shop = True), - DS3LocationData("FS: Heavy Soul Arrow (Yoel/Yuria)", "Heavy Soul Arrow", + DS3LocationData("FS: Heavy Soul Arrow - Yoel/Yuria", "Heavy Soul Arrow", offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, shop = True), - DS3LocationData("FS: Magic Weapon (Yoel/Yuria)", "Magic Weapon", + DS3LocationData("FS: Magic Weapon - Yoel/Yuria", "Magic Weapon", offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, shop = True), - DS3LocationData("FS: Magic Shield (Yoel/Yuria)", "Magic Shield", + DS3LocationData("FS: Magic Shield - Yoel/Yuria", "Magic Shield", offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, shop = True), - DS3LocationData("FS: Soul Greatsword (Yoel/Yuria)", "Soul Greatsword", + DS3LocationData("FS: Soul Greatsword - Yoel/Yuria", "Soul Greatsword", offline = '99,0:-1:50000,110000,70000450,70000475:', missable = True, npc = True, shop = True), - DS3LocationData("FS: Dark Hand (Yoel/Yuria)", "Dark Hand", missable = True, npc = True), - DS3LocationData("FS: Untrue White Ring (Yoel/Yuria)", "Untrue White Ring", missable = True, + DS3LocationData("FS: Dark Hand - Yoel/Yuria", "Dark Hand", missable = True, npc = True), + DS3LocationData("FS: Untrue White Ring - Yoel/Yuria", "Untrue White Ring", missable = True, npc = True), - DS3LocationData("FS: Untrue Dark Ring (Yoel/Yuria)", "Untrue Dark Ring", missable = True, + DS3LocationData("FS: Untrue Dark Ring - Yoel/Yuria", "Untrue Dark Ring", missable = True, npc = True), - DS3LocationData("FS: Londor Braille Divine Tome (Yoel/Yuria)", "Londor Braille Divine Tome", + DS3LocationData("FS: Londor Braille Divine Tome - Yoel/Yuria", "Londor Braille Divine Tome", offline = '99,0:-1:40000,110000,70000116:', missable = True, npc = True), - DS3LocationData("FS: Darkdrift (Yoel/Yuria)", "Darkdrift", missable = True, drop = True, + DS3LocationData("FS: Darkdrift - Yoel/Yuria", "Darkdrift", missable = True, drop = True, npc = True), # kill her or kill Soul of Cinder # Cornyx of the Great Swamp # These aren't missable because the Shrine Handmaid will carry them if you kill Cornyx. - DS3LocationData("FS: Fireball (Cornyx)", "Fireball", npc = True, shop = True), - DS3LocationData("FS: Fire Surge (Cornyx)", "Fire Surge", npc = True, shop = True), - DS3LocationData("FS: Great Combustion (Cornyx)", "Great Combustion", npc = True, + DS3LocationData("FS: Fireball - Cornyx", "Fireball", npc = True, shop = True), + DS3LocationData("FS: Fire Surge - Cornyx", "Fire Surge", npc = True, shop = True), + DS3LocationData("FS: Great Combustion - Cornyx", "Great Combustion", npc = True, shop = True), - DS3LocationData("FS: Flash Sweat (Cornyx)", "Flash Sweat", npc = True, shop = True), + DS3LocationData("FS: Flash Sweat - Cornyx", "Flash Sweat", npc = True, shop = True), # These are missable if you kill Cornyx before giving him the right tomes. - DS3LocationData("FS: Poison Mist (Cornyx for Great Swamp Tome)", "Poison Mist", + DS3LocationData("FS: Poison Mist - Cornyx for Great Swamp Tome", "Poison Mist", missable = True, npc = True, shop = True), - DS3LocationData("FS: Fire Orb (Cornyx for Great Swamp Tome)", "Fire Orb", missable = True, + DS3LocationData("FS: Fire Orb - Cornyx for Great Swamp Tome", "Fire Orb", missable = True, npc = True, shop = True), - DS3LocationData("FS: Profuse Sweat (Cornyx for Great Swamp Tome)", "Profuse Sweat", + DS3LocationData("FS: Profuse Sweat - Cornyx for Great Swamp Tome", "Profuse Sweat", missable = True, npc = True, shop = True), - DS3LocationData("FS: Bursting Fireball (Cornyx for Great Swamp Tome)", "Bursting Fireball", + DS3LocationData("FS: Bursting Fireball - Cornyx for Great Swamp Tome", "Bursting Fireball", missable = True, npc = True, shop = True), - DS3LocationData("FS: Acid Surge (Cornyx for Carthus Tome)", "Acid Surge", missable = True, + DS3LocationData("FS: Acid Surge - Cornyx for Carthus Tome", "Acid Surge", missable = True, npc = True, shop = True), - DS3LocationData("FS: Carthus Flame Arc (Cornyx for Carthus Tome)", "Carthus Flame Arc", + DS3LocationData("FS: Carthus Flame Arc - Cornyx for Carthus Tome", "Carthus Flame Arc", missable = True, npc = True, shop = True), - DS3LocationData("FS: Carthus Beacon (Cornyx for Carthus Tome)", "Carthus Beacon", + DS3LocationData("FS: Carthus Beacon - Cornyx for Carthus Tome", "Carthus Beacon", missable = True, npc = True, shop = True), - DS3LocationData("FS: Great Chaos Fire Orb (Cornyx for Izalith Tome)", + DS3LocationData("FS: Great Chaos Fire Orb - Cornyx for Izalith Tome", "Great Chaos Fire Orb", missable = True, npc = True, shop = True), - DS3LocationData("FS: Chaos Storm (Cornyx for Izalith Tome)", "Chaos Storm", missable = True, + DS3LocationData("FS: Chaos Storm - Cornyx for Izalith Tome", "Chaos Storm", missable = True, npc = True, shop = True), # Irina of Carim # These aren't in their own location because you don't actually need the Grave Key to access # Irena—you can just fall down the cliff near Eygon. - DS3LocationData("FS: Saint's Ring (Irina)", "Saint's Ring", npc = True, shop = True), - DS3LocationData("FS: Heal (Irina)", "Heal", npc = True, shop = True), - DS3LocationData("FS: Replenishment (Irina)", "Replenishment", npc = True, shop = True), - DS3LocationData("FS: Caressing Tears (Irina)", "Caressing Tears", npc = True, shop = True), - DS3LocationData("FS: Homeward (Irina)", "Homeward", npc = True, shop = True), - DS3LocationData("FS: Med Heal (Irina for Tome of Carim)", "Med Heal", missable = True, + DS3LocationData("FS: Saint's Ring - Irina", "Saint's Ring", npc = True, shop = True), + DS3LocationData("FS: Heal - Irina", "Heal", npc = True, shop = True), + DS3LocationData("FS: Replenishment - Irina", "Replenishment", npc = True, shop = True), + DS3LocationData("FS: Caressing Tears - Irina", "Caressing Tears", npc = True, shop = True), + DS3LocationData("FS: Homeward - Irina", "Homeward", npc = True, shop = True), + DS3LocationData("FS: Med Heal - Irina for Tome of Carim", "Med Heal", missable = True, npc = True, shop = True), - DS3LocationData("FS: Tears of Denial (Irina for Tome of Carim)", "Tears of Denial", + DS3LocationData("FS: Tears of Denial - Irina for Tome of Carim", "Tears of Denial", missable = True, npc = True, shop = True), - DS3LocationData("FS: Force (Irina for Tome of Carim)", "Force", missable = True, npc = True, + DS3LocationData("FS: Force - Irina for Tome of Carim", "Force", missable = True, npc = True, shop = True), - DS3LocationData("FS: Bountiful Light (Irina for Tome of Lothric)", "Bountiful Light", + DS3LocationData("FS: Bountiful Light - Irina for Tome of Lothric", "Bountiful Light", missable = True, npc = True, shop = True), - DS3LocationData("FS: Magic Barrier (Irina for Tome of Lothric)", "Magic Barrier", + DS3LocationData("FS: Magic Barrier - Irina for Tome of Lothric", "Magic Barrier", missable = True, npc = True, shop = True), - DS3LocationData("FS: Blessed Weapon (Irina for Tome of Lothric)", "Blessed Weapon", + DS3LocationData("FS: Blessed Weapon - Irina for Tome of Lothric", "Blessed Weapon", missable = True, npc = True, shop = True), ], "Road of Sacrifices": [ DS3LocationData("RS: Soul of a Crystal Sage", "Soul of a Crystal Sage", prominent = True, boss = True), - DS3LocationData("RS: Exile Greatsword (NPC drop by Farron Keep)", "Exile Greatsword", + DS3LocationData("RS: Exile Greatsword - NPC drop by Farron Keep", "Exile Greatsword", hostile_npc = True), # Exile Knight #2 drop - DS3LocationData("RS: Great Club (NPC drop by Farron Keep)", "Great Club", + DS3LocationData("RS: Great Club - NPC drop by Farron Keep", "Great Club", hostile_npc = True), # Exile Knight #1 drop - DS3LocationData("RS: Heysel Pick (Heysel drop)", "Heysel Pick", missable = True, + DS3LocationData("RS: Heysel Pick - Heysel drop", "Heysel Pick", missable = True, hostile_npc = True), - DS3LocationData("RS: Xanthous Crown (Heysel drop)", "Xanthous Crown", missable = True, + DS3LocationData("RS: Xanthous Crown - Heysel drop", "Xanthous Crown", missable = True, hostile_npc = True), - DS3LocationData("RS: Butcher Knife (NPC drop beneath road)", "Butcher Knife", + DS3LocationData("RS: Butcher Knife - NPC drop beneath road", "Butcher Knife", hostile_npc = True), # Madwoman - DS3LocationData("RS: Titanite Shard (water by Halfway Fortress)", "Titanite Shard"), - DS3LocationData("RS: Titanite Shard (woods, left of path from Halfway Fortress)", + DS3LocationData("RS: Titanite Shard - water by Halfway Fortress", "Titanite Shard"), + DS3LocationData("RS: Titanite Shard - woods, left of path from Halfway Fortress", "Titanite Shard"), - DS3LocationData("RS: Green Blossom (by deep water)", "Green Blossom x4"), - DS3LocationData("RS: Estus Shard (left of fire behind stronghold left room)", + DS3LocationData("RS: Green Blossom - by deep water", "Green Blossom x4"), + DS3LocationData("RS: Estus Shard - left of fire behind stronghold left room", "Estus Shard"), - DS3LocationData("RS: Ring of Sacrifice (stronghold, drop from right room balcony)", + DS3LocationData("RS: Ring of Sacrifice - stronghold, drop from right room balcony", "Ring of Sacrifice", hidden = True), # hidden fall - DS3LocationData("RS: Soul of an Unknown Traveler (drop along wall from Halfway Fortress)", + DS3LocationData("RS: Soul of an Unknown Traveler - drop along wall from Halfway Fortress", "Soul of an Unknown Traveler"), - DS3LocationData("RS: Fallen Knight Helm (water's edge by Farron Keep)", + DS3LocationData("RS: Fallen Knight Helm - water's edge by Farron Keep", "Fallen Knight Helm"), - DS3LocationData("RS: Fallen Knight Armor (water's edge by Farron Keep)", + DS3LocationData("RS: Fallen Knight Armor - water's edge by Farron Keep", "Fallen Knight Armor"), - DS3LocationData("RS: Fallen Knight Gauntlets (water's edge by Farron Keep)", + DS3LocationData("RS: Fallen Knight Gauntlets - water's edge by Farron Keep", "Fallen Knight Gauntlets"), - DS3LocationData("RS: Fallen Knight Trousers (water's edge by Farron Keep)", + DS3LocationData("RS: Fallen Knight Trousers - water's edge by Farron Keep", "Fallen Knight Trousers"), - DS3LocationData("RS: Heretic's Staff (stronghold left room)", "Heretic's Staff"), - DS3LocationData("RS: Large Soul of an Unknown Traveler (left of stairs to Farron Keep)", + DS3LocationData("RS: Heretic's Staff - stronghold left room", "Heretic's Staff"), + DS3LocationData("RS: Large Soul of an Unknown Traveler - left of stairs to Farron Keep", "Large Soul of an Unknown Traveler"), - DS3LocationData("RS: Conjurator Hood (deep water)", "Conjurator Hood"), - DS3LocationData("RS: Conjurator Robe (deep water)", "Conjurator Robe"), - DS3LocationData("RS: Conjurator Manchettes (deep water)", "Conjurator Manchettes"), - DS3LocationData("RS: Conjurator Boots (deep water)", "Conjurator Boots"), - DS3LocationData("RS: Soul of an Unknown Traveler (right of door to stronghold left)", + DS3LocationData("RS: Conjurator Hood - deep water", "Conjurator Hood"), + DS3LocationData("RS: Conjurator Robe - deep water", "Conjurator Robe"), + DS3LocationData("RS: Conjurator Manchettes - deep water", "Conjurator Manchettes"), + DS3LocationData("RS: Conjurator Boots - deep water", "Conjurator Boots"), + DS3LocationData("RS: Soul of an Unknown Traveler - right of door to stronghold left", "Soul of an Unknown Traveler"), - DS3LocationData("RS: Green Blossom (water beneath stronghold)", "Green Blossom x2"), - DS3LocationData("RS: Great Swamp Pyromancy Tome (deep water)", + DS3LocationData("RS: Green Blossom - water beneath stronghold", "Green Blossom x2"), + DS3LocationData("RS: Great Swamp Pyromancy Tome - deep water", "Great Swamp Pyromancy Tome"), - DS3LocationData("RS: Homeward Bone (balcony by Farron Keep)", "Homeward Bone x2"), - DS3LocationData("RS: Titanite Shard (woods, surrounded by enemies)", "Titanite Shard"), - DS3LocationData("RS: Twin Dragon Greatshield (woods by Crucifixion Woods bonfire)", + DS3LocationData("RS: Homeward Bone - balcony by Farron Keep", "Homeward Bone x2"), + DS3LocationData("RS: Titanite Shard - woods, surrounded by enemies", "Titanite Shard"), + DS3LocationData("RS: Twin Dragon Greatshield - woods by Crucifixion Woods bonfire", "Twin Dragon Greatshield"), - DS3LocationData("RS: Sorcerer Hood (water beneath stronghold)", "Sorcerer Hood", + DS3LocationData("RS: Sorcerer Hood - water beneath stronghold", "Sorcerer Hood", hidden = True), # Hidden fall - DS3LocationData("RS: Sorcerer Robe (water beneath stronghold)", "Sorcerer Robe", + DS3LocationData("RS: Sorcerer Robe - water beneath stronghold", "Sorcerer Robe", hidden = True), # Hidden fall - DS3LocationData("RS: Sorcerer Gloves (water beneath stronghold)", "Sorcerer Gloves", + DS3LocationData("RS: Sorcerer Gloves - water beneath stronghold", "Sorcerer Gloves", hidden = True), # Hidden fall - DS3LocationData("RS: Sorcerer Trousers (water beneath stronghold)", "Sorcerer Trousers", + DS3LocationData("RS: Sorcerer Trousers - water beneath stronghold", "Sorcerer Trousers", hidden = True), # Hidden fall - DS3LocationData("RS: Sage Ring (water beneath stronghold)", "Sage Ring", + DS3LocationData("RS: Sage Ring - water beneath stronghold", "Sage Ring", hidden = True), # Hidden fall - DS3LocationData("RS: Grass Crest Shield (water by Crucifixion Woods bonfire)", + DS3LocationData("RS: Grass Crest Shield - water by Crucifixion Woods bonfire", "Grass Crest Shield"), - DS3LocationData("RS: Ember (right of fire behind stronghold left room)", "Ember"), - DS3LocationData("RS: Blue Bug Pellet (broken stairs by Orbeck)", "Blue Bug Pellet x2"), - DS3LocationData("RS: Soul of an Unknown Traveler (road, by wagon)", + DS3LocationData("RS: Ember - right of fire behind stronghold left room", "Ember"), + DS3LocationData("RS: Blue Bug Pellet - broken stairs by Orbeck", "Blue Bug Pellet x2"), + DS3LocationData("RS: Soul of an Unknown Traveler - road, by wagon", "Soul of an Unknown Traveler"), - DS3LocationData("RS: Shriving Stone (road, by start)", "Shriving Stone"), - DS3LocationData("RS: Titanite Shard (road, on bridge after you go under)", + DS3LocationData("RS: Shriving Stone - road, by start", "Shriving Stone"), + DS3LocationData("RS: Titanite Shard - road, on bridge after you go under", "Titanite Shard"), - DS3LocationData("RS: Brigand Twindaggers (beneath road)", "Brigand Twindaggers"), - DS3LocationData("RS: Braille Divine Tome of Carim (drop from bridge to Halfway Fortress)", + DS3LocationData("RS: Brigand Twindaggers - beneath road", "Brigand Twindaggers"), + DS3LocationData("RS: Braille Divine Tome of Carim - drop from bridge to Halfway Fortress", "Braille Divine Tome of Carim", hidden = True), # Hidden fall - DS3LocationData("RS: Ember (right of Halfway Fortress entrance)", "Ember"), - DS3LocationData("RS: Sellsword Twinblades (keep perimeter)", "Sellsword Twinblades"), - DS3LocationData("RS: Golden Falcon Shield (path from stronghold right room to Farron Keep)", + DS3LocationData("RS: Ember - right of Halfway Fortress entrance", "Ember"), + DS3LocationData("RS: Sellsword Twinblades - keep perimeter", "Sellsword Twinblades"), + DS3LocationData("RS: Golden Falcon Shield - path from stronghold right room to Farron Keep", "Golden Falcon Shield"), - DS3LocationData("RS: Brigand Axe (beneath road)", "Brigand Axe"), - DS3LocationData("RS: Brigand Hood (beneath road)", "Brigand Hood"), - DS3LocationData("RS: Brigand Armor (beneath road)", "Brigand Armor"), - DS3LocationData("RS: Brigand Gauntlets (beneath road)", "Brigand Gauntlets"), - DS3LocationData("RS: Brigand Trousers (beneath road)", "Brigand Trousers"), - DS3LocationData("RS: Morne's Ring (drop from bridge to Halfway Fortress)", "Morne's Ring", + DS3LocationData("RS: Brigand Axe - beneath road", "Brigand Axe"), + DS3LocationData("RS: Brigand Hood - beneath road", "Brigand Hood"), + DS3LocationData("RS: Brigand Armor - beneath road", "Brigand Armor"), + DS3LocationData("RS: Brigand Gauntlets - beneath road", "Brigand Gauntlets"), + DS3LocationData("RS: Brigand Trousers - beneath road", "Brigand Trousers"), + DS3LocationData("RS: Morne's Ring - drop from bridge to Halfway Fortress", "Morne's Ring", hidden = True), # Hidden fall - DS3LocationData("RS: Sellsword Helm (keep perimeter balcony)", "Sellsword Helm"), - DS3LocationData("RS: Sellsword Armor (keep perimeter balcony)", "Sellsword Armor"), - DS3LocationData("RS: Sellsword Gauntlet (keep perimeter balcony)", "Sellsword Gauntlet"), - DS3LocationData("RS: Sellsword Trousers (keep perimeter balcony)", "Sellsword Trousers"), - DS3LocationData("RS: Farron Coal (keep perimeter)", "Farron Coal"), - DS3LocationData("RS: Chloranthy Ring+2 (road, drop across from carriage)", + DS3LocationData("RS: Sellsword Helm - keep perimeter balcony", "Sellsword Helm"), + DS3LocationData("RS: Sellsword Armor - keep perimeter balcony", "Sellsword Armor"), + DS3LocationData("RS: Sellsword Gauntlet - keep perimeter balcony", "Sellsword Gauntlet"), + DS3LocationData("RS: Sellsword Trousers - keep perimeter balcony", "Sellsword Trousers"), + DS3LocationData("RS: Farron Coal - keep perimeter", "Farron Coal"), + DS3LocationData("RS: Chloranthy Ring+2 - road, drop across from carriage", "Chloranthy Ring+2", hidden = True, ngp = True), # Hidden fall - DS3LocationData("RS: Lingering Dragoncrest Ring+1 (water)", "Lingering Dragoncrest Ring+1", + DS3LocationData("RS: Lingering Dragoncrest Ring+1 - water", "Lingering Dragoncrest Ring+1", ngp = True), - DS3LocationData("RS: Great Swamp Ring (miniboss drop, by Farron Keep)", + DS3LocationData("RS: Great Swamp Ring - miniboss drop, by Farron Keep", "Great Swamp Ring", miniboss = True), # Giant Crab drop - DS3LocationData("RS: Blue Sentinels (Horace)", "Blue Sentinels", + DS3LocationData("RS: Blue Sentinels - Horace", "Blue Sentinels", missable = True, npc = True), # Horace quest - DS3LocationData("RS: Crystal Gem (stronghold, lizard)", "Crystal Gem"), - DS3LocationData("RS: Fading Soul (woods by Crucifixion Woods bonfire)", "Fading Soul", + DS3LocationData("RS: Crystal Gem - stronghold, lizard", "Crystal Gem"), + DS3LocationData("RS: Fading Soul - woods by Crucifixion Woods bonfire", "Fading Soul", offline = '03,0:53300210::'), # Orbeck shop, all missable because he'll disappear if you don't talk to him for too long or # if you don't give him a scroll. - DS3LocationData("FS: Farron Dart (Orbeck)", "Farron Dart", + DS3LocationData("FS: Farron Dart - Orbeck", "Farron Dart", offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), - DS3LocationData("FS: Soul Arrow (Orbeck)", "Soul Arrow", + DS3LocationData("FS: Soul Arrow - Orbeck", "Soul Arrow", offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), - DS3LocationData("FS: Great Soul Arrow (Orbeck)", "Great Soul Arrow", missable = True, + DS3LocationData("FS: Great Soul Arrow - Orbeck", "Great Soul Arrow", missable = True, npc = True, shop = True), - DS3LocationData("FS: Heavy Soul Arrow (Orbeck)", "Heavy Soul Arrow", + DS3LocationData("FS: Heavy Soul Arrow - Orbeck", "Heavy Soul Arrow", offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), - DS3LocationData("FS: Great Heavy Soul Arrow (Orbeck)", "Great Heavy Soul Arrow", + DS3LocationData("FS: Great Heavy Soul Arrow - Orbeck", "Great Heavy Soul Arrow", missable = True, npc = True, shop = True), - DS3LocationData("FS: Magic Weapon (Orbeck)", "Magic Weapon", + DS3LocationData("FS: Magic Weapon - Orbeck", "Magic Weapon", offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), - DS3LocationData("FS: Magic Shield (Orbeck)", "Magic Shield", + DS3LocationData("FS: Magic Shield - Orbeck", "Magic Shield", offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, shop = True), - DS3LocationData("FS: Spook (Orbeck)", "Spook", missable = True, npc = True, shop = True), - DS3LocationData("FS: Aural Decoy (Orbeck)", "Aural Decoy", missable = True, npc = True, + DS3LocationData("FS: Spook - Orbeck", "Spook", missable = True, npc = True, shop = True), + DS3LocationData("FS: Aural Decoy - Orbeck", "Aural Decoy", missable = True, npc = True, shop = True), - DS3LocationData("FS: Soul Greatsword (Orbeck)", "Soul Greatsword", + DS3LocationData("FS: Soul Greatsword - Orbeck", "Soul Greatsword", offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True), - DS3LocationData("FS: Farron Flashsword (Orbeck)", "Farron Flashsword", missable = True, + DS3LocationData("FS: Farron Flashsword - Orbeck", "Farron Flashsword", missable = True, npc = True, shop = True), - DS3LocationData("FS: Pestilent Mist (Orbeck for any scroll)", "Pestilent Mist", + DS3LocationData("FS: Pestilent Mist - Orbeck for any scroll", "Pestilent Mist", missable = True, npc = True, shop = True), - DS3LocationData("FS: Great Farron Dart (Orbeck for Sage's Scroll)", "Great Farron Dart", + DS3LocationData("FS: Great Farron Dart - Orbeck for Sage's Scroll", "Great Farron Dart", missable = True, npc = True, shop = True), - DS3LocationData("FS: Farron Hail (Orbeck for Sage's Scroll)", "Farron Hail", + DS3LocationData("FS: Farron Hail - Orbeck for Sage's Scroll", "Farron Hail", missable = True, npc = True, shop = True), - DS3LocationData("FS: Homing Soulmass (Orbeck for Logan's Scroll)", "Homing Soulmass", + DS3LocationData("FS: Homing Soulmass - Orbeck for Logan's Scroll", "Homing Soulmass", missable = True, npc = True, shop = True), - DS3LocationData("FS: Soul Spear (Orbeck for Logan's Scroll)", "Soul Spear", + DS3LocationData("FS: Soul Spear - Orbeck for Logan's Scroll", "Soul Spear", missable = True, npc = True, shop = True), - DS3LocationData("FS: Homing Crystal Soulmass (Orbeck for Crystal Scroll)", + DS3LocationData("FS: Homing Crystal Soulmass - Orbeck for Crystal Scroll", "Homing Crystal Soulmass", missable = True, npc = True, shop = True), - DS3LocationData("FS: Crystal Soul Spear (Orbeck for Crystal Scroll)", "Crystal Soul Spear", + DS3LocationData("FS: Crystal Soul Spear - Orbeck for Crystal Scroll", "Crystal Soul Spear", missable = True, npc = True, shop = True), - DS3LocationData("FS: Crystal Magic Weapon (Orbeck for Crystal Scroll)", + DS3LocationData("FS: Crystal Magic Weapon - Orbeck for Crystal Scroll", "Crystal Magic Weapon", missable = True, npc = True, shop = True), - DS3LocationData("FS: Cast Light (Orbeck for Golden Scroll)", "Cast Light", missable = True, + DS3LocationData("FS: Cast Light - Orbeck for Golden Scroll", "Cast Light", missable = True, npc = True, shop = True), - DS3LocationData("FS: Twisted Wall of Light (Orbeck for Golden Scroll)", + DS3LocationData("FS: Twisted Wall of Light - Orbeck for Golden Scroll", "Twisted Wall of Light", missable = True, npc = True, shop = True), - DS3LocationData("FS: Hidden Weapon (Orbeck for Golden Scroll)", "Hidden Weapon", + DS3LocationData("FS: Hidden Weapon - Orbeck for Golden Scroll", "Hidden Weapon", missable = True, npc = True, shop = True), - DS3LocationData("FS: Hidden Body (Orbeck for Golden Scroll)", "Hidden Body", + DS3LocationData("FS: Hidden Body - Orbeck for Golden Scroll", "Hidden Body", missable = True, npc = True, shop = True), - DS3LocationData("FS: Repair (Orbeck for Golden Scroll)", "Repair", missable = True, + DS3LocationData("FS: Repair - Orbeck for Golden Scroll", "Repair", missable = True, npc = True, shop = True), - DS3LocationData("FS: Clandestine Coat (shop with Orbeck's Ashes)", "Clandestine Coat", + DS3LocationData("FS: Clandestine Coat - shop with Orbeck's Ashes", "Clandestine Coat", missable = True, npc = True, shop = True), # Shrine Handmaid with Orbeck's Ashes + reload - DS3LocationData("FS: Young Dragon Ring (Orbeck for one scroll and buying three spells)", + DS3LocationData("FS: Young Dragon Ring - Orbeck for one scroll and buying three spells", "Young Dragon Ring", missable = True, npc = True), - DS3LocationData("FS: Slumbering Dragoncrest Ring (Orbeck for buying four specific spells)", + DS3LocationData("FS: Slumbering Dragoncrest Ring - Orbeck for buying four specific spells", "Slumbering Dragoncrest Ring", missable = True, npc = True), DS3LocationData("RS -> CD", None), DS3LocationData("RS -> FK", None), # Shrine Handmaid after killing exiles - DS3LocationData("FS: Exile Mask (shop after killing NPCs in RS)", "Exile Mask", + DS3LocationData("FS: Exile Mask - shop after killing NPCs in RS", "Exile Mask", hostile_npc = True, shop = True, hidden = True), - DS3LocationData("FS: Exile Armor (shop after killing NPCs in RS)", "Exile Armor", + DS3LocationData("FS: Exile Armor - shop after killing NPCs in RS", "Exile Armor", hostile_npc = True, shop = True, hidden = True), - DS3LocationData("FS: Exile Gauntlets (shop after killing NPCs in RS)", "Exile Gauntlets", + DS3LocationData("FS: Exile Gauntlets - shop after killing NPCs in RS", "Exile Gauntlets", hostile_npc = True, shop = True, hidden = True), - DS3LocationData("FS: Exile Leggings (shop after killing NPCs in RS)", "Exile Leggings", + DS3LocationData("FS: Exile Leggings - shop after killing NPCs in RS", "Exile Leggings", hostile_npc = True, shop = True, hidden = True), # Shrine Handmaid after killing Crystal Sage - DS3LocationData("FS: Sage's Big Hat (shop after killing RS boss)", "Sage's Big Hat", + DS3LocationData("FS: Sage's Big Hat - shop after killing RS boss", "Sage's Big Hat", boss = True, shop = True), # Yuria of Londor for Orbeck's Ashes - DS3LocationData("FS: Morion Blade (Yuria for Orbeck's Ashes)", "Morion Blade", + DS3LocationData("FS: Morion Blade - Yuria for Orbeck's Ashes", "Morion Blade", missable = True, npc = True), ], "Cathedral of the Deep": [ - DS3LocationData("CD: Herald Helm (path, by fire)", "Herald Helm"), - DS3LocationData("CD: Herald Armor (path, by fire)", "Herald Armor"), - DS3LocationData("CD: Herald Gloves (path, by fire)", "Herald Gloves"), - DS3LocationData("CD: Herald Trousers (path, by fire)", "Herald Trousers"), - DS3LocationData("CD: Twinkling Titanite (path, lizard #1)", "Twinkling Titanite", + DS3LocationData("CD: Herald Helm - path, by fire", "Herald Helm"), + DS3LocationData("CD: Herald Armor - path, by fire", "Herald Armor"), + DS3LocationData("CD: Herald Gloves - path, by fire", "Herald Gloves"), + DS3LocationData("CD: Herald Trousers - path, by fire", "Herald Trousers"), + DS3LocationData("CD: Twinkling Titanite - path, lizard #1", "Twinkling Titanite", lizard = True), - DS3LocationData("CD: Twinkling Titanite (path, lizard #2)", "Twinkling Titanite", + DS3LocationData("CD: Twinkling Titanite - path, lizard #2", "Twinkling Titanite", lizard = True), - DS3LocationData("CD: Small Doll (boss drop)", "Small Doll", prominent = True, + DS3LocationData("CD: Small Doll - boss drop", "Small Doll", prominent = True, progression = True, boss = True), DS3LocationData("CD: Soul of the Deacons of the Deep", "Soul of the Deacons of the Deep", boss = True), - DS3LocationData("CD: Black Eye Orb (Rosaria from Leonhard's quest)", "Black Eye Orb", + DS3LocationData("CD: Black Eye Orb - Rosaria from Leonhard's quest", "Black Eye Orb", missable = True, npc = True), - DS3LocationData("CD: Winged Spear (kill Patches)", "Winged Spear", drop = True, + DS3LocationData("CD: Winged Spear - kill Patches", "Winged Spear", drop = True, missable = True), # Patches (kill) - DS3LocationData("CD: Spider Shield (NPC drop on path)", "Spider Shield", + DS3LocationData("CD: Spider Shield - NPC drop on path", "Spider Shield", hostile_npc = True), # Brigand - DS3LocationData("CD: Notched Whip (Cleansing Chapel)", "Notched Whip"), - DS3LocationData("CD: Titanite Shard (Cleansing Chapel windowsill, by miniboss)", + DS3LocationData("CD: Notched Whip - Cleansing Chapel", "Notched Whip"), + DS3LocationData("CD: Titanite Shard - Cleansing Chapel windowsill, by miniboss", "Titanite Shard"), - DS3LocationData("CD: Astora Greatsword (graveyard, left of entrance)", "Astora Greatsword"), - DS3LocationData("CD: Executioner's Greatsword (graveyard, far end)", + DS3LocationData("CD: Astora Greatsword - graveyard, left of entrance", "Astora Greatsword"), + DS3LocationData("CD: Executioner's Greatsword - graveyard, far end", "Executioner's Greatsword"), - DS3LocationData("CD: Undead Bone Shard (gravestone by white tree)", "Undead Bone Shard"), - DS3LocationData("CD: Curse Ward Greatshield (by ladder from white tree to moat)", + DS3LocationData("CD: Undead Bone Shard - gravestone by white tree", "Undead Bone Shard"), + DS3LocationData("CD: Curse Ward Greatshield - by ladder from white tree to moat", "Curse Ward Greatshield"), - DS3LocationData("CD: Titanite Shard (moat, far end)", "Titanite Shard"), - DS3LocationData("CD: Large Soul of an Unknown Traveler (lower roofs, semicircle balcony)", + DS3LocationData("CD: Titanite Shard - moat, far end", "Titanite Shard"), + DS3LocationData("CD: Large Soul of an Unknown Traveler - lower roofs, semicircle balcony", "Large Soul of an Unknown Traveler"), - DS3LocationData("CD: Paladin's Ashes (path, guarded by lower NPC)", "Paladin's Ashes", + DS3LocationData("CD: Paladin's Ashes - path, guarded by lower NPC", "Paladin's Ashes", progression = True), - DS3LocationData("CD: Arbalest (upper roofs, end of furthest buttress)", "Arbalest"), - DS3LocationData("CD: Ember (by back door)", "Ember"), - DS3LocationData("CD: Ember (side chapel upstairs, up ladder)", "Ember"), - DS3LocationData("CD: Poisonbite Ring (moat, hall past miniboss)", "Poisonbite Ring"), - DS3LocationData("CD: Drang Armor (main hall, east)", "Drang Armor"), - DS3LocationData("CD: Ember (edge of platform before boss)", "Ember"), - DS3LocationData("CD: Duel Charm (next to Patches in onion armor)", "Duel Charm x3"), - DS3LocationData("CD: Seek Guidance (side chapel upstairs)", "Seek Guidance"), - DS3LocationData("CD: Estus Shard (monument outside Cleansing Chapel)", "Estus Shard"), - DS3LocationData("CD: Maiden Hood (main hall south)", "Maiden Hood"), - DS3LocationData("CD: Maiden Robe (main hall south)", "Maiden Robe"), - DS3LocationData("CD: Maiden Gloves (main hall south)", "Maiden Gloves"), - DS3LocationData("CD: Maiden Skirt (main hall south)", "Maiden Skirt"), - DS3LocationData("CD: Pale Tongue (upper roofs, outdoors far end)", "Pale Tongue"), - DS3LocationData("CD: Fading Soul (graveyard, far end)", "Fading Soul"), - DS3LocationData("CD: Blessed Gem (upper roofs, rafters)", "Blessed Gem"), - DS3LocationData("CD: Red Bug Pellet (right of cathedral front doors)", "Red Bug Pellet"), - DS3LocationData("CD: Soul of a Nameless Soldier (main hall south)", + DS3LocationData("CD: Arbalest - upper roofs, end of furthest buttress", "Arbalest"), + DS3LocationData("CD: Ember - by back door", "Ember"), + DS3LocationData("CD: Ember - side chapel upstairs, up ladder", "Ember"), + DS3LocationData("CD: Poisonbite Ring - moat, hall past miniboss", "Poisonbite Ring"), + DS3LocationData("CD: Drang Armor - main hall, east", "Drang Armor"), + DS3LocationData("CD: Ember - edge of platform before boss", "Ember"), + DS3LocationData("CD: Duel Charm - next to Patches in onion armor", "Duel Charm x3"), + DS3LocationData("CD: Seek Guidance - side chapel upstairs", "Seek Guidance"), + DS3LocationData("CD: Estus Shard - monument outside Cleansing Chapel", "Estus Shard"), + DS3LocationData("CD: Maiden Hood - main hall south", "Maiden Hood"), + DS3LocationData("CD: Maiden Robe - main hall south", "Maiden Robe"), + DS3LocationData("CD: Maiden Gloves - main hall south", "Maiden Gloves"), + DS3LocationData("CD: Maiden Skirt - main hall south", "Maiden Skirt"), + DS3LocationData("CD: Pale Tongue - upper roofs, outdoors far end", "Pale Tongue"), + DS3LocationData("CD: Fading Soul - graveyard, far end", "Fading Soul"), + DS3LocationData("CD: Blessed Gem - upper roofs, rafters", "Blessed Gem"), + DS3LocationData("CD: Red Bug Pellet - right of cathedral front doors", "Red Bug Pellet"), + DS3LocationData("CD: Soul of a Nameless Soldier - main hall south", "Soul of a Nameless Soldier"), - DS3LocationData("CD: Duel Charm (by first elevator)", "Duel Charm"), - DS3LocationData("CD: Large Soul of an Unknown Traveler (main hall south, side path)", + DS3LocationData("CD: Duel Charm - by first elevator", "Duel Charm"), + DS3LocationData("CD: Large Soul of an Unknown Traveler - main hall south, side path", "Large Soul of an Unknown Traveler"), - DS3LocationData("CD: Ember (side chapel, miniboss room)", "Ember"), - DS3LocationData("CD: Repair Powder (by white tree)", "Repair Powder x3"), - DS3LocationData("CD: Large Soul of an Unknown Traveler (by white tree #1)", + DS3LocationData("CD: Ember - side chapel, miniboss room", "Ember"), + DS3LocationData("CD: Repair Powder - by white tree", "Repair Powder x3"), + DS3LocationData("CD: Large Soul of an Unknown Traveler - by white tree #1", "Large Soul of an Unknown Traveler"), - DS3LocationData("CD: Large Soul of an Unknown Traveler (by white tree #2)", + DS3LocationData("CD: Large Soul of an Unknown Traveler - by white tree #2", "Large Soul of an Unknown Traveler"), - DS3LocationData("CD: Undead Hunter Charm (lower roofs, up stairs between buttresses)", + DS3LocationData("CD: Undead Hunter Charm - lower roofs, up stairs between buttresses", "Undead Hunter Charm x3"), - DS3LocationData("CD: Red Bug Pellet (lower roofs, up stairs between buttresses)", + DS3LocationData("CD: Red Bug Pellet - lower roofs, up stairs between buttresses", "Red Bug Pellet x3"), - DS3LocationData("CD: Titanite Shard (outside building by white tree)", "Titanite Shard", + DS3LocationData("CD: Titanite Shard - outside building by white tree", "Titanite Shard", hidden = True), # Easily missable side path - DS3LocationData("CD: Titanite Shard (moat, up a slope)", "Titanite Shard"), - DS3LocationData("CD: Rusted Coin (left of cathedral front doors, behind crates)", + DS3LocationData("CD: Titanite Shard - moat, up a slope", "Titanite Shard"), + DS3LocationData("CD: Rusted Coin - left of cathedral front doors, behind crates", "Rusted Coin x2", hidden = True), - DS3LocationData("CD: Drang Hammers (main hall east)", "Drang Hammers"), - DS3LocationData("CD: Drang Shoes (main hall east)", "Drang Shoes"), - DS3LocationData("CD: Large Soul of an Unknown Traveler (main hall east)", + DS3LocationData("CD: Drang Hammers - main hall east", "Drang Hammers"), + DS3LocationData("CD: Drang Shoes - main hall east", "Drang Shoes"), + DS3LocationData("CD: Large Soul of an Unknown Traveler - main hall east", "Large Soul of an Unknown Traveler"), - DS3LocationData("CD: Pale Tongue (main hall east)", "Pale Tongue"), - DS3LocationData("CD: Drang Gauntlets (main hall east)", "Drang Gauntlets"), - DS3LocationData("CD: Soul of a Nameless Soldier (lower roofs, side room)", + DS3LocationData("CD: Pale Tongue - main hall east", "Pale Tongue"), + DS3LocationData("CD: Drang Gauntlets - main hall east", "Drang Gauntlets"), + DS3LocationData("CD: Soul of a Nameless Soldier - lower roofs, side room", "Soul of a Nameless Soldier"), - DS3LocationData("CD: Exploding Bolt (ledge above main hall south)", "Exploding Bolt x6"), - DS3LocationData("CD: Lloyd's Sword Ring (ledge above main hall south)", + DS3LocationData("CD: Exploding Bolt - ledge above main hall south", "Exploding Bolt x6"), + DS3LocationData("CD: Lloyd's Sword Ring - ledge above main hall south", "Lloyd's Sword Ring"), - DS3LocationData("CD: Soul of a Nameless Soldier (ledge above main hall south)", + DS3LocationData("CD: Soul of a Nameless Soldier - ledge above main hall south", "Soul of a Nameless Soldier"), - DS3LocationData("CD: Homeward Bone (outside main hall south door)", "Homeward Bone x2"), - DS3LocationData("CD: Deep Gem (down stairs by first elevator)", "Deep Gem"), - DS3LocationData("CD: Titanite Shard (path, side path by Cathedral of the Deep bonfire)", + DS3LocationData("CD: Homeward Bone - outside main hall south door", "Homeward Bone x2"), + DS3LocationData("CD: Deep Gem - down stairs by first elevator", "Deep Gem"), + DS3LocationData("CD: Titanite Shard - path, side path by Cathedral of the Deep bonfire", "Titanite Shard"), - DS3LocationData("CD: Large Soul of an Unknown Traveler (path, against outer wall)", + DS3LocationData("CD: Large Soul of an Unknown Traveler - path, against outer wall", "Large Soul of an Unknown Traveler"), # Before the stairs leading down into the Deacons fight - DS3LocationData("CD: Ring of the Evil Eye+1 (by stairs to boss)", "Ring of the Evil Eye+1", + DS3LocationData("CD: Ring of the Evil Eye+1 - by stairs to boss", "Ring of the Evil Eye+1", ngp = True), - DS3LocationData("CD: Ring of Favor+2 (upper roofs, on buttress)", "Ring of Favor+2", + DS3LocationData("CD: Ring of Favor+2 - upper roofs, on buttress", "Ring of Favor+2", hidden = True, ngp = True), # Hidden fall - DS3LocationData("CD: Crest Shield (path, drop down by Cathedral of the Deep bonfire)", + DS3LocationData("CD: Crest Shield - path, drop down by Cathedral of the Deep bonfire", "Crest Shield", hidden = True), # Hidden fall - DS3LocationData("CD: Young White Branch (by white tree #1)", "Young White Branch"), - DS3LocationData("CD: Young White Branch (by white tree #2)", "Young White Branch"), - DS3LocationData("CD: Saint-tree Bellvine (moat, by water)", "Saint-tree Bellvine"), - DS3LocationData("CD: Saint Bident (outside main hall south door)", "Saint Bident"), + DS3LocationData("CD: Young White Branch - by white tree #1", "Young White Branch"), + DS3LocationData("CD: Young White Branch - by white tree #2", "Young White Branch"), + DS3LocationData("CD: Saint-tree Bellvine - moat, by water", "Saint-tree Bellvine"), + DS3LocationData("CD: Saint Bident - outside main hall south door", "Saint Bident"), # Archdeacon set is hidden because you have to return to a cleared area - DS3LocationData("CD: Archdeacon White Crown (boss room after killing boss)", + DS3LocationData("CD: Archdeacon White Crown - boss room after killing boss", "Archdeacon White Crown", boss = True, hidden = True), - DS3LocationData("CD: Archdeacon Holy Garb (boss room after killing boss)", + DS3LocationData("CD: Archdeacon Holy Garb - boss room after killing boss", "Archdeacon Holy Garb", boss = True, hidden = True), - DS3LocationData("CD: Archdeacon Skirt (boss room after killing boss)", "Archdeacon Skirt", + DS3LocationData("CD: Archdeacon Skirt - boss room after killing boss", "Archdeacon Skirt", boss = True, hidden = True), # Heysel items may not be missable, but it's not clear what causes them to trigger - DS3LocationData("CD: Heysel Pick (Heysel Corpse-Grub in Rosaria's Bed Chamber)", + DS3LocationData("CD: Heysel Pick - Heysel Corpse-Grub in Rosaria's Bed Chamber", "Heysel Pick", missable = True), - DS3LocationData("CD: Xanthous Crown (Heysel Corpse-Grub in Rosaria's Bed Chamber)", + DS3LocationData("CD: Xanthous Crown - Heysel Corpse-Grub in Rosaria's Bed Chamber", "Xanthous Crown", missable = True), - DS3LocationData("CD: Deep Ring (upper roofs, passive mob drop in first tower)", "Deep Ring", + DS3LocationData("CD: Deep Ring - upper roofs, passive mob drop in first tower", "Deep Ring", drop = True, hidden = True), - DS3LocationData("CD: Deep Braille Divine Tome (mimic by side chapel)", + DS3LocationData("CD: Deep Braille Divine Tome - mimic by side chapel", "Deep Braille Divine Tome", mimic = True), - DS3LocationData("CD: Red Sign Soapstone (passive mob drop by Rosaria's Bed Chamber)", + DS3LocationData("CD: Red Sign Soapstone - passive mob drop by Rosaria's Bed Chamber", "Red Sign Soapstone", drop = True, hidden = True), - DS3LocationData("CD: Aldrich's Sapphire (side chapel, miniboss drop)", "Aldrich's Sapphire", + DS3LocationData("CD: Aldrich's Sapphire - side chapel, miniboss drop", "Aldrich's Sapphire", miniboss = True), # Deep Accursed Drop - DS3LocationData("CD: Titanite Scale (moat, miniboss drop)", "Titanite Scale", + DS3LocationData("CD: Titanite Scale - moat, miniboss drop", "Titanite Scale", miniboss = True), # Ravenous Crystal Lizard drop - DS3LocationData("CD: Twinkling Titanite (moat, lizard #1)", "Twinkling Titanite", + DS3LocationData("CD: Twinkling Titanite - moat, lizard #1", "Twinkling Titanite", lizard = True), - DS3LocationData("CD: Twinkling Titanite (moat, lizard #2)", "Twinkling Titanite", + DS3LocationData("CD: Twinkling Titanite - moat, lizard #2", "Twinkling Titanite", lizard = True), - DS3LocationData("CD: Rosaria's Fingers (Rosaria)", "Rosaria's Fingers", + DS3LocationData("CD: Rosaria's Fingers - Rosaria", "Rosaria's Fingers", hidden = True), # Hidden fall DS3LocationData("CD -> PW1", None), # Longfinger Kirk drops - DS3LocationData("CD: Barbed Straight Sword (Kirk drop)", "Barbed Straight Sword", + DS3LocationData("CD: Barbed Straight Sword - Kirk drop", "Barbed Straight Sword", missable = True, hostile_npc = True), - DS3LocationData("CD: Spiked Shield (Kirk drop)", "Spiked Shield", missable = True, + DS3LocationData("CD: Spiked Shield - Kirk drop", "Spiked Shield", missable = True, hostile_npc = True), # In Rosaria's Bed Chamber - DS3LocationData("CD: Helm of Thorns (Rosaria's Bed Chamber after killing Kirk)", + DS3LocationData("CD: Helm of Thorns - Rosaria's Bed Chamber after killing Kirk", "Helm of Thorns", missable = True, hostile_npc = True), - DS3LocationData("CD: Armor of Thorns (Rosaria's Bed Chamber after killing Kirk)", + DS3LocationData("CD: Armor of Thorns - Rosaria's Bed Chamber after killing Kirk", "Armor of Thorns", missable = True, hostile_npc = True), - DS3LocationData("CD: Gauntlets of Thorns (Rosaria's Bed Chamber after killing Kirk)", + DS3LocationData("CD: Gauntlets of Thorns - Rosaria's Bed Chamber after killing Kirk", "Gauntlets of Thorns", missable = True, hostile_npc = True), - DS3LocationData("CD: Leggings of Thorns (Rosaria's Bed Chamber after killing Kirk)", + DS3LocationData("CD: Leggings of Thorns - Rosaria's Bed Chamber after killing Kirk", "Leggings of Thorns", missable = True, hostile_npc = True), # Unbreakable Patches - DS3LocationData("CD: Rusted Coin (don't forgive Patches)", "Rusted Coin", + DS3LocationData("CD: Rusted Coin - don't forgive Patches", "Rusted Coin", missable = True, npc = True), - DS3LocationData("FS: Rusted Gold Coin (don't forgive Patches)", "Rusted Gold Coin", + DS3LocationData("FS: Rusted Gold Coin - don't forgive Patches", "Rusted Gold Coin", offline = '99,0:50006201::', missable = True, npc = True), # Don't forgive Patches - DS3LocationData("CD: Shotel (Patches)", "Shotel", missable = True, npc = True, shop = True), - DS3LocationData("CD: Ember (Patches)", "Ember", missable = True, npc = True, shop = True), - DS3LocationData("CD: Hidden Blessing (Patches)", "Hidden Blessing", missable = True, + DS3LocationData("CD: Shotel - Patches", "Shotel", missable = True, npc = True, shop = True), + DS3LocationData("CD: Ember - Patches", "Ember", missable = True, npc = True, shop = True), + DS3LocationData("CD: Hidden Blessing - Patches", "Hidden Blessing", missable = True, npc = True, shop = True), - DS3LocationData("CD: Horsehoof Ring (Patches)", "Horsehoof Ring", missable = True, + DS3LocationData("CD: Horsehoof Ring - Patches", "Horsehoof Ring", missable = True, npc = True, drop = True, shop = True), # (kill or buy) ], "Farron Keep": [ - DS3LocationData("FK: Lightning Spear (upper keep, far side of the wall)", + DS3LocationData("FK: Lightning Spear - upper keep, far side of the wall", "Lightning Spear"), - DS3LocationData("FK: Dragon Crest Shield (upper keep, far side of the wall)", + DS3LocationData("FK: Dragon Crest Shield - upper keep, far side of the wall", "Dragon Crest Shield"), DS3LocationData("FK: Soul of the Blood of the Wolf", "Soul of the Blood of the Wolf", boss = True), @@ -1188,555 +1188,555 @@ def __init__( "Cinders of a Lord - Abyss Watcher", offline = "03,0:50002100::", prominent = True, progression = True, boss = True), - DS3LocationData("FK: Manikin Claws (Londor Pale Shade drop)", "Manikin Claws", + DS3LocationData("FK: Manikin Claws - Londor Pale Shade drop", "Manikin Claws", missable = True, hostile_npc = True, npc = True), # Londor Pale Shade (if Yoel/Yuria hostile) - DS3LocationData("FK: Purple Moss Clump (keep ruins, ritual island)", + DS3LocationData("FK: Purple Moss Clump - keep ruins, ritual island", "Purple Moss Clump x2"), - DS3LocationData("FK: Purple Moss Clump (ramp directly in front of Farron Keep bonfire)", + DS3LocationData("FK: Purple Moss Clump - ramp directly in front of Farron Keep bonfire", "Purple Moss Clump x4"), - DS3LocationData("FK: Greatsword (ramp by keep ruins ritual island)", "Greatsword"), - DS3LocationData("FK: Hollow Gem (perimeter, drop down into swamp)", "Hollow Gem", + DS3LocationData("FK: Greatsword - ramp by keep ruins ritual island", "Greatsword"), + DS3LocationData("FK: Hollow Gem - perimeter, drop down into swamp", "Hollow Gem", hidden = True), - DS3LocationData("FK: Purple Moss Clump (Farron Keep bonfire, around right corner)", + DS3LocationData("FK: Purple Moss Clump - Farron Keep bonfire, around right corner", "Purple Moss Clump x3"), - DS3LocationData("FK: Undead Bone Shard (pavilion by keep ruins bonfire island)", + DS3LocationData("FK: Undead Bone Shard - pavilion by keep ruins bonfire island", "Undead Bone Shard"), - DS3LocationData("FK: Atonement (perimeter, drop down into swamp)", "Atonement", + DS3LocationData("FK: Atonement - perimeter, drop down into swamp", "Atonement", hidden = True), - DS3LocationData("FK: Titanite Shard (by ladder to keep proper)", "Titanite Shard"), - DS3LocationData("FK: Iron Flesh (Farron Keep bonfire, right after exit)", "Iron Flesh"), - DS3LocationData("FK: Stone Parma (near wall by left island)", "Stone Parma"), - DS3LocationData("FK: Rotten Pine Resin (left island, behind fire)", "Rotten Pine Resin x2"), - DS3LocationData("FK: Titanite Shard (between left island and keep ruins)", "Titanite Shard"), - DS3LocationData("FK: Rusted Gold Coin (right island, behind wall)", "Rusted Gold Coin", + DS3LocationData("FK: Titanite Shard - by ladder to keep proper", "Titanite Shard"), + DS3LocationData("FK: Iron Flesh - Farron Keep bonfire, right after exit", "Iron Flesh"), + DS3LocationData("FK: Stone Parma - near wall by left island", "Stone Parma"), + DS3LocationData("FK: Rotten Pine Resin - left island, behind fire", "Rotten Pine Resin x2"), + DS3LocationData("FK: Titanite Shard - between left island and keep ruins", "Titanite Shard"), + DS3LocationData("FK: Rusted Gold Coin - right island, behind wall", "Rusted Gold Coin", hidden = True), - DS3LocationData("FK: Nameless Knight Helm (corner of keep and right island)", + DS3LocationData("FK: Nameless Knight Helm - corner of keep and right island", "Nameless Knight Helm"), - DS3LocationData("FK: Nameless Knight Armor (corner of keep and right island)", + DS3LocationData("FK: Nameless Knight Armor - corner of keep and right island", "Nameless Knight Armor"), - DS3LocationData("FK: Nameless Knight Gauntlets (corner of keep and right island)", + DS3LocationData("FK: Nameless Knight Gauntlets - corner of keep and right island", "Nameless Knight Gauntlets"), - DS3LocationData("FK: Nameless Knight Leggings (corner of keep and right island)", + DS3LocationData("FK: Nameless Knight Leggings - corner of keep and right island", "Nameless Knight Leggings"), - DS3LocationData("FK: Shriving Stone (perimeter, just past stone doors)", "Shriving Stone"), - DS3LocationData("FK: Repair Powder (outside hidden cave)", "Repair Powder x4", + DS3LocationData("FK: Shriving Stone - perimeter, just past stone doors", "Shriving Stone"), + DS3LocationData("FK: Repair Powder - outside hidden cave", "Repair Powder x4", hidden = True), - DS3LocationData("FK: Golden Scroll (hidden cave)", "Golden Scroll", hidden = True), - DS3LocationData("FK: Sage's Scroll (near wall by keep ruins bonfire island)", + DS3LocationData("FK: Golden Scroll - hidden cave", "Golden Scroll", hidden = True), + DS3LocationData("FK: Sage's Scroll - near wall by keep ruins bonfire island", "Sage's Scroll"), - DS3LocationData("FK: Dreamchaser's Ashes (keep proper, illusory wall)", + DS3LocationData("FK: Dreamchaser's Ashes - keep proper, illusory wall", "Dreamchaser's Ashes", progression = True, hidden = True), - DS3LocationData("FK: Titanite Shard (keep ruins bonfire island, under ramp)", + DS3LocationData("FK: Titanite Shard - keep ruins bonfire island, under ramp", "Titanite Shard"), - DS3LocationData("FK: Wolf's Blood Swordgrass (by ladder to keep proper)", + DS3LocationData("FK: Wolf's Blood Swordgrass - by ladder to keep proper", "Wolf's Blood Swordgrass"), - DS3LocationData("FK: Great Magic Weapon (perimeter, by door to Road of Sacrifices)", + DS3LocationData("FK: Great Magic Weapon - perimeter, by door to Road of Sacrifices", "Great Magic Weapon"), - DS3LocationData("FK: Ember (perimeter, path to boss)", "Ember"), - DS3LocationData("FK: Titanite Shard (swamp by right island)", "Titanite Shard x2"), - DS3LocationData("FK: Titanite Shard (by left island stairs)", "Titanite Shard"), - DS3LocationData("FK: Titanite Shard (by keep ruins ritual island stairs)", "Titanite Shard"), - DS3LocationData("FK: Black Bug Pellet (perimeter, hill by boss door)", + DS3LocationData("FK: Ember - perimeter, path to boss", "Ember"), + DS3LocationData("FK: Titanite Shard - swamp by right island", "Titanite Shard x2"), + DS3LocationData("FK: Titanite Shard - by left island stairs", "Titanite Shard"), + DS3LocationData("FK: Titanite Shard - by keep ruins ritual island stairs", "Titanite Shard"), + DS3LocationData("FK: Black Bug Pellet - perimeter, hill by boss door", "Black Bug Pellet x3"), - DS3LocationData("FK: Rotten Pine Resin (outside pavilion by left island)", + DS3LocationData("FK: Rotten Pine Resin - outside pavilion by left island", "Rotten Pine Resin x4"), - DS3LocationData("FK: Poison Gem (near wall by keep ruins bridge)", "Poison Gem"), - DS3LocationData("FK: Ragged Mask (Farron Keep bonfire, around left corner)", "Ragged Mask"), - DS3LocationData("FK: Estus Shard (between Farron Keep bonfire and left island)", + DS3LocationData("FK: Poison Gem - near wall by keep ruins bridge", "Poison Gem"), + DS3LocationData("FK: Ragged Mask - Farron Keep bonfire, around left corner", "Ragged Mask"), + DS3LocationData("FK: Estus Shard - between Farron Keep bonfire and left island", "Estus Shard"), - DS3LocationData("FK: Homeward Bone (right island, behind fire)", "Homeward Bone x2"), - DS3LocationData("FK: Titanite Shard (Farron Keep bonfire, left after exit)", + DS3LocationData("FK: Homeward Bone - right island, behind fire", "Homeward Bone x2"), + DS3LocationData("FK: Titanite Shard - Farron Keep bonfire, left after exit", "Titanite Shard"), - DS3LocationData("FK: Large Soul of a Nameless Soldier (corner of keep and right island)", + DS3LocationData("FK: Large Soul of a Nameless Soldier - corner of keep and right island", "Large Soul of a Nameless Soldier", hidden = True), # Tricky corner to spot - DS3LocationData("FK: Prism Stone (by left island stairs)", "Prism Stone x10"), - DS3LocationData("FK: Large Soul of a Nameless Soldier (near wall by right island)", + DS3LocationData("FK: Prism Stone - by left island stairs", "Prism Stone x10"), + DS3LocationData("FK: Large Soul of a Nameless Soldier - near wall by right island", "Large Soul of a Nameless Soldier"), - DS3LocationData("FK: Sage's Coal (pavilion by left island)", "Sage's Coal"), - DS3LocationData("FK: Gold Pine Bundle (by white tree)", "Gold Pine Bundle x6"), - DS3LocationData("FK: Ember (by white tree)", "Ember"), - DS3LocationData("FK: Soul of a Nameless Soldier (by white tree)", "Soul of a Nameless Soldier"), - DS3LocationData("FK: Large Soul of an Unknown Traveler (by white tree)", + DS3LocationData("FK: Sage's Coal - pavilion by left island", "Sage's Coal"), + DS3LocationData("FK: Gold Pine Bundle - by white tree", "Gold Pine Bundle x6"), + DS3LocationData("FK: Ember - by white tree", "Ember"), + DS3LocationData("FK: Soul of a Nameless Soldier - by white tree", "Soul of a Nameless Soldier"), + DS3LocationData("FK: Large Soul of an Unknown Traveler - by white tree", "Large Soul of an Unknown Traveler"), - DS3LocationData("FK: Greataxe (upper keep, by miniboss)", "Greataxe"), - DS3LocationData("FK: Ember (upper keep, by miniboss #1)", "Ember"), - DS3LocationData("FK: Ember (upper keep, by miniboss #2)", "Ember"), - DS3LocationData("FK: Dark Stoneplate Ring+2 (keep ruins ritual island, behind wall)", + DS3LocationData("FK: Greataxe - upper keep, by miniboss", "Greataxe"), + DS3LocationData("FK: Ember - upper keep, by miniboss #1", "Ember"), + DS3LocationData("FK: Ember - upper keep, by miniboss #2", "Ember"), + DS3LocationData("FK: Dark Stoneplate Ring+2 - keep ruins ritual island, behind wall", "Dark Stoneplate Ring+2", ngp = True, hidden = True), - DS3LocationData("FK: Magic Stoneplate Ring+1 (between right island and wall)", + DS3LocationData("FK: Magic Stoneplate Ring+1 - between right island and wall", "Magic Stoneplate Ring+1", ngp = True), - DS3LocationData("FK: Wolf Ring+1 (keep ruins bonfire island, outside building)", + DS3LocationData("FK: Wolf Ring+1 - keep ruins bonfire island, outside building", "Wolf Ring+1", ngp = True), - DS3LocationData("FK: Antiquated Dress (hidden cave)", "Antiquated Dress", hidden = True), - DS3LocationData("FK: Antiquated Gloves (hidden cave)", "Antiquated Gloves", hidden = True), - DS3LocationData("FK: Antiquated Skirt (hidden cave)", "Antiquated Skirt", hidden = True), - DS3LocationData("FK: Sunlight Talisman (estus soup island, by ladder to keep proper)", + DS3LocationData("FK: Antiquated Dress - hidden cave", "Antiquated Dress", hidden = True), + DS3LocationData("FK: Antiquated Gloves - hidden cave", "Antiquated Gloves", hidden = True), + DS3LocationData("FK: Antiquated Skirt - hidden cave", "Antiquated Skirt", hidden = True), + DS3LocationData("FK: Sunlight Talisman - estus soup island, by ladder to keep proper", "Sunlight Talisman"), - DS3LocationData("FK: Young White Branch (by white tree #1)", "Young White Branch"), - DS3LocationData("FK: Young White Branch (by white tree #2)", "Young White Branch"), - DS3LocationData("FK: Crown of Dusk (by white tree)", "Crown of Dusk"), - DS3LocationData("FK: Lingering Dragoncrest Ring (by white tree, miniboss drop)", + DS3LocationData("FK: Young White Branch - by white tree #1", "Young White Branch"), + DS3LocationData("FK: Young White Branch - by white tree #2", "Young White Branch"), + DS3LocationData("FK: Crown of Dusk - by white tree", "Crown of Dusk"), + DS3LocationData("FK: Lingering Dragoncrest Ring - by white tree, miniboss drop", "Lingering Dragoncrest Ring", miniboss = True), # Great Crab drop - DS3LocationData("FK: Pharis's Hat (miniboss drop, by keep ruins near wall)", + DS3LocationData("FK: Pharis's Hat - miniboss drop, by keep ruins near wall", "Pharis's Hat", miniboss = True), # Elder Ghru drop - DS3LocationData("FK: Black Bow of Pharis (miniboss drop, by keep ruins near wall)", + DS3LocationData("FK: Black Bow of Pharis - miniboss drop, by keep ruins near wall", "Black Bow of Pharis", miniboss = True), # Elder Ghru drop - DS3LocationData("FK: Titanite Scale (perimeter, miniboss drop)", "Titanite Scale x2", + DS3LocationData("FK: Titanite Scale - perimeter, miniboss drop", "Titanite Scale x2", miniboss = True), # Ravenous Crystal Lizard drop - DS3LocationData("FK: Large Titanite Shard (upper keep, lizard in open)", + DS3LocationData("FK: Large Titanite Shard - upper keep, lizard in open", "Large Titanite Shard", lizard = True), - DS3LocationData("FK: Large Titanite Shard (upper keep, lizard by wyvern)", + DS3LocationData("FK: Large Titanite Shard - upper keep, lizard by wyvern", "Large Titanite Shard", lizard = True), - DS3LocationData("FK: Heavy Gem (upper keep, lizard on stairs)", "Heavy Gem", lizard = True), - DS3LocationData("FK: Twinkling Titanite (keep proper, lizard)", "Twinkling Titanite", + DS3LocationData("FK: Heavy Gem - upper keep, lizard on stairs", "Heavy Gem", lizard = True), + DS3LocationData("FK: Twinkling Titanite - keep proper, lizard", "Twinkling Titanite", lizard = True), - DS3LocationData("FK: Soul of a Stray Demon (upper keep, miniboss drop)", + DS3LocationData("FK: Soul of a Stray Demon - upper keep, miniboss drop", "Soul of a Stray Demon", miniboss = True), - DS3LocationData("FK: Watchdogs of Farron (Old Wolf)", "Watchdogs of Farron"), - DS3LocationData("FS: Hawkwood's Shield (Hawkwood)", "Hawkwood's Shield", missable = True, + DS3LocationData("FK: Watchdogs of Farron - Old Wolf", "Watchdogs of Farron"), + DS3LocationData("FS: Hawkwood's Shield - Hawkwood", "Hawkwood's Shield", missable = True, npc = True), # Hawkwood (quest, after Greatwood, Sage, Watchers, and Deacons) - DS3LocationData("US: Hawk Ring (Giant Archer)", "Hawk Ring", drop = True, + DS3LocationData("US: Hawk Ring - Giant Archer", "Hawk Ring", drop = True, npc = True), # Giant archer (kill or quest), here because you need to # collect all seven White Branch locations to get it peacefully DS3LocationData("FK -> CC", None), # Hawkwood after killing Abyss Watchers - DS3LocationData("FS: Farron Ring (Hawkwood)", "Farron Ring", + DS3LocationData("FS: Farron Ring - Hawkwood", "Farron Ring", missable = True, npc = True), # Shrine Handmaid after killing Abyss Watchers - DS3LocationData("FS: Undead Legion Helm (shop after killing FK boss)", "Undead Legion Helm", + DS3LocationData("FS: Undead Legion Helm - shop after killing FK boss", "Undead Legion Helm", boss = True, shop = True), - DS3LocationData("FS: Undead Legion Armor (shop after killing FK boss)", + DS3LocationData("FS: Undead Legion Armor - shop after killing FK boss", "Undead Legion Armor", boss = True, shop = True), - DS3LocationData("FS: Undead Legion Gauntlet (shop after killing FK boss)", + DS3LocationData("FS: Undead Legion Gauntlet - shop after killing FK boss", "Undead Legion Gauntlet", boss = True, shop = True), - DS3LocationData("FS: Undead Legion Leggings (shop after killing FK boss)", + DS3LocationData("FS: Undead Legion Leggings - shop after killing FK boss", "Undead Legion Leggings", boss = True, shop = True), # Appears after killing Havel Knight in Archdragon Peak - DS3LocationData("FK: Havel's Helm (upper keep, after killing AP belfry roof NPC)", + DS3LocationData("FK: Havel's Helm - upper keep, after killing AP belfry roof NPC", "Havel's Helm", hidden = True, hostile_npc = True), - DS3LocationData("FK: Havel's Armor (upper keep, after killing AP belfry roof NPC)", + DS3LocationData("FK: Havel's Armor - upper keep, after killing AP belfry roof NPC", "Havel's Armor", hidden = True, hostile_npc = True), - DS3LocationData("FK: Havel's Gauntlets (upper keep, after killing AP belfry roof NPC)", + DS3LocationData("FK: Havel's Gauntlets - upper keep, after killing AP belfry roof NPC", "Havel's Gauntlets", hidden = True, hostile_npc = True), - DS3LocationData("FK: Havel's Leggings (upper keep, after killing AP belfry roof NPC)", + DS3LocationData("FK: Havel's Leggings - upper keep, after killing AP belfry roof NPC", "Havel's Leggings", hidden = True, hostile_npc = True), ], "Catacombs of Carthus": [ DS3LocationData("CC: Soul of High Lord Wolnir", "Soul of High Lord Wolnir", prominent = True, boss = True), - DS3LocationData("CC: Carthus Rouge (atrium upper, left after entrance)", + DS3LocationData("CC: Carthus Rouge - atrium upper, left after entrance", "Carthus Rouge x2"), - DS3LocationData("CC: Sharp Gem (atrium lower, right before exit)", "Sharp Gem"), - DS3LocationData("CC: Soul of a Nameless Soldier (atrium lower, down hall)", + DS3LocationData("CC: Sharp Gem - atrium lower, right before exit", "Sharp Gem"), + DS3LocationData("CC: Soul of a Nameless Soldier - atrium lower, down hall", "Soul of a Nameless Soldier"), - DS3LocationData("CC: Titanite Shard (atrium lower, corner by stairs)", "Titanite Shard x2"), - DS3LocationData("CC: Bloodred Moss Clump (atrium lower, down more stairs)", + DS3LocationData("CC: Titanite Shard - atrium lower, corner by stairs", "Titanite Shard x2"), + DS3LocationData("CC: Bloodred Moss Clump - atrium lower, down more stairs", "Bloodred Moss Clump x3"), - DS3LocationData("CC: Carthus Milkring (crypt upper, among pots)", "Carthus Milkring"), - DS3LocationData("CC: Ember (atrium, on long stairway)", "Ember"), - DS3LocationData("CC: Carthus Rouge (crypt across, corner)", "Carthus Rouge x3"), - DS3LocationData("CC: Ember (crypt upper, end of hall past hole)", "Ember"), - DS3LocationData("CC: Carthus Bloodring (crypt lower, end of side hall)", "Carthus Bloodring"), - DS3LocationData("CC: Titanite Shard (crypt lower, left of entrance)", "Titanite Shard x2"), - DS3LocationData("CC: Titanite Shard (crypt lower, start of side hall)", "Titanite Shard x2"), - DS3LocationData("CC: Ember (crypt lower, shortcut to cavern)", "Ember"), - DS3LocationData("CC: Carthus Pyromancy Tome (atrium lower, jump from bridge)", + DS3LocationData("CC: Carthus Milkring - crypt upper, among pots", "Carthus Milkring"), + DS3LocationData("CC: Ember - atrium, on long stairway", "Ember"), + DS3LocationData("CC: Carthus Rouge - crypt across, corner", "Carthus Rouge x3"), + DS3LocationData("CC: Ember - crypt upper, end of hall past hole", "Ember"), + DS3LocationData("CC: Carthus Bloodring - crypt lower, end of side hall", "Carthus Bloodring"), + DS3LocationData("CC: Titanite Shard - crypt lower, left of entrance", "Titanite Shard x2"), + DS3LocationData("CC: Titanite Shard - crypt lower, start of side hall", "Titanite Shard x2"), + DS3LocationData("CC: Ember - crypt lower, shortcut to cavern", "Ember"), + DS3LocationData("CC: Carthus Pyromancy Tome - atrium lower, jump from bridge", "Carthus Pyromancy Tome", hidden = True), # Behind illusory wall or hidden drop - DS3LocationData("CC: Large Titanite Shard (crypt upper, skeleton ball hall)", + DS3LocationData("CC: Large Titanite Shard - crypt upper, skeleton ball hall", "Large Titanite Shard"), - DS3LocationData("CC: Large Titanite Shard (crypt across, middle hall)", + DS3LocationData("CC: Large Titanite Shard - crypt across, middle hall", "Large Titanite Shard"), - DS3LocationData("CC: Yellow Bug Pellet (cavern, on overlook)", "Yellow Bug Pellet x3"), - DS3LocationData("CC: Large Soul of a Nameless Soldier (cavern, before bridge)", + DS3LocationData("CC: Yellow Bug Pellet - cavern, on overlook", "Yellow Bug Pellet x3"), + DS3LocationData("CC: Large Soul of a Nameless Soldier - cavern, before bridge", "Large Soul of a Nameless Soldier"), - DS3LocationData("CC: Black Bug Pellet (cavern, before bridge)", "Black Bug Pellet x2"), - DS3LocationData("CC: Grave Warden's Ashes (crypt across, corner)", "Grave Warden's Ashes", + DS3LocationData("CC: Black Bug Pellet - cavern, before bridge", "Black Bug Pellet x2"), + DS3LocationData("CC: Grave Warden's Ashes - crypt across, corner", "Grave Warden's Ashes", progression = True), - DS3LocationData("CC: Large Titanite Shard (tomb lower)", "Large Titanite Shard"), - DS3LocationData("CC: Large Soul of a Nameless Soldier (tomb lower)", + DS3LocationData("CC: Large Titanite Shard - tomb lower", "Large Titanite Shard"), + DS3LocationData("CC: Large Soul of a Nameless Soldier - tomb lower", "Large Soul of a Nameless Soldier"), - DS3LocationData("CC: Old Sage's Blindfold (tomb, hall before bonfire)", + DS3LocationData("CC: Old Sage's Blindfold - tomb, hall before bonfire", "Old Sage's Blindfold"), - DS3LocationData("CC: Witch's Ring (tomb, hall before bonfire)", "Witch's Ring"), - DS3LocationData("CC: Soul of a Nameless Soldier (atrium upper, up more stairs)", + DS3LocationData("CC: Witch's Ring - tomb, hall before bonfire", "Witch's Ring"), + DS3LocationData("CC: Soul of a Nameless Soldier - atrium upper, up more stairs", "Soul of a Nameless Soldier"), - DS3LocationData("CC: Grave Warden Pyromancy Tome (boss arena)", + DS3LocationData("CC: Grave Warden Pyromancy Tome - boss arena", "Grave Warden Pyromancy Tome"), - DS3LocationData("CC: Large Soul of an Unknown Traveler (crypt upper, hall middle)", + DS3LocationData("CC: Large Soul of an Unknown Traveler - crypt upper, hall middle", "Large Soul of an Unknown Traveler"), - DS3LocationData("CC: Ring of Steel Protection+2 (atrium upper, drop onto pillar)", + DS3LocationData("CC: Ring of Steel Protection+2 - atrium upper, drop onto pillar", "Ring of Steel Protection+2", ngp = True), - DS3LocationData("CC: Thunder Stoneplate Ring+1 (crypt upper, among pots)", + DS3LocationData("CC: Thunder Stoneplate Ring+1 - crypt upper, among pots", "Thunder Stoneplate Ring+1", ngp = True), - DS3LocationData("CC: Undead Bone Shard (crypt upper, skeleton ball drop)", + DS3LocationData("CC: Undead Bone Shard - crypt upper, skeleton ball drop", "Undead Bone Shard", hidden = True), # Skeleton Ball puzzle - DS3LocationData("CC: Dark Gem (crypt lower, skeleton ball drop)", "Dark Gem", + DS3LocationData("CC: Dark Gem - crypt lower, skeleton ball drop", "Dark Gem", hidden = True), # Skeleton Ball puzzle - DS3LocationData("CC: Black Blade (tomb, mimic)", "Black Blade", mimic = True), - DS3LocationData("CC: Soul of a Demon (tomb, miniboss drop)", "Soul of a Demon", + DS3LocationData("CC: Black Blade - tomb, mimic", "Black Blade", mimic = True), + DS3LocationData("CC: Soul of a Demon - tomb, miniboss drop", "Soul of a Demon", miniboss = True), - DS3LocationData("CC: Twinkling Titanite (atrium lower, lizard down more stairs)", + DS3LocationData("CC: Twinkling Titanite - atrium lower, lizard down more stairs", "Twinkling Titanite", lizard = True), - DS3LocationData("CC: Fire Gem (cavern, lizard)", "Fire Gem", lizard = True), - DS3LocationData("CC: Homeward Bone (bridge)", "Homeward Bone"), - DS3LocationData("CC: Pontiff's Right Eye (bridge, miniboss drop)", + DS3LocationData("CC: Fire Gem - cavern, lizard", "Fire Gem", lizard = True), + DS3LocationData("CC: Homeward Bone - bridge", "Homeward Bone"), + DS3LocationData("CC: Pontiff's Right Eye - bridge, miniboss drop", "Pontiff's Right Eye", miniboss = True), # Sulyvahn's Beast drop # Shrine Handmaid after killing High Lord Wolnir - DS3LocationData("FS: Wolnir's Crown (shop after killing CC boss)", "Wolnir's Crown", + DS3LocationData("FS: Wolnir's Crown - shop after killing CC boss", "Wolnir's Crown", boss = True, shop = True), ], "Smouldering Lake": [ DS3LocationData("SL: Soul of the Old Demon King", "Soul of the Old Demon King", prominent = True, boss = True), - DS3LocationData("SL: Fume Ultra Greatsword (ruins basement, NPC drop)", + DS3LocationData("SL: Fume Ultra Greatsword - ruins basement, NPC drop", "Fume Ultra Greatsword", hostile_npc = True), # Knight Slayer Tsorig drop - DS3LocationData("SL: Black Iron Greatshield (ruins basement, NPC drop)", + DS3LocationData("SL: Black Iron Greatshield - ruins basement, NPC drop", "Black Iron Greatshield", hostile_npc = True), # Knight Slayer Tsorig drop - DS3LocationData("SL: Large Titanite Shard (ledge by Demon Ruins bonfire)", + DS3LocationData("SL: Large Titanite Shard - ledge by Demon Ruins bonfire", "Large Titanite Shard"), - DS3LocationData("SL: Large Titanite Shard (lake, by entrance)", "Large Titanite Shard"), - DS3LocationData("SL: Large Titanite Shard (lake, straight from entrance)", + DS3LocationData("SL: Large Titanite Shard - lake, by entrance", "Large Titanite Shard"), + DS3LocationData("SL: Large Titanite Shard - lake, straight from entrance", "Large Titanite Shard"), - DS3LocationData("SL: Large Titanite Shard (lake, by tree #1)", "Large Titanite Shard"), - DS3LocationData("SL: Large Titanite Shard (lake, by miniboss)", "Large Titanite Shard"), - DS3LocationData("SL: Yellow Bug Pellet (side lake)", "Yellow Bug Pellet x2"), - DS3LocationData("SL: Large Titanite Shard (side lake #1)", "Large Titanite Shard"), - DS3LocationData("SL: Large Titanite Shard (side lake #2)", "Large Titanite Shard"), - DS3LocationData("SL: Large Titanite Shard (lake, by tree #2)", "Large Titanite Shard"), - DS3LocationData("SL: Speckled Stoneplate Ring (lake, ballista breaks bricks)", + DS3LocationData("SL: Large Titanite Shard - lake, by tree #1", "Large Titanite Shard"), + DS3LocationData("SL: Large Titanite Shard - lake, by miniboss", "Large Titanite Shard"), + DS3LocationData("SL: Yellow Bug Pellet - side lake", "Yellow Bug Pellet x2"), + DS3LocationData("SL: Large Titanite Shard - side lake #1", "Large Titanite Shard"), + DS3LocationData("SL: Large Titanite Shard - side lake #2", "Large Titanite Shard"), + DS3LocationData("SL: Large Titanite Shard - lake, by tree #2", "Large Titanite Shard"), + DS3LocationData("SL: Speckled Stoneplate Ring - lake, ballista breaks bricks", "Speckled Stoneplate Ring", hidden = True), # Requires careful ballista shot - DS3LocationData("SL: Homeward Bone (path to ballista)", "Homeward Bone x2"), - DS3LocationData("SL: Ember (ruins main upper, hall end by hole)", "Ember"), - DS3LocationData("SL: Chaos Gem (lake, far end by mob)", "Chaos Gem"), - DS3LocationData("SL: Ember (ruins main lower, path to antechamber)", "Ember"), - DS3LocationData("SL: Izalith Pyromancy Tome (antechamber, room near bonfire)", + DS3LocationData("SL: Homeward Bone - path to ballista", "Homeward Bone x2"), + DS3LocationData("SL: Ember - ruins main upper, hall end by hole", "Ember"), + DS3LocationData("SL: Chaos Gem - lake, far end by mob", "Chaos Gem"), + DS3LocationData("SL: Ember - ruins main lower, path to antechamber", "Ember"), + DS3LocationData("SL: Izalith Pyromancy Tome - antechamber, room near bonfire", "Izalith Pyromancy Tome"), - DS3LocationData("SL: Black Knight Sword (ruins main lower, illusory wall in far hall)", + DS3LocationData("SL: Black Knight Sword - ruins main lower, illusory wall in far hall", "Black Knight Sword", hidden = True), - DS3LocationData("SL: Ember (ruins main upper, just after entrance)", "Ember"), - DS3LocationData("SL: Quelana Pyromancy Tome (ruins main lower, illusory wall in grey room)", + DS3LocationData("SL: Ember - ruins main upper, just after entrance", "Ember"), + DS3LocationData("SL: Quelana Pyromancy Tome - ruins main lower, illusory wall in grey room", "Quelana Pyromancy Tome", hidden = True), - DS3LocationData("SL: Izalith Staff (ruins basement, second illusory wall behind chest)", + DS3LocationData("SL: Izalith Staff - ruins basement, second illusory wall behind chest", "Izalith Staff", hidden = True), - DS3LocationData("SL: White Hair Talisman (ruins main lower, in lava)", + DS3LocationData("SL: White Hair Talisman - ruins main lower, in lava", "White Hair Talisman", missable = True), # This may not even be possible to get without enough fire # protection gear which the player may not have - DS3LocationData("SL: Toxic Mist (ruins main lower, in lava)", "Toxic Mist", + DS3LocationData("SL: Toxic Mist - ruins main lower, in lava", "Toxic Mist", missable = True), # This is _probably_ reachable with normal gear, but it # still sucks and will probably force a death. - DS3LocationData("SL: Undead Bone Shard (ruins main lower, left after stairs)", + DS3LocationData("SL: Undead Bone Shard - ruins main lower, left after stairs", "Undead Bone Shard"), - DS3LocationData("SL: Titanite Scale (ruins basement, path to lava)", "Titanite Scale"), - DS3LocationData("SL: Shield of Want (lake, by miniboss)", "Shield of Want"), - DS3LocationData("SL: Soul of a Crestfallen Knight (ruins basement, above lava)", + DS3LocationData("SL: Titanite Scale - ruins basement, path to lava", "Titanite Scale"), + DS3LocationData("SL: Shield of Want - lake, by miniboss", "Shield of Want"), + DS3LocationData("SL: Soul of a Crestfallen Knight - ruins basement, above lava", "Soul of a Crestfallen Knight"), # Lava items are missable because they require a complex set of armor, rings, spells, and # undead bone shards to reliably access without dying. - DS3LocationData("SL: Ember (ruins basement, in lava)", "Ember", missable = True), # In lava - DS3LocationData("SL: Sacred Flame (ruins basement, in lava)", "Sacred Flame", + DS3LocationData("SL: Ember - ruins basement, in lava", "Ember", missable = True), # In lava + DS3LocationData("SL: Sacred Flame - ruins basement, in lava", "Sacred Flame", missable = True), # In lava - DS3LocationData("SL: Dragonrider Bow (by ladder from ruins basement to ballista)", + DS3LocationData("SL: Dragonrider Bow - by ladder from ruins basement to ballista", "Dragonrider Bow", hidden = True), # Hidden fall - DS3LocationData("SL: Estus Shard (antechamber, illusory wall)", "Estus Shard", + DS3LocationData("SL: Estus Shard - antechamber, illusory wall", "Estus Shard", hidden = True), - DS3LocationData("SL: Bloodbite Ring+1 (behind ballista)", "Bloodbite Ring+1", ngp = True), - DS3LocationData("SL: Flame Stoneplate Ring+2 (ruins main lower, illusory wall in far hall)", + DS3LocationData("SL: Bloodbite Ring+1 - behind ballista", "Bloodbite Ring+1", ngp = True), + DS3LocationData("SL: Flame Stoneplate Ring+2 - ruins main lower, illusory wall in far hall", "Flame Stoneplate Ring+2", ngp = True, hidden = True), - DS3LocationData("SL: Large Titanite Shard (ruins basement, illusory wall in upper hall)", + DS3LocationData("SL: Large Titanite Shard - ruins basement, illusory wall in upper hall", "Large Titanite Shard x3", hidden = True), - DS3LocationData("SL: Undead Bone Shard (lake, miniboss drop)", "Undead Bone Shard", + DS3LocationData("SL: Undead Bone Shard - lake, miniboss drop", "Undead Bone Shard", miniboss = True), # Sand Worm drop - DS3LocationData("SL: Lightning Stake (lake, miniboss drop)", "Lightning Stake", + DS3LocationData("SL: Lightning Stake - lake, miniboss drop", "Lightning Stake", miniboss = True), # Sand Worm drop - DS3LocationData("SL: Twinkling Titanite (path to side lake, lizard)", "Twinkling Titanite", + DS3LocationData("SL: Twinkling Titanite - path to side lake, lizard", "Twinkling Titanite", lizard = True), - DS3LocationData("SL: Titanite Chunk (path to side lake, lizard)", "Titanite Chunk", + DS3LocationData("SL: Titanite Chunk - path to side lake, lizard", "Titanite Chunk", lizard = True), - DS3LocationData("SL: Chaos Gem (antechamber, lizard at end of long hall)", "Chaos Gem", + DS3LocationData("SL: Chaos Gem - antechamber, lizard at end of long hall", "Chaos Gem", lizard = True), - DS3LocationData("SL: Knight Slayer's Ring (ruins basement, NPC drop)", + DS3LocationData("SL: Knight Slayer's Ring - ruins basement, NPC drop", "Knight Slayer's Ring", hostile_npc = True), # Knight Slayer Tsorig drop # Horace the Hushed # These are listed here even though you can kill Horace in the Road of Sacrifices because # the player may want to complete his and Anri's quest first. - DS3LocationData("SL: Llewellyn Shield (Horace drop)", "Llewellyn Shield", npc = True, + DS3LocationData("SL: Llewellyn Shield - Horace drop", "Llewellyn Shield", npc = True, hostile_npc = True), - DS3LocationData("FS: Executioner Helm (shop after killing Horace)", "Executioner Helm", + DS3LocationData("FS: Executioner Helm - shop after killing Horace", "Executioner Helm", npc = True, hostile_npc = True, shop = True, hidden = True), - DS3LocationData("FS: Executioner Armor (shop after killing Horace)", "Executioner Armor", + DS3LocationData("FS: Executioner Armor - shop after killing Horace", "Executioner Armor", npc = True, hostile_npc = True, shop = True, hidden = True), - DS3LocationData("FS: Executioner Gauntlets (shop after killing Horace)", + DS3LocationData("FS: Executioner Gauntlets - shop after killing Horace", "Executioner Gauntlets", hostile_npc = True, npc = True, shop = True, hidden = True), - DS3LocationData("FS: Executioner Leggings (shop after killing Horace)", + DS3LocationData("FS: Executioner Leggings - shop after killing Horace", "Executioner Leggings", hostile_npc = True, npc = True, shop = True, hidden = True), # Shrine Handmaid after killing Knight Slayer Tsorig - DS3LocationData("FS: Black Iron Helm (shop after killing Tsorig)", "Black Iron Helm", + DS3LocationData("FS: Black Iron Helm - shop after killing Tsorig", "Black Iron Helm", hostile_npc = True, shop = True, hidden = True), - DS3LocationData("FS: Black Iron Armor (shop after killing Tsorig)", "Black Iron Armor", + DS3LocationData("FS: Black Iron Armor - shop after killing Tsorig", "Black Iron Armor", hostile_npc = True, shop = True, hidden = True), - DS3LocationData("FS: Black Iron Gauntlets (shop after killing Tsorig)", + DS3LocationData("FS: Black Iron Gauntlets - shop after killing Tsorig", "Black Iron Gauntlets", hostile_npc = True, shop = True, hidden = True), - DS3LocationData("FS: Black Iron Leggings (shop after killing Tsorig)", + DS3LocationData("FS: Black Iron Leggings - shop after killing Tsorig", "Black Iron Leggings", hostile_npc = True, shop = True, hidden = True), # Near Cornyx's cage after killing Old Demon King with Cuculus - DS3LocationData("US: Spotted Whip (by Cornyx's cage after Cuculus quest)", "Spotted Whip", + DS3LocationData("US: Spotted Whip - by Cornyx's cage after Cuculus quest", "Spotted Whip", missable = True, boss = True, npc = True), - DS3LocationData("US: Cornyx's Garb (by Cornyx's cage after Cuculus quest)", + DS3LocationData("US: Cornyx's Garb - by Cornyx's cage after Cuculus quest", "Cornyx's Garb", offline = '02,0:53100100::', missable = True, boss = True, npc = True), - DS3LocationData("US: Cornyx's Wrap (by Cornyx's cage after Cuculus quest)", "Cornyx's Wrap", + DS3LocationData("US: Cornyx's Wrap - by Cornyx's cage after Cuculus quest", "Cornyx's Wrap", offline = '02,0:53100100::', missable = True, boss = True, npc = True), - DS3LocationData("US: Cornyx's Skirt (by Cornyx's cage after Cuculus quest)", + DS3LocationData("US: Cornyx's Skirt - by Cornyx's cage after Cuculus quest", "Cornyx's Skirt", offline = '02,0:53100100::', missable = True, boss = True, npc = True), ], "Irithyll of the Boreal Valley": [ DS3LocationData("IBV: Soul of Pontiff Sulyvahn", "Soul of Pontiff Sulyvahn", prominent = True, boss = True), - DS3LocationData("IBV: Large Soul of a Nameless Soldier (central, by bonfire)", + DS3LocationData("IBV: Large Soul of a Nameless Soldier - central, by bonfire", "Large Soul of a Nameless Soldier"), - DS3LocationData("IBV: Large Titanite Shard (ascent, down ladder in last building)", + DS3LocationData("IBV: Large Titanite Shard - ascent, down ladder in last building", "Large Titanite Shard"), - DS3LocationData("IBV: Soul of a Weary Warrior (central, by first fountain)", + DS3LocationData("IBV: Soul of a Weary Warrior - central, by first fountain", "Soul of a Weary Warrior"), - DS3LocationData("IBV: Soul of a Weary Warrior (central, railing by first fountain)", + DS3LocationData("IBV: Soul of a Weary Warrior - central, railing by first fountain", "Soul of a Weary Warrior"), - DS3LocationData("IBV: Rime-blue Moss Clump (central, by bonfire)", "Rime-blue Moss Clump"), - DS3LocationData("IBV: Witchtree Branch (by Dorhys)", "Witchtree Branch", + DS3LocationData("IBV: Rime-blue Moss Clump - central, by bonfire", "Rime-blue Moss Clump"), + DS3LocationData("IBV: Witchtree Branch - by Dorhys", "Witchtree Branch", hidden = True), # Behind illusory wall - DS3LocationData("IBV: Large Titanite Shard (central, side path after first fountain)", + DS3LocationData("IBV: Large Titanite Shard - central, side path after first fountain", "Large Titanite Shard"), - DS3LocationData("IBV: Budding Green Blossom (central, by second fountain)", + DS3LocationData("IBV: Budding Green Blossom - central, by second fountain", "Budding Green Blossom"), - DS3LocationData("IBV: Rime-blue Moss Clump (central, past second fountain)", + DS3LocationData("IBV: Rime-blue Moss Clump - central, past second fountain", "Rime-blue Moss Clump x2"), - DS3LocationData("IBV: Large Titanite Shard (central, balcony just before plaza)", + DS3LocationData("IBV: Large Titanite Shard - central, balcony just before plaza", "Large Titanite Shard"), - DS3LocationData("IBV: Large Titanite Shard (path to Dorhys)", "Large Titanite Shard", + DS3LocationData("IBV: Large Titanite Shard - path to Dorhys", "Large Titanite Shard", hidden = True), # Behind illusory wall - DS3LocationData("IBV: Ring of the Sun's First Born (fall from in front of cathedral)", + DS3LocationData("IBV: Ring of the Sun's First Born - fall from in front of cathedral", "Ring of the Sun's First Born", hidden = True), # Hidden fall - DS3LocationData("IBV: Large Soul of a Nameless Soldier (stairs to plaza)", + DS3LocationData("IBV: Large Soul of a Nameless Soldier - stairs to plaza", "Large Soul of a Nameless Soldier"), - DS3LocationData("IBV: Large Titanite Shard (plaza, balcony overlooking ascent)", + DS3LocationData("IBV: Large Titanite Shard - plaza, balcony overlooking ascent", "Large Titanite Shard"), - DS3LocationData("IBV: Large Titanite Shard (plaza, by stairs to church)", + DS3LocationData("IBV: Large Titanite Shard - plaza, by stairs to church", "Large Titanite Shard"), - DS3LocationData("IBV: Soul of a Weary Warrior (plaza, side room lower)", + DS3LocationData("IBV: Soul of a Weary Warrior - plaza, side room lower", "Soul of a Weary Warrior"), - DS3LocationData("IBV: Magic Clutch Ring (plaza, illusory wall)", "Magic Clutch Ring", + DS3LocationData("IBV: Magic Clutch Ring - plaza, illusory wall", "Magic Clutch Ring", hidden = True), # Behind illusory wall - DS3LocationData("IBV: Fading Soul (descent, cliff edge #1)", "Fading Soul"), - DS3LocationData("IBV: Fading Soul (descent, cliff edge #2)", "Fading Soul"), - DS3LocationData("IBV: Homeward Bone (descent, before gravestone)", "Homeward Bone x3"), - DS3LocationData("IBV: Undead Bone Shard (descent, behind gravestone)", "Undead Bone Shard", + DS3LocationData("IBV: Fading Soul - descent, cliff edge #1", "Fading Soul"), + DS3LocationData("IBV: Fading Soul - descent, cliff edge #2", "Fading Soul"), + DS3LocationData("IBV: Homeward Bone - descent, before gravestone", "Homeward Bone x3"), + DS3LocationData("IBV: Undead Bone Shard - descent, behind gravestone", "Undead Bone Shard", hidden = True), # Hidden behind gravestone - DS3LocationData("IBV: Kukri (descent, side path)", "Kukri x8"), - DS3LocationData("IBV: Rusted Gold Coin (descent, side path)", "Rusted Gold Coin"), - DS3LocationData("IBV: Blue Bug Pellet (descent, dark room)", "Blue Bug Pellet x2"), - DS3LocationData("IBV: Shriving Stone (descent, dark room rafters)", "Shriving Stone"), - DS3LocationData("IBV: Blood Gem (descent, platform before lake)", "Blood Gem"), - DS3LocationData("IBV: Green Blossom (lake, by stairs from descent)", "Green Blossom x3"), - DS3LocationData("IBV: Ring of Sacrifice (lake, right of stairs from descent)", + DS3LocationData("IBV: Kukri - descent, side path", "Kukri x8"), + DS3LocationData("IBV: Rusted Gold Coin - descent, side path", "Rusted Gold Coin"), + DS3LocationData("IBV: Blue Bug Pellet - descent, dark room", "Blue Bug Pellet x2"), + DS3LocationData("IBV: Shriving Stone - descent, dark room rafters", "Shriving Stone"), + DS3LocationData("IBV: Blood Gem - descent, platform before lake", "Blood Gem"), + DS3LocationData("IBV: Green Blossom - lake, by stairs from descent", "Green Blossom x3"), + DS3LocationData("IBV: Ring of Sacrifice - lake, right of stairs from descent", "Ring of Sacrifice"), - DS3LocationData("IBV: Great Heal (lake, dead Corpse-Grub)", "Great Heal"), - DS3LocationData("IBV: Large Soul of a Nameless Soldier (lake island)", + DS3LocationData("IBV: Great Heal - lake, dead Corpse-Grub", "Great Heal"), + DS3LocationData("IBV: Large Soul of a Nameless Soldier - lake island", "Large Soul of a Nameless Soldier"), - DS3LocationData("IBV: Green Blossom (lake wall)", "Green Blossom x3"), - DS3LocationData("IBV: Dung Pie (sewer #1)", "Dung Pie x3"), - DS3LocationData("IBV: Dung Pie (sewer #2)", "Dung Pie x3"), + DS3LocationData("IBV: Green Blossom - lake wall", "Green Blossom x3"), + DS3LocationData("IBV: Dung Pie - sewer #1", "Dung Pie x3"), + DS3LocationData("IBV: Dung Pie - sewer #2", "Dung Pie x3"), # These don't actually guard any single item sales. Maybe we can inject one manually? - DS3LocationData("IBV: Excrement-covered Ashes (sewer, by stairs)", + DS3LocationData("IBV: Excrement-covered Ashes - sewer, by stairs", "Excrement-covered Ashes"), - DS3LocationData("IBV: Large Soul of a Nameless Soldier (ascent, after great hall)", + DS3LocationData("IBV: Large Soul of a Nameless Soldier - ascent, after great hall", "Large Soul of a Nameless Soldier"), - DS3LocationData("IBV: Soul of a Weary Warrior (ascent, by final staircase)", + DS3LocationData("IBV: Soul of a Weary Warrior - ascent, by final staircase", "Soul of a Weary Warrior"), - DS3LocationData("IBV: Large Titanite Shard (ascent, by elevator door)", + DS3LocationData("IBV: Large Titanite Shard - ascent, by elevator door", "Large Titanite Shard"), - DS3LocationData("IBV: Blue Bug Pellet (ascent, in last building)", "Blue Bug Pellet x2"), - DS3LocationData("IBV: Ember (shortcut from church to cathedral)", "Ember"), - DS3LocationData("IBV: Green Blossom (lake, by Distant Manor)", "Green Blossom"), - DS3LocationData("IBV: Lightning Gem (plaza center)", "Lightning Gem"), - DS3LocationData("IBV: Large Soul of a Nameless Soldier (central, by second fountain)", + DS3LocationData("IBV: Blue Bug Pellet - ascent, in last building", "Blue Bug Pellet x2"), + DS3LocationData("IBV: Ember - shortcut from church to cathedral", "Ember"), + DS3LocationData("IBV: Green Blossom - lake, by Distant Manor", "Green Blossom"), + DS3LocationData("IBV: Lightning Gem - plaza center", "Lightning Gem"), + DS3LocationData("IBV: Large Soul of a Nameless Soldier - central, by second fountain", "Large Soul of a Nameless Soldier"), - DS3LocationData("IBV: Soul of a Weary Warrior (plaza, side room upper)", + DS3LocationData("IBV: Soul of a Weary Warrior - plaza, side room upper", "Soul of a Weary Warrior"), - DS3LocationData("IBV: Proof of a Concord Kept (Church of Yorshka altar)", + DS3LocationData("IBV: Proof of a Concord Kept - Church of Yorshka altar", "Proof of a Concord Kept"), - DS3LocationData("IBV: Rusted Gold Coin (Distant Manor, drop after stairs)", + DS3LocationData("IBV: Rusted Gold Coin - Distant Manor, drop after stairs", "Rusted Gold Coin"), - DS3LocationData("IBV: Chloranthy Ring+1 (plaza, behind altar)", "Chloranthy Ring+1", + DS3LocationData("IBV: Chloranthy Ring+1 - plaza, behind altar", "Chloranthy Ring+1", ngp = True), - DS3LocationData("IBV: Covetous Gold Serpent Ring+1 (descent, drop after dark room)", + DS3LocationData("IBV: Covetous Gold Serpent Ring+1 - descent, drop after dark room", "Covetous Gold Serpent Ring+1", ngp = True, hidden = True), # Hidden fall - DS3LocationData("IBV: Wood Grain Ring+2 (ascent, right after great hall)", "Wood Grain Ring+2", + DS3LocationData("IBV: Wood Grain Ring+2 - ascent, right after great hall", "Wood Grain Ring+2", ngp = True), - DS3LocationData("IBV: Divine Blessing (great hall, chest)", "Divine Blessing"), - DS3LocationData("IBV: Smough's Great Hammer (great hall, chest)", + DS3LocationData("IBV: Divine Blessing - great hall, chest", "Divine Blessing"), + DS3LocationData("IBV: Smough's Great Hammer - great hall, chest", "Smough's Great Hammer"), - DS3LocationData("IBV: Yorshka's Spear (descent, dark room rafers chest)", "Yorshka's Spear"), - DS3LocationData("IBV: Leo Ring (great hall, chest)", "Leo Ring"), - DS3LocationData("IBV: Dorhys' Gnawing (Dorhys drop)", "Dorhys' Gnawing", + DS3LocationData("IBV: Yorshka's Spear - descent, dark room rafers chest", "Yorshka's Spear"), + DS3LocationData("IBV: Leo Ring - great hall, chest", "Leo Ring"), + DS3LocationData("IBV: Dorhys' Gnawing - Dorhys drop", "Dorhys' Gnawing", hidden = True), # Behind illusory wall - DS3LocationData("IBV: Divine Blessing (great hall, mob drop)", + DS3LocationData("IBV: Divine Blessing - great hall, mob drop", "Divine Blessing", drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight - DS3LocationData("IBV: Large Titanite Shard (great hall, main floor mob drop)", + DS3LocationData("IBV: Large Titanite Shard - great hall, main floor mob drop", "Large Titanite Shard", drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight - DS3LocationData("IBV: Large Titanite Shard (great hall, upstairs mob drop #1)", + DS3LocationData("IBV: Large Titanite Shard - great hall, upstairs mob drop #1", "Large Titanite Shard x2", drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight - DS3LocationData("IBV: Large Titanite Shard (great hall, upstairs mob drop #2)", + DS3LocationData("IBV: Large Titanite Shard - great hall, upstairs mob drop #2", "Large Titanite Shard x2", drop = True, hidden = True), # Guaranteed drop from normal-looking Silver Knight - DS3LocationData("IBV: Roster of Knights (descent, first landing)", "Roster of Knights"), - DS3LocationData("IBV: Twinkling Titanite (descent, lizard behind illusory wall)", + DS3LocationData("IBV: Roster of Knights - descent, first landing", "Roster of Knights"), + DS3LocationData("IBV: Twinkling Titanite - descent, lizard behind illusory wall", "Twinkling Titanite", lizard = True, hidden = True), # Behind illusory wall - DS3LocationData("IBV: Twinkling Titanite (central, lizard before plaza)", + DS3LocationData("IBV: Twinkling Titanite - central, lizard before plaza", "Twinkling Titanite", lizard = True), - DS3LocationData("IBV: Large Titanite Shard (Distant Manor, under overhang)", + DS3LocationData("IBV: Large Titanite Shard - Distant Manor, under overhang", "Large Titanite Shard"), - DS3LocationData("IBV: Siegbräu (Siegward)", "Siegbräu", missable = True, npc = True), - DS3LocationData("IBV: Emit Force (Siegward)", "Emit Force", missable = True, npc = True), + DS3LocationData("IBV: Siegbräu - Siegward", "Siegbräu", missable = True, npc = True), + DS3LocationData("IBV: Emit Force - Siegward", "Emit Force", missable = True, npc = True), DS3LocationData("IBV -> AL", None), DS3LocationData("IBV -> ID", None), # After winning both Londor Pale Shade invasions - DS3LocationData("FS: Sneering Mask (Yoel's room, kill Londor Pale Shade twice)", + DS3LocationData("FS: Sneering Mask - Yoel's room, kill Londor Pale Shade twice", "Sneering Mask", missable = True, hostile_npc = True), - DS3LocationData("FS: Pale Shade Robe (Yoel's room, kill Londor Pale Shade twice)", + DS3LocationData("FS: Pale Shade Robe - Yoel's room, kill Londor Pale Shade twice", "Pale Shade Robe", missable = True, hostile_npc = True), - DS3LocationData("FS: Pale Shade Gloves (Yoel's room, kill Londor Pale Shade twice)", + DS3LocationData("FS: Pale Shade Gloves - Yoel's room, kill Londor Pale Shade twice", "Pale Shade Gloves", missable = True, hostile_npc = True), - DS3LocationData("FS: Pale Shade Trousers (Yoel's room, kill Londor Pale Shade twice)", + DS3LocationData("FS: Pale Shade Trousers - Yoel's room, kill Londor Pale Shade twice", "Pale Shade Trousers", missable = True, hostile_npc = True), # Anri of Astora - DS3LocationData("IBV: Ring of the Evil Eye (Anri)", "Ring of the Evil Eye", missable = True, + DS3LocationData("IBV: Ring of the Evil Eye - Anri", "Ring of the Evil Eye", missable = True, npc = True), # Sirris quest after killing Creighton - DS3LocationData("FS: Mail Breaker (Sirris for killing Creighton)", "Mail Breaker", + DS3LocationData("FS: Mail Breaker - Sirris for killing Creighton", "Mail Breaker", offline = '99,0:50006080::', missable = True, hostile_npc = True, npc = True), - DS3LocationData("FS: Silvercat Ring (Sirris for killing Creighton)", "Silvercat Ring", + DS3LocationData("FS: Silvercat Ring - Sirris for killing Creighton", "Silvercat Ring", missable = True, hostile_npc = True, npc = True), - DS3LocationData("IBV: Dragonslayer's Axe (Creighton drop)", "Dragonslayer's Axe", + DS3LocationData("IBV: Dragonslayer's Axe - Creighton drop", "Dragonslayer's Axe", missable = True, hostile_npc = True, npc = True), - DS3LocationData("IBV: Creighton's Steel Mask (bridge after killing Creighton)", + DS3LocationData("IBV: Creighton's Steel Mask - bridge after killing Creighton", "Creighton's Steel Mask", missable = True, hostile_npc = True, npc = True), - DS3LocationData("IBV: Mirrah Chain Mail (bridge after killing Creighton)", + DS3LocationData("IBV: Mirrah Chain Mail - bridge after killing Creighton", "Mirrah Chain Mail", missable = True, hostile_npc = True, npc = True), - DS3LocationData("IBV: Mirrah Chain Gloves (bridge after killing Creighton)", + DS3LocationData("IBV: Mirrah Chain Gloves - bridge after killing Creighton", "Mirrah Chain Gloves", missable = True, hostile_npc = True, npc = True), - DS3LocationData("IBV: Mirrah Chain Leggings (bridge after killing Creighton)", + DS3LocationData("IBV: Mirrah Chain Leggings - bridge after killing Creighton", "Mirrah Chain Leggings", missable = True, hostile_npc = True, npc = True), ], "Irithyll Dungeon": [ - DS3LocationData("ID: Titanite Slab (Siegward)", "Titanite Slab", missable = True, + DS3LocationData("ID: Titanite Slab - Siegward", "Titanite Slab", missable = True, npc = True), - DS3LocationData("ID: Murakumo (Alva drop)", "Murakumo", missable = True, + DS3LocationData("ID: Murakumo - Alva drop", "Murakumo", missable = True, hostile_npc = True), - DS3LocationData("ID: Large Titanite Shard (after bonfire, second cell on right)", + DS3LocationData("ID: Large Titanite Shard - after bonfire, second cell on right", "Large Titanite Shard"), - DS3LocationData("ID: Fading Soul (B1 near, main hall)", "Fading Soul"), - DS3LocationData("ID: Large Soul of a Nameless Soldier (B2, hall by stairs)", + DS3LocationData("ID: Fading Soul - B1 near, main hall", "Fading Soul"), + DS3LocationData("ID: Large Soul of a Nameless Soldier - B2, hall by stairs", "Large Soul of a Nameless Soldier"), - DS3LocationData("ID: Jailbreaker's Key (B1 far, cell after gate)", "Jailbreaker's Key"), - DS3LocationData("ID: Pale Pine Resin (B1 far, cell with broken wall)", + DS3LocationData("ID: Jailbreaker's Key - B1 far, cell after gate", "Jailbreaker's Key"), + DS3LocationData("ID: Pale Pine Resin - B1 far, cell with broken wall", "Pale Pine Resin x2"), - DS3LocationData("ID: Simple Gem (B2 far, cell by stairs)", "Simple Gem"), - DS3LocationData("ID: Large Soul of a Nameless Soldier (B2 far, by lift)", + DS3LocationData("ID: Simple Gem - B2 far, cell by stairs", "Simple Gem"), + DS3LocationData("ID: Large Soul of a Nameless Soldier - B2 far, by lift", "Large Soul of a Nameless Soldier"), - DS3LocationData("ID: Large Titanite Shard (B1 far, rightmost cell)", + DS3LocationData("ID: Large Titanite Shard - B1 far, rightmost cell", "Large Titanite Shard"), - DS3LocationData("ID: Homeward Bone (path from B2 to pit)", "Homeward Bone x2"), - DS3LocationData("ID: Bellowing Dragoncrest Ring (drop from B1 towards pit)", + DS3LocationData("ID: Homeward Bone - path from B2 to pit", "Homeward Bone x2"), + DS3LocationData("ID: Bellowing Dragoncrest Ring - drop from B1 towards pit", "Bellowing Dragoncrest Ring", conditional = True), - DS3LocationData("ID: Soul of a Weary Warrior (by drop to pit)", "Soul of a Weary Warrior"), - DS3LocationData("ID: Soul of a Crestfallen Knight (balcony above pit)", + DS3LocationData("ID: Soul of a Weary Warrior - by drop to pit", "Soul of a Weary Warrior"), + DS3LocationData("ID: Soul of a Crestfallen Knight - balcony above pit", "Soul of a Crestfallen Knight"), - DS3LocationData("ID: Lightning Bolt (awning over pit)", "Lightning Bolt x9"), - DS3LocationData("ID: Large Titanite Shard (pit)", "Large Titanite Shard"), - DS3LocationData("ID: Profaned Flame (pit)", "Profaned Flame"), - DS3LocationData("ID: Large Titanite Shard (pit)", "Large Titanite Shard"), - DS3LocationData("ID: Soul of a Weary Warrior (stairs between pit and B3)", + DS3LocationData("ID: Lightning Bolt - awning over pit", "Lightning Bolt x9"), + DS3LocationData("ID: Large Titanite Shard - pit", "Large Titanite Shard"), + DS3LocationData("ID: Profaned Flame - pit", "Profaned Flame"), + DS3LocationData("ID: Large Titanite Shard - pit", "Large Titanite Shard"), + DS3LocationData("ID: Soul of a Weary Warrior - stairs between pit and B3", "Soul of a Weary Warrior"), - DS3LocationData("ID: Dung Pie (B3, by path from pit)", "Dung Pie x4"), - DS3LocationData("ID: Ember (B3 center)", "Ember"), - DS3LocationData("ID: Ember (B3 far right)", "Ember"), - DS3LocationData("ID: Profaned Coal (B3 far, left cell)", "Profaned Coal"), - DS3LocationData("ID: Large Titanite Shard (B3 near, right corner)", "Large Titanite Shard"), - DS3LocationData("ID: Old Sorcerer Hat (B2 near, middle cell)", "Old Sorcerer Hat"), - DS3LocationData("ID: Old Sorcerer Coat (B2 near, middle cell)", "Old Sorcerer Coat"), - DS3LocationData("ID: Old Sorcerer Gauntlets (B2 near, middle cell)", + DS3LocationData("ID: Dung Pie - B3, by path from pit", "Dung Pie x4"), + DS3LocationData("ID: Ember - B3 center", "Ember"), + DS3LocationData("ID: Ember - B3 far right", "Ember"), + DS3LocationData("ID: Profaned Coal - B3 far, left cell", "Profaned Coal"), + DS3LocationData("ID: Large Titanite Shard - B3 near, right corner", "Large Titanite Shard"), + DS3LocationData("ID: Old Sorcerer Hat - B2 near, middle cell", "Old Sorcerer Hat"), + DS3LocationData("ID: Old Sorcerer Coat - B2 near, middle cell", "Old Sorcerer Coat"), + DS3LocationData("ID: Old Sorcerer Gauntlets - B2 near, middle cell", "Old Sorcerer Gauntlets"), - DS3LocationData("ID: Old Sorcerer Boots (B2 near, middle cell)", "Old Sorcerer Boots"), - DS3LocationData("ID: Large Soul of a Weary Warrior (just before Profaned Capital)", + DS3LocationData("ID: Old Sorcerer Boots - B2 near, middle cell", "Old Sorcerer Boots"), + DS3LocationData("ID: Large Soul of a Weary Warrior - just before Profaned Capital", "Large Soul of a Weary Warrior"), - DS3LocationData("ID: Covetous Gold Serpent Ring (Siegward's cell)", + DS3LocationData("ID: Covetous Gold Serpent Ring - Siegward's cell", "Covetous Gold Serpent Ring", conditional = True), - DS3LocationData("ID: Lightning Blade (B3 lift, middle platform)", "Lightning Blade"), - DS3LocationData("ID: Rusted Coin (after bonfire, first cell on left)", "Rusted Coin"), - DS3LocationData("ID: Dusk Crown Ring (B3 far, right cell)", "Dusk Crown Ring"), - DS3LocationData("ID: Pickaxe (path from pit to B3)", "Pickaxe"), - DS3LocationData("ID: Xanthous Ashes (B3 far, right cell)", "Xanthous Ashes", + DS3LocationData("ID: Lightning Blade - B3 lift, middle platform", "Lightning Blade"), + DS3LocationData("ID: Rusted Coin - after bonfire, first cell on left", "Rusted Coin"), + DS3LocationData("ID: Dusk Crown Ring - B3 far, right cell", "Dusk Crown Ring"), + DS3LocationData("ID: Pickaxe - path from pit to B3", "Pickaxe"), + DS3LocationData("ID: Xanthous Ashes - B3 far, right cell", "Xanthous Ashes", progression = True), - DS3LocationData("ID: Large Titanite Shard (B1 near, by door)", "Large Titanite Shard"), - DS3LocationData("ID: Rusted Gold Coin (after bonfire, last cell on right)", + DS3LocationData("ID: Large Titanite Shard - B1 near, by door", "Large Titanite Shard"), + DS3LocationData("ID: Rusted Gold Coin - after bonfire, last cell on right", "Rusted Gold Coin"), - DS3LocationData("ID: Large Titanite Shard (stairs between pit and B3)", + DS3LocationData("ID: Large Titanite Shard - stairs between pit and B3", "Large Titanite Shard"), - DS3LocationData("ID: Old Cell Key (stairs between pit and B3)", "Old Cell Key"), - DS3LocationData("ID: Covetous Silver Serpent Ring+1 (pit lift, middle platform)", + DS3LocationData("ID: Old Cell Key - stairs between pit and B3", "Old Cell Key"), + DS3LocationData("ID: Covetous Silver Serpent Ring+1 - pit lift, middle platform", "Covetous Silver Serpent Ring+1", ngp = True), - DS3LocationData("ID: Dragon Torso Stone (B3, outside lift)", "Dragon Torso Stone"), - DS3LocationData("ID: Prisoner Chief's Ashes (B2 near, locked cell by stairs)", + DS3LocationData("ID: Dragon Torso Stone - B3, outside lift", "Dragon Torso Stone"), + DS3LocationData("ID: Prisoner Chief's Ashes - B2 near, locked cell by stairs", "Prisoner Chief's Ashes", progression = True), - DS3LocationData("ID: Great Magic Shield (B2 near, mob drop in far left cell)", + DS3LocationData("ID: Great Magic Shield - B2 near, mob drop in far left cell", "Great Magic Shield", drop = True, hidden = True), # Guaranteed drop from a normal-looking Corpse-Grub - DS3LocationData("ID: Dragonslayer Lightning Arrow (pit, mimic in hall)", + DS3LocationData("ID: Dragonslayer Lightning Arrow - pit, mimic in hall", "Dragonslayer Lightning Arrow x10", mimic = True), - DS3LocationData("ID: Titanite Scale (B3 far, mimic in hall)", "Titanite Scale x2", + DS3LocationData("ID: Titanite Scale - B3 far, mimic in hall", "Titanite Scale x2", mimic = True), - DS3LocationData("ID: Dark Clutch Ring (stairs between pit and B3, mimic)", + DS3LocationData("ID: Dark Clutch Ring - stairs between pit and B3, mimic", "Dark Clutch Ring", mimic = True), - DS3LocationData("ID: Estus Shard (mimic on path from B2 to pit)", "Estus Shard", + DS3LocationData("ID: Estus Shard - mimic on path from B2 to pit", "Estus Shard", mimic = True), - DS3LocationData("ID: Titanite Chunk (balcony above pit, lizard)", "Titanite Chunk", + DS3LocationData("ID: Titanite Chunk - balcony above pit, lizard", "Titanite Chunk", lizard = True), - DS3LocationData("ID: Titanite Scale (B2 far, lizard)", "Titanite Scale", lizard = True), - DS3LocationData("ID: Dung Pie (pit, miniboss drop)", "Dung Pie x4", + DS3LocationData("ID: Titanite Scale - B2 far, lizard", "Titanite Scale", lizard = True), + DS3LocationData("ID: Dung Pie - pit, miniboss drop", "Dung Pie x4", miniboss = True), # Giant slave drop - DS3LocationData("ID: Titanite Chunk (pit, miniboss drop)", "Titanite Chunk", + DS3LocationData("ID: Titanite Chunk - pit, miniboss drop", "Titanite Chunk", miniboss = True), # Giant Slave Drop # Alva (requires ember) - DS3LocationData("ID: Alva Helm (B3 near, by Karla's cell, after killing Alva)", "Alva Helm", + DS3LocationData("ID: Alva Helm - B3 near, by Karla's cell, after killing Alva", "Alva Helm", missable = True, npc = True), - DS3LocationData("ID: Alva Armor (B3 near, by Karla's cell, after killing Alva)", + DS3LocationData("ID: Alva Armor - B3 near, by Karla's cell, after killing Alva", "Alva Armor", missable = True, npc = True), - DS3LocationData("ID: Alva Gauntlets (B3 near, by Karla's cell, after killing Alva)", + DS3LocationData("ID: Alva Gauntlets - B3 near, by Karla's cell, after killing Alva", "Alva Gauntlets", missable = True, npc = True), - DS3LocationData("ID: Alva Leggings (B3 near, by Karla's cell, after killing Alva)", + DS3LocationData("ID: Alva Leggings - B3 near, by Karla's cell, after killing Alva", "Alva Leggings", missable = True, npc = True), ], "Profaned Capital": [ @@ -1744,61 +1744,61 @@ def __init__( DS3LocationData("PC: Cinders of a Lord - Yhorm the Giant", "Cinders of a Lord - Yhorm the Giant", offline = "07,0:50002170::", prominent = True, progression = True, boss = True), - DS3LocationData("PC: Logan's Scroll (chapel roof, NPC drop)", "Logan's Scroll", + DS3LocationData("PC: Logan's Scroll - chapel roof, NPC drop", "Logan's Scroll", hostile_npc = True), # Sorcerer - DS3LocationData("PC: Purging Stone (chapel ground floor)", "Purging Stone x3"), - DS3LocationData("PC: Rusted Coin (tower exterior)", "Rusted Coin x2"), - DS3LocationData("PC: Rusted Gold Coin (halls above swamp)", "Rusted Gold Coin"), - DS3LocationData("PC: Purging Stone (swamp, by chapel ladder)", "Purging Stone"), - DS3LocationData("PC: Cursebite Ring (swamp, below halls)", "Cursebite Ring"), - DS3LocationData("PC: Poison Gem (swamp, below halls)", "Poison Gem"), - DS3LocationData("PC: Shriving Stone (swamp, by chapel door)", "Shriving Stone"), - DS3LocationData("PC: Poison Arrow (chapel roof)", "Poison Arrow x18"), - DS3LocationData("PC: Rubbish (chapel, down stairs from second floor)", "Rubbish"), - DS3LocationData("PC: Onislayer Greatarrow (bridge)", "Onislayer Greatarrow x8"), - DS3LocationData("PC: Large Soul of a Weary Warrior (bridge, far end)", + DS3LocationData("PC: Purging Stone - chapel ground floor", "Purging Stone x3"), + DS3LocationData("PC: Rusted Coin - tower exterior", "Rusted Coin x2"), + DS3LocationData("PC: Rusted Gold Coin - halls above swamp", "Rusted Gold Coin"), + DS3LocationData("PC: Purging Stone - swamp, by chapel ladder", "Purging Stone"), + DS3LocationData("PC: Cursebite Ring - swamp, below halls", "Cursebite Ring"), + DS3LocationData("PC: Poison Gem - swamp, below halls", "Poison Gem"), + DS3LocationData("PC: Shriving Stone - swamp, by chapel door", "Shriving Stone"), + DS3LocationData("PC: Poison Arrow - chapel roof", "Poison Arrow x18"), + DS3LocationData("PC: Rubbish - chapel, down stairs from second floor", "Rubbish"), + DS3LocationData("PC: Onislayer Greatarrow - bridge", "Onislayer Greatarrow x8"), + DS3LocationData("PC: Large Soul of a Weary Warrior - bridge, far end", "Large Soul of a Weary Warrior"), - DS3LocationData("PC: Rusted Coin (below bridge #1)", "Rusted Coin"), - DS3LocationData("PC: Rusted Coin (below bridge #2)", "Rusted Coin"), - DS3LocationData("PC: Blooming Purple Moss Clump (walkway above swamp)", + DS3LocationData("PC: Rusted Coin - below bridge #1", "Rusted Coin"), + DS3LocationData("PC: Rusted Coin - below bridge #2", "Rusted Coin"), + DS3LocationData("PC: Blooming Purple Moss Clump - walkway above swamp", "Blooming Purple Moss Clump x3"), - DS3LocationData("PC: Wrath of the Gods (chapel, drop from roof)", "Wrath of the Gods"), - DS3LocationData("PC: Onislayer Greatbow (drop from bridge)", "Onislayer Greatbow", + DS3LocationData("PC: Wrath of the Gods - chapel, drop from roof", "Wrath of the Gods"), + DS3LocationData("PC: Onislayer Greatbow - drop from bridge", "Onislayer Greatbow", hidden = True), # Hidden fall - DS3LocationData("PC: Jailer's Key Ring (hall past chapel)", "Jailer's Key Ring", + DS3LocationData("PC: Jailer's Key Ring - hall past chapel", "Jailer's Key Ring", progression = True), - DS3LocationData("PC: Ember (palace, far room)", "Ember"), - DS3LocationData("PC: Flame Stoneplate Ring+1 (chapel, drop from roof towards entrance)", + DS3LocationData("PC: Ember - palace, far room", "Ember"), + DS3LocationData("PC: Flame Stoneplate Ring+1 - chapel, drop from roof towards entrance", "Flame Stoneplate Ring+1", ngp = True, hidden = True), # Hidden fall - DS3LocationData("PC: Magic Stoneplate Ring+2 (tower base)", "Magic Stoneplate Ring+2", + DS3LocationData("PC: Magic Stoneplate Ring+2 - tower base", "Magic Stoneplate Ring+2", ngp = True), - DS3LocationData("PC: Court Sorcerer Hood (chapel, second floor)", "Court Sorcerer Hood"), - DS3LocationData("PC: Court Sorcerer Robe (chapel, second floor)", "Court Sorcerer Robe"), - DS3LocationData("PC: Court Sorcerer Gloves (chapel, second floor)", "Court Sorcerer Gloves"), - DS3LocationData("PC: Court Sorcerer Trousers (chapel, second floor)", + DS3LocationData("PC: Court Sorcerer Hood - chapel, second floor", "Court Sorcerer Hood"), + DS3LocationData("PC: Court Sorcerer Robe - chapel, second floor", "Court Sorcerer Robe"), + DS3LocationData("PC: Court Sorcerer Gloves - chapel, second floor", "Court Sorcerer Gloves"), + DS3LocationData("PC: Court Sorcerer Trousers - chapel, second floor", "Court Sorcerer Trousers"), - DS3LocationData("PC: Storm Ruler (boss room)", "Storm Ruler"), - DS3LocationData("PC: Undead Bone Shard (by bonfire)", "Undead Bone Shard"), - DS3LocationData("PC: Eleonora (chapel ground floor, kill mob)", "Eleonora", + DS3LocationData("PC: Storm Ruler - boss room", "Storm Ruler"), + DS3LocationData("PC: Undead Bone Shard - by bonfire", "Undead Bone Shard"), + DS3LocationData("PC: Eleonora - chapel ground floor, kill mob", "Eleonora", drop = True, hidden = True), # Guaranteed drop from a normal-looking Monstrosity of Sin - DS3LocationData("PC: Rusted Gold Coin (palace, mimic in far room)", "Rusted Gold Coin x2", + DS3LocationData("PC: Rusted Gold Coin - palace, mimic in far room", "Rusted Gold Coin x2", mimic = True), - DS3LocationData("PC: Court Sorcerer's Staff (chapel, mimic on second floor)", + DS3LocationData("PC: Court Sorcerer's Staff - chapel, mimic on second floor", "Court Sorcerer's Staff", mimic = True), - DS3LocationData("PC: Greatshield of Glory (palace, mimic in far room)", + DS3LocationData("PC: Greatshield of Glory - palace, mimic in far room", "Greatshield of Glory", mimic = True), - DS3LocationData("PC: Twinkling Titanite (halls above swamp, lizard #1)", + DS3LocationData("PC: Twinkling Titanite - halls above swamp, lizard #1", "Twinkling Titanite", lizard = True), - DS3LocationData("PC: Twinkling Titanite (halls above swamp, lizard #2)", + DS3LocationData("PC: Twinkling Titanite - halls above swamp, lizard #2", "Twinkling Titanite", lizard = True), - DS3LocationData("PC: Siegbräu (Siegward after killing boss)", "Siegbräu", + DS3LocationData("PC: Siegbräu - Siegward after killing boss", "Siegbräu", missable = True, npc = True), # Siegward drops (kill or quest) - DS3LocationData("PC: Storm Ruler (Siegward)", "Storm Ruler", offline = '02,0:50006218::', + DS3LocationData("PC: Storm Ruler - Siegward", "Storm Ruler", offline = '02,0:50006218::', missable = True, drop = True, npc = True), - DS3LocationData("PC: Pierce Shield (Siegward)", "Pierce Shield", missable = True, + DS3LocationData("PC: Pierce Shield - Siegward", "Pierce Shield", missable = True, drop = True, npc = True), ], # We consider "Anor Londo" to be everything accessible only after killing Pontiff. This doesn't @@ -1809,294 +1809,294 @@ def __init__( DS3LocationData("AL: Cinders of a Lord - Aldrich", "Cinders of a Lord - Aldrich", offline = '06,0:50002130::', prominent = True, progression = True, boss = True), - DS3LocationData("AL: Yorshka's Chime (kill Yorshka)", "Yorshka's Chime", missable = True, + DS3LocationData("AL: Yorshka's Chime - kill Yorshka", "Yorshka's Chime", missable = True, drop = True, npc = True), # Hidden walkway, missable because it will break Sirris's quest - DS3LocationData("AL: Drang Twinspears (plaza, NPC drop)", "Drang Twinspears", drop = True, + DS3LocationData("AL: Drang Twinspears - plaza, NPC drop", "Drang Twinspears", drop = True, hidden = True), - DS3LocationData("AL: Estus Shard (dark cathedral, by left stairs)", "Estus Shard"), - DS3LocationData("AL: Painting Guardian's Curved Sword (prison tower rafters)", + DS3LocationData("AL: Estus Shard - dark cathedral, by left stairs", "Estus Shard"), + DS3LocationData("AL: Painting Guardian's Curved Sword - prison tower rafters", "Painting Guardian's Curved Sword", hidden = True), # Invisible walkway - DS3LocationData("AL: Brass Helm (tomb)", "Brass Helm", + DS3LocationData("AL: Brass Helm - tomb", "Brass Helm", hidden = True), # Behind illusory wall - DS3LocationData("AL: Brass Armor (tomb)", "Brass Armor", + DS3LocationData("AL: Brass Armor - tomb", "Brass Armor", hidden = True), # Behind illusory wall - DS3LocationData("AL: Brass Gauntlets (tomb)", "Brass Gauntlets", + DS3LocationData("AL: Brass Gauntlets - tomb", "Brass Gauntlets", hidden = True), # Behind illusory wall - DS3LocationData("AL: Brass Leggings (tomb)", "Brass Leggings", + DS3LocationData("AL: Brass Leggings - tomb", "Brass Leggings", hidden = True), # Behind illusory wall - DS3LocationData("AL: Human Dregs (water reserves)", "Human Dregs", + DS3LocationData("AL: Human Dregs - water reserves", "Human Dregs", hidden = True), # Behind illusory wall - DS3LocationData("AL: Ember (spiral staircase, bottom)", "Ember"), - DS3LocationData("AL: Large Titanite Shard (bottom of the furthest buttress)", + DS3LocationData("AL: Ember - spiral staircase, bottom", "Ember"), + DS3LocationData("AL: Large Titanite Shard - bottom of the furthest buttress", "Large Titanite Shard"), - DS3LocationData("AL: Large Titanite Shard (right after light cathedral)", + DS3LocationData("AL: Large Titanite Shard - right after light cathedral", "Large Titanite Shard"), - DS3LocationData("AL: Large Titanite Shard (walkway, side path by cathedral)", + DS3LocationData("AL: Large Titanite Shard - walkway, side path by cathedral", "Large Titanite Shard"), - DS3LocationData("AL: Soul of a Weary Warrior (plaza, nearer)", "Soul of a Weary Warrior"), - DS3LocationData("AL: Ember (plaza, right side)", "Ember"), - DS3LocationData("AL: Ember (plaza, further)", "Ember"), - DS3LocationData("AL: Large Titanite Shard (after light cathedral)", + DS3LocationData("AL: Soul of a Weary Warrior - plaza, nearer", "Soul of a Weary Warrior"), + DS3LocationData("AL: Ember - plaza, right side", "Ember"), + DS3LocationData("AL: Ember - plaza, further", "Ember"), + DS3LocationData("AL: Large Titanite Shard - after light cathedral", "Large Titanite Shard"), - DS3LocationData("AL: Dark Stoneplate Ring (by dark stairs up from plaza)", + DS3LocationData("AL: Dark Stoneplate Ring - by dark stairs up from plaza", "Dark Stoneplate Ring"), - DS3LocationData("AL: Large Titanite Shard (bottom of the nearest buttress)", + DS3LocationData("AL: Large Titanite Shard - bottom of the nearest buttress", "Large Titanite Shard"), - DS3LocationData("AL: Deep Gem (water reserves)", "Deep Gem"), - DS3LocationData("AL: Titanite Scale (top of ladder up to buttresses)", "Titanite Scale"), - DS3LocationData("AL: Dragonslayer Greatarrow (drop from nearest buttress)", + DS3LocationData("AL: Deep Gem - water reserves", "Deep Gem"), + DS3LocationData("AL: Titanite Scale - top of ladder up to buttresses", "Titanite Scale"), + DS3LocationData("AL: Dragonslayer Greatarrow - drop from nearest buttress", "Dragonslayer Greatarrow x5", offline = '06,0:53700620::', hidden = True), # Hidden fall - DS3LocationData("AL: Dragonslayer Greatbow (drop from nearest buttress)", + DS3LocationData("AL: Dragonslayer Greatbow - drop from nearest buttress", "Dragonslayer Greatbow", offline = '06,0:53700620::', hidden = True), # Hidden fall - DS3LocationData("AL: Easterner's Ashes (below top of furthest buttress)", + DS3LocationData("AL: Easterner's Ashes - below top of furthest buttress", "Easterner's Ashes", progression = True), - DS3LocationData("AL: Painting Guardian Hood (prison tower, rafters)", + DS3LocationData("AL: Painting Guardian Hood - prison tower, rafters", "Painting Guardian Hood", hidden = True), # Invisible walkway - DS3LocationData("AL: Painting Guardian Gown (prison tower, rafters)", + DS3LocationData("AL: Painting Guardian Gown - prison tower, rafters", "Painting Guardian Gown", hidden = True), # Invisible walkway - DS3LocationData("AL: Painting Guardian Gloves (prison tower, rafters)", + DS3LocationData("AL: Painting Guardian Gloves - prison tower, rafters", "Painting Guardian Gloves", hidden = True), # Invisible walkway - DS3LocationData("AL: Painting Guardian Waistcloth (prison tower, rafters)", + DS3LocationData("AL: Painting Guardian Waistcloth - prison tower, rafters", "Painting Guardian Waistcloth", hidden = True), # Invisible walkway - DS3LocationData("AL: Soul of a Crestfallen Knight (right of dark cathedral entrance)", + DS3LocationData("AL: Soul of a Crestfallen Knight - right of dark cathedral entrance", "Soul of a Crestfallen Knight"), - DS3LocationData("AL: Moonlight Arrow (dark cathedral, up right stairs)", + DS3LocationData("AL: Moonlight Arrow - dark cathedral, up right stairs", "Moonlight Arrow x6"), - DS3LocationData("AL: Proof of a Concord Kept (dark cathedral, up left stairs)", + DS3LocationData("AL: Proof of a Concord Kept - dark cathedral, up left stairs", "Proof of a Concord Kept"), - DS3LocationData("AL: Large Soul of a Weary Warrior (left of dark cathedral entrance)", + DS3LocationData("AL: Large Soul of a Weary Warrior - left of dark cathedral entrance", "Large Soul of a Weary Warrior"), - DS3LocationData("AL: Giant's Coal (by giant near dark cathedral)", "Giant's Coal"), - DS3LocationData("AL: Havel's Ring+2 (prison tower, rafters)", "Havel's Ring+2", ngp = True, + DS3LocationData("AL: Giant's Coal - by giant near dark cathedral", "Giant's Coal"), + DS3LocationData("AL: Havel's Ring+2 - prison tower, rafters", "Havel's Ring+2", ngp = True, hidden = True), # Invisible walkway - DS3LocationData("AL: Ring of Favor+1 (light cathedral, upstairs)", "Ring of Favor+1", + DS3LocationData("AL: Ring of Favor+1 - light cathedral, upstairs", "Ring of Favor+1", ngp = True), - DS3LocationData("AL: Sun Princess Ring (dark cathedral, after boss)", "Sun Princess Ring"), - DS3LocationData("AL: Reversal Ring (tomb, chest in corner)", "Reversal Ring", + DS3LocationData("AL: Sun Princess Ring - dark cathedral, after boss", "Sun Princess Ring"), + DS3LocationData("AL: Reversal Ring - tomb, chest in corner", "Reversal Ring", hidden = True), # Behind illusory wall - DS3LocationData("AL: Golden Ritual Spear (light cathedral, mimic upstairs)", + DS3LocationData("AL: Golden Ritual Spear - light cathedral, mimic upstairs", "Golden Ritual Spear", mimic = True), - DS3LocationData("AL: Ring of Favor (water reserves, both minibosses)", "Ring of Favor", + DS3LocationData("AL: Ring of Favor - water reserves, both minibosses", "Ring of Favor", miniboss = True, hidden = True), # Sulyvahn's Beast Duo drop, behind illusory wall - DS3LocationData("AL: Blade of the Darkmoon (Yorshka with Darkmoon Loyalty)", + DS3LocationData("AL: Blade of the Darkmoon - Yorshka with Darkmoon Loyalty", "Blade of the Darkmoon", missable = True, drop = True, npc = True), # Hidden walkway, missable because it will break Sirris's quest - DS3LocationData("AL: Simple Gem (light cathedral, lizard upstairs)", "Simple Gem", + DS3LocationData("AL: Simple Gem - light cathedral, lizard upstairs", "Simple Gem", lizard = True), - DS3LocationData("AL: Twinkling Titanite (lizard after light cathedral #1)", + DS3LocationData("AL: Twinkling Titanite - lizard after light cathedral #1", "Twinkling Titanite", lizard = True), - DS3LocationData("AL: Twinkling Titanite (lizard after light cathedral #2)", + DS3LocationData("AL: Twinkling Titanite - lizard after light cathedral #2", "Twinkling Titanite", lizard = True), - DS3LocationData("AL: Aldrich's Ruby (dark cathedral, miniboss)", "Aldrich's Ruby", + DS3LocationData("AL: Aldrich's Ruby - dark cathedral, miniboss", "Aldrich's Ruby", miniboss = True), # Deep Accursed drop - DS3LocationData("AL: Aldrich Faithful (water reserves, talk to McDonnel)", "Aldrich Faithful", + DS3LocationData("AL: Aldrich Faithful - water reserves, talk to McDonnel", "Aldrich Faithful", hidden = True), # Behind illusory wall - DS3LocationData("FS: Budding Green Blossom (shop killing Creighton and AL boss)", + DS3LocationData("FS: Budding Green Blossom - shop killing Creighton and AL boss", "Budding Green Blossom", offline = '99,0:-1:110000,70000118:', missable = True, npc = True, shop = True), # sold by Shrine Maiden after killing Aldrich and helping # Sirris defeat Creighton # Sirris (quest completion) - DS3LocationData("FS: Sunset Shield (by grave after killing Hodrick w/Sirris)", + DS3LocationData("FS: Sunset Shield - by grave after killing Hodrick w/Sirris", "Sunset Shield", missable = True, hostile_npc = True, npc = True), # In Pit of Hollows after killing Hodrick - DS3LocationData("US: Sunset Helm (Pit of Hollows after killing Hodrick w/Sirris)", + DS3LocationData("US: Sunset Helm - Pit of Hollows after killing Hodrick w/Sirris", "Sunset Helm", missable = True, hostile_npc = True, npc = True), - DS3LocationData("US: Sunset Armor (pit of hollows after killing Hodrick w/Sirris)", + DS3LocationData("US: Sunset Armor - pit of hollows after killing Hodrick w/Sirris", "Sunset Armor", missable = True, hostile_npc = True, npc = True), - DS3LocationData("US: Sunset Gauntlets (pit of hollows after killing Hodrick w/Sirris)", + DS3LocationData("US: Sunset Gauntlets - pit of hollows after killing Hodrick w/Sirris", "Sunset Gauntlets", missable = True, hostile_npc = True, npc = True), - DS3LocationData("US: Sunset Leggings (pit of hollows after killing Hodrick w/Sirris)", + DS3LocationData("US: Sunset Leggings - pit of hollows after killing Hodrick w/Sirris", "Sunset Leggings", missable = True, hostile_npc = True, npc = True), # Shrine Handmaid after killing Sulyvahn's Beast Duo - DS3LocationData("FS: Helm of Favor (shop after killing water reserve minibosses)", + DS3LocationData("FS: Helm of Favor - shop after killing water reserve minibosses", "Helm of Favor", hidden = True, miniboss = True, shop = True), - DS3LocationData("FS: Embraced Armor of Favor (shop after killing water reserve minibosses)", + DS3LocationData("FS: Embraced Armor of Favor - shop after killing water reserve minibosses", "Embraced Armor of Favor", hidden = True, miniboss = True, shop = True), - DS3LocationData("FS: Gauntlets of Favor (shop after killing water reserve minibosses)", + DS3LocationData("FS: Gauntlets of Favor - shop after killing water reserve minibosses", "Gauntlets of Favor", hidden = True, miniboss = True, shop = True), - DS3LocationData("FS: Leggings of Favor (shop after killing water reserve minibosses)", + DS3LocationData("FS: Leggings of Favor - shop after killing water reserve minibosses", "Leggings of Favor", hidden = True, miniboss = True, shop = True), # Anri of Astora - DS3LocationData("AL: Chameleon (tomb after marrying Anri)", "Chameleon", missable = True, + DS3LocationData("AL: Chameleon - tomb after marrying Anri", "Chameleon", missable = True, npc = True), - DS3LocationData("AL: Anri's Straight Sword (Anri quest)","Anri's Straight Sword", + DS3LocationData("AL: Anri's Straight Sword - Anri quest","Anri's Straight Sword", missable = True, npc = True), # Shrine Handmaid after killing Ringfinger Leonhard # This is listed here even though you can kill Leonhard immediately because we want the # logic to assume people will do his full quest. Missable because he can disappear forever # if you use up all your Pale Tongues. - DS3LocationData("FS: Leonhard's Garb (shop after killing Leonhard)", + DS3LocationData("FS: Leonhard's Garb - shop after killing Leonhard", "Leonhard's Garb", hidden = True, npc = True, shop = True, missable = True), - DS3LocationData("FS: Leonhard's Gauntlets (shop after killing Leonhard)", + DS3LocationData("FS: Leonhard's Gauntlets - shop after killing Leonhard", "Leonhard's Gauntlets", hidden = True, npc = True, shop = True, missable = True), - DS3LocationData("FS: Leonhard's Trousers (shop after killing Leonhard)", + DS3LocationData("FS: Leonhard's Trousers - shop after killing Leonhard", "Leonhard's Trousers", hidden = True, npc = True, shop = True, missable = True), # Shrine Handmaid after killing Alrich, Devourer of Gods - DS3LocationData("FS: Smough's Helm (shop after killing AL boss)", "Smough's Helm", + DS3LocationData("FS: Smough's Helm - shop after killing AL boss", "Smough's Helm", boss = True, shop = True), - DS3LocationData("FS: Smough's Armor (shop after killing AL boss)", "Smough's Armor", + DS3LocationData("FS: Smough's Armor - shop after killing AL boss", "Smough's Armor", boss = True, shop = True), - DS3LocationData("FS: Smough's Gauntlets (shop after killing AL boss)", "Smough's Gauntlets", + DS3LocationData("FS: Smough's Gauntlets - shop after killing AL boss", "Smough's Gauntlets", boss = True, shop = True), - DS3LocationData("FS: Smough's Leggings (shop after killing AL boss)", "Smough's Leggings", + DS3LocationData("FS: Smough's Leggings - shop after killing AL boss", "Smough's Leggings", boss = True, shop = True), # Shrine Handmaid after killing Anri or completing their quest - DS3LocationData("FS: Elite Knight Helm (shop after Anri quest)", "Elite Knight Helm", + DS3LocationData("FS: Elite Knight Helm - shop after Anri quest", "Elite Knight Helm", missable = True, npc = True, shop = True), - DS3LocationData("FS: Elite Knight Armor (shop after Anri quest)", "Elite Knight Armor", + DS3LocationData("FS: Elite Knight Armor - shop after Anri quest", "Elite Knight Armor", missable = True, npc = True, shop = True), - DS3LocationData("FS: Elite Knight Gauntlets (shop after Anri quest)", + DS3LocationData("FS: Elite Knight Gauntlets - shop after Anri quest", "Elite Knight Gauntlets", missable = True, npc = True, shop = True), - DS3LocationData("FS: Elite Knight Leggings (shop after Anri quest)", + DS3LocationData("FS: Elite Knight Leggings - shop after Anri quest", "Elite Knight Leggings", missable = True, npc = True, shop = True), # Ringfinger Leonhard (quest or kill) - DS3LocationData("AL: Crescent Moon Sword (Leonhard drop)", "Crescent Moon Sword", + DS3LocationData("AL: Crescent Moon Sword - Leonhard drop", "Crescent Moon Sword", missable = True, npc = True), - DS3LocationData("AL: Silver Mask (Leonhard drop)", "Silver Mask", missable = True, + DS3LocationData("AL: Silver Mask - Leonhard drop", "Silver Mask", missable = True, npc = True), - DS3LocationData("AL: Soul of Rosaria (Leonhard drop)", "Soul of Rosaria", missable = True, + DS3LocationData("AL: Soul of Rosaria - Leonhard drop", "Soul of Rosaria", missable = True, npc = True), ], "Lothric Castle": [ DS3LocationData("LC: Soul of Dragonslayer Armour", "Soul of Dragonslayer Armour", prominent = True, boss = True), - DS3LocationData("LC: Sniper Bolt (moat, right path end)", "Sniper Bolt x11"), - DS3LocationData("LC: Sniper Crossbow (moat, right path end)", "Sniper Crossbow"), - DS3LocationData("LC: Titanite Scale (dark room, upper balcony)", "Titanite Scale"), - DS3LocationData("LC: Titanite Chunk (dark room mid, out door opposite wyvern)", + DS3LocationData("LC: Sniper Bolt - moat, right path end", "Sniper Bolt x11"), + DS3LocationData("LC: Sniper Crossbow - moat, right path end", "Sniper Crossbow"), + DS3LocationData("LC: Titanite Scale - dark room, upper balcony", "Titanite Scale"), + DS3LocationData("LC: Titanite Chunk - dark room mid, out door opposite wyvern", "Titanite Chunk"), - DS3LocationData("LC: Greatlance (overlooking Dragon Barracks bonfire)", "Greatlance"), - DS3LocationData("LC: Titanite Chunk (ascent, first balcony)", "Titanite Chunk"), - DS3LocationData("LC: Titanite Chunk (ascent, turret before barricades)", "Titanite Chunk"), - DS3LocationData("LC: Sacred Bloom Shield (ascent, behind illusory wall)", + DS3LocationData("LC: Greatlance - overlooking Dragon Barracks bonfire", "Greatlance"), + DS3LocationData("LC: Titanite Chunk - ascent, first balcony", "Titanite Chunk"), + DS3LocationData("LC: Titanite Chunk - ascent, turret before barricades", "Titanite Chunk"), + DS3LocationData("LC: Sacred Bloom Shield - ascent, behind illusory wall", "Sacred Bloom Shield", hidden = True), # Behind illusory wall - DS3LocationData("LC: Titanite Chunk (ascent, final turret)", "Titanite Chunk x2"), - DS3LocationData("LC: Refined Gem (plaza)", "Refined Gem"), - DS3LocationData("LC: Soul of a Crestfallen Knight (by lift bottom)", + DS3LocationData("LC: Titanite Chunk - ascent, final turret", "Titanite Chunk x2"), + DS3LocationData("LC: Refined Gem - plaza", "Refined Gem"), + DS3LocationData("LC: Soul of a Crestfallen Knight - by lift bottom", "Soul of a Crestfallen Knight"), - DS3LocationData("LC: Undead Bone Shard (moat, far ledge)", "Undead Bone Shard"), - DS3LocationData("LC: Lightning Urn (moat, right path, first room)", "Lightning Urn x3"), - DS3LocationData("LC: Titanite Chunk (moat #1)", "Titanite Chunk"), - DS3LocationData("LC: Titanite Chunk (moat #2)", "Titanite Chunk"), - DS3LocationData("LC: Titanite Chunk (moat, near ledge)", "Titanite Chunk"), - DS3LocationData("LC: Caitha's Chime (chapel, drop onto roof)", "Caitha's Chime"), - DS3LocationData("LC: Lightning Urn (plaza)", "Lightning Urn x6"), - DS3LocationData("LC: Ember (plaza, by gate)", "Ember"), - DS3LocationData("LC: Raw Gem (plaza left)", "Raw Gem"), - DS3LocationData("LC: Black Firebomb (dark room lower)", "Black Firebomb x3"), - DS3LocationData("LC: Pale Pine Resin (dark room upper, by mimic)", "Pale Pine Resin"), - DS3LocationData("LC: Large Soul of a Weary Warrior (main hall, by lever)", + DS3LocationData("LC: Undead Bone Shard - moat, far ledge", "Undead Bone Shard"), + DS3LocationData("LC: Lightning Urn - moat, right path, first room", "Lightning Urn x3"), + DS3LocationData("LC: Titanite Chunk - moat #1", "Titanite Chunk"), + DS3LocationData("LC: Titanite Chunk - moat #2", "Titanite Chunk"), + DS3LocationData("LC: Titanite Chunk - moat, near ledge", "Titanite Chunk"), + DS3LocationData("LC: Caitha's Chime - chapel, drop onto roof", "Caitha's Chime"), + DS3LocationData("LC: Lightning Urn - plaza", "Lightning Urn x6"), + DS3LocationData("LC: Ember - plaza, by gate", "Ember"), + DS3LocationData("LC: Raw Gem - plaza left", "Raw Gem"), + DS3LocationData("LC: Black Firebomb - dark room lower", "Black Firebomb x3"), + DS3LocationData("LC: Pale Pine Resin - dark room upper, by mimic", "Pale Pine Resin"), + DS3LocationData("LC: Large Soul of a Weary Warrior - main hall, by lever", "Large Soul of a Weary Warrior"), - DS3LocationData("LC: Sunlight Medal (by lift top)", "Sunlight Medal"), - DS3LocationData("LC: Soul of a Crestfallen Knight (wyvern room, balcony)", + DS3LocationData("LC: Sunlight Medal - by lift top", "Sunlight Medal"), + DS3LocationData("LC: Soul of a Crestfallen Knight - wyvern room, balcony", "Soul of a Crestfallen Knight", hidden = True), # Hidden fall - DS3LocationData("LC: Titanite Chunk (altar roof)", "Titanite Chunk"), - DS3LocationData("LC: Titanite Scale (dark room mid, out door opposite wyvern)", + DS3LocationData("LC: Titanite Chunk - altar roof", "Titanite Chunk"), + DS3LocationData("LC: Titanite Scale - dark room mid, out door opposite wyvern", "Titanite Scale"), - DS3LocationData("LC: Large Soul of a Nameless Soldier (moat, right path)", + DS3LocationData("LC: Large Soul of a Nameless Soldier - moat, right path", "Large Soul of a Nameless Soldier"), - DS3LocationData("LC: Knight's Ring (altar)", "Knight's Ring"), - DS3LocationData("LC: Ember (main hall, left of stairs)", "Ember"), - DS3LocationData("LC: Large Soul of a Weary Warrior (ascent, last turret)", + DS3LocationData("LC: Knight's Ring - altar", "Knight's Ring"), + DS3LocationData("LC: Ember - main hall, left of stairs", "Ember"), + DS3LocationData("LC: Large Soul of a Weary Warrior - ascent, last turret", "Large Soul of a Weary Warrior"), - DS3LocationData("LC: Ember (by Dragon Barracks bonfire)", "Ember"), - DS3LocationData("LC: Twinkling Titanite (ascent, side room)", "Twinkling Titanite"), - DS3LocationData("LC: Large Soul of a Nameless Soldier (dark room mid)", + DS3LocationData("LC: Ember - by Dragon Barracks bonfire", "Ember"), + DS3LocationData("LC: Twinkling Titanite - ascent, side room", "Twinkling Titanite"), + DS3LocationData("LC: Large Soul of a Nameless Soldier - dark room mid", "Large Soul of a Nameless Soldier"), - DS3LocationData("LC: Ember (plaza center)", "Ember"), - DS3LocationData("LC: Winged Knight Helm (ascent, behind illusory wall)", + DS3LocationData("LC: Ember - plaza center", "Ember"), + DS3LocationData("LC: Winged Knight Helm - ascent, behind illusory wall", "Winged Knight Helm", hidden = True), - DS3LocationData("LC: Winged Knight Armor (ascent, behind illusory wall)", + DS3LocationData("LC: Winged Knight Armor - ascent, behind illusory wall", "Winged Knight Armor", hidden = True), - DS3LocationData("LC: Winged Knight Gauntlets (ascent, behind illusory wall)", + DS3LocationData("LC: Winged Knight Gauntlets - ascent, behind illusory wall", "Winged Knight Gauntlets", hidden = True), - DS3LocationData("LC: Winged Knight Leggings (ascent, behind illusory wall)", + DS3LocationData("LC: Winged Knight Leggings - ascent, behind illusory wall", "Winged Knight Leggings", hidden = True), - DS3LocationData("LC: Rusted Coin (chapel)", "Rusted Coin x2"), - DS3LocationData("LC: Braille Divine Tome of Lothric (wyvern room)", + DS3LocationData("LC: Rusted Coin - chapel", "Rusted Coin x2"), + DS3LocationData("LC: Braille Divine Tome of Lothric - wyvern room", "Braille Divine Tome of Lothric", hidden = True), # Hidden fall - DS3LocationData("LC: Red Tearstone Ring (chapel, drop onto roof)", "Red Tearstone Ring"), - DS3LocationData("LC: Twinkling Titanite (moat, left side)", "Twinkling Titanite x2"), - DS3LocationData("LC: Large Soul of a Nameless Soldier (plaza left, by pillar)", + DS3LocationData("LC: Red Tearstone Ring - chapel, drop onto roof", "Red Tearstone Ring"), + DS3LocationData("LC: Twinkling Titanite - moat, left side", "Twinkling Titanite x2"), + DS3LocationData("LC: Large Soul of a Nameless Soldier - plaza left, by pillar", "Large Soul of a Nameless Soldier"), - DS3LocationData("LC: Titanite Scale (altar)", "Titanite Scale x3"), - DS3LocationData("LC: Titanite Scale (chapel, chest)", "Titanite Scale"), + DS3LocationData("LC: Titanite Scale - altar", "Titanite Scale x3"), + DS3LocationData("LC: Titanite Scale - chapel, chest", "Titanite Scale"), DS3LocationData("LC: Hood of Prayer", "Hood of Prayer"), - DS3LocationData("LC: Robe of Prayer (ascent, chest at beginning)", "Robe of Prayer"), - DS3LocationData("LC: Skirt of Prayer (ascent, chest at beginning)", "Skirt of Prayer"), - DS3LocationData("LC: Spirit Tree Crest Shield (basement, chest)", + DS3LocationData("LC: Robe of Prayer - ascent, chest at beginning", "Robe of Prayer"), + DS3LocationData("LC: Skirt of Prayer - ascent, chest at beginning", "Skirt of Prayer"), + DS3LocationData("LC: Spirit Tree Crest Shield - basement, chest", "Spirit Tree Crest Shield"), - DS3LocationData("LC: Titanite Scale (basement, chest)", "Titanite Scale"), - DS3LocationData("LC: Twinkling Titanite (basement, chest #1)", "Twinkling Titanite"), - DS3LocationData("LC: Twinkling Titanite (basement, chest #2)", "Twinkling Titanite x2"), - DS3LocationData("LC: Life Ring+2 (dark room mid, out door opposite wyvern, drop down)", + DS3LocationData("LC: Titanite Scale - basement, chest", "Titanite Scale"), + DS3LocationData("LC: Twinkling Titanite - basement, chest #1", "Twinkling Titanite"), + DS3LocationData("LC: Twinkling Titanite - basement, chest #2", "Twinkling Titanite x2"), + DS3LocationData("LC: Life Ring+2 - dark room mid, out door opposite wyvern, drop down", "Life Ring+2", ngp = True, hidden = True), # Hidden fall - DS3LocationData("LC: Dark Stoneplate Ring+1 (wyvern room, balcony)", + DS3LocationData("LC: Dark Stoneplate Ring+1 - wyvern room, balcony", "Dark Stoneplate Ring+1", ngp = True, hidden = True), # Hidden fall - DS3LocationData("LC: Thunder Stoneplate Ring+2 (chapel, drop onto roof)", + DS3LocationData("LC: Thunder Stoneplate Ring+2 - chapel, drop onto roof", "Thunder Stoneplate Ring+2", ngp = True), - DS3LocationData("LC: Sunlight Straight Sword (wyvern room, mimic)", + DS3LocationData("LC: Sunlight Straight Sword - wyvern room, mimic", "Sunlight Straight Sword", mimic = True, hidden = True), # Hidden fall - DS3LocationData("LC: Titanite Scale (dark room, upper, mimic)", "Titanite Scale x3", + DS3LocationData("LC: Titanite Scale - dark room, upper, mimic", "Titanite Scale x3", mimic = True), - DS3LocationData("LC: Ember (wyvern room, wyvern foot mob drop)", "Ember x2", + DS3LocationData("LC: Ember - wyvern room, wyvern foot mob drop", "Ember x2", drop = True, hidden = True), # Hidden fall, Pus of Man Wyvern drop - DS3LocationData("LC: Titanite Chunk (wyvern room, wyvern foot mob drop)", "Titanite Chunk x2", + DS3LocationData("LC: Titanite Chunk - wyvern room, wyvern foot mob drop", "Titanite Chunk x2", drop = True, hidden = True), # Hidden fall, Pus of Man Wyvern drop - DS3LocationData("LC: Ember (dark room mid, pus of man mob drop)", "Ember x2", + DS3LocationData("LC: Ember - dark room mid, pus of man mob drop", "Ember x2", drop = True), # Pus of Man Wyvern drop - DS3LocationData("LC: Titanite Chunk (dark room mid, pus of man mob drop)", + DS3LocationData("LC: Titanite Chunk - dark room mid, pus of man mob drop", "Titanite Chunk x2"), - DS3LocationData("LC: Irithyll Rapier (basement, miniboss drop)", "Irithyll Rapier", + DS3LocationData("LC: Irithyll Rapier - basement, miniboss drop", "Irithyll Rapier", miniboss = True), # Boreal Outrider drop - DS3LocationData("LC: Twinkling Titanite (dark room mid, out door opposite wyvern, lizard)", + DS3LocationData("LC: Twinkling Titanite - dark room mid, out door opposite wyvern, lizard", "Twinkling Titanite x2", lizard = True), - DS3LocationData("LC: Twinkling Titanite (moat, right path, lizard)", + DS3LocationData("LC: Twinkling Titanite - moat, right path, lizard", "Twinkling Titanite x2", lizard = True), - DS3LocationData("LC: Gotthard Twinswords (by Grand Archives door, after PC and AL bosses)", + DS3LocationData("LC: Gotthard Twinswords - by Grand Archives door, after PC and AL bosses", "Gotthard Twinswords", conditional = True), - DS3LocationData("LC: Grand Archives Key (by Grand Archives door, after PC and AL bosses)", + DS3LocationData("LC: Grand Archives Key - by Grand Archives door, after PC and AL bosses", "Grand Archives Key", prominent = True, progression = True, conditional = True), - DS3LocationData("LC: Titanite Chunk (down stairs after boss)", "Titanite Chunk"), + DS3LocationData("LC: Titanite Chunk - down stairs after boss", "Titanite Chunk"), # Eygon of Carim (kill or quest) - DS3LocationData("FS: Morne's Great Hammer (Eygon)", "Morne's Great Hammer", npc = True), - DS3LocationData("FS: Moaning Shield (Eygon)", "Moaning Shield", npc = True), + DS3LocationData("FS: Morne's Great Hammer - Eygon", "Morne's Great Hammer", npc = True), + DS3LocationData("FS: Moaning Shield - Eygon", "Moaning Shield", npc = True), # Shrine Handmaid after killing Dragonslayer Armour (or Eygon of Carim) - DS3LocationData("FS: Dancer's Crown (shop after killing LC entry boss)", "Dancer's Crown", + DS3LocationData("FS: Dancer's Crown - shop after killing LC entry boss", "Dancer's Crown", boss = True, shop = True), - DS3LocationData("FS: Dancer's Armor (shop after killing LC entry boss)", "Dancer's Armor", + DS3LocationData("FS: Dancer's Armor - shop after killing LC entry boss", "Dancer's Armor", boss = True, shop = True), - DS3LocationData("FS: Dancer's Gauntlets (shop after killing LC entry boss)", + DS3LocationData("FS: Dancer's Gauntlets - shop after killing LC entry boss", "Dancer's Gauntlets", boss = True, shop = True), - DS3LocationData("FS: Dancer's Leggings (shop after killing LC entry boss)", + DS3LocationData("FS: Dancer's Leggings - shop after killing LC entry boss", "Dancer's Leggings", boss = True, shop = True), # Shrine Handmaid after killing Dragonslayer Armour (or Eygon of Carim) - DS3LocationData("FS: Morne's Helm (shop after killing Eygon or LC boss)", "Morne's Helm", + DS3LocationData("FS: Morne's Helm - shop after killing Eygon or LC boss", "Morne's Helm", boss = True, shop = True), - DS3LocationData("FS: Morne's Armor (shop after killing Eygon or LC boss)", "Morne's Armor", + DS3LocationData("FS: Morne's Armor - shop after killing Eygon or LC boss", "Morne's Armor", boss = True, shop = True), - DS3LocationData("FS: Morne's Gauntlets (shop after killing Eygon or LC boss)", + DS3LocationData("FS: Morne's Gauntlets - shop after killing Eygon or LC boss", "Morne's Gauntlets", boss = True, shop = True), - DS3LocationData("FS: Morne's Leggings (shop after killing Eygon or LC boss)", + DS3LocationData("FS: Morne's Leggings - shop after killing Eygon or LC boss", "Morne's Leggings", boss = True, shop = True), ], "Consumed King's Garden": [ @@ -2104,363 +2104,363 @@ def __init__( prominent = True, boss = True), # Could classify this as "hidden" because it's midway down an elevator, but the elevator is # so slow and the midway point is so obvious that it's not actually hard to find. - DS3LocationData("CKG: Estus Shard (balcony)", "Estus Shard"), - DS3LocationData("CKG: Shadow Mask (under center platform)", "Shadow Mask"), - DS3LocationData("CKG: Shadow Garb (under rotunda)", "Shadow Garb"), - DS3LocationData("CKG: Shadow Gauntlets (under rotunda)", "Shadow Gauntlets"), - DS3LocationData("CKG: Shadow Leggings (under rotunda)", "Shadow Leggings"), - DS3LocationData("CKG: Black Firebomb (under rotunda)", "Black Firebomb x2"), - DS3LocationData("CKG: Claw (under rotunda)", "Claw"), - DS3LocationData("CKG: Titanite Chunk (up lone stairway)", "Titanite Chunk"), - DS3LocationData("CKG: Dragonscale Ring (shortcut, leave halfway down lift)", + DS3LocationData("CKG: Estus Shard - balcony", "Estus Shard"), + DS3LocationData("CKG: Shadow Mask - under center platform", "Shadow Mask"), + DS3LocationData("CKG: Shadow Garb - under rotunda", "Shadow Garb"), + DS3LocationData("CKG: Shadow Gauntlets - under rotunda", "Shadow Gauntlets"), + DS3LocationData("CKG: Shadow Leggings - under rotunda", "Shadow Leggings"), + DS3LocationData("CKG: Black Firebomb - under rotunda", "Black Firebomb x2"), + DS3LocationData("CKG: Claw - under rotunda", "Claw"), + DS3LocationData("CKG: Titanite Chunk - up lone stairway", "Titanite Chunk"), + DS3LocationData("CKG: Dragonscale Ring - shortcut, leave halfway down lift", "Dragonscale Ring"), - DS3LocationData("CKG: Human Pine Resin (toxic pool, past rotunda)", "Human Pine Resin"), - DS3LocationData("CKG: Titanite Chunk (shortcut)", "Titanite Chunk"), - DS3LocationData("CKG: Titanite Chunk (balcony, drop onto rubble)", "Titanite Chunk"), - DS3LocationData("CKG: Soul of a Weary Warrior (before first lift)", + DS3LocationData("CKG: Human Pine Resin - toxic pool, past rotunda", "Human Pine Resin"), + DS3LocationData("CKG: Titanite Chunk - shortcut", "Titanite Chunk"), + DS3LocationData("CKG: Titanite Chunk - balcony, drop onto rubble", "Titanite Chunk"), + DS3LocationData("CKG: Soul of a Weary Warrior - before first lift", "Soul of a Weary Warrior"), - DS3LocationData("CKG: Dark Gem (under lone stairway)", "Dark Gem"), - DS3LocationData("CKG: Titanite Scale (shortcut)", "Titanite Scale"), - DS3LocationData("CKG: Human Pine Resin (by lone stairway bottom)", + DS3LocationData("CKG: Dark Gem - under lone stairway", "Dark Gem"), + DS3LocationData("CKG: Titanite Scale - shortcut", "Titanite Scale"), + DS3LocationData("CKG: Human Pine Resin - by lone stairway bottom", "Human Pine Resin x2"), - DS3LocationData("CKG: Titanite Chunk (right of shortcut lift bottom)", "Titanite Chunk"), - DS3LocationData("CKG: Ring of Sacrifice (under balcony)", "Ring of Sacrifice"), - DS3LocationData("CKG: Wood Grain Ring+1 (by first elevator bottom)", "Wood Grain Ring+1", + DS3LocationData("CKG: Titanite Chunk - right of shortcut lift bottom", "Titanite Chunk"), + DS3LocationData("CKG: Ring of Sacrifice - under balcony", "Ring of Sacrifice"), + DS3LocationData("CKG: Wood Grain Ring+1 - by first elevator bottom", "Wood Grain Ring+1", ngp = True), - DS3LocationData("CKG: Sage Ring+2 (balcony, drop onto rubble, jump back)", "Sage Ring+2", + DS3LocationData("CKG: Sage Ring+2 - balcony, drop onto rubble, jump back", "Sage Ring+2", ngp = True, hidden = True), - DS3LocationData("CKG: Titanite Scale (tomb, chest #1)", "Titanite Scale"), - DS3LocationData("CKG: Titanite Scale (tomb, chest #2)", "Titanite Scale"), - DS3LocationData("CKG: Magic Stoneplate Ring (mob drop before boss)", + DS3LocationData("CKG: Titanite Scale - tomb, chest #1", "Titanite Scale"), + DS3LocationData("CKG: Titanite Scale - tomb, chest #2", "Titanite Scale"), + DS3LocationData("CKG: Magic Stoneplate Ring - mob drop before boss", "Magic Stoneplate Ring", drop = True, hidden = True), # Guaranteed drop from a normal-looking Cathedral Knight DS3LocationData("CKG -> UG", None), # After Oceiros's boss room, only once the Drakeblood summon in AP has been killed - DS3LocationData("CKG: Drakeblood Helm (tomb, after killing AP mausoleum NPC)", + DS3LocationData("CKG: Drakeblood Helm - tomb, after killing AP mausoleum NPC", "Drakeblood Helm", hostile_npc = True, hidden = True), - DS3LocationData("CKG: Drakeblood Armor (tomb, after killing AP mausoleum NPC)", + DS3LocationData("CKG: Drakeblood Armor - tomb, after killing AP mausoleum NPC", "Drakeblood Armor", hostile_npc = True, hidden = True), - DS3LocationData("CKG: Drakeblood Gauntlets (tomb, after killing AP mausoleum NPC)", + DS3LocationData("CKG: Drakeblood Gauntlets - tomb, after killing AP mausoleum NPC", "Drakeblood Gauntlets", hostile_npc = True, hidden = True), - DS3LocationData("CKG: Drakeblood Leggings (tomb, after killing AP mausoleum NPC)", + DS3LocationData("CKG: Drakeblood Leggings - tomb, after killing AP mausoleum NPC", "Drakeblood Leggings", hostile_npc = True, hidden = True), ], "Grand Archives": [ - DS3LocationData("GA: Titanite Slab (final elevator secret)", "Titanite Slab", + DS3LocationData("GA: Titanite Slab - final elevator secret", "Titanite Slab", hidden = True), DS3LocationData("GA: Soul of the Twin Princes", "Soul of the Twin Princes", boss = True), DS3LocationData("GA: Cinders of a Lord - Lothric Prince", "Cinders of a Lord - Lothric Prince", offline = "09,0:50002040::", prominent = True, progression = True, boss = True), - DS3LocationData("GA: Onikiri and Ubadachi (outside 5F, NPC drop)", "Onikiri and Ubadachi", + DS3LocationData("GA: Onikiri and Ubadachi - outside 5F, NPC drop", "Onikiri and Ubadachi", hostile_npc = True, # Black Hand Kamui drop missable = True), # This is placed at the location the NPC gets randomized # to, which makes it hard to include in logic. - DS3LocationData("GA: Golden Wing Crest Shield (outside 5F, NPC drop)", + DS3LocationData("GA: Golden Wing Crest Shield - outside 5F, NPC drop", "Golden Wing Crest Shield", hostile_npc = True), # Lion Knight Albert drop - DS3LocationData("GA: Sage's Crystal Staff (outside 5F, NPC drop)", + DS3LocationData("GA: Sage's Crystal Staff - outside 5F, NPC drop", "Sage's Crystal Staff", hostile_npc = True), # Daughter of Crystal Kriemhild drop - DS3LocationData("GA: Titanite Chunk (1F, up right stairs)", "Titanite Chunk"), - DS3LocationData("GA: Titanite Chunk (1F, path from wax pool)", "Titanite Chunk"), - DS3LocationData("GA: Soul of a Crestfallen Knight (1F, loop left after drop)", + DS3LocationData("GA: Titanite Chunk - 1F, up right stairs", "Titanite Chunk"), + DS3LocationData("GA: Titanite Chunk - 1F, path from wax pool", "Titanite Chunk"), + DS3LocationData("GA: Soul of a Crestfallen Knight - 1F, loop left after drop", "Soul of a Crestfallen Knight"), - DS3LocationData("GA: Titanite Chunk (1F, balcony)", "Titanite Chunk"), - DS3LocationData("GA: Fleshbite Ring (up stairs from 4F)", "Fleshbite Ring"), - DS3LocationData("GA: Soul of a Crestfallen Knight (path to dome)", + DS3LocationData("GA: Titanite Chunk - 1F, balcony", "Titanite Chunk"), + DS3LocationData("GA: Fleshbite Ring - up stairs from 4F", "Fleshbite Ring"), + DS3LocationData("GA: Soul of a Crestfallen Knight - path to dome", "Soul of a Crestfallen Knight"), - DS3LocationData("GA: Soul of a Nameless Soldier (dark room)", "Soul of a Nameless Soldier"), - DS3LocationData("GA: Crystal Chime (1F, path from wax pool)", "Crystal Chime"), - DS3LocationData("GA: Titanite Scale (dark room, upstairs)", "Titanite Scale"), - DS3LocationData("GA: Estus Shard (dome, far balcony)", "Estus Shard"), - DS3LocationData("GA: Homeward Bone (2F early balcony)", "Homeward Bone x3"), - DS3LocationData("GA: Titanite Scale (2F, titanite scale atop bookshelf)", "Titanite Scale", + DS3LocationData("GA: Soul of a Nameless Soldier - dark room", "Soul of a Nameless Soldier"), + DS3LocationData("GA: Crystal Chime - 1F, path from wax pool", "Crystal Chime"), + DS3LocationData("GA: Titanite Scale - dark room, upstairs", "Titanite Scale"), + DS3LocationData("GA: Estus Shard - dome, far balcony", "Estus Shard"), + DS3LocationData("GA: Homeward Bone - 2F early balcony", "Homeward Bone x3"), + DS3LocationData("GA: Titanite Scale - 2F, titanite scale atop bookshelf", "Titanite Scale", hidden = True), # Hidden fall - DS3LocationData("GA: Titanite Chunk (2F, by wax pool)", "Titanite Chunk"), - DS3LocationData("GA: Hollow Gem (rooftops lower, in hall)", "Hollow Gem", + DS3LocationData("GA: Titanite Chunk - 2F, by wax pool", "Titanite Chunk"), + DS3LocationData("GA: Hollow Gem - rooftops lower, in hall", "Hollow Gem", hidden = True), # Hidden fall - DS3LocationData("GA: Titanite Scale (3F, corner up stairs)", "Titanite Scale"), - DS3LocationData("GA: Titanite Scale (1F, up stairs on bookshelf)", "Titanite Scale"), - DS3LocationData("GA: Titanite Scale (3F, by ladder to 2F late)", "Titanite Scale", + DS3LocationData("GA: Titanite Scale - 3F, corner up stairs", "Titanite Scale"), + DS3LocationData("GA: Titanite Scale - 1F, up stairs on bookshelf", "Titanite Scale"), + DS3LocationData("GA: Titanite Scale - 3F, by ladder to 2F late", "Titanite Scale", hidden = True), # Hidden by a table - DS3LocationData("GA: Shriving Stone (2F late, by ladder from 3F)", "Shriving Stone"), - DS3LocationData("GA: Large Soul of a Crestfallen Knight (4F, back)", + DS3LocationData("GA: Shriving Stone - 2F late, by ladder from 3F", "Shriving Stone"), + DS3LocationData("GA: Large Soul of a Crestfallen Knight - 4F, back", "Large Soul of a Crestfallen Knight"), - DS3LocationData("GA: Titanite Chunk (rooftopps, balcony)", "Titanite Chunk"), - DS3LocationData("GA: Titanite Scale (rooftops lower, path to 2F)", "Titanite Scale x3", + DS3LocationData("GA: Titanite Chunk - rooftopps, balcony", "Titanite Chunk"), + DS3LocationData("GA: Titanite Scale - rooftops lower, path to 2F", "Titanite Scale x3", hidden = True), # Hidden fall - DS3LocationData("GA: Titanite Chunk (rooftops lower, ledge by buttress)", "Titanite Chunk", + DS3LocationData("GA: Titanite Chunk - rooftops lower, ledge by buttress", "Titanite Chunk", hidden = True), # Hidden fall - DS3LocationData("GA: Soul of a Weary Warrior (rooftops, by lizards)", + DS3LocationData("GA: Soul of a Weary Warrior - rooftops, by lizards", "Soul of a Weary Warrior"), - DS3LocationData("GA: Titanite Chunk (rooftops, just before 5F)", "Titanite Chunk"), - DS3LocationData("GA: Ember (5F, by entrance)", "Ember"), - DS3LocationData("GA: Blessed Gem (rafters)", "Blessed Gem"), - DS3LocationData("GA: Titanite Chunk (5F, far balcony)", "Titanite Chunk x2"), - DS3LocationData("GA: Large Soul of a Crestfallen Knight (outside 5F)", + DS3LocationData("GA: Titanite Chunk - rooftops, just before 5F", "Titanite Chunk"), + DS3LocationData("GA: Ember - 5F, by entrance", "Ember"), + DS3LocationData("GA: Blessed Gem - rafters", "Blessed Gem"), + DS3LocationData("GA: Titanite Chunk - 5F, far balcony", "Titanite Chunk x2"), + DS3LocationData("GA: Large Soul of a Crestfallen Knight - outside 5F", "Large Soul of a Crestfallen Knight"), - DS3LocationData("GA: Avelyn (1F, drop from 3F onto bookshelves)", "Avelyn", + DS3LocationData("GA: Avelyn - 1F, drop from 3F onto bookshelves", "Avelyn", hidden = True), # Hidden fall - DS3LocationData("GA: Titanite Chunk (2F, right after dark room)", "Titanite Chunk"), - DS3LocationData("GA: Hunter's Ring (dome, very top)", "Hunter's Ring"), - DS3LocationData("GA: Divine Pillars of Light (cage above rafters)", + DS3LocationData("GA: Titanite Chunk - 2F, right after dark room", "Titanite Chunk"), + DS3LocationData("GA: Hunter's Ring - dome, very top", "Hunter's Ring"), + DS3LocationData("GA: Divine Pillars of Light - cage above rafters", "Divine Pillars of Light"), - DS3LocationData("GA: Power Within (dark room, behind retractable bookshelf)", + DS3LocationData("GA: Power Within - dark room, behind retractable bookshelf", "Power Within", hidden = True), # Switch in darkened room - DS3LocationData("GA: Sage Ring+1 (rafters, second level down)", "Sage Ring+1", ngp = True), - DS3LocationData("GA: Lingering Dragoncrest Ring+2 (dome, room behind spire)", + DS3LocationData("GA: Sage Ring+1 - rafters, second level down", "Sage Ring+1", ngp = True), + DS3LocationData("GA: Lingering Dragoncrest Ring+2 - dome, room behind spire", "Lingering Dragoncrest Ring+2", ngp = True), - DS3LocationData("GA: Divine Blessing (rafters, down lower level ladder)", + DS3LocationData("GA: Divine Blessing - rafters, down lower level ladder", "Divine Blessing"), - DS3LocationData("GA: Twinkling Titanite (rafters, down lower level ladder)", + DS3LocationData("GA: Twinkling Titanite - rafters, down lower level ladder", "Twinkling Titanite x3"), - DS3LocationData("GA: Witch's Locks (dark room, behind retractable bookshelf)", + DS3LocationData("GA: Witch's Locks - dark room, behind retractable bookshelf", "Witch's Locks", hidden = True), # Switch in darkened room - DS3LocationData("GA: Titanite Slab (1F, after pulling 2F switch)", "Titanite Slab", + DS3LocationData("GA: Titanite Slab - 1F, after pulling 2F switch", "Titanite Slab", hidden = True), - DS3LocationData("GA: Titanite Scale (5F, chest by exit)", "Titanite Scale x3"), - DS3LocationData("GA: Soul Stream (3F, behind illusory wall)", "Soul Stream", + DS3LocationData("GA: Titanite Scale - 5F, chest by exit", "Titanite Scale x3"), + DS3LocationData("GA: Soul Stream - 3F, behind illusory wall", "Soul Stream", hidden = True), # Behind illusory wall - DS3LocationData("GA: Scholar Ring (2F, between late and early)", "Scholar Ring"), - DS3LocationData("GA: Undead Bone Shard (5F, by entrance)", "Undead Bone Shard"), - DS3LocationData("GA: Titanite Slab (dome, kill all mobs)", "Titanite Slab", + DS3LocationData("GA: Scholar Ring - 2F, between late and early", "Scholar Ring"), + DS3LocationData("GA: Undead Bone Shard - 5F, by entrance", "Undead Bone Shard"), + DS3LocationData("GA: Titanite Slab - dome, kill all mobs", "Titanite Slab", drop = True, hidden = True), # Guaranteed drop from killing all Winged Knights - DS3LocationData("GA: Outrider Knight Helm (3F, behind illusory wall, miniboss drop)", + DS3LocationData("GA: Outrider Knight Helm - 3F, behind illusory wall, miniboss drop", "Outrider Knight Helm", miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop - DS3LocationData("GA: Outrider Knight Armor (3F, behind illusory wall, miniboss drop)", + DS3LocationData("GA: Outrider Knight Armor - 3F, behind illusory wall, miniboss drop", "Outrider Knight Armor", miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop - DS3LocationData("GA: Outrider Knight Gauntlets (3F, behind illusory wall, miniboss drop)", + DS3LocationData("GA: Outrider Knight Gauntlets - 3F, behind illusory wall, miniboss drop", "Outrider Knight Gauntlets", miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop - DS3LocationData("GA: Outrider Knight Leggings (3F, behind illusory wall, miniboss drop)", + DS3LocationData("GA: Outrider Knight Leggings - 3F, behind illusory wall, miniboss drop", "Outrider Knight Leggings", miniboss = True, hidden = True), # Behind illusory wall, Outrider Knight drop - DS3LocationData("GA: Crystal Scroll (2F late, miniboss drop)", "Crystal Scroll", + DS3LocationData("GA: Crystal Scroll - 2F late, miniboss drop", "Crystal Scroll", miniboss = True), # Crystal Sage drop - DS3LocationData("GA: Twinkling Titanite (dark room, lizard #1)", "Twinkling Titanite", + DS3LocationData("GA: Twinkling Titanite - dark room, lizard #1", "Twinkling Titanite", lizard = True), - DS3LocationData("GA: Chaos Gem (dark room, lizard)", "Chaos Gem", lizard = True), - DS3LocationData("GA: Twinkling Titanite (1F, lizard by drop)", "Twinkling Titanite", + DS3LocationData("GA: Chaos Gem - dark room, lizard", "Chaos Gem", lizard = True), + DS3LocationData("GA: Twinkling Titanite - 1F, lizard by drop", "Twinkling Titanite", lizard = True), - DS3LocationData("GA: Crystal Gem (1F, lizard by drop)", "Crystal Gem", lizard = True), - DS3LocationData("GA: Twinkling Titanite (2F, lizard by entrance)", "Twinkling Titanite x2", + DS3LocationData("GA: Crystal Gem - 1F, lizard by drop", "Crystal Gem", lizard = True), + DS3LocationData("GA: Twinkling Titanite - 2F, lizard by entrance", "Twinkling Titanite x2", lizard = True), - DS3LocationData("GA: Titanite Scale (1F, drop from 2F late onto bookshelves, lizard)", + DS3LocationData("GA: Titanite Scale - 1F, drop from 2F late onto bookshelves, lizard", "Titanite Scale x2", lizard = True, hidden = True), # Hidden fall - DS3LocationData("GA: Twinkling Titanite (rooftops, lizard #1)", "Twinkling Titanite", + DS3LocationData("GA: Twinkling Titanite - rooftops, lizard #1", "Twinkling Titanite", lizard = True), - DS3LocationData("GA: Heavy Gem (rooftops, lizard)", "Heavy Gem", lizard = True), - DS3LocationData("GA: Twinkling Titanite (rooftops, lizard #2)", "Twinkling Titanite", + DS3LocationData("GA: Heavy Gem - rooftops, lizard", "Heavy Gem", lizard = True), + DS3LocationData("GA: Twinkling Titanite - rooftops, lizard #2", "Twinkling Titanite", lizard = True), - DS3LocationData("GA: Sharp Gem (rooftops, lizard)", "Sharp Gem", lizard = True), - DS3LocationData("GA: Twinkling Titanite (up stairs from 4F, lizard)", "Twinkling Titanite", + DS3LocationData("GA: Sharp Gem - rooftops, lizard", "Sharp Gem", lizard = True), + DS3LocationData("GA: Twinkling Titanite - up stairs from 4F, lizard", "Twinkling Titanite", lizard = True), - DS3LocationData("GA: Refined Gem (up stairs from 4F, lizard)", "Refined Gem", + DS3LocationData("GA: Refined Gem - up stairs from 4F, lizard", "Refined Gem", lizard = True), - DS3LocationData("GA: Twinkling Titanite (dark room, lizard #2)", "Twinkling Titanite x2", + DS3LocationData("GA: Twinkling Titanite - dark room, lizard #2", "Twinkling Titanite x2", lizard = True), # Shrine Handmaid after killing NPCs - DS3LocationData("FS: Faraam Helm (shop after killing GA NPC)", "Faraam Helm", + DS3LocationData("FS: Faraam Helm - shop after killing GA NPC", "Faraam Helm", hidden = True, hostile_npc = True, shop = True), - DS3LocationData("GA: Faraam Armor (shop after killing GA NPC)", "Faraam Armor", + DS3LocationData("GA: Faraam Armor - shop after killing GA NPC", "Faraam Armor", hidden = True, hostile_npc = True, shop = True), - DS3LocationData("GA: Faraam Gauntlets (shop after killing GA NPC)", "Faraam Gauntlets", + DS3LocationData("GA: Faraam Gauntlets - shop after killing GA NPC", "Faraam Gauntlets", hidden = True, hostile_npc = True, shop = True), - DS3LocationData("GA: Faraam Boots (shop after killing GA NPC)", "Faraam Boots", + DS3LocationData("GA: Faraam Boots - shop after killing GA NPC", "Faraam Boots", hidden = True, hostile_npc = True, shop = True), - DS3LocationData("GA: Black Hand Hat (shop after killing GA NPC)", "Black Hand Hat", + DS3LocationData("GA: Black Hand Hat - shop after killing GA NPC", "Black Hand Hat", hidden = True, hostile_npc = True, shop = True), - DS3LocationData("GA: Black Hand Armor (shop after killing GA NPC)", "Black Hand Armor", + DS3LocationData("GA: Black Hand Armor - shop after killing GA NPC", "Black Hand Armor", hidden = True, hostile_npc = True, shop = True), # Shrine Handmaid after killing Lothric, Younger Prince - DS3LocationData("FS: Lorian's Helm (shop after killing GA boss)", "Lorian's Helm", + DS3LocationData("FS: Lorian's Helm - shop after killing GA boss", "Lorian's Helm", boss = True, shop = True), - DS3LocationData("FS: Lorian's Armor (shop after killing GA boss)", "Lorian's Armor", + DS3LocationData("FS: Lorian's Armor - shop after killing GA boss", "Lorian's Armor", boss = True, shop = True), - DS3LocationData("FS: Lorian's Gauntlets (shop after killing GA boss)", "Lorian's Gauntlets", + DS3LocationData("FS: Lorian's Gauntlets - shop after killing GA boss", "Lorian's Gauntlets", boss = True, shop = True), - DS3LocationData("FS: Lorian's Leggings (shop after killing GA boss)", "Lorian's Leggings", + DS3LocationData("FS: Lorian's Leggings - shop after killing GA boss", "Lorian's Leggings", boss = True, shop = True), # Sirris quest completion + beat Twin Princes - DS3LocationData("FS: Sunless Talisman (Sirris, kill GA boss)", "Sunless Talisman", + DS3LocationData("FS: Sunless Talisman - Sirris, kill GA boss", "Sunless Talisman", missable = True, npc = True), - DS3LocationData("FS: Sunless Veil (shop, Sirris quest, kill GA boss)", "Sunless Veil", + DS3LocationData("FS: Sunless Veil - shop, Sirris quest, kill GA boss", "Sunless Veil", missable = True, npc = True, shop = True), - DS3LocationData("FS: Sunless Armor (shop, Sirris quest, kill GA boss)", "Sunless Armor", + DS3LocationData("FS: Sunless Armor - shop, Sirris quest, kill GA boss", "Sunless Armor", missable = True, npc = True, shop = True), - DS3LocationData("FS: Sunless Gauntlets (shop, Sirris quest, kill GA boss)", + DS3LocationData("FS: Sunless Gauntlets - shop, Sirris quest, kill GA boss", "Sunless Gauntlets", missable = True, npc = True, shop = True), - DS3LocationData("FS: Sunless Leggings (shop, Sirris quest, kill GA boss)", + DS3LocationData("FS: Sunless Leggings - shop, Sirris quest, kill GA boss", "Sunless Leggings", missable = True, npc = True, shop = True), ], "Untended Graves": [ DS3LocationData("UG: Soul of Champion Gundyr", "Soul of Champion Gundyr", prominent = True, boss = True), - DS3LocationData("UG: Priestess Ring (shop)", "Priestess Ring", shop = True), - DS3LocationData("UG: Shriving Stone (swamp, by bonfire)", "Shriving Stone"), - DS3LocationData("UG: Titanite Chunk (swamp, left path by fountain)", "Titanite Chunk"), - DS3LocationData("UG: Soul of a Crestfallen Knight (swamp, center)", + DS3LocationData("UG: Priestess Ring - shop", "Priestess Ring", shop = True), + DS3LocationData("UG: Shriving Stone - swamp, by bonfire", "Shriving Stone"), + DS3LocationData("UG: Titanite Chunk - swamp, left path by fountain", "Titanite Chunk"), + DS3LocationData("UG: Soul of a Crestfallen Knight - swamp, center", "Soul of a Crestfallen Knight"), - DS3LocationData("UG: Titanite Chunk (swamp, right path by fountain)", "Titanite Chunk"), - DS3LocationData("UG: Ashen Estus Ring (swamp, path opposite bonfire)", "Ashen Estus Ring"), - DS3LocationData("UG: Black Knight Glaive (boss arena)", "Black Knight Glaive"), - DS3LocationData("UG: Hidden Blessing (cemetery, behind coffin)", "Hidden Blessing"), - DS3LocationData("UG: Eyes of a Fire Keeper (shrine, Irina's room)", "Eyes of a Fire Keeper", + DS3LocationData("UG: Titanite Chunk - swamp, right path by fountain", "Titanite Chunk"), + DS3LocationData("UG: Ashen Estus Ring - swamp, path opposite bonfire", "Ashen Estus Ring"), + DS3LocationData("UG: Black Knight Glaive - boss arena", "Black Knight Glaive"), + DS3LocationData("UG: Hidden Blessing - cemetery, behind coffin", "Hidden Blessing"), + DS3LocationData("UG: Eyes of a Fire Keeper - shrine, Irina's room", "Eyes of a Fire Keeper", hidden = True), # Illusory wall - DS3LocationData("UG: Soul of a Crestfallen Knight (environs, above shrine entrance)", + DS3LocationData("UG: Soul of a Crestfallen Knight - environs, above shrine entrance", "Soul of a Crestfallen Knight"), - DS3LocationData("UG: Blacksmith Hammer (shrine, Andre's room)", "Blacksmith Hammer"), - DS3LocationData("UG: Chaos Blade (environs, left of shrine)", "Chaos Blade"), - DS3LocationData("UG: Hornet Ring (environs, right of main path after killing FK boss)", + DS3LocationData("UG: Blacksmith Hammer - shrine, Andre's room", "Blacksmith Hammer"), + DS3LocationData("UG: Chaos Blade - environs, left of shrine", "Chaos Blade"), + DS3LocationData("UG: Hornet Ring - environs, right of main path after killing FK boss", "Hornet Ring", conditional = True), - DS3LocationData("UG: Coiled Sword Fragment (shrine, dead bonfire)", "Coiled Sword Fragment", + DS3LocationData("UG: Coiled Sword Fragment - shrine, dead bonfire", "Coiled Sword Fragment", boss = True), - DS3LocationData("UG: Life Ring+3 (shrine, behind big throne)", "Life Ring+3", ngp = True), - DS3LocationData("UG: Ring of Steel Protection+1 (environs, behind bell tower)", + DS3LocationData("UG: Life Ring+3 - shrine, behind big throne", "Life Ring+3", ngp = True), + DS3LocationData("UG: Ring of Steel Protection+1 - environs, behind bell tower", "Ring of Steel Protection+1", ngp = True), # Yuria shop, or Shrine Handmaiden with Hollow's Ashes # This is here because this is where the ashes end up if you kill Yoel or Yuria - DS3LocationData("FS: Ring of Sacrifice (Yuria shop)", "Ring of Sacrifice", + DS3LocationData("FS: Ring of Sacrifice - Yuria shop", "Ring of Sacrifice", offline = '99,0:-1:40000,110000,70000107,70000116:', npc = True, shop = True), # Untended Graves Handmaid # All shop items are missable because she can be killed, except Priestess ring because she # drops it on death anyway. - DS3LocationData("UG: Ember (shop)", "Ember", shop = True, missable = True), + DS3LocationData("UG: Ember - shop", "Ember", shop = True, missable = True), # Untended Graves Handmaid after killing Abyss Watchers - DS3LocationData("UG: Wolf Knight Helm (shop after killing FK boss)", "Wolf Knight Helm", + DS3LocationData("UG: Wolf Knight Helm - shop after killing FK boss", "Wolf Knight Helm", boss = True, shop = True, conditional = True, missable = True), - DS3LocationData("UG: Wolf Knight Armor (shop after killing FK boss)", + DS3LocationData("UG: Wolf Knight Armor - shop after killing FK boss", "Wolf Knight Armor", boss = True, shop = True, missable = True), - DS3LocationData("UG: Wolf Knight Gauntlets (shop after killing FK boss)", + DS3LocationData("UG: Wolf Knight Gauntlets - shop after killing FK boss", "Wolf Knight Gauntlets", boss = True, shop = True, missable = True), - DS3LocationData("UG: Wolf Knight Leggings (shop after killing FK boss)", + DS3LocationData("UG: Wolf Knight Leggings - shop after killing FK boss", "Wolf Knight Leggings", boss = True, shop = True, missable = True), # Shrine Handmaid after killing Champion Gundyr - DS3LocationData("FS: Gundyr's Helm (shop after killing UG boss)", "Gundyr's Helm", + DS3LocationData("FS: Gundyr's Helm - shop after killing UG boss", "Gundyr's Helm", boss = True, shop = True), - DS3LocationData("FS: Gundyr's Armor (shop after killing UG boss)", "Gundyr's Armor", + DS3LocationData("FS: Gundyr's Armor - shop after killing UG boss", "Gundyr's Armor", boss = True, shop = True), - DS3LocationData("FS: Gundyr's Gauntlets (shop after killing UG boss)", "Gundyr's Gauntlets", + DS3LocationData("FS: Gundyr's Gauntlets - shop after killing UG boss", "Gundyr's Gauntlets", boss = True, shop = True), - DS3LocationData("FS: Gundyr's Leggings (shop after killing UG boss)", "Gundyr's Leggings", + DS3LocationData("FS: Gundyr's Leggings - shop after killing UG boss", "Gundyr's Leggings", boss = True, shop = True), ], "Archdragon Peak": [ - DS3LocationData("AP: Dragon Head Stone (fort, boss drop)", "Dragon Head Stone", + DS3LocationData("AP: Dragon Head Stone - fort, boss drop", "Dragon Head Stone", prominent = True, boss = True), DS3LocationData("AP: Soul of the Nameless King", "Soul of the Nameless King", prominent = True, boss = True), - DS3LocationData("AP: Dragon Tooth (belfry roof, NPC drop)", "Dragon Tooth", + DS3LocationData("AP: Dragon Tooth - belfry roof, NPC drop", "Dragon Tooth", hostile_npc = True), # Havel Knight drop - DS3LocationData("AP: Havel's Greatshield (belfry roof, NPC drop)", "Havel's Greatshield", + DS3LocationData("AP: Havel's Greatshield - belfry roof, NPC drop", "Havel's Greatshield", hostile_npc = True), # Havel Knight drop - DS3LocationData("AP: Drakeblood Greatsword (mausoleum, NPC drop)", "Drakeblood Greatsword", + DS3LocationData("AP: Drakeblood Greatsword - mausoleum, NPC drop", "Drakeblood Greatsword", hostile_npc = True), - DS3LocationData("AP: Ricard's Rapier (belfry, NPC drop)", "Ricard's Rapier", + DS3LocationData("AP: Ricard's Rapier - belfry, NPC drop", "Ricard's Rapier", hostile_npc = True), - DS3LocationData("AP: Lightning Clutch Ring (intro, left of boss door)", + DS3LocationData("AP: Lightning Clutch Ring - intro, left of boss door", "Lightning Clutch Ring"), - DS3LocationData("AP: Stalk Dung Pie (fort overlook)", "Stalk Dung Pie x6"), - DS3LocationData("AP: Titanite Chunk (fort, second room balcony)", "Titanite Chunk"), - DS3LocationData("AP: Titanite Scale (mausoleum, downstairs balcony #1)", + DS3LocationData("AP: Stalk Dung Pie - fort overlook", "Stalk Dung Pie x6"), + DS3LocationData("AP: Titanite Chunk - fort, second room balcony", "Titanite Chunk"), + DS3LocationData("AP: Titanite Scale - mausoleum, downstairs balcony #1", "Titanite Scale"), - DS3LocationData("AP: Soul of a Weary Warrior (intro, first cliff edge)", + DS3LocationData("AP: Soul of a Weary Warrior - intro, first cliff edge", "Soul of a Weary Warrior"), - DS3LocationData("AP: Titanite Chunk (intro, left before archway)", "Titanite Chunk"), - DS3LocationData("AP: Lightning Gem (intro, side rise)", "Lightning Gem"), - DS3LocationData("AP: Homeward Bone (intro, path to bonfire)", "Homeward Bone x2"), - DS3LocationData("AP: Soul of a Nameless Soldier (intro, right before archway)", + DS3LocationData("AP: Titanite Chunk - intro, left before archway", "Titanite Chunk"), + DS3LocationData("AP: Lightning Gem - intro, side rise", "Lightning Gem"), + DS3LocationData("AP: Homeward Bone - intro, path to bonfire", "Homeward Bone x2"), + DS3LocationData("AP: Soul of a Nameless Soldier - intro, right before archway", "Soul of a Nameless Soldier"), - DS3LocationData("AP: Titanite Chunk (intro, archway corner)", "Titanite Chunk"), - DS3LocationData("AP: Ember (fort overlook #2)", "Ember"), - DS3LocationData("AP: Large Soul of a Weary Warrior (fort, center)", + DS3LocationData("AP: Titanite Chunk - intro, archway corner", "Titanite Chunk"), + DS3LocationData("AP: Ember - fort overlook #2", "Ember"), + DS3LocationData("AP: Large Soul of a Weary Warrior - fort, center", "Large Soul of a Weary Warrior"), - DS3LocationData("AP: Large Soul of a Nameless Soldier (fort, by stairs to first room)", + DS3LocationData("AP: Large Soul of a Nameless Soldier - fort, by stairs to first room", "Large Soul of a Nameless Soldier"), - DS3LocationData("AP: Lightning Urn (fort, left of first room entrance)", + DS3LocationData("AP: Lightning Urn - fort, left of first room entrance", "Lightning Urn x4"), - DS3LocationData("AP: Lightning Bolt (rotunda)", "Lightning Bolt x12"), - DS3LocationData("AP: Titanite Chunk (rotunda)", "Titanite Chunk x2"), + DS3LocationData("AP: Lightning Bolt - rotunda", "Lightning Bolt x12"), + DS3LocationData("AP: Titanite Chunk - rotunda", "Titanite Chunk x2"), # Not 100% sure about this location name, can't find this on any maps - DS3LocationData("AP: Dung Pie (fort, landing after second room)", "Dung Pie x3"), - DS3LocationData("AP: Titanite Scale (mausoleum, downstairs balcony #2)", "Titanite Scale"), - DS3LocationData("AP: Soul of a Weary Warrior (walkway, building window)", + DS3LocationData("AP: Dung Pie - fort, landing after second room", "Dung Pie x3"), + DS3LocationData("AP: Titanite Scale - mausoleum, downstairs balcony #2", "Titanite Scale"), + DS3LocationData("AP: Soul of a Weary Warrior - walkway, building window", "Soul of a Weary Warrior"), - DS3LocationData("AP: Soul of a Crestfallen Knight (mausoleum, upstairs)", + DS3LocationData("AP: Soul of a Crestfallen Knight - mausoleum, upstairs", "Soul of a Crestfallen Knight"), - DS3LocationData("AP: Titanite Chunk (intro, behind rock)", "Titanite Chunk"), - DS3LocationData("AP: Ember (fort overlook #2)", "Ember"), - DS3LocationData("AP: Thunder Stoneplate Ring (walkway, up ladder)", + DS3LocationData("AP: Titanite Chunk - intro, behind rock", "Titanite Chunk"), + DS3LocationData("AP: Ember - fort overlook #2", "Ember"), + DS3LocationData("AP: Thunder Stoneplate Ring - walkway, up ladder", "Thunder Stoneplate Ring"), - DS3LocationData("AP: Titanite Scale (mausoleum, upstairs balcony)", "Titanite Scale"), - DS3LocationData("AP: Ember (belfry, below bell)", "Ember"), - DS3LocationData("AP: Ancient Dragon Greatshield (intro, on archway)", + DS3LocationData("AP: Titanite Scale - mausoleum, upstairs balcony", "Titanite Scale"), + DS3LocationData("AP: Ember - belfry, below bell", "Ember"), + DS3LocationData("AP: Ancient Dragon Greatshield - intro, on archway", "Ancient Dragon Greatshield"), - DS3LocationData("AP: Large Soul of a Crestfallen Knight (summit, by fountain)", + DS3LocationData("AP: Large Soul of a Crestfallen Knight - summit, by fountain", "Large Soul of a Crestfallen Knight"), - DS3LocationData("AP: Dragon Chaser's Ashes (summit, side path)", "Dragon Chaser's Ashes", + DS3LocationData("AP: Dragon Chaser's Ashes - summit, side path", "Dragon Chaser's Ashes", progression = True), - DS3LocationData("AP: Ember (intro, by bonfire)", "Ember"), - DS3LocationData("AP: Dragonslayer Spear (gate after mausoleum)", "Dragonslayer Spear"), - DS3LocationData("AP: Dragonslayer Helm (plaza)", "Dragonslayer Helm"), - DS3LocationData("AP: Dragonslayer Armor (plaza)", "Dragonslayer Armor"), - DS3LocationData("AP: Dragonslayer Gauntlets (plaza)", "Dragonslayer Gauntlets"), - DS3LocationData("AP: Dragonslayer Leggings (plaza)", "Dragonslayer Leggings"), - DS3LocationData("AP: Twinkling Titanite (fort, end of rafters)", "Twinkling Titanite x2"), - DS3LocationData("AP: Twinkling Titanite (fort, down second room balcony ladder)", + DS3LocationData("AP: Ember - intro, by bonfire", "Ember"), + DS3LocationData("AP: Dragonslayer Spear - gate after mausoleum", "Dragonslayer Spear"), + DS3LocationData("AP: Dragonslayer Helm - plaza", "Dragonslayer Helm"), + DS3LocationData("AP: Dragonslayer Armor - plaza", "Dragonslayer Armor"), + DS3LocationData("AP: Dragonslayer Gauntlets - plaza", "Dragonslayer Gauntlets"), + DS3LocationData("AP: Dragonslayer Leggings - plaza", "Dragonslayer Leggings"), + DS3LocationData("AP: Twinkling Titanite - fort, end of rafters", "Twinkling Titanite x2"), + DS3LocationData("AP: Twinkling Titanite - fort, down second room balcony ladder", "Twinkling Titanite x2"), - DS3LocationData("AP: Titanite Slab (belfry roof)", "Titanite Slab"), - DS3LocationData("AP: Great Magic Barrier (drop off belfry roof)", "Great Magic Barrier", + DS3LocationData("AP: Titanite Slab - belfry roof", "Titanite Slab"), + DS3LocationData("AP: Great Magic Barrier - drop off belfry roof", "Great Magic Barrier", hidden = True), # Hidden fall - DS3LocationData("AP: Titanite Slab (plaza)", "Titanite Slab"), - DS3LocationData("AP: Ring of Steel Protection (fort overlook, beside stairs)", + DS3LocationData("AP: Titanite Slab - plaza", "Titanite Slab"), + DS3LocationData("AP: Ring of Steel Protection - fort overlook, beside stairs", "Ring of Steel Protection"), - DS3LocationData("AP: Havel's Ring+1 (summit, after building)", "Havel's Ring+1", + DS3LocationData("AP: Havel's Ring+1 - summit, after building", "Havel's Ring+1", ngp = True), - DS3LocationData("AP: Covetous Gold Serpent Ring+2 (plaza)", "Covetous Gold Serpent Ring+2", + DS3LocationData("AP: Covetous Gold Serpent Ring+2 - plaza", "Covetous Gold Serpent Ring+2", ngp = True), - DS3LocationData("AP: Titanite Scale (walkway building)", "Titanite Scale x3"), - DS3LocationData("AP: Twinkling Titanite (belfry, by ladder to roof)", + DS3LocationData("AP: Titanite Scale - walkway building", "Titanite Scale x3"), + DS3LocationData("AP: Twinkling Titanite - belfry, by ladder to roof", "Twinkling Titanite x3"), - DS3LocationData("AP: Twinkling Dragon Torso Stone (summit, gesture at altar)", + DS3LocationData("AP: Twinkling Dragon Torso Stone - summit, gesture at altar", "Twinkling Dragon Torso Stone", hidden = True), # Requires gesture - DS3LocationData("AP: Calamity Ring (mausoleum, gesture at altar)", "Calamity Ring", + DS3LocationData("AP: Calamity Ring - mausoleum, gesture at altar", "Calamity Ring", hidden = True), # Requires gesture - DS3LocationData("AP: Twinkling Titanite (walkway building, lizard)", + DS3LocationData("AP: Twinkling Titanite - walkway building, lizard", "Twinkling Titanite x3", lizard = True), - DS3LocationData("AP: Titanite Chunk (walkway, miniboss drop)", "Titanite Chunk x6", + DS3LocationData("AP: Titanite Chunk - walkway, miniboss drop", "Titanite Chunk x6", miniboss = True), # Wyvern miniboss drop - DS3LocationData("AP: Titanite Scale (walkway, miniboss drop)", "Titanite Scale x3", + DS3LocationData("AP: Titanite Scale - walkway, miniboss drop", "Titanite Scale x3", miniboss = True), # Wyvern miniboss drop - DS3LocationData("AP: Twinkling Titanite (walkway, miniboss drop)", "Twinkling Titanite x3", + DS3LocationData("AP: Twinkling Titanite - walkway, miniboss drop", "Twinkling Titanite x3", miniboss = True), # Wyvern miniboss drop - DS3LocationData("FS: Hawkwood's Swordgrass (Andre after gesture in AP summit)", + DS3LocationData("FS: Hawkwood's Swordgrass - Andre after gesture in AP summit", "Hawkwood's Swordgrass", conditional = True, hidden = True), # Shrine Handmaid after killing Nameless King - DS3LocationData("FS: Golden Crown (shop after killing AP boss)", "Golden Crown", + DS3LocationData("FS: Golden Crown - shop after killing AP boss", "Golden Crown", boss = True, shop = True), - DS3LocationData("FS: Dragonscale Armor (shop after killing AP boss)", "Dragonscale Armor", + DS3LocationData("FS: Dragonscale Armor - shop after killing AP boss", "Dragonscale Armor", boss = True, shop = True), - DS3LocationData("FS: Golden Bracelets (shop after killing AP boss)", "Golden Bracelets", + DS3LocationData("FS: Golden Bracelets - shop after killing AP boss", "Golden Bracelets", boss = True, shop = True), - DS3LocationData("FS: Dragonscale Waistcloth (shop after killing AP boss)", + DS3LocationData("FS: Dragonscale Waistcloth - shop after killing AP boss", "Dragonscale Waistcloth", boss = True, shop = True), - DS3LocationData("FK: Twinkling Dragon Head Stone (Hawkwood drop)", + DS3LocationData("FK: Twinkling Dragon Head Stone - Hawkwood drop", "Twinkling Dragon Head Stone", missable = True, npc = True), # Hawkwood (quest) ], @@ -2468,553 +2468,553 @@ def __init__( DS3LocationData("KFF: Soul of the Lords", "Soul of the Lords", boss = True), # Shrine Handmaid after placing all Cinders of a Lord - DS3LocationData("FS: Titanite Slab (shop after placing all Cinders)", "Titanite Slab", + DS3LocationData("FS: Titanite Slab - shop after placing all Cinders", "Titanite Slab", offline = '99,0:-1:9210,110000:', hidden = True), - DS3LocationData("FS: Firelink Helm (shop after placing all Cinders)", "Firelink Helm", + DS3LocationData("FS: Firelink Helm - shop after placing all Cinders", "Firelink Helm", boss = True, shop = True), - DS3LocationData("FS: Firelink Armor (shop after placing all Cinders)", "Firelink Armor", + DS3LocationData("FS: Firelink Armor - shop after placing all Cinders", "Firelink Armor", boss = True, shop = True), - DS3LocationData("FS: Firelink Gauntlets (shop after placing all Cinders)", + DS3LocationData("FS: Firelink Gauntlets - shop after placing all Cinders", "Firelink Gauntlets", boss = True, shop = True), - DS3LocationData("FS: Firelink Leggings (shop after placing all Cinders)", + DS3LocationData("FS: Firelink Leggings - shop after placing all Cinders", "Firelink Leggings", boss = True, shop = True), # Yuria (quest, after Soul of Cinder) - DS3LocationData("FS: Billed Mask (Yuria after killing KFF boss)", "Billed Mask", + DS3LocationData("FS: Billed Mask - Yuria after killing KFF boss", "Billed Mask", missable = True, npc = True), - DS3LocationData("FS: Black Dress (Yuria after killing KFF boss)", "Black Dress", + DS3LocationData("FS: Black Dress - Yuria after killing KFF boss", "Black Dress", missable = True, npc = True), - DS3LocationData("FS: Black Gauntlets (Yuria after killing KFF boss)", "Black Gauntlets", + DS3LocationData("FS: Black Gauntlets - Yuria after killing KFF boss", "Black Gauntlets", missable = True, npc = True), - DS3LocationData("FS: Black Leggings (Yuria after killing KFF boss)", "Black Leggings", + DS3LocationData("FS: Black Leggings - Yuria after killing KFF boss", "Black Leggings", missable = True, npc = True), ], # DLC "Painted World of Ariandel (Before Contraption)": [ - DS3LocationData("PW1: Valorheart (boss drop)", "Valorheart", prominent = True, boss = True), - DS3LocationData("PW1: Contraption Key (library, NPC drop)", "Contraption Key", + DS3LocationData("PW1: Valorheart - boss drop", "Valorheart", prominent = True, boss = True), + DS3LocationData("PW1: Contraption Key - library, NPC drop", "Contraption Key", prominent = True, progression = True, hostile_npc = True), # Sir Vilhelm drop - DS3LocationData("PW1: Onyx Blade (library, NPC drop)", "Onyx Blade", + DS3LocationData("PW1: Onyx Blade - library, NPC drop", "Onyx Blade", hostile_npc = True), # Sir Vilhelm drop - DS3LocationData("PW1: Chillbite Ring (Friede)", "Chillbite Ring", + DS3LocationData("PW1: Chillbite Ring - Friede", "Chillbite Ring", npc = True), # Friede conversation - DS3LocationData("PW1: Rime-blue Moss Clump (snowfield upper, starting cave)", + DS3LocationData("PW1: Rime-blue Moss Clump - snowfield upper, starting cave", "Rime-blue Moss Clump x2"), - DS3LocationData("PW1: Poison Gem (snowfield upper, forward from bonfire)", "Poison Gem"), - DS3LocationData("PW1: Large Soul of an Unknown Traveler (snowfield lower, path back up)", + DS3LocationData("PW1: Poison Gem - snowfield upper, forward from bonfire", "Poison Gem"), + DS3LocationData("PW1: Large Soul of an Unknown Traveler - snowfield lower, path back up", "Large Soul of an Unknown Traveler"), - DS3LocationData("PW1: Follower Javelin (snowfield lower, path back up)", "Follower Javelin"), - DS3LocationData("PW1: Large Soul of an Unknown Traveler (snowfield lower, path to village)", + DS3LocationData("PW1: Follower Javelin - snowfield lower, path back up", "Follower Javelin"), + DS3LocationData("PW1: Large Soul of an Unknown Traveler - snowfield lower, path to village", "Large Soul of an Unknown Traveler"), - DS3LocationData("PW1: Homeward Bone (snowfield village, outcropping)", "Homeward Bone x6"), - DS3LocationData("PW1: Blessed Gem (snowfield, behind tower)", "Blessed Gem", + DS3LocationData("PW1: Homeward Bone - snowfield village, outcropping", "Homeward Bone x6"), + DS3LocationData("PW1: Blessed Gem - snowfield, behind tower", "Blessed Gem", hidden = True), # Hidden behind a tower - DS3LocationData("PW1: Captain's Ashes (snowfield tower, 6F)", "Captain's Ashes", + DS3LocationData("PW1: Captain's Ashes - snowfield tower, 6F", "Captain's Ashes", progression = True), - DS3LocationData("PW1: Black Firebomb (snowfield lower, path to bonfire)", + DS3LocationData("PW1: Black Firebomb - snowfield lower, path to bonfire", "Black Firebomb x2"), - DS3LocationData("PW1: Shriving Stone (below bridge near)", "Shriving Stone"), - DS3LocationData("PW1: Millwood Greatarrow (snowfield village, loop back to lower)", + DS3LocationData("PW1: Shriving Stone - below bridge near", "Shriving Stone"), + DS3LocationData("PW1: Millwood Greatarrow - snowfield village, loop back to lower", "Millwood Greatarrow x5"), - DS3LocationData("PW1: Millwood Greatbow (snowfield village, loop back to lower)", + DS3LocationData("PW1: Millwood Greatbow - snowfield village, loop back to lower", "Millwood Greatbow"), - DS3LocationData("PW1: Large Soul of an Unknown Traveler (snowfield upper)", + DS3LocationData("PW1: Large Soul of an Unknown Traveler - snowfield upper", "Large Soul of an Unknown Traveler"), - DS3LocationData("PW1: Rusted Coin (snowfield lower, straight from fall)", "Rusted Coin"), - DS3LocationData("PW1: Large Titanite Shard (snowfield lower, left from fall)", + DS3LocationData("PW1: Rusted Coin - snowfield lower, straight from fall", "Rusted Coin"), + DS3LocationData("PW1: Large Titanite Shard - snowfield lower, left from fall", "Large Titanite Shard"), - DS3LocationData("PW1: Large Soul of an Unknown Traveler (settlement courtyard, cliff)", + DS3LocationData("PW1: Large Soul of an Unknown Traveler - settlement courtyard, cliff", "Large Soul of an Unknown Traveler"), - DS3LocationData("PW1: Crow Quills (settlement loop, jump into courtyard)", "Crow Quills", + DS3LocationData("PW1: Crow Quills - settlement loop, jump into courtyard", "Crow Quills", hidden = True), # Hidden fall - DS3LocationData("PW1: Simple Gem (settlement, lowest level, behind gate)", "Simple Gem"), - DS3LocationData("PW1: Large Soul of an Unknown Traveler (settlement, by ladder to bonfire)", + DS3LocationData("PW1: Simple Gem - settlement, lowest level, behind gate", "Simple Gem"), + DS3LocationData("PW1: Large Soul of an Unknown Traveler - settlement, by ladder to bonfire", "Large Soul of an Unknown Traveler"), - DS3LocationData("PW1: Slave Knight Hood (settlement roofs, drop by ladder)", + DS3LocationData("PW1: Slave Knight Hood - settlement roofs, drop by ladder", "Slave Knight Hood"), - DS3LocationData("PW1: Slave Knight Armor (settlement roofs, drop by ladder)", + DS3LocationData("PW1: Slave Knight Armor - settlement roofs, drop by ladder", "Slave Knight Armor"), - DS3LocationData("PW1: Slave Knight Gauntlets (settlement roofs, drop by ladder)", + DS3LocationData("PW1: Slave Knight Gauntlets - settlement roofs, drop by ladder", "Slave Knight Gauntlets"), - DS3LocationData("PW1: Slave Knight Leggings (settlement roofs, drop by ladder)", + DS3LocationData("PW1: Slave Knight Leggings - settlement roofs, drop by ladder", "Slave Knight Leggings"), - DS3LocationData("PW1: Ember (settlement main, left building after bridge)", "Ember"), - DS3LocationData("PW1: Dark Gem (settlement back, egg building)", "Dark Gem"), - DS3LocationData("PW1: Large Soul of an Unknown Traveler (settlement roofs, balcony)", + DS3LocationData("PW1: Ember - settlement main, left building after bridge", "Ember"), + DS3LocationData("PW1: Dark Gem - settlement back, egg building", "Dark Gem"), + DS3LocationData("PW1: Large Soul of an Unknown Traveler - settlement roofs, balcony", "Large Soul of an Unknown Traveler"), - DS3LocationData("PW1: Large Soul of an Unknown Traveler (settlement loop, by bonfire)", + DS3LocationData("PW1: Large Soul of an Unknown Traveler - settlement loop, by bonfire", "Large Soul of an Unknown Traveler"), - DS3LocationData("PW1: Rusted Gold Coin (settlement roofs, roof near second ladder)", + DS3LocationData("PW1: Rusted Gold Coin - settlement roofs, roof near second ladder", "Rusted Gold Coin x3"), - DS3LocationData("PW1: Soul of a Crestfallen Knight (settlement hall, rafters)", + DS3LocationData("PW1: Soul of a Crestfallen Knight - settlement hall, rafters", "Soul of a Crestfallen Knight"), - DS3LocationData("PW1: Way of White Corona (settlement hall, by altar)", + DS3LocationData("PW1: Way of White Corona - settlement hall, by altar", "Way of White Corona"), - DS3LocationData("PW1: Rusted Coin (right of library)", "Rusted Coin x2"), - DS3LocationData("PW1: Young White Branch (right of library)", "Young White Branch"), - DS3LocationData("PW1: Budding Green Blossom (settlement courtyard, ledge)", + DS3LocationData("PW1: Rusted Coin - right of library", "Rusted Coin x2"), + DS3LocationData("PW1: Young White Branch - right of library", "Young White Branch"), + DS3LocationData("PW1: Budding Green Blossom - settlement courtyard, ledge", "Budding Green Blossom x3"), - DS3LocationData("PW1: Crow Talons (settlement roofs, near bonfire)", "Crow Talons"), - DS3LocationData("PW1: Hollow Gem (beside chapel)", "Hollow Gem"), - DS3LocationData("PW1: Rime-blue Moss Clump (below bridge far)", "Rime-blue Moss Clump x4"), - DS3LocationData("PW1: Follower Sabre (roots above depths)", "Follower Sabre"), - DS3LocationData("PW1: Ember (roots above depths)", "Ember"), - DS3LocationData("PW1: Snap Freeze (depths, far end, mob drop)", "Snap Freeze", drop = True, + DS3LocationData("PW1: Crow Talons - settlement roofs, near bonfire", "Crow Talons"), + DS3LocationData("PW1: Hollow Gem - beside chapel", "Hollow Gem"), + DS3LocationData("PW1: Rime-blue Moss Clump - below bridge far", "Rime-blue Moss Clump x4"), + DS3LocationData("PW1: Follower Sabre - roots above depths", "Follower Sabre"), + DS3LocationData("PW1: Ember - roots above depths", "Ember"), + DS3LocationData("PW1: Snap Freeze - depths, far end, mob drop", "Snap Freeze", drop = True, hidden = True), # Guaranteed drop from normal-looking Tree Woman - DS3LocationData("PW1: Rime-blue Moss Clump (snowfield upper, overhang)", + DS3LocationData("PW1: Rime-blue Moss Clump - snowfield upper, overhang", "Rime-blue Moss Clump"), - DS3LocationData("PW1: Large Soul of an Unknown Traveler (snowfield lower, by cliff)", + DS3LocationData("PW1: Large Soul of an Unknown Traveler - snowfield lower, by cliff", "Large Soul of an Unknown Traveler"), - DS3LocationData("PW1: Ember (settlement, building near bonfire)", "Ember"), - DS3LocationData("PW1: Frozen Weapon (snowfield lower, egg zone)", "Frozen Weapon"), - DS3LocationData("PW1: Titanite Slab (depths, up secret ladder)", "Titanite Slab", + DS3LocationData("PW1: Ember - settlement, building near bonfire", "Ember"), + DS3LocationData("PW1: Frozen Weapon - snowfield lower, egg zone", "Frozen Weapon"), + DS3LocationData("PW1: Titanite Slab - depths, up secret ladder", "Titanite Slab", offline = '11,0:54500640::', hidden = True), # Must kill normal-looking Tree Woman - DS3LocationData("PW1: Homeward Bone (depths, up hill)", "Homeward Bone x2"), - DS3LocationData("PW1: Large Soul of an Unknown Traveler (below snowfield village overhang)", + DS3LocationData("PW1: Homeward Bone - depths, up hill", "Homeward Bone x2"), + DS3LocationData("PW1: Large Soul of an Unknown Traveler - below snowfield village overhang", "Large Soul of an Unknown Traveler"), - DS3LocationData("PW1: Large Soul of a Weary Warrior (settlement hall roof)", + DS3LocationData("PW1: Large Soul of a Weary Warrior - settlement hall roof", "Large Soul of a Weary Warrior"), - DS3LocationData("PW1: Large Soul of an Unknown Traveler (settlement back)", + DS3LocationData("PW1: Large Soul of an Unknown Traveler - settlement back", "Large Soul of an Unknown Traveler"), - DS3LocationData("PW1: Heavy Gem (snowfield village)", "Heavy Gem"), - DS3LocationData("PW1: Large Soul of a Weary Warrior (snowfield tower, 6F)", + DS3LocationData("PW1: Heavy Gem - snowfield village", "Heavy Gem"), + DS3LocationData("PW1: Large Soul of a Weary Warrior - snowfield tower, 6F", "Large Soul of a Weary Warrior"), - DS3LocationData("PW1: Millwood Battle Axe (snowfield tower, 5F)", "Millwood Battle Axe"), - DS3LocationData("PW1: Ethereal Oak Shield (snowfield tower, 3F)", "Ethereal Oak Shield"), - DS3LocationData("PW1: Soul of a Weary Warrior (snowfield tower, 1F)", + DS3LocationData("PW1: Millwood Battle Axe - snowfield tower, 5F", "Millwood Battle Axe"), + DS3LocationData("PW1: Ethereal Oak Shield - snowfield tower, 3F", "Ethereal Oak Shield"), + DS3LocationData("PW1: Soul of a Weary Warrior - snowfield tower, 1F", "Soul of a Weary Warrior"), - DS3LocationData("PW1: Twinkling Titanite (snowfield tower, 3F lizard)", + DS3LocationData("PW1: Twinkling Titanite - snowfield tower, 3F lizard", "Twinkling Titanite", lizard = True), - DS3LocationData("PW1: Large Titanite Shard (lizard under bridge near)", + DS3LocationData("PW1: Large Titanite Shard - lizard under bridge near", "Large Titanite Shard", lizard = True), - DS3LocationData("PW1: Twinkling Titanite (roots, lizard)", "Twinkling Titanite", + DS3LocationData("PW1: Twinkling Titanite - roots, lizard", "Twinkling Titanite", lizard = True), - DS3LocationData("PW1: Twinkling Titanite (settlement roofs, lizard before hall)", + DS3LocationData("PW1: Twinkling Titanite - settlement roofs, lizard before hall", "Twinkling Titanite", lizard = True), - DS3LocationData("PW1: Large Titanite Shard (settlement loop, lizard)", + DS3LocationData("PW1: Large Titanite Shard - settlement loop, lizard", "Large Titanite Shard x2", lizard = True), ], "Painted World of Ariandel (After Contraption)": [ DS3LocationData("PW2: Soul of Sister Friede", "Soul of Sister Friede", prominent = True, boss = True), - DS3LocationData("PW2: Titanite Slab (boss drop)", "Titanite Slab", + DS3LocationData("PW2: Titanite Slab - boss drop", "Titanite Slab", offline = '11,0:50004700::', boss = True), # One-time drop after Friede Phase 2 - DS3LocationData("PW2: Floating Chaos (Dunnel drop)", "Floating Chaos", hostile_npc = True, + DS3LocationData("PW2: Floating Chaos - Dunnel drop", "Floating Chaos", hostile_npc = True, hidden = True), # Livid Pyromancer Dunnel drop (requires ember) - DS3LocationData("PW2: Prism Stone (pass, tree by beginning)", "Prism Stone x10"), - DS3LocationData("PW2: Titanite Chunk (pass, cliff overlooking bonfire)", "Titanite Chunk"), - DS3LocationData("PW2: Titanite Chunk (pass, by kickable tree)", "Titanite Chunk"), - DS3LocationData("PW2: Follower Shield (pass, far cliffside)", "Follower Shield"), - DS3LocationData("PW2: Large Titanite Shard (pass, just before B1)", + DS3LocationData("PW2: Prism Stone - pass, tree by beginning", "Prism Stone x10"), + DS3LocationData("PW2: Titanite Chunk - pass, cliff overlooking bonfire", "Titanite Chunk"), + DS3LocationData("PW2: Titanite Chunk - pass, by kickable tree", "Titanite Chunk"), + DS3LocationData("PW2: Follower Shield - pass, far cliffside", "Follower Shield"), + DS3LocationData("PW2: Large Titanite Shard - pass, just before B1", "Large Titanite Shard x2"), - DS3LocationData("PW2: Quakestone Hammer (pass, side path near B1)", "Quakestone Hammer"), - DS3LocationData("PW2: Ember (pass, central alcove)", "Ember"), - DS3LocationData("PW2: Large Titanite Shard (pass, far side path)", + DS3LocationData("PW2: Quakestone Hammer - pass, side path near B1", "Quakestone Hammer"), + DS3LocationData("PW2: Ember - pass, central alcove", "Ember"), + DS3LocationData("PW2: Large Titanite Shard - pass, far side path", "Large Titanite Shard x2"), - DS3LocationData("PW2: Soul of a Crestfallen Knight (pit edge #1)", + DS3LocationData("PW2: Soul of a Crestfallen Knight - pit edge #1", "Soul of a Crestfallen Knight"), - DS3LocationData("PW2: Soul of a Crestfallen Knight (pit edge #2)", + DS3LocationData("PW2: Soul of a Crestfallen Knight - pit edge #2", "Soul of a Crestfallen Knight"), - DS3LocationData("PW2: Large Soul of a Crestfallen Knight (pit, by tree)", + DS3LocationData("PW2: Large Soul of a Crestfallen Knight - pit, by tree", "Large Soul of a Crestfallen Knight"), - DS3LocationData("PW2: Earth Seeker (pit cave)", "Earth Seeker"), - DS3LocationData("PW2: Follower Torch (pass, far side path)", "Follower Torch"), - DS3LocationData("PW2: Dung Pie (B1)", "Dung Pie x2"), + DS3LocationData("PW2: Earth Seeker - pit cave", "Earth Seeker"), + DS3LocationData("PW2: Follower Torch - pass, far side path", "Follower Torch"), + DS3LocationData("PW2: Dung Pie - B1", "Dung Pie x2"), DS3LocationData("PW2: Vilhelm's Helm", "Vilhelm's Helm"), - DS3LocationData("PW2: Vilhelm's Armor (B2, along wall)", "Vilhelm's Armor"), - DS3LocationData("PW2: Vilhelm's Gauntlets (B2, along wall)", "Vilhelm's Gauntlets"), - DS3LocationData("PW2: Vilhelm's Leggings (B2, along wall)", "Vilhelm's Leggings"), - DS3LocationData("PW2: Blood Gem (B2, center)", "Blood Gem"), - DS3LocationData("PW2: Pyromancer's Parting Flame (rotunda)", + DS3LocationData("PW2: Vilhelm's Armor - B2, along wall", "Vilhelm's Armor"), + DS3LocationData("PW2: Vilhelm's Gauntlets - B2, along wall", "Vilhelm's Gauntlets"), + DS3LocationData("PW2: Vilhelm's Leggings - B2, along wall", "Vilhelm's Leggings"), + DS3LocationData("PW2: Blood Gem - B2, center", "Blood Gem"), + DS3LocationData("PW2: Pyromancer's Parting Flame - rotunda", "Pyromancer's Parting Flame", hidden = True), # Behind illusory wall - DS3LocationData("PW2: Homeward Bone (rotunda)", "Homeward Bone x2", + DS3LocationData("PW2: Homeward Bone - rotunda", "Homeward Bone x2", hidden = True), # Behind illusory wall - DS3LocationData("PW2: Twinkling Titanite (B3, lizard #1)", "Twinkling Titanite", + DS3LocationData("PW2: Twinkling Titanite - B3, lizard #1", "Twinkling Titanite", lizard = True), - DS3LocationData("PW2: Twinkling Titanite (B3, lizard #2)", "Twinkling Titanite", + DS3LocationData("PW2: Twinkling Titanite - B3, lizard #2", "Twinkling Titanite", lizard = True), DS3LocationData("PW2 -> DH", None), # Corvian Settler after killing Friede - DS3LocationData("PW1: Titanite Slab (Corvian)", "Titanite Slab", missable = True, + DS3LocationData("PW1: Titanite Slab - Corvian", "Titanite Slab", missable = True, npc = True), # Shrine Handmaid after killing Sister Friede - DS3LocationData("FS: Ordained Hood (shop after killing PW2 boss)", "Ordained Hood", + DS3LocationData("FS: Ordained Hood - shop after killing PW2 boss", "Ordained Hood", boss = True, shop = True), - DS3LocationData("FS: Ordained Dress (shop after killing PW2 boss)", "Ordained Dress", + DS3LocationData("FS: Ordained Dress - shop after killing PW2 boss", "Ordained Dress", boss = True, shop = True), - DS3LocationData("FS: Ordained Trousers (shop after killing PW2 boss)", "Ordained Trousers", + DS3LocationData("FS: Ordained Trousers - shop after killing PW2 boss", "Ordained Trousers", boss = True, shop = True), ], "Dreg Heap": [ DS3LocationData("DH: Soul of the Demon Prince", "Soul of the Demon Prince", prominent = True, boss = True), - DS3LocationData("DH: Siegbräu (Lapp)", "Siegbräu", missable = True, drop = True, + DS3LocationData("DH: Siegbräu - Lapp", "Siegbräu", missable = True, drop = True, npc = True), # Lapp (quest or kill) - DS3LocationData("DH: Flame Fan (swamp upper, NPC drop)", "Flame Fan", + DS3LocationData("DH: Flame Fan - swamp upper, NPC drop", "Flame Fan", hostile_npc = True), # Desert Pyromancer Zoey drop - DS3LocationData("DH: Ember (castle, behind spire)", "Ember"), - DS3LocationData("DH: Soul of a Weary Warrior (castle overhang)", "Soul of a Weary Warrior"), - DS3LocationData("DH: Titanite Chunk (castle, up stairs)", "Titanite Chunk"), - DS3LocationData("DH: Aquamarine Dagger (castle, up stairs)", "Aquamarine Dagger"), - DS3LocationData("DH: Twinkling Titanite (library, chandelier)", "Twinkling Titanite"), - DS3LocationData("DH: Murky Hand Scythe (library, behind bookshelves)", "Murky Hand Scythe"), - DS3LocationData("DH: Divine Blessing (library, after drop)", "Divine Blessing"), - DS3LocationData("DH: Ring of Steel Protection+3 (ledge before church)", + DS3LocationData("DH: Ember - castle, behind spire", "Ember"), + DS3LocationData("DH: Soul of a Weary Warrior - castle overhang", "Soul of a Weary Warrior"), + DS3LocationData("DH: Titanite Chunk - castle, up stairs", "Titanite Chunk"), + DS3LocationData("DH: Aquamarine Dagger - castle, up stairs", "Aquamarine Dagger"), + DS3LocationData("DH: Twinkling Titanite - library, chandelier", "Twinkling Titanite"), + DS3LocationData("DH: Murky Hand Scythe - library, behind bookshelves", "Murky Hand Scythe"), + DS3LocationData("DH: Divine Blessing - library, after drop", "Divine Blessing"), + DS3LocationData("DH: Ring of Steel Protection+3 - ledge before church", "Ring of Steel Protection+3"), - DS3LocationData("DH: Soul of a Crestfallen Knight (church, altar)", + DS3LocationData("DH: Soul of a Crestfallen Knight - church, altar", "Soul of a Crestfallen Knight"), - DS3LocationData("DH: Rusted Coin (behind fountain after church)", "Rusted Coin x2"), - DS3LocationData("DH: Titanite Chunk (pantry, first room)", "Titanite Chunk"), - DS3LocationData("DH: Murky Longstaff (pantry, last room)", "Murky Longstaff"), - DS3LocationData("DH: Ember (pantry, behind crates just before upstairs)", "Ember", + DS3LocationData("DH: Rusted Coin - behind fountain after church", "Rusted Coin x2"), + DS3LocationData("DH: Titanite Chunk - pantry, first room", "Titanite Chunk"), + DS3LocationData("DH: Murky Longstaff - pantry, last room", "Murky Longstaff"), + DS3LocationData("DH: Ember - pantry, behind crates just before upstairs", "Ember", hidden = True), # Behind illusory wall - DS3LocationData("DH: Great Soul Dregs (pantry upstairs)", "Great Soul Dregs", + DS3LocationData("DH: Great Soul Dregs - pantry upstairs", "Great Soul Dregs", hidden = True), # Behind illusory wall - DS3LocationData("DH: Covetous Silver Serpent Ring+3 (pantry upstairs, drop down)", + DS3LocationData("DH: Covetous Silver Serpent Ring+3 - pantry upstairs, drop down", "Covetous Silver Serpent Ring+3", hidden = True), # Behind illusory wall - DS3LocationData("DH: Titanite Chunk (path from church, by pillar)", "Titanite Chunk"), - DS3LocationData("DH: Homeward Bone (end of path from church)", "Homeward Bone x3"), - DS3LocationData("DH: Lightning Urn (wall outside church)", "Lightning Urn x4"), - DS3LocationData("DH: Projected Heal (parapets balcony)", "Projected Heal"), - DS3LocationData("DH: Large Soul of a Weary Warrior (parapets, hall)", + DS3LocationData("DH: Titanite Chunk - path from church, by pillar", "Titanite Chunk"), + DS3LocationData("DH: Homeward Bone - end of path from church", "Homeward Bone x3"), + DS3LocationData("DH: Lightning Urn - wall outside church", "Lightning Urn x4"), + DS3LocationData("DH: Projected Heal - parapets balcony", "Projected Heal"), + DS3LocationData("DH: Large Soul of a Weary Warrior - parapets, hall", "Large Soul of a Weary Warrior"), - DS3LocationData("DH: Lothric War Banner (parapets, end of hall)", "Lothric War Banner"), - DS3LocationData("DH: Titanite Scale (library, back of room)", "Titanite Scale"), - DS3LocationData("DH: Black Firebomb (ruins, up windmill from bonfire)", "Black Firebomb x4"), - DS3LocationData("DH: Titanite Chunk (ruins, path from bonfire)", "Titanite Chunk"), - DS3LocationData("DH: Twinkling Titanite (ruins, root near bonfire)", "Twinkling Titanite"), - DS3LocationData("DH: Desert Pyromancer Garb (ruins, by shack near cliff)", + DS3LocationData("DH: Lothric War Banner - parapets, end of hall", "Lothric War Banner"), + DS3LocationData("DH: Titanite Scale - library, back of room", "Titanite Scale"), + DS3LocationData("DH: Black Firebomb - ruins, up windmill from bonfire", "Black Firebomb x4"), + DS3LocationData("DH: Titanite Chunk - ruins, path from bonfire", "Titanite Chunk"), + DS3LocationData("DH: Twinkling Titanite - ruins, root near bonfire", "Twinkling Titanite"), + DS3LocationData("DH: Desert Pyromancer Garb - ruins, by shack near cliff", "Desert Pyromancer Garb"), - DS3LocationData("DH: Titanite Chunk (ruins, by far shack)", "Titanite Chunk x2"), - DS3LocationData("DH: Giant Door Shield (ruins, path below far shack)", "Giant Door Shield"), - DS3LocationData("DH: Ember (ruins, alcove before swamp)", "Ember"), - DS3LocationData("DH: Desert Pyromancer Gloves (swamp, far right)", + DS3LocationData("DH: Titanite Chunk - ruins, by far shack", "Titanite Chunk x2"), + DS3LocationData("DH: Giant Door Shield - ruins, path below far shack", "Giant Door Shield"), + DS3LocationData("DH: Ember - ruins, alcove before swamp", "Ember"), + DS3LocationData("DH: Desert Pyromancer Gloves - swamp, far right", "Desert Pyromancer Gloves"), - DS3LocationData("DH: Desert Pyromancer Skirt (swamp right, by roots)", + DS3LocationData("DH: Desert Pyromancer Skirt - swamp right, by roots", "Desert Pyromancer Skirt"), - DS3LocationData("DH: Titanite Scale (swamp upper, drop and jump into tower)", + DS3LocationData("DH: Titanite Scale - swamp upper, drop and jump into tower", "Titanite Scale"), - DS3LocationData("DH: Purple Moss Clump (swamp shack)", "Purple Moss Clump x4"), - DS3LocationData("DH: Ring of Favor+3 (swamp right, up root)", "Ring of Favor+3"), - DS3LocationData("DH: Titanite Chunk (swamp right, drop partway up root)", "Titanite Chunk"), - DS3LocationData("DH: Large Soul of a Weary Warrior (swamp, under overhang)", + DS3LocationData("DH: Purple Moss Clump - swamp shack", "Purple Moss Clump x4"), + DS3LocationData("DH: Ring of Favor+3 - swamp right, up root", "Ring of Favor+3"), + DS3LocationData("DH: Titanite Chunk - swamp right, drop partway up root", "Titanite Chunk"), + DS3LocationData("DH: Large Soul of a Weary Warrior - swamp, under overhang", "Large Soul of a Weary Warrior"), - DS3LocationData("DH: Titanite Slab (swamp, path under overhang)", "Titanite Slab"), - DS3LocationData("DH: Titanite Chunk (swamp, along buildings)", "Titanite Chunk"), - DS3LocationData("DH: Loincloth (swamp, left edge)", "Loincloth"), - DS3LocationData("DH: Titanite Chunk (swamp, path to upper)", "Titanite Chunk"), - DS3LocationData("DH: Large Soul of a Weary Warrior (swamp center)", + DS3LocationData("DH: Titanite Slab - swamp, path under overhang", "Titanite Slab"), + DS3LocationData("DH: Titanite Chunk - swamp, along buildings", "Titanite Chunk"), + DS3LocationData("DH: Loincloth - swamp, left edge", "Loincloth"), + DS3LocationData("DH: Titanite Chunk - swamp, path to upper", "Titanite Chunk"), + DS3LocationData("DH: Large Soul of a Weary Warrior - swamp center", "Large Soul of a Weary Warrior"), - DS3LocationData("DH: Harald Curved Greatsword (swamp left, under root)", + DS3LocationData("DH: Harald Curved Greatsword - swamp left, under root", "Harald Curved Greatsword"), - DS3LocationData("DH: Homeward Bone (swamp left, on root)", "Homeward Bone"), - DS3LocationData("DH: Prism Stone (swamp upper, tunnel start)", "Prism Stone x6"), - DS3LocationData("DH: Desert Pyromancer Hood (swamp upper, tunnel end)", + DS3LocationData("DH: Homeward Bone - swamp left, on root", "Homeward Bone"), + DS3LocationData("DH: Prism Stone - swamp upper, tunnel start", "Prism Stone x6"), + DS3LocationData("DH: Desert Pyromancer Hood - swamp upper, tunnel end", "Desert Pyromancer Hood"), - DS3LocationData("DH: Twinkling Titanite (swamp upper, drop onto root)", + DS3LocationData("DH: Twinkling Titanite - swamp upper, drop onto root", "Twinkling Titanite", hidden = True), # Hidden fall - DS3LocationData("DH: Divine Blessing (swamp upper, building roof)", "Divine Blessing"), - DS3LocationData("DH: Ember (ruins, alcove on cliff)", "Ember", hidden = True), # Hidden fall - DS3LocationData("DH: Small Envoy Banner (boss drop)", "Small Envoy Banner", + DS3LocationData("DH: Divine Blessing - swamp upper, building roof", "Divine Blessing"), + DS3LocationData("DH: Ember - ruins, alcove on cliff", "Ember", hidden = True), # Hidden fall + DS3LocationData("DH: Small Envoy Banner - boss drop", "Small Envoy Banner", progression = True, boss = True), - DS3LocationData("DH: Twinkling Titanite (ruins, alcove on cliff, mob drop)", + DS3LocationData("DH: Twinkling Titanite - ruins, alcove on cliff, mob drop", "Twinkling Titanite x2", drop = True, hidden = True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim - DS3LocationData("DH: Twinkling Titanite (swamp upper, mob drop on roof)", + DS3LocationData("DH: Twinkling Titanite - swamp upper, mob drop on roof", "Twinkling Titanite x2", drop = True, hidden = True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim - DS3LocationData("DH: Twinkling Titanite (path after church, mob drop)", + DS3LocationData("DH: Twinkling Titanite - path after church, mob drop", "Twinkling Titanite x2", drop = True, hidden = True), # Guaranteed drop from killing normal-looking pilgrim # Stone-humped Hag's shop - DS3LocationData("DH: Splitleaf Greatsword (shop)", "Splitleaf Greatsword", shop = True), - DS3LocationData("DH: Divine Blessing (shop)", "Divine Blessing", shop = True), - DS3LocationData("DH: Hidden Blessing (shop)", "Hidden Blessing", shop = True), - DS3LocationData("DH: Rusted Gold Coin (shop)", "Rusted Gold Coin", shop = True), - DS3LocationData("DH: Ember (shop)", "Ember", shop = True), + DS3LocationData("DH: Splitleaf Greatsword - shop", "Splitleaf Greatsword", shop = True), + DS3LocationData("DH: Divine Blessing - shop", "Divine Blessing", shop = True), + DS3LocationData("DH: Hidden Blessing - shop", "Hidden Blessing", shop = True), + DS3LocationData("DH: Rusted Gold Coin - shop", "Rusted Gold Coin", shop = True), + DS3LocationData("DH: Ember - shop", "Ember", shop = True), ], "Ringed City": [ - DS3LocationData("RC: Titanite Slab (mid boss drop)", "Titanite Slab", + DS3LocationData("RC: Titanite Slab - mid boss drop", "Titanite Slab", prominent = True, boss = True), # Halflight drop, only once - DS3LocationData("RC: Filianore's Spear Ornament (mid boss drop)", + DS3LocationData("RC: Filianore's Spear Ornament - mid boss drop", "Filianore's Spear Ornament"), DS3LocationData("RC: Soul of Darkeater Midir", "Soul of Darkeater Midir", prominent = True, boss = True), - DS3LocationData("RC: Sacred Chime of Filianore (ashes, NPC drop)", + DS3LocationData("RC: Sacred Chime of Filianore - ashes, NPC drop", "Sacred Chime of Filianore", hostile_npc = True), # Shira (kill or quest) - DS3LocationData("RC: Titanite Slab (ashes, NPC drop)", "Titanite Slab", + DS3LocationData("RC: Titanite Slab - ashes, NPC drop", "Titanite Slab", hostile_npc = True), # Shira (kill or quest) - DS3LocationData("RC: Crucifix of the Mad King (ashes, NPC drop)", + DS3LocationData("RC: Crucifix of the Mad King - ashes, NPC drop", "Crucifix of the Mad King", hostile_npc = True), # Shira drop - DS3LocationData("RC: Ledo's Great Hammer (streets high, opposite building, NPC drop)", + DS3LocationData("RC: Ledo's Great Hammer - streets high, opposite building, NPC drop", "Ledo's Great Hammer", hostile_npc = True), # Silver Knight Ledo drop - DS3LocationData("RC: Wolf Ring+3 (street gardens, NPC drop)", "Wolf Ring+3", + DS3LocationData("RC: Wolf Ring+3 - street gardens, NPC drop", "Wolf Ring+3", hostile_npc = True), # Alva drop - DS3LocationData("RC: Blindfold Mask (grave, NPC drop)", "Blindfold Mask", + DS3LocationData("RC: Blindfold Mask - grave, NPC drop", "Blindfold Mask", hostile_npc = True), # Moaning Knight drop - DS3LocationData("RC: Titanite Scale (wall top, behind spawn)", "Titanite Scale"), - DS3LocationData("RC: Ruin Helm (wall top, under stairs to bonfire)", "Ruin Helm"), - DS3LocationData("RC: Ruin Armor (wall top, under stairs to bonfire)", "Ruin Armor"), - DS3LocationData("RC: Ruin Gauntlets (wall top, under stairs to bonfire)", "Ruin Gauntlets"), - DS3LocationData("RC: Ruin Leggings (wall top, under stairs to bonfire)", "Ruin Leggings"), - DS3LocationData("RC: Budding Green Blossom (wall top, in flower cluster)", + DS3LocationData("RC: Titanite Scale - wall top, behind spawn", "Titanite Scale"), + DS3LocationData("RC: Ruin Helm - wall top, under stairs to bonfire", "Ruin Helm"), + DS3LocationData("RC: Ruin Armor - wall top, under stairs to bonfire", "Ruin Armor"), + DS3LocationData("RC: Ruin Gauntlets - wall top, under stairs to bonfire", "Ruin Gauntlets"), + DS3LocationData("RC: Ruin Leggings - wall top, under stairs to bonfire", "Ruin Leggings"), + DS3LocationData("RC: Budding Green Blossom - wall top, in flower cluster", "Budding Green Blossom x2"), - DS3LocationData("RC: Titanite Chunk (wall top, among graves)", "Titanite Chunk x2"), - DS3LocationData("RC: Ember (wall top, by statue)", "Ember"), - DS3LocationData("RC: Budding Green Blossom (wall top, flowers by stairs)", + DS3LocationData("RC: Titanite Chunk - wall top, among graves", "Titanite Chunk x2"), + DS3LocationData("RC: Ember - wall top, by statue", "Ember"), + DS3LocationData("RC: Budding Green Blossom - wall top, flowers by stairs", "Budding Green Blossom x2"), - DS3LocationData("RC: Hidden Blessing (wall top, tomb under platform)", "Hidden Blessing", + DS3LocationData("RC: Hidden Blessing - wall top, tomb under platform", "Hidden Blessing", hidden = True), # hidden fall - DS3LocationData("RC: Soul of a Crestfallen Knight (wall top, under drop)", + DS3LocationData("RC: Soul of a Crestfallen Knight - wall top, under drop", "Soul of a Crestfallen Knight", hidden = True), # hidden fall - DS3LocationData("RC: Large Soul of a Weary Warrior (wall top, right of small tomb)", + DS3LocationData("RC: Large Soul of a Weary Warrior - wall top, right of small tomb", "Large Soul of a Weary Warrior"), - DS3LocationData("RC: Ember (wall upper, balcony)", "Ember"), - DS3LocationData("RC: Purging Stone (wall top, by door to upper)", "Purging Stone x2"), - DS3LocationData("RC: Hollow Gem (wall upper, path to tower)", "Hollow Gem"), - DS3LocationData("RC: Titanite Chunk (wall upper, courtyard alcove)", "Titanite Chunk"), - DS3LocationData("RC: Twinkling Titanite (wall tower, jump from chandelier)", + DS3LocationData("RC: Ember - wall upper, balcony", "Ember"), + DS3LocationData("RC: Purging Stone - wall top, by door to upper", "Purging Stone x2"), + DS3LocationData("RC: Hollow Gem - wall upper, path to tower", "Hollow Gem"), + DS3LocationData("RC: Titanite Chunk - wall upper, courtyard alcove", "Titanite Chunk"), + DS3LocationData("RC: Twinkling Titanite - wall tower, jump from chandelier", "Twinkling Titanite", hidden = True), # Hidden fall - DS3LocationData("RC: Shriving Stone (wall tower, bottom floor center)", "Shriving Stone"), - DS3LocationData("RC: Shira's Crown (Shira's room after killing ashes NPC)", "Shira's Crown", + DS3LocationData("RC: Shriving Stone - wall tower, bottom floor center", "Shriving Stone"), + DS3LocationData("RC: Shira's Crown - Shira's room after killing ashes NPC", "Shira's Crown", hidden = True), # Have to return to a cleared area - DS3LocationData("RC: Shira's Armor (Shira's room after killing ashes NPC)", "Shira's Armor", + DS3LocationData("RC: Shira's Armor - Shira's room after killing ashes NPC", "Shira's Armor", hidden = True), # Have to return to a cleared area - DS3LocationData("RC: Shira's Gloves (Shira's room after killing ashes NPC)", + DS3LocationData("RC: Shira's Gloves - Shira's room after killing ashes NPC", "Shira's Gloves", hidden = True), # Have to return to a cleared area - DS3LocationData("RC: Shira's Trousers (Shira's room after killing ashes NPC)", + DS3LocationData("RC: Shira's Trousers - Shira's room after killing ashes NPC", "Shira's Trousers", hidden = True), # Have to return to a cleared area - DS3LocationData("RC: Mossfruit (streets near left, path to garden)", "Mossfruit x2"), - DS3LocationData("RC: Large Soul of a Crestfallen Knight (streets, far stairs)", + DS3LocationData("RC: Mossfruit - streets near left, path to garden", "Mossfruit x2"), + DS3LocationData("RC: Large Soul of a Crestfallen Knight - streets, far stairs", "Large Soul of a Crestfallen Knight"), - DS3LocationData("RC: Ringed Knight Spear (streets, down far right hall)", + DS3LocationData("RC: Ringed Knight Spear - streets, down far right hall", "Ringed Knight Spear"), - DS3LocationData("RC: Black Witch Hat (streets garden)", "Black Witch Hat", + DS3LocationData("RC: Black Witch Hat - streets garden", "Black Witch Hat", hostile_npc = True), # Alva - DS3LocationData("RC: Black Witch Garb (streets garden)", "Black Witch Garb", + DS3LocationData("RC: Black Witch Garb - streets garden", "Black Witch Garb", hostile_npc = True), # Alva - DS3LocationData("RC: Black Witch Wrappings (streets garden)", "Black Witch Wrappings", + DS3LocationData("RC: Black Witch Wrappings - streets garden", "Black Witch Wrappings", hostile_npc = True), # Alva - DS3LocationData("RC: Black Witch Trousers (streets garden)", "Black Witch Trousers", + DS3LocationData("RC: Black Witch Trousers - streets garden", "Black Witch Trousers", hostile_npc = True), # Alva - DS3LocationData("RC: Dragonhead Shield (streets monument, across bridge)", + DS3LocationData("RC: Dragonhead Shield - streets monument, across bridge", "Dragonhead Shield", hidden = True), # "Show Your Humanity" puzzle - DS3LocationData("RC: Titanite Chunk (streets, near left drop)", "Titanite Chunk", + DS3LocationData("RC: Titanite Chunk - streets, near left drop", "Titanite Chunk", hidden = True), # Hidden fall - DS3LocationData("RC: Mossfruit (streets, far left alcove)", "Mossfruit x2"), - DS3LocationData("RC: Large Soul of a Crestfallen Knight (streets monument, across bridge)", + DS3LocationData("RC: Mossfruit - streets, far left alcove", "Mossfruit x2"), + DS3LocationData("RC: Large Soul of a Crestfallen Knight - streets monument, across bridge", "Large Soul of a Crestfallen Knight", hidden = True), # "Show Your Humanity" puzzle - DS3LocationData("RC: Covetous Gold Serpent Ring+3 (streets, by Lapp)", + DS3LocationData("RC: Covetous Gold Serpent Ring+3 - streets, by Lapp", "Covetous Gold Serpent Ring+3"), - DS3LocationData("RC: Titanite Chunk (streets high, building opposite)", "Titanite Chunk x2"), - DS3LocationData("RC: Dark Gem (swamp near, by stairs)", "Dark Gem"), - DS3LocationData("RC: Prism Stone (swamp near, path to bonfire)", "Prism Stone x4"), - DS3LocationData("RC: Ringed Knight Straight Sword (swamp near, pillar by bonfire)", + DS3LocationData("RC: Titanite Chunk - streets high, building opposite", "Titanite Chunk x2"), + DS3LocationData("RC: Dark Gem - swamp near, by stairs", "Dark Gem"), + DS3LocationData("RC: Prism Stone - swamp near, path to bonfire", "Prism Stone x4"), + DS3LocationData("RC: Ringed Knight Straight Sword - swamp near, pillar by bonfire", "Ringed Knight Straight Sword"), - DS3LocationData("RC: Havel's Ring+3 (streets high, drop from building opposite)", + DS3LocationData("RC: Havel's Ring+3 - streets high, drop from building opposite", "Havel's Ring+3", hidden = True), # Hidden fall - DS3LocationData("RC: Titanite Chunk (swamp near left, opposite ladder)", "Titanite Chunk"), - DS3LocationData("RC: Twinkling Titanite (swamp near left)", "Twinkling Titanite"), - DS3LocationData("RC: Soul of a Weary Warrior (swamp center)", "Soul of a Weary Warrior"), - DS3LocationData("RC: Preacher's Right Arm (swamp near right, by crystal)", + DS3LocationData("RC: Titanite Chunk - swamp near left, opposite ladder", "Titanite Chunk"), + DS3LocationData("RC: Twinkling Titanite - swamp near left", "Twinkling Titanite"), + DS3LocationData("RC: Soul of a Weary Warrior - swamp center", "Soul of a Weary Warrior"), + DS3LocationData("RC: Preacher's Right Arm - swamp near right, by crystal", "Preacher's Right Arm"), - DS3LocationData("RC: Rubbish (swamp far, by crystal)", "Rubbish"), - DS3LocationData("RC: Titanite Chunk (swamp near right, by sinking church)", + DS3LocationData("RC: Rubbish - swamp far, by crystal", "Rubbish"), + DS3LocationData("RC: Titanite Chunk - swamp near right, by sinking church", "Titanite Chunk"), - DS3LocationData("RC: Black Witch Veil (swamp near right, by sinking church)", + DS3LocationData("RC: Black Witch Veil - swamp near right, by sinking church", "Black Witch Veil"), - DS3LocationData("RC: Twinkling Titanite (swamp near right, on sinking church)", + DS3LocationData("RC: Twinkling Titanite - swamp near right, on sinking church", "Twinkling Titanite"), - DS3LocationData("RC: Soul of a Crestfallen Knight (swamp near left, by ladder)", + DS3LocationData("RC: Soul of a Crestfallen Knight - swamp near left, by ladder", "Soul of a Crestfallen Knight"), - DS3LocationData("RC: White Preacher Head (swamp near, ground near bonfire exit)", + DS3LocationData("RC: White Preacher Head - swamp near, ground near bonfire exit", "White Preacher Head"), - DS3LocationData("RC: Titanite Scale (swamp far, by miniboss)", "Titanite Scale"), - DS3LocationData("RC: Titanite Scale (upper cliff, path under bridge)", "Titanite Scale"), - DS3LocationData("RC: Dragonhead Greatshield (upper cliff, under bridge)", + DS3LocationData("RC: Titanite Scale - swamp far, by miniboss", "Titanite Scale"), + DS3LocationData("RC: Titanite Scale - upper cliff, path under bridge", "Titanite Scale"), + DS3LocationData("RC: Dragonhead Greatshield - upper cliff, under bridge", "Dragonhead Greatshield"), - DS3LocationData("RC: Titanite Scale (upper cliff, first alcove)", "Titanite Scale x2"), - DS3LocationData("RC: Rubbish (upper cliff, middle)", "Rubbish"), - DS3LocationData("RC: Large Soul of a Weary Warrior (upper cliff, end)", + DS3LocationData("RC: Titanite Scale - upper cliff, first alcove", "Titanite Scale x2"), + DS3LocationData("RC: Rubbish - upper cliff, middle", "Rubbish"), + DS3LocationData("RC: Large Soul of a Weary Warrior - upper cliff, end", "Large Soul of a Weary Warrior"), - DS3LocationData("RC: Titanite Scale (upper cliff, lower path)", "Titanite Scale x2"), - DS3LocationData("RC: Titanite Scale (lower cliff, bridge)", "Titanite Scale"), - DS3LocationData("RC: Lightning Gem (grave, room after first drop)", "Lightning Gem"), - DS3LocationData("RC: Blessed Gem (grave, down lowest stairs)", "Blessed Gem"), - DS3LocationData("RC: Simple Gem (grave, up stairs after first drop)", "Simple Gem"), - DS3LocationData("RC: Large Soul of a Weary Warrior (wall lower, past two illusory walls)", + DS3LocationData("RC: Titanite Scale - upper cliff, lower path", "Titanite Scale x2"), + DS3LocationData("RC: Titanite Scale - lower cliff, bridge", "Titanite Scale"), + DS3LocationData("RC: Lightning Gem - grave, room after first drop", "Lightning Gem"), + DS3LocationData("RC: Blessed Gem - grave, down lowest stairs", "Blessed Gem"), + DS3LocationData("RC: Simple Gem - grave, up stairs after first drop", "Simple Gem"), + DS3LocationData("RC: Large Soul of a Weary Warrior - wall lower, past two illusory walls", "Large Soul of a Weary Warrior", hidden = True), - DS3LocationData("RC: Lightning Arrow (wall lower, past three illusory walls)", + DS3LocationData("RC: Lightning Arrow - wall lower, past three illusory walls", "Lightning Arrow"), - DS3LocationData("RC: Chloranthy Ring+3 (wall hidden, drop onto statue)", + DS3LocationData("RC: Chloranthy Ring+3 - wall hidden, drop onto statue", "Chloranthy Ring+3", hidden = True), # Hidden fall - DS3LocationData("RC: Ember (wall hidden, statue room)", "Ember"), - DS3LocationData("RC: Filianore's Spear Ornament (wall hidden, by ladder)", + DS3LocationData("RC: Ember - wall hidden, statue room", "Ember"), + DS3LocationData("RC: Filianore's Spear Ornament - wall hidden, by ladder", "Filianore's Spear Ornament"), - DS3LocationData("RC: Antiquated Plain Garb (wall hidden, before boss)", + DS3LocationData("RC: Antiquated Plain Garb - wall hidden, before boss", "Antiquated Plain Garb"), - DS3LocationData("RC: Violet Wrappings (wall hidden, before boss)", "Violet Wrappings"), - DS3LocationData("RC: Soul of a Weary Warrior (upper cliff, by first alcove)", + DS3LocationData("RC: Violet Wrappings - wall hidden, before boss", "Violet Wrappings"), + DS3LocationData("RC: Soul of a Weary Warrior - upper cliff, by first alcove", "Soul of a Weary Warrior"), - DS3LocationData("RC: Twinkling Titanite (church path, left of boss door)", + DS3LocationData("RC: Twinkling Titanite - church path, left of boss door", "Twinkling Titanite x2"), - DS3LocationData("RC: Budding Green Blossom (church path)", "Budding Green Blossom x3"), - DS3LocationData("RC: Titanite Chunk (swamp center, along edge)", "Titanite Chunk"), - DS3LocationData("RC: Large Soul of a Weary Warrior (swamp center)", + DS3LocationData("RC: Budding Green Blossom - church path", "Budding Green Blossom x3"), + DS3LocationData("RC: Titanite Chunk - swamp center, along edge", "Titanite Chunk"), + DS3LocationData("RC: Large Soul of a Weary Warrior - swamp center", "Large Soul of a Weary Warrior"), - DS3LocationData("RC: Soul of a Weary Warrior (swamp right, by sunken church)", + DS3LocationData("RC: Soul of a Weary Warrior - swamp right, by sunken church", "Soul of a Weary Warrior"), - DS3LocationData("RC: Titanite Scale (swamp far, by miniboss)", "Titanite Scale"), - DS3LocationData("RC: Soul of a Crestfallen Knight (swamp far, behind crystal)", + DS3LocationData("RC: Titanite Scale - swamp far, by miniboss", "Titanite Scale"), + DS3LocationData("RC: Soul of a Crestfallen Knight - swamp far, behind crystal", "Soul of a Crestfallen Knight"), - DS3LocationData("RC: White Birch Bow (swamp far left, up hill)", "White Birch Bow"), - DS3LocationData("RC: Titanite Chunk (swamp far left, up hill)", "Titanite Chunk"), - DS3LocationData("RC: Young White Branch (swamp far left, by white tree)", + DS3LocationData("RC: White Birch Bow - swamp far left, up hill", "White Birch Bow"), + DS3LocationData("RC: Titanite Chunk - swamp far left, up hill", "Titanite Chunk"), + DS3LocationData("RC: Young White Branch - swamp far left, by white tree", "Young White Branch"), - DS3LocationData("RC: Young White Branch (swamp far left, by white tree)", + DS3LocationData("RC: Young White Branch - swamp far left, by white tree", "Young White Branch"), - DS3LocationData("RC: Young White Branch (swamp far left, by white tree)", + DS3LocationData("RC: Young White Branch - swamp far left, by white tree", "Young White Branch"), - DS3LocationData("RC: Ringed Knight Paired Greatswords (church path, mob drop)", + DS3LocationData("RC: Ringed Knight Paired Greatswords - church path, mob drop", "Ringed Knight Paired Greatswords", drop = True, hidden = True), # Guaranteed drop from a normal-looking Ringed Knight - DS3LocationData("RC: Hidden Blessing (swamp center, mob drop)", "Hidden Blessing", + DS3LocationData("RC: Hidden Blessing - swamp center, mob drop", "Hidden Blessing", drop = True, hidden = True), # Guaranteed drop from Judicator - DS3LocationData("RC: Divine Blessing (wall top, mob drop)", "Divine Blessing", + DS3LocationData("RC: Divine Blessing - wall top, mob drop", "Divine Blessing", drop = True, hidden = True), # Guaranteed drop from Judicator - DS3LocationData("RC: Divine Blessing (streets monument, mob drop)", "Divine Blessing", + DS3LocationData("RC: Divine Blessing - streets monument, mob drop", "Divine Blessing", drop = True, hidden = True), # Guaranteed drop from Judicator, "Show Your Humanity" puzzle - DS3LocationData("RC: Ring of the Evil Eye+3 (grave, mimic)", "Ring of the Evil Eye+3", + DS3LocationData("RC: Ring of the Evil Eye+3 - grave, mimic", "Ring of the Evil Eye+3", mimic = True), - DS3LocationData("RC: Iron Dragonslayer Helm (swamp far, miniboss drop)", + DS3LocationData("RC: Iron Dragonslayer Helm - swamp far, miniboss drop", "Iron Dragonslayer Helm", miniboss = True), - DS3LocationData("RC: Iron Dragonslayer Armor (swamp far, miniboss drop)", + DS3LocationData("RC: Iron Dragonslayer Armor - swamp far, miniboss drop", "Iron Dragonslayer Armor", miniboss = True), - DS3LocationData("RC: Iron Dragonslayer Gauntlets (swamp far, miniboss drop)", + DS3LocationData("RC: Iron Dragonslayer Gauntlets - swamp far, miniboss drop", "Iron Dragonslayer Gauntlets", miniboss = True), - DS3LocationData("RC: Iron Dragonslayer Leggings (swamp far, miniboss drop)", + DS3LocationData("RC: Iron Dragonslayer Leggings - swamp far, miniboss drop", "Iron Dragonslayer Leggings", miniboss = True), - DS3LocationData("RC: Church Guardian Shiv (swamp far left, in building)", + DS3LocationData("RC: Church Guardian Shiv - swamp far left, in building", "Church Guardian Shiv"), - DS3LocationData("RC: Spears of the Church (hidden boss drop)", "Spears of the Church", + DS3LocationData("RC: Spears of the Church - hidden boss drop", "Spears of the Church", boss = True), # Midir drop - DS3LocationData("RC: Ritual Spear Fragment (church path)", "Ritual Spear Fragment"), - DS3LocationData("RC: Titanite Scale (grave, lizard after first drop)", "Titanite Scale", + DS3LocationData("RC: Ritual Spear Fragment - church path", "Ritual Spear Fragment"), + DS3LocationData("RC: Titanite Scale - grave, lizard after first drop", "Titanite Scale", lizard = True), - DS3LocationData("RC: Twinkling Titanite (grave, lizard after first drop)", + DS3LocationData("RC: Twinkling Titanite - grave, lizard after first drop", "Twinkling Titanite", lizard = True), - DS3LocationData("RC: Titanite Scale (wall lower, lizard)", "Titanite Scale x2", + DS3LocationData("RC: Titanite Scale - wall lower, lizard", "Titanite Scale x2", lizard = True), - DS3LocationData("RC: Twinkling Titanite (streets high, lizard)", "Twinkling Titanite x2", + DS3LocationData("RC: Twinkling Titanite - streets high, lizard", "Twinkling Titanite x2", lizard = True), - DS3LocationData("RC: Titanite Scale (wall top, lizard on side path)", "Titanite Scale", + DS3LocationData("RC: Titanite Scale - wall top, lizard on side path", "Titanite Scale", lizard = True), - DS3LocationData("RC: Twinkling Titanite (wall top, lizard on side path)", + DS3LocationData("RC: Twinkling Titanite - wall top, lizard on side path", "Twinkling Titanite", lizard = True), DS3LocationData("RC: Soul of Slave Knight Gael", "Soul of Slave Knight Gael", prominent = True, boss = True), - DS3LocationData("RC: Blood of the Dark Soul (end boss drop)", "Blood of the Dark Soul"), - DS3LocationData("RC: Titanite Slab (ashes, mob drop)", "Titanite Slab", + DS3LocationData("RC: Blood of the Dark Soul - end boss drop", "Blood of the Dark Soul"), + DS3LocationData("RC: Titanite Slab - ashes, mob drop", "Titanite Slab", drop = True, hidden = True), # Guaranteed drop from normal-looking Ringed Knight # Lapp - DS3LocationData("RC: Siegbräu (Lapp)", "Siegbräu", missable = True, + DS3LocationData("RC: Siegbräu - Lapp", "Siegbräu", missable = True, npc = True), # Lapp (quest) # Quest or Shrine Handmaiden after death - DS3LocationData("RC: Lapp's Helm (Lapp)", "Lapp's Helm", npc = True, shop = True), - DS3LocationData("RC: Lapp's Armor (Lapp)", "Lapp's Armor", npc = True, shop = True), - DS3LocationData("RC: Lapp's Gauntlets (Lapp)", "Lapp's Gauntlets", npc = True, shop = True), - DS3LocationData("RC: Lapp's Leggings (Lapp)", "Lapp's Leggings", npc = True, shop = True), + DS3LocationData("RC: Lapp's Helm - Lapp", "Lapp's Helm", npc = True, shop = True), + DS3LocationData("RC: Lapp's Armor - Lapp", "Lapp's Armor", npc = True, shop = True), + DS3LocationData("RC: Lapp's Gauntlets - Lapp", "Lapp's Gauntlets", npc = True, shop = True), + DS3LocationData("RC: Lapp's Leggings - Lapp", "Lapp's Leggings", npc = True, shop = True), ], # Unlockable shops. We only bother creating a "region" for these for shops that are locked # behind keys and always have items available either through the shop or through the NPC's # ashes. "Greirat's Shop": [ - DS3LocationData("FS: Blue Tearstone Ring (Greirat)", "Blue Tearstone Ring", + DS3LocationData("FS: Blue Tearstone Ring - Greirat", "Blue Tearstone Ring", offline = '01,0:50006120::', npc = True), - DS3LocationData("FS: Ember (Greirat)", "Ember", offline = "99,0:-1:110000,120000,70000110:", + DS3LocationData("FS: Ember - Greirat", "Ember", offline = "99,0:-1:110000,120000,70000110:", shop = True, npc = True), # Undead Settlement rewards - DS3LocationData("FS: Divine Blessing (Greirat from US)", "Divine Blessing", + DS3LocationData("FS: Divine Blessing - Greirat from US", "Divine Blessing", offline = '99,0:-1:110000,120000,70000150,70000175:', missable = True, shop = True, npc = True), - DS3LocationData("FS: Ember (Greirat from US)", "Ember", + DS3LocationData("FS: Ember - Greirat from US", "Ember", offline = '99,0:-1:110000,120000,70000150,70000175:', missable = True, shop = True, npc = True), # Irityhll rewards - DS3LocationData("FS: Divine Blessing (Greirat from IBV)", "Divine Blessing", + DS3LocationData("FS: Divine Blessing - Greirat from IBV", "Divine Blessing", offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), - DS3LocationData("FS: Hidden Blessing (Greirat from IBV)", "Hidden Blessing", + DS3LocationData("FS: Hidden Blessing - Greirat from IBV", "Hidden Blessing", offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), - DS3LocationData("FS: Titanite Scale (Greirat from IBV)", "Titanite Scale", + DS3LocationData("FS: Titanite Scale - Greirat from IBV", "Titanite Scale", offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), - DS3LocationData("FS: Twinkling Titanite (Greirat from IBV)", "Twinkling Titanite", + DS3LocationData("FS: Twinkling Titanite - Greirat from IBV", "Twinkling Titanite", offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, shop = True, npc = True), # Lothric rewards (from Shrine Handmaid) - DS3LocationData("FS: Ember (shop for Greirat's Ashes)", "Twinkling Titanite", + DS3LocationData("FS: Ember - shop for Greirat's Ashes", "Twinkling Titanite", offline = '99,0:-1:110000,120000,70000152,70000177:', missable = True, shop = True, npc = True), ], "Karla's Shop": [ - DS3LocationData("FS: Affinity (Karla)", "Affinity", shop = True, npc = True), - DS3LocationData("FS: Dark Edge (Karla)", "Dark Edge", shop = True, npc = True), + DS3LocationData("FS: Affinity - Karla", "Affinity", shop = True, npc = True), + DS3LocationData("FS: Dark Edge - Karla", "Dark Edge", shop = True, npc = True), # Quelana Pyromancy Tome - DS3LocationData("FS: Firestorm (Karla for Quelana Tome)", "Firestorm", missable = True, + DS3LocationData("FS: Firestorm - Karla for Quelana Tome", "Firestorm", missable = True, shop = True, npc = True), - DS3LocationData("FS: Rapport (Karla for Quelana Tome)", "Rapport", missable = True, + DS3LocationData("FS: Rapport - Karla for Quelana Tome", "Rapport", missable = True, shop = True, npc = True), - DS3LocationData("FS: Fire Whip (Karla for Quelana Tome)", "Fire Whip", missable = True, + DS3LocationData("FS: Fire Whip - Karla for Quelana Tome", "Fire Whip", missable = True, shop = True, npc = True), # Grave Warden Pyromancy Tome - DS3LocationData("FS: Black Flame (Karla for Grave Warden Tome)", "Black Flame", + DS3LocationData("FS: Black Flame - Karla for Grave Warden Tome", "Black Flame", missable = True, shop = True, npc = True), - DS3LocationData("FS: Black Fire Orb (Karla for Grave Warden Tome)", "Black Fire Orb", + DS3LocationData("FS: Black Fire Orb - Karla for Grave Warden Tome", "Black Fire Orb", missable = True, shop = True, npc = True), # Deep Braille Divine Tome. This can also be given to Irina but it'll fail her quest - DS3LocationData("FS: Gnaw (Karla for Deep Braille Tome)", "Gnaw", missable = True, + DS3LocationData("FS: Gnaw - Karla for Deep Braille Tome", "Gnaw", missable = True, npc = True, shop = True), - DS3LocationData("FS: Deep Protection (Karla for Deep Braille Tome)", "Deep Protection", + DS3LocationData("FS: Deep Protection - Karla for Deep Braille Tome", "Deep Protection", missable = True, npc = True, shop = True), # Londor Braille Divine Tome. This can also be given to Irina but it'll fail her quest - DS3LocationData("FS: Vow of Silence (Karla for Londor Tome)", "Vow of Silence", + DS3LocationData("FS: Vow of Silence - Karla for Londor Tome", "Vow of Silence", missable = True, npc = True, shop = True), - DS3LocationData("FS: Dark Blade (Karla for Londor Tome)", "Dark Blade", missable = True, + DS3LocationData("FS: Dark Blade - Karla for Londor Tome", "Dark Blade", missable = True, npc = True, shop = True), - DS3LocationData("FS: Dead Again (Karla for Londor Tome)", "Dead Again", missable = True, + DS3LocationData("FS: Dead Again - Karla for Londor Tome", "Dead Again", missable = True, npc = True, shop = True), # Drops on death. Missable because the player would have to decide between killing her or # seeing everything she sells. - DS3LocationData("FS: Karla's Pointed Hat (kill Karla)", "Karla's Pointed Hat", + DS3LocationData("FS: Karla's Pointed Hat - kill Karla", "Karla's Pointed Hat", offline = '07,0:50006150::', missable = True, drop = True, npc = True), - DS3LocationData("FS: Karla's Coat (kill Karla)", "Karla's Coat", + DS3LocationData("FS: Karla's Coat - kill Karla", "Karla's Coat", offline = '07,0:50006150::', missable = True, drop = True, npc = True), - DS3LocationData("FS: Karla's Gloves (kill Karla)", "Karla's Gloves", + DS3LocationData("FS: Karla's Gloves - kill Karla", "Karla's Gloves", offline = '07,0:50006150::', missable = True, drop = True, npc = True), - DS3LocationData("FS: Karla's Trousers (kill Karla)", "Karla's Trousers", + DS3LocationData("FS: Karla's Trousers - kill Karla", "Karla's Trousers", offline = '07,0:50006150::', missable = True, drop = True, npc = True), ], } diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 9651fcd535a8..145f16e9fbca 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -133,7 +133,7 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: if not self.options.enable_dlc and boss.dlc: return False - if not self.is_location_available("PC: Storm Ruler (boss room)"): + if not self.is_location_available("PC: Storm Ruler - boss room"): # If the Storm Ruler isn't randomized, make sure the player can get to the normal Storm # Ruler location before they need to get through Yhorm. if boss.before_storm_ruler: return False @@ -141,7 +141,7 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: # If the Small Doll also wasn't randomized, make sure Yhorm isn't blocking access to it # or it won't be possible to get into Profaned Capital before beating him. if ( - not self.is_location_available("CD: Small Doll (boss drop)") + not self.is_location_available("CD: Small Doll - boss drop") and boss.name in {"Crystal Sage", "Deacons of the Deep"} ): return False @@ -154,7 +154,7 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: return any( self.is_location_available(location) and location.name not in excluded - and location.name != "CA: Coiled Sword (boss drop)" + and location.name != "CA: Coiled Sword - boss drop" for location in location_tables["Cemetery of Ash"] ) @@ -263,13 +263,13 @@ def create_region(self, region_name, location_table) -> Region: ) or ( # Mark Red Eye Orb as missable if Lift Chamber Key isn't randomized, because # the latter is missable by default. - not self.is_location_available("FS: Lift Chamber Key (Leonhard)") - and location.name == "HWL: Red Eye Orb (wall tower, miniboss)" + not self.is_location_available("FS: Lift Chamber Key - Leonhard") + and location.name == "HWL: Red Eye Orb - wall tower, miniboss" ): new_location.progress_type = LocationProgressType.EXCLUDED else: # Don't allow Siegward's Storm Ruler to mark Yhorm as defeatable. - if location.name == "PC: Storm Ruler (Siegward)": continue + if location.name == "PC: Storm Ruler - Siegward": continue # Replace non-randomized progression items with events event_item = ( @@ -465,14 +465,14 @@ def set_rules(self) -> None: self._add_entrance_rule("Painted World of Ariandel (After Contraption)", "Small Doll") # Define the access rules to some specific locations - if self.is_location_available("FS: Lift Chamber Key (Leonhard)"): - self._add_location_rule("HWL: Red Eye Orb (wall tower, miniboss)", + if self.is_location_available("FS: Lift Chamber Key - Leonhard"): + self._add_location_rule("HWL: Red Eye Orb - wall tower, miniboss", "Lift Chamber Key") - self._add_location_rule("ID: Bellowing Dragoncrest Ring (drop from B1 towards pit)", + self._add_location_rule("ID: Bellowing Dragoncrest Ring - drop from B1 towards pit", "Jailbreaker's Key") - self._add_location_rule("ID: Covetous Gold Serpent Ring (Siegward's cell)", "Old Cell Key") + self._add_location_rule("ID: Covetous Gold Serpent Ring - Siegward's cell", "Old Cell Key") self._add_location_rule( - "UG: Hornet Ring (environs, right of main path after killing FK boss)", + "UG: Hornet Ring - environs, right of main path after killing FK boss", "Small Lothric Banner" ) self._add_entrance_rule("Karla's Shop", "Jailer's Key Ring") @@ -498,7 +498,7 @@ def set_rules(self) -> None: ] } for (ash, items) in ashes.items(): - self._add_location_rule([f"FS: {item} ({ash})" for item in items], ash) + self._add_location_rule([f"FS: {item} - {ash}" for item in items], ash) # Soul transposition transpositions = [ @@ -556,7 +556,7 @@ def set_rules(self) -> None: ] for (soul, soul_name, items) in transpositions: self._add_location_rule([ - f"FS: {item} (Ludleth for {soul_name})" for item in items + f"FS: {item} - Ludleth for {soul_name}" for item in items ], soul) # List missable locations even though they never contain progression items so that the game @@ -564,10 +564,10 @@ def set_rules(self) -> None: # rules for boss transposition items as well, but then we couldn't freely reorder boss soul # locations for smoothing. - self._add_location_rule("FS: Lift Chamber Key (Leonhard)", "Pale Tongue") + self._add_location_rule("FS: Lift Chamber Key - Leonhard", "Pale Tongue") self._add_location_rule([ - "FK: Twinkling Dragon Head Stone (Hawkwood drop)", - "FS: Hawkwood's Swordgrass (Andre after gesture in AP summit)" + "FK: Twinkling Dragon Head Stone - Hawkwood drop", + "FS: Hawkwood's Swordgrass - Andre after gesture in AP summit" ], "Twinkling Dragon Torso Stone") # Shop unlocks @@ -624,25 +624,25 @@ def set_rules(self) -> None: for (shop, unlocks) in shop_unlocks.items(): for (key, key_name, items) in unlocks: self._add_location_rule( - [f"FS: {item} ({shop} for {key_name})" for item in items], key) + [f"FS: {item} - {shop} for {key_name}" for item in items], key) self._add_location_rule([ - "FS: Divine Blessing (Greirat from US)", - "FS: Ember (Greirat from US)", + "FS: Divine Blessing - Greirat from US", + "FS: Ember - Greirat from US", ], lambda state: state.can_reach("Go To Undead Settlement", "Entrance", self.player)) self._add_location_rule([ - "FS: Divine Blessing (Greirat from IBV)", - "FS: Hidden Blessing (Greirat from IBV)", - "FS: Titanite Scale (Greirat from IBV)", - "FS: Twinkling Titanite (Greirat from IBV)", - "FS: Ember (shop for Greirat's Ashes)" + "FS: Divine Blessing - Greirat from IBV", + "FS: Hidden Blessing - Greirat from IBV", + "FS: Titanite Scale - Greirat from IBV", + "FS: Twinkling Titanite - Greirat from IBV", + "FS: Ember - shop for Greirat's Ashes" ], lambda state: state.can_reach( "Go To Irithyll of the Boreal Valley", "Entrance", self.player )) self._add_location_rule( - "FS: Ember (shop for Greirat's Ashes)", + "FS: Ember - shop for Greirat's Ashes", lambda state: state.can_reach("Go To Grand Archives", "Entrance", self.player) ) @@ -663,27 +663,27 @@ def set_rules(self) -> None: "Eleonora": "Hollow Gem", } for (given, received) in crow.items(): - self._add_location_rule(f"FSBT: {received} (crow for {given})", given) + self._add_location_rule(f"FSBT: {received} - crow for {given}", given) # The offline randomizer edits events to guarantee that Greirat won't go to Lothric until # Grand Archives is available, so his shop will always be available one way or another. self._add_entrance_rule("Greirat's Shop", "Cell Key") self._add_location_rule([ - f"FS: {item} (shop after killing Leonhard)" + f"FS: {item} - shop after killing Leonhard" for item in ["Leonhard's Garb", "Leonhard's Gauntlets", "Leonhard's Trousers"] ], "Black Eye Orb") # You could just kill NPCs for these, but it's more fun to ensure the player can do # their quests. - self._add_location_rule("HWL: Basin of Vows (Emma)", "Small Doll") + self._add_location_rule("HWL: Basin of Vows - Emma", "Small Doll") self._add_location_rule( - "ID: Prisoner Chief's Ashes (B2 near, locked cell by stairs)", + "ID: Prisoner Chief's Ashes - B2 near, locked cell by stairs", "Jailer's Key Ring" ) self._add_location_rule([ - "US: Old Sage's Blindfold (kill Cornyx)", "US: Cornyx's Garb (kill Cornyx)", - "US: Cornyx's Wrap (kill Cornyx)", "US: Cornyx's Skirt (kill Cornyx)" + "US: Old Sage's Blindfold - kill Cornyx", "US: Cornyx's Garb - kill Cornyx", + "US: Cornyx's Wrap - kill Cornyx", "US: Cornyx's Skirt - kill Cornyx" ], lambda state: ( state.has("Great Swamp Pyromancy Tome", self.player) and state.has("Carthus Pyromancy Tome", self.player) @@ -716,43 +716,43 @@ def has_any_scroll(state): self._add_location_rule("HWL: Soul of the Dancer", has_any_scroll) self._add_location_rule([ - "LC: Grand Archives Key (by Grand Archives door, after PC and AL bosses)", - "LC: Gotthard Twinswords (by Grand Archives door, after PC and AL bosses)" + "LC: Grand Archives Key - by Grand Archives door, after PC and AL bosses", + "LC: Gotthard Twinswords - by Grand Archives door, after PC and AL bosses" ], lambda state: ( state.can_reach("AL: Cinders of a Lord - Aldrich", "Location", self.player) and state.can_reach("PC: Cinders of a Lord - Yhorm the Giant", "Location", self.player) )) self._add_location_rule([ - "FS: Morne's Great Hammer (Eygon)", - "FS: Moaning Shield (Eygon)" + "FS: Morne's Great Hammer - Eygon", + "FS: Moaning Shield - Eygon" ], lambda state: ( state.can_reach("LC: Soul of Dragonslayer Armour", "Location", self.player) and state.can_reach("FK: Soul of the Blood of the Wolf", "Location", self.player) )) self._add_location_rule([ - "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)", + "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", ], lambda state: state.can_reach("Go To Archdragon Peak", "Entrance", self.player)) self._add_location_rule([ - "FK: Havel's Helm (upper keep, after killing AP belfry roof NPC)", - "FK: Havel's Armor (upper keep, after killing AP belfry roof NPC)", - "FK: Havel's Gauntlets (upper keep, after killing AP belfry roof NPC)", - "FK: Havel's Leggings (upper keep, after killing AP belfry roof NPC)", + "FK: Havel's Helm - upper keep, after killing AP belfry roof NPC", + "FK: Havel's Armor - upper keep, after killing AP belfry roof NPC", + "FK: Havel's Gauntlets - upper keep, after killing AP belfry roof NPC", + "FK: Havel's Leggings - upper keep, after killing AP belfry roof NPC", ], lambda state: state.can_reach("Go To Archdragon Peak", "Entrance", self.player)) self._add_location_rule([ - "RC: Dragonhead Shield (streets monument, across bridge)", - "RC: Large Soul of a Crestfallen Knight (streets monument, across bridge)", - "RC: Divine Blessing (streets monument, mob drop)", - "RC: Lapp's Helm (Lapp)", - "RC: Lapp's Armor (Lapp)", - "RC: Lapp's Gauntlets (Lapp)", - "RC: Lapp's Leggings (Lapp)", + "RC: Dragonhead Shield - streets monument, across bridge", + "RC: Large Soul of a Crestfallen Knight - streets monument, across bridge", + "RC: Divine Blessing - streets monument, mob drop", + "RC: Lapp's Helm - Lapp", + "RC: Lapp's Armor - Lapp", + "RC: Lapp's Gauntlets - Lapp", + "RC: Lapp's Leggings - Lapp", ], "Chameleon") # Forbid shops from carrying items with multiple counts (the offline randomizer has its own @@ -768,9 +768,9 @@ def has_any_scroll(state): # This particular location is bugged, and will drop two copies of whatever item is placed # there. - if self.is_location_available("US: Young White Branch (by white tree #2)"): + if self.is_location_available("US: Young White Branch - by white tree #2"): loc = self.multiworld.get_location( - "US: Young White Branch (by white tree #2)", + "US: Young White Branch - by white tree #2", self.player ) add_item_rule(loc, lambda item: item.player == self.player and not item.data.unique) @@ -881,7 +881,7 @@ def pre_fill(self) -> None: # doesn't get locked out by bad rolls on the next two fills. if self.yhorm_location.name == 'Iudex Gundyr': self._fill_local_item("Storm Ruler", {"Cemetery of Ash"}, - lambda location: location.name != "CA: Coiled Sword (boss drop)", + lambda location: location.name != "CA: Coiled Sword - boss drop", mandatory = True) # Don't place this in the multiworld because it's necessary almost immediately, and don't diff --git a/worlds/dark_souls_3/detailed_location_descriptions.py b/worlds/dark_souls_3/detailed_location_descriptions.py index 13879f742b0f..715aca758cff 100644 --- a/worlds/dark_souls_3/detailed_location_descriptions.py +++ b/worlds/dark_souls_3/detailed_location_descriptions.py @@ -14,7 +14,7 @@ from .Locations import location_dictionary -location_re = re.compile(r'^([A-Z0-9]+): (.*?)(?:$| \()') +location_re = re.compile(r'^([A-Z0-9]+): (.*?)(?:$| - )') if __name__ == '__main__': # TODO: update this to the main branch of the main randomizer once Archipelago support is merged diff --git a/worlds/dark_souls_3/docs/locations_en.md b/worlds/dark_souls_3/docs/locations_en.md index 529a9abb8e7b..5858cdcc02d3 100644 --- a/worlds/dark_souls_3/docs/locations_en.md +++ b/worlds/dark_souls_3/docs/locations_en.md @@ -671,1502 +671,1506 @@ offline _Dark Souls III_ randomizer]. - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + +
Location nameDetailed description
AL: Aldrich Faithful (water reserves, talk to McDonnel)Given by Archdeacon McDonnel in Water Reserves.
AL: Aldrich's Ruby (dark cathedral, miniboss)Dropped by the Deep Accursed who drops down when you open the Anor Londo Cathedral shortcut
AL: Anri's Straight Sword (Anri quest)Dropped by Anri of Astora upon death or completing quest. In the Darkmoon Tomb with Lord of Hollows route, or given by Ludleth if summoned to defeat Aldrich.
AL: Blade of the Darkmoon (Yorshka with Darkmoon Loyalty)Given by Yorshka after learning the Darkmoon Loyalty gesture from Sirris, or by killing her
AL: Brass Armor (tomb)Behind the illusory statue in the hallway leading to the Darkmoon Tomb
AL: Brass Gauntlets (tomb)Behind the illusory statue in the hallway leading to the Darkmoon Tomb
AL: Brass Helm (tomb)Behind the illusory statue in the hallway leading to the Darkmoon Tomb
AL: Brass Leggings (tomb)Behind the illusory statue in the hallway leading to the Darkmoon Tomb
AL: Chameleon (tomb after marrying Anri)Dropped by the Stone-humped Hag assassin after Anri reaches the Church of Yorshka, either in the church or after marrying Anri
AL: Aldrich Faithful - water reserves, talk to McDonnelGiven by Archdeacon McDonnel in Water Reserves.
AL: Aldrich's Ruby - dark cathedral, minibossDropped by the Deep Accursed who drops down when you open the Anor Londo Cathedral shortcut
AL: Anri's Straight Sword - Anri questDropped by Anri of Astora upon death or completing quest. In the Darkmoon Tomb with Lord of Hollows route, or given by Ludleth if summoned to defeat Aldrich.
AL: Blade of the Darkmoon - Yorshka with Darkmoon LoyaltyGiven by Yorshka after learning the Darkmoon Loyalty gesture from Sirris, or by killing her
AL: Brass Armor - tombBehind the illusory statue in the hallway leading to the Darkmoon Tomb
AL: Brass Gauntlets - tombBehind the illusory statue in the hallway leading to the Darkmoon Tomb
AL: Brass Helm - tombBehind the illusory statue in the hallway leading to the Darkmoon Tomb
AL: Brass Leggings - tombBehind the illusory statue in the hallway leading to the Darkmoon Tomb
AL: Chameleon - tomb after marrying AnriDropped by the Stone-humped Hag assassin after Anri reaches the Church of Yorshka, either in the church or after marrying Anri
AL: Cinders of a Lord - AldrichDropped by Aldrich
AL: Crescent Moon Sword (Leonhard drop)Drop by Ringfinger Leonhard upon death. Includes Soul of Rosaria if invaded in Anor Londo.
AL: Dark Stoneplate Ring (by dark stairs up from plaza)After the Pontiff fight, in the dark hallways to the left of the area with the Giant Slaves
AL: Deep Gem (water reserves)In the open in the Water Reserves
AL: Dragonslayer Greatarrow (drop from nearest buttress)Dropping down from about halfway down the flying buttress closest to the entrance to the Darkmoon Tomb
AL: Dragonslayer Greatbow (drop from nearest buttress)Dropping down from about halfway down the flying buttress closest to the entrance to the Darkmoon Tomb
AL: Drang Twinspears (plaza, NPC drop)Dropped by Drang Twinspears-wielding knight on the stairs leading up to the Anor Londo Silver Knights
AL: Easterner's Ashes (below top of furthest buttress)Dropping down from the rightmost flying buttress, or the rightmost set of stairs
AL: Ember (plaza, further)After the Pontiff fight, in the middle of the area with the Giant Slaves
AL: Ember (plaza, right side)After the Pontiff fight, next to one of the Giant Slaves on the right side
AL: Ember (spiral staircase, bottom)Next to the lever that summons the rotating Anor Londo stairs at the bottom
AL: Estus Shard (dark cathedral, by left stairs)In a chest on the floor of the Anor Londo cathedral
AL: Giant's Coal (by giant near dark cathedral)On the Giant Blacksmith's corpse in Anor Londo
AL: Golden Ritual Spear (light cathedral, mimic upstairs)Drop from a mimic in the higher levels of Pontiff's cathedral, accessible from the Deacons after the Pontiff fight
AL: Havel's Ring+2 (prison tower, rafters)On the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Human Dregs (water reserves)In the open in the Water Reserves
AL: Large Soul of a Weary Warrior (left of dark cathedral entrance)In front of the Anor Londo cathedral, slightly to the left
AL: Large Titanite Shard (after light cathedral)After the Pontiff fight, on the balcony to the right of the area with the Giant Slaves
AL: Large Titanite Shard (bottom of the furthest buttress)At the base of the rightmost flying buttress leading up to Anor Londo
AL: Large Titanite Shard (bottom of the nearest buttress)On the tower leading back from Anor Londo to the shortcut to Irithyll, down the flying buttress closest to the Darkmoon Tomb entrance.
AL: Large Titanite Shard (right after light cathedral)After Pontiff's cathedral, hugging the wall to the right
AL: Large Titanite Shard (walkway, side path by cathedral)After the Pontiff fight, going back from the Deacons area to the original cathedral, before a dropdown
AL: Moonlight Arrow (dark cathedral, up right stairs)In the Anor Londo cathedral, up the stairs on the right side
AL: Painting Guardian Gloves (prison tower, rafters)On the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Painting Guardian Gown (prison tower, rafters)On the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Painting Guardian Hood (prison tower, rafters)On the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Painting Guardian Waistcloth (prison tower, rafters)On the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Painting Guardian's Curved Sword (prison tower rafters)On the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Proof of a Concord Kept (dark cathedral, up left stairs)In the Anor Londo cathedral, halfway down the stairs on the left side next to some Deacons
AL: Reversal Ring (tomb, chest in corner)In a chest in Darkmoon Tomb
AL: Ring of Favor (water reserves, both minibosses)Dropped after killing both of Sulyvahn's Beasts in the Water Reserves
AL: Ring of Favor+1 (light cathedral, upstairs)In the higher levels of Pontiff's cathedral, accessible from the Deacons after the Pontiff fight
AL: Silver Mask (Leonhard drop)Drop by Ringfinger Leonhard upon death. Includes Soul of Rosaria if invaded in Anor Londo.
AL: Simple Gem (light cathedral, lizard upstairs)Dropped by a Crystal Lizard in the higher levels of Pontiff's cathedral, accessible from the Deacons after the Pontiff fight
AL: Crescent Moon Sword - Leonhard dropDrop by Ringfinger Leonhard upon death. Includes Soul of Rosaria if invaded in Anor Londo.
AL: Dark Stoneplate Ring - by dark stairs up from plazaAfter the Pontiff fight, in the dark hallways to the left of the area with the Giant Slaves
AL: Deep Gem - water reservesIn the open in the Water Reserves
AL: Dragonslayer Greatarrow - drop from nearest buttressDropping down from about halfway down the flying buttress closest to the entrance to the Darkmoon Tomb
AL: Dragonslayer Greatbow - drop from nearest buttressDropping down from about halfway down the flying buttress closest to the entrance to the Darkmoon Tomb
AL: Drang Twinspears - plaza, NPC dropDropped by Drang Twinspears-wielding knight on the stairs leading up to the Anor Londo Silver Knights
AL: Easterner's Ashes - below top of furthest buttressDropping down from the rightmost flying buttress, or the rightmost set of stairs
AL: Ember - plaza, furtherAfter the Pontiff fight, in the middle of the area with the Giant Slaves
AL: Ember - plaza, right sideAfter the Pontiff fight, next to one of the Giant Slaves on the right side
AL: Ember - spiral staircase, bottomNext to the lever that summons the rotating Anor Londo stairs at the bottom
AL: Estus Shard - dark cathedral, by left stairsIn a chest on the floor of the Anor Londo cathedral
AL: Giant's Coal - by giant near dark cathedralOn the Giant Blacksmith's corpse in Anor Londo
AL: Golden Ritual Spear - light cathedral, mimic upstairsDrop from a mimic in the higher levels of Pontiff's cathedral, accessible from the Deacons after the Pontiff fight
AL: Havel's Ring+2 - prison tower, raftersOn the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Human Dregs - water reservesIn the open in the Water Reserves
AL: Large Soul of a Weary Warrior - left of dark cathedral entranceIn front of the Anor Londo cathedral, slightly to the left
AL: Large Titanite Shard - after light cathedralAfter the Pontiff fight, on the balcony to the right of the area with the Giant Slaves
AL: Large Titanite Shard - bottom of the furthest buttressAt the base of the rightmost flying buttress leading up to Anor Londo
AL: Large Titanite Shard - bottom of the nearest buttressOn the tower leading back from Anor Londo to the shortcut to Irithyll, down the flying buttress closest to the Darkmoon Tomb entrance.
AL: Large Titanite Shard - right after light cathedralAfter Pontiff's cathedral, hugging the wall to the right
AL: Large Titanite Shard - walkway, side path by cathedralAfter the Pontiff fight, going back from the Deacons area to the original cathedral, before a dropdown
AL: Moonlight Arrow - dark cathedral, up right stairsIn the Anor Londo cathedral, up the stairs on the right side
AL: Painting Guardian Gloves - prison tower, raftersOn the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Painting Guardian Gown - prison tower, raftersOn the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Painting Guardian Hood - prison tower, raftersOn the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Painting Guardian Waistcloth - prison tower, raftersOn the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Painting Guardian's Curved Sword - prison tower raftersOn the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka
AL: Proof of a Concord Kept - dark cathedral, up left stairsIn the Anor Londo cathedral, halfway down the stairs on the left side next to some Deacons
AL: Reversal Ring - tomb, chest in cornerIn a chest in Darkmoon Tomb
AL: Ring of Favor - water reserves, both minibossesDropped after killing both of Sulyvahn's Beasts in the Water Reserves
AL: Ring of Favor+1 - light cathedral, upstairsIn the higher levels of Pontiff's cathedral, accessible from the Deacons after the Pontiff fight
AL: Silver Mask - Leonhard dropDrop by Ringfinger Leonhard upon death. Includes Soul of Rosaria if invaded in Anor Londo.
AL: Simple Gem - light cathedral, lizard upstairsDropped by a Crystal Lizard in the higher levels of Pontiff's cathedral, accessible from the Deacons after the Pontiff fight
AL: Soul of AldrichDropped by Aldrich
AL: Soul of Rosaria (Leonhard drop)Drop by Ringfinger Leonhard upon death. Includes Soul of Rosaria if invaded in Anor Londo.
AL: Soul of a Crestfallen Knight (right of dark cathedral entrance)To the right of the Anor Londo cathedral entrance, past the red-eyed Silver Knight
AL: Soul of a Weary Warrior (plaza, nearer)After the Pontiff fight, in the middle of the area with the Giant Slaves
AL: Sun Princess Ring (dark cathedral, after boss)In the Anor Londo cathedral after defeating Aldrich, up the elevators in Gwynevere's Chamber
AL: Titanite Scale (top of ladder up to buttresses)On the platform after the stairs leading up to Anor Londo from the Water Reserves building
AL: Twinkling Titanite (lizard after light cathedral #1)Dropped a Crystal Lizard straight after the Pontiff fight
AL: Yorshka's Chime (kill Yorshka)Dropped by Yorshka upon death.
AP: Ancient Dragon Greatshield (intro, on archway)After the Archdragon Peak bonfire, on top of the arch in front of the Ancient Wyvern fight
AP: Calamity Ring (mausoleum, gesture at altar)Received using Path of the Dragon at the Altar by the Mausoleum bonfire
AP: Covetous Gold Serpent Ring+2 (plaza)In the Nameless King boss arena after he is defeated
AP: Dragon Chaser's Ashes (summit, side path)In the run-up to the Dragon Altar after the Belfry bonfire, in a side path to the left side
AP: Dragon Head Stone (fort, boss drop)Dropped by Ancient Wyvern
AP: Dragon Tooth (belfry roof, NPC drop)Dropped from any of the Havel Knights
AP: Dragonslayer Armor (plaza)In the Nameless King boss arena after he is defeated
AP: Dragonslayer Gauntlets (plaza)In the Nameless King boss arena after he is defeated
AP: Dragonslayer Helm (plaza)In the Nameless King boss arena after he is defeated
AP: Dragonslayer Leggings (plaza)In the Nameless King boss arena after he is defeated
AP: Dragonslayer Spear (gate after mausoleum)In the gate connecting the Dragon-Kin Mausoleum area to the bridge where the Nameless King fight takes place
AP: Drakeblood Greatsword (mausoleum, NPC drop)Dropped by the Drakeblood Knight summoned by the Serpent-Man Summoner
AP: Dung Pie (fort, landing after second room)On a landing going up the stairs from the Ancient Wyvern to the chainaxe Man-Serpent area
AP: Ember (belfry, below bell)From the right of where Ancient Wyvern first lands
AP: Ember (fort overlook #2)From the right of where Ancient Wyvern first lands
AP: Ember (intro, by bonfire)In the area below the bell lever, either dropping down near the lever or going down the stairs from the open fountain area after the Belfry bonfire
AP: Great Magic Barrier (drop off belfry roof)Dropping down to the left from the area with the Havel Knight and the dead Wyvern
AP: Havel's Greatshield (belfry roof, NPC drop)Dropped from any of the Havel Knights
AP: Havel's Ring+1 (summit, after building)Just past the building with all of the Man-Serpents on the way to the Dragon Altar, on the left side
AP: Homeward Bone (intro, path to bonfire)From the start of the area, along the left path leading to the first bonfire
AP: Large Soul of a Crestfallen Knight (summit, by fountain)In the middle of the open fountain area after the Belfry bonfire
AP: Large Soul of a Nameless Soldier (fort, by stairs to first room)to the left of where the Ancient Wyvern lands
AP: Large Soul of a Weary Warrior (fort, center)Where the Ancient Wyvern lands
AP: Lightning Bolt (rotunda)On top of the ruined dome found going up spiral stairs to the left before the bridge with the chainaxe Man-Serpent
AP: Lightning Clutch Ring (intro, left of boss door)To the left of gate leading to Ancient Wyvern, past the Rock Lizard
AP: Lightning Gem (intro, side rise)From the start of the area, up a ledge in between two forked paths toward the first bonfire
AP: Lightning Urn (fort, left of first room entrance)On the path to the left of where the Ancient Wyvern lands, left of the building entrance
AP: Ricard's Rapier (belfry, NPC drop)Dropped by the Richard Champion summoned by the Serpent-Man Summoner
AP: Ring of Steel Protection (fort overlook, beside stairs)To the right of the area where the Ancient Wyvern lands, dropping down onto the ledge
AP: Soul of a Crestfallen Knight (mausoleum, upstairs)From the Mausoleum bonfire, up the second set of stairs to the right
AP: Soul of a Nameless Soldier (intro, right before archway)From the Archdragon Peak bonfire, going right before the arch before Ancient Wyvern
AP: Soul of a Weary Warrior (intro, first cliff edge)At the very start of the area on the left cliff edge
AP: Soul of a Weary Warrior (walkway, building window)On the way to the Belfry bonfire after the sagging wooden bridge, on a ledge visible in a room with a Crystal Lizard, accessible by a tricky jump or just going around the other side
AL: Soul of Rosaria - Leonhard dropDrop by Ringfinger Leonhard upon death. Includes Soul of Rosaria if invaded in Anor Londo.
AL: Soul of a Crestfallen Knight - right of dark cathedral entranceTo the right of the Anor Londo cathedral entrance, past the red-eyed Silver Knight
AL: Soul of a Weary Warrior - plaza, nearerAfter the Pontiff fight, in the middle of the area with the Giant Slaves
AL: Sun Princess Ring - dark cathedral, after bossIn the Anor Londo cathedral after defeating Aldrich, up the elevators in Gwynevere's Chamber
AL: Titanite Scale - top of ladder up to buttressesOn the platform after the stairs leading up to Anor Londo from the Water Reserves building
AL: Twinkling Titanite - lizard after light cathedral #1Dropped a Crystal Lizard straight after the Pontiff fight
AL: Twinkling Titanite - lizard after light cathedral #2Dropped a Crystal Lizard straight after the Pontiff fight
AL: Yorshka's Chime - kill YorshkaDropped by Yorshka upon death.
AP: Ancient Dragon Greatshield - intro, on archwayAfter the Archdragon Peak bonfire, on top of the arch in front of the Ancient Wyvern fight
AP: Calamity Ring - mausoleum, gesture at altarReceived using Path of the Dragon at the Altar by the Mausoleum bonfire
AP: Covetous Gold Serpent Ring+2 - plazaIn the Nameless King boss arena after he is defeated
AP: Dragon Chaser's Ashes - summit, side pathIn the run-up to the Dragon Altar after the Belfry bonfire, in a side path to the left side
AP: Dragon Head Stone - fort, boss dropDropped by Ancient Wyvern
AP: Dragon Tooth - belfry roof, NPC dropDropped from any of the Havel Knights
AP: Dragonslayer Armor - plazaIn the Nameless King boss arena after he is defeated
AP: Dragonslayer Gauntlets - plazaIn the Nameless King boss arena after he is defeated
AP: Dragonslayer Helm - plazaIn the Nameless King boss arena after he is defeated
AP: Dragonslayer Leggings - plazaIn the Nameless King boss arena after he is defeated
AP: Dragonslayer Spear - gate after mausoleumIn the gate connecting the Dragon-Kin Mausoleum area to the bridge where the Nameless King fight takes place
AP: Drakeblood Greatsword - mausoleum, NPC dropDropped by the Drakeblood Knight summoned by the Serpent-Man Summoner
AP: Dung Pie - fort, landing after second roomOn a landing going up the stairs from the Ancient Wyvern to the chainaxe Man-Serpent area
AP: Ember - belfry, below bellFrom the right of where Ancient Wyvern first lands
AP: Ember - fort overlook #2From the right of where Ancient Wyvern first lands
AP: Ember - intro, by bonfireIn the area below the bell lever, either dropping down near the lever or going down the stairs from the open fountain area after the Belfry bonfire
AP: Great Magic Barrier - drop off belfry roofDropping down to the left from the area with the Havel Knight and the dead Wyvern
AP: Havel's Greatshield - belfry roof, NPC dropDropped from any of the Havel Knights
AP: Havel's Ring+1 - summit, after buildingJust past the building with all of the Man-Serpents on the way to the Dragon Altar, on the left side
AP: Homeward Bone - intro, path to bonfireFrom the start of the area, along the left path leading to the first bonfire
AP: Large Soul of a Crestfallen Knight - summit, by fountainIn the middle of the open fountain area after the Belfry bonfire
AP: Large Soul of a Nameless Soldier - fort, by stairs to first roomto the left of where the Ancient Wyvern lands
AP: Large Soul of a Weary Warrior - fort, centerWhere the Ancient Wyvern lands
AP: Lightning Bolt - rotundaOn top of the ruined dome found going up spiral stairs to the left before the bridge with the chainaxe Man-Serpent
AP: Lightning Clutch Ring - intro, left of boss doorTo the left of gate leading to Ancient Wyvern, past the Rock Lizard
AP: Lightning Gem - intro, side riseFrom the start of the area, up a ledge in between two forked paths toward the first bonfire
AP: Lightning Urn - fort, left of first room entranceOn the path to the left of where the Ancient Wyvern lands, left of the building entrance
AP: Ricard's Rapier - belfry, NPC dropDropped by the Richard Champion summoned by the Serpent-Man Summoner
AP: Ring of Steel Protection - fort overlook, beside stairsTo the right of the area where the Ancient Wyvern lands, dropping down onto the ledge
AP: Soul of a Crestfallen Knight - mausoleum, upstairsFrom the Mausoleum bonfire, up the second set of stairs to the right
AP: Soul of a Nameless Soldier - intro, right before archwayFrom the Archdragon Peak bonfire, going right before the arch before Ancient Wyvern
AP: Soul of a Weary Warrior - intro, first cliff edgeAt the very start of the area on the left cliff edge
AP: Soul of a Weary Warrior - walkway, building windowOn the way to the Belfry bonfire after the sagging wooden bridge, on a ledge visible in a room with a Crystal Lizard, accessible by a tricky jump or just going around the other side
AP: Soul of the Nameless KingDropped by Nameless King
AP: Stalk Dung Pie (fort overlook)From the right of where Ancient Wyvern first lands
AP: Thunder Stoneplate Ring (walkway, up ladder)After the long hallway after the Mausoleum bonfire, before the rope bridge, up the long ladder
AP: Titanite Chunk (fort, second room balcony)After going left of where Ancient Wyvern lands and left again, rather than going up the stairs to the right, go to the open area to the left
AP: Titanite Chunk (intro, archway corner)From the Archdragon Peak bonfire, under the arch, immediately to the right
AP: Titanite Chunk (intro, behind rock)Almost at the Archdragon Peak bonfire, behind a rock in the area with many Man-Serpents
AP: Titanite Chunk (intro, left before archway)After the Archdragon Peak bonfire, going left before the arch before Ancient Wyvern
AP: Titanite Chunk (rotunda)On top of the ruined dome found going up spiral stairs to the left before the bridge with the chainaxe Man-Serpent
AP: Titanite Chunk (walkway, miniboss drop)Dropped by the second Ancient Wyvern patrolling the path up to the Belfry
AP: Titanite Scale (mausoleum, downstairs balcony #1)From the Mausoleum bonfire, up the stairs to the left, past the Rock Lizard
AP: Titanite Scale (mausoleum, downstairs balcony #2)From the Mausoleum bonfire, up the stairs to the left, past the Rock Lizard
AP: Titanite Scale (mausoleum, upstairs balcony)From the Mausoleum bonfire, up the first stairs to the right, going around toward the Man-Serpent Summoner, on the balcony on the side
AP: Titanite Scale (walkway building)In a chest after the sagging wooden bridge on the way to the Belfry, in the building with the Crystal Lizard
AP: Titanite Scale (walkway, miniboss drop)Dropped by the second Ancient Wyvern patrolling the path up to the Belfry
AP: Titanite Slab (belfry roof)Next to the Havel Knight by the dead Wyvern
AP: Titanite Slab (plaza)In the Nameless King boss arena after he is defeated
AP: Twinkling Dragon Torso Stone (summit, gesture at altar)Received using Path of the Dragon at the Altar after the Belfry bonfire. Hawkwood also uses the gesture there when summoned.
AP: Twinkling Titanite (belfry, by ladder to roof)In the chest before the ladder climbing up to the Havel Knight
AP: Twinkling Titanite (fort, down second room balcony ladder)After going left of where Ancient Wyvern lands and left again, rather than going up the stairs to the right, go to the open area to the left and then down the ladder
AP: Twinkling Titanite (fort, end of rafters)Dropping down to the left of the Mausoleum bonfire, all the way down the wooden rafters
AP: Twinkling Titanite (walkway building, lizard)Dropped by Crystal Lizard in the building after the sagging wooden bridge toward the Belfry
AP: Twinkling Titanite (walkway, miniboss drop)Dropped by the second Ancient Wyvern patrolling the path up to the Belfry
CA: Coiled Sword (boss drop)Dropped by Iudex Gundyr
CA: Firebomb (down the cliff edge)Along the cliff edge before the Iudex Gundyr fight, to the right
CA: Soul of a Deserted Corpse (right of spawn)At the very start of the game
CA: Soul of an Unknown Traveler (by miniboss)In the area with the Ravenous Crystal Lizard
CA: Speckled Stoneplate Ring+1 (by miniboss)In the area with the Ravenous Crystal Lizard, along the right wall
CA: Titanite Scale (miniboss drop)Dropped by Ravenous Crystal Lizard
CA: Titanite Shard (jump to coffin)Making a jump to a coffin after the Cemetery of Ash bonfire
CC: Black Blade (tomb, mimic)Dropped by the mimic before Smouldering Lake
CC: Black Bug Pellet (cavern, before bridge)In the area where many many skeletons are before the bridge you can cut
CC: Bloodred Moss Clump (atrium lower, down more stairs)To the left before going down the main stairwell in the Catacombs, past the skeleton ambush and where Anri is standing, near the Crystal Lizard
CC: Carthus Bloodring (crypt lower, end of side hall)At the very end of the Bonewheel Skeleton area
CC: Carthus Milkring (crypt upper, among pots)After the first Skeleton Ball, in the hallway alcove with the many dark-exploding pots
CC: Carthus Pyromancy Tome (atrium lower, jump from bridge)Down the hallway to the right before going down the main stairwell in the Catacombs and through an illusory wall on the left, or making a difficult dropdown from the top-level platform
CC: Carthus Rouge (atrium upper, left after entrance)To the right after first entering the Catacombs
CC: Carthus Rouge (crypt across, corner)Making a difficult jump between the hallway after the first Skeleton Ball and the area at the same level on the opposite side, or going up the stairs from the main hall
CC: Dark Gem (crypt lower, skeleton ball drop)Dropped by second Skeleton Ball after killing its sorcerer skeleton
CC: Ember (atrium, on long stairway)On the main stairwell in Catacombs
CC: Ember (crypt lower, shortcut to cavern)In the short hallway with the level shortcut where Knight Slayer Tsorig invades
CC: Ember (crypt upper, end of hall past hole)Going right from the Catacombs bonfire, down the hall to the left, then to the right. After a hole that drops down into the Bonewheel Skeleton area.
CC: Fire Gem (cavern, lizard)Dropped by a Crystal Lizard found between the Catacombs main halls and the ledge overlooking the bridge you can cut down
CC: Grave Warden Pyromancy Tome (boss arena)In Wolnir's arena, or in the back left of the room containing his bonfire if not picked up in the arena
CC: Grave Warden's Ashes (crypt across, corner)From the Catacombs bonfire, down the stairs into the main hall and up the stairs to the other side, on the far left side. Stairwell past the illusory wall is most direct.
CC: Homeward Bone (bridge)Found right before the wall blocking access to Irithyll
CC: Large Soul of a Nameless Soldier (cavern, before bridge)In the area where many many skeletons are before the bridge you can cut
CC: Large Soul of a Nameless Soldier (tomb lower)Down the ramp from the Fire Demon, where all the skeletons are
CC: Large Soul of an Unknown Traveler (crypt upper, hall middle)Going right from the Catacombs bonfire, then down the long hallway after the hallway to the left
CC: Large Titanite Shard (crypt across, middle hall)From the Catacombs bonfire, down the stairs into the main hall and up the stairs to the other side, in a middle hallway
CC: Large Titanite Shard (crypt upper, skeleton ball hall)Going right from the Catacombs bonfire, to the end of the hallway where second Skeleton Ball rolls
CC: Large Titanite Shard (tomb lower)Down the ramp from the Fire Demon, where all the skeletons are
CC: Old Sage's Blindfold (tomb, hall before bonfire)Down the ramp from the Fire Demon, straight down the hallway past the room with the Abandoned Tomb bonfire
CC: Pontiff's Right Eye (bridge, miniboss drop)Dropped by killing Sulyvahn's Beast on the bridge to Irithyll or in the lake below
CC: Ring of Steel Protection+2 (atrium upper, drop onto pillar)From the first bridge in Catacombs where the first skeletons are encountered, parallel to the long stairwell, walk off onto a pillar on the left side.
CC: Sharp Gem (atrium lower, right before exit)Down the hallway to the right before going down the main stairwell in the Catacombs
AP: Stalk Dung Pie - fort overlookFrom the right of where Ancient Wyvern first lands
AP: Thunder Stoneplate Ring - walkway, up ladderAfter the long hallway after the Mausoleum bonfire, before the rope bridge, up the long ladder
AP: Titanite Chunk - fort, second room balconyAfter going left of where Ancient Wyvern lands and left again, rather than going up the stairs to the right, go to the open area to the left
AP: Titanite Chunk - intro, archway cornerFrom the Archdragon Peak bonfire, under the arch, immediately to the right
AP: Titanite Chunk - intro, behind rockAlmost at the Archdragon Peak bonfire, behind a rock in the area with many Man-Serpents
AP: Titanite Chunk - intro, left before archwayAfter the Archdragon Peak bonfire, going left before the arch before Ancient Wyvern
AP: Titanite Chunk - rotundaOn top of the ruined dome found going up spiral stairs to the left before the bridge with the chainaxe Man-Serpent
AP: Titanite Chunk - walkway, miniboss dropDropped by the second Ancient Wyvern patrolling the path up to the Belfry
AP: Titanite Scale - mausoleum, downstairs balcony #1From the Mausoleum bonfire, up the stairs to the left, past the Rock Lizard
AP: Titanite Scale - mausoleum, downstairs balcony #2From the Mausoleum bonfire, up the stairs to the left, past the Rock Lizard
AP: Titanite Scale - mausoleum, upstairs balconyFrom the Mausoleum bonfire, up the first stairs to the right, going around toward the Man-Serpent Summoner, on the balcony on the side
AP: Titanite Scale - walkway buildingIn a chest after the sagging wooden bridge on the way to the Belfry, in the building with the Crystal Lizard
AP: Titanite Scale - walkway, miniboss dropDropped by the second Ancient Wyvern patrolling the path up to the Belfry
AP: Titanite Slab - belfry roofNext to the Havel Knight by the dead Wyvern
AP: Titanite Slab - plazaIn the Nameless King boss arena after he is defeated
AP: Twinkling Dragon Torso Stone - summit, gesture at altarReceived using Path of the Dragon at the Altar after the Belfry bonfire. Hawkwood also uses the gesture there when summoned.
AP: Twinkling Titanite - belfry, by ladder to roofIn the chest before the ladder climbing up to the Havel Knight
AP: Twinkling Titanite - fort, down second room balcony ladderAfter going left of where Ancient Wyvern lands and left again, rather than going up the stairs to the right, go to the open area to the left and then down the ladder
AP: Twinkling Titanite - fort, end of raftersDropping down to the left of the Mausoleum bonfire, all the way down the wooden rafters
AP: Twinkling Titanite - walkway building, lizardDropped by Crystal Lizard in the building after the sagging wooden bridge toward the Belfry
AP: Twinkling Titanite - walkway, miniboss dropDropped by the second Ancient Wyvern patrolling the path up to the Belfry
CA: Coiled Sword - boss dropDropped by Iudex Gundyr
CA: Firebomb - down the cliff edgeAlong the cliff edge before the Iudex Gundyr fight, to the right
CA: Soul of a Deserted Corpse - right of spawnAt the very start of the game
CA: Soul of an Unknown Traveler - by minibossIn the area with the Ravenous Crystal Lizard
CA: Speckled Stoneplate Ring+1 - by minibossIn the area with the Ravenous Crystal Lizard, along the right wall
CA: Titanite Scale - miniboss dropDropped by Ravenous Crystal Lizard
CA: Titanite Shard - jump to coffinMaking a jump to a coffin after the Cemetery of Ash bonfire
CC: Black Blade - tomb, mimicDropped by the mimic before Smouldering Lake
CC: Black Bug Pellet - cavern, before bridgeIn the area where many many skeletons are before the bridge you can cut
CC: Bloodred Moss Clump - atrium lower, down more stairsTo the left before going down the main stairwell in the Catacombs, past the skeleton ambush and where Anri is standing, near the Crystal Lizard
CC: Carthus Bloodring - crypt lower, end of side hallAt the very end of the Bonewheel Skeleton area
CC: Carthus Milkring - crypt upper, among potsAfter the first Skeleton Ball, in the hallway alcove with the many dark-exploding pots
CC: Carthus Pyromancy Tome - atrium lower, jump from bridgeDown the hallway to the right before going down the main stairwell in the Catacombs and through an illusory wall on the left, or making a difficult dropdown from the top-level platform
CC: Carthus Rouge - atrium upper, left after entranceTo the right after first entering the Catacombs
CC: Carthus Rouge - crypt across, cornerMaking a difficult jump between the hallway after the first Skeleton Ball and the area at the same level on the opposite side, or going up the stairs from the main hall
CC: Dark Gem - crypt lower, skeleton ball dropDropped by second Skeleton Ball after killing its sorcerer skeleton
CC: Ember - atrium, on long stairwayOn the main stairwell in Catacombs
CC: Ember - crypt lower, shortcut to cavernIn the short hallway with the level shortcut where Knight Slayer Tsorig invades
CC: Ember - crypt upper, end of hall past holeGoing right from the Catacombs bonfire, down the hall to the left, then to the right. After a hole that drops down into the Bonewheel Skeleton area.
CC: Fire Gem - cavern, lizardDropped by a Crystal Lizard found between the Catacombs main halls and the ledge overlooking the bridge you can cut down
CC: Grave Warden Pyromancy Tome - boss arenaIn Wolnir's arena, or in the back left of the room containing his bonfire if not picked up in the arena
CC: Grave Warden's Ashes - crypt across, cornerFrom the Catacombs bonfire, down the stairs into the main hall and up the stairs to the other side, on the far left side. Stairwell past the illusory wall is most direct.
CC: Homeward Bone - bridgeFound right before the wall blocking access to Irithyll
CC: Large Soul of a Nameless Soldier - cavern, before bridgeIn the area where many many skeletons are before the bridge you can cut
CC: Large Soul of a Nameless Soldier - tomb lowerDown the ramp from the Fire Demon, where all the skeletons are
CC: Large Soul of an Unknown Traveler - crypt upper, hall middleGoing right from the Catacombs bonfire, then down the long hallway after the hallway to the left
CC: Large Titanite Shard - crypt across, middle hallFrom the Catacombs bonfire, down the stairs into the main hall and up the stairs to the other side, in a middle hallway
CC: Large Titanite Shard - crypt upper, skeleton ball hallGoing right from the Catacombs bonfire, to the end of the hallway where second Skeleton Ball rolls
CC: Large Titanite Shard - tomb lowerDown the ramp from the Fire Demon, where all the skeletons are
CC: Old Sage's Blindfold - tomb, hall before bonfireDown the ramp from the Fire Demon, straight down the hallway past the room with the Abandoned Tomb bonfire
CC: Pontiff's Right Eye - bridge, miniboss dropDropped by killing Sulyvahn's Beast on the bridge to Irithyll or in the lake below
CC: Ring of Steel Protection+2 - atrium upper, drop onto pillarFrom the first bridge in Catacombs where the first skeletons are encountered, parallel to the long stairwell, walk off onto a pillar on the left side.
CC: Sharp Gem - atrium lower, right before exitDown the hallway to the right before going down the main stairwell in the Catacombs
CC: Soul of High Lord WolnirDropped by High Lord Wolnir
CC: Soul of a Demon (tomb, miniboss drop)Dropped by the Fire Demon before Smouldering Lake
CC: Soul of a Nameless Soldier (atrium lower, down hall)All the way down the hallway to the right before going down the main stairwell in the Catacombs
CC: Soul of a Nameless Soldier (atrium upper, up more stairs)From the room before the Catacombs main stairwell, up the two ramps and to the end of the long hallway crossing the room
CC: Thunder Stoneplate Ring+1 (crypt upper, among pots)After the first Skeleton Ball, in the hallway alcove with the many dark-exploding pots, behind one of the pillars
CC: Titanite Shard (atrium lower, corner by stairs)To the left before going down the main stairwell in the Catacombs, behind the pensive Carthus Cursed Sword Skeleton
CC: Titanite Shard (crypt lower, left of entrance)In the main hall after the Catacombs bonfire, down the stairs and to the left
CC: Titanite Shard (crypt lower, start of side hall)In the Bonewheel Skeleton area, on the left side under a Writhing Flesh
CC: Twinkling Titanite (atrium lower, lizard down more stairs)Dropped by a Crystal Lizard found to the left before going down the main stairwell in the Catacombs, past the skeleton ambush and past where Anri is standing
CC: Undead Bone Shard (crypt upper, skeleton ball drop)Dropped by first Skeleton Ball after killing its sorcerer skeleton
CC: Witch's Ring (tomb, hall before bonfire)Down the ramp from the Fire Demon, straight down the hallway past the room with the Abandoned Tomb bonfire
CC: Yellow Bug Pellet (cavern, on overlook)To the right of the Carthus Curved Sword Skeleton overlooking the pit Horace falls into
CD: Aldrich's Sapphire (side chapel, miniboss drop)Dropped by the Deep Accursed
CD: Arbalest (upper roofs, end of furthest buttress)Before the rafters on the way to Rosaria, up a flying buttress, past a halberd-wielding Large Hollow Soldier to the right, and down another flying buttress to the right
CD: Archdeacon Holy Garb (boss room after killing boss)Near the Deacons of the Deep bonfire, found after resting at it
CD: Archdeacon Skirt (boss room after killing boss)Near the Deacons of the Deep bonfire, found after resting at it
CD: Archdeacon White Crown (boss room after killing boss)Near the Deacons of the Deep bonfire, found after resting at it
CD: Armor of Thorns (Rosaria's Bed Chamber after killing Kirk)Found in Rosaria's Bed Chamber after killing Longfinger Kirk
CD: Astora Greatsword (graveyard, left of entrance)Down one of the side paths to the left in the Reanimated Corpse area
CD: Barbed Straight Sword (Kirk drop)Dropped by Longfinger Kirk when he invades in the cathedral central room
CD: Black Eye Orb (Rosaria from Leonhard's quest)On Rosaria's corpse after joining Rosaria's Fingers, exhausing Leonhard's dialogue there and reaching the Profaned Capital bonfire.
CD: Blessed Gem (upper roofs, rafters)In the rafters leading to Rosaria, guarded by a Cathedral Knight to the right
CD: Crest Shield (path, drop down by Cathedral of the Deep bonfire)On a grave near the Cathedral of the Deep bonfire, accessed by dropping down to the right
CD: Curse Ward Greatshield (by ladder from white tree to moat)Taking a right after the Infested Corpse graveyard, before the shortcut ladder down to the Ravenous Crystal Lizard area
CD: Deep Braille Divine Tome (mimic by side chapel)Dropped by the Mimic before the room with the patrolling Cathedral Knight and Deep Accursed
CD: Deep Gem (down stairs by first elevator)Coming from the room where you first see deacons, go down instead of continuing to the main cathedral room. Guarded by a pensive Cathedral Evangelist.
CD: Deep Ring (upper roofs, passive mob drop in first tower)Dropped by the passive Deacon on the way to Rosaria
CD: Drang Armor (main hall, east)In the Giant Slave muck pit leading up to Deacons
CD: Drang Gauntlets (main hall east)In the Giant Slave muck pit leading up to Deacons
CD: Drang Hammers (main hall east)In the Giant Slave muck pit leading up to Deacons, underneath the stairwell
CD: Drang Shoes (main hall east)In the Giant Slave muck pit leading up to Deacons
CD: Duel Charm (by first elevator)After opening the cathedral's backdoor, where the Deacon enemies are first seen, under a fountain that spouts poison
CD: Duel Charm (next to Patches in onion armor)To the right of the bridge leading to Rosaria, from the Deacons side. Patches will lower the bridge if you try to cross from this side.
CD: Ember (Patches)Sold by Patches in Firelink Shrine
CD: Ember (by back door)Past the pair of Grave Wardens and the Cathedral backdoor against a wall, guarded by a greataxe-wielding Large Hollow Soldier
CD: Ember (edge of platform before boss)On the edge of the chapel before Deacons overlooking the Giant Slaves
CD: Ember (side chapel upstairs, up ladder)Up a ladder and past the Cathedral Evangelist from the top level of the room with the patrolling Cathedral Knight and Deep Accursed
CD: Ember (side chapel, miniboss room)In the room with the Deep Accursed
CD: Estus Shard (monument outside Cleansing Chapel)Right outside of the Cleansing Chapel. Requires killing praying hollows.
CD: Executioner's Greatsword (graveyard, far end)In an open area down one of the side paths to the left in the Reanimated Corpse area
CD: Exploding Bolt (ledge above main hall south)On the ledge where the Giant Slave slams his arms down
CD: Fading Soul (graveyard, far end)In an open area down one of the side paths to the left in the Reanimated Corpse area, next to the Executioner's Greatsword
CD: Gauntlets of Thorns (Rosaria's Bed Chamber after killing Kirk)Found in Rosaria's Bed Chamber after killing Longfinger Kirk
CD: Helm of Thorns (Rosaria's Bed Chamber after killing Kirk)Found in Rosaria's Bed Chamber after killing Longfinger Kirk
CD: Herald Armor (path, by fire)Guarded by the Cathedral Evangelist after the Crystal Sage fight
CD: Herald Gloves (path, by fire)Guarded by the Cathedral Evangelist after the Crystal Sage fight
CD: Herald Helm (path, by fire)Guarded by the Cathedral Evangelist after the Crystal Sage fight
CD: Herald Trousers (path, by fire)Guarded by the Cathedral Evangelist after the Crystal Sage fight
CD: Heysel Pick (Heysel Corpse-Grub in Rosaria's Bed Chamber)Dropped by the Heysel Corpse-grub in Rosaria's Bed Chamber
CD: Hidden Blessing (Patches)Sold by Patches after Greirat pillages Lothric Castle, telling Patches, and Patches returning
CD: Homeward Bone (outside main hall south door)Past the cathedral doors guarded by the Giant Slave opposite to the Deacons fight
CD: Horsehoof Ring (Patches)Sold or dropped by Patches after he mentions Greirat
CD: Large Soul of an Unknown Traveler (by white tree #1)In the graveyard with the White Birch and Infested Corpses
CD: Large Soul of an Unknown Traveler (by white tree #2)In the graveyard with the White Birch and Infested Corpses
CD: Large Soul of an Unknown Traveler (lower roofs, semicircle balcony)On the cathedral roof after climbing up the flying buttresses, on the edge of the semicircle platform balcony
CD: Large Soul of an Unknown Traveler (main hall east)In the Giant Slave muck pit leading up to Deacons
CD: Large Soul of an Unknown Traveler (main hall south, side path)Down a side path with poison-spouting fountains in the main cathedral room, accessible from the Cleansing Chapel shortcut, patrolled by a Cathedral Knight
CD: Large Soul of an Unknown Traveler (path, against outer wall)From the Cathedral of the Deep bonfire after the Brigand, against the wall in the area with the dogs and crossbowmen
CD: Leggings of Thorns (Rosaria's Bed Chamber after killing Kirk)Found in Rosaria's Bed Chamber after killing Longfinger Kirk
CD: Lloyd's Sword Ring (ledge above main hall south)On the ledge where the Giant Slave slams his arms down
CD: Maiden Gloves (main hall south)In the muck pit with the Giant Slave that can attack with his arms
CD: Maiden Hood (main hall south)In the muck pit with the Giant Slave that can attack with his arms
CD: Maiden Robe (main hall south)In the muck pit with the Giant Slave that can attack with his arms
CD: Maiden Skirt (main hall south)In the muck pit with the Giant Slave that can attack with his arms
CD: Notched Whip (Cleansing Chapel)In a corner of the Cleansing Chapel
CD: Paladin's Ashes (path, guarded by lower NPC)At the very start of the area, guarded by the Fallen Knight
CD: Pale Tongue (main hall east)In the Giant Slave muck pit leading up to Deacons
CD: Pale Tongue (upper roofs, outdoors far end)Before the rafters on the way to Rosaria, up a flying buttress and straight right, passing a halberd-wielding Large Hollow Soldier
CD: Poisonbite Ring (moat, hall past miniboss)In the pit with the Infested Corpse, accessible from the Ravenous Crystal Lizard area or from dropping down near the second Cleansing Chapel shortcut
CD: Red Bug Pellet (lower roofs, up stairs between buttresses)In the area after the cathedral roof against the wall of the cathedral, down the path from the Cathedral Evangelist.
CD: Red Bug Pellet (right of cathedral front doors)Up the stairs past the Infested Corpse graveyard and the left, toward the roof path to the right of the cathedral doors
CD: Red Sign Soapstone (passive mob drop by Rosaria's Bed Chamber)Dropped by passive Corpse-grub against the wall near the entrance to Rosaria's Bed Chamber
CD: Repair Powder (by white tree)In the graveyard with the White Birch and Infested Corpses
CD: Ring of Favor+2 (upper roofs, on buttress)Before the rafters on the way to Rosaria, up a flying buttress, behind a greataxe-wielding Large Hollow Soldier to the left
CD: Ring of the Evil Eye+1 (by stairs to boss)Before the stairs leading down into the Deacons fight
CD: Rosaria's Fingers (Rosaria)Given by Rosaria.
CD: Rusted Coin (don't forgive Patches)Given by Patches after not forgiving him after he lowers the bridge in Cathedral of the Deep.
CD: Rusted Coin (left of cathedral front doors, behind crates)Up the stairs past the Infested Corpse graveyard and to the left, hidden behind some crates to the left of the cathedral door
CD: Saint Bident (outside main hall south door)Past the cathedral doors guarded by the Giant Slave opposite to the Deacons fight
CD: Saint-tree Bellvine (moat, by water)In the Infested Corpse moat beneath the Cathedral
CD: Seek Guidance (side chapel upstairs)Above the room with the patrolling Cathedral Knight and Deep Accursed, below a writhing flesh on the ceiling.
CD: Shotel (Patches)Sold by Patches
CD: Small Doll (boss drop)Dropped by Deacons of the Deep
CD: Soul of a Nameless Soldier (ledge above main hall south)On the ledge where the Giant Slave slams his arms down
CD: Soul of a Nameless Soldier (lower roofs, side room)Coming from the cathedral roof, past the three crossbowmen to the path patrolled by the halberd-wielding Large Hollow Soldier, in a room to the left with many thralls.
CD: Soul of a Nameless Soldier (main hall south)In the muck pit with the Giant Slave that can attack with his arms
CC: Soul of a Demon - tomb, miniboss dropDropped by the Fire Demon before Smouldering Lake
CC: Soul of a Nameless Soldier - atrium lower, down hallAll the way down the hallway to the right before going down the main stairwell in the Catacombs
CC: Soul of a Nameless Soldier - atrium upper, up more stairsFrom the room before the Catacombs main stairwell, up the two ramps and to the end of the long hallway crossing the room
CC: Thunder Stoneplate Ring+1 - crypt upper, among potsAfter the first Skeleton Ball, in the hallway alcove with the many dark-exploding pots, behind one of the pillars
CC: Titanite Shard - atrium lower, corner by stairsTo the left before going down the main stairwell in the Catacombs, behind the pensive Carthus Cursed Sword Skeleton
CC: Titanite Shard - crypt lower, left of entranceIn the main hall after the Catacombs bonfire, down the stairs and to the left
CC: Titanite Shard - crypt lower, start of side hallIn the Bonewheel Skeleton area, on the left side under a Writhing Flesh
CC: Twinkling Titanite - atrium lower, lizard down more stairsDropped by a Crystal Lizard found to the left before going down the main stairwell in the Catacombs, past the skeleton ambush and past where Anri is standing
CC: Undead Bone Shard - crypt upper, skeleton ball dropDropped by first Skeleton Ball after killing its sorcerer skeleton
CC: Witch's Ring - tomb, hall before bonfireDown the ramp from the Fire Demon, straight down the hallway past the room with the Abandoned Tomb bonfire
CC: Yellow Bug Pellet - cavern, on overlookTo the right of the Carthus Curved Sword Skeleton overlooking the pit Horace falls into
CD: Aldrich's Sapphire - side chapel, miniboss dropDropped by the Deep Accursed
CD: Arbalest - upper roofs, end of furthest buttressBefore the rafters on the way to Rosaria, up a flying buttress, past a halberd-wielding Large Hollow Soldier to the right, and down another flying buttress to the right
CD: Archdeacon Holy Garb - boss room after killing bossNear the Deacons of the Deep bonfire, found after resting at it
CD: Archdeacon Skirt - boss room after killing bossNear the Deacons of the Deep bonfire, found after resting at it
CD: Archdeacon White Crown - boss room after killing bossNear the Deacons of the Deep bonfire, found after resting at it
CD: Armor of Thorns - Rosaria's Bed Chamber after killing KirkFound in Rosaria's Bed Chamber after killing Longfinger Kirk
CD: Astora Greatsword - graveyard, left of entranceDown one of the side paths to the left in the Reanimated Corpse area
CD: Barbed Straight Sword - Kirk dropDropped by Longfinger Kirk when he invades in the cathedral central room
CD: Black Eye Orb - Rosaria from Leonhard's questOn Rosaria's corpse after joining Rosaria's Fingers, exhausing Leonhard's dialogue there and reaching the Profaned Capital bonfire.
CD: Blessed Gem - upper roofs, raftersIn the rafters leading to Rosaria, guarded by a Cathedral Knight to the right
CD: Crest Shield - path, drop down by Cathedral of the Deep bonfireOn a grave near the Cathedral of the Deep bonfire, accessed by dropping down to the right
CD: Curse Ward Greatshield - by ladder from white tree to moatTaking a right after the Infested Corpse graveyard, before the shortcut ladder down to the Ravenous Crystal Lizard area
CD: Deep Braille Divine Tome - mimic by side chapelDropped by the Mimic before the room with the patrolling Cathedral Knight and Deep Accursed
CD: Deep Gem - down stairs by first elevatorComing from the room where you first see deacons, go down instead of continuing to the main cathedral room. Guarded by a pensive Cathedral Evangelist.
CD: Deep Ring - upper roofs, passive mob drop in first towerDropped by the passive Deacon on the way to Rosaria
CD: Drang Armor - main hall, eastIn the Giant Slave muck pit leading up to Deacons
CD: Drang Gauntlets - main hall eastIn the Giant Slave muck pit leading up to Deacons
CD: Drang Hammers - main hall eastIn the Giant Slave muck pit leading up to Deacons, underneath the stairwell
CD: Drang Shoes - main hall eastIn the Giant Slave muck pit leading up to Deacons
CD: Duel Charm - by first elevatorAfter opening the cathedral's backdoor, where the Deacon enemies are first seen, under a fountain that spouts poison
CD: Duel Charm - next to Patches in onion armorTo the right of the bridge leading to Rosaria, from the Deacons side. Patches will lower the bridge if you try to cross from this side.
CD: Ember - PatchesSold by Patches in Firelink Shrine
CD: Ember - by back doorPast the pair of Grave Wardens and the Cathedral backdoor against a wall, guarded by a greataxe-wielding Large Hollow Soldier
CD: Ember - edge of platform before bossOn the edge of the chapel before Deacons overlooking the Giant Slaves
CD: Ember - side chapel upstairs, up ladderUp a ladder and past the Cathedral Evangelist from the top level of the room with the patrolling Cathedral Knight and Deep Accursed
CD: Ember - side chapel, miniboss roomIn the room with the Deep Accursed
CD: Estus Shard - monument outside Cleansing ChapelRight outside of the Cleansing Chapel. Requires killing praying hollows.
CD: Executioner's Greatsword - graveyard, far endIn an open area down one of the side paths to the left in the Reanimated Corpse area
CD: Exploding Bolt - ledge above main hall southOn the ledge where the Giant Slave slams his arms down
CD: Fading Soul - graveyard, far endIn an open area down one of the side paths to the left in the Reanimated Corpse area, next to the Executioner's Greatsword
CD: Gauntlets of Thorns - Rosaria's Bed Chamber after killing KirkFound in Rosaria's Bed Chamber after killing Longfinger Kirk
CD: Helm of Thorns - Rosaria's Bed Chamber after killing KirkFound in Rosaria's Bed Chamber after killing Longfinger Kirk
CD: Herald Armor - path, by fireGuarded by the Cathedral Evangelist after the Crystal Sage fight
CD: Herald Gloves - path, by fireGuarded by the Cathedral Evangelist after the Crystal Sage fight
CD: Herald Helm - path, by fireGuarded by the Cathedral Evangelist after the Crystal Sage fight
CD: Herald Trousers - path, by fireGuarded by the Cathedral Evangelist after the Crystal Sage fight
CD: Heysel Pick - Heysel Corpse-Grub in Rosaria's Bed ChamberDropped by the Heysel Corpse-grub in Rosaria's Bed Chamber
CD: Hidden Blessing - PatchesSold by Patches after Greirat pillages Lothric Castle, telling Patches, and Patches returning
CD: Homeward Bone - outside main hall south doorPast the cathedral doors guarded by the Giant Slave opposite to the Deacons fight
CD: Horsehoof Ring - PatchesSold or dropped by Patches after he mentions Greirat
CD: Large Soul of an Unknown Traveler - by white tree #1In the graveyard with the White Birch and Infested Corpses
CD: Large Soul of an Unknown Traveler - by white tree #2In the graveyard with the White Birch and Infested Corpses
CD: Large Soul of an Unknown Traveler - lower roofs, semicircle balconyOn the cathedral roof after climbing up the flying buttresses, on the edge of the semicircle platform balcony
CD: Large Soul of an Unknown Traveler - main hall eastIn the Giant Slave muck pit leading up to Deacons
CD: Large Soul of an Unknown Traveler - main hall south, side pathDown a side path with poison-spouting fountains in the main cathedral room, accessible from the Cleansing Chapel shortcut, patrolled by a Cathedral Knight
CD: Large Soul of an Unknown Traveler - path, against outer wallFrom the Cathedral of the Deep bonfire after the Brigand, against the wall in the area with the dogs and crossbowmen
CD: Leggings of Thorns - Rosaria's Bed Chamber after killing KirkFound in Rosaria's Bed Chamber after killing Longfinger Kirk
CD: Lloyd's Sword Ring - ledge above main hall southOn the ledge where the Giant Slave slams his arms down
CD: Maiden Gloves - main hall southIn the muck pit with the Giant Slave that can attack with his arms
CD: Maiden Hood - main hall southIn the muck pit with the Giant Slave that can attack with his arms
CD: Maiden Robe - main hall southIn the muck pit with the Giant Slave that can attack with his arms
CD: Maiden Skirt - main hall southIn the muck pit with the Giant Slave that can attack with his arms
CD: Notched Whip - Cleansing ChapelIn a corner of the Cleansing Chapel
CD: Paladin's Ashes - path, guarded by lower NPCAt the very start of the area, guarded by the Fallen Knight
CD: Pale Tongue - main hall eastIn the Giant Slave muck pit leading up to Deacons
CD: Pale Tongue - upper roofs, outdoors far endBefore the rafters on the way to Rosaria, up a flying buttress and straight right, passing a halberd-wielding Large Hollow Soldier
CD: Poisonbite Ring - moat, hall past minibossIn the pit with the Infested Corpse, accessible from the Ravenous Crystal Lizard area or from dropping down near the second Cleansing Chapel shortcut
CD: Red Bug Pellet - lower roofs, up stairs between buttressesIn the area after the cathedral roof against the wall of the cathedral, down the path from the Cathedral Evangelist.
CD: Red Bug Pellet - right of cathedral front doorsUp the stairs past the Infested Corpse graveyard and the left, toward the roof path to the right of the cathedral doors
CD: Red Sign Soapstone - passive mob drop by Rosaria's Bed ChamberDropped by passive Corpse-grub against the wall near the entrance to Rosaria's Bed Chamber
CD: Repair Powder - by white treeIn the graveyard with the White Birch and Infested Corpses
CD: Ring of Favor+2 - upper roofs, on buttressBefore the rafters on the way to Rosaria, up a flying buttress, behind a greataxe-wielding Large Hollow Soldier to the left
CD: Ring of the Evil Eye+1 - by stairs to bossBefore the stairs leading down into the Deacons fight
CD: Rosaria's Fingers - RosariaGiven by Rosaria.
CD: Rusted Coin - don't forgive PatchesGiven by Patches after not forgiving him after he lowers the bridge in Cathedral of the Deep.
CD: Rusted Coin - left of cathedral front doors, behind cratesUp the stairs past the Infested Corpse graveyard and to the left, hidden behind some crates to the left of the cathedral door
CD: Saint Bident - outside main hall south doorPast the cathedral doors guarded by the Giant Slave opposite to the Deacons fight
CD: Saint-tree Bellvine - moat, by waterIn the Infested Corpse moat beneath the Cathedral
CD: Seek Guidance - side chapel upstairsAbove the room with the patrolling Cathedral Knight and Deep Accursed, below a writhing flesh on the ceiling.
CD: Shotel - PatchesSold by Patches
CD: Small Doll - boss dropDropped by Deacons of the Deep
CD: Soul of a Nameless Soldier - ledge above main hall southOn the ledge where the Giant Slave slams his arms down
CD: Soul of a Nameless Soldier - lower roofs, side roomComing from the cathedral roof, past the three crossbowmen to the path patrolled by the halberd-wielding Large Hollow Soldier, in a room to the left with many thralls.
CD: Soul of a Nameless Soldier - main hall southIn the muck pit with the Giant Slave that can attack with his arms
CD: Soul of the Deacons of the DeepDropped by Deacons of the Deep
CD: Spider Shield (NPC drop on path)Dropped by the brigand at the start of Cathedral of the Deep
CD: Spiked Shield (Kirk drop)Dropped by Longfinger Kirk when he invades in the cathedral central room
CD: Titanite Scale (moat, miniboss drop)Dropped by the Ravenous Crystal Lizard outside of the Cathedral
CD: Titanite Shard (Cleansing Chapel windowsill, by miniboss)On the ledge dropping back down into Cleansing Chapel from the area with the Ravenous Crystal Lizard
CD: Titanite Shard (moat, far end)Behind the cathedral near the Infested Corpse moat, going from the Ravenous Crystal Lizard
CD: Titanite Shard (moat, up a slope)Up one of the slopes in the Ravenous Crystal Lizard area
CD: Titanite Shard (outside building by white tree)Past the Infested Corpse graveyard to the left, hidden along the left wall of the building with the shortcut ladder and Curse Ward Greatshield
CD: Titanite Shard (path, side path by Cathedral of the Deep bonfire)Up a path to the left after the Cathedral of the Deep bonfire, after the Fallen Knight and before the Brigand
CD: Twinkling Titanite (moat, lizard #1)Dropped by the Crystal Lizard behind the cathedral near the Infested Corpse moat, going from the Ravenous Crystal Lizard
CD: Twinkling Titanite (moat, lizard #2)Dropped by the Crystal Lizard under the cathedral near the Infested Corpse moat, going from the Ravenous Crystal Lizard
CD: Twinkling Titanite (path, lizard #1)Dropped by the first Crystal Lizard after the Crystal Sage fight
CD: Twinkling Titanite (path, lizard #2)Dropped by the second Crystal Lizard after the Crystal Sage fight
CD: Undead Bone Shard (gravestone by white tree)In the graveyard with the Infested Corpses, on a coffin partly hanging off of the ledge
CD: Undead Hunter Charm (lower roofs, up stairs between buttresses)In the area after the cathedral roof guarded by a Cathedral Evangelist. Can be jumped to from a flying buttress or by going around and back
CD: Winged Spear (kill Patches)Dropped by Patches when killed in his own armor.
CD: Xanthous Crown (Heysel Corpse-Grub in Rosaria's Bed Chamber)Dropped by the Heysel Corpse-grub in Rosaria's Bed Chamber
CD: Young White Branch (by white tree #1)By the White Birch tree in the Infested Corpse graveyard
CD: Young White Branch (by white tree #2)By the White Birch tree in the Infested Corpse graveyard
CKG: Black Firebomb (under rotunda)Under the platform in the middle of the garden, in the toxic pool
CKG: Claw (under rotunda)Under the platform in the middle of the garden, in the toxic pool
CKG: Dark Gem (under lone stairway)Following the left wall, behind the standalone set of stairs
CKG: Dragonscale Ring (shortcut, leave halfway down lift)From the middle level of the second elevator, toward the Oceiros boss fight
CKG: Drakeblood Armor (tomb, after killing AP mausoleum NPC)On the Drakeblood Knight after Oceiros fight, after defeating the Drakeblood Knight from the Serpent-Man Summoner
CKG: Drakeblood Gauntlets (tomb, after killing AP mausoleum NPC)On the Drakeblood Knight after Oceiros fight, after defeating the Drakeblood Knight from the Serpent-Man Summoner
CKG: Drakeblood Helm (tomb, after killing AP mausoleum NPC)On the Drakeblood Knight after Oceiros fight, after defeating the Drakeblood Knight from the Serpent-Man Summoner
CKG: Drakeblood Leggings (tomb, after killing AP mausoleum NPC)On the Drakeblood Knight after Oceiros fight, after defeating the Drakeblood Knight from the Serpent-Man Summoner
CKG: Estus Shard (balcony)From the middle level of the first Consumed King's Gardens elevator, out the balcony and to the right
CKG: Human Pine Resin (by lone stairway bottom)On the right side of the garden, following the wall past the entrance to the shortcut elevator building, in a toxic pool
CKG: Human Pine Resin (toxic pool, past rotunda)In between two platforms near the middle of the garden, by a tree in a toxic pool
CKG: Magic Stoneplate Ring (mob drop before boss)Dropped by the Cathedral Knight closest to the Oceiros fog gate
CKG: Ring of Sacrifice (under balcony)Along the right wall of the garden, next to the first elevator building
CKG: Sage Ring+2 (balcony, drop onto rubble, jump back)From the middle platform of the first elevator in the target, going out and dropping off to the left, and then running off onto the ruined arch behind.
CKG: Shadow Garb (under rotunda)Under the platform in the middle of the garden, in the toxic pool
CKG: Shadow Gauntlets (under rotunda)Under the platform in the middle of the garden, in the toxic pool
CKG: Shadow Leggings (under rotunda)Under the platform in the middle of the garden, in the toxic pool
CKG: Shadow Mask (under center platform)Under the platform in the middle of the garden, in the toxic pool
CD: Spider Shield - NPC drop on pathDropped by the brigand at the start of Cathedral of the Deep
CD: Spiked Shield - Kirk dropDropped by Longfinger Kirk when he invades in the cathedral central room
CD: Titanite Scale - moat, miniboss dropDropped by the Ravenous Crystal Lizard outside of the Cathedral
CD: Titanite Shard - Cleansing Chapel windowsill, by minibossOn the ledge dropping back down into Cleansing Chapel from the area with the Ravenous Crystal Lizard
CD: Titanite Shard - moat, far endBehind the cathedral near the Infested Corpse moat, going from the Ravenous Crystal Lizard
CD: Titanite Shard - moat, up a slopeUp one of the slopes in the Ravenous Crystal Lizard area
CD: Titanite Shard - outside building by white treePast the Infested Corpse graveyard to the left, hidden along the left wall of the building with the shortcut ladder and Curse Ward Greatshield
CD: Titanite Shard - path, side path by Cathedral of the Deep bonfireUp a path to the left after the Cathedral of the Deep bonfire, after the Fallen Knight and before the Brigand
CD: Twinkling Titanite - moat, lizard #1Dropped by the Crystal Lizard behind the cathedral near the Infested Corpse moat, going from the Ravenous Crystal Lizard
CD: Twinkling Titanite - moat, lizard #2Dropped by the Crystal Lizard under the cathedral near the Infested Corpse moat, going from the Ravenous Crystal Lizard
CD: Twinkling Titanite - path, lizard #1Dropped by the first Crystal Lizard after the Crystal Sage fight
CD: Twinkling Titanite - path, lizard #2Dropped by the second Crystal Lizard after the Crystal Sage fight
CD: Undead Bone Shard - gravestone by white treeIn the graveyard with the Infested Corpses, on a coffin partly hanging off of the ledge
CD: Undead Hunter Charm - lower roofs, up stairs between buttressesIn the area after the cathedral roof guarded by a Cathedral Evangelist. Can be jumped to from a flying buttress or by going around and back
CD: Winged Spear - kill PatchesDropped by Patches when killed in his own armor.
CD: Xanthous Crown - Heysel Corpse-Grub in Rosaria's Bed ChamberDropped by the Heysel Corpse-grub in Rosaria's Bed Chamber
CD: Young White Branch - by white tree #1By the White Birch tree in the Infested Corpse graveyard
CD: Young White Branch - by white tree #2By the White Birch tree in the Infested Corpse graveyard
CKG: Black Firebomb - under rotundaUnder the platform in the middle of the garden, in the toxic pool
CKG: Claw - under rotundaUnder the platform in the middle of the garden, in the toxic pool
CKG: Dark Gem - under lone stairwayFollowing the left wall, behind the standalone set of stairs
CKG: Dragonscale Ring - shortcut, leave halfway down liftFrom the middle level of the second elevator, toward the Oceiros boss fight
CKG: Drakeblood Armor - tomb, after killing AP mausoleum NPCOn the Drakeblood Knight after Oceiros fight, after defeating the Drakeblood Knight from the Serpent-Man Summoner
CKG: Drakeblood Gauntlets - tomb, after killing AP mausoleum NPCOn the Drakeblood Knight after Oceiros fight, after defeating the Drakeblood Knight from the Serpent-Man Summoner
CKG: Drakeblood Helm - tomb, after killing AP mausoleum NPCOn the Drakeblood Knight after Oceiros fight, after defeating the Drakeblood Knight from the Serpent-Man Summoner
CKG: Drakeblood Leggings - tomb, after killing AP mausoleum NPCOn the Drakeblood Knight after Oceiros fight, after defeating the Drakeblood Knight from the Serpent-Man Summoner
CKG: Estus Shard - balconyFrom the middle level of the first Consumed King's Gardens elevator, out the balcony and to the right
CKG: Human Pine Resin - by lone stairway bottomOn the right side of the garden, following the wall past the entrance to the shortcut elevator building, in a toxic pool
CKG: Human Pine Resin - toxic pool, past rotundaIn between two platforms near the middle of the garden, by a tree in a toxic pool
CKG: Magic Stoneplate Ring - mob drop before bossDropped by the Cathedral Knight closest to the Oceiros fog gate
CKG: Ring of Sacrifice - under balconyAlong the right wall of the garden, next to the first elevator building
CKG: Sage Ring+2 - balcony, drop onto rubble, jump backFrom the middle platform of the first elevator in the target, going out and dropping off to the left, and then running off onto the ruined arch behind.
CKG: Shadow Garb - under rotundaUnder the platform in the middle of the garden, in the toxic pool
CKG: Shadow Gauntlets - under rotundaUnder the platform in the middle of the garden, in the toxic pool
CKG: Shadow Leggings - under rotundaUnder the platform in the middle of the garden, in the toxic pool
CKG: Shadow Mask - under center platformUnder the platform in the middle of the garden, in the toxic pool
CKG: Soul of Consumed OceirosDropped by Consumed King Oceiros
CKG: Soul of a Weary Warrior (before first lift)On the path leading to the first elevator from Lothric Castle
CKG: Titanite Chunk (balcony, drop onto rubble)From the middle platform of the first elevator, dropping down to the left
CKG: Titanite Chunk (right of shortcut lift bottom)On the right side of the garden, following the wall past the entrance to the shortcut elevator building, all the way to the end
CKG: Titanite Chunk (shortcut)Right inside of the shortcut door leading to Oceiros from Lothric/Dancer bonfire
CKG: Titanite Chunk (up lone stairway)Following the left wall of the garden, in and up the standalone set of stairs
CKG: Titanite Scale (shortcut)In the room leading to the Oceiros shortcut elevator from Lothric/Dancer, in the first floor alcove.
CKG: Titanite Scale (tomb, chest #1)Chest after Oceiros fight
CKG: Titanite Scale (tomb, chest #2)Chest after Oceiros fight
CKG: Wood Grain Ring+1 (by first elevator bottom)Behind the first elevator going down into the garden, in the toxic pool
DH: Aquamarine Dagger (castle, up stairs)Up the second flight of stairs to the left of the starting area with the murkmen, before the long drop
DH: Black Firebomb (ruins, up windmill from bonfire)To the left of the Earthen Peak Ruins bonfire, past the ruined windmill, next to many Poisonhorn bugs.
DH: Covetous Silver Serpent Ring+3 (pantry upstairs, drop down)After exiting the building with the Lothric Knights where the front crumbles, to the last room of the building to the right, up stairs past an illusory wall to the left, then dropping down after exiting the building from the last room.
DH: Desert Pyromancer Garb (ruins, by shack near cliff)Behind a shack near the edge of the cliff of the area targeted by the second angel.
DH: Desert Pyromancer Gloves (swamp, far right)After dropping down in the poison swamp area, against the wall straight to the right.
DH: Desert Pyromancer Hood (swamp upper, tunnel end)At the end of the tunnel with Desert Pyromancy Zoey, to the right of the final branches.
DH: Desert Pyromancer Skirt (swamp right, by roots)In the poison swamp, against a tree guarded by a few Poisonhorn bugs in the front right.
DH: Divine Blessing (library, after drop)After the dropdown where an angel first targets you, behind you
DH: Divine Blessing (shop)Sold by Stone-humped Hag, or in her ashes
DH: Divine Blessing (swamp upper, building roof)On a rooftop of one of the buildings bordering the poison swamp. Can be reached by dropping down from the final tree branch and accessing the roof to the right.
DH: Ember (castle, behind spire)At the start of the area, behind a spire to the right of first drop down
DH: Ember (pantry, behind crates just before upstairs)After exiting the building with the Lothric Knights where the front crumbles, to the last room end of the building to the right, up stairs past an illusory wall to the left, in the second-to-last room of the sequence, behind some crates to the left.
DH: Ember (ruins, alcove before swamp)In an alcove providing cover from the second angel's projectiles, before dropping down in the poison swamp area.
DH: Ember (ruins, alcove on cliff)In the area with the pilgrim responsible for the second angel, below the Within Earthen Peak Ruins bonfire. Can be accessed by dropping down from a cliff edge, dropping down to the right of the bonfire.
DH: Ember (shop)Sold by Stone-humped Hag, or in her ashes
DH: Flame Fan (swamp upper, NPC drop)Dropped by Desert Pyromancer Zoey
DH: Giant Door Shield (ruins, path below far shack)Descending down a path from the edge of the cliff of the area targeted by the second angel, to the very end of the cliff.
DH: Great Soul Dregs (pantry upstairs)After exiting the building with the Lothric Knights where the front crumbles, to the last room of the building to the right, up stairs past an illusory wall to the left, then all the way to the end of the last room.
DH: Harald Curved Greatsword (swamp left, under root)In the back leftmost area of the poison swamp, underneath the tree branch leading up and out, guarded by a stationary Harald Legion Knight.
DH: Hidden Blessing (shop)Sold by Stone-humped Hag, or in her ashes
DH: Homeward Bone (end of path from church)Immediately before dropping into the area with the Earthen Peak Ruins bonfire, next to Gael's flag.
DH: Homeward Bone (swamp left, on root)All the way to the end of a short path in the back leftmost area of the poison swamp, where you can plunge attack the stationary Harald Legion Knight.
DH: Large Soul of a Weary Warrior (parapets, hall)After crossing the spire bridge that crashes into the building with the Lothric Knights, past Lapp's initial location, dropping down behind the murkman and dropping down again, in a corner to the left.
DH: Large Soul of a Weary Warrior (swamp center)In the middle of the poison swamp.
DH: Large Soul of a Weary Warrior (swamp, under overhang)In the cavern adjacent to the poison swamp, surrounded by a few Poisonhorn bugs.
DH: Lightning Urn (wall outside church)After the dropdown where an angel first targets you, against the wall on the left.
DH: Loincloth (swamp, left edge)In the leftmost edge of the poison swamp after dropping down, guarded by 6 Poisonhorn bugs.
DH: Lothric War Banner (parapets, end of hall)After crossing the spire bridge that crashes into the building with the Lothric Knights, past Lapp's initial location, dropping down behind the murkman and dropping down again, at the end of the hallway to the right.
DH: Murky Hand Scythe (library, behind bookshelves)After the first long drop into the building which looks like Grand Archives, to the left up the bookshelf stairs and behind the bookshelves
DH: Murky Longstaff (pantry, last room)After exiting the building with the Lothric Knights where the front crumbles, in the third furthest room in the building to the right.
DH: Prism Stone (swamp upper, tunnel start)Near the start of the tunnel with Desert Pyromancer Zoey.
DH: Projected Heal (parapets balcony)After crossing the spire bridge that crashes into the building with the Lothric Knights, past Lapp's initial location, dropping down behind the murkman, against a wall in the area with the Lothric War Banner Knight and many murkmen.
DH: Purple Moss Clump (swamp shack)In the ruined shack with Poisonhorn bugs straight ahead of the dropdown into the poison swamp area.
DH: Ring of Favor+3 (swamp right, up root)Up the long branch close to the dropdown into the poison swamp area, in front of the cavern.
DH: Ring of Steel Protection+3 (ledge before church)After the dropdown where an angel first targets you, on an exposed edge to the left. Difficult to get without killing the angel.
DH: Rusted Coin (behind fountain after church)After exiting the building with the Lothric Knights where the front crumbles, behind the fountain on the right side.
DH: Rusted Gold Coin (shop)Sold by Stone-humped Hag, or in her ashes
DH: Siegbräu (Lapp)Given by Lapp after collecting the Titanite Slab in Earthen Peak Ruins, or left after Demon Princes fight, or dropped upon death if not given.
DH: Small Envoy Banner (boss drop)Found in the small room after beating Demon Prince.
DH: Soul of a Crestfallen Knight (church, altar)In the building where the front crumbles, guarded by the two Lothric Knights at the front of the chapel.
DH: Soul of a Weary Warrior (castle overhang)The bait item at the start of the area which falls down with you into the ruined building below.
CKG: Soul of a Weary Warrior - before first liftOn the path leading to the first elevator from Lothric Castle
CKG: Titanite Chunk - balcony, drop onto rubbleFrom the middle platform of the first elevator, dropping down to the left
CKG: Titanite Chunk - right of shortcut lift bottomOn the right side of the garden, following the wall past the entrance to the shortcut elevator building, all the way to the end
CKG: Titanite Chunk - shortcutRight inside of the shortcut door leading to Oceiros from Lothric/Dancer bonfire
CKG: Titanite Chunk - up lone stairwayFollowing the left wall of the garden, in and up the standalone set of stairs
CKG: Titanite Scale - shortcutIn the room leading to the Oceiros shortcut elevator from Lothric/Dancer, in the first floor alcove.
CKG: Titanite Scale - tomb, chest #1Chest after Oceiros fight
CKG: Titanite Scale - tomb, chest #2Chest after Oceiros fight
CKG: Wood Grain Ring+1 - by first elevator bottomBehind the first elevator going down into the garden, in the toxic pool
DH: Aquamarine Dagger - castle, up stairsUp the second flight of stairs to the left of the starting area with the murkmen, before the long drop
DH: Black Firebomb - ruins, up windmill from bonfireTo the left of the Earthen Peak Ruins bonfire, past the ruined windmill, next to many Poisonhorn bugs.
DH: Covetous Silver Serpent Ring+3 - pantry upstairs, drop downAfter exiting the building with the Lothric Knights where the front crumbles, to the last room of the building to the right, up stairs past an illusory wall to the left, then dropping down after exiting the building from the last room.
DH: Desert Pyromancer Garb - ruins, by shack near cliffBehind a shack near the edge of the cliff of the area targeted by the second angel.
DH: Desert Pyromancer Gloves - swamp, far rightAfter dropping down in the poison swamp area, against the wall straight to the right.
DH: Desert Pyromancer Hood - swamp upper, tunnel endAt the end of the tunnel with Desert Pyromancy Zoey, to the right of the final branches.
DH: Desert Pyromancer Skirt - swamp right, by rootsIn the poison swamp, against a tree guarded by a few Poisonhorn bugs in the front right.
DH: Divine Blessing - library, after dropAfter the dropdown where an angel first targets you, behind you
DH: Divine Blessing - shopSold by Stone-humped Hag, or in her ashes
DH: Divine Blessing - swamp upper, building roofOn a rooftop of one of the buildings bordering the poison swamp. Can be reached by dropping down from the final tree branch and accessing the roof to the right.
DH: Ember - castle, behind spireAt the start of the area, behind a spire to the right of first drop down
DH: Ember - pantry, behind crates just before upstairsAfter exiting the building with the Lothric Knights where the front crumbles, to the last room end of the building to the right, up stairs past an illusory wall to the left, in the second-to-last room of the sequence, behind some crates to the left.
DH: Ember - ruins, alcove before swampIn an alcove providing cover from the second angel's projectiles, before dropping down in the poison swamp area.
DH: Ember - ruins, alcove on cliffIn the area with the pilgrim responsible for the second angel, below the Within Earthen Peak Ruins bonfire. Can be accessed by dropping down from a cliff edge, dropping down to the right of the bonfire.
DH: Ember - shopSold by Stone-humped Hag, or in her ashes
DH: Flame Fan - swamp upper, NPC dropDropped by Desert Pyromancer Zoey
DH: Giant Door Shield - ruins, path below far shackDescending down a path from the edge of the cliff of the area targeted by the second angel, to the very end of the cliff.
DH: Great Soul Dregs - pantry upstairsAfter exiting the building with the Lothric Knights where the front crumbles, to the last room of the building to the right, up stairs past an illusory wall to the left, then all the way to the end of the last room.
DH: Harald Curved Greatsword - swamp left, under rootIn the back leftmost area of the poison swamp, underneath the tree branch leading up and out, guarded by a stationary Harald Legion Knight.
DH: Hidden Blessing - shopSold by Stone-humped Hag, or in her ashes
DH: Homeward Bone - end of path from churchImmediately before dropping into the area with the Earthen Peak Ruins bonfire, next to Gael's flag.
DH: Homeward Bone - swamp left, on rootAll the way to the end of a short path in the back leftmost area of the poison swamp, where you can plunge attack the stationary Harald Legion Knight.
DH: Large Soul of a Weary Warrior - parapets, hallAfter crossing the spire bridge that crashes into the building with the Lothric Knights, past Lapp's initial location, dropping down behind the murkman and dropping down again, in a corner to the left.
DH: Large Soul of a Weary Warrior - swamp centerIn the middle of the poison swamp.
DH: Large Soul of a Weary Warrior - swamp, under overhangIn the cavern adjacent to the poison swamp, surrounded by a few Poisonhorn bugs.
DH: Lightning Urn - wall outside churchAfter the dropdown where an angel first targets you, against the wall on the left.
DH: Loincloth - swamp, left edgeIn the leftmost edge of the poison swamp after dropping down, guarded by 6 Poisonhorn bugs.
DH: Lothric War Banner - parapets, end of hallAfter crossing the spire bridge that crashes into the building with the Lothric Knights, past Lapp's initial location, dropping down behind the murkman and dropping down again, at the end of the hallway to the right.
DH: Murky Hand Scythe - library, behind bookshelvesAfter the first long drop into the building which looks like Grand Archives, to the left up the bookshelf stairs and behind the bookshelves
DH: Murky Longstaff - pantry, last roomAfter exiting the building with the Lothric Knights where the front crumbles, in the third furthest room in the building to the right.
DH: Prism Stone - swamp upper, tunnel startNear the start of the tunnel with Desert Pyromancer Zoey.
DH: Projected Heal - parapets balconyAfter crossing the spire bridge that crashes into the building with the Lothric Knights, past Lapp's initial location, dropping down behind the murkman, against a wall in the area with the Lothric War Banner Knight and many murkmen.
DH: Purple Moss Clump - swamp shackIn the ruined shack with Poisonhorn bugs straight ahead of the dropdown into the poison swamp area.
DH: Ring of Favor+3 - swamp right, up rootUp the long branch close to the dropdown into the poison swamp area, in front of the cavern.
DH: Ring of Steel Protection+3 - ledge before churchAfter the dropdown where an angel first targets you, on an exposed edge to the left. Difficult to get without killing the angel.
DH: Rusted Coin - behind fountain after churchAfter exiting the building with the Lothric Knights where the front crumbles, behind the fountain on the right side.
DH: Rusted Gold Coin - shopSold by Stone-humped Hag, or in her ashes
DH: Siegbräu - LappGiven by Lapp after collecting the Titanite Slab in Earthen Peak Ruins, or left after Demon Princes fight, or dropped upon death if not given.
DH: Small Envoy Banner - boss dropFound in the small room after beating Demon Prince.
DH: Soul of a Crestfallen Knight - church, altarIn the building where the front crumbles, guarded by the two Lothric Knights at the front of the chapel.
DH: Soul of a Weary Warrior - castle overhangThe bait item at the start of the area which falls down with you into the ruined building below.
DH: Soul of the Demon PrinceDropped by Demon Prince
DH: Splitleaf Greatsword (shop)Sold by Stone-humped Hag, or in her ashes
DH: Titanite Chunk (castle, up stairs)Up first flight of stairs to the left of the starting area with the murkmen, before the long drop
DH: Titanite Chunk (pantry, first room)After exiting the building with the Lothric Knights where the front crumbles, on a ledge in the first room of the building to the right.
DH: Titanite Chunk (path from church, by pillar)Before dropping into the area with the Earthen Peak Ruins bonfire, behind a pillar in front of a murkman pool.
DH: Titanite Chunk (ruins, by far shack)In front of a shack at the far edge of the cliff of the area targeted by the second angel. There is a shortcut dropdown to the left of the building.
DH: Titanite Chunk (ruins, path from bonfire)At the Earthen Peak Ruins bonfire, straight a bit then all the way left, near the edge of the cliff in the area targeted by the second angel.
DH: Titanite Chunk (swamp right, drop partway up root)Partway up the long branch close to the dropdown into the poison swamp area, in front of the cavern, dropping down to a branch to the left.
DH: Titanite Chunk (swamp, along buildings)After dropping down into the poison swamp, along the buildings on the left side.
DH: Titanite Chunk (swamp, path to upper)Partway up the branch that leads out of the poison swamp, on a very exposed branch jutting out to the left.
DH: Titanite Scale (library, back of room)After the first long drop into the building which looks like Grand Archives, behind you at the back of the room
DH: Titanite Scale (swamp upper, drop and jump into tower)At the very end of the last tree branch before dropping down toward the Within Earthen Peak Ruins bonfire, drop down to the left instead. Make a jump into the interior of the overturned tower to the left.
DH: Titanite Slab (swamp, path under overhang)Deep within the cavern adjacent to the poison swamp, to the back and then left. Alternatively, given by Lapp after exhausting dialogue near the bonfire and dying, or left after he moves on, or dropped upon death if not given.
DH: Twinkling Titanite (library, chandelier)After the first long drop into the building which looks like Grand Archives, straight ahead hanging from a chandelier on the ground
DH: Twinkling Titanite (path after church, mob drop)Dropped the pilgrim responsible for the first angel encountered, below the spire bridge that forms by crashing into the building.
DH: Twinkling Titanite (ruins, alcove on cliff, mob drop)Dropped by the pilgrim responsible for the second angel, below the Within Earthen Peak Ruins bonfire. Can be accessed by dropping down from a cliff edge, or dropping down to the right of the bonfire.
DH: Twinkling Titanite (ruins, root near bonfire)Treasure visible straight ahead of the Earthen Peak Ruins bonfire on a branch. Can be accessed by following the right wall from the bonfire until a point of access onto the branch is found.
DH: Twinkling Titanite (swamp upper, drop onto root)On the final tree branches before dropping down toward the Within Earthen Peak Ruins bonfire, drop down on a smaller branch to the right. This loops back to the original branch.
DH: Twinkling Titanite (swamp upper, mob drop on roof)Dropped by the pilgrim responsible for the third angel in the swamp. Rather than heading left into the tunnel with Desert Pyromancy Zoey, go right onto a shack roof. Drop down onto a tree branch at the end, then drop down to another roof.
FK: Antiquated Dress (hidden cave)In a chest in the cave found along the keep wall in the basilisk area, with the Elizabeth corpse
FK: Antiquated Gloves (hidden cave)In a chest in the cave found along the keep wall in the basilisk area, with the Elizabeth corpse
FK: Antiquated Skirt (hidden cave)In a chest in the cave found along the keep wall in the basilisk area, with the Elizabeth corpse
FK: Atonement (perimeter, drop down into swamp)Dropping down from the Farron Keep Perimeter building, to the right past the bonfire, before the stairs going up
FK: Black Bow of Pharis (miniboss drop, by keep ruins near wall)Dropped the Elder Ghru on the left side of the group of three to the left of the Keep Ruins bonfire, as approached from the ritual fire.
FK: Black Bug Pellet (perimeter, hill by boss door)On the small hill to the right of the Abyss Watchers entrance, guarded by a spear-wielding Ghru Grunt
DH: Splitleaf Greatsword - shopSold by Stone-humped Hag, or in her ashes
DH: Titanite Chunk - castle, up stairsUp first flight of stairs to the left of the starting area with the murkmen, before the long drop
DH: Titanite Chunk - pantry, first roomAfter exiting the building with the Lothric Knights where the front crumbles, on a ledge in the first room of the building to the right.
DH: Titanite Chunk - path from church, by pillarBefore dropping into the area with the Earthen Peak Ruins bonfire, behind a pillar in front of a murkman pool.
DH: Titanite Chunk - ruins, by far shackIn front of a shack at the far edge of the cliff of the area targeted by the second angel. There is a shortcut dropdown to the left of the building.
DH: Titanite Chunk - ruins, path from bonfireAt the Earthen Peak Ruins bonfire, straight a bit then all the way left, near the edge of the cliff in the area targeted by the second angel.
DH: Titanite Chunk - swamp right, drop partway up rootPartway up the long branch close to the dropdown into the poison swamp area, in front of the cavern, dropping down to a branch to the left.
DH: Titanite Chunk - swamp, along buildingsAfter dropping down into the poison swamp, along the buildings on the left side.
DH: Titanite Chunk - swamp, path to upperPartway up the branch that leads out of the poison swamp, on a very exposed branch jutting out to the left.
DH: Titanite Scale - library, back of roomAfter the first long drop into the building which looks like Grand Archives, behind you at the back of the room
DH: Titanite Scale - swamp upper, drop and jump into towerAt the very end of the last tree branch before dropping down toward the Within Earthen Peak Ruins bonfire, drop down to the left instead. Make a jump into the interior of the overturned tower to the left.
DH: Titanite Slab - swamp, path under overhangDeep within the cavern adjacent to the poison swamp, to the back and then left. Alternatively, given by Lapp after exhausting dialogue near the bonfire and dying, or left after he moves on, or dropped upon death if not given.
DH: Twinkling Titanite - library, chandelierAfter the first long drop into the building which looks like Grand Archives, straight ahead hanging from a chandelier on the ground
DH: Twinkling Titanite - path after church, mob dropDropped the pilgrim responsible for the first angel encountered, below the spire bridge that forms by crashing into the building.
DH: Twinkling Titanite - ruins, alcove on cliff, mob dropDropped by the pilgrim responsible for the second angel, below the Within Earthen Peak Ruins bonfire. Can be accessed by dropping down from a cliff edge, or dropping down to the right of the bonfire.
DH: Twinkling Titanite - ruins, root near bonfireTreasure visible straight ahead of the Earthen Peak Ruins bonfire on a branch. Can be accessed by following the right wall from the bonfire until a point of access onto the branch is found.
DH: Twinkling Titanite - swamp upper, drop onto rootOn the final tree branches before dropping down toward the Within Earthen Peak Ruins bonfire, drop down on a smaller branch to the right. This loops back to the original branch.
DH: Twinkling Titanite - swamp upper, mob drop on roofDropped by the pilgrim responsible for the third angel in the swamp. Rather than heading left into the tunnel with Desert Pyromancy Zoey, go right onto a shack roof. Drop down onto a tree branch at the end, then drop down to another roof.
FK: Antiquated Dress - hidden caveIn a chest in the cave found along the keep wall in the basilisk area, with the Elizabeth corpse
FK: Antiquated Gloves - hidden caveIn a chest in the cave found along the keep wall in the basilisk area, with the Elizabeth corpse
FK: Antiquated Skirt - hidden caveIn a chest in the cave found along the keep wall in the basilisk area, with the Elizabeth corpse
FK: Atonement - perimeter, drop down into swampDropping down from the Farron Keep Perimeter building, to the right past the bonfire, before the stairs going up
FK: Black Bow of Pharis - miniboss drop, by keep ruins near wallDropped the Elder Ghru on the left side of the group of three to the left of the Keep Ruins bonfire, as approached from the ritual fire.
FK: Black Bug Pellet - perimeter, hill by boss doorOn the small hill to the right of the Abyss Watchers entrance, guarded by a spear-wielding Ghru Grunt
FK: Cinders of a Lord - Abyss WatcherDropped by Abyss Watchers
FK: Crown of Dusk (by white tree)Near the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Dark Stoneplate Ring+2 (keep ruins ritual island, behind wall)Hidden behind the right wall of the ritual fire before Keep Ruins
FK: Dragon Crest Shield (upper keep, far side of the wall)Up the elevator from Old Wolf of Farron bonfire, and dropping down to Crystal Lizard area, in the open.
FK: Dreamchaser's Ashes (keep proper, illusory wall)Near the Old Wolf of Farron bonfire, behind an illusory wall near the Crystal Lizard
FK: Ember (by white tree)Near the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Ember (perimeter, path to boss)Guarded by a spear-wielding Ghru Grunt to the right of the main path leading up to Abyss Watchers
FK: Ember (upper keep, by miniboss #1)Guarded by Stray Demon, up from the Old Wolf of Farron bonfire
FK: Ember (upper keep, by miniboss #2)Guarded by Stray Demon, up from the Old Wolf of Farron bonfire
FK: Estus Shard (between Farron Keep bonfire and left island)Straight ahead from the Farron Keep bonfire to the ritual fire stairs, guarded by a slug
FK: Gold Pine Bundle (by white tree)Near the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Golden Scroll (hidden cave)In a cave found along the keep wall in the basilisk area, with the Elizabeth corpse
FK: Great Magic Weapon (perimeter, by door to Road of Sacrifices)Next to the shortcut leading from Farron Keep Perimeter back into Crucifixion Woods, past the Ravenous Crystal Lizard
FK: Greataxe (upper keep, by miniboss)Guarded by Stray Demon, up from the Old Wolf of Farron bonfire
FK: Greatsword (ramp by keep ruins ritual island)In the middle of the swamp, on the pair of long ramps furthest from the Farron Keep bonfire, going out forward and slightly right from the bonfire.
FK: Havel's Armor (upper keep, after killing AP belfry roof NPC)Appears by Stray Demon, up from the Old Wolf of Farron bonfire, after the Havel Knight guarding the Titanite Slab in Archdragon Peak has been killed
FK: Havel's Gauntlets (upper keep, after killing AP belfry roof NPC)Appears by Stray Demon, up from the Old Wolf of Farron bonfire, after the Havel Knight guarding the Titanite Slab in Archdragon Peak has been killed
FK: Havel's Helm (upper keep, after killing AP belfry roof NPC)Appears by Stray Demon, up from the Old Wolf of Farron bonfire, after the Havel Knight guarding the Titanite Slab in Archdragon Peak has been killed
FK: Havel's Leggings (upper keep, after killing AP belfry roof NPC)Appears by Stray Demon, up from the Old Wolf of Farron bonfire, after the Havel Knight guarding the Titanite Slab in Archdragon Peak has been killed
FK: Heavy Gem (upper keep, lizard on stairs)Dropped by the Crystal Lizard that scurries up the stairs in the area dropping down from near Stray Demon, up from Old Wolf of Farron bonfire
FK: Hollow Gem (perimeter, drop down into swamp)Dropping down from the Farron Keep Perimeter building, to the right past the bonfire, before the stairs going up
FK: Homeward Bone (right island, behind fire)Behind the ritual fire with stairs guarded by Elder Ghrus/basilisks
FK: Iron Flesh (Farron Keep bonfire, right after exit)In the open in the swamp, heading straight right from Farron Keep bonfire
FK: Large Soul of a Nameless Soldier (corner of keep and right island)Hidden in a corner to the right of the stairs leading up to the ritual fire from the basilisk area
FK: Large Soul of a Nameless Soldier (near wall by right island)To the left of the stairs leading up to the ritual fire from the Basilisk area, by the keep wall
FK: Large Soul of an Unknown Traveler (by white tree)On a tree close to the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Large Titanite Shard (upper keep, lizard by wyvern)Dropped by the farther Crystal Lizard in the area dropping down from near Stray Demon, up from Old Wolf of Farron bonfire
FK: Large Titanite Shard (upper keep, lizard in open)Dropped by the closer Crystal Lizard in the area dropping down from near Stray Demon, up from Old Wolf of Farron bonfire
FK: Lightning Spear (upper keep, far side of the wall)Up the elevator from Old Wolf of Farron bonfire, and dropping down to Crystal Lizard area, in the open.
FK: Lingering Dragoncrest Ring (by white tree, miniboss drop)Dropped by the Greater Crab patrolling the birch tree where the Giant shoots arrows
FK: Magic Stoneplate Ring+1 (between right island and wall)Behind a tree in the basilisk area, heading directly right from Farron Keep bonfire
FK: Manikin Claws (Londor Pale Shade drop)Dropped by Londor Pale Shade when he invades near the basilisks, if Yoel or Yuria have been betrayed
FK: Nameless Knight Armor (corner of keep and right island)From the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill
FK: Nameless Knight Gauntlets (corner of keep and right island)From the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill
FK: Nameless Knight Helm (corner of keep and right island)From the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill
FK: Nameless Knight Leggings (corner of keep and right island)From the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill
FK: Pharis's Hat (miniboss drop, by keep ruins near wall)Dropped the Elder Ghru in the back of the group of three to the left of the Keep Ruins bonfire, as approached from the ritual fire.
FK: Poison Gem (near wall by keep ruins bridge)From the left of the bridge leading from the ritual fire to the Keep Ruins bonfire, guarded by the three Elder Ghru
FK: Prism Stone (by left island stairs)On an island to the left of the stairs leading up to the ritual fire straight ahead of the Farron Keep bonfire
FK: Purple Moss Clump (Farron Keep bonfire, around right corner)Along the inner wall of the keep, making an immediate right from Farron Keep bonfire
FK: Purple Moss Clump (keep ruins, ritual island)Close to the ritual fire before the Keep Ruins bonfire
FK: Purple Moss Clump (ramp directly in front of Farron Keep bonfire)In the middle of the swamp, on the pair of long ramps closest to the Farron Keep bonfire, going out forward and slightly right from the bonfire.
FK: Ragged Mask (Farron Keep bonfire, around left corner)Along the inner wall of the keep, making an immediate left from Farron Keep bonfire, guarded by slugs
FK: Repair Powder (outside hidden cave)Along the keep wall in the basilisk area, outside of the cave with the Elizabeth corpse and Golden Scroll
FK: Rotten Pine Resin (left island, behind fire)In the area behind the ritual fire which is straight ahead of the Farron Keep bonfire
FK: Rotten Pine Resin (outside pavilion by left island)From the Farron Keep bonfire straight ahead to the pavillion guarded by the Darkwraith, just to the left of the ritual fire stairs
FK: Rusted Gold Coin (right island, behind wall)Hidden behind the right wall of the ritual fire with stairs guarded by Elder Ghrus/basilisks
FK: Sage's Coal (pavilion by left island)In the pavillion guarded by a Darkwraith, straight ahead from the Farron Keep bonfire to the left of the ritual fire stairs
FK: Sage's Scroll (near wall by keep ruins bonfire island)Along the keep inner wall, heading left from the stone doors past the crab area, surrounded by many Ghru enemies
FK: Shriving Stone (perimeter, just past stone doors)Past the stone doors, on the path leading up to Abyss Watchers by the Corvians
FK: Soul of a Nameless Soldier (by white tree)Near the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Soul of a Stray Demon (upper keep, miniboss drop)Dropped by Stray Demon on the bridge above Farron Keep
FK: Crown of Dusk - by white treeNear the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Dark Stoneplate Ring+2 - keep ruins ritual island, behind wallHidden behind the right wall of the ritual fire before Keep Ruins
FK: Dragon Crest Shield - upper keep, far side of the wallUp the elevator from Old Wolf of Farron bonfire, and dropping down to Crystal Lizard area, in the open.
FK: Dreamchaser's Ashes - keep proper, illusory wallNear the Old Wolf of Farron bonfire, behind an illusory wall near the Crystal Lizard
FK: Ember - by white treeNear the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Ember - perimeter, path to bossGuarded by a spear-wielding Ghru Grunt to the right of the main path leading up to Abyss Watchers
FK: Ember - upper keep, by miniboss #1Guarded by Stray Demon, up from the Old Wolf of Farron bonfire
FK: Ember - upper keep, by miniboss #2Guarded by Stray Demon, up from the Old Wolf of Farron bonfire
FK: Estus Shard - between Farron Keep bonfire and left islandStraight ahead from the Farron Keep bonfire to the ritual fire stairs, guarded by a slug
FK: Gold Pine Bundle - by white treeNear the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Golden Scroll - hidden caveIn a cave found along the keep wall in the basilisk area, with the Elizabeth corpse
FK: Great Magic Weapon - perimeter, by door to Road of SacrificesNext to the shortcut leading from Farron Keep Perimeter back into Crucifixion Woods, past the Ravenous Crystal Lizard
FK: Greataxe - upper keep, by minibossGuarded by Stray Demon, up from the Old Wolf of Farron bonfire
FK: Greatsword - ramp by keep ruins ritual islandIn the middle of the swamp, on the pair of long ramps furthest from the Farron Keep bonfire, going out forward and slightly right from the bonfire.
FK: Havel's Armor - upper keep, after killing AP belfry roof NPCAppears by Stray Demon, up from the Old Wolf of Farron bonfire, after the Havel Knight guarding the Titanite Slab in Archdragon Peak has been killed
FK: Havel's Gauntlets - upper keep, after killing AP belfry roof NPCAppears by Stray Demon, up from the Old Wolf of Farron bonfire, after the Havel Knight guarding the Titanite Slab in Archdragon Peak has been killed
FK: Havel's Helm - upper keep, after killing AP belfry roof NPCAppears by Stray Demon, up from the Old Wolf of Farron bonfire, after the Havel Knight guarding the Titanite Slab in Archdragon Peak has been killed
FK: Havel's Leggings - upper keep, after killing AP belfry roof NPCAppears by Stray Demon, up from the Old Wolf of Farron bonfire, after the Havel Knight guarding the Titanite Slab in Archdragon Peak has been killed
FK: Heavy Gem - upper keep, lizard on stairsDropped by the Crystal Lizard that scurries up the stairs in the area dropping down from near Stray Demon, up from Old Wolf of Farron bonfire
FK: Hollow Gem - perimeter, drop down into swampDropping down from the Farron Keep Perimeter building, to the right past the bonfire, before the stairs going up
FK: Homeward Bone - right island, behind fireBehind the ritual fire with stairs guarded by Elder Ghrus/basilisks
FK: Iron Flesh - Farron Keep bonfire, right after exitIn the open in the swamp, heading straight right from Farron Keep bonfire
FK: Large Soul of a Nameless Soldier - corner of keep and right islandHidden in a corner to the right of the stairs leading up to the ritual fire from the basilisk area
FK: Large Soul of a Nameless Soldier - near wall by right islandTo the left of the stairs leading up to the ritual fire from the Basilisk area, by the keep wall
FK: Large Soul of an Unknown Traveler - by white treeOn a tree close to the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Large Titanite Shard - upper keep, lizard by wyvernDropped by the farther Crystal Lizard in the area dropping down from near Stray Demon, up from Old Wolf of Farron bonfire
FK: Large Titanite Shard - upper keep, lizard in openDropped by the closer Crystal Lizard in the area dropping down from near Stray Demon, up from Old Wolf of Farron bonfire
FK: Lightning Spear - upper keep, far side of the wallUp the elevator from Old Wolf of Farron bonfire, and dropping down to Crystal Lizard area, in the open.
FK: Lingering Dragoncrest Ring - by white tree, miniboss dropDropped by the Greater Crab patrolling the birch tree where the Giant shoots arrows
FK: Magic Stoneplate Ring+1 - between right island and wallBehind a tree in the basilisk area, heading directly right from Farron Keep bonfire
FK: Manikin Claws - Londor Pale Shade dropDropped by Londor Pale Shade when he invades near the basilisks, if Yoel or Yuria have been betrayed
FK: Nameless Knight Armor - corner of keep and right islandFrom the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill
FK: Nameless Knight Gauntlets - corner of keep and right islandFrom the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill
FK: Nameless Knight Helm - corner of keep and right islandFrom the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill
FK: Nameless Knight Leggings - corner of keep and right islandFrom the Keep Ruins bonfire to the ritual fire stairs patrolled by Elder Ghrus, along the edge of the ritual fire hill
FK: Pharis's Hat - miniboss drop, by keep ruins near wallDropped the Elder Ghru in the back of the group of three to the left of the Keep Ruins bonfire, as approached from the ritual fire.
FK: Poison Gem - near wall by keep ruins bridgeFrom the left of the bridge leading from the ritual fire to the Keep Ruins bonfire, guarded by the three Elder Ghru
FK: Prism Stone - by left island stairsOn an island to the left of the stairs leading up to the ritual fire straight ahead of the Farron Keep bonfire
FK: Purple Moss Clump - Farron Keep bonfire, around right cornerAlong the inner wall of the keep, making an immediate right from Farron Keep bonfire
FK: Purple Moss Clump - keep ruins, ritual islandClose to the ritual fire before the Keep Ruins bonfire
FK: Purple Moss Clump - ramp directly in front of Farron Keep bonfireIn the middle of the swamp, on the pair of long ramps closest to the Farron Keep bonfire, going out forward and slightly right from the bonfire.
FK: Ragged Mask - Farron Keep bonfire, around left cornerAlong the inner wall of the keep, making an immediate left from Farron Keep bonfire, guarded by slugs
FK: Repair Powder - outside hidden caveAlong the keep wall in the basilisk area, outside of the cave with the Elizabeth corpse and Golden Scroll
FK: Rotten Pine Resin - left island, behind fireIn the area behind the ritual fire which is straight ahead of the Farron Keep bonfire
FK: Rotten Pine Resin - outside pavilion by left islandFrom the Farron Keep bonfire straight ahead to the pavillion guarded by the Darkwraith, just to the left of the ritual fire stairs
FK: Rusted Gold Coin - right island, behind wallHidden behind the right wall of the ritual fire with stairs guarded by Elder Ghrus/basilisks
FK: Sage's Coal - pavilion by left islandIn the pavillion guarded by a Darkwraith, straight ahead from the Farron Keep bonfire to the left of the ritual fire stairs
FK: Sage's Scroll - near wall by keep ruins bonfire islandAlong the keep inner wall, heading left from the stone doors past the crab area, surrounded by many Ghru enemies
FK: Shriving Stone - perimeter, just past stone doorsPast the stone doors, on the path leading up to Abyss Watchers by the Corvians
FK: Soul of a Nameless Soldier - by white treeNear the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Soul of a Stray Demon - upper keep, miniboss dropDropped by Stray Demon on the bridge above Farron Keep
FK: Soul of the Blood of the WolfDropped by Abyss Watchers
FK: Stone Parma (near wall by left island)Along the inner wall of the keep, making an left from Farron Keep bonfire but before the area with the Darkwraith, guarded by a slug
FK: Sunlight Talisman (estus soup island, by ladder to keep proper)By the pot of estus soup to the left of the stairs leading up to Old Wolf of Farron
FK: Titanite Scale (perimeter, miniboss drop)Dropped by Ravenous Crystal Lizard near the shortcut from Farron Keep back to Road of Sacrifices
FK: Titanite Shard (Farron Keep bonfire, left after exit)Along the inner wall of the keep, making an left from Farron Keep bonfire, by the second group of four slugs
FK: Titanite Shard (between left island and keep ruins)In the swamp area with the Ghru Leaper between the Keep Ruins ritual fire and ritual fire straight ahead of Farron Keep bonfire, opposite from the keep wall
FK: Titanite Shard (by keep ruins ritual island stairs)By the stairs leading up to the Keep Ruins ritual fire from the middle of the swamp
FK: Titanite Shard (by ladder to keep proper)In the swamp area close to the foot of the ladder leading to Old Wolf of Farron bonfire
FK: Titanite Shard (by left island stairs)In front of the stairs leading up to the ritual fire straight ahead of the Farron Keep bonfire
FK: Titanite Shard (keep ruins bonfire island, under ramp)Under the ramp leading down from the Keep Ruins bonfire
FK: Titanite Shard (swamp by right island)Behind a tree patrolled by an Elder Ghru close to the ritual fire stairs
FK: Twinkling Dragon Head Stone (Hawkwood drop)Dropped by Hawkwood after killing him in the Abyss Watchers arena, after running up to the altar in Archdragon Peak. Twinkling Dragon Torso Stone needs to be acquired first.
FK: Twinkling Titanite (keep proper, lizard)Dropped by the Crystal Lizard on the balcony behind the Old Wolf of Farron bonfire
FK: Undead Bone Shard (pavilion by keep ruins bonfire island)In a standalone pavillion down the ramp from Keep Ruins bonfire and to the right
FK: Watchdogs of Farron (Old Wolf)Given by Old Wolf of Farron.
FK: Wolf Ring+1 (keep ruins bonfire island, outside building)To the right of the building with the Keep Ruins bonfire, when approached from the ritual fire
FK: Wolf's Blood Swordgrass (by ladder to keep proper)To the left of the ladder leading up to the Old Wolf of Farron bonfire
FK: Young White Branch (by white tree #1)Near the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Young White Branch (by white tree #2)Near the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FS: Acid Surge (Cornyx for Carthus Tome)Sold by Cornyx after giving him the Carthus Pyromancy Tome
FS: Affinity (Karla)Sold by Karla after recruiting her, or in her ashes
FS: Alluring Skull (Mortician's Ashes)Sold by Handmaid after giving Mortician's Ashes
FS: Arstor's Spear (Ludleth for Greatwood)Boss weapon for Curse-Rotted Greatwood
FS: Aural Decoy (Orbeck)Sold by Orbeck
FS: Billed Mask (Yuria after killing KFF boss)Dropped by Yuria upon death or quest completion.
FS: Black Dress (Yuria after killing KFF boss)Dropped by Yuria upon death or quest completion.
FS: Black Fire Orb (Karla for Grave Warden Tome)Sold by Karla after giving her the Grave Warden Pyromancy Tome
FS: Black Flame (Karla for Grave Warden Tome)Sold by Karla after giving her the Grave Warden Pyromancy Tome
FS: Black Gauntlets (Yuria after killing KFF boss)Dropped by Yuria upon death or quest completion.
FS: Black Iron Armor (shop after killing Tsorig)Sold by Handmaid after killing Knight Slayer Tsorig in Smouldering Lake
FS: Black Iron Gauntlets (shop after killing Tsorig)Sold by Handmaid after killing Knight Slayer Tsorig in Smouldering Lake
FS: Black Iron Helm (shop after killing Tsorig)Sold by Handmaid after killing Knight Slayer Tsorig in Smouldering Lake
FS: Black Iron Leggings (shop after killing Tsorig)Sold by Handmaid after killing Knight Slayer Tsorig in Smouldering Lake
FS: Black Leggings (Yuria after killing KFF boss)Dropped by Yuria upon death or quest completion.
FS: Black Serpent (Ludleth for Wolnir)Boss weapon for High Lord Wolnir
FS: Blessed Weapon (Irina for Tome of Lothric)Sold by Irina after giving her the Braille Divine Tome of Lothric
FS: Blue Tearstone Ring (Greirat)Given by Greirat upon rescuing him from the High Wall cell
FS: Boulder Heave (Ludleth for Stray Demon)Boss weapon for Stray Demon
FS: Bountiful Light (Irina for Tome of Lothric)Sold by Irina after giving her the Braille Divine Tome of Lothric
FS: Bountiful Sunlight (Ludleth for Rosaria)Boss weapon for Rosaria, available after Leonhard is killed
FS: Broken Straight Sword (gravestone after boss)Near the grave after Iudex Gundyr fight
FS: Budding Green Blossom (shop killing Creighton and AL boss)Sold by Handmaid after receiving Silvercat Ring item lot from Sirris and defeating Aldrich
FS: Bursting Fireball (Cornyx for Great Swamp Tome)Sold by Cornyx after giving him the Great Swamp Pyromancy Tome
FS: Caressing Tears (Irina)Sold by Irina after recruiting her, or in her ashes
FS: Carthus Beacon (Cornyx for Carthus Tome)Sold by Cornyx after giving him the Carthus Pyromancy Tome
FS: Carthus Flame Arc (Cornyx for Carthus Tome)Sold by Cornyx after giving him the Carthus Pyromancy Tome
FS: Cast Light (Orbeck for Golden Scroll)Sold by Orbeck after giving him the Golden Scroll
FS: Chaos Bed Vestiges (Ludleth for Old Demon King)Boss weapon for Old Demon King
FS: Chaos Storm (Cornyx for Izalith Tome)Sold by Cornyx after giving him Izalith Pyromancy Tome
FS: Clandestine Coat (shop with Orbeck's Ashes)Sold by Handmaid after giving Orbeck's Ashes and reloading
FS: Cleric's Candlestick (Ludleth for Deacons)Boss weapon for Deacons of the Deep
FS: Cracked Red Eye Orb (Leonhard)Given by Ringfinger Leonhard in Firelink Shrine after reaching Tower on the Wall bonfire
FS: Crystal Hail (Ludleth for Sage)Boss weapon for Crystal Sage
FS: Crystal Magic Weapon (Orbeck for Crystal Scroll)Sold by Orbeck after giving him the Crystal Scroll
FS: Crystal Sage's Rapier (Ludleth for Sage)Boss weapon for Crystal Sage
FS: Crystal Soul Spear (Orbeck for Crystal Scroll)Sold by Orbeck after giving him the Crystal Scroll
FS: Dancer's Armor (shop after killing LC entry boss)Sold by Handmaid after defeating Dancer of the Boreal Valley
FS: Dancer's Crown (shop after killing LC entry boss)Sold by Handmaid after defeating Dancer of the Boreal Valley
FS: Dancer's Enchanted Swords (Ludleth for Dancer)Boss weapon for Dancer of the Boreal Valley
FS: Dancer's Gauntlets (shop after killing LC entry boss)Sold by Handmaid after defeating Dancer of the Boreal Valley
FS: Dancer's Leggings (shop after killing LC entry boss)Sold by Handmaid after defeating Dancer of the Boreal Valley
FS: Dark Blade (Karla for Londor Tome)Sold by Irina or Karla after giving one the Londor Braille Divine Tome
FS: Dark Edge (Karla)Sold by Karla after recruiting her, or in her ashes
FS: Dark Hand (Yoel/Yuria)Sold by Yuria
FS: Darkdrift (Yoel/Yuria)Dropped by Yuria upon death or quest completion.
FS: Darkmoon Longbow (Ludleth for Aldrich)Boss weapon for Aldrich
FS: Dead Again (Karla for Londor Tome)Sold by Irina or Karla after giving one the Londor Braille Divine Tome
FS: Deep Protection (Karla for Deep Braille Tome)Sold by Irina or Karla after giving one the Deep Braille Divine Tome
FS: Deep Soul (Ludleth for Deacons)Boss weapon for Deacons of the Deep
FS: Demon's Fist (Ludleth for Fire Demon)Boss weapon for Fire Demon
FS: Demon's Greataxe (Ludleth for Fire Demon)Boss weapon for Fire Demon
FS: Demon's Scar (Ludleth for Demon Prince)Boss weapon for Demon Prince
FS: Divine Blessing (Greirat from IBV)Sold by Greirat after pillaging Irithyll
FS: Divine Blessing (Greirat from US)Sold by Greirat after pillaging Undead Settlement
FS: Dragonscale Armor (shop after killing AP boss)Sold by Handmaid after defeating Nameless King
FS: Dragonscale Waistcloth (shop after killing AP boss)Sold by Handmaid after defeating Nameless King
FS: Dragonslayer Greataxe (Ludleth for Dragonslayer)Boss weapon for Dragonslayer Armour
FS: Dragonslayer Greatshield (Ludleth for Dragonslayer)Boss weapon for Dragonslayer Armour
FS: Dragonslayer Swordspear (Ludleth for Nameless)Boss weapon for Nameless King
FS: Dried Finger (shop)Sold by both Shrine Handmaid and Untended Graves Handmaid
FS: East-West Shield (tree by shrine entrance)In a tree to the left of the Firelink Shrine entrance
FS: Eastern Armor (Easterner's Ashes)Sold by Handmaid after giving Easterner's Ashes
FS: Eastern Gauntlets (Easterner's Ashes)Sold by Handmaid after giving Easterner's Ashes
FS: Eastern Helm (Easterner's Ashes)Sold by Handmaid after giving Easterner's Ashes
FS: Eastern Leggings (Easterner's Ashes)Sold by Handmaid after giving Easterner's Ashes
FS: Elite Knight Armor (shop after Anri quest)Sold by Handmaid after completing Anri's questline or killing Anri
FS: Elite Knight Gauntlets (shop after Anri quest)Sold by Handmaid after completing Anri's questline or killing Anri
FS: Elite Knight Helm (shop after Anri quest)Sold by Handmaid after completing Anri's questline or killing Anri
FS: Elite Knight Leggings (shop after Anri quest)Sold by Handmaid after completing Anri's questline or killing Anri
FS: Ember (Dragon Chaser's Ashes)Sold by Handmaid after giving Dragon Chaser's Ashes
FS: Ember (Grave Warden's Ashes)Sold by Handmaid after giving Grave Warden's Ashes
FS: Ember (Greirat from US)Sold by Greirat after pillaging Undead Settlement
FS: Ember (Greirat)Sold by Greirat after recruiting him, or in his ashes
FS: Ember (Mortician's Ashes)Sold by Handmaid after giving Mortician's Ashes
FS: Ember (above shrine entrance)Above the Firelink Shrine entrance, up stairs/slope from either left or right of the entrance
FS: Ember (path right of Firelink entrance)On a cliffside to the right of the main path leading up to Firelink Shrine, guarded by a dog
FS: Ember (shop for Greirat's Ashes)Sold by Handmaid after Greirat pillages Lothric Castle and handing in ashes
FS: Ember (shop)Sold by Handmaid
FS: Embraced Armor of Favor (shop after killing water reserve minibosses)Sold by Handmaid after killing Sulyvahn's Beasts in Water Reserve
FS: Executioner Armor (shop after killing Horace)Sold by Handmaid after killing Horace the Hushed
FS: Executioner Gauntlets (shop after killing Horace)Sold by Handmaid after killing Horace the Hushed
FS: Executioner Helm (shop after killing Horace)Sold by Handmaid after killing Horace the Hushed
FS: Executioner Leggings (shop after killing Horace)Sold by Handmaid after killing Horace the Hushed
FS: Exile Armor (shop after killing NPCs in RS)Sold by Handmaid after killing the exiles just before Farron Keep
FS: Exile Gauntlets (shop after killing NPCs in RS)Sold by Handmaid after killing the exiles just before Farron Keep
FS: Exile Leggings (shop after killing NPCs in RS)Sold by Handmaid after killing the exiles just before Farron Keep
FS: Exile Mask (shop after killing NPCs in RS)Sold by Handmaid after killing the exiles just before Farron Keep
FS: Faraam Helm (shop after killing GA NPC)Sold by Handmaid after killing Lion Knight Albert
FS: Farron Dart (Orbeck)Sold by Orbeck
FS: Farron Dart (shop)Sold by Handmaid
FS: Farron Flashsword (Orbeck)Sold by Orbeck
FS: Farron Greatsword (Ludleth for Abyss Watchers)Boss weapon for Abyss Watchers
FS: Farron Hail (Orbeck for Sage's Scroll)Sold by Orbeck after giving him the Sage's Scroll
FS: Farron Ring (Hawkwood)Given by Hawkwood, or dropped upon death, after defeating Abyss Watchers.
FS: Fire Orb (Cornyx for Great Swamp Tome)Sold by Cornyx after giving him the Great Swamp Pyromancy Tome
FS: Fire Surge (Cornyx)Sold by Cornyx after recruiting him, or in his ashes
FS: Fire Whip (Karla for Quelana Tome)Sold by Karla after giving her the Quelana Pyromancy Tome
FS: Fireball (Cornyx)Sold by Cornyx after recruiting him, or in his ashes
FS: Firelink Armor (shop after placing all Cinders)Sold by Handmaid after defeating Soul of Cinder
FS: Firelink Gauntlets (shop after placing all Cinders)Sold by Handmaid after defeating Soul of Cinder
FS: Firelink Greatsword (Ludleth for Cinder)Boss weapon for Soul of Cinder
FS: Firelink Helm (shop after placing all Cinders)Sold by Handmaid after defeating Soul of Cinder
FS: Firelink Leggings (shop after placing all Cinders)Sold by Handmaid after defeating Soul of Cinder
FS: Firestorm (Karla for Quelana Tome)Sold by Karla after giving her the Quelana Pyromancy Tome
FS: Flash Sweat (Cornyx)Sold by Cornyx after recruiting him, or in his ashes
FS: Force (Irina for Tome of Carim)Sold by Irina after giving her the Braille Divine Tome of Carim
FS: Frayed Blade (Ludleth for Midir)Boss weapon for Darkeater Midir
FS: Friede's Great Scythe (Ludleth for Friede)Boss weapon for Sister Friede
FS: Gael's Greatsword (Ludleth for Gael)Boss weapon for Slave Knight Gael
FS: Gauntlets of Favor (shop after killing water reserve minibosses)Sold by Handmaid after killing Sulyvahn's Beasts in Water Reserve
FS: Gnaw (Karla for Deep Braille Tome)Sold by Irina or Karla after giving one the Deep Braille Divine Tome
FS: Golden Bracelets (shop after killing AP boss)Sold by Handmaid after defeating Nameless King
FS: Golden Crown (shop after killing AP boss)Sold by Handmaid after defeating Nameless King
FS: Grave Key (Mortician's Ashes)Sold by Handmaid after giving Mortician's Ashes
FS: Great Chaos Fire Orb (Cornyx for Izalith Tome)Sold by Cornyx after giving him Izalith Pyromancy Tome
FS: Great Combustion (Cornyx)Sold by Cornyx after recruiting him, or in his ashes
FS: Great Farron Dart (Orbeck for Sage's Scroll)Sold by Orbeck after giving him the Sage's Scroll
FS: Great Heavy Soul Arrow (Orbeck)Sold by Orbeck
FS: Great Soul Arrow (Orbeck)Sold by Orbeck
FS: Greatsword of Judgment (Ludleth for Pontiff)Boss weapon for Pontiff Sulyvahn
FS: Gundyr's Armor (shop after killing UG boss)Sold by Handmaid after defeating Champion Gundyr
FS: Gundyr's Gauntlets (shop after killing UG boss)Sold by Handmaid after defeating Champion Gundyr
FS: Gundyr's Halberd (Ludleth for Champion)Boss weapon for Champion Gundyr
FS: Gundyr's Helm (shop after killing UG boss)Sold by Handmaid after defeating Champion Gundyr
FS: Gundyr's Leggings (shop after killing UG boss)Sold by Handmaid after defeating Champion Gundyr
FS: Havel's Ring (Ludleth for Stray Demon)Boss weapon for Stray Demon
FS: Hawkwood's Shield (Hawkwood)Left by Hawkwood after defeating Abyss Watchers, Curse-Rotted Greatwood, Deacons of the Deep, and Crystal Sage
FS: Hawkwood's Swordgrass (Andre after gesture in AP summit)Given by Andre after praying at the Dragon Altar in Archdragon Peak, after acquiring Twinkling Dragon Torso Stone.
FS: Heal (Irina)Sold by Irina after recruiting her, or in her ashes
FS: Heal Aid (shop)Sold by Handmaid
FS: Heavy Soul Arrow (Orbeck)Sold by Orbeck
FS: Heavy Soul Arrow (Yoel/Yuria)Sold by Yoel/Yuria
FS: Helm of Favor (shop after killing water reserve minibosses)Sold by Handmaid after killing Sulyvahn's Beasts in Water Reserve
FS: Hidden Blessing (Dreamchaser's Ashes)Sold by Greirat after pillaging Irithyll
FS: Hidden Blessing (Greirat from IBV)Sold by Greirat after pillaging Irithyll
FS: Hidden Body (Orbeck for Golden Scroll)Sold by Orbeck after giving him the Golden Scroll
FS: Hidden Weapon (Orbeck for Golden Scroll)Sold by Orbeck after giving him the Golden Scroll
FS: Hollowslayer Greatsword (Ludleth for Greatwood)Boss weapon for Curse-Rotted Greatwood
FS: Homeward (Irina)Sold by Irina after recruiting her, or in her ashes
FS: Homeward Bone (cliff edge after boss)Along the cliff edge straight ahead of the Iudex Gundyr fight
FS: Homeward Bone (path above shrine entrace)To the right of the Firelink Shrine entrance, up a slope and before the ledge on top of a coffin
FS: Homing Crystal Soulmass (Orbeck for Crystal Scroll)Sold by Orbeck after giving him the Crystal Scroll
FS: Homing Soulmass (Orbeck for Logan's Scroll)Sold by Orbeck after giving him Logan's Scroll
FS: Karla's Coat (Prisoner Chief's Ashes)Sold by Handmaid after giving Prisoner Chief's Ashes
FS: Karla's Coat (kill Karla)Dropped from Karla upon death
FS: Karla's Gloves (Prisoner Chief's Ashes)Sold by Handmaid after giving Prisoner Chief's Ashes
FS: Karla's Gloves (kill Karla)Dropped from Karla upon death
FS: Karla's Pointed Hat (Prisoner Chief's Ashes)Sold by Handmaid after giving Prisoner Chief's Ashes
FS: Karla's Pointed Hat (kill Karla)Dropped from Karla upon death
FS: Karla's Trousers (Prisoner Chief's Ashes)Sold by Handmaid after giving Prisoner Chief's Ashes
FS: Karla's Trousers (kill Karla)Dropped from Karla upon death
FS: Leggings of Favor (shop after killing water reserve minibosses)Sold by Handmaid after killing Sulyvahn's Beasts in Water Reserve
FS: Leonhard's Garb (shop after killing Leonhard)Sold by Handmaid after killing Leonhard
FS: Leonhard's Gauntlets (shop after killing Leonhard)Sold by Handmaid after killing Leonhard
FS: Leonhard's Trousers (shop after killing Leonhard)Sold by Handmaid after killing Leonhard
FS: Life Ring (Dreamchaser's Ashes)Sold by Handmaid after giving Dreamchaser's Ashes
FS: Lifehunt Scythe (Ludleth for Aldrich)Boss weapon for Aldrich
FS: Lift Chamber Key (Leonhard)Given by Ringfinger Leonhard after acquiring a Pale Tongue.
FS: Lightning Storm (Ludleth for Nameless)Boss weapon for Nameless King
FS: Lloyd's Shield Ring (Paladin's Ashes)Sold by Handmaid after giving Paladin's Ashes
FS: Londor Braille Divine Tome (Yoel/Yuria)Sold by Yuria
FS: Lorian's Armor (shop after killing GA boss)Sold by Handmaid after defeating Lothric, Younger Prince
FS: Lorian's Gauntlets (shop after killing GA boss)Sold by Handmaid after defeating Lothric, Younger Prince
FS: Lorian's Greatsword (Ludleth for Princes)Boss weapon for Twin Princes
FS: Lorian's Helm (shop after killing GA boss)Sold by Handmaid after defeating Lothric, Younger Prince
FS: Lorian's Leggings (shop after killing GA boss)Sold by Handmaid after defeating Lothric, Younger Prince
FS: Lothric's Holy Sword (Ludleth for Princes)Boss weapon for Twin Princes
FS: Magic Barrier (Irina for Tome of Lothric)Sold by Irina after giving her the Braille Divine Tome of Lothric
FS: Magic Shield (Orbeck)Sold by Orbeck
FS: Magic Shield (Yoel/Yuria)Sold by Yoel/Yuria
FS: Magic Weapon (Orbeck)Sold by Orbeck
FS: Magic Weapon (Yoel/Yuria)Sold by Yoel/Yuria
FS: Mail Breaker (Sirris for killing Creighton)Given by Sirris talking to her in Firelink Shrine after invading and vanquishing Creighton.
FS: Master's Attire (NPC drop)Dropped by Sword Master
FS: Master's Gloves (NPC drop)Dropped by Sword Master
FS: Med Heal (Irina for Tome of Carim)Sold by Irina after giving her the Braille Divine Tome of Carim
FS: Millwood Knight Armor (Captain's Ashes)Sold by Handmaid after giving Captain's Ashes
FS: Millwood Knight Gauntlets (Captain's Ashes)Sold by Handmaid after giving Captain's Ashes
FS: Millwood Knight Helm (Captain's Ashes)Sold by Handmaid after giving Captain's Ashes
FS: Millwood Knight Leggings (Captain's Ashes)Sold by Handmaid after giving Captain's Ashes
FS: Moaning Shield (Eygon)Dropped by Eygon of Carim
FS: Moonlight Greatsword (Ludleth for Oceiros)Boss weapon for Oceiros, the Consumed King
FS: Morion Blade (Yuria for Orbeck's Ashes)Given by Yuria after giving Orbeck's Ashes after she asks you to assassinate him, after he moves to Firelink Shrine. Can be done without killing Orbeck, by completing his questline.
FS: Morne's Armor (shop after killing Eygon or LC boss)Sold by Handmaid after killing Eygon of Carim or defeating Dragonslayer Armour
FS: Morne's Gauntlets (shop after killing Eygon or LC boss)Sold by Handmaid after killing Eygon of Carim or defeating Dragonslayer Armour
FS: Morne's Great Hammer (Eygon)Dropped by Eygon of Carim
FS: Morne's Helm (shop after killing Eygon or LC boss)Sold by Handmaid after killing Eygon of Carim or defeating Dragonslayer Armour
FS: Morne's Leggings (shop after killing Eygon or LC boss)Sold by Handmaid after killing Eygon of Carim or defeating Dragonslayer Armour
FS: Old King's Great Hammer (Ludleth for Old Demon King)Boss weapon for Old Demon King
FS: Old Moonlight (Ludleth for Midir)Boss weapon for Darkeater Midir
FS: Ordained Dress (shop after killing PW2 boss)Sold by Handmaid after defeating Sister Friede
FS: Ordained Hood (shop after killing PW2 boss)Sold by Handmaid after defeating Sister Friede
FS: Ordained Trousers (shop after killing PW2 boss)Sold by Handmaid after defeating Sister Friede
FS: Pale Shade Gloves (Yoel's room, kill Londor Pale Shade twice)In Yoel/Yuria's area after defeating both Londor Pale Shade invasions
FS: Pale Shade Robe (Yoel's room, kill Londor Pale Shade twice)In Yoel/Yuria's area after defeating both Londor Pale Shade invasions
FS: Pale Shade Trousers (Yoel's room, kill Londor Pale Shade twice)In Yoel/Yuria's area after defeating both Londor Pale Shade invasions
FS: Pestilent Mist (Orbeck for any scroll)Sold by Orbeck after giving him any scroll
FS: Poison Mist (Cornyx for Great Swamp Tome)Sold by Cornyx after giving him the Great Swamp Pyromancy Tome
FS: Pontiff's Left Eye (Ludleth for Vordt)Boss weapon for Vordt of the Boreal Valley
FS: Prisoner's Chain (Ludleth for Champion)Boss weapon for Champion Gundyr
FS: Profaned Greatsword (Ludleth for Pontiff)Boss weapon for Pontiff Sulyvahn
FS: Profuse Sweat (Cornyx for Great Swamp Tome)Sold by Cornyx after giving him the Great Swamp Pyromancy Tome
FS: Rapport (Karla for Quelana Tome)Sold by Karla after giving her the Quelana Pyromancy Tome
FS: Refined Gem (Captain's Ashes)Sold by Handmaid after giving Captain's Ashes
FS: Repair (Orbeck for Golden Scroll)Sold by Orbeck after giving him the Golden Scroll
FS: Repeating Crossbow (Ludleth for Gael)Boss weapon for Slave Knight Gael
FS: Replenishment (Irina)Sold by Irina after recruiting her, or in her ashes
FS: Ring of Sacrifice (Yuria shop)Sold by Yuria, or by Handmaid after giving Hollow's Ashes
FS: Rose of Ariandel (Ludleth for Friede)Boss weapon for Sister Friede
FS: Rusted Gold Coin (don't forgive Patches)Given by Patches after not forgiving him after he locks you in the Bell Tower.
FS: Sage's Big Hat (shop after killing RS boss)Sold by Handmaid after defeating Crystal Sage
FS: Saint's Ring (Irina)Sold by Irina after recruiting her, or in her ashes
FS: Seething Chaos (Ludleth for Demon Prince)Boss weapon for Demon Prince
FS: Silvercat Ring (Sirris for killing Creighton)Given by Sirris talking to her in Firelink Shrine after invading and vanquishing Creighton.
FS: Skull Ring (kill Ludleth)Dropped by Ludleth upon death, including after placing all cinders. Note that if killed before giving Transposing Kiln, transposition is not possible.
FS: Slumbering Dragoncrest Ring (Orbeck for buying four specific spells)Given by Orbeck after purchasing the shop items corresponding to Aural Decoy, Farron Flashsword, Spook (starting items), and Pestlient Mist (after giving one scroll).
FS: Smough's Armor (shop after killing AL boss)Sold by Handmaid after defeating Alrich, Devourer of Gods
FS: Smough's Gauntlets (shop after killing AL boss)Sold by Handmaid after defeating Alrich, Devourer of Gods
FS: Smough's Helm (shop after killing AL boss)Sold by Handmaid after defeating Alrich, Devourer of Gods
FS: Smough's Leggings (shop after killing AL boss)Sold by Handmaid after defeating Alrich, Devourer of Gods
FS: Sneering Mask (Yoel's room, kill Londor Pale Shade twice)In Yoel/Yuria's area after defeating both Londor Pale Shade invasions
FS: Soothing Sunlight (Ludleth for Dancer)Boss weapon for Dancer of the Boreal Valley
FS: Soul Arrow (Orbeck)Sold by Orbeck
FS: Soul Arrow (Yoel/Yuria)Sold by Yoel/Yuria
FS: Soul Arrow (shop)Sold by Handmaid
FS: Soul Greatsword (Orbeck)Sold by Orbeck
FS: Soul Greatsword (Yoel/Yuria)Sold by Yoel/Yuria after using Draw Out True Strength
FS: Soul Spear (Orbeck for Logan's Scroll)Sold by Orbeck after giving him Logan's Scroll
FS: Soul of a Deserted Corpse (bell tower door)Next to the door requiring the Tower Key
FS: Spook (Orbeck)Sold by Orbeck
FS: Storm Curved Sword (Ludleth for Nameless)Boss weapon for Nameless King
FS: Sunless Armor (shop, Sirris quest, kill GA boss)Sold by Handmaid after completing Sirris' questline
FS: Sunless Gauntlets (shop, Sirris quest, kill GA boss)Sold by Handmaid after completing Sirris' questline
FS: Sunless Leggings (shop, Sirris quest, kill GA boss)Sold by Handmaid after completing Sirris' questline
FS: Sunless Talisman (Sirris, kill GA boss)Dropped by Sirris on death or quest completion.
FS: Sunless Veil (shop, Sirris quest, kill GA boss)Sold by Handmaid after completing Sirris' questline
FS: Sunlight Spear (Ludleth for Cinder)Boss weapon for Soul of Cinder
FS: Sunset Shield (by grave after killing Hodrick w/Sirris)Left by Sirris upon quest completion.
FS: Tears of Denial (Irina for Tome of Carim)Sold by Irina after giving her the Braille Divine Tome of Carim
FS: Titanite Scale (Greirat from IBV)Sold by Greirat after pillaging Irithyll
FS: Titanite Slab (shop after placing all Cinders)Sold by Handmaid after placing all Cinders of a Lord on their thrones
FS: Tower Key (shop)Sold by both Shrine Handmaid and Untended Graves Handmaid
FS: Twinkling Titanite (Greirat from IBV)Sold by Greirat after pillaging Irithyll
FS: Twisted Wall of Light (Orbeck for Golden Scroll)Sold by Orbeck after giving him the Golden Scroll
FS: Uchigatana (NPC drop)Dropped by Sword Master
FS: Undead Legion Armor (shop after killing FK boss)Sold by Handmaid after defeating Abyss Watchers
FS: Undead Legion Gauntlet (shop after killing FK boss)Sold by Handmaid after defeating Abyss Watchers
FS: Undead Legion Helm (shop after killing FK boss)Sold by Handmaid after defeating Abyss Watchers
FS: Undead Legion Leggings (shop after killing FK boss)Sold by Handmaid after defeating Abyss Watchers
FS: Untrue Dark Ring (Yoel/Yuria)Sold by Yuria
FS: Untrue White Ring (Yoel/Yuria)Sold by Yuria
FS: Vordt's Great Hammer (Ludleth for Vordt)Boss weapon for Vordt of the Boreal Valley
FS: Vow of Silence (Karla for Londor Tome)Sold by Irina or Karla after giving one the Londor Braille Divine Tome
FS: Washing Pole (Easterner's Ashes)Sold by Handmaid after giving Easterner's Ashes
FS: White Dragon Breath (Ludleth for Oceiros)Boss weapon for Oceiros, the Consumed King
FS: White Sign Soapstone (shop)Sold by both Shrine Handmaid and Untended Graves Handmaid
FS: Wolf Knight's Greatsword (Ludleth for Abyss Watchers)Boss weapon for Abyss Watchers
FS: Wolf Ring+2 (left of boss room exit)After Iudex Gundyr on the left
FS: Wolnir's Crown (shop after killing CC boss)Sold by Handmaid after defeating High Lord Wolnir
FS: Wolnir's Holy Sword (Ludleth for Wolnir)Boss weapon for High Lord Wolnir
FS: Wood Grain Ring (Easterner's Ashes)Sold by Handmaid after giving Easterner's Ashes
FS: Xanthous Gloves (Xanthous Ashes)Sold by Handmaid after giving Xanthous Ashes
FS: Xanthous Overcoat (Xanthous Ashes)Sold by Handmaid after giving Xanthous Ashes
FS: Xanthous Trousers (Xanthous Ashes)Sold by Handmaid after giving Xanthous Ashes
FS: Yhorm's Great Machete (Ludleth for Yhorm)Boss weapon for Yhorm the Giant
FS: Yhorm's Greatshield (Ludleth for Yhorm)Boss weapon for Yhorm the Giant
FS: Young Dragon Ring (Orbeck for one scroll and buying three spells)Given by Orbeck after purchasing four sorceries from him, and giving him one scroll, as a non-sorcerer.
FSBT: Armor of the Sun (crow for Siegbräu)Trade Siegbrau with crow
FSBT: Blessed Gem (crow for Moaning Shield)Trade Moaning Shield with crow
FSBT: Covetous Silver Serpent Ring (illusory wall past rafters)From the Firelink Shrine roof, past the rafters and an illusory wall
FSBT: Estus Ring (tower base)Dropping down from the Bell Tower to where Irina eventually resides
FSBT: Estus Shard (rafters)In the Firelink Shrine rafters, accessible from the roof
FSBT: Fire Keeper Gloves (partway down tower)Dropping down to the left after entering the Bell Tower. Align with the center of the closest floor tile row and run off the edge at full speed, aiming slightly left.
FSBT: Fire Keeper Robe (partway down tower)Dropping down to the left after entering the Bell Tower. Align with the center of the closest floor tile row and run off the edge at full speed, aiming slightly left.
FSBT: Fire Keeper Skirt (partway down tower)Dropping down to the left after entering the Bell Tower. Align with the center of the closest floor tile row and run off the edge at full speed, aiming slightly left.
FSBT: Fire Keeper Soul (tower top)At the top of the Bell Tower
FSBT: Hello Carving (crow for Alluring Skull)Trade Alluring Skull with crow
FSBT: Help me! Carving (crow for any sacred chime)Trade any Sacred Chime with crow
FSBT: Hollow Gem (crow for Eleonora)Trade Eleonora with crow
FSBT: Homeward Bone (roof)On Firelink Shrine roof
FSBT: I'm sorry Carving (crow for Shriving Stone)Trade Shriving Stone with crow
FSBT: Iron Bracelets (crow for Homeward Bone)Trade Homeward Bone with crow
FSBT: Iron Helm (crow for Lightning Urn)Trade Lightning Urn with crow
FSBT: Iron Leggings (crow for Seed of a Giant Tree)Trade Seed of a Giant Tree with crow
FSBT: Large Titanite Shard (crow for Firebomb)Trade Firebomb or Rope Firebomb with crow
FSBT: Lightning Gem (crow for Xanthous Crown)Trade Xanthous Crown with crow
FSBT: Lucatiel's Mask (crow for Vertebra Shackle)Trade Vertebra Shackle with crow
FSBT: Porcine Shield (crow for Undead Bone Shard)Trade Undead Bone Shard with crow
FSBT: Ring of Sacrifice (crow for Loretta's Bone)Trade Loretta's Bone with crow
FSBT: Sunlight Shield (crow for Mendicant's Staff)Trade Mendicant's Staff with crow
FSBT: Thank you Carving (crow for Hidden Blessing)Trade Hidden Blessing with crow
FSBT: Titanite Chunk (crow for Black Firebomb)Trade Black Firebomb or Rope Black Firebomb with crow
FSBT: Titanite Scale (crow for Blacksmith Hammer)Trade Blacksmith Hammer with crow
FSBT: Titanite Slab (crow for Coiled Sword Fragment)Trade Coiled Sword Fragment with crow
FSBT: Twinkling Titanite (crow for Large Leather Shield)Trade Large Leather Shield with crow
FSBT: Twinkling Titanite (crow for Prism Stone)Trade Prism Stone with crow
FSBT: Twinkling Titanite (lizard behind Firelink)Dropped by the Crystal Lizard behind Firelink Shrine. Can be accessed with tree jump by going all the way around the roof, left of the entrance to the rafters, or alternatively dropping down from the Bell Tower.
FSBT: Very good! Carving (crow for Divine Blessing)Trade Divine Blessing with crow
GA: Avelyn (1F, drop from 3F onto bookshelves)On top of a bookshelf on the Archive first floor, accessible by going halfway up the stairs to the third floor, dropping down past the Grand Archives Scholar, and then dropping down again
GA: Black Hand Armor (shop after killing GA NPC)Sold by Handmaid after killing Black Hand Kumai
GA: Black Hand Hat (shop after killing GA NPC)Sold by Handmaid after killing Black Hand Kumai
GA: Blessed Gem (rafters)On the rafters high above the Archives, can be accessed by dropping down from the Winged Knight roof area
GA: Chaos Gem (dark room, lizard)Dropped by a Crystal Lizard on the Archives first floor in the dark room past the large wax pool
FK: Stone Parma - near wall by left islandAlong the inner wall of the keep, making an left from Farron Keep bonfire but before the area with the Darkwraith, guarded by a slug
FK: Sunlight Talisman - estus soup island, by ladder to keep properBy the pot of estus soup to the left of the stairs leading up to Old Wolf of Farron
FK: Titanite Scale - perimeter, miniboss dropDropped by Ravenous Crystal Lizard near the shortcut from Farron Keep back to Road of Sacrifices
FK: Titanite Shard - Farron Keep bonfire, left after exitAlong the inner wall of the keep, making an left from Farron Keep bonfire, by the second group of four slugs
FK: Titanite Shard - between left island and keep ruinsIn the swamp area with the Ghru Leaper between the Keep Ruins ritual fire and ritual fire straight ahead of Farron Keep bonfire, opposite from the keep wall
FK: Titanite Shard - by keep ruins ritual island stairsBy the stairs leading up to the Keep Ruins ritual fire from the middle of the swamp
FK: Titanite Shard - by ladder to keep properIn the swamp area close to the foot of the ladder leading to Old Wolf of Farron bonfire
FK: Titanite Shard - by left island stairsIn front of the stairs leading up to the ritual fire straight ahead of the Farron Keep bonfire
FK: Titanite Shard - keep ruins bonfire island, under rampUnder the ramp leading down from the Keep Ruins bonfire
FK: Titanite Shard - swamp by right islandBehind a tree patrolled by an Elder Ghru close to the ritual fire stairs
FK: Twinkling Dragon Head Stone - Hawkwood dropDropped by Hawkwood after killing him in the Abyss Watchers arena, after running up to the altar in Archdragon Peak. Twinkling Dragon Torso Stone needs to be acquired first.
FK: Twinkling Titanite - keep proper, lizardDropped by the Crystal Lizard on the balcony behind the Old Wolf of Farron bonfire
FK: Undead Bone Shard - pavilion by keep ruins bonfire islandIn a standalone pavillion down the ramp from Keep Ruins bonfire and to the right
FK: Watchdogs of Farron - Old WolfGiven by Old Wolf of Farron.
FK: Wolf Ring+1 - keep ruins bonfire island, outside buildingTo the right of the building with the Keep Ruins bonfire, when approached from the ritual fire
FK: Wolf's Blood Swordgrass - by ladder to keep properTo the left of the ladder leading up to the Old Wolf of Farron bonfire
FK: Young White Branch - by white tree #1Near the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FK: Young White Branch - by white tree #2Near the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows
FS: Acid Surge - Cornyx for Carthus TomeSold by Cornyx after giving him the Carthus Pyromancy Tome
FS: Affinity - KarlaSold by Karla after recruiting her, or in her ashes
FS: Alluring Skull - Mortician's AshesSold by Handmaid after giving Mortician's Ashes
FS: Arstor's Spear - Ludleth for GreatwoodBoss weapon for Curse-Rotted Greatwood
FS: Aural Decoy - OrbeckSold by Orbeck
FS: Billed Mask - Yuria after killing KFF bossDropped by Yuria upon death or quest completion.
FS: Black Dress - Yuria after killing KFF bossDropped by Yuria upon death or quest completion.
FS: Black Fire Orb - Karla for Grave Warden TomeSold by Karla after giving her the Grave Warden Pyromancy Tome
FS: Black Flame - Karla for Grave Warden TomeSold by Karla after giving her the Grave Warden Pyromancy Tome
FS: Black Gauntlets - Yuria after killing KFF bossDropped by Yuria upon death or quest completion.
FS: Black Iron Armor - shop after killing TsorigSold by Handmaid after killing Knight Slayer Tsorig in Smouldering Lake
FS: Black Iron Gauntlets - shop after killing TsorigSold by Handmaid after killing Knight Slayer Tsorig in Smouldering Lake
FS: Black Iron Helm - shop after killing TsorigSold by Handmaid after killing Knight Slayer Tsorig in Smouldering Lake
FS: Black Iron Leggings - shop after killing TsorigSold by Handmaid after killing Knight Slayer Tsorig in Smouldering Lake
FS: Black Leggings - Yuria after killing KFF bossDropped by Yuria upon death or quest completion.
FS: Black Serpent - Ludleth for WolnirBoss weapon for High Lord Wolnir
FS: Blessed Weapon - Irina for Tome of LothricSold by Irina after giving her the Braille Divine Tome of Lothric
FS: Blue Tearstone Ring - GreiratGiven by Greirat upon rescuing him from the High Wall cell
FS: Boulder Heave - Ludleth for Stray DemonBoss weapon for Stray Demon
FS: Bountiful Light - Irina for Tome of LothricSold by Irina after giving her the Braille Divine Tome of Lothric
FS: Bountiful Sunlight - Ludleth for RosariaBoss weapon for Rosaria, available after Leonhard is killed
FS: Broken Straight Sword - gravestone after bossNear the grave after Iudex Gundyr fight
FS: Budding Green Blossom - shop killing Creighton and AL bossSold by Handmaid after receiving Silvercat Ring item lot from Sirris and defeating Aldrich
FS: Bursting Fireball - Cornyx for Great Swamp TomeSold by Cornyx after giving him the Great Swamp Pyromancy Tome
FS: Caressing Tears - IrinaSold by Irina after recruiting her, or in her ashes
FS: Carthus Beacon - Cornyx for Carthus TomeSold by Cornyx after giving him the Carthus Pyromancy Tome
FS: Carthus Flame Arc - Cornyx for Carthus TomeSold by Cornyx after giving him the Carthus Pyromancy Tome
FS: Cast Light - Orbeck for Golden ScrollSold by Orbeck after giving him the Golden Scroll
FS: Chaos Bed Vestiges - Ludleth for Old Demon KingBoss weapon for Old Demon King
FS: Chaos Storm - Cornyx for Izalith TomeSold by Cornyx after giving him Izalith Pyromancy Tome
FS: Clandestine Coat - shop with Orbeck's AshesSold by Handmaid after giving Orbeck's Ashes and reloading
FS: Cleric's Candlestick - Ludleth for DeaconsBoss weapon for Deacons of the Deep
FS: Cracked Red Eye Orb - LeonhardGiven by Ringfinger Leonhard in Firelink Shrine after reaching Tower on the Wall bonfire
FS: Crystal Hail - Ludleth for SageBoss weapon for Crystal Sage
FS: Crystal Magic Weapon - Orbeck for Crystal ScrollSold by Orbeck after giving him the Crystal Scroll
FS: Crystal Sage's Rapier - Ludleth for SageBoss weapon for Crystal Sage
FS: Crystal Soul Spear - Orbeck for Crystal ScrollSold by Orbeck after giving him the Crystal Scroll
FS: Dancer's Armor - shop after killing LC entry bossSold by Handmaid after defeating Dancer of the Boreal Valley
FS: Dancer's Crown - shop after killing LC entry bossSold by Handmaid after defeating Dancer of the Boreal Valley
FS: Dancer's Enchanted Swords - Ludleth for DancerBoss weapon for Dancer of the Boreal Valley
FS: Dancer's Gauntlets - shop after killing LC entry bossSold by Handmaid after defeating Dancer of the Boreal Valley
FS: Dancer's Leggings - shop after killing LC entry bossSold by Handmaid after defeating Dancer of the Boreal Valley
FS: Dark Blade - Karla for Londor TomeSold by Irina or Karla after giving one the Londor Braille Divine Tome
FS: Dark Edge - KarlaSold by Karla after recruiting her, or in her ashes
FS: Dark Hand - Yoel/YuriaSold by Yuria
FS: Darkdrift - Yoel/YuriaDropped by Yuria upon death or quest completion.
FS: Darkmoon Longbow - Ludleth for AldrichBoss weapon for Aldrich
FS: Dead Again - Karla for Londor TomeSold by Irina or Karla after giving one the Londor Braille Divine Tome
FS: Deep Protection - Karla for Deep Braille TomeSold by Irina or Karla after giving one the Deep Braille Divine Tome
FS: Deep Soul - Ludleth for DeaconsBoss weapon for Deacons of the Deep
FS: Demon's Fist - Ludleth for Fire DemonBoss weapon for Fire Demon
FS: Demon's Greataxe - Ludleth for Fire DemonBoss weapon for Fire Demon
FS: Demon's Scar - Ludleth for Demon PrinceBoss weapon for Demon Prince
FS: Divine Blessing - Greirat from IBVSold by Greirat after pillaging Irithyll
FS: Divine Blessing - Greirat from USSold by Greirat after pillaging Undead Settlement
FS: Dragonscale Armor - shop after killing AP bossSold by Handmaid after defeating Nameless King
FS: Dragonscale Waistcloth - shop after killing AP bossSold by Handmaid after defeating Nameless King
FS: Dragonslayer Greataxe - Ludleth for DragonslayerBoss weapon for Dragonslayer Armour
FS: Dragonslayer Greatshield - Ludleth for DragonslayerBoss weapon for Dragonslayer Armour
FS: Dragonslayer Swordspear - Ludleth for NamelessBoss weapon for Nameless King
FS: Dried Finger - shopSold by both Shrine Handmaid and Untended Graves Handmaid
FS: East-West Shield - tree by shrine entranceIn a tree to the left of the Firelink Shrine entrance
FS: Eastern Armor - Easterner's AshesSold by Handmaid after giving Easterner's Ashes
FS: Eastern Gauntlets - Easterner's AshesSold by Handmaid after giving Easterner's Ashes
FS: Eastern Helm - Easterner's AshesSold by Handmaid after giving Easterner's Ashes
FS: Eastern Leggings - Easterner's AshesSold by Handmaid after giving Easterner's Ashes
FS: Elite Knight Armor - shop after Anri questSold by Handmaid after completing Anri's questline or killing Anri
FS: Elite Knight Gauntlets - shop after Anri questSold by Handmaid after completing Anri's questline or killing Anri
FS: Elite Knight Helm - shop after Anri questSold by Handmaid after completing Anri's questline or killing Anri
FS: Elite Knight Leggings - shop after Anri questSold by Handmaid after completing Anri's questline or killing Anri
FS: Ember - Dragon Chaser's AshesSold by Handmaid after giving Dragon Chaser's Ashes
FS: Ember - Grave Warden's AshesSold by Handmaid after giving Grave Warden's Ashes
FS: Ember - GreiratSold by Greirat after recruiting him, or in his ashes
FS: Ember - Greirat from USSold by Greirat after pillaging Undead Settlement
FS: Ember - Mortician's AshesSold by Handmaid after giving Mortician's Ashes
FS: Ember - above shrine entranceAbove the Firelink Shrine entrance, up stairs/slope from either left or right of the entrance
FS: Ember - path right of Firelink entranceOn a cliffside to the right of the main path leading up to Firelink Shrine, guarded by a dog
FS: Ember - shopSold by Handmaid
FS: Ember - shop for Greirat's AshesSold by Handmaid after Greirat pillages Lothric Castle and handing in ashes
FS: Embraced Armor of Favor - shop after killing water reserve minibossesSold by Handmaid after killing Sulyvahn's Beasts in Water Reserve
FS: Executioner Armor - shop after killing HoraceSold by Handmaid after killing Horace the Hushed
FS: Executioner Gauntlets - shop after killing HoraceSold by Handmaid after killing Horace the Hushed
FS: Executioner Helm - shop after killing HoraceSold by Handmaid after killing Horace the Hushed
FS: Executioner Leggings - shop after killing HoraceSold by Handmaid after killing Horace the Hushed
FS: Exile Armor - shop after killing NPCs in RSSold by Handmaid after killing the exiles just before Farron Keep
FS: Exile Gauntlets - shop after killing NPCs in RSSold by Handmaid after killing the exiles just before Farron Keep
FS: Exile Leggings - shop after killing NPCs in RSSold by Handmaid after killing the exiles just before Farron Keep
FS: Exile Mask - shop after killing NPCs in RSSold by Handmaid after killing the exiles just before Farron Keep
FS: Faraam Helm - shop after killing GA NPCSold by Handmaid after killing Lion Knight Albert
FS: Farron Dart - OrbeckSold by Orbeck
FS: Farron Dart - shopSold by Handmaid
FS: Farron Flashsword - OrbeckSold by Orbeck
FS: Farron Greatsword - Ludleth for Abyss WatchersBoss weapon for Abyss Watchers
FS: Farron Hail - Orbeck for Sage's ScrollSold by Orbeck after giving him the Sage's Scroll
FS: Farron Ring - HawkwoodGiven by Hawkwood, or dropped upon death, after defeating Abyss Watchers.
FS: Fire Orb - Cornyx for Great Swamp TomeSold by Cornyx after giving him the Great Swamp Pyromancy Tome
FS: Fire Surge - CornyxSold by Cornyx after recruiting him, or in his ashes
FS: Fire Whip - Karla for Quelana TomeSold by Karla after giving her the Quelana Pyromancy Tome
FS: Fireball - CornyxSold by Cornyx after recruiting him, or in his ashes
FS: Firelink Armor - shop after placing all CindersSold by Handmaid after defeating Soul of Cinder
FS: Firelink Gauntlets - shop after placing all CindersSold by Handmaid after defeating Soul of Cinder
FS: Firelink Greatsword - Ludleth for CinderBoss weapon for Soul of Cinder
FS: Firelink Helm - shop after placing all CindersSold by Handmaid after defeating Soul of Cinder
FS: Firelink Leggings - shop after placing all CindersSold by Handmaid after defeating Soul of Cinder
FS: Firestorm - Karla for Quelana TomeSold by Karla after giving her the Quelana Pyromancy Tome
FS: Flash Sweat - CornyxSold by Cornyx after recruiting him, or in his ashes
FS: Force - Irina for Tome of CarimSold by Irina after giving her the Braille Divine Tome of Carim
FS: Frayed Blade - Ludleth for MidirBoss weapon for Darkeater Midir
FS: Friede's Great Scythe - Ludleth for FriedeBoss weapon for Sister Friede
FS: Gael's Greatsword - Ludleth for GaelBoss weapon for Slave Knight Gael
FS: Gauntlets of Favor - shop after killing water reserve minibossesSold by Handmaid after killing Sulyvahn's Beasts in Water Reserve
FS: Gnaw - Karla for Deep Braille TomeSold by Irina or Karla after giving one the Deep Braille Divine Tome
FS: Golden Bracelets - shop after killing AP bossSold by Handmaid after defeating Nameless King
FS: Golden Crown - shop after killing AP bossSold by Handmaid after defeating Nameless King
FS: Grave Key - Mortician's AshesSold by Handmaid after giving Mortician's Ashes
FS: Great Chaos Fire Orb - Cornyx for Izalith TomeSold by Cornyx after giving him Izalith Pyromancy Tome
FS: Great Combustion - CornyxSold by Cornyx after recruiting him, or in his ashes
FS: Great Farron Dart - Orbeck for Sage's ScrollSold by Orbeck after giving him the Sage's Scroll
FS: Great Heavy Soul Arrow - OrbeckSold by Orbeck
FS: Great Soul Arrow - OrbeckSold by Orbeck
FS: Greatsword of Judgment - Ludleth for PontiffBoss weapon for Pontiff Sulyvahn
FS: Gundyr's Armor - shop after killing UG bossSold by Handmaid after defeating Champion Gundyr
FS: Gundyr's Gauntlets - shop after killing UG bossSold by Handmaid after defeating Champion Gundyr
FS: Gundyr's Halberd - Ludleth for ChampionBoss weapon for Champion Gundyr
FS: Gundyr's Helm - shop after killing UG bossSold by Handmaid after defeating Champion Gundyr
FS: Gundyr's Leggings - shop after killing UG bossSold by Handmaid after defeating Champion Gundyr
FS: Havel's Ring - Ludleth for Stray DemonBoss weapon for Stray Demon
FS: Hawkwood's Shield - HawkwoodLeft by Hawkwood after defeating Abyss Watchers, Curse-Rotted Greatwood, Deacons of the Deep, and Crystal Sage
FS: Hawkwood's Swordgrass - Andre after gesture in AP summitGiven by Andre after praying at the Dragon Altar in Archdragon Peak, after acquiring Twinkling Dragon Torso Stone.
FS: Heal - IrinaSold by Irina after recruiting her, or in her ashes
FS: Heal Aid - shopSold by Handmaid
FS: Heavy Soul Arrow - OrbeckSold by Orbeck
FS: Heavy Soul Arrow - Yoel/YuriaSold by Yoel/Yuria
FS: Helm of Favor - shop after killing water reserve minibossesSold by Handmaid after killing Sulyvahn's Beasts in Water Reserve
FS: Hidden Blessing - Dreamchaser's AshesSold by Greirat after pillaging Irithyll
FS: Hidden Blessing - Greirat from IBVSold by Greirat after pillaging Irithyll
FS: Hidden Body - Orbeck for Golden ScrollSold by Orbeck after giving him the Golden Scroll
FS: Hidden Weapon - Orbeck for Golden ScrollSold by Orbeck after giving him the Golden Scroll
FS: Hollowslayer Greatsword - Ludleth for GreatwoodBoss weapon for Curse-Rotted Greatwood
FS: Homeward - IrinaSold by Irina after recruiting her, or in her ashes
FS: Homeward Bone - cliff edge after bossAlong the cliff edge straight ahead of the Iudex Gundyr fight
FS: Homeward Bone - path above shrine entraceTo the right of the Firelink Shrine entrance, up a slope and before the ledge on top of a coffin
FS: Homing Crystal Soulmass - Orbeck for Crystal ScrollSold by Orbeck after giving him the Crystal Scroll
FS: Homing Soulmass - Orbeck for Logan's ScrollSold by Orbeck after giving him Logan's Scroll
FS: Karla's Coat - Prisoner Chief's AshesSold by Handmaid after giving Prisoner Chief's Ashes
FS: Karla's Coat - kill KarlaDropped from Karla upon death
FS: Karla's Gloves - Prisoner Chief's AshesSold by Handmaid after giving Prisoner Chief's Ashes
FS: Karla's Gloves - kill KarlaDropped from Karla upon death
FS: Karla's Pointed Hat - Prisoner Chief's AshesSold by Handmaid after giving Prisoner Chief's Ashes
FS: Karla's Pointed Hat - kill KarlaDropped from Karla upon death
FS: Karla's Trousers - Prisoner Chief's AshesSold by Handmaid after giving Prisoner Chief's Ashes
FS: Karla's Trousers - kill KarlaDropped from Karla upon death
FS: Leggings of Favor - shop after killing water reserve minibossesSold by Handmaid after killing Sulyvahn's Beasts in Water Reserve
FS: Leonhard's Garb - shop after killing LeonhardSold by Handmaid after killing Leonhard
FS: Leonhard's Gauntlets - shop after killing LeonhardSold by Handmaid after killing Leonhard
FS: Leonhard's Trousers - shop after killing LeonhardSold by Handmaid after killing Leonhard
FS: Life Ring - Dreamchaser's AshesSold by Handmaid after giving Dreamchaser's Ashes
FS: Lifehunt Scythe - Ludleth for AldrichBoss weapon for Aldrich
FS: Lift Chamber Key - LeonhardGiven by Ringfinger Leonhard after acquiring a Pale Tongue.
FS: Lightning Storm - Ludleth for NamelessBoss weapon for Nameless King
FS: Lloyd's Shield Ring - Paladin's AshesSold by Handmaid after giving Paladin's Ashes
FS: Londor Braille Divine Tome - Yoel/YuriaSold by Yuria
FS: Lorian's Armor - shop after killing GA bossSold by Handmaid after defeating Lothric, Younger Prince
FS: Lorian's Gauntlets - shop after killing GA bossSold by Handmaid after defeating Lothric, Younger Prince
FS: Lorian's Greatsword - Ludleth for PrincesBoss weapon for Twin Princes
FS: Lorian's Helm - shop after killing GA bossSold by Handmaid after defeating Lothric, Younger Prince
FS: Lorian's Leggings - shop after killing GA bossSold by Handmaid after defeating Lothric, Younger Prince
FS: Lothric's Holy Sword - Ludleth for PrincesBoss weapon for Twin Princes
FS: Magic Barrier - Irina for Tome of LothricSold by Irina after giving her the Braille Divine Tome of Lothric
FS: Magic Shield - OrbeckSold by Orbeck
FS: Magic Shield - Yoel/YuriaSold by Yoel/Yuria
FS: Magic Weapon - OrbeckSold by Orbeck
FS: Magic Weapon - Yoel/YuriaSold by Yoel/Yuria
FS: Mail Breaker - Sirris for killing CreightonGiven by Sirris talking to her in Firelink Shrine after invading and vanquishing Creighton.
FS: Master's Attire - NPC dropDropped by Sword Master
FS: Master's Gloves - NPC dropDropped by Sword Master
FS: Med Heal - Irina for Tome of CarimSold by Irina after giving her the Braille Divine Tome of Carim
FS: Millwood Knight Armor - Captain's AshesSold by Handmaid after giving Captain's Ashes
FS: Millwood Knight Gauntlets - Captain's AshesSold by Handmaid after giving Captain's Ashes
FS: Millwood Knight Helm - Captain's AshesSold by Handmaid after giving Captain's Ashes
FS: Millwood Knight Leggings - Captain's AshesSold by Handmaid after giving Captain's Ashes
FS: Moaning Shield - EygonDropped by Eygon of Carim
FS: Moonlight Greatsword - Ludleth for OceirosBoss weapon for Oceiros, the Consumed King
FS: Morion Blade - Yuria for Orbeck's AshesGiven by Yuria after giving Orbeck's Ashes after she asks you to assassinate him, after he moves to Firelink Shrine. Can be done without killing Orbeck, by completing his questline.
FS: Morne's Armor - shop after killing Eygon or LC bossSold by Handmaid after killing Eygon of Carim or defeating Dragonslayer Armour
FS: Morne's Gauntlets - shop after killing Eygon or LC bossSold by Handmaid after killing Eygon of Carim or defeating Dragonslayer Armour
FS: Morne's Great Hammer - EygonDropped by Eygon of Carim
FS: Morne's Helm - shop after killing Eygon or LC bossSold by Handmaid after killing Eygon of Carim or defeating Dragonslayer Armour
FS: Morne's Leggings - shop after killing Eygon or LC bossSold by Handmaid after killing Eygon of Carim or defeating Dragonslayer Armour
FS: Old King's Great Hammer - Ludleth for Old Demon KingBoss weapon for Old Demon King
FS: Old Moonlight - Ludleth for MidirBoss weapon for Darkeater Midir
FS: Ordained Dress - shop after killing PW2 bossSold by Handmaid after defeating Sister Friede
FS: Ordained Hood - shop after killing PW2 bossSold by Handmaid after defeating Sister Friede
FS: Ordained Trousers - shop after killing PW2 bossSold by Handmaid after defeating Sister Friede
FS: Pale Shade Gloves - Yoel's room, kill Londor Pale Shade twiceIn Yoel/Yuria's area after defeating both Londor Pale Shade invasions
FS: Pale Shade Robe - Yoel's room, kill Londor Pale Shade twiceIn Yoel/Yuria's area after defeating both Londor Pale Shade invasions
FS: Pale Shade Trousers - Yoel's room, kill Londor Pale Shade twiceIn Yoel/Yuria's area after defeating both Londor Pale Shade invasions
FS: Pestilent Mist - Orbeck for any scrollSold by Orbeck after giving him any scroll
FS: Poison Mist - Cornyx for Great Swamp TomeSold by Cornyx after giving him the Great Swamp Pyromancy Tome
FS: Pontiff's Left Eye - Ludleth for VordtBoss weapon for Vordt of the Boreal Valley
FS: Prisoner's Chain - Ludleth for ChampionBoss weapon for Champion Gundyr
FS: Profaned Greatsword - Ludleth for PontiffBoss weapon for Pontiff Sulyvahn
FS: Profuse Sweat - Cornyx for Great Swamp TomeSold by Cornyx after giving him the Great Swamp Pyromancy Tome
FS: Rapport - Karla for Quelana TomeSold by Karla after giving her the Quelana Pyromancy Tome
FS: Refined Gem - Captain's AshesSold by Handmaid after giving Captain's Ashes
FS: Repair - Orbeck for Golden ScrollSold by Orbeck after giving him the Golden Scroll
FS: Repeating Crossbow - Ludleth for GaelBoss weapon for Slave Knight Gael
FS: Replenishment - IrinaSold by Irina after recruiting her, or in her ashes
FS: Ring of Sacrifice - Yuria shopSold by Yuria, or by Handmaid after giving Hollow's Ashes
FS: Rose of Ariandel - Ludleth for FriedeBoss weapon for Sister Friede
FS: Rusted Gold Coin - don't forgive PatchesGiven by Patches after not forgiving him after he locks you in the Bell Tower.
FS: Sage's Big Hat - shop after killing RS bossSold by Handmaid after defeating Crystal Sage
FS: Saint's Ring - IrinaSold by Irina after recruiting her, or in her ashes
FS: Seething Chaos - Ludleth for Demon PrinceBoss weapon for Demon Prince
FS: Silvercat Ring - Sirris for killing CreightonGiven by Sirris talking to her in Firelink Shrine after invading and vanquishing Creighton.
FS: Skull Ring - kill LudlethDropped by Ludleth upon death, including after placing all cinders. Note that if killed before giving Transposing Kiln, transposition is not possible.
FS: Slumbering Dragoncrest Ring - Orbeck for buying four specific spellsGiven by Orbeck after purchasing the shop items corresponding to Aural Decoy, Farron Flashsword, Spook (starting items), and Pestlient Mist (after giving one scroll).
FS: Smough's Armor - shop after killing AL bossSold by Handmaid after defeating Alrich, Devourer of Gods
FS: Smough's Gauntlets - shop after killing AL bossSold by Handmaid after defeating Alrich, Devourer of Gods
FS: Smough's Helm - shop after killing AL bossSold by Handmaid after defeating Alrich, Devourer of Gods
FS: Smough's Leggings - shop after killing AL bossSold by Handmaid after defeating Alrich, Devourer of Gods
FS: Sneering Mask - Yoel's room, kill Londor Pale Shade twiceIn Yoel/Yuria's area after defeating both Londor Pale Shade invasions
FS: Soothing Sunlight - Ludleth for DancerBoss weapon for Dancer of the Boreal Valley
FS: Soul Arrow - OrbeckSold by Orbeck
FS: Soul Arrow - Yoel/YuriaSold by Yoel/Yuria
FS: Soul Arrow - shopSold by Handmaid
FS: Soul Greatsword - OrbeckSold by Orbeck
FS: Soul Greatsword - Yoel/YuriaSold by Yoel/Yuria after using Draw Out True Strength
FS: Soul Spear - Orbeck for Logan's ScrollSold by Orbeck after giving him Logan's Scroll
FS: Soul of a Deserted Corpse - bell tower doorNext to the door requiring the Tower Key
FS: Spook - OrbeckSold by Orbeck
FS: Storm Curved Sword - Ludleth for NamelessBoss weapon for Nameless King
FS: Sunless Armor - shop, Sirris quest, kill GA bossSold by Handmaid after completing Sirris' questline
FS: Sunless Gauntlets - shop, Sirris quest, kill GA bossSold by Handmaid after completing Sirris' questline
FS: Sunless Leggings - shop, Sirris quest, kill GA bossSold by Handmaid after completing Sirris' questline
FS: Sunless Talisman - Sirris, kill GA bossDropped by Sirris on death or quest completion.
FS: Sunless Veil - shop, Sirris quest, kill GA bossSold by Handmaid after completing Sirris' questline
FS: Sunlight Spear - Ludleth for CinderBoss weapon for Soul of Cinder
FS: Sunset Shield - by grave after killing Hodrick w/SirrisLeft by Sirris upon quest completion.
FS: Tears of Denial - Irina for Tome of CarimSold by Irina after giving her the Braille Divine Tome of Carim
FS: Titanite Scale - Greirat from IBVSold by Greirat after pillaging Irithyll
FS: Titanite Slab - shop after placing all CindersSold by Handmaid after placing all Cinders of a Lord on their thrones
FS: Tower Key - shopSold by both Shrine Handmaid and Untended Graves Handmaid
FS: Twinkling Titanite - Greirat from IBVSold by Greirat after pillaging Irithyll
FS: Twisted Wall of Light - Orbeck for Golden ScrollSold by Orbeck after giving him the Golden Scroll
FS: Uchigatana - NPC dropDropped by Sword Master
FS: Undead Legion Armor - shop after killing FK bossSold by Handmaid after defeating Abyss Watchers
FS: Undead Legion Gauntlet - shop after killing FK bossSold by Handmaid after defeating Abyss Watchers
FS: Undead Legion Helm - shop after killing FK bossSold by Handmaid after defeating Abyss Watchers
FS: Undead Legion Leggings - shop after killing FK bossSold by Handmaid after defeating Abyss Watchers
FS: Untrue Dark Ring - Yoel/YuriaSold by Yuria
FS: Untrue White Ring - Yoel/YuriaSold by Yuria
FS: Vordt's Great Hammer - Ludleth for VordtBoss weapon for Vordt of the Boreal Valley
FS: Vow of Silence - Karla for Londor TomeSold by Irina or Karla after giving one the Londor Braille Divine Tome
FS: Washing Pole - Easterner's AshesSold by Handmaid after giving Easterner's Ashes
FS: White Dragon Breath - Ludleth for OceirosBoss weapon for Oceiros, the Consumed King
FS: White Sign Soapstone - shopSold by both Shrine Handmaid and Untended Graves Handmaid
FS: Wolf Knight's Greatsword - Ludleth for Abyss WatchersBoss weapon for Abyss Watchers
FS: Wolf Ring+2 - left of boss room exitAfter Iudex Gundyr on the left
FS: Wolnir's Crown - shop after killing CC bossSold by Handmaid after defeating High Lord Wolnir
FS: Wolnir's Holy Sword - Ludleth for WolnirBoss weapon for High Lord Wolnir
FS: Wood Grain Ring - Easterner's AshesSold by Handmaid after giving Easterner's Ashes
FS: Xanthous Gloves - Xanthous AshesSold by Handmaid after giving Xanthous Ashes
FS: Xanthous Overcoat - Xanthous AshesSold by Handmaid after giving Xanthous Ashes
FS: Xanthous Trousers - Xanthous AshesSold by Handmaid after giving Xanthous Ashes
FS: Yhorm's Great Machete - Ludleth for YhormBoss weapon for Yhorm the Giant
FS: Yhorm's Greatshield - Ludleth for YhormBoss weapon for Yhorm the Giant
FS: Young Dragon Ring - Orbeck for one scroll and buying three spellsGiven by Orbeck after purchasing four sorceries from him, and giving him one scroll, as a non-sorcerer.
FSBT: Armor of the Sun - crow for SiegbräuTrade Siegbrau with crow
FSBT: Blessed Gem - crow for Moaning ShieldTrade Moaning Shield with crow
FSBT: Covetous Silver Serpent Ring - illusory wall past raftersFrom the Firelink Shrine roof, past the rafters and an illusory wall
FSBT: Estus Ring - tower baseDropping down from the Bell Tower to where Irina eventually resides
FSBT: Estus Shard - raftersIn the Firelink Shrine rafters, accessible from the roof
FSBT: Fire Keeper Gloves - partway down towerDropping down to the left after entering the Bell Tower. Align with the center of the closest floor tile row and run off the edge at full speed, aiming slightly left.
FSBT: Fire Keeper Robe - partway down towerDropping down to the left after entering the Bell Tower. Align with the center of the closest floor tile row and run off the edge at full speed, aiming slightly left.
FSBT: Fire Keeper Skirt - partway down towerDropping down to the left after entering the Bell Tower. Align with the center of the closest floor tile row and run off the edge at full speed, aiming slightly left.
FSBT: Fire Keeper Soul - tower topAt the top of the Bell Tower
FSBT: Hello Carving - crow for Alluring SkullTrade Alluring Skull with crow
FSBT: Help me! Carving - crow for any sacred chimeTrade any Sacred Chime with crow
FSBT: Hollow Gem - crow for EleonoraTrade Eleonora with crow
FSBT: Homeward Bone - roofOn Firelink Shrine roof
FSBT: I'm sorry Carving - crow for Shriving StoneTrade Shriving Stone with crow
FSBT: Iron Bracelets - crow for Homeward BoneTrade Homeward Bone with crow
FSBT: Iron Helm - crow for Lightning UrnTrade Lightning Urn with crow
FSBT: Iron Leggings - crow for Seed of a Giant TreeTrade Seed of a Giant Tree with crow
FSBT: Large Titanite Shard - crow for FirebombTrade Firebomb or Rope Firebomb with crow
FSBT: Lightning Gem - crow for Xanthous CrownTrade Xanthous Crown with crow
FSBT: Lucatiel's Mask - crow for Vertebra ShackleTrade Vertebra Shackle with crow
FSBT: Porcine Shield - crow for Undead Bone ShardTrade Undead Bone Shard with crow
FSBT: Ring of Sacrifice - crow for Loretta's BoneTrade Loretta's Bone with crow
FSBT: Sunlight Shield - crow for Mendicant's StaffTrade Mendicant's Staff with crow
FSBT: Thank you Carving - crow for Hidden BlessingTrade Hidden Blessing with crow
FSBT: Titanite Chunk - crow for Black FirebombTrade Black Firebomb or Rope Black Firebomb with crow
FSBT: Titanite Scale - crow for Blacksmith HammerTrade Blacksmith Hammer with crow
FSBT: Titanite Slab - crow for Coiled Sword FragmentTrade Coiled Sword Fragment with crow
FSBT: Twinkling Titanite - crow for Large Leather ShieldTrade Large Leather Shield with crow
FSBT: Twinkling Titanite - crow for Prism StoneTrade Prism Stone with crow
FSBT: Twinkling Titanite - lizard behind FirelinkDropped by the Crystal Lizard behind Firelink Shrine. Can be accessed with tree jump by going all the way around the roof, left of the entrance to the rafters, or alternatively dropping down from the Bell Tower.
FSBT: Very good! Carving - crow for Divine BlessingTrade Divine Blessing with crow
GA: Avelyn - 1F, drop from 3F onto bookshelvesOn top of a bookshelf on the Archive first floor, accessible by going halfway up the stairs to the third floor, dropping down past the Grand Archives Scholar, and then dropping down again
GA: Black Hand Armor - shop after killing GA NPCSold by Handmaid after killing Black Hand Kumai
GA: Black Hand Hat - shop after killing GA NPCSold by Handmaid after killing Black Hand Kumai
GA: Blessed Gem - raftersOn the rafters high above the Archives, can be accessed by dropping down from the Winged Knight roof area
GA: Chaos Gem - dark room, lizardDropped by a Crystal Lizard on the Archives first floor in the dark room past the large wax pool
GA: Cinders of a Lord - Lothric PrinceDropped by Twin Princes
GA: Crystal Chime (1F, path from wax pool)On the Archives first floor, in the room with the Lothric Knight, to the right
GA: Crystal Gem (1F, lizard by drop)Dropped by the Crystal Lizard on the Archives first floor along the left wall
GA: Crystal Scroll (2F late, miniboss drop)Dropped by the Grand Archives Crystal Sage
GA: Divine Blessing (rafters, down lower level ladder)In a chest reachable after dropping down from the Archives rafters and down a ladder near the Corpse-grub
GA: Divine Pillars of Light (cage above rafters)In a cage above the rafters high above the Archives, can be accessed by dropping down from the Winged Knight roof area
GA: Ember (5F, by entrance)On a balcony high in the Archives overlooking the area with the Grand Archives Scholars with a shortcut ladder, on the opposite side from the wax pool
GA: Estus Shard (dome, far balcony)On the Archives roof near the three Winged Knights, in a side area overlooking the ocean.
GA: Faraam Armor (shop after killing GA NPC)Sold by Handmaid after killing Lion Knight Albert
GA: Faraam Boots (shop after killing GA NPC)Sold by Handmaid after killing Lion Knight Albert
GA: Faraam Gauntlets (shop after killing GA NPC)Sold by Handmaid after killing Lion Knight Albert
GA: Fleshbite Ring (up stairs from 4F)From the first shortcut elevator with the movable bookshelf, past the Scholars right before going outside onto the roof, in an alcove to the right with many Clawed Curse bookshelves
GA: Golden Wing Crest Shield (outside 5F, NPC drop)Dropped by Lion Knight Albert before the stairs leading up to Twin Princes
GA: Heavy Gem (rooftops, lizard)Dropped by one of the pair of Crystal Lizards, on the right side, found going up a slope past the gargoyle on the Archives roof
GA: Hollow Gem (rooftops lower, in hall)Going onto the roof and down the first ladder, dropping down on either side from the ledge facing the ocean, in a tunnel underneath the ledge
GA: Homeward Bone (2F early balcony)On the Archives second floor, on the balcony with the ladder going up to the Crystal Sage
GA: Hunter's Ring (dome, very top)At the top of the ladder in roof the area with the Winged Knights
GA: Large Soul of a Crestfallen Knight (4F, back)In the back of a Clawed Curse-heavy corridor of bookshelves, in the area with the Grand Archives Scholars and dropdown ladder, after the first shortcut elevator with the movable bookshelf
GA: Large Soul of a Crestfallen Knight (outside 5F)In the middle of the area with the three human NPCs attacking you, before the Grand Archives bonfire shortcut elevator
GA: Lingering Dragoncrest Ring+2 (dome, room behind spire)Near the tower with the Winged Knights, up the stairs on the opposite side from the ladder leading up to the Hunter's Ring
GA: Onikiri and Ubadachi (outside 5F, NPC drop)Dropped by Black Hand Kamui before the stairs leading up to Twin Princes
GA: Outrider Knight Armor (3F, behind illusory wall, miniboss drop)Dropped by an Outrider Knight past the Crystal Sage's third floor location and an illusory wall
GA: Outrider Knight Gauntlets (3F, behind illusory wall, miniboss drop)Dropped by an Outrider Knight past the Crystal Sage's third floor location and an illusory wall
GA: Outrider Knight Helm (3F, behind illusory wall, miniboss drop)Dropped by an Outrider Knight past the Crystal Sage's third floor location and an illusory wall
GA: Outrider Knight Leggings (3F, behind illusory wall, miniboss drop)Dropped by an Outrider Knight past the Crystal Sage's third floor location and an illusory wall
GA: Power Within (dark room, behind retractable bookshelf)Behind a bookshelf in the dark room with the Crystal Lizards, moved by a lever in the same room
GA: Refined Gem (up stairs from 4F, lizard)Dropped by a Crystal Lizard found heading from the first elevator shortcut with the movable bookshelf, on the right side up the stairs before exiting to the roof
GA: Sage Ring+1 (rafters, second level down)On the rafters high above the Grand Archives, dropping down from the cage to the high rafters to the rafters below with the Corpse-grub
GA: Sage's Crystal Staff (outside 5F, NPC drop)Dropped by Daughter of Crystal Kriemhild before the stairs leading up to Twin Princes
GA: Scholar Ring (2F, between late and early)On the corpse of a sitting Archives Scholar between two bookshelves, accessible by activating a lever before crossing the bridge that is the Crystal Sage's final location
GA: Sharp Gem (rooftops, lizard)Dropped by one of the pair of Crystal Lizards, on the left side, found going up a slope past the gargoyle on the Archives roof
GA: Shriving Stone (2F late, by ladder from 3F)Going from the Crystal Sage's location on the third floor to its location on the bridge, after descending the ladder
GA: Soul Stream (3F, behind illusory wall)Past the Crystal Sage's third floor location, an illusory wall, and an Outrider Knight, on the corpse of a sitting Archives Scholar
GA: Soul of a Crestfallen Knight (1F, loop left after drop)On the Archives first floor, hugging the left wall, on a ledge that loops back around to the left wall
GA: Soul of a Crestfallen Knight (path to dome)On balcony of the building with the second shortcut elevator down to the bonfire, accessible by going up the spiral stairs to the left
GA: Soul of a Nameless Soldier (dark room)On the Archives first floor, after the wax pool, against a Clawed Curse bookshelf
GA: Soul of a Weary Warrior (rooftops, by lizards)On the Archives roof, going up the first rooftop slope where a Gargoyle always attacks you
GA: Crystal Chime - 1F, path from wax poolOn the Archives first floor, in the room with the Lothric Knight, to the right
GA: Crystal Gem - 1F, lizard by dropDropped by the Crystal Lizard on the Archives first floor along the left wall
GA: Crystal Scroll - 2F late, miniboss dropDropped by the Grand Archives Crystal Sage
GA: Divine Blessing - rafters, down lower level ladderIn a chest reachable after dropping down from the Archives rafters and down a ladder near the Corpse-grub
GA: Divine Pillars of Light - cage above raftersIn a cage above the rafters high above the Archives, can be accessed by dropping down from the Winged Knight roof area
GA: Ember - 5F, by entranceOn a balcony high in the Archives overlooking the area with the Grand Archives Scholars with a shortcut ladder, on the opposite side from the wax pool
GA: Estus Shard - dome, far balconyOn the Archives roof near the three Winged Knights, in a side area overlooking the ocean.
GA: Faraam Armor - shop after killing GA NPCSold by Handmaid after killing Lion Knight Albert
GA: Faraam Boots - shop after killing GA NPCSold by Handmaid after killing Lion Knight Albert
GA: Faraam Gauntlets - shop after killing GA NPCSold by Handmaid after killing Lion Knight Albert
GA: Fleshbite Ring - up stairs from 4FFrom the first shortcut elevator with the movable bookshelf, past the Scholars right before going outside onto the roof, in an alcove to the right with many Clawed Curse bookshelves
GA: Golden Wing Crest Shield - outside 5F, NPC dropDropped by Lion Knight Albert before the stairs leading up to Twin Princes
GA: Heavy Gem - rooftops, lizardDropped by one of the pair of Crystal Lizards, on the right side, found going up a slope past the gargoyle on the Archives roof
GA: Hollow Gem - rooftops lower, in hallGoing onto the roof and down the first ladder, dropping down on either side from the ledge facing the ocean, in a tunnel underneath the ledge
GA: Homeward Bone - 2F early balconyOn the Archives second floor, on the balcony with the ladder going up to the Crystal Sage
GA: Hunter's Ring - dome, very topAt the top of the ladder in roof the area with the Winged Knights
GA: Large Soul of a Crestfallen Knight - 4F, backIn the back of a Clawed Curse-heavy corridor of bookshelves, in the area with the Grand Archives Scholars and dropdown ladder, after the first shortcut elevator with the movable bookshelf
GA: Large Soul of a Crestfallen Knight - outside 5FIn the middle of the area with the three human NPCs attacking you, before the Grand Archives bonfire shortcut elevator
GA: Lingering Dragoncrest Ring+2 - dome, room behind spireNear the tower with the Winged Knights, up the stairs on the opposite side from the ladder leading up to the Hunter's Ring
GA: Onikiri and Ubadachi - outside 5F, NPC dropDropped by Black Hand Kamui before the stairs leading up to Twin Princes
GA: Outrider Knight Armor - 3F, behind illusory wall, miniboss dropDropped by an Outrider Knight past the Crystal Sage's third floor location and an illusory wall
GA: Outrider Knight Gauntlets - 3F, behind illusory wall, miniboss dropDropped by an Outrider Knight past the Crystal Sage's third floor location and an illusory wall
GA: Outrider Knight Helm - 3F, behind illusory wall, miniboss dropDropped by an Outrider Knight past the Crystal Sage's third floor location and an illusory wall
GA: Outrider Knight Leggings - 3F, behind illusory wall, miniboss dropDropped by an Outrider Knight past the Crystal Sage's third floor location and an illusory wall
GA: Power Within - dark room, behind retractable bookshelfBehind a bookshelf in the dark room with the Crystal Lizards, moved by a lever in the same room
GA: Refined Gem - up stairs from 4F, lizardDropped by a Crystal Lizard found heading from the first elevator shortcut with the movable bookshelf, on the right side up the stairs before exiting to the roof
GA: Sage Ring+1 - rafters, second level downOn the rafters high above the Grand Archives, dropping down from the cage to the high rafters to the rafters below with the Corpse-grub
GA: Sage's Crystal Staff - outside 5F, NPC dropDropped by Daughter of Crystal Kriemhild before the stairs leading up to Twin Princes
GA: Scholar Ring - 2F, between late and earlyOn the corpse of a sitting Archives Scholar between two bookshelves, accessible by activating a lever before crossing the bridge that is the Crystal Sage's final location
GA: Sharp Gem - rooftops, lizardDropped by one of the pair of Crystal Lizards, on the left side, found going up a slope past the gargoyle on the Archives roof
GA: Shriving Stone - 2F late, by ladder from 3FGoing from the Crystal Sage's location on the third floor to its location on the bridge, after descending the ladder
GA: Soul Stream - 3F, behind illusory wallPast the Crystal Sage's third floor location, an illusory wall, and an Outrider Knight, on the corpse of a sitting Archives Scholar
GA: Soul of a Crestfallen Knight - 1F, loop left after dropOn the Archives first floor, hugging the left wall, on a ledge that loops back around to the left wall
GA: Soul of a Crestfallen Knight - path to domeOn balcony of the building with the second shortcut elevator down to the bonfire, accessible by going up the spiral stairs to the left
GA: Soul of a Nameless Soldier - dark roomOn the Archives first floor, after the wax pool, against a Clawed Curse bookshelf
GA: Soul of a Weary Warrior - rooftops, by lizardsOn the Archives roof, going up the first rooftop slope where a Gargoyle always attacks you
GA: Soul of the Twin PrincesDropped by Twin Princes
GA: Titanite Chunk (1F, balcony)On the Archives first floor, on balcony overlooking the entrance opposite from the Grand Archives Scholars wax pool
GA: Titanite Chunk (1F, path from wax pool)On the Archives first floor, toward the Lothric Knight, turning right to a ledge leading back to the entrance area
GA: Titanite Chunk (1F, up right stairs)Going right after entering the Archives entrance and up the short flight of stairs
GA: Titanite Chunk (2F, by wax pool)Up the stairs from the Archives second floor on the right side from the entrance, in a corner near the small wax pool
GA: Titanite Chunk (2F, right after dark room)Exiting from the dark room with the Crystal Lizards on the first floor onto the second floor main room, then taking an immediate right
GA: Titanite Chunk (5F, far balcony)On a balcony outside where Lothric Knight stands on the top floor of the Archives, accessing by going right from the final wax pool or by dropping down from the gargoyle area
GA: Titanite Chunk (rooftopps, balcony)Going onto the roof and down the first ladder, all the way down the ledge facing the ocean to the right
GA: Titanite Chunk (rooftops lower, ledge by buttress)Going onto the roof and down the first ladder, dropping down on either side from the ledge facing the ocean, on a roof ledge to the right
GA: Titanite Chunk (rooftops, just before 5F)On the Archives roof, after a short dropdown, in the small area where the two Gargoyles attack you
GA: Titanite Scale (1F, drop from 2F late onto bookshelves, lizard)Dropped by a Crystal Lizard on first floor bookshelves. Can be acessed by dropping down to the left at the end of the bridge which is the Crystal Sage's final location
GA: Titanite Scale (1F, up stairs on bookshelf)On the Archives first floor, up a movable set of stairs near the large wax pool, on top of a bookshelf
GA: Titanite Scale (2F, titanite scale atop bookshelf)On top of a bookshelf on the Archive second floor, accessible by going halfway up the stairs to the third floor and dropping down near a Grand Archives Scholar
GA: Titanite Scale (3F, by ladder to 2F late)Going from the Crystal Sage's location on the third floor to its location on the bridge, on the left side of the ladder you descend, behind a table
GA: Titanite Scale (3F, corner up stairs)From the Grand Archives third floor up past the thralls, in a corner with bookshelves to the left
GA: Titanite Scale (5F, chest by exit)In a chest after the first elevator shortcut with the movable bookshelf, in the area with the Grand Archives Scholars, to the left of the stairwell leading up to the roof
GA: Titanite Scale (dark room, upstairs)Right after going up the stairs to the Archives second floor, on the left guarded by a Grand Archives Scholar and a sequence of Clawed Curse bookshelves
GA: Titanite Scale (rooftops lower, path to 2F)Going onto the roof and down the first ladder, dropping down on either side from the ledge facing the ocean, then going past the corvians all the way to the left and making a jump
GA: Titanite Slab (1F, after pulling 2F switch)In a chest on the Archives first floor, behind a bookshelf moved by pulling a lever in the middle of the second floor between two cursed bookshelves
GA: Titanite Slab (dome, kill all mobs)Dropped by killing all three Winged Knights on top of the Archives
GA: Titanite Slab (final elevator secret)At the bottom of the shortcut elevator right outside the Twin Princes fight. Requires sending the elevator up to the top from the middle, and then riding the lower elevator down.
GA: Twinkling Titanite (1F, lizard by drop)Dropped by the Crystal Lizard on the Archives first floor along the left wall
GA: Twinkling Titanite (2F, lizard by entrance)Dropped by the Crystal Lizard on the Archives second floor, going toward the stairs/balcony
GA: Twinkling Titanite (dark room, lizard #1)Dropped by a Crystal Lizard on the Archives first floor in the dark room past the large wax pool
GA: Twinkling Titanite (dark room, lizard #2)Dropped by a Crystal Lizard on the Archives first floor in the dark room past the large wax pool
GA: Twinkling Titanite (rafters, down lower level ladder)In a chest reachable after dropping down from the Archives rafters and down a ladder near the Corpse-grub
GA: Twinkling Titanite (rooftops, lizard #1)Dropped by one of the pair of Crystal Lizards, on the right side, found going up a slope past the gargoyle on the Archives roof
GA: Twinkling Titanite (rooftops, lizard #2)Dropped by one of the pair of Crystal Lizards, on the left side, found going up a slope past the gargoyle on the Archives roof
GA: Twinkling Titanite (up stairs from 4F, lizard)Dropped by a Crystal Lizard found heading from the first elevator shortcut with the movable bookshelf, on the right side up the stairs before exiting to the roof
GA: Undead Bone Shard (5F, by entrance)On the corpse of a sitting Archives Scholar on a balcony high in the Archives overlooking the area with the Grand Archives Scholars with a shortcut ladder, near the final wax pool
GA: Witch's Locks (dark room, behind retractable bookshelf)Behind a bookshelf in the dark room with the Crystal Lizards, moved by a lever in the same room
HWL: Astora Straight Sword (fort walkway, drop down)In the building with the Pus of Man on the roof, past the Lothric Knight down a hallway obscured by a wooden wheel, dropping down past the edge
HWL: Basin of Vows (Emma)Dropped by Emma upon killing her. This is possible to do at any time
HWL: Battle Axe (flame tower, mimic)Dropped by mimic in the building guarded by the fire-breathing wyvern
HWL: Binoculars (corpse tower, upper platform)In the area with the dead wyvern, at the top of a set of stairs past a Hollow Soldier
HWL: Black Firebomb (small roof over fountain)After roof with Pus of Man, on the edge of another rooftop to the left where you can drop down into Winged Knight area
HWL: Broadsword (fort, room off walkway)In the building with the Pus of Man on the roof, past the Lothric Knight in an alcove to the left
HWL: Cell Key (fort ground, down stairs)In the basement of the building with Pus of Man on the roof, down the stairs guarded by a dog
HWL: Claymore (flame plaza)In the area where the wyvern breathes fire, farthest away from the door
HWL: Club (flame plaza)In the area where the wyvern breathes fire, in the open
HWL: Ember (back tower, transforming hollow)Dropped by the Pus of Man on the tower to the right of the High Wall bonfire after transformation
HWL: Ember (flame plaza)In the area where the wyvern breathes fire, in the open
HWL: Ember (fort roof, transforming hollow)Dropped by the Pus of Man on the roof after the Tower on the Wall bonfire after transformation
HWL: Ember (fountain #1)In the area with the Winged Knight
HWL: Ember (fountain #2)In the area with the Winged Knight
HWL: Estus Shard (fort ground, on anvil)In the basement of the building with the Pus of Man on the roof, on the blacksmith anvil
HWL: Firebomb (corpse tower, under table)In the building near the dead wyvern, behind a table near the ladder you descend
HWL: Firebomb (fort roof)Next to the Pus of Man on the roof
HWL: Firebomb (top of ladder to fountain)By the long ladder leading down to the area with the Winged Knight
HWL: Firebomb (wall tower, beam)In the building with the Tower on the Wall bonfire, on a wooden beam overhanging the lower levels
HWL: Fleshbite Ring+1 (fort roof, jump to other roof)Jumping from the roof with the Pus of Man to a nearby building with a fenced roof
HWL: Gold Pine Resin (corpse tower, drop)Dropping past the dead wyvern, down the left path from the High Wall bonfire
HWL: Green Blossom (fort walkway, hall behind wheel)In the building with the Pus of Man on the roof, past the Lothric Knight down a hallway obscured by a wooden wheel
HWL: Green Blossom (shortcut, lower courtyard)In the courtyard at the bottom of the shortcut elevator
HWL: Large Soul of a Deserted Corpse (flame plaza)In the area where the wyvern breathes fire, behind one of the praying statues
HWL: Large Soul of a Deserted Corpse (fort roof)On the edge of the roof with the Pus of Man
HWL: Large Soul of a Deserted Corpse (platform by fountain)Coming from the elevator shortcut, on a side path to the left (toward Winged Knight area)
HWL: Longbow (back tower)Down the path from the right of the High Wall bonfire, where the Pus of Man and crossbowman are
HWL: Lucerne (promenade, side path)On one of the side paths from the main path connecting Dancer and Vordt fights, patrolled by a Lothric Knight
HWL: Mail Breaker (wall tower, path to Greirat)In the basement of the building with the Tower on the Wall bonfire on the roof, before Greirat's cell
HWL: Rapier (fountain, corner)In a corner in the area with the Winged Knight
HWL: Raw Gem (fort roof, lizard)Dropped by the Crystal Lizard on the rooftop after the Tower on the Wall bonfire
HWL: Red Eye Orb (wall tower, miniboss)Dropped by the Darkwraith past the Lift Chamber Key
HWL: Refined Gem (promenade miniboss)Dropped by the red-eyed Lothric Knight to the left of the Dancer's room entrance
HWL: Ring of Sacrifice (awning by fountain)Coming from the elevator shortcut, on a side path to the left (toward Winged Knight area), jumping onto a wooden support
HWL: Ring of the Evil Eye+2 (fort ground, far wall)In the basement of the building with the Pus of Man on the roof, on the far wall past the stairwell, behind some barrels
HWL: Silver Eagle Kite Shield (fort mezzanine)In the chest on the balcony overlooking the basement of the building with the Pus of Man on the roof
HWL: Small Lothric Banner (Emma)Given by Emma, or dropped upon death
GA: Titanite Chunk - 1F, balconyOn the Archives first floor, on balcony overlooking the entrance opposite from the Grand Archives Scholars wax pool
GA: Titanite Chunk - 1F, path from wax poolOn the Archives first floor, toward the Lothric Knight, turning right to a ledge leading back to the entrance area
GA: Titanite Chunk - 1F, up right stairsGoing right after entering the Archives entrance and up the short flight of stairs
GA: Titanite Chunk - 2F, by wax poolUp the stairs from the Archives second floor on the right side from the entrance, in a corner near the small wax pool
GA: Titanite Chunk - 2F, right after dark roomExiting from the dark room with the Crystal Lizards on the first floor onto the second floor main room, then taking an immediate right
GA: Titanite Chunk - 5F, far balconyOn a balcony outside where Lothric Knight stands on the top floor of the Archives, accessing by going right from the final wax pool or by dropping down from the gargoyle area
GA: Titanite Chunk - rooftopps, balconyGoing onto the roof and down the first ladder, all the way down the ledge facing the ocean to the right
GA: Titanite Chunk - rooftops lower, ledge by buttressGoing onto the roof and down the first ladder, dropping down on either side from the ledge facing the ocean, on a roof ledge to the right
GA: Titanite Chunk - rooftops, just before 5FOn the Archives roof, after a short dropdown, in the small area where the two Gargoyles attack you
GA: Titanite Scale - 1F, drop from 2F late onto bookshelves, lizardDropped by a Crystal Lizard on first floor bookshelves. Can be acessed by dropping down to the left at the end of the bridge which is the Crystal Sage's final location
GA: Titanite Scale - 1F, up stairs on bookshelfOn the Archives first floor, up a movable set of stairs near the large wax pool, on top of a bookshelf
GA: Titanite Scale - 2F, titanite scale atop bookshelfOn top of a bookshelf on the Archive second floor, accessible by going halfway up the stairs to the third floor and dropping down near a Grand Archives Scholar
GA: Titanite Scale - 3F, by ladder to 2F lateGoing from the Crystal Sage's location on the third floor to its location on the bridge, on the left side of the ladder you descend, behind a table
GA: Titanite Scale - 3F, corner up stairsFrom the Grand Archives third floor up past the thralls, in a corner with bookshelves to the left
GA: Titanite Scale - 5F, chest by exitIn a chest after the first elevator shortcut with the movable bookshelf, in the area with the Grand Archives Scholars, to the left of the stairwell leading up to the roof
GA: Titanite Scale - dark room, upstairsRight after going up the stairs to the Archives second floor, on the left guarded by a Grand Archives Scholar and a sequence of Clawed Curse bookshelves
GA: Titanite Scale - rooftops lower, path to 2FGoing onto the roof and down the first ladder, dropping down on either side from the ledge facing the ocean, then going past the corvians all the way to the left and making a jump
GA: Titanite Slab - 1F, after pulling 2F switchIn a chest on the Archives first floor, behind a bookshelf moved by pulling a lever in the middle of the second floor between two cursed bookshelves
GA: Titanite Slab - dome, kill all mobsDropped by killing all three Winged Knights on top of the Archives
GA: Titanite Slab - final elevator secretAt the bottom of the shortcut elevator right outside the Twin Princes fight. Requires sending the elevator up to the top from the middle, and then riding the lower elevator down.
GA: Twinkling Titanite - 1F, lizard by dropDropped by the Crystal Lizard on the Archives first floor along the left wall
GA: Twinkling Titanite - 2F, lizard by entranceDropped by the Crystal Lizard on the Archives second floor, going toward the stairs/balcony
GA: Twinkling Titanite - dark room, lizard #1Dropped by a Crystal Lizard on the Archives first floor in the dark room past the large wax pool
GA: Twinkling Titanite - dark room, lizard #2Dropped by a Crystal Lizard on the Archives first floor in the dark room past the large wax pool
GA: Twinkling Titanite - rafters, down lower level ladderIn a chest reachable after dropping down from the Archives rafters and down a ladder near the Corpse-grub
GA: Twinkling Titanite - rooftops, lizard #1Dropped by one of the pair of Crystal Lizards, on the right side, found going up a slope past the gargoyle on the Archives roof
GA: Twinkling Titanite - rooftops, lizard #2Dropped by one of the pair of Crystal Lizards, on the left side, found going up a slope past the gargoyle on the Archives roof
GA: Twinkling Titanite - up stairs from 4F, lizardDropped by a Crystal Lizard found heading from the first elevator shortcut with the movable bookshelf, on the right side up the stairs before exiting to the roof
GA: Undead Bone Shard - 5F, by entranceOn the corpse of a sitting Archives Scholar on a balcony high in the Archives overlooking the area with the Grand Archives Scholars with a shortcut ladder, near the final wax pool
GA: Witch's Locks - dark room, behind retractable bookshelfBehind a bookshelf in the dark room with the Crystal Lizards, moved by a lever in the same room
HWL: Astora Straight Sword - fort walkway, drop downIn the building with the Pus of Man on the roof, past the Lothric Knight down a hallway obscured by a wooden wheel, dropping down past the edge
HWL: Basin of Vows - EmmaDropped by Emma upon killing her. This is possible to do at any time
HWL: Battle Axe - flame tower, mimicDropped by mimic in the building guarded by the fire-breathing wyvern
HWL: Binoculars - corpse tower, upper platformIn the area with the dead wyvern, at the top of a set of stairs past a Hollow Soldier
HWL: Black Firebomb - small roof over fountainAfter roof with Pus of Man, on the edge of another rooftop to the left where you can drop down into Winged Knight area
HWL: Broadsword - fort, room off walkwayIn the building with the Pus of Man on the roof, past the Lothric Knight in an alcove to the left
HWL: Cell Key - fort ground, down stairsIn the basement of the building with Pus of Man on the roof, down the stairs guarded by a dog
HWL: Claymore - flame plazaIn the area where the wyvern breathes fire, farthest away from the door
HWL: Club - flame plazaIn the area where the wyvern breathes fire, in the open
HWL: Ember - back tower, transforming hollowDropped by the Pus of Man on the tower to the right of the High Wall bonfire after transformation
HWL: Ember - flame plazaIn the area where the wyvern breathes fire, in the open
HWL: Ember - fort roof, transforming hollowDropped by the Pus of Man on the roof after the Tower on the Wall bonfire after transformation
HWL: Ember - fountain #1In the area with the Winged Knight
HWL: Ember - fountain #2In the area with the Winged Knight
HWL: Estus Shard - fort ground, on anvilIn the basement of the building with the Pus of Man on the roof, on the blacksmith anvil
HWL: Firebomb - corpse tower, under tableIn the building near the dead wyvern, behind a table near the ladder you descend
HWL: Firebomb - fort roofNext to the Pus of Man on the roof
HWL: Firebomb - top of ladder to fountainBy the long ladder leading down to the area with the Winged Knight
HWL: Firebomb - wall tower, beamIn the building with the Tower on the Wall bonfire, on a wooden beam overhanging the lower levels
HWL: Fleshbite Ring+1 - fort roof, jump to other roofJumping from the roof with the Pus of Man to a nearby building with a fenced roof
HWL: Gold Pine Resin - corpse tower, dropDropping past the dead wyvern, down the left path from the High Wall bonfire
HWL: Green Blossom - fort walkway, hall behind wheelIn the building with the Pus of Man on the roof, past the Lothric Knight down a hallway obscured by a wooden wheel
HWL: Green Blossom - shortcut, lower courtyardIn the courtyard at the bottom of the shortcut elevator
HWL: Large Soul of a Deserted Corpse - flame plazaIn the area where the wyvern breathes fire, behind one of the praying statues
HWL: Large Soul of a Deserted Corpse - fort roofOn the edge of the roof with the Pus of Man
HWL: Large Soul of a Deserted Corpse - platform by fountainComing from the elevator shortcut, on a side path to the left (toward Winged Knight area)
HWL: Longbow - back towerDown the path from the right of the High Wall bonfire, where the Pus of Man and crossbowman are
HWL: Lucerne - promenade, side pathOn one of the side paths from the main path connecting Dancer and Vordt fights, patrolled by a Lothric Knight
HWL: Mail Breaker - wall tower, path to GreiratIn the basement of the building with the Tower on the Wall bonfire on the roof, before Greirat's cell
HWL: Rapier - fountain, cornerIn a corner in the area with the Winged Knight
HWL: Raw Gem - fort roof, lizardDropped by the Crystal Lizard on the rooftop after the Tower on the Wall bonfire
HWL: Red Eye Orb - wall tower, minibossDropped by the Darkwraith past the Lift Chamber Key
HWL: Refined Gem - promenade minibossDropped by the red-eyed Lothric Knight to the left of the Dancer's room entrance
HWL: Ring of Sacrifice - awning by fountainComing from the elevator shortcut, on a side path to the left (toward Winged Knight area), jumping onto a wooden support
HWL: Ring of the Evil Eye+2 - fort ground, far wallIn the basement of the building with the Pus of Man on the roof, on the far wall past the stairwell, behind some barrels
HWL: Silver Eagle Kite Shield - fort mezzanineIn the chest on the balcony overlooking the basement of the building with the Pus of Man on the roof
HWL: Small Lothric Banner - EmmaGiven by Emma, or dropped upon death
HWL: Soul of Boreal Valley VordtDropped by Vordt of the Boreal Valley
HWL: Soul of a Deserted Corpse (by wall tower door)Right before the entrance to the building with the Tower on the Wall bonfire
HWL: Soul of a Deserted Corpse (corpse tower, bottom floor)Down the ladder of the building near the dead wyvern, on the way to the living wyvern
HWL: Soul of a Deserted Corpse (fort entry, corner)In the corner of the room with a Lothric Knight, with the Pus of Man on the roof
HWL: Soul of a Deserted Corpse (fountain, path to promenade)In between the Winged Knight area and the Dancer/Vordt corridor
HWL: Soul of a Deserted Corpse (path to back tower, by lift door)Where the Greataxe Hollow Soldier patrols outside of the elevator shortcut entrance
HWL: Soul of a Deserted Corpse (path to corpse tower)At the very start, heading left from the High Wall bonfire
HWL: Soul of a Deserted Corpse (wall tower, right of exit)Exiting the building with the Tower on the Wall bonfire on the roof, immediately to the right
HWL: Soul of a Deserted Corpse - by wall tower doorRight before the entrance to the building with the Tower on the Wall bonfire
HWL: Soul of a Deserted Corpse - corpse tower, bottom floorDown the ladder of the building near the dead wyvern, on the way to the living wyvern
HWL: Soul of a Deserted Corpse - fort entry, cornerIn the corner of the room with a Lothric Knight, with the Pus of Man on the roof
HWL: Soul of a Deserted Corpse - fountain, path to promenadeIn between the Winged Knight area and the Dancer/Vordt corridor
HWL: Soul of a Deserted Corpse - path to back tower, by lift doorWhere the Greataxe Hollow Soldier patrols outside of the elevator shortcut entrance
HWL: Soul of a Deserted Corpse - path to corpse towerAt the very start, heading left from the High Wall bonfire
HWL: Soul of a Deserted Corpse - wall tower, right of exitExiting the building with the Tower on the Wall bonfire on the roof, immediately to the right
HWL: Soul of the DancerDropped by Dancer of the Boreal Valley
HWL: Standard Arrow (back tower)Down the path from the right of the High Wall bonfire, where the Pus of Man and crossbowman are
HWL: Throwing Knife (shortcut, lift top)At the top of the elevator shortcut, opposite from the one-way door
HWL: Throwing Knife (wall tower, path to Greirat)In the basement of the building with the Tower on the Wall bonfire, in the room with the explosive barrels
HWL: Titanite Shard (back tower, transforming hollow)Dropped by the Pus of Man on the tower to the right of the High Wall bonfire after transformation
HWL: Titanite Shard (fort ground behind crates)Behind some wooden crates in the basement of the building with the Pus of Man on the roof
HWL: Titanite Shard (fort roof, transforming hollow)Dropped by the Pus of Man on the roof after the Tower on the Wall bonfire after transformation
HWL: Titanite Shard (fort, room off entry)In the building with the Pus of Man on the roof, in a room to the left and up the short stairs
HWL: Titanite Shard (wall tower, corner by bonfire)On the balcony with the Tower on the Wall bonfire
HWL: Undead Hunter Charm (fort, room off entry, in pot)In the building with the Pus of Man on the roof, in a room to the left, in a pot you have to break
HWL: Way of Blue (Emma)Given by Emma or dropped upon death.
IBV: Blood Gem (descent, platform before lake)In front of the tree in the courtyard before going down the stairs to the lake leading to the Distant Manor bonfire
IBV: Blue Bug Pellet (ascent, in last building)In the final building before Pontiff's cathedral, coming from the sewer, on the first floor
IBV: Blue Bug Pellet (descent, dark room)In the dark area with the Irithyllian slaves, to the left of the staircase
IBV: Budding Green Blossom (central, by second fountain)Next to the fountain up the stairs from the Central Irithyll bonfire
IBV: Chloranthy Ring+1 (plaza, behind altar)In the area before and below Pontiff's cathedral, behind the central structure
IBV: Covetous Gold Serpent Ring+1 (descent, drop after dark room)After the dark area with the Irithyllian slaves, drop down to the right
IBV: Creighton's Steel Mask (bridge after killing Creighton)Following Sirris' questline, found on the bridge to Irithyll after being invaded by Creighton the Wanderer in the graveyard after the Church of Yorshka.
IBV: Divine Blessing (great hall, chest)In a chest up the stairs in the room with the Silver Knight staring at the painting
IBV: Divine Blessing (great hall, mob)One-time drop from the Silver Knight staring at the painting in Irithyll
IBV: Dorhys' Gnawing (Dorhys drop)Dropped by Cathedral Evangelist Dorhys, past an illusory railing past the Central Irithyll Fire Witches and to the left
IBV: Dragonslayer's Axe (Creighton drop)Following Sirris' questline, dropped by Creighton the Wanderer when he invades in the graveyard after the Church of Yorshka.
IBV: Dung Pie (sewer #1)In the area with the sewer centipedes
IBV: Dung Pie (sewer #2)In the area with the sewer centipedes
IBV: Ember (shortcut from church to cathedral)After the gate shortcut from Church of Yorshka to Pontiff's cathedral
IBV: Emit Force (Siegward)Given by Siegward meeting him in the Irithyll kitchen after the Sewer Centipedes.
IBV: Excrement-covered Ashes (sewer, by stairs)In the area with the sewer centipedes, before going up the stairs to the kitchen
IBV: Fading Soul (descent, cliff edge #1)In the graveyard down the stairs from the Church of Yorshka, at the cliff edge
IBV: Fading Soul (descent, cliff edge #2)In the graveyard down the stairs from the Church of Yorshka, at the cliff edge
IBV: Great Heal (lake, dead Corpse-Grub)On the Corpse-grub at the edge of the lake leading to the Distant Manor bonfire
IBV: Green Blossom (lake wall)On the wall of the lake leading to the Distant Manor bonfire
IBV: Green Blossom (lake, by Distant Manor)In the lake close to the Distant Manor bonfire
IBV: Green Blossom (lake, by stairs from descent)Going down the stairs into the lake leading to the Distant Manor bonfire
IBV: Homeward Bone (descent, before gravestone)In the graveyard down the stairs from the Church of Yorshka, in front of the grave with the Corvian
IBV: Kukri (descent, side path)Down the stairs from the graveyard after Church of Yorshka, before the group of dogs in the left path
IBV: Large Soul of a Nameless Soldier (ascent, after great hall)By the tree near the stairs from the sewer leading up to Pontiff's cathedral, where the first dogs attack you
IBV: Large Soul of a Nameless Soldier (central, by bonfire)By the Central Irithyll bonfire
IBV: Large Soul of a Nameless Soldier (central, by second fountain)Next to the fountain up the stairs from the Central Irithyll bonfire
IBV: Large Soul of a Nameless Soldier (lake island)On an island in the lake leading to the Distant Manor bonfire
IBV: Large Soul of a Nameless Soldier (stairs to plaza)On the path from Central Irithyll bonfire, before making the left toward Church of Yorshka
IBV: Large Titanite Shard (ascent, by elevator door)On the path from the sewer leading up to Pontiff's cathedral, to the right of the statue surrounded by dogs
IBV: Large Titanite Shard (ascent, down ladder in last building)Outside the final building before Pontiff's cathedral, coming from the sewer, dropping down to the left before the entrance
IBV: Large Titanite Shard (central, balcony just before plaza)From the Central Irithyll bonfire, on the balcony with the second Fire Witch.
IBV: Large Titanite Shard (central, side path after first fountain)Up the stairs from the Central Irithyll bonfire, on a railing to the right
IBV: Large Titanite Shard (great hall, mob)One-time drop from the Silver Knight staring at the painting in Irithyll
IBV: Large Titanite Shard (path to Dorhys)Before the area with Cathedral Evangelist Dorhys, past an illusory railing past the Central Irithyll Fire Witches
IBV: Large Titanite Shard (plaza, balcony overlooking ascent)On the path from Central Irithyll bonfire, instead of going left toward the Church of Yorshka, going right, on the balcony
IBV: Large Titanite Shard (plaza, by stairs to church)To the left of the stairs leading up to the Church of Yorshka from Central Irithyll
IBV: Leo Ring (great hall, chest)In a chest up the stairs in the room with the Silver Knight staring at the painting
IBV: Lightning Gem (plaza center)In the area before and below Pontiff's cathedral, in the center guarded by the enemies
IBV: Magic Clutch Ring (plaza, illusory wall)In the area before and below Pontiff's cathedral, behind an illusory wall to the right
IBV: Mirrah Chain Gloves (bridge after killing Creighton)Following Sirris' questline, found on the bridge to Irithyll after being invaded by Creighton the Wanderer in the graveyard after the Church of Yorshka.
IBV: Mirrah Chain Leggings (bridge after killing Creighton)Following Sirris' questline, found on the bridge to Irithyll after being invaded by Creighton the Wanderer in the graveyard after the Church of Yorshka.
IBV: Mirrah Chain Mail (bridge after killing Creighton)Following Sirris' questline, found on the bridge to Irithyll after being invaded by Creighton the Wanderer in the graveyard after the Church of Yorshka.
IBV: Proof of a Concord Kept (Church of Yorshka altar)At the altar in the Church of Yorshka
IBV: Rime-blue Moss Clump (central, by bonfire)By the Central Irithyll bonfire
IBV: Rime-blue Moss Clump (central, past second fountain)From the Central Irithyll bonfire, to the left before the first Fire Witch.
IBV: Ring of Sacrifice (lake, right of stairs from descent)Near the sewer centipede at the start of the lake leading to the Distant Manor bonfire
IBV: Ring of the Evil Eye (Anri)Given by Anri of Astora in the Church of Yorshka, or if told of Horace's whereabouts in the Catacombs
IBV: Ring of the Sun's First Born (fall from in front of cathedral)Dropping down from in front of Pontiff Sulyvahn's church toward the Church of Yorshka
IBV: Roster of Knights (descent, first landing)On the landing going down the stairs from Church of Yorshka to the graveyard
IBV: Rusted Gold Coin (Distant Manor, down stairs)Dropping down after the first set of stairs leading from Distant Manor bonfire
IBV: Rusted Gold Coin (descent, side path)Down the stairs from the graveyard after Church of Yorshka, guarded by the group of dogs in the left path
IBV: Shriving Stone (descent, dark room rafters)On the rafters in the dark area with the Irithyllian slaves
IBV: Siegbräu (Siegward)Given by Siegward meeting him in the Irithyll kitchen after the Sewer Centipedes.
IBV: Smough's Great Hammer (great hall, chest)In a chest up the stairs in the room with the Silver Knight staring at the painting
HWL: Standard Arrow - back towerDown the path from the right of the High Wall bonfire, where the Pus of Man and crossbowman are
HWL: Throwing Knife - shortcut, lift topAt the top of the elevator shortcut, opposite from the one-way door
HWL: Throwing Knife - wall tower, path to GreiratIn the basement of the building with the Tower on the Wall bonfire, in the room with the explosive barrels
HWL: Titanite Shard - back tower, transforming hollowDropped by the Pus of Man on the tower to the right of the High Wall bonfire after transformation
HWL: Titanite Shard - fort ground behind cratesBehind some wooden crates in the basement of the building with the Pus of Man on the roof
HWL: Titanite Shard - fort roof, transforming hollowDropped by the Pus of Man on the roof after the Tower on the Wall bonfire after transformation
HWL: Titanite Shard - fort, room off entryIn the building with the Pus of Man on the roof, in a room to the left and up the short stairs
HWL: Titanite Shard - wall tower, corner by bonfireOn the balcony with the Tower on the Wall bonfire
HWL: Undead Hunter Charm - fort, room off entry, in potIn the building with the Pus of Man on the roof, in a room to the left, in a pot you have to break
HWL: Way of Blue - EmmaGiven by Emma or dropped upon death.
IBV: Blood Gem - descent, platform before lakeIn front of the tree in the courtyard before going down the stairs to the lake leading to the Distant Manor bonfire
IBV: Blue Bug Pellet - ascent, in last buildingIn the final building before Pontiff's cathedral, coming from the sewer, on the first floor
IBV: Blue Bug Pellet - descent, dark roomIn the dark area with the Irithyllian slaves, to the left of the staircase
IBV: Budding Green Blossom - central, by second fountainNext to the fountain up the stairs from the Central Irithyll bonfire
IBV: Chloranthy Ring+1 - plaza, behind altarIn the area before and below Pontiff's cathedral, behind the central structure
IBV: Covetous Gold Serpent Ring+1 - descent, drop after dark roomAfter the dark area with the Irithyllian slaves, drop down to the right
IBV: Creighton's Steel Mask - bridge after killing CreightonFollowing Sirris' questline, found on the bridge to Irithyll after being invaded by Creighton the Wanderer in the graveyard after the Church of Yorshka.
IBV: Divine Blessing - great hall, chestIn a chest up the stairs in the room with the Silver Knight staring at the painting
IBV: Divine Blessing - great hall, mob dropOne-time drop from the Silver Knight staring at the painting in Irithyll
IBV: Dorhys' Gnawing - Dorhys dropDropped by Cathedral Evangelist Dorhys, past an illusory railing past the Central Irithyll Fire Witches and to the left
IBV: Dragonslayer's Axe - Creighton dropFollowing Sirris' questline, dropped by Creighton the Wanderer when he invades in the graveyard after the Church of Yorshka.
IBV: Dung Pie - sewer #1In the area with the sewer centipedes
IBV: Dung Pie - sewer #2In the area with the sewer centipedes
IBV: Ember - shortcut from church to cathedralAfter the gate shortcut from Church of Yorshka to Pontiff's cathedral
IBV: Emit Force - SiegwardGiven by Siegward meeting him in the Irithyll kitchen after the Sewer Centipedes.
IBV: Excrement-covered Ashes - sewer, by stairsIn the area with the sewer centipedes, before going up the stairs to the kitchen
IBV: Fading Soul - descent, cliff edge #1In the graveyard down the stairs from the Church of Yorshka, at the cliff edge
IBV: Fading Soul - descent, cliff edge #2In the graveyard down the stairs from the Church of Yorshka, at the cliff edge
IBV: Great Heal - lake, dead Corpse-GrubOn the Corpse-grub at the edge of the lake leading to the Distant Manor bonfire
IBV: Green Blossom - lake wallOn the wall of the lake leading to the Distant Manor bonfire
IBV: Green Blossom - lake, by Distant ManorIn the lake close to the Distant Manor bonfire
IBV: Green Blossom - lake, by stairs from descentGoing down the stairs into the lake leading to the Distant Manor bonfire
IBV: Homeward Bone - descent, before gravestoneIn the graveyard down the stairs from the Church of Yorshka, in front of the grave with the Corvian
IBV: Kukri - descent, side pathDown the stairs from the graveyard after Church of Yorshka, before the group of dogs in the left path
IBV: Large Soul of a Nameless Soldier - ascent, after great hallBy the tree near the stairs from the sewer leading up to Pontiff's cathedral, where the first dogs attack you
IBV: Large Soul of a Nameless Soldier - central, by bonfireBy the Central Irithyll bonfire
IBV: Large Soul of a Nameless Soldier - central, by second fountainNext to the fountain up the stairs from the Central Irithyll bonfire
IBV: Large Soul of a Nameless Soldier - lake islandOn an island in the lake leading to the Distant Manor bonfire
IBV: Large Soul of a Nameless Soldier - stairs to plazaOn the path from Central Irithyll bonfire, before making the left toward Church of Yorshka
IBV: Large Titanite Shard - ascent, by elevator doorOn the path from the sewer leading up to Pontiff's cathedral, to the right of the statue surrounded by dogs
IBV: Large Titanite Shard - ascent, down ladder in last buildingOutside the final building before Pontiff's cathedral, coming from the sewer, dropping down to the left before the entrance
IBV: Large Titanite Shard - central, balcony just before plazaFrom the Central Irithyll bonfire, on the balcony with the second Fire Witch.
IBV: Large Titanite Shard - central, side path after first fountainUp the stairs from the Central Irithyll bonfire, on a railing to the right
IBV: Large Titanite Shard - great hall, main floor mob dropOne-time drop from the Silver Knight staring at the painting in Irithyll
IBV: Large Titanite Shard - great hall, upstairs mob drop #1One-time drop from the Silver Knight on the balcony of the room with the painting
IBV: Large Titanite Shard - great hall, upstairs mob drop #2One-time drop from the Silver Knight on the balcony of the room with the painting
IBV: Large Titanite Shard - path to DorhysBefore the area with Cathedral Evangelist Dorhys, past an illusory railing past the Central Irithyll Fire Witches
IBV: Large Titanite Shard - plaza, balcony overlooking ascentOn the path from Central Irithyll bonfire, instead of going left toward the Church of Yorshka, going right, on the balcony
IBV: Large Titanite Shard - plaza, by stairs to churchTo the left of the stairs leading up to the Church of Yorshka from Central Irithyll
IBV: Leo Ring - great hall, chestIn a chest up the stairs in the room with the Silver Knight staring at the painting
IBV: Lightning Gem - plaza centerIn the area before and below Pontiff's cathedral, in the center guarded by the enemies
IBV: Magic Clutch Ring - plaza, illusory wallIn the area before and below Pontiff's cathedral, behind an illusory wall to the right
IBV: Mirrah Chain Gloves - bridge after killing CreightonFollowing Sirris' questline, found on the bridge to Irithyll after being invaded by Creighton the Wanderer in the graveyard after the Church of Yorshka.
IBV: Mirrah Chain Leggings - bridge after killing CreightonFollowing Sirris' questline, found on the bridge to Irithyll after being invaded by Creighton the Wanderer in the graveyard after the Church of Yorshka.
IBV: Mirrah Chain Mail - bridge after killing CreightonFollowing Sirris' questline, found on the bridge to Irithyll after being invaded by Creighton the Wanderer in the graveyard after the Church of Yorshka.
IBV: Proof of a Concord Kept - Church of Yorshka altarAt the altar in the Church of Yorshka
IBV: Rime-blue Moss Clump - central, by bonfireBy the Central Irithyll bonfire
IBV: Rime-blue Moss Clump - central, past second fountainFrom the Central Irithyll bonfire, to the left before the first Fire Witch.
IBV: Ring of Sacrifice - lake, right of stairs from descentNear the sewer centipede at the start of the lake leading to the Distant Manor bonfire
IBV: Ring of the Evil Eye - AnriGiven by Anri of Astora in the Church of Yorshka, or if told of Horace's whereabouts in the Catacombs
IBV: Ring of the Sun's First Born - fall from in front of cathedralDropping down from in front of Pontiff Sulyvahn's church toward the Church of Yorshka
IBV: Roster of Knights - descent, first landingOn the landing going down the stairs from Church of Yorshka to the graveyard
IBV: Rusted Gold Coin - Distant Manor, drop after stairsDropping down after the first set of stairs leading from Distant Manor bonfire
IBV: Rusted Gold Coin - descent, side pathDown the stairs from the graveyard after Church of Yorshka, guarded by the group of dogs in the left path
IBV: Shriving Stone - descent, dark room raftersOn the rafters in the dark area with the Irithyllian slaves
IBV: Siegbräu - SiegwardGiven by Siegward meeting him in the Irithyll kitchen after the Sewer Centipedes.
IBV: Smough's Great Hammer - great hall, chestIn a chest up the stairs in the room with the Silver Knight staring at the painting
IBV: Soul of Pontiff SulyvahnDropped by Pontiff Sulyvahn
IBV: Soul of a Weary Warrior (ascent, by final staircase)Toward the end of the path from the sewer leading up to Pontiff's cathedral, to the left of the final staircase
IBV: Soul of a Weary Warrior (central, by first fountain)By the Central Irithyll bonfire
IBV: Soul of a Weary Warrior (central, railing by first fountain)On the railing overlooking the Central Irithyll bonfire, at the very start
IBV: Soul of a Weary Warrior (plaza, side room lower)Dropping down from the path from Church of Yorshka to Pontiff, guarded by the pensive Fire Witch
IBV: Soul of a Weary Warrior (plaza, side room upper)In the path from Church of Yorshka to Pontiff's cathedral, at the broken ledge you can drop down onto the Fire Witch
IBV: Twinkling Titanite (central, lizard before plaza)Dropped by a Crystal Lizard past the Central Irithyll Fire Witches and to the left
IBV: Twinkling Titanite (descent, lizard behind illusory wall)Dropped by a Crystal Lizard behind an illusory wall before going down the stairs to the lake leading to the Distant Manor bonfire
IBV: Undead Bone Shard (descent, behind gravestone)In the graveyard down the stairs from the Church of Yorshka, behind the grave with the Corvian
IBV: Witchtree Branch (by Dorhys)In the area with Cathedral Evangelist Dorhys, past an illusory railing past the Central Irithyll Fire Witches
IBV: Wood Grain Ring+2 (ascent, right after great hall)Leaving the building with the Silver Knight staring at the painting, instead of going left up the stairs, go right
IBV: Yorshka's Spear (descent, dark room rafers chest)In a chest in the rafters of the dark area with the Irithyllian slaves
ID: Alva Armor (B3 near, by Karla's cell, after killing Alva)In the main Jailer cell block on the floor close to Karla's cell, if the invading Alva is killed
ID: Alva Gauntlets (B3 near, by Karla's cell, after killing Alva)In the main Jailer cell block on the floor close to Karla's cell, if the invading Alva is killed
ID: Alva Helm (B3 near, by Karla's cell, after killing Alva)In the main Jailer cell block on the floor close to Karla's cell, if the invading Alva is killed
ID: Alva Leggings (B3 near, by Karla's cell, after killing Alva)In the main Jailer cell block on the floor close to Karla's cell, if the invading Alva is killed
ID: Bellowing Dragoncrest Ring (drop from B1 towards pit)Dropping down from the Jailbreaker's Key shortcut at the end of the top corridor on the bonfire side in Irithyll Dungeon
ID: Covetous Gold Serpent Ring (Siegward's cell)In the Old Cell where Siegward is rescued
ID: Covetous Silver Serpent Ring+1 (pit lift, middle platform)On one of the platforms in elevator shaft of the shortcut elevator from the Giant Slave area to the Irithyll Dungeon bonfire
ID: Dark Clutch Ring (stairs between pit and B3, mimic)Dropped by the mimic found going past the Giant Slave to the sewer with the rats and the basilisks, up the first flight of stairs, on the left side
ID: Dragon Torso Stone (B3, outside lift)On the balcony corpse in the Path of the Dragon pose
ID: Dragonslayer Lightning Arrow (pit, mimic in hall)Dropped by the mimic in the side corridor from where the Giant Slave is standing, before the long ladder
ID: Dung Pie (B3, by path from pit)In the room with the Giant Hound Rats
ID: Dung Pie (pit, miniboss drop)Drop from the Giant Slave
ID: Dusk Crown Ring (B3 far, right cell)In the cell in the main Jailer cell block to the left of the Profaned Capital exit
ID: Ember (B3 center)At the center pillar in the main Jailer cell block
ID: Ember (B3 far right)In the main Jailer cell block, on the left side coming from the Profaned Capital
ID: Estus Shard (mimic on path from B2 to pit)Dropped by the mimic in the room after the outside area of Irithyll Dungeon overlooking Profaned Capital
ID: Fading Soul (B1 near, main hall)On the top corridor on the bonfire side in Irithyll Dungeon, close to the first Jailer
ID: Great Magic Shield (B2 near, mob drop in far left cell)One-time drop from the Infested Corpse in the bottom corridor on the bonfire side of Irithyll Dungeon, in the closest cell
ID: Homeward Bone (path from B2 to pit)In the part of Irithyll Dungeon overlooking the Profaned Capital, after exiting the last jail cell corridor
ID: Jailbreaker's Key (B1 far, cell after gate)In the cell of the top corridor opposite to the bonfire in Irithyll Dungeon
ID: Large Soul of a Nameless Soldier (B2 far, by lift)Taking the elevator up from the area you can use Path of the Dragon, before the one-way door
ID: Large Soul of a Nameless Soldier (B2, hall by stairs)At the end of the bottom corridor on the bonfire side in Irithyll Dungeon
ID: Large Soul of a Weary Warrior (just before Profaned Capital)In the open area before the bridge leading into Profaned Capital from Irithyll Dungeon
ID: Large Titanite Shard (B1 far, rightmost cell)In a cell on the far end of the top corridor opposite to the bonfire in Irithyll Dungeon, nearby the Jailer
ID: Large Titanite Shard (B1 near, just past bonfire)In the second cell on the right after Irithyll Dungeon bonfire
ID: Large Titanite Shard (B3 near, right corner)On the floor where the Giant Slave is standing
ID: Large Titanite Shard (pit)On the floor where the Giant Slave is standing
ID: Large Titanite Shard (stairs between pit and B3)In the main Jailer cell block, to the left of the hallway leading to the Path of the Dragon area
ID: Lightning Blade (B3 lift, middle platform)On the middle platform riding the elevator up from the Path of the Dragon area
ID: Lightning Bolt (awning over pit)On the wooden overhangs above the Giant Slave. Can be reached by dropping down after climbing the long ladder around the area where the Giant stands.
ID: Murakumo (Alva drop)Dropped by Alva, Seeker of the Spurned when he invades in the cliffside path to Irithyll Dungeon
ID: Old Cell Key (stairs between pit and B3)In a chest found going past the Giant Slave to the sewer with the rats and the basilisks, up the stairs to the end, on the right side
ID: Old Sorcerer Boots (B2 near, middle cell)In one of the cells on the bottom corridor on the bonfire side in Irithyll Dungeon, close to the bonfire, with many Infested Corpses
ID: Old Sorcerer Coat (B2 near, middle cell)In one of the cells on the bottom corridor on the bonfire side in Irithyll Dungeon, close to the bonfire, with many Infested Corpses
ID: Old Sorcerer Gauntlets (B2 near, middle cell)In one of the cells on the bottom corridor on the bonfire side in Irithyll Dungeon, close to the bonfire, with many Infested Corpses
ID: Old Sorcerer Hat (B2 near, middle cell)In one of the cells on the bottom corridor on the bonfire side in Irithyll Dungeon, close to the bonfire, with many Infested Corpses
ID: Pale Pine Resin (B1 far, cell with broken wall)In the jail cell with the broken wall in the top corridor opposite to the bonfire in Irithyll Dungeon, near the passive Wretch on the wall
ID: Pickaxe (path from pit to B3)Passing by the Giant Slave, before the tunnel with the rats and basilisks
ID: Prisoner Chief's Ashes (B2 near, locked cell by stairs)In the cell at the far end of the bottom corridor on the bonfire side in Irithyll Dungeon
ID: Profaned Coal (B3 far, left cell)In the room with the Wretches next to the main Jailer cell block, guarded by a Wretch
ID: Profaned Flame (pit)On the floor where the Giant Slave is standing
ID: Rusted Coin (B1 near, just past bonfire)In the first cell on the left from the Irithyll dungeon bonfire
ID: Rusted Gold Coin (B1 near, end of hall by door)In the third cell on the right from the Irithyll Dungeon bonfire
ID: Simple Gem (B2 far, cell by stairs)In the cell near the bottom corridor opposite to the bonfire in Irithyll Dungeon, adjacent to the room with three Jailers and Cage Spiders
ID: Soul of a Crestfallen Knight (balcony above pit)Under whether the Giant Slave is resting his head
ID: Soul of a Weary Warrior (by drop to pit)At the end of the room with many peasant hollows after the Estus Shard minic
ID: Soul of a Weary Warrior (stairs between pit and B3)Going past the Giant Slave to the sewer with the rats and the basilisks, up the first flight of stairs
ID: Titanite Chunk (balcony above pit, lizard)Dropped by the Crystal Lizard where the Giant Slave is resting his head
ID: Titanite Chunk (pit, miniboss drop)Drop from the Giant Slave
ID: Titanite Scale (B2 far, lizard)Dropped by the Crystal Lizard on the bottom corridor opposite from the bonfire in Irithyll Dungeon where a Wretch attacks you
ID: Titanite Scale (B3 far, mimic in hall)Dropped by the mimic in the main Jailer cell block
ID: Titanite Slab (Siegward)Given by Siegward after unlocking Old Cell or on quest completion
ID: Xanthous Ashes (B3 far, right cell)In the cell in the main Jailer cell block to the left of the Profaned Capital exit
IBV: Soul of a Weary Warrior - ascent, by final staircaseToward the end of the path from the sewer leading up to Pontiff's cathedral, to the left of the final staircase
IBV: Soul of a Weary Warrior - central, by first fountainBy the Central Irithyll bonfire
IBV: Soul of a Weary Warrior - central, railing by first fountainOn the railing overlooking the Central Irithyll bonfire, at the very start
IBV: Soul of a Weary Warrior - plaza, side room lowerDropping down from the path from Church of Yorshka to Pontiff, guarded by the pensive Fire Witch
IBV: Soul of a Weary Warrior - plaza, side room upperIn the path from Church of Yorshka to Pontiff's cathedral, at the broken ledge you can drop down onto the Fire Witch
IBV: Twinkling Titanite - central, lizard before plazaDropped by a Crystal Lizard past the Central Irithyll Fire Witches and to the left
IBV: Twinkling Titanite - descent, lizard behind illusory wallDropped by a Crystal Lizard behind an illusory wall before going down the stairs to the lake leading to the Distant Manor bonfire
IBV: Undead Bone Shard - descent, behind gravestoneIn the graveyard down the stairs from the Church of Yorshka, behind the grave with the Corvian
IBV: Witchtree Branch - by DorhysIn the area with Cathedral Evangelist Dorhys, past an illusory railing past the Central Irithyll Fire Witches
IBV: Wood Grain Ring+2 - ascent, right after great hallLeaving the building with the Silver Knight staring at the painting, instead of going left up the stairs, go right
IBV: Yorshka's Spear - descent, dark room rafers chestIn a chest in the rafters of the dark area with the Irithyllian slaves
ID: Alva Armor - B3 near, by Karla's cell, after killing AlvaIn the main Jailer cell block on the floor close to Karla's cell, if the invading Alva is killed
ID: Alva Gauntlets - B3 near, by Karla's cell, after killing AlvaIn the main Jailer cell block on the floor close to Karla's cell, if the invading Alva is killed
ID: Alva Helm - B3 near, by Karla's cell, after killing AlvaIn the main Jailer cell block on the floor close to Karla's cell, if the invading Alva is killed
ID: Alva Leggings - B3 near, by Karla's cell, after killing AlvaIn the main Jailer cell block on the floor close to Karla's cell, if the invading Alva is killed
ID: Bellowing Dragoncrest Ring - drop from B1 towards pitDropping down from the Jailbreaker's Key shortcut at the end of the top corridor on the bonfire side in Irithyll Dungeon
ID: Covetous Gold Serpent Ring - Siegward's cellIn the Old Cell where Siegward is rescued
ID: Covetous Silver Serpent Ring+1 - pit lift, middle platformOn one of the platforms in elevator shaft of the shortcut elevator from the Giant Slave area to the Irithyll Dungeon bonfire
ID: Dark Clutch Ring - stairs between pit and B3, mimicDropped by the mimic found going past the Giant Slave to the sewer with the rats and the basilisks, up the first flight of stairs, on the left side
ID: Dragon Torso Stone - B3, outside liftOn the balcony corpse in the Path of the Dragon pose
ID: Dragonslayer Lightning Arrow - pit, mimic in hallDropped by the mimic in the side corridor from where the Giant Slave is standing, before the long ladder
ID: Dung Pie - B3, by path from pitIn the room with the Giant Hound Rats
ID: Dung Pie - pit, miniboss dropDrop from the Giant Slave
ID: Dusk Crown Ring - B3 far, right cellIn the cell in the main Jailer cell block to the left of the Profaned Capital exit
ID: Ember - B3 centerAt the center pillar in the main Jailer cell block
ID: Ember - B3 far rightIn the main Jailer cell block, on the left side coming from the Profaned Capital
ID: Estus Shard - mimic on path from B2 to pitDropped by the mimic in the room after the outside area of Irithyll Dungeon overlooking Profaned Capital
ID: Fading Soul - B1 near, main hallOn the top corridor on the bonfire side in Irithyll Dungeon, close to the first Jailer
ID: Great Magic Shield - B2 near, mob drop in far left cellOne-time drop from the Infested Corpse in the bottom corridor on the bonfire side of Irithyll Dungeon, in the closest cell
ID: Homeward Bone - path from B2 to pitIn the part of Irithyll Dungeon overlooking the Profaned Capital, after exiting the last jail cell corridor
ID: Jailbreaker's Key - B1 far, cell after gateIn the cell of the top corridor opposite to the bonfire in Irithyll Dungeon
ID: Large Soul of a Nameless Soldier - B2 far, by liftTaking the elevator up from the area you can use Path of the Dragon, before the one-way door
ID: Large Soul of a Nameless Soldier - B2, hall by stairsAt the end of the bottom corridor on the bonfire side in Irithyll Dungeon
ID: Large Soul of a Weary Warrior - just before Profaned CapitalIn the open area before the bridge leading into Profaned Capital from Irithyll Dungeon
ID: Large Titanite Shard - B1 far, rightmost cellIn a cell on the far end of the top corridor opposite to the bonfire in Irithyll Dungeon, nearby the Jailer
ID: Large Titanite Shard - B1 near, by doorIn the main Jailer cell block, to the left of the hallway leading to the Path of the Dragon area
ID: Large Titanite Shard - B3 near, right cornerOn the floor where the Giant Slave is standing
ID: Large Titanite Shard - after bonfire, second cell on rightIn the second cell on the right after Irithyll Dungeon bonfire
ID: Large Titanite Shard - pitOn the floor where the Giant Slave is standing
ID: Large Titanite Shard - stairs between pit and B3Seemingly unused treasure
ID: Lightning Blade - B3 lift, middle platformOn the middle platform riding the elevator up from the Path of the Dragon area
ID: Lightning Bolt - awning over pitOn the wooden overhangs above the Giant Slave. Can be reached by dropping down after climbing the long ladder around the area where the Giant stands.
ID: Murakumo - Alva dropDropped by Alva, Seeker of the Spurned when he invades in the cliffside path to Irithyll Dungeon
ID: Old Cell Key - stairs between pit and B3In a chest found going past the Giant Slave to the sewer with the rats and the basilisks, up the stairs to the end, on the right side
ID: Old Sorcerer Boots - B2 near, middle cellIn one of the cells on the bottom corridor on the bonfire side in Irithyll Dungeon, close to the bonfire, with many Infested Corpses
ID: Old Sorcerer Coat - B2 near, middle cellIn one of the cells on the bottom corridor on the bonfire side in Irithyll Dungeon, close to the bonfire, with many Infested Corpses
ID: Old Sorcerer Gauntlets - B2 near, middle cellIn one of the cells on the bottom corridor on the bonfire side in Irithyll Dungeon, close to the bonfire, with many Infested Corpses
ID: Old Sorcerer Hat - B2 near, middle cellIn one of the cells on the bottom corridor on the bonfire side in Irithyll Dungeon, close to the bonfire, with many Infested Corpses
ID: Pale Pine Resin - B1 far, cell with broken wallIn the jail cell with the broken wall in the top corridor opposite to the bonfire in Irithyll Dungeon, near the passive Wretch on the wall
ID: Pickaxe - path from pit to B3Passing by the Giant Slave, before the tunnel with the rats and basilisks
ID: Prisoner Chief's Ashes - B2 near, locked cell by stairsIn the cell at the far end of the bottom corridor on the bonfire side in Irithyll Dungeon
ID: Profaned Coal - B3 far, left cellIn the room with the Wretches next to the main Jailer cell block, guarded by a Wretch
ID: Profaned Flame - pitOn the floor where the Giant Slave is standing
ID: Rusted Coin - after bonfire, first cell on leftIn the first cell on the left from the Irithyll dungeon bonfire
ID: Rusted Gold Coin - after bonfire, last cell on rightIn the third cell on the right from the Irithyll Dungeon bonfire
ID: Simple Gem - B2 far, cell by stairsIn the cell near the bottom corridor opposite to the bonfire in Irithyll Dungeon, adjacent to the room with three Jailers and Cage Spiders
ID: Soul of a Crestfallen Knight - balcony above pitUnder whether the Giant Slave is resting his head
ID: Soul of a Weary Warrior - by drop to pitAt the end of the room with many peasant hollows after the Estus Shard minic
ID: Soul of a Weary Warrior - stairs between pit and B3Going past the Giant Slave to the sewer with the rats and the basilisks, up the first flight of stairs
ID: Titanite Chunk - balcony above pit, lizardDropped by the Crystal Lizard where the Giant Slave is resting his head
ID: Titanite Chunk - pit, miniboss dropDrop from the Giant Slave
ID: Titanite Scale - B2 far, lizardDropped by the Crystal Lizard on the bottom corridor opposite from the bonfire in Irithyll Dungeon where a Wretch attacks you
ID: Titanite Scale - B3 far, mimic in hallDropped by the mimic in the main Jailer cell block
ID: Titanite Slab - SiegwardGiven by Siegward after unlocking Old Cell or on quest completion
ID: Xanthous Ashes - B3 far, right cellIn the cell in the main Jailer cell block to the left of the Profaned Capital exit
KFF: Soul of the LordsDropped by Soul of Cinder
LC: Black Firebomb (dark room lower)In the room with the firebomb-throwing hollows, against the wall on the lowest level
LC: Braille Divine Tome of Lothric (wyvern room)In the room next to the second Pus of Man wyvern
LC: Caitha's Chime (chapel, drop onto roof)Dropping down from the chapel balcony where the Red Tearstone Ring is found, and then dropping down again towards the Lothric knights
LC: Dark Stoneplate Ring+1 (wyvern room, balcony)Through the room next to the second Pus of Man wyvern, on the balcony outside
LC: Ember (by Dragon Barracks bonfire)Near the Dragon Barracks bonfire
LC: Ember (dark room mid, pus of man mob drop)Dropped by the first Pus of Man wyvern
LC: Ember (main hall, left of stairs)To the left of the stairs past the Dragon Barracks grate
LC: Ember (plaza center)In the area where the Pus of Man wyverns breathe fire
LC: Ember (plaza, by gate)On the railing near the area where the Pus of Man wyverns breathe fire, before the gate
LC: Ember (wyvern room, wyvern foot mob drop)Dropped by the second Pus of Man wyvern
LC: Gotthard Twinswords (by Grand Archives door, after PC and AL bosses)Before the door to the Grand Archives after Aldrich and Yhorm are killed
LC: Grand Archives Key (by Grand Archives door, after PC and AL bosses)Before the door to the Grand Archives after Aldrich and Yhorm are killed
LC: Greatlance (overlooking Dragon Barracks bonfire)Guarded by a pensive Lothric Knight after the Dragon Barracks bonfire and continuing up the stairs
LC: Black Firebomb - dark room lowerIn the room with the firebomb-throwing hollows, against the wall on the lowest level
LC: Braille Divine Tome of Lothric - wyvern roomIn the room next to the second Pus of Man wyvern
LC: Caitha's Chime - chapel, drop onto roofDropping down from the chapel balcony where the Red Tearstone Ring is found, and then dropping down again towards the Lothric knights
LC: Dark Stoneplate Ring+1 - wyvern room, balconyThrough the room next to the second Pus of Man wyvern, on the balcony outside
LC: Ember - by Dragon Barracks bonfireNear the Dragon Barracks bonfire
LC: Ember - dark room mid, pus of man mob dropDropped by the first Pus of Man wyvern
LC: Ember - main hall, left of stairsTo the left of the stairs past the Dragon Barracks grate
LC: Ember - plaza centerIn the area where the Pus of Man wyverns breathe fire
LC: Ember - plaza, by gateOn the railing near the area where the Pus of Man wyverns breathe fire, before the gate
LC: Ember - wyvern room, wyvern foot mob dropDropped by the second Pus of Man wyvern
LC: Gotthard Twinswords - by Grand Archives door, after PC and AL bossesBefore the door to the Grand Archives after Aldrich and Yhorm are killed
LC: Grand Archives Key - by Grand Archives door, after PC and AL bossesBefore the door to the Grand Archives after Aldrich and Yhorm are killed
LC: Greatlance - overlooking Dragon Barracks bonfireGuarded by a pensive Lothric Knight after the Dragon Barracks bonfire and continuing up the stairs
LC: Hood of PrayerIn a chest right after the Lothric Castle bonfire
LC: Irithyll Rapier (basement, miniboss drop)Dropped by the Boreal Outrider Knight in the basement
LC: Knight's Ring (altar)Climbing the ladder to the rooftop outside the Dragonslayer Armour fight, past the Large Hollow Soldier, down into the room with the tables
LC: Large Soul of a Nameless Soldier (dark room mid)In the room with the firebomb-throwing hollows, up the ladder
LC: Large Soul of a Nameless Soldier (moat, right path)Found on the ledge after dropping into the area with the Pus of Man transforming hollows and making the entire loop
LC: Large Soul of a Nameless Soldier (plaza left, by pillar)In the building to the left of the area where the Pus of Man wyverns breathe fire, against a pillar
LC: Large Soul of a Weary Warrior (ascent, last turret)Rather than going up the stairs to the Dragon Barracks bonfire, continue straight down the stairs and forwards
LC: Large Soul of a Weary Warrior (main hall, by lever)On a ledge to the right of the lever opening the grate
LC: Life Ring+2 (dark room mid, out door opposite wyvern, drop down)Past the room with the firebomb-throwing hollows and Pus of Man wyvern, around to the front, dropping down past where the Titanite Chunk is
LC: Lightning Urn (moat, right path, first room)Starting the loop from where the Pus of Man hollows transform, behind some crates in the first room
LC: Lightning Urn (plaza)In the area where the Pus of Man wyverns breathe fire
LC: Pale Pine Resin (dark room upper, by mimic)In the room with the firebomb-throwing hollows, next to the mimic in the far back left
LC: Raw Gem (plaza left)On a balcony to the left of the area where the Pus of Man wyverns breathe fire, where the Hollow Soldier throws Undead Hunter Charms
LC: Red Tearstone Ring (chapel, drop onto roof)From the chapel to the right of the Dragonslayer Armour fight, on the balcony to the left
LC: Refined Gem (plaza)In the area where the Pus of Man wyverns breathe fire
LC: Robe of Prayer (ascent, chest at beginning)In a chest right after the Lothric Castle bonfire
LC: Rusted Coin (chapel)In the chapel to the right of the Dragonslayer Armour fight
LC: Sacred Bloom Shield (ascent, behind illusory wall)Up the ladder where the Winged Knight is waiting, past an illusory wall
LC: Skirt of Prayer (ascent, chest at beginning)In a chest right after the Lothric Castle bonfire
LC: Sniper Bolt (moat, right path end)Hanging from the arch passed under on the way to the Dragon Barracks bonfire. Can be accessed by dropping into the area with the Pus of Man transforming hollows and making the entire loop, but going left at the end
LC: Sniper Crossbow (moat, right path end)Hanging from the arch passed under on the way to the Dragon Barracks bonfire. Can be accessed by dropping into the area with the Pus of Man transforming hollows and making the entire loop, but going left at the end
LC: Irithyll Rapier - basement, miniboss dropDropped by the Boreal Outrider Knight in the basement
LC: Knight's Ring - altarClimbing the ladder to the rooftop outside the Dragonslayer Armour fight, past the Large Hollow Soldier, down into the room with the tables
LC: Large Soul of a Nameless Soldier - dark room midIn the room with the firebomb-throwing hollows, up the ladder
LC: Large Soul of a Nameless Soldier - moat, right pathFound on the ledge after dropping into the area with the Pus of Man transforming hollows and making the entire loop
LC: Large Soul of a Nameless Soldier - plaza left, by pillarIn the building to the left of the area where the Pus of Man wyverns breathe fire, against a pillar
LC: Large Soul of a Weary Warrior - ascent, last turretRather than going up the stairs to the Dragon Barracks bonfire, continue straight down the stairs and forwards
LC: Large Soul of a Weary Warrior - main hall, by leverOn a ledge to the right of the lever opening the grate
LC: Life Ring+2 - dark room mid, out door opposite wyvern, drop downPast the room with the firebomb-throwing hollows and Pus of Man wyvern, around to the front, dropping down past where the Titanite Chunk is
LC: Lightning Urn - moat, right path, first roomStarting the loop from where the Pus of Man hollows transform, behind some crates in the first room
LC: Lightning Urn - plazaIn the area where the Pus of Man wyverns breathe fire
LC: Pale Pine Resin - dark room upper, by mimicIn the room with the firebomb-throwing hollows, next to the mimic in the far back left
LC: Raw Gem - plaza leftOn a balcony to the left of the area where the Pus of Man wyverns breathe fire, where the Hollow Soldier throws Undead Hunter Charms
LC: Red Tearstone Ring - chapel, drop onto roofFrom the chapel to the right of the Dragonslayer Armour fight, on the balcony to the left
LC: Refined Gem - plazaIn the area where the Pus of Man wyverns breathe fire
LC: Robe of Prayer - ascent, chest at beginningIn a chest right after the Lothric Castle bonfire
LC: Rusted Coin - chapelIn the chapel to the right of the Dragonslayer Armour fight
LC: Sacred Bloom Shield - ascent, behind illusory wallUp the ladder where the Winged Knight is waiting, past an illusory wall
LC: Skirt of Prayer - ascent, chest at beginningIn a chest right after the Lothric Castle bonfire
LC: Sniper Bolt - moat, right path endHanging from the arch passed under on the way to the Dragon Barracks bonfire. Can be accessed by dropping into the area with the Pus of Man transforming hollows and making the entire loop, but going left at the end
LC: Sniper Crossbow - moat, right path endHanging from the arch passed under on the way to the Dragon Barracks bonfire. Can be accessed by dropping into the area with the Pus of Man transforming hollows and making the entire loop, but going left at the end
LC: Soul of Dragonslayer ArmourDropped by Dragonslayer Armour
LC: Soul of a Crestfallen Knight (by lift bottom)Guarded by a buffed Lothric Knight straight from the Dancer bonfire
LC: Soul of a Crestfallen Knight (wyvern room, balcony)On a ledge accessible after the second Pus of Man wyvern is defeated
LC: Spirit Tree Crest Shield (basement, chest)In a chest in the basement with the Outrider Knight
LC: Sunlight Medal (by lift top)Next to the shortcut elevator outside of the Dragonslayer Armour fight that goes down to the start of the area
LC: Sunlight Straight Sword (wyvern room, mimic)Dropped by the mimic in the room next to the second Pus of Man wyvern
LC: Thunder Stoneplate Ring+2 (chapel, drop onto roof)Dropping down from the chapel balcony where the Red Tearstone Ring is found, out on the edge
LC: Titanite Chunk (altar roof)Climbing the ladder to the rooftop outside the Dragonslayer Armour fight, overlooking the tree
LC: Titanite Chunk (ascent, final turret)Rather than going up the stairs to the Dragon Barracks bonfire, continue straight down the stairs, then right
LC: Titanite Chunk (ascent, first balcony)Right after the Lothric Castle bonfire, out on the balcony
LC: Titanite Chunk (ascent, turret before barricades)From the Lothric Castle bonfire, up the stairs, straight, and then down the stairs behind the barricade
LC: Titanite Chunk (dark room mid, out door opposite wyvern)From the room with the firebomb-throwing hollows, past the Pus of Man Wyvern and back around the front, before the Crystal Lizard
LC: Titanite Chunk (dark room mid, pus of man mob drop)Dropped by the first Pus of Man wyvern
LC: Titanite Chunk (down stairs after boss)Down the stairs to the right after Dragonslayer Armour
LC: Titanite Chunk (moat #1)In the center of the area where the Pus of Man hollows transform
LC: Titanite Chunk (moat #2)In the center of the area where the Pus of Man hollows transform
LC: Titanite Chunk (moat, near ledge)Dropping down from the bridge where the Pus of Man wyverns breathe fire on the near side to the bonfire
LC: Titanite Chunk (wyvern room, wyvern foot mob drop)Dropped by the second Pus of Man wyvern
LC: Titanite Scale (altar)In a chest climbing the ladder to the rooftop outside the Dragonslayer Armour fight, continuing the loop past the Red-Eyed Lothric Knight
LC: Titanite Scale (basement, chest)In a chest in the basement with the Outrider Knight
LC: Titanite Scale (chapel, chest)In a chest in the chapel to the right of the Dragonslayer Armour fight
LC: Titanite Scale (dark room mid, out door opposite wyvern)Passing through the room with the firebomb-throwing hollows and the Pus of Man wyvern around to the front, overlooking the area where the wyverns breathe fire
LC: Titanite Scale (dark room, upper balcony)In the room with the firebomb-throwing hollows, at the very top on a balcony to the right
LC: Titanite Scale (dark room, upper, mimic)Dropped by the crawling mimic at the top of the room with the firebomb-throwing hollows
LC: Twinkling Titanite (ascent, side room)In the room where the Winged Knight drops down
LC: Twinkling Titanite (basement, chest #1)In a chest in the basement with the Outrider Knight
LC: Twinkling Titanite (basement, chest #2)In a chest in the basement with the Outrider Knight
LC: Twinkling Titanite (dark room mid, out door opposite wyvern, lizard)Dropped by the Crystal Lizard after the room with the firebomb-throwing hollows around the front
LC: Twinkling Titanite (moat, left side)Behind one of the Pus of Man transforming hollows, to the left of the bridge to the wyvern fire-breathing area
LC: Twinkling Titanite (moat, right path, lizard)Dropped by the Crystal Lizard near the thieves after dropping down to the area with the Pus of Man transforming hollows
LC: Undead Bone Shard (moat, far ledge)Dropping down from the bridge where the Pus of Man wyverns breathe fire on the far side from the bonfire
LC: Winged Knight Armor (ascent, behind illusory wall)In the area where the Winged Knight drops down, up the ladder and past the illusory wall
LC: Winged Knight Gauntlets (ascent, behind illusory wall)In the area where the Winged Knight drops down, up the ladder and past the illusory wall
LC: Winged Knight Helm (ascent, behind illusory wall)In the area where the Winged Knight drops down, up the ladder and past the illusory wall
LC: Winged Knight Leggings (ascent, behind illusory wall)In the area where the Winged Knight drops down, up the ladder and past the illusory wall
PC: Blooming Purple Moss Clump (walkway above swamp)At the right end of the plank before dropping down into the Profaned Capital toxic pool
LC: Soul of a Crestfallen Knight - by lift bottomGuarded by a buffed Lothric Knight straight from the Dancer bonfire
LC: Soul of a Crestfallen Knight - wyvern room, balconyOn a ledge accessible after the second Pus of Man wyvern is defeated
LC: Spirit Tree Crest Shield - basement, chestIn a chest in the basement with the Outrider Knight
LC: Sunlight Medal - by lift topNext to the shortcut elevator outside of the Dragonslayer Armour fight that goes down to the start of the area
LC: Sunlight Straight Sword - wyvern room, mimicDropped by the mimic in the room next to the second Pus of Man wyvern
LC: Thunder Stoneplate Ring+2 - chapel, drop onto roofDropping down from the chapel balcony where the Red Tearstone Ring is found, out on the edge
LC: Titanite Chunk - altar roofClimbing the ladder to the rooftop outside the Dragonslayer Armour fight, overlooking the tree
LC: Titanite Chunk - ascent, final turretRather than going up the stairs to the Dragon Barracks bonfire, continue straight down the stairs, then right
LC: Titanite Chunk - ascent, first balconyRight after the Lothric Castle bonfire, out on the balcony
LC: Titanite Chunk - ascent, turret before barricadesFrom the Lothric Castle bonfire, up the stairs, straight, and then down the stairs behind the barricade
LC: Titanite Chunk - dark room mid, out door opposite wyvernFrom the room with the firebomb-throwing hollows, past the Pus of Man Wyvern and back around the front, before the Crystal Lizard
LC: Titanite Chunk - dark room mid, pus of man mob dropDropped by the first Pus of Man wyvern
LC: Titanite Chunk - down stairs after bossDown the stairs to the right after Dragonslayer Armour
LC: Titanite Chunk - moat #1In the center of the area where the Pus of Man hollows transform
LC: Titanite Chunk - moat #2In the center of the area where the Pus of Man hollows transform
LC: Titanite Chunk - moat, near ledgeDropping down from the bridge where the Pus of Man wyverns breathe fire on the near side to the bonfire
LC: Titanite Chunk - wyvern room, wyvern foot mob dropDropped by the second Pus of Man wyvern
LC: Titanite Scale - altarIn a chest climbing the ladder to the rooftop outside the Dragonslayer Armour fight, continuing the loop past the Red-Eyed Lothric Knight
LC: Titanite Scale - basement, chestIn a chest in the basement with the Outrider Knight
LC: Titanite Scale - chapel, chestIn a chest in the chapel to the right of the Dragonslayer Armour fight
LC: Titanite Scale - dark room mid, out door opposite wyvernPassing through the room with the firebomb-throwing hollows and the Pus of Man wyvern around to the front, overlooking the area where the wyverns breathe fire
LC: Titanite Scale - dark room, upper balconyIn the room with the firebomb-throwing hollows, at the very top on a balcony to the right
LC: Titanite Scale - dark room, upper, mimicDropped by the crawling mimic at the top of the room with the firebomb-throwing hollows
LC: Twinkling Titanite - ascent, side roomIn the room where the Winged Knight drops down
LC: Twinkling Titanite - basement, chest #1In a chest in the basement with the Outrider Knight
LC: Twinkling Titanite - basement, chest #2In a chest in the basement with the Outrider Knight
LC: Twinkling Titanite - dark room mid, out door opposite wyvern, lizardDropped by the Crystal Lizard after the room with the firebomb-throwing hollows around the front
LC: Twinkling Titanite - moat, left sideBehind one of the Pus of Man transforming hollows, to the left of the bridge to the wyvern fire-breathing area
LC: Twinkling Titanite - moat, right path, lizardDropped by the Crystal Lizard near the thieves after dropping down to the area with the Pus of Man transforming hollows
LC: Undead Bone Shard - moat, far ledgeDropping down from the bridge where the Pus of Man wyverns breathe fire on the far side from the bonfire
LC: Winged Knight Armor - ascent, behind illusory wallIn the area where the Winged Knight drops down, up the ladder and past the illusory wall
LC: Winged Knight Gauntlets - ascent, behind illusory wallIn the area where the Winged Knight drops down, up the ladder and past the illusory wall
LC: Winged Knight Helm - ascent, behind illusory wallIn the area where the Winged Knight drops down, up the ladder and past the illusory wall
LC: Winged Knight Leggings - ascent, behind illusory wallIn the area where the Winged Knight drops down, up the ladder and past the illusory wall
PC: Blooming Purple Moss Clump - walkway above swampAt the right end of the plank before dropping down into the Profaned Capital toxic pool
PC: Cinders of a Lord - Yhorm the GiantDropped by Yhorm the Giant
PC: Court Sorcerer Gloves (chapel, second floor)On the second floor of the Monstrosity of Sin building in front of the Monstrosity of Sin
PC: Court Sorcerer Hood (chapel, second floor)On the second floor of the Monstrosity of Sin building in front of the Monstrosity of Sin
PC: Court Sorcerer Robe (chapel, second floor)On the second floor of the Monstrosity of Sin building in front of the Monstrosity of Sin
PC: Court Sorcerer Trousers (chapel, second floor)On the second floor of the Monstrosity of Sin building in front of the Monstrosity of Sin
PC: Court Sorcerer's Staff (chapel, mimic on second floor)Dropped by the mimic on the second floor of the Monstrosity of Sin building
PC: Cursebite Ring (swamp, below halls)In the inner cave of the Profaned Capital toxic pool
PC: Eleonora (chapel ground floor, kill mob)Dropped by the Monstrosity of Sin on the first floor, furthest away from the door
PC: Ember (palace, far room)To the right of the Profaned Flame, in the room with the many Jailers looking at the mimics
PC: Flame Stoneplate Ring+1 (chapel, drop from roof towards entrance)Dropping down from the roof connected to the second floor of the Monstrosity of Sin building, above the main entrance to the building
PC: Greatshield of Glory (palace, mimic in far room)Dropped by the left mimic surrounded by the Jailers to the right of the Profaned Flame
PC: Jailer's Key Ring (hall past chapel)Past the Profaned Capital Court Sorcerer, in the corridor overlooking the Irithyll Dungeon Giant Slave area
PC: Large Soul of a Weary Warrior (bridge, far end)On the way from the Profaned Capital bonfire toward the Profaned Flame, crossing the bridge without dropping down
PC: Logan's Scroll (chapel roof, NPC drop)Dropped by the court sorcerer above the toxic pool
PC: Magic Stoneplate Ring+2 (tower base)At the base of the Profaned Capital structure, going all the way around the outside wall clockwise
PC: Onislayer Greatarrow (bridge)Item on the bridge descending from the Profaned Capital bonfire into the Profaned Flame building
PC: Onislayer Greatbow (drop from bridge)From the bridge leading from the Profaned Capital bonfire to Yhorm, onto the ruined pillars shortcut to the right, behind you after the first dropdown.
PC: Pierce Shield (Siegward)Dropped by Siegward upon death or quest completion, and sold by Patches while Siegward is in the well.
PC: Poison Arrow (chapel roof)At the far end of the roof with the Court Sorcerer
PC: Poison Gem (swamp, below halls)In the inner cave of the Profaned Capital toxic pool
PC: Purging Stone (chapel ground floor)At the back of the room with the three Monstrosities of Sin on the first floor
PC: Purging Stone (swamp, by chapel ladder)In the middle of the Profaned Capital toxic pool, near the ladder to the Court Sorcerer
PC: Rubbish (chapel, down stairs from second floor)Hanging corpse visible from Profaned Capital accessible from the second floor of the building with the Monstrosities of Sin, in the back right
PC: Rusted Coin (below bridge #1)Among the rubble before the steps leading up to the Profaned Flame
PC: Rusted Coin (below bridge #2)Among the rubble before the steps leading up to the Profaned Flame
PC: Rusted Coin (tower exterior)Treasure visible on a ledge in the Profaned Capital bonfire. Can be accessed by climbing a ladder outside the main structure.
PC: Rusted Gold Coin (halls above swamp)In the corridors leading to the Profaned Capital toxic pool
PC: Rusted Gold Coin (palace, mimic in far room)Dropped by the right mimic surrounded by the Jailers to the right of the Profaned Flame
PC: Shriving Stone (swamp, by chapel door)At the far end of the Profaned Capital toxic pool, to the left of the door leading to the Monstrosities of Sin
PC: Siegbräu (Siegward after killing boss)Given by Siegward after helping him defeat Yhorm the Giant. You must talk to him before Emma teleports you.
PC: Court Sorcerer Gloves - chapel, second floorOn the second floor of the Monstrosity of Sin building in front of the Monstrosity of Sin
PC: Court Sorcerer Hood - chapel, second floorOn the second floor of the Monstrosity of Sin building in front of the Monstrosity of Sin
PC: Court Sorcerer Robe - chapel, second floorOn the second floor of the Monstrosity of Sin building in front of the Monstrosity of Sin
PC: Court Sorcerer Trousers - chapel, second floorOn the second floor of the Monstrosity of Sin building in front of the Monstrosity of Sin
PC: Court Sorcerer's Staff - chapel, mimic on second floorDropped by the mimic on the second floor of the Monstrosity of Sin building
PC: Cursebite Ring - swamp, below hallsIn the inner cave of the Profaned Capital toxic pool
PC: Eleonora - chapel ground floor, kill mobDropped by the Monstrosity of Sin on the first floor, furthest away from the door
PC: Ember - palace, far roomTo the right of the Profaned Flame, in the room with the many Jailers looking at the mimics
PC: Flame Stoneplate Ring+1 - chapel, drop from roof towards entranceDropping down from the roof connected to the second floor of the Monstrosity of Sin building, above the main entrance to the building
PC: Greatshield of Glory - palace, mimic in far roomDropped by the left mimic surrounded by the Jailers to the right of the Profaned Flame
PC: Jailer's Key Ring - hall past chapelPast the Profaned Capital Court Sorcerer, in the corridor overlooking the Irithyll Dungeon Giant Slave area
PC: Large Soul of a Weary Warrior - bridge, far endOn the way from the Profaned Capital bonfire toward the Profaned Flame, crossing the bridge without dropping down
PC: Logan's Scroll - chapel roof, NPC dropDropped by the court sorcerer above the toxic pool
PC: Magic Stoneplate Ring+2 - tower baseAt the base of the Profaned Capital structure, going all the way around the outside wall clockwise
PC: Onislayer Greatarrow - bridgeItem on the bridge descending from the Profaned Capital bonfire into the Profaned Flame building
PC: Onislayer Greatbow - drop from bridgeFrom the bridge leading from the Profaned Capital bonfire to Yhorm, onto the ruined pillars shortcut to the right, behind you after the first dropdown.
PC: Pierce Shield - SiegwardDropped by Siegward upon death or quest completion, and sold by Patches while Siegward is in the well.
PC: Poison Arrow - chapel roofAt the far end of the roof with the Court Sorcerer
PC: Poison Gem - swamp, below hallsIn the inner cave of the Profaned Capital toxic pool
PC: Purging Stone - chapel ground floorAt the back of the room with the three Monstrosities of Sin on the first floor
PC: Purging Stone - swamp, by chapel ladderIn the middle of the Profaned Capital toxic pool, near the ladder to the Court Sorcerer
PC: Rubbish - chapel, down stairs from second floorHanging corpse visible from Profaned Capital accessible from the second floor of the building with the Monstrosities of Sin, in the back right
PC: Rusted Coin - below bridge #1Among the rubble before the steps leading up to the Profaned Flame
PC: Rusted Coin - below bridge #2Among the rubble before the steps leading up to the Profaned Flame
PC: Rusted Coin - tower exteriorTreasure visible on a ledge in the Profaned Capital bonfire. Can be accessed by climbing a ladder outside the main structure.
PC: Rusted Gold Coin - halls above swampIn the corridors leading to the Profaned Capital toxic pool
PC: Rusted Gold Coin - palace, mimic in far roomDropped by the right mimic surrounded by the Jailers to the right of the Profaned Flame
PC: Shriving Stone - swamp, by chapel doorAt the far end of the Profaned Capital toxic pool, to the left of the door leading to the Monstrosities of Sin
PC: Siegbräu - Siegward after killing bossGiven by Siegward after helping him defeat Yhorm the Giant. You must talk to him before Emma teleports you.
PC: Soul of Yhorm the GiantDropped by Yhorm the Giant
PC: Storm Ruler (Siegward)Dropped by Siegward upon death or quest completion.
PC: Storm Ruler (boss room)To the right of Yhorm's throne
PC: Twinkling Titanite (halls above swamp, lizard #1)Dropped by the second Crystal Lizard in the corridors before the Profaned Capital toxic pool
PC: Undead Bone Shard (by bonfire)On the corpse of Laddersmith Gilligan next to the Profaned Capital bonfire
PC: Wrath of the Gods (chapel, drop from roof)Dropping down from the roof of the Monstrosity of Sin building where the Court Sorcerer is
PW1: Black Firebomb (snowfield lower, path to bonfire)Dropping down after the first snow overhang and following the wall on the left, past the rotting bed descending toward the second bonfire
PW1: Blessed Gem (snowfield, behind tower)Behind the Millwood Knight tower in the first area, approach from the right side
PW1: Budding Green Blossom (settlement courtyard, ledge)After sliding down the slope on the way to Corvian Settlement, dropping down hugging the left wall
PW1: Captain's Ashes (snowfield tower, 6F)At the very top of the Millwood Knight tower after climbing up the second ladder
PW1: Champion's Bones (boss drop)Dropped by Champion's Gravetender
PW1: Chillbite Ring (Friede)Given by Sister Friede while she is sitting in the Ariandel Chapel, or on the stool after she moves.
PW1: Contraption Key (library, NPC drop)Dropped by Sir Vilhelm
PW1: Crow Quills (settlement loop, jump into courtyard)Crossing the bridge after Corvian Settlement bonfire, follow the left edge past another bridge until a dropdown point looping back to the bonfire. Go right and jump past some barrels onto the central platform.
PW1: Crow Talons (settlement roofs, near bonfire)After climbing the ladder onto Corvian Settlement rooftops, dropping down on a bridge to the left, into the building, then looping around onto its roof.
PW1: Dark Gem (settlement back, egg building)Dropping down to the right of the gate guarded by a Corvian Knight in Corvian Settlement, inside of the last building on the right
PW1: Ember (roots above depths)In the tree branch area after climbing down the rope bridge, hugging a right wall past a Follower Javelin wielder
PW1: Ember (settlement main, left building after bridge)Crossing the bridge after Corvian Settlement bonfire, in the building to the left.
PW1: Ember (settlement, building near bonfire)In the first building in Corvian Settlement next to the bonfire building
PW1: Ethereal Oak Shield (snowfield tower, 3F)In the Millwood Knight tower on a Millwood Knight corpse, after climbing the first ladder, then going down the staircase
PW1: Follower Javelin (snowfield lower, path back up)Dropping down after the first snow overhang, follow the right wall around and up a slope, past the Followers
PW1: Follower Sabre (roots above depths)On a tree branch after climbing down the rope bridge. Rather than hugging a right wall toward a Follower Javelin wielder, drop off to the left.
PW1: Frozen Weapon (snowfield lower, egg zone)Dropping down after the first snow overhang, in the rotting bed along the left side
PW1: Heavy Gem (snowfield village)Before the Millwood Knight tower, on the far side of one of the ruined walls targeted by the archer
PW1: Hollow Gem (beside chapel)To the right of the entrance to the Ariandel
PW1: Homeward Bone (depths, up hill)In the Depths of the Painting, up a hill next to the giant crabs.
PW1: Homeward Bone (snowfield village, outcropping)Dropping down after the first snow overhang and following the cliff on the right, making a sharp right after a ruined wall segment before approaching the Millwood Knight tower
PW1: Large Soul of a Weary Warrior (settlement hall roof)On top of the chapel with the Corvian Knight to the left of Vilhelm's building
PW1: Large Soul of a Weary Warrior (snowfield tower, 6F)At the very top of the Millwood Knight tower after climbing up the second ladder, on a Millwood Knight corpse
PW1: Large Soul of an Unknown Traveler (below snowfield village overhang)Up the slope to the left of the Millwood Knight tower, dropping down after a snow overhang, then several more ledges.
PW1: Large Soul of an Unknown Traveler (settlement back)In Corvian Settlement, on the ground before the ladder climbing onto the rooftops
PW1: Large Soul of an Unknown Traveler (settlement courtyard, cliff)After sliding down the slope on the way to Corvian Settlement, on a cliff to the right and behind
PW1: Large Soul of an Unknown Traveler (settlement loop, by bonfire)Crossing the bridge after Corvian Settlement bonfire, follow the left edge past another bridge until a dropdown point looping back to the bonfire. On the corpse in a hole in the wall leading back to the bonfire.
PW1: Large Soul of an Unknown Traveler (settlement roofs, balcony)After climbing the ladder onto Corvian Settlement rooftops, dropping down on a bridge to the left, on the other side of the bridge.
PW1: Large Soul of an Unknown Traveler (settlement, by ladder to bonfire)To the right of the ladder leading up to Corvian Settlement bonfire.
PW1: Large Soul of an Unknown Traveler (snowfield lower, by cliff)Dropping down after the first snow overhang, between the forest and the cliff edge, before where the large wolf drops down
PW1: Large Soul of an Unknown Traveler (snowfield lower, path back up)Dropping down after the first snow overhang, follow the right wall around and up a slope, past the Followers
PW1: Large Soul of an Unknown Traveler (snowfield lower, path to village)Dropping down after the first snow overhang and following the cliff on the right, on a tree past where the large wolf jumps down
PW1: Large Soul of an Unknown Traveler (snowfield upper)Going straight after the first bonfire, to the left of the caving snow overhand
PW1: Large Titanite Shard (lizard under bridge near)Dropped by a Crystal Lizard after the Rope Bridge Cave on the way to Corvian Settlement
PW1: Large Titanite Shard (settlement loop, lizard)Crossing the bridge after Corvian Settlement bonfire, follow the left edge past another bridge until a dropdown point looping back to the bonfire. Hug the bonfire building's outer wall along the right side.
PW1: Large Titanite Shard (snowfield lower, left from fall)Dropping down after the first snow overhang, guarded by a Tree Woman overlooking the rotting bed along the left wall
PW1: Millwood Battle Axe (snowfield tower, 5F)In the Milkwood Knight tower, either dropping down from rafters after climbing the second ladder or making a risky jump
PW1: Millwood Greatarrow (snowfield village, loop back to lower)Dropping down after the first snow overhang and following the cliff on the right, making the full loop around, up the slope leading towards where the large wolf drops down
PW1: Millwood Greatbow (snowfield village, loop back to lower)Dropping down after the first snow overhang and following the cliff on the right, making the full loop around, up the slope leading towards where the large wolf drops down
PW1: Onyx Blade (library, NPC drop)Dropped by Sir Vilhelm
PW1: Poison Gem (snowfield upper, forward from bonfire)Following the left wall from the start, guarded by a Giant Fly
PW1: Rime-blue Moss Clump (below bridge far)In a small alcove to the right after climbing down the rope bridge
PW1: Rime-blue Moss Clump (snowfield upper, overhang)On the first snow overhang at the start. It drops down at the same time you do.
PW1: Rime-blue Moss Clump (snowfield upper, starting cave)In the starting cave
PW1: Rusted Coin (right of library)To the right of Vilhelm's building
PW1: Rusted Coin (snowfield lower, straight from fall)Dropping down after the first snow overhang, shortly straight ahead
PW1: Rusted Gold Coin (settlement roofs, roof near second ladder)After climbing the second ladder on the Corvian Settlement rooftops, immediately dropping off the bridge to the right, on a rooftop
PW1: Shriving Stone (below bridge near)After the Rope Bridge Cave bonfire, dropping down before the bridge, following the ledge all the way to the right
PW1: Simple Gem (settlement, lowest level, behind gate)Crossing the bridge after Corvian Settlement bonfire, follow the left edge until a bridge, then drop down on the right side. Guarded by a Sewer Centipede.
PW1: Slave Knight Armor (settlement roofs, drop by ladder)In Corvian Settlement, rather than climbing up a ladder leading to a bridge to the roof of the chapel with the Corvian Knight, dropping down a hole to the left of the ladder into the building below.
PW1: Slave Knight Gauntlets (settlement roofs, drop by ladder)In Corvian Settlement, rather than climbing up a ladder leading to a bridge to the roof of the chapel with the Corvian Knight, dropping down a hole to the left of the ladder into the building below.
PW1: Slave Knight Hood (settlement roofs, drop by ladder)In Corvian Settlement, rather than climbing up a ladder leading to a bridge to the roof of the chapel with the Corvian Knight, dropping down a hole to the left of the ladder into the building below.
PW1: Slave Knight Leggings (settlement roofs, drop by ladder)In Corvian Settlement, rather than climbing up a ladder leading to a bridge to the roof of the chapel with the Corvian Knight, dropping down a hole to the left of the ladder into the building below.
PW1: Snap Freeze (depths, far end, mob drop)In the Depths of the Painting, past the giant crabs, guarded by a special Tree Woman. Killing her drops down a very long nearby ladder.
PW1: Soul of a Crestfallen Knight (settlement hall, rafters)In the rafters of the chapel with the Corvian Knight to the left of Vilhelm's building. Can drop down from the windows exposed to the roof.
PW1: Soul of a Weary Warrior (snowfield tower, 1F)At the bottom of the Millwood Knight tower on a Millwood Knight corpse
PW1: Titanite Slab (Corvian)Given by the Corvian NPC in the building next to Corvian Settlement bonfire.
PW1: Titanite Slab (depths, up secret ladder)One-time drop after killing Father Ariandel and Friede (phase 2) for the first time.
PW1: Twinkling Titanite (roots, lizard)Dropped by a Crystal Lizard in the tree branch area after climbing down the rope bridge, before the ledge with the Follower Javelin wielder
PW1: Twinkling Titanite (settlement roofs, lizard before hall)Dropped by a Crystal Lizard on a bridge in Corvian Settlement before the rooftop of the chapel with the Corvian Knight inside.
PW1: Twinkling Titanite (snowfield tower, 3F lizard)Dropped by a Crystal Lizard in the Millwood Knight tower, climbing up the first ladder and descending the stairs down
PW1: Valorheart (boss drop)Dropped by Champion's Gravetender
PW1: Way of White Corona (settlement hall, by altar)In the chapel with the Corvian Knight to the left of Vilhelm's building, in front of the altar.
PW1: Young White Branch (right of library)To the right of Vilhelm's building
PW2: Blood Gem (B2, center)On the lower level of the Ariandel Chapel basement, in the middle
PW2: Dung Pie (B1)On the higher level of the Ariandel Chapel basement, on a wooden beam overlooking the lower level
PW2: Earth Seeker (pit cave)In the area after Snowy Mountain Pass with the giant tree and Earth Seeker Millwood Knight, in the cave
PW2: Ember (pass, central alcove)After the Snowy Mountain Pass bonfire, going left of the bell stuck in the ground, in a small alcove along the left wall
PW2: Floating Chaos (Dunnel drop)Dropped by Livid Pyromancer Dunnel when he invades while embered, whether boss is defeated or not. On the second level of Priscilla's building above the Gravetender fight, accessed from the lowest level of the Ariandel Chapel basement, past an illusory wall nearly straight left of the mechanism that moves the statue, then carefully dropping down tree branches.
PW2: Follower Shield (pass, far cliffside)After the Snowy Mountain Pass bonfire, going left of the bell stuck in the ground, on the cliff ledge past the open area, to the left
PW2: Follower Torch (pass, far side path)On the way to the Ariandel Chapel basement, where the first wolf enemies reappear, going all the way down the slope on the edge of the map. Guarded by a Follower
PW2: Homeward Bone (rotunda)On the second level of Priscilla's building above the Gravetender fight. Can be accessed from the lowest level of the Ariandel Chapel basement, past an illusory wall nearly straight left of the mechanism that moves the statue, then carefully dropping down tree branches.
PW2: Large Soul of a Crestfallen Knight (pit, by tree)In the area after Snowy Mountain Pass with the giant tree and Earth Seeker Millwood Knight, by the tree
PW2: Large Titanite Shard (pass, far side path)On the way to the Ariandel Chapel basement, where the first wolf enemies reappear, going partway down the slope on the edge of the map
PW2: Large Titanite Shard (pass, just before B1)On the way to Ariandel Chapel basement, past the Millwood Knights and before the first rotten tree that can be knocked down
PW2: Prism Stone (pass, tree by beginning)Up the slope and to the left after the Snowy Mountain Pass, straight ahead by a tree
PW2: Pyromancer's Parting Flame (rotunda)On the second level of Priscilla's building above the Gravetender fight. Can be accessed from the lowest level of the Ariandel Chapel basement, past an illusory wall nearly straight left of the mechanism that moves the statue, then carefully dropping down tree branches.
PW2: Quakestone Hammer (pass, side path near B1)On the way to Ariandel Chapel basement, rather than going right past the two Millwood Knights, go left, guarded by a very strong Millwood Knight
PC: Storm Ruler - SiegwardDropped by Siegward upon death or quest completion.
PC: Storm Ruler - boss roomTo the right of Yhorm's throne
PC: Twinkling Titanite - halls above swamp, lizard #1Dropped by the second Crystal Lizard in the corridors before the Profaned Capital toxic pool
PC: Twinkling Titanite - halls above swamp, lizard #2Dropped by the first Crystal Lizard in the corridors before the Profaned Capital toxic pool
PC: Undead Bone Shard - by bonfireOn the corpse of Laddersmith Gilligan next to the Profaned Capital bonfire
PC: Wrath of the Gods - chapel, drop from roofDropping down from the roof of the Monstrosity of Sin building where the Court Sorcerer is
PW1: Black Firebomb - snowfield lower, path to bonfireDropping down after the first snow overhang and following the wall on the left, past the rotting bed descending toward the second bonfire
PW1: Blessed Gem - snowfield, behind towerBehind the Millwood Knight tower in the first area, approach from the right side
PW1: Budding Green Blossom - settlement courtyard, ledgeAfter sliding down the slope on the way to Corvian Settlement, dropping down hugging the left wall
PW1: Captain's Ashes - snowfield tower, 6FAt the very top of the Millwood Knight tower after climbing up the second ladder
PW1: Chillbite Ring - FriedeGiven by Sister Friede while she is sitting in the Ariandel Chapel, or on the stool after she moves.
PW1: Contraption Key - library, NPC dropDropped by Sir Vilhelm
PW1: Crow Quills - settlement loop, jump into courtyardCrossing the bridge after Corvian Settlement bonfire, follow the left edge past another bridge until a dropdown point looping back to the bonfire. Go right and jump past some barrels onto the central platform.
PW1: Crow Talons - settlement roofs, near bonfireAfter climbing the ladder onto Corvian Settlement rooftops, dropping down on a bridge to the left, into the building, then looping around onto its roof.
PW1: Dark Gem - settlement back, egg buildingDropping down to the right of the gate guarded by a Corvian Knight in Corvian Settlement, inside of the last building on the right
PW1: Ember - roots above depthsIn the tree branch area after climbing down the rope bridge, hugging a right wall past a Follower Javelin wielder
PW1: Ember - settlement main, left building after bridgeCrossing the bridge after Corvian Settlement bonfire, in the building to the left.
PW1: Ember - settlement, building near bonfireIn the first building in Corvian Settlement next to the bonfire building
PW1: Ethereal Oak Shield - snowfield tower, 3FIn the Millwood Knight tower on a Millwood Knight corpse, after climbing the first ladder, then going down the staircase
PW1: Follower Javelin - snowfield lower, path back upDropping down after the first snow overhang, follow the right wall around and up a slope, past the Followers
PW1: Follower Sabre - roots above depthsOn a tree branch after climbing down the rope bridge. Rather than hugging a right wall toward a Follower Javelin wielder, drop off to the left.
PW1: Frozen Weapon - snowfield lower, egg zoneDropping down after the first snow overhang, in the rotting bed along the left side
PW1: Heavy Gem - snowfield villageBefore the Millwood Knight tower, on the far side of one of the ruined walls targeted by the archer
PW1: Hollow Gem - beside chapelTo the right of the entrance to the Ariandel
PW1: Homeward Bone - depths, up hillIn the Depths of the Painting, up a hill next to the giant crabs.
PW1: Homeward Bone - snowfield village, outcroppingDropping down after the first snow overhang and following the cliff on the right, making a sharp right after a ruined wall segment before approaching the Millwood Knight tower
PW1: Large Soul of a Weary Warrior - settlement hall roofOn top of the chapel with the Corvian Knight to the left of Vilhelm's building
PW1: Large Soul of a Weary Warrior - snowfield tower, 6FAt the very top of the Millwood Knight tower after climbing up the second ladder, on a Millwood Knight corpse
PW1: Large Soul of an Unknown Traveler - below snowfield village overhangUp the slope to the left of the Millwood Knight tower, dropping down after a snow overhang, then several more ledges.
PW1: Large Soul of an Unknown Traveler - settlement backIn Corvian Settlement, on the ground before the ladder climbing onto the rooftops
PW1: Large Soul of an Unknown Traveler - settlement courtyard, cliffAfter sliding down the slope on the way to Corvian Settlement, on a cliff to the right and behind
PW1: Large Soul of an Unknown Traveler - settlement loop, by bonfireCrossing the bridge after Corvian Settlement bonfire, follow the left edge past another bridge until a dropdown point looping back to the bonfire. On the corpse in a hole in the wall leading back to the bonfire.
PW1: Large Soul of an Unknown Traveler - settlement roofs, balconyAfter climbing the ladder onto Corvian Settlement rooftops, dropping down on a bridge to the left, on the other side of the bridge.
PW1: Large Soul of an Unknown Traveler - settlement, by ladder to bonfireTo the right of the ladder leading up to Corvian Settlement bonfire.
PW1: Large Soul of an Unknown Traveler - snowfield lower, by cliffDropping down after the first snow overhang, between the forest and the cliff edge, before where the large wolf drops down
PW1: Large Soul of an Unknown Traveler - snowfield lower, path back upDropping down after the first snow overhang, follow the right wall around and up a slope, past the Followers
PW1: Large Soul of an Unknown Traveler - snowfield lower, path to villageDropping down after the first snow overhang and following the cliff on the right, on a tree past where the large wolf jumps down
PW1: Large Soul of an Unknown Traveler - snowfield upperGoing straight after the first bonfire, to the left of the caving snow overhand
PW1: Large Titanite Shard - lizard under bridge nearDropped by a Crystal Lizard after the Rope Bridge Cave on the way to Corvian Settlement
PW1: Large Titanite Shard - settlement loop, lizardCrossing the bridge after Corvian Settlement bonfire, follow the left edge past another bridge until a dropdown point looping back to the bonfire. Hug the bonfire building's outer wall along the right side.
PW1: Large Titanite Shard - snowfield lower, left from fallDropping down after the first snow overhang, guarded by a Tree Woman overlooking the rotting bed along the left wall
PW1: Millwood Battle Axe - snowfield tower, 5FIn the Milkwood Knight tower, either dropping down from rafters after climbing the second ladder or making a risky jump
PW1: Millwood Greatarrow - snowfield village, loop back to lowerDropping down after the first snow overhang and following the cliff on the right, making the full loop around, up the slope leading towards where the large wolf drops down
PW1: Millwood Greatbow - snowfield village, loop back to lowerDropping down after the first snow overhang and following the cliff on the right, making the full loop around, up the slope leading towards where the large wolf drops down
PW1: Onyx Blade - library, NPC dropDropped by Sir Vilhelm
PW1: Poison Gem - snowfield upper, forward from bonfireFollowing the left wall from the start, guarded by a Giant Fly
PW1: Rime-blue Moss Clump - below bridge farIn a small alcove to the right after climbing down the rope bridge
PW1: Rime-blue Moss Clump - snowfield upper, overhangOn the first snow overhang at the start. It drops down at the same time you do.
PW1: Rime-blue Moss Clump - snowfield upper, starting caveIn the starting cave
PW1: Rusted Coin - right of libraryTo the right of Vilhelm's building
PW1: Rusted Coin - snowfield lower, straight from fallDropping down after the first snow overhang, shortly straight ahead
PW1: Rusted Gold Coin - settlement roofs, roof near second ladderAfter climbing the second ladder on the Corvian Settlement rooftops, immediately dropping off the bridge to the right, on a rooftop
PW1: Shriving Stone - below bridge nearAfter the Rope Bridge Cave bonfire, dropping down before the bridge, following the ledge all the way to the right
PW1: Simple Gem - settlement, lowest level, behind gateCrossing the bridge after Corvian Settlement bonfire, follow the left edge until a bridge, then drop down on the right side. Guarded by a Sewer Centipede.
PW1: Slave Knight Armor - settlement roofs, drop by ladderIn Corvian Settlement, rather than climbing up a ladder leading to a bridge to the roof of the chapel with the Corvian Knight, dropping down a hole to the left of the ladder into the building below.
PW1: Slave Knight Gauntlets - settlement roofs, drop by ladderIn Corvian Settlement, rather than climbing up a ladder leading to a bridge to the roof of the chapel with the Corvian Knight, dropping down a hole to the left of the ladder into the building below.
PW1: Slave Knight Hood - settlement roofs, drop by ladderIn Corvian Settlement, rather than climbing up a ladder leading to a bridge to the roof of the chapel with the Corvian Knight, dropping down a hole to the left of the ladder into the building below.
PW1: Slave Knight Leggings - settlement roofs, drop by ladderIn Corvian Settlement, rather than climbing up a ladder leading to a bridge to the roof of the chapel with the Corvian Knight, dropping down a hole to the left of the ladder into the building below.
PW1: Snap Freeze - depths, far end, mob dropIn the Depths of the Painting, past the giant crabs, guarded by a special Tree Woman. Killing her drops down a very long nearby ladder.
PW1: Soul of a Crestfallen Knight - settlement hall, raftersIn the rafters of the chapel with the Corvian Knight to the left of Vilhelm's building. Can drop down from the windows exposed to the roof.
PW1: Soul of a Weary Warrior - snowfield tower, 1FAt the bottom of the Millwood Knight tower on a Millwood Knight corpse
PW1: Titanite Slab - CorvianGiven by the Corvian NPC in the building next to Corvian Settlement bonfire.
PW1: Titanite Slab - depths, up secret ladderIn the Depths of the Painting, past the giant crabs, killing a special Tree Woman drops down a very long nearby ladder. Climb the ladder and also the ladder after that one.
PW1: Twinkling Titanite - roots, lizardDropped by a Crystal Lizard in the tree branch area after climbing down the rope bridge, before the ledge with the Follower Javelin wielder
PW1: Twinkling Titanite - settlement roofs, lizard before hallDropped by a Crystal Lizard on a bridge in Corvian Settlement before the rooftop of the chapel with the Corvian Knight inside.
PW1: Twinkling Titanite - snowfield tower, 3F lizardDropped by a Crystal Lizard in the Millwood Knight tower, climbing up the first ladder and descending the stairs down
PW1: Valorheart - boss dropDropped by Champion's Gravetender
PW1: Way of White Corona - settlement hall, by altarIn the chapel with the Corvian Knight to the left of Vilhelm's building, in front of the altar.
PW1: Young White Branch - right of libraryTo the right of Vilhelm's building
PW2: Blood Gem - B2, centerOn the lower level of the Ariandel Chapel basement, in the middle
PW2: Dung Pie - B1On the higher level of the Ariandel Chapel basement, on a wooden beam overlooking the lower level
PW2: Earth Seeker - pit caveIn the area after Snowy Mountain Pass with the giant tree and Earth Seeker Millwood Knight, in the cave
PW2: Ember - pass, central alcoveAfter the Snowy Mountain Pass bonfire, going left of the bell stuck in the ground, in a small alcove along the left wall
PW2: Floating Chaos - Dunnel dropDropped by Livid Pyromancer Dunnel when he invades while embered, whether boss is defeated or not. On the second level of Priscilla's building above the Gravetender fight, accessed from the lowest level of the Ariandel Chapel basement, past an illusory wall nearly straight left of the mechanism that moves the statue, then carefully dropping down tree branches.
PW2: Follower Shield - pass, far cliffsideAfter the Snowy Mountain Pass bonfire, going left of the bell stuck in the ground, on the cliff ledge past the open area, to the left
PW2: Follower Torch - pass, far side pathOn the way to the Ariandel Chapel basement, where the first wolf enemies reappear, going all the way down the slope on the edge of the map. Guarded by a Follower
PW2: Homeward Bone - rotundaOn the second level of Priscilla's building above the Gravetender fight. Can be accessed from the lowest level of the Ariandel Chapel basement, past an illusory wall nearly straight left of the mechanism that moves the statue, then carefully dropping down tree branches.
PW2: Large Soul of a Crestfallen Knight - pit, by treeIn the area after Snowy Mountain Pass with the giant tree and Earth Seeker Millwood Knight, by the tree
PW2: Large Titanite Shard - pass, far side pathOn the way to the Ariandel Chapel basement, where the first wolf enemies reappear, going partway down the slope on the edge of the map
PW2: Large Titanite Shard - pass, just before B1On the way to Ariandel Chapel basement, past the Millwood Knights and before the first rotten tree that can be knocked down
PW2: Prism Stone - pass, tree by beginningUp the slope and to the left after the Snowy Mountain Pass, straight ahead by a tree
PW2: Pyromancer's Parting Flame - rotundaOn the second level of Priscilla's building above the Gravetender fight. Can be accessed from the lowest level of the Ariandel Chapel basement, past an illusory wall nearly straight left of the mechanism that moves the statue, then carefully dropping down tree branches.
PW2: Quakestone Hammer - pass, side path near B1On the way to Ariandel Chapel basement, rather than going right past the two Millwood Knights, go left, guarded by a very strong Millwood Knight
PW2: Soul of Sister FriedeDropped by Sister Friede
PW2: Soul of a Crestfallen Knight (pit edge #1)In the area after Snowy Mountain Pass with the giant tree and Earth Seeker Millwood Knight, along the edge
PW2: Soul of a Crestfallen Knight (pit edge #2)In the area after Snowy Mountain Pass with the giant tree and Earth Seeker Millwood Knight, along the edge
PW2: Titanite Chunk (pass, by kickable tree)After the Snowy Mountain Pass bonfire, on a ledge to the right of the slope with the bell stuck in the ground, behind a tree
PW2: Titanite Chunk (pass, cliff overlooking bonfire)On a cliff overlooking the Snowy Mountain Pass bonfire. Requires following the left wall
PW2: Titanite Slab (boss drop)One-time drop after killing Father Ariandel and Friede (phase 2) for the first time.
PW2: Twinkling Titanite (B3, lizard #1)Dropped by a Crystal Lizard past an illusory wall nearly straight left of the mechanism that moves the statue in the lowest level of the Ariandel Chapel basement
PW2: Twinkling Titanite (B3, lizard #2)Dropped by a Crystal Lizard past an illusory wall nearly straight left of the mechanism that moves the statue in the lowest level of the Ariandel Chapel basement
PW2: Vilhelm's Armor (B2, along wall)On the lower level of the Ariandel Chapel basement, along a wall to the left of the contraption that turns the statue
PW2: Vilhelm's Gauntlets (B2, along wall)On the lower level of the Ariandel Chapel basement, along a wall to the left of the contraption that turns the statue
PW2: Soul of a Crestfallen Knight - pit edge #1In the area after Snowy Mountain Pass with the giant tree and Earth Seeker Millwood Knight, along the edge
PW2: Soul of a Crestfallen Knight - pit edge #2In the area after Snowy Mountain Pass with the giant tree and Earth Seeker Millwood Knight, along the edge
PW2: Titanite Chunk - pass, by kickable treeAfter the Snowy Mountain Pass bonfire, on a ledge to the right of the slope with the bell stuck in the ground, behind a tree
PW2: Titanite Chunk - pass, cliff overlooking bonfireOn a cliff overlooking the Snowy Mountain Pass bonfire. Requires following the left wall
PW2: Titanite Slab - boss dropOne-time drop after killing Father Ariandel and Friede (phase 2) for the first time.
PW2: Twinkling Titanite - B3, lizard #1Dropped by a Crystal Lizard past an illusory wall nearly straight left of the mechanism that moves the statue in the lowest level of the Ariandel Chapel basement
PW2: Twinkling Titanite - B3, lizard #2Dropped by a Crystal Lizard past an illusory wall nearly straight left of the mechanism that moves the statue in the lowest level of the Ariandel Chapel basement
PW2: Vilhelm's Armor - B2, along wallOn the lower level of the Ariandel Chapel basement, along a wall to the left of the contraption that turns the statue
PW2: Vilhelm's Gauntlets - B2, along wallOn the lower level of the Ariandel Chapel basement, along a wall to the left of the contraption that turns the statue
PW2: Vilhelm's HelmOn the lower level of the Ariandel Chapel basement, along a wall to the left of the contraption that turns the statue
PW2: Vilhelm's Leggings (B2, along wall)On the lower level of the Ariandel Chapel basement, along a wall to the left of the contraption that turns the statue
RC: Antiquated Plain Garb (wall hidden, before boss)In the chapel before the Midir fight in the Ringed Inner Wall building.
RC: Black Witch Garb (streets garden)Guarded by Alva (invades whether embered or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight.
RC: Black Witch Hat (streets garden)Guarded by Alva (invades whether embered or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight.
RC: Black Witch Trousers (streets garden)Guarded by Alva (invades whether embered or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight.
RC: Black Witch Veil (swamp near right, by sinking church)To the left of the submerged building with 4 Ringed Knights, near a spear-wielding knight.
RC: Black Witch Wrappings (streets garden)Guarded by Alva (invades whether embered or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight.
RC: Blessed Gem (grave, down lowest stairs)In Shared Grave, after dropping down near Gael's flag and dropping down again, behind you. Or from the bonfire, go back through the side tunnel with the skeletons and down the stairs after that.
RC: Blindfold Mask (grave, NPC drop)Dropped by Moaning Knight (invades whether embered or not, or boss defeated or not) in Shared Grave.
RC: Blood of the Dark Soul (end boss drop)Dropped by Slave Knight Gael
RC: Budding Green Blossom (church path)On the way to the Halflight building.
RC: Budding Green Blossom (wall top, flowers by stairs)In a patch of flowers to the right of the stairs leading up to the first Judicator along the left wall of the courtyard are Mausoleum Lookout.
RC: Budding Green Blossom (wall top, in flower cluster)Along the left wall of the courtyard after Mausoleum Lookout, in a patch of flowers.
RC: Chloranthy Ring+3 (wall hidden, drop onto statue)From the mid level of the Ringed Inner Wall elevator that leads to the Midir fight, dropping back down toward the way to Filianore, onto a platform with a Gwyn statue. Try to land on the platform rather than the statue.
RC: Church Guardian Shiv (swamp far left, in building)Inside of the building at the remote end of the muck pit surrounded by praying Hollow Clerics.
RC: Covetous Gold Serpent Ring+3 (streets, by Lapp)Going up the very long ladder from the muck pit, then up some stairs, to the left, and across the bridge, in a building past the Ringed Knights. Also where Lapp can be found to tell him of the Purging Monument.
RC: Crucifix of the Mad King (ashes, NPC drop)Dropped by Shira, who invades you (ember not required) in the far-future version of her room
RC: Dark Gem (swamp near, by stairs)In the middle of the muck pit, close to the long stairs.
RC: Divine Blessing (streets monument, mob drop)Dropped by the Judicator near the Purging Monument area. Requires solving "Show Your Humanity" puzzle.
RC: Divine Blessing (wall top, mob drop)Dropped by the Judicator after the Mausoleum Lookup bonfire.
RC: Dragonhead Greatshield (upper cliff, under bridge)Down a slope to the right of the bridge where Midir first assaults you, past a sword-wielding Ringed Knight, under the bridge.
RC: Dragonhead Shield (streets monument, across bridge)Found in Purging Monument area, across the bridge from the monument. Requires solving "Show Your Humanity" puzzle.
RC: Ember (wall hidden, statue room)From the mid level of the Ringed Inner Wall elevator that leads to the Midir fight, in the room with the illusory statue.
RC: Ember (wall top, by statue)Along the left wall of the courtyard after Mausoleum Lookout, in front of a tall monument.
RC: Ember (wall upper, balcony)On the balcony attached to the room with the Ringed Inner Wall bonfire.
RC: Filianore's Spear Ornament (mid boss drop)Dropped by Halflight, Spear of the Church
RC: Filianore's Spear Ornament (wall hidden, by ladder)Next the ladder leading down to the chapel before the Midir fight in the Ringed Inner Wall building.
RC: Havel's Ring+3 (streets high, drop from building opposite)Dropping down from the building where Silver Knight Ledo invades. The building is up the very long ladder from the muck pit, down the path all the way to the right.
RC: Hidden Blessing (swamp center, mob drop)Dropped by Judicator patrolling the muck pit.
RC: Hidden Blessing (wall top, tomb under platform)In a tomb underneath the platform with the first Judicator, accessed by approaching from Mausoleum Lookout bonfire.
RC: Hollow Gem (wall upper, path to tower)Heading down the cursed stairs after Ringed Inner Wall bonfire and another short flight of stairs, hanging on a balcony.
RC: Iron Dragonslayer Armor (swamp far, miniboss drop)Dropped by Dragonslayer Armour at the far end of the muck pit.
RC: Iron Dragonslayer Gauntlets (swamp far, miniboss drop)Dropped by Dragonslayer Armour at the far end of the muck pit.
RC: Iron Dragonslayer Helm (swamp far, miniboss drop)Dropped by Dragonslayer Armour at the far end of the muck pit.
RC: Iron Dragonslayer Leggings (swamp far, miniboss drop)Dropped by Dragonslayer Armour at the far end of the muck pit.
RC: Lapp's Armor (Lapp)Left at Lapp's final location in Shared Grave after his quest is complete, or sold by Shrine Handmaid upon killing Lapp.
RC: Lapp's Gauntlets (Lapp)Left at Lapp's final location in Shared Grave after his quest is complete, or sold by Shrine Handmaid upon killing Lapp.
RC: Lapp's Helm (Lapp)Left at Lapp's final location in Shared Grave after his quest is complete, or sold by Shrine Handmaid upon killing Lapp.
RC: Lapp's Leggings (Lapp)Left at Lapp's final location in Shared Grave after his quest is complete, or sold by Shrine Handmaid upon killing Lapp.
RC: Large Soul of a Crestfallen Knight (streets monument, across bridge)Found in Purging Monument area, on the other side of the bridge leading to the monument. Requires solving "Show Your Humanity" puzzle.
RC: Large Soul of a Crestfallen Knight (streets, far stairs)Toward the bottom of the stairs leading down to the muck pit.
RC: Large Soul of a Weary Warrior (swamp center)In the muck pit approaching where the Judicator patrols from the stairs.
RC: Large Soul of a Weary Warrior (upper cliff, end)Toward the end of the upper path attacked Midir's fire-breathing.
RC: Large Soul of a Weary Warrior (wall lower, past two illusory walls)In the Ringed Inner Wall building coming from Shared Grave, past two illusory walls on the right side of the ascending stairs.
RC: Large Soul of a Weary Warrior (wall top, right of small tomb)In the open toward the end of the courtyard after the Mausoleum Lookout bonfire, on the right side of the small tomb.
RC: Ledo's Great Hammer (streets high, opposite building, NPC drop)Dropped by Silver Knight Ledo (invades whether embered or not, or boss defeated or not) in the building down the path to the right after climbing the very long ladder from the muck area.
RC: Lightning Arrow (wall lower, past three illusory walls)In the Ringed Inner Wall building coming from Shared Grave, past three illusory walls on the right side of the ascending stairs.
RC: Lightning Gem (grave, room after first drop)In Shared Grave, in the first room encountered after falling down from the crumbling stairs and continuing upward.
RC: Mossfruit (streets near left, path to garden)Partway down the stairs from Shira, across the bridge.
RC: Mossfruit (streets, far left alcove)Near the bottom of the stairs before the muck pit, in an alcove to the left.
RC: Preacher's Right Arm (swamp near right, by crystal)In the muck pit behind a crystal-covered structure, close to the Ringed City Streets shortcut entrance.
RC: Prism Stone (swamp near, path to bonfire)On the balcony of the path leading up to Ringed City Streets bonfire from the muck pit.
RC: Purging Stone (wall top, by door to upper)At the end of the path from Mausoleum Lookup to Ringed Inner Wall, just outside the door.
RC: Ring of the Evil Eye+3 (grave, mimic)Dropped by mimic in Shared Grave. In one of the rooms after dropping down near Gael's flag and then dropping down again.
RC: Ringed Knight Paired Greatswords (church path, mob drop)Dropped by Ringed Knight with paired greatswords before Filianore building.
RC: Ringed Knight Spear (streets, down far right hall)In a courtyard guarded by a spear-wielding Ringed Knight. Can be accessed from a hallway filled with cursed clerics on the right side going down the long stairs, or by climbing up the long ladder from the muck pit and dropping down past the Locust Preacher.
RC: Ringed Knight Straight Sword (swamp near, pillar by bonfire)On a monument next to the Ringed City Streets building. Can be easily accessed after unlocking the shortcut by following the left wall inside and then outside the building.
RC: Ritual Spear Fragment (church path)To the right of the Paired Greatswords Ringed Knight on the way to Halflight.
RC: Rubbish (swamp far, by crystal)In the remote end of the muck pit, next to a massive crystal structure between a giant tree and the building with praying Hollow Clerics, guarded by several Locust Preachers.
RC: Rubbish (upper cliff, middle)In the middle of the upper path attacked Midir's fire-breathing, after the first alcove.
RC: Ruin Armor (wall top, under stairs to bonfire)Underneath the stairs leading down from Mausoleum Lookout.
RC: Ruin Gauntlets (wall top, under stairs to bonfire)Underneath the stairs leading down from Mausoleum Lookout.
RC: Ruin Helm (wall top, under stairs to bonfire)Underneath the stairs leading down from Mausoleum Lookout.
RC: Ruin Leggings (wall top, under stairs to bonfire)Underneath the stairs leading down from Mausoleum Lookout.
RC: Sacred Chime of Filianore (ashes, NPC drop)Given by Shira after accepting her request to kill Midir, or dropped by her in post-Filianore Ringed City.
RC: Shira's Armor (Shira's room after killing ashes NPC)Found in Shira's room in Ringed City after killing her in post-Filianore Ringed City.
RC: Shira's Crown (Shira's room after killing ashes NPC)Found in Shira's room in Ringed City after killing her in post-Filianore Ringed City.
RC: Shira's Gloves (Shira's room after killing ashes NPC)Found in Shira's room in Ringed City after killing her in post-Filianore Ringed City.
RC: Shira's Trousers (Shira's room after killing ashes NPC)Found in Shira's room in Ringed City after killing her in post-Filianore Ringed City.
RC: Shriving Stone (wall tower, bottom floor center)In the cylindrical building before the long stairs with many Harald Legion Knights, in the center structure on the first floor.
RC: Siegbräu (Lapp)Given by Lapp within the Ringed Inner Wall.
RC: Simple Gem (grave, up stairs after first drop)In Shared Grave, following the path after falling down from the crumbling stairs and continuing upward.
PW2: Vilhelm's Leggings - B2, along wallOn the lower level of the Ariandel Chapel basement, along a wall to the left of the contraption that turns the statue
RC: Antiquated Plain Garb - wall hidden, before bossIn the chapel before the Midir fight in the Ringed Inner Wall building.
RC: Black Witch Garb - streets gardenGuarded by Alva (invades whether embered or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight.
RC: Black Witch Hat - streets gardenGuarded by Alva (invades whether embered or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight.
RC: Black Witch Trousers - streets gardenGuarded by Alva (invades whether embered or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight.
RC: Black Witch Veil - swamp near right, by sinking churchTo the left of the submerged building with 4 Ringed Knights, near a spear-wielding knight.
RC: Black Witch Wrappings - streets gardenGuarded by Alva (invades whether embered or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight.
RC: Blessed Gem - grave, down lowest stairsIn Shared Grave, after dropping down near Gael's flag and dropping down again, behind you. Or from the bonfire, go back through the side tunnel with the skeletons and down the stairs after that.
RC: Blindfold Mask - grave, NPC dropDropped by Moaning Knight (invades whether embered or not, or boss defeated or not) in Shared Grave.
RC: Blood of the Dark Soul - end boss dropDropped by Slave Knight Gael
RC: Budding Green Blossom - church pathOn the way to the Halflight building.
RC: Budding Green Blossom - wall top, flowers by stairsIn a patch of flowers to the right of the stairs leading up to the first Judicator along the left wall of the courtyard are Mausoleum Lookout.
RC: Budding Green Blossom - wall top, in flower clusterAlong the left wall of the courtyard after Mausoleum Lookout, in a patch of flowers.
RC: Chloranthy Ring+3 - wall hidden, drop onto statueFrom the mid level of the Ringed Inner Wall elevator that leads to the Midir fight, dropping back down toward the way to Filianore, onto a platform with a Gwyn statue. Try to land on the platform rather than the statue.
RC: Church Guardian Shiv - swamp far left, in buildingInside of the building at the remote end of the muck pit surrounded by praying Hollow Clerics.
RC: Covetous Gold Serpent Ring+3 - streets, by LappGoing up the very long ladder from the muck pit, then up some stairs, to the left, and across the bridge, in a building past the Ringed Knights. Also where Lapp can be found to tell him of the Purging Monument.
RC: Crucifix of the Mad King - ashes, NPC dropDropped by Shira, who invades you (ember not required) in the far-future version of her room
RC: Dark Gem - swamp near, by stairsIn the middle of the muck pit, close to the long stairs.
RC: Divine Blessing - streets monument, mob dropDropped by the Judicator near the Purging Monument area. Requires solving "Show Your Humanity" puzzle.
RC: Divine Blessing - wall top, mob dropDropped by the Judicator after the Mausoleum Lookup bonfire.
RC: Dragonhead Greatshield - upper cliff, under bridgeDown a slope to the right of the bridge where Midir first assaults you, past a sword-wielding Ringed Knight, under the bridge.
RC: Dragonhead Shield - streets monument, across bridgeFound in Purging Monument area, across the bridge from the monument. Requires solving "Show Your Humanity" puzzle.
RC: Ember - wall hidden, statue roomFrom the mid level of the Ringed Inner Wall elevator that leads to the Midir fight, in the room with the illusory statue.
RC: Ember - wall top, by statueAlong the left wall of the courtyard after Mausoleum Lookout, in front of a tall monument.
RC: Ember - wall upper, balconyOn the balcony attached to the room with the Ringed Inner Wall bonfire.
RC: Filianore's Spear Ornament - mid boss dropDropped by Halflight, Spear of the Church
RC: Filianore's Spear Ornament - wall hidden, by ladderNext the ladder leading down to the chapel before the Midir fight in the Ringed Inner Wall building.
RC: Havel's Ring+3 - streets high, drop from building oppositeDropping down from the building where Silver Knight Ledo invades. The building is up the very long ladder from the muck pit, down the path all the way to the right.
RC: Hidden Blessing - swamp center, mob dropDropped by Judicator patrolling the muck pit.
RC: Hidden Blessing - wall top, tomb under platformIn a tomb underneath the platform with the first Judicator, accessed by approaching from Mausoleum Lookout bonfire.
RC: Hollow Gem - wall upper, path to towerHeading down the cursed stairs after Ringed Inner Wall bonfire and another short flight of stairs, hanging on a balcony.
RC: Iron Dragonslayer Armor - swamp far, miniboss dropDropped by Dragonslayer Armour at the far end of the muck pit.
RC: Iron Dragonslayer Gauntlets - swamp far, miniboss dropDropped by Dragonslayer Armour at the far end of the muck pit.
RC: Iron Dragonslayer Helm - swamp far, miniboss dropDropped by Dragonslayer Armour at the far end of the muck pit.
RC: Iron Dragonslayer Leggings - swamp far, miniboss dropDropped by Dragonslayer Armour at the far end of the muck pit.
RC: Lapp's Armor - LappLeft at Lapp's final location in Shared Grave after his quest is complete, or sold by Shrine Handmaid upon killing Lapp.
RC: Lapp's Gauntlets - LappLeft at Lapp's final location in Shared Grave after his quest is complete, or sold by Shrine Handmaid upon killing Lapp.
RC: Lapp's Helm - LappLeft at Lapp's final location in Shared Grave after his quest is complete, or sold by Shrine Handmaid upon killing Lapp.
RC: Lapp's Leggings - LappLeft at Lapp's final location in Shared Grave after his quest is complete, or sold by Shrine Handmaid upon killing Lapp.
RC: Large Soul of a Crestfallen Knight - streets monument, across bridgeFound in Purging Monument area, on the other side of the bridge leading to the monument. Requires solving "Show Your Humanity" puzzle.
RC: Large Soul of a Crestfallen Knight - streets, far stairsToward the bottom of the stairs leading down to the muck pit.
RC: Large Soul of a Weary Warrior - swamp centerIn the muck pit approaching where the Judicator patrols from the stairs.
RC: Large Soul of a Weary Warrior - upper cliff, endToward the end of the upper path attacked Midir's fire-breathing.
RC: Large Soul of a Weary Warrior - wall lower, past two illusory wallsIn the Ringed Inner Wall building coming from Shared Grave, past two illusory walls on the right side of the ascending stairs.
RC: Large Soul of a Weary Warrior - wall top, right of small tombIn the open toward the end of the courtyard after the Mausoleum Lookout bonfire, on the right side of the small tomb.
RC: Ledo's Great Hammer - streets high, opposite building, NPC dropDropped by Silver Knight Ledo (invades whether embered or not, or boss defeated or not) in the building down the path to the right after climbing the very long ladder from the muck area.
RC: Lightning Arrow - wall lower, past three illusory wallsIn the Ringed Inner Wall building coming from Shared Grave, past three illusory walls on the right side of the ascending stairs.
RC: Lightning Gem - grave, room after first dropIn Shared Grave, in the first room encountered after falling down from the crumbling stairs and continuing upward.
RC: Mossfruit - streets near left, path to gardenPartway down the stairs from Shira, across the bridge.
RC: Mossfruit - streets, far left alcoveNear the bottom of the stairs before the muck pit, in an alcove to the left.
RC: Preacher's Right Arm - swamp near right, by crystalIn the muck pit behind a crystal-covered structure, close to the Ringed City Streets shortcut entrance.
RC: Prism Stone - swamp near, path to bonfireOn the balcony of the path leading up to Ringed City Streets bonfire from the muck pit.
RC: Purging Stone - wall top, by door to upperAt the end of the path from Mausoleum Lookup to Ringed Inner Wall, just outside the door.
RC: Ring of the Evil Eye+3 - grave, mimicDropped by mimic in Shared Grave. In one of the rooms after dropping down near Gael's flag and then dropping down again.
RC: Ringed Knight Paired Greatswords - church path, mob dropDropped by Ringed Knight with paired greatswords before Filianore building.
RC: Ringed Knight Spear - streets, down far right hallIn a courtyard guarded by a spear-wielding Ringed Knight. Can be accessed from a hallway filled with cursed clerics on the right side going down the long stairs, or by climbing up the long ladder from the muck pit and dropping down past the Locust Preacher.
RC: Ringed Knight Straight Sword - swamp near, pillar by bonfireOn a monument next to the Ringed City Streets building. Can be easily accessed after unlocking the shortcut by following the left wall inside and then outside the building.
RC: Ritual Spear Fragment - church pathTo the right of the Paired Greatswords Ringed Knight on the way to Halflight.
RC: Rubbish - swamp far, by crystalIn the remote end of the muck pit, next to a massive crystal structure between a giant tree and the building with praying Hollow Clerics, guarded by several Locust Preachers.
RC: Rubbish - upper cliff, middleIn the middle of the upper path attacked Midir's fire-breathing, after the first alcove.
RC: Ruin Armor - wall top, under stairs to bonfireUnderneath the stairs leading down from Mausoleum Lookout.
RC: Ruin Gauntlets - wall top, under stairs to bonfireUnderneath the stairs leading down from Mausoleum Lookout.
RC: Ruin Helm - wall top, under stairs to bonfireUnderneath the stairs leading down from Mausoleum Lookout.
RC: Ruin Leggings - wall top, under stairs to bonfireUnderneath the stairs leading down from Mausoleum Lookout.
RC: Sacred Chime of Filianore - ashes, NPC dropGiven by Shira after accepting her request to kill Midir, or dropped by her in post-Filianore Ringed City.
RC: Shira's Armor - Shira's room after killing ashes NPCFound in Shira's room in Ringed City after killing her in post-Filianore Ringed City.
RC: Shira's Crown - Shira's room after killing ashes NPCFound in Shira's room in Ringed City after killing her in post-Filianore Ringed City.
RC: Shira's Gloves - Shira's room after killing ashes NPCFound in Shira's room in Ringed City after killing her in post-Filianore Ringed City.
RC: Shira's Trousers - Shira's room after killing ashes NPCFound in Shira's room in Ringed City after killing her in post-Filianore Ringed City.
RC: Shriving Stone - wall tower, bottom floor centerIn the cylindrical building before the long stairs with many Harald Legion Knights, in the center structure on the first floor.
RC: Siegbräu - LappGiven by Lapp within the Ringed Inner Wall.
RC: Simple Gem - grave, up stairs after first dropIn Shared Grave, following the path after falling down from the crumbling stairs and continuing upward.
RC: Soul of Darkeater MidirDropped by Darkeater Midir
RC: Soul of Slave Knight GaelDropped by Slave Knight Gael
RC: Soul of a Crestfallen Knight (swamp far, behind crystal)Behind a crystal structure at the far end of the muck pit, close to the building with the praying Hollow Clerics before Dragonslayer Armour.
RC: Soul of a Crestfallen Knight (swamp near left, by ladder)In the muck pit behind all of the Hollow Clerics near the very long ladder.
RC: Soul of a Crestfallen Knight (wall top, under drop)After dropping down onto the side path on the right side of the Mausoleum Lookout courtyard to where the Crystal Lizard is, behind you.
RC: Soul of a Weary Warrior (swamp center)In the middle of the muck pit where the Judicator is patrolling.
RC: Soul of a Weary Warrior (swamp right, by sunken church)In between where the Judicator patrols in the muck pit and the submerged building with the 4 Ringed Knights. Provides some shelter from his arrows.
RC: Soul of a Weary Warrior (upper cliff, by first alcove)In front of the first alcove providing shelter from Midir's fire-breathing on the way to Shared Grave.
RC: Spears of the Church (hidden boss drop)Dropped by Darkeater Midir
RC: Titanite Chunk (streets high, building opposite)Down a path past the room where Silver Knight Ledo invades. The building is up the very long ladder from the muck pit, down the path all the way to the right.
RC: Titanite Chunk (streets, near left drop)Near the top of the stairs by Shira, dropping down in an alcove to the left.
RC: Titanite Chunk (swamp center, along edge)Along the edge of the muck pit close to where the Judicator patrols.
RC: Titanite Chunk (swamp far left, up hill)Up a hill at the edge of the muck pit with the Hollow Clerics.
RC: Titanite Chunk (swamp near left, opposite ladder)At the edge of the muck pit, on the opposite side of the wall from the very long ladder.
RC: Titanite Chunk (swamp near right, by sinking church)At the very edge of the muck pit, to the left of the submerged building with 4 Ringed Knights.
RC: Titanite Chunk (wall top, among graves)Along the right edge of the courtyard after Mausoleum Lookout in a cluster of graves.
RC: Titanite Chunk (wall upper, courtyard alcove)In the courtyard where the first Ringed Knight is seen, along the right wall into an alcove.
RC: Titanite Scale (grave, lizard after first drop)In the area at the far end of the muck pit with the Dragonslayer Armour.
RC: Titanite Scale (lower cliff, bridge)On the final bridge where Midir attacks before you knock him off.
RC: Titanite Scale (swamp far, by miniboss)In the area at the far end of the muck pit with the Dragonslayer Armour.
RC: Titanite Scale (upper cliff, first alcove)In the first alcove providing shelter from Midir's fire-breathing on the way to Shared Grave.
RC: Titanite Scale (upper cliff, lower path)After dropping down from the upper path attacked by Midir's fire-breathing to the lower path.
RC: Titanite Scale (upper cliff, path under bridge)Partway down a slope to the right of the bridge where Midir first assaults you.
RC: Titanite Scale (wall lower, lizard)Dropped by the Crystal Lizard right after the crumbling stairs in Shared Grave.
RC: Titanite Scale (wall top, behind spawn)Behind you at the very start of the level.
RC: Titanite Scale (wall top, lizard on side path)Dropped by the Crystal Lizard on the stairs going up from Shared Grave to Ringed Inner Wall elevator.
RC: Titanite Slab (ashes, NPC drop)Given by Shira after defeating Midir, or dropped by her in post-Filianore Ringed City.
RC: Titanite Slab (ashes, mob drop)Dropped by the Ringed Knight wandering around near Gael's arena
RC: Titanite Slab (mid boss drop)Dropped by Halflight, Spear of the Church
RC: Twinkling Titanite (church path, left of boss door)Dropping down to the left of the door leading to Halflight.
RC: Twinkling Titanite (grave, lizard after first drop)Dropped by the Crystal Lizard right after the crumbling stairs in Shared Grave.
RC: Twinkling Titanite (streets high, lizard)Dropped by the Crystal Lizard which runs across the bridge after climbing the very long ladder up from the muck pit.
RC: Twinkling Titanite (swamp near left)At the left edge of the muck pit coming from the stairs, guarded by a Preacher Locust.
RC: Twinkling Titanite (swamp near right, on sinking church)Following the sloped roof of the submerged building with the 4 Ringed Knights, along the back wall
RC: Twinkling Titanite (wall top, lizard on side path)Dropped by the first Crystal Lizard on the side path on the right side of the Mausoleum Lookout courtyard
RC: Twinkling Titanite (wall tower, jump from chandelier)In the cylindrical building before the long stairs with many Harald Legion Knights. Carefully drop down to the chandelier in the center, then jump to the second floor. The item is on a ledge.
RC: Violet Wrappings (wall hidden, before boss)In the chapel before the Midir fight in the Ringed Inner Wall building.
RC: White Birch Bow (swamp far left, up hill)Up a hill at the edge of the muck pit with the Hollow Clerics.
RC: White Preacher Head (swamp near, ground near bonfire exit)Past the balcony to the right of the Ringed City Streets bonfire room entrance. Can be accessed by dropping down straight after from the bonfire, then around to the left.
RC: Wolf Ring+3 (street gardens, NPC drop)Dropped by Alva (invades whether embered or not, or boss defeated or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight.
RC: Young White Branch (swamp far left, by white tree)Next to a small birch tree at the edge of the muck pit, between the hill with the aggressive Hollow Clerics and the building with the praying Hollow Clerics outside.
RS: Blue Bug Pellet (broken stairs by Orbeck)On the broken stairs leading down from Orbeck's area, on the opposite side from Orbeck
RS: Blue Sentinels (Horace)Given by Horace the Hushed by first "talking" to him, or upon death.
RS: Braille Divine Tome of Carim (drop from bridge to Halfway Fortress)Dropping down before the bridge leading up to Halfway Fortress from Road of Sacrifices, guarded by the maggot belly dog
RS: Brigand Armor (beneath road)In the middle of the path where the Madwoman waits in Road of Sacrifices
RS: Brigand Axe (beneath road)At the start of the path leading down to the Madwoman in Road of Sacrifices
RS: Brigand Gauntlets (beneath road)In the middle of the path where the Madwoman waits in Road of Sacrifices
RS: Brigand Hood (beneath road)In the middle of the path where the Madwoman waits in Road of Sacrifices
RS: Brigand Trousers (beneath road)In the middle of the path where the Madwoman waits in Road of Sacrifices
RS: Brigand Twindaggers (beneath road)At the end of the path guarded by the Madwoman in Road of Sacrifices
RS: Butcher Knife (NPC drop beneath road)Dropped by the Butcher Knife-wielding madwoman near the start of Road of Sacrifices
RS: Chloranthy Ring+2 (road, drop across from carriage)Found dropping down from the first Storyteller Corvian on the left side rather than the right side. You can then further drop down to where the madwoman is, after healing.
RS: Conjurator Boots (deep water)In the deep water part of the Crucifixion Woods crab area, between a large tree and the keep wall
RS: Conjurator Hood (deep water)In the deep water part of the Crucifixion Woods crab area, between a large tree and the keep wall
RS: Conjurator Manchettes (deep water)In the deep water part of the Crucifixion Woods crab area, between a large tree and the keep wall
RS: Conjurator Robe (deep water)In the deep water part of the Crucifixion Woods crab area, between a large tree and the keep wall
RS: Crystal Gem (stronghold, lizard)Dropped by the Crystal Lizard in the building before Crystal Sage
RS: Ember (right of Halfway Fortress entrance)On the ledge with the Corvian with the Storyteller Staff, to the right of the Halfway Fortress entrance
RS: Ember (right of fire behind stronghold left room)Behind the building before Crystal Sage, approached from Crucifixion Woods bonfire. Can drop down on left side or go under bridge on right side
RS: Estus Shard (left of fire behind stronghold left room)Behind the building leading to Crystal Sage, approached from Crucifixion Woods bonfire. Can drop down on left side of go under bridge on right side
RS: Exile Greatsword (NPC drop by Farron Keep)Dropped by the greatsword-wielding Exile Knight before the ladder down to Farron Keep
RS: Fading Soul (woods by Crucifixion Woods bonfire)Dropping down from the Crucifixion Woods bonfire toward the Halfway Fortress, guarded by dogs
RS: Fallen Knight Armor (water's edge by Farron Keep)On the edge of the water surrounding the building where you descend into Farron Keep
RS: Fallen Knight Gauntlets (water's edge by Farron Keep)On the edge of the water surrounding the building where you descend into Farron Keep
RS: Fallen Knight Helm (water's edge by Farron Keep)On the edge of the water surrounding the building where you descend into Farron Keep
RS: Fallen Knight Trousers (water's edge by Farron Keep)On the edge of the water surrounding the building where you descend into Farron Keep
RS: Farron Coal (keep perimeter)At the end of the Farron Keep Perimeter building on Crucifixion Woods side, behind the Black Knight
RS: Golden Falcon Shield (path from stronghold right room to Farron Keep)Halfway up the stairs to the sorcerer in the building before Crystal Sage, entering from the stairs leading up from the crab area, go straight and follow the path down
RS: Grass Crest Shield (water by Crucifixion Woods bonfire)Dropping down into the crab area from Crucifixion Woods, on the other side of a tree from the greater crab
RS: Great Club (NPC drop by Farron Keep)Dropped by the club-wielding Exile Knight before the ladder down to Farron Keep
RS: Great Swamp Pyromancy Tome (deep water)In the deep water part of the Crucifixion Woods crab area, between a large tree and the keep wall
RS: Great Swamp Ring (miniboss drop, by Farron Keep)Dropped by Greater Crab in Crucifixion Woods close to the Farron Keep outer wall
RS: Green Blossom (by deep water)In the Crucifixion Woods crab area out in the open, close to the edge of the deep water area
RS: Green Blossom (water beneath stronghold)In the Crucifixion Woods crab area close to the Crucifixion Woods bonfire, along the left wall of the water area, to the right of the entrance to the building before Crystal Sage
RS: Heretic's Staff (stronghold left room)In the building before Crystal Sage, entering from near Cruficixion Woods, in a corner under the first stairwell and balcony
RS: Heysel Pick (Heysel drop)Dropped by Heysel when she invades in Road of Sacrifices
RS: Homeward Bone (balcony by Farron Keep)At the far end of the building where you descend into Farron Keep, by the balcony
RS: Large Soul of an Unknown Traveler (left of stairs to Farron Keep)In the area before you descend into Farron Keep, before the stairs to the far left
RS: Lingering Dragoncrest Ring+1 (water)On a tree by the greater crab near the Crucifixion Woods bonfire, after the Grass Crest Shield tree
RS: Morne's Ring (drop from bridge to Halfway Fortress)Dropping down before the bridge leading up to Halfway Fortress from Road of Sacrifices, guarded by the maggot belly dog
RS: Ring of Sacrifice (stronghold, drop from right room balcony)Drop down from the platform behind the sorcerer in the building before Crystal Sage, entering from the stairs leading up from the crab area
RS: Sage Ring (water beneath stronghold)In an alcove under the building before Crystal Sage, guarded by a Lycanthrope, accessible from the swamp or from dropping down
RS: Sellsword Armor (keep perimeter balcony)In the Farron Keep Perimeter building on Crucifixion Woods side, on the balcony on the right side overlooking the Black Knight
RS: Sellsword Gauntlet (keep perimeter balcony)In the Farron Keep Perimeter building on Crucifixion Woods side, on the balcony on the right side overlooking the Black Knight
RS: Sellsword Helm (keep perimeter balcony)In the Farron Keep Perimeter building on Crucifixion Woods side, on the balcony on the right side overlooking the Black Knight
RS: Sellsword Trousers (keep perimeter balcony)In the Farron Keep Perimeter building on Crucifixion Woods side, on the balcony on the right side overlooking the Black Knight
RS: Sellsword Twinblades (keep perimeter)In the Farron Keep Perimeter building on Crucifixion Woods side, behind and to the right of the Black Knight
RS: Shriving Stone (road, by start)Dropping down to the left of the first Corvian enemy in Road of Sacrifices
RS: Sorcerer Gloves (water beneath stronghold)In an alcove under the building before Crystal Sage, guarded by a Lycanthrope, accessible from the swamp or from dropping down
RS: Sorcerer Hood (water beneath stronghold)In an alcove under the building before Crystal Sage, guarded by a Lycanthrope, accessible from the swamp or from dropping down
RS: Sorcerer Robe (water beneath stronghold)In an alcove under the building before Crystal Sage, guarded by a Lycanthrope, accessible from the swamp or from dropping down
RS: Sorcerer Trousers (water beneath stronghold)In an alcove under the building before Crystal Sage, guarded by a Lycanthrope, accessible from the swamp or from dropping down
RC: Soul of a Crestfallen Knight - swamp far, behind crystalBehind a crystal structure at the far end of the muck pit, close to the building with the praying Hollow Clerics before Dragonslayer Armour.
RC: Soul of a Crestfallen Knight - swamp near left, by ladderIn the muck pit behind all of the Hollow Clerics near the very long ladder.
RC: Soul of a Crestfallen Knight - wall top, under dropAfter dropping down onto the side path on the right side of the Mausoleum Lookout courtyard to where the Crystal Lizard is, behind you.
RC: Soul of a Weary Warrior - swamp centerIn the middle of the muck pit where the Judicator is patrolling.
RC: Soul of a Weary Warrior - swamp right, by sunken churchIn between where the Judicator patrols in the muck pit and the submerged building with the 4 Ringed Knights. Provides some shelter from his arrows.
RC: Soul of a Weary Warrior - upper cliff, by first alcoveIn front of the first alcove providing shelter from Midir's fire-breathing on the way to Shared Grave.
RC: Spears of the Church - hidden boss dropDropped by Darkeater Midir
RC: Titanite Chunk - streets high, building oppositeDown a path past the room where Silver Knight Ledo invades. The building is up the very long ladder from the muck pit, down the path all the way to the right.
RC: Titanite Chunk - streets, near left dropNear the top of the stairs by Shira, dropping down in an alcove to the left.
RC: Titanite Chunk - swamp center, along edgeAlong the edge of the muck pit close to where the Judicator patrols.
RC: Titanite Chunk - swamp far left, up hillUp a hill at the edge of the muck pit with the Hollow Clerics.
RC: Titanite Chunk - swamp near left, opposite ladderAt the edge of the muck pit, on the opposite side of the wall from the very long ladder.
RC: Titanite Chunk - swamp near right, by sinking churchAt the very edge of the muck pit, to the left of the submerged building with 4 Ringed Knights.
RC: Titanite Chunk - wall top, among gravesAlong the right edge of the courtyard after Mausoleum Lookout in a cluster of graves.
RC: Titanite Chunk - wall upper, courtyard alcoveIn the courtyard where the first Ringed Knight is seen, along the right wall into an alcove.
RC: Titanite Scale - grave, lizard after first dropIn the area at the far end of the muck pit with the Dragonslayer Armour.
RC: Titanite Scale - lower cliff, bridgeOn the final bridge where Midir attacks before you knock him off.
RC: Titanite Scale - swamp far, by minibossIn the area at the far end of the muck pit with the Dragonslayer Armour.
RC: Titanite Scale - upper cliff, first alcoveIn the first alcove providing shelter from Midir's fire-breathing on the way to Shared Grave.
RC: Titanite Scale - upper cliff, lower pathAfter dropping down from the upper path attacked by Midir's fire-breathing to the lower path.
RC: Titanite Scale - upper cliff, path under bridgePartway down a slope to the right of the bridge where Midir first assaults you.
RC: Titanite Scale - wall lower, lizardDropped by the Crystal Lizard right after the crumbling stairs in Shared Grave.
RC: Titanite Scale - wall top, behind spawnBehind you at the very start of the level.
RC: Titanite Scale - wall top, lizard on side pathDropped by the Crystal Lizard on the stairs going up from Shared Grave to Ringed Inner Wall elevator.
RC: Titanite Slab - ashes, NPC dropGiven by Shira after defeating Midir, or dropped by her in post-Filianore Ringed City.
RC: Titanite Slab - ashes, mob dropDropped by the Ringed Knight wandering around near Gael's arena
RC: Titanite Slab - mid boss dropDropped by Halflight, Spear of the Church
RC: Twinkling Titanite - church path, left of boss doorDropping down to the left of the door leading to Halflight.
RC: Twinkling Titanite - grave, lizard after first dropDropped by the Crystal Lizard right after the crumbling stairs in Shared Grave.
RC: Twinkling Titanite - streets high, lizardDropped by the Crystal Lizard which runs across the bridge after climbing the very long ladder up from the muck pit.
RC: Twinkling Titanite - swamp near leftAt the left edge of the muck pit coming from the stairs, guarded by a Preacher Locust.
RC: Twinkling Titanite - swamp near right, on sinking churchFollowing the sloped roof of the submerged building with the 4 Ringed Knights, along the back wall
RC: Twinkling Titanite - wall top, lizard on side pathDropped by the first Crystal Lizard on the side path on the right side of the Mausoleum Lookout courtyard
RC: Twinkling Titanite - wall tower, jump from chandelierIn the cylindrical building before the long stairs with many Harald Legion Knights. Carefully drop down to the chandelier in the center, then jump to the second floor. The item is on a ledge.
RC: Violet Wrappings - wall hidden, before bossIn the chapel before the Midir fight in the Ringed Inner Wall building.
RC: White Birch Bow - swamp far left, up hillUp a hill at the edge of the muck pit with the Hollow Clerics.
RC: White Preacher Head - swamp near, ground near bonfire exitPast the balcony to the right of the Ringed City Streets bonfire room entrance. Can be accessed by dropping down straight after from the bonfire, then around to the left.
RC: Wolf Ring+3 - street gardens, NPC dropDropped by Alva (invades whether embered or not, or boss defeated or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight.
RC: Young White Branch - swamp far left, by white treeNext to a small birch tree at the edge of the muck pit, between the hill with the aggressive Hollow Clerics and the building with the praying Hollow Clerics outside.
RS: Blue Bug Pellet - broken stairs by OrbeckOn the broken stairs leading down from Orbeck's area, on the opposite side from Orbeck
RS: Blue Sentinels - HoraceGiven by Horace the Hushed by first "talking" to him, or upon death.
RS: Braille Divine Tome of Carim - drop from bridge to Halfway FortressDropping down before the bridge leading up to Halfway Fortress from Road of Sacrifices, guarded by the maggot belly dog
RS: Brigand Armor - beneath roadIn the middle of the path where the Madwoman waits in Road of Sacrifices
RS: Brigand Axe - beneath roadAt the start of the path leading down to the Madwoman in Road of Sacrifices
RS: Brigand Gauntlets - beneath roadIn the middle of the path where the Madwoman waits in Road of Sacrifices
RS: Brigand Hood - beneath roadIn the middle of the path where the Madwoman waits in Road of Sacrifices
RS: Brigand Trousers - beneath roadIn the middle of the path where the Madwoman waits in Road of Sacrifices
RS: Brigand Twindaggers - beneath roadAt the end of the path guarded by the Madwoman in Road of Sacrifices
RS: Butcher Knife - NPC drop beneath roadDropped by the Butcher Knife-wielding madwoman near the start of Road of Sacrifices
RS: Chloranthy Ring+2 - road, drop across from carriageFound dropping down from the first Storyteller Corvian on the left side rather than the right side. You can then further drop down to where the madwoman is, after healing.
RS: Conjurator Boots - deep waterIn the deep water part of the Crucifixion Woods crab area, between a large tree and the keep wall
RS: Conjurator Hood - deep waterIn the deep water part of the Crucifixion Woods crab area, between a large tree and the keep wall
RS: Conjurator Manchettes - deep waterIn the deep water part of the Crucifixion Woods crab area, between a large tree and the keep wall
RS: Conjurator Robe - deep waterIn the deep water part of the Crucifixion Woods crab area, between a large tree and the keep wall
RS: Crystal Gem - stronghold, lizardDropped by the Crystal Lizard in the building before Crystal Sage
RS: Ember - right of Halfway Fortress entranceOn the ledge with the Corvian with the Storyteller Staff, to the right of the Halfway Fortress entrance
RS: Ember - right of fire behind stronghold left roomBehind the building before Crystal Sage, approached from Crucifixion Woods bonfire. Can drop down on left side or go under bridge on right side
RS: Estus Shard - left of fire behind stronghold left roomBehind the building leading to Crystal Sage, approached from Crucifixion Woods bonfire. Can drop down on left side of go under bridge on right side
RS: Exile Greatsword - NPC drop by Farron KeepDropped by the greatsword-wielding Exile Knight before the ladder down to Farron Keep
RS: Fading Soul - woods by Crucifixion Woods bonfireDropping down from the Crucifixion Woods bonfire toward the Halfway Fortress, guarded by dogs
RS: Fallen Knight Armor - water's edge by Farron KeepOn the edge of the water surrounding the building where you descend into Farron Keep
RS: Fallen Knight Gauntlets - water's edge by Farron KeepOn the edge of the water surrounding the building where you descend into Farron Keep
RS: Fallen Knight Helm - water's edge by Farron KeepOn the edge of the water surrounding the building where you descend into Farron Keep
RS: Fallen Knight Trousers - water's edge by Farron KeepOn the edge of the water surrounding the building where you descend into Farron Keep
RS: Farron Coal - keep perimeterAt the end of the Farron Keep Perimeter building on Crucifixion Woods side, behind the Black Knight
RS: Golden Falcon Shield - path from stronghold right room to Farron KeepHalfway up the stairs to the sorcerer in the building before Crystal Sage, entering from the stairs leading up from the crab area, go straight and follow the path down
RS: Grass Crest Shield - water by Crucifixion Woods bonfireDropping down into the crab area from Crucifixion Woods, on the other side of a tree from the greater crab
RS: Great Club - NPC drop by Farron KeepDropped by the club-wielding Exile Knight before the ladder down to Farron Keep
RS: Great Swamp Pyromancy Tome - deep waterIn the deep water part of the Crucifixion Woods crab area, between a large tree and the keep wall
RS: Great Swamp Ring - miniboss drop, by Farron KeepDropped by Greater Crab in Crucifixion Woods close to the Farron Keep outer wall
RS: Green Blossom - by deep waterIn the Crucifixion Woods crab area out in the open, close to the edge of the deep water area
RS: Green Blossom - water beneath strongholdIn the Crucifixion Woods crab area close to the Crucifixion Woods bonfire, along the left wall of the water area, to the right of the entrance to the building before Crystal Sage
RS: Heretic's Staff - stronghold left roomIn the building before Crystal Sage, entering from near Cruficixion Woods, in a corner under the first stairwell and balcony
RS: Heysel Pick - Heysel dropDropped by Heysel when she invades in Road of Sacrifices
RS: Homeward Bone - balcony by Farron KeepAt the far end of the building where you descend into Farron Keep, by the balcony
RS: Large Soul of an Unknown Traveler - left of stairs to Farron KeepIn the area before you descend into Farron Keep, before the stairs to the far left
RS: Lingering Dragoncrest Ring+1 - waterOn a tree by the greater crab near the Crucifixion Woods bonfire, after the Grass Crest Shield tree
RS: Morne's Ring - drop from bridge to Halfway FortressDropping down before the bridge leading up to Halfway Fortress from Road of Sacrifices, guarded by the maggot belly dog
RS: Ring of Sacrifice - stronghold, drop from right room balconyDrop down from the platform behind the sorcerer in the building before Crystal Sage, entering from the stairs leading up from the crab area
RS: Sage Ring - water beneath strongholdIn an alcove under the building before Crystal Sage, guarded by a Lycanthrope, accessible from the swamp or from dropping down
RS: Sellsword Armor - keep perimeter balconyIn the Farron Keep Perimeter building on Crucifixion Woods side, on the balcony on the right side overlooking the Black Knight
RS: Sellsword Gauntlet - keep perimeter balconyIn the Farron Keep Perimeter building on Crucifixion Woods side, on the balcony on the right side overlooking the Black Knight
RS: Sellsword Helm - keep perimeter balconyIn the Farron Keep Perimeter building on Crucifixion Woods side, on the balcony on the right side overlooking the Black Knight
RS: Sellsword Trousers - keep perimeter balconyIn the Farron Keep Perimeter building on Crucifixion Woods side, on the balcony on the right side overlooking the Black Knight
RS: Sellsword Twinblades - keep perimeterIn the Farron Keep Perimeter building on Crucifixion Woods side, behind and to the right of the Black Knight
RS: Shriving Stone - road, by startDropping down to the left of the first Corvian enemy in Road of Sacrifices
RS: Sorcerer Gloves - water beneath strongholdIn an alcove under the building before Crystal Sage, guarded by a Lycanthrope, accessible from the swamp or from dropping down
RS: Sorcerer Hood - water beneath strongholdIn an alcove under the building before Crystal Sage, guarded by a Lycanthrope, accessible from the swamp or from dropping down
RS: Sorcerer Robe - water beneath strongholdIn an alcove under the building before Crystal Sage, guarded by a Lycanthrope, accessible from the swamp or from dropping down
RS: Sorcerer Trousers - water beneath strongholdIn an alcove under the building before Crystal Sage, guarded by a Lycanthrope, accessible from the swamp or from dropping down
RS: Soul of a Crystal SageDropped by Crystal Sage
RS: Soul of an Unknown Traveler (drop along wall from Halfway Fortress)From Halfway Fortress, hug the right wall and drop down twice on the way to the crab area
RS: Soul of an Unknown Traveler (right of door to stronghold left)Out in the open to the right of the building before Crystal Sage, as entered from Crufixion Woods bonfire
RS: Soul of an Unknown Traveler (road, by wagon)To the right of the overturned wagon descending from the Road of Sacrifices bonfire
RS: Titanite Shard (road, on bridge after you go under)Crossing the bridge you go under after the first Road of Sacrifices bonfire, after a sleeping Corvian and another Corvian guarding the pickup
RS: Titanite Shard (water by Halfway Fortress)Dropping down into the Crucifixion Woods crab area right after Halfway Fortress, on the left wall heading toward the Black Knight building, guarded by dog
RS: Titanite Shard (woods, left of path from Halfway Fortress)Hugging the left wall from Halfway Fortress to Crystal Sage, behind you after the first dropdown
RS: Titanite Shard (woods, surrounded by enemies)Hugging the left wall from Halfway Fortress to the Crystal Sage bonfire, after a dropdown surrounded by seven Poisonhorn bugs
RS: Twin Dragon Greatshield (woods by Crucifixion Woods bonfire)In the middle of the area with the Poisonhorn bugs and Lycanthrope Hunters, following the wall where the bugs guard a Titanite Shard
RS: Xanthous Crown (Heysel drop)Dropped by Heysel when she invades in Road of Sacrifices
SL: Black Iron Greatshield (ruins basement, NPC drop)Dropped by Knight Slayer Tsorig in Smouldering Lake
SL: Black Knight Sword (ruins main lower, illusory wall in far hall)On the far exit of the Demon Ruins main hall, past an illusory wall, guarded by a Black Knight
SL: Bloodbite Ring+1 (behind ballista)Behind the ballista, overlooking Smouldering Lake
SL: Chaos Gem (antechamber, lizard at end of long hall)Dropped by the Crystal Lizard found from the Antechamber bonfire, toward the Demon Cleric and to the right, then all the way down
SL: Chaos Gem (lake, far end by mob)In Smouldering Lake along the wall underneath the balista, all the way to the left past two crabs
SL: Dragonrider Bow (by ladder from ruins basement to ballista)After climbing up the ladder after the Black Knight in Demon Ruins, falling back down to a ledge
SL: Ember (ruins basement, in lava)In the lava pit under the Black Knight, by Knight Slayer Tsorig
SL: Ember (ruins main lower, path to antechamber)Going down the stairs from the Antechamber bonfire, to the right, at the end of the short hallway to the next right
SL: Ember (ruins main upper, hall end by hole)In the Demon Ruins, hugging the right wall from the Demon Ruins bonfire, or making a jump from the illusory hall corridor from Antechamber bonfire
SL: Ember (ruins main upper, just after entrance)Behind the first Demon Cleric from the Demon Ruins bonfire
SL: Estus Shard (antechamber, illusory wall)Behind an illusory wall and Smouldering Writhing Flesh-filled corridor from Antechamber bonfire
SL: Flame Stoneplate Ring+2 (ruins main lower, illusory wall in far hall)On the far exit of the Demon Ruins main hall, past an illusory wall, past the Black Knight, hidden in a corner
SL: Fume Ultra Greatsword (ruins basement, NPC drop)Dropped by Knight Slayer Tsorig in Smouldering Lake
SL: Homeward Bone (path to ballista)In the area targeted by the ballista after the long ladder guarded by the Black Knight, before the Bonewheel Skeletons
SL: Izalith Pyromancy Tome (antechamber, room near bonfire)In the room straight down from the Antechamber bonfire, past a Demon Cleric, surrounded by many Ghrus.
SL: Izalith Staff (ruins basement, second illusory wall behind chest)Past an illusory wall to the left of the Large Hound Rat in Demon Ruins, and then past another illusory wall, before the basilisk area
SL: Knight Slayer's Ring (ruins basement, NPC drop)Dropped by Knight Slayer Tsorig after invading in the Catacombs
SL: Large Titanite Shard (lake, by entrance)In the middle of Smouldering Lake, close to the Abandoned Tomb
SL: Large Titanite Shard (lake, by miniboss)In the middle of Smouldering Lake, under the Carthus Sandworm
SL: Large Titanite Shard (lake, by tree #1)In the middle of Smouldering Lake, by a tree before the hallway to the pit
SL: Large Titanite Shard (lake, by tree #2)In the middle of Smouldering Lake, by a tree before the hallway to the pit
SL: Large Titanite Shard (lake, straight from entrance)In the middle of Smouldering Lake, in between Abandoned Tomb and Demon Ruins
SL: Large Titanite Shard (ledge by Demon Ruins bonfire)On a corpse hanging off the ledge outside the Demon Ruins bonfire
SL: Large Titanite Shard (ruins basement, illusory wall in upper hall)In a chest past an illusory wall to the left of the Large Hound Rat in Demon Ruins, before the basilisk area
SL: Large Titanite Shard (side lake #1)In the Smouldering Lake pit where Horace can be found, following the right wall from Abandoned Tomb
SL: Large Titanite Shard (side lake #2)In the Smouldering Lake pit where Horace can be found, following the right wall from Abandoned Tomb
SL: Lightning Stake (lake, miniboss drop)Dropped by the giant Carthus Sandworm
SL: Llewellyn Shield (Horace drop)Dropped by Horace the Hushed upon death or quest completion.
SL: Quelana Pyromancy Tome (ruins main lower, illusory wall in grey room)At the far end of the Demon Ruins main hall to the right, where the rats are, then another right and past the illusory wall
SL: Sacred Flame (ruins basement, in lava)In the lava pit under the Black Knight, by Knight Slayer Tsorig
SL: Shield of Want (lake, by miniboss)In the middle of Smouldering Lake, under the Carthus Sandworm
SL: Soul of a Crestfallen Knight (ruins basement, above lava)Next to the Black Knight in Demon Ruins
RS: Soul of an Unknown Traveler - drop along wall from Halfway FortressFrom Halfway Fortress, hug the right wall and drop down twice on the way to the crab area
RS: Soul of an Unknown Traveler - right of door to stronghold leftOut in the open to the right of the building before Crystal Sage, as entered from Crufixion Woods bonfire
RS: Soul of an Unknown Traveler - road, by wagonTo the right of the overturned wagon descending from the Road of Sacrifices bonfire
RS: Titanite Shard - road, on bridge after you go underCrossing the bridge you go under after the first Road of Sacrifices bonfire, after a sleeping Corvian and another Corvian guarding the pickup
RS: Titanite Shard - water by Halfway FortressDropping down into the Crucifixion Woods crab area right after Halfway Fortress, on the left wall heading toward the Black Knight building, guarded by dog
RS: Titanite Shard - woods, left of path from Halfway FortressHugging the left wall from Halfway Fortress to Crystal Sage, behind you after the first dropdown
RS: Titanite Shard - woods, surrounded by enemiesHugging the left wall from Halfway Fortress to the Crystal Sage bonfire, after a dropdown surrounded by seven Poisonhorn bugs
RS: Twin Dragon Greatshield - woods by Crucifixion Woods bonfireIn the middle of the area with the Poisonhorn bugs and Lycanthrope Hunters, following the wall where the bugs guard a Titanite Shard
RS: Xanthous Crown - Heysel dropDropped by Heysel when she invades in Road of Sacrifices
SL: Black Iron Greatshield - ruins basement, NPC dropDropped by Knight Slayer Tsorig in Smouldering Lake
SL: Black Knight Sword - ruins main lower, illusory wall in far hallOn the far exit of the Demon Ruins main hall, past an illusory wall, guarded by a Black Knight
SL: Bloodbite Ring+1 - behind ballistaBehind the ballista, overlooking Smouldering Lake
SL: Chaos Gem - antechamber, lizard at end of long hallDropped by the Crystal Lizard found from the Antechamber bonfire, toward the Demon Cleric and to the right, then all the way down
SL: Chaos Gem - lake, far end by mobIn Smouldering Lake along the wall underneath the balista, all the way to the left past two crabs
SL: Dragonrider Bow - by ladder from ruins basement to ballistaAfter climbing up the ladder after the Black Knight in Demon Ruins, falling back down to a ledge
SL: Ember - ruins basement, in lavaIn the lava pit under the Black Knight, by Knight Slayer Tsorig
SL: Ember - ruins main lower, path to antechamberGoing down the stairs from the Antechamber bonfire, to the right, at the end of the short hallway to the next right
SL: Ember - ruins main upper, hall end by holeIn the Demon Ruins, hugging the right wall from the Demon Ruins bonfire, or making a jump from the illusory hall corridor from Antechamber bonfire
SL: Ember - ruins main upper, just after entranceBehind the first Demon Cleric from the Demon Ruins bonfire
SL: Estus Shard - antechamber, illusory wallBehind an illusory wall and Smouldering Writhing Flesh-filled corridor from Antechamber bonfire
SL: Flame Stoneplate Ring+2 - ruins main lower, illusory wall in far hallOn the far exit of the Demon Ruins main hall, past an illusory wall, past the Black Knight, hidden in a corner
SL: Fume Ultra Greatsword - ruins basement, NPC dropDropped by Knight Slayer Tsorig in Smouldering Lake
SL: Homeward Bone - path to ballistaIn the area targeted by the ballista after the long ladder guarded by the Black Knight, before the Bonewheel Skeletons
SL: Izalith Pyromancy Tome - antechamber, room near bonfireIn the room straight down from the Antechamber bonfire, past a Demon Cleric, surrounded by many Ghrus.
SL: Izalith Staff - ruins basement, second illusory wall behind chestPast an illusory wall to the left of the Large Hound Rat in Demon Ruins, and then past another illusory wall, before the basilisk area
SL: Knight Slayer's Ring - ruins basement, NPC dropDropped by Knight Slayer Tsorig after invading in the Catacombs
SL: Large Titanite Shard - lake, by entranceIn the middle of Smouldering Lake, close to the Abandoned Tomb
SL: Large Titanite Shard - lake, by minibossIn the middle of Smouldering Lake, under the Carthus Sandworm
SL: Large Titanite Shard - lake, by tree #1In the middle of Smouldering Lake, by a tree before the hallway to the pit
SL: Large Titanite Shard - lake, by tree #2In the middle of Smouldering Lake, by a tree before the hallway to the pit
SL: Large Titanite Shard - lake, straight from entranceIn the middle of Smouldering Lake, in between Abandoned Tomb and Demon Ruins
SL: Large Titanite Shard - ledge by Demon Ruins bonfireOn a corpse hanging off the ledge outside the Demon Ruins bonfire
SL: Large Titanite Shard - ruins basement, illusory wall in upper hallIn a chest past an illusory wall to the left of the Large Hound Rat in Demon Ruins, before the basilisk area
SL: Large Titanite Shard - side lake #1In the Smouldering Lake pit where Horace can be found, following the right wall from Abandoned Tomb
SL: Large Titanite Shard - side lake #2In the Smouldering Lake pit where Horace can be found, following the right wall from Abandoned Tomb
SL: Lightning Stake - lake, miniboss dropDropped by the giant Carthus Sandworm
SL: Llewellyn Shield - Horace dropDropped by Horace the Hushed upon death or quest completion.
SL: Quelana Pyromancy Tome - ruins main lower, illusory wall in grey roomAt the far end of the Demon Ruins main hall to the right, where the rats are, then another right and past the illusory wall
SL: Sacred Flame - ruins basement, in lavaIn the lava pit under the Black Knight, by Knight Slayer Tsorig
SL: Shield of Want - lake, by minibossIn the middle of Smouldering Lake, under the Carthus Sandworm
SL: Soul of a Crestfallen Knight - ruins basement, above lavaNext to the Black Knight in Demon Ruins
SL: Soul of the Old Demon KingDropped by Old Demon King in Smouldering Lake
SL: Speckled Stoneplate Ring (lake, ballista breaks bricks)Behind a destructible wall in Smouldering Lake which the ballista has to destroy
SL: Titanite Chunk (path to side lake, lizard)Dropped by the second Crystal Lizard in the cave leading to the pit where Horace can be found in Smouldering Lake
SL: Titanite Scale (ruins basement, path to lava)In the area with Basilisks on the way to the ballista
SL: Toxic Mist (ruins main lower, in lava)At the far end of the Demon Ruins main hall to the right, where the rats are, then another right and past the illusory wall, in the middle of the lava pit.
SL: Twinkling Titanite (path to side lake, lizard)Dropped by the first Crystal Lizard in the cave leading to the pit where Horace can be found in Smouldering Lake
SL: Undead Bone Shard (lake, miniboss drop)Dropped by the giant Carthus Sandworm
SL: Undead Bone Shard (ruins main lower, left after stairs)In the close end of the Demon Ruins main hall, right below a Smouldering Writhing Flesh
SL: White Hair Talisman (ruins main lower, in lava)At the far end of the Demon Ruins main hall to the right, where the rats are, then another right and past the illusory wall, at the far end of the lava pit.
SL: Yellow Bug Pellet (side lake)In the Smouldering Lake pit where Horace can be found, following the right wall from Abandoned Tomb
UG: Ashen Estus Ring (swamp, path opposite bonfire)In the coffin similar to your initial spawn location, guarded by Corvians
UG: Black Knight Glaive (boss arena)In the Champion Gundyr boss area
UG: Blacksmith Hammer (shrine, Andre's room)Where Andre sits in Firelink Shrine
UG: Chaos Blade (environs, left of shrine)Where Sword Master is in Firelink Shrine
UG: Coiled Sword Fragment (shrine, dead bonfire)In the dead Firelink Shrine bonfire
UG: Ember (shop)Sold by Untended Graves Handmaid
UG: Eyes of a Fire Keeper (shrine, Irina's room)Behind an illusory wall, in the same location Irina sits in Firelink Shrine
UG: Hidden Blessing (cemetery, behind coffin)Behind the coffin that had a Titanite Shard in Cemetary of Ash
UG: Hornet Ring (environs, right of main path after killing FK boss)On a cliffside to the right of the main path leading up to dark Firelink Shrine, after Abyss Watchers is defeated.
UG: Life Ring+3 (shrine, behind big throne)Behind Prince Lothric's throne
UG: Priestess Ring (shop)Sold or dropped by Untended Graves Handmaid. Killing her is not recommended
UG: Ring of Steel Protection+1 (environs, behind bell tower)Behind Bell Tower to the right
UG: Shriving Stone (swamp, by bonfire)At the very start of the area
SL: Speckled Stoneplate Ring - lake, ballista breaks bricksBehind a destructible wall in Smouldering Lake which the ballista has to destroy
SL: Titanite Chunk - path to side lake, lizardDropped by the second Crystal Lizard in the cave leading to the pit where Horace can be found in Smouldering Lake
SL: Titanite Scale - ruins basement, path to lavaIn the area with Basilisks on the way to the ballista
SL: Toxic Mist - ruins main lower, in lavaAt the far end of the Demon Ruins main hall to the right, where the rats are, then another right and past the illusory wall, in the middle of the lava pit.
SL: Twinkling Titanite - path to side lake, lizardDropped by the first Crystal Lizard in the cave leading to the pit where Horace can be found in Smouldering Lake
SL: Undead Bone Shard - lake, miniboss dropDropped by the giant Carthus Sandworm
SL: Undead Bone Shard - ruins main lower, left after stairsIn the close end of the Demon Ruins main hall, right below a Smouldering Writhing Flesh
SL: White Hair Talisman - ruins main lower, in lavaAt the far end of the Demon Ruins main hall to the right, where the rats are, then another right and past the illusory wall, at the far end of the lava pit.
SL: Yellow Bug Pellet - side lakeIn the Smouldering Lake pit where Horace can be found, following the right wall from Abandoned Tomb
UG: Ashen Estus Ring - swamp, path opposite bonfireIn the coffin similar to your initial spawn location, guarded by Corvians
UG: Black Knight Glaive - boss arenaIn the Champion Gundyr boss area
UG: Blacksmith Hammer - shrine, Andre's roomWhere Andre sits in Firelink Shrine
UG: Chaos Blade - environs, left of shrineWhere Sword Master is in Firelink Shrine
UG: Coiled Sword Fragment - shrine, dead bonfireIn the dead Firelink Shrine bonfire
UG: Ember - shopSold by Untended Graves Handmaid
UG: Eyes of a Fire Keeper - shrine, Irina's roomBehind an illusory wall, in the same location Irina sits in Firelink Shrine
UG: Hidden Blessing - cemetery, behind coffinBehind the coffin that had a Titanite Shard in Cemetary of Ash
UG: Hornet Ring - environs, right of main path after killing FK bossOn a cliffside to the right of the main path leading up to dark Firelink Shrine, after Abyss Watchers is defeated.
UG: Life Ring+3 - shrine, behind big throneBehind Prince Lothric's throne
UG: Priestess Ring - shopSold or dropped by Untended Graves Handmaid. Killing her is not recommended
UG: Ring of Steel Protection+1 - environs, behind bell towerBehind Bell Tower to the right
UG: Shriving Stone - swamp, by bonfireAt the very start of the area
UG: Soul of Champion GundyrDropped by Champion Gundyr
UG: Soul of a Crestfallen Knight (environs, above shrine entrance)Above the Firelink Shrine entrance, up stairs/slope from either left or right of the entrance
UG: Soul of a Crestfallen Knight (swamp, center)Close to where Ashen Estus Flask was in Cemetary of Ash
UG: Titanite Chunk (swamp, left path by fountain)In a path to the left of where Ashen Estus Flask was in Cemetary of Ash
UG: Titanite Chunk (swamp, right path by fountain)In a path to the right of where Ashen Estus Flask was in Cemetary of Ash
UG: Wolf Knight Armor (shop after killing FK boss)Sold by Untended Graves Handmaid after defeating Abyss Watchers
UG: Wolf Knight Gauntlets (shop after killing FK boss)Sold by Untended Graves Handmaid after defeating Abyss Watchers
UG: Wolf Knight Helm (shop after killing FK boss)Sold by Untended Graves Handmaid after defeating Abyss Watchers
UG: Wolf Knight Leggings (shop after killing FK boss)Sold by Untended Graves Handmaid after defeating Abyss Watchers
US: Alluring Skull (foot, behind carriage)Guarded by two dogs after the Foot of the High Wall bonfire
US: Alluring Skull (on the way to tower, behind building)After the ravine bridge leading to Eygon and the Giant's tower, wrapping around the building to the right.
US: Alluring Skull (tower village building, upstairs)Up the stairs of the building with Cage Spiders after the Fire Demon, before the dogs
US: Bloodbite Ring (miniboss in sewer)Dropped by the large rat in the sewers with grave access
US: Blue Wooden Shield (graveyard by white tree)After Dilapidated Bridge bonfire, in the back of the Giant's arrow area. Guarded by a flamberge-wielding thrall.
US: Caduceus Round Shield (right after stable exit)After exiting the building across the bridge to the right of the first Undead Settlement building, to the left
US: Caestus (sewer)In the tunnel with the Giant Hound Rat and Grave Key door, from the ravine bridge toward Dilapidated Bridge bonfire
US: Charcoal Pine Bundle (first building)On the bottom floor of the first building
US: Charcoal Pine Resin (hanging corpse room)In the building after the burning tree and Cathedral Evangelist, in the room with the many hanging corpses
US: Chloranthy Ring (tower village, jump from roof)At the end of the Fire Demon loop, in the tower where you have to drop down after the roof
US: Cleric Blue Robe (graveyard by white tree)After Dilapidated Bridge bonfire, in the back of the Giant's arrow area. Guarded by a flamberge-wielding thrall.
US: Cleric Gloves (graveyard by white tree)After Dilapidated Bridge bonfire, in the back of the Giant's arrow area. Guarded by a flamberge-wielding thrall.
US: Cleric Hat (graveyard by white tree)After Dilapidated Bridge bonfire, in the back of the Giant's arrow area. Guarded by a flamberge-wielding thrall.
US: Cleric Trousers (graveyard by white tree)After Dilapidated Bridge bonfire, in the back of the Giant's arrow area. Guarded by a flamberge-wielding thrall.
US: Cornyx's Garb (by Cornyx's cage after Cuculus quest)Appears next to Cornyx's cage after defeating Old Demon King with Cuculus surviving
US: Cornyx's Garb (kill Cornyx)Dropped by Cornyx
US: Cornyx's Skirt (by Cornyx's cage after Cuculus quest)Appears next to Cornyx's cage after defeating Old Demon King with Cuculus surviving
US: Cornyx's Skirt (kill Cornyx)Dropped by Cornyx
US: Cornyx's Wrap (by Cornyx's cage after Cuculus quest)Appears next to Cornyx's cage after defeating Old Demon King with Cuculus surviving
US: Cornyx's Wrap (kill Cornyx)Dropped by Cornyx
US: Covetous Silver Serpent Ring+2 (tower village, drop down from roof)At the back of a roof near the end of the Fire Demon loop, dropping down past where Flynn's Ring is
US: Ember (behind burning tree)Behind the burning tree with the Cathedral Evangelist
US: Ember (bridge on the way to tower)On the ravine bridge leading toward Eygon and the Giant's tower
US: Ember (by stairs to boss)Next to the stairs leading up to Curse-Rotted Greatwood fight, near a tree guarded by a dog
US: Ember (by white tree)Near the Birch Tree where giant shoots arrows
US: Ember (tower basement, miniboss)In the room with the Outrider Knight
US: Estus Shard (under burning tree)In front of the burning tree guarded by the Cathedral Evangelist
US: Fading Soul (by white tree)Near the Birch Tree where giant shoots arrows
US: Fading Soul (outside stable)In the thrall area to the right of the bridge to the right of the burning tree with the Cathedral Evangelist
US: Fire Clutch Ring (wooden walkway past stable)From the area bombarded by firebombs above the Cliff Underside bonfire
US: Fire Gem (tower village, miniboss drop)Dropped by the Fire Demon you fight with Siegward
US: Firebomb (stable roof)In the thrall area across the bridge from the first Undead Settlement building, on a rooftop overlooking the Cliff Underside area.
US: Flame Stoneplate Ring (hanging corpse by Mound-Maker transport)On a hanging corpse in the area with the Pit of Hollows cage manservant, after the thrall area, overlooking the entrance to the Giant's tower.
US: Flynn's Ring (tower village, rooftop)On the roof toward the end of the Fire Demon loop, past the Cathedral Evangelists
US: Great Scythe (building by white tree, balcony)On the balcony of the building before Curse-Rotted Greatwood, coming from Dilapidated Bridge bonfire
US: Hand Axe (by Cornyx)Next to Cornyx's cell
US: Hawk Ring (Giant Archer)Dropped by Giant, either by killing him or collecting all of the birch tree items locations in the base game.
US: Heavy Gem (Hawkwood)Given or dropped by Hawkwood after defeating Curse-Rotted Greatwood or Crystal Sage
US: Heavy Gem (chasm, lizard)Drop by Crystal Lizard in ravine accessible by Grave Key or dropping down near Eygon.
US: Homeward Bone (???)Given by Holy Knight Hodrick before fighting Curse-Rotted Greatwood, or on his corpse in the Pit of Hollows.
US: Homeward Bone (foot, drop overloop)Under Foot of the High Wall bonfire, around where Yoel can be first met
US: Homeward Bone (stable roof)In the thrall area across the bridge from the first Undead Settlement building, on a roof overlooking the ravine bridge.
US: Homeward Bone (tower village, jump from roof)At the end of the loop from the Siegward Demon fight, after dropping down from the roof onto the tower with Chloranthy Ring, to the right of the tower entrance
US: Human Pine Resin (tower village building, chest upstairs)In a chest after Fire Demon. Cage Spiders activate open opening it.
US: Irithyll Straight Sword (miniboss drop, by Road of Sacrifices)Dropped by the Boreal Outright Knight before Road of Sacrifices
US: Kukri (hanging corpse above burning tree)Hanging corpse high above the burning tree with the Cathedral Evangelist. Must be shot down with an arrow or projective.
US: Large Club (tower village, by miniboss)In the Fire Demon area
US: Large Soul of a Deserted Corpse (across from Foot of the High Wall)On the opposite tower from the Foot of the High Wall bonfire
US: Large Soul of a Deserted Corpse (around corner by Cliff Underside)After going up the stairs from Curse-Rotted Greatwood to Cliff Underside area, on a cliff edge to the right
US: Large Soul of a Deserted Corpse (by white tree)Near the Birch Tree where giant shoots arrows
US: Large Soul of a Deserted Corpse (hanging corpse room, over stairs)On a hanging corpse in the building after the burning tree. Can be knocked down by dropping onto the stairs through the broken railing.
US: Large Soul of a Deserted Corpse (on the way to tower, by well)After the ravine bridge leading toward Eygon and the Giant's tower, next to the well to the right
US: Large Soul of a Deserted Corpse (stable)In the building with stables across the bridge and to the right from the first Undead Settlement building
US: Life Ring+1 (tower on the way to village)On the wooden rafters near where Siegward is waiting for Fire Demon
US: Loincloth (by Velka statue)Next to the Velka statue. Requires Grave Key or dropping down near Eygon and backtracking through the skeleton area.
US: Loretta's Bone (first building, hanging corpse on balcony)On a hanging corpse after the first building, can be knocked down by rolling into it
US: Mirrah Gloves (tower village, jump from roof)At the end of the Fire Demon loop, in the tower where you have to drop down after the roof
US: Mirrah Trousers (tower village, jump from roof)At the end of the Fire Demon loop, in the tower where you have to drop down after the roof
US: Mirrah Vest (tower village, jump from roof)At the end of the Fire Demon loop, in the tower where you have to drop down after the roof
US: Mortician's Ashes (graveyard by white tree)In the area past the Dilapidated Bridge bonfire, where the Giant is shooting arrows, at the close end of the graveyard
US: Mound-makers (Hodrick)Given by Hodrick if accessing the Pit of Hollows before fighting Curse-Rotted Greatwood, or dropped after invading him with Sirris.
US: Northern Armor (tower village, hanging corpse)Hanging corpse in the Fire Demon fight area, can be knocked down by rolling into it
US: Northern Gloves (tower village, hanging corpse)Hanging corpse in the Fire Demon fight area, can be knocked down by rolling into it
US: Northern Helm (tower village, hanging corpse)Hanging corpse in the Fire Demon fight area, can be knocked down by rolling into it
US: Northern Trousers (tower village, hanging corpse)Hanging corpse in the Fire Demon fight area, can be knocked down by rolling into it
US: Old Sage's Blindfold (kill Cornyx)Dropped by Cornyx
US: Pale Tongue (tower village, hanging corpse)Hanging corpse in the Fire Demon fight area, can be knocked down by rolling into it
US: Partizan (hanging corpse above Cliff Underside)On a hanging corpse on the path from Cliff Underside to Cornyx's cage. Must be shot down with an arrow or projective.
US: Plank Shield (outside stable, by NPC)In the thrall area across the bridge from the first Undead Settlement building, on a cliff edge overlooking the ravine bridge.
US: Poisonbite Ring+1 (graveyard by white tree, near well)Behind the well in the back of area where the Giant shoots arrows, nearby where the flamerge-wielding thrall drops down.
US: Pyromancy Flame (Cornyx)Given by Cornyx in Firelink Shrine or dropped.
US: Red Bug Pellet (tower village building, basement)On the floor of the building after the Fire Demon encounter
US: Red Hilted Halberd (chasm crypt)In the skeleton area accessible from Grave Key or dropping down from near Eygon
US: Red and White Shield (chasm, hanging corpse)On a hanging corpse in the ravine accessible with the Grave Key or dropping down near Eygon, to the entrance of Irina's prison. Must be shot down with an arrow or projective.
US: Reinforced Club (by white tree)Near the Birch Tree where giant shoots arrows
US: Repair Powder (first building, balcony)On the balcony of the first Undead Settlement building
US: Rusted Coin (awning above Dilapidated Bridge)On a wooden ledge near the Dilapidated Bridge bonfire. Must be jumped to from near Cathedral Evangelist enemy
US: Saint's Talisman (chasm, by ladder)From the ravine accessible via Grave Key or dropping near Eygon, before ladder leading up to Irina of Carim
US: Sharp Gem (lizard by Dilapidated Bridge)Drop by Crystal Lizard near Dilapidated Bridge bonfire.
US: Siegbräu (Siegward)Given by Siegward after helping him defeat the Fire Demon.
US: Small Leather Shield (first building, hanging corpse by entrance)Hanging corpse in the first building, to the right of the entrance
US: Soul of a Nameless Soldier (top of tower)At the top of the tower where Giant shoots arrows
US: Soul of an Unknown Traveler (back alley, past crates)After exiting the building after the burning tree on the way to the Dilapidated Bridge bonfire. Hidden behind some crates between two buildings on the right.
US: Soul of an Unknown Traveler (chasm crypt)In the skeleton area accessible Grave Key or dropping down from near Eygon
US: Soul of an Unknown Traveler (pillory past stable)In the area bombarded by firebombs above the Cliff Underside bonfire
US: Soul of an Unknown Traveler (portcullis by burning tree)Behind a grate to the left of the burning tree and Cathedral Evangelist
UG: Soul of a Crestfallen Knight - environs, above shrine entranceAbove the Firelink Shrine entrance, up stairs/slope from either left or right of the entrance
UG: Soul of a Crestfallen Knight - swamp, centerClose to where Ashen Estus Flask was in Cemetary of Ash
UG: Titanite Chunk - swamp, left path by fountainIn a path to the left of where Ashen Estus Flask was in Cemetary of Ash
UG: Titanite Chunk - swamp, right path by fountainIn a path to the right of where Ashen Estus Flask was in Cemetary of Ash
UG: Wolf Knight Armor - shop after killing FK bossSold by Untended Graves Handmaid after defeating Abyss Watchers
UG: Wolf Knight Gauntlets - shop after killing FK bossSold by Untended Graves Handmaid after defeating Abyss Watchers
UG: Wolf Knight Helm - shop after killing FK bossSold by Untended Graves Handmaid after defeating Abyss Watchers
UG: Wolf Knight Leggings - shop after killing FK bossSold by Untended Graves Handmaid after defeating Abyss Watchers
US: Alluring Skull - foot, behind carriageGuarded by two dogs after the Foot of the High Wall bonfire
US: Alluring Skull - on the way to tower, behind buildingAfter the ravine bridge leading to Eygon and the Giant's tower, wrapping around the building to the right.
US: Alluring Skull - tower village building, upstairsUp the stairs of the building with Cage Spiders after the Fire Demon, before the dogs
US: Bloodbite Ring - miniboss in sewerDropped by the large rat in the sewers with grave access
US: Blue Wooden Shield - graveyard by white treeAfter Dilapidated Bridge bonfire, in the back of the Giant's arrow area. Guarded by a flamberge-wielding thrall.
US: Caduceus Round Shield - right after stable exitAfter exiting the building across the bridge to the right of the first Undead Settlement building, to the left
US: Caestus - sewerIn the tunnel with the Giant Hound Rat and Grave Key door, from the ravine bridge toward Dilapidated Bridge bonfire
US: Charcoal Pine Bundle - first buildingOn the bottom floor of the first building
US: Charcoal Pine Resin - hanging corpse roomIn the building after the burning tree and Cathedral Evangelist, in the room with the many hanging corpses
US: Chloranthy Ring - tower village, jump from roofAt the end of the Fire Demon loop, in the tower where you have to drop down after the roof
US: Cleric Blue Robe - graveyard by white treeAfter Dilapidated Bridge bonfire, in the back of the Giant's arrow area. Guarded by a flamberge-wielding thrall.
US: Cleric Gloves - graveyard by white treeAfter Dilapidated Bridge bonfire, in the back of the Giant's arrow area. Guarded by a flamberge-wielding thrall.
US: Cleric Hat - graveyard by white treeAfter Dilapidated Bridge bonfire, in the back of the Giant's arrow area. Guarded by a flamberge-wielding thrall.
US: Cleric Trousers - graveyard by white treeAfter Dilapidated Bridge bonfire, in the back of the Giant's arrow area. Guarded by a flamberge-wielding thrall.
US: Cornyx's Garb - by Cornyx's cage after Cuculus questAppears next to Cornyx's cage after defeating Old Demon King with Cuculus surviving
US: Cornyx's Garb - kill CornyxDropped by Cornyx
US: Cornyx's Skirt - by Cornyx's cage after Cuculus questAppears next to Cornyx's cage after defeating Old Demon King with Cuculus surviving
US: Cornyx's Skirt - kill CornyxDropped by Cornyx
US: Cornyx's Wrap - by Cornyx's cage after Cuculus questAppears next to Cornyx's cage after defeating Old Demon King with Cuculus surviving
US: Cornyx's Wrap - kill CornyxDropped by Cornyx
US: Covetous Silver Serpent Ring+2 - tower village, drop down from roofAt the back of a roof near the end of the Fire Demon loop, dropping down past where Flynn's Ring is
US: Ember - behind burning treeBehind the burning tree with the Cathedral Evangelist
US: Ember - bridge on the way to towerOn the ravine bridge leading toward Eygon and the Giant's tower
US: Ember - by stairs to bossNext to the stairs leading up to Curse-Rotted Greatwood fight, near a tree guarded by a dog
US: Ember - by white treeNear the Birch Tree where giant shoots arrows
US: Ember - tower basement, minibossIn the room with the Outrider Knight
US: Estus Shard - under burning treeIn front of the burning tree guarded by the Cathedral Evangelist
US: Fading Soul - by white treeNear the Birch Tree where giant shoots arrows
US: Fading Soul - outside stableIn the thrall area to the right of the bridge to the right of the burning tree with the Cathedral Evangelist
US: Fire Clutch Ring - wooden walkway past stableFrom the area bombarded by firebombs above the Cliff Underside bonfire
US: Fire Gem - tower village, miniboss dropDropped by the Fire Demon you fight with Siegward
US: Firebomb - stable roofIn the thrall area across the bridge from the first Undead Settlement building, on a rooftop overlooking the Cliff Underside area.
US: Flame Stoneplate Ring - hanging corpse by Mound-Maker transportOn a hanging corpse in the area with the Pit of Hollows cage manservant, after the thrall area, overlooking the entrance to the Giant's tower.
US: Flynn's Ring - tower village, rooftopOn the roof toward the end of the Fire Demon loop, past the Cathedral Evangelists
US: Great Scythe - building by white tree, balconyOn the balcony of the building before Curse-Rotted Greatwood, coming from Dilapidated Bridge bonfire
US: Hand Axe - by CornyxNext to Cornyx's cell
US: Hawk Ring - Giant ArcherDropped by Giant, either by killing him or collecting all of the birch tree items locations in the base game.
US: Heavy Gem - HawkwoodGiven or dropped by Hawkwood after defeating Curse-Rotted Greatwood or Crystal Sage
US: Heavy Gem - chasm, lizardDrop by Crystal Lizard in ravine accessible by Grave Key or dropping down near Eygon.
US: Homeward Bone - foot, drop overloopUnder Foot of the High Wall bonfire, around where Yoel can be first met
US: Homeward Bone - stable roofIn the thrall area across the bridge from the first Undead Settlement building, on a roof overlooking the ravine bridge.
US: Homeward Bone - tower village, jump from roofAt the end of the loop from the Siegward Demon fight, after dropping down from the roof onto the tower with Chloranthy Ring, to the right of the tower entrance
US: Homeward Bone - tower village, right at startUnder Foot of the High Wall bonfire, around where Yoel can be first met
US: Human Pine Resin - tower village building, chest upstairsIn a chest after Fire Demon. Cage Spiders activate open opening it.
US: Irithyll Straight Sword - miniboss drop, by Road of SacrificesDropped by the Boreal Outright Knight before Road of Sacrifices
US: Kukri - hanging corpse above burning treeHanging corpse high above the burning tree with the Cathedral Evangelist. Must be shot down with an arrow or projective.
US: Large Club - tower village, by minibossIn the Fire Demon area
US: Large Soul of a Deserted Corpse - across from Foot of the High WallOn the opposite tower from the Foot of the High Wall bonfire
US: Large Soul of a Deserted Corpse - around corner by Cliff UndersideAfter going up the stairs from Curse-Rotted Greatwood to Cliff Underside area, on a cliff edge to the right
US: Large Soul of a Deserted Corpse - by white treeNear the Birch Tree where giant shoots arrows
US: Large Soul of a Deserted Corpse - hanging corpse room, over stairsOn a hanging corpse in the building after the burning tree. Can be knocked down by dropping onto the stairs through the broken railing.
US: Large Soul of a Deserted Corpse - on the way to tower, by wellAfter the ravine bridge leading toward Eygon and the Giant's tower, next to the well to the right
US: Large Soul of a Deserted Corpse - stableIn the building with stables across the bridge and to the right from the first Undead Settlement building
US: Life Ring+1 - tower on the way to villageOn the wooden rafters near where Siegward is waiting for Fire Demon
US: Loincloth - by Velka statueNext to the Velka statue. Requires Grave Key or dropping down near Eygon and backtracking through the skeleton area.
US: Loretta's Bone - first building, hanging corpse on balconyOn a hanging corpse after the first building, can be knocked down by rolling into it
US: Mirrah Gloves - tower village, jump from roofAt the end of the Fire Demon loop, in the tower where you have to drop down after the roof
US: Mirrah Trousers - tower village, jump from roofAt the end of the Fire Demon loop, in the tower where you have to drop down after the roof
US: Mirrah Vest - tower village, jump from roofAt the end of the Fire Demon loop, in the tower where you have to drop down after the roof
US: Mortician's Ashes - graveyard by white treeIn the area past the Dilapidated Bridge bonfire, where the Giant is shooting arrows, at the close end of the graveyard
US: Mound-makers - HodrickGiven by Hodrick if accessing the Pit of Hollows before fighting Curse-Rotted Greatwood, or dropped after invading him with Sirris.
US: Northern Armor - tower village, hanging corpseHanging corpse in the Fire Demon fight area, can be knocked down by rolling into it
US: Northern Gloves - tower village, hanging corpseHanging corpse in the Fire Demon fight area, can be knocked down by rolling into it
US: Northern Helm - tower village, hanging corpseHanging corpse in the Fire Demon fight area, can be knocked down by rolling into it
US: Northern Trousers - tower village, hanging corpseHanging corpse in the Fire Demon fight area, can be knocked down by rolling into it
US: Old Sage's Blindfold - kill CornyxDropped by Cornyx
US: Pale Tongue - tower village, hanging corpseHanging corpse in the Fire Demon fight area, can be knocked down by rolling into it
US: Partizan - hanging corpse above Cliff UndersideOn a hanging corpse on the path from Cliff Underside to Cornyx's cage. Must be shot down with an arrow or projective.
US: Plank Shield - outside stable, by NPCIn the thrall area across the bridge from the first Undead Settlement building, on a cliff edge overlooking the ravine bridge.
US: Poisonbite Ring+1 - graveyard by white tree, near wellBehind the well in the back of area where the Giant shoots arrows, nearby where the flamerge-wielding thrall drops down.
US: Pyromancy Flame - CornyxGiven by Cornyx in Firelink Shrine or dropped.
US: Red Bug Pellet - tower village building, basementOn the floor of the building after the Fire Demon encounter
US: Red Hilted Halberd - chasm cryptIn the skeleton area accessible from Grave Key or dropping down from near Eygon
US: Red and White Shield - chasm, hanging corpseOn a hanging corpse in the ravine accessible with the Grave Key or dropping down near Eygon, to the entrance of Irina's prison. Must be shot down with an arrow or projective.
US: Reinforced Club - by white treeNear the Birch Tree where giant shoots arrows
US: Repair Powder - first building, balconyOn the balcony of the first Undead Settlement building
US: Rusted Coin - awning above Dilapidated BridgeOn a wooden ledge near the Dilapidated Bridge bonfire. Must be jumped to from near Cathedral Evangelist enemy
US: Saint's Talisman - chasm, by ladderFrom the ravine accessible via Grave Key or dropping near Eygon, before ladder leading up to Irina of Carim
US: Sharp Gem - lizard by Dilapidated BridgeDrop by Crystal Lizard near Dilapidated Bridge bonfire.
US: Siegbräu - SiegwardGiven by Siegward after helping him defeat the Fire Demon.
US: Small Leather Shield - first building, hanging corpse by entranceHanging corpse in the first building, to the right of the entrance
US: Soul of a Nameless Soldier - top of towerAt the top of the tower where Giant shoots arrows
US: Soul of an Unknown Traveler - back alley, past cratesAfter exiting the building after the burning tree on the way to the Dilapidated Bridge bonfire. Hidden behind some crates between two buildings on the right.
US: Soul of an Unknown Traveler - chasm cryptIn the skeleton area accessible Grave Key or dropping down from near Eygon
US: Soul of an Unknown Traveler - pillory past stableIn the area bombarded by firebombs above the Cliff Underside bonfire
US: Soul of an Unknown Traveler - portcullis by burning treeBehind a grate to the left of the burning tree and Cathedral Evangelist
US: Soul of the Rotted GreatwoodDropped by Curse Rotted Greatwood
US: Spotted Whip (by Cornyx's cage after Cuculus quest)Appears next to Cornyx's cage after defeating Old Demon King with Cuculus surviving
US: Sunset Armor (pit of hollows after killing Hodrick w/Sirris)Found in Pit of Hollows after completing Sirris' questline.
US: Sunset Gauntlets (pit of hollows after killing Hodrick w/Sirris)Found in Pit of Hollows after completing Sirris' questline.
US: Sunset Helm (Pit of Hollows after killing Hodrick w/Sirris)Found in Pit of Hollows after completing Sirris' questline.
US: Sunset Leggings (pit of hollows after killing Hodrick w/Sirris)Found in Pit of Hollows after completing Sirris' questline.
US: Titanite Shard (back alley, side path)On a side path to the right of the Cathedral Evangelist before the Dilapidated Bridge bonfire
US: Titanite Shard (back alley, up ladder)Next to the Cathedral Evangelist close to the Dilapidated Bridge bonfire
US: Titanite Shard (chasm #1)In the ravine accessible from Grave Key or dropping down from near Eygon
US: Titanite Shard (chasm #2)In the ravine accessible from Grave Key or dropping down from near Eygon
US: Titanite Shard (lower path to Cliff Underside)At the end of the cliffside path next to Cliff Underside bonfire, guarded by a Hollow Peasant wielding a four-pronged plow.
US: Titanite Shard (porch after burning tree)In front of the building after the burning tree and Cathedral Evangelist
US: Tower Key (kill Irina)Dropped by Irina of Carim
US: Transposing Kiln (boss drop)Dropped by Curse Rotted Greatwood
US: Undead Bone Shard (by white tree)In the area past the Dilapidated Bridge bonfire, where the Giant is shooting arrows, jumping to the floating platform on the right
US: Wargod Wooden Shield (Pit of Hollows)In the Pit of Hollows
US: Warrior of Sunlight (hanging corpse room, drop through hole)Dropping through a hole in the floor in the first building after the burning tree.
US: Whip (back alley, behind wooden wall)In one of the houses between building after the burning tree and the Dilapidated Bridge bonfire
US: Young White Branch (by white tree #1)Near the Birch Tree where giant shoots arrows
US: Young White Branch (by white tree #2)Near the Birch Tree where giant shoots arrows
US: Spotted Whip - by Cornyx's cage after Cuculus questAppears next to Cornyx's cage after defeating Old Demon King with Cuculus surviving
US: Sunset Armor - pit of hollows after killing Hodrick w/SirrisFound in Pit of Hollows after completing Sirris' questline.
US: Sunset Gauntlets - pit of hollows after killing Hodrick w/SirrisFound in Pit of Hollows after completing Sirris' questline.
US: Sunset Helm - Pit of Hollows after killing Hodrick w/SirrisFound in Pit of Hollows after completing Sirris' questline.
US: Sunset Leggings - pit of hollows after killing Hodrick w/SirrisFound in Pit of Hollows after completing Sirris' questline.
US: Titanite Shard - back alley, side pathOn a side path to the right of the Cathedral Evangelist before the Dilapidated Bridge bonfire
US: Titanite Shard - back alley, up ladderNext to the Cathedral Evangelist close to the Dilapidated Bridge bonfire
US: Titanite Shard - chasm #1In the ravine accessible from Grave Key or dropping down from near Eygon
US: Titanite Shard - chasm #2In the ravine accessible from Grave Key or dropping down from near Eygon
US: Titanite Shard - lower path to Cliff UndersideAt the end of the cliffside path next to Cliff Underside bonfire, guarded by a Hollow Peasant wielding a four-pronged plow.
US: Titanite Shard - porch after burning treeIn front of the building after the burning tree and Cathedral Evangelist
US: Tower Key - kill IrinaDropped by Irina of Carim
US: Transposing Kiln - boss dropDropped by Curse Rotted Greatwood
US: Undead Bone Shard - by white treeIn the area past the Dilapidated Bridge bonfire, where the Giant is shooting arrows, jumping to the floating platform on the right
US: Wargod Wooden Shield - Pit of HollowsIn the Pit of Hollows
US: Warrior of Sunlight - hanging corpse room, drop through holeDropping through a hole in the floor in the first building after the burning tree.
US: Whip - back alley, behind wooden wallIn one of the houses between building after the burning tree and the Dilapidated Bridge bonfire
US: Young White Branch - by white tree #1Near the Birch Tree where giant shoots arrows
US: Young White Branch - by white tree #2Near the Birch Tree where giant shoots arrows
From 7ed270e7d768a32a1caf4e86df4a2c2e9b8eeb59 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 9 Jan 2024 19:39:56 -0800 Subject: [PATCH 123/238] Update and fix more locations --- worlds/dark_souls_3/Bosses.py | 6 +- worlds/dark_souls_3/Items.py | 10 +-- worlds/dark_souls_3/Locations.py | 73 +++++++++++----------- worlds/dark_souls_3/docs/locations_en.md | 73 ++++++++++++---------- worlds/dark_souls_3/test/TestDarkSouls3.py | 14 +++-- 5 files changed, 87 insertions(+), 89 deletions(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index 0c15ea4de976..99c51e6a76fd 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -193,10 +193,8 @@ class DS3BossInfo: "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", - "PW1: Champion's Bones - boss drop", - }), + DS3BossInfo("Champion's Gravetender and Gravetender Greatwolf", 4500860, dlc = True, + locations = {"PW1: Valorheart - boss drop"}), DS3BossInfo("Sister Friede", 4500801, dlc = True, region = "Dreg Heap", locations = { "PW2: Soul of Sister Friede", "PW2: Titanite Slab - boss drop", diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 33c9237b51ee..c018767673a9 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -142,16 +142,10 @@ class DS3ItemData(): skip: bool = False """Whether to omit this item from randomization and replace it with filler or unique items.""" - force_unique: bool = False - """Whether to ensure only one copy of this item appears in the run. - - This is automatically done for non-MISC items, but may be useful for MISC items in some cases. - """ - @property def unique(self): """Whether this item should be unique, appearing only once in the randomizer.""" - return self.force_unique or self.category not in { + return self.category not in { DS3ItemCategory.MISC, DS3ItemCategory.SOUL, DS3ItemCategory.UPGRADE, DS3ItemCategory.HEALING, } @@ -1040,7 +1034,7 @@ def flatten(l): DS3ItemData("Pale Tongue", 0x40000175, DS3ItemCategory.MISC, classification = ItemClassification.progression), DS3ItemData("Vertebra Shackle", 0x40000176, DS3ItemCategory.MISC, - classification = ItemClassification.progression, force_unique = True), # Crow trade + classification = ItemClassification.progression), # Crow trade DS3ItemData("Sunlight Medal", 0x40000177, DS3ItemCategory.MISC, skip = True), DS3ItemData("Dragon Head Stone", 0x40000179, DS3ItemCategory.UNIQUE), DS3ItemData("Dragon Torso Stone", 0x4000017A, DS3ItemCategory.UNIQUE), diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 35e8b3a2b3ea..a2833b99e4ce 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -659,7 +659,8 @@ def __init__( DS3LocationData("US: Titanite Shard - porch after burning tree", "Titanite Shard"), DS3LocationData("US: Alluring Skull - tower village building, upstairs", "Alluring Skull x2"), - DS3LocationData("US: Charcoal Pine Bundle - first building", "Charcoal Pine Bundle x2"), + DS3LocationData("US: Charcoal Pine Bundle - first building, middle floor", + "Charcoal Pine Bundle x2"), DS3LocationData("US: Blue Wooden Shield - graveyard by white tree", "Blue Wooden Shield"), DS3LocationData("US: Cleric Hat - graveyard by white tree", "Cleric Hat"), DS3LocationData("US: Cleric Blue Robe - graveyard by white tree", "Cleric Blue Robe"), @@ -671,7 +672,8 @@ def __init__( DS3LocationData("US: Loincloth - by Velka statue", "Loincloth"), DS3LocationData("US: Bloodbite Ring - miniboss in sewer", "Bloodbite Ring", miniboss = True), # Giant Rat drop - DS3LocationData("US: Charcoal Pine Bundle - first building", "Charcoal Pine Bundle x2"), + DS3LocationData("US: Charcoal Pine Bundle - first building, bottom floor", + "Charcoal Pine Bundle x2"), DS3LocationData("US: Soul of an Unknown Traveler - back alley, past crates", "Soul of an Unknown Traveler", hidden = True), DS3LocationData("US: Titanite Shard - back alley, up ladder", "Titanite Shard"), @@ -1383,8 +1385,8 @@ def __init__( DS3LocationData("CC: Twinkling Titanite - atrium lower, lizard down more stairs", "Twinkling Titanite", lizard = True), DS3LocationData("CC: Fire Gem - cavern, lizard", "Fire Gem", lizard = True), - DS3LocationData("CC: Homeward Bone - bridge", "Homeward Bone"), - DS3LocationData("CC: Pontiff's Right Eye - bridge, miniboss drop", + DS3LocationData("CC: Homeward Bone - Irithyll bridge", "Homeward Bone"), + DS3LocationData("CC: Pontiff's Right Eye - Irithyll bridge, miniboss drop", "Pontiff's Right Eye", miniboss = True), # Sulyvahn's Beast drop # Shrine Handmaid after killing High Lord Wolnir @@ -1674,9 +1676,9 @@ def __init__( DS3LocationData("ID: Soul of a Crestfallen Knight - balcony above pit", "Soul of a Crestfallen Knight"), DS3LocationData("ID: Lightning Bolt - awning over pit", "Lightning Bolt x9"), - DS3LocationData("ID: Large Titanite Shard - pit", "Large Titanite Shard"), + DS3LocationData("ID: Large Titanite Shard - pit #1", "Large Titanite Shard"), DS3LocationData("ID: Profaned Flame - pit", "Profaned Flame"), - DS3LocationData("ID: Large Titanite Shard - pit", "Large Titanite Shard"), + DS3LocationData("ID: Large Titanite Shard - pit #2", "Large Titanite Shard"), DS3LocationData("ID: Soul of a Weary Warrior - stairs between pit and B3", "Soul of a Weary Warrior"), DS3LocationData("ID: Dung Pie - B3, by path from pit", "Dung Pie x4"), @@ -1702,8 +1704,6 @@ def __init__( DS3LocationData("ID: Large Titanite Shard - B1 near, by door", "Large Titanite Shard"), DS3LocationData("ID: Rusted Gold Coin - after bonfire, last cell on right", "Rusted Gold Coin"), - DS3LocationData("ID: Large Titanite Shard - stairs between pit and B3", - "Large Titanite Shard"), DS3LocationData("ID: Old Cell Key - stairs between pit and B3", "Old Cell Key"), DS3LocationData("ID: Covetous Silver Serpent Ring+1 - pit lift, middle platform", "Covetous Silver Serpent Ring+1", ngp = True), @@ -2386,7 +2386,7 @@ def __init__( DS3LocationData("AP: Soul of a Nameless Soldier - intro, right before archway", "Soul of a Nameless Soldier"), DS3LocationData("AP: Titanite Chunk - intro, archway corner", "Titanite Chunk"), - DS3LocationData("AP: Ember - fort overlook #2", "Ember"), + DS3LocationData("AP: Ember - fort overlook #1", "Ember"), DS3LocationData("AP: Large Soul of a Weary Warrior - fort, center", "Large Soul of a Weary Warrior"), DS3LocationData("AP: Large Soul of a Nameless Soldier - fort, by stairs to first room", @@ -2760,7 +2760,7 @@ def __init__( hostile_npc = True), # Alva drop DS3LocationData("RC: Blindfold Mask - grave, NPC drop", "Blindfold Mask", hostile_npc = True), # Moaning Knight drop - DS3LocationData("RC: Titanite Scale - wall top, behind spawn", "Titanite Scale"), + DS3LocationData("RC: Titanite Scale - wall top, behind spawn", "Titanite Scale"), # wrong DS3LocationData("RC: Ruin Helm - wall top, under stairs to bonfire", "Ruin Helm"), DS3LocationData("RC: Ruin Armor - wall top, under stairs to bonfire", "Ruin Armor"), DS3LocationData("RC: Ruin Gauntlets - wall top, under stairs to bonfire", "Ruin Gauntlets"), @@ -2817,37 +2817,36 @@ def __init__( "Covetous Gold Serpent Ring+3"), DS3LocationData("RC: Titanite Chunk - streets high, building opposite", "Titanite Chunk x2"), DS3LocationData("RC: Dark Gem - swamp near, by stairs", "Dark Gem"), - DS3LocationData("RC: Prism Stone - swamp near, path to bonfire", "Prism Stone x4"), - DS3LocationData("RC: Ringed Knight Straight Sword - swamp near, pillar by bonfire", + DS3LocationData("RC: Prism Stone - swamp near, railing by bonfire", "Prism Stone x4"), + DS3LocationData("RC: Ringed Knight Straight Sword - swamp near, tower on peninsula", "Ringed Knight Straight Sword"), DS3LocationData("RC: Havel's Ring+3 - streets high, drop from building opposite", "Havel's Ring+3", hidden = True), # Hidden fall - DS3LocationData("RC: Titanite Chunk - swamp near left, opposite ladder", "Titanite Chunk"), + DS3LocationData("RC: Titanite Chunk - swamp near left, by spire top", "Titanite Chunk"), DS3LocationData("RC: Twinkling Titanite - swamp near left", "Twinkling Titanite"), DS3LocationData("RC: Soul of a Weary Warrior - swamp center", "Soul of a Weary Warrior"), - DS3LocationData("RC: Preacher's Right Arm - swamp near right, by crystal", + DS3LocationData("RC: Preacher's Right Arm - swamp near right, by tower", "Preacher's Right Arm"), DS3LocationData("RC: Rubbish - swamp far, by crystal", "Rubbish"), - DS3LocationData("RC: Titanite Chunk - swamp near right, by sinking church", + DS3LocationData("RC: Titanite Chunk - swamp near right, behind rock", "Titanite Chunk"), - DS3LocationData("RC: Black Witch Veil - swamp near right, by sinking church", + DS3LocationData("RC: Black Witch Veil - swamp near right, by sunken church", "Black Witch Veil"), - DS3LocationData("RC: Twinkling Titanite - swamp near right, on sinking church", + DS3LocationData("RC: Twinkling Titanite - swamp near right, on sunken church", "Twinkling Titanite"), - DS3LocationData("RC: Soul of a Crestfallen Knight - swamp near left, by ladder", + DS3LocationData("RC: Soul of a Crestfallen Knight - swamp near left, nook", "Soul of a Crestfallen Knight"), DS3LocationData("RC: White Preacher Head - swamp near, ground near bonfire exit", "White Preacher Head"), DS3LocationData("RC: Titanite Scale - swamp far, by miniboss", "Titanite Scale"), - DS3LocationData("RC: Titanite Scale - upper cliff, path under bridge", "Titanite Scale"), - DS3LocationData("RC: Dragonhead Greatshield - upper cliff, under bridge", + DS3LocationData("RC: Dragonhead Greatshield - lower cliff, under bridge", "Dragonhead Greatshield"), - DS3LocationData("RC: Titanite Scale - upper cliff, first alcove", "Titanite Scale x2"), - DS3LocationData("RC: Rubbish - upper cliff, middle", "Rubbish"), - DS3LocationData("RC: Large Soul of a Weary Warrior - upper cliff, end", + DS3LocationData("RC: Titanite Scale - lower cliff, path under bridge", "Titanite Scale x2"), + DS3LocationData("RC: Rubbish - lower cliff, middle", "Rubbish"), + DS3LocationData("RC: Large Soul of a Weary Warrior - lower cliff, end", "Large Soul of a Weary Warrior"), - DS3LocationData("RC: Titanite Scale - upper cliff, lower path", "Titanite Scale x2"), - DS3LocationData("RC: Titanite Scale - lower cliff, bridge", "Titanite Scale"), + DS3LocationData("RC: Titanite Scale - lower cliff, first alcove", "Titanite Scale x2"), + DS3LocationData("RC: Titanite Scale - lower cliff, lower path", "Titanite Scale"), DS3LocationData("RC: Lightning Gem - grave, room after first drop", "Lightning Gem"), DS3LocationData("RC: Blessed Gem - grave, down lowest stairs", "Blessed Gem"), DS3LocationData("RC: Simple Gem - grave, up stairs after first drop", "Simple Gem"), @@ -2863,26 +2862,26 @@ def __init__( DS3LocationData("RC: Antiquated Plain Garb - wall hidden, before boss", "Antiquated Plain Garb"), DS3LocationData("RC: Violet Wrappings - wall hidden, before boss", "Violet Wrappings"), - DS3LocationData("RC: Soul of a Weary Warrior - upper cliff, by first alcove", + DS3LocationData("RC: Soul of a Weary Warrior - lower cliff, by first alcove", "Soul of a Weary Warrior"), DS3LocationData("RC: Twinkling Titanite - church path, left of boss door", "Twinkling Titanite x2"), DS3LocationData("RC: Budding Green Blossom - church path", "Budding Green Blossom x3"), - DS3LocationData("RC: Titanite Chunk - swamp center, along edge", "Titanite Chunk"), - DS3LocationData("RC: Large Soul of a Weary Warrior - swamp center", + DS3LocationData("RC: Titanite Chunk - swamp center, peninsula edge", "Titanite Chunk"), + DS3LocationData("RC: Large Soul of a Weary Warrior - swamp center, by peninsula", "Large Soul of a Weary Warrior"), DS3LocationData("RC: Soul of a Weary Warrior - swamp right, by sunken church", "Soul of a Weary Warrior"), - DS3LocationData("RC: Titanite Scale - swamp far, by miniboss", "Titanite Scale"), + DS3LocationData("RC: Titanite Scale - upper cliff, bridge", "Titanite Scale"), DS3LocationData("RC: Soul of a Crestfallen Knight - swamp far, behind crystal", "Soul of a Crestfallen Knight"), DS3LocationData("RC: White Birch Bow - swamp far left, up hill", "White Birch Bow"), DS3LocationData("RC: Titanite Chunk - swamp far left, up hill", "Titanite Chunk"), - DS3LocationData("RC: Young White Branch - swamp far left, by white tree", + DS3LocationData("RC: Young White Branch - swamp far left, by white tree #1", "Young White Branch"), - DS3LocationData("RC: Young White Branch - swamp far left, by white tree", + DS3LocationData("RC: Young White Branch - swamp far left, by white tree #2", "Young White Branch"), - DS3LocationData("RC: Young White Branch - swamp far left, by white tree", + DS3LocationData("RC: Young White Branch - swamp far left, by white tree #3", "Young White Branch"), DS3LocationData("RC: Ringed Knight Paired Greatswords - church path, mob drop", "Ringed Knight Paired Greatswords", drop = True, @@ -2909,16 +2908,14 @@ def __init__( DS3LocationData("RC: Spears of the Church - hidden boss drop", "Spears of the Church", boss = True), # Midir drop DS3LocationData("RC: Ritual Spear Fragment - church path", "Ritual Spear Fragment"), - DS3LocationData("RC: Titanite Scale - grave, lizard after first drop", "Titanite Scale", - lizard = True), - DS3LocationData("RC: Twinkling Titanite - grave, lizard after first drop", + DS3LocationData("RC: Titanite Scale - swamp far, lagoon entrance", "Titanite Scale"), + DS3LocationData("RC: Twinkling Titanite - grave, lizard past first drop", "Twinkling Titanite", lizard = True), - DS3LocationData("RC: Titanite Scale - wall lower, lizard", "Titanite Scale x2", + DS3LocationData("RC: Titanite Scale - grave, lizard past first drop", "Titanite Scale", lizard = True), DS3LocationData("RC: Twinkling Titanite - streets high, lizard", "Twinkling Titanite x2", lizard = True), - DS3LocationData("RC: Titanite Scale - wall top, lizard on side path", "Titanite Scale", - lizard = True), + DS3LocationData("RC: Titanite Scale - wall lower, lizard", "Titanite Scale", lizard = True), DS3LocationData("RC: Twinkling Titanite - wall top, lizard on side path", "Twinkling Titanite", lizard = True), DS3LocationData("RC: Soul of Slave Knight Gael", "Soul of Slave Knight Gael", diff --git a/worlds/dark_souls_3/docs/locations_en.md b/worlds/dark_souls_3/docs/locations_en.md index 5858cdcc02d3..a968a61ea07a 100644 --- a/worlds/dark_souls_3/docs/locations_en.md +++ b/worlds/dark_souls_3/docs/locations_en.md @@ -645,13 +645,13 @@ of Halflight, Gael, and Midir, respectively. to heading out from the Ringed City Streets bonfire, and "near" and "far" are relative to that bonfire as well. -* **Upper cliff:** The cliffside path leading from the swamp into the shared +* **Lower cliff:** The cliffside path leading from the swamp into the shared grave, where Midir breathes fire. * **Grave:** The cylindrical chamber with spiral stairs around the edges, connecting the two cliffs, containing the Shared Grave bonfire. -* **Lower cliff:** The cliffside path leading out of the grave to the lower +* **Upper cliff:** The cliffside path leading out of the grave to the lower wall. * **Church path:** The sunlit path from the lower cliff up to the Church of @@ -736,9 +736,10 @@ offline _Dark Souls III_ randomizer]. AP: Dragonslayer Spear - gate after mausoleumIn the gate connecting the Dragon-Kin Mausoleum area to the bridge where the Nameless King fight takes place AP: Drakeblood Greatsword - mausoleum, NPC dropDropped by the Drakeblood Knight summoned by the Serpent-Man Summoner AP: Dung Pie - fort, landing after second roomOn a landing going up the stairs from the Ancient Wyvern to the chainaxe Man-Serpent area -AP: Ember - belfry, below bellFrom the right of where Ancient Wyvern first lands +AP: Ember - belfry, below bellIn the area below the bell lever, either dropping down near the lever or going down the stairs from the open fountain area after the Belfry bonfire +AP: Ember - fort overlook #1From the right of where Ancient Wyvern first lands AP: Ember - fort overlook #2From the right of where Ancient Wyvern first lands -AP: Ember - intro, by bonfireIn the area below the bell lever, either dropping down near the lever or going down the stairs from the open fountain area after the Belfry bonfire +AP: Ember - intro, by bonfireNext to the Archdragon Peak bonfire AP: Great Magic Barrier - drop off belfry roofDropping down to the left from the area with the Havel Knight and the dead Wyvern AP: Havel's Greatshield - belfry roof, NPC dropDropped from any of the Havel Knights AP: Havel's Ring+1 - summit, after buildingJust past the building with all of the Man-Serpents on the way to the Dragon Altar, on the left side @@ -800,7 +801,7 @@ offline _Dark Souls III_ randomizer]. CC: Fire Gem - cavern, lizardDropped by a Crystal Lizard found between the Catacombs main halls and the ledge overlooking the bridge you can cut down CC: Grave Warden Pyromancy Tome - boss arenaIn Wolnir's arena, or in the back left of the room containing his bonfire if not picked up in the arena CC: Grave Warden's Ashes - crypt across, cornerFrom the Catacombs bonfire, down the stairs into the main hall and up the stairs to the other side, on the far left side. Stairwell past the illusory wall is most direct. -CC: Homeward Bone - bridgeFound right before the wall blocking access to Irithyll +CC: Homeward Bone - Irithyll bridgeFound right before the wall blocking access to Irithyll CC: Large Soul of a Nameless Soldier - cavern, before bridgeIn the area where many many skeletons are before the bridge you can cut CC: Large Soul of a Nameless Soldier - tomb lowerDown the ramp from the Fire Demon, where all the skeletons are CC: Large Soul of an Unknown Traveler - crypt upper, hall middleGoing right from the Catacombs bonfire, then down the long hallway after the hallway to the left @@ -808,7 +809,7 @@ offline _Dark Souls III_ randomizer]. CC: Large Titanite Shard - crypt upper, skeleton ball hallGoing right from the Catacombs bonfire, to the end of the hallway where second Skeleton Ball rolls CC: Large Titanite Shard - tomb lowerDown the ramp from the Fire Demon, where all the skeletons are CC: Old Sage's Blindfold - tomb, hall before bonfireDown the ramp from the Fire Demon, straight down the hallway past the room with the Abandoned Tomb bonfire -CC: Pontiff's Right Eye - bridge, miniboss dropDropped by killing Sulyvahn's Beast on the bridge to Irithyll or in the lake below +CC: Pontiff's Right Eye - Irithyll bridge, miniboss dropDropped by killing Sulyvahn's Beast on the bridge to Irithyll or in the lake below CC: Ring of Steel Protection+2 - atrium upper, drop onto pillarFrom the first bridge in Catacombs where the first skeletons are encountered, parallel to the long stairwell, walk off onto a pillar on the left side. CC: Sharp Gem - atrium lower, right before exitDown the hallway to the right before going down the main stairwell in the Catacombs CC: Soul of High Lord WolnirDropped by High Lord Wolnir @@ -1538,6 +1539,7 @@ offline _Dark Souls III_ randomizer]. IBV: Large Soul of a Nameless Soldier - central, by second fountainNext to the fountain up the stairs from the Central Irithyll bonfire IBV: Large Soul of a Nameless Soldier - lake islandOn an island in the lake leading to the Distant Manor bonfire IBV: Large Soul of a Nameless Soldier - stairs to plazaOn the path from Central Irithyll bonfire, before making the left toward Church of Yorshka +IBV: Large Titanite Shard - Distant Manor, under overhangUnder overhang next to second set of stairs leading from Distant Manor bonfire IBV: Large Titanite Shard - ascent, by elevator doorOn the path from the sewer leading up to Pontiff's cathedral, to the right of the statue surrounded by dogs IBV: Large Titanite Shard - ascent, down ladder in last buildingOutside the final building before Pontiff's cathedral, coming from the sewer, dropping down to the left before the entrance IBV: Large Titanite Shard - central, balcony just before plazaFrom the Central Irithyll bonfire, on the balcony with the second Fire Witch. @@ -1602,11 +1604,11 @@ offline _Dark Souls III_ randomizer]. ID: Large Soul of a Nameless Soldier - B2, hall by stairsAt the end of the bottom corridor on the bonfire side in Irithyll Dungeon ID: Large Soul of a Weary Warrior - just before Profaned CapitalIn the open area before the bridge leading into Profaned Capital from Irithyll Dungeon ID: Large Titanite Shard - B1 far, rightmost cellIn a cell on the far end of the top corridor opposite to the bonfire in Irithyll Dungeon, nearby the Jailer -ID: Large Titanite Shard - B1 near, by doorIn the main Jailer cell block, to the left of the hallway leading to the Path of the Dragon area -ID: Large Titanite Shard - B3 near, right cornerOn the floor where the Giant Slave is standing +ID: Large Titanite Shard - B1 near, by doorAt the end of the top corridor on the bonfire side in Irithyll Dungeon, before the Jailbreaker's Key door +ID: Large Titanite Shard - B3 near, right cornerIn the main Jailer cell block, to the left of the hallway leading to the Path of the Dragon area ID: Large Titanite Shard - after bonfire, second cell on rightIn the second cell on the right after Irithyll Dungeon bonfire -ID: Large Titanite Shard - pitOn the floor where the Giant Slave is standing -ID: Large Titanite Shard - stairs between pit and B3Seemingly unused treasure +ID: Large Titanite Shard - pit #1On the floor where the Giant Slave is standing +ID: Large Titanite Shard - pit #2On the floor where the Giant Slave is standing ID: Lightning Blade - B3 lift, middle platformOn the middle platform riding the elevator up from the Path of the Dragon area ID: Lightning Bolt - awning over pitOn the wooden overhangs above the Giant Slave. Can be reached by dropping down after climbing the long ladder around the area where the Giant stands. ID: Murakumo - Alva dropDropped by Alva, Seeker of the Spurned when he invades in the cliffside path to Irithyll Dungeon @@ -1833,7 +1835,7 @@ offline _Dark Souls III_ randomizer]. RC: Black Witch Garb - streets gardenGuarded by Alva (invades whether embered or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight. RC: Black Witch Hat - streets gardenGuarded by Alva (invades whether embered or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight. RC: Black Witch Trousers - streets gardenGuarded by Alva (invades whether embered or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight. -RC: Black Witch Veil - swamp near right, by sinking churchTo the left of the submerged building with 4 Ringed Knights, near a spear-wielding knight. +RC: Black Witch Veil - swamp near right, by sunken churchTo the left of the submerged building with 4 Ringed Knights, near a spear-wielding knight. RC: Black Witch Wrappings - streets gardenGuarded by Alva (invades whether embered or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight. RC: Blessed Gem - grave, down lowest stairsIn Shared Grave, after dropping down near Gael's flag and dropping down again, behind you. Or from the bonfire, go back through the side tunnel with the skeletons and down the stairs after that. RC: Blindfold Mask - grave, NPC dropDropped by Moaning Knight (invades whether embered or not, or boss defeated or not) in Shared Grave. @@ -1848,7 +1850,7 @@ offline _Dark Souls III_ randomizer]. RC: Dark Gem - swamp near, by stairsIn the middle of the muck pit, close to the long stairs. RC: Divine Blessing - streets monument, mob dropDropped by the Judicator near the Purging Monument area. Requires solving "Show Your Humanity" puzzle. RC: Divine Blessing - wall top, mob dropDropped by the Judicator after the Mausoleum Lookup bonfire. -RC: Dragonhead Greatshield - upper cliff, under bridgeDown a slope to the right of the bridge where Midir first assaults you, past a sword-wielding Ringed Knight, under the bridge. +RC: Dragonhead Greatshield - lower cliff, under bridgeDown a slope to the right of the bridge where Midir first assaults you, past a sword-wielding Ringed Knight, under the bridge. RC: Dragonhead Shield - streets monument, across bridgeFound in Purging Monument area, across the bridge from the monument. Requires solving "Show Your Humanity" puzzle. RC: Ember - wall hidden, statue roomFrom the mid level of the Ringed Inner Wall elevator that leads to the Midir fight, in the room with the illusory statue. RC: Ember - wall top, by statueAlong the left wall of the courtyard after Mausoleum Lookout, in front of a tall monument. @@ -1869,8 +1871,8 @@ offline _Dark Souls III_ randomizer]. RC: Lapp's Leggings - LappLeft at Lapp's final location in Shared Grave after his quest is complete, or sold by Shrine Handmaid upon killing Lapp. RC: Large Soul of a Crestfallen Knight - streets monument, across bridgeFound in Purging Monument area, on the other side of the bridge leading to the monument. Requires solving "Show Your Humanity" puzzle. RC: Large Soul of a Crestfallen Knight - streets, far stairsToward the bottom of the stairs leading down to the muck pit. -RC: Large Soul of a Weary Warrior - swamp centerIn the muck pit approaching where the Judicator patrols from the stairs. -RC: Large Soul of a Weary Warrior - upper cliff, endToward the end of the upper path attacked Midir's fire-breathing. +RC: Large Soul of a Weary Warrior - lower cliff, endToward the end of the upper path attacked Midir's fire-breathing. +RC: Large Soul of a Weary Warrior - swamp center, by peninsulaIn the muck pit approaching where the Judicator patrols from the stairs. RC: Large Soul of a Weary Warrior - wall lower, past two illusory wallsIn the Ringed Inner Wall building coming from Shared Grave, past two illusory walls on the right side of the ascending stairs. RC: Large Soul of a Weary Warrior - wall top, right of small tombIn the open toward the end of the courtyard after the Mausoleum Lookout bonfire, on the right side of the small tomb. RC: Ledo's Great Hammer - streets high, opposite building, NPC dropDropped by Silver Knight Ledo (invades whether embered or not, or boss defeated or not) in the building down the path to the right after climbing the very long ladder from the muck area. @@ -1878,16 +1880,16 @@ offline _Dark Souls III_ randomizer]. RC: Lightning Gem - grave, room after first dropIn Shared Grave, in the first room encountered after falling down from the crumbling stairs and continuing upward. RC: Mossfruit - streets near left, path to gardenPartway down the stairs from Shira, across the bridge. RC: Mossfruit - streets, far left alcoveNear the bottom of the stairs before the muck pit, in an alcove to the left. -RC: Preacher's Right Arm - swamp near right, by crystalIn the muck pit behind a crystal-covered structure, close to the Ringed City Streets shortcut entrance. -RC: Prism Stone - swamp near, path to bonfireOn the balcony of the path leading up to Ringed City Streets bonfire from the muck pit. +RC: Preacher's Right Arm - swamp near right, by towerIn the muck pit behind a crystal-covered structure, close to the Ringed City Streets shortcut entrance. +RC: Prism Stone - swamp near, railing by bonfireOn the balcony of the path leading up to Ringed City Streets bonfire from the muck pit. RC: Purging Stone - wall top, by door to upperAt the end of the path from Mausoleum Lookup to Ringed Inner Wall, just outside the door. RC: Ring of the Evil Eye+3 - grave, mimicDropped by mimic in Shared Grave. In one of the rooms after dropping down near Gael's flag and then dropping down again. RC: Ringed Knight Paired Greatswords - church path, mob dropDropped by Ringed Knight with paired greatswords before Filianore building. RC: Ringed Knight Spear - streets, down far right hallIn a courtyard guarded by a spear-wielding Ringed Knight. Can be accessed from a hallway filled with cursed clerics on the right side going down the long stairs, or by climbing up the long ladder from the muck pit and dropping down past the Locust Preacher. -RC: Ringed Knight Straight Sword - swamp near, pillar by bonfireOn a monument next to the Ringed City Streets building. Can be easily accessed after unlocking the shortcut by following the left wall inside and then outside the building. +RC: Ringed Knight Straight Sword - swamp near, tower on peninsulaOn a monument next to the Ringed City Streets building. Can be easily accessed after unlocking the shortcut by following the left wall inside and then outside the building. RC: Ritual Spear Fragment - church pathTo the right of the Paired Greatswords Ringed Knight on the way to Halflight. +RC: Rubbish - lower cliff, middleIn the middle of the upper path attacked Midir's fire-breathing, after the first alcove. RC: Rubbish - swamp far, by crystalIn the remote end of the muck pit, next to a massive crystal structure between a giant tree and the building with praying Hollow Clerics, guarded by several Locust Preachers. -RC: Rubbish - upper cliff, middleIn the middle of the upper path attacked Midir's fire-breathing, after the first alcove. RC: Ruin Armor - wall top, under stairs to bonfireUnderneath the stairs leading down from Mausoleum Lookout. RC: Ruin Gauntlets - wall top, under stairs to bonfireUnderneath the stairs leading down from Mausoleum Lookout. RC: Ruin Helm - wall top, under stairs to bonfireUnderneath the stairs leading down from Mausoleum Lookout. @@ -1903,44 +1905,46 @@ offline _Dark Souls III_ randomizer]. RC: Soul of Darkeater MidirDropped by Darkeater Midir RC: Soul of Slave Knight GaelDropped by Slave Knight Gael RC: Soul of a Crestfallen Knight - swamp far, behind crystalBehind a crystal structure at the far end of the muck pit, close to the building with the praying Hollow Clerics before Dragonslayer Armour. -RC: Soul of a Crestfallen Knight - swamp near left, by ladderIn the muck pit behind all of the Hollow Clerics near the very long ladder. +RC: Soul of a Crestfallen Knight - swamp near left, nookIn the muck pit behind all of the Hollow Clerics near the very long ladder. RC: Soul of a Crestfallen Knight - wall top, under dropAfter dropping down onto the side path on the right side of the Mausoleum Lookout courtyard to where the Crystal Lizard is, behind you. +RC: Soul of a Weary Warrior - lower cliff, by first alcoveIn front of the first alcove providing shelter from Midir's fire-breathing on the way to Shared Grave. RC: Soul of a Weary Warrior - swamp centerIn the middle of the muck pit where the Judicator is patrolling. RC: Soul of a Weary Warrior - swamp right, by sunken churchIn between where the Judicator patrols in the muck pit and the submerged building with the 4 Ringed Knights. Provides some shelter from his arrows. -RC: Soul of a Weary Warrior - upper cliff, by first alcoveIn front of the first alcove providing shelter from Midir's fire-breathing on the way to Shared Grave. RC: Spears of the Church - hidden boss dropDropped by Darkeater Midir RC: Titanite Chunk - streets high, building oppositeDown a path past the room where Silver Knight Ledo invades. The building is up the very long ladder from the muck pit, down the path all the way to the right. RC: Titanite Chunk - streets, near left dropNear the top of the stairs by Shira, dropping down in an alcove to the left. -RC: Titanite Chunk - swamp center, along edgeAlong the edge of the muck pit close to where the Judicator patrols. +RC: Titanite Chunk - swamp center, peninsula edgeAlong the edge of the muck pit close to where the Judicator patrols. RC: Titanite Chunk - swamp far left, up hillUp a hill at the edge of the muck pit with the Hollow Clerics. -RC: Titanite Chunk - swamp near left, opposite ladderAt the edge of the muck pit, on the opposite side of the wall from the very long ladder. -RC: Titanite Chunk - swamp near right, by sinking churchAt the very edge of the muck pit, to the left of the submerged building with 4 Ringed Knights. +RC: Titanite Chunk - swamp near left, by spire topAt the edge of the muck pit, on the opposite side of the wall from the very long ladder. +RC: Titanite Chunk - swamp near right, behind rockAt the very edge of the muck pit, to the left of the submerged building with 4 Ringed Knights. RC: Titanite Chunk - wall top, among gravesAlong the right edge of the courtyard after Mausoleum Lookout in a cluster of graves. RC: Titanite Chunk - wall upper, courtyard alcoveIn the courtyard where the first Ringed Knight is seen, along the right wall into an alcove. -RC: Titanite Scale - grave, lizard after first dropIn the area at the far end of the muck pit with the Dragonslayer Armour. -RC: Titanite Scale - lower cliff, bridgeOn the final bridge where Midir attacks before you knock him off. +RC: Titanite Scale - grave, lizard past first dropDropped by the Crystal Lizard right after the crumbling stairs in Shared Grave. +RC: Titanite Scale - lower cliff, first alcoveIn the first alcove providing shelter from Midir's fire-breathing on the way to Shared Grave. +RC: Titanite Scale - lower cliff, lower pathAfter dropping down from the upper path attacked by Midir's fire-breathing to the lower path. +RC: Titanite Scale - lower cliff, path under bridgePartway down a slope to the right of the bridge where Midir first assaults you. RC: Titanite Scale - swamp far, by minibossIn the area at the far end of the muck pit with the Dragonslayer Armour. -RC: Titanite Scale - upper cliff, first alcoveIn the first alcove providing shelter from Midir's fire-breathing on the way to Shared Grave. -RC: Titanite Scale - upper cliff, lower pathAfter dropping down from the upper path attacked by Midir's fire-breathing to the lower path. -RC: Titanite Scale - upper cliff, path under bridgePartway down a slope to the right of the bridge where Midir first assaults you. -RC: Titanite Scale - wall lower, lizardDropped by the Crystal Lizard right after the crumbling stairs in Shared Grave. +RC: Titanite Scale - swamp far, lagoon entranceIn the area at the far end of the muck pit with the Dragonslayer Armour. +RC: Titanite Scale - upper cliff, bridgeOn the final bridge where Midir attacks before you knock him off. +RC: Titanite Scale - wall lower, lizardDropped by the Crystal Lizard on the stairs going up from Shared Grave to Ringed Inner Wall elevator. RC: Titanite Scale - wall top, behind spawnBehind you at the very start of the level. -RC: Titanite Scale - wall top, lizard on side pathDropped by the Crystal Lizard on the stairs going up from Shared Grave to Ringed Inner Wall elevator. RC: Titanite Slab - ashes, NPC dropGiven by Shira after defeating Midir, or dropped by her in post-Filianore Ringed City. RC: Titanite Slab - ashes, mob dropDropped by the Ringed Knight wandering around near Gael's arena RC: Titanite Slab - mid boss dropDropped by Halflight, Spear of the Church RC: Twinkling Titanite - church path, left of boss doorDropping down to the left of the door leading to Halflight. -RC: Twinkling Titanite - grave, lizard after first dropDropped by the Crystal Lizard right after the crumbling stairs in Shared Grave. +RC: Twinkling Titanite - grave, lizard past first dropDropped by the Crystal Lizard right after the crumbling stairs in Shared Grave. RC: Twinkling Titanite - streets high, lizardDropped by the Crystal Lizard which runs across the bridge after climbing the very long ladder up from the muck pit. RC: Twinkling Titanite - swamp near leftAt the left edge of the muck pit coming from the stairs, guarded by a Preacher Locust. -RC: Twinkling Titanite - swamp near right, on sinking churchFollowing the sloped roof of the submerged building with the 4 Ringed Knights, along the back wall +RC: Twinkling Titanite - swamp near right, on sunken churchFollowing the sloped roof of the submerged building with the 4 Ringed Knights, along the back wall RC: Twinkling Titanite - wall top, lizard on side pathDropped by the first Crystal Lizard on the side path on the right side of the Mausoleum Lookout courtyard RC: Twinkling Titanite - wall tower, jump from chandelierIn the cylindrical building before the long stairs with many Harald Legion Knights. Carefully drop down to the chandelier in the center, then jump to the second floor. The item is on a ledge. RC: Violet Wrappings - wall hidden, before bossIn the chapel before the Midir fight in the Ringed Inner Wall building. RC: White Birch Bow - swamp far left, up hillUp a hill at the edge of the muck pit with the Hollow Clerics. RC: White Preacher Head - swamp near, ground near bonfire exitPast the balcony to the right of the Ringed City Streets bonfire room entrance. Can be accessed by dropping down straight after from the bonfire, then around to the left. RC: Wolf Ring+3 - street gardens, NPC dropDropped by Alva (invades whether embered or not, or boss defeated or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight. -RC: Young White Branch - swamp far left, by white treeNext to a small birch tree at the edge of the muck pit, between the hill with the aggressive Hollow Clerics and the building with the praying Hollow Clerics outside. +RC: Young White Branch - swamp far left, by white tree #1Next to a small birch tree at the edge of the muck pit, between the hill with the aggressive Hollow Clerics and the building with the praying Hollow Clerics outside. +RC: Young White Branch - swamp far left, by white tree #2Next to a small birch tree at the edge of the muck pit, between the hill with the aggressive Hollow Clerics and the building with the praying Hollow Clerics outside. +RC: Young White Branch - swamp far left, by white tree #3Next to a small birch tree at the edge of the muck pit, between the hill with the aggressive Hollow Clerics and the building with the praying Hollow Clerics outside. RS: Blue Bug Pellet - broken stairs by OrbeckOn the broken stairs leading down from Orbeck's area, on the opposite side from Orbeck RS: Blue Sentinels - HoraceGiven by Horace the Hushed by first "talking" to him, or upon death. RS: Braille Divine Tome of Carim - drop from bridge to Halfway FortressDropping down before the bridge leading up to Halfway Fortress from Road of Sacrifices, guarded by the maggot belly dog @@ -2073,7 +2077,8 @@ offline _Dark Souls III_ randomizer]. US: Blue Wooden Shield - graveyard by white treeAfter Dilapidated Bridge bonfire, in the back of the Giant's arrow area. Guarded by a flamberge-wielding thrall. US: Caduceus Round Shield - right after stable exitAfter exiting the building across the bridge to the right of the first Undead Settlement building, to the left US: Caestus - sewerIn the tunnel with the Giant Hound Rat and Grave Key door, from the ravine bridge toward Dilapidated Bridge bonfire -US: Charcoal Pine Bundle - first buildingOn the bottom floor of the first building +US: Charcoal Pine Bundle - first building, bottom floorDown the stairs in the first building +US: Charcoal Pine Bundle - first building, middle floorOn the bottom floor of the first building US: Charcoal Pine Resin - hanging corpse roomIn the building after the burning tree and Cathedral Evangelist, in the room with the many hanging corpses US: Chloranthy Ring - tower village, jump from roofAt the end of the Fire Demon loop, in the tower where you have to drop down after the roof US: Cleric Blue Robe - graveyard by white treeAfter Dilapidated Bridge bonfire, in the back of the Giant's arrow area. Guarded by a flamberge-wielding thrall. diff --git a/worlds/dark_souls_3/test/TestDarkSouls3.py b/worlds/dark_souls_3/test/TestDarkSouls3.py index 0f3e84e736ff..93424886fef4 100644 --- a/worlds/dark_souls_3/test/TestDarkSouls3.py +++ b/worlds/dark_souls_3/test/TestDarkSouls3.py @@ -10,7 +10,15 @@ class DarkSouls3Test(WorldTestBase): def testLocationDefaultItems(self): for locations in location_tables.values(): for location in locations: - self.assertIn(location.default_item_name, item_dictionary) + if location.default_item_name: + self.assertIn(location.default_item_name, item_dictionary) + + def testLocationsUnique(self): + names = set() + for locations in location_tables.values(): + for location in locations: + self.assertNotIn(location.name, names) + names.add(location.name) def testBossRegions(self): all_regions = set(location_tables) @@ -23,7 +31,3 @@ def testBossLocations(self): for boss in all_bosses: for location in boss.locations: self.assertIn(location, all_locations) - - def testForceUnique(self): - tongues = self.get_items_by_name("Pale Tongue") - self.assertEqual(len(tongues), 1, "There should only be one Pale Tongue in the item pool.") From 7155948a4afb47c22ca6f5f15dfaf12a66ee0fef Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 18 Jan 2024 14:16:26 -0800 Subject: [PATCH 124/238] Fix Soul of Cinder boss name --- worlds/dark_souls_3/Bosses.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index 99c51e6a76fd..e2dd040f957e 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -237,7 +237,7 @@ class DS3BossInfo: "RC: Soul of Slave Knight Gael", "RC: Blood of the Dark Soul - end boss drop", }), - DS3BossInfo("Soul of Cinder", 4100800), + DS3BossInfo("Lords of Cinder", 4100800), ] default_yhorm_location = DS3BossInfo("Yhorm the Giant", 3900800, locations = { From 1cf52653ae851d401cfb464b1349ecb23f8ccb7c Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 19 Jan 2024 16:36:24 -0800 Subject: [PATCH 125/238] Fix some logic issues --- worlds/dark_souls_3/__init__.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 145f16e9fbca..3902cd102833 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -462,7 +462,10 @@ def set_rules(self) -> None: self._add_entrance_rule("Ringed City", "Small Envoy Banner") if self.options.late_dlc: - self._add_entrance_rule("Painted World of Ariandel (After Contraption)", "Small Doll") + self._add_entrance_rule( + "Painted World of Ariandel (Before Contraption)", + "Small Doll" + ) # Define the access rules to some specific locations if self.is_location_available("FS: Lift Chamber Key - Leonhard"): @@ -812,9 +815,13 @@ def has_any_scroll(state): item.name for item in self.multiworld.itempool if item.player == self.player } - # Always make this available early because so many items are useless without it. if 'Pyromancy Flame' in randomized_items: - self.multiworld.early_items[self.player]['Pyromancy Flame'] = 1 + # Make this available early because so many items are useless without it. + self.multiworld.early_items[self.player]['Pyromancy Flame'] = 2 + if 'Transposing Kiln' in randomized_items: + # Make this available early so players can make use of their boss souls. + self.multiworld.early_items[self.player]['Transposing Kiln'] = 2 + # Make this available pretty early if 'Small Lothric Banner' in randomized_items: if self.options.early_banner == "early_global": self.multiworld.early_items[self.player]['Small Lothric Banner'] = 1 From c87cb9b1980f1d8196fc639ad2aee9e70ad27cfd Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 19 Jan 2024 17:19:27 -0800 Subject: [PATCH 126/238] Add item groups and document item/location groups --- worlds/dark_souls_3/Items.py | 54 ++++++++++++ worlds/dark_souls_3/__init__.py | 12 +-- worlds/dark_souls_3/docs/en_Dark Souls III.md | 8 +- worlds/dark_souls_3/docs/items_en.md | 19 ++++ worlds/dark_souls_3/docs/locations_en.md | 86 +++++++++++++++++++ 5 files changed, 169 insertions(+), 10 deletions(-) create mode 100644 worlds/dark_souls_3/docs/items_en.md diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index c018767673a9..fb52d2d290bc 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -156,6 +156,31 @@ def __post_init__(self): if not self.base_ds3_code: self.base_ds3_code = self.ds3_code DS3ItemData.__item_id += 1 + def item_groups(self) -> List[str]: + """The names of item groups this item should appear in. + + This is computed from the properties assigned to this item.""" + names = [] + if self.classification == ItemClassification.progression: names.append("Progression") + if self.name.startswith("Cinders of a Lord -"): names.append("Cinders") + + names.append({ + DS3ItemCategory.WEAPON_UPGRADE_5: "Weapons", + DS3ItemCategory.WEAPON_UPGRADE_10: "Weapons", + DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE: "Weapons", + DS3ItemCategory.SHIELD: "Shields", + DS3ItemCategory.SHIELD_INFUSIBLE: "Shields", + DS3ItemCategory.ARMOR: "Armor", + DS3ItemCategory.RING: "Rings", + DS3ItemCategory.SPELL: "Spells", + DS3ItemCategory.MISC: "Miscellaneous", + DS3ItemCategory.UNIQUE: "Unique", + DS3ItemCategory.BOSS: "Boss Souls", + DS3ItemCategory.SOUL: "Small Souls", + DS3ItemCategory.UPGRADE: "Upgrade", + DS3ItemCategory.HEALING: "Healing", + }[default_item.category]) + def counts(self, counts: List[int]) -> Generator["DS3ItemData", None, None]: """Returns an iterable of copies of this item with the given counts.""" yield self @@ -1614,14 +1639,43 @@ def flatten(l): DS3ItemData("Dorris Swarm", 0x40393870, DS3ItemCategory.UNIQUE), ] + +item_name_groups = { + "Progression": set(), + "Cinders": set(), + "Weapons": set(), + "Shields": set(), + "Armor": set(), + "Rings": set(), + "Spells": set(), + "Miscellaneous": set(), + "Unique": set(), + "Boss Souls": set(), + "Small Souls": set(), + "Upgrade": set(), + "Healing": set(), +} + + item_descriptions = { + "Progression": "Items which unlock locations.", "Cinders": """ All four Cinders of a Lord. Once you have these four, you can fight Soul of Cinder and win the game. """, + "Miscellaneous": "Generic stackable items, such as arrows, firebombs, buffs, and so on.", + "Unique": """ + Items that are unique per NG cycle, such as scrolls, keys, ashes, and so on. Doesn't include + equipment, spells, or souls. + """, + "Boss Souls": "Souls that can be traded with Ludleth, including Soul of Rosaria.", + "Small Souls": "Soul items, not including boss souls.", + "Upgrade": "Upgrade items, including titanite, gems, and Shriving Stones.", + "Healing": "Undead Bone Shards and Estus Shards.", } + _all_items = _vanilla_items + _dlc_items filler_item_names = [item_data.name for item_data in _all_items if item_data.filler] diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 3902cd102833..362bce50ab35 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -11,7 +11,7 @@ from worlds.generic.Rules import CollectionRule, set_rule, add_rule, add_item_rule from .Bosses import DS3BossInfo, all_bosses, default_yhorm_location -from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, Infusion, UsefulIf, filler_item_names, item_dictionary +from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, Infusion, UsefulIf, filler_item_names, item_descriptions, item_dictionary, item_name_groups from .Locations import DarkSouls3Location, DS3LocationData, location_tables, location_descriptions, location_dictionary, location_name_groups, region_order from .Options import DarkSouls3Options, EarlySmallLothricBanner @@ -61,15 +61,9 @@ class DarkSouls3World(World): for location in locations } location_name_groups = location_name_groups - item_name_groups = { - "Cinders": { - "Cinders of a Lord - Abyss Watcher", - "Cinders of a Lord - Aldrich", - "Cinders of a Lord - Yhorm the Giant", - "Cinders of a Lord - Lothric Prince" - } - } + item_name_groups = item_name_groups location_descriptions = location_descriptions + item_descriptions = item_descriptions yhorm_location: Optional[DS3BossInfo] """If enemy randomization is enabled, this is the boss who Yhorm the Giant should replace. diff --git a/worlds/dark_souls_3/docs/en_Dark Souls III.md b/worlds/dark_souls_3/docs/en_Dark Souls III.md index b74f3db5534d..2acee3d28cc7 100644 --- a/worlds/dark_souls_3/docs/en_Dark Souls III.md +++ b/worlds/dark_souls_3/docs/en_Dark Souls III.md @@ -23,10 +23,16 @@ The goal is to find the four "Cinders of a Lord" items randomized into the multi Practically anything can be found in other worlds including pieces of armor, upgraded weapons, key items, consumables, spells, upgrade materials, etc... -## What do Dark Souls III location names mean? +## Where can I learn more about Dark Souls III locations? Location names have to pack a lot of information into very little space. To better understand them, check out the [location guide], which explains all the names used in locations and provides more detailed descriptions for each individual location. [location guide]: /tutorial/Dark%20Souls%20III/locations/en + +## Where can I learn more about Dark Souls III items? + +Check out the [item guide], which explains the named groups available for items. + +[item guide]: /tutorial/Dark%20Souls%20III/items/en diff --git a/worlds/dark_souls_3/docs/items_en.md b/worlds/dark_souls_3/docs/items_en.md new file mode 100644 index 000000000000..ba100257cc14 --- /dev/null +++ b/worlds/dark_souls_3/docs/items_en.md @@ -0,0 +1,19 @@ +# Dark Souls III Items + +## Item Groups + +The Dark Souls III randomizer supports a number of item group names, which can +be used in YAML options like `local_items` to refer to many items at once: + +* **Progression:** Items which unlock locations. +* **Cinders:** All four Cinders of a Lord. Once you have these four, you can + fight Soul of Cinder and win the game. +* **Miscellaneous:** Generic stackable items, such as arrows, firebombs, buffs, + and so on. +* **Unique:** Items that are unique per NG cycle, such as scrolls, keys, ashes, + and so on. Doesn't include equipment, spells, or souls. +* **Boss Souls:** Souls that can be traded with Ludleth, including Soul of + Rosaria. +* **Small Souls:** Soul items, not including boss souls. +* **Upgrade:** Upgrade items, including titanite, gems, and Shriving Stones. +* **Healing:** Undead Bone Shards and Estus Shards. diff --git a/worlds/dark_souls_3/docs/locations_en.md b/worlds/dark_souls_3/docs/locations_en.md index a968a61ea07a..a733611bfc10 100644 --- a/worlds/dark_souls_3/docs/locations_en.md +++ b/worlds/dark_souls_3/docs/locations_en.md @@ -1,5 +1,91 @@ # Dark Souls III Locations +## Table of Contents + +* [Location Groups](#location-groups) +* [Understanding Location Names](#understanding-location-names) + * [HWL: High Wall of Lothric](#high-wall-of-lothric) + * [US: Undead Settlement](#undead-settlement) + * [RS: Road of Sacrifices](#road-of-sacrifices) + * [CD: Cathedral of the Deep](#cathedral-of-the-deep) + * [FK: Farron Keep](#farron-keep) + * [CC: Catacombs of Carthus](#catacombs-of-carthus) + * [SL: Smouldering Lake](#smouldering-lake) + * [IBV: Irithyll of the Boreal Valley](#irithyll-of-the-boreal-valley) + * [ID: Irithyll Dungeon](#irithyll-dungeon) + * [PC: Profaned Capital](#profaned-capital) + * [AL: Anor Londo](#anor-londo) + * [LC: Lothric Castle](#lothric-castle) + * [CKG: Consumed King's Garden](#consumed-kings-garden) + * [GA: Grand Archives](#grand-archives) + * [UG: Untended Graves](#untended-graves) + * [AP: Archdragon Peak](#archdragon-peak) + * [PW1: Painted World of Ariandel (Before Contraption)](#painted-world-of-ariandel-%28before-contraption%29) + * [PW2: Painted World of Ariandel (After Contraption)](#painted-world-of-ariandel-%28after-contraption%29) + * [DH: Dreg Heap](#dreg-heap) + * [RC: Ringed City](#ringed-city) +* [Detailed Location Descriptions](#detailed-location-descriptions) + +## Location Groups + +The Dark Souls III randomizer supports a number of location group names, which +can be used in YAML options like `exclude_locations` to refer to many locations +at once: + +* **Prominent:** A small number of locations that are in very obvious locations. + Mostly boss drops. Ideal for setting as priority locations. + +* **Progression:** Locations that contain items in vanilla which unlock other + locations. + +* **Boss rewards:** Boss drops. Does not include soul transfusions or shop + items. + +* **Miniboss Rewards:** Miniboss drops. Only includes enemies considered + minibosses by the enemy randomizer. + +* **Mimic Rewards:** Drops from enemies that are mimics in vanilla. + +* **Hostile NPC Rewards:** Drops from NPCs that are hostile to you. This + includes scripted invaders and initially-friendly NPCs that must be fought as + part of their quest. + +* **Friendly NPC Rewards:** Items given by friendly NPCs as part of their quests + or from non-violent interaction. + +* **Upgrade:** Locations that contain upgrade items in vanilla, including + titanite, gems, and Shriving Stones. + +* **Small Souls:** Locations that contain soul items in vanilla, not including + boss souls. + +* **Boss Souls:** Locations that contain boss souls in vanilla, as well as Soul + of Rosaria. + +* **Unique:** Locations that contain items in vanilla that are unique per NG + cycle, such as scrolls, keys, ashes, and so on. Doesn't cover equipment, + spells, or souls. + +* **Healing:** Locations that contain Undead Bone Shards and Estus Shards in + vanilla. + +* **Miscellaneous:** Locations that contain generic stackable items in vanilla, + such as arrows, firebombs, buffs, and so on. + +* **Hidden:** Locations that are particularly difficult to find, such as behind + illusory walls, down hidden drops, and so on. Does not include large locations + like Untended Graves or Archdragon Peak. + +* **Weapons:** Locations that contain weapons in vanilla. + +* **Shields:** Locations that contain shields in vanilla. + +* **Armor:** Locations that contain armor in vanilla. + +* **Rings:** Locations that contain rings in vanilla. + +* **Spells:** Locations that contain spells in vanilla. + ## Understanding Location Names All locations begin with an abbreviation indicating their general region. Most From 06c85c0d367fbfbb298136fd6ca1e8450fb370d9 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 21 Jan 2024 16:47:26 -0800 Subject: [PATCH 127/238] Fix the display name for "Impatient Mimics" --- worlds/dark_souls_3/Options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 14d221e931b1..b671ba6d39bd 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -438,7 +438,7 @@ class ImpatientMimicsOption(Toggle): This is ignored unless enemies are randomized. """ - display_name = "All Chests Are Mimics" + display_name = "Impatient Mimics" class DS3ExcludeLocations(ExcludeLocations): From fd1807937856f4de97f7140d488efbc0c6b4c9ef Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 23 Jan 2024 01:01:50 -0800 Subject: [PATCH 128/238] Properly handle Transposing Kiln and Pyromancer's Flame --- worlds/dark_souls_3/Items.py | 4 ++-- worlds/dark_souls_3/__init__.py | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index fb52d2d290bc..436de9792521 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -464,7 +464,7 @@ def flatten(l): DS3ItemData("Saint's Talisman", 0x00CACA10, DS3ItemCategory.WEAPON_UPGRADE_10), DS3ItemData("White Hair Talisman", 0x00CAF120, DS3ItemCategory.WEAPON_UPGRADE_5), DS3ItemData("Pyromancy Flame", 0x00CC77C0, DS3ItemCategory.WEAPON_UPGRADE_10, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Dragonslayer Greatbow", 0x00CF8500, DS3ItemCategory.WEAPON_UPGRADE_5), DS3ItemData("Short Bow", 0x00D5C690, DS3ItemCategory.WEAPON_UPGRADE_10), DS3ItemData("Composite Bow", 0x00D5EDA0, DS3ItemCategory.WEAPON_UPGRADE_10), @@ -1249,7 +1249,7 @@ def flatten(l): DS3ItemData("Crystal Scroll", 0x40000856, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), DS3ItemData("Transposing Kiln", 0x40000857, DS3ItemCategory.UNIQUE, - classification = ItemClassification.useful), + classification = ItemClassification.progression), DS3ItemData("Coiled Sword", 0x40000859, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), DS3ItemData("Eyes of a Fire Keeper", 0x4000085A, DS3ItemCategory.UNIQUE, diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 362bce50ab35..a10ac99bab15 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -554,7 +554,9 @@ def set_rules(self) -> None: for (soul, soul_name, items) in transpositions: self._add_location_rule([ f"FS: {item} - Ludleth for {soul_name}" for item in items - ], soul) + ], lambda state: ( + state.has(soul, self.player) and state.has("Transposing Kiln", self.player) + )) # List missable locations even though they never contain progression items so that the game # knows what sphere they're in. This is especially useful for item smoothing. We could add @@ -809,12 +811,13 @@ def has_any_scroll(state): item.name for item in self.multiworld.itempool if item.player == self.player } + if 'Pyromancy Flame' in randomized_items: # Make this available early because so many items are useless without it. - self.multiworld.early_items[self.player]['Pyromancy Flame'] = 2 + self._add_entrance_rule("Road of Sacrifices", "Pyromancy Flame") if 'Transposing Kiln' in randomized_items: # Make this available early so players can make use of their boss souls. - self.multiworld.early_items[self.player]['Transposing Kiln'] = 2 + self._add_entrance_rule("Road of Sacrifices", "Transposing Kiln") # Make this available pretty early if 'Small Lothric Banner' in randomized_items: if self.options.early_banner == "early_global": From f9ac6ed749f34cbb6af093471e73ffb5ebe5878d Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Thu, 22 Feb 2024 17:38:16 -0500 Subject: [PATCH 129/238] Testing --- worlds/dark_souls_3/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index a10ac99bab15..044882ca9154 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -569,7 +569,7 @@ def set_rules(self) -> None: "FS: Hawkwood's Swordgrass - Andre after gesture in AP summit" ], "Twinkling Dragon Torso Stone") - # Shop unlocks + # Shop unlocks: shop_unlocks = { "Cornyx": [ ( From 2d9b282a70a77e6950eb4149d2d6aea3f8727958 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Thu, 22 Feb 2024 18:18:45 -0500 Subject: [PATCH 130/238] Some fixes to NPC quests, late basin, and transposing kiln --- worlds/dark_souls_3/__init__.py | 68 +++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 044882ca9154..13f6a46afcce 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -446,7 +446,7 @@ def set_rules(self) -> None: state.has("Cinders of a Lord - Lothric Prince", self.player)) if self.options.late_basin_of_vows: - self._add_entrance_rule("Lothric Castle", "Small Lothric Banner") + self._add_entrance_rule("Lothric Castle", lambda state: state.can_reach("Go To Road of Sacrifices", "Entrance", self.player)) # DLC Access Rules Below if self.options.enable_dlc: @@ -468,6 +468,7 @@ def set_rules(self) -> None: self._add_location_rule("ID: Bellowing Dragoncrest Ring - drop from B1 towards pit", "Jailbreaker's Key") self._add_location_rule("ID: Covetous Gold Serpent Ring - Siegward's cell", "Old Cell Key") + self._add_location_rule("ID: Titanite Slab - Siegward", "Old Cell Key") self._add_location_rule( "UG: Hornet Ring - environs, right of main path after killing FK boss", "Small Lothric Banner" @@ -554,7 +555,7 @@ def set_rules(self) -> None: for (soul, soul_name, items) in transpositions: self._add_location_rule([ f"FS: {item} - Ludleth for {soul_name}" for item in items - ], lambda state: ( + ], lambda state, soul=soul: ( state.has(soul, self.player) and state.has("Transposing Kiln", self.player) )) @@ -569,7 +570,7 @@ def set_rules(self) -> None: "FS: Hawkwood's Swordgrass - Andre after gesture in AP summit" ], "Twinkling Dragon Torso Stone") - # Shop unlocks: + # Shop unlocks shop_unlocks = { "Cornyx": [ ( @@ -680,6 +681,8 @@ def set_rules(self) -> None: "ID: Prisoner Chief's Ashes - B2 near, locked cell by stairs", "Jailer's Key Ring" ) + + # Cornyx self._add_location_rule([ "US: Old Sage's Blindfold - kill Cornyx", "US: Cornyx's Garb - kill Cornyx", "US: Cornyx's Wrap - kill Cornyx", "US: Cornyx's Skirt - kill Cornyx" @@ -689,6 +692,63 @@ def set_rules(self) -> None: and state.has("Izalith Pyromancy Tome", self.player) )) + # Irina + self._add_location_rule([ + "US: Tower Key - kill Irina" + ], lambda state: ( + state.has("Braille Divine Tome of Carim", self.player) + and state.has("Braille Divine Tome of Lothric", self.player) + )) + + # Orbeck + self._add_location_rule([ + "FS: Morion Blade - Yuria for Orbeck's Ashes", + "FS: Clandestine Coat - shop with Orbeck's Ashes" + ], lambda state: ( + state.has("Golden Scroll", self.player) + and state.has("Logan's Scroll", self.player) + and state.has("Crystal Scroll", self.player) + and state.has("Sage's Scroll", self.player) + )) + + # Karla + self._add_location_rule([ + "FS: Karla's Trousers - kill Karla", + "FS: Karla's Pointed Hat - kill Karla", + "FS: Karla's Gloves - kill Karla", + "FS: Karla's Coat - kill Karla" + ], lambda state: ( + state.has("Deep Braille Divine Tome", self.player) + and state.has("Londor Braille Divine Tome", self.player) + and state.has("Quelana Pyromancy Tome", self.player) + and state.has("Grave Warden Pyromancy Tome", self.player) + )) + + # Patches + self._add_location_rule([ + "CD: Winged Spear - kill Patches" + ], lambda state: ( + state.has("Small Doll", self.player) + and state.has("Basin of Vows", self.player) + and state.has("Loretta's Bone", self.player) + and state.has("Tower Key", self.player) + and state.has("Cell Key", self.player) + )) + + self._add_location_rule([ + "FS: Rusted Gold Coin - don't forgive Patches" + ], lambda state: ( + state.has("Tower Key", self.player) + )) + + # Leonhard + self._add_location_rule([ + "CD: Black Eye Orb - Rosaria from Leonhard's quest" + ], lambda state: ( + state.has("Pale Tongue", self.player) + and state.has("Lift Chamber Key", self.player) + )) + # Make sure that the player can keep Orbeck around by giving him at least one scroll # before killing Abyss Watchers. def has_any_scroll(state): @@ -708,7 +768,7 @@ def has_any_scroll(state): # Lump Soul of the Dancer in with LC for locations that should not be reachable # before having access to US. (Prevents requiring getting Basin to fight Dancer to get SLB to go to US) if self.options.late_basin_of_vows: - self._add_location_rule("HWL: Soul of the Dancer", "Small Lothric Banner") + self._add_location_rule("HWL: Soul of the Dancer", lambda state: state.can_reach("Go To Road of Sacrifices", "Entrance", self.player)) # This isn't really necessary, but it ensures that the game logic knows players will # want to do Lothric Castle after at least being _able_ to access Catacombs. This is # useful for smooth item placement. From 1790975a4527125de0d27feaf1ac08447f9a1f22 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 25 Feb 2024 22:26:53 -0800 Subject: [PATCH 131/238] Improve a couple location names --- worlds/dark_souls_3/Locations.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index a2833b99e4ce..874dd9debd07 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -2603,7 +2603,7 @@ def __init__( DS3LocationData("PW2: Titanite Slab - boss drop", "Titanite Slab", offline = '11,0:50004700::', boss = True), # One-time drop after Friede Phase 2 - DS3LocationData("PW2: Floating Chaos - Dunnel drop", "Floating Chaos", hostile_npc = True, + DS3LocationData("PW2: Floating Chaos - NPC drop", "Floating Chaos", hostile_npc = True, hidden = True), # Livid Pyromancer Dunnel drop (requires ember) DS3LocationData("PW2: Prism Stone - pass, tree by beginning", "Prism Stone x10"), DS3LocationData("PW2: Titanite Chunk - pass, cliff overlooking bonfire", "Titanite Chunk"), @@ -2836,7 +2836,7 @@ def __init__( "Twinkling Titanite"), DS3LocationData("RC: Soul of a Crestfallen Knight - swamp near left, nook", "Soul of a Crestfallen Knight"), - DS3LocationData("RC: White Preacher Head - swamp near, ground near bonfire exit", + DS3LocationData("RC: White Preacher Head - swamp near, nook right of stairs", "White Preacher Head"), DS3LocationData("RC: Titanite Scale - swamp far, by miniboss", "Titanite Scale"), DS3LocationData("RC: Dragonhead Greatshield - lower cliff, under bridge", From f918a470641a960dd4096d9171d80d75e8bc023e Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 26 Feb 2024 00:01:34 -0800 Subject: [PATCH 132/238] Split out and improve missable NPC item logic --- worlds/dark_souls_3/Bosses.py | 8 +- worlds/dark_souls_3/Locations.py | 15 +- worlds/dark_souls_3/Options.py | 2 +- worlds/dark_souls_3/__init__.py | 247 ++++++++++++++++++++++++++----- 4 files changed, 225 insertions(+), 47 deletions(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index e2dd040f957e..20a2d165926b 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -43,7 +43,7 @@ class DS3BossInfo: "US: Soul of the Rotted Greatwood", "US: Transposing Kiln - boss drop", "US: Wargod Wooden Shield - Pit of Hollows", - "FS: Hawkwood's Shield - Hawkwood", + "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", @@ -58,12 +58,12 @@ class DS3BossInfo: DS3BossInfo("Crystal Sage", 3300850, region = "Cathedral of the Deep", locations = { "RS: Soul of a Crystal Sage", "FS: Sage's Big Hat - shop after killing RS boss", - "FS: Hawkwood's Shield - Hawkwood", + "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 - Hawkwood", + "FS: Hawkwood's Shield - gravestone after Hawkwood leaves", }), DS3BossInfo("Abyss Watchers", 3300801, before_storm_ruler = True, region = "Catacombs of Carthus", locations = { @@ -79,7 +79,7 @@ class DS3BossInfo: "UG: Wolf Knight Gauntlets - shop after killing FK boss", "UG: Wolf Knight Leggings - shop after killing FK boss", "FS: Farron Ring - Hawkwood", - "FS: Hawkwood's Shield - Hawkwood", + "FS: Hawkwood's Shield - gravestone after Hawkwood leaves", }), DS3BossInfo("High Lord Wolnir", 3800800, before_storm_ruler = True, region = "Irithyll of the Boreal Valley", locations = { diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 874dd9debd07..950045aacd9f 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1174,8 +1174,6 @@ def __init__( npc = True), # Don't forgive Patches DS3LocationData("CD: Shotel - Patches", "Shotel", missable = True, npc = True, shop = True), DS3LocationData("CD: Ember - Patches", "Ember", missable = True, npc = True, shop = True), - DS3LocationData("CD: Hidden Blessing - Patches", "Hidden Blessing", missable = True, - npc = True, shop = True), DS3LocationData("CD: Horsehoof Ring - Patches", "Horsehoof Ring", missable = True, npc = True, drop = True, shop = True), # (kill or buy) ], @@ -1296,7 +1294,8 @@ def __init__( DS3LocationData("FK: Soul of a Stray Demon - upper keep, miniboss drop", "Soul of a Stray Demon", miniboss = True), DS3LocationData("FK: Watchdogs of Farron - Old Wolf", "Watchdogs of Farron"), - DS3LocationData("FS: Hawkwood's Shield - Hawkwood", "Hawkwood's Shield", missable = True, + DS3LocationData("FS: Hawkwood's Shield - gravestone after Hawkwood leaves", + "Hawkwood's Shield", missable = True, npc = True), # Hawkwood (quest, after Greatwood, Sage, Watchers, and Deacons) DS3LocationData("US: Hawk Ring - Giant Archer", "Hawk Ring", drop = True, npc = True), # Giant archer (kill or quest), here because you need to @@ -1896,9 +1895,9 @@ def __init__( DS3LocationData("AL: Aldrich Faithful - water reserves, talk to McDonnel", "Aldrich Faithful", hidden = True), # Behind illusory wall - DS3LocationData("FS: Budding Green Blossom - shop killing Creighton and AL boss", - "Budding Green Blossom", - offline = '99,0:-1:110000,70000118:', missable = True, npc = True, + DS3LocationData("FS: Budding Green Blossom - shop after killing Creighton and AL boss", + "Budding Green Blossom", offline = '99,0:-1:110000,70000118:', + missable = True, npc = True, shop = True), # sold by Shrine Maiden after killing Aldrich and helping # Sirris defeat Creighton @@ -2301,6 +2300,10 @@ def __init__( "Sunless Gauntlets", missable = True, npc = True, shop = True), DS3LocationData("FS: Sunless Leggings - shop, Sirris quest, kill GA boss", "Sunless Leggings", missable = True, npc = True, shop = True), + + # Unbreakable Patches + DS3LocationData("FS: Hidden Blessing - Patches after searching GA", "Hidden Blessing", + missable = True, npc = True, shop = True), ], "Untended Graves": [ DS3LocationData("UG: Soul of Champion Gundyr", "Soul of Champion Gundyr", prominent = True, diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index b671ba6d39bd..29241053e9f0 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -33,7 +33,7 @@ class MissableLocationsOption(Choice): * Unnecessary: Missable locations can't have progression items, but they can have useful items. * Unimportant: Neither progression items nor useful items can be placed in - missablek locations. + missable locations. * Unrandomized: Missable locations always contain the same item as in vanilla Dark Souls III. diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index a10ac99bab15..c5c6b73a7ad1 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -558,17 +558,6 @@ def set_rules(self) -> None: state.has(soul, self.player) and state.has("Transposing Kiln", self.player) )) - # List missable locations even though they never contain progression items so that the game - # knows what sphere they're in. This is especially useful for item smoothing. We could add - # rules for boss transposition items as well, but then we couldn't freely reorder boss soul - # locations for smoothing. - - self._add_location_rule("FS: Lift Chamber Key - Leonhard", "Pale Tongue") - self._add_location_rule([ - "FK: Twinkling Dragon Head Stone - Hawkwood drop", - "FS: Hawkwood's Swordgrass - Andre after gesture in AP summit" - ], "Twinkling Dragon Torso Stone") - # Shop unlocks shop_unlocks = { "Cornyx": [ @@ -625,25 +614,7 @@ def set_rules(self) -> None: self._add_location_rule( [f"FS: {item} - {shop} for {key_name}" for item in items], key) - self._add_location_rule([ - "FS: Divine Blessing - Greirat from US", - "FS: Ember - Greirat from US", - ], lambda state: state.can_reach("Go To Undead Settlement", "Entrance", self.player)) - self._add_location_rule([ - "FS: Divine Blessing - Greirat from IBV", - "FS: Hidden Blessing - Greirat from IBV", - "FS: Titanite Scale - Greirat from IBV", - "FS: Twinkling Titanite - Greirat from IBV", - "FS: Ember - shop for Greirat's Ashes" - ], lambda state: state.can_reach( - "Go To Irithyll of the Boreal Valley", - "Entrance", - self.player - )) - self._add_location_rule( - "FS: Ember - shop for Greirat's Ashes", - lambda state: state.can_reach("Go To Grand Archives", "Entrance", self.player) - ) + self._add_npc_rules() # Crow items crow = { @@ -718,16 +689,16 @@ def has_any_scroll(state): "LC: Grand Archives Key - by Grand Archives door, after PC and AL bosses", "LC: Gotthard Twinswords - by Grand Archives door, after PC and AL bosses" ], lambda state: ( - state.can_reach("AL: Cinders of a Lord - Aldrich", "Location", self.player) and - state.can_reach("PC: Cinders of a Lord - Yhorm the Giant", "Location", self.player) + self._can_get(state, "AL: Cinders of a Lord - Aldrich") and + self._can_get(state, "PC: Cinders of a Lord - Yhorm the Giant") )) self._add_location_rule([ "FS: Morne's Great Hammer - Eygon", "FS: Moaning Shield - Eygon" ], lambda state: ( - state.can_reach("LC: Soul of Dragonslayer Armour", "Location", self.player) and - state.can_reach("FK: Soul of the Blood of the Wolf", "Location", self.player) + self._can_get(state, "LC: Soul of Dragonslayer Armour") and + self._can_get(state, "FK: Soul of the Blood of the Wolf") )) self._add_location_rule([ @@ -735,14 +706,14 @@ def has_any_scroll(state): "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", - ], lambda state: state.can_reach("Go To Archdragon Peak", "Entrance", self.player)) + ], lambda state: self._can_go_to(state, "Archdragon Peak")) self._add_location_rule([ "FK: Havel's Helm - upper keep, after killing AP belfry roof NPC", "FK: Havel's Armor - upper keep, after killing AP belfry roof NPC", "FK: Havel's Gauntlets - upper keep, after killing AP belfry roof NPC", "FK: Havel's Leggings - upper keep, after killing AP belfry roof NPC", - ], lambda state: state.can_reach("Go To Archdragon Peak", "Entrance", self.player)) + ], lambda state: self._can_go_to(state, "Archdragon Peak")) self._add_location_rule([ "RC: Dragonhead Shield - streets monument, across bridge", @@ -825,6 +796,200 @@ def has_any_scroll(state): elif self.options.early_banner == "early_local": self.multiworld.local_early_items[self.player]['Small Lothric Banner'] = 1 + def _add_npc_rules(self) -> None: + """Adds rules for items accessible via NPC quests. + + We list missable locations here even though they never contain progression items so that the + game knows what sphere they're in. This is especially useful for item smoothing. (We could + add rules for boss transposition items as well, but then we couldn't freely reorder boss + soul locations for smoothing.) + """ + + ## Greirat + + self._add_location_rule([ + "FS: Divine Blessing - Greirat from US", + "FS: Ember - Greirat from US", + ], lambda state: ( + self._can_go_to(state, "Undead Settlement") + and state.has("Loretta's Bone", self.player) + )) + self._add_location_rule([ + "FS: Divine Blessing - Greirat from IBV", + "FS: Hidden Blessing - Greirat from IBV", + "FS: Titanite Scale - Greirat from IBV", + "FS: Twinkling Titanite - Greirat from IBV", + "FS: Ember - shop for Greirat's Ashes" + ], lambda state: ( + self._can_go_to(state, "Irithyll of the Boreal Valley") + and self._can_get(state, "FS: Divine Blessing - Greirat from US") + # Either Patches or Siegward can save Greirat, but we assume the player will want to use + # Patches because it's harder to screw up + and self._can_get(state, "CD: Shotel - Patches") + )) + self._add_location_rule([ + "FS: Ember - shop for Greirat's Ashes", + ], lambda state: ( + self._can_go_to(state, "Grand Archives") + and self._can_get(state, "FS: Divine Blessing - Greirat from IBV") + )) + + ## Patches + + # There are two ways to get Patches to open up shop in Firelink. You can either get tricked + # in the firelink bell tower, or you can beat the Abyss Watchers. Because the bell tower + # route can be missed if the player accesses the tower before resting in Rosaria's Bed + # Chamber, we assume the player will trigger the shop via Abyss Watchers. + self._add_location_rule([ + "CD: Shotel - Patches", + "CD: Ember - Patches", + ], lambda state: self._can_get(state, "FK: Soul of the Blood of the Wolf")) + + # The forgiveness coin is ONLY accessible through the bell tower interaction, so if the + # player has chosen to allow important items in missable locations we ensuer that the bell + # tower can't be accessed until after cathedral + if self.options.missable_locations == "unnecessary": + self._add_entrance_rule( + "Firelink Shrine Bell Tower", + lambda state: self._can_go_to(state, "Cathedral of the Deep") + ) + self._add_location_rule([ + "FS: Rusted Gold Coin - don't forgive Patches" + ], lambda state: self._can_go_to(state, "Firelink Shrine Bell Tower")) + + # Patches sells this after you tell him to search for Greirat in Grand Archives + self._add_location_rule([ + "FS: Hidden Blessing - Patches after searching GA" + ], lambda state: ( + self._can_get(state, "CD: Shotel - Patches") + and self._can_get(state, "FS: Ember - shop for Greirat's Ashes") + )) + + # Only make the player kill Patches once all his other items are available + self._add_location_rule([ + "CD: Winged Spear - kill Patches", + # You don't _have_ to kill him for this, but he has to be in Firelink at the same time + # as Greirat to get it in the shop and that may not be feasible if the player progresses + # Greirat's quest much faster. + "CD: Horsehoof Ring - Patches", + ], lambda state: ( + self._can_get(state, "FS: Hidden Blessing - Patches after searching GA") + and self._can_get(state, "FS: Rusted Gold Coin - don't forgive Patches") + )) + + ## Leonhard + + self._add_location_rule([ + # Talk to Leonhard in Firelink with a Pale Tongue after lighting Cliff Underside or + # killing Greatwood. This doesn't consume the Pale Tongue, it just has to be in + # inventory + "FS: Lift Chamber Key - Leonhard", + # Progress Leonhard's quest and then return to Rosaria after lighting Profaned Capital + "CD: Black Eye Orb - Rosaria from Leonhard's quest", + ], "Pale Tongue") + + ## Hawkwood + + # After Hawkwood leaves and once you have the Torso Stone, you can fight him for dragon + # stones. Andre will give Swordgrass as a hint as well + self._add_location_rule([ + "FK: Twinkling Dragon Head Stone - Hawkwood drop", + "FS: Hawkwood's Swordgrass - Andre after gesture in AP summit" + ], lambda state: ( + self._can_get(state, "FS: Hawkwood's Shield - gravestone after Hawkwood leaves") + and state.has("Twinkling Dragon Torso Stone", self.player) + )) + + ## Siegward + + # Unlock Siegward's cell after progressing his quest + self._add_location_rule("ID: Titanite Slab - Siegward", "Old Cell Key") + + # These drop after completing Siegward's quest and talking to him in Yhorm's arena + self._add_location_rule([ + "PC: Siegbräu - Siegward after killing boss", + "PC: Storm Ruler - Siegward", + "PC: Pierce Shield - Siegward", + ], lambda state: ( + self._can_get(state, "ID: Titanite Slab - Siegward") + and self._can_get(state, "PC: Soul of Yhorm the Giant") + )) + + ## Sirris + + # Kill Greatwood and turn in Dreamchaser's Ashes to trigger this opportunity for invasion + self._add_location_rule([ + "FS: Mail Breaker - Sirris for killing Creighton", + "FS: Silvercat Ring - Sirris for killing Creighton", + ], lambda state: ( + self._can_get(state, "US: Soul of the Rotted Greatwood") + and state.has("Dreamchaser's Ashes", self.player) + )) + + # Kill Creighton and Aldrich to trigger this opportunity for invasion + self._add_location_rule([ + "FS: Budding Green Blossom - shop after killing Creighton and AL boss", + "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", + ], lambda state: ( + self._can_get(state, "FS: Mail Breaker - Sirris for killing Creighton") + and self._can_get(state, "AL: Soul of Aldrich") + )) + + # Kill Hodrick and Twin Princes to trigger the end of the quest + self._add_location_rule([ + "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", + # Killing Yorshka will anger Sirris and stop her quest, so don't expect it until the + # quest is done + "AL: Yorshka's Chime - kill Yorshka", + ], lambda state: ( + self._can_get(state, "US: Soul of the Rotted Greatwood") + and state.has("Dreamchaser's Ashes", self.player) + )) + + ## Cornyx + + self._add_location_rule([ + "US: Old Sage's Blindfold - kill Cornyx", + "US: Cornyx's Garb - kill Cornyx", + "US: Cornyx's Wrap - kill Cornyx", + "US: Cornyx's Skirt - kill Cornyx", + ], lambda state: ( + state.has("Great Swamp Pyromancy Tome", self.player) + and state.has("Carthus Pyromancy Tome", self.player) + and state.has("Izalith Pyromancy Tome", self.player) + )) + + ## Irina + + self._add_location_rule([ + "US: Tower Key - kill Irina", + ], lambda state: ( + state.has("Braille Divine Tome of Carim", self.player) + and state.has("Braille Divine Tome of Lothric", self.player) + )) + + ## Karla + + self._add_location_rule([ + "FS: Karla's Pointed Hat - kill Karla", + "FS: Karla's Coat - kill Karla", + "FS: Karla's Gloves - kill Karla", + "FS: Karla's Trousers - kill Karla", + ], lambda state: ( + state.has("Quelana Pyromancy Tome", self.player) + and state.has("Grave Warden Pyromancy Tome", self.player) + and state.has("Deep Braille Divine Tome", self.player) + and state.has("Londor Braille Divine Tome", self.player) + )) + def _add_location_rule(self, location: Union[str, List[str]], rule: Union[CollectionRule, str]) -> None: """Sets a rule for the given location if it that location is randomized. @@ -851,6 +1016,16 @@ def _add_entrance_rule(self, region: str, rule: Union[CollectionRule, str]) -> N add_rule(self.multiworld.get_entrance("Go To " + region, self.player), rule) + def _can_go_to(self, state, region) -> None: + """Returns whether state can access the given region name.""" + return state.can_reach(f"Go To {region}", "Entrance", self.player) + + + def _can_get(self, state, location) -> None: + """Returns whether state can access the given location name.""" + return state.can_reach(location, "Location", self.player) + + def is_location_available(self, location: Union[str, DS3LocationData]) -> bool: """Returns whether the given location is being randomized.""" if isinstance(location, DS3LocationData): From c03c81e33939d8f3ca2a00eacc7c41232b6dc623 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 26 Feb 2024 00:16:32 -0800 Subject: [PATCH 133/238] Don't allow crow trades to have foreign items --- worlds/dark_souls_3/__init__.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index c5c6b73a7ad1..8d9cb0d34e7f 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -633,7 +633,15 @@ def set_rules(self) -> None: "Eleonora": "Hollow Gem", } for (given, received) in crow.items(): - self._add_location_rule(f"FSBT: {received} - crow for {given}", given) + name = f"FSBT: {received} - crow for {given}" + self._add_location_rule(name, given) + + # Don't let crow items have foreign items because they're picked up in a way that's + # missed by the hook we use to send location items + add_item_rule( + self.multiworld.get_location(name, self.player), + lambda item: item.player == self.player + ) # The offline randomizer edits events to guarantee that Greirat won't go to Lothric until # Grand Archives is available, so his shop will always be available one way or another. From 3efee40d0b583b17616f22192f6c28b374b98f80 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 26 Feb 2024 00:23:58 -0800 Subject: [PATCH 134/238] Fix a variable capture bug --- worlds/dark_souls_3/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 8d9cb0d34e7f..227723eb4cc8 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -554,7 +554,7 @@ def set_rules(self) -> None: for (soul, soul_name, items) in transpositions: self._add_location_rule([ f"FS: {item} - Ludleth for {soul_name}" for item in items - ], lambda state: ( + ], lambda state, soul=soul: ( state.has(soul, self.player) and state.has("Transposing Kiln", self.player) )) From 991a62f294bae01ba43e645db456da2b6cd1cfcc Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 26 Feb 2024 00:29:10 -0800 Subject: [PATCH 135/238] Make sure early items are accessible early even with early Castle --- worlds/dark_souls_3/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 227723eb4cc8..84955eeee5d1 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -794,9 +794,13 @@ def has_any_scroll(state): if 'Pyromancy Flame' in randomized_items: # Make this available early because so many items are useless without it. self._add_entrance_rule("Road of Sacrifices", "Pyromancy Flame") + self._add_entrance_rule("Consumed King's Garden", "Pyromancy Flame") + self._add_entrance_rule("Grand Archives", "Pyromancy Flame") if 'Transposing Kiln' in randomized_items: # Make this available early so players can make use of their boss souls. self._add_entrance_rule("Road of Sacrifices", "Transposing Kiln") + self._add_entrance_rule("Consumed King's Garden", "Transposing Kiln") + self._add_entrance_rule("Grand Archives", "Transposing Kiln") # Make this available pretty early if 'Small Lothric Banner' in randomized_items: if self.options.early_banner == "early_global": From d6c68fc64f7e6754434d0c3cddbc4f9185b5500b Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 2 Mar 2024 23:28:54 -0800 Subject: [PATCH 136/238] Mark ID giant slave drops as missable --- worlds/dark_souls_3/Locations.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 950045aacd9f..e9a3ab9d2c95 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1723,10 +1723,13 @@ def __init__( DS3LocationData("ID: Titanite Chunk - balcony above pit, lizard", "Titanite Chunk", lizard = True), DS3LocationData("ID: Titanite Scale - B2 far, lizard", "Titanite Scale", lizard = True), + + # These are missable because of a bug that causes them to be dropped wherever the giant is + # randomized to, instead of where the miniboss is in vanilla. DS3LocationData("ID: Dung Pie - pit, miniboss drop", "Dung Pie x4", - miniboss = True), # Giant slave drop + miniboss = True, missable = True), # Giant slave drop DS3LocationData("ID: Titanite Chunk - pit, miniboss drop", "Titanite Chunk", - miniboss = True), # Giant Slave Drop + miniboss = True, missable = True), # Giant Slave Drop # Alva (requires ember) DS3LocationData("ID: Alva Helm - B3 near, by Karla's cell, after killing Alva", "Alva Helm", From 4f6094bdd8dae8bcb00256884b2c6274c0419f3b Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 2 Mar 2024 23:49:07 -0800 Subject: [PATCH 137/238] Make sure late basin means that early items aren't behind it --- worlds/dark_souls_3/__init__.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 84955eeee5d1..10a9a4db9e9f 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -687,11 +687,21 @@ def has_any_scroll(state): # Lump Soul of the Dancer in with LC for locations that should not be reachable # before having access to US. (Prevents requiring getting Basin to fight Dancer to get SLB to go to US) if self.options.late_basin_of_vows: - self._add_location_rule("HWL: Soul of the Dancer", "Small Lothric Banner") - # This isn't really necessary, but it ensures that the game logic knows players will - # want to do Lothric Castle after at least being _able_ to access Catacombs. This is - # useful for smooth item placement. - self._add_location_rule("HWL: Soul of the Dancer", has_any_scroll) + self._add_location_rule("HWL: Soul of the Dancer", lambda state: ( + state.has("Small Lothric Banner", self.player) + # Make sure these are actually available early. + and ( + "Transposing Kiln" not in randomized_items + or state.has("Transposing Kiln", self.player) + ) and ( + "Pyromancy Flame" not in randomized_items + or state.has("Pyromancy Flame", self.player) + ) + # This isn't really necessary, but it ensures that the game logic knows players will + # want to do Lothric Castle after at least being _able_ to access Catacombs. This is + # useful for smooth item placement. + and has_any_scroll(state) + )) self._add_location_rule([ "LC: Grand Archives Key - by Grand Archives door, after PC and AL bosses", From 420a042ac74007af5d6eb7f868d799e17be7bb47 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 3 Mar 2024 00:04:20 -0800 Subject: [PATCH 138/238] Make is_location_available explicitly private --- worlds/dark_souls_3/__init__.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 10a9a4db9e9f..5fe7e755e7e2 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -127,7 +127,7 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: if not self.options.enable_dlc and boss.dlc: return False - if not self.is_location_available("PC: Storm Ruler - boss room"): + if not self._is_location_available("PC: Storm Ruler - boss room"): # If the Storm Ruler isn't randomized, make sure the player can get to the normal Storm # Ruler location before they need to get through Yhorm. if boss.before_storm_ruler: return False @@ -135,7 +135,7 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: # If the Small Doll also wasn't randomized, make sure Yhorm isn't blocking access to it # or it won't be possible to get into Profaned Capital before beating him. if ( - not self.is_location_available("CD: Small Doll - boss drop") + not self._is_location_available("CD: Small Doll - boss drop") and boss.name in {"Crystal Sage", "Deacons of the Deep"} ): return False @@ -146,7 +146,7 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: # allow Yhorm as Iudex Gundyr if there's at least one available location. excluded = self.options.exclude_locations.value return any( - self.is_location_available(location) + self._is_location_available(location) and location.name not in excluded and location.name != "CA: Coiled Sword - boss drop" for location in location_tables["Cemetery of Ash"] @@ -250,14 +250,14 @@ def create_region(self, region_name, location_table) -> Region: excluded = self.options.exclude_locations.value for location in location_table: - if self.is_location_available(location): + if self._is_location_available(location): new_location = DarkSouls3Location(self.player, location, new_region) if ( location.missable and self.options.missable_locations == "unimportant" ) or ( # Mark Red Eye Orb as missable if Lift Chamber Key isn't randomized, because # the latter is missable by default. - not self.is_location_available("FS: Lift Chamber Key - Leonhard") + not self._is_location_available("FS: Lift Chamber Key - Leonhard") and location.name == "HWL: Red Eye Orb - wall tower, miniboss" ): new_location.progress_type = LocationProgressType.EXCLUDED @@ -299,7 +299,7 @@ def create_items(self): itempool: List[DarkSouls3Item] = [] num_required_extra_items = 0 for location in self.multiworld.get_unfilled_locations(self.player): - if not self.is_location_available(location.name): + if not self._is_location_available(location.name): raise Exception("DS3 generation bug: Added an unavailable location.") item = item_dictionary[location.data.default_item_name] @@ -462,7 +462,7 @@ def set_rules(self) -> None: ) # Define the access rules to some specific locations - if self.is_location_available("FS: Lift Chamber Key - Leonhard"): + if self._is_location_available("FS: Lift Chamber Key - Leonhard"): self._add_location_rule("HWL: Red Eye Orb - wall tower, miniboss", "Lift Chamber Key") self._add_location_rule("ID: Bellowing Dragoncrest Ring - drop from B1 towards pit", @@ -746,7 +746,7 @@ def has_any_scroll(state): # Forbid shops from carrying items with multiple counts (the offline randomizer has its own # logic for choosing how many shop items to sell), and from carring soul items. for location in location_dictionary.values(): - if self.is_location_available(location): + if self._is_location_available(location): if location.shop: add_item_rule(self.multiworld.get_location(location.name, self.player), lambda item: ( @@ -756,7 +756,7 @@ def has_any_scroll(state): # This particular location is bugged, and will drop two copies of whatever item is placed # there. - if self.is_location_available("US: Young White Branch - by white tree #2"): + if self._is_location_available("US: Young White Branch - by white tree #2"): loc = self.multiworld.get_location( "US: Young White Branch - by white tree #2", self.player @@ -789,7 +789,7 @@ def has_any_scroll(state): else set() ) for location in unnecessary_locations: - if self.is_location_available(location): + if self._is_location_available(location): add_item_rule(self.multiworld.get_location(location, self.player), lambda item: item.classification not in { ItemClassification.progression, @@ -1020,7 +1020,7 @@ def _add_location_rule(self, location: Union[str, List[str]], rule: Union[Collec """ locations = location if type(location) is list else [location] for location in locations: - if not self.is_location_available(location): return + if not self._is_location_available(location): return if isinstance(rule, str): assert item_dictionary[rule].classification == ItemClassification.progression rule = lambda state, item=rule: state.has(item, self.player) @@ -1048,7 +1048,7 @@ def _can_get(self, state, location) -> None: return state.can_reach(location, "Location", self.player) - def is_location_available(self, location: Union[str, DS3LocationData]) -> bool: + def _is_location_available(self, location: Union[str, DS3LocationData]) -> bool: """Returns whether the given location is being randomized.""" if isinstance(location, DS3LocationData): data = location @@ -1126,7 +1126,7 @@ def _fill_local_item( self.multiworld.get_location(location.name, self.player) for region in regions for location in location_tables[region] - if self.is_location_available(location) + if self._is_location_available(location) and not location.missable and not location.conditional and (not additional_condition or additional_condition(location)) @@ -1175,7 +1175,7 @@ def post_fill(self): for region in region_order # Shuffle locations within each region. for location in self._shuffle(location_tables[region]) - if self.is_location_available(location) + if self._is_location_available(location) ] # All DarkSouls3Items for this world that have been assigned anywhere, grouped by name From 84433da86afc63c375e97bca18cfaf12170cd6af Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 3 Mar 2024 00:11:07 -0800 Subject: [PATCH 139/238] Add an _add_item_rule utility that checks availability --- worlds/dark_souls_3/__init__.py | 46 ++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 5fe7e755e7e2..f0879bc1efc1 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -8,7 +8,7 @@ from Options import Toggle from worlds.AutoWorld import World, WebWorld -from worlds.generic.Rules import CollectionRule, set_rule, add_rule, add_item_rule +from worlds.generic.Rules import CollectionRule, ItemRule, set_rule, add_rule, add_item_rule from .Bosses import DS3BossInfo, all_bosses, default_yhorm_location from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, Infusion, UsefulIf, filler_item_names, item_descriptions, item_dictionary, item_name_groups @@ -638,10 +638,7 @@ def set_rules(self) -> None: # Don't let crow items have foreign items because they're picked up in a way that's # missed by the hook we use to send location items - add_item_rule( - self.multiworld.get_location(name, self.player), - lambda item: item.player == self.player - ) + self._add_item_rule(name, lambda item: item.player == self.player) # The offline randomizer edits events to guarantee that Greirat won't go to Lothric until # Grand Archives is available, so his shop will always be available one way or another. @@ -746,22 +743,22 @@ def has_any_scroll(state): # Forbid shops from carrying items with multiple counts (the offline randomizer has its own # logic for choosing how many shop items to sell), and from carring soul items. for location in location_dictionary.values(): - if self._is_location_available(location): - if location.shop: - add_item_rule(self.multiworld.get_location(location.name, self.player), - lambda item: ( - item.player != self.player or - (item.data.count == 1 and not item.data.souls) - )) + if location.shop: + self._add_item_rule( + location.name, + lambda item: ( + item.player != self.player or + (item.data.count == 1 and not item.data.souls) + ) + ) # This particular location is bugged, and will drop two copies of whatever item is placed # there. if self._is_location_available("US: Young White Branch - by white tree #2"): - loc = self.multiworld.get_location( + self._add_item_rule( "US: Young White Branch - by white tree #2", - self.player + lambda item: item.player == self.player and not item.data.unique ) - add_item_rule(loc, lambda item: item.player == self.player and not item.data.unique) # Make sure the Storm Ruler is available BEFORE Yhorm the Giant if self.yhorm_location.region: @@ -789,12 +786,13 @@ def has_any_scroll(state): else set() ) for location in unnecessary_locations: - if self._is_location_available(location): - add_item_rule(self.multiworld.get_location(location, self.player), - lambda item: item.classification not in { - ItemClassification.progression, - ItemClassification.progression_skip_balancing - }) + self._add_item_rule( + location, + lambda item: item.classification not in { + ItemClassification.progression, + ItemClassification.progression_skip_balancing + } + ) randomized_items = { item.name for item in self.multiworld.itempool @@ -1038,6 +1036,12 @@ def _add_entrance_rule(self, region: str, rule: Union[CollectionRule, str]) -> N add_rule(self.multiworld.get_entrance("Go To " + region, self.player), rule) + def _add_item_rule(self, location: str, rule: ItemRule) -> None: + """Sets a rule for what items are allowed in a given location.""" + if not self._is_location_available(location): return + add_item_rule(self.multiworld.get_location(location, self.player), rule) + + def _can_go_to(self, state, region) -> None: """Returns whether state can access the given region name.""" return state.can_reach(f"Go To {region}", "Entrance", self.player) From ef4a792acf684f95bdeee1f71bbd1df2dcc849f3 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 3 Mar 2024 01:51:12 -0800 Subject: [PATCH 140/238] Clear excluded items if excluded_locations == "unnecessary" --- worlds/dark_souls_3/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index f0879bc1efc1..369b8cd84f0a 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -287,6 +287,12 @@ def create_region(self, region_name, location_table) -> Region: new_region.locations.append(new_location) + # If we allow useful items in the excluded locations, we don't want Archipelago's fill + # algorithm to consider them excluded because it never allows useful items there. Instead, + # we manually add item rules to exclude important items. + if self.options.excluded_locations == "unnecessary": + self.options.exclude_locations.value.clear() + self.multiworld.regions.append(new_region) return new_region From df06596f5717868a5e8f8202c061a3e0005ca774 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 3 Mar 2024 16:28:12 -0800 Subject: [PATCH 141/238] Don't allow upgrades/infusions in crow trades --- worlds/dark_souls_3/Items.py | 14 ++++++++++++-- worlds/dark_souls_3/__init__.py | 8 +++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 436de9792521..a263994ea960 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -194,10 +194,15 @@ def counts(self, counts: List[int]) -> Generator["DS3ItemData", None, None]: filler = False, # Don't count multiples as filler by default ) + @property + def is_infused(self) -> bool: + """Returns whether this item is an infused weapon.""" + return self.ds3_code - self.base_ds3_code >= 100 + def infuse(self, infusion: Infusion) -> "DS3ItemData": """Returns this item with the given infusion applied.""" if not self.category.is_infusible: raise RuntimeError(f"{self.name} is not infusible.") - if self.ds3_code - self.base_ds3_code >= 100: + if self.is_infused: raise RuntimeError(f"{self.name} is already infused.") # We can't change the name or AP code when infusing/upgrading weapons, because they both @@ -210,12 +215,17 @@ def infuse(self, infusion: Infusion) -> "DS3ItemData": filler = False, ) + @property + def is_upgraded(self) -> bool: + """Returns whether this item is a weapon that's upgraded beyond level 0.""" + return (self.ds3_code - self.base_ds3_code) % 100 != 0 + def upgrade(self, level: int) -> "DS3ItemData": """Upgrades this item to the given level.""" if not self.category.upgrade_level: raise RuntimeError(f"{self.name} is not upgradable.") if level > self.category.upgrade_level: raise RuntimeError(f"{self.name} can't be upgraded to +{level}.") - if (self.ds3_code - self.base_ds3_code) % 100 != 0: + if self.is_upgraded: raise RuntimeError(f"{self.name} is already upgraded.") # We can't change the name or AP code when infusing/upgrading weapons, because they both diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 369b8cd84f0a..30970a46fc7d 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -644,7 +644,13 @@ def set_rules(self) -> None: # Don't let crow items have foreign items because they're picked up in a way that's # missed by the hook we use to send location items - self._add_item_rule(name, lambda item: item.player == self.player) + self._add_item_rule(name, lambda item: ( + item.player == self.player + # Because of the weird way they're delivered, crow items don't seem to support + # infused or upgraded weapons. + and not item.data.is_infused + and not item.data.is_upgraded + )) # The offline randomizer edits events to guarantee that Greirat won't go to Lothric until # Grand Archives is available, so his shop will always be available one way or another. From 418f34a55fca85030f863cb8b7522dbe6ea436a0 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 3 Mar 2024 16:33:35 -0800 Subject: [PATCH 142/238] Fix the documentation for deprecated options --- worlds/dark_souls_3/Options.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 29241053e9f0..5cb389ac78ab 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -53,7 +53,7 @@ class RandomizeWeaponLocations(DefaultOnToggle): Setting this to false is now equivalent to adding "Weapons" to the "Exclude Locations" option. It does _not_ cause the locations not be randomized - unless "Excluded Locations" is also set to "Original Items". + unless "Excluded Locations" is also set to "Unrandomized". """ display_name = "Randomize Weapon Locations" @@ -63,7 +63,7 @@ class RandomizeShieldLocations(DefaultOnToggle): Setting this to false is now equivalent to adding "Shields" to the "Exclude Locations" option. It does _not_ cause the locations not be randomized - unless "Excluded Locations" is also set to "Original Items". + unless "Excluded Locations" is also set to "Unrandomized". """ display_name = "Randomize Shield Locations" @@ -73,7 +73,7 @@ class RandomizeArmorLocations(DefaultOnToggle): Setting this to false is now equivalent to adding "Armor" to the "Exclude Locations" option. It does _not_ cause the locations not be randomized - unless "Excluded Locations" is also set to "Original Items". + unless "Excluded Locations" is also set to "Unrandomized". """ display_name = "Randomize Armor Locations" @@ -83,7 +83,7 @@ class RandomizeRingLocations(DefaultOnToggle): Setting this to false is now equivalent to adding "Rings" to the "Exclude Locations" option. It does _not_ cause the locations not be randomized - unless "Excluded Locations" is also set to "Original Items". + unless "Excluded Locations" is also set to "Unrandomized". """ display_name = "Randomize Ring Locations" @@ -93,7 +93,7 @@ class RandomizeSpellLocations(DefaultOnToggle): Setting this to false is now equivalent to adding "Spells" to the "Exclude Locations" option. It does _not_ cause the locations not be randomized - unless "Excluded Locations" is also set to "Original Items". + unless "Excluded Locations" is also set to "Unrandomized". """ display_name = "Randomize Spell Locations" @@ -103,7 +103,7 @@ class RandomizeKeyLocations(DefaultOnToggle): Setting this to false is now equivalent to adding "Progression" to the "Exclude Locations" option. It does _not_ cause the locations not be - randomized unless "Excluded Locations" is also set to "Original Items". + randomized unless "Excluded Locations" is also set to "Unrandomized". """ display_name = "Randomize Key Locations" @@ -113,7 +113,7 @@ class RandomizeBossSoulLocations(DefaultOnToggle): Setting this to false is now equivalent to adding "Boss Souls" to the "Exclude Locations" option. It does _not_ cause the locations not be - randomized unless "Excluded Locations" is also set to "Original Items". + randomized unless "Excluded Locations" is also set to "Unrandomized". """ display_name = "Randomize Key Locations" @@ -123,7 +123,7 @@ class RandomizeNPCLocations(DefaultOnToggle): Setting this to false is now equivalent to adding "Friendly NPC Rewards" to the "Exclude Locations" option. It does _not_ cause the locations not be - randomized unless "Excluded Locations" is also set to "Original Items". + randomized unless "Excluded Locations" is also set to "Unrandomized". """ display_name = "Randomize NPC Locations" @@ -133,7 +133,7 @@ class RandomizeMiscLocations(DefaultOnToggle): Setting this to false is now equivalent to adding "Unique" to the "Exclude Locations" option. It does _not_ cause the locations not be randomized - unless "Excluded Locations" is also set to "Original Items". + unless "Excluded Locations" is also set to "Unrandomized". """ display_name = "Randomize Miscellaneous Locations" @@ -143,7 +143,7 @@ class RandomizeHealthLocations(DefaultOnToggle): Setting this to false is now equivalent to adding "Healing" to the "Exclude Locations" option. It does _not_ cause the locations not be randomized - unless "Excluded Locations" is also set to "Original Items". + unless "Excluded Locations" is also set to "Unrandomized". """ display_name = "Randomize Health Locations" @@ -153,7 +153,7 @@ class RandomizeProgressiveLocationsOption(DefaultOnToggle): Setting this to false is now equivalent to adding "Miscellaneous" to the "Exclude Locations" option. It does _not_ cause the locations not be - randomized unless "Excluded Locations" is also set to "Original Items". + randomized unless "Excluded Locations" is also set to "Unrandomized". """ display_name = "Randomize Progressive Locations" From 4a676e0b7948597adfcd3a1f89be996eb8406e8d Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 3 Mar 2024 16:36:08 -0800 Subject: [PATCH 143/238] Create events for all excluded locations This allows `can_reach` logic to work even if the locations are randomized. --- worlds/dark_souls_3/__init__.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 30970a46fc7d..87f1f49377f4 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -265,12 +265,11 @@ def create_region(self, region_name, location_table) -> Region: # Don't allow Siegward's Storm Ruler to mark Yhorm as defeatable. if location.name == "PC: Storm Ruler - Siegward": continue - # Replace non-randomized progression items with events + # Replace non-randomized items with events event_item = ( self.create_item(location.default_item_name) if location.default_item_name else DarkSouls3Item.event(location.name, self.player) ) - if event_item.classification != ItemClassification.progression: continue new_location = DarkSouls3Location( self.player, @@ -1064,10 +1063,15 @@ def _can_get(self, state, location) -> None: return state.can_reach(location, "Location", self.player) - def _is_location_available(self, location: Union[str, DS3LocationData]) -> bool: + def _is_location_available( + self, + location: Union[str, DS3LocationData, DarkSouls3Location] + ) -> bool: """Returns whether the given location is being randomized.""" if isinstance(location, DS3LocationData): data = location + elif isinstance(location, DarkSouls3Location): + data = location.data else: data = location_dictionary[location] @@ -1197,7 +1201,7 @@ def post_fill(self): # All DarkSouls3Items for this world that have been assigned anywhere, grouped by name full_items_by_name = defaultdict(list) for location in self.multiworld.get_filled_locations(): - if location.item.player == self.player: + if location.item.player == self.player and self._is_location_available(location): full_items_by_name[location.item.name].append(location.item) def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: From 1024c3af572540447ca420de814ec58baf7d5aa0 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 3 Mar 2024 21:11:25 -0800 Subject: [PATCH 144/238] Fix up Patches' and Siegward's logic based on some manual testing --- worlds/dark_souls_3/__init__.py | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 87f1f49377f4..aaad0397f729 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -867,26 +867,19 @@ def _add_npc_rules(self) -> None: ## Patches - # There are two ways to get Patches to open up shop in Firelink. You can either get tricked - # in the firelink bell tower, or you can beat the Abyss Watchers. Because the bell tower - # route can be missed if the player accesses the tower before resting in Rosaria's Bed - # Chamber, we assume the player will trigger the shop via Abyss Watchers. + # Patches will only set up shop in Firelink once he's tricked you in the bell tower. He'll + # only do _that_ once you've spoken to Siegward after killing the Fire Demon and lit the + # Rosaria's Bed Chamber bonfire. He _won't_ set up shop in the Cathedral if you light the + # Rosaria's Bed Chamber bonfire before getting tricked by him, so we assume these locations + # require the bell tower. self._add_location_rule([ "CD: Shotel - Patches", "CD: Ember - Patches", - ], lambda state: self._can_get(state, "FK: Soul of the Blood of the Wolf")) - - # The forgiveness coin is ONLY accessible through the bell tower interaction, so if the - # player has chosen to allow important items in missable locations we ensuer that the bell - # tower can't be accessed until after cathedral - if self.options.missable_locations == "unnecessary": - self._add_entrance_rule( - "Firelink Shrine Bell Tower", - lambda state: self._can_go_to(state, "Cathedral of the Deep") - ) - self._add_location_rule([ "FS: Rusted Gold Coin - don't forgive Patches" - ], lambda state: self._can_go_to(state, "Firelink Shrine Bell Tower")) + ], lambda state: ( + self._can_go_to(state, "Firelink Shrine Bell Tower") + and self._can_go_to(state, "Cathedral of the Deep") + )) # Patches sells this after you tell him to search for Greirat in Grand Archives self._add_location_rule([ @@ -934,7 +927,13 @@ def _add_npc_rules(self) -> None: ## Siegward # Unlock Siegward's cell after progressing his quest - self._add_location_rule("ID: Titanite Slab - Siegward", "Old Cell Key") + self._add_location_rule([ + "ID: Titanite Slab - Siegward", + ], lambda state: ( + state.has("Old Cell Key", self.player) + # Progressing Siegward's quest requires buying his armor from Patches. + and self._can_get(state, "CD: Shotel - Patches") + )) # These drop after completing Siegward's quest and talking to him in Yhorm's arena self._add_location_rule([ From aa1332689ef59bb13d13f2ba990baf642552e166 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 3 Mar 2024 23:13:30 -0800 Subject: [PATCH 145/238] Factor out more sub-methods for setting location rules --- worlds/dark_souls_3/__init__.py | 539 +++++++++++++++++--------------- 1 file changed, 289 insertions(+), 250 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index aaad0397f729..bfefa1fd6cd4 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -429,7 +429,18 @@ def get_filler_item_name(self) -> str: def set_rules(self) -> None: - # Define the access rules to the entrances + randomized_items = { + item.name for item in self.multiworld.itempool + if item.player == self.player + } + + self._add_shop_rules() + self._add_npc_rules() + self._add_transposition_rules() + self._add_crow_rules() + self._add_unnecessary_location_rules() + self._add_early_item_rules(randomized_items) + self._add_entrance_rule("Firelink Shrine Bell Tower", "Tower Key") self._add_entrance_rule("Undead Settlement", "Small Lothric Banner") self._add_entrance_rule("Road of Sacrifices", "US -> RS") @@ -475,220 +486,17 @@ def set_rules(self) -> None: self._add_location_rule("ID: Covetous Gold Serpent Ring - Siegward's cell", "Old Cell Key") self._add_location_rule( "UG: Hornet Ring - environs, right of main path after killing FK boss", - "Small Lothric Banner" + lambda state: self._can_get(state, "FK: Cinders of a Lord - Abyss Watcher"), ) - self._add_entrance_rule("Karla's Shop", "Jailer's Key Ring") - - # Ashes - ashes = { - "Mortician's Ashes": ["Alluring Skull", "Ember", "Grave Key"], - "Dreamchaser's Ashes": ["Life Ring", "Hidden Blessing"], - "Paladin's Ashes": ["Lloyd's Shield Ring"], - "Grave Warden's Ashes": ["Ember"], - "Prisoner Chief's Ashes": [ - "Karla's Pointed Hat", "Karla's Coat", "Karla's Gloves", "Karla's Trousers" - ], - "Xanthous Ashes": ["Xanthous Overcoat", "Xanthous Gloves", "Xanthous Trousers"], - "Dragon Chaser's Ashes": ["Ember"], - "Easterner's Ashes": [ - "Washing Pole", "Eastern Helm", "Eastern Armor", "Eastern Gauntlets", - "Eastern Leggings", "Wood Grain Ring", - ], - "Captain's Ashes": [ - "Millwood Knight Helm", "Millwood Knight Armor", "Millwood Knight Gauntlets", - "Millwood Knight Leggings", "Refined Gem", - ] - } - for (ash, items) in ashes.items(): - self._add_location_rule([f"FS: {item} - {ash}" for item in items], ash) - - # Soul transposition - transpositions = [ - ( - "Soul of Boreal Valley Vordt", "Vordt", - ["Vordt's Great Hammer", "Pontiff's Left Eye"] - ), - ("Soul of Rosaria", "Rosaria", ["Bountiful Sunlight"]), - ("Soul of Aldrich", "Aldrich", ["Darkmoon Longbow", "Lifehunt Scythe"]), - ( - "Soul of the Rotted Greatwood", "Greatwood", - ["Hollowslayer Greatsword", "Arstor's Spear"] - ), - ("Soul of a Crystal Sage", "Sage", ["Crystal Sage's Rapier", "Crystal Hail"]), - ("Soul of the Deacons of the Deep", "Deacons", ["Cleric's Candlestick", "Deep Soul"]), - ("Soul of a Stray Demon", "Stray Demon", ["Havel's Ring", "Boulder Heave"]), - ( - "Soul of the Blood of the Wolf", "Abyss Watchers", - ["Farron Greatsword", "Wolf Knight's Greatsword"] - ), - ("Soul of High Lord Wolnir", "Wolnir", ["Wolnir's Holy Sword", "Black Serpent"]), - ("Soul of a Demon", "Fire Demon", ["Demon's Greataxe", "Demon's Fist"]), - ( - "Soul of the Old Demon King", "Old Demon King", - ["Old King's Great Hammer", "Chaos Bed Vestiges"] - ), - ( - "Soul of Pontiff Sulyvahn", "Pontiff", - ["Greatsword of Judgment", "Profaned Greatsword"] - ), - ("Soul of Yhorm the Giant", "Yhorm", ["Yhorm's Great Machete", "Yhorm's Greatshield"]), - ("Soul of the Dancer", "Dancer", ["Dancer's Enchanted Swords", "Soothing Sunlight"]), - ( - "Soul of Dragonslayer Armour", "Dragonslayer", - ["Dragonslayer Greataxe", "Dragonslayer Greatshield"] - ), - ( - "Soul of Consumed Oceiros", "Oceiros", - ["Moonlight Greatsword", "White Dragon Breath"] - ), - ( - "Soul of the Twin Princes", "Princes", - ["Lorian's Greatsword", "Lothric's Holy Sword"] - ), - ("Soul of Champion Gundyr", "Champion", ["Gundyr's Halberd", "Prisoner's Chain"]), - ( - "Soul of the Nameless King", "Nameless", - ["Storm Curved Sword", "Dragonslayer Swordspear", "Lightning Storm"] - ), - ("Soul of the Lords", "Cinder", ["Firelink Greatsword", "Sunlight Spear"]), - ("Soul of Sister Friede", "Friede", ["Friede's Great Scythe", "Rose of Ariandel"]), - ("Soul of the Demon Prince", "Demon Prince", ["Demon's Scar", "Seething Chaos"]), - ("Soul of Darkeater Midir", "Midir", ["Frayed Blade", "Old Moonlight"]), - ("Soul of Slave Knight Gael", "Gael", ["Gael's Greatsword", "Repeating Crossbow"]), - ] - for (soul, soul_name, items) in transpositions: - self._add_location_rule([ - f"FS: {item} - Ludleth for {soul_name}" for item in items - ], lambda state, soul=soul: ( - state.has(soul, self.player) and state.has("Transposing Kiln", self.player) - )) - - # Shop unlocks - shop_unlocks = { - "Cornyx": [ - ( - "Great Swamp Pyromancy Tome", "Great Swamp Tome", - ["Poison Mist", "Fire Orb", "Profuse Sweat", "Bursting Fireball"] - ), - ( - "Carthus Pyromancy Tome", "Carthus Tome", - ["Acid Surge", "Carthus Flame Arc", "Carthus Beacon"] - ), - ("Izalith Pyromancy Tome", "Izalith Tome", ["Great Chaos Fire Orb", "Chaos Storm"]), - ], - "Irina": [ - ( - "Braille Divine Tome of Carim", "Tome of Carim", - ["Med Heal", "Tears of Denial", "Force"] - ), - ( - "Braille Divine Tome of Lothric", "Tome of Lothric", - ["Bountiful Light", "Magic Barrier", "Blessed Weapon"] - ), - ], - "Orbeck": [ - ("Sage's Scroll", "Sage's Scroll", ["Great Farron Dart", "Farron Hail"]), - ( - "Golden Scroll", "Golden Scroll", - [ - "Cast Light", "Repair", "Hidden Weapon", "Hidden Body", - "Twisted Wall of Light" - ], - ), - ("Logan's Scroll", "Logan's Scroll", ["Homing Soulmass", "Soul Spear"]), - ( - "Crystal Scroll", "Crystal Scroll", - ["Homing Crystal Soulmass", "Crystal Soul Spear", "Crystal Magic Weapon"] - ), - ], - "Karla": [ - ("Quelana Pyromancy Tome", "Quelana Tome", ["Firestorm", "Rapport", "Fire Whip"]), - ( - "Grave Warden Pyromancy Tome", "Grave Warden Tome", - ["Black Flame", "Black Fire Orb"] - ), - ("Deep Braille Divine Tome", "Deep Braille Tome", ["Gnaw", "Deep Protection"]), - ( - "Londor Braille Divine Tome", "Londor Tome", - ["Vow of Silence", "Dark Blade", "Dead Again"] - ), - ], - } - for (shop, unlocks) in shop_unlocks.items(): - for (key, key_name, items) in unlocks: - self._add_location_rule( - [f"FS: {item} - {shop} for {key_name}" for item in items], key) - - self._add_npc_rules() - - # Crow items - crow = { - "Loretta's Bone": "Ring of Sacrifice", - # "Avelyn": "Titanite Scale", # Missing from offline randomizer - "Coiled Sword Fragment": "Titanite Slab", - "Seed of a Giant Tree": "Iron Leggings", - "Siegbräu": "Armor of the Sun", - # Offline randomizer can't randomize Hodrick's drop yet - # "Vertebra Shackle": "Lucatiel's Mask", - "Xanthous Crown": "Lightning Gem", - "Mendicant's Staff": "Sunlight Shield", - "Blacksmith Hammer": "Titanite Scale", - "Large Leather Shield": "Twinkling Titanite", - "Moaning Shield": "Blessed Gem", - "Eleonora": "Hollow Gem", - } - for (given, received) in crow.items(): - name = f"FSBT: {received} - crow for {given}" - self._add_location_rule(name, given) - - # Don't let crow items have foreign items because they're picked up in a way that's - # missed by the hook we use to send location items - self._add_item_rule(name, lambda item: ( - item.player == self.player - # Because of the weird way they're delivered, crow items don't seem to support - # infused or upgraded weapons. - and not item.data.is_infused - and not item.data.is_upgraded - )) - - # The offline randomizer edits events to guarantee that Greirat won't go to Lothric until - # Grand Archives is available, so his shop will always be available one way or another. - self._add_entrance_rule("Greirat's Shop", "Cell Key") - - self._add_location_rule([ - f"FS: {item} - shop after killing Leonhard" - for item in ["Leonhard's Garb", "Leonhard's Gauntlets", "Leonhard's Trousers"] - ], "Black Eye Orb") - - # You could just kill NPCs for these, but it's more fun to ensure the player can do - # their quests. - self._add_location_rule("HWL: Basin of Vows - Emma", "Small Doll") self._add_location_rule( "ID: Prisoner Chief's Ashes - B2 near, locked cell by stairs", "Jailer's Key Ring" ) - self._add_location_rule([ - "US: Old Sage's Blindfold - kill Cornyx", "US: Cornyx's Garb - kill Cornyx", - "US: Cornyx's Wrap - kill Cornyx", "US: Cornyx's Skirt - kill Cornyx" - ], lambda state: ( - state.has("Great Swamp Pyromancy Tome", self.player) - and state.has("Carthus Pyromancy Tome", self.player) - and state.has("Izalith Pyromancy Tome", self.player) - )) + self._add_entrance_rule("Karla's Shop", "Jailer's Key Ring") - # Make sure that the player can keep Orbeck around by giving him at least one scroll - # before killing Abyss Watchers. - def has_any_scroll(state): - return (state.has("Sage's Scroll", self.player) or - state.has("Golden Scroll", self.player) or - state.has("Logan's Scroll", self.player) or - state.has("Crystal Scroll", self.player)) - self._add_location_rule("FK: Soul of the Blood of the Wolf", has_any_scroll) - self._add_location_rule("FK: Cinders of a Lord - Abyss Watcher", has_any_scroll) - self._add_entrance_rule("Catacombs of Carthus", has_any_scroll) - # Not really necessary but ensures players can decide which way to go - if self.options.enable_dlc: - self._add_entrance_rule("Painted World of Ariandel (After Contraption)", has_any_scroll) + # The offline randomizer edits events to guarantee that Greirat won't go to Lothric until + # Grand Archives is available, so his shop will always be available one way or another. + self._add_entrance_rule("Greirat's Shop", "Cell Key") self._add_location_rule("HWL: Soul of the Dancer", "Basin of Vows") @@ -708,7 +516,7 @@ def has_any_scroll(state): # This isn't really necessary, but it ensures that the game logic knows players will # want to do Lothric Castle after at least being _able_ to access Catacombs. This is # useful for smooth item placement. - and has_any_scroll(state) + and self._has_any_scroll(state) )) self._add_location_rule([ @@ -783,49 +591,89 @@ def has_any_scroll(state): state.has("Cinders of a Lord - Aldrich", self.player) and \ state.has("Cinders of a Lord - Lothric Prince", self.player) - unnecessary_locations = ( - self.options.exclude_locations.value - if self.options.excluded_locations == "unnecessary" - else set() - ).union( - { - location.name - for location in self.multiworld.get_locations() - if location.player == self.player and location.data.missable - } - if self.options.missable_locations == "unnecessary" - else set() - ) - for location in unnecessary_locations: - self._add_item_rule( - location, - lambda item: item.classification not in { - ItemClassification.progression, - ItemClassification.progression_skip_balancing - } - ) - randomized_items = { - item.name for item in self.multiworld.itempool - if item.player == self.player + def _add_shop_rules(self) -> None: + """Adds rules for items unlocked in shops.""" + + # Ashes + ashes = { + "Mortician's Ashes": ["Alluring Skull", "Ember", "Grave Key"], + "Dreamchaser's Ashes": ["Life Ring", "Hidden Blessing"], + "Paladin's Ashes": ["Lloyd's Shield Ring"], + "Grave Warden's Ashes": ["Ember"], + "Prisoner Chief's Ashes": [ + "Karla's Pointed Hat", "Karla's Coat", "Karla's Gloves", "Karla's Trousers" + ], + "Xanthous Ashes": ["Xanthous Overcoat", "Xanthous Gloves", "Xanthous Trousers"], + "Dragon Chaser's Ashes": ["Ember"], + "Easterner's Ashes": [ + "Washing Pole", "Eastern Helm", "Eastern Armor", "Eastern Gauntlets", + "Eastern Leggings", "Wood Grain Ring", + ], + "Captain's Ashes": [ + "Millwood Knight Helm", "Millwood Knight Armor", "Millwood Knight Gauntlets", + "Millwood Knight Leggings", "Refined Gem", + ] } + for (ash, items) in ashes.items(): + self._add_location_rule([f"FS: {item} - {ash}" for item in items], ash) + + # Shop unlocks + shop_unlocks = { + "Cornyx": [ + ( + "Great Swamp Pyromancy Tome", "Great Swamp Tome", + ["Poison Mist", "Fire Orb", "Profuse Sweat", "Bursting Fireball"] + ), + ( + "Carthus Pyromancy Tome", "Carthus Tome", + ["Acid Surge", "Carthus Flame Arc", "Carthus Beacon"] + ), + ("Izalith Pyromancy Tome", "Izalith Tome", ["Great Chaos Fire Orb", "Chaos Storm"]), + ], + "Irina": [ + ( + "Braille Divine Tome of Carim", "Tome of Carim", + ["Med Heal", "Tears of Denial", "Force"] + ), + ( + "Braille Divine Tome of Lothric", "Tome of Lothric", + ["Bountiful Light", "Magic Barrier", "Blessed Weapon"] + ), + ], + "Orbeck": [ + ("Sage's Scroll", "Sage's Scroll", ["Great Farron Dart", "Farron Hail"]), + ( + "Golden Scroll", "Golden Scroll", + [ + "Cast Light", "Repair", "Hidden Weapon", "Hidden Body", + "Twisted Wall of Light" + ], + ), + ("Logan's Scroll", "Logan's Scroll", ["Homing Soulmass", "Soul Spear"]), + ( + "Crystal Scroll", "Crystal Scroll", + ["Homing Crystal Soulmass", "Crystal Soul Spear", "Crystal Magic Weapon"] + ), + ], + "Karla": [ + ("Quelana Pyromancy Tome", "Quelana Tome", ["Firestorm", "Rapport", "Fire Whip"]), + ( + "Grave Warden Pyromancy Tome", "Grave Warden Tome", + ["Black Flame", "Black Fire Orb"] + ), + ("Deep Braille Divine Tome", "Deep Braille Tome", ["Gnaw", "Deep Protection"]), + ( + "Londor Braille Divine Tome", "Londor Tome", + ["Vow of Silence", "Dark Blade", "Dead Again"] + ), + ], + } + for (shop, unlocks) in shop_unlocks.items(): + for (key, key_name, items) in unlocks: + self._add_location_rule( + [f"FS: {item} - {shop} for {key_name}" for item in items], key) - if 'Pyromancy Flame' in randomized_items: - # Make this available early because so many items are useless without it. - self._add_entrance_rule("Road of Sacrifices", "Pyromancy Flame") - self._add_entrance_rule("Consumed King's Garden", "Pyromancy Flame") - self._add_entrance_rule("Grand Archives", "Pyromancy Flame") - if 'Transposing Kiln' in randomized_items: - # Make this available early so players can make use of their boss souls. - self._add_entrance_rule("Road of Sacrifices", "Transposing Kiln") - self._add_entrance_rule("Consumed King's Garden", "Transposing Kiln") - self._add_entrance_rule("Grand Archives", "Transposing Kiln") - # Make this available pretty early - if 'Small Lothric Banner' in randomized_items: - if self.options.early_banner == "early_global": - self.multiworld.early_items[self.player]['Small Lothric Banner'] = 1 - elif self.options.early_banner == "early_local": - self.multiworld.local_early_items[self.player]['Small Lothric Banner'] = 1 def _add_npc_rules(self) -> None: """Adds rules for items accessible via NPC quests. @@ -834,6 +682,10 @@ def _add_npc_rules(self) -> None: game knows what sphere they're in. This is especially useful for item smoothing. (We could add rules for boss transposition items as well, but then we couldn't freely reorder boss soul locations for smoothing.) + + Generally, for locations that can be accessed early by killing NPCs, we set up requirements + assuming the player _doesn't_ so they aren't forced to start killing allies to advance the + quest. """ ## Greirat @@ -912,6 +764,11 @@ def _add_npc_rules(self) -> None: "CD: Black Eye Orb - Rosaria from Leonhard's quest", ], "Pale Tongue") + self._add_location_rule([ + f"FS: {item} - shop after killing Leonhard" + for item in ["Leonhard's Garb", "Leonhard's Gauntlets", "Leonhard's Trousers"] + ], "Black Eye Orb") + ## Hawkwood # After Hawkwood leaves and once you have the Torso Stone, you can fight him for dragon @@ -997,6 +854,15 @@ def _add_npc_rules(self) -> None: and state.has("Izalith Pyromancy Tome", self.player) )) + self._add_location_rule([ + "US: Old Sage's Blindfold - kill Cornyx", "US: Cornyx's Garb - kill Cornyx", + "US: Cornyx's Wrap - kill Cornyx", "US: Cornyx's Skirt - kill Cornyx" + ], lambda state: ( + state.has("Great Swamp Pyromancy Tome", self.player) + and state.has("Carthus Pyromancy Tome", self.player) + and state.has("Izalith Pyromancy Tome", self.player) + )) + ## Irina self._add_location_rule([ @@ -1020,6 +886,179 @@ def _add_npc_rules(self) -> None: and state.has("Londor Braille Divine Tome", self.player) )) + ## Emma + + self._add_location_rule("HWL: Basin of Vows - Emma", "Small Doll") + + ## Orbeck + + # Make sure that the player can keep Orbeck around by giving him at least one scroll + # before killing Abyss Watchers. + def has_any_scroll(state): + self._add_location_rule("FK: Soul of the Blood of the Wolf", self._has_any_scroll) + self._add_location_rule("FK: Cinders of a Lord - Abyss Watcher", self._has_any_scroll) + self._add_entrance_rule("Catacombs of Carthus", self._has_any_scroll) + # Not really necessary but ensures players can decide which way to go + if self.options.enable_dlc: + self._add_entrance_rule( + "Painted World of Ariandel (After Contraption)", + self._has_any_scroll + ) + + + def _add_transposition_rules(self) -> None: + """Adds rules for items obtainable from Ludleth by soul transposition.""" + + transpositions = [ + ( + "Soul of Boreal Valley Vordt", "Vordt", + ["Vordt's Great Hammer", "Pontiff's Left Eye"] + ), + ("Soul of Rosaria", "Rosaria", ["Bountiful Sunlight"]), + ("Soul of Aldrich", "Aldrich", ["Darkmoon Longbow", "Lifehunt Scythe"]), + ( + "Soul of the Rotted Greatwood", "Greatwood", + ["Hollowslayer Greatsword", "Arstor's Spear"] + ), + ("Soul of a Crystal Sage", "Sage", ["Crystal Sage's Rapier", "Crystal Hail"]), + ("Soul of the Deacons of the Deep", "Deacons", ["Cleric's Candlestick", "Deep Soul"]), + ("Soul of a Stray Demon", "Stray Demon", ["Havel's Ring", "Boulder Heave"]), + ( + "Soul of the Blood of the Wolf", "Abyss Watchers", + ["Farron Greatsword", "Wolf Knight's Greatsword"] + ), + ("Soul of High Lord Wolnir", "Wolnir", ["Wolnir's Holy Sword", "Black Serpent"]), + ("Soul of a Demon", "Fire Demon", ["Demon's Greataxe", "Demon's Fist"]), + ( + "Soul of the Old Demon King", "Old Demon King", + ["Old King's Great Hammer", "Chaos Bed Vestiges"] + ), + ( + "Soul of Pontiff Sulyvahn", "Pontiff", + ["Greatsword of Judgment", "Profaned Greatsword"] + ), + ("Soul of Yhorm the Giant", "Yhorm", ["Yhorm's Great Machete", "Yhorm's Greatshield"]), + ("Soul of the Dancer", "Dancer", ["Dancer's Enchanted Swords", "Soothing Sunlight"]), + ( + "Soul of Dragonslayer Armour", "Dragonslayer", + ["Dragonslayer Greataxe", "Dragonslayer Greatshield"] + ), + ( + "Soul of Consumed Oceiros", "Oceiros", + ["Moonlight Greatsword", "White Dragon Breath"] + ), + ( + "Soul of the Twin Princes", "Princes", + ["Lorian's Greatsword", "Lothric's Holy Sword"] + ), + ("Soul of Champion Gundyr", "Champion", ["Gundyr's Halberd", "Prisoner's Chain"]), + ( + "Soul of the Nameless King", "Nameless", + ["Storm Curved Sword", "Dragonslayer Swordspear", "Lightning Storm"] + ), + ("Soul of the Lords", "Cinder", ["Firelink Greatsword", "Sunlight Spear"]), + ("Soul of Sister Friede", "Friede", ["Friede's Great Scythe", "Rose of Ariandel"]), + ("Soul of the Demon Prince", "Demon Prince", ["Demon's Scar", "Seething Chaos"]), + ("Soul of Darkeater Midir", "Midir", ["Frayed Blade", "Old Moonlight"]), + ("Soul of Slave Knight Gael", "Gael", ["Gael's Greatsword", "Repeating Crossbow"]), + ] + for (soul, soul_name, items) in transpositions: + self._add_location_rule([ + f"FS: {item} - Ludleth for {soul_name}" for item in items + ], lambda state, soul=soul: ( + state.has(soul, self.player) and state.has("Transposing Kiln", self.player) + )) + + + def _add_crow_rules(self) -> None: + """Adds rules for for items obtainable by trading items to the crow on Firelink roof.""" + + crow = { + "Loretta's Bone": "Ring of Sacrifice", + # "Avelyn": "Titanite Scale", # Missing from offline randomizer + "Coiled Sword Fragment": "Titanite Slab", + "Seed of a Giant Tree": "Iron Leggings", + "Siegbräu": "Armor of the Sun", + # Offline randomizer can't randomize Hodrick's drop yet + # "Vertebra Shackle": "Lucatiel's Mask", + "Xanthous Crown": "Lightning Gem", + "Mendicant's Staff": "Sunlight Shield", + "Blacksmith Hammer": "Titanite Scale", + "Large Leather Shield": "Twinkling Titanite", + "Moaning Shield": "Blessed Gem", + "Eleonora": "Hollow Gem", + } + for (given, received) in crow.items(): + name = f"FSBT: {received} - crow for {given}" + self._add_location_rule(name, given) + + # Don't let crow items have foreign items because they're picked up in a way that's + # missed by the hook we use to send location items + self._add_item_rule(name, lambda item: ( + item.player == self.player + # Because of the weird way they're delivered, crow items don't seem to support + # infused or upgraded weapons. + and not item.data.is_infused + and not item.data.is_upgraded + )) + + + def _add_unnecessary_location_rules(self) -> None: + """Adds rules for locations that can contain useful but not necessary items.""" + + unnecessary_locations = ( + self.options.exclude_locations.value + if self.options.excluded_locations == "unnecessary" + else set() + ).union( + { + location.name + for location in self.multiworld.get_locations() + if location.player == self.player and location.data.missable + } + if self.options.missable_locations == "unnecessary" + else set() + ) + for location in unnecessary_locations: + self._add_item_rule( + location, + lambda item: item.classification not in { + ItemClassification.progression, + ItemClassification.progression_skip_balancing + } + ) + + + def _add_early_item_rules(self, randomized_items: Set[str]) -> None: + """Adds rules to make sure specific items are available early.""" + + if 'Pyromancy Flame' in randomized_items: + # Make this available early because so many items are useless without it. + self._add_entrance_rule("Road of Sacrifices", "Pyromancy Flame") + self._add_entrance_rule("Consumed King's Garden", "Pyromancy Flame") + self._add_entrance_rule("Grand Archives", "Pyromancy Flame") + if 'Transposing Kiln' in randomized_items: + # Make this available early so players can make use of their boss souls. + self._add_entrance_rule("Road of Sacrifices", "Transposing Kiln") + self._add_entrance_rule("Consumed King's Garden", "Transposing Kiln") + self._add_entrance_rule("Grand Archives", "Transposing Kiln") + # Make this available pretty early + if 'Small Lothric Banner' in randomized_items: + if self.options.early_banner == "early_global": + self.multiworld.early_items[self.player]['Small Lothric Banner'] = 1 + elif self.options.early_banner == "early_local": + self.multiworld.local_early_items[self.player]['Small Lothric Banner'] = 1 + + + def _has_any_scroll(self, state: CollectionState) -> bool: + """Returns whether the given state has any scroll item.""" + return ( + state.has("Sage's Scroll", self.player) + or state.has("Golden Scroll", self.player) + or state.has("Logan's Scroll", self.player) + or state.has("Crystal Scroll", self.player) + ) + def _add_location_rule(self, location: Union[str, List[str]], rule: Union[CollectionRule, str]) -> None: """Sets a rule for the given location if it that location is randomized. From 21b171fd1ea55e37cb48f4876fe7e2d0b798b855 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 4 Mar 2024 14:58:13 -0500 Subject: [PATCH 146/238] Oops, left these in --- worlds/dark_souls_3/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 026e01e93465..c71f4451c733 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -253,8 +253,8 @@ def create_region(self, region_name, location_table) -> Region: if self._is_location_available(location): new_location = DarkSouls3Location(self.player, location, new_region) if ( -# location.missable and self.options.missable_locations == "unimportant" -# ) or ( + location.missable and self.options.missable_locations == "unimportant" + ) or ( # Mark Red Eye Orb as missable if Lift Chamber Key isn't randomized, because # the latter is missable by default. not self._is_location_available("FS: Lift Chamber Key - Leonhard") @@ -1299,6 +1299,7 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: offworld = self._shuffle(loc for loc in locations if loc.game != "Dark Souls III") onworld = sorted((loc for loc in locations if loc.game == "Dark Souls III"), key=lambda loc: loc.data.region_value) + # Give offworld regions the last (best) items within a given sphere for location in onworld + offworld: new_item = self._pop_item(location, item_order) From 2177c6efa4a71776620e8c17fef3e4d441da896c Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 4 Mar 2024 14:58:34 -0500 Subject: [PATCH 147/238] Fixing name --- worlds/dark_souls_3/Options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 5cb389ac78ab..54750d89e553 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -115,7 +115,7 @@ class RandomizeBossSoulLocations(DefaultOnToggle): "Exclude Locations" option. It does _not_ cause the locations not be randomized unless "Excluded Locations" is also set to "Unrandomized". """ - display_name = "Randomize Key Locations" + display_name = "Randomize Boss Soul Locations" class RandomizeNPCLocations(DefaultOnToggle): From cef7a4907bc1e9a47e14b12ae8b3cbb571947aa3 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 4 Mar 2024 14:59:53 -0500 Subject: [PATCH 148/238] Left that in too --- worlds/dark_souls_3/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index c71f4451c733..6886f7a87f2a 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -778,8 +778,6 @@ def _add_npc_rules(self) -> None: "CD: Black Eye Orb - Rosaria from Leonhard's quest", ], "Pale Tongue") - self._add_location_rule("CD: Black Eye Orb - Rosaria from Leonhard's quest", "Lift Chamber Key") - self._add_location_rule([ f"FS: {item} - shop after killing Leonhard" for item in ["Leonhard's Garb", "Leonhard's Gauntlets", "Leonhard's Trousers"] From d881f43a1121ebde9dcf76048bcf755b7a31f767 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 4 Mar 2024 15:08:52 -0500 Subject: [PATCH 149/238] Changing to NamedRange to support special_range_names --- worlds/dark_souls_3/Options.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 54750d89e553..c4161d033d50 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -3,7 +3,7 @@ import json import typing -from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, ItemDict, Option, PerGameCommonOptions, Range, Toggle, VerifyKeys +from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, ItemDict, Option, PerGameCommonOptions, Range, NamedRange, Toggle, VerifyKeys class ExcludedLocationsOption(Choice): @@ -233,7 +233,7 @@ class RandomizeInfusionOption(Toggle): display_name = "Randomize Infusion" -class RandomizeInfusionPercentageOption(Range): +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 From 781acc545551ec8934ce02ea5c1d6b6482fe127b Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 4 Mar 2024 15:09:54 -0500 Subject: [PATCH 150/238] Alphabetizing --- worlds/dark_souls_3/Options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index c4161d033d50..b7d8658ac0cd 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -3,7 +3,7 @@ import json import typing -from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, ItemDict, Option, PerGameCommonOptions, Range, NamedRange, Toggle, VerifyKeys +from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, ItemDict, NamedRange, Option, PerGameCommonOptions, Range, Toggle, VerifyKeys class ExcludedLocationsOption(Choice): From 3010b792aedfc8781b5b2bb6435e089d7c50130f Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 5 Mar 2024 17:48:35 -0800 Subject: [PATCH 151/238] Don't call _is_location_available on foreign locations --- worlds/dark_souls_3/__init__.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 6886f7a87f2a..a6ed1273922b 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -1259,7 +1259,9 @@ def post_fill(self): # All DarkSouls3Items for this world that have been assigned anywhere, grouped by name full_items_by_name = defaultdict(list) for location in self.multiworld.get_filled_locations(): - if location.item.player == self.player and self._is_location_available(location): + if location.item.player == self.player and ( + location.player != self.player or self._is_location_available(location) + ): full_items_by_name[location.item.name].append(location.item) def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: @@ -1285,6 +1287,21 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: names = {item.name for item in item_order} + all_matching_locations = [ + loc + for locations in locations_by_sphere + for loc in locations + if loc.item.player == self.player + and not loc.locked + and loc.item.name in names + ] + + if len(item_order) != len(all_matching_locations): + raise Exception( + f"DS3 bug: there are {len(all_matching_locations)} locations that can " + + f"contain smoothed items, but only {len(item_order)} items to smooth." + ) + for i, all_locations in enumerate(locations_by_sphere): locations = [ loc for loc in all_locations From 24f7c682967d875b7cb3bc493c182f694bbedd94 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 5 Mar 2024 19:57:49 -0800 Subject: [PATCH 152/238] Add missing Leonhard items --- worlds/dark_souls_3/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index a6ed1273922b..4c00c8e9d9e9 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -779,6 +779,10 @@ def _add_npc_rules(self) -> None: ], "Pale Tongue") self._add_location_rule([ + "AL: Crescent Moon Sword - Leonhard drop", + "AL: Silver Mask - Leonhard drop", + "AL: Soul of Rosaria - Leonhard drop", + ] + [ f"FS: {item} - shop after killing Leonhard" for item in ["Leonhard's Garb", "Leonhard's Gauntlets", "Leonhard's Trousers"] ], "Black Eye Orb") From a7fb2842ef905bb529ebf18205cbbb9d39a78332 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 11 Mar 2024 19:15:47 -0400 Subject: [PATCH 153/238] Changing late basin to have a post-small-doll option --- worlds/dark_souls_3/Options.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index b7d8658ac0cd..4f6e2e826597 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -308,9 +308,17 @@ class EarlySmallLothricBanner(Choice): default = option_off -class LateBasinOfVowsOption(Toggle): - """This option makes it so the Basin of Vows is still randomized, but guarantees you that you wont have to venture into Lothric Castle to find your Small Lothric Banner to get out of High Wall of Lothric. So you may find Basin of Vows early, but you wont have to fight Dancer to find your Small Lothric Banner.""" +class LateBasinOfVowsOption(Choice): + """This option makes it so the Basin of Vows is still randomized, but you can choose the requirements to venture into Lothric Castle. + "Off": You may have to enter Lothric Castle and the areas beyond it before finding your Small Lothric Banner. + "After Small Lothric Banner": You are guaranteed to find your Small Lothric Banner before needing to enter Lothric Castle. + "After Small Doll": You are guaranteed to find your Small Lothric Banner and your Small Doll before needing to enter Lothric Castle.""" 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(Toggle): From 2935f86b01b6e4fc269b5749572ba4533b349da7 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 11 Mar 2024 19:24:42 -0400 Subject: [PATCH 154/238] Update basin option, add logic for some of Leonhard Hawkwood and Orbeck --- worlds/dark_souls_3/__init__.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index a6ed1273922b..2b4407f894be 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -477,6 +477,8 @@ def set_rules(self) -> None: # useful for smooth item placement. and self._has_any_scroll(state) )) + if self.options.late_basin_of_vows == "after_small_doll": + self._add_entrance_rule("Lothric Castle", "Small Doll") # DLC Access Rules Below if self.options.enable_dlc: @@ -532,6 +534,8 @@ def set_rules(self) -> None: # useful for smooth item placement. and self._has_any_scroll(state) )) + if self.options.late_basin_of_vows == "after_small_doll": + self._add_entrance_rule("Lothric Castle", "Small Doll") self._add_location_rule([ "LC: Grand Archives Key - by Grand Archives door, after PC and AL bosses", @@ -778,6 +782,12 @@ def _add_npc_rules(self) -> None: "CD: Black Eye Orb - Rosaria from Leonhard's quest", ], "Pale Tongue") + self._add_location_rule([ + "AL: Crescent Moon Sword - Leonhard drop", + "AL: Silver Mask - Leonhard drop", + "AL: Soul of Rosaria - Leonhard drop" + ], "Black Eye Orb") + self._add_location_rule([ f"FS: {item} - shop after killing Leonhard" for item in ["Leonhard's Garb", "Leonhard's Gauntlets", "Leonhard's Trousers"] @@ -785,6 +795,13 @@ def _add_npc_rules(self) -> None: ## Hawkwood + # Hawkwood only leaves after defating Abyss Watchers, Curse-Rotted Greatwood, Deacons of the Deep and Crystal Sage + # All of these are covered by the Farron Keep placement except for Abyss Watchers + self._add_location_rule( + "FS: Hawkwood's Shield - gravestone after Hawkwood leaves", + lambda state: self._can_get(state, "FK: Cinders of a Lord - Abyss Watcher") + ) + # After Hawkwood leaves and once you have the Torso Stone, you can fight him for dragon # stones. Andre will give Swordgrass as a hint as well self._add_location_rule([ @@ -916,6 +933,9 @@ def _add_npc_rules(self) -> None: and state.has("Sage's Scroll", self.player) )) + self._add_location_rule("FS: Pestilent Mist - Orbeck for any scroll", self._has_any_scroll) + self._add_location_rule("FS: Young Dragon Ring - Orbeck for one scroll and buying three spells", self._has_any_scroll) + # Make sure that the player can keep Orbeck around by giving him at least one scroll # before killing Abyss Watchers. self._add_location_rule("FK: Soul of the Blood of the Wolf", self._has_any_scroll) From 88ac89b19f080b70abad2c954212b39141847cd0 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 11 Mar 2024 19:27:36 -0400 Subject: [PATCH 155/238] Simplifying an option, fixing a copy-paste error --- worlds/dark_souls_3/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 2b4407f894be..9270f0c3f6f5 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -112,7 +112,7 @@ def generate_early(self): ) ): self.multiworld.early_items[self.player]['Storm Ruler'] = 1 - self.multiworld.worlds[self.player].options.local_items.value.add('Storm Ruler') + self.options.local_items.value.add('Storm Ruler') else: self.yhorm_location = default_yhorm_location @@ -535,7 +535,7 @@ def set_rules(self) -> None: and self._has_any_scroll(state) )) if self.options.late_basin_of_vows == "after_small_doll": - self._add_entrance_rule("Lothric Castle", "Small Doll") + self._add_location_rule("HWL: Soul of the Dancer", "Small Doll") self._add_location_rule([ "LC: Grand Archives Key - by Grand Archives door, after PC and AL bosses", From ca213e62c26b1cd1313bbc38b51cc16d0291d26d Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 11 Mar 2024 19:30:18 -0400 Subject: [PATCH 156/238] Removing trailing whitespace --- worlds/dark_souls_3/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 9270f0c3f6f5..0f3ec99c7bad 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -935,7 +935,7 @@ def _add_npc_rules(self) -> None: self._add_location_rule("FS: Pestilent Mist - Orbeck for any scroll", self._has_any_scroll) self._add_location_rule("FS: Young Dragon Ring - Orbeck for one scroll and buying three spells", self._has_any_scroll) - + # Make sure that the player can keep Orbeck around by giving him at least one scroll # before killing Abyss Watchers. self._add_location_rule("FK: Soul of the Blood of the Wolf", self._has_any_scroll) From 2d83b148c0c2a4138e205c9a2f8029cd6fbd49cc Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 16 Mar 2024 15:06:11 -0400 Subject: [PATCH 157/238] Changing lost items to go into start inventory --- worlds/dark_souls_3/__init__.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index a6ed1273922b..bba6d71f9d69 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -5,6 +5,7 @@ from typing import Callable, Dict, Set, List, Optional, TextIO, Union from BaseClasses import CollectionState, MultiWorld, Region, Item, Location, LocationProgressType, Entrance, Tutorial, ItemClassification +from logging import warning from Options import Toggle from worlds.AutoWorld import World, WebWorld @@ -327,7 +328,8 @@ def create_items(self): guaranteed_items = {"Path of the Dragon": 1} guaranteed_items.update(self.options.guaranteed_items) if len(removable_items) == 0 and num_required_extra_items == 0: - raise Exception("Can't add Path of the Dragon to the item pool") + warning(f"Couldn't add \"Path of the Dragon\" to the item pool for {self.multiworld.get_player_name(self.player)}. Adding it to starting inventory instead.") + self.multiworld.push_precollected(self.create_item("Path of the Dragon")) for item_name in guaranteed_items: # Break early just in case nothing is removable (if user is trying to guarantee more @@ -367,12 +369,21 @@ def create_items(self): injectable_items = [ item for item in item_dictionary.values() - if item.inject and (not item.is_dlc or self.options.enable_dlc) + if item.inject and (not item.is_dlc or self.options.enable_dlc) and item.classification != ItemClassification.progression ] + injectable_prog = ["Mendicant's Staff", "Seed of a Giant Tree", "Large Leather Shield"] + self.multiworld.random.shuffle(injectable_prog) number_to_inject = min(num_required_extra_items, len(injectable_items)) + for item in self.multiworld.random.sample(injectable_prog, k=min(3, number_to_inject)): + num_required_extra_items -= 1 + number_to_inject -= 1 + itempool.append(self.create_item(injectable_prog.pop())) for item in self.multiworld.random.sample(injectable_items, k=number_to_inject): num_required_extra_items -= 1 itempool.append(self.create_item(item.name)) + for item in injectable_prog: + self.multiworld.push_precollected(self.create_item(item)) + warning(f"Couldn't add \"{item}\" to the item pool for {self.multiworld.get_player_name(self.player)}. Adding it to starting inventory instead.") # Extra filler items for locations containing skip items itempool.extend(self.create_filler() for _ in range(num_required_extra_items)) From 3900c2e2c2be7f8b80408c36e9b9bc6cf1535f1b Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 16 Mar 2024 16:00:56 -0400 Subject: [PATCH 158/238] Revert Basin changes --- worlds/dark_souls_3/Options.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 4f6e2e826597..edf80797ee01 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -308,17 +308,8 @@ class EarlySmallLothricBanner(Choice): default = option_off -class LateBasinOfVowsOption(Choice): - """This option makes it so the Basin of Vows is still randomized, but you can choose the requirements to venture into Lothric Castle. - "Off": You may have to enter Lothric Castle and the areas beyond it before finding your Small Lothric Banner. - "After Small Lothric Banner": You are guaranteed to find your Small Lothric Banner before needing to enter Lothric Castle. - "After Small Doll": You are guaranteed to find your Small Lothric Banner and your Small Doll before needing to enter Lothric Castle.""" - 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 LateBasinOfVowsOption(Toggle): + """This option makes it so the Basin of Vows is still randomized, but guarantees you that you wont have to venture into Lothric Castle to find your Small Lothric Banner to get out of High Wall of Lothric. So you may find Basin of Vows early, but you wont have to fight Dancer to find your Small Lothric Banner.""" class LateDLCOption(Toggle): From ed9b5b46f38bded0049812706355ad82a4c3648b Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 16 Mar 2024 16:02:01 -0400 Subject: [PATCH 159/238] Oops --- worlds/dark_souls_3/Options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index edf80797ee01..d35e51fb1267 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -310,7 +310,7 @@ class EarlySmallLothricBanner(Choice): class LateBasinOfVowsOption(Toggle): """This option makes it so the Basin of Vows is still randomized, but guarantees you that you wont have to venture into Lothric Castle to find your Small Lothric Banner to get out of High Wall of Lothric. So you may find Basin of Vows early, but you wont have to fight Dancer to find your Small Lothric Banner.""" - + display_name = "Late Basin of Vows" class LateDLCOption(Toggle): """This option makes it so you are guaranteed to find your Small Doll without having to venture off into the DLC, effectively putting anything in the DLC in logic after finding both Contraption Key and Small Doll, and being able to get into Irithyll of the Boreal Valley.""" From 40d31748446e6f457f700994e9322a5a5f80b5b7 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 16 Mar 2024 16:02:18 -0400 Subject: [PATCH 160/238] Update Options.py --- worlds/dark_souls_3/Options.py | 1 + 1 file changed, 1 insertion(+) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index d35e51fb1267..b7d8658ac0cd 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -312,6 +312,7 @@ class LateBasinOfVowsOption(Toggle): """This option makes it so the Basin of Vows is still randomized, but guarantees you that you wont have to venture into Lothric Castle to find your Small Lothric Banner to get out of High Wall of Lothric. So you may find Basin of Vows early, but you wont have to fight Dancer to find your Small Lothric Banner.""" display_name = "Late Basin of Vows" + class LateDLCOption(Toggle): """This option makes it so you are guaranteed to find your Small Doll without having to venture off into the DLC, effectively putting anything in the DLC in logic after finding both Contraption Key and Small Doll, and being able to get into Irithyll of the Boreal Valley.""" display_name = "Late DLC" From d0bb26aa1addfee07d4366289aa524eb75c90424 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 16 Mar 2024 16:03:09 -0400 Subject: [PATCH 161/238] Reverting small doll changes --- worlds/dark_souls_3/__init__.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 0f3ec99c7bad..de23ef383f92 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -477,8 +477,6 @@ def set_rules(self) -> None: # useful for smooth item placement. and self._has_any_scroll(state) )) - if self.options.late_basin_of_vows == "after_small_doll": - self._add_entrance_rule("Lothric Castle", "Small Doll") # DLC Access Rules Below if self.options.enable_dlc: @@ -534,8 +532,6 @@ def set_rules(self) -> None: # useful for smooth item placement. and self._has_any_scroll(state) )) - if self.options.late_basin_of_vows == "after_small_doll": - self._add_location_rule("HWL: Soul of the Dancer", "Small Doll") self._add_location_rule([ "LC: Grand Archives Key - by Grand Archives door, after PC and AL bosses", From faab4e3939a305266f4972a133d70dceb5edf15b Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 16 Mar 2024 23:36:00 -0400 Subject: [PATCH 162/238] Farron Keep boss requirement logic --- worlds/dark_souls_3/__init__.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index de23ef383f92..ee3e02dd32f3 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -498,9 +498,13 @@ def set_rules(self) -> None: self._add_location_rule("ID: Bellowing Dragoncrest Ring - drop from B1 towards pit", "Jailbreaker's Key") self._add_location_rule("ID: Covetous Gold Serpent Ring - Siegward's cell", "Old Cell Key") - self._add_location_rule( + self._add_location_rule([ "UG: Hornet Ring - environs, right of main path after killing FK boss", - lambda state: self._can_get(state, "FK: Cinders of a Lord - Abyss Watcher"), + "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" + ], lambda state: self._can_get(state, "FK: Cinders of a Lord - Abyss Watcher") ) self._add_location_rule( "ID: Prisoner Chief's Ashes - B2 near, locked cell by stairs", @@ -793,9 +797,10 @@ def _add_npc_rules(self) -> None: # Hawkwood only leaves after defating Abyss Watchers, Curse-Rotted Greatwood, Deacons of the Deep and Crystal Sage # All of these are covered by the Farron Keep placement except for Abyss Watchers - self._add_location_rule( - "FS: Hawkwood's Shield - gravestone after Hawkwood leaves", - lambda state: self._can_get(state, "FK: Cinders of a Lord - Abyss Watcher") + self._add_location_rule([ + "FS: Hawkwood's Shield - gravestone after Hawkwood leaves", + "FS: Farron Ring - Hawkwood" + ], lambda state: self._can_get(state, "FK: Cinders of a Lord - Abyss Watcher") ) # After Hawkwood leaves and once you have the Torso Stone, you can fight him for dragon @@ -936,6 +941,10 @@ def _add_npc_rules(self) -> None: # before killing Abyss Watchers. self._add_location_rule("FK: Soul of the Blood of the Wolf", self._has_any_scroll) self._add_location_rule("FK: Cinders of a Lord - Abyss Watcher", self._has_any_scroll) + self._add_location_rule("FS: Undead Legion Helm - shop after killing FK boss", self._has_any_scroll) + self._add_location_rule("FS: Undead Legion Armor - shop after killing FK boss", self._has_any_scroll) + self._add_location_rule("FS: Undead Legion Gauntlet - shop after killing FK boss", self._has_any_scroll) + self._add_location_rule("FS: Undead Legion Leggings - shop after killing FK boss", self._has_any_scroll) self._add_entrance_rule("Catacombs of Carthus", self._has_any_scroll) # Not really necessary but ensures players can decide which way to go if self.options.enable_dlc: From 36726f38a603040d8c11e1f2d8ab338037b458ad Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 18 Mar 2024 16:27:19 -0400 Subject: [PATCH 163/238] Add Scroll for late_dlc --- worlds/dark_souls_3/__init__.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index ee3e02dd32f3..7465fdd89809 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -486,10 +486,8 @@ def set_rules(self) -> None: self._add_entrance_rule("Ringed City", "Small Envoy Banner") if self.options.late_dlc: - self._add_entrance_rule( - "Painted World of Ariandel (Before Contraption)", - "Small Doll" - ) + self._add_entrance_rule("Painted World of Ariandel (Before Contraption)", "Small Doll") + self._add_entrance_rule("Painted World of Ariandel (Before Contraption)", self._has_any_scroll) # Define the access rules to some specific locations if self._is_location_available("FS: Lift Chamber Key - Leonhard"): From 8a5bb24531b645df262cd5c21fc1704fa93f5547 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 18 Mar 2024 23:40:35 -0400 Subject: [PATCH 164/238] Fixing excluded unnecessary locations --- worlds/dark_souls_3/__init__.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 7465fdd89809..808b600a870e 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -286,12 +286,6 @@ def create_region(self, region_name, location_table) -> Region: new_region.locations.append(new_location) - # If we allow useful items in the excluded locations, we don't want Archipelago's fill - # algorithm to consider them excluded because it never allows useful items there. Instead, - # we manually add item rules to exclude important items. - if self.options.excluded_locations == "unnecessary": - self.options.exclude_locations.value.clear() - self.multiworld.regions.append(new_region) return new_region @@ -1051,6 +1045,9 @@ def _add_crow_rules(self) -> None: def _add_unnecessary_location_rules(self) -> None: """Adds rules for locations that can contain useful but not necessary items.""" + # If we allow useful items in the excluded locations, we don't want Archipelago's fill + # algorithm to consider them excluded because it never allows useful items there. Instead, + # we manually add item rules to exclude important items. unnecessary_locations = ( self.options.exclude_locations.value @@ -1071,6 +1068,9 @@ def _add_unnecessary_location_rules(self) -> None: lambda item: not item.advancement ) + if self.options.excluded_locations == "unnecessary": + self.options.exclude_locations.value.clear() + def _add_early_item_rules(self, randomized_items: Set[str]) -> None: """Adds rules to make sure specific items are available early.""" From 13bde30900dc6e412979d345eebea18aacda6748 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 19 Mar 2024 16:09:02 -0400 Subject: [PATCH 165/238] Adding Priestess Ring as being after UG boss --- worlds/dark_souls_3/Bosses.py | 1 + 1 file changed, 1 insertion(+) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index 20a2d165926b..15acf96e3d77 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -146,6 +146,7 @@ class DS3BossInfo: "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", From 2f9f6af3a9e342ef23bb6ea0f52397399e937309 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 19 Mar 2024 16:13:04 -0400 Subject: [PATCH 166/238] Removing missable from Corvian Titanite Slab --- worlds/dark_souls_3/Locations.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index e9a3ab9d2c95..bb96acb7504f 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -2646,8 +2646,7 @@ def __init__( DS3LocationData("PW2 -> DH", None), # Corvian Settler after killing Friede - DS3LocationData("PW1: Titanite Slab - Corvian", "Titanite Slab", missable = True, - npc = True), + DS3LocationData("PW1: Titanite Slab - Corvian", "Titanite Slab", npc = True), # Shrine Handmaid after killing Sister Friede DS3LocationData("FS: Ordained Hood - shop after killing PW2 boss", "Ordained Hood", From abce3c4c6d7bb6328276ae43eb63366fb0f5d6ee Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 19 Mar 2024 22:53:03 -0400 Subject: [PATCH 167/238] Adding KFF Yhorm boss locks --- worlds/dark_souls_3/Bosses.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index 15acf96e3d77..046539c8c510 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -238,7 +238,13 @@ class DS3BossInfo: "RC: Soul of Slave Knight Gael", "RC: Blood of the Dark Soul - end boss drop", }), - DS3BossInfo("Lords of Cinder", 4100800), + 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 = { From 015b9934db3e538629d28dbc3092726b5ea4b8ea Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 19 Mar 2024 23:07:10 -0400 Subject: [PATCH 168/238] Screams about Creighton --- worlds/dark_souls_3/__init__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 808b600a870e..756fbf21a698 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -832,6 +832,11 @@ def _add_npc_rules(self) -> None: self._add_location_rule([ "FS: Mail Breaker - Sirris for killing Creighton", "FS: Silvercat Ring - Sirris for killing Creighton", + "IBV: Creighton's Steel Mask - bridge after killing Creighton", + "IBV: Mirrah Chain Gloves - bridge after killing Creighton", + "IBV: Mirrah Chain Leggings - bridge after killing Creighton", + "IBV: Mirrah Chain Mail - bridge after killing Creighton", + "IBV: Dragonslayer's Axe - Creighton drop" ], lambda state: ( self._can_get(state, "US: Soul of the Rotted Greatwood") and state.has("Dreamchaser's Ashes", self.player) From e39813d1ab424c4756b9fbc0c81f80f8efb7d1ca Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Thu, 21 Mar 2024 08:21:13 -0400 Subject: [PATCH 169/238] Elite Knight Set isn't permanently missable --- worlds/dark_souls_3/Locations.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index bb96acb7504f..d8ed33cef27d 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1958,13 +1958,13 @@ def __init__( # Shrine Handmaid after killing Anri or completing their quest DS3LocationData("FS: Elite Knight Helm - shop after Anri quest", "Elite Knight Helm", - missable = True, npc = True, shop = True), + npc = True, shop = True), DS3LocationData("FS: Elite Knight Armor - shop after Anri quest", "Elite Knight Armor", - missable = True, npc = True, shop = True), + npc = True, shop = True), DS3LocationData("FS: Elite Knight Gauntlets - shop after Anri quest", - "Elite Knight Gauntlets", missable = True, npc = True, shop = True), + "Elite Knight Gauntlets", npc = True, shop = True), DS3LocationData("FS: Elite Knight Leggings - shop after Anri quest", - "Elite Knight Leggings", missable = True, npc = True, shop = True), + "Elite Knight Leggings", npc = True, shop = True), # Ringfinger Leonhard (quest or kill) DS3LocationData("AL: Crescent Moon Sword - Leonhard drop", "Crescent Moon Sword", From 460ebbc86fb4864a8ac92eb69b54e59f030172c9 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Thu, 21 Mar 2024 14:15:47 -0400 Subject: [PATCH 170/238] Adding Kiln requirement to KFF --- worlds/dark_souls_3/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 756fbf21a698..4f5027f50277 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -453,7 +453,8 @@ def set_rules(self) -> None: lambda state: state.has("Cinders of a Lord - Abyss Watcher", self.player) and state.has("Cinders of a Lord - Yhorm the Giant", self.player) and state.has("Cinders of a Lord - Aldrich", self.player) and - state.has("Cinders of a Lord - Lothric Prince", self.player)) + state.has("Cinders of a Lord - Lothric Prince", self.player) and + state.has("Transposing Kiln", self.player)) if self.options.late_basin_of_vows: self._add_entrance_rule("Lothric Castle", lambda state: ( From 2db5991f38b8623ecc6227e8c9d8c99f1b498b45 Mon Sep 17 00:00:00 2001 From: Exempt-Medic Date: Thu, 21 Mar 2024 15:39:19 -0400 Subject: [PATCH 171/238] fixing valid_keys and item groups --- worlds/dark_souls_3/Items.py | 8 +++++++- worlds/dark_souls_3/Options.py | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index a263994ea960..60660ef7ae74 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -179,7 +179,9 @@ def item_groups(self) -> List[str]: DS3ItemCategory.SOUL: "Small Souls", DS3ItemCategory.UPGRADE: "Upgrade", DS3ItemCategory.HEALING: "Healing", - }[default_item.category]) + }[self.category]) + + return names def counts(self, counts: List[int]) -> Generator["DS3ItemData", None, None]: """Returns an iterable of copies of this item with the given counts.""" @@ -1688,5 +1690,9 @@ def flatten(l): _all_items = _vanilla_items + _dlc_items +for item_data in _all_items: + for group_name in item_data.item_groups(): + item_name_groups[group_name].add(item_data.name) + filler_item_names = [item_data.name for item_data in _all_items if item_data.filler] item_dictionary = {item_data.name: item_data for item_data in _all_items} diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index b7d8658ac0cd..a882e7039120 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -346,7 +346,7 @@ class RandomEnemyPresetOption(Option[typing.Dict[str, typing.Any]], VerifyKeys): supports_weighting = False default = {} - valid_keys: ["Description", "RecommendFullRandomization", "RecommendNoEnemyProgression", + valid_keys = ["Description", "RecommendFullRandomization", "RecommendNoEnemyProgression", "OopsAll", "Boss", "Miniboss", "Basic", "BuffBasicEnemiesAsBosses", "DontRandomize", "RemoveSource", "Enemies"] From 64257fdbd01606f21a3c51a303d534cafe81b24b Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Thu, 21 Mar 2024 20:09:22 -0400 Subject: [PATCH 172/238] Fixing an option-checker --- worlds/dark_souls_3/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 4f5027f50277..4c980bc17d3a 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -108,7 +108,7 @@ def generate_early(self): self.yhorm_location.name == "Iudex Gundyr" or self.yhorm_location.name == "Vordt of the Boreal Valley" or ( self.yhorm_location.name == "Dancer of the Boreal Valley" and - not self.multiworld.late_basin_of_vows + not self.options.late_basin_of_vows ) ): self.multiworld.early_items[self.player]['Storm Ruler'] = 1 From 5175934e4328f36189e404363a73227b1193c64e Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Thu, 21 Mar 2024 23:44:42 -0400 Subject: [PATCH 173/238] Throwing unplaceable Storm Ruler into start inventory --- worlds/dark_souls_3/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index bba6d71f9d69..05e302ef1689 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -1226,7 +1226,8 @@ def _fill_local_item( if not candidate_locations: if not mandatory: return - raise Exception(f"No valid locations to place {name}") + warning(f"Couldn't place \"{name}\" in a valid location for {self.multiworld.get_player_name(self.player)}. Adding it to starting inventory instead.") + self.multiworld.push_precollected(self.create_item(name)) location = self.multiworld.random.choice(candidate_locations) location.place_locked_item(item) From b0fff0046ba09021fbbfeed7114404588a7a3923 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 25 Mar 2024 21:44:19 -0700 Subject: [PATCH 174/238] Update locations --- worlds/dark_souls_3/Locations.py | 2 +- worlds/dark_souls_3/docs/locations_en.md | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index e9a3ab9d2c95..90a2cff4263b 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1839,7 +1839,7 @@ def __init__( DS3LocationData("AL: Soul of a Weary Warrior - plaza, nearer", "Soul of a Weary Warrior"), DS3LocationData("AL: Ember - plaza, right side", "Ember"), DS3LocationData("AL: Ember - plaza, further", "Ember"), - DS3LocationData("AL: Large Titanite Shard - after light cathedral", + DS3LocationData("AL: Large Titanite Shard - balcony by dead giants", "Large Titanite Shard"), DS3LocationData("AL: Dark Stoneplate Ring - by dark stairs up from plaza", "Dark Stoneplate Ring"), diff --git a/worlds/dark_souls_3/docs/locations_en.md b/worlds/dark_souls_3/docs/locations_en.md index a733611bfc10..fd721f6cecf1 100644 --- a/worlds/dark_souls_3/docs/locations_en.md +++ b/worlds/dark_souls_3/docs/locations_en.md @@ -783,7 +783,7 @@ offline _Dark Souls III_ randomizer]. AL: Havel's Ring+2 - prison tower, raftersOn the rafters dropping down from Yorshka's Prison Tower to the Church of Yorshka AL: Human Dregs - water reservesIn the open in the Water Reserves AL: Large Soul of a Weary Warrior - left of dark cathedral entranceIn front of the Anor Londo cathedral, slightly to the left -AL: Large Titanite Shard - after light cathedralAfter the Pontiff fight, on the balcony to the right of the area with the Giant Slaves +AL: Large Titanite Shard - balcony by dead giantsAfter the Pontiff fight, on the balcony to the right of the area with the Giant Slaves AL: Large Titanite Shard - bottom of the furthest buttressAt the base of the rightmost flying buttress leading up to Anor Londo AL: Large Titanite Shard - bottom of the nearest buttressOn the tower leading back from Anor Londo to the shortcut to Irithyll, down the flying buttress closest to the Darkmoon Tomb entrance. AL: Large Titanite Shard - right after light cathedralAfter Pontiff's cathedral, hugging the wall to the right @@ -947,7 +947,6 @@ offline _Dark Souls III_ randomizer]. CD: Herald Helm - path, by fireGuarded by the Cathedral Evangelist after the Crystal Sage fight CD: Herald Trousers - path, by fireGuarded by the Cathedral Evangelist after the Crystal Sage fight CD: Heysel Pick - Heysel Corpse-Grub in Rosaria's Bed ChamberDropped by the Heysel Corpse-grub in Rosaria's Bed Chamber -CD: Hidden Blessing - PatchesSold by Patches after Greirat pillages Lothric Castle, telling Patches, and Patches returning CD: Homeward Bone - outside main hall south doorPast the cathedral doors guarded by the Giant Slave opposite to the Deacons fight CD: Horsehoof Ring - PatchesSold or dropped by Patches after he mentions Greirat CD: Large Soul of an Unknown Traveler - by white tree #1In the graveyard with the White Birch and Infested Corpses @@ -1190,7 +1189,7 @@ offline _Dark Souls III_ randomizer]. FS: Bountiful Light - Irina for Tome of LothricSold by Irina after giving her the Braille Divine Tome of Lothric FS: Bountiful Sunlight - Ludleth for RosariaBoss weapon for Rosaria, available after Leonhard is killed FS: Broken Straight Sword - gravestone after bossNear the grave after Iudex Gundyr fight -FS: Budding Green Blossom - shop killing Creighton and AL bossSold by Handmaid after receiving Silvercat Ring item lot from Sirris and defeating Aldrich +FS: Budding Green Blossom - shop after killing Creighton and AL bossSold by Handmaid after receiving Silvercat Ring item lot from Sirris and defeating Aldrich FS: Bursting Fireball - Cornyx for Great Swamp TomeSold by Cornyx after giving him the Great Swamp Pyromancy Tome FS: Caressing Tears - IrinaSold by Irina after recruiting her, or in her ashes FS: Carthus Beacon - Cornyx for Carthus TomeSold by Cornyx after giving him the Carthus Pyromancy Tome @@ -1295,7 +1294,7 @@ offline _Dark Souls III_ randomizer]. FS: Gundyr's Helm - shop after killing UG bossSold by Handmaid after defeating Champion Gundyr FS: Gundyr's Leggings - shop after killing UG bossSold by Handmaid after defeating Champion Gundyr FS: Havel's Ring - Ludleth for Stray DemonBoss weapon for Stray Demon -FS: Hawkwood's Shield - HawkwoodLeft by Hawkwood after defeating Abyss Watchers, Curse-Rotted Greatwood, Deacons of the Deep, and Crystal Sage +FS: Hawkwood's Shield - gravestone after Hawkwood leavesLeft by Hawkwood after defeating Abyss Watchers, Curse-Rotted Greatwood, Deacons of the Deep, and Crystal Sage FS: Hawkwood's Swordgrass - Andre after gesture in AP summitGiven by Andre after praying at the Dragon Altar in Archdragon Peak, after acquiring Twinkling Dragon Torso Stone. FS: Heal - IrinaSold by Irina after recruiting her, or in her ashes FS: Heal Aid - shopSold by Handmaid @@ -1304,6 +1303,7 @@ offline _Dark Souls III_ randomizer]. FS: Helm of Favor - shop after killing water reserve minibossesSold by Handmaid after killing Sulyvahn's Beasts in Water Reserve FS: Hidden Blessing - Dreamchaser's AshesSold by Greirat after pillaging Irithyll FS: Hidden Blessing - Greirat from IBVSold by Greirat after pillaging Irithyll +FS: Hidden Blessing - Patches after searching GASold by Handmaid after giving Dreamchaser's Ashes, saying where they were found FS: Hidden Body - Orbeck for Golden ScrollSold by Orbeck after giving him the Golden Scroll FS: Hidden Weapon - Orbeck for Golden ScrollSold by Orbeck after giving him the Golden Scroll FS: Hollowslayer Greatsword - Ludleth for GreatwoodBoss weapon for Curse-Rotted Greatwood @@ -1895,7 +1895,7 @@ offline _Dark Souls III_ randomizer]. PW2: Dung Pie - B1On the higher level of the Ariandel Chapel basement, on a wooden beam overlooking the lower level PW2: Earth Seeker - pit caveIn the area after Snowy Mountain Pass with the giant tree and Earth Seeker Millwood Knight, in the cave PW2: Ember - pass, central alcoveAfter the Snowy Mountain Pass bonfire, going left of the bell stuck in the ground, in a small alcove along the left wall -PW2: Floating Chaos - Dunnel dropDropped by Livid Pyromancer Dunnel when he invades while embered, whether boss is defeated or not. On the second level of Priscilla's building above the Gravetender fight, accessed from the lowest level of the Ariandel Chapel basement, past an illusory wall nearly straight left of the mechanism that moves the statue, then carefully dropping down tree branches. +PW2: Floating Chaos - NPC dropDropped by Livid Pyromancer Dunnel when he invades while embered, whether boss is defeated or not. On the second level of Priscilla's building above the Gravetender fight, accessed from the lowest level of the Ariandel Chapel basement, past an illusory wall nearly straight left of the mechanism that moves the statue, then carefully dropping down tree branches. PW2: Follower Shield - pass, far cliffsideAfter the Snowy Mountain Pass bonfire, going left of the bell stuck in the ground, on the cliff ledge past the open area, to the left PW2: Follower Torch - pass, far side pathOn the way to the Ariandel Chapel basement, where the first wolf enemies reappear, going all the way down the slope on the edge of the map. Guarded by a Follower PW2: Homeward Bone - rotundaOn the second level of Priscilla's building above the Gravetender fight. Can be accessed from the lowest level of the Ariandel Chapel basement, past an illusory wall nearly straight left of the mechanism that moves the statue, then carefully dropping down tree branches. @@ -2026,7 +2026,7 @@ offline _Dark Souls III_ randomizer]. RC: Twinkling Titanite - wall tower, jump from chandelierIn the cylindrical building before the long stairs with many Harald Legion Knights. Carefully drop down to the chandelier in the center, then jump to the second floor. The item is on a ledge. RC: Violet Wrappings - wall hidden, before bossIn the chapel before the Midir fight in the Ringed Inner Wall building. RC: White Birch Bow - swamp far left, up hillUp a hill at the edge of the muck pit with the Hollow Clerics. -RC: White Preacher Head - swamp near, ground near bonfire exitPast the balcony to the right of the Ringed City Streets bonfire room entrance. Can be accessed by dropping down straight after from the bonfire, then around to the left. +RC: White Preacher Head - swamp near, nook right of stairsPast the balcony to the right of the Ringed City Streets bonfire room entrance. Can be accessed by dropping down straight after from the bonfire, then around to the left. RC: Wolf Ring+3 - street gardens, NPC dropDropped by Alva (invades whether embered or not, or boss defeated or not), partway down the stairs from Shira, across the bridge, and past the Ringed Knight. RC: Young White Branch - swamp far left, by white tree #1Next to a small birch tree at the edge of the muck pit, between the hill with the aggressive Hollow Clerics and the building with the praying Hollow Clerics outside. RC: Young White Branch - swamp far left, by white tree #2Next to a small birch tree at the edge of the muck pit, between the hill with the aggressive Hollow Clerics and the building with the praying Hollow Clerics outside. From aca2dbec276ae18eab18859b8a94c66ca89804ee Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 25 Mar 2024 23:45:55 -0700 Subject: [PATCH 175/238] Refactor item injection --- worlds/dark_souls_3/Items.py | 5 ++- worlds/dark_souls_3/__init__.py | 72 +++++++++++++++++++++------------ 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 60660ef7ae74..f657bd2f4e3d 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -1292,9 +1292,10 @@ def flatten(l): DS3ItemData("Easterner's Ashes", 0x40000868, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), - # Fake item for controlling access to Archdragon Peak + # Fake item for controlling access to Archdragon Peak. The real drop isn't actually an item as + # such so we have to inject this because there's no slot for it to come from. DS3ItemData("Path of the Dragon", 0x40002346, DS3ItemCategory.UNIQUE, - classification = ItemClassification.progression), + inject = True, classification = ItemClassification.progression), # Spells DS3ItemData("Farron Dart", 0x40124F80, DS3ItemCategory.SPELL), diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 5e62d6234713..860552b08920 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -2,10 +2,10 @@ from collections.abc import Sequence from collections import defaultdict import json +from logging import warning from typing import Callable, Dict, Set, List, Optional, TextIO, Union from BaseClasses import CollectionState, MultiWorld, Region, Item, Location, LocationProgressType, Entrance, Tutorial, ItemClassification -from logging import warning from Options import Toggle from worlds.AutoWorld import World, WebWorld @@ -319,12 +319,6 @@ def create_items(self): # A list of items we can replace removable_items = [item for item in itempool if item.classification == ItemClassification.filler] - guaranteed_items = {"Path of the Dragon": 1} - guaranteed_items.update(self.options.guaranteed_items) - if len(removable_items) == 0 and num_required_extra_items == 0: - warning(f"Couldn't add \"Path of the Dragon\" to the item pool for {self.multiworld.get_player_name(self.player)}. Adding it to starting inventory instead.") - self.multiworld.push_precollected(self.create_item("Path of the Dragon")) - for item_name in guaranteed_items: # Break early just in case nothing is removable (if user is trying to guarantee more # items than the pool can hold, for example) @@ -360,24 +354,9 @@ def create_items(self): itempool.append(self.create_item(item_name)) - injectable_items = [ - item for item - in item_dictionary.values() - if item.inject and (not item.is_dlc or self.options.enable_dlc) and item.classification != ItemClassification.progression - ] - injectable_prog = ["Mendicant's Staff", "Seed of a Giant Tree", "Large Leather Shield"] - self.multiworld.random.shuffle(injectable_prog) - number_to_inject = min(num_required_extra_items, len(injectable_items)) - for item in self.multiworld.random.sample(injectable_prog, k=min(3, number_to_inject)): - num_required_extra_items -= 1 - number_to_inject -= 1 - itempool.append(self.create_item(injectable_prog.pop())) - for item in self.multiworld.random.sample(injectable_items, k=number_to_inject): - num_required_extra_items -= 1 - itempool.append(self.create_item(item.name)) - for item in injectable_prog: - self.multiworld.push_precollected(self.create_item(item)) - warning(f"Couldn't add \"{item}\" to the item pool for {self.multiworld.get_player_name(self.player)}. Adding it to starting inventory instead.") + injectables = self._create_injectable_items(num_required_extra_items) + num_required_extra_items -= len(injectables) + itempool.extend(injectables) # Extra filler items for locations containing skip items itempool.extend(self.create_filler() for _ in range(num_required_extra_items)) @@ -386,6 +365,49 @@ def create_items(self): self.multiworld.itempool += itempool + def _create_injectable_items(self, num_required_extra_items: int) -> List[Item]: + """Returns a list of items to inject into the multiworld instead of skipped items. + + If there isn't enough room to inject all the necessary progression items + that are in missable locations by default, this adds them to the + player's starting inventoy. + """ + + all_injectable_items = [ + item for item + in item_dictionary.values() + if item.inject and (not item.is_dlc or self.options.enable_dlc) + ] + injectable_progression = [ + item for item in all_injectable_items + if item.classification == ItemClassification.progression + ] + injectable_non_progression = [ + item for item in all_injectable_items + if item.classification != ItemClassification.progression + ] + + number_to_inject = min(num_required_extra_items, len(all_injectable_items)) + items = ( + self.multiworld.random.sample(injectable_progression, k=min(3, number_to_inject)) + + self.multiworld.random.sample( + injectable_non_progression, + k=max(0, number_to_inject - len(injectable_progression)) + ) + ) + + if number_to_inject < len(injectable_progression): + for item in injectable_progression: + if item in items: continue + self.multiworld.push_precollected(self.create_item(item)) + warning( + f"Couldn't add \"{item}\" to the item pool for " + + f"{self.multiworld.get_player_name(self.player)}. Adding it to the starting " + + f"inventory instead." + ) + + return [self.create_item(item) for item in items] + def create_item(self, item: Union[str, DS3ItemData]) -> Item: data = item if isinstance(item, DS3ItemData) else item_dictionary[item] From 93ef22f87970bd703ecdf28eddbd32e8378522f8 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 26 Mar 2024 00:51:19 -0700 Subject: [PATCH 176/238] Update setup doc --- worlds/dark_souls_3/docs/setup_en.md | 62 ++++++++++++++-------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/worlds/dark_souls_3/docs/setup_en.md b/worlds/dark_souls_3/docs/setup_en.md index 7a3ca4e9bd86..17840fdb2857 100644 --- a/worlds/dark_souls_3/docs/setup_en.md +++ b/worlds/dark_souls_3/docs/setup_en.md @@ -7,49 +7,49 @@ ## Optional Software -- [Dark Souls III Maptracker Pack](https://github.com/Br00ty/DS3_AP_Maptracker/releases/latest), for use with [Poptracker](https://github.com/black-sliver/PopTracker/releases) +- Map tracker not yet updated for 3.0.0 -## General Concept +## Setting Up - -**This mod can ban you permanently from the FromSoftware servers if used online.** - -The Dark Souls III AP Client is a dinput8.dll triggered when launching Dark Souls III. This .dll file will launch a command -prompt where you can read information about your run and write any command to interact with the Archipelago server. +First, download the client from the link above. It doesn't need to go into any particular directory; +it'll automatically locate _Dark Souls III_ in your Steam in your Steam installation folder. -This client has only been tested with the Official Steam version of the game at version 1.15. It does not matter which DLCs are installed. However, you will have to downpatch your Dark Souls III installation from current patch. +Version 3.0.0 of the randomizer _only_ supports the latest version of _Dark Souls III_, 1.15.2. This +is the latest version, so you don't need to do any downpatching! However, if you've already +downpatched your game to use an older version of the randomizer, you'll need to reinstall the latest +version before using this version. -## Downpatching Dark Souls III +### One-Time Setup -To downpatch DS3 for use with Archipelago, use the following instructions from the speedsouls wiki database. +Before you first connect to a multiworld, you need to generate the local data files for your world's +randomized item and (optionally) enemy locations. You only need to do this once per multiworld. -1. Launch Steam (in online mode). -2. Press the Windows Key + R. This will open the Run window. -3. Open the Steam console by typing the following string: steam://open/console , Steam should now open in Console Mode. -4. Insert the string of the depot you wish to download. For the AP supported v1.15, you will want to use: download_depot 374320 374321 4471176929659548333. -5. Steam will now download the depot. Note: There is no progress bar of the download in Steam, but it is still downloading in the background. -6. Turn off auto-updates in Steam by right-clicking Dark Souls III in your library > Properties > Updates > set "Automatic Updates" to "Only update this game when I launch it" (or change the value for AutoUpdateBehavior to 1 in "\Steam\steamapps\appmanifest_374320.acf"). -7. Back up your existing game folder in "\Steam\steamapps\common\DARK SOULS III". -8. Return back to Steam console. Once the download is complete, it should say so along with the temporary local directory in which the depot has been stored. This is usually something like "\Steam\steamapps\content\app_XXXXXX\depot_XXXXXX". Back up this game folder as well. -9. Delete your existing game folder in "\Steam\steamapps\common\DARK SOULS III", then replace it with your game folder in "\Steam\steamapps\content\app_XXXXXX\depot_XXXXXX". -10. Back up and delete your save file "DS30000.sl2" in AppData. AppData is hidden by default. To locate it, press Windows Key + R, type %appdata% and hit enter or: open File Explorer > View > Hidden Items and follow "C:\Users\your username\AppData\Roaming\DarkSoulsIII\numbers". -11. If you did all these steps correctly, you should be able to confirm your game version in the upper left corner after launching Dark Souls III. +1. Before you first connect to a multiworld, run `randomizer\DS3Randomizer.exe`. +2. Put in your Archipelago room address (usually something like `archipelago.gg:12345`), your player + name (also known as your "slot name"), and your password if you have one. -## Installing the Archipelago mod +3. Click "Load" and wait a minute or two. -Get the dinput8.dll from the [Dark Souls III AP Client](https://github.com/Marechal-L/Dark-Souls-III-Archipelago-client/releases) and -add it at the root folder of your game (e.g. "SteamLibrary\steamapps\common\DARK SOULS III\Game") +### Running and Connecting the Game -## Joining a MultiWorld Game +To run _Dark Souls III_ in Archipelago mode: -1. Run Steam in offline mode, both to avoid being banned and to prevent Steam from updating the game files -2. Launch Dark Souls III -3. Type in "/connect {SERVER_IP}:{SERVER_PORT} {SLOT_NAME}" in the "Windows Command Prompt" that opened -4. Once connected, create a new game, choose a class and wait for the others before starting -5. You can quit and launch at anytime during a game +1. Start Steam. **Do not run in offline mode.** The mod will make sure you don't connect to the + DS3 servers, and running Steam in offline mode will make certain scripted invaders fail to spawn. -## Where do I get a config file? +2. Run `launchmod_darksouls3.bat`. This will start _Dark Souls III_ as well as a command prompt that + you can use to interact with the Archipelago server. + +3. Type `/connect {SERVER_IP}:{SERVER_PORT} {SLOT_NAME}` into the command prompt, with the + appropriate values filled in. + +4. Start playing as normal. An "Archipelago connected" message will appear onscreen once you have + control of your character and the connection is established. + +## Frequently Asked Questions + +### Where do I get a config file? The [Player Settings](/games/Dark%20Souls%20III/player-settings) page on the website allows you to configure your personal settings and export them into a config file. From 6bd510782da0f457d7644dcbaae00a582c3ff4b7 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 26 Mar 2024 15:48:13 -0400 Subject: [PATCH 177/238] Small fixes --- worlds/dark_souls_3/__init__.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 860552b08920..ea9fd46907c7 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -389,7 +389,10 @@ def _create_injectable_items(self, num_required_extra_items: int) -> List[Item]: number_to_inject = min(num_required_extra_items, len(all_injectable_items)) items = ( - self.multiworld.random.sample(injectable_progression, k=min(3, number_to_inject)) + + self.multiworld.random.sample( + injectable_progression, + k=min(len(injectable_progression), number_to_inject) + ) + self.multiworld.random.sample( injectable_non_progression, k=max(0, number_to_inject - len(injectable_progression)) @@ -428,7 +431,7 @@ def create_item(self, item: Union[str, DS3ItemData]) -> Item: and data.category.upgrade_level # Because we require the Pyromancy Flame to be available early, don't upgrade it so it # doesn't get shuffled around by weapon smoothing. - and not data.name == "Pyromancy FLame" + and not data.name == "Pyromancy Flame" ): # if the user made an error and set a min higher than the max we default to the max max_5 = self.options.max_levels_in_5 @@ -516,7 +519,7 @@ def set_rules(self) -> None: if self.options.late_dlc: self._add_entrance_rule( "Painted World of Ariandel (Before Contraption)", - lambda state: state.has("Small Doll") and self._has_any_scroll(state)) + lambda state: state.has("Small Doll", self.player) and self._has_any_scroll(state)) # Define the access rules to some specific locations if self._is_location_available("FS: Lift Chamber Key - Leonhard"): From 207fe45cf90faf4187bb13e58b50af8541cb2709 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 30 Mar 2024 15:20:50 -0700 Subject: [PATCH 178/238] Fix another location name --- worlds/dark_souls_3/Locations.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 36fd268f40fe..8232b51d9296 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -2123,8 +2123,7 @@ def __init__( "Soul of a Weary Warrior"), DS3LocationData("CKG: Dark Gem - under lone stairway", "Dark Gem"), DS3LocationData("CKG: Titanite Scale - shortcut", "Titanite Scale"), - DS3LocationData("CKG: Human Pine Resin - by lone stairway bottom", - "Human Pine Resin x2"), + DS3LocationData("CKG: Human Pine Resin - pool by lift", "Human Pine Resin x2"), DS3LocationData("CKG: Titanite Chunk - right of shortcut lift bottom", "Titanite Chunk"), DS3LocationData("CKG: Ring of Sacrifice - under balcony", "Ring of Sacrifice"), DS3LocationData("CKG: Wood Grain Ring+1 - by first elevator bottom", "Wood Grain Ring+1", From d1b1a7cdaf4e5e32839a5c1ead0638679ace5fc6 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 30 Mar 2024 15:21:06 -0700 Subject: [PATCH 179/238] Fix injection calculation --- worlds/dark_souls_3/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 860552b08920..1c1609f7b3b3 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -389,8 +389,11 @@ def _create_injectable_items(self, num_required_extra_items: int) -> List[Item]: number_to_inject = min(num_required_extra_items, len(all_injectable_items)) items = ( - self.multiworld.random.sample(injectable_progression, k=min(3, number_to_inject)) + self.multiworld.random.sample( + injectable_progression, + k=min(len(injectable_progression), number_to_inject) + ) + + self.multiworld.random.sample( injectable_non_progression, k=max(0, number_to_inject - len(injectable_progression)) ) From 35c32b21263af1bde3b940e3b18229131bdc0815 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 30 Mar 2024 15:30:25 -0700 Subject: [PATCH 180/238] Inject guaranteed items along with progression items --- worlds/dark_souls_3/__init__.py | 58 +++++++++------------------------ 1 file changed, 15 insertions(+), 43 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 1c1609f7b3b3..1c2d92b97004 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -319,41 +319,6 @@ def create_items(self): # A list of items we can replace removable_items = [item for item in itempool if item.classification == ItemClassification.filler] - for item_name in guaranteed_items: - # Break early just in case nothing is removable (if user is trying to guarantee more - # items than the pool can hold, for example) - if len(removable_items) == 0 and num_required_extra_items == 0: - break - - num_existing_copies = len([item for item in itempool if item.name == item_name]) - for _ in range(guaranteed_items[item_name]): - if num_existing_copies > 0: - num_existing_copies -= 1 - continue - - if num_required_extra_items > 0: - # We can just add them instead of using filler later - num_required_extra_items -= 1 - else: - if len(removable_items) == 0: - break - - # Try to construct a list of items with the same category that can be removed - # If none exist, just remove something at random - removable_shortlist = [ - item for item - in removable_items - if item_dictionary[item.name].category == item_dictionary[item_name].category - ] - if len(removable_shortlist) == 0: - removable_shortlist = removable_items - - removed_item = self.multiworld.random.choice(removable_shortlist) - removable_items.remove(removed_item) # To avoid trying to replace the same item twice - itempool.remove(removed_item) - - itempool.append(self.create_item(item_name)) - injectables = self._create_injectable_items(num_required_extra_items) num_required_extra_items -= len(injectables) itempool.extend(injectables) @@ -378,11 +343,15 @@ def _create_injectable_items(self, num_required_extra_items: int) -> List[Item]: in item_dictionary.values() if item.inject and (not item.is_dlc or self.options.enable_dlc) ] - injectable_progression = [ + injectable_mandatory = [ item for item in all_injectable_items if item.classification == ItemClassification.progression + ] + [ + item + for (item, count) in self.options.guaranteed_items.items() + for _ in range(0, count) ] - injectable_non_progression = [ + injectable_optional = [ item for item in all_injectable_items if item.classification != ItemClassification.progression ] @@ -390,17 +359,20 @@ def _create_injectable_items(self, num_required_extra_items: int) -> List[Item]: number_to_inject = min(num_required_extra_items, len(all_injectable_items)) items = ( self.multiworld.random.sample( - injectable_progression, - k=min(len(injectable_progression), number_to_inject) + injectable_mandatory, + k=min(len(injectable_mandatory), number_to_inject) ) + self.multiworld.random.sample( - injectable_non_progression, - k=max(0, number_to_inject - len(injectable_progression)) + injectable_optional, + k=max(0, number_to_inject - len(injectable_mandatory)) ) ) - if number_to_inject < len(injectable_progression): - for item in injectable_progression: + if number_to_inject < len(injectable_mandatory): + # It's worth considering the possibility of _removing_ unimportant + # items from the pool to inject these instead rather than just + # making them part of the starting health back + for item in injectable_mandatory: if item in items: continue self.multiworld.push_precollected(self.create_item(item)) warning( From 23deb3f650918663c7fd9859fa357b7bf3133d54 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 30 Mar 2024 16:07:09 -0700 Subject: [PATCH 181/238] 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. --- worlds/dark_souls_3/Bosses.py | 36 +++++++--------- worlds/dark_souls_3/Locations.py | 5 --- worlds/dark_souls_3/__init__.py | 72 +++++++++++++++++++++++--------- 3 files changed, 66 insertions(+), 47 deletions(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index ce1b036a6901..7aedf685afcc 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -7,7 +7,7 @@ @dataclass class DS3BossInfo: - """The set of locations and regions a given boss location blocks access to.""" + """The set of locations a given boss location blocks access to.""" name: str """The boss's name.""" @@ -25,9 +25,6 @@ class DS3BossInfo: aren't randomized. """ - region: Optional[str] = None - """The name the region that can't be accessed until the boss is dead, if one exists.""" - locations: Optional[str] = field(default_factory=set) """Additional individual locations that can't be accessed until the boss is dead.""" @@ -35,10 +32,10 @@ class DS3BossInfo: # Note: the offline 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, region = "Firelink Shrine", + 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, - region = "Undead Settlement", locations = {"HWL: Soul of Boreal Valley Vordt"}), + locations = {"HWL: Soul of Boreal Valley Vordt"}), DS3BossInfo("Curse-rotted Greatwood", 3100800, locations = { "US: Soul of the Rotted Greatwood", "US: Transposing Kiln - boss drop", @@ -55,7 +52,7 @@ class DS3BossInfo: "FS: Sunless Gauntlets - shop, Sirris quest, kill GA boss", "FS: Sunless Leggings - shop, Sirris quest, kill GA boss", }), - DS3BossInfo("Crystal Sage", 3300850, region = "Cathedral of the Deep", locations = { + 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", @@ -65,8 +62,7 @@ class DS3BossInfo: "CD: Small Doll - boss drop", "FS: Hawkwood's Shield - gravestone after Hawkwood leaves", }), - DS3BossInfo("Abyss Watchers", 3300801, before_storm_ruler = True, - region = "Catacombs of Carthus", locations = { + 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", @@ -76,14 +72,13 @@ class DS3BossInfo: "FS: Farron Ring - Hawkwood", "FS: Hawkwood's Shield - gravestone after Hawkwood leaves", }), - DS3BossInfo("High Lord Wolnir", 3800800, before_storm_ruler = True, - region = "Irithyll of the Boreal Valley", locations = { + 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, region = "Anor Londo", locations = { + DS3BossInfo("Pontiff Sulyvahn", 3700850, locations = { "IBV: Soul of Pontiff Sulyvahn", }), DS3BossInfo("Old Demon King", 3800830, locations = { @@ -101,14 +96,14 @@ class DS3BossInfo: "FS: Leonhard's Gauntlets - shop after killing Leonhard", "FS: Leonhard's Trousers - shop after killing Leonhard", }), - DS3BossInfo("Dancer of the Boreal Valley", 3000899, region = "Lothric Castle", locations = { + 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, region = "Grand Archives", locations = { + 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", @@ -116,7 +111,7 @@ class DS3BossInfo: "FS: Morne's Leggings - shop after killing Eygon or LC boss", "LC: Titanite Chunk - down stairs after boss", }), - DS3BossInfo("Consumed King Oceiros", 3000830, region = "Untended Graves", locations = { + DS3BossInfo("Consumed King Oceiros", 3000830, locations = { "CKG: Soul of Consumed Oceiros", "CKG: Titanite Scale - tomb, chest #1", "CKG: Titanite Scale - tomb, chest #2", @@ -147,10 +142,7 @@ class DS3BossInfo: "UG: Wolf Knight Gauntlets - shop after killing FK boss", "UG: Wolf Knight Leggings - shop after killing FK boss", }), - # This is a white lie, you can get to a bunch of items in AP before you beat the Wyvern, but - # this saves us from having to split the entire region in two just to mark which specific items - # are before and after. - DS3BossInfo("Ancient Wyvern", 3200800, region = "Archdragon Peak"), + 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", @@ -191,7 +183,7 @@ class DS3BossInfo: }), DS3BossInfo("Champion's Gravetender and Gravetender Greatwolf", 4500860, dlc = True, locations = {"PW1: Valorheart - boss drop"}), - DS3BossInfo("Sister Friede", 4500801, dlc = True, region = "Dreg Heap", locations = { + DS3BossInfo("Sister Friede", 4500801, dlc = True, locations = { "PW2: Soul of Sister Friede", "PW2: Titanite Slab - boss drop", "PW1: Titanite Slab - Corvian", @@ -199,14 +191,14 @@ class DS3BossInfo: "FS: Ordained Dress - shop after killing PW2 boss", "FS: Ordained Trousers - shop after killing PW2 boss", }), - DS3BossInfo("Blackflame Friede", 4500800, dlc = True, region = "Dreg Heap", locations = { + 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, region = "Ringed City", locations = { + DS3BossInfo("Demon Prince", 5000801, dlc = True, locations = { "DH: Soul of the Demon Prince", "DH: Small Envoy Banner - boss drop", }), diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 8232b51d9296..8a561ac85487 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1000,7 +1000,6 @@ def __init__( "Young Dragon Ring", missable = True, npc = True), DS3LocationData("FS: Slumbering Dragoncrest Ring - Orbeck for buying four specific spells", "Slumbering Dragoncrest Ring", missable = True, npc = True), - DS3LocationData("RS -> CD", None), DS3LocationData("RS -> FK", None), # Shrine Handmaid after killing exiles @@ -1300,7 +1299,6 @@ def __init__( DS3LocationData("US: Hawk Ring - Giant Archer", "Hawk Ring", drop = True, npc = True), # Giant archer (kill or quest), here because you need to # collect all seven White Branch locations to get it peacefully - DS3LocationData("FK -> CC", None), # Hawkwood after killing Abyss Watchers DS3LocationData("FS: Farron Ring - Hawkwood", "Farron Ring", @@ -1616,7 +1614,6 @@ def __init__( "Large Titanite Shard"), DS3LocationData("IBV: Siegbräu - Siegward", "Siegbräu", missable = True, npc = True), DS3LocationData("IBV: Emit Force - Siegward", "Emit Force", missable = True, npc = True), - DS3LocationData("IBV -> AL", None), DS3LocationData("IBV -> ID", None), # After winning both Londor Pale Shade invasions @@ -2135,7 +2132,6 @@ def __init__( DS3LocationData("CKG: Magic Stoneplate Ring - mob drop before boss", "Magic Stoneplate Ring", drop = True, hidden = True), # Guaranteed drop from a normal-looking Cathedral Knight - DS3LocationData("CKG -> UG", None), # After Oceiros's boss room, only once the Drakeblood summon in AP has been killed DS3LocationData("CKG: Drakeblood Helm - tomb, after killing AP mausoleum NPC", @@ -2642,7 +2638,6 @@ def __init__( lizard = True), DS3LocationData("PW2: Twinkling Titanite - B3, lizard #2", "Twinkling Titanite", lizard = True), - DS3LocationData("PW2 -> DH", None), # Corvian Settler after killing Friede DS3LocationData("PW1: Titanite Slab - Corvian", "Titanite Slab", npc = True), diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 1c2d92b97004..fc23d23b8d99 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -444,25 +444,49 @@ def set_rules(self) -> None: self._add_early_item_rules(randomized_items) self._add_entrance_rule("Firelink Shrine Bell Tower", "Tower Key") - self._add_entrance_rule("Undead Settlement", "Small Lothric Banner") + self._add_entrance_rule("Undead Settlement", lambda state: ( + state.has("Small Lothric Banner", self.player) + and self._can_get(state, "HWL: Soul of Boreal Valley Vordt") + )) self._add_entrance_rule("Road of Sacrifices", "US -> RS") - self._add_entrance_rule("Cathedral of the Deep", "RS -> CD") + self._add_entrance_rule( + "Cathedral of the Deep", + lambda state: self._can_get(state, "RS: Soul of a Crystal Sage") + ) self._add_entrance_rule("Farron Keep", "RS -> FK") - self._add_entrance_rule("Catacombs of Carthus", "FK -> CC") + self._add_entrance_rule( + "Catacombs of Carthus", + lambda state: self._can_get(state, "FK: Soul of the Blood of the Wolf") + ) self._add_entrance_rule("Irithyll Dungeon", "IBV -> ID") - self._add_entrance_rule("Lothric Castle", "Basin of Vows") - self._add_entrance_rule("Untended Graves", "CKG -> UG") - self._add_entrance_rule("Irithyll of the Boreal Valley", "Small Doll") - self._add_entrance_rule("Anor Londo", "IBV -> AL") - self._add_entrance_rule("Archdragon Peak", "Path of the Dragon") - self._add_entrance_rule("Grand Archives", "Grand Archives Key") self._add_entrance_rule( - "Kiln of the First Flame", - lambda state: state.has("Cinders of a Lord - Abyss Watcher", self.player) and - state.has("Cinders of a Lord - Yhorm the Giant", self.player) and - state.has("Cinders of a Lord - Aldrich", self.player) and - state.has("Cinders of a Lord - Lothric Prince", self.player) and - state.has("Transposing Kiln", self.player)) + "Lothric Castle", + lambda state: self._can_get(state, "HWL: Soul of the Dancer") + ) + self._add_entrance_rule( + "Untended Graves", + lambda state: self._can_get(state, "CKG: Soul of Consumed Oceiros") + ) + self._add_entrance_rule("Irithyll of the Boreal Valley", lambda state: ( + state.has("Small Doll", self.player) + and self._can_get(state, "CC: Soul of High Lord Wolnir") + )) + self._add_entrance_rule( + "Anor Londo", + lambda state: self._can_get(state, "IBV: Soul of Pontiff Sulyvahn") + ) + self._add_entrance_rule("Archdragon Peak", "Path of the Dragon") + self._add_entrance_rule("Grand Archives", lambda state: ( + state.has("Grand Archives Key", self.player) + and self._can_get(state, "LC: Soul of Dragonslayer Armour") + )) + self._add_entrance_rule("Kiln of the First Flame", lambda state: ( + state.has("Cinders of a Lord - Abyss Watcher", self.player) + and state.has("Cinders of a Lord - Yhorm the Giant", self.player) + and state.has("Cinders of a Lord - Aldrich", self.player) + and state.has("Cinders of a Lord - Lothric Prince", self.player) + and state.has("Transposing Kiln", self.player) + )) if self.options.late_basin_of_vows: self._add_entrance_rule("Lothric Castle", lambda state: ( @@ -485,8 +509,14 @@ def set_rules(self) -> None: if self.options.enable_dlc: self._add_entrance_rule("Painted World of Ariandel (Before Contraption)", "CD -> PW1") self._add_entrance_rule("Painted World of Ariandel (After Contraption)", "Contraption Key") - self._add_entrance_rule("Dreg Heap", "PW2 -> DH") - self._add_entrance_rule("Ringed City", "Small Envoy Banner") + self._add_entrance_rule( + "Dreg Heap", + lambda state: self._can_get(state, "PW2: Soul of Sister Friede") + ) + self._add_entrance_rule("Ringed City", lambda state: ( + state.has("Small Envoy Banner", self.player) + and self._can_get(state, "DH: Soul of the Demon Prince") + )) if self.options.late_dlc: self._add_entrance_rule( @@ -599,8 +629,11 @@ def set_rules(self) -> None: ) # Make sure the Storm Ruler is available BEFORE Yhorm the Giant - if self.yhorm_location.region: - self._add_entrance_rule(self.yhorm_location.region, "Storm Ruler") + if self.yhorm_location.name == "Ancient Wyvern": + # This is a white lie, you can get to a bunch of items in AP before you beat the Wyvern, + # but this saves us from having to split the entire region in two just to mark which + # specific items are before and after. + self._add_entrance_rule("Archdragon Peak", "Storm Ruler") for location in self.yhorm_location.locations: self._add_location_rule(location, "Storm Ruler") @@ -950,7 +983,6 @@ def _add_npc_rules(self) -> None: "UG: Wolf Knight Leggings - shop after killing FK boss", ], self._has_any_scroll) - self._add_entrance_rule("Catacombs of Carthus", self._has_any_scroll) # Not really necessary but ensures players can decide which way to go if self.options.enable_dlc: self._add_entrance_rule( From 0528713864c8fb031bea6394e26f4ea19d278173 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 30 Mar 2024 16:09:50 -0700 Subject: [PATCH 182/238] Make sure Sirris's quest can be completed before Pontiff --- worlds/dark_souls_3/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index fc23d23b8d99..3eda4c56f015 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -868,7 +868,9 @@ def _add_npc_rules(self) -> None: "IBV: Mirrah Chain Gloves - bridge after killing Creighton", "IBV: Mirrah Chain Leggings - bridge after killing Creighton", "IBV: Mirrah Chain Mail - bridge after killing Creighton", - "IBV: Dragonslayer's Axe - Creighton drop" + "IBV: Dragonslayer's Axe - Creighton drop", + # Killing Pontiff without progressing Sirris's quest will break it. + "IBV: Soul of Pontiff Sulyvahn" ], lambda state: ( self._can_get(state, "US: Soul of the Rotted Greatwood") and state.has("Dreamchaser's Ashes", self.player) From 9c28ef7c59b53fd4c83c9fe322e38fb2c099c786 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 30 Mar 2024 21:01:41 -0400 Subject: [PATCH 183/238] Removing unused list --- worlds/dark_souls_3/__init__.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index ccfb7f76fa29..1d1c29bae066 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -316,9 +316,6 @@ def create_items(self): item_set.add(location.data.default_item_name) itempool.append(self.create_item(location.data.default_item_name)) - # A list of items we can replace - removable_items = [item for item in itempool if item.classification == ItemClassification.filler] - injectables = self._create_injectable_items(num_required_extra_items) num_required_extra_items -= len(injectables) itempool.extend(injectables) From 356b9ebfdb4d2044e953ac88ce9bd5dae9332227 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 30 Mar 2024 21:07:59 -0400 Subject: [PATCH 184/238] Changing dict to list --- worlds/dark_souls_3/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 1d1c29bae066..24cb72254bb4 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -1249,7 +1249,7 @@ def pre_fill(self) -> None: # Fill this manually so that, if very few slots are available in Cemetery of Ash, this # doesn't get locked out by bad rolls on the next two fills. if self.yhorm_location.name == 'Iudex Gundyr': - self._fill_local_item("Storm Ruler", {"Cemetery of Ash"}, + self._fill_local_item("Storm Ruler", ["Cemetery of Ash"], lambda location: location.name != "CA: Coiled Sword - boss drop", mandatory = True) From 57537ddabcf6b6985a2fe93dcb87311b13f04778 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 30 Mar 2024 21:35:45 -0400 Subject: [PATCH 185/238] Removing unused test --- worlds/dark_souls_3/test/TestDarkSouls3.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/worlds/dark_souls_3/test/TestDarkSouls3.py b/worlds/dark_souls_3/test/TestDarkSouls3.py index 93424886fef4..e590cd732b41 100644 --- a/worlds/dark_souls_3/test/TestDarkSouls3.py +++ b/worlds/dark_souls_3/test/TestDarkSouls3.py @@ -20,12 +20,6 @@ def testLocationsUnique(self): self.assertNotIn(location.name, names) names.add(location.name) - def testBossRegions(self): - all_regions = set(location_tables) - for boss in all_bosses: - if boss.region: - self.assertIn(boss.region, all_regions) - def testBossLocations(self): all_locations = {location.name for locations in location_tables.values() for location in locations} for boss in all_bosses: From 40941594c6ea2c51b37c75e43041c4201eccf1ed Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 1 Apr 2024 00:04:13 -0400 Subject: [PATCH 186/238] Update __init__.py --- worlds/dark_souls_3/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 24cb72254bb4..be8ca319cbba 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -373,7 +373,7 @@ def _create_injectable_items(self, num_required_extra_items: int) -> List[Item]: if item in items: continue self.multiworld.push_precollected(self.create_item(item)) warning( - f"Couldn't add \"{item}\" to the item pool for " + + f"Couldn't add \"{item.name}\" to the item pool for " + f"{self.multiworld.get_player_name(self.player)}. Adding it to the starting " + f"inventory instead." ) From 7261d9a00e2f5484a1e98908a62d0bffdad44734 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 2 Apr 2024 21:03:09 -0400 Subject: [PATCH 187/238] self.multiworld.random -> self.random (#9) --- worlds/dark_souls_3/__init__.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index be8ca319cbba..ecf8db8447ab 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -101,7 +101,7 @@ def generate_early(self): # Randomize Yhorm manually so that we know where to place the Storm Ruler. if self.options.randomize_enemies: - self.yhorm_location = self.multiworld.random.choice( + self.yhorm_location = self.random.choice( [boss for boss in all_bosses if self._allow_boss_for_yhorm(boss)]) # If Yhorm is early, make sure the Storm Ruler is easily available to avoid BK @@ -355,11 +355,11 @@ def _create_injectable_items(self, num_required_extra_items: int) -> List[Item]: number_to_inject = min(num_required_extra_items, len(all_injectable_items)) items = ( - self.multiworld.random.sample( + self.random.sample( injectable_mandatory, k=min(len(injectable_mandatory), number_to_inject) ) - + self.multiworld.random.sample( + + self.random.sample( injectable_optional, k=max(0, number_to_inject - len(injectable_mandatory)) ) @@ -409,22 +409,22 @@ def create_item(self, item: Union[str, DS3ItemData]) -> Item: min_10 = min(self.options.min_levels_in_10, max_10) weapon_level_percentage = self.options.randomize_weapon_level_percentage - if self.multiworld.random.randint(0, 99) < weapon_level_percentage: + if self.random.randint(0, 99) < weapon_level_percentage: if data.category.upgrade_level == 5: - data = data.upgrade(self.multiworld.random.randint(min_5, max_5)) + data = data.upgrade(self.random.randint(min_5, max_5)) elif data.category.upgrade_level == 10: - data = data.upgrade(self.multiworld.random.randint(min_10, max_10)) + data = data.upgrade(self.random.randint(min_10, max_10)) if self.options.randomize_infusion and data.category.is_infusible: infusion_percentage = self.options.randomize_infusion_percentage - if self.multiworld.random.randint(0, 99) < infusion_percentage: - data = data.infuse(self.multiworld.random.choice(list(Infusion))) + if self.random.randint(0, 99) < infusion_percentage: + data = data.infuse(self.random.choice(list(Infusion))) return DarkSouls3Item(self.player, data, classification=classification) def get_filler_item_name(self) -> str: - return self.multiworld.random.choice(filler_item_names) + return self.random.choice(filler_item_names) def set_rules(self) -> None: @@ -1308,7 +1308,7 @@ def _fill_local_item( warning(f"Couldn't place \"{name}\" in a valid location for {self.multiworld.get_player_name(self.player)}. Adding it to starting inventory instead.") self.multiworld.push_precollected(self.create_item(name)) - location = self.multiworld.random.choice(candidate_locations) + location = self.random.choice(candidate_locations) location.place_locked_item(item) self.multiworld.itempool.remove(item) @@ -1441,7 +1441,7 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: def _shuffle(self, seq: Sequence) -> List: """Returns a shuffled copy of a sequence.""" copy = list(seq) - self.multiworld.random.shuffle(copy) + self.random.shuffle(copy) return copy From f246c699c8f89b5134fbd7dea23cdc18004174be Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 2 Apr 2024 15:25:48 -0700 Subject: [PATCH 188/238] Fix some miscellaneous location issues --- worlds/dark_souls_3/Bosses.py | 20 ++++++++++++++++++++ worlds/dark_souls_3/Locations.py | 25 ++++++++++++++----------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index 7aedf685afcc..50c003380d66 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -220,10 +220,30 @@ class DS3BossInfo: 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", diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 8a561ac85487..93aaa42cf5a2 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1530,7 +1530,7 @@ def __init__( DS3LocationData("IBV: Ring of the Sun's First Born - fall from in front of cathedral", "Ring of the Sun's First Born", hidden = True), # Hidden fall - DS3LocationData("IBV: Large Soul of a Nameless Soldier - stairs to plaza", + DS3LocationData("IBV: Large Soul of a Nameless Soldier - path to plaza", "Large Soul of a Nameless Soldier"), DS3LocationData("IBV: Large Titanite Shard - plaza, balcony overlooking ascent", "Large Titanite Shard"), @@ -1589,7 +1589,7 @@ def __init__( DS3LocationData("IBV: Divine Blessing - great hall, chest", "Divine Blessing"), DS3LocationData("IBV: Smough's Great Hammer - great hall, chest", "Smough's Great Hammer"), - DS3LocationData("IBV: Yorshka's Spear - descent, dark room rafers chest", "Yorshka's Spear"), + DS3LocationData("IBV: Yorshka's Spear - descent, dark room rafters chest", "Yorshka's Spear"), DS3LocationData("IBV: Leo Ring - great hall, chest", "Leo Ring"), DS3LocationData("IBV: Dorhys' Gnawing - Dorhys drop", "Dorhys' Gnawing", hidden = True), # Behind illusory wall @@ -1652,7 +1652,7 @@ def __init__( npc = True), DS3LocationData("ID: Murakumo - Alva drop", "Murakumo", missable = True, hostile_npc = True), - DS3LocationData("ID: Large Titanite Shard - after bonfire, second cell on right", + DS3LocationData("ID: Large Titanite Shard - after bonfire, second cell on left", "Large Titanite Shard"), DS3LocationData("ID: Fading Soul - B1 near, main hall", "Fading Soul"), DS3LocationData("ID: Large Soul of a Nameless Soldier - B2, hall by stairs", @@ -2218,7 +2218,7 @@ def __init__( "Witch's Locks", hidden = True), # Switch in darkened room DS3LocationData("GA: Titanite Slab - 1F, after pulling 2F switch", "Titanite Slab", hidden = True), - DS3LocationData("GA: Titanite Scale - 5F, chest by exit", "Titanite Scale x3"), + DS3LocationData("GA: Titanite Scale - 4F, chest by exit", "Titanite Scale x3"), DS3LocationData("GA: Soul Stream - 3F, behind illusory wall", "Soul Stream", hidden = True), # Behind illusory wall DS3LocationData("GA: Scholar Ring - 2F, between late and early", "Scholar Ring"), @@ -2266,15 +2266,15 @@ def __init__( # Shrine Handmaid after killing NPCs DS3LocationData("FS: Faraam Helm - shop after killing GA NPC", "Faraam Helm", hidden = True, hostile_npc = True, shop = True), - DS3LocationData("GA: Faraam Armor - shop after killing GA NPC", "Faraam Armor", + DS3LocationData("FS: Faraam Armor - shop after killing GA NPC", "Faraam Armor", hidden = True, hostile_npc = True, shop = True), - DS3LocationData("GA: Faraam Gauntlets - shop after killing GA NPC", "Faraam Gauntlets", + DS3LocationData("FS: Faraam Gauntlets - shop after killing GA NPC", "Faraam Gauntlets", hidden = True, hostile_npc = True, shop = True), - DS3LocationData("GA: Faraam Boots - shop after killing GA NPC", "Faraam Boots", + DS3LocationData("FS: Faraam Boots - shop after killing GA NPC", "Faraam Boots", hidden = True, hostile_npc = True, shop = True), - DS3LocationData("GA: Black Hand Hat - shop after killing GA NPC", "Black Hand Hat", + DS3LocationData("FS: Black Hand Hat - shop after killing GA NPC", "Black Hand Hat", hidden = True, hostile_npc = True, shop = True), - DS3LocationData("GA: Black Hand Armor - shop after killing GA NPC", "Black Hand Armor", + DS3LocationData("FS: Black Hand Armor - shop after killing GA NPC", "Black Hand Armor", hidden = True, hostile_npc = True, shop = True), # Shrine Handmaid after killing Lothric, Younger Prince @@ -2754,9 +2754,12 @@ def __init__( DS3LocationData("RC: Crucifix of the Mad King - ashes, NPC drop", "Crucifix of the Mad King", hostile_npc = True), # Shira drop DS3LocationData("RC: Ledo's Great Hammer - streets high, opposite building, NPC drop", - "Ledo's Great Hammer", hostile_npc = True), # Silver Knight Ledo drop + "Ledo's Great Hammer", hostile_npc = True, + missable = True), # Silver Knight Ledo drop, doesn't invade once Halflight + # is defeated DS3LocationData("RC: Wolf Ring+3 - street gardens, NPC drop", "Wolf Ring+3", - hostile_npc = True), # Alva drop + hostile_npc = True, + missable = True), # Alva drop, doesn't invade once Halflight is defeated DS3LocationData("RC: Blindfold Mask - grave, NPC drop", "Blindfold Mask", hostile_npc = True), # Moaning Knight drop DS3LocationData("RC: Titanite Scale - wall top, behind spawn", "Titanite Scale"), # wrong From 3c4a23719b149b7a0b93e633ba57d1ec36d3e29f Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 2 Apr 2024 18:44:48 -0700 Subject: [PATCH 189/238] Rewrite the DS3 intro page/FAQ --- worlds/dark_souls_3/docs/en_Dark Souls III.md | 123 +++++++++++++++--- worlds/dark_souls_3/docs/locations_en.md | 2 + 2 files changed, 109 insertions(+), 16 deletions(-) diff --git a/worlds/dark_souls_3/docs/en_Dark Souls III.md b/worlds/dark_souls_3/docs/en_Dark Souls III.md index 2acee3d28cc7..c88a56740856 100644 --- a/worlds/dark_souls_3/docs/en_Dark Souls III.md +++ b/worlds/dark_souls_3/docs/en_Dark Souls III.md @@ -1,33 +1,124 @@ # Dark Souls III +## What do I need to do to randomize DS3? + +See full instructions on [the setup page]. + +[the setup page]: /tutorial/Dark%20Souls%20III/setup/en + ## Where is the settings page? -The [player settings page for this game](../player-settings) contains all the options you need to configure and export a -config file. +The [player settings page for this game] contains all the options you need to +configure and export a config file. + +[player settings page for this game]: ../player-settings ## What does randomization do to this game? -Items that can be picked up from static corpses, taken from chests, or earned from defeating enemies or NPCs can be -randomized. Common pickups like titanite shards or firebombs can be randomized as "progressive" items. That is, the -location "Titanite Shard #5" is the fifth titanite shard you pick up, no matter where it was from. This is also what -happens when you randomize Estus Shards and Undead Bone Shards. +1. All item locations are randomized, including those in the overworld, in + shops, and dropped by enemies. Most locations can contain games from other + worlds, and any items from your world can appear in other players' worlds. + +2. By default, all enemies and bosses are randomized. This can be disabled by + setting "Randomize Enemies" to false. + +3. By default, the starting equipment for each class is randomized. This can be + disabled by setting "Randomize Starting Loadout" to false. + +4. By setting the "Randomize Weapon Level" or "Randomize Infusion" options, you + can randomize whether the weapons you find will be upgraded or infused. + +## What's the goal? + +Your goal is to find the four "Cinders of a Lord" items randomized into the +multiworld and defeat the boss in the Kiln of the First Flame. + +## Do I have to check every item in every area? + +Dark Souls III has about 1500 item locations, which is a lot of checks for a +single run! But you don't necessarily need to check all of them. Locations that +you can potentially miss, such as rewards for failable quests or soul +transposition items, will _never_ have items required for any game to progress. +The following types of locations are also guaranteed not to contain progression +items by default: + +* **Hidden:** Locations that are particularly difficult to find, such as behind + illusory walls, down hidden drops, and so on. Does not include large locations + like Untended Graves or Archdragon Peak. + +* **Small Crystal Lizards:** Drops from small crystal lizards. + +* **Upgrade:** Locations that contain upgrade items in vanilla, including + titanite, gems, and Shriving Stones. + +* **Small Souls:** Locations that contain soul items in vanilla, not including + boss souls. + +* **Miscellaneous:** Locations that contain generic stackable items in vanilla, + such as arrows, firebombs, buffs, and so on. + +You can customize which locations are guaranteed not to contain progression +items by setting the `exclude_locations` field in your YAML to the [location +groups] you want to omit. For example, this is the default setting but without +"Hidden" so that hidden locations can contain progression items: + +[location groups]: /tutorial/Dark%20Souls%20III/locations/en#location-groups + +```json +Dark Souls III: + exclude_locations: + - Small Crystal Lizards + - Upgrade + - Small Souls + - Miscellaneous +``` + +This allows _all_ non-missable locations to have progression items, if you're in +for the long haul: + +```json +Dark Souls III: + exclude_locations: [] +``` + +## What if I don't want to do the whole game? -It's also possible to randomize the upgrade level of weapons and shields as well as their infusions (if they can have -one). Additionally, there are settings that can make the randomized experience more convenient or more interesting, such as -removing weapon requirements or auto-equipping whatever equipment you most recently received. +If you want a shorter DS3 randomizer experience, you can exclude entire regions +from containing progression items. The items and enemies from those regions will +still be included in the randomization pool, but none of them will be mandatory. +For example, the following configuration just requires you to play the game +through Irithyll of the Boreal Valley: -The goal is to find the four "Cinders of a Lord" items randomized into the multiworld and defeat the Soul of Cinder. +```json +Dark Souls III: + # Enable the DLC so it's included in the randomization pool + enable_dlc: true -## What Dark Souls III items can appear in other players' worlds? + exclude_locations: + # Exclude late-game and DLC regions + - Lothric Castle + - Consumed King's Garden + - Untended Graves + - Grand Archives + - Archdragon Peak + - Painted World of Ariandel + - Dreg Heap + - Ringed City -Practically anything can be found in other worlds including pieces of armor, upgraded weapons, key items, consumables, -spells, upgrade materials, etc... + # Default exclusions + - Hidden + - Small Crystal Lizards + - Upgrade + - Small Souls + - Miscellaneous +``` ## Where can I learn more about Dark Souls III locations? -Location names have to pack a lot of information into very little space. To better understand them, -check out the [location guide], which explains all the names used in locations and provides more -detailed descriptions for each individual location. +Location names have to pack a lot of information into very little space. To +better understand them, check out the [location guide], which explains all the +names used in locations and provides more detailed descriptions for each +individual location. [location guide]: /tutorial/Dark%20Souls%20III/locations/en diff --git a/worlds/dark_souls_3/docs/locations_en.md b/worlds/dark_souls_3/docs/locations_en.md index fd721f6cecf1..00c3e864bea4 100644 --- a/worlds/dark_souls_3/docs/locations_en.md +++ b/worlds/dark_souls_3/docs/locations_en.md @@ -53,6 +53,8 @@ at once: * **Friendly NPC Rewards:** Items given by friendly NPCs as part of their quests or from non-violent interaction. +* **Small Crystal Lizards:** Drops from small crystal lizards. + * **Upgrade:** Locations that contain upgrade items in vanilla, including titanite, gems, and Shriving Stones. From 980daff1f7b4e938dadba12101730d18a8641dcc Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 2 Apr 2024 21:48:06 -0400 Subject: [PATCH 190/238] Removing modifying the itempool after fill (#7) Co-authored-by: Natalie Weizenbaum --- worlds/dark_souls_3/__init__.py | 152 +++++++++++++++++--------------- 1 file changed, 83 insertions(+), 69 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index ecf8db8447ab..1247c0364609 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -79,7 +79,7 @@ def __init__(self, multiworld: MultiWorld, player: int): self.locked_locations = [] self.main_path_locations = [] self.enabled_location_categories = set() - + self.all_excluded_locations = set() def generate_early(self): if not self.options.enable_weapon_locations: @@ -99,6 +99,8 @@ def generate_early(self): if not self.options.enable_health_upgrade_locations: self._exclude_location_group("Healing") + self.all_excluded_locations.update(self.options.exclude_locations.value) + # Randomize Yhorm manually so that we know where to place the Storm Ruler. if self.options.randomize_enemies: self.yhorm_location = self.random.choice( @@ -326,6 +328,8 @@ def create_items(self): # Add items to itempool self.multiworld.itempool += itempool + self._fill_local_items() + def _create_injectable_items(self, num_required_extra_items: int) -> List[Item]: """Returns a list of items to inject into the multiworld instead of skipped items. @@ -423,6 +427,83 @@ def create_item(self, item: Union[str, DS3ItemData]) -> Item: return DarkSouls3Item(self.player, data, classification=classification) + def _fill_local_items(self) -> None: + """Removes certain items from the item pool and manually places them in the local world. + + We can't do this in pre_fill because the itempool may not be modified after create_items. + """ + # If Yhorm is at Iudex Gundyr, Storm Ruler must be randomized, so it can always be moved. + # Fill this manually so that, if very few slots are available in Cemetery of Ash, this + # doesn't get locked out by bad rolls on the next two fills. + if self.yhorm_location.name == 'Iudex Gundyr': + self._fill_local_item("Storm Ruler", ["Cemetery of Ash"], + lambda location: location.name != "CA: Coiled Sword - boss drop") + + # If the Coiled Sword is vanilla, it is early enough and doesn't need to be placed. + # Don't place this in the multiworld because it's necessary almost immediately, and don't + # mark it as a blocker for HWL because having a miniscule Sphere 1 screws with progression balancing. + if self._is_location_available("CA: Coiled Sword - boss drop"): + self._fill_local_item("Coiled Sword", ["Cemetery of Ash", "Firelink Shrine"]) + + # If the HWL Raw Gem is vanilla, it is early enough and doesn't need to be removed. If + # upgrade smoothing is enabled, make sure one raw gem is available early for SL1 players + if ( + self._is_location_available("HWL: Raw Gem - fort roof, lizard") + and self.options.smooth_upgrade_items + ): + self._fill_local_item("Raw Gem", [ + "Cemetery of Ash", + "Firelink Shrine", + "High Wall of Lothric" + ]) + + + def _fill_local_item( + self, name: str, + regions: List[str], + additional_condition: Optional[Callable[[DarkSouls3Location], bool]] = None, + ) -> None: + """Chooses a valid location for the item with the given name and places it there. + + This always chooses a local location among the given regions. If additional_condition is + passed, only locations meeting that condition will be considered. + + If the item could not be placed, it will be added to starting inventory. + """ + item = next( + ( + item for item in self.multiworld.itempool + if item.player == self.player and item.name == name + ), + None + ) + if not item: return + + candidate_locations = [ + location for location in ( + self.multiworld.get_location(location.name, self.player) + for region in regions + for location in location_tables[region] + if self._is_location_available(location) + and not location.missable + and not location.conditional + and (not additional_condition or additional_condition(location)) + ) + if not location.item and location.progress_type != LocationProgressType.EXCLUDED + and location.item_rule(item) + ] + + if not candidate_locations: + warning(f"Couldn't place \"{name}\" in a valid location for {self.multiworld.get_player_name(self.player)}. Adding it to starting inventory instead.") + self.multiworld.push_precollected(self.create_item(name)) + return + + location = self.random.choice(candidate_locations) + location.place_locked_item(item) + self.multiworld.itempool.remove(item) + + + def get_filler_item_name(self) -> str: return self.random.choice(filler_item_names) @@ -1229,7 +1310,7 @@ def _is_location_available( and (not data.ngp or self.options.enable_ngp) and not ( self.options.excluded_locations == "unrandomized" - and data.name in self.options.exclude_locations + and data.name in self.all_excluded_locations ) and not ( self.options.missable_locations == "unrandomized" @@ -1245,73 +1326,6 @@ def write_spoiler(self, spoiler_handle: TextIO) -> None: f"{self.multiworld.get_player_name(self.player)}'s world\n") - def pre_fill(self) -> None: - # Fill this manually so that, if very few slots are available in Cemetery of Ash, this - # doesn't get locked out by bad rolls on the next two fills. - if self.yhorm_location.name == 'Iudex Gundyr': - self._fill_local_item("Storm Ruler", ["Cemetery of Ash"], - lambda location: location.name != "CA: Coiled Sword - boss drop", - mandatory = True) - - # Don't place this in the multiworld because it's necessary almost immediately, and don't - # mark it as a blocker for HWL because having a miniscule Sphere 1 screws with progression - # balancing. - self._fill_local_item("Coiled Sword", ["Cemetery of Ash", "Firelink Shrine"]) - - # If upgrade smoothing is enabled, make sure one raw gem is available early for SL1 players - if self.options.smooth_upgrade_items: - self._fill_local_item("Raw Gem", [ - "Cemetery of Ash", - "Firelink Shrine", - "High Wall of Lothric" - ]) - - - def _fill_local_item( - self, name: str, - regions: List[str], - additional_condition: Optional[Callable[[DarkSouls3Location], bool]] = None, - mandatory = False, - ) -> None: - """Chooses a valid location for the item with the given name and places it there. - - This always chooses a local location among the given regions. If additional_condition is - passed, only locations meeting that condition will be considered. - - If mandatory is True, this will throw an error if the item could not be filled in. - """ - item = next( - ( - item for item in self.multiworld.itempool - if item.player == self.player and item.name == name - ), - None - ) - if not item: return - - candidate_locations = [ - location for location in ( - self.multiworld.get_location(location.name, self.player) - for region in regions - for location in location_tables[region] - if self._is_location_available(location) - and not location.missable - and not location.conditional - and (not additional_condition or additional_condition(location)) - ) - if not location.item and location.progress_type != LocationProgressType.EXCLUDED - and location.item_rule(item) - ] - - if not candidate_locations: - if not mandatory: return - warning(f"Couldn't place \"{name}\" in a valid location for {self.multiworld.get_player_name(self.player)}. Adding it to starting inventory instead.") - self.multiworld.push_precollected(self.create_item(name)) - - location = self.random.choice(candidate_locations) - location.place_locked_item(item) - self.multiworld.itempool.remove(item) - def post_fill(self): """If item smoothing is enabled, rearrange items so they scale up smoothly through the run. From 5bb391b8f3eed79049ec5437ab07533c8197eb55 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 2 Apr 2024 21:48:27 -0400 Subject: [PATCH 191/238] Small fixes to the setup guide (#10) Small fixes, adding an example for connecting --- worlds/dark_souls_3/docs/setup_en.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/worlds/dark_souls_3/docs/setup_en.md b/worlds/dark_souls_3/docs/setup_en.md index 17840fdb2857..ed90289a8baf 100644 --- a/worlds/dark_souls_3/docs/setup_en.md +++ b/worlds/dark_souls_3/docs/setup_en.md @@ -12,7 +12,7 @@ ## Setting Up First, download the client from the link above. It doesn't need to go into any particular directory; -it'll automatically locate _Dark Souls III_ in your Steam in your Steam installation folder. +it'll automatically locate _Dark Souls III_ in your Steam installation folder. Version 3.0.0 of the randomizer _only_ supports the latest version of _Dark Souls III_, 1.15.2. This is the latest version, so you don't need to do any downpatching! However, if you've already @@ -42,7 +42,7 @@ To run _Dark Souls III_ in Archipelago mode: you can use to interact with the Archipelago server. 3. Type `/connect {SERVER_IP}:{SERVER_PORT} {SLOT_NAME}` into the command prompt, with the - appropriate values filled in. + appropriate values filled in. For example: `/connect archipelago.gg:24242 PlayerName`. 4. Start playing as normal. An "Archipelago connected" message will appear onscreen once you have control of your character and the connection is established. @@ -51,5 +51,5 @@ To run _Dark Souls III_ in Archipelago mode: ### Where do I get a config file? -The [Player Settings](/games/Dark%20Souls%20III/player-settings) page on the website allows you to -configure your personal settings and export them into a config file. +The [Player Options](/games/Dark%20Souls%20III/player-options) page on the website allows you to +configure your personal options and export them into a config file. From 6c79f7da3ca87299e6780e7f271d1d32b4f01167 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 2 Apr 2024 21:50:06 -0400 Subject: [PATCH 192/238] Expanded Late Basin of Vows and Late DLC (#6) --- worlds/dark_souls_3/Options.py | 24 ++++++++++++++++++++---- worlds/dark_souls_3/__init__.py | 9 +++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index a882e7039120..6afaceba2942 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -308,14 +308,30 @@ class EarlySmallLothricBanner(Choice): default = option_off -class LateBasinOfVowsOption(Toggle): - """This option makes it so the Basin of Vows is still randomized, but guarantees you that you wont have to venture into Lothric Castle to find your Small Lothric Banner to get out of High Wall of Lothric. So you may find Basin of Vows early, but you wont have to fight Dancer to find your Small Lothric Banner.""" +class LateBasinOfVowsOption(Choice): + """This option makes it so the Basin of Vows is still randomized, but you can choose the requirements to venture into Lothric Castle. + "Off": You may have to enter Lothric Castle and the areas beyond it before finding your Small Lothric Banner. + "After Small Lothric Banner": You are guaranteed to find your Small Lothric Banner before needing to enter Lothric Castle. + "After Small Doll": You are guaranteed to find your Small Lothric Banner and your Small Doll before needing to enter Lothric Castle.""" 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(Toggle): - """This option makes it so you are guaranteed to find your Small Doll without having to venture off into the DLC, effectively putting anything in the DLC in logic after finding both Contraption Key and Small Doll, and being able to get into Irithyll of the Boreal Valley.""" +class LateDLCOption(Choice): + """This option makes it so the Small Doll is still randomized, but you can choose the requirements to venture into Painted World of Ariandel. + "Off": You may have to enter Ariandel and the areas beyond it before finding your Small Doll. + "After Small Doll": You are guaranteed to find your Small Doll before needing to enter Ariandel. + "After Basin": You are guaranteed to find your Small Doll and your Basin of Vows before needing to enter Ariandel.""" 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): diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 1247c0364609..e69862d175d6 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -583,6 +583,9 @@ def set_rules(self) -> None: and self._has_any_scroll(state) )) + if self.options.late_basin_of_vows > 1: # After Small Doll + self._add_entrance_rule("Lothric Castle", "Small Doll") + # DLC Access Rules Below if self.options.enable_dlc: self._add_entrance_rule("Painted World of Ariandel (Before Contraption)", "CD -> PW1") @@ -601,6 +604,9 @@ def set_rules(self) -> None: "Painted World of Ariandel (Before Contraption)", lambda state: state.has("Small Doll", self.player) and self._has_any_scroll(state)) + if self.options.late_dlc > 1: # After Basin + self._add_entrance_rule("Painted World of Ariandel (Before Contraption)", "Basin of Vows") + # Define the access rules to some specific locations if self._is_location_available("FS: Lift Chamber Key - Leonhard"): self._add_location_rule("HWL: Red Eye Orb - wall tower, miniboss", @@ -646,6 +652,9 @@ def set_rules(self) -> None: and self._has_any_scroll(state) )) + if self.options.late_basin_of_vows > 1: # After Small Doll + self._add_location_rule("HWL: Soul of the Dancer", "Small Doll") + self._add_location_rule([ "LC: Grand Archives Key - by Grand Archives door, after PC and AL bosses", "LC: Gotthard Twinswords - by Grand Archives door, after PC and AL bosses" From 9131e913a4c4d9d876ac16e081a9c12063c90233 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 2 Apr 2024 18:58:19 -0700 Subject: [PATCH 193/238] Add proper requirements for CD: Black Eye Orb --- worlds/dark_souls_3/__init__.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index e69862d175d6..9e3a62aa0c70 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -903,6 +903,17 @@ def _add_npc_rules(self) -> None: "CD: Black Eye Orb - Rosaria from Leonhard's quest", ], "Pale Tongue") + self._add_location_rule([ + "CD: Black Eye Orb - Rosaria from Leonhard's quest", + ], lambda state: ( + # The Black Eye Orb location won't spawn until you kill the HWL miniboss and resting at + # the Profaned Capital bonfire. + self._can_get(state, "HWL: Red Eye Orb - wall tower, miniboss") + and self._can_go_to(state, "Profaned Capital") + )) + + # Perhaps counterintuitively, you CAN fight Leonhard before you access the location that + # would normally give you the Black Eye Orb. self._add_location_rule([ "AL: Crescent Moon Sword - Leonhard drop", "AL: Silver Mask - Leonhard drop", From 7a1ac5f0712a66f0823295fb68b95548dc2f2e1a Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 7 Apr 2024 18:47:09 -0700 Subject: [PATCH 194/238] Fix Aldrich's name --- worlds/dark_souls_3/Bosses.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index 50c003380d66..25ab6dcbaf54 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -84,7 +84,7 @@ class DS3BossInfo: DS3BossInfo("Old Demon King", 3800830, locations = { "SL: Soul of the Old Demon King", }), - DS3BossInfo("Aldrich, Devourer of Men", 3700800, locations = { + 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", From 153c46ac6969729bdf60a841f8fde56cbdd045a2 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 10 Apr 2024 17:49:35 -0700 Subject: [PATCH 195/238] Document the differences with the 2.x.x branch --- worlds/dark_souls_3/docs/en_Dark Souls III.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/worlds/dark_souls_3/docs/en_Dark Souls III.md b/worlds/dark_souls_3/docs/en_Dark Souls III.md index ebd85bf27845..e51c0b74ddae 100644 --- a/worlds/dark_souls_3/docs/en_Dark Souls III.md +++ b/worlds/dark_souls_3/docs/en_Dark Souls III.md @@ -131,3 +131,68 @@ individual location. Check out the [item guide], which explains the named groups available for items. [item guide]: /tutorial/Dark%20Souls%20III/items/en + +## What's the difference from 2.x.x? + +Version 3.0.0 and forward of the Dark Souls III Archipelago client has a number +of substantial differences with the older 2.x.x versions. Improvements include: + +* Support for randomizing all item locations, not just unique items, without + needing progressive pickup lists. + +* Support for randomizing items in shops, starting loadouts, Path of the Dragon, + and more. + +* Built-in integration with the enemy randomizer, including consistent seeding + for races and configuration via the web interface and the standard Archipelago + YAML file. + +* Support for the latest patch for Dark Souls III, 1.15.2. Note that older + patches are currently *not* supported, although if [ModEngine2] ever adds + support they should work fine. + + [ModEngine2]: https://github.com/soulsmods/ModEngine2 + +* Optional smooth distribution for upgrade items, upgraded weapons, and soul + items so you're more likely to see weaker items earlier and more powerful + items later. + +* More detailed location names that indicate where a location is, not just what + it replaces. + +* Other players' item names are visible in DS3. + +* If you pick up items while offline, they'll still send once you reconnect. + +However, not all YAML fields from 2.x.x are supported as-is in 3.0.0, and some +new fields are available. Consider [generating a new YAML configuration] for use +with 3.x.x. + +[generating a new YAML configuration]: /games/Dark%20Souls%20III/player-options + +The following options have been removed: + +* `enable_boss_locations` is now controlled by the `soul_locations` option. + +* `enable_progressive_locations` was removed because all locations are now + individually randomized rather than replaced with a progressive list. + +* `pool_type` has been removed. Since there are no longer any non-randomized + items in randomized categories, there's not a meaningful distinction between + "shuffle" and "various" mode. + +In addition, the following options have changed: + +* `enable_*_locations` options have all been deprecated. Instead, you can now + add [location group names] to the `exclude_locations` option to prevent them + from containing important items. + + [location group names]: /tutorial/Dark%20Souls%20III/locations/en#location-groups + + By default, the Hidden, Small Crystal Lizards, Upgrade, Small Souls, and + Miscellaneous groups are in `exclude_locations`. Once you've chosen your + excluded locations, you can set `excluded_locations: unrandomized` to preserve + the default vanilla item placements for all excluded locations. + +* The location names used in options like `exclude_locations` have changed. See + the [location guide] for a full description. From d3ba319f36993a1a33250d02ab835e35ea5e9dce Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 11 Apr 2024 21:12:00 -0700 Subject: [PATCH 196/238] Don't crash if there are more items than locations in smoothing --- worlds/dark_souls_3/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 5d12e1165259..5f8b9e674ea5 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -1422,7 +1422,10 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: and loc.item.name in names ] - if len(item_order) != len(all_matching_locations): + # It's expected that there may be more total items than there are matching locations if + # the player has chosen a more limited accessibility option, since the matching + # locations *only* include items in the spheres of accessibility. + if len(item_order) < len(all_matching_locations): raise Exception( f"DS3 bug: there are {len(all_matching_locations)} locations that can " + f"contain smoothed items, but only {len(item_order)} items to smooth." From 2d15ccd31083428e606e81e0d6f6aff27494a6b1 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 13 Apr 2024 00:08:55 -0700 Subject: [PATCH 197/238] Apply suggestions from code review Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> --- worlds/dark_souls_3/docs/locations_en.md | 28 +++++++++++------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/worlds/dark_souls_3/docs/locations_en.md b/worlds/dark_souls_3/docs/locations_en.md index 00c3e864bea4..74832d72995a 100644 --- a/worlds/dark_souls_3/docs/locations_en.md +++ b/worlds/dark_souls_3/docs/locations_en.md @@ -193,7 +193,7 @@ General notes: * **Tower:** The tower at the end of the region with the giant archer at the top. -* **Tower village:** The village reachable from the tower, where the Fire Giant +* **Tower village:** The village reachable from the tower, where the Fire Demon patrols in vanilla. ### Road of Sacrifices @@ -219,16 +219,15 @@ region. * "Right room" is the room up the stairs closer to Farron Keep. -* **Keep perimiter:** The building with the Black Knight and the locked door to +* **Keep perimeter:** The building with the Black Knight and the locked door to the Farron Keep Perimeter bonfire. ### Cathedral of the Deep * **Path:** The path from Road of Sacrifices to the cathedral proper. -* **Moat:** The circular path around the base of the area in front of the - cathedral, with the Ravenous Crystal Lizard in vanilla. Only the lowest part - actually has any water. +* **Moat:** The circular path around the base of the front of the + cathedral, with the Ravenous Crystal Lizard and Corpse-Grubs in vanilla. * **Graveyard:** The area with respawning enemies up the hill from the Cleansing Chapel bonfire. @@ -296,8 +295,8 @@ Catacombs of Carthus region. * "Upper" is the floor the long stairway leads to that also contains the Catacombs of Carthus bonfire. * "Lower" is the floor with rats and bonewheels in vanilla. - * "Across" is the area reached by going up a different set of stairs from - downstairs. + * "Across" is the area reached by going up the set of stairs across from + the entrance downstairs. * **Cavern:** The even larger open area past the crypt with the rope bridge to the boss arena. @@ -319,12 +318,12 @@ Catacombs of Carthus region. * **Ruins main:** The area you first enter after the Demon Ruins bonfire. * "Upper" is the floor you begin on. - * "Lower" is the floor down the stairs from upper. + * "Lower" is the floor down the stairs. -* **Antechamber:** The area up a different flight of stairs from ruins main - lower, with the Old King's Antechamber bonfire. +* **Antechamber:** The area up the flight of stairs near the +Old King's Antechamber bonfire. -* **Ruins basement:** The area further down from ruins main lower, with a many +* **Ruins basement:** The area further down from ruins main lower, with many basilisks and Knight Slayer Tsorig in vanilla. ### Irithyll of the Boreal Valley @@ -386,7 +385,7 @@ from the "near" side of the floor to the "far" side. * "Far" is the opposite side with the mimic. * **B3 lift:** The elevator from B3 (near where you can use Path of the Dragon - to go to Archdragon Peak) up to B2 far. + to go to Archdragon Peak) up to B2. ### Profaned Capital @@ -396,7 +395,7 @@ from the "near" side of the floor to the "far" side. lower floor of the tower, going into the corridor to the left, and falling down a hole. -* **Chapel:** The building in the swamp, with Monstrosities of Sin in it in +* **Chapel:** The building in the swamp containing Monstrosities of Sin in vanilla. * **Bridge:** The long bridge from the tower into the palace. @@ -412,8 +411,7 @@ story. * **Light cathedral:** The cathedral in which you fight Pontiff Sulyvahn in vanilla. -* **Plaza:** The wide open area filled with dead Giant Slaves and a couple live - ones in vanilla. +* **Plaza:** The wide open area filled with Giant Slaves in vanilla. * **Walkway:** The path above the plaza leading to the second floor of the light cathedral, with Deacons in vanilla. From 44cd5721e61b2128afc4f217529b0217f4e96ae9 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 13 Apr 2024 00:08:44 -0700 Subject: [PATCH 198/238] Code review --- worlds/dark_souls_3/__init__.py | 53 ++++++++++++++---------- worlds/dark_souls_3/docs/locations_en.md | 22 ++++++---- 2 files changed, 45 insertions(+), 30 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 5f8b9e674ea5..a10026cfe509 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -51,9 +51,7 @@ class DarkSouls3World(World): game: str = "Dark Souls III" options: DarkSouls3Options options_dataclass = DarkSouls3Options - topology_present: bool = True web = DarkSouls3Web() - data_version = 9 base_id = 100000 required_client_version = (0, 4, 2) item_name_to_id = {data.name: data.ap_code for data in item_dictionary.values()} @@ -73,6 +71,12 @@ class DarkSouls3World(World): This is used to determine where the Storm Ruler can be placed. """ + all_excluded_locations: Set[str] = set() + """This is the same value as `self.options.exclude_locations.value` initially, but if + `options.exclude_locations` gets cleared due to `excluded_locations: unnecessary` this still + holds the old locations so we can ensure they don't get necessary items. + """ + def __init__(self, multiworld: MultiWorld, player: int): super().__init__(multiworld, player) @@ -148,10 +152,9 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: # Cemetery of Ash has very few locations and all of them are excluded by default, so only # allow Yhorm as Iudex Gundyr if there's at least one available location. - excluded = self.options.exclude_locations.value return any( self._is_location_available(location) - and location.name not in excluded + and location.name not in self.options.exclude_locations.value and location.name != "CA: Coiled Sword - boss drop" for location in location_tables["Cemetery of Ash"] ) @@ -269,7 +272,7 @@ def create_region(self, region_name, location_table) -> Region: # Don't allow Siegward's Storm Ruler to mark Yhorm as defeatable. if location.name == "PC: Storm Ruler - Siegward": continue - # Replace non-randomized items with events + # Replace non-randomized items with events that give the default item event_item = ( self.create_item(location.default_item_name) if location.default_item_name else DarkSouls3Item.event(location.name, self.player) @@ -389,7 +392,7 @@ def _create_injectable_items(self, num_required_extra_items: int) -> List[Item]: def create_item(self, item: Union[str, DS3ItemData]) -> Item: data = item if isinstance(item, DS3ItemData) else item_dictionary[item] classification = None - if self.multiworld and ( + if self.multiworld and data.useful_if != UsefulIf.DEFAULT and ( ( data.useful_if == UsefulIf.BASE and not self.options.enable_dlc and @@ -494,15 +497,31 @@ def _fill_local_item( and location.item_rule(item) ] + self.multiworld.itempool.remove(item) + if not candidate_locations: warning(f"Couldn't place \"{name}\" in a valid location for {self.multiworld.get_player_name(self.player)}. Adding it to starting inventory instead.") + location = next( + (location for location in self.multiworld.get_locations() if location.item == item), + None + ) + if location: self._replace_with_filler(location) self.multiworld.push_precollected(self.create_item(name)) return location = self.random.choice(candidate_locations) location.place_locked_item(item) - self.multiworld.itempool.remove(item) - + + def _replace_with_filler(self, location: DarkSouls3Location) -> None: + """If possible, choose a filler item to replace location's current contents with.""" + if location.locked: return + + # Try 10 filler items. If none of them work, give up and leave it as-is. + for _ in range(0, 10): + candidate = self.create_filler() + if location.item_rule(candidate): + location.item = item + return def get_filler_item_name(self) -> str: @@ -1279,6 +1298,10 @@ def _add_location_rule(self, location: Union[str, List[str]], rule: Union[Collec """ locations = location if type(location) is list else [location] for location in locations: + data = location_dictionary[location] + if data.dlc and not self.options.enable_dlc: return False + if data.ngp and not self.options.enable_ngp: return False + if not self._is_location_available(location): return if isinstance(rule, str): assert item_dictionary[rule].classification == ItemClassification.progression @@ -1359,19 +1382,7 @@ def post_fill(self): state: CollectionState = CollectionState(self.multiworld) unchecked_locations = set(self.multiworld.get_locations()) - locations_by_sphere: List[Set[Location]] = [] - - while len(unchecked_locations) > 0: - sphere_locations = {loc for loc in unchecked_locations if state.can_reach(loc)} - locations_by_sphere.append(self._shuffle(sorted(sphere_locations))) - - old_length = len(unchecked_locations) - unchecked_locations.difference_update(sphere_locations) - if len(unchecked_locations) == old_length: break # Unreachable locations - - state.sweep_for_events(key_only=True, locations=unchecked_locations) - for location in sphere_locations: - if location.event: state.collect(location.item, True, location) + locations_by_sphere = list(self.multiworld.get_spheres()) # All items in the base game in approximately the order they appear all_item_order = [ diff --git a/worlds/dark_souls_3/docs/locations_en.md b/worlds/dark_souls_3/docs/locations_en.md index 74832d72995a..454ad2fa1523 100644 --- a/worlds/dark_souls_3/docs/locations_en.md +++ b/worlds/dark_souls_3/docs/locations_en.md @@ -41,8 +41,10 @@ at once: * **Boss rewards:** Boss drops. Does not include soul transfusions or shop items. -* **Miniboss Rewards:** Miniboss drops. Only includes enemies considered - minibosses by the enemy randomizer. +* **Miniboss Rewards:** Miniboss drops. Minibosses are large enemies that don't + respawn after being killed and usually drop some sort of treasure, such as + Boreal Outrider Knights and Ravenous Crystal Lizards. Only includes enemies + considered minibosses by the enemy randomizer. * **Mimic Rewards:** Drops from enemies that are mimics in vanilla. @@ -123,7 +125,7 @@ General notes: * "Miniboss" are large enemies that don't respawn after being killed and usually drop some sort of treasure, such as Boreal Outrider Knights and Ravenous - Crystal Lizards. They usually don't have boss bars, but a few of them do. + Crystal Lizards. * NPC quest items are always in the first location you can get them _without_ killing the NPC or ending the quest early. @@ -184,7 +186,8 @@ General notes: * **White tree:** The birch tree by the Dilapidated Bridge bonfire, where the giant shoots arrows. -* **Sewer:** The underground passage between the +* **Sewer:** The underground passage between the chasm and the Dilapidated + Bridge bonfire. * **Chasm:** The chasm underneath the bridge on the way to the tower. It's possible to get into the chasm without a key by dropping down next to Eygon of @@ -276,7 +279,7 @@ region. elevator from the Old Wolf of Farron bonfire. * **Perimeter:** The area from near the Farron Keep Perimeter bonfire, including - the stony section and the path to the boss. + the stone building and the path to the boss. ### Catacombs of Carthus @@ -340,7 +343,7 @@ considered part of Anor Londo. crystal lizard just before the plaza. * **Plaza:** The area in front of and below the cathedral, with a locked door up - to it and a locked elevator to the ascent. + to the cathedral and a locked elevator to the Ascent. * **Descent:** The path from the Church of Yorshka bonfire down to the lake. @@ -358,8 +361,9 @@ considered part of Anor Londo. ### Irithyll Dungeon -In Irithyll Dungeon locations, "left" and "right" are always oriented facing -from the "near" side of the floor to the "far" side. +In Irithyll Dungeon locations, "left" and "right" are always oriented as though +"near" is where you stand and "far" is where you're facing. (For example, you +enter the dungeon from the bonfire on the near left.) * **B1:** The floor on which the player enters the dungeon, with the Irithyll Dungeon bonfire. @@ -379,7 +383,7 @@ from the "near" side of the floor to the "far" side. Dungeon bonfire. * **B3:** The lowest floor, with Karla's cell, a lift back to B2, and the exit - onwards to Profaned Capital. + onwards to the Profaned Capital. * "Near" is the side with Karla's cell and the the path from the pit. * "Far" is the opposite side with the mimic. From 1913aba73a22a9d772ebc8af54b414c36af0ec9e Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 13 Apr 2024 00:11:48 -0700 Subject: [PATCH 199/238] Fix _replace_with_filler --- worlds/dark_souls_3/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index a10026cfe509..aa427ba44e30 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -520,7 +520,7 @@ def _replace_with_filler(self, location: DarkSouls3Location) -> None: for _ in range(0, 10): candidate = self.create_filler() if location.item_rule(candidate): - location.item = item + location.item = candidate return From c5ce224adf0b7d5679145ac7da895a3f02531917 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 13 Apr 2024 00:12:28 -0700 Subject: [PATCH 200/238] Don't use the shared flatten function in SM --- worlds/sm/variaRandomizer/logic/smbool.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/worlds/sm/variaRandomizer/logic/smbool.py b/worlds/sm/variaRandomizer/logic/smbool.py index 99084e4a44f8..b7f596cbbb08 100644 --- a/worlds/sm/variaRandomizer/logic/smbool.py +++ b/worlds/sm/variaRandomizer/logic/smbool.py @@ -1,4 +1,8 @@ -from Utils import flatten +def flatten(l): + if type(l) is list: + return [ y for x in l for y in flatten(x) ] + else: + return [ l ] # super metroid boolean class SMBool: From 947d18c5e71172ba5515b8eed75e02b08a92ed68 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 16 Apr 2024 22:51:24 -0700 Subject: [PATCH 201/238] Track local items separately rather than iterating the multiworld --- worlds/dark_souls_3/__init__.py | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index aa427ba44e30..5ea2017bb7cd 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -77,6 +77,10 @@ class DarkSouls3World(World): holds the old locations so we can ensure they don't get necessary items. """ + local_itempool: Optional[List[DarkSouls3Item]] + """The pool of all items within this particular world. This is a subset of + `self.multiworld.itempool`.""" + def __init__(self, multiworld: MultiWorld, player: int): super().__init__(multiworld, player) @@ -302,7 +306,7 @@ def create_items(self): item_set: Set[str] = set() # Gather all default items on randomized locations - itempool: List[DarkSouls3Item] = [] + self.local_itempool = [] num_required_extra_items = 0 for location in self.multiworld.get_unfilled_locations(self.player): if not self._is_location_available(location.name): @@ -312,7 +316,7 @@ def create_items(self): if item.skip: num_required_extra_items += 1 elif not item.unique: - itempool.append(self.create_item(location.data.default_item_name)) + self.local_itempool.append(self.create_item(location.data.default_item_name)) else: # For unique items, make sure there aren't duplicates in the item set even if there # are multiple in-game locations that provide them. @@ -320,17 +324,17 @@ def create_items(self): num_required_extra_items += 1 else: item_set.add(location.data.default_item_name) - itempool.append(self.create_item(location.data.default_item_name)) + self.local_itempool.append(self.create_item(location.data.default_item_name)) injectables = self._create_injectable_items(num_required_extra_items) num_required_extra_items -= len(injectables) - itempool.extend(injectables) + self.local_itempool.extend(injectables) # Extra filler items for locations containing skip items - itempool.extend(self.create_filler() for _ in range(num_required_extra_items)) + self.local_itempool.extend(self.create_filler() for _ in range(num_required_extra_items)) # Add items to itempool - self.multiworld.itempool += itempool + self.multiworld.itempool += self.local_itempool self._fill_local_items() @@ -474,13 +478,7 @@ def _fill_local_item( If the item could not be placed, it will be added to starting inventory. """ - item = next( - ( - item for item in self.multiworld.itempool - if item.player == self.player and item.name == name - ), - None - ) + item = next((item for item in self.local_itempool if item.name == name), None) if not item: return candidate_locations = [ @@ -498,6 +496,7 @@ def _fill_local_item( ] self.multiworld.itempool.remove(item) + self.local_itempool.remove(item) if not candidate_locations: warning(f"Couldn't place \"{name}\" in a valid location for {self.multiworld.get_player_name(self.player)}. Adding it to starting inventory instead.") @@ -529,10 +528,7 @@ def get_filler_item_name(self) -> str: def set_rules(self) -> None: - randomized_items = { - item.name for item in self.multiworld.itempool - if item.player == self.player - } + randomized_items = {item.name for item in self.local_itempool} self._add_shop_rules() self._add_npc_rules() From 7d1d9b39e77a87e9f3f1b41957287c536109581b Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Mon, 22 Apr 2024 19:45:47 -0400 Subject: [PATCH 202/238] Various formatting/docs changes suggested by PyCharm (#12) --- worlds/dark_souls_3/Bosses.py | 13 +- worlds/dark_souls_3/Items.py | 12 +- worlds/dark_souls_3/Locations.py | 1881 ++++++++--------- worlds/dark_souls_3/Options.py | 12 +- worlds/dark_souls_3/__init__.py | 34 +- .../detailed_location_descriptions.py | 3 +- worlds/dark_souls_3/docs/en_Dark Souls III.md | 8 +- worlds/dark_souls_3/docs/locations_en.md | 66 +- 8 files changed, 1011 insertions(+), 1018 deletions(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index 25ab6dcbaf54..654893200a6b 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -5,6 +5,7 @@ from dataclasses import dataclass, field from typing import Optional, Set + @dataclass class DS3BossInfo: """The set of locations a given boss location blocks access to.""" @@ -25,17 +26,19 @@ class DS3BossInfo: aren't randomized. """ - locations: Optional[str] = field(default_factory=set) + locations: Optional[Set[str]] = field(default_factory=set) """Additional individual locations that can't be accessed until the boss is dead.""" # Note: the offline 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("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", diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index f657bd2f4e3d..7093fdb75726 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -1,4 +1,4 @@ -from dataclasses import dataclass, field +from dataclasses import dataclass import dataclasses from enum import IntEnum import types @@ -92,7 +92,7 @@ class UsefulIf(IntEnum): @dataclass -class DS3ItemData(): +class DS3ItemData: __item_id: ClassVar[int] = 100000 """The next item ID to use when creating item data.""" @@ -130,7 +130,7 @@ class DS3ItemData(): difference. """ - souls: Set[int] = None + souls: int = None """If this is a consumable item that gives souls, the number of souls it gives.""" useful_if: UsefulIf = UsefulIf.DEFAULT @@ -453,7 +453,7 @@ def flatten(l): DS3ItemData("Storyteller's Staff", 0x00C76EB0, DS3ItemCategory.WEAPON_UPGRADE_10), DS3ItemData("Mendicant's Staff", 0x00C795C0, DS3ItemCategory.WEAPON_UPGRADE_10, classification = ItemClassification.progression, # Crow trade - inject = True), # This is just a random drop normally but we need it in-logic + inject = True), # This is just a random drop normally, but we need it in-logic DS3ItemData("Man-grub's Staff", 0x00C7E3E0, DS3ItemCategory.WEAPON_UPGRADE_5, inject = True), # Covenant reward DS3ItemData("Archdeacon's Great Staff", 0x00C80AF0, DS3ItemCategory.WEAPON_UPGRADE_5, @@ -509,7 +509,7 @@ def flatten(l): DS3ItemData("Round Shield", 0x0131A230, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Large Leather Shield", 0x0131C940, DS3ItemCategory.SHIELD_INFUSIBLE, classification = ItemClassification.progression, # Crow trade - inject = True), # This is a shop/infinite drop item but we need it in logic + inject = True), # This is a shop/infinite drop item, but we need it in logic DS3ItemData("Hawkwood's Shield", 0x01323E70, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Iron Round Shield", 0x01326580, DS3ItemCategory.SHIELD_INFUSIBLE), DS3ItemData("Wooden Shield", 0x0132DAB0, DS3ItemCategory.SHIELD_INFUSIBLE), @@ -1293,7 +1293,7 @@ def flatten(l): classification = ItemClassification.progression), # Fake item for controlling access to Archdragon Peak. The real drop isn't actually an item as - # such so we have to inject this because there's no slot for it to come from. + # such, so we have to inject this because there's no slot for it to come from. DS3ItemData("Path of the Dragon", 0x40002346, DS3ItemCategory.UNIQUE, inject = True, classification = ItemClassification.progression), diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 93aaa42cf5a2..a418fe0a7db1 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1,11 +1,9 @@ -from enum import IntEnum from typing import ClassVar, Optional, Dict, List, Set from dataclasses import dataclass -from BaseClasses import ItemClassification, Location, LocationProgressType, Region +from BaseClasses import ItemClassification, Location, Region from .Items import DS3ItemCategory, item_dictionary - # Regions in approximate order of reward, mostly measured by how high-quality the upgrade items are # in each region. region_order = [ @@ -33,7 +31,7 @@ "Lothric Castle", "Consumed King's Garden", "Untended Graves", - # List this late becaues it contains a Titanite Slab in the base game + # List this late because it contains a Titanite Slab in the base game "Firelink Shrine Bell Tower", "Grand Archives", "Archdragon Peak", @@ -205,21 +203,21 @@ def location_groups(self) -> List[str]: default_item = item_dictionary[self.default_item_name] names.append({ - DS3ItemCategory.WEAPON_UPGRADE_5: "Weapons", - DS3ItemCategory.WEAPON_UPGRADE_10: "Weapons", - DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE: "Weapons", - DS3ItemCategory.SHIELD: "Shields", - DS3ItemCategory.SHIELD_INFUSIBLE: "Shields", - DS3ItemCategory.ARMOR: "Armor", - DS3ItemCategory.RING: "Rings", - DS3ItemCategory.SPELL: "Spells", - DS3ItemCategory.MISC: "Miscellaneous", - DS3ItemCategory.UNIQUE: "Unique", - DS3ItemCategory.BOSS: "Boss Souls", - DS3ItemCategory.SOUL: "Small Souls", - DS3ItemCategory.UPGRADE: "Upgrade", - DS3ItemCategory.HEALING: "Healing", - }[default_item.category]) + DS3ItemCategory.WEAPON_UPGRADE_5: "Weapons", + DS3ItemCategory.WEAPON_UPGRADE_10: "Weapons", + DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE: "Weapons", + DS3ItemCategory.SHIELD: "Shields", + DS3ItemCategory.SHIELD_INFUSIBLE: "Shields", + DS3ItemCategory.ARMOR: "Armor", + DS3ItemCategory.RING: "Rings", + DS3ItemCategory.SPELL: "Spells", + DS3ItemCategory.MISC: "Miscellaneous", + DS3ItemCategory.UNIQUE: "Unique", + DS3ItemCategory.BOSS: "Boss Souls", + DS3ItemCategory.SOUL: "Small Souls", + DS3ItemCategory.UPGRADE: "Upgrade", + DS3ItemCategory.HEALING: "Healing", + }[default_item.category]) if default_item.classification == ItemClassification.progression: names.append("Progression") @@ -272,20 +270,20 @@ def __init__( DS3LocationData("CA: Soul of an Unknown Traveler - by miniboss", "Soul of an Unknown Traveler"), DS3LocationData("CA: Speckled Stoneplate Ring+1 - by miniboss", - "Speckled Stoneplate Ring+1", ngp = True), - DS3LocationData("CA: Titanite Scale - miniboss drop", "Titanite Scale", miniboss = True), - DS3LocationData("CA: Coiled Sword - boss drop", "Coiled Sword", prominent = True, - progression = True, boss = True), + "Speckled Stoneplate Ring+1", ngp=True), + DS3LocationData("CA: Titanite Scale - miniboss drop", "Titanite Scale", miniboss=True), + DS3LocationData("CA: Coiled Sword - boss drop", "Coiled Sword", prominent=True, + progression=True, boss=True), ], "Firelink Shrine": [ # Ludleth drop, does not permanently die - DS3LocationData("FS: Skull Ring - kill Ludleth", "Skull Ring", hidden = True, drop = True, - npc = True), + DS3LocationData("FS: Skull Ring - kill Ludleth", "Skull Ring", hidden=True, drop=True, + npc=True), # Sword Master drops - DS3LocationData("FS: Uchigatana - NPC drop", "Uchigatana", hostile_npc = True), - DS3LocationData("FS: Master's Attire - NPC drop", "Master's Attire", hostile_npc = True), - DS3LocationData("FS: Master's Gloves - NPC drop", "Master's Gloves", hostile_npc = True), + DS3LocationData("FS: Uchigatana - NPC drop", "Uchigatana", hostile_npc=True), + DS3LocationData("FS: Master's Attire - NPC drop", "Master's Attire", hostile_npc=True), + DS3LocationData("FS: Master's Gloves - NPC drop", "Master's Gloves", hostile_npc=True), DS3LocationData("FS: Broken Straight Sword - gravestone after boss", "Broken Straight Sword"), @@ -294,178 +292,178 @@ def __init__( DS3LocationData("FS: Soul of a Deserted Corpse - bell tower door", "Soul of a Deserted Corpse"), DS3LocationData("FS: East-West Shield - tree by shrine entrance", "East-West Shield"), - DS3LocationData("FS: Homeward Bone - path above shrine entrace", "Homeward Bone"), + DS3LocationData("FS: Homeward Bone - path above shrine entrance", "Homeward Bone"), DS3LocationData("FS: Ember - above shrine entrance", "Ember"), - DS3LocationData("FS: Wolf Ring+2 - left of boss room exit", "Wolf Ring+2", ngp = True), + DS3LocationData("FS: Wolf Ring+2 - left of boss room exit", "Wolf Ring+2", ngp=True), # Leonhard (quest) DS3LocationData("FS: Cracked Red Eye Orb - Leonhard", "Cracked Red Eye Orb x5", - missable = True, npc = True), + missable=True, npc=True), # Leonhard (kill or quest), missable because he can disappear sometimes - DS3LocationData("FS: Lift Chamber Key - Leonhard", "Lift Chamber Key", missable = True, - npc = True, drop = True), + DS3LocationData("FS: Lift Chamber Key - Leonhard", "Lift Chamber Key", missable=True, + npc=True, drop=True), # Shrine Handmaid shop - DS3LocationData("FS: White Sign Soapstone - shop", "White Sign Soapstone", shop = True), - DS3LocationData("FS: Dried Finger - shop", "Dried Finger", shop = True), - DS3LocationData("FS: Tower Key - shop", "Tower Key", progression = True, shop = True), - DS3LocationData("FS: Ember - shop", "Ember", offline = '99,0:-1:110000:', shop = True), - DS3LocationData("FS: Farron Dart - shop", "Farron Dart", offline = '99,0:-1:110000:', - shop = True), - DS3LocationData("FS: Soul Arrow - shop", "Soul Arrow", offline = '99,0:-1:110000:', - shop = True), - DS3LocationData("FS: Heal Aid - shop", "Heal Aid", shop = True), - DS3LocationData("FS: Alluring Skull - Mortician's Ashes", "Alluring Skull", shop = True, - conditional = True), + DS3LocationData("FS: White Sign Soapstone - shop", "White Sign Soapstone", shop=True), + DS3LocationData("FS: Dried Finger - shop", "Dried Finger", shop=True), + DS3LocationData("FS: Tower Key - shop", "Tower Key", progression=True, shop=True), + DS3LocationData("FS: Ember - shop", "Ember", offline='99,0:-1:110000:', shop=True), + DS3LocationData("FS: Farron Dart - shop", "Farron Dart", offline='99,0:-1:110000:', + shop=True), + DS3LocationData("FS: Soul Arrow - shop", "Soul Arrow", offline='99,0:-1:110000:', + shop=True), + DS3LocationData("FS: Heal Aid - shop", "Heal Aid", shop=True), + DS3LocationData("FS: Alluring Skull - Mortician's Ashes", "Alluring Skull", shop=True, + conditional=True), DS3LocationData("FS: Ember - Mortician's Ashes", "Ember", - offline = '99,0:-1:110000,70000100:', shop = True, conditional = True), - DS3LocationData("FS: Grave Key - Mortician's Ashes", "Grave Key", shop = True, - conditional = True), - DS3LocationData("FS: Life Ring - Dreamchaser's Ashes", "Life Ring", shop = True, - conditional = True), + offline='99,0:-1:110000,70000100:', shop=True, conditional=True), + DS3LocationData("FS: Grave Key - Mortician's Ashes", "Grave Key", shop=True, + conditional=True), + DS3LocationData("FS: Life Ring - Dreamchaser's Ashes", "Life Ring", shop=True, + conditional=True), # Only if you say where the ashes were found DS3LocationData("FS: Hidden Blessing - Dreamchaser's Ashes", "Hidden Blessing", - missable = True, shop = True), + missable=True, shop=True), DS3LocationData("FS: Lloyd's Shield Ring - Paladin's Ashes", "Lloyd's Shield Ring", - shop = True, conditional = True), + shop=True, conditional=True), DS3LocationData("FS: Ember - Grave Warden's Ashes", "Ember", - offline = '99,0:-1:110000,70000103:', shop = True, conditional = True), + offline='99,0:-1:110000,70000103:', shop=True, conditional=True), # Prisoner Chief's Ashes DS3LocationData("FS: Karla's Pointed Hat - Prisoner Chief's Ashes", "Karla's Pointed Hat", - offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), + offline='99,0:-1:110000,70000105:', shop=True, conditional=True), DS3LocationData("FS: Karla's Coat - Prisoner Chief's Ashes", "Karla's Coat", - offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), + offline='99,0:-1:110000,70000105:', shop=True, conditional=True), DS3LocationData("FS: Karla's Gloves - Prisoner Chief's Ashes", "Karla's Gloves", - offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), + offline='99,0:-1:110000,70000105:', shop=True, conditional=True), DS3LocationData("FS: Karla's Trousers - Prisoner Chief's Ashes", "Karla's Trousers", - offline = '99,0:-1:110000,70000105:', shop = True, conditional = True), - DS3LocationData("FS: Xanthous Overcoat - Xanthous Ashes", "Xanthous Overcoat", shop = True, - conditional = True), - DS3LocationData("FS: Xanthous Gloves - Xanthous Ashes", "Xanthous Gloves", shop = True, - conditional = True), - DS3LocationData("FS: Xanthous Trousers - Xanthous Ashes", "Xanthous Trousers", shop = True, - conditional = True), + offline='99,0:-1:110000,70000105:', shop=True, conditional=True), + DS3LocationData("FS: Xanthous Overcoat - Xanthous Ashes", "Xanthous Overcoat", shop=True, + conditional=True), + DS3LocationData("FS: Xanthous Gloves - Xanthous Ashes", "Xanthous Gloves", shop=True, + conditional=True), + DS3LocationData("FS: Xanthous Trousers - Xanthous Ashes", "Xanthous Trousers", shop=True, + conditional=True), DS3LocationData("FS: Ember - Dragon Chaser's Ashes", "Ember", - offline = '99,0:-1:110000,70000108:', shop = True, conditional = True), - DS3LocationData("FS: Washing Pole - Easterner's Ashes", "Washing Pole", shop = True, - conditional = True), - DS3LocationData("FS: Eastern Helm - Easterner's Ashes", "Eastern Helm", shop = True, - conditional = True), - DS3LocationData("FS: Eastern Armor - Easterner's Ashes", "Eastern Armor", shop = True, - conditional = True), + offline='99,0:-1:110000,70000108:', shop=True, conditional=True), + DS3LocationData("FS: Washing Pole - Easterner's Ashes", "Washing Pole", shop=True, + conditional=True), + DS3LocationData("FS: Eastern Helm - Easterner's Ashes", "Eastern Helm", shop=True, + conditional=True), + DS3LocationData("FS: Eastern Armor - Easterner's Ashes", "Eastern Armor", shop=True, + conditional=True), DS3LocationData("FS: Eastern Gauntlets - Easterner's Ashes", "Eastern Gauntlets", - shop = True, conditional = True), - DS3LocationData("FS: Eastern Leggings - Easterner's Ashes", "Eastern Leggings", shop = True, - conditional = True), - DS3LocationData("FS: Wood Grain Ring - Easterner's Ashes", "Wood Grain Ring", shop = True, - conditional = True), + shop=True, conditional=True), + DS3LocationData("FS: Eastern Leggings - Easterner's Ashes", "Eastern Leggings", shop=True, + conditional=True), + DS3LocationData("FS: Wood Grain Ring - Easterner's Ashes", "Wood Grain Ring", shop=True, + conditional=True), DS3LocationData("FS: Millwood Knight Helm - Captain's Ashes", "Millwood Knight Helm", - dlc = True, shop = True, conditional = True), + dlc=True, shop=True, conditional=True), DS3LocationData("FS: Millwood Knight Armor - Captain's Ashes", "Millwood Knight Armor", - dlc = True, shop = True, conditional = True), + dlc=True, shop=True, conditional=True), DS3LocationData("FS: Millwood Knight Gauntlets - Captain's Ashes", - "Millwood Knight Gauntlets", dlc = True, shop = True, conditional = True), + "Millwood Knight Gauntlets", dlc=True, shop=True, conditional=True), DS3LocationData("FS: Millwood Knight Leggings - Captain's Ashes", - "Millwood Knight Leggings", dlc = True, shop = True, conditional = True), - DS3LocationData("FS: Refined Gem - Captain's Ashes", "Refined Gem", dlc = True, shop = True, - conditional = True), + "Millwood Knight Leggings", dlc=True, shop=True, conditional=True), + DS3LocationData("FS: Refined Gem - Captain's Ashes", "Refined Gem", dlc=True, shop=True, + conditional=True), # Ludleth Shop DS3LocationData("FS: Vordt's Great Hammer - Ludleth for Vordt", "Vordt's Great Hammer", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Pontiff's Left Eye - Ludleth for Vordt", "Pontiff's Left Eye", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Bountiful Sunlight - Ludleth for Rosaria", "Bountiful Sunlight", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Darkmoon Longbow - Ludleth for Aldrich", "Darkmoon Longbow", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Lifehunt Scythe - Ludleth for Aldrich", "Lifehunt Scythe", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Hollowslayer Greatsword - Ludleth for Greatwood", - "Hollowslayer Greatsword", missable = True, boss = True, shop = True), + "Hollowslayer Greatsword", missable=True, boss=True, shop=True), DS3LocationData("FS: Arstor's Spear - Ludleth for Greatwood", "Arstor's Spear", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Crystal Sage's Rapier - Ludleth for Sage", "Crystal Sage's Rapier", - missable = True, boss = True, shop = True), - DS3LocationData("FS: Crystal Hail - Ludleth for Sage", "Crystal Hail", missable = True, - boss = True, shop = True), + missable=True, boss=True, shop=True), + DS3LocationData("FS: Crystal Hail - Ludleth for Sage", "Crystal Hail", missable=True, + boss=True, shop=True), DS3LocationData("FS: Cleric's Candlestick - Ludleth for Deacons", "Cleric's Candlestick", - missable = True, boss = True, shop = True), - DS3LocationData("FS: Deep Soul - Ludleth for Deacons", "Deep Soul", missable = True, - boss = True, shop = True), + missable=True, boss=True, shop=True), + DS3LocationData("FS: Deep Soul - Ludleth for Deacons", "Deep Soul", missable=True, + boss=True, shop=True), DS3LocationData("FS: Havel's Ring - Ludleth for Stray Demon", "Havel's Ring", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Boulder Heave - Ludleth for Stray Demon", "Boulder Heave", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Farron Greatsword - Ludleth for Abyss Watchers", "Farron Greatsword", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Wolf Knight's Greatsword - Ludleth for Abyss Watchers", - "Wolf Knight's Greatsword", missable = True, boss = True, shop = True), + "Wolf Knight's Greatsword", missable=True, boss=True, shop=True), DS3LocationData("FS: Wolnir's Holy Sword - Ludleth for Wolnir", "Wolnir's Holy Sword", - missable = True, boss = True, shop = True), - DS3LocationData("FS: Black Serpent - Ludleth for Wolnir", "Black Serpent", missable = True, - boss = True, shop = True), + missable=True, boss=True, shop=True), + DS3LocationData("FS: Black Serpent - Ludleth for Wolnir", "Black Serpent", missable=True, + boss=True, shop=True), DS3LocationData("FS: Demon's Greataxe - Ludleth for Fire Demon", "Demon's Greataxe", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Demon's Fist - Ludleth for Fire Demon", "Demon's Fist", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Old King's Great Hammer - Ludleth for Old Demon King", - "Old King's Great Hammer", missable = True, boss = True, shop = True), + "Old King's Great Hammer", missable=True, boss=True, shop=True), DS3LocationData("FS: Chaos Bed Vestiges - Ludleth for Old Demon King", "Chaos Bed Vestiges", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Greatsword of Judgment - Ludleth for Pontiff", - "Greatsword of Judgment", missable = True, boss = True, shop = True), + "Greatsword of Judgment", missable=True, boss=True, shop=True), DS3LocationData("FS: Profaned Greatsword - Ludleth for Pontiff", "Profaned Greatsword", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Yhorm's Great Machete - Ludleth for Yhorm", "Yhorm's Great Machete", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Yhorm's Greatshield - Ludleth for Yhorm", "Yhorm's Greatshield", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Dancer's Enchanted Swords - Ludleth for Dancer", - "Dancer's Enchanted Swords", missable = True, boss = True, shop = True), + "Dancer's Enchanted Swords", missable=True, boss=True, shop=True), DS3LocationData("FS: Soothing Sunlight - Ludleth for Dancer", "Soothing Sunlight", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Dragonslayer Greataxe - Ludleth for Dragonslayer", - "Dragonslayer Greataxe", missable = True, boss = True, shop = True), + "Dragonslayer Greataxe", missable=True, boss=True, shop=True), DS3LocationData("FS: Dragonslayer Greatshield - Ludleth for Dragonslayer", - "Dragonslayer Greatshield", missable = True, boss = True, shop = True), + "Dragonslayer Greatshield", missable=True, boss=True, shop=True), DS3LocationData("FS: Moonlight Greatsword - Ludleth for Oceiros", "Moonlight Greatsword", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: White Dragon Breath - Ludleth for Oceiros", "White Dragon Breath", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Lorian's Greatsword - Ludleth for Princes", "Lorian's Greatsword", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Lothric's Holy Sword - Ludleth for Princes", "Lothric's Holy Sword", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Gundyr's Halberd - Ludleth for Champion", "Gundyr's Halberd", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Prisoner's Chain - Ludleth for Champion", "Prisoner's Chain", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Storm Curved Sword - Ludleth for Nameless", "Storm Curved Sword", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Dragonslayer Swordspear - Ludleth for Nameless", - "Dragonslayer Swordspear", missable = True, boss = True, shop = True), + "Dragonslayer Swordspear", missable=True, boss=True, shop=True), DS3LocationData("FS: Lightning Storm - Ludleth for Nameless", "Lightning Storm", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Firelink Greatsword - Ludleth for Cinder", "Firelink Greatsword", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Sunlight Spear - Ludleth for Cinder", "Sunlight Spear", - missable = True, boss = True, shop = True), + missable=True, boss=True, shop=True), DS3LocationData("FS: Friede's Great Scythe - Ludleth for Friede", "Friede's Great Scythe", - missable = True, dlc = True, boss = True, shop = True), + missable=True, dlc=True, boss=True, shop=True), DS3LocationData("FS: Rose of Ariandel - Ludleth for Friede", "Rose of Ariandel", - missable = True, dlc = True, boss = True, shop = True), + missable=True, dlc=True, boss=True, shop=True), DS3LocationData("FS: Demon's Scar - Ludleth for Demon Prince", "Demon's Scar", - missable = True, dlc = True, boss = True, shop = True), + missable=True, dlc=True, boss=True, shop=True), DS3LocationData("FS: Seething Chaos - Ludleth for Demon Prince", "Seething Chaos", - missable = True, dlc = True, boss = True, shop = True), - DS3LocationData("FS: Frayed Blade - Ludleth for Midir", "Frayed Blade", missable = True, - dlc = True, boss = True, shop = True), - DS3LocationData("FS: Old Moonlight - Ludleth for Midir", "Old Moonlight", missable = True, - dlc = True, boss = True, shop = True), + missable=True, dlc=True, boss=True, shop=True), + DS3LocationData("FS: Frayed Blade - Ludleth for Midir", "Frayed Blade", missable=True, + dlc=True, boss=True, shop=True), + DS3LocationData("FS: Old Moonlight - Ludleth for Midir", "Old Moonlight", missable=True, + dlc=True, boss=True, shop=True), DS3LocationData("FS: Gael's Greatsword - Ludleth for Gael", "Gael's Greatsword", - missable = True, dlc = True, boss = True, shop = True), + missable=True, dlc=True, boss=True, shop=True), DS3LocationData("FS: Repeating Crossbow - Ludleth for Gael", "Repeating Crossbow", - missable = True, dlc = True, boss = True, shop = True), + missable=True, dlc=True, boss=True, shop=True), ], "Firelink Shrine Bell Tower": [ # Guarded by Tower Key @@ -477,69 +475,69 @@ def __init__( DS3LocationData("FSBT: Fire Keeper Gloves - partway down tower", "Fire Keeper Gloves"), DS3LocationData("FSBT: Fire Keeper Skirt - partway down tower", "Fire Keeper Skirt"), DS3LocationData("FSBT: Covetous Silver Serpent Ring - illusory wall past rafters", - "Covetous Silver Serpent Ring", hidden = True), + "Covetous Silver Serpent Ring", hidden=True), DS3LocationData("FSBT: Twinkling Titanite - lizard behind Firelink", - "Twinkling Titanite", lizard = True), + "Twinkling Titanite", lizard=True), # Mark all crow trades as missable since no one wants to have to try trading everything just # in case it gives a progression item. DS3LocationData("FSBT: Iron Bracelets - crow for Homeward Bone", "Iron Bracelets", - missable = True), + missable=True), DS3LocationData("FSBT: Ring of Sacrifice - crow for Loretta's Bone", "Ring of Sacrifice", - missable = True), + missable=True), DS3LocationData("FSBT: Porcine Shield - crow for Undead Bone Shard", "Porcine Shield", - missable = True), + missable=True), DS3LocationData("FSBT: Lucatiel's Mask - crow for Vertebra Shackle", "Lucatiel's Mask", - missable = True), + missable=True), DS3LocationData("FSBT: Very good! Carving - crow for Divine Blessing", - "Very good! Carving", missable = True), + "Very good! Carving", missable=True), DS3LocationData("FSBT: Thank you Carving - crow for Hidden Blessing", "Thank you Carving", - missable = True), + missable=True), DS3LocationData("FSBT: I'm sorry Carving - crow for Shriving Stone", "I'm sorry Carving", - missable = True), + missable=True), DS3LocationData("FSBT: Sunlight Shield - crow for Mendicant's Staff", "Sunlight Shield", - missable = True), + missable=True), DS3LocationData("FSBT: Hollow Gem - crow for Eleonora", "Hollow Gem", - missable = True), + missable=True), DS3LocationData("FSBT: Titanite Scale - crow for Blacksmith Hammer", "Titanite Scale x3", - offline = '99,0:50004330::', missable = True), + offline='99,0:50004330::', missable=True), DS3LocationData("FSBT: Help me! Carving - crow for any sacred chime", "Help me! Carving", - missable = True), + missable=True), DS3LocationData("FSBT: Titanite Slab - crow for Coiled Sword Fragment", "Titanite Slab", - missable = True), + missable=True), DS3LocationData("FSBT: Hello Carving - crow for Alluring Skull", "Hello Carving", - missable = True), + missable=True), DS3LocationData("FSBT: Armor of the Sun - crow for Siegbräu", "Armor of the Sun", - missable = True), + missable=True), DS3LocationData("FSBT: Large Titanite Shard - crow for Firebomb", "Large Titanite Shard", - missable = True), + missable=True), DS3LocationData("FSBT: Titanite Chunk - crow for Black Firebomb", "Titanite Chunk", - missable = True), - DS3LocationData("FSBT: Iron Helm - crow for Lightning Urn", "Iron Helm", missable = True), + missable=True), + DS3LocationData("FSBT: Iron Helm - crow for Lightning Urn", "Iron Helm", missable=True), DS3LocationData("FSBT: Twinkling Titanite - crow for Prism Stone", "Twinkling Titanite", - missable = True), + missable=True), DS3LocationData("FSBT: Iron Leggings - crow for Seed of a Giant Tree", "Iron Leggings", - missable = True), + missable=True), DS3LocationData("FSBT: Lightning Gem - crow for Xanthous Crown", "Lightning Gem", - missable = True), + missable=True), DS3LocationData("FSBT: Twinkling Titanite - crow for Large Leather Shield", - "Twinkling Titanite", missable = True), + "Twinkling Titanite", missable=True), DS3LocationData("FSBT: Blessed Gem - crow for Moaning Shield", "Blessed Gem", - missable = True), + missable=True), ], "High Wall of Lothric": [ DS3LocationData("HWL: Soul of Boreal Valley Vordt", "Soul of Boreal Valley Vordt", - prominent = True, boss = True), - DS3LocationData("HWL: Soul of the Dancer", "Soul of the Dancer", prominent = True, - boss = True), - DS3LocationData("HWL: Basin of Vows - Emma", "Basin of Vows", prominent = True, - progression = True, conditional = True), + prominent=True, boss=True), + DS3LocationData("HWL: Soul of the Dancer", "Soul of the Dancer", prominent=True, + boss=True), + DS3LocationData("HWL: Basin of Vows - Emma", "Basin of Vows", prominent=True, + progression=True, conditional=True), DS3LocationData("HWL: Small Lothric Banner - Emma", "Small Lothric Banner", - prominent = True, progression = True), + prominent=True, progression=True), DS3LocationData("HWL: Green Blossom - fort walkway, hall behind wheel", "Green Blossom x2", - hidden = True), + hidden=True), DS3LocationData("HWL: Gold Pine Resin - corpse tower, drop", "Gold Pine Resin x2", - hidden = True), + hidden=True), DS3LocationData("HWL: Large Soul of a Deserted Corpse - flame plaza", "Large Soul of a Deserted Corpse"), DS3LocationData("HWL: Soul of a Deserted Corpse - by wall tower door", @@ -555,9 +553,9 @@ def __init__( DS3LocationData("HWL: Ember - flame plaza", "Ember"), DS3LocationData("HWL: Firebomb - corpse tower, under table", "Firebomb x2"), DS3LocationData("HWL: Titanite Shard - wall tower, corner by bonfire", "Titanite Shard", - hidden = True), + hidden=True), DS3LocationData("HWL: Undead Hunter Charm - fort, room off entry, in pot", - "Undead Hunter Charm x2", hidden = True), + "Undead Hunter Charm x2", hidden=True), DS3LocationData("HWL: Firebomb - top of ladder to fountain", "Firebomb x3"), DS3LocationData("HWL: Cell Key - fort ground, down stairs", "Cell Key"), DS3LocationData("HWL: Ember - fountain #1", "Ember"), @@ -566,7 +564,7 @@ def __init__( DS3LocationData("HWL: Lucerne - promenade, side path", "Lucerne"), DS3LocationData("HWL: Mail Breaker - wall tower, path to Greirat", "Mail Breaker"), DS3LocationData("HWL: Titanite Shard - fort ground behind crates", "Titanite Shard", - hidden = True), + hidden=True), DS3LocationData("HWL: Rapier - fountain, corner", "Rapier"), DS3LocationData("HWL: Titanite Shard - fort, room off entry", "Titanite Shard"), DS3LocationData("HWL: Large Soul of a Deserted Corpse - fort roof", @@ -576,10 +574,10 @@ def __init__( "Soul of a Deserted Corpse"), DS3LocationData("HWL: Ember - fountain #2", "Ember"), DS3LocationData("HWL: Large Soul of a Deserted Corpse - platform by fountain", - "Large Soul of a Deserted Corpse", hidden = True), # Easily missed turnoff + "Large Soul of a Deserted Corpse", hidden=True), # Easily missed turnoff DS3LocationData("HWL: Binoculars - corpse tower, upper platform", "Binoculars"), DS3LocationData("HWL: Ring of Sacrifice - awning by fountain", - "Ring of Sacrifice", hidden = True), # Easily missed turnoff + "Ring of Sacrifice", hidden=True), # Easily missed turnoff DS3LocationData("HWL: Throwing Knife - shortcut, lift top", "Throwing Knife x6"), DS3LocationData("HWL: Soul of a Deserted Corpse - path to back tower, by lift door", "Soul of a Deserted Corpse"), @@ -592,55 +590,55 @@ def __init__( "Soul of a Deserted Corpse"), DS3LocationData("HWL: Estus Shard - fort ground, on anvil", "Estus Shard"), DS3LocationData("HWL: Fleshbite Ring+1 - fort roof, jump to other roof", - "Fleshbite Ring+1", ngp = True, hidden = True), # Hidden jump + "Fleshbite Ring+1", ngp=True, hidden=True), # Hidden jump DS3LocationData("HWL: Ring of the Evil Eye+2 - fort ground, far wall", - "Ring of the Evil Eye+2", ngp = True, hidden = True), # In barrels + "Ring of the Evil Eye+2", ngp=True, hidden=True), # In barrels DS3LocationData("HWL: Silver Eagle Kite Shield - fort mezzanine", "Silver Eagle Kite Shield"), DS3LocationData("HWL: Astora Straight Sword - fort walkway, drop down", - "Astora Straight Sword", hidden = True), # Hidden fall + "Astora Straight Sword", hidden=True), # Hidden fall DS3LocationData("HWL: Battle Axe - flame tower, mimic", "Battle Axe", - offline = '01,0:53000960::', mimic = True), + offline='01,0:53000960::', mimic=True), # Only dropped after transformation - DS3LocationData("HWL: Ember - fort roof, transforming hollow", "Ember", hidden = True), + DS3LocationData("HWL: Ember - fort roof, transforming hollow", "Ember", hidden=True), DS3LocationData("HWL: Titanite Shard - fort roof, transforming hollow", "Titanite Shard", - hidden = True), - DS3LocationData("HWL: Ember - back tower, transforming hollow", "Ember", hidden = True), + hidden=True), + DS3LocationData("HWL: Ember - back tower, transforming hollow", "Ember", hidden=True), DS3LocationData("HWL: Titanite Shard - back tower, transforming hollow", "Titanite Shard", - hidden = True), + hidden=True), - DS3LocationData("HWL: Refined Gem - promenade miniboss", "Refined Gem", miniboss = True), + DS3LocationData("HWL: Refined Gem - promenade miniboss", "Refined Gem", miniboss=True), DS3LocationData("HWL: Way of Blue - Emma", "Way of Blue"), # Categorize this as an NPC item so that it doesn't get randomized if the Lift Chamber Key # isn't randomized, since in that case it's missable. DS3LocationData("HWL: Red Eye Orb - wall tower, miniboss", "Red Eye Orb", - conditional = True, miniboss = True, npc = True), - DS3LocationData("HWL: Raw Gem - fort roof, lizard", "Raw Gem", lizard = True), + conditional=True, miniboss=True, npc=True), + DS3LocationData("HWL: Raw Gem - fort roof, lizard", "Raw Gem", lizard=True), ], "Undead Settlement": [ DS3LocationData("US: Soul of the Rotted Greatwood", "Soul of the Rotted Greatwood", - prominent = True, boss = True), - DS3LocationData("US: Transposing Kiln - boss drop", "Transposing Kiln", boss = True), + prominent=True, boss=True), + DS3LocationData("US: Transposing Kiln - boss drop", "Transposing Kiln", boss=True), # Missable because it's unavailable if you start as a Pyromancer - DS3LocationData("US: Pyromancy Flame - Cornyx", "Pyromancy Flame", missable = True, - npc = True), + DS3LocationData("US: Pyromancy Flame - Cornyx", "Pyromancy Flame", missable=True, + npc=True), DS3LocationData("US: Old Sage's Blindfold - kill Cornyx", "Old Sage's Blindfold", - npc = True), + npc=True), DS3LocationData("US: Cornyx's Garb - kill Cornyx", "Cornyx's Garb", - offline = '02,0:50006141::', npc = True), + offline='02,0:50006141::', npc=True), DS3LocationData("US: Cornyx's Wrap - kill Cornyx", "Cornyx's Wrap", - offline = '02,0:50006141::', npc = True), + offline='02,0:50006141::', npc=True), DS3LocationData("US: Cornyx's Skirt - kill Cornyx", "Cornyx's Skirt", - offline = '02,0:50006141::', npc = True), - DS3LocationData("US: Tower Key - kill Irina", "Tower Key", missable = True, npc = True), + offline='02,0:50006141::', npc=True), + DS3LocationData("US: Tower Key - kill Irina", "Tower Key", missable=True, npc=True), DS3LocationData("US: Flynn's Ring - tower village, rooftop", "Flynn's Ring"), DS3LocationData("US: Undead Bone Shard - by white tree", "Undead Bone Shard"), DS3LocationData("US: Alluring Skull - foot, behind carriage", "Alluring Skull x2"), DS3LocationData("US: Mortician's Ashes - graveyard by white tree", "Mortician's Ashes", - progression = True), + progression=True), DS3LocationData("US: Homeward Bone - tower village, jump from roof", "Homeward Bone x2", - offline = '02,0:53100040::', hidden = True), # Hidden fall + offline='02,0:53100040::', hidden=True), # Hidden fall DS3LocationData("US: Caduceus Round Shield - right after stable exit", "Caduceus Round Shield"), DS3LocationData("US: Ember - tower basement, miniboss", "Ember"), @@ -648,7 +646,7 @@ def __init__( "Soul of an Unknown Traveler"), DS3LocationData("US: Repair Powder - first building, balcony", "Repair Powder x2"), DS3LocationData("US: Homeward Bone - stable roof", "Homeward Bone x2", - offline = '02,0:53100090::'), + offline='02,0:53100090::'), DS3LocationData("US: Titanite Shard - back alley, side path", "Titanite Shard"), DS3LocationData("US: Wargod Wooden Shield - Pit of Hollows", "Wargod Wooden Shield"), DS3LocationData("US: Large Soul of a Deserted Corpse - on the way to tower, by well", @@ -671,11 +669,11 @@ def __init__( DS3LocationData("US: Charcoal Pine Resin - hanging corpse room", "Charcoal Pine Resin x2"), DS3LocationData("US: Loincloth - by Velka statue", "Loincloth"), DS3LocationData("US: Bloodbite Ring - miniboss in sewer", "Bloodbite Ring", - miniboss = True), # Giant Rat drop + miniboss=True), # Giant Rat drop DS3LocationData("US: Charcoal Pine Bundle - first building, bottom floor", "Charcoal Pine Bundle x2"), DS3LocationData("US: Soul of an Unknown Traveler - back alley, past crates", - "Soul of an Unknown Traveler", hidden = True), + "Soul of an Unknown Traveler", hidden=True), DS3LocationData("US: Titanite Shard - back alley, up ladder", "Titanite Shard"), DS3LocationData("US: Red Hilted Halberd - chasm crypt", "Red Hilted Halberd"), DS3LocationData("US: Rusted Coin - awning above Dilapidated Bridge", "Rusted Coin x2"), @@ -688,32 +686,32 @@ def __init__( DS3LocationData("US: Titanite Shard - chasm #2", "Titanite Shard"), DS3LocationData("US: Fading Soul - outside stable", "Fading Soul"), DS3LocationData("US: Titanite Shard - lower path to Cliff Underside", "Titanite Shard", - hidden = True), # hidden fall + hidden=True), # hidden fall DS3LocationData("US: Hand Axe - by Cornyx", "Hand Axe"), DS3LocationData("US: Soul of an Unknown Traveler - pillory past stable", "Soul of an Unknown Traveler"), DS3LocationData("US: Ember - by stairs to boss", "Ember"), DS3LocationData("US: Mirrah Vest - tower village, jump from roof", "Mirrah Vest", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("US: Mirrah Gloves - tower village, jump from roof", "Mirrah Gloves", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("US: Mirrah Trousers - tower village, jump from roof", "Mirrah Trousers", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("US: Plank Shield - outside stable, by NPC", "Plank Shield"), DS3LocationData("US: Red Bug Pellet - tower village building, basement", "Red Bug Pellet x2"), DS3LocationData("US: Chloranthy Ring - tower village, jump from roof", "Chloranthy Ring", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("US: Fire Clutch Ring - wooden walkway past stable", "Fire Clutch Ring"), DS3LocationData("US: Estus Shard - under burning tree", "Estus Shard"), DS3LocationData("US: Firebomb - stable roof", "Firebomb x6"), # In enemy rando, the enemy may not burst through the wall and make this room obvious - DS3LocationData("US: Whip - back alley, behind wooden wall", "Whip", hidden = True), + DS3LocationData("US: Whip - back alley, behind wooden wall", "Whip", hidden=True), DS3LocationData("US: Great Scythe - building by white tree, balcony", "Great Scythe"), - DS3LocationData("US: Homeward Bone - foot, drop overloop", "Homeward Bone", - offline = '02,0:53100540::'), + DS3LocationData("US: Homeward Bone - foot, drop overlook", "Homeward Bone", + offline='02,0:53100540::'), DS3LocationData("US: Large Soul of a Deserted Corpse - around corner by Cliff Underside", - "Large Soul of a Deserted Corpse", hidden = True), # Hidden corner + "Large Soul of a Deserted Corpse", hidden=True), # Hidden corner DS3LocationData("US: Ember - behind burning tree", "Ember"), DS3LocationData("US: Large Soul of a Deserted Corpse - across from Foot of the High Wall", "Large Soul of a Deserted Corpse"), @@ -734,127 +732,127 @@ def __init__( DS3LocationData("US: Northern Trousers - tower village, hanging corpse", "Northern Trousers"), DS3LocationData("US: Partizan - hanging corpse above Cliff Underside", "Partizan", - missable = True), # requires projectile + missable=True), # requires projectile DS3LocationData("US: Flame Stoneplate Ring - hanging corpse by Mound-Maker transport", "Flame Stoneplate Ring"), DS3LocationData("US: Red and White Shield - chasm, hanging corpse", "Red and White Shield", - offline = "02,0:53100740::", missable = True), # requires projectile + offline="02,0:53100740::", missable=True), # requires projectile DS3LocationData("US: Small Leather Shield - first building, hanging corpse by entrance", "Small Leather Shield"), DS3LocationData("US: Pale Tongue - tower village, hanging corpse", "Pale Tongue"), DS3LocationData("US: Large Soul of a Deserted Corpse - hanging corpse room, over stairs", "Large Soul of a Deserted Corpse"), DS3LocationData("US: Kukri - hanging corpse above burning tree", "Kukri x9", - missable = True), # requires projectile - DS3LocationData("US: Life Ring+1 - tower on the way to village", "Life Ring+1", ngp = True), + missable=True), # requires projectile + DS3LocationData("US: Life Ring+1 - tower on the way to village", "Life Ring+1", ngp=True), DS3LocationData("US: Poisonbite Ring+1 - graveyard by white tree, near well", - "Poisonbite Ring+1", ngp = True), + "Poisonbite Ring+1", ngp=True), DS3LocationData("US: Covetous Silver Serpent Ring+2 - tower village, drop down from roof", - "Covetous Silver Serpent Ring+2", ngp = True, hidden = True), # Hidden fall + "Covetous Silver Serpent Ring+2", ngp=True, hidden=True), # Hidden fall DS3LocationData("US: Human Pine Resin - tower village building, chest upstairs", "Human Pine Resin x4"), DS3LocationData("US: Homeward Bone - tower village, right at start", "Homeward Bone", - offline = '02,0:53100540::'), + offline='02,0:53100540::'), DS3LocationData("US: Irithyll Straight Sword - miniboss drop, by Road of Sacrifices", - "Irithyll Straight Sword", miniboss = True), - DS3LocationData("US: Fire Gem - tower village, miniboss drop", "Fire Gem", miniboss = True), + "Irithyll Straight Sword", miniboss=True), + DS3LocationData("US: Fire Gem - tower village, miniboss drop", "Fire Gem", miniboss=True), DS3LocationData("US: Warrior of Sunlight - hanging corpse room, drop through hole", - "Warrior of Sunlight", hidden = True), # hidden fall - DS3LocationData("US: Mound-makers - Hodrick", "Mound-makers", missable = True), - DS3LocationData("US: Sharp Gem - lizard by Dilapidated Bridge", "Sharp Gem", lizard = True), - DS3LocationData("US: Heavy Gem - chasm, lizard", "Heavy Gem", lizard = True), - DS3LocationData("US: Siegbräu - Siegward", "Siegbräu", missable = True, npc = True), - DS3LocationData("US: Heavy Gem - Hawkwood", "Heavy Gem", offline = '00,0:50006070::', - missable = True, npc = True), # Hawkwood (quest, after Greatwood or Sage) + "Warrior of Sunlight", hidden=True), # hidden fall + DS3LocationData("US: Mound-makers - Hodrick", "Mound-makers", missable=True), + DS3LocationData("US: Sharp Gem - lizard by Dilapidated Bridge", "Sharp Gem", lizard=True), + DS3LocationData("US: Heavy Gem - chasm, lizard", "Heavy Gem", lizard=True), + DS3LocationData("US: Siegbräu - Siegward", "Siegbräu", missable=True, npc=True), + DS3LocationData("US: Heavy Gem - Hawkwood", "Heavy Gem", offline='00,0:50006070::', + missable=True, npc=True), # Hawkwood (quest, after Greatwood or Sage) DS3LocationData("US -> RS", None), # Yoel/Yuria of Londor DS3LocationData("FS: Soul Arrow - Yoel/Yuria", "Soul Arrow", - offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, - shop = True), + offline='99,0:-1:50000,110000,70000116:', missable=True, npc=True, + shop=True), DS3LocationData("FS: Heavy Soul Arrow - Yoel/Yuria", "Heavy Soul Arrow", - offline = '99,0:-1:50000,110000,70000116:', - missable = True, npc = True, shop = True), + offline='99,0:-1:50000,110000,70000116:', + missable=True, npc=True, shop=True), DS3LocationData("FS: Magic Weapon - Yoel/Yuria", "Magic Weapon", - offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, - shop = True), + offline='99,0:-1:50000,110000,70000116:', missable=True, npc=True, + shop=True), DS3LocationData("FS: Magic Shield - Yoel/Yuria", "Magic Shield", - offline = '99,0:-1:50000,110000,70000116:', missable = True, npc = True, - shop = True), + offline='99,0:-1:50000,110000,70000116:', missable=True, npc=True, + shop=True), DS3LocationData("FS: Soul Greatsword - Yoel/Yuria", "Soul Greatsword", - offline = '99,0:-1:50000,110000,70000450,70000475:', missable = True, - npc = True, shop = True), - DS3LocationData("FS: Dark Hand - Yoel/Yuria", "Dark Hand", missable = True, npc = True), - DS3LocationData("FS: Untrue White Ring - Yoel/Yuria", "Untrue White Ring", missable = True, - npc = True), - DS3LocationData("FS: Untrue Dark Ring - Yoel/Yuria", "Untrue Dark Ring", missable = True, - npc = True), + offline='99,0:-1:50000,110000,70000450,70000475:', missable=True, + npc=True, shop=True), + DS3LocationData("FS: Dark Hand - Yoel/Yuria", "Dark Hand", missable=True, npc=True), + DS3LocationData("FS: Untrue White Ring - Yoel/Yuria", "Untrue White Ring", missable=True, + npc=True), + DS3LocationData("FS: Untrue Dark Ring - Yoel/Yuria", "Untrue Dark Ring", missable=True, + npc=True), DS3LocationData("FS: Londor Braille Divine Tome - Yoel/Yuria", "Londor Braille Divine Tome", - offline = '99,0:-1:40000,110000,70000116:', missable = True, npc = True), - DS3LocationData("FS: Darkdrift - Yoel/Yuria", "Darkdrift", missable = True, drop = True, - npc = True), # kill her or kill Soul of Cinder + offline='99,0:-1:40000,110000,70000116:', missable=True, npc=True), + DS3LocationData("FS: Darkdrift - Yoel/Yuria", "Darkdrift", missable=True, drop=True, + npc=True), # kill her or kill Soul of Cinder # Cornyx of the Great Swamp # These aren't missable because the Shrine Handmaid will carry them if you kill Cornyx. - DS3LocationData("FS: Fireball - Cornyx", "Fireball", npc = True, shop = True), - DS3LocationData("FS: Fire Surge - Cornyx", "Fire Surge", npc = True, shop = True), - DS3LocationData("FS: Great Combustion - Cornyx", "Great Combustion", npc = True, - shop = True), - DS3LocationData("FS: Flash Sweat - Cornyx", "Flash Sweat", npc = True, shop = True), + DS3LocationData("FS: Fireball - Cornyx", "Fireball", npc=True, shop=True), + DS3LocationData("FS: Fire Surge - Cornyx", "Fire Surge", npc=True, shop=True), + DS3LocationData("FS: Great Combustion - Cornyx", "Great Combustion", npc=True, + shop=True), + DS3LocationData("FS: Flash Sweat - Cornyx", "Flash Sweat", npc=True, shop=True), # These are missable if you kill Cornyx before giving him the right tomes. DS3LocationData("FS: Poison Mist - Cornyx for Great Swamp Tome", "Poison Mist", - missable = True, npc = True, shop = True), - DS3LocationData("FS: Fire Orb - Cornyx for Great Swamp Tome", "Fire Orb", missable = True, - npc = True, shop = True), + missable=True, npc=True, shop=True), + DS3LocationData("FS: Fire Orb - Cornyx for Great Swamp Tome", "Fire Orb", missable=True, + npc=True, shop=True), DS3LocationData("FS: Profuse Sweat - Cornyx for Great Swamp Tome", "Profuse Sweat", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), DS3LocationData("FS: Bursting Fireball - Cornyx for Great Swamp Tome", "Bursting Fireball", - missable = True, npc = True, shop = True), - DS3LocationData("FS: Acid Surge - Cornyx for Carthus Tome", "Acid Surge", missable = True, - npc = True, shop = True), + missable=True, npc=True, shop=True), + DS3LocationData("FS: Acid Surge - Cornyx for Carthus Tome", "Acid Surge", missable=True, + npc=True, shop=True), DS3LocationData("FS: Carthus Flame Arc - Cornyx for Carthus Tome", "Carthus Flame Arc", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), DS3LocationData("FS: Carthus Beacon - Cornyx for Carthus Tome", "Carthus Beacon", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), DS3LocationData("FS: Great Chaos Fire Orb - Cornyx for Izalith Tome", - "Great Chaos Fire Orb", missable = True, npc = True, shop = True), - DS3LocationData("FS: Chaos Storm - Cornyx for Izalith Tome", "Chaos Storm", missable = True, - npc = True, shop = True), + "Great Chaos Fire Orb", missable=True, npc=True, shop=True), + DS3LocationData("FS: Chaos Storm - Cornyx for Izalith Tome", "Chaos Storm", missable=True, + npc=True, shop=True), # Irina of Carim # These aren't in their own location because you don't actually need the Grave Key to access # Irena—you can just fall down the cliff near Eygon. - DS3LocationData("FS: Saint's Ring - Irina", "Saint's Ring", npc = True, shop = True), - DS3LocationData("FS: Heal - Irina", "Heal", npc = True, shop = True), - DS3LocationData("FS: Replenishment - Irina", "Replenishment", npc = True, shop = True), - DS3LocationData("FS: Caressing Tears - Irina", "Caressing Tears", npc = True, shop = True), - DS3LocationData("FS: Homeward - Irina", "Homeward", npc = True, shop = True), - DS3LocationData("FS: Med Heal - Irina for Tome of Carim", "Med Heal", missable = True, - npc = True, shop = True), + DS3LocationData("FS: Saint's Ring - Irina", "Saint's Ring", npc=True, shop=True), + DS3LocationData("FS: Heal - Irina", "Heal", npc=True, shop=True), + DS3LocationData("FS: Replenishment - Irina", "Replenishment", npc=True, shop=True), + DS3LocationData("FS: Caressing Tears - Irina", "Caressing Tears", npc=True, shop=True), + DS3LocationData("FS: Homeward - Irina", "Homeward", npc=True, shop=True), + DS3LocationData("FS: Med Heal - Irina for Tome of Carim", "Med Heal", missable=True, + npc=True, shop=True), DS3LocationData("FS: Tears of Denial - Irina for Tome of Carim", "Tears of Denial", - missable = True, npc = True, shop = True), - DS3LocationData("FS: Force - Irina for Tome of Carim", "Force", missable = True, npc = True, - shop = True), + missable=True, npc=True, shop=True), + DS3LocationData("FS: Force - Irina for Tome of Carim", "Force", missable=True, npc=True, + shop=True), DS3LocationData("FS: Bountiful Light - Irina for Tome of Lothric", "Bountiful Light", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), DS3LocationData("FS: Magic Barrier - Irina for Tome of Lothric", "Magic Barrier", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), DS3LocationData("FS: Blessed Weapon - Irina for Tome of Lothric", "Blessed Weapon", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), ], "Road of Sacrifices": [ - DS3LocationData("RS: Soul of a Crystal Sage", "Soul of a Crystal Sage", prominent = True, - boss = True), + DS3LocationData("RS: Soul of a Crystal Sage", "Soul of a Crystal Sage", prominent=True, + boss=True), DS3LocationData("RS: Exile Greatsword - NPC drop by Farron Keep", "Exile Greatsword", - hostile_npc = True), # Exile Knight #2 drop + hostile_npc=True), # Exile Knight #2 drop DS3LocationData("RS: Great Club - NPC drop by Farron Keep", "Great Club", - hostile_npc = True), # Exile Knight #1 drop - DS3LocationData("RS: Heysel Pick - Heysel drop", "Heysel Pick", missable = True, - hostile_npc = True), - DS3LocationData("RS: Xanthous Crown - Heysel drop", "Xanthous Crown", missable = True, - hostile_npc = True), + hostile_npc=True), # Exile Knight #1 drop + DS3LocationData("RS: Heysel Pick - Heysel drop", "Heysel Pick", missable=True, + hostile_npc=True), + DS3LocationData("RS: Xanthous Crown - Heysel drop", "Xanthous Crown", missable=True, + hostile_npc=True), DS3LocationData("RS: Butcher Knife - NPC drop beneath road", "Butcher Knife", - hostile_npc = True), # Madwoman + hostile_npc=True), # Madwoman DS3LocationData("RS: Titanite Shard - water by Halfway Fortress", "Titanite Shard"), DS3LocationData("RS: Titanite Shard - woods, left of path from Halfway Fortress", "Titanite Shard"), @@ -862,7 +860,7 @@ def __init__( DS3LocationData("RS: Estus Shard - left of fire behind stronghold left room", "Estus Shard"), DS3LocationData("RS: Ring of Sacrifice - stronghold, drop from right room balcony", - "Ring of Sacrifice", hidden = True), # hidden fall + "Ring of Sacrifice", hidden=True), # hidden fall DS3LocationData("RS: Soul of an Unknown Traveler - drop along wall from Halfway Fortress", "Soul of an Unknown Traveler"), DS3LocationData("RS: Fallen Knight Helm - water's edge by Farron Keep", @@ -890,15 +888,15 @@ def __init__( DS3LocationData("RS: Twin Dragon Greatshield - woods by Crucifixion Woods bonfire", "Twin Dragon Greatshield"), DS3LocationData("RS: Sorcerer Hood - water beneath stronghold", "Sorcerer Hood", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("RS: Sorcerer Robe - water beneath stronghold", "Sorcerer Robe", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("RS: Sorcerer Gloves - water beneath stronghold", "Sorcerer Gloves", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("RS: Sorcerer Trousers - water beneath stronghold", "Sorcerer Trousers", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("RS: Sage Ring - water beneath stronghold", "Sage Ring", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("RS: Grass Crest Shield - water by Crucifixion Woods bonfire", "Grass Crest Shield"), DS3LocationData("RS: Ember - right of fire behind stronghold left room", "Ember"), @@ -910,7 +908,7 @@ def __init__( "Titanite Shard"), DS3LocationData("RS: Brigand Twindaggers - beneath road", "Brigand Twindaggers"), DS3LocationData("RS: Braille Divine Tome of Carim - drop from bridge to Halfway Fortress", - "Braille Divine Tome of Carim", hidden = True), # Hidden fall + "Braille Divine Tome of Carim", hidden=True), # Hidden fall DS3LocationData("RS: Ember - right of Halfway Fortress entrance", "Ember"), DS3LocationData("RS: Sellsword Twinblades - keep perimeter", "Sellsword Twinblades"), DS3LocationData("RS: Golden Falcon Shield - path from stronghold right room to Farron Keep", @@ -921,104 +919,104 @@ def __init__( DS3LocationData("RS: Brigand Gauntlets - beneath road", "Brigand Gauntlets"), DS3LocationData("RS: Brigand Trousers - beneath road", "Brigand Trousers"), DS3LocationData("RS: Morne's Ring - drop from bridge to Halfway Fortress", "Morne's Ring", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("RS: Sellsword Helm - keep perimeter balcony", "Sellsword Helm"), DS3LocationData("RS: Sellsword Armor - keep perimeter balcony", "Sellsword Armor"), DS3LocationData("RS: Sellsword Gauntlet - keep perimeter balcony", "Sellsword Gauntlet"), DS3LocationData("RS: Sellsword Trousers - keep perimeter balcony", "Sellsword Trousers"), DS3LocationData("RS: Farron Coal - keep perimeter", "Farron Coal"), DS3LocationData("RS: Chloranthy Ring+2 - road, drop across from carriage", - "Chloranthy Ring+2", hidden = True, ngp = True), # Hidden fall + "Chloranthy Ring+2", hidden=True, ngp=True), # Hidden fall DS3LocationData("RS: Lingering Dragoncrest Ring+1 - water", "Lingering Dragoncrest Ring+1", - ngp = True), + ngp=True), DS3LocationData("RS: Great Swamp Ring - miniboss drop, by Farron Keep", - "Great Swamp Ring", miniboss = True), # Giant Crab drop + "Great Swamp Ring", miniboss=True), # Giant Crab drop DS3LocationData("RS: Blue Sentinels - Horace", "Blue Sentinels", - missable = True, npc = True), # Horace quest + missable=True, npc=True), # Horace quest DS3LocationData("RS: Crystal Gem - stronghold, lizard", "Crystal Gem"), DS3LocationData("RS: Fading Soul - woods by Crucifixion Woods bonfire", "Fading Soul", - offline = '03,0:53300210::'), + offline='03,0:53300210::'), # Orbeck shop, all missable because he'll disappear if you don't talk to him for too long or # if you don't give him a scroll. DS3LocationData("FS: Farron Dart - Orbeck", "Farron Dart", - offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, - shop = True), + offline='99,0:-1:110000,130100,70000111:', missable=True, npc=True, + shop=True), DS3LocationData("FS: Soul Arrow - Orbeck", "Soul Arrow", - offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, - shop = True), - DS3LocationData("FS: Great Soul Arrow - Orbeck", "Great Soul Arrow", missable = True, - npc = True, shop = True), + offline='99,0:-1:110000,130100,70000111:', missable=True, npc=True, + shop=True), + DS3LocationData("FS: Great Soul Arrow - Orbeck", "Great Soul Arrow", missable=True, + npc=True, shop=True), DS3LocationData("FS: Heavy Soul Arrow - Orbeck", "Heavy Soul Arrow", - offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, - shop = True), + offline='99,0:-1:110000,130100,70000111:', missable=True, npc=True, + shop=True), DS3LocationData("FS: Great Heavy Soul Arrow - Orbeck", "Great Heavy Soul Arrow", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), DS3LocationData("FS: Magic Weapon - Orbeck", "Magic Weapon", - offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, - shop = True), + offline='99,0:-1:110000,130100,70000111:', missable=True, npc=True, + shop=True), DS3LocationData("FS: Magic Shield - Orbeck", "Magic Shield", - offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True, - shop = True), - DS3LocationData("FS: Spook - Orbeck", "Spook", missable = True, npc = True, shop = True), - DS3LocationData("FS: Aural Decoy - Orbeck", "Aural Decoy", missable = True, npc = True, - shop = True), + offline='99,0:-1:110000,130100,70000111:', missable=True, npc=True, + shop=True), + DS3LocationData("FS: Spook - Orbeck", "Spook", missable=True, npc=True, shop=True), + DS3LocationData("FS: Aural Decoy - Orbeck", "Aural Decoy", missable=True, npc=True, + shop=True), DS3LocationData("FS: Soul Greatsword - Orbeck", "Soul Greatsword", - offline = '99,0:-1:110000,130100,70000111:', missable = True, npc = True), - DS3LocationData("FS: Farron Flashsword - Orbeck", "Farron Flashsword", missable = True, - npc = True, shop = True), + offline='99,0:-1:110000,130100,70000111:', missable=True, npc=True), + DS3LocationData("FS: Farron Flashsword - Orbeck", "Farron Flashsword", missable=True, + npc=True, shop=True), DS3LocationData("FS: Pestilent Mist - Orbeck for any scroll", "Pestilent Mist", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), DS3LocationData("FS: Great Farron Dart - Orbeck for Sage's Scroll", "Great Farron Dart", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), DS3LocationData("FS: Farron Hail - Orbeck for Sage's Scroll", "Farron Hail", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), DS3LocationData("FS: Homing Soulmass - Orbeck for Logan's Scroll", "Homing Soulmass", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), DS3LocationData("FS: Soul Spear - Orbeck for Logan's Scroll", "Soul Spear", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), DS3LocationData("FS: Homing Crystal Soulmass - Orbeck for Crystal Scroll", - "Homing Crystal Soulmass", missable = True, npc = True, shop = True), + "Homing Crystal Soulmass", missable=True, npc=True, shop=True), DS3LocationData("FS: Crystal Soul Spear - Orbeck for Crystal Scroll", "Crystal Soul Spear", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), DS3LocationData("FS: Crystal Magic Weapon - Orbeck for Crystal Scroll", - "Crystal Magic Weapon", missable = True, npc = True, shop = True), - DS3LocationData("FS: Cast Light - Orbeck for Golden Scroll", "Cast Light", missable = True, - npc = True, shop = True), + "Crystal Magic Weapon", missable=True, npc=True, shop=True), + DS3LocationData("FS: Cast Light - Orbeck for Golden Scroll", "Cast Light", missable=True, + npc=True, shop=True), DS3LocationData("FS: Twisted Wall of Light - Orbeck for Golden Scroll", - "Twisted Wall of Light", missable = True, npc = True, shop = True), + "Twisted Wall of Light", missable=True, npc=True, shop=True), DS3LocationData("FS: Hidden Weapon - Orbeck for Golden Scroll", "Hidden Weapon", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), DS3LocationData("FS: Hidden Body - Orbeck for Golden Scroll", "Hidden Body", - missable = True, npc = True, shop = True), - DS3LocationData("FS: Repair - Orbeck for Golden Scroll", "Repair", missable = True, - npc = True, shop = True), + missable=True, npc=True, shop=True), + DS3LocationData("FS: Repair - Orbeck for Golden Scroll", "Repair", missable=True, + npc=True, shop=True), DS3LocationData("FS: Clandestine Coat - shop with Orbeck's Ashes", "Clandestine Coat", - missable = True, npc = True, - shop = True), # Shrine Handmaid with Orbeck's Ashes + reload + missable=True, npc=True, + shop=True), # Shrine Handmaid with Orbeck's Ashes + reload DS3LocationData("FS: Young Dragon Ring - Orbeck for one scroll and buying three spells", - "Young Dragon Ring", missable = True, npc = True), + "Young Dragon Ring", missable=True, npc=True), DS3LocationData("FS: Slumbering Dragoncrest Ring - Orbeck for buying four specific spells", - "Slumbering Dragoncrest Ring", missable = True, npc = True), + "Slumbering Dragoncrest Ring", missable=True, npc=True), DS3LocationData("RS -> FK", None), # Shrine Handmaid after killing exiles DS3LocationData("FS: Exile Mask - shop after killing NPCs in RS", "Exile Mask", - hostile_npc = True, shop = True, hidden = True), + hostile_npc=True, shop=True, hidden=True), DS3LocationData("FS: Exile Armor - shop after killing NPCs in RS", "Exile Armor", - hostile_npc = True, shop = True, hidden = True), + hostile_npc=True, shop=True, hidden=True), DS3LocationData("FS: Exile Gauntlets - shop after killing NPCs in RS", "Exile Gauntlets", - hostile_npc = True, shop = True, hidden = True), + hostile_npc=True, shop=True, hidden=True), DS3LocationData("FS: Exile Leggings - shop after killing NPCs in RS", "Exile Leggings", - hostile_npc = True, shop = True, hidden = True), + hostile_npc=True, shop=True, hidden=True), # Shrine Handmaid after killing Crystal Sage DS3LocationData("FS: Sage's Big Hat - shop after killing RS boss", "Sage's Big Hat", - boss = True, shop = True), + boss=True, shop=True), # Yuria of Londor for Orbeck's Ashes DS3LocationData("FS: Morion Blade - Yuria for Orbeck's Ashes", "Morion Blade", - missable = True, npc = True), + missable=True, npc=True), ], "Cathedral of the Deep": [ DS3LocationData("CD: Herald Helm - path, by fire", "Herald Helm"), @@ -1026,19 +1024,19 @@ def __init__( DS3LocationData("CD: Herald Gloves - path, by fire", "Herald Gloves"), DS3LocationData("CD: Herald Trousers - path, by fire", "Herald Trousers"), DS3LocationData("CD: Twinkling Titanite - path, lizard #1", "Twinkling Titanite", - lizard = True), + lizard=True), DS3LocationData("CD: Twinkling Titanite - path, lizard #2", "Twinkling Titanite", - lizard = True), - DS3LocationData("CD: Small Doll - boss drop", "Small Doll", prominent = True, - progression = True, boss = True), + lizard=True), + DS3LocationData("CD: Small Doll - boss drop", "Small Doll", prominent=True, + progression=True, boss=True), DS3LocationData("CD: Soul of the Deacons of the Deep", "Soul of the Deacons of the Deep", - boss = True), + boss=True), DS3LocationData("CD: Black Eye Orb - Rosaria from Leonhard's quest", "Black Eye Orb", - missable = True, npc = True), - DS3LocationData("CD: Winged Spear - kill Patches", "Winged Spear", drop = True, - missable = True), # Patches (kill) + missable=True, npc=True), + DS3LocationData("CD: Winged Spear - kill Patches", "Winged Spear", drop=True, + missable=True), # Patches (kill) DS3LocationData("CD: Spider Shield - NPC drop on path", "Spider Shield", - hostile_npc = True), # Brigand + hostile_npc=True), # Brigand DS3LocationData("CD: Notched Whip - Cleansing Chapel", "Notched Whip"), DS3LocationData("CD: Titanite Shard - Cleansing Chapel windowsill, by miniboss", "Titanite Shard"), @@ -1052,7 +1050,7 @@ def __init__( DS3LocationData("CD: Large Soul of an Unknown Traveler - lower roofs, semicircle balcony", "Large Soul of an Unknown Traveler"), DS3LocationData("CD: Paladin's Ashes - path, guarded by lower NPC", "Paladin's Ashes", - progression = True), + progression=True), DS3LocationData("CD: Arbalest - upper roofs, end of furthest buttress", "Arbalest"), DS3LocationData("CD: Ember - by back door", "Ember"), DS3LocationData("CD: Ember - side chapel upstairs, up ladder", "Ember"), @@ -1086,10 +1084,10 @@ def __init__( DS3LocationData("CD: Red Bug Pellet - lower roofs, up stairs between buttresses", "Red Bug Pellet x3"), DS3LocationData("CD: Titanite Shard - outside building by white tree", "Titanite Shard", - hidden = True), # Easily missable side path + hidden=True), # Easily missable side path DS3LocationData("CD: Titanite Shard - moat, up a slope", "Titanite Shard"), DS3LocationData("CD: Rusted Coin - left of cathedral front doors, behind crates", - "Rusted Coin x2", hidden = True), + "Rusted Coin x2", hidden=True), DS3LocationData("CD: Drang Hammers - main hall east", "Drang Hammers"), DS3LocationData("CD: Drang Shoes - main hall east", "Drang Shoes"), DS3LocationData("CD: Large Soul of an Unknown Traveler - main hall east", @@ -1111,70 +1109,70 @@ def __init__( "Large Soul of an Unknown Traveler"), # Before the stairs leading down into the Deacons fight DS3LocationData("CD: Ring of the Evil Eye+1 - by stairs to boss", "Ring of the Evil Eye+1", - ngp = True), + ngp=True), DS3LocationData("CD: Ring of Favor+2 - upper roofs, on buttress", "Ring of Favor+2", - hidden = True, ngp = True), # Hidden fall + hidden=True, ngp=True), # Hidden fall DS3LocationData("CD: Crest Shield - path, drop down by Cathedral of the Deep bonfire", - "Crest Shield", hidden = True), # Hidden fall + "Crest Shield", hidden=True), # Hidden fall DS3LocationData("CD: Young White Branch - by white tree #1", "Young White Branch"), DS3LocationData("CD: Young White Branch - by white tree #2", "Young White Branch"), DS3LocationData("CD: Saint-tree Bellvine - moat, by water", "Saint-tree Bellvine"), DS3LocationData("CD: Saint Bident - outside main hall south door", "Saint Bident"), # Archdeacon set is hidden because you have to return to a cleared area DS3LocationData("CD: Archdeacon White Crown - boss room after killing boss", - "Archdeacon White Crown", boss = True, hidden = True), + "Archdeacon White Crown", boss=True, hidden=True), DS3LocationData("CD: Archdeacon Holy Garb - boss room after killing boss", - "Archdeacon Holy Garb", boss = True, hidden = True), + "Archdeacon Holy Garb", boss=True, hidden=True), DS3LocationData("CD: Archdeacon Skirt - boss room after killing boss", "Archdeacon Skirt", - boss = True, hidden = True), + boss=True, hidden=True), # Heysel items may not be missable, but it's not clear what causes them to trigger DS3LocationData("CD: Heysel Pick - Heysel Corpse-Grub in Rosaria's Bed Chamber", - "Heysel Pick", missable = True), + "Heysel Pick", missable=True), DS3LocationData("CD: Xanthous Crown - Heysel Corpse-Grub in Rosaria's Bed Chamber", - "Xanthous Crown", missable = True), + "Xanthous Crown", missable=True), DS3LocationData("CD: Deep Ring - upper roofs, passive mob drop in first tower", "Deep Ring", - drop = True, hidden = True), + drop=True, hidden=True), DS3LocationData("CD: Deep Braille Divine Tome - mimic by side chapel", - "Deep Braille Divine Tome", mimic = True), + "Deep Braille Divine Tome", mimic=True), DS3LocationData("CD: Red Sign Soapstone - passive mob drop by Rosaria's Bed Chamber", - "Red Sign Soapstone", drop = True, hidden = True), + "Red Sign Soapstone", drop=True, hidden=True), DS3LocationData("CD: Aldrich's Sapphire - side chapel, miniboss drop", "Aldrich's Sapphire", - miniboss = True), # Deep Accursed Drop + miniboss=True), # Deep Accursed Drop DS3LocationData("CD: Titanite Scale - moat, miniboss drop", "Titanite Scale", - miniboss = True), # Ravenous Crystal Lizard drop + miniboss=True), # Ravenous Crystal Lizard drop DS3LocationData("CD: Twinkling Titanite - moat, lizard #1", "Twinkling Titanite", - lizard = True), + lizard=True), DS3LocationData("CD: Twinkling Titanite - moat, lizard #2", "Twinkling Titanite", - lizard = True), + lizard=True), DS3LocationData("CD: Rosaria's Fingers - Rosaria", "Rosaria's Fingers", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("CD -> PW1", None), # Longfinger Kirk drops DS3LocationData("CD: Barbed Straight Sword - Kirk drop", "Barbed Straight Sword", - missable = True, hostile_npc = True), - DS3LocationData("CD: Spiked Shield - Kirk drop", "Spiked Shield", missable = True, - hostile_npc = True), + missable=True, hostile_npc=True), + DS3LocationData("CD: Spiked Shield - Kirk drop", "Spiked Shield", missable=True, + hostile_npc=True), # In Rosaria's Bed Chamber DS3LocationData("CD: Helm of Thorns - Rosaria's Bed Chamber after killing Kirk", - "Helm of Thorns", missable = True, hostile_npc = True), + "Helm of Thorns", missable=True, hostile_npc=True), DS3LocationData("CD: Armor of Thorns - Rosaria's Bed Chamber after killing Kirk", - "Armor of Thorns", missable = True, hostile_npc = True), + "Armor of Thorns", missable=True, hostile_npc=True), DS3LocationData("CD: Gauntlets of Thorns - Rosaria's Bed Chamber after killing Kirk", - "Gauntlets of Thorns", missable = True, hostile_npc = True), + "Gauntlets of Thorns", missable=True, hostile_npc=True), DS3LocationData("CD: Leggings of Thorns - Rosaria's Bed Chamber after killing Kirk", - "Leggings of Thorns", missable = True, hostile_npc = True), + "Leggings of Thorns", missable=True, hostile_npc=True), # Unbreakable Patches DS3LocationData("CD: Rusted Coin - don't forgive Patches", "Rusted Coin", - missable = True, npc = True), + missable=True, npc=True), DS3LocationData("FS: Rusted Gold Coin - don't forgive Patches", "Rusted Gold Coin", - offline = '99,0:50006201::', missable = True, - npc = True), # Don't forgive Patches - DS3LocationData("CD: Shotel - Patches", "Shotel", missable = True, npc = True, shop = True), - DS3LocationData("CD: Ember - Patches", "Ember", missable = True, npc = True, shop = True), - DS3LocationData("CD: Horsehoof Ring - Patches", "Horsehoof Ring", missable = True, - npc = True, drop = True, shop = True), # (kill or buy) + offline='99,0:50006201::', missable=True, + npc=True), # Don't forgive Patches + DS3LocationData("CD: Shotel - Patches", "Shotel", missable=True, npc=True, shop=True), + DS3LocationData("CD: Ember - Patches", "Ember", missable=True, npc=True, shop=True), + DS3LocationData("CD: Horsehoof Ring - Patches", "Horsehoof Ring", missable=True, + npc=True, drop=True, shop=True), # (kill or buy) ], "Farron Keep": [ DS3LocationData("FK: Lightning Spear - upper keep, far side of the wall", @@ -1182,34 +1180,34 @@ def __init__( DS3LocationData("FK: Dragon Crest Shield - upper keep, far side of the wall", "Dragon Crest Shield"), DS3LocationData("FK: Soul of the Blood of the Wolf", "Soul of the Blood of the Wolf", - boss = True), + boss=True), DS3LocationData("FK: Cinders of a Lord - Abyss Watcher", "Cinders of a Lord - Abyss Watcher", - offline = "03,0:50002100::", prominent = True, progression = True, - boss = True), + offline="03,0:50002100::", prominent=True, progression=True, + boss=True), DS3LocationData("FK: Manikin Claws - Londor Pale Shade drop", "Manikin Claws", - missable = True, hostile_npc = True, - npc = True), # Londor Pale Shade (if Yoel/Yuria hostile) + missable=True, hostile_npc=True, + npc=True), # Londor Pale Shade (if Yoel/Yuria hostile) DS3LocationData("FK: Purple Moss Clump - keep ruins, ritual island", "Purple Moss Clump x2"), DS3LocationData("FK: Purple Moss Clump - ramp directly in front of Farron Keep bonfire", "Purple Moss Clump x4"), DS3LocationData("FK: Greatsword - ramp by keep ruins ritual island", "Greatsword"), DS3LocationData("FK: Hollow Gem - perimeter, drop down into swamp", "Hollow Gem", - hidden = True), + hidden=True), DS3LocationData("FK: Purple Moss Clump - Farron Keep bonfire, around right corner", "Purple Moss Clump x3"), DS3LocationData("FK: Undead Bone Shard - pavilion by keep ruins bonfire island", "Undead Bone Shard"), DS3LocationData("FK: Atonement - perimeter, drop down into swamp", "Atonement", - hidden = True), + hidden=True), DS3LocationData("FK: Titanite Shard - by ladder to keep proper", "Titanite Shard"), DS3LocationData("FK: Iron Flesh - Farron Keep bonfire, right after exit", "Iron Flesh"), DS3LocationData("FK: Stone Parma - near wall by left island", "Stone Parma"), DS3LocationData("FK: Rotten Pine Resin - left island, behind fire", "Rotten Pine Resin x2"), DS3LocationData("FK: Titanite Shard - between left island and keep ruins", "Titanite Shard"), DS3LocationData("FK: Rusted Gold Coin - right island, behind wall", "Rusted Gold Coin", - hidden = True), + hidden=True), DS3LocationData("FK: Nameless Knight Helm - corner of keep and right island", "Nameless Knight Helm"), DS3LocationData("FK: Nameless Knight Armor - corner of keep and right island", @@ -1220,12 +1218,12 @@ def __init__( "Nameless Knight Leggings"), DS3LocationData("FK: Shriving Stone - perimeter, just past stone doors", "Shriving Stone"), DS3LocationData("FK: Repair Powder - outside hidden cave", "Repair Powder x4", - hidden = True), - DS3LocationData("FK: Golden Scroll - hidden cave", "Golden Scroll", hidden = True), + hidden=True), + DS3LocationData("FK: Golden Scroll - hidden cave", "Golden Scroll", hidden=True), DS3LocationData("FK: Sage's Scroll - near wall by keep ruins bonfire island", "Sage's Scroll"), DS3LocationData("FK: Dreamchaser's Ashes - keep proper, illusory wall", - "Dreamchaser's Ashes", progression = True, hidden = True), + "Dreamchaser's Ashes", progression=True, hidden=True), DS3LocationData("FK: Titanite Shard - keep ruins bonfire island, under ramp", "Titanite Shard"), DS3LocationData("FK: Wolf's Blood Swordgrass - by ladder to keep proper", @@ -1248,7 +1246,7 @@ def __init__( DS3LocationData("FK: Titanite Shard - Farron Keep bonfire, left after exit", "Titanite Shard"), DS3LocationData("FK: Large Soul of a Nameless Soldier - corner of keep and right island", - "Large Soul of a Nameless Soldier", hidden = True), # Tricky corner to spot + "Large Soul of a Nameless Soldier", hidden=True), # Tricky corner to spot DS3LocationData("FK: Prism Stone - by left island stairs", "Prism Stone x10"), DS3LocationData("FK: Large Soul of a Nameless Soldier - near wall by right island", "Large Soul of a Nameless Soldier"), @@ -1262,71 +1260,71 @@ def __init__( DS3LocationData("FK: Ember - upper keep, by miniboss #1", "Ember"), DS3LocationData("FK: Ember - upper keep, by miniboss #2", "Ember"), DS3LocationData("FK: Dark Stoneplate Ring+2 - keep ruins ritual island, behind wall", - "Dark Stoneplate Ring+2", ngp = True, hidden = True), + "Dark Stoneplate Ring+2", ngp=True, hidden=True), DS3LocationData("FK: Magic Stoneplate Ring+1 - between right island and wall", - "Magic Stoneplate Ring+1", ngp = True), + "Magic Stoneplate Ring+1", ngp=True), DS3LocationData("FK: Wolf Ring+1 - keep ruins bonfire island, outside building", - "Wolf Ring+1", ngp = True), - DS3LocationData("FK: Antiquated Dress - hidden cave", "Antiquated Dress", hidden = True), - DS3LocationData("FK: Antiquated Gloves - hidden cave", "Antiquated Gloves", hidden = True), - DS3LocationData("FK: Antiquated Skirt - hidden cave", "Antiquated Skirt", hidden = True), + "Wolf Ring+1", ngp=True), + DS3LocationData("FK: Antiquated Dress - hidden cave", "Antiquated Dress", hidden=True), + DS3LocationData("FK: Antiquated Gloves - hidden cave", "Antiquated Gloves", hidden=True), + DS3LocationData("FK: Antiquated Skirt - hidden cave", "Antiquated Skirt", hidden=True), DS3LocationData("FK: Sunlight Talisman - estus soup island, by ladder to keep proper", "Sunlight Talisman"), DS3LocationData("FK: Young White Branch - by white tree #1", "Young White Branch"), DS3LocationData("FK: Young White Branch - by white tree #2", "Young White Branch"), DS3LocationData("FK: Crown of Dusk - by white tree", "Crown of Dusk"), DS3LocationData("FK: Lingering Dragoncrest Ring - by white tree, miniboss drop", - "Lingering Dragoncrest Ring", miniboss = True), # Great Crab drop + "Lingering Dragoncrest Ring", miniboss=True), # Great Crab drop DS3LocationData("FK: Pharis's Hat - miniboss drop, by keep ruins near wall", - "Pharis's Hat", miniboss = True), # Elder Ghru drop + "Pharis's Hat", miniboss=True), # Elder Ghru drop DS3LocationData("FK: Black Bow of Pharis - miniboss drop, by keep ruins near wall", - "Black Bow of Pharis", miniboss = True), # Elder Ghru drop + "Black Bow of Pharis", miniboss=True), # Elder Ghru drop DS3LocationData("FK: Titanite Scale - perimeter, miniboss drop", "Titanite Scale x2", - miniboss = True), # Ravenous Crystal Lizard drop + miniboss=True), # Ravenous Crystal Lizard drop DS3LocationData("FK: Large Titanite Shard - upper keep, lizard in open", - "Large Titanite Shard", lizard = True), + "Large Titanite Shard", lizard=True), DS3LocationData("FK: Large Titanite Shard - upper keep, lizard by wyvern", - "Large Titanite Shard", lizard = True), - DS3LocationData("FK: Heavy Gem - upper keep, lizard on stairs", "Heavy Gem", lizard = True), + "Large Titanite Shard", lizard=True), + DS3LocationData("FK: Heavy Gem - upper keep, lizard on stairs", "Heavy Gem", lizard=True), DS3LocationData("FK: Twinkling Titanite - keep proper, lizard", "Twinkling Titanite", - lizard = True), + lizard=True), DS3LocationData("FK: Soul of a Stray Demon - upper keep, miniboss drop", - "Soul of a Stray Demon", miniboss = True), + "Soul of a Stray Demon", miniboss=True), DS3LocationData("FK: Watchdogs of Farron - Old Wolf", "Watchdogs of Farron"), DS3LocationData("FS: Hawkwood's Shield - gravestone after Hawkwood leaves", - "Hawkwood's Shield", missable = True, - npc = True), # Hawkwood (quest, after Greatwood, Sage, Watchers, and Deacons) - DS3LocationData("US: Hawk Ring - Giant Archer", "Hawk Ring", drop = True, - npc = True), # Giant archer (kill or quest), here because you need to - # collect all seven White Branch locations to get it peacefully + "Hawkwood's Shield", missable=True, + npc=True), # Hawkwood (quest, after Greatwood, Sage, Watchers, and Deacons) + DS3LocationData("US: Hawk Ring - Giant Archer", "Hawk Ring", drop=True, + npc=True), # Giant archer (kill or quest), here because you need to + # collect all seven White Branch locations to get it peacefully # Hawkwood after killing Abyss Watchers DS3LocationData("FS: Farron Ring - Hawkwood", "Farron Ring", - missable = True, npc = True), + missable=True, npc=True), # Shrine Handmaid after killing Abyss Watchers DS3LocationData("FS: Undead Legion Helm - shop after killing FK boss", "Undead Legion Helm", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Undead Legion Armor - shop after killing FK boss", - "Undead Legion Armor", boss = True, shop = True), + "Undead Legion Armor", boss=True, shop=True), DS3LocationData("FS: Undead Legion Gauntlet - shop after killing FK boss", - "Undead Legion Gauntlet", boss = True, shop = True), + "Undead Legion Gauntlet", boss=True, shop=True), DS3LocationData("FS: Undead Legion Leggings - shop after killing FK boss", - "Undead Legion Leggings", boss = True, shop = True), + "Undead Legion Leggings", boss=True, shop=True), # Appears after killing Havel Knight in Archdragon Peak DS3LocationData("FK: Havel's Helm - upper keep, after killing AP belfry roof NPC", - "Havel's Helm", hidden = True, hostile_npc = True), + "Havel's Helm", hidden=True, hostile_npc=True), DS3LocationData("FK: Havel's Armor - upper keep, after killing AP belfry roof NPC", - "Havel's Armor", hidden = True, hostile_npc = True), + "Havel's Armor", hidden=True, hostile_npc=True), DS3LocationData("FK: Havel's Gauntlets - upper keep, after killing AP belfry roof NPC", - "Havel's Gauntlets", hidden = True, hostile_npc = True), + "Havel's Gauntlets", hidden=True, hostile_npc=True), DS3LocationData("FK: Havel's Leggings - upper keep, after killing AP belfry roof NPC", - "Havel's Leggings", hidden = True, hostile_npc = True), + "Havel's Leggings", hidden=True, hostile_npc=True), ], "Catacombs of Carthus": [ DS3LocationData("CC: Soul of High Lord Wolnir", "Soul of High Lord Wolnir", - prominent = True, boss = True), + prominent=True, boss=True), DS3LocationData("CC: Carthus Rouge - atrium upper, left after entrance", "Carthus Rouge x2"), DS3LocationData("CC: Sharp Gem - atrium lower, right before exit", "Sharp Gem"), @@ -1345,7 +1343,7 @@ def __init__( DS3LocationData("CC: Ember - crypt lower, shortcut to cavern", "Ember"), DS3LocationData("CC: Carthus Pyromancy Tome - atrium lower, jump from bridge", "Carthus Pyromancy Tome", - hidden = True), # Behind illusory wall or hidden drop + hidden=True), # Behind illusory wall or hidden drop DS3LocationData("CC: Large Titanite Shard - crypt upper, skeleton ball hall", "Large Titanite Shard"), DS3LocationData("CC: Large Titanite Shard - crypt across, middle hall", @@ -1355,7 +1353,7 @@ def __init__( "Large Soul of a Nameless Soldier"), DS3LocationData("CC: Black Bug Pellet - cavern, before bridge", "Black Bug Pellet x2"), DS3LocationData("CC: Grave Warden's Ashes - crypt across, corner", "Grave Warden's Ashes", - progression = True), + progression=True), DS3LocationData("CC: Large Titanite Shard - tomb lower", "Large Titanite Shard"), DS3LocationData("CC: Large Soul of a Nameless Soldier - tomb lower", "Large Soul of a Nameless Soldier"), @@ -1369,34 +1367,34 @@ def __init__( DS3LocationData("CC: Large Soul of an Unknown Traveler - crypt upper, hall middle", "Large Soul of an Unknown Traveler"), DS3LocationData("CC: Ring of Steel Protection+2 - atrium upper, drop onto pillar", - "Ring of Steel Protection+2", ngp = True), + "Ring of Steel Protection+2", ngp=True), DS3LocationData("CC: Thunder Stoneplate Ring+1 - crypt upper, among pots", - "Thunder Stoneplate Ring+1", ngp = True), + "Thunder Stoneplate Ring+1", ngp=True), DS3LocationData("CC: Undead Bone Shard - crypt upper, skeleton ball drop", - "Undead Bone Shard", hidden = True), # Skeleton Ball puzzle + "Undead Bone Shard", hidden=True), # Skeleton Ball puzzle DS3LocationData("CC: Dark Gem - crypt lower, skeleton ball drop", "Dark Gem", - hidden = True), # Skeleton Ball puzzle - DS3LocationData("CC: Black Blade - tomb, mimic", "Black Blade", mimic = True), + hidden=True), # Skeleton Ball puzzle + DS3LocationData("CC: Black Blade - tomb, mimic", "Black Blade", mimic=True), DS3LocationData("CC: Soul of a Demon - tomb, miniboss drop", "Soul of a Demon", - miniboss = True), + miniboss=True), DS3LocationData("CC: Twinkling Titanite - atrium lower, lizard down more stairs", - "Twinkling Titanite", lizard = True), - DS3LocationData("CC: Fire Gem - cavern, lizard", "Fire Gem", lizard = True), + "Twinkling Titanite", lizard=True), + DS3LocationData("CC: Fire Gem - cavern, lizard", "Fire Gem", lizard=True), DS3LocationData("CC: Homeward Bone - Irithyll bridge", "Homeward Bone"), DS3LocationData("CC: Pontiff's Right Eye - Irithyll bridge, miniboss drop", - "Pontiff's Right Eye", miniboss = True), # Sulyvahn's Beast drop + "Pontiff's Right Eye", miniboss=True), # Sulyvahn's Beast drop # Shrine Handmaid after killing High Lord Wolnir DS3LocationData("FS: Wolnir's Crown - shop after killing CC boss", "Wolnir's Crown", - boss = True, shop = True), + boss=True, shop=True), ], "Smouldering Lake": [ DS3LocationData("SL: Soul of the Old Demon King", "Soul of the Old Demon King", - prominent = True, boss = True), + prominent=True, boss=True), DS3LocationData("SL: Fume Ultra Greatsword - ruins basement, NPC drop", - "Fume Ultra Greatsword", hostile_npc = True), # Knight Slayer Tsorig drop + "Fume Ultra Greatsword", hostile_npc=True), # Knight Slayer Tsorig drop DS3LocationData("SL: Black Iron Greatshield - ruins basement, NPC drop", - "Black Iron Greatshield", hostile_npc = True), # Knight Slayer Tsorig drop + "Black Iron Greatshield", hostile_npc=True), # Knight Slayer Tsorig drop DS3LocationData("SL: Large Titanite Shard - ledge by Demon Ruins bonfire", "Large Titanite Shard"), DS3LocationData("SL: Large Titanite Shard - lake, by entrance", "Large Titanite Shard"), @@ -1409,7 +1407,7 @@ def __init__( DS3LocationData("SL: Large Titanite Shard - side lake #2", "Large Titanite Shard"), DS3LocationData("SL: Large Titanite Shard - lake, by tree #2", "Large Titanite Shard"), DS3LocationData("SL: Speckled Stoneplate Ring - lake, ballista breaks bricks", - "Speckled Stoneplate Ring", hidden = True), # Requires careful ballista shot + "Speckled Stoneplate Ring", hidden=True), # Requires careful ballista shot DS3LocationData("SL: Homeward Bone - path to ballista", "Homeward Bone x2"), DS3LocationData("SL: Ember - ruins main upper, hall end by hole", "Ember"), DS3LocationData("SL: Chaos Gem - lake, far end by mob", "Chaos Gem"), @@ -1417,19 +1415,19 @@ def __init__( DS3LocationData("SL: Izalith Pyromancy Tome - antechamber, room near bonfire", "Izalith Pyromancy Tome"), DS3LocationData("SL: Black Knight Sword - ruins main lower, illusory wall in far hall", - "Black Knight Sword", hidden = True), + "Black Knight Sword", hidden=True), DS3LocationData("SL: Ember - ruins main upper, just after entrance", "Ember"), DS3LocationData("SL: Quelana Pyromancy Tome - ruins main lower, illusory wall in grey room", - "Quelana Pyromancy Tome", hidden = True), + "Quelana Pyromancy Tome", hidden=True), DS3LocationData("SL: Izalith Staff - ruins basement, second illusory wall behind chest", - "Izalith Staff", hidden = True), + "Izalith Staff", hidden=True), DS3LocationData("SL: White Hair Talisman - ruins main lower, in lava", "White Hair Talisman", - missable = True), # This may not even be possible to get without enough fire - # protection gear which the player may not have + missable=True), # This may not even be possible to get without enough fire + # protection gear which the player may not have DS3LocationData("SL: Toxic Mist - ruins main lower, in lava", "Toxic Mist", - missable = True), # This is _probably_ reachable with normal gear, but it - # still sucks and will probably force a death. + missable=True), # This is _probably_ reachable with normal gear, but it + # still sucks and will probably force a death. DS3LocationData("SL: Undead Bone Shard - ruins main lower, left after stairs", "Undead Bone Shard"), DS3LocationData("SL: Titanite Scale - ruins basement, path to lava", "Titanite Scale"), @@ -1439,73 +1437,73 @@ def __init__( # Lava items are missable because they require a complex set of armor, rings, spells, and # undead bone shards to reliably access without dying. - DS3LocationData("SL: Ember - ruins basement, in lava", "Ember", missable = True), # In lava + DS3LocationData("SL: Ember - ruins basement, in lava", "Ember", missable=True), # In lava DS3LocationData("SL: Sacred Flame - ruins basement, in lava", "Sacred Flame", - missable = True), # In lava + missable=True), # In lava DS3LocationData("SL: Dragonrider Bow - by ladder from ruins basement to ballista", - "Dragonrider Bow", hidden = True), # Hidden fall + "Dragonrider Bow", hidden=True), # Hidden fall DS3LocationData("SL: Estus Shard - antechamber, illusory wall", "Estus Shard", - hidden = True), - DS3LocationData("SL: Bloodbite Ring+1 - behind ballista", "Bloodbite Ring+1", ngp = True), + hidden=True), + DS3LocationData("SL: Bloodbite Ring+1 - behind ballista", "Bloodbite Ring+1", ngp=True), DS3LocationData("SL: Flame Stoneplate Ring+2 - ruins main lower, illusory wall in far hall", - "Flame Stoneplate Ring+2", ngp = True, hidden = True), + "Flame Stoneplate Ring+2", ngp=True, hidden=True), DS3LocationData("SL: Large Titanite Shard - ruins basement, illusory wall in upper hall", - "Large Titanite Shard x3", hidden = True), + "Large Titanite Shard x3", hidden=True), DS3LocationData("SL: Undead Bone Shard - lake, miniboss drop", "Undead Bone Shard", - miniboss = True), # Sand Worm drop + miniboss=True), # Sand Worm drop DS3LocationData("SL: Lightning Stake - lake, miniboss drop", "Lightning Stake", - miniboss = True), # Sand Worm drop + miniboss=True), # Sand Worm drop DS3LocationData("SL: Twinkling Titanite - path to side lake, lizard", "Twinkling Titanite", - lizard = True), + lizard=True), DS3LocationData("SL: Titanite Chunk - path to side lake, lizard", "Titanite Chunk", - lizard = True), + lizard=True), DS3LocationData("SL: Chaos Gem - antechamber, lizard at end of long hall", "Chaos Gem", - lizard = True), + lizard=True), DS3LocationData("SL: Knight Slayer's Ring - ruins basement, NPC drop", - "Knight Slayer's Ring", hostile_npc = True), # Knight Slayer Tsorig drop + "Knight Slayer's Ring", hostile_npc=True), # Knight Slayer Tsorig drop # Horace the Hushed # These are listed here even though you can kill Horace in the Road of Sacrifices because # the player may want to complete his and Anri's quest first. - DS3LocationData("SL: Llewellyn Shield - Horace drop", "Llewellyn Shield", npc = True, - hostile_npc = True), + DS3LocationData("SL: Llewellyn Shield - Horace drop", "Llewellyn Shield", npc=True, + hostile_npc=True), DS3LocationData("FS: Executioner Helm - shop after killing Horace", "Executioner Helm", - npc = True, hostile_npc = True, shop = True, hidden = True), + npc=True, hostile_npc=True, shop=True, hidden=True), DS3LocationData("FS: Executioner Armor - shop after killing Horace", "Executioner Armor", - npc = True, hostile_npc = True, shop = True, hidden = True), + npc=True, hostile_npc=True, shop=True, hidden=True), DS3LocationData("FS: Executioner Gauntlets - shop after killing Horace", - "Executioner Gauntlets", hostile_npc = True, npc = True, shop = True, - hidden = True), + "Executioner Gauntlets", hostile_npc=True, npc=True, shop=True, + hidden=True), DS3LocationData("FS: Executioner Leggings - shop after killing Horace", - "Executioner Leggings", hostile_npc = True, npc = True, shop = True, - hidden = True), + "Executioner Leggings", hostile_npc=True, npc=True, shop=True, + hidden=True), # Shrine Handmaid after killing Knight Slayer Tsorig DS3LocationData("FS: Black Iron Helm - shop after killing Tsorig", "Black Iron Helm", - hostile_npc = True, shop = True, hidden = True), + hostile_npc=True, shop=True, hidden=True), DS3LocationData("FS: Black Iron Armor - shop after killing Tsorig", "Black Iron Armor", - hostile_npc = True, shop = True, hidden = True), + hostile_npc=True, shop=True, hidden=True), DS3LocationData("FS: Black Iron Gauntlets - shop after killing Tsorig", - "Black Iron Gauntlets", hostile_npc = True, shop = True, hidden = True), + "Black Iron Gauntlets", hostile_npc=True, shop=True, hidden=True), DS3LocationData("FS: Black Iron Leggings - shop after killing Tsorig", - "Black Iron Leggings", hostile_npc = True, shop = True, hidden = True), + "Black Iron Leggings", hostile_npc=True, shop=True, hidden=True), # Near Cornyx's cage after killing Old Demon King with Cuculus DS3LocationData("US: Spotted Whip - by Cornyx's cage after Cuculus quest", "Spotted Whip", - missable = True, boss = True, npc = True), + missable=True, boss=True, npc=True), DS3LocationData("US: Cornyx's Garb - by Cornyx's cage after Cuculus quest", - "Cornyx's Garb", offline = '02,0:53100100::', missable = True, boss = True, - npc = True), + "Cornyx's Garb", offline='02,0:53100100::', missable=True, boss=True, + npc=True), DS3LocationData("US: Cornyx's Wrap - by Cornyx's cage after Cuculus quest", "Cornyx's Wrap", - offline = '02,0:53100100::', missable = True, boss = True, npc = True), + offline='02,0:53100100::', missable=True, boss=True, npc=True), DS3LocationData("US: Cornyx's Skirt - by Cornyx's cage after Cuculus quest", - "Cornyx's Skirt", offline = '02,0:53100100::', missable = True, boss = True, - npc = True), + "Cornyx's Skirt", offline='02,0:53100100::', missable=True, boss=True, + npc=True), ], "Irithyll of the Boreal Valley": [ DS3LocationData("IBV: Soul of Pontiff Sulyvahn", "Soul of Pontiff Sulyvahn", - prominent = True, boss = True), + prominent=True, boss=True), DS3LocationData("IBV: Large Soul of a Nameless Soldier - central, by bonfire", "Large Soul of a Nameless Soldier"), DS3LocationData("IBV: Large Titanite Shard - ascent, down ladder in last building", @@ -1516,7 +1514,7 @@ def __init__( "Soul of a Weary Warrior"), DS3LocationData("IBV: Rime-blue Moss Clump - central, by bonfire", "Rime-blue Moss Clump"), DS3LocationData("IBV: Witchtree Branch - by Dorhys", "Witchtree Branch", - hidden = True), # Behind illusory wall + hidden=True), # Behind illusory wall DS3LocationData("IBV: Large Titanite Shard - central, side path after first fountain", "Large Titanite Shard"), DS3LocationData("IBV: Budding Green Blossom - central, by second fountain", @@ -1526,10 +1524,10 @@ def __init__( DS3LocationData("IBV: Large Titanite Shard - central, balcony just before plaza", "Large Titanite Shard"), DS3LocationData("IBV: Large Titanite Shard - path to Dorhys", "Large Titanite Shard", - hidden = True), # Behind illusory wall + hidden=True), # Behind illusory wall DS3LocationData("IBV: Ring of the Sun's First Born - fall from in front of cathedral", "Ring of the Sun's First Born", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("IBV: Large Soul of a Nameless Soldier - path to plaza", "Large Soul of a Nameless Soldier"), DS3LocationData("IBV: Large Titanite Shard - plaza, balcony overlooking ascent", @@ -1539,12 +1537,12 @@ def __init__( DS3LocationData("IBV: Soul of a Weary Warrior - plaza, side room lower", "Soul of a Weary Warrior"), DS3LocationData("IBV: Magic Clutch Ring - plaza, illusory wall", "Magic Clutch Ring", - hidden = True), # Behind illusory wall + hidden=True), # Behind illusory wall DS3LocationData("IBV: Fading Soul - descent, cliff edge #1", "Fading Soul"), DS3LocationData("IBV: Fading Soul - descent, cliff edge #2", "Fading Soul"), DS3LocationData("IBV: Homeward Bone - descent, before gravestone", "Homeward Bone x3"), DS3LocationData("IBV: Undead Bone Shard - descent, behind gravestone", "Undead Bone Shard", - hidden = True), # Hidden behind gravestone + hidden=True), # Hidden behind gravestone DS3LocationData("IBV: Kukri - descent, side path", "Kukri x8"), DS3LocationData("IBV: Rusted Gold Coin - descent, side path", "Rusted Gold Coin"), DS3LocationData("IBV: Blue Bug Pellet - descent, dark room", "Blue Bug Pellet x2"), @@ -1581,77 +1579,77 @@ def __init__( DS3LocationData("IBV: Rusted Gold Coin - Distant Manor, drop after stairs", "Rusted Gold Coin"), DS3LocationData("IBV: Chloranthy Ring+1 - plaza, behind altar", "Chloranthy Ring+1", - ngp = True), + ngp=True), DS3LocationData("IBV: Covetous Gold Serpent Ring+1 - descent, drop after dark room", - "Covetous Gold Serpent Ring+1", ngp = True, hidden = True), # Hidden fall + "Covetous Gold Serpent Ring+1", ngp=True, hidden=True), # Hidden fall DS3LocationData("IBV: Wood Grain Ring+2 - ascent, right after great hall", "Wood Grain Ring+2", - ngp = True), + ngp=True), DS3LocationData("IBV: Divine Blessing - great hall, chest", "Divine Blessing"), DS3LocationData("IBV: Smough's Great Hammer - great hall, chest", "Smough's Great Hammer"), DS3LocationData("IBV: Yorshka's Spear - descent, dark room rafters chest", "Yorshka's Spear"), DS3LocationData("IBV: Leo Ring - great hall, chest", "Leo Ring"), DS3LocationData("IBV: Dorhys' Gnawing - Dorhys drop", "Dorhys' Gnawing", - hidden = True), # Behind illusory wall + hidden=True), # Behind illusory wall DS3LocationData("IBV: Divine Blessing - great hall, mob drop", - "Divine Blessing", drop = True, - hidden = True), # Guaranteed drop from normal-looking Silver Knight + "Divine Blessing", drop=True, + hidden=True), # Guaranteed drop from normal-looking Silver Knight DS3LocationData("IBV: Large Titanite Shard - great hall, main floor mob drop", - "Large Titanite Shard", drop = True, - hidden = True), # Guaranteed drop from normal-looking Silver Knight + "Large Titanite Shard", drop=True, + hidden=True), # Guaranteed drop from normal-looking Silver Knight DS3LocationData("IBV: Large Titanite Shard - great hall, upstairs mob drop #1", - "Large Titanite Shard x2", drop = True, - hidden = True), # Guaranteed drop from normal-looking Silver Knight + "Large Titanite Shard x2", drop=True, + hidden=True), # Guaranteed drop from normal-looking Silver Knight DS3LocationData("IBV: Large Titanite Shard - great hall, upstairs mob drop #2", - "Large Titanite Shard x2", drop = True, - hidden = True), # Guaranteed drop from normal-looking Silver Knight + "Large Titanite Shard x2", drop=True, + hidden=True), # Guaranteed drop from normal-looking Silver Knight DS3LocationData("IBV: Roster of Knights - descent, first landing", "Roster of Knights"), DS3LocationData("IBV: Twinkling Titanite - descent, lizard behind illusory wall", - "Twinkling Titanite", lizard = True, hidden = True), # Behind illusory wall + "Twinkling Titanite", lizard=True, hidden=True), # Behind illusory wall DS3LocationData("IBV: Twinkling Titanite - central, lizard before plaza", - "Twinkling Titanite", lizard = True), + "Twinkling Titanite", lizard=True), DS3LocationData("IBV: Large Titanite Shard - Distant Manor, under overhang", "Large Titanite Shard"), - DS3LocationData("IBV: Siegbräu - Siegward", "Siegbräu", missable = True, npc = True), - DS3LocationData("IBV: Emit Force - Siegward", "Emit Force", missable = True, npc = True), + DS3LocationData("IBV: Siegbräu - Siegward", "Siegbräu", missable=True, npc=True), + DS3LocationData("IBV: Emit Force - Siegward", "Emit Force", missable=True, npc=True), DS3LocationData("IBV -> ID", None), # After winning both Londor Pale Shade invasions DS3LocationData("FS: Sneering Mask - Yoel's room, kill Londor Pale Shade twice", - "Sneering Mask", missable = True, hostile_npc = True), + "Sneering Mask", missable=True, hostile_npc=True), DS3LocationData("FS: Pale Shade Robe - Yoel's room, kill Londor Pale Shade twice", - "Pale Shade Robe", missable = True, hostile_npc = True), + "Pale Shade Robe", missable=True, hostile_npc=True), DS3LocationData("FS: Pale Shade Gloves - Yoel's room, kill Londor Pale Shade twice", - "Pale Shade Gloves", missable = True, hostile_npc = True), + "Pale Shade Gloves", missable=True, hostile_npc=True), DS3LocationData("FS: Pale Shade Trousers - Yoel's room, kill Londor Pale Shade twice", - "Pale Shade Trousers", missable = True, hostile_npc = True), + "Pale Shade Trousers", missable=True, hostile_npc=True), # Anri of Astora - DS3LocationData("IBV: Ring of the Evil Eye - Anri", "Ring of the Evil Eye", missable = True, - npc = True), + DS3LocationData("IBV: Ring of the Evil Eye - Anri", "Ring of the Evil Eye", missable=True, + npc=True), # Sirris quest after killing Creighton DS3LocationData("FS: Mail Breaker - Sirris for killing Creighton", "Mail Breaker", - offline = '99,0:50006080::', missable = True, hostile_npc = True, - npc = True), + offline='99,0:50006080::', missable=True, hostile_npc=True, + npc=True), DS3LocationData("FS: Silvercat Ring - Sirris for killing Creighton", "Silvercat Ring", - missable = True, hostile_npc = True, npc = True), + missable=True, hostile_npc=True, npc=True), DS3LocationData("IBV: Dragonslayer's Axe - Creighton drop", "Dragonslayer's Axe", - missable = True, hostile_npc = True, npc = True), + missable=True, hostile_npc=True, npc=True), DS3LocationData("IBV: Creighton's Steel Mask - bridge after killing Creighton", - "Creighton's Steel Mask", missable = True, hostile_npc = True, npc = True), + "Creighton's Steel Mask", missable=True, hostile_npc=True, npc=True), DS3LocationData("IBV: Mirrah Chain Mail - bridge after killing Creighton", - "Mirrah Chain Mail", missable = True, hostile_npc = True, npc = True), + "Mirrah Chain Mail", missable=True, hostile_npc=True, npc=True), DS3LocationData("IBV: Mirrah Chain Gloves - bridge after killing Creighton", - "Mirrah Chain Gloves", missable = True, hostile_npc = True, npc = True), + "Mirrah Chain Gloves", missable=True, hostile_npc=True, npc=True), DS3LocationData("IBV: Mirrah Chain Leggings - bridge after killing Creighton", - "Mirrah Chain Leggings", missable = True, hostile_npc = True, npc = True), + "Mirrah Chain Leggings", missable=True, hostile_npc=True, npc=True), ], "Irithyll Dungeon": [ - DS3LocationData("ID: Titanite Slab - Siegward", "Titanite Slab", missable = True, - npc = True), - DS3LocationData("ID: Murakumo - Alva drop", "Murakumo", missable = True, - hostile_npc = True), + DS3LocationData("ID: Titanite Slab - Siegward", "Titanite Slab", missable=True, + npc=True), + DS3LocationData("ID: Murakumo - Alva drop", "Murakumo", missable=True, + hostile_npc=True), DS3LocationData("ID: Large Titanite Shard - after bonfire, second cell on left", "Large Titanite Shard"), DS3LocationData("ID: Fading Soul - B1 near, main hall", "Fading Soul"), @@ -1667,7 +1665,7 @@ def __init__( "Large Titanite Shard"), DS3LocationData("ID: Homeward Bone - path from B2 to pit", "Homeward Bone x2"), DS3LocationData("ID: Bellowing Dragoncrest Ring - drop from B1 towards pit", - "Bellowing Dragoncrest Ring", conditional = True), + "Bellowing Dragoncrest Ring", conditional=True), DS3LocationData("ID: Soul of a Weary Warrior - by drop to pit", "Soul of a Weary Warrior"), DS3LocationData("ID: Soul of a Crestfallen Knight - balcony above pit", "Soul of a Crestfallen Knight"), @@ -1690,61 +1688,61 @@ def __init__( DS3LocationData("ID: Large Soul of a Weary Warrior - just before Profaned Capital", "Large Soul of a Weary Warrior"), DS3LocationData("ID: Covetous Gold Serpent Ring - Siegward's cell", - "Covetous Gold Serpent Ring", conditional = True), + "Covetous Gold Serpent Ring", conditional=True), DS3LocationData("ID: Lightning Blade - B3 lift, middle platform", "Lightning Blade"), DS3LocationData("ID: Rusted Coin - after bonfire, first cell on left", "Rusted Coin"), DS3LocationData("ID: Dusk Crown Ring - B3 far, right cell", "Dusk Crown Ring"), DS3LocationData("ID: Pickaxe - path from pit to B3", "Pickaxe"), DS3LocationData("ID: Xanthous Ashes - B3 far, right cell", "Xanthous Ashes", - progression = True), + progression=True), DS3LocationData("ID: Large Titanite Shard - B1 near, by door", "Large Titanite Shard"), DS3LocationData("ID: Rusted Gold Coin - after bonfire, last cell on right", "Rusted Gold Coin"), DS3LocationData("ID: Old Cell Key - stairs between pit and B3", "Old Cell Key"), DS3LocationData("ID: Covetous Silver Serpent Ring+1 - pit lift, middle platform", - "Covetous Silver Serpent Ring+1", ngp = True), + "Covetous Silver Serpent Ring+1", ngp=True), DS3LocationData("ID: Dragon Torso Stone - B3, outside lift", "Dragon Torso Stone"), DS3LocationData("ID: Prisoner Chief's Ashes - B2 near, locked cell by stairs", - "Prisoner Chief's Ashes", progression = True), + "Prisoner Chief's Ashes", progression=True), DS3LocationData("ID: Great Magic Shield - B2 near, mob drop in far left cell", - "Great Magic Shield", drop = True, - hidden = True), # Guaranteed drop from a normal-looking Corpse-Grub + "Great Magic Shield", drop=True, + hidden=True), # Guaranteed drop from a normal-looking Corpse-Grub DS3LocationData("ID: Dragonslayer Lightning Arrow - pit, mimic in hall", - "Dragonslayer Lightning Arrow x10", mimic = True), + "Dragonslayer Lightning Arrow x10", mimic=True), DS3LocationData("ID: Titanite Scale - B3 far, mimic in hall", "Titanite Scale x2", - mimic = True), + mimic=True), DS3LocationData("ID: Dark Clutch Ring - stairs between pit and B3, mimic", - "Dark Clutch Ring", mimic = True), + "Dark Clutch Ring", mimic=True), DS3LocationData("ID: Estus Shard - mimic on path from B2 to pit", "Estus Shard", - mimic = True), + mimic=True), DS3LocationData("ID: Titanite Chunk - balcony above pit, lizard", "Titanite Chunk", - lizard = True), - DS3LocationData("ID: Titanite Scale - B2 far, lizard", "Titanite Scale", lizard = True), + lizard=True), + DS3LocationData("ID: Titanite Scale - B2 far, lizard", "Titanite Scale", lizard=True), # These are missable because of a bug that causes them to be dropped wherever the giant is # randomized to, instead of where the miniboss is in vanilla. DS3LocationData("ID: Dung Pie - pit, miniboss drop", "Dung Pie x4", - miniboss = True, missable = True), # Giant slave drop + miniboss=True, missable=True), # Giant slave drop DS3LocationData("ID: Titanite Chunk - pit, miniboss drop", "Titanite Chunk", - miniboss = True, missable = True), # Giant Slave Drop + miniboss=True, missable=True), # Giant Slave Drop # Alva (requires ember) DS3LocationData("ID: Alva Helm - B3 near, by Karla's cell, after killing Alva", "Alva Helm", - missable = True, npc = True), + missable=True, npc=True), DS3LocationData("ID: Alva Armor - B3 near, by Karla's cell, after killing Alva", - "Alva Armor", missable = True, npc = True), + "Alva Armor", missable=True, npc=True), DS3LocationData("ID: Alva Gauntlets - B3 near, by Karla's cell, after killing Alva", - "Alva Gauntlets", missable = True, npc = True), + "Alva Gauntlets", missable=True, npc=True), DS3LocationData("ID: Alva Leggings - B3 near, by Karla's cell, after killing Alva", - "Alva Leggings", missable = True, npc = True), + "Alva Leggings", missable=True, npc=True), ], "Profaned Capital": [ - DS3LocationData("PC: Soul of Yhorm the Giant", "Soul of Yhorm the Giant", boss = True), + DS3LocationData("PC: Soul of Yhorm the Giant", "Soul of Yhorm the Giant", boss=True), DS3LocationData("PC: Cinders of a Lord - Yhorm the Giant", - "Cinders of a Lord - Yhorm the Giant", offline = "07,0:50002170::", - prominent = True, progression = True, boss = True), + "Cinders of a Lord - Yhorm the Giant", offline="07,0:50002170::", + prominent=True, progression=True, boss=True), DS3LocationData("PC: Logan's Scroll - chapel roof, NPC drop", "Logan's Scroll", - hostile_npc = True), # Sorcerer + hostile_npc=True), # Sorcerer DS3LocationData("PC: Purging Stone - chapel ground floor", "Purging Stone x3"), DS3LocationData("PC: Rusted Coin - tower exterior", "Rusted Coin x2"), DS3LocationData("PC: Rusted Gold Coin - halls above swamp", "Rusted Gold Coin"), @@ -1754,7 +1752,7 @@ def __init__( DS3LocationData("PC: Shriving Stone - swamp, by chapel door", "Shriving Stone"), DS3LocationData("PC: Poison Arrow - chapel roof", "Poison Arrow x18"), DS3LocationData("PC: Rubbish - chapel, down stairs from second floor", "Rubbish"), - DS3LocationData("PC: Onislayer Greatarrow - bridge", "Onislayer Greatarrow x8"), + DS3LocationData("PC: Monolayers Greatarrow - bridge", "Onislayer Greatarrow x8"), DS3LocationData("PC: Large Soul of a Weary Warrior - bridge, far end", "Large Soul of a Weary Warrior"), DS3LocationData("PC: Rusted Coin - below bridge #1", "Rusted Coin"), @@ -1763,14 +1761,14 @@ def __init__( "Blooming Purple Moss Clump x3"), DS3LocationData("PC: Wrath of the Gods - chapel, drop from roof", "Wrath of the Gods"), DS3LocationData("PC: Onislayer Greatbow - drop from bridge", "Onislayer Greatbow", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("PC: Jailer's Key Ring - hall past chapel", "Jailer's Key Ring", - progression = True), + progression=True), DS3LocationData("PC: Ember - palace, far room", "Ember"), DS3LocationData("PC: Flame Stoneplate Ring+1 - chapel, drop from roof towards entrance", - "Flame Stoneplate Ring+1", ngp = True, hidden = True), # Hidden fall + "Flame Stoneplate Ring+1", ngp=True, hidden=True), # Hidden fall DS3LocationData("PC: Magic Stoneplate Ring+2 - tower base", "Magic Stoneplate Ring+2", - ngp = True), + ngp=True), DS3LocationData("PC: Court Sorcerer Hood - chapel, second floor", "Court Sorcerer Hood"), DS3LocationData("PC: Court Sorcerer Robe - chapel, second floor", "Court Sorcerer Robe"), DS3LocationData("PC: Court Sorcerer Gloves - chapel, second floor", "Court Sorcerer Gloves"), @@ -1779,53 +1777,53 @@ def __init__( DS3LocationData("PC: Storm Ruler - boss room", "Storm Ruler"), DS3LocationData("PC: Undead Bone Shard - by bonfire", "Undead Bone Shard"), DS3LocationData("PC: Eleonora - chapel ground floor, kill mob", "Eleonora", - drop = True, - hidden = True), # Guaranteed drop from a normal-looking Monstrosity of Sin + drop=True, + hidden=True), # Guaranteed drop from a normal-looking Monstrosity of Sin DS3LocationData("PC: Rusted Gold Coin - palace, mimic in far room", "Rusted Gold Coin x2", - mimic = True), + mimic=True), DS3LocationData("PC: Court Sorcerer's Staff - chapel, mimic on second floor", - "Court Sorcerer's Staff", mimic = True), + "Court Sorcerer's Staff", mimic=True), DS3LocationData("PC: Greatshield of Glory - palace, mimic in far room", - "Greatshield of Glory", mimic = True), + "Greatshield of Glory", mimic=True), DS3LocationData("PC: Twinkling Titanite - halls above swamp, lizard #1", - "Twinkling Titanite", lizard = True), + "Twinkling Titanite", lizard=True), DS3LocationData("PC: Twinkling Titanite - halls above swamp, lizard #2", - "Twinkling Titanite", lizard = True), + "Twinkling Titanite", lizard=True), DS3LocationData("PC: Siegbräu - Siegward after killing boss", "Siegbräu", - missable = True, npc = True), + missable=True, npc=True), # Siegward drops (kill or quest) - DS3LocationData("PC: Storm Ruler - Siegward", "Storm Ruler", offline = '02,0:50006218::', - missable = True, drop = True, npc = True), - DS3LocationData("PC: Pierce Shield - Siegward", "Pierce Shield", missable = True, - drop = True, npc = True), + DS3LocationData("PC: Storm Ruler - Siegward", "Storm Ruler", offline='02,0:50006218::', + missable=True, drop=True, npc=True), + DS3LocationData("PC: Pierce Shield - Siegward", "Pierce Shield", missable=True, + drop=True, npc=True), ], # We consider "Anor Londo" to be everything accessible only after killing Pontiff. This doesn't # match up one-to-one with where the game pops up the region name, but it balances items better # and covers the region that's full of DS1 Anor Londo references. "Anor Londo": [ - DS3LocationData("AL: Soul of Aldrich", "Soul of Aldrich", boss = True), + DS3LocationData("AL: Soul of Aldrich", "Soul of Aldrich", boss=True), DS3LocationData("AL: Cinders of a Lord - Aldrich", "Cinders of a Lord - Aldrich", - offline = '06,0:50002130::', prominent = True, progression = True, - boss = True), - DS3LocationData("AL: Yorshka's Chime - kill Yorshka", "Yorshka's Chime", missable = True, - drop = True, - npc = True), # Hidden walkway, missable because it will break Sirris's quest - DS3LocationData("AL: Drang Twinspears - plaza, NPC drop", "Drang Twinspears", drop = True, - hidden = True), + offline='06,0:50002130::', prominent=True, progression=True, + boss=True), + DS3LocationData("AL: Yorshka's Chime - kill Yorshka", "Yorshka's Chime", missable=True, + drop=True, + npc=True), # Hidden walkway, missable because it will break Sirris's quest + DS3LocationData("AL: Drang Twinspears - plaza, NPC drop", "Drang Twinspears", drop=True, + hidden=True), DS3LocationData("AL: Estus Shard - dark cathedral, by left stairs", "Estus Shard"), DS3LocationData("AL: Painting Guardian's Curved Sword - prison tower rafters", - "Painting Guardian's Curved Sword", hidden = True), # Invisible walkway + "Painting Guardian's Curved Sword", hidden=True), # Invisible walkway DS3LocationData("AL: Brass Helm - tomb", "Brass Helm", - hidden = True), # Behind illusory wall + hidden=True), # Behind illusory wall DS3LocationData("AL: Brass Armor - tomb", "Brass Armor", - hidden = True), # Behind illusory wall + hidden=True), # Behind illusory wall DS3LocationData("AL: Brass Gauntlets - tomb", "Brass Gauntlets", - hidden = True), # Behind illusory wall + hidden=True), # Behind illusory wall DS3LocationData("AL: Brass Leggings - tomb", "Brass Leggings", - hidden = True), # Behind illusory wall + hidden=True), # Behind illusory wall DS3LocationData("AL: Human Dregs - water reserves", "Human Dregs", - hidden = True), # Behind illusory wall + hidden=True), # Behind illusory wall DS3LocationData("AL: Ember - spiral staircase, bottom", "Ember"), DS3LocationData("AL: Large Titanite Shard - bottom of the furthest buttress", "Large Titanite Shard"), @@ -1845,21 +1843,21 @@ def __init__( DS3LocationData("AL: Deep Gem - water reserves", "Deep Gem"), DS3LocationData("AL: Titanite Scale - top of ladder up to buttresses", "Titanite Scale"), DS3LocationData("AL: Dragonslayer Greatarrow - drop from nearest buttress", - "Dragonslayer Greatarrow x5", offline = '06,0:53700620::', - hidden = True), # Hidden fall + "Dragonslayer Greatarrow x5", offline='06,0:53700620::', + hidden=True), # Hidden fall DS3LocationData("AL: Dragonslayer Greatbow - drop from nearest buttress", - "Dragonslayer Greatbow", offline = '06,0:53700620::', - hidden = True), # Hidden fall + "Dragonslayer Greatbow", offline='06,0:53700620::', + hidden=True), # Hidden fall DS3LocationData("AL: Easterner's Ashes - below top of furthest buttress", - "Easterner's Ashes", progression = True), + "Easterner's Ashes", progression=True), DS3LocationData("AL: Painting Guardian Hood - prison tower, rafters", - "Painting Guardian Hood", hidden = True), # Invisible walkway + "Painting Guardian Hood", hidden=True), # Invisible walkway DS3LocationData("AL: Painting Guardian Gown - prison tower, rafters", - "Painting Guardian Gown", hidden = True), # Invisible walkway + "Painting Guardian Gown", hidden=True), # Invisible walkway DS3LocationData("AL: Painting Guardian Gloves - prison tower, rafters", - "Painting Guardian Gloves", hidden = True), # Invisible walkway + "Painting Guardian Gloves", hidden=True), # Invisible walkway DS3LocationData("AL: Painting Guardian Waistcloth - prison tower, rafters", - "Painting Guardian Waistcloth", hidden = True), # Invisible walkway + "Painting Guardian Waistcloth", hidden=True), # Invisible walkway DS3LocationData("AL: Soul of a Crestfallen Knight - right of dark cathedral entrance", "Soul of a Crestfallen Knight"), DS3LocationData("AL: Moonlight Arrow - dark cathedral, up right stairs", @@ -1869,111 +1867,111 @@ def __init__( DS3LocationData("AL: Large Soul of a Weary Warrior - left of dark cathedral entrance", "Large Soul of a Weary Warrior"), DS3LocationData("AL: Giant's Coal - by giant near dark cathedral", "Giant's Coal"), - DS3LocationData("AL: Havel's Ring+2 - prison tower, rafters", "Havel's Ring+2", ngp = True, - hidden = True), # Invisible walkway + DS3LocationData("AL: Havel's Ring+2 - prison tower, rafters", "Havel's Ring+2", ngp=True, + hidden=True), # Invisible walkway DS3LocationData("AL: Ring of Favor+1 - light cathedral, upstairs", "Ring of Favor+1", - ngp = True), + ngp=True), DS3LocationData("AL: Sun Princess Ring - dark cathedral, after boss", "Sun Princess Ring"), DS3LocationData("AL: Reversal Ring - tomb, chest in corner", "Reversal Ring", - hidden = True), # Behind illusory wall + hidden=True), # Behind illusory wall DS3LocationData("AL: Golden Ritual Spear - light cathedral, mimic upstairs", - "Golden Ritual Spear", mimic = True), + "Golden Ritual Spear", mimic=True), DS3LocationData("AL: Ring of Favor - water reserves, both minibosses", "Ring of Favor", - miniboss = True, - hidden = True), # Sulyvahn's Beast Duo drop, behind illusory wall + miniboss=True, + hidden=True), # Sulyvahn's Beast Duo drop, behind illusory wall DS3LocationData("AL: Blade of the Darkmoon - Yorshka with Darkmoon Loyalty", - "Blade of the Darkmoon", missable = True, drop = True, - npc = True), # Hidden walkway, missable because it will break Sirris's quest + "Blade of the Darkmoon", missable=True, drop=True, + npc=True), # Hidden walkway, missable because it will break Sirris's quest DS3LocationData("AL: Simple Gem - light cathedral, lizard upstairs", "Simple Gem", - lizard = True), + lizard=True), DS3LocationData("AL: Twinkling Titanite - lizard after light cathedral #1", - "Twinkling Titanite", lizard = True), + "Twinkling Titanite", lizard=True), DS3LocationData("AL: Twinkling Titanite - lizard after light cathedral #2", - "Twinkling Titanite", lizard = True), + "Twinkling Titanite", lizard=True), DS3LocationData("AL: Aldrich's Ruby - dark cathedral, miniboss", "Aldrich's Ruby", - miniboss = True), # Deep Accursed drop + miniboss=True), # Deep Accursed drop DS3LocationData("AL: Aldrich Faithful - water reserves, talk to McDonnel", "Aldrich Faithful", - hidden = True), # Behind illusory wall + hidden=True), # Behind illusory wall DS3LocationData("FS: Budding Green Blossom - shop after killing Creighton and AL boss", - "Budding Green Blossom", offline = '99,0:-1:110000,70000118:', - missable = True, npc = True, - shop = True), # sold by Shrine Maiden after killing Aldrich and helping - # Sirris defeat Creighton + "Budding Green Blossom", offline='99,0:-1:110000,70000118:', + missable=True, npc=True, + shop=True), # sold by Shrine Maiden after killing Aldrich and helping + # Sirris defeat Creighton # Sirris (quest completion) DS3LocationData("FS: Sunset Shield - by grave after killing Hodrick w/Sirris", - "Sunset Shield", missable = True, hostile_npc = True, npc = True), + "Sunset Shield", missable=True, hostile_npc=True, npc=True), # In Pit of Hollows after killing Hodrick DS3LocationData("US: Sunset Helm - Pit of Hollows after killing Hodrick w/Sirris", - "Sunset Helm", missable = True, hostile_npc = True, npc = True), + "Sunset Helm", missable=True, hostile_npc=True, npc=True), DS3LocationData("US: Sunset Armor - pit of hollows after killing Hodrick w/Sirris", - "Sunset Armor", missable = True, hostile_npc = True, npc = True), + "Sunset Armor", missable=True, hostile_npc=True, npc=True), DS3LocationData("US: Sunset Gauntlets - pit of hollows after killing Hodrick w/Sirris", - "Sunset Gauntlets", missable = True, hostile_npc = True, npc = True), + "Sunset Gauntlets", missable=True, hostile_npc=True, npc=True), DS3LocationData("US: Sunset Leggings - pit of hollows after killing Hodrick w/Sirris", - "Sunset Leggings", missable = True, hostile_npc = True, npc = True), + "Sunset Leggings", missable=True, hostile_npc=True, npc=True), # Shrine Handmaid after killing Sulyvahn's Beast Duo DS3LocationData("FS: Helm of Favor - shop after killing water reserve minibosses", - "Helm of Favor", hidden = True, miniboss = True, shop = True), + "Helm of Favor", hidden=True, miniboss=True, shop=True), DS3LocationData("FS: Embraced Armor of Favor - shop after killing water reserve minibosses", - "Embraced Armor of Favor", hidden = True, miniboss = True, shop = True), + "Embraced Armor of Favor", hidden=True, miniboss=True, shop=True), DS3LocationData("FS: Gauntlets of Favor - shop after killing water reserve minibosses", - "Gauntlets of Favor", hidden = True, miniboss = True, shop = True), + "Gauntlets of Favor", hidden=True, miniboss=True, shop=True), DS3LocationData("FS: Leggings of Favor - shop after killing water reserve minibosses", - "Leggings of Favor", hidden = True, miniboss = True, shop = True), + "Leggings of Favor", hidden=True, miniboss=True, shop=True), # Anri of Astora - DS3LocationData("AL: Chameleon - tomb after marrying Anri", "Chameleon", missable = True, - npc = True), + DS3LocationData("AL: Chameleon - tomb after marrying Anri", "Chameleon", missable=True, + npc=True), DS3LocationData("AL: Anri's Straight Sword - Anri quest", "Anri's Straight Sword", - missable = True, npc = True), + missable=True, npc=True), # Shrine Handmaid after killing Ringfinger Leonhard # This is listed here even though you can kill Leonhard immediately because we want the # logic to assume people will do his full quest. Missable because he can disappear forever # if you use up all your Pale Tongues. DS3LocationData("FS: Leonhard's Garb - shop after killing Leonhard", - "Leonhard's Garb", hidden = True, npc = True, shop = True, missable = True), + "Leonhard's Garb", hidden=True, npc=True, shop=True, missable=True), DS3LocationData("FS: Leonhard's Gauntlets - shop after killing Leonhard", - "Leonhard's Gauntlets", hidden = True, npc = True, shop = True, - missable = True), + "Leonhard's Gauntlets", hidden=True, npc=True, shop=True, + missable=True), DS3LocationData("FS: Leonhard's Trousers - shop after killing Leonhard", - "Leonhard's Trousers", hidden = True, npc = True, shop = True, - missable = True), + "Leonhard's Trousers", hidden=True, npc=True, shop=True, + missable=True), # Shrine Handmaid after killing Alrich, Devourer of Gods DS3LocationData("FS: Smough's Helm - shop after killing AL boss", "Smough's Helm", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Smough's Armor - shop after killing AL boss", "Smough's Armor", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Smough's Gauntlets - shop after killing AL boss", "Smough's Gauntlets", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Smough's Leggings - shop after killing AL boss", "Smough's Leggings", - boss = True, shop = True), + boss=True, shop=True), # Ringfinger Leonhard (quest or kill) DS3LocationData("AL: Crescent Moon Sword - Leonhard drop", "Crescent Moon Sword", - missable = True, npc = True), - DS3LocationData("AL: Silver Mask - Leonhard drop", "Silver Mask", missable = True, - npc = True), - DS3LocationData("AL: Soul of Rosaria - Leonhard drop", "Soul of Rosaria", missable = True, - npc = True), + missable=True, npc=True), + DS3LocationData("AL: Silver Mask - Leonhard drop", "Silver Mask", missable=True, + npc=True), + DS3LocationData("AL: Soul of Rosaria - Leonhard drop", "Soul of Rosaria", missable=True, + npc=True), # Shrine Handmaid after killing Anri or completing their quest DS3LocationData("FS: Elite Knight Helm - shop after Anri quest", "Elite Knight Helm", - npc = True, shop = True), + npc=True, shop=True), DS3LocationData("FS: Elite Knight Armor - shop after Anri quest", "Elite Knight Armor", - npc = True, shop = True), + npc=True, shop=True), DS3LocationData("FS: Elite Knight Gauntlets - shop after Anri quest", - "Elite Knight Gauntlets", npc = True, shop = True), + "Elite Knight Gauntlets", npc=True, shop=True), DS3LocationData("FS: Elite Knight Leggings - shop after Anri quest", - "Elite Knight Leggings", npc = True, shop = True), + "Elite Knight Leggings", npc=True, shop=True), ], "Lothric Castle": [ DS3LocationData("LC: Soul of Dragonslayer Armour", "Soul of Dragonslayer Armour", - prominent = True, boss = True), + prominent=True, boss=True), DS3LocationData("LC: Sniper Bolt - moat, right path end", "Sniper Bolt x11"), DS3LocationData("LC: Sniper Crossbow - moat, right path end", "Sniper Crossbow"), DS3LocationData("LC: Titanite Scale - dark room, upper balcony", "Titanite Scale"), @@ -1983,7 +1981,7 @@ def __init__( DS3LocationData("LC: Titanite Chunk - ascent, first balcony", "Titanite Chunk"), DS3LocationData("LC: Titanite Chunk - ascent, turret before barricades", "Titanite Chunk"), DS3LocationData("LC: Sacred Bloom Shield - ascent, behind illusory wall", - "Sacred Bloom Shield", hidden = True), # Behind illusory wall + "Sacred Bloom Shield", hidden=True), # Behind illusory wall DS3LocationData("LC: Titanite Chunk - ascent, final turret", "Titanite Chunk x2"), DS3LocationData("LC: Refined Gem - plaza", "Refined Gem"), DS3LocationData("LC: Soul of a Crestfallen Knight - by lift bottom", @@ -2003,7 +2001,7 @@ def __init__( "Large Soul of a Weary Warrior"), DS3LocationData("LC: Sunlight Medal - by lift top", "Sunlight Medal"), DS3LocationData("LC: Soul of a Crestfallen Knight - wyvern room, balcony", - "Soul of a Crestfallen Knight", hidden = True), # Hidden fall + "Soul of a Crestfallen Knight", hidden=True), # Hidden fall DS3LocationData("LC: Titanite Chunk - altar roof", "Titanite Chunk"), DS3LocationData("LC: Titanite Scale - dark room mid, out door opposite wyvern", "Titanite Scale"), @@ -2019,16 +2017,16 @@ def __init__( "Large Soul of a Nameless Soldier"), DS3LocationData("LC: Ember - plaza center", "Ember"), DS3LocationData("LC: Winged Knight Helm - ascent, behind illusory wall", - "Winged Knight Helm", hidden = True), + "Winged Knight Helm", hidden=True), DS3LocationData("LC: Winged Knight Armor - ascent, behind illusory wall", - "Winged Knight Armor", hidden = True), + "Winged Knight Armor", hidden=True), DS3LocationData("LC: Winged Knight Gauntlets - ascent, behind illusory wall", - "Winged Knight Gauntlets", hidden = True), + "Winged Knight Gauntlets", hidden=True), DS3LocationData("LC: Winged Knight Leggings - ascent, behind illusory wall", - "Winged Knight Leggings", hidden = True), + "Winged Knight Leggings", hidden=True), DS3LocationData("LC: Rusted Coin - chapel", "Rusted Coin x2"), DS3LocationData("LC: Braille Divine Tome of Lothric - wyvern room", - "Braille Divine Tome of Lothric", hidden = True), # Hidden fall + "Braille Divine Tome of Lothric", hidden=True), # Hidden fall DS3LocationData("LC: Red Tearstone Ring - chapel, drop onto roof", "Red Tearstone Ring"), DS3LocationData("LC: Twinkling Titanite - moat, left side", "Twinkling Titanite x2"), DS3LocationData("LC: Large Soul of a Nameless Soldier - plaza left, by pillar", @@ -2044,63 +2042,63 @@ def __init__( DS3LocationData("LC: Twinkling Titanite - basement, chest #1", "Twinkling Titanite"), DS3LocationData("LC: Twinkling Titanite - basement, chest #2", "Twinkling Titanite x2"), DS3LocationData("LC: Life Ring+2 - dark room mid, out door opposite wyvern, drop down", - "Life Ring+2", ngp = True, hidden = True), # Hidden fall + "Life Ring+2", ngp=True, hidden=True), # Hidden fall DS3LocationData("LC: Dark Stoneplate Ring+1 - wyvern room, balcony", - "Dark Stoneplate Ring+1", ngp = True, hidden = True), # Hidden fall + "Dark Stoneplate Ring+1", ngp=True, hidden=True), # Hidden fall DS3LocationData("LC: Thunder Stoneplate Ring+2 - chapel, drop onto roof", - "Thunder Stoneplate Ring+2", ngp = True), + "Thunder Stoneplate Ring+2", ngp=True), DS3LocationData("LC: Sunlight Straight Sword - wyvern room, mimic", - "Sunlight Straight Sword", mimic = True, hidden = True), # Hidden fall + "Sunlight Straight Sword", mimic=True, hidden=True), # Hidden fall DS3LocationData("LC: Titanite Scale - dark room, upper, mimic", "Titanite Scale x3", - mimic = True), + mimic=True), DS3LocationData("LC: Ember - wyvern room, wyvern foot mob drop", "Ember x2", - drop = True, hidden = True), # Hidden fall, Pus of Man Wyvern drop + drop=True, hidden=True), # Hidden fall, Pus of Man Wyvern drop DS3LocationData("LC: Titanite Chunk - wyvern room, wyvern foot mob drop", "Titanite Chunk x2", - drop = True, hidden = True), # Hidden fall, Pus of Man Wyvern drop + drop=True, hidden=True), # Hidden fall, Pus of Man Wyvern drop DS3LocationData("LC: Ember - dark room mid, pus of man mob drop", "Ember x2", - drop = True), # Pus of Man Wyvern drop + drop=True), # Pus of Man Wyvern drop DS3LocationData("LC: Titanite Chunk - dark room mid, pus of man mob drop", "Titanite Chunk x2"), DS3LocationData("LC: Irithyll Rapier - basement, miniboss drop", "Irithyll Rapier", - miniboss = True), # Boreal Outrider drop + miniboss=True), # Boreal Outrider drop DS3LocationData("LC: Twinkling Titanite - dark room mid, out door opposite wyvern, lizard", - "Twinkling Titanite x2", lizard = True), + "Twinkling Titanite x2", lizard=True), DS3LocationData("LC: Twinkling Titanite - moat, right path, lizard", - "Twinkling Titanite x2", lizard = True), + "Twinkling Titanite x2", lizard=True), DS3LocationData("LC: Gotthard Twinswords - by Grand Archives door, after PC and AL bosses", - "Gotthard Twinswords", conditional = True), + "Gotthard Twinswords", conditional=True), DS3LocationData("LC: Grand Archives Key - by Grand Archives door, after PC and AL bosses", - "Grand Archives Key", prominent = True, progression = True, - conditional = True), + "Grand Archives Key", prominent=True, progression=True, + conditional=True), DS3LocationData("LC: Titanite Chunk - down stairs after boss", "Titanite Chunk"), # Eygon of Carim (kill or quest) - DS3LocationData("FS: Morne's Great Hammer - Eygon", "Morne's Great Hammer", npc = True), - DS3LocationData("FS: Moaning Shield - Eygon", "Moaning Shield", npc = True), + DS3LocationData("FS: Morne's Great Hammer - Eygon", "Morne's Great Hammer", npc=True), + DS3LocationData("FS: Moaning Shield - Eygon", "Moaning Shield", npc=True), # Shrine Handmaid after killing Dragonslayer Armour (or Eygon of Carim) DS3LocationData("FS: Dancer's Crown - shop after killing LC entry boss", "Dancer's Crown", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Dancer's Armor - shop after killing LC entry boss", "Dancer's Armor", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Dancer's Gauntlets - shop after killing LC entry boss", - "Dancer's Gauntlets", boss = True, shop = True), + "Dancer's Gauntlets", boss=True, shop=True), DS3LocationData("FS: Dancer's Leggings - shop after killing LC entry boss", - "Dancer's Leggings", boss = True, shop = True), + "Dancer's Leggings", boss=True, shop=True), # Shrine Handmaid after killing Dragonslayer Armour (or Eygon of Carim) DS3LocationData("FS: Morne's Helm - shop after killing Eygon or LC boss", "Morne's Helm", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Morne's Armor - shop after killing Eygon or LC boss", "Morne's Armor", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Morne's Gauntlets - shop after killing Eygon or LC boss", - "Morne's Gauntlets", boss = True, shop = True), + "Morne's Gauntlets", boss=True, shop=True), DS3LocationData("FS: Morne's Leggings - shop after killing Eygon or LC boss", - "Morne's Leggings", boss = True, shop = True), + "Morne's Leggings", boss=True, shop=True), ], "Consumed King's Garden": [ DS3LocationData("CKG: Soul of Consumed Oceiros", "Soul of Consumed Oceiros", - prominent = True, boss = True), + prominent=True, boss=True), # Could classify this as "hidden" because it's midway down an elevator, but the elevator is # so slow and the midway point is so obvious that it's not actually hard to find. DS3LocationData("CKG: Estus Shard - balcony", "Estus Shard"), @@ -2124,43 +2122,43 @@ def __init__( DS3LocationData("CKG: Titanite Chunk - right of shortcut lift bottom", "Titanite Chunk"), DS3LocationData("CKG: Ring of Sacrifice - under balcony", "Ring of Sacrifice"), DS3LocationData("CKG: Wood Grain Ring+1 - by first elevator bottom", "Wood Grain Ring+1", - ngp = True), + ngp=True), DS3LocationData("CKG: Sage Ring+2 - balcony, drop onto rubble, jump back", "Sage Ring+2", - ngp = True, hidden = True), + ngp=True, hidden=True), DS3LocationData("CKG: Titanite Scale - tomb, chest #1", "Titanite Scale"), DS3LocationData("CKG: Titanite Scale - tomb, chest #2", "Titanite Scale"), DS3LocationData("CKG: Magic Stoneplate Ring - mob drop before boss", - "Magic Stoneplate Ring", drop = True, - hidden = True), # Guaranteed drop from a normal-looking Cathedral Knight + "Magic Stoneplate Ring", drop=True, + hidden=True), # Guaranteed drop from a normal-looking Cathedral Knight # After Oceiros's boss room, only once the Drakeblood summon in AP has been killed DS3LocationData("CKG: Drakeblood Helm - tomb, after killing AP mausoleum NPC", - "Drakeblood Helm", hostile_npc = True, hidden = True), + "Drakeblood Helm", hostile_npc=True, hidden=True), DS3LocationData("CKG: Drakeblood Armor - tomb, after killing AP mausoleum NPC", - "Drakeblood Armor", hostile_npc = True, hidden = True), + "Drakeblood Armor", hostile_npc=True, hidden=True), DS3LocationData("CKG: Drakeblood Gauntlets - tomb, after killing AP mausoleum NPC", - "Drakeblood Gauntlets", hostile_npc = True, hidden = True), + "Drakeblood Gauntlets", hostile_npc=True, hidden=True), DS3LocationData("CKG: Drakeblood Leggings - tomb, after killing AP mausoleum NPC", - "Drakeblood Leggings", hostile_npc = True, hidden = True), + "Drakeblood Leggings", hostile_npc=True, hidden=True), ], "Grand Archives": [ DS3LocationData("GA: Titanite Slab - final elevator secret", "Titanite Slab", - hidden = True), - DS3LocationData("GA: Soul of the Twin Princes", "Soul of the Twin Princes", boss = True), + hidden=True), + DS3LocationData("GA: Soul of the Twin Princes", "Soul of the Twin Princes", boss=True), DS3LocationData("GA: Cinders of a Lord - Lothric Prince", "Cinders of a Lord - Lothric Prince", - offline = "09,0:50002040::", prominent = True, progression = True, - boss = True), + offline="09,0:50002040::", prominent=True, progression=True, + boss=True), DS3LocationData("GA: Onikiri and Ubadachi - outside 5F, NPC drop", "Onikiri and Ubadachi", - hostile_npc = True, # Black Hand Kamui drop - missable = True), # This is placed at the location the NPC gets randomized - # to, which makes it hard to include in logic. + hostile_npc=True, # Black Hand Kamui drop + missable=True), # This is placed at the location the NPC gets randomized + # to, which makes it hard to include in logic. DS3LocationData("GA: Golden Wing Crest Shield - outside 5F, NPC drop", "Golden Wing Crest Shield", - hostile_npc = True), # Lion Knight Albert drop + hostile_npc=True), # Lion Knight Albert drop DS3LocationData("GA: Sage's Crystal Staff - outside 5F, NPC drop", "Sage's Crystal Staff", - hostile_npc = True), # Daughter of Crystal Kriemhild drop + hostile_npc=True), # Daughter of Crystal Kriemhild drop DS3LocationData("GA: Titanite Chunk - 1F, up right stairs", "Titanite Chunk"), DS3LocationData("GA: Titanite Chunk - 1F, path from wax pool", "Titanite Chunk"), DS3LocationData("GA: Soul of a Crestfallen Knight - 1F, loop left after drop", @@ -2175,22 +2173,22 @@ def __init__( DS3LocationData("GA: Estus Shard - dome, far balcony", "Estus Shard"), DS3LocationData("GA: Homeward Bone - 2F early balcony", "Homeward Bone x3"), DS3LocationData("GA: Titanite Scale - 2F, titanite scale atop bookshelf", "Titanite Scale", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("GA: Titanite Chunk - 2F, by wax pool", "Titanite Chunk"), DS3LocationData("GA: Hollow Gem - rooftops lower, in hall", "Hollow Gem", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("GA: Titanite Scale - 3F, corner up stairs", "Titanite Scale"), DS3LocationData("GA: Titanite Scale - 1F, up stairs on bookshelf", "Titanite Scale"), DS3LocationData("GA: Titanite Scale - 3F, by ladder to 2F late", "Titanite Scale", - hidden = True), # Hidden by a table + hidden=True), # Hidden by a table DS3LocationData("GA: Shriving Stone - 2F late, by ladder from 3F", "Shriving Stone"), DS3LocationData("GA: Large Soul of a Crestfallen Knight - 4F, back", "Large Soul of a Crestfallen Knight"), - DS3LocationData("GA: Titanite Chunk - rooftopps, balcony", "Titanite Chunk"), + DS3LocationData("GA: Titanite Chunk - rooftops, balcony", "Titanite Chunk"), DS3LocationData("GA: Titanite Scale - rooftops lower, path to 2F", "Titanite Scale x3", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("GA: Titanite Chunk - rooftops lower, ledge by buttress", "Titanite Chunk", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("GA: Soul of a Weary Warrior - rooftops, by lizards", "Soul of a Weary Warrior"), DS3LocationData("GA: Titanite Chunk - rooftops, just before 5F", "Titanite Chunk"), @@ -2200,113 +2198,113 @@ def __init__( DS3LocationData("GA: Large Soul of a Crestfallen Knight - outside 5F", "Large Soul of a Crestfallen Knight"), DS3LocationData("GA: Avelyn - 1F, drop from 3F onto bookshelves", "Avelyn", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("GA: Titanite Chunk - 2F, right after dark room", "Titanite Chunk"), DS3LocationData("GA: Hunter's Ring - dome, very top", "Hunter's Ring"), DS3LocationData("GA: Divine Pillars of Light - cage above rafters", "Divine Pillars of Light"), DS3LocationData("GA: Power Within - dark room, behind retractable bookshelf", - "Power Within", hidden = True), # Switch in darkened room - DS3LocationData("GA: Sage Ring+1 - rafters, second level down", "Sage Ring+1", ngp = True), + "Power Within", hidden=True), # Switch in darkened room + DS3LocationData("GA: Sage Ring+1 - rafters, second level down", "Sage Ring+1", ngp=True), DS3LocationData("GA: Lingering Dragoncrest Ring+2 - dome, room behind spire", - "Lingering Dragoncrest Ring+2", ngp = True), + "Lingering Dragoncrest Ring+2", ngp=True), DS3LocationData("GA: Divine Blessing - rafters, down lower level ladder", "Divine Blessing"), DS3LocationData("GA: Twinkling Titanite - rafters, down lower level ladder", "Twinkling Titanite x3"), DS3LocationData("GA: Witch's Locks - dark room, behind retractable bookshelf", - "Witch's Locks", hidden = True), # Switch in darkened room + "Witch's Locks", hidden=True), # Switch in darkened room DS3LocationData("GA: Titanite Slab - 1F, after pulling 2F switch", "Titanite Slab", - hidden = True), + hidden=True), DS3LocationData("GA: Titanite Scale - 4F, chest by exit", "Titanite Scale x3"), DS3LocationData("GA: Soul Stream - 3F, behind illusory wall", "Soul Stream", - hidden = True), # Behind illusory wall + hidden=True), # Behind illusory wall DS3LocationData("GA: Scholar Ring - 2F, between late and early", "Scholar Ring"), DS3LocationData("GA: Undead Bone Shard - 5F, by entrance", "Undead Bone Shard"), DS3LocationData("GA: Titanite Slab - dome, kill all mobs", "Titanite Slab", - drop = True, - hidden = True), # Guaranteed drop from killing all Winged Knights + drop=True, + hidden=True), # Guaranteed drop from killing all Winged Knights DS3LocationData("GA: Outrider Knight Helm - 3F, behind illusory wall, miniboss drop", - "Outrider Knight Helm", miniboss = True, - hidden = True), # Behind illusory wall, Outrider Knight drop + "Outrider Knight Helm", miniboss=True, + hidden=True), # Behind illusory wall, Outrider Knight drop DS3LocationData("GA: Outrider Knight Armor - 3F, behind illusory wall, miniboss drop", - "Outrider Knight Armor", miniboss = True, - hidden = True), # Behind illusory wall, Outrider Knight drop + "Outrider Knight Armor", miniboss=True, + hidden=True), # Behind illusory wall, Outrider Knight drop DS3LocationData("GA: Outrider Knight Gauntlets - 3F, behind illusory wall, miniboss drop", - "Outrider Knight Gauntlets", miniboss = True, - hidden = True), # Behind illusory wall, Outrider Knight drop + "Outrider Knight Gauntlets", miniboss=True, + hidden=True), # Behind illusory wall, Outrider Knight drop DS3LocationData("GA: Outrider Knight Leggings - 3F, behind illusory wall, miniboss drop", - "Outrider Knight Leggings", miniboss = True, - hidden = True), # Behind illusory wall, Outrider Knight drop + "Outrider Knight Leggings", miniboss=True, + hidden=True), # Behind illusory wall, Outrider Knight drop DS3LocationData("GA: Crystal Scroll - 2F late, miniboss drop", "Crystal Scroll", - miniboss = True), # Crystal Sage drop + miniboss=True), # Crystal Sage drop DS3LocationData("GA: Twinkling Titanite - dark room, lizard #1", "Twinkling Titanite", - lizard = True), - DS3LocationData("GA: Chaos Gem - dark room, lizard", "Chaos Gem", lizard = True), + lizard=True), + DS3LocationData("GA: Chaos Gem - dark room, lizard", "Chaos Gem", lizard=True), DS3LocationData("GA: Twinkling Titanite - 1F, lizard by drop", "Twinkling Titanite", - lizard = True), - DS3LocationData("GA: Crystal Gem - 1F, lizard by drop", "Crystal Gem", lizard = True), + lizard=True), + DS3LocationData("GA: Crystal Gem - 1F, lizard by drop", "Crystal Gem", lizard=True), DS3LocationData("GA: Twinkling Titanite - 2F, lizard by entrance", "Twinkling Titanite x2", - lizard = True), + lizard=True), DS3LocationData("GA: Titanite Scale - 1F, drop from 2F late onto bookshelves, lizard", - "Titanite Scale x2", lizard = True, hidden = True), # Hidden fall + "Titanite Scale x2", lizard=True, hidden=True), # Hidden fall DS3LocationData("GA: Twinkling Titanite - rooftops, lizard #1", "Twinkling Titanite", - lizard = True), - DS3LocationData("GA: Heavy Gem - rooftops, lizard", "Heavy Gem", lizard = True), + lizard=True), + DS3LocationData("GA: Heavy Gem - rooftops, lizard", "Heavy Gem", lizard=True), DS3LocationData("GA: Twinkling Titanite - rooftops, lizard #2", "Twinkling Titanite", - lizard = True), - DS3LocationData("GA: Sharp Gem - rooftops, lizard", "Sharp Gem", lizard = True), + lizard=True), + DS3LocationData("GA: Sharp Gem - rooftops, lizard", "Sharp Gem", lizard=True), DS3LocationData("GA: Twinkling Titanite - up stairs from 4F, lizard", "Twinkling Titanite", - lizard = True), + lizard=True), DS3LocationData("GA: Refined Gem - up stairs from 4F, lizard", "Refined Gem", - lizard = True), + lizard=True), DS3LocationData("GA: Twinkling Titanite - dark room, lizard #2", "Twinkling Titanite x2", - lizard = True), + lizard=True), # Shrine Handmaid after killing NPCs DS3LocationData("FS: Faraam Helm - shop after killing GA NPC", "Faraam Helm", - hidden = True, hostile_npc = True, shop = True), + hidden=True, hostile_npc=True, shop=True), DS3LocationData("FS: Faraam Armor - shop after killing GA NPC", "Faraam Armor", - hidden = True, hostile_npc = True, shop = True), + hidden=True, hostile_npc=True, shop=True), DS3LocationData("FS: Faraam Gauntlets - shop after killing GA NPC", "Faraam Gauntlets", - hidden = True, hostile_npc = True, shop = True), + hidden=True, hostile_npc=True, shop=True), DS3LocationData("FS: Faraam Boots - shop after killing GA NPC", "Faraam Boots", - hidden = True, hostile_npc = True, shop = True), + hidden=True, hostile_npc=True, shop=True), DS3LocationData("FS: Black Hand Hat - shop after killing GA NPC", "Black Hand Hat", - hidden = True, hostile_npc = True, shop = True), + hidden=True, hostile_npc=True, shop=True), DS3LocationData("FS: Black Hand Armor - shop after killing GA NPC", "Black Hand Armor", - hidden = True, hostile_npc = True, shop = True), + hidden=True, hostile_npc=True, shop=True), # Shrine Handmaid after killing Lothric, Younger Prince DS3LocationData("FS: Lorian's Helm - shop after killing GA boss", "Lorian's Helm", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Lorian's Armor - shop after killing GA boss", "Lorian's Armor", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Lorian's Gauntlets - shop after killing GA boss", "Lorian's Gauntlets", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Lorian's Leggings - shop after killing GA boss", "Lorian's Leggings", - boss = True, shop = True), + boss=True, shop=True), # Sirris quest completion + beat Twin Princes DS3LocationData("FS: Sunless Talisman - Sirris, kill GA boss", "Sunless Talisman", - missable = True, npc = True), + missable=True, npc=True), DS3LocationData("FS: Sunless Veil - shop, Sirris quest, kill GA boss", "Sunless Veil", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), DS3LocationData("FS: Sunless Armor - shop, Sirris quest, kill GA boss", "Sunless Armor", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), DS3LocationData("FS: Sunless Gauntlets - shop, Sirris quest, kill GA boss", - "Sunless Gauntlets", missable = True, npc = True, shop = True), + "Sunless Gauntlets", missable=True, npc=True, shop=True), DS3LocationData("FS: Sunless Leggings - shop, Sirris quest, kill GA boss", - "Sunless Leggings", missable = True, npc = True, shop = True), + "Sunless Leggings", missable=True, npc=True, shop=True), # Unbreakable Patches DS3LocationData("FS: Hidden Blessing - Patches after searching GA", "Hidden Blessing", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), ], "Untended Graves": [ - DS3LocationData("UG: Soul of Champion Gundyr", "Soul of Champion Gundyr", prominent = True, - boss = True), - DS3LocationData("UG: Priestess Ring - shop", "Priestess Ring", shop = True), + DS3LocationData("UG: Soul of Champion Gundyr", "Soul of Champion Gundyr", prominent=True, + boss=True), + DS3LocationData("UG: Priestess Ring - shop", "Priestess Ring", shop=True), DS3LocationData("UG: Shriving Stone - swamp, by bonfire", "Shriving Stone"), DS3LocationData("UG: Titanite Chunk - swamp, left path by fountain", "Titanite Chunk"), DS3LocationData("UG: Soul of a Crestfallen Knight - swamp, center", @@ -2316,63 +2314,63 @@ def __init__( DS3LocationData("UG: Black Knight Glaive - boss arena", "Black Knight Glaive"), DS3LocationData("UG: Hidden Blessing - cemetery, behind coffin", "Hidden Blessing"), DS3LocationData("UG: Eyes of a Fire Keeper - shrine, Irina's room", "Eyes of a Fire Keeper", - hidden = True), # Illusory wall + hidden=True), # Illusory wall DS3LocationData("UG: Soul of a Crestfallen Knight - environs, above shrine entrance", "Soul of a Crestfallen Knight"), DS3LocationData("UG: Blacksmith Hammer - shrine, Andre's room", "Blacksmith Hammer"), DS3LocationData("UG: Chaos Blade - environs, left of shrine", "Chaos Blade"), DS3LocationData("UG: Hornet Ring - environs, right of main path after killing FK boss", - "Hornet Ring", conditional = True), + "Hornet Ring", conditional=True), DS3LocationData("UG: Coiled Sword Fragment - shrine, dead bonfire", "Coiled Sword Fragment", - boss = True), - DS3LocationData("UG: Life Ring+3 - shrine, behind big throne", "Life Ring+3", ngp = True), + boss=True), + DS3LocationData("UG: Life Ring+3 - shrine, behind big throne", "Life Ring+3", ngp=True), DS3LocationData("UG: Ring of Steel Protection+1 - environs, behind bell tower", - "Ring of Steel Protection+1", ngp = True), + "Ring of Steel Protection+1", ngp=True), # Yuria shop, or Shrine Handmaiden with Hollow's Ashes # This is here because this is where the ashes end up if you kill Yoel or Yuria DS3LocationData("FS: Ring of Sacrifice - Yuria shop", "Ring of Sacrifice", - offline = '99,0:-1:40000,110000,70000107,70000116:', npc = True, - shop = True), + offline='99,0:-1:40000,110000,70000107,70000116:', npc=True, + shop=True), # Untended Graves Handmaid # All shop items are missable because she can be killed, except Priestess ring because she # drops it on death anyway. - DS3LocationData("UG: Ember - shop", "Ember", shop = True, missable = True), + DS3LocationData("UG: Ember - shop", "Ember", shop=True, missable=True), # Untended Graves Handmaid after killing Abyss Watchers DS3LocationData("UG: Wolf Knight Helm - shop after killing FK boss", "Wolf Knight Helm", - boss = True, shop = True, conditional = True, - missable = True), + boss=True, shop=True, conditional=True, + missable=True), DS3LocationData("UG: Wolf Knight Armor - shop after killing FK boss", - "Wolf Knight Armor", boss = True, shop = True, missable = True), + "Wolf Knight Armor", boss=True, shop=True, missable=True), DS3LocationData("UG: Wolf Knight Gauntlets - shop after killing FK boss", - "Wolf Knight Gauntlets", boss = True, shop = True, missable = True), + "Wolf Knight Gauntlets", boss=True, shop=True, missable=True), DS3LocationData("UG: Wolf Knight Leggings - shop after killing FK boss", - "Wolf Knight Leggings", boss = True, shop = True, missable = True), + "Wolf Knight Leggings", boss=True, shop=True, missable=True), # Shrine Handmaid after killing Champion Gundyr DS3LocationData("FS: Gundyr's Helm - shop after killing UG boss", "Gundyr's Helm", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Gundyr's Armor - shop after killing UG boss", "Gundyr's Armor", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Gundyr's Gauntlets - shop after killing UG boss", "Gundyr's Gauntlets", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Gundyr's Leggings - shop after killing UG boss", "Gundyr's Leggings", - boss = True, shop = True), + boss=True, shop=True), ], "Archdragon Peak": [ DS3LocationData("AP: Dragon Head Stone - fort, boss drop", "Dragon Head Stone", - prominent = True, boss = True), + prominent=True, boss=True), DS3LocationData("AP: Soul of the Nameless King", "Soul of the Nameless King", - prominent = True, boss = True), + prominent=True, boss=True), DS3LocationData("AP: Dragon Tooth - belfry roof, NPC drop", "Dragon Tooth", - hostile_npc = True), # Havel Knight drop + hostile_npc=True), # Havel Knight drop DS3LocationData("AP: Havel's Greatshield - belfry roof, NPC drop", "Havel's Greatshield", - hostile_npc = True), # Havel Knight drop + hostile_npc=True), # Havel Knight drop DS3LocationData("AP: Drakeblood Greatsword - mausoleum, NPC drop", "Drakeblood Greatsword", - hostile_npc = True), + hostile_npc=True), DS3LocationData("AP: Ricard's Rapier - belfry, NPC drop", "Ricard's Rapier", - hostile_npc = True), + hostile_npc=True), DS3LocationData("AP: Lightning Clutch Ring - intro, left of boss door", "Lightning Clutch Ring"), DS3LocationData("AP: Stalk Dung Pie - fort overlook", "Stalk Dung Pie x6"), @@ -2414,7 +2412,7 @@ def __init__( DS3LocationData("AP: Large Soul of a Crestfallen Knight - summit, by fountain", "Large Soul of a Crestfallen Knight"), DS3LocationData("AP: Dragon Chaser's Ashes - summit, side path", "Dragon Chaser's Ashes", - progression = True), + progression=True), DS3LocationData("AP: Ember - intro, by bonfire", "Ember"), DS3LocationData("AP: Dragonslayer Spear - gate after mausoleum", "Dragonslayer Spear"), DS3LocationData("AP: Dragonslayer Helm - plaza", "Dragonslayer Helm"), @@ -2426,81 +2424,81 @@ def __init__( "Twinkling Titanite x2"), DS3LocationData("AP: Titanite Slab - belfry roof", "Titanite Slab"), DS3LocationData("AP: Great Magic Barrier - drop off belfry roof", "Great Magic Barrier", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("AP: Titanite Slab - plaza", "Titanite Slab"), DS3LocationData("AP: Ring of Steel Protection - fort overlook, beside stairs", "Ring of Steel Protection"), DS3LocationData("AP: Havel's Ring+1 - summit, after building", "Havel's Ring+1", - ngp = True), + ngp=True), DS3LocationData("AP: Covetous Gold Serpent Ring+2 - plaza", "Covetous Gold Serpent Ring+2", - ngp = True), + ngp=True), DS3LocationData("AP: Titanite Scale - walkway building", "Titanite Scale x3"), DS3LocationData("AP: Twinkling Titanite - belfry, by ladder to roof", "Twinkling Titanite x3"), DS3LocationData("AP: Twinkling Dragon Torso Stone - summit, gesture at altar", - "Twinkling Dragon Torso Stone", hidden = True), # Requires gesture + "Twinkling Dragon Torso Stone", hidden=True), # Requires gesture DS3LocationData("AP: Calamity Ring - mausoleum, gesture at altar", "Calamity Ring", - hidden = True), # Requires gesture + hidden=True), # Requires gesture DS3LocationData("AP: Twinkling Titanite - walkway building, lizard", - "Twinkling Titanite x3", lizard = True), + "Twinkling Titanite x3", lizard=True), DS3LocationData("AP: Titanite Chunk - walkway, miniboss drop", "Titanite Chunk x6", - miniboss = True), # Wyvern miniboss drop + miniboss=True), # Wyvern miniboss drop DS3LocationData("AP: Titanite Scale - walkway, miniboss drop", "Titanite Scale x3", - miniboss = True), # Wyvern miniboss drop + miniboss=True), # Wyvern miniboss drop DS3LocationData("AP: Twinkling Titanite - walkway, miniboss drop", "Twinkling Titanite x3", - miniboss = True), # Wyvern miniboss drop + miniboss=True), # Wyvern miniboss drop DS3LocationData("FS: Hawkwood's Swordgrass - Andre after gesture in AP summit", - "Hawkwood's Swordgrass", conditional = True, hidden = True), + "Hawkwood's Swordgrass", conditional=True, hidden=True), # Shrine Handmaid after killing Nameless King DS3LocationData("FS: Golden Crown - shop after killing AP boss", "Golden Crown", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Dragonscale Armor - shop after killing AP boss", "Dragonscale Armor", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Golden Bracelets - shop after killing AP boss", "Golden Bracelets", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Dragonscale Waistcloth - shop after killing AP boss", - "Dragonscale Waistcloth", boss = True, shop = True), + "Dragonscale Waistcloth", boss=True, shop=True), DS3LocationData("FK: Twinkling Dragon Head Stone - Hawkwood drop", - "Twinkling Dragon Head Stone", missable = True, - npc = True), # Hawkwood (quest) + "Twinkling Dragon Head Stone", missable=True, + npc=True), # Hawkwood (quest) ], "Kiln of the First Flame": [ - DS3LocationData("KFF: Soul of the Lords", "Soul of the Lords", boss = True), + DS3LocationData("KFF: Soul of the Lords", "Soul of the Lords", boss=True), # Shrine Handmaid after placing all Cinders of a Lord DS3LocationData("FS: Titanite Slab - shop after placing all Cinders", "Titanite Slab", - offline = '99,0:-1:9210,110000:', hidden = True), + offline='99,0:-1:9210,110000:', hidden=True), DS3LocationData("FS: Firelink Helm - shop after placing all Cinders", "Firelink Helm", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Firelink Armor - shop after placing all Cinders", "Firelink Armor", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Firelink Gauntlets - shop after placing all Cinders", - "Firelink Gauntlets", boss = True, shop = True), + "Firelink Gauntlets", boss=True, shop=True), DS3LocationData("FS: Firelink Leggings - shop after placing all Cinders", - "Firelink Leggings", boss = True, shop = True), + "Firelink Leggings", boss=True, shop=True), # Yuria (quest, after Soul of Cinder) DS3LocationData("FS: Billed Mask - Yuria after killing KFF boss", "Billed Mask", - missable = True, npc = True), + missable=True, npc=True), DS3LocationData("FS: Black Dress - Yuria after killing KFF boss", "Black Dress", - missable = True, npc = True), + missable=True, npc=True), DS3LocationData("FS: Black Gauntlets - Yuria after killing KFF boss", "Black Gauntlets", - missable = True, npc = True), + missable=True, npc=True), DS3LocationData("FS: Black Leggings - Yuria after killing KFF boss", "Black Leggings", - missable = True, npc = True), + missable=True, npc=True), ], # DLC "Painted World of Ariandel (Before Contraption)": [ - DS3LocationData("PW1: Valorheart - boss drop", "Valorheart", prominent = True, boss = True), + DS3LocationData("PW1: Valorheart - boss drop", "Valorheart", prominent=True, boss=True), DS3LocationData("PW1: Contraption Key - library, NPC drop", "Contraption Key", - prominent = True, progression = True, - hostile_npc = True), # Sir Vilhelm drop + prominent=True, progression=True, + hostile_npc=True), # Sir Vilhelm drop DS3LocationData("PW1: Onyx Blade - library, NPC drop", "Onyx Blade", - hostile_npc = True), # Sir Vilhelm drop + hostile_npc=True), # Sir Vilhelm drop DS3LocationData("PW1: Chillbite Ring - Friede", "Chillbite Ring", - npc = True), # Friede conversation + npc=True), # Friede conversation DS3LocationData("PW1: Rime-blue Moss Clump - snowfield upper, starting cave", "Rime-blue Moss Clump x2"), DS3LocationData("PW1: Poison Gem - snowfield upper, forward from bonfire", "Poison Gem"), @@ -2511,9 +2509,9 @@ def __init__( "Large Soul of an Unknown Traveler"), DS3LocationData("PW1: Homeward Bone - snowfield village, outcropping", "Homeward Bone x6"), DS3LocationData("PW1: Blessed Gem - snowfield, behind tower", "Blessed Gem", - hidden = True), # Hidden behind a tower + hidden=True), # Hidden behind a tower DS3LocationData("PW1: Captain's Ashes - snowfield tower, 6F", "Captain's Ashes", - progression = True), + progression=True), DS3LocationData("PW1: Black Firebomb - snowfield lower, path to bonfire", "Black Firebomb x2"), DS3LocationData("PW1: Shriving Stone - below bridge near", "Shriving Stone"), @@ -2529,7 +2527,7 @@ def __init__( DS3LocationData("PW1: Large Soul of an Unknown Traveler - settlement courtyard, cliff", "Large Soul of an Unknown Traveler"), DS3LocationData("PW1: Crow Quills - settlement loop, jump into courtyard", "Crow Quills", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("PW1: Simple Gem - settlement, lowest level, behind gate", "Simple Gem"), DS3LocationData("PW1: Large Soul of an Unknown Traveler - settlement, by ladder to bonfire", "Large Soul of an Unknown Traveler"), @@ -2562,8 +2560,8 @@ def __init__( DS3LocationData("PW1: Rime-blue Moss Clump - below bridge far", "Rime-blue Moss Clump x4"), DS3LocationData("PW1: Follower Sabre - roots above depths", "Follower Sabre"), DS3LocationData("PW1: Ember - roots above depths", "Ember"), - DS3LocationData("PW1: Snap Freeze - depths, far end, mob drop", "Snap Freeze", drop = True, - hidden = True), # Guaranteed drop from normal-looking Tree Woman + DS3LocationData("PW1: Snap Freeze - depths, far end, mob drop", "Snap Freeze", drop=True, + hidden=True), # Guaranteed drop from normal-looking Tree Woman DS3LocationData("PW1: Rime-blue Moss Clump - snowfield upper, overhang", "Rime-blue Moss Clump"), DS3LocationData("PW1: Large Soul of an Unknown Traveler - snowfield lower, by cliff", @@ -2571,8 +2569,8 @@ def __init__( DS3LocationData("PW1: Ember - settlement, building near bonfire", "Ember"), DS3LocationData("PW1: Frozen Weapon - snowfield lower, egg zone", "Frozen Weapon"), DS3LocationData("PW1: Titanite Slab - depths, up secret ladder", "Titanite Slab", - offline = '11,0:54500640::', - hidden = True), # Must kill normal-looking Tree Woman + offline='11,0:54500640::', + hidden=True), # Must kill normal-looking Tree Woman DS3LocationData("PW1: Homeward Bone - depths, up hill", "Homeward Bone x2"), DS3LocationData("PW1: Large Soul of an Unknown Traveler - below snowfield village overhang", "Large Soul of an Unknown Traveler"), @@ -2588,24 +2586,24 @@ def __init__( DS3LocationData("PW1: Soul of a Weary Warrior - snowfield tower, 1F", "Soul of a Weary Warrior"), DS3LocationData("PW1: Twinkling Titanite - snowfield tower, 3F lizard", - "Twinkling Titanite", lizard = True), + "Twinkling Titanite", lizard=True), DS3LocationData("PW1: Large Titanite Shard - lizard under bridge near", - "Large Titanite Shard", lizard = True), + "Large Titanite Shard", lizard=True), DS3LocationData("PW1: Twinkling Titanite - roots, lizard", "Twinkling Titanite", - lizard = True), + lizard=True), DS3LocationData("PW1: Twinkling Titanite - settlement roofs, lizard before hall", - "Twinkling Titanite", lizard = True), + "Twinkling Titanite", lizard=True), DS3LocationData("PW1: Large Titanite Shard - settlement loop, lizard", - "Large Titanite Shard x2", lizard = True), + "Large Titanite Shard x2", lizard=True), ], "Painted World of Ariandel (After Contraption)": [ - DS3LocationData("PW2: Soul of Sister Friede", "Soul of Sister Friede", prominent = True, - boss = True), + DS3LocationData("PW2: Soul of Sister Friede", "Soul of Sister Friede", prominent=True, + boss=True), DS3LocationData("PW2: Titanite Slab - boss drop", "Titanite Slab", - offline = '11,0:50004700::', - boss = True), # One-time drop after Friede Phase 2 - DS3LocationData("PW2: Floating Chaos - NPC drop", "Floating Chaos", hostile_npc = True, - hidden = True), # Livid Pyromancer Dunnel drop (requires ember) + offline='11,0:50004700::', + boss=True), # One-time drop after Friede Phase 2 + DS3LocationData("PW2: Floating Chaos - NPC drop", "Floating Chaos", hostile_npc=True, + hidden=True), # Livid Pyromancer Dunnel drop (requires ember) DS3LocationData("PW2: Prism Stone - pass, tree by beginning", "Prism Stone x10"), DS3LocationData("PW2: Titanite Chunk - pass, cliff overlooking bonfire", "Titanite Chunk"), DS3LocationData("PW2: Titanite Chunk - pass, by kickable tree", "Titanite Chunk"), @@ -2631,32 +2629,32 @@ def __init__( DS3LocationData("PW2: Vilhelm's Leggings - B2, along wall", "Vilhelm's Leggings"), DS3LocationData("PW2: Blood Gem - B2, center", "Blood Gem"), DS3LocationData("PW2: Pyromancer's Parting Flame - rotunda", - "Pyromancer's Parting Flame", hidden = True), # Behind illusory wall + "Pyromancer's Parting Flame", hidden=True), # Behind illusory wall DS3LocationData("PW2: Homeward Bone - rotunda", "Homeward Bone x2", - hidden = True), # Behind illusory wall + hidden=True), # Behind illusory wall DS3LocationData("PW2: Twinkling Titanite - B3, lizard #1", "Twinkling Titanite", - lizard = True), + lizard=True), DS3LocationData("PW2: Twinkling Titanite - B3, lizard #2", "Twinkling Titanite", - lizard = True), + lizard=True), # Corvian Settler after killing Friede - DS3LocationData("PW1: Titanite Slab - Corvian", "Titanite Slab", npc = True), + DS3LocationData("PW1: Titanite Slab - Corvian", "Titanite Slab", npc=True), # Shrine Handmaid after killing Sister Friede DS3LocationData("FS: Ordained Hood - shop after killing PW2 boss", "Ordained Hood", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Ordained Dress - shop after killing PW2 boss", "Ordained Dress", - boss = True, shop = True), + boss=True, shop=True), DS3LocationData("FS: Ordained Trousers - shop after killing PW2 boss", "Ordained Trousers", - boss = True, shop = True), + boss=True, shop=True), ], "Dreg Heap": [ DS3LocationData("DH: Soul of the Demon Prince", "Soul of the Demon Prince", - prominent = True, boss = True), - DS3LocationData("DH: Siegbräu - Lapp", "Siegbräu", missable = True, drop = True, - npc = True), # Lapp (quest or kill) + prominent=True, boss=True), + DS3LocationData("DH: Siegbräu - Lapp", "Siegbräu", missable=True, drop=True, + npc=True), # Lapp (quest or kill) DS3LocationData("DH: Flame Fan - swamp upper, NPC drop", "Flame Fan", - hostile_npc = True), # Desert Pyromancer Zoey drop + hostile_npc=True), # Desert Pyromancer Zoey drop DS3LocationData("DH: Ember - castle, behind spire", "Ember"), DS3LocationData("DH: Soul of a Weary Warrior - castle overhang", "Soul of a Weary Warrior"), DS3LocationData("DH: Titanite Chunk - castle, up stairs", "Titanite Chunk"), @@ -2672,11 +2670,11 @@ def __init__( DS3LocationData("DH: Titanite Chunk - pantry, first room", "Titanite Chunk"), DS3LocationData("DH: Murky Longstaff - pantry, last room", "Murky Longstaff"), DS3LocationData("DH: Ember - pantry, behind crates just before upstairs", "Ember", - hidden = True), # Behind illusory wall + hidden=True), # Behind illusory wall DS3LocationData("DH: Great Soul Dregs - pantry upstairs", "Great Soul Dregs", - hidden = True), # Behind illusory wall + hidden=True), # Behind illusory wall DS3LocationData("DH: Covetous Silver Serpent Ring+3 - pantry upstairs, drop down", - "Covetous Silver Serpent Ring+3", hidden = True), # Behind illusory wall + "Covetous Silver Serpent Ring+3", hidden=True), # Behind illusory wall DS3LocationData("DH: Titanite Chunk - path from church, by pillar", "Titanite Chunk"), DS3LocationData("DH: Homeward Bone - end of path from church", "Homeward Bone x3"), DS3LocationData("DH: Lightning Urn - wall outside church", "Lightning Urn x4"), @@ -2717,52 +2715,52 @@ def __init__( DS3LocationData("DH: Desert Pyromancer Hood - swamp upper, tunnel end", "Desert Pyromancer Hood"), DS3LocationData("DH: Twinkling Titanite - swamp upper, drop onto root", - "Twinkling Titanite", hidden = True), # Hidden fall + "Twinkling Titanite", hidden=True), # Hidden fall DS3LocationData("DH: Divine Blessing - swamp upper, building roof", "Divine Blessing"), - DS3LocationData("DH: Ember - ruins, alcove on cliff", "Ember", hidden = True), # Hidden fall + DS3LocationData("DH: Ember - ruins, alcove on cliff", "Ember", hidden=True), # Hidden fall DS3LocationData("DH: Small Envoy Banner - boss drop", "Small Envoy Banner", - progression = True, boss = True), + progression=True, boss=True), DS3LocationData("DH: Twinkling Titanite - ruins, alcove on cliff, mob drop", - "Twinkling Titanite x2", drop = True, - hidden = True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim + "Twinkling Titanite x2", drop=True, + hidden=True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim DS3LocationData("DH: Twinkling Titanite - swamp upper, mob drop on roof", - "Twinkling Titanite x2", drop = True, - hidden = True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim + "Twinkling Titanite x2", drop=True, + hidden=True), # Hidden fall, also guaranteed drop from killing normal-looking pilgrim DS3LocationData("DH: Twinkling Titanite - path after church, mob drop", - "Twinkling Titanite x2", drop = True, - hidden = True), # Guaranteed drop from killing normal-looking pilgrim + "Twinkling Titanite x2", drop=True, + hidden=True), # Guaranteed drop from killing normal-looking pilgrim # Stone-humped Hag's shop - DS3LocationData("DH: Splitleaf Greatsword - shop", "Splitleaf Greatsword", shop = True), - DS3LocationData("DH: Divine Blessing - shop", "Divine Blessing", shop = True), - DS3LocationData("DH: Hidden Blessing - shop", "Hidden Blessing", shop = True), - DS3LocationData("DH: Rusted Gold Coin - shop", "Rusted Gold Coin", shop = True), - DS3LocationData("DH: Ember - shop", "Ember", shop = True), + DS3LocationData("DH: Splitleaf Greatsword - shop", "Splitleaf Greatsword", shop=True), + DS3LocationData("DH: Divine Blessing - shop", "Divine Blessing", shop=True), + DS3LocationData("DH: Hidden Blessing - shop", "Hidden Blessing", shop=True), + DS3LocationData("DH: Rusted Gold Coin - shop", "Rusted Gold Coin", shop=True), + DS3LocationData("DH: Ember - shop", "Ember", shop=True), ], "Ringed City": [ DS3LocationData("RC: Titanite Slab - mid boss drop", "Titanite Slab", - prominent = True, boss = True), # Halflight drop, only once + prominent=True, boss=True), # Halflight drop, only once DS3LocationData("RC: Filianore's Spear Ornament - mid boss drop", "Filianore's Spear Ornament"), - DS3LocationData("RC: Soul of Darkeater Midir", "Soul of Darkeater Midir", prominent = True, - boss = True), + DS3LocationData("RC: Soul of Darkeater Midir", "Soul of Darkeater Midir", prominent=True, + boss=True), DS3LocationData("RC: Sacred Chime of Filianore - ashes, NPC drop", "Sacred Chime of Filianore", - hostile_npc = True), # Shira (kill or quest) + hostile_npc=True), # Shira (kill or quest) DS3LocationData("RC: Titanite Slab - ashes, NPC drop", "Titanite Slab", - hostile_npc = True), # Shira (kill or quest) + hostile_npc=True), # Shira (kill or quest) DS3LocationData("RC: Crucifix of the Mad King - ashes, NPC drop", - "Crucifix of the Mad King", hostile_npc = True), # Shira drop + "Crucifix of the Mad King", hostile_npc=True), # Shira drop DS3LocationData("RC: Ledo's Great Hammer - streets high, opposite building, NPC drop", - "Ledo's Great Hammer", hostile_npc = True, - missable = True), # Silver Knight Ledo drop, doesn't invade once Halflight - # is defeated + "Ledo's Great Hammer", hostile_npc=True, + missable=True), # Silver Knight Ledo drop, doesn't invade once Halflight + # is defeated DS3LocationData("RC: Wolf Ring+3 - street gardens, NPC drop", "Wolf Ring+3", - hostile_npc = True, - missable = True), # Alva drop, doesn't invade once Halflight is defeated + hostile_npc=True, + missable=True), # Alva drop, doesn't invade once Halflight is defeated DS3LocationData("RC: Blindfold Mask - grave, NPC drop", "Blindfold Mask", - hostile_npc = True), # Moaning Knight drop - DS3LocationData("RC: Titanite Scale - wall top, behind spawn", "Titanite Scale"), # wrong + hostile_npc=True), # Moaning Knight drop + DS3LocationData("RC: Titanite Scale - wall top, behind spawn", "Titanite Scale"), # wrong DS3LocationData("RC: Ruin Helm - wall top, under stairs to bonfire", "Ruin Helm"), DS3LocationData("RC: Ruin Armor - wall top, under stairs to bonfire", "Ruin Armor"), DS3LocationData("RC: Ruin Gauntlets - wall top, under stairs to bonfire", "Ruin Gauntlets"), @@ -2774,9 +2772,9 @@ def __init__( DS3LocationData("RC: Budding Green Blossom - wall top, flowers by stairs", "Budding Green Blossom x2"), DS3LocationData("RC: Hidden Blessing - wall top, tomb under platform", "Hidden Blessing", - hidden = True), # hidden fall + hidden=True), # hidden fall DS3LocationData("RC: Soul of a Crestfallen Knight - wall top, under drop", - "Soul of a Crestfallen Knight", hidden = True), # hidden fall + "Soul of a Crestfallen Knight", hidden=True), # hidden fall DS3LocationData("RC: Large Soul of a Weary Warrior - wall top, right of small tomb", "Large Soul of a Weary Warrior"), DS3LocationData("RC: Ember - wall upper, balcony", "Ember"), @@ -2784,37 +2782,37 @@ def __init__( DS3LocationData("RC: Hollow Gem - wall upper, path to tower", "Hollow Gem"), DS3LocationData("RC: Titanite Chunk - wall upper, courtyard alcove", "Titanite Chunk"), DS3LocationData("RC: Twinkling Titanite - wall tower, jump from chandelier", - "Twinkling Titanite", hidden = True), # Hidden fall + "Twinkling Titanite", hidden=True), # Hidden fall DS3LocationData("RC: Shriving Stone - wall tower, bottom floor center", "Shriving Stone"), DS3LocationData("RC: Shira's Crown - Shira's room after killing ashes NPC", "Shira's Crown", - hidden = True), # Have to return to a cleared area + hidden=True), # Have to return to a cleared area DS3LocationData("RC: Shira's Armor - Shira's room after killing ashes NPC", "Shira's Armor", - hidden = True), # Have to return to a cleared area + hidden=True), # Have to return to a cleared area DS3LocationData("RC: Shira's Gloves - Shira's room after killing ashes NPC", - "Shira's Gloves", hidden = True), # Have to return to a cleared area + "Shira's Gloves", hidden=True), # Have to return to a cleared area DS3LocationData("RC: Shira's Trousers - Shira's room after killing ashes NPC", - "Shira's Trousers", hidden = True), # Have to return to a cleared area + "Shira's Trousers", hidden=True), # Have to return to a cleared area DS3LocationData("RC: Mossfruit - streets near left, path to garden", "Mossfruit x2"), DS3LocationData("RC: Large Soul of a Crestfallen Knight - streets, far stairs", "Large Soul of a Crestfallen Knight"), DS3LocationData("RC: Ringed Knight Spear - streets, down far right hall", "Ringed Knight Spear"), DS3LocationData("RC: Black Witch Hat - streets garden", "Black Witch Hat", - hostile_npc = True), # Alva + hostile_npc=True), # Alva DS3LocationData("RC: Black Witch Garb - streets garden", "Black Witch Garb", - hostile_npc = True), # Alva + hostile_npc=True), # Alva DS3LocationData("RC: Black Witch Wrappings - streets garden", "Black Witch Wrappings", - hostile_npc = True), # Alva + hostile_npc=True), # Alva DS3LocationData("RC: Black Witch Trousers - streets garden", "Black Witch Trousers", - hostile_npc = True), # Alva + hostile_npc=True), # Alva DS3LocationData("RC: Dragonhead Shield - streets monument, across bridge", - "Dragonhead Shield", hidden = True), # "Show Your Humanity" puzzle + "Dragonhead Shield", hidden=True), # "Show Your Humanity" puzzle DS3LocationData("RC: Titanite Chunk - streets, near left drop", "Titanite Chunk", - hidden = True), # Hidden fall + hidden=True), # Hidden fall DS3LocationData("RC: Mossfruit - streets, far left alcove", "Mossfruit x2"), DS3LocationData("RC: Large Soul of a Crestfallen Knight - streets monument, across bridge", "Large Soul of a Crestfallen Knight", - hidden = True), # "Show Your Humanity" puzzle + hidden=True), # "Show Your Humanity" puzzle DS3LocationData("RC: Covetous Gold Serpent Ring+3 - streets, by Lapp", "Covetous Gold Serpent Ring+3"), DS3LocationData("RC: Titanite Chunk - streets high, building opposite", "Titanite Chunk x2"), @@ -2823,7 +2821,7 @@ def __init__( DS3LocationData("RC: Ringed Knight Straight Sword - swamp near, tower on peninsula", "Ringed Knight Straight Sword"), DS3LocationData("RC: Havel's Ring+3 - streets high, drop from building opposite", - "Havel's Ring+3", hidden = True), # Hidden fall + "Havel's Ring+3", hidden=True), # Hidden fall DS3LocationData("RC: Titanite Chunk - swamp near left, by spire top", "Titanite Chunk"), DS3LocationData("RC: Twinkling Titanite - swamp near left", "Twinkling Titanite"), DS3LocationData("RC: Soul of a Weary Warrior - swamp center", "Soul of a Weary Warrior"), @@ -2853,11 +2851,11 @@ def __init__( DS3LocationData("RC: Blessed Gem - grave, down lowest stairs", "Blessed Gem"), DS3LocationData("RC: Simple Gem - grave, up stairs after first drop", "Simple Gem"), DS3LocationData("RC: Large Soul of a Weary Warrior - wall lower, past two illusory walls", - "Large Soul of a Weary Warrior", hidden = True), + "Large Soul of a Weary Warrior", hidden=True), DS3LocationData("RC: Lightning Arrow - wall lower, past three illusory walls", "Lightning Arrow"), DS3LocationData("RC: Chloranthy Ring+3 - wall hidden, drop onto statue", - "Chloranthy Ring+3", hidden = True), # Hidden fall + "Chloranthy Ring+3", hidden=True), # Hidden fall DS3LocationData("RC: Ember - wall hidden, statue room", "Ember"), DS3LocationData("RC: Filianore's Spear Ornament - wall hidden, by ladder", "Filianore's Spear Ornament"), @@ -2886,55 +2884,55 @@ def __init__( DS3LocationData("RC: Young White Branch - swamp far left, by white tree #3", "Young White Branch"), DS3LocationData("RC: Ringed Knight Paired Greatswords - church path, mob drop", - "Ringed Knight Paired Greatswords", drop = True, - hidden = True), # Guaranteed drop from a normal-looking Ringed Knight + "Ringed Knight Paired Greatswords", drop=True, + hidden=True), # Guaranteed drop from a normal-looking Ringed Knight DS3LocationData("RC: Hidden Blessing - swamp center, mob drop", "Hidden Blessing", - drop = True, hidden = True), # Guaranteed drop from Judicator + drop=True, hidden=True), # Guaranteed drop from Judicator DS3LocationData("RC: Divine Blessing - wall top, mob drop", "Divine Blessing", - drop = True, hidden = True), # Guaranteed drop from Judicator + drop=True, hidden=True), # Guaranteed drop from Judicator DS3LocationData("RC: Divine Blessing - streets monument, mob drop", "Divine Blessing", - drop = True, - hidden = True), # Guaranteed drop from Judicator, "Show Your Humanity" puzzle + drop=True, + hidden=True), # Guaranteed drop from Judicator, "Show Your Humanity" puzzle DS3LocationData("RC: Ring of the Evil Eye+3 - grave, mimic", "Ring of the Evil Eye+3", - mimic = True), + mimic=True), DS3LocationData("RC: Iron Dragonslayer Helm - swamp far, miniboss drop", - "Iron Dragonslayer Helm", miniboss = True), + "Iron Dragonslayer Helm", miniboss=True), DS3LocationData("RC: Iron Dragonslayer Armor - swamp far, miniboss drop", - "Iron Dragonslayer Armor", miniboss = True), + "Iron Dragonslayer Armor", miniboss=True), DS3LocationData("RC: Iron Dragonslayer Gauntlets - swamp far, miniboss drop", - "Iron Dragonslayer Gauntlets", miniboss = True), + "Iron Dragonslayer Gauntlets", miniboss=True), DS3LocationData("RC: Iron Dragonslayer Leggings - swamp far, miniboss drop", - "Iron Dragonslayer Leggings", miniboss = True), + "Iron Dragonslayer Leggings", miniboss=True), DS3LocationData("RC: Church Guardian Shiv - swamp far left, in building", "Church Guardian Shiv"), DS3LocationData("RC: Spears of the Church - hidden boss drop", "Spears of the Church", - boss = True), # Midir drop + boss=True), # Midir drop DS3LocationData("RC: Ritual Spear Fragment - church path", "Ritual Spear Fragment"), DS3LocationData("RC: Titanite Scale - swamp far, lagoon entrance", "Titanite Scale"), DS3LocationData("RC: Twinkling Titanite - grave, lizard past first drop", - "Twinkling Titanite", lizard = True), + "Twinkling Titanite", lizard=True), DS3LocationData("RC: Titanite Scale - grave, lizard past first drop", "Titanite Scale", - lizard = True), + lizard=True), DS3LocationData("RC: Twinkling Titanite - streets high, lizard", "Twinkling Titanite x2", - lizard = True), - DS3LocationData("RC: Titanite Scale - wall lower, lizard", "Titanite Scale", lizard = True), + lizard=True), + DS3LocationData("RC: Titanite Scale - wall lower, lizard", "Titanite Scale", lizard=True), DS3LocationData("RC: Twinkling Titanite - wall top, lizard on side path", - "Twinkling Titanite", lizard = True), + "Twinkling Titanite", lizard=True), DS3LocationData("RC: Soul of Slave Knight Gael", "Soul of Slave Knight Gael", - prominent = True, boss = True), + prominent=True, boss=True), DS3LocationData("RC: Blood of the Dark Soul - end boss drop", "Blood of the Dark Soul"), DS3LocationData("RC: Titanite Slab - ashes, mob drop", "Titanite Slab", - drop = True, - hidden = True), # Guaranteed drop from normal-looking Ringed Knight + drop=True, + hidden=True), # Guaranteed drop from normal-looking Ringed Knight # Lapp - DS3LocationData("RC: Siegbräu - Lapp", "Siegbräu", missable = True, - npc = True), # Lapp (quest) + DS3LocationData("RC: Siegbräu - Lapp", "Siegbräu", missable=True, + npc=True), # Lapp (quest) # Quest or Shrine Handmaiden after death - DS3LocationData("RC: Lapp's Helm - Lapp", "Lapp's Helm", npc = True, shop = True), - DS3LocationData("RC: Lapp's Armor - Lapp", "Lapp's Armor", npc = True, shop = True), - DS3LocationData("RC: Lapp's Gauntlets - Lapp", "Lapp's Gauntlets", npc = True, shop = True), - DS3LocationData("RC: Lapp's Leggings - Lapp", "Lapp's Leggings", npc = True, shop = True), + DS3LocationData("RC: Lapp's Helm - Lapp", "Lapp's Helm", npc=True, shop=True), + DS3LocationData("RC: Lapp's Armor - Lapp", "Lapp's Armor", npc=True, shop=True), + DS3LocationData("RC: Lapp's Gauntlets - Lapp", "Lapp's Gauntlets", npc=True, shop=True), + DS3LocationData("RC: Lapp's Leggings - Lapp", "Lapp's Leggings", npc=True, shop=True), ], # Unlockable shops. We only bother creating a "region" for these for shops that are locked @@ -2942,79 +2940,79 @@ def __init__( # ashes. "Greirat's Shop": [ DS3LocationData("FS: Blue Tearstone Ring - Greirat", "Blue Tearstone Ring", - offline = '01,0:50006120::', npc = True), - DS3LocationData("FS: Ember - Greirat", "Ember", offline = "99,0:-1:110000,120000,70000110:", - shop = True, npc = True), + offline='01,0:50006120::', npc=True), + DS3LocationData("FS: Ember - Greirat", "Ember", offline="99,0:-1:110000,120000,70000110:", + shop=True, npc=True), # Undead Settlement rewards DS3LocationData("FS: Divine Blessing - Greirat from US", "Divine Blessing", - offline = '99,0:-1:110000,120000,70000150,70000175:', missable = True, - shop = True, npc = True), + offline='99,0:-1:110000,120000,70000150,70000175:', missable=True, + shop=True, npc=True), DS3LocationData("FS: Ember - Greirat from US", "Ember", - offline = '99,0:-1:110000,120000,70000150,70000175:', missable = True, - shop = True, npc = True), + offline='99,0:-1:110000,120000,70000150,70000175:', missable=True, + shop=True, npc=True), # Irityhll rewards DS3LocationData("FS: Divine Blessing - Greirat from IBV", "Divine Blessing", - offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, - shop = True, npc = True), + offline='99,0:-1:110000,120000,70000151,70000176:', missable=True, + shop=True, npc=True), DS3LocationData("FS: Hidden Blessing - Greirat from IBV", "Hidden Blessing", - offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, - shop = True, npc = True), + offline='99,0:-1:110000,120000,70000151,70000176:', missable=True, + shop=True, npc=True), DS3LocationData("FS: Titanite Scale - Greirat from IBV", "Titanite Scale", - offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, - shop = True, npc = True), + offline='99,0:-1:110000,120000,70000151,70000176:', missable=True, + shop=True, npc=True), DS3LocationData("FS: Twinkling Titanite - Greirat from IBV", "Twinkling Titanite", - offline = '99,0:-1:110000,120000,70000151,70000176:', missable = True, - shop = True, npc = True), + offline='99,0:-1:110000,120000,70000151,70000176:', missable=True, + shop=True, npc=True), # Lothric rewards (from Shrine Handmaid) DS3LocationData("FS: Ember - shop for Greirat's Ashes", "Twinkling Titanite", - offline = '99,0:-1:110000,120000,70000152,70000177:', missable = True, - shop = True, npc = True), + offline='99,0:-1:110000,120000,70000152,70000177:', missable=True, + shop=True, npc=True), ], "Karla's Shop": [ - DS3LocationData("FS: Affinity - Karla", "Affinity", shop = True, npc = True), - DS3LocationData("FS: Dark Edge - Karla", "Dark Edge", shop = True, npc = True), + DS3LocationData("FS: Affinity - Karla", "Affinity", shop=True, npc=True), + DS3LocationData("FS: Dark Edge - Karla", "Dark Edge", shop=True, npc=True), # Quelana Pyromancy Tome - DS3LocationData("FS: Firestorm - Karla for Quelana Tome", "Firestorm", missable = True, - shop = True, npc = True), - DS3LocationData("FS: Rapport - Karla for Quelana Tome", "Rapport", missable = True, - shop = True, npc = True), - DS3LocationData("FS: Fire Whip - Karla for Quelana Tome", "Fire Whip", missable = True, - shop = True, npc = True), + DS3LocationData("FS: Firestorm - Karla for Quelana Tome", "Firestorm", missable=True, + shop=True, npc=True), + DS3LocationData("FS: Rapport - Karla for Quelana Tome", "Rapport", missable=True, + shop=True, npc=True), + DS3LocationData("FS: Fire Whip - Karla for Quelana Tome", "Fire Whip", missable=True, + shop=True, npc=True), # Grave Warden Pyromancy Tome DS3LocationData("FS: Black Flame - Karla for Grave Warden Tome", "Black Flame", - missable = True, shop = True, npc = True), + missable=True, shop=True, npc=True), DS3LocationData("FS: Black Fire Orb - Karla for Grave Warden Tome", "Black Fire Orb", - missable = True, shop = True, npc = True), + missable=True, shop=True, npc=True), - # Deep Braille Divine Tome. This can also be given to Irina but it'll fail her quest - DS3LocationData("FS: Gnaw - Karla for Deep Braille Tome", "Gnaw", missable = True, - npc = True, shop = True), + # Deep Braille Divine Tome. This can also be given to Irina, but it'll fail her quest + DS3LocationData("FS: Gnaw - Karla for Deep Braille Tome", "Gnaw", missable=True, + npc=True, shop=True), DS3LocationData("FS: Deep Protection - Karla for Deep Braille Tome", "Deep Protection", - missable = True, npc = True, shop = True), + missable=True, npc=True, shop=True), - # Londor Braille Divine Tome. This can also be given to Irina but it'll fail her quest + # Londor Braille Divine Tome. This can also be given to Irina, but it'll fail her quest DS3LocationData("FS: Vow of Silence - Karla for Londor Tome", "Vow of Silence", - missable = True, npc = True, shop = True), - DS3LocationData("FS: Dark Blade - Karla for Londor Tome", "Dark Blade", missable = True, - npc = True, shop = True), - DS3LocationData("FS: Dead Again - Karla for Londor Tome", "Dead Again", missable = True, - npc = True, shop = True), + missable=True, npc=True, shop=True), + DS3LocationData("FS: Dark Blade - Karla for Londor Tome", "Dark Blade", missable=True, + npc=True, shop=True), + DS3LocationData("FS: Dead Again - Karla for Londor Tome", "Dead Again", missable=True, + npc=True, shop=True), # Drops on death. Missable because the player would have to decide between killing her or # seeing everything she sells. DS3LocationData("FS: Karla's Pointed Hat - kill Karla", "Karla's Pointed Hat", - offline = '07,0:50006150::', missable = True, drop = True, npc = True), + offline='07,0:50006150::', missable=True, drop=True, npc=True), DS3LocationData("FS: Karla's Coat - kill Karla", "Karla's Coat", - offline = '07,0:50006150::', missable = True, drop = True, npc = True), + offline='07,0:50006150::', missable=True, drop=True, npc=True), DS3LocationData("FS: Karla's Gloves - kill Karla", "Karla's Gloves", - offline = '07,0:50006150::', missable = True, drop = True, npc = True), + offline='07,0:50006150::', missable=True, drop=True, npc=True), DS3LocationData("FS: Karla's Trousers - kill Karla", "Karla's Trousers", - offline = '07,0:50006150::', missable = True, drop = True, npc = True), + offline='07,0:50006150::', missable=True, drop=True, npc=True), ], } @@ -3038,7 +3036,6 @@ def __init__( for location in location_tables[region]: location.conditional = True - location_name_groups: Dict[str, Set[str]] = { # We could insert these locations automatically with setdefault(), but we set them up explicitly # instead so we can choose the ordering. @@ -3064,31 +3061,30 @@ def __init__( "Spells": set(), } - location_descriptions = { "Prominent": "A small number of locations that are in very obvious locations. Mostly boss " + \ - "drops. Ideal for setting as priority locations.", + "drops. Ideal for setting as priority locations.", "Progression": "Locations that contain items in vanilla which unlock other locations.", "Boss Rewards": "Boss drops. Does not include soul transfusions or shop items.", "Miniboss Rewards": "Miniboss drops. Only includes enemies considered minibosses by the " + \ - "enemy randomizer.", + "enemy randomizer.", "Mimic Rewards": "Drops from enemies that are mimics in vanilla.", "Hostile NPC Rewards": "Drops from NPCs that are hostile to you. This includes scripted " + \ - "invaders and initially-friendly NPCs that must be fought as part of their quest.", + "invaders and initially-friendly NPCs that must be fought as part of their quest.", "Friendly NPC Rewards": "Items given by friendly NPCs as part of their quests or from " + \ - "non-violent interaction.", + "non-violent interaction.", "Upgrade": "Locations that contain upgrade items in vanilla, including titanite, gems, and " + \ - "Shriving Stones.", + "Shriving Stones.", "Small Souls": "Locations that contain soul items in vanilla, not including boss souls.", "Boss Souls": "Locations that contain boss souls in vanilla, as well as Soul of Rosaria.", "Unique": "Locations that contain items in vanilla that are unique per NG cycle, such as " + \ - "scrolls, keys, ashes, and so on. Doesn't cover equipment, spells, or souls.", + "scrolls, keys, ashes, and so on. Doesn't cover equipment, spells, or souls.", "Healing": "Locations that contain Undead Bone Shards and Estus Shards in vanilla.", "Miscellaneous": "Locations that contain generic stackable items in vanilla, such as arrows, " + - "firebombs, buffs, and so on.", + "firebombs, buffs, and so on.", "Hidden": "Locations that are particularly difficult to find, such as behind illusory " + \ - "walls, down hidden drops, and so on. Does not include large locations like Untended " + \ - "Graves or Archdragon Peak.", + "walls, down hidden drops, and so on. Does not include large locations like Untended " + \ + "Graves or Archdragon Peak.", "Weapons": "Locations that contain weapons in vanilla.", "Shields": "Locations that contain shields in vanilla.", "Armor": "Locations that contain armor in vanilla.", @@ -3096,7 +3092,6 @@ def __init__( "Spells": "Locations that contain spells in vanilla.", } - location_dictionary: Dict[str, DS3LocationData] = {} for location_name, location_table in location_tables.items(): location_dictionary.update({location_data.name: location_data for location_data in location_table}) @@ -3115,13 +3110,13 @@ def __init__( location_name_groups["Painted World of Ariandel"] = ( location_name_groups["Painted World of Ariandel (Before Contraption)"] - .union(location_name_groups["Painted World of Ariandel (After Contraption)"]) + .union(location_name_groups["Painted World of Ariandel (After Contraption)"]) ) del location_name_groups["Painted World of Ariandel (Before Contraption)"] del location_name_groups["Painted World of Ariandel (After Contraption)"] location_name_groups["DLC"] = ( location_name_groups["Painted World of Ariandel"] - .union(location_name_groups["Dreg Heap"]) - .union(location_name_groups["Ringed City"]) + .union(location_name_groups["Dreg Heap"]) + .union(location_name_groups["Ringed City"]) ) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 6afaceba2942..c675fc509940 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -299,8 +299,8 @@ class MaxLevelsIn10WeaponPoolOption(Range): class EarlySmallLothricBanner(Choice): - """This option makes it so the user can choose to force the Small Lothric Banner into an early sphere in their world or - into an early sphere across all worlds.""" + """This option makes it so the user can choose to force the Small Lothric Banner into an early sphere in their world + or into an early sphere across all worlds.""" display_name = "Early Small Lothric Banner" option_off = 0 option_early_global = 1 @@ -363,8 +363,8 @@ class RandomEnemyPresetOption(Option[typing.Dict[str, typing.Any]], VerifyKeys): default = {} valid_keys = ["Description", "RecommendFullRandomization", "RecommendNoEnemyProgression", - "OopsAll", "Boss", "Miniboss", "Basic", "BuffBasicEnemiesAsBosses", - "DontRandomize", "RemoveSource", "Enemies"] + "OopsAll", "Boss", "Miniboss", "Basic", "BuffBasicEnemiesAsBosses", + "DontRandomize", "RemoveSource", "Enemies"] def __init__(self, value: typing.Dict[str, typing.Any]): self.value = deepcopy(value) @@ -374,7 +374,7 @@ def get_option_name(self, value: typing.Dict[str, typing.Any]): @classmethod def from_any(cls, data: typing.Dict[str, typing.Any]) -> "RandomEnemyPresetOption": - if type(data) == dict: + if isinstance(data, dict): cls.verify_keys(data) return cls(data) else: @@ -386,7 +386,7 @@ class RandomizeMimicsWithEnemiesOption(Toggle): 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 Mimcs as well if you enable this. + enable Impatient Mimics as well if you enable this. This is ignored unless enemies are randomized. """ diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 5ea2017bb7cd..4e75bb5601f8 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -6,10 +6,9 @@ from typing import Callable, Dict, Set, List, Optional, TextIO, Union from BaseClasses import CollectionState, MultiWorld, Region, Item, Location, LocationProgressType, Entrance, Tutorial, ItemClassification -from Options import Toggle from worlds.AutoWorld import World, WebWorld -from worlds.generic.Rules import CollectionRule, ItemRule, set_rule, add_rule, add_item_rule +from worlds.generic.Rules import CollectionRule, ItemRule, add_rule, add_item_rule from .Bosses import DS3BossInfo, all_bosses, default_yhorm_location from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, Infusion, UsefulIf, filler_item_names, item_descriptions, item_dictionary, item_name_groups @@ -44,11 +43,11 @@ class DarkSouls3Web(WebWorld): class DarkSouls3World(World): """ Dark souls III is an Action role-playing game and is part of the Souls series developed by FromSoftware. - Played in a third-person perspective, players have access to various weapons, armour, magic, and consumables that + Played from a third-person perspective, players have access to various weapons, armour, magic, and consumables that they can use to fight their enemies. """ - game: str = "Dark Souls III" + game = "Dark Souls III" options: DarkSouls3Options options_dataclass = DarkSouls3Options web = DarkSouls3Web() @@ -166,8 +165,7 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: def create_regions(self): # Create Vanilla Regions - regions: Dict[str, Region] = {} - regions["Menu"] = self.create_region("Menu", {}) + regions: Dict[str, Region] = {"Menu": self.create_region("Menu", {})} regions.update({region_name: self.create_region(region_name, location_tables[region_name]) for region_name in [ "Cemetery of Ash", "Firelink Shrine", @@ -344,7 +342,7 @@ def _create_injectable_items(self, num_required_extra_items: int) -> List[Item]: If there isn't enough room to inject all the necessary progression items that are in missable locations by default, this adds them to the - player's starting inventoy. + player's starting inventory. """ all_injectable_items = [ @@ -415,10 +413,10 @@ def create_item(self, item: Union[str, DS3ItemData]) -> Item: and not data.name == "Pyromancy Flame" ): # if the user made an error and set a min higher than the max we default to the max - max_5 = self.options.max_levels_in_5 - min_5 = min(self.options.min_levels_in_5, max_5) - max_10 = self.options.max_levels_in_10 - min_10 = min(self.options.min_levels_in_10, max_10) + max_5 = self.options.max_levels_in_5.value + min_5 = min(self.options.min_levels_in_5.value, max_5) + max_10 = self.options.max_levels_in_10.value + min_10 = min(self.options.min_levels_in_10.value, max_10) weapon_level_percentage = self.options.randomize_weapon_level_percentage if self.random.randint(0, 99) < weapon_level_percentage: @@ -712,7 +710,7 @@ def set_rules(self) -> None: ], "Chameleon") # Forbid shops from carrying items with multiple counts (the offline randomizer has its own - # logic for choosing how many shop items to sell), and from carring soul items. + # logic for choosing how many shop items to sell), and from carrying soul items. for location in location_dictionary.values(): if location.shop: self._add_item_rule( @@ -1187,13 +1185,13 @@ def _add_transposition_rules(self) -> None: for (soul, soul_name, items) in transpositions: self._add_location_rule([ f"FS: {item} - Ludleth for {soul_name}" for item in items - ], lambda state, soul=soul: ( - state.has(soul, self.player) and state.has("Transposing Kiln", self.player) + ], lambda state, s=soul: ( + state.has(s, self.player) and state.has("Transposing Kiln", self.player) )) def _add_crow_rules(self) -> None: - """Adds rules for for items obtainable by trading items to the crow on Firelink roof.""" + """Adds rules for items obtainable by trading items to the crow on Firelink roof.""" crow = { "Loretta's Bone": "Ring of Sacrifice", @@ -1376,8 +1374,6 @@ def post_fill(self): region order, and then the best items in a sphere go into the multiworld. """ - state: CollectionState = CollectionState(self.multiworld) - unchecked_locations = set(self.multiworld.get_locations()) locations_by_sphere = list(self.multiworld.get_spheres()) # All items in the base game in approximately the order they appear @@ -1447,7 +1443,7 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: ] # Check the game, not the player, because we know how to sort within regions for DS3 - offworld = self._shuffle(loc for loc in locations if loc.game != "Dark Souls III") + offworld = self._shuffle([loc for loc in locations if loc.game != "Dark Souls III"]) onworld = sorted((loc for loc in locations if loc.game == "Dark Souls III"), key=lambda loc: loc.data.region_value) @@ -1527,7 +1523,7 @@ def fill_slot_data(self) -> Dict[str, object]: # A map from Archipelago's location IDs to the keys the offline # randomizer uses to identify locations. - location_ids_to_keys: Dict[str, str] = {} + location_ids_to_keys: Dict[int, str] = {} for location in self.multiworld.get_filled_locations(self.player): # Skip events and only look at this world's locations if (location.address is not None and location.item.code is not None diff --git a/worlds/dark_souls_3/detailed_location_descriptions.py b/worlds/dark_souls_3/detailed_location_descriptions.py index 715aca758cff..d25837232691 100644 --- a/worlds/dark_souls_3/detailed_location_descriptions.py +++ b/worlds/dark_souls_3/detailed_location_descriptions.py @@ -47,7 +47,6 @@ location: len(descriptions) for (location, descriptions) in descriptions_by_location.items() } - location_names_to_descriptions = {} for location in location_dictionary.values(): if location.ap_code is None: continue @@ -57,7 +56,7 @@ match = location_re.match(location.name) if not match: - raise Exception(f'Location name "{location.name}" doesn\'t match expected format.') + raise Exception(f"Location name \"{location.name}\" doesn't match expected format.") item_candidates = descriptions_by_item[match[2]] if len(item_candidates) == 1: diff --git a/worlds/dark_souls_3/docs/en_Dark Souls III.md b/worlds/dark_souls_3/docs/en_Dark Souls III.md index e51c0b74ddae..ca7b835b3a8e 100644 --- a/worlds/dark_souls_3/docs/en_Dark Souls III.md +++ b/worlds/dark_souls_3/docs/en_Dark Souls III.md @@ -28,7 +28,7 @@ need to configure and export a config file. 4. By setting the "Randomize Weapon Level" or "Randomize Infusion" options, you can randomize whether the weapons you find will be upgraded or infused. -There are also other settings that can make playing the game more convenient or +There are also options that can make playing the game more convenient or bring a new experience, like removing equip loads or auto-equipping weapons as you pick them up. Check out [the options page][options] for more! @@ -68,7 +68,7 @@ groups] you want to omit. For example, this is the default setting but without [location groups]: /tutorial/Dark%20Souls%20III/locations/en#location-groups -```json +```yaml Dark Souls III: exclude_locations: - Small Crystal Lizards @@ -80,7 +80,7 @@ Dark Souls III: This allows _all_ non-missable locations to have progression items, if you're in for the long haul: -```json +```yaml Dark Souls III: exclude_locations: [] ``` @@ -93,7 +93,7 @@ still be included in the randomization pool, but none of them will be mandatory. For example, the following configuration just requires you to play the game through Irithyll of the Boreal Valley: -```json +```yaml Dark Souls III: # Enable the DLC so it's included in the randomization pool enable_dlc: true diff --git a/worlds/dark_souls_3/docs/locations_en.md b/worlds/dark_souls_3/docs/locations_en.md index 454ad2fa1523..c16746ff26a5 100644 --- a/worlds/dark_souls_3/docs/locations_en.md +++ b/worlds/dark_souls_3/docs/locations_en.md @@ -20,8 +20,8 @@ * [GA: Grand Archives](#grand-archives) * [UG: Untended Graves](#untended-graves) * [AP: Archdragon Peak](#archdragon-peak) - * [PW1: Painted World of Ariandel (Before Contraption)](#painted-world-of-ariandel-%28before-contraption%29) - * [PW2: Painted World of Ariandel (After Contraption)](#painted-world-of-ariandel-%28after-contraption%29) + * [PW1: Painted World of Ariandel (Before Contraption)](#painted-world-of-ariandel-before-contraption) + * [PW2: Painted World of Ariandel (After Contraption)](#painted-world-of-ariandel-after-contraption) * [DH: Dreg Heap](#dreg-heap) * [RC: Ringed City](#ringed-city) * [Detailed Location Descriptions](#detailed-location-descriptions) @@ -114,8 +114,8 @@ short. * **GA:** [Grand Archives](#grand-archives) * **UG:** [Untended Graves](#untended-graves) * **AP:** [Archdragon Peak](#archdragon-peak) -* **PW1:** [Painted World of Ariandel (Before Contraption)](#painted-world-of-ariandel-%28before-contraption%29) -* **PW2:** [Painted World of Ariandel (After Contraption)](#painted-world-of-ariandel-%28after-contraption%29) +* **PW1:** [Painted World of Ariandel (Before Contraption)](#painted-world-of-ariandel-before-contraption) +* **PW2:** [Painted World of Ariandel (After Contraption)](#painted-world-of-ariandel-after-contraption) * **DH:** [Dreg Heap](#dreg-heap) * **RC:** [Ringed City](#ringed-city) @@ -385,7 +385,7 @@ enter the dungeon from the bonfire on the near left.) * **B3:** The lowest floor, with Karla's cell, a lift back to B2, and the exit onwards to the Profaned Capital. - * "Near" is the side with Karla's cell and the the path from the pit. + * "Near" is the side with Karla's cell and the path from the pit. * "Far" is the opposite side with the mimic. * **B3 lift:** The elevator from B3 (near where you can use Path of the Dragon @@ -670,7 +670,7 @@ the painter, including the basement beneath the chapel. * **Castle:** The building with The Dreg Heap bonfire, up to the large fall into the library. -* **Library:** The building with the stained glass window that you fall into +* **Library:** The building with the stained-glass window that you fall into from the castle. * **Church:** The building below and to the right of the library, which the @@ -731,7 +731,7 @@ of Halflight, Gael, and Midir, respectively. * "Monument": The area around the purging monument, which can only be accessed by solving the "Show Your Humanity" puzzle. -* **Swamp:** The wet area past the city streets. "Left and "right" are relative +* **Swamp:** The wet area past the city streets. "Left" and "right" are relative to heading out from the Ringed City Streets bonfire, and "near" and "far" are relative to that bonfire as well. @@ -751,7 +751,7 @@ of Halflight, Gael, and Midir, respectively. ## Detailed Location Descriptions -These location decsriptions were originally written by [Matt Gruen] for [the +These location descriptions were originally written by [Matt Gruen] for [the offline _Dark Souls III_ randomizer]. [Matt Gruen]: https://thefifthmatt.com/ @@ -922,7 +922,7 @@ offline _Dark Souls III_ randomizer]. CD: Armor of Thorns - Rosaria's Bed Chamber after killing KirkFound in Rosaria's Bed Chamber after killing Longfinger Kirk CD: Astora Greatsword - graveyard, left of entranceDown one of the side paths to the left in the Reanimated Corpse area CD: Barbed Straight Sword - Kirk dropDropped by Longfinger Kirk when he invades in the cathedral central room -CD: Black Eye Orb - Rosaria from Leonhard's questOn Rosaria's corpse after joining Rosaria's Fingers, exhausing Leonhard's dialogue there and reaching the Profaned Capital bonfire. +CD: Black Eye Orb - Rosaria from Leonhard's questOn Rosaria's corpse after joining Rosaria's Fingers, exhausting Leonhard's dialogue there and reaching the Profaned Capital bonfire. CD: Blessed Gem - upper roofs, raftersIn the rafters leading to Rosaria, guarded by a Cathedral Knight to the right CD: Crest Shield - path, drop down by Cathedral of the Deep bonfireOn a grave near the Cathedral of the Deep bonfire, accessed by dropping down to the right CD: Curse Ward Greatshield - by ladder from white tree to moatTaking a right after the Infested Corpse graveyard, before the shortcut ladder down to the Ravenous Crystal Lizard area @@ -1063,7 +1063,7 @@ offline _Dark Souls III_ randomizer]. DH: Loincloth - swamp, left edgeIn the leftmost edge of the poison swamp after dropping down, guarded by 6 Poisonhorn bugs. DH: Lothric War Banner - parapets, end of hallAfter crossing the spire bridge that crashes into the building with the Lothric Knights, past Lapp's initial location, dropping down behind the murkman and dropping down again, at the end of the hallway to the right. DH: Murky Hand Scythe - library, behind bookshelvesAfter the first long drop into the building which looks like Grand Archives, to the left up the bookshelf stairs and behind the bookshelves -DH: Murky Longstaff - pantry, last roomAfter exiting the building with the Lothric Knights where the front crumbles, in the third furthest room in the building to the right. +DH: Murky Longstaff - pantry, last roomAfter exiting the building with the Lothric Knights where the front crumbles, in the third-furthest room in the building to the right. DH: Prism Stone - swamp upper, tunnel startNear the start of the tunnel with Desert Pyromancer Zoey. DH: Projected Heal - parapets balconyAfter crossing the spire bridge that crashes into the building with the Lothric Knights, past Lapp's initial location, dropping down behind the murkman, against a wall in the area with the Lothric War Banner Knight and many murkmen. DH: Purple Moss Clump - swamp shackIn the ruined shack with Poisonhorn bugs straight ahead of the dropdown into the poison swamp area. @@ -1145,18 +1145,18 @@ offline _Dark Souls III_ randomizer]. FK: Ragged Mask - Farron Keep bonfire, around left cornerAlong the inner wall of the keep, making an immediate left from Farron Keep bonfire, guarded by slugs FK: Repair Powder - outside hidden caveAlong the keep wall in the basilisk area, outside of the cave with the Elizabeth corpse and Golden Scroll FK: Rotten Pine Resin - left island, behind fireIn the area behind the ritual fire which is straight ahead of the Farron Keep bonfire -FK: Rotten Pine Resin - outside pavilion by left islandFrom the Farron Keep bonfire straight ahead to the pavillion guarded by the Darkwraith, just to the left of the ritual fire stairs +FK: Rotten Pine Resin - outside pavilion by left islandFrom the Farron Keep bonfire straight ahead to the pavilion guarded by the Darkwraith, just to the left of the ritual fire stairs FK: Rusted Gold Coin - right island, behind wallHidden behind the right wall of the ritual fire with stairs guarded by Elder Ghrus/basilisks -FK: Sage's Coal - pavilion by left islandIn the pavillion guarded by a Darkwraith, straight ahead from the Farron Keep bonfire to the left of the ritual fire stairs +FK: Sage's Coal - pavilion by left islandIn the pavilion guarded by a Darkwraith, straight ahead from the Farron Keep bonfire to the left of the ritual fire stairs FK: Sage's Scroll - near wall by keep ruins bonfire islandAlong the keep inner wall, heading left from the stone doors past the crab area, surrounded by many Ghru enemies FK: Shriving Stone - perimeter, just past stone doorsPast the stone doors, on the path leading up to Abyss Watchers by the Corvians FK: Soul of a Nameless Soldier - by white treeNear the swamp birch tree patrolled by the greater crab, where the Giant shoots arrows FK: Soul of a Stray Demon - upper keep, miniboss dropDropped by Stray Demon on the bridge above Farron Keep FK: Soul of the Blood of the WolfDropped by Abyss Watchers -FK: Stone Parma - near wall by left islandAlong the inner wall of the keep, making an left from Farron Keep bonfire but before the area with the Darkwraith, guarded by a slug +FK: Stone Parma - near wall by left islandAlong the inner wall of the keep, making a left from Farron Keep bonfire but before the area with the Darkwraith, guarded by a slug FK: Sunlight Talisman - estus soup island, by ladder to keep properBy the pot of estus soup to the left of the stairs leading up to Old Wolf of Farron FK: Titanite Scale - perimeter, miniboss dropDropped by Ravenous Crystal Lizard near the shortcut from Farron Keep back to Road of Sacrifices -FK: Titanite Shard - Farron Keep bonfire, left after exitAlong the inner wall of the keep, making an left from Farron Keep bonfire, by the second group of four slugs +FK: Titanite Shard - Farron Keep bonfire, left after exitAlong the inner wall of the keep, making a left from Farron Keep bonfire, by the second group of four slugs FK: Titanite Shard - between left island and keep ruinsIn the swamp area with the Ghru Leaper between the Keep Ruins ritual fire and ritual fire straight ahead of Farron Keep bonfire, opposite from the keep wall FK: Titanite Shard - by keep ruins ritual island stairsBy the stairs leading up to the Keep Ruins ritual fire from the middle of the swamp FK: Titanite Shard - by ladder to keep properIn the swamp area close to the foot of the ladder leading to Old Wolf of Farron bonfire @@ -1165,7 +1165,7 @@ offline _Dark Souls III_ randomizer]. FK: Titanite Shard - swamp by right islandBehind a tree patrolled by an Elder Ghru close to the ritual fire stairs FK: Twinkling Dragon Head Stone - Hawkwood dropDropped by Hawkwood after killing him in the Abyss Watchers arena, after running up to the altar in Archdragon Peak. Twinkling Dragon Torso Stone needs to be acquired first. FK: Twinkling Titanite - keep proper, lizardDropped by the Crystal Lizard on the balcony behind the Old Wolf of Farron bonfire -FK: Undead Bone Shard - pavilion by keep ruins bonfire islandIn a standalone pavillion down the ramp from Keep Ruins bonfire and to the right +FK: Undead Bone Shard - pavilion by keep ruins bonfire islandIn a standalone pavilion down the ramp from Keep Ruins bonfire and to the right FK: Watchdogs of Farron - Old WolfGiven by Old Wolf of Farron. FK: Wolf Ring+1 - keep ruins bonfire island, outside buildingTo the right of the building with the Keep Ruins bonfire, when approached from the ritual fire FK: Wolf's Blood Swordgrass - by ladder to keep properTo the left of the ladder leading up to the Old Wolf of Farron bonfire @@ -1246,7 +1246,7 @@ offline _Dark Souls III_ randomizer]. FS: Ember - GreiratSold by Greirat after recruiting him, or in his ashes FS: Ember - Greirat from USSold by Greirat after pillaging Undead Settlement FS: Ember - Mortician's AshesSold by Handmaid after giving Mortician's Ashes -FS: Ember - above shrine entranceAbove the Firelink Shrine entrance, up stairs/slope from either left or right of the entrance +FS: Ember - above shrine entranceAbove the Firelink Shrine entrance, up the stairs/slope from either left or right of the entrance FS: Ember - path right of Firelink entranceOn a cliffside to the right of the main path leading up to Firelink Shrine, guarded by a dog FS: Ember - shopSold by Handmaid FS: Ember - shop for Greirat's AshesSold by Handmaid after Greirat pillages Lothric Castle and handing in ashes @@ -1313,7 +1313,7 @@ offline _Dark Souls III_ randomizer]. FS: Hollowslayer Greatsword - Ludleth for GreatwoodBoss weapon for Curse-Rotted Greatwood FS: Homeward - IrinaSold by Irina after recruiting her, or in her ashes FS: Homeward Bone - cliff edge after bossAlong the cliff edge straight ahead of the Iudex Gundyr fight -FS: Homeward Bone - path above shrine entraceTo the right of the Firelink Shrine entrance, up a slope and before the ledge on top of a coffin +FS: Homeward Bone - path above shrine entranceTo the right of the Firelink Shrine entrance, up a slope and before the ledge on top of a coffin FS: Homing Crystal Soulmass - Orbeck for Crystal ScrollSold by Orbeck after giving him the Crystal Scroll FS: Homing Soulmass - Orbeck for Logan's ScrollSold by Orbeck after giving him Logan's Scroll FS: Karla's Coat - Prisoner Chief's AshesSold by Handmaid after giving Prisoner Chief's Ashes @@ -1388,7 +1388,7 @@ offline _Dark Souls III_ randomizer]. FS: Seething Chaos - Ludleth for Demon PrinceBoss weapon for Demon Prince FS: Silvercat Ring - Sirris for killing CreightonGiven by Sirris talking to her in Firelink Shrine after invading and vanquishing Creighton. FS: Skull Ring - kill LudlethDropped by Ludleth upon death, including after placing all cinders. Note that if killed before giving Transposing Kiln, transposition is not possible. -FS: Slumbering Dragoncrest Ring - Orbeck for buying four specific spellsGiven by Orbeck after purchasing the shop items corresponding to Aural Decoy, Farron Flashsword, Spook (starting items), and Pestlient Mist (after giving one scroll). +FS: Slumbering Dragoncrest Ring - Orbeck for buying four specific spellsGiven by Orbeck after purchasing the shop items corresponding to Aural Decoy, Farron Flashsword, Spook (starting items), and Pestilent Mist (after giving one scroll). FS: Smough's Armor - shop after killing AL bossSold by Handmaid after defeating Alrich, Devourer of Gods FS: Smough's Gauntlets - shop after killing AL bossSold by Handmaid after defeating Alrich, Devourer of Gods FS: Smough's Helm - shop after killing AL bossSold by Handmaid after defeating Alrich, Devourer of Gods @@ -1440,7 +1440,7 @@ offline _Dark Souls III_ randomizer]. FS: Yhorm's Great Machete - Ludleth for YhormBoss weapon for Yhorm the Giant FS: Yhorm's Greatshield - Ludleth for YhormBoss weapon for Yhorm the Giant FS: Young Dragon Ring - Orbeck for one scroll and buying three spellsGiven by Orbeck after purchasing four sorceries from him, and giving him one scroll, as a non-sorcerer. -FSBT: Armor of the Sun - crow for SiegbräuTrade Siegbrau with crow +FSBT: Armor of the Sun - crow for SiegbräuTrade Siegbräu with crow FSBT: Blessed Gem - crow for Moaning ShieldTrade Moaning Shield with crow FSBT: Covetous Silver Serpent Ring - illusory wall past raftersFrom the Firelink Shrine roof, past the rafters and an illusory wall FSBT: Estus Ring - tower baseDropping down from the Bell Tower to where Irina eventually resides @@ -1520,10 +1520,10 @@ offline _Dark Souls III_ randomizer]. GA: Titanite Chunk - 2F, by wax poolUp the stairs from the Archives second floor on the right side from the entrance, in a corner near the small wax pool GA: Titanite Chunk - 2F, right after dark roomExiting from the dark room with the Crystal Lizards on the first floor onto the second floor main room, then taking an immediate right GA: Titanite Chunk - 5F, far balconyOn a balcony outside where Lothric Knight stands on the top floor of the Archives, accessing by going right from the final wax pool or by dropping down from the gargoyle area -GA: Titanite Chunk - rooftopps, balconyGoing onto the roof and down the first ladder, all the way down the ledge facing the ocean to the right +GA: Titanite Chunk - rooftops, balconyGoing onto the roof and down the first ladder, all the way down the ledge facing the ocean to the right GA: Titanite Chunk - rooftops lower, ledge by buttressGoing onto the roof and down the first ladder, dropping down on either side from the ledge facing the ocean, on a roof ledge to the right GA: Titanite Chunk - rooftops, just before 5FOn the Archives roof, after a short dropdown, in the small area where the two Gargoyles attack you -GA: Titanite Scale - 1F, drop from 2F late onto bookshelves, lizardDropped by a Crystal Lizard on first floor bookshelves. Can be acessed by dropping down to the left at the end of the bridge which is the Crystal Sage's final location +GA: Titanite Scale - 1F, drop from 2F late onto bookshelves, lizardDropped by a Crystal Lizard on first floor bookshelves. Can be accessed by dropping down to the left at the end of the bridge which is the Crystal Sage's final location GA: Titanite Scale - 1F, up stairs on bookshelfOn the Archives first floor, up a movable set of stairs near the large wax pool, on top of a bookshelf GA: Titanite Scale - 2F, titanite scale atop bookshelfOn top of a bookshelf on the Archive second floor, accessible by going halfway up the stairs to the third floor and dropping down near a Grand Archives Scholar GA: Titanite Scale - 3F, by ladder to 2F lateGoing from the Crystal Sage's location on the third floor to its location on the bridge, on the left side of the ladder you descend, behind a table @@ -1669,7 +1669,7 @@ offline _Dark Souls III_ randomizer]. IBV: Undead Bone Shard - descent, behind gravestoneIn the graveyard down the stairs from the Church of Yorshka, behind the grave with the Corvian IBV: Witchtree Branch - by DorhysIn the area with Cathedral Evangelist Dorhys, past an illusory railing past the Central Irithyll Fire Witches IBV: Wood Grain Ring+2 - ascent, right after great hallLeaving the building with the Silver Knight staring at the painting, instead of going left up the stairs, go right -IBV: Yorshka's Spear - descent, dark room rafers chestIn a chest in the rafters of the dark area with the Irithyllian slaves +IBV: Yorshka's Spear - descent, dark room rafters chestIn a chest in the rafters of the dark area with the Irithyllian slaves ID: Alva Armor - B3 near, by Karla's cell, after killing AlvaIn the main Jailer cell block on the floor close to Karla's cell, if the invading Alva is killed ID: Alva Gauntlets - B3 near, by Karla's cell, after killing AlvaIn the main Jailer cell block on the floor close to Karla's cell, if the invading Alva is killed ID: Alva Helm - B3 near, by Karla's cell, after killing AlvaIn the main Jailer cell block on the floor close to Karla's cell, if the invading Alva is killed @@ -1716,7 +1716,7 @@ offline _Dark Souls III_ randomizer]. ID: Rusted Gold Coin - after bonfire, last cell on rightIn the third cell on the right from the Irithyll Dungeon bonfire ID: Simple Gem - B2 far, cell by stairsIn the cell near the bottom corridor opposite to the bonfire in Irithyll Dungeon, adjacent to the room with three Jailers and Cage Spiders ID: Soul of a Crestfallen Knight - balcony above pitUnder whether the Giant Slave is resting his head -ID: Soul of a Weary Warrior - by drop to pitAt the end of the room with many peasant hollows after the Estus Shard minic +ID: Soul of a Weary Warrior - by drop to pitAt the end of the room with many peasant hollows after the Estus Shard mimic ID: Soul of a Weary Warrior - stairs between pit and B3Going past the Giant Slave to the sewer with the rats and the basilisks, up the first flight of stairs ID: Titanite Chunk - balcony above pit, lizardDropped by the Crystal Lizard where the Giant Slave is resting his head ID: Titanite Chunk - pit, miniboss dropDrop from the Giant Slave @@ -2068,7 +2068,7 @@ offline _Dark Souls III_ randomizer]. RS: Great Swamp Ring - miniboss drop, by Farron KeepDropped by Greater Crab in Crucifixion Woods close to the Farron Keep outer wall RS: Green Blossom - by deep waterIn the Crucifixion Woods crab area out in the open, close to the edge of the deep water area RS: Green Blossom - water beneath strongholdIn the Crucifixion Woods crab area close to the Crucifixion Woods bonfire, along the left wall of the water area, to the right of the entrance to the building before Crystal Sage -RS: Heretic's Staff - stronghold left roomIn the building before Crystal Sage, entering from near Cruficixion Woods, in a corner under the first stairwell and balcony +RS: Heretic's Staff - stronghold left roomIn the building before Crystal Sage, entering from near Crucifixion Woods, in a corner under the first stairwell and balcony RS: Heysel Pick - Heysel dropDropped by Heysel when she invades in Road of Sacrifices RS: Homeward Bone - balcony by Farron KeepAt the far end of the building where you descend into Farron Keep, by the balcony RS: Large Soul of an Unknown Traveler - left of stairs to Farron KeepIn the area before you descend into Farron Keep, before the stairs to the far left @@ -2088,7 +2088,7 @@ offline _Dark Souls III_ randomizer]. RS: Sorcerer Trousers - water beneath strongholdIn an alcove under the building before Crystal Sage, guarded by a Lycanthrope, accessible from the swamp or from dropping down RS: Soul of a Crystal SageDropped by Crystal Sage RS: Soul of an Unknown Traveler - drop along wall from Halfway FortressFrom Halfway Fortress, hug the right wall and drop down twice on the way to the crab area -RS: Soul of an Unknown Traveler - right of door to stronghold leftOut in the open to the right of the building before Crystal Sage, as entered from Crufixion Woods bonfire +RS: Soul of an Unknown Traveler - right of door to stronghold leftOut in the open to the right of the building before Crystal Sage, as entered from Crucifixion Woods bonfire RS: Soul of an Unknown Traveler - road, by wagonTo the right of the overturned wagon descending from the Road of Sacrifices bonfire RS: Titanite Shard - road, on bridge after you go underCrossing the bridge you go under after the first Road of Sacrifices bonfire, after a sleeping Corvian and another Corvian guarding the pickup RS: Titanite Shard - water by Halfway FortressDropping down into the Crucifixion Woods crab area right after Halfway Fortress, on the left wall heading toward the Black Knight building, guarded by dog @@ -2100,7 +2100,7 @@ offline _Dark Souls III_ randomizer]. SL: Black Knight Sword - ruins main lower, illusory wall in far hallOn the far exit of the Demon Ruins main hall, past an illusory wall, guarded by a Black Knight SL: Bloodbite Ring+1 - behind ballistaBehind the ballista, overlooking Smouldering Lake SL: Chaos Gem - antechamber, lizard at end of long hallDropped by the Crystal Lizard found from the Antechamber bonfire, toward the Demon Cleric and to the right, then all the way down -SL: Chaos Gem - lake, far end by mobIn Smouldering Lake along the wall underneath the balista, all the way to the left past two crabs +SL: Chaos Gem - lake, far end by mobIn Smouldering Lake along the wall underneath the ballista, all the way to the left past two crabs SL: Dragonrider Bow - by ladder from ruins basement to ballistaAfter climbing up the ladder after the Black Knight in Demon Ruins, falling back down to a ledge SL: Ember - ruins basement, in lavaIn the lava pit under the Black Knight, by Knight Slayer Tsorig SL: Ember - ruins main lower, path to antechamberGoing down the stairs from the Antechamber bonfire, to the right, at the end of the short hallway to the next right @@ -2145,17 +2145,17 @@ offline _Dark Souls III_ randomizer]. UG: Coiled Sword Fragment - shrine, dead bonfireIn the dead Firelink Shrine bonfire UG: Ember - shopSold by Untended Graves Handmaid UG: Eyes of a Fire Keeper - shrine, Irina's roomBehind an illusory wall, in the same location Irina sits in Firelink Shrine -UG: Hidden Blessing - cemetery, behind coffinBehind the coffin that had a Titanite Shard in Cemetary of Ash +UG: Hidden Blessing - cemetery, behind coffinBehind the coffin that had a Titanite Shard in Cemetery of Ash UG: Hornet Ring - environs, right of main path after killing FK bossOn a cliffside to the right of the main path leading up to dark Firelink Shrine, after Abyss Watchers is defeated. UG: Life Ring+3 - shrine, behind big throneBehind Prince Lothric's throne UG: Priestess Ring - shopSold or dropped by Untended Graves Handmaid. Killing her is not recommended UG: Ring of Steel Protection+1 - environs, behind bell towerBehind Bell Tower to the right UG: Shriving Stone - swamp, by bonfireAt the very start of the area UG: Soul of Champion GundyrDropped by Champion Gundyr -UG: Soul of a Crestfallen Knight - environs, above shrine entranceAbove the Firelink Shrine entrance, up stairs/slope from either left or right of the entrance -UG: Soul of a Crestfallen Knight - swamp, centerClose to where Ashen Estus Flask was in Cemetary of Ash -UG: Titanite Chunk - swamp, left path by fountainIn a path to the left of where Ashen Estus Flask was in Cemetary of Ash -UG: Titanite Chunk - swamp, right path by fountainIn a path to the right of where Ashen Estus Flask was in Cemetary of Ash +UG: Soul of a Crestfallen Knight - environs, above shrine entranceAbove the Firelink Shrine entrance, up the stairs/slope from either left or right of the entrance +UG: Soul of a Crestfallen Knight - swamp, centerClose to where Ashen Estus Flask was in Cemetery of Ash +UG: Titanite Chunk - swamp, left path by fountainIn a path to the left of where Ashen Estus Flask was in Cemetery of Ash +UG: Titanite Chunk - swamp, right path by fountainIn a path to the right of where Ashen Estus Flask was in Cemetery of Ash UG: Wolf Knight Armor - shop after killing FK bossSold by Untended Graves Handmaid after defeating Abyss Watchers UG: Wolf Knight Gauntlets - shop after killing FK bossSold by Untended Graves Handmaid after defeating Abyss Watchers UG: Wolf Knight Helm - shop after killing FK bossSold by Untended Graves Handmaid after defeating Abyss Watchers @@ -2200,7 +2200,7 @@ offline _Dark Souls III_ randomizer]. US: Hawk Ring - Giant ArcherDropped by Giant, either by killing him or collecting all of the birch tree items locations in the base game. US: Heavy Gem - HawkwoodGiven or dropped by Hawkwood after defeating Curse-Rotted Greatwood or Crystal Sage US: Heavy Gem - chasm, lizardDrop by Crystal Lizard in ravine accessible by Grave Key or dropping down near Eygon. -US: Homeward Bone - foot, drop overloopUnder Foot of the High Wall bonfire, around where Yoel can be first met +US: Homeward Bone - foot, drop overlookUnder Foot of the High Wall bonfire, around where Yoel can be first met US: Homeward Bone - stable roofIn the thrall area across the bridge from the first Undead Settlement building, on a roof overlooking the ravine bridge. US: Homeward Bone - tower village, jump from roofAt the end of the loop from the Siegward Demon fight, after dropping down from the roof onto the tower with Chloranthy Ring, to the right of the tower entrance US: Homeward Bone - tower village, right at startUnder Foot of the High Wall bonfire, around where Yoel can be first met @@ -2230,7 +2230,7 @@ offline _Dark Souls III_ randomizer]. US: Pale Tongue - tower village, hanging corpseHanging corpse in the Fire Demon fight area, can be knocked down by rolling into it US: Partizan - hanging corpse above Cliff UndersideOn a hanging corpse on the path from Cliff Underside to Cornyx's cage. Must be shot down with an arrow or projective. US: Plank Shield - outside stable, by NPCIn the thrall area across the bridge from the first Undead Settlement building, on a cliff edge overlooking the ravine bridge. -US: Poisonbite Ring+1 - graveyard by white tree, near wellBehind the well in the back of area where the Giant shoots arrows, nearby where the flamerge-wielding thrall drops down. +US: Poisonbite Ring+1 - graveyard by white tree, near wellBehind the well in the back of area where the Giant shoots arrows, nearby where the flamberge-wielding thrall drops down. US: Pyromancy Flame - CornyxGiven by Cornyx in Firelink Shrine or dropped. US: Red Bug Pellet - tower village building, basementOn the floor of the building after the Fire Demon encounter US: Red Hilted Halberd - chasm cryptIn the skeleton area accessible from Grave Key or dropping down from near Eygon From bf17d82c1dac096f63bea14f9d3f98bd7f6e8cec Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 28 Apr 2024 22:00:09 -0700 Subject: [PATCH 203/238] Drop deprecated options --- worlds/dark_souls_3/Options.py | 123 +------------------------------- worlds/dark_souls_3/__init__.py | 17 ----- 2 files changed, 1 insertion(+), 139 deletions(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index c675fc509940..9cf7c881c3c5 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -46,118 +46,8 @@ class MissableLocationsOption(Choice): option_unimportant = 2 option_unrandomized = 3 default = 2 - - -class RandomizeWeaponLocations(DefaultOnToggle): - """DEPRECATED (use "Excluded Locations" options instead) - - Setting this to false is now equivalent to adding "Weapons" to the "Exclude - Locations" option. It does _not_ cause the locations not be randomized - unless "Excluded Locations" is also set to "Unrandomized". - """ - display_name = "Randomize Weapon Locations" - - -class RandomizeShieldLocations(DefaultOnToggle): - """DEPRECATED (use "Excluded Locations" options instead) - - Setting this to false is now equivalent to adding "Shields" to the "Exclude - Locations" option. It does _not_ cause the locations not be randomized - unless "Excluded Locations" is also set to "Unrandomized". - """ - display_name = "Randomize Shield Locations" - - -class RandomizeArmorLocations(DefaultOnToggle): - """DEPRECATED (use "Excluded Locations" options instead) - - Setting this to false is now equivalent to adding "Armor" to the "Exclude - Locations" option. It does _not_ cause the locations not be randomized - unless "Excluded Locations" is also set to "Unrandomized". - """ - display_name = "Randomize Armor Locations" - - -class RandomizeRingLocations(DefaultOnToggle): - """DEPRECATED (use "Excluded Locations" options instead) - - Setting this to false is now equivalent to adding "Rings" to the "Exclude - Locations" option. It does _not_ cause the locations not be randomized - unless "Excluded Locations" is also set to "Unrandomized". - """ - display_name = "Randomize Ring Locations" - - -class RandomizeSpellLocations(DefaultOnToggle): - """DEPRECATED (use "Excluded Locations" options instead) - - Setting this to false is now equivalent to adding "Spells" to the "Exclude - Locations" option. It does _not_ cause the locations not be randomized - unless "Excluded Locations" is also set to "Unrandomized". - """ - display_name = "Randomize Spell Locations" - - -class RandomizeKeyLocations(DefaultOnToggle): - """DEPRECATED (use "Excluded Locations" options instead) - - Setting this to false is now equivalent to adding "Progression" to the - "Exclude Locations" option. It does _not_ cause the locations not be - randomized unless "Excluded Locations" is also set to "Unrandomized". - """ - display_name = "Randomize Key Locations" - - -class RandomizeBossSoulLocations(DefaultOnToggle): - """DEPRECATED (use "Excluded Locations" options instead) - - Setting this to false is now equivalent to adding "Boss Souls" to the - "Exclude Locations" option. It does _not_ cause the locations not be - randomized unless "Excluded Locations" is also set to "Unrandomized". - """ - display_name = "Randomize Boss Soul Locations" - - -class RandomizeNPCLocations(DefaultOnToggle): - """DEPRECATED (use "Excluded Locations" options instead) - - Setting this to false is now equivalent to adding "Friendly NPC Rewards" to - the "Exclude Locations" option. It does _not_ cause the locations not be - randomized unless "Excluded Locations" is also set to "Unrandomized". - """ - display_name = "Randomize NPC Locations" - - -class RandomizeMiscLocations(DefaultOnToggle): - """DEPRECATED (use "Excluded Locations" options instead) - - Setting this to false is now equivalent to adding "Unique" to the "Exclude - Locations" option. It does _not_ cause the locations not be randomized - unless "Excluded Locations" is also set to "Unrandomized". - """ - display_name = "Randomize Miscellaneous Locations" - - -class RandomizeHealthLocations(DefaultOnToggle): - """DEPRECATED (use "Excluded Locations" options instead) - - Setting this to false is now equivalent to adding "Healing" to the "Exclude - Locations" option. It does _not_ cause the locations not be randomized - unless "Excluded Locations" is also set to "Unrandomized". - """ - display_name = "Randomize Health Locations" - - -class RandomizeProgressiveLocationsOption(DefaultOnToggle): - """DEPRECATED (use "Excluded Locations" options instead) - - Setting this to false is now equivalent to adding "Miscellaneous" to the - "Exclude Locations" option. It does _not_ cause the locations not be - randomized unless "Excluded Locations" is also set to "Unrandomized". - """ - display_name = "Randomize Progressive Locations" - + class SmoothSoulItemsOption(DefaultOnToggle): """Whether to distribute soul items in a similar order as the base game. @@ -466,17 +356,6 @@ class DS3ExcludeLocations(ExcludeLocations): class DarkSouls3Options(PerGameCommonOptions): excluded_locations: ExcludedLocationsOption missable_locations: MissableLocationsOption - enable_weapon_locations: RandomizeWeaponLocations - enable_shield_locations: RandomizeShieldLocations - enable_armor_locations: RandomizeArmorLocations - enable_ring_locations: RandomizeRingLocations - enable_spell_locations: RandomizeSpellLocations - enable_key_locations: RandomizeKeyLocations - enable_boss_locations: RandomizeBossSoulLocations - enable_npc_locations: RandomizeNPCLocations - enable_misc_locations: RandomizeMiscLocations - enable_health_upgrade_locations: RandomizeHealthLocations - enable_progressive_locations: RandomizeProgressiveLocationsOption smooth_soul_items: SmoothSoulItemsOption smooth_upgrade_items: SmoothUpgradeItemsOption smooth_upgraded_weapons: SmoothUpgradedWeaponsOption diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 4e75bb5601f8..67506bff8ba8 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -90,23 +90,6 @@ def __init__(self, multiworld: MultiWorld, player: int): self.all_excluded_locations = set() def generate_early(self): - if not self.options.enable_weapon_locations: - self._exclude_location_group("Weapons") - if not self.options.enable_shield_locations: - self._exclude_location_group("Shields") - if not self.options.enable_armor_locations: - self._exclude_location_group("Armor") - if not self.options.enable_ring_locations: - self._exclude_location_group("Rings") - if not self.options.enable_spell_locations: - self._exclude_location_group("Spells") - if not self.options.enable_key_locations: - self._exclude_location_group("Progression") - if not self.options.enable_misc_locations: - self._exclude_location_group("Unique") - if not self.options.enable_health_upgrade_locations: - self._exclude_location_group("Healing") - self.all_excluded_locations.update(self.options.exclude_locations.value) # Randomize Yhorm manually so that we know where to place the Storm Ruler. From e4b4daaaeb7adeb7ae496aeea1f7d0cd47d9b61a Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 28 Apr 2024 22:35:05 -0700 Subject: [PATCH 204/238] Rename "offline randomizer" to "static randomizer" which is clearer --- worlds/dark_souls_3/Bosses.py | 4 +- worlds/dark_souls_3/Locations.py | 136 +++++++++--------- worlds/dark_souls_3/Options.py | 4 +- worlds/dark_souls_3/__init__.py | 18 +-- .../detailed_location_descriptions.py | 16 +-- worlds/dark_souls_3/docs/en_Dark Souls III.md | 38 ++--- worlds/dark_souls_3/docs/items_en.md | 5 + worlds/dark_souls_3/docs/locations_en.md | 9 +- 8 files changed, 120 insertions(+), 110 deletions(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index 654893200a6b..e69fb574a13b 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -1,4 +1,4 @@ -# In almost all cases, we leave boss and enemy randomization up to the offline randomizer. But for +# 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. @@ -30,7 +30,7 @@ class DS3BossInfo: """Additional individual locations that can't be accessed until the boss is dead.""" -# Note: the offline randomizer splits up some bosses into separate fights for separate phases, each +# 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 = { diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index a418fe0a7db1..2c4a44c46489 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -70,16 +70,16 @@ class DS3LocationData: This is used to sort locations when placing items like the base game. """ - offline: Optional[str] = None - """The key in the offline randomizer's Slots table that corresponds to this location. + static: Optional[str] = None + """The key in the static randomizer's Slots table that corresponds to this location. - By default, the offline randomizer chooses its location based on the region and the item name. + By default, the static randomizer chooses its location based on the region and the item name. If the item name is unique across the whole game, it can also look it up based on that alone. If there are multiple instances of the same item type in the same region, it will assume its order (in annotations.txt) matches Archipelago's order. In cases where this heuristic doesn't work, such as when Archipelago's region categorization or - item name disagrees with the offline randomizer's, this field is used to provide an explicit + item name disagrees with the static randomizer's, this field is used to provide an explicit association instead. """ @@ -306,16 +306,16 @@ def __init__( DS3LocationData("FS: White Sign Soapstone - shop", "White Sign Soapstone", shop=True), DS3LocationData("FS: Dried Finger - shop", "Dried Finger", shop=True), DS3LocationData("FS: Tower Key - shop", "Tower Key", progression=True, shop=True), - DS3LocationData("FS: Ember - shop", "Ember", offline='99,0:-1:110000:', shop=True), - DS3LocationData("FS: Farron Dart - shop", "Farron Dart", offline='99,0:-1:110000:', + DS3LocationData("FS: Ember - shop", "Ember", static='99,0:-1:110000:', shop=True), + DS3LocationData("FS: Farron Dart - shop", "Farron Dart", static='99,0:-1:110000:', shop=True), - DS3LocationData("FS: Soul Arrow - shop", "Soul Arrow", offline='99,0:-1:110000:', + DS3LocationData("FS: Soul Arrow - shop", "Soul Arrow", static='99,0:-1:110000:', shop=True), DS3LocationData("FS: Heal Aid - shop", "Heal Aid", shop=True), DS3LocationData("FS: Alluring Skull - Mortician's Ashes", "Alluring Skull", shop=True, conditional=True), DS3LocationData("FS: Ember - Mortician's Ashes", "Ember", - offline='99,0:-1:110000,70000100:', shop=True, conditional=True), + static='99,0:-1:110000,70000100:', shop=True, conditional=True), DS3LocationData("FS: Grave Key - Mortician's Ashes", "Grave Key", shop=True, conditional=True), DS3LocationData("FS: Life Ring - Dreamchaser's Ashes", "Life Ring", shop=True, @@ -326,16 +326,16 @@ def __init__( DS3LocationData("FS: Lloyd's Shield Ring - Paladin's Ashes", "Lloyd's Shield Ring", shop=True, conditional=True), DS3LocationData("FS: Ember - Grave Warden's Ashes", "Ember", - offline='99,0:-1:110000,70000103:', shop=True, conditional=True), + static='99,0:-1:110000,70000103:', shop=True, conditional=True), # Prisoner Chief's Ashes DS3LocationData("FS: Karla's Pointed Hat - Prisoner Chief's Ashes", "Karla's Pointed Hat", - offline='99,0:-1:110000,70000105:', shop=True, conditional=True), + static='99,0:-1:110000,70000105:', shop=True, conditional=True), DS3LocationData("FS: Karla's Coat - Prisoner Chief's Ashes", "Karla's Coat", - offline='99,0:-1:110000,70000105:', shop=True, conditional=True), + static='99,0:-1:110000,70000105:', shop=True, conditional=True), DS3LocationData("FS: Karla's Gloves - Prisoner Chief's Ashes", "Karla's Gloves", - offline='99,0:-1:110000,70000105:', shop=True, conditional=True), + static='99,0:-1:110000,70000105:', shop=True, conditional=True), DS3LocationData("FS: Karla's Trousers - Prisoner Chief's Ashes", "Karla's Trousers", - offline='99,0:-1:110000,70000105:', shop=True, conditional=True), + static='99,0:-1:110000,70000105:', shop=True, conditional=True), DS3LocationData("FS: Xanthous Overcoat - Xanthous Ashes", "Xanthous Overcoat", shop=True, conditional=True), DS3LocationData("FS: Xanthous Gloves - Xanthous Ashes", "Xanthous Gloves", shop=True, @@ -343,7 +343,7 @@ def __init__( DS3LocationData("FS: Xanthous Trousers - Xanthous Ashes", "Xanthous Trousers", shop=True, conditional=True), DS3LocationData("FS: Ember - Dragon Chaser's Ashes", "Ember", - offline='99,0:-1:110000,70000108:', shop=True, conditional=True), + static='99,0:-1:110000,70000108:', shop=True, conditional=True), DS3LocationData("FS: Washing Pole - Easterner's Ashes", "Washing Pole", shop=True, conditional=True), DS3LocationData("FS: Eastern Helm - Easterner's Ashes", "Eastern Helm", shop=True, @@ -500,7 +500,7 @@ def __init__( DS3LocationData("FSBT: Hollow Gem - crow for Eleonora", "Hollow Gem", missable=True), DS3LocationData("FSBT: Titanite Scale - crow for Blacksmith Hammer", "Titanite Scale x3", - offline='99,0:50004330::', missable=True), + static='99,0:50004330::', missable=True), DS3LocationData("FSBT: Help me! Carving - crow for any sacred chime", "Help me! Carving", missable=True), DS3LocationData("FSBT: Titanite Slab - crow for Coiled Sword Fragment", "Titanite Slab", @@ -598,7 +598,7 @@ def __init__( DS3LocationData("HWL: Astora Straight Sword - fort walkway, drop down", "Astora Straight Sword", hidden=True), # Hidden fall DS3LocationData("HWL: Battle Axe - flame tower, mimic", "Battle Axe", - offline='01,0:53000960::', mimic=True), + static='01,0:53000960::', mimic=True), # Only dropped after transformation DS3LocationData("HWL: Ember - fort roof, transforming hollow", "Ember", hidden=True), @@ -626,11 +626,11 @@ def __init__( DS3LocationData("US: Old Sage's Blindfold - kill Cornyx", "Old Sage's Blindfold", npc=True), DS3LocationData("US: Cornyx's Garb - kill Cornyx", "Cornyx's Garb", - offline='02,0:50006141::', npc=True), + static='02,0:50006141::', npc=True), DS3LocationData("US: Cornyx's Wrap - kill Cornyx", "Cornyx's Wrap", - offline='02,0:50006141::', npc=True), + static='02,0:50006141::', npc=True), DS3LocationData("US: Cornyx's Skirt - kill Cornyx", "Cornyx's Skirt", - offline='02,0:50006141::', npc=True), + static='02,0:50006141::', npc=True), DS3LocationData("US: Tower Key - kill Irina", "Tower Key", missable=True, npc=True), DS3LocationData("US: Flynn's Ring - tower village, rooftop", "Flynn's Ring"), DS3LocationData("US: Undead Bone Shard - by white tree", "Undead Bone Shard"), @@ -638,7 +638,7 @@ def __init__( DS3LocationData("US: Mortician's Ashes - graveyard by white tree", "Mortician's Ashes", progression=True), DS3LocationData("US: Homeward Bone - tower village, jump from roof", "Homeward Bone x2", - offline='02,0:53100040::', hidden=True), # Hidden fall + static='02,0:53100040::', hidden=True), # Hidden fall DS3LocationData("US: Caduceus Round Shield - right after stable exit", "Caduceus Round Shield"), DS3LocationData("US: Ember - tower basement, miniboss", "Ember"), @@ -646,7 +646,7 @@ def __init__( "Soul of an Unknown Traveler"), DS3LocationData("US: Repair Powder - first building, balcony", "Repair Powder x2"), DS3LocationData("US: Homeward Bone - stable roof", "Homeward Bone x2", - offline='02,0:53100090::'), + static='02,0:53100090::'), DS3LocationData("US: Titanite Shard - back alley, side path", "Titanite Shard"), DS3LocationData("US: Wargod Wooden Shield - Pit of Hollows", "Wargod Wooden Shield"), DS3LocationData("US: Large Soul of a Deserted Corpse - on the way to tower, by well", @@ -709,7 +709,7 @@ def __init__( DS3LocationData("US: Whip - back alley, behind wooden wall", "Whip", hidden=True), DS3LocationData("US: Great Scythe - building by white tree, balcony", "Great Scythe"), DS3LocationData("US: Homeward Bone - foot, drop overlook", "Homeward Bone", - offline='02,0:53100540::'), + static='02,0:53100540::'), DS3LocationData("US: Large Soul of a Deserted Corpse - around corner by Cliff Underside", "Large Soul of a Deserted Corpse", hidden=True), # Hidden corner DS3LocationData("US: Ember - behind burning tree", "Ember"), @@ -736,7 +736,7 @@ def __init__( DS3LocationData("US: Flame Stoneplate Ring - hanging corpse by Mound-Maker transport", "Flame Stoneplate Ring"), DS3LocationData("US: Red and White Shield - chasm, hanging corpse", "Red and White Shield", - offline="02,0:53100740::", missable=True), # requires projectile + static="02,0:53100740::", missable=True), # requires projectile DS3LocationData("US: Small Leather Shield - first building, hanging corpse by entrance", "Small Leather Shield"), DS3LocationData("US: Pale Tongue - tower village, hanging corpse", "Pale Tongue"), @@ -752,7 +752,7 @@ def __init__( DS3LocationData("US: Human Pine Resin - tower village building, chest upstairs", "Human Pine Resin x4"), DS3LocationData("US: Homeward Bone - tower village, right at start", "Homeward Bone", - offline='02,0:53100540::'), + static='02,0:53100540::'), DS3LocationData("US: Irithyll Straight Sword - miniboss drop, by Road of Sacrifices", "Irithyll Straight Sword", miniboss=True), DS3LocationData("US: Fire Gem - tower village, miniboss drop", "Fire Gem", miniboss=True), @@ -762,25 +762,25 @@ def __init__( DS3LocationData("US: Sharp Gem - lizard by Dilapidated Bridge", "Sharp Gem", lizard=True), DS3LocationData("US: Heavy Gem - chasm, lizard", "Heavy Gem", lizard=True), DS3LocationData("US: Siegbräu - Siegward", "Siegbräu", missable=True, npc=True), - DS3LocationData("US: Heavy Gem - Hawkwood", "Heavy Gem", offline='00,0:50006070::', + DS3LocationData("US: Heavy Gem - Hawkwood", "Heavy Gem", static='00,0:50006070::', missable=True, npc=True), # Hawkwood (quest, after Greatwood or Sage) DS3LocationData("US -> RS", None), # Yoel/Yuria of Londor DS3LocationData("FS: Soul Arrow - Yoel/Yuria", "Soul Arrow", - offline='99,0:-1:50000,110000,70000116:', missable=True, npc=True, + static='99,0:-1:50000,110000,70000116:', missable=True, npc=True, shop=True), DS3LocationData("FS: Heavy Soul Arrow - Yoel/Yuria", "Heavy Soul Arrow", - offline='99,0:-1:50000,110000,70000116:', + static='99,0:-1:50000,110000,70000116:', missable=True, npc=True, shop=True), DS3LocationData("FS: Magic Weapon - Yoel/Yuria", "Magic Weapon", - offline='99,0:-1:50000,110000,70000116:', missable=True, npc=True, + static='99,0:-1:50000,110000,70000116:', missable=True, npc=True, shop=True), DS3LocationData("FS: Magic Shield - Yoel/Yuria", "Magic Shield", - offline='99,0:-1:50000,110000,70000116:', missable=True, npc=True, + static='99,0:-1:50000,110000,70000116:', missable=True, npc=True, shop=True), DS3LocationData("FS: Soul Greatsword - Yoel/Yuria", "Soul Greatsword", - offline='99,0:-1:50000,110000,70000450,70000475:', missable=True, + static='99,0:-1:50000,110000,70000450,70000475:', missable=True, npc=True, shop=True), DS3LocationData("FS: Dark Hand - Yoel/Yuria", "Dark Hand", missable=True, npc=True), DS3LocationData("FS: Untrue White Ring - Yoel/Yuria", "Untrue White Ring", missable=True, @@ -788,7 +788,7 @@ def __init__( DS3LocationData("FS: Untrue Dark Ring - Yoel/Yuria", "Untrue Dark Ring", missable=True, npc=True), DS3LocationData("FS: Londor Braille Divine Tome - Yoel/Yuria", "Londor Braille Divine Tome", - offline='99,0:-1:40000,110000,70000116:', missable=True, npc=True), + static='99,0:-1:40000,110000,70000116:', missable=True, npc=True), DS3LocationData("FS: Darkdrift - Yoel/Yuria", "Darkdrift", missable=True, drop=True, npc=True), # kill her or kill Soul of Cinder @@ -935,34 +935,34 @@ def __init__( missable=True, npc=True), # Horace quest DS3LocationData("RS: Crystal Gem - stronghold, lizard", "Crystal Gem"), DS3LocationData("RS: Fading Soul - woods by Crucifixion Woods bonfire", "Fading Soul", - offline='03,0:53300210::'), + static='03,0:53300210::'), # Orbeck shop, all missable because he'll disappear if you don't talk to him for too long or # if you don't give him a scroll. DS3LocationData("FS: Farron Dart - Orbeck", "Farron Dart", - offline='99,0:-1:110000,130100,70000111:', missable=True, npc=True, + static='99,0:-1:110000,130100,70000111:', missable=True, npc=True, shop=True), DS3LocationData("FS: Soul Arrow - Orbeck", "Soul Arrow", - offline='99,0:-1:110000,130100,70000111:', missable=True, npc=True, + static='99,0:-1:110000,130100,70000111:', missable=True, npc=True, shop=True), DS3LocationData("FS: Great Soul Arrow - Orbeck", "Great Soul Arrow", missable=True, npc=True, shop=True), DS3LocationData("FS: Heavy Soul Arrow - Orbeck", "Heavy Soul Arrow", - offline='99,0:-1:110000,130100,70000111:', missable=True, npc=True, + static='99,0:-1:110000,130100,70000111:', missable=True, npc=True, shop=True), DS3LocationData("FS: Great Heavy Soul Arrow - Orbeck", "Great Heavy Soul Arrow", missable=True, npc=True, shop=True), DS3LocationData("FS: Magic Weapon - Orbeck", "Magic Weapon", - offline='99,0:-1:110000,130100,70000111:', missable=True, npc=True, + static='99,0:-1:110000,130100,70000111:', missable=True, npc=True, shop=True), DS3LocationData("FS: Magic Shield - Orbeck", "Magic Shield", - offline='99,0:-1:110000,130100,70000111:', missable=True, npc=True, + static='99,0:-1:110000,130100,70000111:', missable=True, npc=True, shop=True), DS3LocationData("FS: Spook - Orbeck", "Spook", missable=True, npc=True, shop=True), DS3LocationData("FS: Aural Decoy - Orbeck", "Aural Decoy", missable=True, npc=True, shop=True), DS3LocationData("FS: Soul Greatsword - Orbeck", "Soul Greatsword", - offline='99,0:-1:110000,130100,70000111:', missable=True, npc=True), + static='99,0:-1:110000,130100,70000111:', missable=True, npc=True), DS3LocationData("FS: Farron Flashsword - Orbeck", "Farron Flashsword", missable=True, npc=True, shop=True), DS3LocationData("FS: Pestilent Mist - Orbeck for any scroll", "Pestilent Mist", @@ -1167,7 +1167,7 @@ def __init__( DS3LocationData("CD: Rusted Coin - don't forgive Patches", "Rusted Coin", missable=True, npc=True), DS3LocationData("FS: Rusted Gold Coin - don't forgive Patches", "Rusted Gold Coin", - offline='99,0:50006201::', missable=True, + static='99,0:50006201::', missable=True, npc=True), # Don't forgive Patches DS3LocationData("CD: Shotel - Patches", "Shotel", missable=True, npc=True, shop=True), DS3LocationData("CD: Ember - Patches", "Ember", missable=True, npc=True, shop=True), @@ -1183,7 +1183,7 @@ def __init__( boss=True), DS3LocationData("FK: Cinders of a Lord - Abyss Watcher", "Cinders of a Lord - Abyss Watcher", - offline="03,0:50002100::", prominent=True, progression=True, + static="03,0:50002100::", prominent=True, progression=True, boss=True), DS3LocationData("FK: Manikin Claws - Londor Pale Shade drop", "Manikin Claws", missable=True, hostile_npc=True, @@ -1493,12 +1493,12 @@ def __init__( DS3LocationData("US: Spotted Whip - by Cornyx's cage after Cuculus quest", "Spotted Whip", missable=True, boss=True, npc=True), DS3LocationData("US: Cornyx's Garb - by Cornyx's cage after Cuculus quest", - "Cornyx's Garb", offline='02,0:53100100::', missable=True, boss=True, + "Cornyx's Garb", static='02,0:53100100::', missable=True, boss=True, npc=True), DS3LocationData("US: Cornyx's Wrap - by Cornyx's cage after Cuculus quest", "Cornyx's Wrap", - offline='02,0:53100100::', missable=True, boss=True, npc=True), + static='02,0:53100100::', missable=True, boss=True, npc=True), DS3LocationData("US: Cornyx's Skirt - by Cornyx's cage after Cuculus quest", - "Cornyx's Skirt", offline='02,0:53100100::', missable=True, boss=True, + "Cornyx's Skirt", static='02,0:53100100::', missable=True, boss=True, npc=True), ], "Irithyll of the Boreal Valley": [ @@ -1630,7 +1630,7 @@ def __init__( # Sirris quest after killing Creighton DS3LocationData("FS: Mail Breaker - Sirris for killing Creighton", "Mail Breaker", - offline='99,0:50006080::', missable=True, hostile_npc=True, + static='99,0:50006080::', missable=True, hostile_npc=True, npc=True), DS3LocationData("FS: Silvercat Ring - Sirris for killing Creighton", "Silvercat Ring", missable=True, hostile_npc=True, npc=True), @@ -1739,7 +1739,7 @@ def __init__( "Profaned Capital": [ DS3LocationData("PC: Soul of Yhorm the Giant", "Soul of Yhorm the Giant", boss=True), DS3LocationData("PC: Cinders of a Lord - Yhorm the Giant", - "Cinders of a Lord - Yhorm the Giant", offline="07,0:50002170::", + "Cinders of a Lord - Yhorm the Giant", static="07,0:50002170::", prominent=True, progression=True, boss=True), DS3LocationData("PC: Logan's Scroll - chapel roof, NPC drop", "Logan's Scroll", hostile_npc=True), # Sorcerer @@ -1793,7 +1793,7 @@ def __init__( missable=True, npc=True), # Siegward drops (kill or quest) - DS3LocationData("PC: Storm Ruler - Siegward", "Storm Ruler", offline='02,0:50006218::', + DS3LocationData("PC: Storm Ruler - Siegward", "Storm Ruler", static='02,0:50006218::', missable=True, drop=True, npc=True), DS3LocationData("PC: Pierce Shield - Siegward", "Pierce Shield", missable=True, drop=True, npc=True), @@ -1804,7 +1804,7 @@ def __init__( "Anor Londo": [ DS3LocationData("AL: Soul of Aldrich", "Soul of Aldrich", boss=True), DS3LocationData("AL: Cinders of a Lord - Aldrich", "Cinders of a Lord - Aldrich", - offline='06,0:50002130::', prominent=True, progression=True, + static='06,0:50002130::', prominent=True, progression=True, boss=True), DS3LocationData("AL: Yorshka's Chime - kill Yorshka", "Yorshka's Chime", missable=True, drop=True, @@ -1843,10 +1843,10 @@ def __init__( DS3LocationData("AL: Deep Gem - water reserves", "Deep Gem"), DS3LocationData("AL: Titanite Scale - top of ladder up to buttresses", "Titanite Scale"), DS3LocationData("AL: Dragonslayer Greatarrow - drop from nearest buttress", - "Dragonslayer Greatarrow x5", offline='06,0:53700620::', + "Dragonslayer Greatarrow x5", static='06,0:53700620::', hidden=True), # Hidden fall DS3LocationData("AL: Dragonslayer Greatbow - drop from nearest buttress", - "Dragonslayer Greatbow", offline='06,0:53700620::', + "Dragonslayer Greatbow", static='06,0:53700620::', hidden=True), # Hidden fall DS3LocationData("AL: Easterner's Ashes - below top of furthest buttress", "Easterner's Ashes", progression=True), @@ -1894,7 +1894,7 @@ def __init__( hidden=True), # Behind illusory wall DS3LocationData("FS: Budding Green Blossom - shop after killing Creighton and AL boss", - "Budding Green Blossom", offline='99,0:-1:110000,70000118:', + "Budding Green Blossom", static='99,0:-1:110000,70000118:', missable=True, npc=True, shop=True), # sold by Shrine Maiden after killing Aldrich and helping # Sirris defeat Creighton @@ -2147,7 +2147,7 @@ def __init__( DS3LocationData("GA: Soul of the Twin Princes", "Soul of the Twin Princes", boss=True), DS3LocationData("GA: Cinders of a Lord - Lothric Prince", "Cinders of a Lord - Lothric Prince", - offline="09,0:50002040::", prominent=True, progression=True, + static="09,0:50002040::", prominent=True, progression=True, boss=True), DS3LocationData("GA: Onikiri and Ubadachi - outside 5F, NPC drop", "Onikiri and Ubadachi", hostile_npc=True, # Black Hand Kamui drop @@ -2330,7 +2330,7 @@ def __init__( # Yuria shop, or Shrine Handmaiden with Hollow's Ashes # This is here because this is where the ashes end up if you kill Yoel or Yuria DS3LocationData("FS: Ring of Sacrifice - Yuria shop", "Ring of Sacrifice", - offline='99,0:-1:40000,110000,70000107,70000116:', npc=True, + static='99,0:-1:40000,110000,70000107,70000116:', npc=True, shop=True), # Untended Graves Handmaid @@ -2468,7 +2468,7 @@ def __init__( # Shrine Handmaid after placing all Cinders of a Lord DS3LocationData("FS: Titanite Slab - shop after placing all Cinders", "Titanite Slab", - offline='99,0:-1:9210,110000:', hidden=True), + static='99,0:-1:9210,110000:', hidden=True), DS3LocationData("FS: Firelink Helm - shop after placing all Cinders", "Firelink Helm", boss=True, shop=True), DS3LocationData("FS: Firelink Armor - shop after placing all Cinders", "Firelink Armor", @@ -2569,7 +2569,7 @@ def __init__( DS3LocationData("PW1: Ember - settlement, building near bonfire", "Ember"), DS3LocationData("PW1: Frozen Weapon - snowfield lower, egg zone", "Frozen Weapon"), DS3LocationData("PW1: Titanite Slab - depths, up secret ladder", "Titanite Slab", - offline='11,0:54500640::', + static='11,0:54500640::', hidden=True), # Must kill normal-looking Tree Woman DS3LocationData("PW1: Homeward Bone - depths, up hill", "Homeward Bone x2"), DS3LocationData("PW1: Large Soul of an Unknown Traveler - below snowfield village overhang", @@ -2600,7 +2600,7 @@ def __init__( DS3LocationData("PW2: Soul of Sister Friede", "Soul of Sister Friede", prominent=True, boss=True), DS3LocationData("PW2: Titanite Slab - boss drop", "Titanite Slab", - offline='11,0:50004700::', + static='11,0:50004700::', boss=True), # One-time drop after Friede Phase 2 DS3LocationData("PW2: Floating Chaos - NPC drop", "Floating Chaos", hostile_npc=True, hidden=True), # Livid Pyromancer Dunnel drop (requires ember) @@ -2940,35 +2940,35 @@ def __init__( # ashes. "Greirat's Shop": [ DS3LocationData("FS: Blue Tearstone Ring - Greirat", "Blue Tearstone Ring", - offline='01,0:50006120::', npc=True), - DS3LocationData("FS: Ember - Greirat", "Ember", offline="99,0:-1:110000,120000,70000110:", + static='01,0:50006120::', npc=True), + DS3LocationData("FS: Ember - Greirat", "Ember", static="99,0:-1:110000,120000,70000110:", shop=True, npc=True), # Undead Settlement rewards DS3LocationData("FS: Divine Blessing - Greirat from US", "Divine Blessing", - offline='99,0:-1:110000,120000,70000150,70000175:', missable=True, + static='99,0:-1:110000,120000,70000150,70000175:', missable=True, shop=True, npc=True), DS3LocationData("FS: Ember - Greirat from US", "Ember", - offline='99,0:-1:110000,120000,70000150,70000175:', missable=True, + static='99,0:-1:110000,120000,70000150,70000175:', missable=True, shop=True, npc=True), # Irityhll rewards DS3LocationData("FS: Divine Blessing - Greirat from IBV", "Divine Blessing", - offline='99,0:-1:110000,120000,70000151,70000176:', missable=True, + static='99,0:-1:110000,120000,70000151,70000176:', missable=True, shop=True, npc=True), DS3LocationData("FS: Hidden Blessing - Greirat from IBV", "Hidden Blessing", - offline='99,0:-1:110000,120000,70000151,70000176:', missable=True, + static='99,0:-1:110000,120000,70000151,70000176:', missable=True, shop=True, npc=True), DS3LocationData("FS: Titanite Scale - Greirat from IBV", "Titanite Scale", - offline='99,0:-1:110000,120000,70000151,70000176:', missable=True, + static='99,0:-1:110000,120000,70000151,70000176:', missable=True, shop=True, npc=True), DS3LocationData("FS: Twinkling Titanite - Greirat from IBV", "Twinkling Titanite", - offline='99,0:-1:110000,120000,70000151,70000176:', missable=True, + static='99,0:-1:110000,120000,70000151,70000176:', missable=True, shop=True, npc=True), # Lothric rewards (from Shrine Handmaid) DS3LocationData("FS: Ember - shop for Greirat's Ashes", "Twinkling Titanite", - offline='99,0:-1:110000,120000,70000152,70000177:', missable=True, + static='99,0:-1:110000,120000,70000152,70000177:', missable=True, shop=True, npc=True), ], "Karla's Shop": [ @@ -3006,13 +3006,13 @@ def __init__( # Drops on death. Missable because the player would have to decide between killing her or # seeing everything she sells. DS3LocationData("FS: Karla's Pointed Hat - kill Karla", "Karla's Pointed Hat", - offline='07,0:50006150::', missable=True, drop=True, npc=True), + static='07,0:50006150::', missable=True, drop=True, npc=True), DS3LocationData("FS: Karla's Coat - kill Karla", "Karla's Coat", - offline='07,0:50006150::', missable=True, drop=True, npc=True), + static='07,0:50006150::', missable=True, drop=True, npc=True), DS3LocationData("FS: Karla's Gloves - kill Karla", "Karla's Gloves", - offline='07,0:50006150::', missable=True, drop=True, npc=True), + static='07,0:50006150::', missable=True, drop=True, npc=True), DS3LocationData("FS: Karla's Trousers - kill Karla", "Karla's Trousers", - offline='07,0:50006150::', missable=True, drop=True, npc=True), + static='07,0:50006150::', missable=True, drop=True, npc=True), ], } diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 9cf7c881c3c5..8b7e1af5fc02 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -244,9 +244,9 @@ class RandomizeEnemiesOption(DefaultOnToggle): class RandomEnemyPresetOption(Option[typing.Dict[str, typing.Any]], VerifyKeys): - """The YAML preset for the offline enemy randomizer. + """The YAML preset for the static enemy randomizer. - See the offline randomizer documentation in randomizer\\presets\\README.txt for details. + See the static randomizer documentation in randomizer\\presets\\README.txt for details. """ display_name = "Random Enemy Preset" supports_weighting = False diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 67506bff8ba8..cc6acfc3532b 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -624,7 +624,7 @@ def set_rules(self) -> None: ) self._add_entrance_rule("Karla's Shop", "Jailer's Key Ring") - # The offline randomizer edits events to guarantee that Greirat won't go to Lothric until + # The static randomizer edits events to guarantee that Greirat won't go to Lothric until # Grand Archives is available, so his shop will always be available one way or another. self._add_entrance_rule("Greirat's Shop", "Cell Key") @@ -692,7 +692,7 @@ def set_rules(self) -> None: "RC: Lapp's Leggings - Lapp", ], "Chameleon") - # Forbid shops from carrying items with multiple counts (the offline randomizer has its own + # Forbid shops from carrying items with multiple counts (the static randomizer has its own # logic for choosing how many shop items to sell), and from carrying soul items. for location in location_dictionary.values(): if location.shop: @@ -1178,11 +1178,11 @@ def _add_crow_rules(self) -> None: crow = { "Loretta's Bone": "Ring of Sacrifice", - # "Avelyn": "Titanite Scale", # Missing from offline randomizer + # "Avelyn": "Titanite Scale", # Missing from static randomizer "Coiled Sword Fragment": "Titanite Slab", "Seed of a Giant Tree": "Iron Leggings", "Siegbräu": "Armor of the Sun", - # Offline randomizer can't randomize Hodrick's drop yet + # Static randomizer can't randomize Hodrick's drop yet # "Vertebra Shackle": "Lucatiel's Mask", "Xanthous Crown": "Lightning Gem", "Mendicant's Staff": "Sunlight Shield", @@ -1504,14 +1504,14 @@ def fill_slot_data(self) -> Dict[str, object]: if item.data.ds3_code: ap_ids_to_ds3_ids[str(item.code)] = item.data.ds3_code if item.data.count != 1: item_counts[str(item.code)] = item.data.count - # A map from Archipelago's location IDs to the keys the offline - # randomizer uses to identify locations. + # A map from Archipelago's location IDs to the keys the static randomizer uses to identify + # locations. location_ids_to_keys: Dict[int, str] = {} for location in self.multiworld.get_filled_locations(self.player): # Skip events and only look at this world's locations if (location.address is not None and location.item.code is not None - and location.data.offline): - location_ids_to_keys[location.address] = location.data.offline + and location.data.static): + location_ids_to_keys[location.address] = location.data.static slot_data = { "options": { @@ -1538,7 +1538,7 @@ def fill_slot_data(self) -> Dict[str, object]: }, "seed": self.multiworld.seed_name, # to verify the server's multiworld "slot": self.multiworld.player_name[self.player], # to connect to server - # Reserializing here is silly, but it's easier for the offline randomizer. + # Reserializing here is silly, but it's easier for the static randomizer. "random_enemy_preset": json.dumps(self.options.random_enemy_preset.value), "yhorm": ( f"{self.yhorm_location.name} {self.yhorm_location.id}" diff --git a/worlds/dark_souls_3/detailed_location_descriptions.py b/worlds/dark_souls_3/detailed_location_descriptions.py index d25837232691..e20c700ab1bc 100644 --- a/worlds/dark_souls_3/detailed_location_descriptions.py +++ b/worlds/dark_souls_3/detailed_location_descriptions.py @@ -1,7 +1,7 @@ # python -m worlds.dark_souls_3.detailed_location_descriptions \ # worlds/dark_souls_3/detailed_location_descriptions.py # -# This script downloads the offline randomizer's descriptions for each location and adds them to +# This script downloads the static randomizer's descriptions for each location and adds them to # the location documentation. from collections import defaultdict @@ -21,10 +21,10 @@ url = 'https://raw.githubusercontent.com/nex3/SoulsRandomizers/archipelago-server/dist/Base/annotations.txt' response = requests.get(url) if response.status_code != 200: - raise Exception(f"Got {response.status_code} when downloading offline randomizer locations") + raise Exception(f"Got {response.status_code} when downloading static randomizer locations") annotations = yaml.load(response.text, Loader=yaml.Loader) - offline_to_archi_regions = { + static_to_archi_regions = { area['Name']: area['Archipelago'] for area in annotations['Areas'] } @@ -38,7 +38,7 @@ descriptions_by_item = defaultdict(list) for slot in annotations['Slots']: - region = offline_to_archi_regions[slot['Area']] + region = static_to_archi_regions[slot['Area']] for item in slot['DebugText']: name = item.split(" - ")[0] descriptions_by_location[(region, name)].append(slot['Text']) @@ -50,8 +50,8 @@ location_names_to_descriptions = {} for location in location_dictionary.values(): if location.ap_code is None: continue - if location.offline: - location_names_to_descriptions[location.name] = descriptions_by_key[location.offline] + if location.static: + location_names_to_descriptions[location.name] = descriptions_by_key[location.static] continue match = location_re.match(location.name) @@ -65,12 +65,12 @@ key = (match[1], match[2]) if key not in descriptions_by_location: - raise Exception(f'No offline randomizer location found matching "{match[1]}: {match[2]}".') + raise Exception(f'No static randomizer location found matching "{match[1]}: {match[2]}".') candidates = descriptions_by_location[key] if len(candidates) == 0: raise Exception( - f'There are only {counts_by_location[key]} locations in the offline randomizer ' + + f'There are only {counts_by_location[key]} locations in the static randomizer ' + f'matching "{match[1]}: {match[2]}", but there are more in Archipelago.' ) diff --git a/worlds/dark_souls_3/docs/en_Dark Souls III.md b/worlds/dark_souls_3/docs/en_Dark Souls III.md index ca7b835b3a8e..25b81f745292 100644 --- a/worlds/dark_souls_3/docs/en_Dark Souls III.md +++ b/worlds/dark_souls_3/docs/en_Dark Souls III.md @@ -1,5 +1,10 @@ # Dark Souls III +Game Page | [Items] | [Locations] + +[Items]: /tutorial/Dark%20Souls%20III/items/en +[Locations]: /tutorial/Dark%20Souls%20III/locations/en + ## What do I need to do to randomize DS3? See full instructions on [the setup page]. @@ -100,6 +105,7 @@ Dark Souls III: exclude_locations: # Exclude late-game and DLC regions + - Anor Londo - Lothric Castle - Consumed King's Garden - Untended Graves @@ -132,26 +138,21 @@ Check out the [item guide], which explains the named groups available for items. [item guide]: /tutorial/Dark%20Souls%20III/items/en -## What's the difference from 2.x.x? +## What's new from 2.x.x? -Version 3.0.0 and forward of the Dark Souls III Archipelago client has a number -of substantial differences with the older 2.x.x versions. Improvements include: +Version 3.0.0 of the Dark Souls III Archipelago client has a number of +substantial differences with the older 2.x.x versions. Improvements include: -* Support for randomizing all item locations, not just unique items, without - needing progressive pickup lists. +* Support for randomizing all item locations, not just unique items. * Support for randomizing items in shops, starting loadouts, Path of the Dragon, and more. * Built-in integration with the enemy randomizer, including consistent seeding - for races and configuration via the web interface and the standard Archipelago - YAML file. - -* Support for the latest patch for Dark Souls III, 1.15.2. Note that older - patches are currently *not* supported, although if [ModEngine2] ever adds - support they should work fine. + for races. - [ModEngine2]: https://github.com/soulsmods/ModEngine2 +* Support for the latest patch for Dark Souls III, 1.15.2. Older patches are + *not* supported. * Optional smooth distribution for upgrade items, upgraded weapons, and soul items so you're more likely to see weaker items earlier and more powerful @@ -162,11 +163,10 @@ of substantial differences with the older 2.x.x versions. Improvements include: * Other players' item names are visible in DS3. -* If you pick up items while offline, they'll still send once you reconnect. +* If you pick up items while static, they'll still send once you reconnect. -However, not all YAML fields from 2.x.x are supported as-is in 3.0.0, and some -new fields are available. Consider [generating a new YAML configuration] for use -with 3.x.x. +However, 2.x.x YAMLs are not compatible with 3.0.0. You'll need to [generate a +new YAML configuration] for use with 3.x.x. [generating a new YAML configuration]: /games/Dark%20Souls%20III/player-options @@ -183,9 +183,9 @@ The following options have been removed: In addition, the following options have changed: -* `enable_*_locations` options have all been deprecated. Instead, you can now - add [location group names] to the `exclude_locations` option to prevent them - from containing important items. +* `enable_*_locations` options have all been removed. Instead, you can now add + [location group names] to the `exclude_locations` option to prevent them from + containing important items. [location group names]: /tutorial/Dark%20Souls%20III/locations/en#location-groups diff --git a/worlds/dark_souls_3/docs/items_en.md b/worlds/dark_souls_3/docs/items_en.md index ba100257cc14..b9de5e500a96 100644 --- a/worlds/dark_souls_3/docs/items_en.md +++ b/worlds/dark_souls_3/docs/items_en.md @@ -1,5 +1,10 @@ # Dark Souls III Items +[Game Page] | Items | [Locations] + +[Game Page]: /games/Dark%20Souls%20III/info/en +[Locations]: /tutorial/Dark%20Souls%20III/locations/en + ## Item Groups The Dark Souls III randomizer supports a number of item group names, which can diff --git a/worlds/dark_souls_3/docs/locations_en.md b/worlds/dark_souls_3/docs/locations_en.md index c16746ff26a5..5df01aa1df4b 100644 --- a/worlds/dark_souls_3/docs/locations_en.md +++ b/worlds/dark_souls_3/docs/locations_en.md @@ -1,5 +1,10 @@ # Dark Souls III Locations +[Game Page] | [Items] | Locations + +[Game Page]: /games/Dark%20Souls%20III/info/en +[Items]: /tutorial/Dark%20Souls%20III/items/en + ## Table of Contents * [Location Groups](#location-groups) @@ -752,10 +757,10 @@ of Halflight, Gael, and Midir, respectively. ## Detailed Location Descriptions These location descriptions were originally written by [Matt Gruen] for [the -offline _Dark Souls III_ randomizer]. +static _Dark Souls III_ randomizer]. [Matt Gruen]: https://thefifthmatt.com/ -[the offline _Dark Souls III_ randomizer]: https://www.nexusmods.com/darksouls3/mods/361 +[the static _Dark Souls III_ randomizer]: https://www.nexusmods.com/darksouls3/mods/361 From e14dd5e35d8fd8d3914bb95d4b10530e6d0afbc7 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 28 Apr 2024 23:32:38 -0700 Subject: [PATCH 205/238] Move `enable_*_locations` under removed options. --- worlds/dark_souls_3/docs/en_Dark Souls III.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/docs/en_Dark Souls III.md b/worlds/dark_souls_3/docs/en_Dark Souls III.md index 25b81f745292..5b406223cbc7 100644 --- a/worlds/dark_souls_3/docs/en_Dark Souls III.md +++ b/worlds/dark_souls_3/docs/en_Dark Souls III.md @@ -181,8 +181,6 @@ The following options have been removed: items in randomized categories, there's not a meaningful distinction between "shuffle" and "various" mode. -In addition, the following options have changed: - * `enable_*_locations` options have all been removed. Instead, you can now add [location group names] to the `exclude_locations` option to prevent them from containing important items. @@ -194,5 +192,7 @@ In addition, the following options have changed: excluded locations, you can set `excluded_locations: unrandomized` to preserve the default vanilla item placements for all excluded locations. +In addition, the following options have changed: + * The location names used in options like `exclude_locations` have changed. See the [location guide] for a full description. From bf0cd05efa567bfce1df0fcda18387d6dee9c334 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 29 Apr 2024 15:36:12 -0700 Subject: [PATCH 206/238] Avoid excluded locations for locally-filled items --- worlds/dark_souls_3/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index cc6acfc3532b..f8830f9d1723 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -472,7 +472,9 @@ def _fill_local_item( and not location.conditional and (not additional_condition or additional_condition(location)) ) - if not location.item and location.progress_type != LocationProgressType.EXCLUDED + # We can't use location.progress_type here because it's not set + # until after `set_rules()` runs. + if not location.item and location.name not in self.all_excluded_locations and location.item_rule(item) ] From 079f992eeea51e7c276e0df860ab347242e26132 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 11 May 2024 17:39:03 -0400 Subject: [PATCH 207/238] Adding Removed options to error (#14) --- worlds/dark_souls_3/Options.py | 18 ++++++++++++++++-- worlds/dark_souls_3/__init__.py | 5 ----- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 8b7e1af5fc02..19af429fb1c2 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -3,7 +3,7 @@ import json import typing -from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, ItemDict, NamedRange, Option, PerGameCommonOptions, Range, Toggle, VerifyKeys +from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, ItemDict, NamedRange, Option, PerGameCommonOptions, Range, Removed, Toggle, VerifyKeys class ExcludedLocationsOption(Choice): @@ -348,7 +348,7 @@ class ImpatientMimicsOption(Toggle): class DS3ExcludeLocations(ExcludeLocations): - """Prevent these locations from having an important item""" + """Forces these locations to have certain types of items, exact behavior depends on the "Excluded Locations" option.""" default = {"Hidden", "Small Crystal Lizards", "Upgrade", "Small Souls", "Miscellaneous"} @@ -391,3 +391,17 @@ class DarkSouls3Options(PerGameCommonOptions): all_chests_are_mimics: AllChestsAreMimicsOption impatient_mimics: ImpatientMimicsOption exclude_locations: DS3ExcludeLocations + + # 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 diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index f8830f9d1723..01f1effba775 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -111,11 +111,6 @@ def generate_early(self): self.yhorm_location = default_yhorm_location - def _exclude_location_group(self, name: str): - """Adds all the locations in the given location group to the set of excluded locations.""" - self.options.exclude_locations.value.update(location_name_groups[name]) - - def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: """Returns whether boss is a valid location for Yhorm in this seed.""" From 9daed637e572b11eaeddaac04e3d8166de72ffcb Mon Sep 17 00:00:00 2001 From: Exempt-Medic Date: Mon, 10 Jun 2024 09:43:06 -0400 Subject: [PATCH 208/238] Changes for WebHost options display and the options overhaul --- worlds/dark_souls_3/Options.py | 273 +++++++++++++++++++++----------- worlds/dark_souls_3/__init__.py | 8 +- 2 files changed, 184 insertions(+), 97 deletions(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 19af429fb1c2..25a4b525e237 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -3,24 +3,22 @@ import json import typing -from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, ItemDict, NamedRange, Option, PerGameCommonOptions, Range, Removed, Toggle, VerifyKeys +from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, ItemDict, NamedRange, Option, OptionGroup, \ + PerGameCommonOptions, Range, Removed, Toggle, VerifyKeys class ExcludedLocationsOption(Choice): - """Which items can be placed in excluded locations in DS3. + """ + Which items can be placed in excluded locations in DS3. - * Unnecessary: Excluded locations can't have progression items, but they can - have useful items. - * Unimportant: Neither progression items nor useful items can be placed in - excluded locations. - * Unrandomized: Excluded locations always contain the same item as in - vanilla Dark Souls III. + - Unnecessary: Excluded locations can't have progression items, but they can have useful items. + - Unimportant: Neither progression items nor useful items can be placed in excluded locations. + - Unrandomized: 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. + 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" + display_name = "Excluded Locations Behavior" option_unnecessary = 1 option_unimportant = 2 option_unrandomized = 3 @@ -28,103 +26,120 @@ class ExcludedLocationsOption(Choice): class MissableLocationsOption(Choice): - """Which items can be placed in locations that can be permanently missed. + """ + Which items can be placed in locations that can be permanently missed. - * Unnecessary: Missable locations can't have progression items, but they can - have useful items. - * Unimportant: Neither progression items nor useful items can be placed in - missable locations. - * Unrandomized: Missable locations always contain the same item as in - vanilla Dark Souls III. + - Unnecessary: Missable locations can't have progression items, but they can have useful items. + - Unimportant: Neither progression items nor useful items can be placed in missable locations. + - Unrandomized: 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. + 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" + display_name = "Missable Locations Behavior" option_unnecessary = 1 option_unimportant = 2 option_unrandomized = 3 default = 2 - + class SmoothSoulItemsOption(DefaultOnToggle): - """Whether to distribute soul items in a similar order as the base game. + """ + Whether to 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. + 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): - """Whether to distribute upgrade items in a similar order as the base game. + """ + Whether to 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. + 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): - """Whether to distribute upgraded weapons in a similar order as the base game. + """ + Whether to 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. + 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" class RandomizeStartingLoadout(DefaultOnToggle): - """Randomizes the equipment characters begin with.""" + """ + Randomizes the equipment characters begin with. + """ display_name = "Randomize Starting Loadout" class RequireOneHandedStartingWeapons(DefaultOnToggle): - """Require starting equipment to be usable one-handed.""" + """ + Require starting equipment to be usable one-handed. + """ display_name = "Require One-Handed Starting Weapons" class GuaranteedItemsOption(ItemDict): - """Guarantees that the specified items will be in the item pool""" + """ + Guarantees that the specified items will be in the item pool. + """ display_name = "Guaranteed Items" class AutoEquipOption(Toggle): - """Automatically equips any received armor or left/right weapons.""" + """ + 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.""" + """ + 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 NoWeaponRequirementsOption(Toggle): - """Disable the weapon requirements by removing any movement or damage penalties, permitting you to use any weapon early.""" + """ + 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""" + """ + Disable the spell requirements permitting you to use any spell. + """ display_name = "No Spell Requirements" class NoEquipLoadOption(Toggle): - """Disable the equip load constraint from the game""" + """ + Disable the equip load constraint from the game. + """ display_name = "No Equip Load" class RandomizeInfusionOption(Toggle): - """Enable this option to infuse a percentage of the pool of weapons and shields.""" + """ + 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""" + """ + 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 @@ -134,12 +149,12 @@ class RandomizeInfusionPercentageOption(NamedRange): 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. + """ + 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 + - 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 @@ -149,7 +164,9 @@ class RandomizeWeaponLevelOption(Choice): class RandomizeWeaponLevelPercentageOption(Range): - """The percentage of weapons in the pool to be upgraded if randomize weapons level is toggled""" + """ + 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 @@ -157,7 +174,9 @@ class RandomizeWeaponLevelPercentageOption(Range): class MinLevelsIn5WeaponPoolOption(Range): - """The minimum upgraded value of a weapon in the pool of weapons that can only reach +5""" + """ + 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 @@ -165,7 +184,9 @@ class MinLevelsIn5WeaponPoolOption(Range): class MaxLevelsIn5WeaponPoolOption(Range): - """The maximum upgraded value of a weapon in the pool of weapons that can only reach +5""" + """ + 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 @@ -173,7 +194,9 @@ class MaxLevelsIn5WeaponPoolOption(Range): class MinLevelsIn10WeaponPoolOption(Range): - """The minimum upgraded value of a weapon in the pool of weapons that can reach +10""" + """ + 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 @@ -181,7 +204,9 @@ class MinLevelsIn10WeaponPoolOption(Range): class MaxLevelsIn10WeaponPoolOption(Range): - """The maximum upgraded value of a weapon in the pool of weapons that can reach +10""" + """ + 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 @@ -189,8 +214,9 @@ class MaxLevelsIn10WeaponPoolOption(Range): class EarlySmallLothricBanner(Choice): - """This option makes it so the user can choose to force the Small Lothric Banner into an early sphere in their world - or into an early sphere across all worlds.""" + """ + This option makes it so the user can choose to force the Small Lothric Banner into an early sphere in their world or into an early sphere across all worlds. + """ display_name = "Early Small Lothric Banner" option_off = 0 option_early_global = 1 @@ -199,10 +225,13 @@ class EarlySmallLothricBanner(Choice): class LateBasinOfVowsOption(Choice): - """This option makes it so the Basin of Vows is still randomized, but you can choose the requirements to venture into Lothric Castle. - "Off": You may have to enter Lothric Castle and the areas beyond it before finding your Small Lothric Banner. - "After Small Lothric Banner": You are guaranteed to find your Small Lothric Banner before needing to enter Lothric Castle. - "After Small Doll": You are guaranteed to find your Small Lothric Banner and your Small Doll before needing to enter Lothric Castle.""" + """ + This option makes it so the Basin of Vows is still randomized, but you can choose the requirements to venture into Lothric Castle. + + - Off: You may have to enter Lothric Castle and the areas beyond it before finding your Small Lothric Banner. + - After Small Lothric Banner: You are guaranteed to find your Small Lothric Banner before needing to enter Lothric Castle. + - After Small Doll: You are guaranteed to find your Small Lothric Banner and your Small Doll before needing to enter Lothric Castle. + """ display_name = "Late Basin of Vows" option_off = 0 alias_false = 0 @@ -212,10 +241,13 @@ class LateBasinOfVowsOption(Choice): class LateDLCOption(Choice): - """This option makes it so the Small Doll is still randomized, but you can choose the requirements to venture into Painted World of Ariandel. - "Off": You may have to enter Ariandel and the areas beyond it before finding your Small Doll. - "After Small Doll": You are guaranteed to find your Small Doll before needing to enter Ariandel. - "After Basin": You are guaranteed to find your Small Doll and your Basin of Vows before needing to enter Ariandel.""" + """ + This option makes it so the Small Doll is still randomized, but you can choose the requirements to venture into Painted World of Ariandel. + + - Off: You may have to enter Ariandel and the areas beyond it before finding your Small Doll. + - After Small Doll: You are guaranteed to find your Small Doll before needing to enter Ariandel. + - After Basin: You are guaranteed to find your Small Doll and your Basin of Vows before needing to enter Ariandel. + """ display_name = "Late DLC" option_off = 0 alias_false = 0 @@ -225,27 +257,32 @@ class LateDLCOption(Choice): class EnableDLCOption(Toggle): - """To use this option, you must own both the ASHES OF ARIANDEL and the RINGED CITY DLC""" + """ + To use this option, you must own both the ASHES OF ARIANDEL and the RINGED CITY DLC. + """ display_name = "Enable DLC" class EnableNGPOption(Toggle): - """Whether to include items and locations exclusive to NG+ cycles""" + """ + Whether to include items and locations exclusive to NG+ cycles. + """ display_name = "Enable NG+" class RandomizeEnemiesOption(DefaultOnToggle): - """Whether to randomize enemy and boss placements. + """ + Whether to randomize enemy and boss placements. - If this is enabled, the Storm Ruler sword is granted immediately upon meeting Yhorm the Giant - instead of being randomized into the world. + If this is enabled, the Storm Ruler sword is granted immediately upon meeting Yhorm the Giant instead of being randomized into the world. """ display_name = "Randomize Enemies" class RandomEnemyPresetOption(Option[typing.Dict[str, typing.Any]], VerifyKeys): - """The YAML preset for the static enemy randomizer. - + """ + The YAML preset for the static enemy randomizer. + See the static randomizer documentation in randomizer\\presets\\README.txt for details. """ display_name = "Random Enemy Preset" @@ -272,11 +309,11 @@ def from_any(cls, data: typing.Dict[str, typing.Any]) -> "RandomEnemyPresetOptio class RandomizeMimicsWithEnemiesOption(Toggle): - """Whether to mix Mimics into the main enemy pool. + """ + Whether to 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. + 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. """ @@ -284,11 +321,11 @@ class RandomizeMimicsWithEnemiesOption(Toggle): class RandomizeSmallCrystalLizardsWithEnemiesOption(Toggle): - """Whether to mix small Crystal Lizards into the main enemy pool. + """ + Whether to 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. + 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. """ @@ -296,7 +333,8 @@ class RandomizeSmallCrystalLizardsWithEnemiesOption(Toggle): class ReduceHarmlessEnemiesOption(Toggle): - """Whether to reduce the frequency that "harmless" enemies appear. + """ + Whether to 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. @@ -307,10 +345,11 @@ class ReduceHarmlessEnemiesOption(Toggle): class SimpleEarlyBossesOption(DefaultOnToggle): - """Whether to avoid replacing Iudex Gundyr and Vordt with late bosses. + """ + Whether to 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 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. """ @@ -318,10 +357,10 @@ class SimpleEarlyBossesOption(DefaultOnToggle): class ScaleEnemiesOption(DefaultOnToggle): - """Whether to scale randomized enemy stats to match the areas in which they appear. + """ + Whether to 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. + 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. """ @@ -329,10 +368,10 @@ class ScaleEnemiesOption(DefaultOnToggle): class AllChestsAreMimicsOption(Toggle): - """Whether to replace all chests with mimics that drop the same items. + """ + Whether to 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. + 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. """ @@ -340,7 +379,8 @@ class AllChestsAreMimicsOption(Toggle): class ImpatientMimicsOption(Toggle): - """Whether mimics should attack as soon as you get close. + """ + Whether mimics should attack as soon as you get close. This is ignored unless enemies are randomized. """ @@ -348,7 +388,9 @@ class ImpatientMimicsOption(Toggle): class DS3ExcludeLocations(ExcludeLocations): - """Forces these locations to have certain types of items, exact behavior depends on the "Excluded Locations" option.""" + """ + Forces these locations to have certain types of items, exact behavior depends on the "Excluded Locations Behavior" option. + """ default = {"Hidden", "Small Crystal Lizards", "Upgrade", "Small Souls", "Miscellaneous"} @@ -405,3 +447,48 @@ class DarkSouls3Options(PerGameCommonOptions): enable_misc_locations: Removed enable_health_upgrade_locations: Removed enable_progressive_locations: Removed + + +option_groups = [ + OptionGroup("Equipment Options", [ + RandomizeStartingLoadout, + RequireOneHandedStartingWeapons, + AutoEquipOption, + LockEquipOption, + NoEquipLoadOption, + NoWeaponRequirementsOption, + NoSpellRequirementsOption, + ]), + OptionGroup("Item Smoothing Options", [ + SmoothSoulItemsOption, + SmoothUpgradeItemsOption, + SmoothUpgradedWeaponsOption, + ]), + OptionGroup("Weapon Infusion and Level Options", [ + RandomizeInfusionOption, + RandomizeInfusionPercentageOption, + RandomizeWeaponLevelOption, + RandomizeWeaponLevelPercentageOption, + MinLevelsIn5WeaponPoolOption, + MaxLevelsIn5WeaponPoolOption, + MinLevelsIn10WeaponPoolOption, + MaxLevelsIn10WeaponPoolOption, + ]), + OptionGroup("Enemy Randomizer Options", [ + RandomizeEnemiesOption, + RandomEnemyPresetOption, + SimpleEarlyBossesOption, + ScaleEnemiesOption, + RandomizeMimicsWithEnemiesOption, + RandomizeSmallCrystalLizardsWithEnemiesOption, + ReduceHarmlessEnemiesOption, + AllChestsAreMimicsOption, + ImpatientMimicsOption, + ]), + OptionGroup("Item & Location Behavior Options", [ + ExcludedLocationsOption, + DS3ExcludeLocations, + MissableLocationsOption, + GuaranteedItemsOption, + ]) +] diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index e9ccb6c36559..8115480af9c2 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -13,7 +13,7 @@ from .Bosses import DS3BossInfo, all_bosses, default_yhorm_location from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, Infusion, UsefulIf, filler_item_names, item_descriptions, item_dictionary, item_name_groups from .Locations import DarkSouls3Location, DS3LocationData, location_tables, location_descriptions, location_dictionary, location_name_groups, region_order -from .Options import DarkSouls3Options, EarlySmallLothricBanner +from .Options import DarkSouls3Options, EarlySmallLothricBanner, option_groups class DarkSouls3Web(WebWorld): @@ -38,7 +38,7 @@ class DarkSouls3Web(WebWorld): ) tutorials = [setup_en, setup_fr] - + option_groups = option_groups item_descriptions = item_descriptions @@ -63,8 +63,8 @@ class DarkSouls3World(World): } location_name_groups = location_name_groups item_name_groups = item_name_groups - location_descriptions = location_descriptions - item_descriptions = item_descriptions + # location_descriptions = location_descriptions + # item_descriptions = item_descriptions yhorm_location: Optional[DS3BossInfo] """If enemy randomization is enabled, this is the boss who Yhorm the Giant should replace. From a61f3a86ea72743533eb1126d67737a095a93dd1 Mon Sep 17 00:00:00 2001 From: Doug Hoskisson Date: Mon, 10 Jun 2024 15:46:18 -0700 Subject: [PATCH 209/238] unpack iterators in item list (#13) --- worlds/dark_souls_3/Items.py | 122 ++++++++++++++++------------------- 1 file changed, 57 insertions(+), 65 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 0c351234953c..9dd9adfa4c28 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -266,38 +266,30 @@ def event(name: str, player: int) -> "DarkSouls3Item": return DarkSouls3Item(player, data) -# TODO: use this from Utils once this is a PR for the main repo and not an APWorld -def flatten(l): - if type(l) is list or type(l) is types.GeneratorType: - return [ y for x in l for y in flatten(x) ] - else: - return [ l ] - - -_vanilla_items = flatten([ +_vanilla_items = [ # Ammunition - DS3ItemData("Standard Arrow", 0x00061A80, DS3ItemCategory.MISC).counts([12]), + *DS3ItemData("Standard Arrow", 0x00061A80, DS3ItemCategory.MISC).counts([12]), DS3ItemData("Standard Arrow x8", 0x00061A80, DS3ItemCategory.MISC, count = 8, filler = True), DS3ItemData("Fire Arrow", 0x00061AE4, DS3ItemCategory.MISC), DS3ItemData("Fire Arrow x8", 0x00061AE4, DS3ItemCategory.MISC, count = 8, filler = True), - DS3ItemData("Poison Arrow", 0x00061B48, DS3ItemCategory.MISC).counts([18]), + *DS3ItemData("Poison Arrow", 0x00061B48, DS3ItemCategory.MISC).counts([18]), DS3ItemData("Poison Arrow x8", 0x00061B48, DS3ItemCategory.MISC, count = 8, filler = True), DS3ItemData("Large Arrow", 0x00061BAC, DS3ItemCategory.MISC), DS3ItemData("Feather Arrow", 0x00061C10, DS3ItemCategory.MISC), - DS3ItemData("Moonlight Arrow", 0x00061C74, DS3ItemCategory.MISC).counts([6]), + *DS3ItemData("Moonlight Arrow", 0x00061C74, DS3ItemCategory.MISC).counts([6]), DS3ItemData("Wood Arrow", 0x00061CD8, DS3ItemCategory.MISC), DS3ItemData("Dark Arrow", 0x00061D3C, DS3ItemCategory.MISC), - DS3ItemData("Dragonslayer Greatarrow", 0x00062250, DS3ItemCategory.MISC).counts([5]), - DS3ItemData("Dragonslayer Lightning Arrow", 0x00062318, DS3ItemCategory.MISC).counts([10]), - DS3ItemData("Onislayer Greatarrow", 0x0006237C, DS3ItemCategory.MISC).counts([8]), + *DS3ItemData("Dragonslayer Greatarrow", 0x00062250, DS3ItemCategory.MISC).counts([5]), + *DS3ItemData("Dragonslayer Lightning Arrow", 0x00062318, DS3ItemCategory.MISC).counts([10]), + *DS3ItemData("Onislayer Greatarrow", 0x0006237C, DS3ItemCategory.MISC).counts([8]), DS3ItemData("Standard Bolt", 0x00062A20, DS3ItemCategory.MISC), DS3ItemData("Heavy Bolt", 0x00062A84, DS3ItemCategory.MISC), - DS3ItemData("Sniper Bolt", 0x00062AE8, DS3ItemCategory.MISC).counts([11]), + *DS3ItemData("Sniper Bolt", 0x00062AE8, DS3ItemCategory.MISC).counts([11]), DS3ItemData("Wood Bolt", 0x00062B4C, DS3ItemCategory.MISC), - DS3ItemData("Lightning Bolt", 0x00062BB0, DS3ItemCategory.MISC).counts([9]), - DS3ItemData("Lightning Bolt", 0x00062BB0, DS3ItemCategory.MISC).counts([12]), + *DS3ItemData("Lightning Bolt", 0x00062BB0, DS3ItemCategory.MISC).counts([9]), + *DS3ItemData("Lightning Bolt", 0x00062BB0, DS3ItemCategory.MISC).counts([12]), DS3ItemData("Splintering Bolt", 0x00062C14, DS3ItemCategory.MISC), - DS3ItemData("Exploding Bolt", 0x00062C78, DS3ItemCategory.MISC).counts([6]), + *DS3ItemData("Exploding Bolt", 0x00062C78, DS3ItemCategory.MISC).counts([6]), # Weapons DS3ItemData("Dagger", 0x000F4240, DS3ItemCategory.WEAPON_UPGRADE_10_INFUSIBLE), @@ -1019,52 +1011,52 @@ def flatten(l): DS3ItemData("Red Sign Soapstone", 0x40000066, DS3ItemCategory.UNIQUE, skip = True), DS3ItemData("Red Eye Orb", 0x40000066, DS3ItemCategory.UNIQUE, skip = True), DS3ItemData("Roster of Knights", 0x4000006C, DS3ItemCategory.UNIQUE, skip = True), - DS3ItemData("Cracked Red Eye Orb", 0x4000006F, DS3ItemCategory.MISC, skip = True).counts([5]), + *DS3ItemData("Cracked Red Eye Orb", 0x4000006F, DS3ItemCategory.MISC, skip = True).counts([5]), DS3ItemData("Black Eye Orb", 0x40000073, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), DS3ItemData("Divine Blessing", 0x400000F0, DS3ItemCategory.MISC), DS3ItemData("Hidden Blessing", 0x400000F1, DS3ItemCategory.MISC), - DS3ItemData("Green Blossom", 0x40000104, DS3ItemCategory.MISC, filler = True).counts([2, 3, 4]), - DS3ItemData("Budding Green Blossom", 0x40000106, DS3ItemCategory.MISC).counts([2, 3]), - DS3ItemData("Bloodred Moss Clump", 0x4000010E, DS3ItemCategory.MISC, filler = True).counts([3]), - DS3ItemData("Purple Moss Clump", 0x4000010F, DS3ItemCategory.MISC, filler = True).counts([2, 3, 4]), - DS3ItemData("Blooming Purple Moss Clump", 0x40000110, DS3ItemCategory.MISC).counts([3]), - DS3ItemData("Purging Stone", 0x40000112, DS3ItemCategory.MISC, skip = True).counts([2, 3]), - DS3ItemData("Rime-blue Moss Clump", 0x40000114, DS3ItemCategory.MISC, filler = True).counts([2, 4]), - DS3ItemData("Repair Powder", 0x40000118, DS3ItemCategory.MISC, filler = True).counts([2, 3, 4]), - DS3ItemData("Kukri", 0x40000122, DS3ItemCategory.MISC).counts([8, 9]), + *DS3ItemData("Green Blossom", 0x40000104, DS3ItemCategory.MISC, filler = True).counts([2, 3, 4]), + *DS3ItemData("Budding Green Blossom", 0x40000106, DS3ItemCategory.MISC).counts([2, 3]), + *DS3ItemData("Bloodred Moss Clump", 0x4000010E, DS3ItemCategory.MISC, filler = True).counts([3]), + *DS3ItemData("Purple Moss Clump", 0x4000010F, DS3ItemCategory.MISC, filler = True).counts([2, 3, 4]), + *DS3ItemData("Blooming Purple Moss Clump", 0x40000110, DS3ItemCategory.MISC).counts([3]), + *DS3ItemData("Purging Stone", 0x40000112, DS3ItemCategory.MISC, skip = True).counts([2, 3]), + *DS3ItemData("Rime-blue Moss Clump", 0x40000114, DS3ItemCategory.MISC, filler = True).counts([2, 4]), + *DS3ItemData("Repair Powder", 0x40000118, DS3ItemCategory.MISC, filler = True).counts([2, 3, 4]), + *DS3ItemData("Kukri", 0x40000122, DS3ItemCategory.MISC).counts([8, 9]), DS3ItemData("Kukri x5", 0x40000122, DS3ItemCategory.MISC, count = 5, filler = True), - DS3ItemData("Firebomb", 0x40000124, DS3ItemCategory.MISC).counts([3, 5, 6]), + *DS3ItemData("Firebomb", 0x40000124, DS3ItemCategory.MISC).counts([3, 5, 6]), DS3ItemData("Firebomb x2", 0x40000124, DS3ItemCategory.MISC, count = 2, filler = True), - DS3ItemData("Dung Pie", 0x40000125, DS3ItemCategory.MISC).counts([2, 4]), + *DS3ItemData("Dung Pie", 0x40000125, DS3ItemCategory.MISC).counts([2, 4]), DS3ItemData("Dung Pie x3", 0x40000125, DS3ItemCategory.MISC, count = 3, filler = True), - DS3ItemData("Alluring Skull", 0x40000126, DS3ItemCategory.MISC, filler = True).counts([2, 3]), - DS3ItemData("Undead Hunter Charm", 0x40000128, DS3ItemCategory.MISC).counts([2, 3]), - DS3ItemData("Black Firebomb", 0x40000129, DS3ItemCategory.MISC, filler = True).counts([2, 3, 4]), + *DS3ItemData("Alluring Skull", 0x40000126, DS3ItemCategory.MISC, filler = True).counts([2, 3]), + *DS3ItemData("Undead Hunter Charm", 0x40000128, DS3ItemCategory.MISC).counts([2, 3]), + *DS3ItemData("Black Firebomb", 0x40000129, DS3ItemCategory.MISC, filler = True).counts([2, 3, 4]), DS3ItemData("Rope Firebomb", 0x4000012B, DS3ItemCategory.MISC), - DS3ItemData("Lightning Urn", 0x4000012C, DS3ItemCategory.MISC, filler = True).counts([3, 4, 6]), + *DS3ItemData("Lightning Urn", 0x4000012C, DS3ItemCategory.MISC, filler = True).counts([3, 4, 6]), DS3ItemData("Rope Black Firebomb", 0x4000012E, DS3ItemCategory.MISC), - DS3ItemData("Stalk Dung Pie", 0x4000012F, DS3ItemCategory.MISC).counts([6]), - DS3ItemData("Duel Charm", 0x40000130, DS3ItemCategory.MISC).counts([3]), - DS3ItemData("Throwing Knife", 0x40000136, DS3ItemCategory.MISC).counts([6, 8]), + *DS3ItemData("Stalk Dung Pie", 0x4000012F, DS3ItemCategory.MISC).counts([6]), + *DS3ItemData("Duel Charm", 0x40000130, DS3ItemCategory.MISC).counts([3]), + *DS3ItemData("Throwing Knife", 0x40000136, DS3ItemCategory.MISC).counts([6, 8]), DS3ItemData("Throwing Knife x5", 0x40000136, DS3ItemCategory.MISC, count = 5, filler = True), DS3ItemData("Poison Throwing Knife", 0x40000137, DS3ItemCategory.MISC), - DS3ItemData("Charcoal Pine Resin", 0x4000014A, DS3ItemCategory.MISC, filler = True).counts([2]), - DS3ItemData("Gold Pine Resin", 0x4000014B, DS3ItemCategory.MISC, filler = True).counts([2]), - DS3ItemData("Human Pine Resin", 0x4000014E, DS3ItemCategory.MISC, filler = True).counts([2, 4]), - DS3ItemData("Carthus Rouge", 0x4000014F, DS3ItemCategory.MISC, filler = True).counts([2, 3]), - DS3ItemData("Pale Pine Resin", 0x40000150, DS3ItemCategory.MISC, filler = True).counts([2]), - DS3ItemData("Charcoal Pine Bundle", 0x40000154, DS3ItemCategory.MISC).counts([2]), - DS3ItemData("Gold Pine Bundle", 0x40000155, DS3ItemCategory.MISC).counts([6]), - DS3ItemData("Rotten Pine Resin", 0x40000157, DS3ItemCategory.MISC).counts([2, 4]), - DS3ItemData("Homeward Bone", 0x4000015E, DS3ItemCategory.MISC, filler = True).counts([2, 3, 6]), + *DS3ItemData("Charcoal Pine Resin", 0x4000014A, DS3ItemCategory.MISC, filler = True).counts([2]), + *DS3ItemData("Gold Pine Resin", 0x4000014B, DS3ItemCategory.MISC, filler = True).counts([2]), + *DS3ItemData("Human Pine Resin", 0x4000014E, DS3ItemCategory.MISC, filler = True).counts([2, 4]), + *DS3ItemData("Carthus Rouge", 0x4000014F, DS3ItemCategory.MISC, filler = True).counts([2, 3]), + *DS3ItemData("Pale Pine Resin", 0x40000150, DS3ItemCategory.MISC, filler = True).counts([2]), + *DS3ItemData("Charcoal Pine Bundle", 0x40000154, DS3ItemCategory.MISC).counts([2]), + *DS3ItemData("Gold Pine Bundle", 0x40000155, DS3ItemCategory.MISC).counts([6]), + *DS3ItemData("Rotten Pine Resin", 0x40000157, DS3ItemCategory.MISC).counts([2, 4]), + *DS3ItemData("Homeward Bone", 0x4000015E, DS3ItemCategory.MISC, filler = True).counts([2, 3, 6]), DS3ItemData("Coiled Sword Fragment", 0x4000015F, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression), # Crow trade DS3ItemData("Wolf's Blood Swordgrass", 0x4000016E, DS3ItemCategory.MISC, skip = True), DS3ItemData("Human Dregs", 0x4000016F, DS3ItemCategory.MISC, skip = True), DS3ItemData("Forked Pale Tongue", 0x40000170, DS3ItemCategory.MISC, skip = True), DS3ItemData("Proof of a Concord Well Kept", 0x40000171, DS3ItemCategory.MISC, skip = True), - DS3ItemData("Prism Stone", 0x40000172, DS3ItemCategory.MISC, skip = True).counts([4, 6, 10]), + *DS3ItemData("Prism Stone", 0x40000172, DS3ItemCategory.MISC, skip = True).counts([4, 6, 10]), DS3ItemData("Binoculars", 0x40000173, DS3ItemCategory.MISC), DS3ItemData("Proof of a Concord Kept", 0x40000174, DS3ItemCategory.MISC, skip = True), # One is needed for Leonhard's quest, others are useful for restatting. @@ -1105,19 +1097,19 @@ def flatten(l): DS3ItemData("Soul of a Great Champion", 0x400001A4, DS3ItemCategory.SOUL, souls = 50000), DS3ItemData("Seed of a Giant Tree", 0x400001B8, DS3ItemCategory.UNIQUE, classification = ItemClassification.progression, inject = True), # Crow trade - DS3ItemData("Mossfruit", 0x400001C4, DS3ItemCategory.MISC, filler = True).counts([2]), + *DS3ItemData("Mossfruit", 0x400001C4, DS3ItemCategory.MISC, filler = True).counts([2]), DS3ItemData("Young White Branch", 0x400001C6, DS3ItemCategory.MISC), - DS3ItemData("Rusted Coin", 0x400001C7, DS3ItemCategory.MISC, filler = True).counts([2]), + *DS3ItemData("Rusted Coin", 0x400001C7, DS3ItemCategory.MISC, filler = True).counts([2]), DS3ItemData("Siegbräu", 0x400001C8, DS3ItemCategory.MISC, classification = ItemClassification.progression), # Crow trade - DS3ItemData("Rusted Gold Coin", 0x400001C9, DS3ItemCategory.MISC, filler = True).counts([2, 3]), - DS3ItemData("Blue Bug Pellet", 0x400001CA, DS3ItemCategory.MISC, filler = True).counts([2]), - DS3ItemData("Red Bug Pellet", 0x400001CB, DS3ItemCategory.MISC, filler = True).counts([2, 3]), - DS3ItemData("Yellow Bug Pellet", 0x400001CC, DS3ItemCategory.MISC, filler = True).counts([2, 3]), - DS3ItemData("Black Bug Pellet", 0x400001CD, DS3ItemCategory.MISC, filler = True).counts([2, 3]), + *DS3ItemData("Rusted Gold Coin", 0x400001C9, DS3ItemCategory.MISC, filler = True).counts([2, 3]), + *DS3ItemData("Blue Bug Pellet", 0x400001CA, DS3ItemCategory.MISC, filler = True).counts([2]), + *DS3ItemData("Red Bug Pellet", 0x400001CB, DS3ItemCategory.MISC, filler = True).counts([2, 3]), + *DS3ItemData("Yellow Bug Pellet", 0x400001CC, DS3ItemCategory.MISC, filler = True).counts([2, 3]), + *DS3ItemData("Black Bug Pellet", 0x400001CD, DS3ItemCategory.MISC, filler = True).counts([2, 3]), DS3ItemData("Young White Branch", 0x400001CF, DS3ItemCategory.MISC, skip = True), DS3ItemData("Dark Sigil", 0x400001EA, DS3ItemCategory.MISC, skip = True), - DS3ItemData("Ember", 0x400001F4, DS3ItemCategory.MISC, filler = True).counts([2]), + *DS3ItemData("Ember", 0x400001F4, DS3ItemCategory.MISC, filler = True).counts([2]), DS3ItemData("Hello Carving", 0x40000208, DS3ItemCategory.UNIQUE, skip = True), DS3ItemData("Thank you Carving", 0x40000209, DS3ItemCategory.UNIQUE, skip = True), DS3ItemData("Very good! Carving", 0x4000020A, DS3ItemCategory.UNIQUE, skip = True), @@ -1163,13 +1155,13 @@ def flatten(l): classification = ItemClassification.progression), DS3ItemData("Soul of a Stray Demon", 0x400002E7, DS3ItemCategory.BOSS, souls = 20000, classification = ItemClassification.progression), - DS3ItemData("Titanite Shard", 0x400003E8, DS3ItemCategory.UPGRADE).counts([2]), - DS3ItemData("Large Titanite Shard", 0x400003E9, DS3ItemCategory.UPGRADE).counts([2, 3]), - DS3ItemData("Titanite Chunk", 0x400003EA, DS3ItemCategory.UPGRADE).counts([2, 6]), + *DS3ItemData("Titanite Shard", 0x400003E8, DS3ItemCategory.UPGRADE).counts([2]), + *DS3ItemData("Large Titanite Shard", 0x400003E9, DS3ItemCategory.UPGRADE).counts([2, 3]), + *DS3ItemData("Titanite Chunk", 0x400003EA, DS3ItemCategory.UPGRADE).counts([2, 6]), DS3ItemData("Titanite Slab", 0x400003EB, DS3ItemCategory.UPGRADE, classification = ItemClassification.useful), - DS3ItemData("Titanite Scale", 0x400003FC, DS3ItemCategory.UPGRADE).counts([2, 3]), - DS3ItemData("Twinkling Titanite", 0x40000406, DS3ItemCategory.UPGRADE).counts([2, 3]), + *DS3ItemData("Titanite Scale", 0x400003FC, DS3ItemCategory.UPGRADE).counts([2, 3]), + *DS3ItemData("Twinkling Titanite", 0x40000406, DS3ItemCategory.UPGRADE).counts([2, 3]), DS3ItemData("Heavy Gem", 0x4000044C, DS3ItemCategory.UPGRADE), DS3ItemData("Sharp Gem", 0x40000456, DS3ItemCategory.UPGRADE), DS3ItemData("Refined Gem", 0x40000460, DS3ItemCategory.UPGRADE), @@ -1409,11 +1401,11 @@ def flatten(l): DS3ItemData("Blessed Weapon", 0x40395F80, DS3ItemCategory.SPELL), DS3ItemData("Deep Protection", 0x40398690, DS3ItemCategory.SPELL), DS3ItemData("Atonement", 0x4039ADA0, DS3ItemCategory.SPELL), -]) +] -_dlc_items = flatten([ +_dlc_items = [ # Ammunition - DS3ItemData("Millwood Greatarrow", 0x000623E0, DS3ItemCategory.MISC).counts([5]), + *DS3ItemData("Millwood Greatarrow", 0x000623E0, DS3ItemCategory.MISC).counts([5]), # Weapons DS3ItemData("Aquamarine Dagger", 0x00116520, DS3ItemCategory.WEAPON_UPGRADE_5), @@ -1567,7 +1559,7 @@ def flatten(l): DS3ItemData("Lightning Arrow", 0x40358B08, DS3ItemCategory.SPELL), DS3ItemData("Way of White Corona", 0x403642A0, DS3ItemCategory.SPELL), DS3ItemData("Projected Heal", 0x40364688, DS3ItemCategory.SPELL), -]) +] for item in _dlc_items: item.is_dlc = True From ac1d2ea90f747a068e97aa30547d847c5cd0b83d Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 10 Jun 2024 16:38:26 -0700 Subject: [PATCH 210/238] 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. --- worlds/AutoWorld.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/AutoWorld.py b/worlds/AutoWorld.py index 6e17f023f6fb..bed375cf080a 100644 --- a/worlds/AutoWorld.py +++ b/worlds/AutoWorld.py @@ -123,8 +123,8 @@ def __new__(mcs, name: str, bases: Tuple[type, ...], dct: Dict[str, Any]) -> Web assert group.options, "A custom defined Option Group must contain at least one Option." # catch incorrectly titled versions of the prebuilt groups so they don't create extra groups title_name = group.name.title() - if title_name in prebuilt_options: - group.name = title_name + assert title_name not in prebuilt_options or title_name == group.name, \ + f"Prebuilt group name \"{group.name}\" must be \"{title_name}\"" if group.name == "Item & Location Options": assert not any(option in item_and_loc_options for option in group.options), \ From d50f334cdcdab22917a0650b17b6bece78a0b215 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 10 Jun 2024 17:40:10 -0700 Subject: [PATCH 211/238] Style changes, rename exclude behavior options, remove guaranteed items option --- worlds/dark_souls_3/Options.py | 436 ++++++++---------- worlds/dark_souls_3/__init__.py | 8 +- worlds/dark_souls_3/docs/en_Dark Souls III.md | 3 + 3 files changed, 200 insertions(+), 247 deletions(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 25a4b525e237..4cc6e74ae483 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -4,142 +4,108 @@ import typing from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, ItemDict, NamedRange, Option, OptionGroup, \ - PerGameCommonOptions, Range, Removed, Toggle, VerifyKeys + PerGameCommonOptions, Range, Removed, Toggle, VerifyKeys, Visibility +## Game Options -class ExcludedLocationsOption(Choice): - """ - Which items can be placed in excluded locations in DS3. - - - Unnecessary: Excluded locations can't have progression items, but they can have useful items. - - Unimportant: Neither progression items nor useful items can be placed in excluded locations. - - Unrandomized: 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_unnecessary = 1 - option_unimportant = 2 - option_unrandomized = 3 - default = 2 - +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 MissableLocationsOption(Choice): - """ - Which items can be placed in locations that can be permanently missed. - - Unnecessary: Missable locations can't have progression items, but they can have useful items. - - Unimportant: Neither progression items nor useful items can be placed in missable locations. - - Unrandomized: Missable locations always contain the same item as in vanilla Dark Souls III. +class LateBasinOfVowsOption(Choice): + """Guarantee that you don't need to enter Lothric Castle until later in the run. - 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. + - 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 = "Missable Locations Behavior" - option_unnecessary = 1 - option_unimportant = 2 - option_unrandomized = 3 - default = 2 + 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 SmoothSoulItemsOption(DefaultOnToggle): - """ - Whether to distribute soul items in a similar order as the base game. +class LateDLCOption(Choice): + """Guarantee that you don't need to enter the DLC until later in the run. - 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. + - 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 = "Smooth Soul Items" + display_name = "Late DLC" + option_off = 0 + alias_false = 0 + option_after_small_doll = 1 + alias_true = 1 + option_after_basin = 2 -class SmoothUpgradeItemsOption(DefaultOnToggle): - """ - Whether to distribute upgrade items in a similar order as the base game. +class EnableDLCOption(Toggle): + """Include DLC locations, items, and enemies in the randomized pools. - 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. + To use this option, you must own both the "Ashes of Ariandel" and the "Ringed City" DLCs. """ - display_name = "Smooth Upgrade Items" + display_name = "Enable DLC" -class SmoothUpgradedWeaponsOption(DefaultOnToggle): - """ - Whether to distribute upgraded weapons in a similar order as the base game. +class EnableNGPOption(Toggle): + """Include items and locations exclusive to NG+ cycles.""" + display_name = "Enable NG+" - 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" +## Equipment class RandomizeStartingLoadout(DefaultOnToggle): - """ - Randomizes the equipment characters begin with. - """ + """Randomizes the equipment characters begin with.""" display_name = "Randomize Starting Loadout" class RequireOneHandedStartingWeapons(DefaultOnToggle): - """ - Require starting equipment to be usable one-handed. - """ + """Require starting equipment to be usable one-handed.""" display_name = "Require One-Handed Starting Weapons" -class GuaranteedItemsOption(ItemDict): - """ - Guarantees that the specified items will be in the item pool. - """ - display_name = "Guaranteed Items" - - class AutoEquipOption(Toggle): - """ - Automatically equips any received armor or left/right weapons. - """ + """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. - """ + """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. - """ + """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. - """ + """Disable the spell requirements permitting you to use any spell.""" display_name = "No Spell Requirements" -class NoEquipLoadOption(Toggle): - """ - Disable the equip load constraint from the game. - """ - display_name = "No Equip Load" - +## Weapons class RandomizeInfusionOption(Toggle): - """ - Enable this option to infuse a percentage of the pool of weapons and shields. - """ + """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. - """ + """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 @@ -149,8 +115,7 @@ class RandomizeInfusionPercentageOption(NamedRange): 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. + """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 @@ -164,9 +129,7 @@ class RandomizeWeaponLevelOption(Choice): class RandomizeWeaponLevelPercentageOption(Range): - """ - The percentage of weapons in the pool to be upgraded if randomize weapons level is toggled. - """ + """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 @@ -174,9 +137,7 @@ class RandomizeWeaponLevelPercentageOption(Range): class MinLevelsIn5WeaponPoolOption(Range): - """ - The minimum upgraded value of a weapon in the pool of weapons that can only reach +5. - """ + """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 @@ -184,9 +145,7 @@ class MinLevelsIn5WeaponPoolOption(Range): class MaxLevelsIn5WeaponPoolOption(Range): - """ - The maximum upgraded value of a weapon in the pool of weapons that can only reach +5. - """ + """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 @@ -194,9 +153,7 @@ class MaxLevelsIn5WeaponPoolOption(Range): class MinLevelsIn10WeaponPoolOption(Range): - """ - The minimum upgraded value of a weapon in the pool of weapons that can reach +10. - """ + """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 @@ -204,116 +161,70 @@ class MinLevelsIn10WeaponPoolOption(Range): class MaxLevelsIn10WeaponPoolOption(Range): - """ - The maximum upgraded value of a weapon in the pool of weapons that can reach +10. - """ + """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 -class EarlySmallLothricBanner(Choice): - """ - This option makes it so the user can choose to force the Small Lothric Banner into an early sphere in their world or into an early sphere across all worlds. - """ - display_name = "Early Small Lothric Banner" - option_off = 0 - option_early_global = 1 - option_early_local = 2 - default = option_off +## Item Smoothing +class SmoothSoulItemsOption(DefaultOnToggle): + """Distribute soul items in a similar order as the base game. -class LateBasinOfVowsOption(Choice): + 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. """ - This option makes it so the Basin of Vows is still randomized, but you can choose the requirements to venture into Lothric Castle. + display_name = "Smooth Soul Items" - - Off: You may have to enter Lothric Castle and the areas beyond it before finding your Small Lothric Banner. - - After Small Lothric Banner: You are guaranteed to find your Small Lothric Banner before needing to enter Lothric Castle. - - After Small Doll: You are guaranteed to find your Small Lothric Banner and your Small Doll before needing to enter Lothric Castle. - """ - 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 SmoothUpgradeItemsOption(DefaultOnToggle): + """Distribute upgrade items in a similar order as the base game. -class LateDLCOption(Choice): + 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. """ - This option makes it so the Small Doll is still randomized, but you can choose the requirements to venture into Painted World of Ariandel. + display_name = "Smooth Upgrade Items" - - Off: You may have to enter Ariandel and the areas beyond it before finding your Small Doll. - - After Small Doll: You are guaranteed to find your Small Doll before needing to enter Ariandel. - - After Basin: You are guaranteed to find your Small Doll and your Basin of Vows before needing to enter Ariandel. - """ - display_name = "Late DLC" - option_off = 0 - alias_false = 0 - option_after_small_doll = 1 - alias_true = 1 - option_after_basin = 2 +class SmoothUpgradedWeaponsOption(DefaultOnToggle): + """Distribute upgraded weapons in a similar order as the base game. -class EnableDLCOption(Toggle): - """ - To use this option, you must own both the ASHES OF ARIANDEL and the RINGED CITY DLC. + 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 = "Enable DLC" + display_name = "Smooth Upgraded Weapons" -class EnableNGPOption(Toggle): - """ - Whether to include items and locations exclusive to NG+ cycles. - """ - display_name = "Enable NG+" - +### Enemies class RandomizeEnemiesOption(DefaultOnToggle): - """ - Whether to randomize enemy and boss placements. - - If this is enabled, the Storm Ruler sword is granted immediately upon meeting Yhorm the Giant instead of being randomized into the world. - """ + """Randomize enemy and boss placements.""" display_name = "Randomize Enemies" -class RandomEnemyPresetOption(Option[typing.Dict[str, typing.Any]], VerifyKeys): - """ - The YAML preset for the static enemy randomizer. +class SimpleEarlyBossesOption(DefaultOnToggle): + """Avoid replacing Iudex Gundyr and Vordt with late bosses. - See the static randomizer documentation in randomizer\\presets\\README.txt for details. + 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 = "Random Enemy Preset" - supports_weighting = False - default = {} + display_name = "Simple Early Bosses" - valid_keys = ["Description", "RecommendFullRandomization", "RecommendNoEnemyProgression", - "OopsAll", "Boss", "Miniboss", "Basic", "BuffBasicEnemiesAsBosses", - "DontRandomize", "RemoveSource", "Enemies"] - def __init__(self, value: typing.Dict[str, typing.Any]): - self.value = deepcopy(value) +class ScaleEnemiesOption(DefaultOnToggle): + """Scale randomized enemy stats to match the areas in which they appear. - def get_option_name(self, value: typing.Dict[str, typing.Any]): - return json.dumps(value) + Disabling this will tend to make the early game much more difficult and the late game much easier. - @classmethod - def from_any(cls, data: typing.Dict[str, typing.Any]) -> "RandomEnemyPresetOption": - if isinstance(data, dict): - cls.verify_keys(data) - return cls(data) - else: - raise NotImplementedError(f"Must be a dictionary, got {type(data)}") + This is ignored unless enemies are randomized. + """ + display_name = "Scale Enemies" class RandomizeMimicsWithEnemiesOption(Toggle): - """ - Whether to mix Mimics into the main enemy pool. + """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. + 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. """ @@ -321,11 +232,9 @@ class RandomizeMimicsWithEnemiesOption(Toggle): class RandomizeSmallCrystalLizardsWithEnemiesOption(Toggle): - """ - Whether to mix small Crystal Lizards into the main enemy pool. + """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. + 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. """ @@ -333,80 +242,120 @@ class RandomizeSmallCrystalLizardsWithEnemiesOption(Toggle): class ReduceHarmlessEnemiesOption(Toggle): - """ - Whether to reduce the frequency that "harmless" enemies appear. + """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. + 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 SimpleEarlyBossesOption(DefaultOnToggle): - """ - Whether to avoid replacing Iudex Gundyr and Vordt with late bosses. +class AllChestsAreMimicsOption(Toggle): + """Replace all chests with mimics that drop the same items. - 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. + 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 = "Simple Early Bosses" - + display_name = "All Chests Are Mimics" -class ScaleEnemiesOption(DefaultOnToggle): - """ - Whether to 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. +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 = "Scale Enemies" + display_name = "Impatient Mimics" -class AllChestsAreMimicsOption(Toggle): +class RandomEnemyPresetOption(Option[typing.Dict[str, typing.Any]], VerifyKeys): + """The YAML preset for the static enemy randomizer. + + See the static randomizer documentation in randomizer\\presets\\README.txt for details. """ - Whether to replace all chests with mimics that drop the same items. + display_name = "Random Enemy Preset" + supports_weighting = False + default = {} - If "Randomize Mimics With Enemies" is set, these chests will instead be replaced with random enemies that drop the same items. + valid_keys = ["Description", "RecommendFullRandomization", "RecommendNoEnemyProgression", + "OopsAll", "Boss", "Miniboss", "Basic", "BuffBasicEnemiesAsBosses", + "DontRandomize", "RemoveSource", "Enemies"] - This is ignored unless enemies are randomized. - """ - display_name = "All Chests Are Mimics" + def __init__(self, value: typing.Dict[str, typing.Any]): + self.value = deepcopy(value) + def get_option_name(self, value: typing.Dict[str, typing.Any]): + return json.dumps(value) -class ImpatientMimicsOption(Toggle): - """ - Whether mimics should attack as soon as you get close. + @classmethod + def from_any(cls, data: typing.Dict[str, typing.Any]) -> "RandomEnemyPresetOption": + if isinstance(data, dict): + cls.verify_keys(data) + return cls(data) + else: + raise NotImplementedError(f"Must be a dictionary, got {type(data)}") - This is ignored unless enemies are randomized. - """ - display_name = "Impatient Mimics" +## Item & Location class DS3ExcludeLocations(ExcludeLocations): + """Prevent these locations from having an important item.""" + default = {"Hidden", "Small Crystal Lizards", "Upgrade", "Small Souls", "Miscellaneous"} + + +class ExcludedLocationBehaviorOption(Choice): + """Which items can be placed in excluded locations in DS3. + + - Unnecessary: Excluded locations can't have progression items, but they can have useful items. + - Unimportant: Neither progression items nor useful items can be placed in excluded locations. + - Unrandomized: 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. """ - Forces these locations to have certain types of items, exact behavior depends on the "Excluded Locations Behavior" option. + display_name = "Excluded Locations Behavior" + option_unnecessary = 1 + option_unimportant = 2 + option_unrandomized = 3 + default = 2 + + +class MissableLocationBehaviorOption(Choice): + """Which items can be placed in locations that can be permanently missed. + + - Unnecessary: Missable locations can't have progression items, but they can have useful items. + - Unimportant: Neither progression items nor useful items can be placed in missable locations. + - Unrandomized: 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. """ - default = {"Hidden", "Small Crystal Lizards", "Upgrade", "Small Souls", "Miscellaneous"} + display_name = "Missable Locations Behavior" + option_unnecessary = 1 + option_unimportant = 2 + option_unrandomized = 3 + default = 2 @dataclass class DarkSouls3Options(PerGameCommonOptions): - excluded_locations: ExcludedLocationsOption - missable_locations: MissableLocationsOption - smooth_soul_items: SmoothSoulItemsOption - smooth_upgrade_items: SmoothUpgradeItemsOption - smooth_upgraded_weapons: SmoothUpgradedWeaponsOption + # 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 - guaranteed_items: GuaranteedItemsOption 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 @@ -415,24 +364,27 @@ class DarkSouls3Options(PerGameCommonOptions): max_levels_in_5: MaxLevelsIn5WeaponPoolOption min_levels_in_10: MinLevelsIn10WeaponPoolOption max_levels_in_10: MaxLevelsIn10WeaponPoolOption - early_banner: EarlySmallLothricBanner - late_basin_of_vows: LateBasinOfVowsOption - late_dlc: LateDLCOption - no_spell_requirements: NoSpellRequirementsOption - no_equip_load: NoEquipLoadOption - death_link: DeathLink - enable_dlc: EnableDLCOption - enable_ngp: EnableNGPOption + + # Item Smoothing + smooth_soul_items: SmoothSoulItemsOption + smooth_upgrade_items: SmoothUpgradeItemsOption + smooth_upgraded_weapons: SmoothUpgradedWeaponsOption + + # Enemies randomize_enemies: RandomizeEnemiesOption - random_enemy_preset: RandomEnemyPresetOption + simple_early_bosses: SimpleEarlyBossesOption + scale_enemies: ScaleEnemiesOption randomize_mimics_with_enemies: RandomizeMimicsWithEnemiesOption randomize_small_crystal_lizards_with_enemies: RandomizeSmallCrystalLizardsWithEnemiesOption reduce_harmless_enemies: ReduceHarmlessEnemiesOption - simple_early_bosses: SimpleEarlyBossesOption - scale_enemies: ScaleEnemiesOption 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 @@ -447,10 +399,13 @@ class DarkSouls3Options(PerGameCommonOptions): 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 Options", [ + OptionGroup("Equipment", [ RandomizeStartingLoadout, RequireOneHandedStartingWeapons, AutoEquipOption, @@ -459,12 +414,7 @@ class DarkSouls3Options(PerGameCommonOptions): NoWeaponRequirementsOption, NoSpellRequirementsOption, ]), - OptionGroup("Item Smoothing Options", [ - SmoothSoulItemsOption, - SmoothUpgradeItemsOption, - SmoothUpgradedWeaponsOption, - ]), - OptionGroup("Weapon Infusion and Level Options", [ + OptionGroup("Weapons", [ RandomizeInfusionOption, RandomizeInfusionPercentageOption, RandomizeWeaponLevelOption, @@ -474,9 +424,13 @@ class DarkSouls3Options(PerGameCommonOptions): MinLevelsIn10WeaponPoolOption, MaxLevelsIn10WeaponPoolOption, ]), - OptionGroup("Enemy Randomizer Options", [ + OptionGroup("Item Smoothing", [ + SmoothSoulItemsOption, + SmoothUpgradeItemsOption, + SmoothUpgradedWeaponsOption, + ]), + OptionGroup("Enemies", [ RandomizeEnemiesOption, - RandomEnemyPresetOption, SimpleEarlyBossesOption, ScaleEnemiesOption, RandomizeMimicsWithEnemiesOption, @@ -484,11 +438,11 @@ class DarkSouls3Options(PerGameCommonOptions): ReduceHarmlessEnemiesOption, AllChestsAreMimicsOption, ImpatientMimicsOption, + RandomEnemyPresetOption, ]), - OptionGroup("Item & Location Behavior Options", [ - ExcludedLocationsOption, + OptionGroup("Item & Location Options", [ DS3ExcludeLocations, - MissableLocationsOption, - GuaranteedItemsOption, + ExcludedLocationBehaviorOption, + MissableLocationBehaviorOption, ]) ] diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 8115480af9c2..0f30b50541a8 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -63,8 +63,8 @@ class DarkSouls3World(World): } location_name_groups = location_name_groups item_name_groups = item_name_groups - # location_descriptions = location_descriptions - # item_descriptions = item_descriptions + location_descriptions = location_descriptions + item_descriptions = item_descriptions yhorm_location: Optional[DS3BossInfo] """If enemy randomization is enabled, this is the boss who Yhorm the Giant should replace. @@ -332,10 +332,6 @@ def _create_injectable_items(self, num_required_extra_items: int) -> List[Item]: injectable_mandatory = [ item for item in all_injectable_items if item.classification == ItemClassification.progression - ] + [ - item - for (item, count) in self.options.guaranteed_items.items() - for _ in range(0, count) ] injectable_optional = [ item for item in all_injectable_items diff --git a/worlds/dark_souls_3/docs/en_Dark Souls III.md b/worlds/dark_souls_3/docs/en_Dark Souls III.md index 5b406223cbc7..06227226aafe 100644 --- a/worlds/dark_souls_3/docs/en_Dark Souls III.md +++ b/worlds/dark_souls_3/docs/en_Dark Souls III.md @@ -192,6 +192,9 @@ The following options have been removed: excluded locations, you can set `excluded_locations: unrandomized` to preserve the default vanilla item placements for all excluded locations. +* `guaranteed_items`: In almost all cases, all items from the base game are now + included somewhere in the multiworld. + In addition, the following options have changed: * The location names used in options like `exclude_locations` have changed. See From 67f1335fc184a03d9d8f6f50d20970f63eefb09b Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 11 Jun 2024 01:11:19 -0400 Subject: [PATCH 212/238] Spacing/Formatting (#18) --- worlds/dark_souls_3/__init__.py | 50 ++++++++------------------------- 1 file changed, 11 insertions(+), 39 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 0f30b50541a8..10d1f1fb9f7b 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -106,12 +106,11 @@ def generate_early(self): not self.options.late_basin_of_vows ) ): - self.multiworld.early_items[self.player]['Storm Ruler'] = 1 - self.options.local_items.value.add('Storm Ruler') + self.multiworld.early_items[self.player]["Storm Ruler"] = 1 + self.options.local_items.value.add("Storm Ruler") else: self.yhorm_location = default_yhorm_location - def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: """Returns whether boss is a valid location for Yhorm in this seed.""" @@ -141,7 +140,6 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: for location in location_tables["Cemetery of Ash"] ) - def create_regions(self): # Create Vanilla Regions regions: Dict[str, Region] = {"Menu": self.create_region("Menu", {})} @@ -228,7 +226,6 @@ def create_connection(from_region: str, to_region: str): create_connection("Painted World of Ariandel (After Contraption)", "Dreg Heap") create_connection("Dreg Heap", "Ringed City") - # For each region, add the associated locations retrieved from the corresponding location_table def create_region(self, region_name, location_table) -> Region: new_region = Region(region_name, self.player, self.multiworld) @@ -277,7 +274,6 @@ def create_region(self, region_name, location_table) -> Region: self.multiworld.regions.append(new_region) return new_region - def create_items(self): # Just used to efficiently deduplicate items item_set: Set[str] = set() @@ -315,7 +311,6 @@ def create_items(self): self._fill_local_items() - def _create_injectable_items(self, num_required_extra_items: int) -> List[Item]: """Returns a list of items to inject into the multiworld instead of skipped items. @@ -365,7 +360,6 @@ def _create_injectable_items(self, num_required_extra_items: int) -> List[Item]: return [self.create_item(item) for item in items] - def create_item(self, item: Union[str, DS3ItemData]) -> Item: data = item if isinstance(item, DS3ItemData) else item_dictionary[item] classification = None @@ -407,7 +401,6 @@ def create_item(self, item: Union[str, DS3ItemData]) -> Item: return DarkSouls3Item(self.player, data, classification=classification) - def _fill_local_items(self) -> None: """Removes certain items from the item pool and manually places them in the local world. @@ -416,7 +409,7 @@ def _fill_local_items(self) -> None: # If Yhorm is at Iudex Gundyr, Storm Ruler must be randomized, so it can always be moved. # Fill this manually so that, if very few slots are available in Cemetery of Ash, this # doesn't get locked out by bad rolls on the next two fills. - if self.yhorm_location.name == 'Iudex Gundyr': + if self.yhorm_location.name == "Iudex Gundyr": self._fill_local_item("Storm Ruler", ["Cemetery of Ash"], lambda location: location.name != "CA: Coiled Sword - boss drop") @@ -438,7 +431,6 @@ def _fill_local_items(self) -> None: "High Wall of Lothric" ]) - def _fill_local_item( self, name: str, regions: List[str], @@ -497,11 +489,9 @@ def _replace_with_filler(self, location: DarkSouls3Location) -> None: location.item = candidate return - def get_filler_item_name(self) -> str: return self.random.choice(filler_item_names) - def set_rules(self) -> None: randomized_items = {item.name for item in self.local_itempool} @@ -574,7 +564,7 @@ def set_rules(self) -> None: and self._has_any_scroll(state) )) - if self.options.late_basin_of_vows > 1: # After Small Doll + if self.options.late_basin_of_vows > 1: # After Small Doll self._add_entrance_rule("Lothric Castle", "Small Doll") # DLC Access Rules Below @@ -595,7 +585,7 @@ def set_rules(self) -> None: "Painted World of Ariandel (Before Contraption)", lambda state: state.has("Small Doll", self.player) and self._has_any_scroll(state)) - if self.options.late_dlc > 1: # After Basin + if self.options.late_dlc > 1: # After Basin self._add_entrance_rule("Painted World of Ariandel (Before Contraption)", "Basin of Vows") # Define the access rules to some specific locations @@ -643,7 +633,7 @@ def set_rules(self) -> None: and self._has_any_scroll(state) )) - if self.options.late_basin_of_vows > 1: # After Small Doll + if self.options.late_basin_of_vows > 1: # After Small Doll self._add_location_rule("HWL: Soul of the Dancer", "Small Doll") self._add_location_rule([ @@ -721,7 +711,6 @@ def set_rules(self) -> None: state.has("Cinders of a Lord - Aldrich", self.player) and \ state.has("Cinders of a Lord - Lothric Prince", self.player) - def _add_shop_rules(self) -> None: """Adds rules for items unlocked in shops.""" @@ -804,7 +793,6 @@ def _add_shop_rules(self) -> None: self._add_location_rule( [f"FS: {item} - {shop} for {key_name}" for item in items], key) - def _add_npc_rules(self) -> None: """Adds rules for items accessible via NPC quests. @@ -1102,7 +1090,6 @@ def _add_npc_rules(self) -> None: self._can_get(state, "AL: Soul of Aldrich") )) - def _add_transposition_rules(self) -> None: """Adds rules for items obtainable from Ludleth by soul transposition.""" @@ -1166,7 +1153,6 @@ def _add_transposition_rules(self) -> None: state.has(s, self.player) and state.has("Transposing Kiln", self.player) )) - def _add_crow_rules(self) -> None: """Adds rules for items obtainable by trading items to the crow on Firelink roof.""" @@ -1199,7 +1185,6 @@ def _add_crow_rules(self) -> None: and not item.data.is_upgraded )) - def _add_unnecessary_location_rules(self) -> None: """Adds rules for locations that can contain useful but not necessary items. @@ -1230,27 +1215,25 @@ def _add_unnecessary_location_rules(self) -> None: if self.options.excluded_locations == "unnecessary": self.options.exclude_locations.value.clear() - def _add_early_item_rules(self, randomized_items: Set[str]) -> None: """Adds rules to make sure specific items are available early.""" - if 'Pyromancy Flame' in randomized_items: + if "Pyromancy Flame" in randomized_items: # Make this available early because so many items are useless without it. self._add_entrance_rule("Road of Sacrifices", "Pyromancy Flame") self._add_entrance_rule("Consumed King's Garden", "Pyromancy Flame") self._add_entrance_rule("Grand Archives", "Pyromancy Flame") - if 'Transposing Kiln' in randomized_items: + if "Transposing Kiln" in randomized_items: # Make this available early so players can make use of their boss souls. self._add_entrance_rule("Road of Sacrifices", "Transposing Kiln") self._add_entrance_rule("Consumed King's Garden", "Transposing Kiln") self._add_entrance_rule("Grand Archives", "Transposing Kiln") # Make this available pretty early - if 'Small Lothric Banner' in randomized_items: + if "Small Lothric Banner" in randomized_items: if self.options.early_banner == "early_global": - self.multiworld.early_items[self.player]['Small Lothric Banner'] = 1 + self.multiworld.early_items[self.player]["Small Lothric Banner"] = 1 elif self.options.early_banner == "early_local": - self.multiworld.local_early_items[self.player]['Small Lothric Banner'] = 1 - + self.multiworld.local_early_items[self.player]["Small Lothric Banner"] = 1 def _has_any_scroll(self, state: CollectionState) -> bool: """Returns whether the given state has any scroll item.""" @@ -1261,7 +1244,6 @@ def _has_any_scroll(self, state: CollectionState) -> bool: or state.has("Crystal Scroll", self.player) ) - def _add_location_rule(self, location: Union[str, List[str]], rule: Union[CollectionRule, str]) -> None: """Sets a rule for the given location if it that location is randomized. @@ -1279,7 +1261,6 @@ def _add_location_rule(self, location: Union[str, List[str]], rule: Union[Collec rule = lambda state, item=rule: state.has(item, self.player) add_rule(self.multiworld.get_location(location, self.player), rule) - def _add_entrance_rule(self, region: str, rule: Union[CollectionRule, str]) -> None: """Sets a rule for the entrance to the given region.""" assert region in location_tables @@ -1290,23 +1271,19 @@ def _add_entrance_rule(self, region: str, rule: Union[CollectionRule, str]) -> N rule = lambda state, item=rule: state.has(item, self.player) add_rule(self.multiworld.get_entrance("Go To " + region, self.player), rule) - def _add_item_rule(self, location: str, rule: ItemRule) -> None: """Sets a rule for what items are allowed in a given location.""" if not self._is_location_available(location): return add_item_rule(self.multiworld.get_location(location, self.player), rule) - def _can_go_to(self, state, region) -> None: """Returns whether state can access the given region name.""" return state.can_reach(f"Go To {region}", "Entrance", self.player) - def _can_get(self, state, location) -> None: """Returns whether state can access the given location name.""" return state.can_reach(location, "Location", self.player) - def _is_location_available( self, location: Union[str, DS3LocationData, DarkSouls3Location] @@ -1333,14 +1310,12 @@ def _is_location_available( ) ) - def write_spoiler(self, spoiler_handle: TextIO) -> None: if self.yhorm_location != default_yhorm_location: spoiler_handle.write( f"Yhorm takes the place of {self.yhorm_location.name} in " + f"{self.multiworld.get_player_name(self.player)}'s world\n") - def post_fill(self): """If item smoothing is enabled, rearrange items so they scale up smoothly through the run. @@ -1455,14 +1430,12 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: upgraded_weapons.sort(key=lambda item: item.level) smooth_items(upgraded_weapons) - def _shuffle(self, seq: Sequence) -> List: """Returns a shuffled copy of a sequence.""" copy = list(seq) self.random.shuffle(copy) return copy - def _pop_item( self, location: Location, @@ -1481,7 +1454,6 @@ def _pop_item( # If we can't find a suitable item, give up and assign an unsuitable one. return items.pop(0) - def fill_slot_data(self) -> Dict[str, object]: slot_data: Dict[str, object] = {} From d506136f999b3e6989584fdc1fa5330c758aaa25 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 11 Jun 2024 01:21:38 -0400 Subject: [PATCH 213/238] Various Fixes (#19) --- worlds/dark_souls_3/Locations.py | 2 +- worlds/dark_souls_3/__init__.py | 57 ++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 2c4a44c46489..4db589aeb02e 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1752,7 +1752,7 @@ def __init__( DS3LocationData("PC: Shriving Stone - swamp, by chapel door", "Shriving Stone"), DS3LocationData("PC: Poison Arrow - chapel roof", "Poison Arrow x18"), DS3LocationData("PC: Rubbish - chapel, down stairs from second floor", "Rubbish"), - DS3LocationData("PC: Monolayers Greatarrow - bridge", "Onislayer Greatarrow x8"), + DS3LocationData("PC: Onislayer Greatarrow - bridge", "Onislayer Greatarrow x8"), DS3LocationData("PC: Large Soul of a Weary Warrior - bridge, far end", "Large Soul of a Weary Warrior"), DS3LocationData("PC: Rusted Coin - below bridge #1", "Rusted Coin"), diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 10d1f1fb9f7b..feef2bab17e1 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -240,15 +240,26 @@ def create_region(self, region_name, location_table) -> Region: if ( location.missable and self.options.missable_locations == "unimportant" ) or ( - # Mark Red Eye Orb as missable if Lift Chamber Key isn't randomized, because - # the latter is missable by default. + # Lift Chamber Key is missable. Exclude Lift-Chamber-Key-Locked locations if it isn't randomized not self._is_location_available("FS: Lift Chamber Key - Leonhard") and location.name == "HWL: Red Eye Orb - wall tower, miniboss" + ) or ( + # Chameleon is missable. Exclude Chameleon-locked locations if it isn't randomized + not self._is_location_available("AL: Chameleon - tomb after marrying Anri") + and location.name in {"RC: Dragonhead Shield - streets monument, across bridge", + "RC: Large Soul of a Crestfallen Knight - streets monument, across bridge", + "RC: Divine Blessing - streets monument, mob drop", "RC: Lapp's Helm - Lapp", + "RC: Lapp's Armor - Lapp", + "RC: Lapp's Gauntlets - Lapp", + "RC: Lapp's Leggings - Lapp"} ): new_location.progress_type = LocationProgressType.EXCLUDED else: - # Don't allow Siegward's Storm Ruler to mark Yhorm as defeatable. - if location.name == "PC: Storm Ruler - Siegward": continue + # Don't allow missable duplicates of progression items to be expected progression. + if location.name in {"PC: Storm Ruler - Siegward", + "US: Pyromancy Flame - Cornyx", + "US: Tower Key - kill Irina"}: + continue # Replace non-randomized items with events that give the default item event_item = ( @@ -264,10 +275,9 @@ def create_region(self, region_name, location_table) -> Region: ) event_item.code = None new_location.place_locked_item(event_item) - if location.name in excluded: excluded.remove(location.name) - - if region_name == "Menu": - add_item_rule(new_location, lambda item: not item.advancement) + if location.name in excluded: + excluded.remove(location.name) + self.all_excluded_locations.remove(location.name) new_region.locations.append(new_location) @@ -354,7 +364,7 @@ def _create_injectable_items(self, num_required_extra_items: int) -> List[Item]: self.multiworld.push_precollected(self.create_item(item)) warning( f"Couldn't add \"{item.name}\" to the item pool for " + - f"{self.multiworld.get_player_name(self.player)}. Adding it to the starting " + + f"{self.player_name}. Adding it to the starting " + f"inventory instead." ) @@ -466,7 +476,7 @@ def _fill_local_item( self.local_itempool.remove(item) if not candidate_locations: - warning(f"Couldn't place \"{name}\" in a valid location for {self.multiworld.get_player_name(self.player)}. Adding it to starting inventory instead.") + warning(f"Couldn't place \"{name}\" in a valid location for {self.player_name}. Adding it to starting inventory instead.") location = next( (location for location in self.multiworld.get_locations() if location.item == item), None @@ -705,11 +715,7 @@ def set_rules(self) -> None: for location in self.yhorm_location.locations: self._add_location_rule(location, "Storm Ruler") - self.multiworld.completion_condition[self.player] = lambda state: \ - state.has("Cinders of a Lord - Abyss Watcher", self.player) and \ - state.has("Cinders of a Lord - Yhorm the Giant", self.player) and \ - state.has("Cinders of a Lord - Aldrich", self.player) and \ - state.has("Cinders of a Lord - Lothric Prince", self.player) + self.multiworld.completion_condition[self.player] = lambda state: self._can_get(state, "KFF: Soul of the Lords") def _add_shop_rules(self) -> None: """Adds rules for items unlocked in shops.""" @@ -1252,8 +1258,8 @@ def _add_location_rule(self, location: Union[str, List[str]], rule: Union[Collec locations = location if type(location) is list else [location] for location in locations: data = location_dictionary[location] - if data.dlc and not self.options.enable_dlc: return False - if data.ngp and not self.options.enable_ngp: return False + if data.dlc and not self.options.enable_dlc: return + if data.ngp and not self.options.enable_ngp: return if not self._is_location_available(location): return if isinstance(rule, str): @@ -1278,11 +1284,11 @@ def _add_item_rule(self, location: str, rule: ItemRule) -> None: def _can_go_to(self, state, region) -> None: """Returns whether state can access the given region name.""" - return state.can_reach(f"Go To {region}", "Entrance", self.player) + return state.can_reach_entrance(f"Go To {region}", self.player) def _can_get(self, state, location) -> None: """Returns whether state can access the given location name.""" - return state.can_reach(location, "Location", self.player) + return state.can_reach_location(location, self.player) def _is_location_available( self, @@ -1311,10 +1317,17 @@ def _is_location_available( ) def write_spoiler(self, spoiler_handle: TextIO) -> None: + text = "" + if self.yhorm_location != default_yhorm_location: - spoiler_handle.write( - f"Yhorm takes the place of {self.yhorm_location.name} in " + - f"{self.multiworld.get_player_name(self.player)}'s world\n") + text += f"\nYhorm takes the place of {self.yhorm_location.name} in {self.player_name}'s world\n" + + if self.options.excluded_locations == "unnecessary": + text += f"\n{self.player_name}'s world excluded: {sorted(self.all_excluded_locations)}\n" + + if text: + text = "\n" + text + "\n" + spoiler_handle.write(text) def post_fill(self): """If item smoothing is enabled, rearrange items so they scale up smoothly through the run. From 9e7cd1f7ebe8f4d69b8bcea7ba3d38768920f5ac Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 11 Jun 2024 01:24:07 -0400 Subject: [PATCH 214/238] Universally Track Yhorm (#20) --- worlds/dark_souls_3/__init__.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index feef2bab17e1..0d33d1734158 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -3,7 +3,7 @@ from collections import defaultdict import json from logging import warning -from typing import Callable, Dict, Set, List, Optional, TextIO, Union +from typing import Any, Callable, Dict, Set, List, Optional, TextIO, Union from BaseClasses import CollectionState, MultiWorld, Region, Item, Location, LocationProgressType, Entrance, Tutorial, ItemClassification @@ -93,8 +93,19 @@ def __init__(self, multiworld: MultiWorld, player: int): def generate_early(self): self.all_excluded_locations.update(self.options.exclude_locations.value) + # Inform Universal Tracker where Yhorm is being randomized to. + if hasattr(self.multiworld, "re_gen_passthrough"): + if "Dark Souls III" in self.multiworld.re_gen_passthrough: + if self.multiworld.re_gen_passthrough["Dark Souls III"]["options"]["randomize_enemies"]: + yhorm_data = self.multiworld.re_gen_passthrough["Dark Souls III"]["yhorm"] + for boss in all_bosses: + if yhorm_data.startswith(boss.name): + self.yhorm_location = boss + else: + self.yhorm_location = default_yhorm_location + # Randomize Yhorm manually so that we know where to place the Storm Ruler. - if self.options.randomize_enemies: + elif self.options.randomize_enemies: self.yhorm_location = self.random.choice( [boss for boss in all_bosses if self._allow_boss_for_yhorm(boss)]) @@ -1530,3 +1541,7 @@ def fill_slot_data(self) -> Dict[str, object]: } return slot_data + + @staticmethod + def interpret_slot_data(slot_data: Dict[str, Any]) -> Dict[str, Any]: + return slot_data From 0e07c378f165412fba2a37bc36bfc1770b33f1ae Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 18 Jun 2024 20:39:41 -0400 Subject: [PATCH 215/238] Account for excluded and missable --- worlds/dark_souls_3/__init__.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 0d33d1734158..503e2c7be635 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -146,7 +146,7 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: # allow Yhorm as Iudex Gundyr if there's at least one available location. return any( self._is_location_available(location) - and location.name not in self.options.exclude_locations.value + and location.name not in self.all_excluded_locations and location.name != "CA: Coiled Sword - boss drop" for location in location_tables["Cemetery of Ash"] ) @@ -249,7 +249,13 @@ def create_region(self, region_name, location_table) -> Region: if self._is_location_available(location): new_location = DarkSouls3Location(self.player, location, new_region) if ( + # Exclude missable, unimportant locations location.missable and self.options.missable_locations == "unimportant" + and not ( + # Unless they are excluded to a higher degree already + location.name in self.all_excluded_locations + and self.options.missable_locations < self.options.excluded_locations + ) ) or ( # Lift Chamber Key is missable. Exclude Lift-Chamber-Key-Locked locations if it isn't randomized not self._is_location_available("FS: Lift Chamber Key - Leonhard") @@ -1211,7 +1217,7 @@ def _add_unnecessary_location_rules(self) -> None: """ unnecessary_locations = ( - self.options.exclude_locations.value + self.options.all_excluded_locations if self.options.excluded_locations == "unnecessary" else set() ).union( @@ -1219,6 +1225,10 @@ def _add_unnecessary_location_rules(self) -> None: location.name for location in self.multiworld.get_locations() if location.player == self.player and location.data.missable + and not ( + location.name in self.all_excluded_locations + and self.options.missable_locations < self.options.excluded_locations + ) } if self.options.missable_locations == "unnecessary" else set() From 8c3ca6949a8419d997558bcfe3bfea09c8b321c0 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 18 Jun 2024 20:46:42 -0400 Subject: [PATCH 216/238] These are behaviors now --- worlds/dark_souls_3/__init__.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 503e2c7be635..9b4b5f494beb 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -250,11 +250,11 @@ def create_region(self, region_name, location_table) -> Region: new_location = DarkSouls3Location(self.player, location, new_region) if ( # Exclude missable, unimportant locations - location.missable and self.options.missable_locations == "unimportant" + location.missable and self.options.missable_locations_behavior == "unimportant" and not ( # Unless they are excluded to a higher degree already location.name in self.all_excluded_locations - and self.options.missable_locations < self.options.excluded_locations + and self.options.missable_locations_behavior < self.options.excluded_locations_behavior ) ) or ( # Lift Chamber Key is missable. Exclude Lift-Chamber-Key-Locked locations if it isn't randomized @@ -1218,7 +1218,7 @@ def _add_unnecessary_location_rules(self) -> None: unnecessary_locations = ( self.options.all_excluded_locations - if self.options.excluded_locations == "unnecessary" + if self.options.excluded_locations_behavior == "unnecessary" else set() ).union( { @@ -1227,10 +1227,10 @@ def _add_unnecessary_location_rules(self) -> None: if location.player == self.player and location.data.missable and not ( location.name in self.all_excluded_locations - and self.options.missable_locations < self.options.excluded_locations + and self.options.missable_locations_behavior < self.options.excluded_locations_behavior ) } - if self.options.missable_locations == "unnecessary" + if self.options.missable_locations_behavior == "unnecessary" else set() ) for location in unnecessary_locations: @@ -1239,7 +1239,7 @@ def _add_unnecessary_location_rules(self) -> None: lambda item: not item.advancement ) - if self.options.excluded_locations == "unnecessary": + if self.options.excluded_locations_behavior == "unnecessary": self.options.exclude_locations.value.clear() def _add_early_item_rules(self, randomized_items: Set[str]) -> None: @@ -1328,11 +1328,11 @@ def _is_location_available( and (not data.dlc or self.options.enable_dlc) and (not data.ngp or self.options.enable_ngp) and not ( - self.options.excluded_locations == "unrandomized" + self.options.excluded_locations_behavior == "unrandomized" and data.name in self.all_excluded_locations ) and not ( - self.options.missable_locations == "unrandomized" + self.options.missable_locations_behavior == "unrandomized" and data.missable ) ) @@ -1343,7 +1343,7 @@ def write_spoiler(self, spoiler_handle: TextIO) -> None: if self.yhorm_location != default_yhorm_location: text += f"\nYhorm takes the place of {self.yhorm_location.name} in {self.player_name}'s world\n" - if self.options.excluded_locations == "unnecessary": + if self.options.excluded_locations_behavior == "unnecessary": text += f"\n{self.player_name}'s world excluded: {sorted(self.all_excluded_locations)}\n" if text: From 434580a870f596d947fba08d8e7f0b0ebb1748f0 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 18 Jun 2024 20:53:16 -0400 Subject: [PATCH 217/238] This is singular, apparently --- worlds/dark_souls_3/__init__.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 9b4b5f494beb..ad11d97ebd83 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -250,11 +250,11 @@ def create_region(self, region_name, location_table) -> Region: new_location = DarkSouls3Location(self.player, location, new_region) if ( # Exclude missable, unimportant locations - location.missable and self.options.missable_locations_behavior == "unimportant" + location.missable and self.options.missable_location_behavior == "unimportant" and not ( # Unless they are excluded to a higher degree already location.name in self.all_excluded_locations - and self.options.missable_locations_behavior < self.options.excluded_locations_behavior + and self.options.missable_location_behavior < self.options.excluded_location_behavior ) ) or ( # Lift Chamber Key is missable. Exclude Lift-Chamber-Key-Locked locations if it isn't randomized @@ -1218,7 +1218,7 @@ def _add_unnecessary_location_rules(self) -> None: unnecessary_locations = ( self.options.all_excluded_locations - if self.options.excluded_locations_behavior == "unnecessary" + if self.options.excluded_location_behavior == "unnecessary" else set() ).union( { @@ -1227,10 +1227,10 @@ def _add_unnecessary_location_rules(self) -> None: if location.player == self.player and location.data.missable and not ( location.name in self.all_excluded_locations - and self.options.missable_locations_behavior < self.options.excluded_locations_behavior + and self.options.missable_location_behavior < self.options.excluded_location_behavior ) } - if self.options.missable_locations_behavior == "unnecessary" + if self.options.missable_location_behavior == "unnecessary" else set() ) for location in unnecessary_locations: @@ -1239,7 +1239,7 @@ def _add_unnecessary_location_rules(self) -> None: lambda item: not item.advancement ) - if self.options.excluded_locations_behavior == "unnecessary": + if self.options.excluded_location_behavior == "unnecessary": self.options.exclude_locations.value.clear() def _add_early_item_rules(self, randomized_items: Set[str]) -> None: @@ -1328,11 +1328,11 @@ def _is_location_available( and (not data.dlc or self.options.enable_dlc) and (not data.ngp or self.options.enable_ngp) and not ( - self.options.excluded_locations_behavior == "unrandomized" + self.options.excluded_location_behavior == "unrandomized" and data.name in self.all_excluded_locations ) and not ( - self.options.missable_locations_behavior == "unrandomized" + self.options.missable_location_behavior == "unrandomized" and data.missable ) ) @@ -1343,7 +1343,7 @@ def write_spoiler(self, spoiler_handle: TextIO) -> None: if self.yhorm_location != default_yhorm_location: text += f"\nYhorm takes the place of {self.yhorm_location.name} in {self.player_name}'s world\n" - if self.options.excluded_locations_behavior == "unnecessary": + if self.options.excluded_location_behavior == "unnecessary": text += f"\n{self.player_name}'s world excluded: {sorted(self.all_excluded_locations)}\n" if text: From 130fe2643c256c1c8ff9d626c59412c9b082fbbb Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 18 Jun 2024 21:19:43 -0400 Subject: [PATCH 218/238] Oops --- worlds/dark_souls_3/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index ad11d97ebd83..b65d05101539 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -1217,7 +1217,7 @@ def _add_unnecessary_location_rules(self) -> None: """ unnecessary_locations = ( - self.options.all_excluded_locations + self.all_excluded_locations if self.options.excluded_location_behavior == "unnecessary" else set() ).union( From 71fdc652bdad343aea92e0318972831d4a7f298d Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Tue, 18 Jun 2024 22:12:48 -0400 Subject: [PATCH 219/238] Fleshing out the priority process --- worlds/dark_souls_3/__init__.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index b65d05101539..876d88647b35 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -294,7 +294,9 @@ def create_region(self, region_name, location_table) -> Region: new_location.place_locked_item(event_item) if location.name in excluded: excluded.remove(location.name) - self.all_excluded_locations.remove(location.name) + # Only remove from all_excluded if excluded does not have priority over missable + if not (self.options.missable_location_behavior < self.options.excluded_location_behavior): + self.all_excluded_locations.remove(location.name) new_region.locations.append(new_location) @@ -1216,15 +1218,25 @@ def _add_unnecessary_location_rules(self) -> None: manually add item rules to exclude important items. """ + all_locations = self.multiworld.get_locations(self.player) + unnecessary_locations = ( - self.all_excluded_locations + { + location.name + for location in all_locations + if location.name in self.all_excluded_locations + and not ( + location.data.missable + and self.options.excluded_location_behavior < self.options.missable_location_behavior + ) + } if self.options.excluded_location_behavior == "unnecessary" else set() ).union( { location.name - for location in self.multiworld.get_locations() - if location.player == self.player and location.data.missable + for location in all_locations + if location.data.missable and not ( location.name in self.all_excluded_locations and self.options.missable_location_behavior < self.options.excluded_location_behavior From 20de5a4af1bc3d16e9f3601f832aeec5c7a3094a Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Fri, 5 Jul 2024 21:56:49 -0500 Subject: [PATCH 220/238] Missable Titanite Lizards and excluded locations (#22) --- worlds/dark_souls_3/Locations.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index 4db589aeb02e..cedf1bb765d7 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -2062,9 +2062,9 @@ def __init__( DS3LocationData("LC: Irithyll Rapier - basement, miniboss drop", "Irithyll Rapier", miniboss=True), # Boreal Outrider drop DS3LocationData("LC: Twinkling Titanite - dark room mid, out door opposite wyvern, lizard", - "Twinkling Titanite x2", lizard=True), + "Twinkling Titanite x2", lizard=True, missable=True), DS3LocationData("LC: Twinkling Titanite - moat, right path, lizard", - "Twinkling Titanite x2", lizard=True), + "Twinkling Titanite x2", lizard=True, missable=True), DS3LocationData("LC: Gotthard Twinswords - by Grand Archives door, after PC and AL bosses", "Gotthard Twinswords", conditional=True), DS3LocationData("LC: Grand Archives Key - by Grand Archives door, after PC and AL bosses", From 6ed17b885337250bf84f62c109d1210c0b106537 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 5 Jul 2024 20:13:41 -0700 Subject: [PATCH 221/238] Small style/efficiency changes --- worlds/dark_souls_3/__init__.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 876d88647b35..bd4b374435a0 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -1221,15 +1221,16 @@ def _add_unnecessary_location_rules(self) -> None: all_locations = self.multiworld.get_locations(self.player) unnecessary_locations = ( - { - location.name - for location in all_locations - if location.name in self.all_excluded_locations - and not ( - location.data.missable - and self.options.excluded_location_behavior < self.options.missable_location_behavior - ) - } + ( + { + location.name + for location in all_locations + if location.name in self.all_excluded_locations + and not location.data.missable + } + if self.options.excluded_location_behavior < self.options.missable_location_behavior + else self.all_excluded_locations + ) if self.options.excluded_location_behavior == "unnecessary" else set() ).union( @@ -1239,7 +1240,8 @@ def _add_unnecessary_location_rules(self) -> None: if location.data.missable and not ( location.name in self.all_excluded_locations - and self.options.missable_location_behavior < self.options.excluded_location_behavior + and self.options.missable_location_behavior < + self.options.excluded_location_behavior ) } if self.options.missable_location_behavior == "unnecessary" From a131bc1c15541d52db20df25692cc901250b9d79 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Fri, 5 Jul 2024 22:16:39 -0500 Subject: [PATCH 222/238] Final passthrough fixes (#24) --- worlds/dark_souls_3/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index bd4b374435a0..de124df1c596 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -110,8 +110,8 @@ def generate_early(self): [boss for boss in all_bosses if self._allow_boss_for_yhorm(boss)]) # If Yhorm is early, make sure the Storm Ruler is easily available to avoid BK + # Iudex Gundyr is handled separately in _fill_local_items if ( - self.yhorm_location.name == "Iudex Gundyr" or self.yhorm_location.name == "Vordt of the Boreal Valley" or ( self.yhorm_location.name == "Dancer of the Boreal Valley" and not self.options.late_basin_of_vows @@ -497,7 +497,7 @@ def _fill_local_item( if not candidate_locations: warning(f"Couldn't place \"{name}\" in a valid location for {self.player_name}. Adding it to starting inventory instead.") location = next( - (location for location in self.multiworld.get_locations() if location.item == item), + (location for location in self.multiworld.get_locations(self.player) if location.data.default_item_name == item.name), None ) if location: self._replace_with_filler(location) @@ -1290,7 +1290,7 @@ def _add_location_rule(self, location: Union[str, List[str]], rule: Union[Collec The rule can just be a single item/event name as well as an explicit rule lambda. """ - locations = location if type(location) is list else [location] + locations = location if isinstance(location, list) else [location] for location in locations: data = location_dictionary[location] if data.dlc and not self.options.enable_dlc: return @@ -1305,7 +1305,7 @@ def _add_location_rule(self, location: Union[str, List[str]], rule: Union[Collec def _add_entrance_rule(self, region: str, rule: Union[CollectionRule, str]) -> None: """Sets a rule for the entrance to the given region.""" assert region in location_tables - if not any(region == reg.name for reg in self.multiworld.regions): return + if not any(region == reg for reg in self.multiworld.regions.region_cache[self.player]): return if isinstance(rule, str): if " -> " not in rule: assert item_dictionary[rule].classification == ItemClassification.progression From dacd4fd293c7147f4c686346e792a07991f84d45 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 5 Jul 2024 20:29:43 -0700 Subject: [PATCH 223/238] Use rich option formatting --- worlds/dark_souls_3/Options.py | 95 ++++++++++++++++++++++----------- worlds/dark_souls_3/__init__.py | 1 + 2 files changed, 65 insertions(+), 31 deletions(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 4cc6e74ae483..762a28ef1483 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -20,9 +20,12 @@ class EarlySmallLothricBanner(Choice): 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. + - **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 @@ -35,9 +38,9 @@ class LateBasinOfVowsOption(Choice): 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. + - **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 @@ -78,7 +81,10 @@ class AutoEquipOption(Toggle): 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.""" + """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" @@ -88,7 +94,9 @@ class NoEquipLoadOption(Toggle): class NoWeaponRequirementsOption(Toggle): - """Disable the weapon requirements by removing any movement or damage penalties, permitting you to use any weapon early.""" + """Disable the weapon requirements by removing any movement or damage penalties, permitting you + to use any weapon early. + """ display_name = "No Weapon Requirements" @@ -105,7 +113,8 @@ class RandomizeInfusionOption(Toggle): class RandomizeInfusionPercentageOption(NamedRange): - """The percentage of weapons/shields in the pool to be infused if Randomize Infusion is toggled.""" + """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 @@ -115,11 +124,12 @@ class RandomizeInfusionPercentageOption(NamedRange): 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. + """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 + - **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 @@ -173,7 +183,9 @@ class MaxLevelsIn10WeaponPoolOption(Range): 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. + 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" @@ -181,7 +193,9 @@ class SmoothSoulItemsOption(DefaultOnToggle): 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. + 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" @@ -189,7 +203,9 @@ class SmoothUpgradeItemsOption(DefaultOnToggle): 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. + 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" @@ -204,7 +220,8 @@ class RandomizeEnemiesOption(DefaultOnToggle): 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 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. """ @@ -214,7 +231,8 @@ class SimpleEarlyBossesOption(DefaultOnToggle): 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. + 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. """ @@ -224,7 +242,9 @@ class ScaleEnemiesOption(DefaultOnToggle): 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. + 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. """ @@ -234,7 +254,8 @@ class RandomizeMimicsWithEnemiesOption(Toggle): 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. + 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. """ @@ -244,7 +265,8 @@ class RandomizeSmallCrystalLizardsWithEnemiesOption(Toggle): 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. + 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. """ @@ -254,7 +276,8 @@ class ReduceHarmlessEnemiesOption(Toggle): 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. + 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. """ @@ -272,7 +295,7 @@ class ImpatientMimicsOption(Toggle): class RandomEnemyPresetOption(Option[typing.Dict[str, typing.Any]], VerifyKeys): """The YAML preset for the static enemy randomizer. - See the static randomizer documentation in randomizer\\presets\\README.txt for details. + See the static randomizer documentation in `randomizer\\presets\\README.txt` for details. """ display_name = "Random Enemy Preset" supports_weighting = False @@ -307,11 +330,16 @@ class DS3ExcludeLocations(ExcludeLocations): class ExcludedLocationBehaviorOption(Choice): """Which items can be placed in excluded locations in DS3. - - Unnecessary: Excluded locations can't have progression items, but they can have useful items. - - Unimportant: Neither progression items nor useful items can be placed in excluded locations. - - Unrandomized: Excluded locations always contain the same item as in vanilla Dark Souls III. + - **Unnecessary:** Excluded locations can't have progression items, but they can have useful + items. + - **Unimportant:** Neither progression items nor useful items can be placed in excluded + locations. + - **Unrandomized:** 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. + 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_unnecessary = 1 @@ -323,11 +351,16 @@ class ExcludedLocationBehaviorOption(Choice): class MissableLocationBehaviorOption(Choice): """Which items can be placed in locations that can be permanently missed. - - Unnecessary: Missable locations can't have progression items, but they can have useful items. - - Unimportant: Neither progression items nor useful items can be placed in missable locations. - - Unrandomized: Missable locations always contain the same item as in vanilla Dark Souls III. + - **Unnecessary:** Missable locations can't have progression items, but they can have useful + items. + - **Unimportant:** Neither progression items nor useful items can be placed in missable + locations. + - **Unrandomized:** 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. + 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_unnecessary = 1 diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index bd4b374435a0..19769ed49b6a 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -40,6 +40,7 @@ class DarkSouls3Web(WebWorld): tutorials = [setup_en, setup_fr] option_groups = option_groups item_descriptions = item_descriptions + rich_text_options_doc = True class DarkSouls3World(World): From 763fd0ed694ccfc78e729746413ef77ceb1c016a Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 8 Jul 2024 13:56:28 -0700 Subject: [PATCH 224/238] Make the behavior option values actual behaviors (#25) --- worlds/dark_souls_3/Options.py | 26 +++++++++++++------------- worlds/dark_souls_3/__init__.py | 26 +++++++++++++------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 762a28ef1483..06e6c3ba6a39 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -328,13 +328,13 @@ class DS3ExcludeLocations(ExcludeLocations): class ExcludedLocationBehaviorOption(Choice): - """Which items can be placed in excluded locations in DS3. + """How to choose items for excluded locations in DS3. - - **Unnecessary:** Excluded locations can't have progression items, but they can have useful + - **Allow Useful:** Excluded locations can't have progression items, but they can have useful items. - - **Unimportant:** Neither progression items nor useful items can be placed in excluded + - **Forbid Useful:** Neither progression items nor useful items can be placed in excluded locations. - - **Unrandomized:** Excluded locations always contain the same item as in vanilla Dark Souls + - **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 @@ -342,20 +342,20 @@ class ExcludedLocationBehaviorOption(Choice): desirable but not strictly necessary. """ display_name = "Excluded Locations Behavior" - option_unnecessary = 1 - option_unimportant = 2 - option_unrandomized = 3 + 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. - - **Unnecessary:** Missable locations can't have progression items, but they can have useful + - **Allow Useful:** Missable locations can't have progression items, but they can have useful items. - - **Unimportant:** Neither progression items nor useful items can be placed in missable + - **Forbid Useful:** Neither progression items nor useful items can be placed in missable locations. - - **Unrandomized:** Missable locations always contain the same item as in vanilla Dark Souls + - **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 @@ -363,9 +363,9 @@ class MissableLocationBehaviorOption(Choice): desirable but not strictly necessary. """ display_name = "Missable Locations Behavior" - option_unnecessary = 1 - option_unimportant = 2 - option_unrandomized = 3 + option_allow_useful = 1 + option_forbid_useful = 2 + option_do_not_randomize = 3 default = 2 diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index bf0cbee185a8..08d9d26bdb33 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -75,7 +75,7 @@ class DarkSouls3World(World): all_excluded_locations: Set[str] = set() """This is the same value as `self.options.exclude_locations.value` initially, but if - `options.exclude_locations` gets cleared due to `excluded_locations: unnecessary` this still + `options.exclude_locations` gets cleared due to `excluded_locations: allow_useful` this still holds the old locations so we can ensure they don't get necessary items. """ @@ -250,8 +250,8 @@ def create_region(self, region_name, location_table) -> Region: if self._is_location_available(location): new_location = DarkSouls3Location(self.player, location, new_region) if ( - # Exclude missable, unimportant locations - location.missable and self.options.missable_location_behavior == "unimportant" + # Exclude missable locations that don't allow useful items + location.missable and self.options.missable_location_behavior == "forbid_useful" and not ( # Unless they are excluded to a higher degree already location.name in self.all_excluded_locations @@ -529,7 +529,7 @@ def set_rules(self) -> None: self._add_npc_rules() self._add_transposition_rules() self._add_crow_rules() - self._add_unnecessary_location_rules() + self._add_allow_useful_location_rules() self._add_early_item_rules(randomized_items) self._add_entrance_rule("Firelink Shrine Bell Tower", "Tower Key") @@ -1211,7 +1211,7 @@ def _add_crow_rules(self) -> None: and not item.data.is_upgraded )) - def _add_unnecessary_location_rules(self) -> None: + def _add_allow_useful_location_rules(self) -> None: """Adds rules for locations that can contain useful but not necessary items. If we allow useful items in the excluded locations, we don't want Archipelago's fill @@ -1221,7 +1221,7 @@ def _add_unnecessary_location_rules(self) -> None: all_locations = self.multiworld.get_locations(self.player) - unnecessary_locations = ( + allow_useful_locations = ( ( { location.name @@ -1232,7 +1232,7 @@ def _add_unnecessary_location_rules(self) -> None: if self.options.excluded_location_behavior < self.options.missable_location_behavior else self.all_excluded_locations ) - if self.options.excluded_location_behavior == "unnecessary" + if self.options.excluded_location_behavior == "allow_useful" else set() ).union( { @@ -1245,16 +1245,16 @@ def _add_unnecessary_location_rules(self) -> None: self.options.excluded_location_behavior ) } - if self.options.missable_location_behavior == "unnecessary" + if self.options.missable_location_behavior == "allow_useful" else set() ) - for location in unnecessary_locations: + for location in allow_useful_locations: self._add_item_rule( location, lambda item: not item.advancement ) - if self.options.excluded_location_behavior == "unnecessary": + if self.options.excluded_location_behavior == "allow_useful": self.options.exclude_locations.value.clear() def _add_early_item_rules(self, randomized_items: Set[str]) -> None: @@ -1343,11 +1343,11 @@ def _is_location_available( and (not data.dlc or self.options.enable_dlc) and (not data.ngp or self.options.enable_ngp) and not ( - self.options.excluded_location_behavior == "unrandomized" + self.options.excluded_location_behavior == "do_not_randomize" and data.name in self.all_excluded_locations ) and not ( - self.options.missable_location_behavior == "unrandomized" + self.options.missable_location_behavior == "do_not_randomize" and data.missable ) ) @@ -1358,7 +1358,7 @@ def write_spoiler(self, spoiler_handle: TextIO) -> None: if self.yhorm_location != default_yhorm_location: text += f"\nYhorm takes the place of {self.yhorm_location.name} in {self.player_name}'s world\n" - if self.options.excluded_location_behavior == "unnecessary": + if self.options.excluded_location_behavior == "allow_useful": text += f"\n{self.player_name}'s world excluded: {sorted(self.all_excluded_locations)}\n" if text: From 5311cb1b22aa0def6cf50115178ae456264b621a Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 20 Jul 2024 15:27:10 -0700 Subject: [PATCH 225/238] Use != --- worlds/dark_souls_3/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 08d9d26bdb33..2327718b9697 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -409,7 +409,7 @@ def create_item(self, item: Union[str, DS3ItemData]) -> Item: and data.category.upgrade_level # Because we require the Pyromancy Flame to be available early, don't upgrade it so it # doesn't get shuffled around by weapon smoothing. - and not data.name == "Pyromancy Flame" + and data.name != "Pyromancy Flame" ): # if the user made an error and set a min higher than the max we default to the max max_5 = self.options.max_levels_in_5.value From 4f96496321e288e89ee6ec695041a86c7fd76b40 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 20 Jul 2024 15:28:46 -0700 Subject: [PATCH 226/238] Remove unused flatten utility --- Utils.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/Utils.py b/Utils.py index 8156a0019cb8..f89330cf7c65 100644 --- a/Utils.py +++ b/Utils.py @@ -2,7 +2,6 @@ import asyncio import json -import types import typing import builtins import os @@ -19,9 +18,9 @@ from argparse import Namespace from settings import Settings, get_settings -from typing import BinaryIO, Coroutine, Generator, Generic, List, Optional, Set, TypeVar, Dict, Any, Union +from typing import BinaryIO, Coroutine, Optional, Set, Dict, Any, Union from typing_extensions import TypeGuard -from yaml import load, load_all, dump, SafeLoader +from yaml import load, load_all, dump try: from yaml import CLoader as UnsafeLoader, CSafeLoader as SafeLoader, CDumper as Dumper @@ -825,14 +824,6 @@ def async_start(co: Coroutine[None, None, typing.Any], name: Optional[str] = Non task.add_done_callback(_faf_tasks.discard) -T = TypeVar("T") -def flatten(l: List[T] | Generator[T] | T) -> List[T]: - if type(l) is list or type(l) is types.GeneratorType: - return [ y for x in l for y in flatten(x) ] - else: - return [ l ] - - def deprecate(message: str): if __debug__: raise Exception(message) From 7e0c09fbb7e6afe2e212d533c2a7b7f7d6e5fde8 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 27 Jul 2024 00:09:41 -0400 Subject: [PATCH 227/238] Some changes from review (#28) --- worlds/dark_souls_3/Items.py | 4 ++-- worlds/dark_souls_3/__init__.py | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 9dd9adfa4c28..01ff758a54aa 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -1677,8 +1677,8 @@ def event(name: str, player: int) -> "DarkSouls3Item": _all_items = _vanilla_items + _dlc_items for item_data in _all_items: - for group_name in item_data.item_groups(): - item_name_groups[group_name].add(item_data.name) + for group_name in item_data.item_groups(): + item_name_groups[group_name].add(item_data.name) filler_item_names = [item_data.name for item_data in _all_items if item_data.filler] item_dictionary = {item_data.name: item_data for item_data in _all_items} diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 2327718b9697..12a504459b4f 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -118,8 +118,7 @@ def generate_early(self): not self.options.late_basin_of_vows ) ): - self.multiworld.early_items[self.player]["Storm Ruler"] = 1 - self.options.local_items.value.add("Storm Ruler") + self.multiworld.local_early_items[self.player]["Storm Ruler"] = 1 else: self.yhorm_location = default_yhorm_location @@ -336,11 +335,12 @@ def create_items(self): # Extra filler items for locations containing skip items self.local_itempool.extend(self.create_filler() for _ in range(num_required_extra_items)) + # Potentially fill some items locally and remove them from the itempool + self._fill_local_items() + # Add items to itempool self.multiworld.itempool += self.local_itempool - self._fill_local_items() - def _create_injectable_items(self, num_required_extra_items: int) -> List[Item]: """Returns a list of items to inject into the multiworld instead of skipped items. @@ -492,7 +492,6 @@ def _fill_local_item( and location.item_rule(item) ] - self.multiworld.itempool.remove(item) self.local_itempool.remove(item) if not candidate_locations: From 36506799c10428e9749f869bedab11b5e28dfe52 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 27 Jul 2024 00:16:23 -0400 Subject: [PATCH 228/238] Fixing determinism and making smooth faster (#29) --- worlds/dark_souls_3/__init__.py | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 12a504459b4f..07c6ef9c58a5 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -1374,7 +1374,8 @@ def post_fill(self): region order, and then the best items in a sphere go into the multiworld. """ - locations_by_sphere = list(self.multiworld.get_spheres()) + locations_by_sphere = [sorted(loc for loc in sphere if loc.item.player == self.player and not loc.locked) + for sphere in self.multiworld.get_spheres()] # All items in the base game in approximately the order they appear all_item_order = [ @@ -1418,11 +1419,9 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: all_matching_locations = [ loc - for locations in locations_by_sphere - for loc in locations - if loc.item.player == self.player - and not loc.locked - and loc.item.name in names + for sphere in locations_by_sphere + for loc in sphere + if loc.item.name in names ] # It's expected that there may be more total items than there are matching locations if @@ -1434,13 +1433,8 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: f"contain smoothed items, but only {len(item_order)} items to smooth." ) - for i, all_locations in enumerate(locations_by_sphere): - locations = [ - loc for loc in all_locations - if loc.item.player == self.player - and not loc.locked - and loc.item.name in names - ] + for sphere in locations_by_sphere: + locations = [loc for loc in sphere if loc.item.name in names] # Check the game, not the player, because we know how to sort within regions for DS3 offworld = self._shuffle([loc for loc in locations if loc.game != "Dark Souls III"]) @@ -1490,13 +1484,8 @@ def _pop_item( items: List[Union[DS3ItemData, DarkSouls3Item]] ) -> Union[DS3ItemData, DarkSouls3Item]: """Returns the next item in items that can be assigned to location.""" - # Non-excluded locations can take any item we throw at them. (More specifically, if they can - # take one item in a group, they can take any other). - if location.progress_type != LocationProgressType.EXCLUDED: return items.pop(0) - - # Excluded locations require filler items. for i, item in enumerate(items): - if item.classification == ItemClassification.filler: + if location.can_fill(self.multiworld.state, item, False): return items.pop(i) # If we can't find a suitable item, give up and assign an unsuitable one. From 2417b5046702ac2d794105576ca709d653e8b7e8 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 26 Jul 2024 21:15:56 -0700 Subject: [PATCH 229/238] Style change --- worlds/dark_souls_3/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 07c6ef9c58a5..81e579dc037a 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -1374,8 +1374,10 @@ def post_fill(self): region order, and then the best items in a sphere go into the multiworld. """ - locations_by_sphere = [sorted(loc for loc in sphere if loc.item.player == self.player and not loc.locked) - for sphere in self.multiworld.get_spheres()] + locations_by_sphere = [ + sorted(loc for loc in sphere if loc.item.player == self.player and not loc.locked) + for sphere in self.multiworld.get_spheres() + ] # All items in the base game in approximately the order they appear all_item_order = [ From 99ae362804eb84465c71b4fbfb530e4c94626601 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 27 Jul 2024 15:46:52 -0400 Subject: [PATCH 230/238] PyCharm and Mypy fixes (#26) Co-authored-by: Scipio Wright --- worlds/dark_souls_3/Items.py | 25 ++++++++++++------------- worlds/dark_souls_3/Locations.py | 13 +++++-------- worlds/dark_souls_3/Options.py | 18 ++++++++++-------- worlds/dark_souls_3/__init__.py | 20 ++++++++------------ 4 files changed, 35 insertions(+), 41 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 01ff758a54aa..42a256355be0 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -1,8 +1,7 @@ from dataclasses import dataclass import dataclasses from enum import IntEnum -import types -from typing import ClassVar, Generator, List, Optional, Set, Union +from typing import cast, ClassVar, Dict, Generator, List, Optional, Set from BaseClasses import Item, ItemClassification @@ -97,10 +96,10 @@ class DS3ItemData: """The next item ID to use when creating item data.""" name: str - ds3_code: int + ds3_code: Optional[int] category: DS3ItemCategory - base_ds3_code: int = None + base_ds3_code: Optional[int] = None """If this is an upgradable weapon, the base ID of the weapon it upgrades from. Otherwise, or if the weapon isn't upgraded, this is the same as ds3_code. @@ -112,7 +111,7 @@ class DS3ItemData: classification: ItemClassification = ItemClassification.filler """How important this item is to the game progression.""" - ap_code: int = None + ap_code: Optional[int] = None """The Archipelago ID for this item.""" is_dlc: bool = False @@ -130,7 +129,7 @@ class DS3ItemData: difference. """ - souls: int = None + souls: Optional[int] = None """If this is a consumable item that gives souls, the number of souls it gives.""" useful_if: UsefulIf = UsefulIf.DEFAULT @@ -199,7 +198,7 @@ def counts(self, counts: List[int]) -> Generator["DS3ItemData", None, None]: @property def is_infused(self) -> bool: """Returns whether this item is an infused weapon.""" - return self.ds3_code - self.base_ds3_code >= 100 + return cast(int, self.ds3_code) - cast(int, self.base_ds3_code) >= 100 def infuse(self, infusion: Infusion) -> "DS3ItemData": """Returns this item with the given infusion applied.""" @@ -213,14 +212,14 @@ def infuse(self, infusion: Infusion) -> "DS3ItemData": return dataclasses.replace( self, name = self.name, - ds3_code = self.ds3_code + infusion.value, + ds3_code = cast(int, self.ds3_code) + infusion.value, filler = False, ) @property def is_upgraded(self) -> bool: """Returns whether this item is a weapon that's upgraded beyond level 0.""" - return (self.ds3_code - self.base_ds3_code) % 100 != 0 + return (cast(int, self.ds3_code) - cast(int, self.base_ds3_code)) % 100 != 0 def upgrade(self, level: int) -> "DS3ItemData": """Upgrades this item to the given level.""" @@ -236,7 +235,7 @@ def upgrade(self, level: int) -> "DS3ItemData": return dataclasses.replace( self, name = self.name, - ds3_code = self.ds3_code + level, + ds3_code = cast(int, self.ds3_code) + level, filler = False, ) @@ -246,9 +245,9 @@ class DarkSouls3Item(Item): data: DS3ItemData @property - def level(self) -> Union[int, None]: + def level(self) -> Optional[int]: """This item's upgrade level, if it's a weapon.""" - return self.data.ds3_code % 100 if self.data.category.upgrade_level else None + return cast(int, self.data.ds3_code) % 100 if self.data.category.upgrade_level else None def __init__( self, @@ -1645,7 +1644,7 @@ def event(name: str, player: int) -> "DarkSouls3Item": ] -item_name_groups = { +item_name_groups: Dict[str, Set] = { "Progression": set(), "Cinders": set(), "Weapons": set(), diff --git a/worlds/dark_souls_3/Locations.py b/worlds/dark_souls_3/Locations.py index cedf1bb765d7..08f4b7cd1a80 100644 --- a/worlds/dark_souls_3/Locations.py +++ b/worlds/dark_souls_3/Locations.py @@ -1,4 +1,4 @@ -from typing import ClassVar, Optional, Dict, List, Set +from typing import cast, ClassVar, Optional, Dict, List, Set from dataclasses import dataclass from BaseClasses import ItemClassification, Location, Region @@ -61,7 +61,7 @@ class DS3LocationData: that progression balancing and item smoothing is more accurate for DS3. """ - ap_code: int = None + ap_code: Optional[int] = None """Archipelago's internal ID for this location (also known as its "address").""" region_value: int = 0 @@ -187,9 +187,6 @@ def location_groups(self) -> List[str]: """The names of location groups this location should appear in. This is computed from the properties assigned to this location.""" - # Events aren't part of any location groups. - if self.is_event: return - names = [] if self.prominent: names.append("Prominent") if self.progression: names.append("Progression") @@ -201,7 +198,7 @@ def location_groups(self) -> List[str]: if self.lizard: names.append("Small Crystal Lizards") if self.hidden: names.append("Hidden") - default_item = item_dictionary[self.default_item_name] + default_item = item_dictionary[cast(str, self.default_item_name)] names.append({ DS3ItemCategory.WEAPON_UPGRADE_5: "Weapons", DS3ItemCategory.WEAPON_UPGRADE_10: "Weapons", @@ -261,7 +258,7 @@ def __init__( # as part of their normal quest, "kill [name]" for items that require killing # them even when they aren't hostile, and just "[name]" for items that are # naturally available as part of their quest. -location_tables = { +location_tables: Dict[str, List[DS3LocationData]] = { "Cemetery of Ash": [ DS3LocationData("CA: Soul of a Deserted Corpse - right of spawn", "Soul of a Deserted Corpse"), @@ -3103,7 +3100,7 @@ def __init__( # Allow entire locations to be added to location sets. if not location_name.endswith(" Shop"): - location_name_groups[location_name] = frozenset([ + location_name_groups[location_name] = set([ location_data.name for location_data in location_table if not location_data.is_event ]) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 06e6c3ba6a39..ab343240b8f5 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -1,13 +1,14 @@ from copy import deepcopy from dataclasses import dataclass import json -import typing +from typing import Any, Dict -from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, ItemDict, NamedRange, Option, OptionGroup, \ - PerGameCommonOptions, Range, Removed, Toggle, VerifyKeys, Visibility +from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, NamedRange, Option, OptionGroup, \ + PerGameCommonOptions, Range, Removed, Toggle, VerifyKeys ## 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" @@ -292,7 +293,7 @@ class ImpatientMimicsOption(Toggle): display_name = "Impatient Mimics" -class RandomEnemyPresetOption(Option[typing.Dict[str, typing.Any]], VerifyKeys): +class RandomEnemyPresetOption(Option[Dict[str, Any]], VerifyKeys): """The YAML preset for the static enemy randomizer. See the static randomizer documentation in `randomizer\\presets\\README.txt` for details. @@ -305,14 +306,15 @@ class RandomEnemyPresetOption(Option[typing.Dict[str, typing.Any]], VerifyKeys): "OopsAll", "Boss", "Miniboss", "Basic", "BuffBasicEnemiesAsBosses", "DontRandomize", "RemoveSource", "Enemies"] - def __init__(self, value: typing.Dict[str, typing.Any]): + def __init__(self, value: Dict[str, Any]): self.value = deepcopy(value) - def get_option_name(self, value: typing.Dict[str, typing.Any]): + @classmethod + def get_option_name(cls, value: Dict[str, Any]) -> str: return json.dumps(value) @classmethod - def from_any(cls, data: typing.Dict[str, typing.Any]) -> "RandomEnemyPresetOption": + def from_any(cls, data: Dict[str, Any]) -> "RandomEnemyPresetOption": if isinstance(data, dict): cls.verify_keys(data) return cls(data) @@ -324,7 +326,7 @@ def from_any(cls, data: typing.Dict[str, typing.Any]) -> "RandomEnemyPresetOptio class DS3ExcludeLocations(ExcludeLocations): """Prevent these locations from having an important item.""" - default = {"Hidden", "Small Crystal Lizards", "Upgrade", "Small Souls", "Miscellaneous"} + default = frozenset({"Hidden", "Small Crystal Lizards", "Upgrade", "Small Souls", "Miscellaneous"}) class ExcludedLocationBehaviorOption(Choice): diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 81e579dc037a..06e8fa185d5f 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -79,19 +79,15 @@ class DarkSouls3World(World): holds the old locations so we can ensure they don't get necessary items. """ - local_itempool: Optional[List[DarkSouls3Item]] + local_itempool: List[DarkSouls3Item] = [] """The pool of all items within this particular world. This is a subset of `self.multiworld.itempool`.""" def __init__(self, multiworld: MultiWorld, player: int): super().__init__(multiworld, player) - self.locked_items = [] - self.locked_locations = [] - self.main_path_locations = [] - self.enabled_location_categories = set() self.all_excluded_locations = set() - def generate_early(self): + def generate_early(self) -> None: self.all_excluded_locations.update(self.options.exclude_locations.value) # Inform Universal Tracker where Yhorm is being randomized to. @@ -151,7 +147,7 @@ def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: for location in location_tables["Cemetery of Ash"] ) - def create_regions(self): + def create_regions(self) -> None: # Create Vanilla Regions regions: Dict[str, Region] = {"Menu": self.create_region("Menu", {})} regions.update({region_name: self.create_region(region_name, location_tables[region_name]) for region_name in [ @@ -303,7 +299,7 @@ def create_region(self, region_name, location_table) -> Region: self.multiworld.regions.append(new_region) return new_region - def create_items(self): + def create_items(self) -> None: # Just used to efficiently deduplicate items item_set: Set[str] = set() @@ -341,7 +337,7 @@ def create_items(self): # Add items to itempool self.multiworld.itempool += self.local_itempool - def _create_injectable_items(self, num_required_extra_items: int) -> List[Item]: + def _create_injectable_items(self, num_required_extra_items: int) -> List[DarkSouls3Item]: """Returns a list of items to inject into the multiworld instead of skipped items. If there isn't enough room to inject all the necessary progression items @@ -390,7 +386,7 @@ def _create_injectable_items(self, num_required_extra_items: int) -> List[Item]: return [self.create_item(item) for item in items] - def create_item(self, item: Union[str, DS3ItemData]) -> Item: + def create_item(self, item: Union[str, DS3ItemData]) -> DarkSouls3Item: data = item if isinstance(item, DS3ItemData) else item_dictionary[item] classification = None if self.multiworld and data.useful_if != UsefulIf.DEFAULT and ( @@ -1317,11 +1313,11 @@ def _add_item_rule(self, location: str, rule: ItemRule) -> None: if not self._is_location_available(location): return add_item_rule(self.multiworld.get_location(location, self.player), rule) - def _can_go_to(self, state, region) -> None: + def _can_go_to(self, state, region) -> bool: """Returns whether state can access the given region name.""" return state.can_reach_entrance(f"Go To {region}", self.player) - def _can_get(self, state, location) -> None: + def _can_get(self, state, location) -> bool: """Returns whether state can access the given location name.""" return state.can_reach_location(location, self.player) From a438bf79e50ba022e06f5f7b04068333cf4e645a Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 27 Jul 2024 15:49:27 -0400 Subject: [PATCH 231/238] Change yhorm default (#30) --- worlds/dark_souls_3/__init__.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 06e8fa185d5f..7728c878a096 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -67,7 +67,7 @@ class DarkSouls3World(World): location_descriptions = location_descriptions item_descriptions = item_descriptions - yhorm_location: Optional[DS3BossInfo] + yhorm_location: DS3BossInfo = default_yhorm_location """If enemy randomization is enabled, this is the boss who Yhorm the Giant should replace. This is used to determine where the Storm Ruler can be placed. @@ -98,8 +98,6 @@ def generate_early(self) -> None: for boss in all_bosses: if yhorm_data.startswith(boss.name): self.yhorm_location = boss - else: - self.yhorm_location = default_yhorm_location # Randomize Yhorm manually so that we know where to place the Storm Ruler. elif self.options.randomize_enemies: @@ -115,8 +113,6 @@ def generate_early(self) -> None: ) ): self.multiworld.local_early_items[self.player]["Storm Ruler"] = 1 - else: - self.yhorm_location = default_yhorm_location def _allow_boss_for_yhorm(self, boss: DS3BossInfo) -> bool: """Returns whether boss is a valid location for Yhorm in this seed.""" From e4d2b65a5de6c87cc73b4c334582a346372206be Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Sat, 27 Jul 2024 16:14:57 -0400 Subject: [PATCH 232/238] Add indirect condition (#27) --- worlds/dark_souls_3/__init__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 7728c878a096..7fe5bc0d66a4 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -969,6 +969,11 @@ def _add_npc_rules(self) -> None: self._can_get(state, "US: Soul of the Rotted Greatwood") and state.has("Dreamchaser's Ashes", self.player) )) + # Add indirect condition since reaching AL requires deafeating Pontiff which requires defeating Greatwood in US + self.multiworld.register_indirect_condition( + self.get_region("Undead Settlement"), + self.get_entrance("Go To Anor Londo") + ) # Kill Creighton and Aldrich to trigger this opportunity for invasion self._add_location_rule([ From 94682ffbb2ee02a1ce0569b4ac0e6e5feb28aca2 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 28 Jul 2024 19:16:08 -0700 Subject: [PATCH 233/238] Update worlds/dark_souls_3/docs/locations_en.md Co-authored-by: Nicholas Saylor <79181893+nicholassaylor@users.noreply.github.com> --- worlds/dark_souls_3/docs/locations_en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/docs/locations_en.md b/worlds/dark_souls_3/docs/locations_en.md index 5df01aa1df4b..ef07b84b2b34 100644 --- a/worlds/dark_souls_3/docs/locations_en.md +++ b/worlds/dark_souls_3/docs/locations_en.md @@ -43,7 +43,7 @@ at once: * **Progression:** Locations that contain items in vanilla which unlock other locations. -* **Boss rewards:** Boss drops. Does not include soul transfusions or shop +* **Boss Rewards:** Boss drops. Does not include soul transfusions or shop items. * **Miniboss Rewards:** Miniboss drops. Minibosses are large enemies that don't From 46014020bd0a2148d72746b19f8101f0aa315948 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sun, 28 Jul 2024 19:24:38 -0700 Subject: [PATCH 234/238] 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. --- worlds/dark_souls_3/__init__.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 7fe5bc0d66a4..5ed3fee28b83 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -1493,18 +1493,14 @@ def _pop_item( def fill_slot_data(self) -> Dict[str, object]: slot_data: Dict[str, object] = {} - our_items = { - location.item - for location in self.multiworld.get_filled_locations() - # item.code None is used for events, which we want to skip - if location.item.code is not None and location.item.player == self.player - } - + # Once all clients support overlapping item IDs, adjust the DS3 AP item IDs to encode the + # in-game ID as well as the count so that we don't need to send this information at all. ap_ids_to_ds3_ids: Dict[str, int] = {} item_counts: Dict[str, int] = {} - for item in our_items: - if item.data.ds3_code: ap_ids_to_ds3_ids[str(item.code)] = item.data.ds3_code - if item.data.count != 1: item_counts[str(item.code)] = item.data.count + for item in item_dictionary.values(): + if item.ap_code is None: continue + if item.ds3_code: ap_ids_to_ds3_ids[str(item.ap_code)] = item.ds3_code + if item.count != 1: item_counts[str(item.ap_code)] = item.count # A map from Archipelago's location IDs to the keys the static randomizer uses to identify # locations. From 3776c3571e16018079f3b04e8e3c4487ea0f03f4 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 5 Aug 2024 19:54:33 -0700 Subject: [PATCH 235/238] Make sure to send AP IDs for infused/upgraded weapons --- worlds/dark_souls_3/Items.py | 9 +++++++++ worlds/dark_souls_3/__init__.py | 21 ++++++++++++++++----- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index 42a256355be0..ab436c05561f 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -238,6 +238,15 @@ def upgrade(self, level: int) -> "DS3ItemData": ds3_code = cast(int, self.ds3_code) + level, filler = False, ) + + def __hash__(self) -> int: + return (self.name, self.ds3_code).__hash__() + + def __eq__(self, other: any) -> bool: + if isinstance(other, self.__class__): + return self.name == other.name and self.ds3_code == other.ds3_code + else: + return False class DarkSouls3Item(Item): diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 5ed3fee28b83..3e1160d0cb27 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -3,17 +3,17 @@ from collections import defaultdict import json from logging import warning -from typing import Any, Callable, Dict, Set, List, Optional, TextIO, Union +from typing import cast, Any, Callable, Dict, Set, List, Optional, TextIO, Union -from BaseClasses import CollectionState, MultiWorld, Region, Item, Location, LocationProgressType, Entrance, Tutorial, ItemClassification +from BaseClasses import CollectionState, MultiWorld, Region, Location, LocationProgressType, Entrance, Tutorial, ItemClassification from worlds.AutoWorld import World, WebWorld from worlds.generic.Rules import CollectionRule, ItemRule, add_rule, add_item_rule from .Bosses import DS3BossInfo, all_bosses, default_yhorm_location -from .Items import DarkSouls3Item, DS3ItemCategory, DS3ItemData, Infusion, UsefulIf, filler_item_names, item_descriptions, item_dictionary, item_name_groups +from .Items import DarkSouls3Item, DS3ItemData, Infusion, UsefulIf, filler_item_names, item_descriptions, item_dictionary, item_name_groups from .Locations import DarkSouls3Location, DS3LocationData, location_tables, location_descriptions, location_dictionary, location_name_groups, region_order -from .Options import DarkSouls3Options, EarlySmallLothricBanner, option_groups +from .Options import DarkSouls3Options, option_groups class DarkSouls3Web(WebWorld): @@ -1495,9 +1495,20 @@ def fill_slot_data(self) -> Dict[str, object]: # Once all clients support overlapping item IDs, adjust the DS3 AP item IDs to encode the # in-game ID as well as the count so that we don't need to send this information at all. + # + # We include all the items the game knows about so that users can manually request items + # that aren't randomized, and then we _also_ include all the items that are placed in + # practice `item_dictionary.values()` doesn't include upgraded or infused weapons. + all_items = { + cast(DS3ItemData, location.item).data + for location in self.multiworld.get_filled_locations() + # item.code None is used for events, which we want to skip + if location.item.code is not None and location.item.player == self.player + }.union(item_dictionary.values()) + ap_ids_to_ds3_ids: Dict[str, int] = {} item_counts: Dict[str, int] = {} - for item in item_dictionary.values(): + for item in all_items: if item.ap_code is None: continue if item.ds3_code: ap_ids_to_ds3_ids[str(item.ap_code)] = item.ds3_code if item.count != 1: item_counts[str(item.ap_code)] = item.count From 5374f51b1718a871157d1737d55f88ba3b88568c Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 5 Aug 2024 20:02:34 -0700 Subject: [PATCH 236/238] Make `RandomEnemyPresetOption` compatible with ArchipelagoMW/Archipelago#3280 (#31) --- worlds/dark_souls_3/Options.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index ab343240b8f5..1256e4416c7c 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -3,8 +3,8 @@ import json from typing import Any, Dict -from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, NamedRange, Option, OptionGroup, \ - PerGameCommonOptions, Range, Removed, Toggle, VerifyKeys +from Options import Choice, DeathLink, DefaultOnToggle, ExcludeLocations, NamedRange, OptionDict, \ + OptionGroup, PerGameCommonOptions, Range, Removed, Toggle ## Game Options @@ -293,10 +293,17 @@ class ImpatientMimicsOption(Toggle): display_name = "Impatient Mimics" -class RandomEnemyPresetOption(Option[Dict[str, Any]], VerifyKeys): +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 @@ -313,14 +320,6 @@ def __init__(self, value: Dict[str, Any]): def get_option_name(cls, value: Dict[str, Any]) -> str: return json.dumps(value) - @classmethod - def from_any(cls, data: Dict[str, Any]) -> "RandomEnemyPresetOption": - if isinstance(data, dict): - cls.verify_keys(data) - return cls(data) - else: - raise NotImplementedError(f"Must be a dictionary, got {type(data)}") - ## Item & Location From 27d4c4137752bbc7a2988c437c37b5d7b046c980 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 5 Aug 2024 21:14:11 -0700 Subject: [PATCH 237/238] Fix cast --- worlds/dark_souls_3/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index 3e1160d0cb27..a3e8d962540e 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -1500,7 +1500,7 @@ def fill_slot_data(self) -> Dict[str, object]: # that aren't randomized, and then we _also_ include all the items that are placed in # practice `item_dictionary.values()` doesn't include upgraded or infused weapons. all_items = { - cast(DS3ItemData, location.item).data + cast(DarkSouls3Item, location.item).data for location in self.multiworld.get_filled_locations() # item.code None is used for events, which we want to skip if location.item.code is not None and location.item.player == self.player From 443a28518788725fb34d1a1309d0034edde01f42 Mon Sep 17 00:00:00 2001 From: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com> Date: Thu, 8 Aug 2024 01:00:10 -0400 Subject: [PATCH 238/238] More typing and small fixes (#32) --- worlds/dark_souls_3/Bosses.py | 4 +-- worlds/dark_souls_3/Items.py | 4 +-- worlds/dark_souls_3/Options.py | 4 --- worlds/dark_souls_3/__init__.py | 53 ++++++++++++++++++--------------- 4 files changed, 33 insertions(+), 32 deletions(-) diff --git a/worlds/dark_souls_3/Bosses.py b/worlds/dark_souls_3/Bosses.py index e69fb574a13b..008a29713202 100644 --- a/worlds/dark_souls_3/Bosses.py +++ b/worlds/dark_souls_3/Bosses.py @@ -3,7 +3,7 @@ # available before his fight. from dataclasses import dataclass, field -from typing import Optional, Set +from typing import Set @dataclass @@ -26,7 +26,7 @@ class DS3BossInfo: aren't randomized. """ - locations: Optional[Set[str]] = field(default_factory=set) + locations: Set[str] = field(default_factory=set) """Additional individual locations that can't be accessed until the boss is dead.""" diff --git a/worlds/dark_souls_3/Items.py b/worlds/dark_souls_3/Items.py index ab436c05561f..19cd79a99414 100644 --- a/worlds/dark_souls_3/Items.py +++ b/worlds/dark_souls_3/Items.py @@ -1,7 +1,7 @@ from dataclasses import dataclass import dataclasses from enum import IntEnum -from typing import cast, ClassVar, Dict, Generator, List, Optional, Set +from typing import Any, cast, ClassVar, Dict, Generator, List, Optional, Set from BaseClasses import Item, ItemClassification @@ -242,7 +242,7 @@ def upgrade(self, level: int) -> "DS3ItemData": def __hash__(self) -> int: return (self.name, self.ds3_code).__hash__() - def __eq__(self, other: any) -> bool: + def __eq__(self, other: Any) -> bool: if isinstance(other, self.__class__): return self.name == other.name and self.ds3_code == other.ds3_code else: diff --git a/worlds/dark_souls_3/Options.py b/worlds/dark_souls_3/Options.py index 1256e4416c7c..ad81dd9f7b85 100644 --- a/worlds/dark_souls_3/Options.py +++ b/worlds/dark_souls_3/Options.py @@ -1,4 +1,3 @@ -from copy import deepcopy from dataclasses import dataclass import json from typing import Any, Dict @@ -313,9 +312,6 @@ class RandomEnemyPresetOption(OptionDict): "OopsAll", "Boss", "Miniboss", "Basic", "BuffBasicEnemiesAsBosses", "DontRandomize", "RemoveSource", "Enemies"] - def __init__(self, value: Dict[str, Any]): - self.value = deepcopy(value) - @classmethod def get_option_name(cls, value: Dict[str, Any]) -> str: return json.dumps(value) diff --git a/worlds/dark_souls_3/__init__.py b/worlds/dark_souls_3/__init__.py index a3e8d962540e..159a870c7658 100644 --- a/worlds/dark_souls_3/__init__.py +++ b/worlds/dark_souls_3/__init__.py @@ -56,11 +56,12 @@ class DarkSouls3World(World): web = DarkSouls3Web() base_id = 100000 required_client_version = (0, 4, 2) - item_name_to_id = {data.name: data.ap_code for data in item_dictionary.values()} + item_name_to_id = {data.name: data.ap_code for data in item_dictionary.values() if data.ap_code is not None} location_name_to_id = { location.name: location.ap_code for locations in location_tables.values() for location in locations + if location.ap_code is not None } location_name_groups = location_name_groups item_name_groups = item_name_groups @@ -302,30 +303,31 @@ def create_items(self) -> None: # Gather all default items on randomized locations self.local_itempool = [] num_required_extra_items = 0 - for location in self.multiworld.get_unfilled_locations(self.player): + for location in cast(List[DarkSouls3Location], self.multiworld.get_unfilled_locations(self.player)): if not self._is_location_available(location.name): raise Exception("DS3 generation bug: Added an unavailable location.") - item = item_dictionary[location.data.default_item_name] + default_item_name = cast(str, location.data.default_item_name) + item = item_dictionary[default_item_name] if item.skip: num_required_extra_items += 1 elif not item.unique: - self.local_itempool.append(self.create_item(location.data.default_item_name)) + self.local_itempool.append(self.create_item(default_item_name)) else: # For unique items, make sure there aren't duplicates in the item set even if there # are multiple in-game locations that provide them. - if location.data.default_item_name in item_set: + if default_item_name in item_set: num_required_extra_items += 1 else: - item_set.add(location.data.default_item_name) - self.local_itempool.append(self.create_item(location.data.default_item_name)) + item_set.add(default_item_name) + self.local_itempool.append(self.create_item(default_item_name)) injectables = self._create_injectable_items(num_required_extra_items) num_required_extra_items -= len(injectables) self.local_itempool.extend(injectables) # Extra filler items for locations containing skip items - self.local_itempool.extend(self.create_filler() for _ in range(num_required_extra_items)) + self.local_itempool.extend(self.create_item(self.get_filler_item_name()) for _ in range(num_required_extra_items)) # Potentially fill some items locally and remove them from the itempool self._fill_local_items() @@ -456,7 +458,7 @@ def _fill_local_items(self) -> None: def _fill_local_item( self, name: str, regions: List[str], - additional_condition: Optional[Callable[[DarkSouls3Location], bool]] = None, + additional_condition: Optional[Callable[[DS3LocationData], bool]] = None, ) -> None: """Chooses a valid location for the item with the given name and places it there. @@ -489,7 +491,7 @@ def _fill_local_item( if not candidate_locations: warning(f"Couldn't place \"{name}\" in a valid location for {self.player_name}. Adding it to starting inventory instead.") location = next( - (location for location in self.multiworld.get_locations(self.player) if location.data.default_item_name == item.name), + (location for location in self._get_our_locations() if location.data.default_item_name == item.name), None ) if location: self._replace_with_filler(location) @@ -969,7 +971,7 @@ def _add_npc_rules(self) -> None: self._can_get(state, "US: Soul of the Rotted Greatwood") and state.has("Dreamchaser's Ashes", self.player) )) - # Add indirect condition since reaching AL requires deafeating Pontiff which requires defeating Greatwood in US + # Add indirect condition since reaching AL requires defeating Pontiff which requires defeating Greatwood in US self.multiworld.register_indirect_condition( self.get_region("Undead Settlement"), self.get_entrance("Go To Anor Londo") @@ -1215,7 +1217,7 @@ def _add_allow_useful_location_rules(self) -> None: manually add item rules to exclude important items. """ - all_locations = self.multiworld.get_locations(self.player) + all_locations = self._get_our_locations() allow_useful_locations = ( ( @@ -1336,8 +1338,8 @@ def _is_location_available( return ( not data.is_event - and (not data.dlc or self.options.enable_dlc) - and (not data.ngp or self.options.enable_ngp) + and (not data.dlc or bool(self.options.enable_dlc)) + and (not data.ngp or bool(self.options.enable_ngp)) and not ( self.options.excluded_location_behavior == "do_not_randomize" and data.name in self.all_excluded_locations @@ -1377,7 +1379,7 @@ def post_fill(self): ] # All items in the base game in approximately the order they appear - all_item_order = [ + all_item_order: List[DS3ItemData] = [ item_dictionary[location.default_item_name] for region in region_order # Shuffle locations within each region. @@ -1386,7 +1388,7 @@ def post_fill(self): ] # All DarkSouls3Items for this world that have been assigned anywhere, grouped by name - full_items_by_name = defaultdict(list) + full_items_by_name: Dict[str, List[DarkSouls3Item]] = defaultdict(list) for location in self.multiworld.get_filled_locations(): if location.item.player == self.player and ( location.player != self.player or self._is_location_available(location) @@ -1401,7 +1403,7 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: """ # Convert items to full DarkSouls3Items. - item_order = [ + converted_item_order: List[DarkSouls3Item] = [ item for item in ( ( # full_items_by_name won't contain DLC items if the DLC is disabled. @@ -1414,7 +1416,7 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: if item and item.code is not None ] - names = {item.name for item in item_order} + names = {item.name for item in converted_item_order} all_matching_locations = [ loc @@ -1426,10 +1428,10 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: # It's expected that there may be more total items than there are matching locations if # the player has chosen a more limited accessibility option, since the matching # locations *only* include items in the spheres of accessibility. - if len(item_order) < len(all_matching_locations): + if len(converted_item_order) < len(all_matching_locations): raise Exception( f"DS3 bug: there are {len(all_matching_locations)} locations that can " + - f"contain smoothed items, but only {len(item_order)} items to smooth." + f"contain smoothed items, but only {len(converted_item_order)} items to smooth." ) for sphere in locations_by_sphere: @@ -1442,7 +1444,7 @@ def smooth_items(item_order: List[Union[DS3ItemData, DarkSouls3Item]]) -> None: # Give offworld regions the last (best) items within a given sphere for location in onworld + offworld: - new_item = self._pop_item(location, item_order) + new_item = self._pop_item(location, converted_item_order) location.item = new_item new_item.location = location @@ -1480,8 +1482,8 @@ def _shuffle(self, seq: Sequence) -> List: def _pop_item( self, location: Location, - items: List[Union[DS3ItemData, DarkSouls3Item]] - ) -> Union[DS3ItemData, DarkSouls3Item]: + items: List[DarkSouls3Item] + ) -> DarkSouls3Item: """Returns the next item in items that can be assigned to location.""" for i, item in enumerate(items): if location.can_fill(self.multiworld.state, item, False): @@ -1490,6 +1492,9 @@ def _pop_item( # If we can't find a suitable item, give up and assign an unsuitable one. return items.pop(0) + def _get_our_locations(self) -> List[DarkSouls3Location]: + return cast(List[DarkSouls3Location], self.multiworld.get_locations(self.player)) + def fill_slot_data(self) -> Dict[str, object]: slot_data: Dict[str, object] = {} @@ -1516,7 +1521,7 @@ def fill_slot_data(self) -> Dict[str, object]: # A map from Archipelago's location IDs to the keys the static randomizer uses to identify # locations. location_ids_to_keys: Dict[int, str] = {} - for location in self.multiworld.get_filled_locations(self.player): + for location in cast(List[DarkSouls3Location], self.multiworld.get_filled_locations(self.player)): # Skip events and only look at this world's locations if (location.address is not None and location.item.code is not None and location.data.static):