Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stat Ratings Refactor #883

Merged
merged 80 commits into from
Aug 18, 2024
Merged
Show file tree
Hide file tree
Changes from 78 commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
3440160
Committing only the proposed high-level structural changes to Stat /
NerdEgghead Jul 28, 2024
c050603
Merge branch 'master' into stats_refactor
NerdEgghead Jul 28, 2024
53b1475
Merge branch 'master' into stats_refactor
NerdEgghead Jul 29, 2024
b272919
Allow back-end Stats arrays to be larger than the arrays used in proto
NerdEgghead Jul 30, 2024
d371820
Migrated stats package to new schema
NerdEgghead Jul 30, 2024
d92eecd
Changed probability representation for tertiary stats to percentage
NerdEgghead Jul 30, 2024
7a6916a
Migrated base stats parser to new schema
NerdEgghead Jul 30, 2024
50ad8f6
Renamed Rating <--> Percent conversion constants for clarity, and
NerdEgghead Jul 30, 2024
66b3cac
Re-named BaseDodge and BaseParry PseudoStats to make their units
NerdEgghead Jul 30, 2024
a6d9434
Fixed typo in PhysicalHitRating PseudoStat name.
NerdEgghead Jul 30, 2024
2b75288
Changed PseudoStats for bonus Hit/Crit taken to also be in percentage
NerdEgghead Jul 31, 2024
a7fde60
Removed deprecated BonusCritRatingTaken PseudoStat, since no Cata
NerdEgghead Jul 31, 2024
3386ce7
Changed BonusHitRating and BonusCritRating Spell properties to
NerdEgghead Jul 31, 2024
cd58a7c
Renamed ExpertisePercentage() helper to DodgeParrySuppression(), in
NerdEgghead Jul 31, 2024
f51d321
Removed BonusMeleeHitPercentTaken and BonusSpellHitPercentTaken
NerdEgghead Jul 31, 2024
e7628af
Renamed stats.FromFloatArray() to stats.FromProtoArray() and
NerdEgghead Jul 31, 2024
ebe4c8f
Implemented universal stat dependencies between HitRating / CritRating
NerdEgghead Jul 31, 2024
1584671
Removed deprecated CharacterStatsTest() and StatWeightsTest() utility
NerdEgghead Aug 1, 2024
e9ed34e
Cleaned up GetHighestStat() utility functions, and removed the redundant
NerdEgghead Aug 1, 2024
0993e14
Finished migrating core package to new schema
NerdEgghead Aug 1, 2024
f73b255
Merge branch 'master' into stats_refactor
NerdEgghead Aug 1, 2024
e9a4527
Migrated warrior package
NerdEgghead Aug 1, 2024
6ae6a21
Migrated druid package
NerdEgghead Aug 1, 2024
9dc603e
Migrated warlock package
NerdEgghead Aug 2, 2024
e356c36
Migrated paladin package
NerdEgghead Aug 2, 2024
473c7d5
Migrated death_knight package
NerdEgghead Aug 2, 2024
d394dbd
Merge branch 'master' into stats_refactor
NerdEgghead Aug 2, 2024
f9d7859
Migrated rogue package
NerdEgghead Aug 2, 2024
19f5673
Migrated mage package
NerdEgghead Aug 2, 2024
eabb674
Merge branch 'master' into stats_refactor
NerdEgghead Aug 4, 2024
9e5395f
Migrated shaman package
NerdEgghead Aug 5, 2024
9f0665f
Migrated priest package
NerdEgghead Aug 5, 2024
3570c4f
Migrated encounters package
NerdEgghead Aug 5, 2024
1f3c0aa
Migrated common package
NerdEgghead Aug 5, 2024
79ba1d3
Migrated hunter package
NerdEgghead Aug 5, 2024
00e4c01
Switch to percentage units for tertiary PseudoStats in the front-end, in
NerdEgghead Aug 5, 2024
ae6a8b9
Renamed UnitStat proto to UIStat for clarity
NerdEgghead Aug 5, 2024
987614a
Migrated DB generation code and re-built the database under the new
NerdEgghead Aug 6, 2024
b8845da
Merge branch 'master' into stats_refactor
NerdEgghead Aug 6, 2024
2223744
Fixed base Hot Streak proc chance calculation to match old value.
NerdEgghead Aug 6, 2024
96390e4
Fixed Hunter pet stat inheritance to match old calculation
NerdEgghead Aug 6, 2024
0cb7e02
Updated Warlock test files so they run
NerdEgghead Aug 6, 2024
ef4bee2
Updated spec sim test results. Aside from Demonology Warlock, the only
NerdEgghead Aug 6, 2024
7683b4c
Migrated remaining core test files so they run
NerdEgghead Aug 6, 2024
c7cdf29
Migrated old TBC effects code
NerdEgghead Aug 6, 2024
853dd8f
Removed equal length check in stats test, since SimStatsLen can now
NerdEgghead Aug 6, 2024
9d02ebf
Fixed missing factor of 100 in exported HastePercent PseudoStats
NerdEgghead Aug 6, 2024
b27a30c
Merge branch 'master' into stats_refactor
NerdEgghead Aug 6, 2024
377a9c1
Intentionally bugged PhysicalCritChance() calculation to match Curse of
NerdEgghead Aug 6, 2024
5d78cad
Fixed bug where Curse of Gul'dan is applying 0.1 Melee Crit Rating on
NerdEgghead Aug 6, 2024
464789e
Refactored front-end stats representations and conversion constants to
NerdEgghead Aug 8, 2024
562fa23
Added support for PseudoStat EP calculations in unit tests, and included
NerdEgghead Aug 8, 2024
eb77c1d
Moved PseudoStat EP test case from Guardian to Assassination for a
NerdEgghead Aug 8, 2024
5bf4482
Implemented logic to remove HitRating and CritRating from stat weights
NerdEgghead Aug 8, 2024
082c3ec
Added front-end logic to automatically add relevant school-specific
NerdEgghead Aug 8, 2024
f674616
Migrated all front-end spec sim config files
NerdEgghead Aug 8, 2024
cda2526
Merge branch 'master' into stats_refactor
NerdEgghead Aug 8, 2024
30c287d
Merge branch 'master' into stats_refactor
NerdEgghead Aug 8, 2024
9c7e62b
Changed statOrder constant to be an array of UnitStat objects rather
NerdEgghead Aug 8, 2024
e7ea24d
Migrated database.ts
NerdEgghead Aug 8, 2024
b3b5f1a
Migrated player.ts
NerdEgghead Aug 8, 2024
bcd583d
Created proper TypeScript class to facilitate operations on
NerdEgghead Aug 9, 2024
05b0b02
Migrated Suggest Reforges code and added additional UnitStat utilities
NerdEgghead Aug 10, 2024
c4dc9e4
Merge branch 'master' into stats_refactor
NerdEgghead Aug 15, 2024
485a626
Removed unused Suggest Gems code from WotLK. Even if we implement this
NerdEgghead Aug 15, 2024
c4cbaef
Migrated inputs modules
NerdEgghead Aug 15, 2024
ea8d86c
Migrated reforge_summary
NerdEgghead Aug 15, 2024
8807e02
Migrated gear_picker modules
NerdEgghead Aug 15, 2024
e7783df
Migrated exporters
NerdEgghead Aug 15, 2024
bf6a2ed
Migrated encounter_picker
NerdEgghead Aug 15, 2024
690e2df
Migrated character stats code, everything now compiles.
NerdEgghead Aug 15, 2024
a7bfd7e
Fixed circular imports between names.ts and stats.ts, and cleaned up
NerdEgghead Aug 15, 2024
ee1d349
Incremented API version, and implemented front-end migration functions
NerdEgghead Aug 16, 2024
a700108
Fixed two crashes associated with Reforge code: (1) implemented a
NerdEgghead Aug 16, 2024
fcdeb9d
Removed soft cap breakpoints from IndividualSimSettings proto, since
NerdEgghead Aug 16, 2024
1c31a45
Fixed a bug where Reforge variables were not being set, and cleaned up
NerdEgghead Aug 16, 2024
161576c
Hide Rating component of displayed stat strings when the value is 0,
NerdEgghead Aug 16, 2024
dcefef7
Display preset Reforge cap selections as % rather than Rating for
NerdEgghead Aug 16, 2024
ecc9f52
Fixed a bug with Bonus Stats migration from old links / presets.
NerdEgghead Aug 17, 2024
6d53502
Merge branch 'master' into stats_refactor
NerdEgghead Aug 18, 2024
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
Binary file modified assets/database/db.bin
Binary file not shown.
14,314 changes: 7,157 additions & 7,157 deletions assets/database/db.json

