SL2 Analyzer
Read a FromSoftware .sl2 save and report what is in it
Loading...
Searching...
No Matches
ds3.py File Reference

Go to the source code of this file.

Namespaces

namespace  sl2
 
namespace  sl2.ds3
 

Functions

 sl2.ds3.load_ds3_ring_effects (base_dir)
 
 sl2.ds3.ds3_ring_level (name)
 Split an equipped ring name into its table key and reinforcement level.
 
 sl2.ds3.ds3_attach_ring_effects (ch, base_dir)
 Attach each equipped ring's documented effect, and the subset of those effects that is a structured modifier to a derived stat.
 
 sl2.ds3.ds3_ring_bonuses (ring_mods)
 Sum the worn rings' structured modifiers.
 
 sl2.ds3.ds3_derived_stats (stats, ring_mods=None)
 DS3 base derived stats that are closed-form functions of attributes only, plus the worn rings' documented bonuses to those same three values.
 
 sl2.ds3.load_ds3_bonfires (base_dir)
 
 sl2.ds3.load_ds3_boss_flags (base_dir)
 
 sl2.ds3.load_ds3_boss_victory (base_dir)
 
 sl2.ds3.load_ds3_lord_cinders (base_dir)
 
 sl2.ds3.load_ds3_questlines (base_dir)
 
 sl2.ds3.load_ds3_pickups (base_dir)
 
 sl2.ds3.load_ds3_enemies (base_dir)
 
 sl2.ds3.load_ds3_npcs (base_dir)
 
 sl2.ds3.load_ds3_covenants (base_dir)
 
 sl2.ds3.load_ds3_endings (base_dir)
 
 sl2.ds3.ds3_goods_cat (iid)
 Refine a DS3 goods id to its finer category (see DS3_GOODS_RANGES).
 
 sl2.ds3.ds3_item_cat (iid, cat)
 Refine a scanned DS3 id's category.
 
 sl2.ds3.scan_inventory (buf, iddb)
 Find inventory by scanning for known item ids in fixed-size records.
 
 sl2.ds3.ds3_find_stats (buf)
 Locate the DS3 stat block by content, or None if none validates.
 
 sl2.ds3.ds3_embered (buf, v)
 DS3 embered state for a slot, or None.
 
 sl2.ds3.ds3_covenant (buf, v)
 DS3 covenant name for a slot, or None.
 
 sl2.ds3.ds3_resolve_weapon (iddb, iid)
 Resolve an equipped DS3 weapon id to a name, unwrapping the baked "+N".
 
 sl2.ds3.ds3_resolve_estus (iid)
 Resolve a DS3 goods id to an Estus flask name with its +N, or None.
 
 sl2.ds3.ds3_gaitem_map (buf)
 Map every GaItem handle to its item id by walking the GaItem array.
 
 sl2.ds3.ds3_equipped_weapons (buf, iddb, v)
 Equipped weapons (up to three per hand) from EquipGameData.
 
 sl2.ds3.ds3_equipped_armor (buf, iddb, v)
 Equipped armour (the four protection slots) from EquipGameData.
 
 sl2.ds3.ds3_equipped_rings (buf, iddb, v)
 Equipped rings (up to four) from EquipGameData.
 
 sl2.ds3.ds3_equipped_ammo (buf, iddb, v)
 Equipped ammunition (the arrow/bolt quiver slots) from EquipGameData.
 
 sl2.ds3.ds3_parse (buf, iddb, name)
 Parse one DS3 slot into the unified dict (full tier where stats validate).
 
 sl2.ds3.ds3_playtime (menu_data, i)
 
 sl2.ds3.ds3_event_flag_base (buf)
 Locate the DS3 event-flag region base in a decrypted slot, or None.
 
 sl2.ds3.ds3_attach_flags (ch, buf, base, base_dir)
 Read DS3 bonfires + boss-defeat flags off the event-flag region and attach them to ch: bonfire_areas as [(area, count, [names])] — every lit bonfire named from load_ds3_bonfires — and merge flag boss evidence into ch["bosses"] (deduping with any soul/gate evidence already there, from both the per-map and the group-6 victory tables), cinders as the Lords of Cinder whose ashes are on the throne, and endings as the endings this character has reached (cumulative, so an NG+ save can hold several).
 
 sl2.ds3.ds3_journey (buf, base)
 

Variables

tuple sl2.ds3.DS3_SLOT_BREAKS = (10, 14, 18, 24, 30, 40, 50, 60, 80, 99)
 DS3 attunement-slot breakpoints (fextralife Attunement table): the nth entry is the ATN needed for the nth spell slot.
 
dict sl2.ds3._DS3_RING_CACHE = {}
 Load db_ds3/ring_effects.json: ring name → {"effect": [lines], "mods": {level: {stat: value}}}.
 
dict sl2.ds3._DS3_BONFIRE_CACHE = {}
 Load the DS3 bonfire table (db_ds3/bonfires.json): area → list of [distance, bit, name], one entry per bonfire.
 
dict sl2.ds3._DS3_BOSS_CACHE = {}
 Load the DS3 boss-defeat flag table (db_ds3/boss_flags.json): boss name → [distance, bit] of its single "boss dead" event flag (the 13xxxx8xx per-map flag).
 
dict sl2.ds3._DS3_VICTORY_CACHE = {}
 Load the DS3 boss-victory flag table (db_ds3/boss_victory.json): boss name → [distance, bit] of its 63xx "boss victory" event flag, a SECOND independent kill signal that survives the soul being consumed.
 
dict sl2.ds3._DS3_CINDER_CACHE = {}
 Load the DS3 Lords-of-Cinder table (db_ds3/lord_cinders.json): lord name → [distance, bit] of the flag set when that lord's Cinders are placed on the Firelink throne.
 
dict sl2.ds3._DS3_QUEST_CACHE = {}
 Load the DS3 NPC-questline table (db_ds3/questlines.json): NPC/source → list of [distance, bit, reward] — one per reward that NPC hands out, each a "you received this" event flag in the common group 50006.
 
dict sl2.ds3._DS3_PICKUP_CACHE = {}
 Load the DS3 world item-pickup table (db_ds3/item_pickups.json): area → list of [distance, bit, item] — one per one-off item lying in that area, each a "you picked this up" event flag in the world groups 533xx–540xx.
 
dict sl2.ds3._DS3_ENEMY_CACHE = {}
 Load the one-time-enemy table (db_ds3/enemies.json): area → list of [distance, bit, enemy type] — one per enemy that does not respawn and whose death DS3 therefore has to remember.
 
dict sl2.ds3._DS3_NPC_CACHE = {}
 Load the DS3 NPC-state table (db_ds3/npcs.json): family → [[distance, bit, label]] — NPCs killed, NPCs turned hostile, questline states.
 
dict sl2.ds3._DS3_COV_CACHE = {}
 Load the DS3 covenant table (db_ds3/covenants.json, {covenant: [[region distance, bit, what it proves]]}).
 
dict sl2.ds3._DS3_ENDING_CACHE = {}
 Load the DS3 endings table (db_ds3/endings.json): ending name → [distance, bit].
 
 sl2.ds3.DS3_RECORD
 DS3 held-item record size and the offset of the quantity within it.
 
 sl2.ds3.DS3_QTY_OFF
 DS3 held-item record size and the offset of the quantity within it.
 
 sl2.ds3.DS3_STAT_D
 DS3 stat block as signed distances from the Vigor field (the anchor).
 
 sl2.ds3.DS3_HP_D
 DS3 max HP, FP, stamina, soul level and souls, same anchor-relative scheme.
 
 sl2.ds3.DS3_FP_D
 DS3 max HP, FP, stamina, soul level and souls, same anchor-relative scheme.
 
 sl2.ds3.DS3_STAM_D
 DS3 max HP, FP, stamina, soul level and souls, same anchor-relative scheme.
 
 sl2.ds3.DS3_LEVEL_D
 DS3 max HP, FP, stamina, soul level and souls, same anchor-relative scheme.
 
 sl2.ds3.DS3_SOULS_D
 DS3 max HP, FP, stamina, soul level and souls, same anchor-relative scheme.
 
int sl2.ds3.DS3_EMBER_D = 188
 DS3 embered flag: a lone uint8 at +188 in the stat-mirror struct behind the stat anchor — 1 = embered, 0 = hollow.
 
int sl2.ds3.DS3_COVENANT_D = 3944
 DS3 covenant: a uint32 EQUIP HANDLE at +3944 from the stat anchor, not a small enum — the game models the covenant as a worn accessory, so the field holds 0xA00027xx and the covenant's own item id is the low 28 bits (Rosaria's Fingers 0xA0002760 -> 10080).
 
