Skip to content

Bulk relation change compares against the wrong state's current relation #1663

Description

@barrulus

Describe the bug

When the "Change relations" dialog applies a relation to several states at once, it tests every selected state against the clicked row's current relation rather than each state's own.

changeRelation() (src/controllers/diplomacy-editor.ts:425) opens with:

if (newRelation === oldRelation) return;

but the Apply handler passes the same currentRelation for every selected state (:385):

for (const oid of objectIds) {
  changeRelation(subjectId, oid, currentRelation, newRelation);
}

where currentRelation came from the single row the dialog was opened from. When the selected states do not all share that relation, the no-op guard checks the wrong value: a state that already holds the target relation is rewritten anyway, and a duplicate entry is appended to the relations chronicle for something that did not change.

Steps to reproduce

  1. Generate any map and open the Diplomacy editor.
  2. Pick a row state S that is a Rival of the selected state, and note some third state T that is already an Ally of S.
  3. Click the relation cell on S's row to open "Change relations" (it opens with Rival as the current relation).
  4. Choose Ally, and tick both the selected state and T.
  5. Apply, then open the relations history.

Expected behavior

T was already an Ally of S, so it should be skipped and nothing about T written to the chronicle. Only the one genuine change should be recorded.

Actual behavior

Reproduced on a freshly generated 7-state map. Subject Fonebia; Flokham a Rival of it; Charland already an Ally of it. Applying "Ally" to both, from the row whose current relation was "Rival", with the chronicle cleared beforehand:

after:     2->1: "Ally"   (correct, genuine change)
           2->3: "Ally"   (unchanged value, but rewritten)
chronicle: ["Defence pact", "Fonebia entered into defensive pact with Flokham"]
           ["Defence pact", "Fonebia entered into defensive pact with Charland"]

The second entry is spurious — that pact already existed.

As a control, the same flow once both relations are "Ally" (so the row's current relation matches each selected state's actual relation) produces 0 chronicle entries, as expected. The guard itself is fine; the defect is specifically the mismatched oldRelation.

Suggested fix

Read each state's own current relation inside the loop:

changeRelation(subjectId, oid, pack.states[subjectId].diplomacy[oid], newRelation);

.map file

Not needed — reproduces on any freshly generated map.

System

  • Version: 1.147.1; code path confirmed present on current master
  • Browser: Chromium 151
  • OS: Linux

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions