Skip to content

Commit 89fbfcf

Browse files
authored
Merge pull request #295 from Trantion897/Add-initiative-ties-resolution-setting
Add initiative ties resolution setting
2 parents ace0a20 + 340a340 commit 89fbfcf

File tree

6 files changed

+77
-15
lines changed

6 files changed

+77
-15
lines changed

src/settings/settings.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import {
2020
DEFAULT_UNDEFINED,
2121
EDIT,
2222
HP,
23-
INITIATIVE
23+
INITIATIVE,
24+
OVERFLOW_TYPE,
25+
RESOLVE_TIES
2426
} from "../utils";
2527
import { RpgSystemSetting, getRpgSystem } from "../utils/rpg-system";
2628
import type { Party } from "./settings.types";
@@ -209,10 +211,10 @@ export default class InitiativeTrackerSettings extends PluginSettingTab {
209211
"Set what happens to healing which goes above creatures' max HP threshold."
210212
)
211213
.addDropdown((d) => {
212-
d.addOption("ignore", "Ignore");
213-
d.addOption("temp", "Add to temp HP");
214-
d.addOption("current", "Add to current HP");
215-
d.setValue(this.plugin.data.hpOverflow ?? "ignore");
214+
d.addOption(OVERFLOW_TYPE.ignore, "Ignore");
215+
d.addOption(OVERFLOW_TYPE.temp, "Add to temp HP");
216+
d.addOption(OVERFLOW_TYPE.current, "Add to current HP");
217+
d.setValue(this.plugin.data.hpOverflow ?? OVERFLOW_TYPE.ignore);
216218
d.onChange(async (v) => {
217219
this.plugin.data.hpOverflow = v;
218220
this.plugin.saveSettings();
@@ -329,6 +331,21 @@ export default class InitiativeTrackerSettings extends PluginSettingTab {
329331
this.display();
330332
});
331333
});
334+
new Setting(additionalContainer)
335+
.setName("Resolve Initiative Ties")
336+
.setDesc(
337+
"Define what happens if two creatures have the same initiative."
338+
)
339+
.addDropdown((d) => {
340+
d.addOption(RESOLVE_TIES.playerFirst, "Player first");
341+
d.addOption(RESOLVE_TIES.npcFirst, "NPC first");
342+
d.addOption(RESOLVE_TIES.random, "Random");
343+
d.setValue(this.plugin.data.resolveTies ?? RESOLVE_TIES.playerFirst);
344+
d.onChange(async (v) => {
345+
this.plugin.data.resolveTies = v;
346+
this.plugin.saveSettings();
347+
});
348+
});
332349
}
333350
private _displayPlayers(additionalContainer: HTMLDetailsElement) {
334351
additionalContainer.empty();

src/settings/settings.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export interface InitiativeTrackerData {
3939
warnedAboutImports: boolean;
4040
logging: boolean;
4141
logFolder: string;
42+
resolveTies: string;
4243
useLegacy: boolean;
4344
diplayPlayerHPValues: boolean;
4445
rollHP: boolean;

src/tracker/stores/tracker.ts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import type { InitiativeTrackerData } from "src/settings/settings.types";
1515
import type { InitiativeViewState } from "../view.types";
1616
import {
1717
OVERFLOW_TYPE,
18+
RESOLVE_TIES,
1819
RollPlayerInitiativeBehavior,
1920
getRpgSystem
2021
} from "src/utils";
@@ -96,7 +97,7 @@ function createTracker() {
9697
return data.descending;
9798
});
9899
let _settings: InitiativeTrackerData | null;
99-
100+
100101
const condensed = derived(creatures, (values) => {
101102
if (_settings?.condense) {
102103
values.forEach((creature, _, arr) => {
@@ -117,9 +118,40 @@ function createTracker() {
117118
const ordered = derived([condensed, data], ([values, data]) => {
118119
const sort = [...values];
119120
sort.sort((a, b) => {
120-
return data.descending
121+
/* Order creatures in this order:
122+
1. By initiative
123+
2. By manual order (drag & drop)
124+
3. According to the resolveTies setting */
125+
if (a.initiative != b.initiative) {
126+
return data.descending
121127
? b.initiative - a.initiative
122128
: a.initiative - b.initiative;
129+
}
130+
131+
if (
132+
a.manualOrder !== null && a.manualOrder !== undefined &&
133+
b.manualOrder !== null && b.manualOrder !== undefined &&
134+
a.manualOrder !== b.manualOrder
135+
) {
136+
const aOrder = a.manualOrder || 0;
137+
const bOrder = b.manualOrder || 0;
138+
return aOrder - bOrder;
139+
}
140+
141+
switch (_settings.resolveTies) {
142+
case RESOLVE_TIES.random:
143+
return Math.random() < 0.5 ? 1 : -1;
144+
case RESOLVE_TIES.playerFirst:
145+
case RESOLVE_TIES.npcFirst:
146+
const aPlayer = a.player ? 1 : 0;
147+
const bPlayer = b.player ? 1 : 0;
148+
if (_settings.resolveTies == RESOLVE_TIES.playerFirst) {
149+
return bPlayer - aPlayer
150+
} else {
151+
return aPlayer - bPlayer
152+
}
153+
}
154+
123155
});
124156
current_order = sort;
125157
return sort;
@@ -331,6 +363,7 @@ function createTracker() {
331363
creature.modifier
332364
);
333365
}
366+
creature.manualOrder = null;
334367
}
335368
return creatures;
336369
}

src/tracker/ui/creatures/Table.svelte

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@
5454
tracker.logNewInitiative(dropped.creature);
5555
}
5656
items = e.detail.items;
57-
$tracker = [...items.map(({ creature }) => creature)];
57+
$tracker = [...items.map(({ creature }, i) => {
58+
creature.manualOrder = i;
59+
return creature;
60+
})];
5861
}
5962
6063
const diceIcon = (node: HTMLElement) => {

src/utils/constants.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ export enum RollPlayerInitiativeBehavior {
1818
SetToZero
1919
}
2020

21+
export const OVERFLOW_TYPE: { [key: string]: string } = {
22+
ignore: "ignore",
23+
current: "current",
24+
temp: "temp"
25+
};
26+
27+
export const RESOLVE_TIES: { [key: string]: string } = {
28+
playerFirst: "playerFirst",
29+
npcFirst: "npcFirst",
30+
random: "random",
31+
};
32+
2133
export const DEFAULT_SETTINGS: InitiativeTrackerData = {
2234
players: [],
2335
parties: [],
@@ -54,11 +66,12 @@ export const DEFAULT_SETTINGS: InitiativeTrackerData = {
5466
player: true,
5567
builder: true
5668
},
57-
hpOverflow: "ignore",
69+
hpOverflow: OVERFLOW_TYPE.ignore,
5870
additiveTemp: false,
5971
rpgSystem: "dnd5e",
6072
logging: false,
6173
logFolder: "/",
74+
resolveTies: RESOLVE_TIES.playerFirst,
6275
useLegacy: false,
6376
diplayPlayerHPValues: true,
6477
rollHP: false,
@@ -71,12 +84,6 @@ export const DEFAULT_SETTINGS: InitiativeTrackerData = {
7184
rollPlayerInitiatives: RollPlayerInitiativeBehavior.Always
7285
};
7386

74-
export const OVERFLOW_TYPE: { [key: string]: string } = {
75-
ignore: "ignore",
76-
current: "current",
77-
temp: "temp"
78-
};
79-
8087
export const DECIMAL_TO_VULGAR_FRACTION: Record<string, string> = {
8188
0.125: "⅛",
8289
0.25: "¼",

src/utils/creature.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export class Creature {
3535
status: Set<Condition> = new Set();
3636
marker: string;
3737
initiative: number;
38+
manualOrder: number;
3839
static: boolean = false;
3940
source: string | string[];
4041
id: string;

0 commit comments

Comments
 (0)