Skip to content

GUI Filter Editor + Dynamic Ignore#2

Open
ansidian wants to merge 5 commits into
exCore2:ExileCore2from
ansidian:ExileCore2
Open

GUI Filter Editor + Dynamic Ignore#2
ansidian wants to merge 5 commits into
exCore2:ExileCore2from
ansidian:ExileCore2

Conversation

@ansidian

Copy link
Copy Markdown

Add a GUI editor for building stash filters, replacing the existing.

  • Visual condition-tree builder (and/or groups, nested conditions)
  • Item scanner: hover an item (inventory/stash/ground) and press a hotkey (default V)
    to pull its attributes into a discovery pool, then build conditions off it
  • Attribute catalog + query parser/compiler so the GUI and existing filters
    stay in sync

No changes to existing Stashie behavior


Also included in the PR: Dynamic Ignore

This was made before the GUI editor so this PR includes the following feature as well.

commit e43c71f, "dynamic item ignore with lock icon"

The editor's item scanner reuses one helper from it (DynamicIgnore.GetHoveredInventoryItem()), so excluding this will require some change:

  1. Move GetHoveredInventoryItem() and GetInventorySlotItems() out of
    Compartments/DynamicIgnore.cs into Compartments/ItemScanner.cs — they're
    self-contained (just find the inventory item under the cursor, no lock logic) —
    and update the call around ItemScanner.cs:47.
  2. Delete Compartments/DynamicIgnore.cs, Classes/ItemFingerprint.cs,
    images/lock.png.
  3. Compartments/FilterManager.cs: remove the DynamicIgnore.PruneToInventory(...)
    and DynamicIgnore.IsLocked(...) lines.
  4. Stashie.cs: remove the DynamicIgnore hotkey register + OnValueChanged, the
    lock.png InitImage block, the icon-corner ListNode setup, and
    DynamicIgnore.HandleHotkey() in Tick().
  5. StashieSettings.cs: remove the DynamicIgnore* settings and
    LockedItemFingerprints.
  6. Stashie.csproj: remove the images\lock.png ItemGroup.
image image image image

ansidian added 5 commits June 16, 2026 11:00
Lock an inventory item (configurable hotkey, default middle-click) to skip
it when stashing and mark it with a lock icon in any cell it occupies.

- DynamicIgnore: hotkey toggle, per-cell icon draw, stash-skip
- ItemFingerprint: stable per-item identity for locks
- locks are persisted across restarts and self-pruned against the live
  inventory at stash time so stale entries don't accumulate
- bundles images/lock.png and copies it to the output directory; falls
  back to a primitive marker if the texture is missing
Replaces hand-editing filter JSON with a visual editor that round-trips
losslessly to and from the raw query.

- condition model + attribute catalog + query compiler/parser for a
  non-destructive raw<->tree round-trip (raw fallback preserves anything
  the builder can't model)
- recursive AND/OR tree editor with per-node menus and arbitrary nesting,
  built on a pure ConditionTreeOps (wrap/convert/move/ungroup/delete)
- item scanner: grab hovered items (inventory/stash/ground) into a
  discovery pool and turn their mods into conditions
- debounced auto-save with live reload, per-column scrolling, defensive
  item reads
- stash-tab assignment keyed by stable filter Id, migrated from the
  name-keyed store
- scoped StashieTheme + Controls helpers
Auto-save (and the manual "Save Filter to File") only reloaded the
stashing engine's rules via LoadCustomFilters, not the stash-tab
assignment menu (GenerateTabMenu). New or renamed filters therefore did
not appear in the tab list until the manual "Reload config" button was
clicked.

Extract the button's two steps into StashieSettingsHandler.ReloadConfig
(LoadCustomFilters + GenerateTabMenu, guarded against a missing filter
file) and route the manual button, SaveCurrentFilter, and AutoSaveTick
through it, so auto-saved edits apply live without a manual reload.
Grabbed items now show a "stats" section in the filter-builder card with
one-click ">= current value" conditions:

- Scalars: Item Level and Quality (all items), Map Tier (waystones).
- Map reward block: Item Rarity, Item Quantity, Pack Size, Monster
  Rarity, Waystone Drop Chance, read from ItemData.ItemStats with clean
  tooltip labels.

IFL's query language is Dynamic LINQ, so stat conditions compile to the
indexer form `ItemStats[GameStat.X] >= N` -- GetValueOrDefault is an
unregistered extension and does not resolve. ItemStats is a
DefaultDictionary, so the bare indexer is eval-safe on items lacking the
key.

Only the "...FinalFromMap" reward stats are emitted; every other
ItemStats entry is a per-mod stat already shown in the mod list. Also
fixes the MapTier attribute DSL (now MapInfo.Tier), which previously
failed to compile and was silently pruned.
…dd Unidentified flag

Grabbed items held a live ItemData and re-read it every frame, so picking an item up right after grabbing reused its memory slot and turned mod values into garbage. Snapshot the chips into plain values, refresh only while the source entity's identity holds, and merge monotonically so a teardown read can never downgrade a good value.

Read mods directly from the live Mods component and isolate each mod read: a single mod whose .Translation throws no longer aborts the enumeration and drops every other mod on the item.

Add an "Unidentified" metadata flag (IsIdentified + notHas) for unidentified Magic/Rare/Unique items, alongside the existing "Identified".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant