diff --git a/sim/core/item_swaps.go b/sim/core/item_swaps.go
index cab1c886b5..9960876d0f 100644
--- a/sim/core/item_swaps.go
+++ b/sim/core/item_swaps.go
@@ -31,8 +31,9 @@ type ItemSwap struct {
}
/*
- TODO All the extra parameters here and the code in multiple places for handling the Weapon struct is really messy,
- we'll need to figure out something cleaner as this will be quite error-prone
+TODO All the extra parameters here and the code in multiple places for handling the Weapon struct is really messy,
+
+ we'll need to figure out something cleaner as this will be quite error-prone
*/
func (character *Character) EnableItemSwap(itemSwap *proto.ItemSwap, mhCritMultiplier float64, ohCritMultiplier float64, rangedCritMultiplier float64) {
items := getItems(itemSwap)
@@ -55,7 +56,7 @@ func (character *Character) RegisterOnItemSwap(callback OnSwapItem) {
character.ItemSwap.onSwapCallbacks = append(character.ItemSwap.onSwapCallbacks, callback)
}
-//Helper for handling Effects that use PPMManager to toggle the aura on/off
+// Helper for handling Effects that use PPMManager to toggle the aura on/off
func (swap *ItemSwap) RegisterOnSwapItemForEffectWithPPMManager(effectID int32, ppm float64, ppmm *PPMManager, aura *Aura) {
character := swap.character
character.RegisterOnItemSwap(func(sim *Simulation) {
@@ -74,7 +75,7 @@ func (swap *ItemSwap) RegisterOnSwapItemForEffectWithPPMManager(effectID int32,
}
-//Helper for handling Effects that use the effectID to toggle the aura on and off
+// Helper for handling Effects that use the effectID to toggle the aura on and off
func (swap *ItemSwap) ReigsterOnSwapItemForEffect(effectID int32, aura *Aura) {
character := swap.character
character.RegisterOnItemSwap(func(sim *Simulation) {
diff --git a/sim/hunter/pet_abilities.go b/sim/hunter/pet_abilities.go
index 46eb0a37cb..86936abd6e 100644
--- a/sim/hunter/pet_abilities.go
+++ b/sim/hunter/pet_abilities.go
@@ -75,7 +75,7 @@ func (ability *PetAbility) TryCast(sim *core.Simulation, target *core.Unit, hp *
return false
}
- hp.SpendFocus(sim, ability.Cost * hp.PseudoStats.CostMultiplier, ability.ActionID)
+ hp.SpendFocus(sim, ability.Cost*hp.PseudoStats.CostMultiplier, ability.ActionID)
ability.Cast(sim, target)
return true
}
diff --git a/sim/paladin/exorcism.go b/sim/paladin/exorcism.go
index 86b25a692b..099f4caec0 100644
--- a/sim/paladin/exorcism.go
+++ b/sim/paladin/exorcism.go
@@ -52,7 +52,7 @@ func (paladin *Paladin) registerExorcismSpell() {
bonusCrit := core.TernaryFloat64(
target.MobType == proto.MobType_MobTypeDemon || target.MobType == proto.MobType_MobTypeUndead,
- 100 * core.CritRatingPerCritChance,
+ 100*core.CritRatingPerCritChance,
0)
spell.BonusCritRating += bonusCrit
diff --git a/sim/shaman/shaman.go b/sim/shaman/shaman.go
index 465ff986fc..3863835728 100644
--- a/sim/shaman/shaman.go
+++ b/sim/shaman/shaman.go
@@ -125,7 +125,7 @@ type Shaman struct {
FlameShockDot *core.Dot
- MaelstromWeaponAura *core.Aura
+ MaelstromWeaponAura *core.Aura
}
// Implemented by each Shaman spec.
diff --git a/ui/core/components/base_modal.ts b/ui/core/components/base_modal.ts
index 46e8b07e6d..e500a474c2 100644
--- a/ui/core/components/base_modal.ts
+++ b/ui/core/components/base_modal.ts
@@ -3,41 +3,71 @@ import { Component } from './component';
import { Modal } from 'bootstrap';
+type ModalSize = 'sm' | 'md' | 'lg' | 'xl';
+
type BaseModalConfig = {
closeButton?: CloseButtonConfig,
+ // Whether or not to add a modal-footer element
+ footer?: boolean,
+ // Whether or not to add a modal-header element
header?: boolean,
+ // Whether or not to allow modal contents to extend past the screen height.
+ // When true, the modal is fixed to the screen height and body contents will scroll.
+ scrollContents?: boolean,
+ // Specify the size of the modal
+ size?: ModalSize,
+ // A title for the modal
+ title?: string | null,
};
const DEFAULT_CONFIG = {
closeButton: {},
+ footer: false,
header: true,
+ scrollContents: false,
+ size: 'lg' as ModalSize,
+ title: null,
}
export class BaseModal extends Component {
readonly config: BaseModalConfig;
readonly modal: Modal;
+ readonly dialog: HTMLElement;
readonly header: HTMLElement | undefined;
readonly body: HTMLElement;
+ readonly footer: HTMLElement | undefined;
- constructor(cssClass: string, config: BaseModalConfig = {}) {
- super(document.body, 'modal');
+ constructor(parent: HTMLElement, cssClass: string, config: BaseModalConfig = {}) {
+ super(parent, 'modal');
this.config = {...DEFAULT_CONFIG, ...config};
+ const modalSizeKlass = this.config.size && this.config.size != 'md' ? `modal-${this.config.size}` : '';
+
this.rootElem.classList.add('fade');
this.rootElem.innerHTML = `
-
+
`;
+ this.dialog = this.rootElem.querySelector('.modal-dialog') as HTMLElement;
+
+ if (this.config.scrollContents) {
+ this.dialog.classList.add('modal-overflow-scroll');
+ }
+
const container = this.rootElem.querySelector('.modal-content') as HTMLElement;
if (this.config.header) {
this.header = document.createElement('div');
this.header.classList.add('modal-header');
container.appendChild(this.header);
+
+ if (this.config.title) {
+ this.header.insertAdjacentHTML('afterbegin', `
${this.config.title}
`);
+ }
}
this.body = document.createElement('div');
@@ -46,6 +76,12 @@ export class BaseModal extends Component {
this.addCloseButton();
+ if (this.config.footer) {
+ this.footer = document.createElement('div');
+ this.footer.classList.add('modal-footer');
+ container.appendChild(this.footer);
+ }
+
this.modal = new Modal(this.rootElem);
this.open();
@@ -69,7 +105,9 @@ export class BaseModal extends Component {
this.rootElem.addEventListener('hide.bs.modal', () => {
const modals = this.rootElem.parentElement?.querySelectorAll('.modal') as NodeListOf
;
const siblingModals = Array.from(modals).filter((e) => e != this.rootElem);
- siblingModals[siblingModals.length - 1].style.zIndex = '1055';
+
+ if (siblingModals.length)
+ siblingModals[siblingModals.length - 1].style.zIndex = '1055';
});
this.modal.show();
diff --git a/ui/core/components/boolean_picker.ts b/ui/core/components/boolean_picker.ts
index ba965e8c6b..f83e806f87 100644
--- a/ui/core/components/boolean_picker.ts
+++ b/ui/core/components/boolean_picker.ts
@@ -16,10 +16,7 @@ export class BooleanPicker extends Input {
constructor(parent: HTMLElement, modObject: ModObject, config: BooleanPickerConfig) {
super(parent, 'boolean-picker-root', modObject, config);
- this.rootElem.classList.add(
- config.cssScheme ? `form-check-${config.cssScheme}` : 'form-check',
- 'form-check-reverse'
- );
+ this.rootElem.classList.add('form-check', 'form-check-reverse');
this.inputElem = document.createElement('input');
this.inputElem.type = 'checkbox';
diff --git a/ui/core/components/detailed_results.ts b/ui/core/components/detailed_results.ts
index 0694a36035..5021897555 100644
--- a/ui/core/components/detailed_results.ts
+++ b/ui/core/components/detailed_results.ts
@@ -211,50 +211,40 @@ export abstract class DetailedResults extends Component {
this.simUI?.sim.settingsChangeEmitter.on(async () => await this.updateSettings());
- const computedStyles = window.getComputedStyle(this.rootElem);
-
- const colorSettings = {
- mainTextColor: computedStyles.getPropertyValue('--main-text-color'),
- };
-
- Chart.defaults.color = colorSettings.mainTextColor;
+ Chart.defaults.color = 'white';
this.resultsFilter = new ResultsFilter({
parent: this.rootElem.getElementsByClassName('results-filter')[0] as HTMLElement,
resultsEmitter: this.resultsEmitter,
- colorSettings: colorSettings,
});
(Array.from(this.rootElem.getElementsByClassName('topline-results')) as Array).forEach(toplineResultsDiv => {
- new ToplineResults({ parent: toplineResultsDiv, resultsEmitter: this.resultsEmitter, colorSettings: colorSettings });
+ new ToplineResults({ parent: toplineResultsDiv, resultsEmitter: this.resultsEmitter });
});
- const castMetrics = new CastMetricsTable({ parent: this.rootElem.getElementsByClassName('cast-metrics')[0] as HTMLElement, resultsEmitter: this.resultsEmitter, colorSettings: colorSettings });
- const meleeMetrics = new MeleeMetricsTable({ parent: this.rootElem.getElementsByClassName('melee-metrics')[0] as HTMLElement, resultsEmitter: this.resultsEmitter, colorSettings: colorSettings });
- const spellMetrics = new SpellMetricsTable({ parent: this.rootElem.getElementsByClassName('spell-metrics')[0] as HTMLElement, resultsEmitter: this.resultsEmitter, colorSettings: colorSettings });
- const healingMetrics = new HealingMetricsTable({ parent: this.rootElem.getElementsByClassName('healing-spell-metrics')[0] as HTMLElement, resultsEmitter: this.resultsEmitter, colorSettings: colorSettings });
- const resourceMetrics = new ResourceMetricsTable({ parent: this.rootElem.getElementsByClassName('resource-metrics')[0] as HTMLElement, resultsEmitter: this.resultsEmitter, colorSettings: colorSettings });
- const playerDamageMetrics = new PlayerDamageMetricsTable({ parent: this.rootElem.getElementsByClassName('player-damage-metrics')[0] as HTMLElement, resultsEmitter: this.resultsEmitter, colorSettings: colorSettings }, this.resultsFilter);
+ const castMetrics = new CastMetricsTable({ parent: this.rootElem.getElementsByClassName('cast-metrics')[0] as HTMLElement, resultsEmitter: this.resultsEmitter });
+ const meleeMetrics = new MeleeMetricsTable({ parent: this.rootElem.getElementsByClassName('melee-metrics')[0] as HTMLElement, resultsEmitter: this.resultsEmitter });
+ const spellMetrics = new SpellMetricsTable({ parent: this.rootElem.getElementsByClassName('spell-metrics')[0] as HTMLElement, resultsEmitter: this.resultsEmitter });
+ const healingMetrics = new HealingMetricsTable({ parent: this.rootElem.getElementsByClassName('healing-spell-metrics')[0] as HTMLElement, resultsEmitter: this.resultsEmitter });
+ const resourceMetrics = new ResourceMetricsTable({ parent: this.rootElem.getElementsByClassName('resource-metrics')[0] as HTMLElement, resultsEmitter: this.resultsEmitter });
+ const playerDamageMetrics = new PlayerDamageMetricsTable({ parent: this.rootElem.getElementsByClassName('player-damage-metrics')[0] as HTMLElement, resultsEmitter: this.resultsEmitter }, this.resultsFilter);
const buffAuraMetrics = new AuraMetricsTable({
parent: this.rootElem.getElementsByClassName('buff-aura-metrics')[0] as HTMLElement,
resultsEmitter: this.resultsEmitter,
- colorSettings: colorSettings,
}, false);
const debuffAuraMetrics = new AuraMetricsTable({
parent: this.rootElem.getElementsByClassName('debuff-aura-metrics')[0] as HTMLElement,
resultsEmitter: this.resultsEmitter,
- colorSettings: colorSettings,
}, true);
- const dpsHistogram = new DpsHistogram({ parent: this.rootElem.getElementsByClassName('dps-histogram')[0] as HTMLElement, resultsEmitter: this.resultsEmitter, colorSettings: colorSettings });
+ const dpsHistogram = new DpsHistogram({ parent: this.rootElem.getElementsByClassName('dps-histogram')[0] as HTMLElement, resultsEmitter: this.resultsEmitter });
- const dtpsMeleeMetrics = new DtpsMeleeMetricsTable({ parent: this.rootElem.getElementsByClassName('dtps-melee-metrics')[0] as HTMLElement, resultsEmitter: this.resultsEmitter, colorSettings: colorSettings });
- const dtpsSpellMetrics = new DtpsSpellMetricsTable({ parent: this.rootElem.getElementsByClassName('dtps-spell-metrics')[0] as HTMLElement, resultsEmitter: this.resultsEmitter, colorSettings: colorSettings });
+ const dtpsMeleeMetrics = new DtpsMeleeMetricsTable({ parent: this.rootElem.getElementsByClassName('dtps-melee-metrics')[0] as HTMLElement, resultsEmitter: this.resultsEmitter });
+ const dtpsSpellMetrics = new DtpsSpellMetricsTable({ parent: this.rootElem.getElementsByClassName('dtps-spell-metrics')[0] as HTMLElement, resultsEmitter: this.resultsEmitter });
const timeline = new Timeline({
parent: this.rootElem.getElementsByClassName('timeline')[0] as HTMLElement,
cssScheme: cssScheme,
resultsEmitter: this.resultsEmitter,
- colorSettings: colorSettings,
});
document.getElementById('timelineTabTab')?.addEventListener('click', event => timeline.render());
@@ -376,19 +366,15 @@ export class EmbeddedDetailedResults extends DetailedResults {
const newTabBtn = document.createElement('div');
newTabBtn.classList.add('detailed-results-controls-div');
- newTabBtn.innerHTML = ``;
+ newTabBtn.innerHTML = ``;
this.rootElem.prepend(newTabBtn);
const computedStyles = window.getComputedStyle(this.rootElem);
const url = new URL(`${window.location.protocol}//${window.location.host}/${REPO_NAME}/detailed_results/index.html`);
- url.searchParams.append('cssScheme', simUI.cssScheme);
- url.searchParams.append('mainTextColor', computedStyles.getPropertyValue('--main-text-color').trim());
- url.searchParams.append('themeColorBackground', computedStyles.getPropertyValue('--theme-color-background').trim());
- url.searchParams.append('themeColorBackgroundRaw', computedStyles.getPropertyValue('--theme-color-background-raw').trim());
- url.searchParams.append('themeBackgroundImage', computedStyles.getPropertyValue('--theme-background-image').trim());
- url.searchParams.append('themeBackgroundOpacity', computedStyles.getPropertyValue('--theme-background-opacity').trim());
+ url.searchParams.append('cssClass', simUI.cssClass);
+
if (simUI.isIndividualSim()) {
url.searchParams.append('isIndividualSim', '');
this.rootElem.classList.add('individual-sim');
diff --git a/ui/core/components/detailed_results/color_settings.ts b/ui/core/components/detailed_results/color_settings.ts
index 53a479fa96..52c73b504b 100644
--- a/ui/core/components/detailed_results/color_settings.ts
+++ b/ui/core/components/detailed_results/color_settings.ts
@@ -1,7 +1,3 @@
-export type ColorSettings = {
- mainTextColor: string,
-};
-
export const actionColors: Array = [
'#dd9933',
'#67074e',
diff --git a/ui/core/components/detailed_results/result_component.ts b/ui/core/components/detailed_results/result_component.ts
index 0589468e93..30f4eba8a2 100644
--- a/ui/core/components/detailed_results/result_component.ts
+++ b/ui/core/components/detailed_results/result_component.ts
@@ -3,8 +3,6 @@ import { SimResult, SimResultFilter } from '../..//proto_utils/sim_result.js';
import { Component } from '../../components/component.js';
import { EventID, TypedEvent } from '../../typed_event.js';
-import { ColorSettings } from './color_settings.js';
-
export interface SimResultData {
eventID: EventID,
result: SimResult,
@@ -16,17 +14,13 @@ export interface ResultComponentConfig {
rootCssClass?: string,
cssScheme?: String | null,
resultsEmitter: TypedEvent,
- colorSettings: ColorSettings,
};
export abstract class ResultComponent extends Component {
- private readonly colorSettings: ColorSettings;
-
private lastSimResult: SimResultData | null;
constructor(config: ResultComponentConfig) {
super(config.parent, config.rootCssClass || '');
- this.colorSettings = config.colorSettings;
this.lastSimResult = null;
config.resultsEmitter.on((eventID, resultData) => {
diff --git a/ui/core/components/detailed_results/timeline.ts b/ui/core/components/detailed_results/timeline.ts
index 756bbf95b7..98ba3d3771 100644
--- a/ui/core/components/detailed_results/timeline.ts
+++ b/ui/core/components/detailed_results/timeline.ts
@@ -58,7 +58,7 @@ export class Timeline extends ResultComponent {
Timeline data visualizes only 1 sim iteration.
-
Sim 1 Iteration
+
Sim 1 Iteration