Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,387 changes: 1,190 additions & 1,197 deletions sim/mage/frost/TestFrost.results

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion sim/mage/frost/frost_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func TestFrost(t *testing.T) {
Race: proto.Race_RaceTroll,
OtherRaces: []proto.Race{proto.Race_RaceOrc},

GearSet: core.GetGearSet("../../../ui/mage/frost/gear_sets", "p1_bis"),
GearSet: core.GetGearSet("../../../ui/mage/frost/gear_sets", "p5_bis"),
OtherGearSets: []core.GearSetCombo{
core.GetGearSet("../../../ui/mage/frost/gear_sets", "p1_prebis"),
},
Expand Down
7 changes: 4 additions & 3 deletions ui/core/components/suggest_reforges_action.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -457,9 +457,10 @@ export class ReforgeOptimizer {
const softCaps = StatCap.cloneSoftCaps(this.softCapsConfig);
for (const [unitStat, limit] of this.breakpointLimits.asUnitStatArray()) {
if (!limit) continue;
const config = softCaps.find(config => config.unitStat.equals(unitStat));
const breakpointLimitExists = config?.breakpoints.some(breakpoint => breakpoint == limit);
if (config && breakpointLimitExists) {
// A stat can have multiple configs (e.g. a SoftCap and a Threshold for the same stat), so apply the
// limit to whichever config actually owns that breakpoint rather than just the first matching stat.
for (const config of softCaps) {
if (!config.unitStat.equals(unitStat) || !config.breakpoints.some(breakpoint => breakpoint == limit)) continue;
config.breakpoints = config.breakpoints.filter(breakpoint => breakpoint <= limit);
if (config.capType === StatCapType.TypeSoftCap) {
config.postCapEPs = config.postCapEPs.slice(0, config.breakpoints.length);
Expand Down
2 changes: 1 addition & 1 deletion ui/core/constants/item_notices.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const ITEM_NOTICES = new Map<number, ItemNoticeData>([
},
]),

...[105150, 102310, 104652, 105399, 105648, 104901].map((itemID): [number, ItemNoticeData] => [
...[].map((itemID): [number, ItemNoticeData] => [
itemID,
[Spec.SpecFrostMage, Spec.SpecArcaneMage, Spec.SpecFireMage].reduce<ItemNoticeData>(
(acc, spec) => {
Expand Down
24 changes: 12 additions & 12 deletions ui/mage/frost/gear_sets/p5_bis.gear.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
{
"items": [
{ "id": 105647, "gems": [95347, 76694], "upgradeStep": "UpgradeStepTwo" },
{ "id": 105647, "gems": [95347, 76667], "upgradeStep": "UpgradeStepTwo" },
{ "id": 105465, "reforging": 138, "upgradeStep": "UpgradeStepTwo" },
{ "id": 99401, "enchant": 4806, "gems": [76694, 76694], "reforging": 147, "upgradeStep": "UpgradeStepTwo" },
{ "id": 102246, "enchant": 4892, "gems": [76694], "reforging": 144, "upgradeStep": "UpgradeStepTwo" },
{ "id": 99400, "enchant": 4419, "gems": [76694, 76694, 76694], "reforging": 145, "upgradeStep": "UpgradeStepTwo" },
{ "id": 105591, "enchant": 4414, "gems": [0], "reforging": 165, "upgradeStep": "UpgradeStepTwo" },
{ "id": 99397, "enchant": 4430, "gems": [76694, 76694, 0], "reforging": 144, "upgradeStep": "UpgradeStepTwo", "tinker": 4898 },
{ "id": 105515, "gems": [76694, 76682, 76694], "reforging": 167, "upgradeStep": "UpgradeStepTwo" },
{ "id": 99399, "enchant": 4895, "gems": [76672, 76668], "reforging": 145, "upgradeStep": "UpgradeStepTwo" },
{ "id": 105493, "enchant": 4429, "gems": [76668], "upgradeStep": "UpgradeStepTwo" },
{ "id": 99401, "enchant": 4806, "gems": [76667, 76667], "reforging": 147, "upgradeStep": "UpgradeStepTwo" },
{ "id": 102246, "enchant": 4892, "gems": [76667], "upgradeStep": "UpgradeStepTwo" },
{ "id": 99400, "enchant": 4419, "gems": [76667, 76667, 76667], "reforging": 144, "upgradeStep": "UpgradeStepTwo" },
{ "id": 105591, "enchant": 4414, "gems": [0], "upgradeStep": "UpgradeStepTwo" },
{ "id": 99397, "enchant": 4430, "gems": [76667, 76667, 0], "reforging": 147, "upgradeStep": "UpgradeStepTwo", "tinker": 4898 },
{ "id": 105515, "gems": [76672, 76636, 76700], "reforging": 138, "upgradeStep": "UpgradeStepTwo" },
{ "id": 99399, "enchant": 4895, "gems": [76700, 76700], "reforging": 145, "upgradeStep": "UpgradeStepTwo" },
{ "id": 105493, "enchant": 4429, "gems": [76700], "upgradeStep": "UpgradeStepTwo" },
{ "id": 105498, "reforging": 140, "upgradeStep": "UpgradeStepTwo" },
{ "id": 105606, "gems": [76694], "reforging": 165, "upgradeStep": "UpgradeStepTwo" },
{ "id": 105606, "gems": [76672], "upgradeStep": "UpgradeStepTwo" },
{ "id": 105422, "upgradeStep": "UpgradeStepTwo" },
{ "id": 105540, "upgradeStep": "UpgradeStepTwo" },
{ "id": 105627, "enchant": 4442, "gems": [76694], "reforging": 145, "upgradeStep": "UpgradeStepTwo" },
{ "id": 105650, "enchant": 4434, "gems": [76694], "upgradeStep": "UpgradeStepTwo" }
{ "id": 105627, "enchant": 4442, "gems": [76672], "reforging": 147, "upgradeStep": "UpgradeStepTwo" },
{ "id": 105650, "enchant": 4434, "gems": [76672], "reforging": 152, "upgradeStep": "UpgradeStepTwo" }
]
}
14 changes: 13 additions & 1 deletion ui/mage/frost/presets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ export const ROTATION_PRESET_AOE = PresetUtils.makePresetAPLRotation('AOE', Fros
// export const ROTATION_PRESET_CLEAVE = PresetUtils.makePresetAPLRotation('Cleave', FrostCleaveApl);

// Preset options for EP weights
export const P5_BIS_EP_PRESET = PresetUtils.makePresetEpWeights(
'Item Level >= 560',
Stats.fromMap({
[Stat.StatIntellect]: 1.31,
[Stat.StatSpellPower]: 1,
[Stat.StatHitRating]: 2.15,
[Stat.StatCritRating]: 0.77,
[Stat.StatHasteRating]: 0.75,
[Stat.StatMasteryRating]: 0.71,
}),
);

export const P3_BIS_EP_PRESET = PresetUtils.makePresetEpWeights(
'Item Level >= 517',
Stats.fromMap({
Expand All @@ -45,7 +57,7 @@ export const P1_BIS_EP_PRESET = PresetUtils.makePresetEpWeights(
Stats.fromMap({
[Stat.StatIntellect]: 1.26,
[Stat.StatSpellPower]: 1,
[Stat.StatHitRating]: 1.30,
[Stat.StatHitRating]: 1.3,
[Stat.StatCritRating]: 0.61,
[Stat.StatHasteRating]: 0.74,
[Stat.StatMasteryRating]: 0.52,
Expand Down
133 changes: 73 additions & 60 deletions ui/mage/frost/sim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const livingBombBreakpoints = [
mageBombBreakpoints.get('7-tick - Living Bomb')!,
mageBombBreakpoints.get('8-tick - Living Bomb')!,
];
const softcapBreakpoints = [mageBombBreakpoints.get('GCD Soft Cap')!];
const gcdCapBreakpoint = mageBombBreakpoints.get('GCD Soft Cap')!;
const netherTempestBreakpoints = [
mageBombBreakpoints.get('15-tick - Nether Tempest')!,
mageBombBreakpoints.get('16-tick - Nether Tempest')!,
Expand All @@ -37,16 +37,22 @@ const P2CritPostCapEPs = [
0.45 * Mechanics.CRIT_RATING_PER_CRIT_PERCENT,
0.35 * Mechanics.CRIT_RATING_PER_CRIT_PERCENT,
];

const P2HastePostCapEPs = [0.46 * Mechanics.HASTE_RATING_PER_HASTE_PERCENT, 0.44 * Mechanics.HASTE_RATING_PER_HASTE_PERCENT];
const P2HastePostCapEP = 0.46 * Mechanics.HASTE_RATING_PER_HASTE_PERCENT;

const P3CritPostCapEPs = [
0.51 * Mechanics.CRIT_RATING_PER_CRIT_PERCENT,
0.44 * Mechanics.CRIT_RATING_PER_CRIT_PERCENT,
0.38 * Mechanics.CRIT_RATING_PER_CRIT_PERCENT,
];
const P3HastePostCapEP = 0.48 * Mechanics.HASTE_RATING_PER_HASTE_PERCENT;

const P3HastePostCapEPs = [0.48 * Mechanics.HASTE_RATING_PER_HASTE_PERCENT, 0.46 * Mechanics.HASTE_RATING_PER_HASTE_PERCENT];
const P5CritPostCapEPs = [
0.76 * Mechanics.CRIT_RATING_PER_CRIT_PERCENT,
0.68 * Mechanics.CRIT_RATING_PER_CRIT_PERCENT,
0.57 * Mechanics.CRIT_RATING_PER_CRIT_PERCENT,
];
const P5HastePostCapEP = 0.66 * Mechanics.HASTE_RATING_PER_HASTE_PERCENT;
const P5HastePostGCDCapEP = 0.52 * Mechanics.HASTE_RATING_PER_HASTE_PERCENT;

const SPEC_CONFIG = registerSpecConfig(Spec.SpecFrostMage, {
cssClass: 'frost-mage-sim-ui',
Expand Down Expand Up @@ -76,18 +82,20 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecFrostMage, {

defaults: {
// Default equipped gear.
gear: Presets.P2_BIS.gear,
gear: Presets.P5_BIS.gear,
// Default EP weights for sorting gear in the gear picker.
epWeights: Presets.P1_BIS_EP_PRESET.epWeights,
epWeights: Presets.P5_BIS_EP_PRESET.epWeights,
statCaps: (() => {
return new Stats().withPseudoStat(PseudoStat.PseudoStatSpellHitPercent, 15);
})(),
// Default soft caps for the Reforge optimizer
softCapBreakpoints: (() => {
const hasteSoftCapBreakpoints = [...livingBombBreakpoints, gcdCapBreakpoint].sort((a, b) => a - b);
const hasteSoftCapConfig = StatCap.fromPseudoStat(PseudoStat.PseudoStatSpellHastePercent, {
breakpoints: [...livingBombBreakpoints, ...softcapBreakpoints],
capType: StatCapType.TypeThreshold,
postCapEPs: P2HastePostCapEPs,
breakpoints: hasteSoftCapBreakpoints,
capType: StatCapType.TypeSoftCap,
// Once the GCD soft cap is passed, the residual value of haste drops, so use the lower post-GCD EP.
postCapEPs: hasteSoftCapBreakpoints.map(breakpoint => (breakpoint >= gcdCapBreakpoint ? P5HastePostGCDCapEP : P5HastePostCapEP)),
});

const critSoftCapConfig = StatCap.fromPseudoStat(PseudoStat.PseudoStatSpellCritPercent, {
Expand Down Expand Up @@ -137,7 +145,7 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecFrostMage, {
},

presets: {
epWeights: [Presets.P1_PREBIS_EP_PRESET, Presets.P1_BIS_EP_PRESET, Presets.P3_BIS_EP_PRESET],
epWeights: [Presets.P1_PREBIS_EP_PRESET, Presets.P1_BIS_EP_PRESET, Presets.P3_BIS_EP_PRESET, Presets.P5_BIS_EP_PRESET],
// Preset rotations that the user can quickly select.
rotations: [Presets.ROTATION_PRESET_DEFAULT, Presets.ROTATION_PRESET_AOE],
// Preset talents that the user can quickly select.
Expand All @@ -159,29 +167,7 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecFrostMage, {
}
},

raidSimPresets: [
{
spec: Spec.SpecFrostMage,
talents: Presets.FrostDefaultTalents.data,
specOptions: Presets.DefaultFrostOptions,
consumables: Presets.DefaultConsumables,
otherDefaults: Presets.OtherDefaults,
defaultFactionRaces: {
[Faction.Unknown]: Race.RaceUnknown,
[Faction.Alliance]: Race.RaceAlliancePandaren,
[Faction.Horde]: Race.RaceOrc,
},
defaultGear: {
[Faction.Unknown]: {},
[Faction.Alliance]: {
1: Presets.P1_PREBIS.gear,
},
[Faction.Horde]: {
1: Presets.P1_PREBIS.gear,
},
},
},
],
raidSimPresets: [],
});

export class FrostMageSimUI extends IndividualSimUI<Spec.SpecFrostMage> {
Expand All @@ -192,43 +178,70 @@ export class FrostMageSimUI extends IndividualSimUI<Spec.SpecFrostMage> {
statSelectionPresets: [MAGE_BREAKPOINTS],
enableBreakpointLimits: true,
getEPDefaults: player => {
let epWeights = player.getEpWeights();
const avgIlvl = player.getGear().getAverageItemLevel(false);
if (avgIlvl >= 517) {
return Presets.P3_BIS_EP_PRESET.epWeights;

if (avgIlvl >= 560) {
epWeights = Presets.P5_BIS_EP_PRESET.epWeights;
} else if (avgIlvl >= 517) {
epWeights = Presets.P3_BIS_EP_PRESET.epWeights;
} else if (avgIlvl >= 500) {
return Presets.P1_BIS_EP_PRESET.epWeights;
epWeights = Presets.P1_BIS_EP_PRESET.epWeights;
} else {
epWeights = Presets.P1_PREBIS_EP_PRESET.epWeights;
}
return Presets.P1_PREBIS_EP_PRESET.epWeights;

const ampModifier = player.getTotalAmplificationTrinketStatModifier();
epWeights = epWeights
.withStat(Stat.StatHasteRating, epWeights.getStat(Stat.StatHasteRating) / ampModifier)
.withStat(Stat.StatMasteryRating, epWeights.getStat(Stat.StatMasteryRating) / ampModifier);

return epWeights;
},
updateSoftCaps: softCaps => {
const avgIlvl = player.getGear().getAverageItemLevel(false);

this.individualConfig.defaults.softCapBreakpoints!.forEach(softCap => {
const softCapToModify = softCaps.find(sc => sc.unitStat.equals(softCap.unitStat));
if (softCap.unitStat.equalsPseudoStat(PseudoStat.PseudoStatSpellHastePercent) && softCapToModify) {
const talents = player.getTalents();
if (talents.livingBomb) {
softCapToModify.breakpoints = [...livingBombBreakpoints, ...softcapBreakpoints];
} else if (talents.netherTempest) {
softCapToModify.breakpoints = [...netherTempestBreakpoints, ...softcapBreakpoints];
} else {
softCapToModify.breakpoints = softcapBreakpoints;
}
if (avgIlvl >= 517) {
softCapToModify.postCapEPs = P3HastePostCapEPs;
} else {
softCapToModify.postCapEPs = P2HastePostCapEPs;
}
const hasteSoftCap = softCaps.find(sc => sc.unitStat.equalsPseudoStat(PseudoStat.PseudoStatSpellHastePercent));
if (hasteSoftCap) {
const talents = player.getTalents();

let talentBreakpoints: number[] = [];
if (talents.livingBomb) {
talentBreakpoints = livingBombBreakpoints;
} else if (talents.netherTempest) {
talentBreakpoints = netherTempestBreakpoints;
}

let postCapEP: number;
let postGCDCapEP: number;
if (avgIlvl >= 560) {
postCapEP = P5HastePostCapEP;
postGCDCapEP = P5HastePostGCDCapEP;
} else if (avgIlvl >= 517) {
postCapEP = P3HastePostCapEP;
postGCDCapEP = P3HastePostCapEP;
} else {
postCapEP = P2HastePostCapEP;
postGCDCapEP = P2HastePostCapEP;
}

if (softCap.unitStat.equalsPseudoStat(PseudoStat.PseudoStatSpellCritPercent) && softCapToModify) {
if (avgIlvl >= 517) {
softCapToModify.postCapEPs = P3CritPostCapEPs;
} else {
softCapToModify.postCapEPs = P2CritPostCapEPs;
}
const breakpoints = [...talentBreakpoints, gcdCapBreakpoint].sort((a, b) => a - b);
hasteSoftCap.breakpoints = breakpoints;
// Once the GCD soft cap is passed, the residual value of haste drops, so use the lower post-GCD EP.
hasteSoftCap.postCapEPs = breakpoints.map(breakpoint => (breakpoint >= gcdCapBreakpoint ? postGCDCapEP : postCapEP));
}

const critSoftCap = softCaps.find(sc => sc.unitStat.equalsPseudoStat(PseudoStat.PseudoStatSpellCritPercent));
if (critSoftCap) {
if (avgIlvl >= 560) {
critSoftCap.postCapEPs = P5CritPostCapEPs;
} else if (avgIlvl >= 517) {
critSoftCap.postCapEPs = P3CritPostCapEPs;
} else {
critSoftCap.postCapEPs = P2CritPostCapEPs;
}
});
}

return softCaps;
},
});
Expand Down
4 changes: 2 additions & 2 deletions ui/warlock/affliction/sim.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecAfflictionWarlock, {

defaults: {
// Default equipped gear.
gear: Presets.P3_PRESET.gear,
gear: Presets.P5_PRESET.gear,

// Default EP weights for sorting gear in the gear picker.
epWeights: Presets.P2_BIS_EP_PRESET.epWeights,
epWeights: Presets.P5_BIS_EP_PRESET.epWeights,
// Default stat caps for the Reforge optimizer
statCaps: (() => {
return new Stats().withPseudoStat(PseudoStat.PseudoStatSpellHitPercent, 15);
Expand Down
Loading