dict sl2.ds3.DS3_COVENANT
 
int sl2.ds3.DS3_LEVEL_BASE = 89
 DS3's soul-level identity: level == (sum of all nine attributes) - 89.
 
int sl2.ds3.SCAN_MIN_RUN = 3
 Shortest run of consecutive records that counts as real inventory.
 
int sl2.ds3.DS3_MAX_RUN_GAP = 48
 Largest gap (bytes) a run may bridge.
 
int sl2.ds3.DS3_GOODS_ID_BASE = 0x40000000
 DS3 goods ids carry a type prefix (0x40000000); the real id is what the game's own EquipParamGoods table uses, and it blocks out cleanly by kind.
 
tuple sl2.ds3.DS3_GOODS_RANGES
 
dict sl2.ds3.DS3_GOODS_OVERRIDE
 The two flask upgrades that sit in the key-item block but are materials.
 
 sl2.ds3.DS3_AMMO_LO
 Where ammunition lives in the weapon id space.
 
 sl2.ds3.DS3_AMMO_HI
 Where ammunition lives in the weapon id space.
 
int sl2.ds3.DS3_EQUIP_D = 664
 EquipGameData sits a fixed 664 bytes past the stat (Vigor) anchor — invariant across saves whose anchor itself moves (56124..75156 on the Joy ladder), so it is read at a fixed anchor-relative offset, not searched for.
 
 sl2.ds3.DS3_ARMOR_SLOTS
 Armour sub-offsets inside EquipGameData (base +0x20..+0x2C), in the game's own head-to-toe order.
 
tuple sl2.ds3.DS3_RING_SLOTS = (0x34, 0x38, 0x3C, 0x40)
 The four ring sub-offsets inside EquipGameData (base +0x34..+0x40).
 
tuple sl2.ds3.DS3_AMMO_SLOTS = (0x08, 0x0C, 0x10, 0x14)
 The ammo sub-offsets (Arrow 1 / Bolt 1 / Arrow 2 / Bolt 2) at base +0x08..+0x14 — GaItem handles like weapons/armour (arrows and bolts share the db's bolts category).
 
 sl2.ds3.DS3_WEAPON_SLOTS
 The six weapon sub-offsets, in the game's own two-hand-by-slot order.
 
int sl2.ds3.DS3_FISTS = 110000
 Item id of the default bare fist (an empty weapon slot reads this, not a null handle), so a slot resolving to it is skipped as "unarmed".
 
int sl2.ds3.DS3_REINF_MAX = 10
 Max reinforcement level, a sanity bound on the id-baked "+N".
 
int sl2.ds3.DS3_GOODS_TYPE = 0x40000000
 The two Estus flasks' base goods ids, and the reinforcement ceiling.
 
tuple sl2.ds3.DS3_ESTUS = ((150, "Estus Flask"), (190, "Ashen Estus Flask"))
 
int sl2.ds3.DS3_ESTUS_MAX = 10
 
int sl2.ds3.DS3_RING_ID_MASK = 0x0FFFFFFF
 A ring's equip handle encodes its own id: the low 28 bits are shared and the type nibble is 0xA where the goods/ring id's is 0x2 — so the id is the handle with its top nibble rewritten to 2 (verified 4/4 on the Joy ring set: 0xa0004e20 → 0x20004e20 = Life Ring, etc.).
 
int sl2.ds3.DS3_RING_ID_TYPE = 0x20000000
 
dict sl2.ds3.DS3_DB_FILES
 DS3 id-scan tables: filename stem to category.
 
int sl2.ds3.DS3_ROSTER_PLAYTIME_OFF = 38
 Play time (seconds, uint32) inside slot i's DS3 roster descriptor.
 
int sl2.ds3.DS3_GAITEM_START = 0x6C
 
int sl2.ds3.DS3_GAITEM_SLOTS = 6144
 
int sl2.ds3.DS3_GAITEM_BIG = 60
 
tuple sl2.ds3.DS3_GAITEM_TYPES_BIG = (0x80000000, 0x90000000)
 
float sl2.ds3.DS3_FLAG_MAX_DENSITY = 0.01
 
int sl2.ds3.DS3_FLAG_SAMPLE = 0x8000
 
int sl2.ds3.DS3_NG_MAX = 99
 DS3 New Game+ cycle (journey count), a uint16 just before the event-flag region, or None.