Large diffs are not rendered by default.

Binary file modified assets/database/leftover_db.bin
Binary file not shown.
58,764 changes: 29,382 additions & 29,382 deletions assets/database/leftover_db.json

Large diffs are not rendered by default.

137 changes: 96 additions & 41 deletions proto/common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ message ProtoVersion {
// protos need to define an api_version field so that the UI code knows
// to up-convert these protos to the new format whenever api_version is
// missing (0) or lower than current_version_number.
option (current_version_number) = 1;
option (current_version_number) = 2;

// The actual field value is only used within unit tests.
int32 saved_version_number = 1;
Expand Down Expand Up @@ -128,8 +128,46 @@ enum Profession {
Archeology = 12;
}

// Keep in sync with sim/core/stats/stats.go.
// NextIndex: 31;
// General rules for Stats vs. PseudoStats at the proto level:
// - Define a property as a Stat if and only if it needs to be present in
// one or more stats arrays embedded in the database files, local storage
// data, or sim links. This generally means that the property is a BASIC
// attribute that is directly found on items or enchants and parsed from
// tooltips during database generation. Alternatively, if the stat is
// required for reconstructing a target NPC from saved Encounter
// settings, then it also belongs in the Stat enum.
//
// - If the above criterion is not satisfied, then the best practice is to
// define the property as a PseudoStat rather than a Stat. For example,
// the various school-specific versions of Hit, Crit, and Haste are all
// defined as PseudoStats from Cataclysm onwards, since only the generic
// Ratings need to be parsed from item data and stored in the sim
// database.
//
// - Note that the above rules apply only for the proto messages used for
// saving and loading data in the browser. It is perfectly okay to define
// additional Stats in the back-end code for convenience or performance
// reasons, such as for automatically propagating linear stat
// dependencies when dynamic stat changes occur in a sim iteration. For
// example, the SpellHit PseudoStat mentioned above is actually modeled
// as a proper Stat in the back-end code so that it can benefit from the
// StatDependency tooling, but is converted to a PseudoStat when writing
// UnitStats protos for character stats and stat weights requests. This
// keeps the item database compact while still giving the UI access to
// calculated tertiary stats like SpellHit, MeleeCrit, RangedHaste, etc.
//
// - When adding new Stats or PseudoStats, make the units for each property
// explicit in the name to avoid confusion. For example, append "Rating"
// to the end of the field name for properties that are represented in
// Rating units (regardless of how they are stored in-game), and append
// "Chance" to the end of the field name for properties that represent
// probabilities (between 0 and 1).
//
// Keep in sync with sim/core/stats/stats.go. As mentioned above, it is okay for
// the Go Stats array to be larger than the size of the Stat enum proto, but the
// shared indices between the two must exactly match.
//
// NextIndex: 27;
enum Stat {
// Primary attributes ("main stat")
StatStrength = 0;
Expand All @@ -139,36 +177,34 @@ enum Stat {

// Reforge-able secondary stats
StatSpirit = 4;
StatMeleeHit = 5;
StatSpellHit = 6;
StatMeleeCrit = 7;
StatSpellCrit = 8;
StatMeleeHaste = 9;
StatSpellHaste = 10;
StatExpertise = 11;
StatDodge = 12;
StatParry = 13;
StatMastery = 14;
StatHitRating = 5;
StatCritRating = 6;
StatHasteRating = 7;
StatExpertiseRating = 8;
StatDodgeRating = 9;
StatParryRating = 10;
StatMasteryRating = 11;

// Non-reforge-able secondary stats found on gear
StatAttackPower = 15;
StatRangedAttackPower = 16;
StatSpellPower = 17;
StatMP5 = 18;
StatSpellPenetration = 19;
StatResilience = 20;
StatArcaneResistance = 21;
StatFireResistance = 22;
StatFrostResistance = 23;
StatNatureResistance = 24;
StatShadowResistance = 25;
StatArmor = 26; // "white armor" that fully scales with all multipliers
StatBonusArmor = 27; // "green armor" that does not scale

// Composite stats that are built up from the above gear stats + buffs
StatHealth = 28;
StatMana = 29;
StatBlock = 30;
StatAttackPower = 12;
StatRangedAttackPower = 13;
StatSpellPower = 14;
StatSpellPenetration = 15;
StatResilienceRating = 16;
StatArcaneResistance = 17;
StatFireResistance = 18;
StatFrostResistance = 19;
StatNatureResistance = 20;
StatShadowResistance = 21;
StatArmor = 22; // "white armor" that fully scales with all multipliers
StatBonusArmor = 23; // "green armor" that does not scale

// Composite stats that are built up from the above gear stats + buffs.
// These still belong in the Stat enum because they can be present on
// some enchants and because the base values need to be stored for NPCs.
StatHealth = 24;
StatMana = 25;
StatMP5 = 26;

// DO NOT add new stats here without discussing it first; new stats come
// with a performance penalty.
Expand Down Expand Up @@ -197,19 +233,38 @@ enum Stat {
}

// Not all pseudostats are included here; just the ones we want to pass
// between the UI and backend.
// between the UI and backend. It's also OK to include things here which aren't
// in the PseudoStats struct.
//
// It's also OK to include things here which aren't in the PseudoStats struct.
// NextIndex: 16;
enum PseudoStat {
PseudoStatMainHandDps = 0;
PseudoStatOffHandDps = 1;
PseudoStatRangedDps = 2;
PseudoStatBlockDamageReduction = 3;
PseudoStatDodge = 4;
PseudoStatParry = 5;
PseudoStatRangedSpeedMultiplier = 6;
PseudoStatMeleeSpeedMultiplier = 7;

// Final buffed values including DR, represented as percentages (0-100)
PseudoStatDodgePercent = 3;
PseudoStatParryPercent = 4;
PseudoStatBlockPercent = 5;

// Net impact of all multiplicative Haste buffs (Bloodlust etc.)
PseudoStatMeleeSpeedMultiplier = 6;
PseudoStatRangedSpeedMultiplier = 7;
PseudoStatCastSpeedMultiplier = 8;

// Final buffed Haste values after combining the above multipliers with
// Haste Rating from gear. Expressed in percentage units (0-100).
PseudoStatMeleeHastePercent = 9;
PseudoStatRangedHastePercent = 10;
PseudoStatSpellHastePercent = 11;

// School-specific fully buffed Hit/Crit stats, also in percentage
// units. These are modeled as proper Stats in the back-end due to stat
// dependencies, but do not need to be stored in any database files.
PseudoStatPhysicalHitPercent = 12;
PseudoStatSpellHitPercent = 13;
PseudoStatPhysicalCritPercent = 14;
PseudoStatSpellCritPercent = 15;
}

message UnitStats {
Expand All @@ -230,9 +285,9 @@ message UnitStats {
}

message ReforgeStat {
int32 id = 1;
repeated Stat fromStat = 2;
repeated Stat toStat = 3;
int32 id = 1;
Stat fromStat = 2;
Stat toStat = 3;
double multiplier = 4;
}

Expand Down
15 changes: 13 additions & 2 deletions proto/ui.proto
Original file line number Diff line number Diff line change
Expand Up @@ -318,11 +318,10 @@ message IndividualSimSettings {
Stat heal_ref_stat = 13;
Stat tank_ref_stat = 14;
UnitStats stat_caps = 15;
repeated StatCapConfig soft_cap_breakpoints = 16;
}

message StatCapConfig {
Stat stat = 1;
UIStat unit_stat = 1;

// Breakpoint values in ascending order
repeated double breakpoints = 2;
Expand All @@ -336,6 +335,18 @@ message StatCapConfig {
repeated double post_cap_EPs = 4;
}

// Represents a single attribute that is either a Stat or a PseudoStat.
// Currently used only within the StatCapConfig UI message for configuring Haste
1337LutZ marked this conversation as resolved.
Show resolved Hide resolved
// caps, and is therefore not versioned, since this message is not imported or
// exported from local storage or links.
message UIStat {
// Uniquely identifies the attribute
oneof unit_stat {
Stat stat = 1;
PseudoStat pseudo_stat = 2;
}
}

enum StatCapType {
TypeUnknown = 0;

Expand Down
8 changes: 4 additions & 4 deletions sim/common/cata/enchant_effects.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func init() {
return character.NewTemporaryStatsAura(
name,
core.ActionID{SpellID: 74221, Tag: tag},
stats.Stats{stats.MeleeHaste: 450, stats.SpellHaste: 450},
stats.Stats{stats.HasteRating: 450},
time.Second*12,
)
}
Expand Down Expand Up @@ -298,7 +298,7 @@ func init() {
statAura := character.NewTemporaryStatsAura(
"Windwalk Proc",
core.ActionID{SpellID: 74243},
stats.Stats{stats.Dodge: 600},
stats.Stats{stats.DodgeRating: 600},
time.Second*10,
)

Expand Down Expand Up @@ -456,15 +456,15 @@ func init() {

// Enchant: 4176, Item: 59595 - R19 Threatfinder
core.NewEnchantEffect(4176, func(agent core.Agent) {
agent.GetCharacter().AddBonusRangedHitRating(88)
agent.GetCharacter().AddBonusRangedHitPercent(88 / core.PhysicalHitRatingPerHitPercent)
})

// Enchant: 4177, Item: 59596 - Safety Catch Removal Kit
core.NewEnchantEffect(4177, func(agent core.Agent) {
character := agent.GetCharacter()
// TODO: This should be ranged-only haste. For now just make it hunter-only.
if character.Class == proto.Class_ClassHunter {
character.AddStats(stats.Stats{stats.MeleeHaste: 88, stats.SpellHaste: 88})
character.AddStat(stats.HasteRating, 88)
}
})

Expand Down
64 changes: 32 additions & 32 deletions sim/common/cata/other_effects.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ func init() {
Duration: time.Second * 20,
MaxStacks: 5,
OnStacksChange: func(aura *core.Aura, sim *core.Simulation, oldStacks, newStacks int32) {
deltaHaste := float64(321) * float64(newStacks-oldStacks)
character.AddStatsDynamic(sim, stats.Stats{stats.MeleeHaste: deltaHaste, stats.SpellHaste: deltaHaste})
deltaHasteRating := float64(321) * float64(newStacks-oldStacks)
character.AddStatDynamic(sim, stats.HasteRating, deltaHasteRating)
},
})

Expand Down Expand Up @@ -366,8 +366,8 @@ func init() {
Duration: time.Second * 20,
MaxStacks: 5,
OnStacksChange: func(aura *core.Aura, sim *core.Simulation, oldStacks, newStacks int32) {
deltaHaste := float64(363) * float64(newStacks-oldStacks)
character.AddStatsDynamic(sim, stats.Stats{stats.MeleeHaste: deltaHaste, stats.SpellHaste: deltaHaste})
deltaHasteRating := float64(363) * float64(newStacks-oldStacks)
character.AddStatDynamic(sim, stats.HasteRating, deltaHasteRating)
},
})

Expand Down Expand Up @@ -549,9 +549,9 @@ func init() {
}))

statBonus := float64(508 * dummyAura.MaxStacks)
buffAuraCrit := character.NewTemporaryStatsAura("Blessing of the Shaper Crit", core.ActionID{SpellID: 96928}, stats.Stats{stats.MeleeCrit: statBonus, stats.SpellCrit: statBonus}, time.Second*15)
buffAuraHaste := character.NewTemporaryStatsAura("Blessing of the Shaper Haste", core.ActionID{SpellID: 96927}, stats.Stats{stats.MeleeHaste: statBonus, stats.SpellHaste: statBonus}, time.Second*15)
buffAuraMastery := character.NewTemporaryStatsAura("Blessing of the Shaper Mastery", core.ActionID{SpellID: 96929}, stats.Stats{stats.Mastery: statBonus}, time.Second*15)
buffAuraCrit := character.NewTemporaryStatsAura("Blessing of the Shaper Crit", core.ActionID{SpellID: 96928}, stats.Stats{stats.CritRating: statBonus}, time.Second*15)
buffAuraHaste := character.NewTemporaryStatsAura("Blessing of the Shaper Haste", core.ActionID{SpellID: 96927}, stats.Stats{stats.HasteRating: statBonus}, time.Second*15)
buffAuraMastery := character.NewTemporaryStatsAura("Blessing of the Shaper Mastery", core.ActionID{SpellID: 96929}, stats.Stats{stats.MasteryRating: statBonus}, time.Second*15)

sharedCD := character.GetOffensiveTrinketCD()
trinketSpell := character.RegisterSpell(core.SpellConfig{
Expand All @@ -571,13 +571,13 @@ func init() {
},

ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
statType := character.GetHighestStat([]stats.Stat{stats.MeleeCrit, stats.SpellCrit, stats.MeleeHaste, stats.SpellHaste, stats.Mastery})
statType := character.GetHighestStatType([]stats.Stat{stats.CritRating, stats.HasteRating, stats.MasteryRating})
switch statType {
case stats.MeleeCrit, stats.SpellCrit:
case stats.CritRating:
buffAuraCrit.Activate(sim)
case stats.MeleeHaste, stats.SpellHaste:
case stats.HasteRating:
buffAuraHaste.Activate(sim)
case stats.Mastery:
case stats.MasteryRating:
buffAuraMastery.Activate(sim)
default:
panic("unexpected statType")
Expand Down Expand Up @@ -626,9 +626,9 @@ func init() {
// the trinket should allow to activate at any number of stacks, should we allow this behaviour at all to the users?
// would also mean that we need the temporary aura to be created on the fly after an environment is finalized
statBonus := float64(575 * dummyAura.MaxStacks)
buffAuraCrit := character.NewTemporaryStatsAura("Blessing of the Shaper Crit (Heroic)", core.ActionID{SpellID: 96928}, stats.Stats{stats.MeleeCrit: statBonus, stats.SpellCrit: statBonus}, time.Second*15)
buffAuraHaste := character.NewTemporaryStatsAura("Blessing of the Shaper Haste (Heroic)", core.ActionID{SpellID: 96927}, stats.Stats{stats.MeleeHaste: statBonus, stats.SpellHaste: statBonus}, time.Second*15)
buffAuraMastery := character.NewTemporaryStatsAura("Blessing of the Shaper Mastery (Heroic)", core.ActionID{SpellID: 96929}, stats.Stats{stats.Mastery: statBonus}, time.Second*15)
buffAuraCrit := character.NewTemporaryStatsAura("Blessing of the Shaper Crit (Heroic)", core.ActionID{SpellID: 96928}, stats.Stats{stats.CritRating: statBonus}, time.Second*15)
buffAuraHaste := character.NewTemporaryStatsAura("Blessing of the Shaper Haste (Heroic)", core.ActionID{SpellID: 96927}, stats.Stats{stats.HasteRating: statBonus}, time.Second*15)
buffAuraMastery := character.NewTemporaryStatsAura("Blessing of the Shaper Mastery (Heroic)", core.ActionID{SpellID: 96929}, stats.Stats{stats.MasteryRating: statBonus}, time.Second*15)

sharedCD := character.GetOffensiveTrinketCD()
trinketSpell := character.RegisterSpell(core.SpellConfig{
Expand All @@ -647,13 +647,13 @@ func init() {
},
},
ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) {
statType := character.GetHighestStat([]stats.Stat{stats.MeleeCrit, stats.SpellCrit, stats.MeleeHaste, stats.SpellHaste, stats.Mastery})
statType := character.GetHighestStatType([]stats.Stat{stats.CritRating, stats.HasteRating, stats.MasteryRating})
switch statType {
case stats.MeleeCrit, stats.SpellCrit:
case stats.CritRating:
buffAuraCrit.Activate(sim)
case stats.MeleeHaste, stats.SpellHaste:
case stats.HasteRating:
buffAuraHaste.Activate(sim)
case stats.Mastery:
case stats.MasteryRating:
buffAuraMastery.Activate(sim)
default:
panic("unexpected statType")
Expand All @@ -679,9 +679,9 @@ func init() {
character := agent.GetCharacter()

bonusStats := 1624.0
procAuraCrit := character.NewTemporaryStatsAura("Matrix Restabilizer Crit Proc", core.ActionID{SpellID: 96978}, stats.Stats{stats.MeleeCrit: bonusStats, stats.SpellCrit: bonusStats}, time.Second*30)
procAuraHaste := character.NewTemporaryStatsAura("Matrix Restabilizer Haste Proc", core.ActionID{SpellID: 96977}, stats.Stats{stats.MeleeHaste: bonusStats, stats.SpellHaste: bonusStats}, time.Second*30)
procAuraMastery := character.NewTemporaryStatsAura("Matrix Restabilizer Mastery Proc", core.ActionID{SpellID: 96979}, stats.Stats{stats.Mastery: bonusStats}, time.Second*30)
procAuraCrit := character.NewTemporaryStatsAura("Matrix Restabilizer Crit Proc", core.ActionID{SpellID: 96978}, stats.Stats{stats.CritRating: bonusStats}, time.Second*30)
procAuraHaste := character.NewTemporaryStatsAura("Matrix Restabilizer Haste Proc", core.ActionID{SpellID: 96977}, stats.Stats{stats.HasteRating: bonusStats}, time.Second*30)
procAuraMastery := character.NewTemporaryStatsAura("Matrix Restabilizer Mastery Proc", core.ActionID{SpellID: 96979}, stats.Stats{stats.MasteryRating: bonusStats}, time.Second*30)

icd := core.Cooldown{
Timer: character.NewTimer(),
Expand All @@ -701,13 +701,13 @@ func init() {
Harmful: true,
Handler: func(sim *core.Simulation, _ *core.Spell, _ *core.SpellResult) {
if icd.IsReady(sim) {
statType := character.GetHighestStat([]stats.Stat{stats.MeleeCrit, stats.SpellCrit, stats.MeleeHaste, stats.SpellHaste, stats.Mastery})
statType := character.GetHighestStatType([]stats.Stat{stats.CritRating, stats.HasteRating, stats.MasteryRating})
switch statType {
case stats.MeleeCrit, stats.SpellCrit:
case stats.CritRating:
procAuraCrit.Activate(sim)
case stats.MeleeHaste, stats.SpellHaste:
case stats.HasteRating:
procAuraHaste.Activate(sim)
case stats.Mastery:
case stats.MasteryRating:
procAuraMastery.Activate(sim)
default:
panic("unexpected statType")
Expand All @@ -722,9 +722,9 @@ func init() {
character := agent.GetCharacter()

bonusStats := 1834.0
procAuraCrit := character.NewTemporaryStatsAura("Matrix Restabilizer Crit Proc (Heroic)", core.ActionID{SpellID: 97140}, stats.Stats{stats.MeleeCrit: bonusStats, stats.SpellCrit: bonusStats}, time.Second*30)
procAuraHaste := character.NewTemporaryStatsAura("Matrix Restabilizer Haste Proc (Heroic)", core.ActionID{SpellID: 97139}, stats.Stats{stats.MeleeHaste: bonusStats, stats.SpellHaste: bonusStats}, time.Second*30)
procAuraMastery := character.NewTemporaryStatsAura("Matrix Restabilizer Mastery Proc (Heroic)", core.ActionID{SpellID: 97141}, stats.Stats{stats.Mastery: bonusStats}, time.Second*30)
procAuraCrit := character.NewTemporaryStatsAura("Matrix Restabilizer Crit Proc (Heroic)", core.ActionID{SpellID: 97140}, stats.Stats{stats.CritRating: bonusStats}, time.Second*30)
procAuraHaste := character.NewTemporaryStatsAura("Matrix Restabilizer Haste Proc (Heroic)", core.ActionID{SpellID: 97139}, stats.Stats{stats.HasteRating: bonusStats}, time.Second*30)
procAuraMastery := character.NewTemporaryStatsAura("Matrix Restabilizer Mastery Proc (Heroic)", core.ActionID{SpellID: 97141}, stats.Stats{stats.MasteryRating: bonusStats}, time.Second*30)

icd := core.Cooldown{
Timer: character.NewTimer(),
Expand All @@ -744,13 +744,13 @@ func init() {
Harmful: true,
Handler: func(sim *core.Simulation, _ *core.Spell, _ *core.SpellResult) {
if icd.IsReady(sim) {
statType := character.GetHighestStat([]stats.Stat{stats.MeleeCrit, stats.SpellCrit, stats.MeleeHaste, stats.SpellHaste, stats.Mastery})
statType := character.GetHighestStatType([]stats.Stat{stats.CritRating, stats.HasteRating, stats.MasteryRating})
switch statType {
case stats.MeleeCrit, stats.SpellCrit:
case stats.CritRating:
procAuraCrit.Activate(sim)
case stats.MeleeHaste, stats.SpellHaste:
case stats.HasteRating:
procAuraHaste.Activate(sim)
case stats.Mastery:
case stats.MasteryRating:
procAuraMastery.Activate(sim)
default:
panic("unexpected statType")
Expand Down
Loading
Loading