Skip to content

Fix Trade Query influence filter: expose Ignore/Any and document pair semantics#9803

Draft
mcagnion wants to merge 5 commits intoPathOfBuildingCommunity:devfrom
mcagnion:bugfix/trade-query-influence-none
Draft

Fix Trade Query influence filter: expose Ignore/Any and document pair semantics#9803
mcagnion wants to merge 5 commits intoPathOfBuildingCommunity:devfrom
mcagnion:bugfix/trade-query-influence-none

Conversation

@mcagnion
Copy link
Copy Markdown
Contributor

@mcagnion mcagnion commented Apr 20, 2026

Description of the problem being solved:

The Trade Query popup's two Influence dropdowns only exposed None and the six named influences (Shaper, Elder, Warlord, Hunter, Crusader, Redeemer). There was no way to express "ignore this slot" (match anything) or "any influence" (require at least one). On top of that, the callback over-normalized several pair combinations (Ignore + None, None + specific, None + Any) back to None / None, so users who picked a meaningful pair that the query-state resolver actually supports would silently lose it — and users stuck at None / None had no way to return to an unfiltered pair.

This PR exposes Ignore and Any as first-class options, drops the UI-side normalization so every pair the user selects flows through to resolveInfluenceQueryState unchanged, and documents the nine distinct pair semantics on a shared tooltip grouped by the number of required influences. Same specific on both sides (e.g., Shaper / Shaper) is redundant at the item level, so the query state resolver treats the second slot as None — the pair now generates the same query as Shaper / None (exactly 1 of that type, pseudo_has_influence_count capped at 1).

Steps taken to verify a working solution:

  • Full busted suite green on the branch worktree (scripts/test-fast.sh --brief).
  • Targeted TestTradeQueryGenerator_spec.lua: 12 successes / 0 failures / 0 errors, including coverage for the Shaper + Shaper → Shaper + None query-state equivalence (exactCount, hasNoneConstraint, cost and needsHasInfluenceFilter all asserted equal to the paired form).
  • Manual verification in-game: tooltip renders correctly, all previously blocked pair states (Ignore / None, None / Any, None / <specific>, etc.) are now reachable and stable.

Before

before

After

after

mcagnion and others added 4 commits April 18, 2026 07:27
Port of bugfix/trade-query-influence-none onto current origin/dev.
Adapted to upstream PathOfBuildingCommunity#9691 changes: combined normalizeInfluenceSelections
with copyEldritch interaction, Watcher's Eye guard, SetSel pattern,
^7 label prefixes. Updated isSpecificInfluenceSelection check for
eldritch weight skip in ExecuteQuery.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The influence callback was over-normalizing Ignore+None and None+specific
pairs, forcing them back to None/None and locking users out of states the
query state resolver already supports (exactCount=1, exactCount=1 plus
that specific). Users stuck at None/None could not return to an
unfiltered pair.

Drop the UI normalization. The callback keeps only the eldritch
side-effect it was carrying. All pair combinations now flow through to
resolveInfluenceQueryState as intended.

Same specific on both sides (Shaper/Shaper) is redundant at the item
level, so resolveInfluenceQueryState treats the second slot as None:
the pair now generates the same query as Shaper/None (exactly 1 of that
type, pseudo_has_influence capped at 1). Without the None constraint the
duplicate specific would have silently produced a looser query than the
paired form. Test coverage added asserts state equality and query-cost
equality with the paired form.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add a shared tooltip on both Influence fields listing the nine distinct
pair semantics (no filter, no influences, exactly 1, at least 1, exactly
2, plus the specific variants). Ordered by the number of required
influences so users can scan to the constraint they want.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
"Cost" was the only occurrence of the term in this file: the rest of the
filter-budget path uses num_extra as the running count of structural
filter slots consumed before weighted mods fill the remainder. Align
with that convention: getInfluenceFilterCost becomes
countInfluenceFilters and the intermediate influenceFilterCost variable
is dropped in favour of a direct assignment to num_extra.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mcagnion mcagnion marked this pull request as draft April 20, 2026 23:56
The three helpers resolveInfluenceQueryState / needsHasInfluenceFilter /
countInfluenceFilters were each exported to the test mock so the spec
could assert on intermediate state. That surface tested the shape of the
computation rather than its outcome.

Introduce buildInfluenceFilters(selection1, selection2) that returns the
exact query fragments ExecuteQuery needs — the and-group filters, the
top-level NOT stats (only populated for "no influences"), and the total
filter-slot count. ExecuteQuery now computes the influence filters and
the slot budget in a single call and inlines the fragments, dropping
~20 lines of duplicated query-building logic.

Tests are rewritten to exercise the helper directly and assert on the
resulting filter table, giving genuine end-to-end coverage of the nine
pair combinations. Only _buildInfluenceFilters, _hasAnyInfluenceModId
and the INFLUENCE_*_INDEX constants remain as test accessors; the three
internal-state helpers are no longer reachable from outside the module.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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