Skip to content

Commit

Permalink
raidemulator: Minor tweaks and >8 player support (#550)
Browse files Browse the repository at this point in the history
  • Loading branch information
valarnin authored Jan 5, 2025
1 parent 3f5cbef commit 4fc0d14
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 29 deletions.
6 changes: 6 additions & 0 deletions ui/raidboss/emulator/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,9 @@ const emulatorLabels: Translation = {
ja: '無出力トリガーを隠す',
cn: '隐藏收集器',
},
' label[for=hideGeneral]': {
en: 'Hide General',
},
} as const;

const emulatorTooltips: Translation = {
Expand All @@ -366,6 +369,9 @@ const emulatorTooltips: Translation = {
ja: '出力がないトリガーを隠す',
cn: '隐藏没有输出的触发器',
},
'.triggerHideGeneral': {
en: 'Hide triggers that are not for a specific zone',
},
'.connectedIndicator': {
en: 'Connected to websocket',
de: 'Mit Websocket verbunden',
Expand Down
87 changes: 60 additions & 27 deletions ui/raidboss/emulator/ui/EmulatedPartyInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export default class EmulatedPartyInfo extends EventBus {
private $triggerInfo: HTMLElement;
private $triggerHideSkippedCheckbox: HTMLInputElement;
private $triggerHideCollectCheckbox: HTMLInputElement;
private $triggerHideGeneralCheckbox: HTMLInputElement;
private $triggerBar: HTMLElement;
private latestDisplayedState: number;
private currentPerspective?: string;
Expand All @@ -98,8 +99,14 @@ export default class EmulatedPartyInfo extends EventBus {
if (!(collector instanceof HTMLInputElement))
throw new UnreachableCode();
this.$triggerHideCollectCheckbox = collector;
const general = querySelectorSafe(document, '.triggerHideGeneral');
if (!(general instanceof HTMLInputElement))
throw new UnreachableCode();
this.$triggerHideGeneralCheckbox = general;
this.$triggerBar = querySelectorSafe(document, '.player-triggers');
this.latestDisplayedState = 0;

// @TODO: Maybe this could be dynamic in scale, or possibly show at least one of each role?
for (let i = 0; i < 8; ++i)
this.triggerBars[i] = querySelectorSafe(this.$triggerBar, `.player${i.toString()}`);

Expand Down Expand Up @@ -129,9 +136,14 @@ export default class EmulatedPartyInfo extends EventBus {
this.hideCollectorTriggers();
else
this.showCollectorTriggers();
if (this.$triggerHideGeneralCheckbox.checked)
this.hideGeneralTriggers();
else
this.showGeneralTriggers();
};
this.$triggerHideSkippedCheckbox.addEventListener('change', this.updateTriggerState);
this.$triggerHideCollectCheckbox.addEventListener('change', this.updateTriggerState);
this.$triggerHideGeneralCheckbox.addEventListener('change', this.updateTriggerState);

this.$triggerItemTemplate = getTemplateChild(document, 'template.trigger-item');
this.$playerInfoRowTemplate = getTemplateChild(document, 'template.player-info-row');
Expand Down Expand Up @@ -164,6 +176,18 @@ export default class EmulatedPartyInfo extends EventBus {
});
}

hideGeneralTriggers(): void {
this.$triggerInfo.querySelectorAll('.trigger-general').forEach((n) => {
n.classList.add('d-none');
});
}

showGeneralTriggers(): void {
this.$triggerInfo.querySelectorAll('.trigger-general').forEach((n) => {
n.classList.remove('d-none');
});
}

updatePartyInfo(emulator: RaidEmulator, timestamp: number): void {
const enc = emulator.currentEncounter;
if (!enc)
Expand Down Expand Up @@ -199,7 +223,7 @@ export default class EmulatedPartyInfo extends EventBus {
if (!isJobOrder(aJob) || !isJobOrder(bJob))
return 0;
return EmulatedPartyInfo.jobOrder.indexOf(aJob) - EmulatedPartyInfo.jobOrder.indexOf(bJob);
}).slice(0, 8);
});
document.querySelectorAll('.playerTriggerInfo').forEach((n) => {
n.remove();
});
Expand All @@ -209,37 +233,39 @@ export default class EmulatedPartyInfo extends EventBus {
const bar = this.triggerBars[i];
const combatant = tracker.combatants[id];
const perspective = encounter.perspectives[id];
if (!bar || !combatant || !perspective)
if (!combatant || !perspective)
throw new UnreachableCode();
const firstState = combatant.nextState(0);
this.displayedParty[id] = obj;
this.$partyInfo.append(obj.$rootElem);
this.$triggerInfo.append(obj.$triggerElem);
bar.classList.remove('tank');
bar.classList.remove('healer');
bar.classList.remove('dps');
if (firstState.Job) {
bar.classList.add(
Util.jobToRole(Util.jobEnumToJob(firstState.Job)),
);
}

const trimmedDuration = encounter.encounter.duration - encounter.encounter.initialOffset;

for (const trigger of perspective.triggers) {
if (
!trigger.status.executed ||
trigger.resolvedOffset > encounter.encounter.duration ||
trigger.resolvedOffset < encounter.encounter.initialOffset
)
continue;

const $e = cloneSafe(this.$triggerItemTemplate);
const adjustedOffset = trigger.resolvedOffset - encounter.encounter.initialOffset;
$e.style.left = `${(adjustedOffset / trimmedDuration * 100).toString()}%`;
const triggerId = trigger.triggerHelper.trigger.id ?? 'Unknown Trigger';
this.tooltips.push(new Tooltip($e, 'bottom', triggerId));
bar.append($e);
if (bar !== undefined) {
bar.classList.remove('tank');
bar.classList.remove('healer');
bar.classList.remove('dps');
if (firstState.Job) {
bar.classList.add(
Util.jobToRole(Util.jobEnumToJob(firstState.Job)),
);
}

const trimmedDuration = encounter.encounter.duration - encounter.encounter.initialOffset;

for (const trigger of perspective.triggers) {
if (
!trigger.status.executed ||
trigger.resolvedOffset > encounter.encounter.duration ||
trigger.resolvedOffset < encounter.encounter.initialOffset
)
continue;

const $e = cloneSafe(this.$triggerItemTemplate);
const adjustedOffset = trigger.resolvedOffset - encounter.encounter.initialOffset;
$e.style.left = `${(adjustedOffset / trimmedDuration * 100).toString()}%`;
const triggerId = trigger.triggerHelper.trigger.id ?? 'Unknown Trigger';
this.tooltips.push(new Tooltip($e, 'bottom', triggerId));
bar.append($e);
}
}
}

Expand Down Expand Up @@ -386,6 +412,13 @@ export default class EmulatedPartyInfo extends EventBus {
else
$trigger.classList.add('trigger-output');

// Could instead map the trigger via ID back to the trigger set and then check the zone info
// on the trigger set, but that's a lot of extra effort and overhead.
if (trigger.triggerHelper.trigger.filename !== '00-misc/general.ts')
$trigger.classList.add('trigger-not-general');
else
$trigger.classList.add('trigger-general');

$triggerContainer.append($trigger);
}

Expand Down
6 changes: 4 additions & 2 deletions ui/raidboss/raidemulator.html
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,15 @@ <h5 class="modal-title"></h5>
<input type="checkbox" name="hideCollector" class="triggerHideCollector translate" checked="checked" id="hideCollector">
<label for="hideCollector"></label>
</div>
<div class="trigger-hide-collector-container translate" data-toggle="tooltip" title="">
<input type="checkbox" name="hideGeneral" class="triggerHideGeneral translate" checked="checked" id="hideGeneral">
<label for="hideGeneral"></label>
</div>
<div style="clear: both"></div>
</div>
</div>
<div class="col-2 party-info-column">
<div class="d-flex flex-column flex-fill">
<div style="height: calc(16.666667vw - 30px)" class="p-1 map">
</div>
<div class="flex-fill party"></div>
</div>
</div>
Expand Down

0 comments on commit 4fc0d14

Please sign in to comment.