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 changes: 1 addition & 1 deletion proto/common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ message Debuffs {
bool spore_cloud = 11;
bool slow = 12;
bool mind_numbing_poison = 13;
bool curse_of_enfeeblement = 14;
bool curse_of_enfeeblement = 14;
}

message ConsumesSpec {
Expand Down
16 changes: 10 additions & 6 deletions sim/common/cata/metagems.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,14 @@ func init() {
agent.GetCharacter().MultiplyStat(stats.Mana, 1.02)
})

// These are handled in character.go, but create empty effects so they are included in tests.
core.NewItemEffect(52291, func(_ core.Agent) {}) // Chaotic Shadowspirit Diamond
core.NewItemEffect(52297, func(_ core.Agent) {}) // Revitalizing Shadowspirit Diamond
core.NewItemEffect(68778, func(_ core.Agent) {}) // Agile Shadowspirit Diamond
core.NewItemEffect(68779, func(_ core.Agent) {}) // Reverberating Shadowspirit Diamond
core.NewItemEffect(68780, func(_ core.Agent) {}) // Burning Shadowspirit Diamond
// Chaotic Shadowspirit Diamond
core.NewItemEffect(52291, core.ApplyMetaGemCriticalDamageEffect)
// Revitalizing Shadowspirit Diamond
core.NewItemEffect(52297, core.ApplyMetaGemCriticalDamageEffect)
// Agile Shadowspirit Diamond
core.NewItemEffect(68778, core.ApplyMetaGemCriticalDamageEffect)
// Reverberating Shadowspirit Diamond
core.NewItemEffect(68779, core.ApplyMetaGemCriticalDamageEffect)
// Burning Shadowspirit Diamond
core.NewItemEffect(68780, core.ApplyMetaGemCriticalDamageEffect)
}
24 changes: 24 additions & 0 deletions sim/common/mop/metagems.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package cata

import (
"github.com/wowsims/mop/sim/core"
)

func init() {

// Keep these in order by item ID
// Agile Primal Diamond
core.NewItemEffect(76884, core.ApplyMetaGemCriticalDamageEffect)
// Burning Primal Diamond
core.NewItemEffect(76885, core.ApplyMetaGemCriticalDamageEffect)
// Reverberating Primal Diamond
core.NewItemEffect(76886, core.ApplyMetaGemCriticalDamageEffect)
// Revitalizing Primal Diamond
core.NewItemEffect(76888, core.ApplyMetaGemCriticalDamageEffect)
// Burning Primal Diamond
core.NewItemEffect(97937, core.ApplyMetaGemCriticalDamageEffect)
// Burning Primal Diamond
core.NewItemEffect(97534, core.ApplyMetaGemCriticalDamageEffect)
// Revitalizing Primal Diamond
core.NewItemEffect(97306, core.ApplyMetaGemCriticalDamageEffect)
}
91 changes: 54 additions & 37 deletions sim/core/buffs.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ func applyBuffEffects(agent Agent, raidBuffs *proto.RaidBuffs, _ *proto.PartyBuf
applyStaminaBuffs(u, raidBuffs)

registerManaTideTotemCD(agent, raidBuffs.ManaTideTotemCount)
registerSkullBannerCD(agent, raidBuffs.SkullBannerCount)

// Individual cooldowns and major buffs
if len(char.Env.Raid.AllPlayerUnits)-char.Env.Raid.NumTargetDummies == 1 {
// Major Haste
Expand Down Expand Up @@ -747,7 +749,9 @@ func registerTricksOfTheTradeCD(agent Agent, tristateConfig proto.TristateEffect
ShouldActivate: func(sim *Simulation, character *Character) bool {
return !character.GetExclusiveEffectCategory("PercentDamageModifier").AnyActive()
},
AddAura: func(sim *Simulation, character *Character) { tricksAura.Activate(sim) },
AddAura: func(sim *Simulation, character *Character) {
tricksAura.Activate(sim)
},
},
1)
}
Expand All @@ -760,13 +764,7 @@ func TricksOfTheTradeAura(character *Unit, actionTag int32, damageMult float64)
Tag: TricksOfTheTradeAuraTag,
ActionID: actionID,
Duration: time.Second * 6,
OnGain: func(aura *Aura, sim *Simulation) {
character.PseudoStats.DamageDealtMultiplier *= damageMult
},
OnExpire: func(aura *Aura, sim *Simulation) {
character.PseudoStats.DamageDealtMultiplier /= damageMult
},
})
}).AttachMultiplicativePseudoStatBuff(&character.PseudoStats.DamageDealtMultiplier, damageMult)

RegisterPercentDamageModifierEffect(aura, damageMult)
return aura
Expand Down Expand Up @@ -819,6 +817,7 @@ func UnholyFrenzyAura(character *Unit, actionTag int32) *Aura {
aura.Unit.MultiplyResourceRegenSpeed(sim, 1/1.2)
},
})

return aura
}

Expand Down Expand Up @@ -868,13 +867,7 @@ func HandOfSacrificeAura(character *Character, actionTag int32) *Aura {
Tag: HandOfSacrificeAuraTag,
ActionID: actionID,
Duration: HandOfSacrificeDuration,
OnGain: func(aura *Aura, sim *Simulation) {
character.PseudoStats.DamageTakenMultiplier *= 0.7
},
OnExpire: func(aura *Aura, sim *Simulation) {
character.PseudoStats.DamageTakenMultiplier /= 0.7
},
})
}).AttachMultiplicativePseudoStatBuff(&character.PseudoStats.DamageTakenMultiplier, 0.7)
}

var PainSuppressionAuraTag = "PainSuppression"
Expand Down Expand Up @@ -902,7 +895,9 @@ func registerPainSuppressionCD(agent Agent, numPainSuppressions int32) {
ShouldActivate: func(sim *Simulation, character *Character) bool {
return true
},
AddAura: func(sim *Simulation, character *Character) { psAura.Activate(sim) },
AddAura: func(sim *Simulation, character *Character) {
psAura.Activate(sim)
},
},
numPainSuppressions)
}
Expand All @@ -915,13 +910,7 @@ func PainSuppressionAura(character *Character, actionTag int32) *Aura {
Tag: PainSuppressionAuraTag,
ActionID: actionID,
Duration: PainSuppressionDuration,
OnGain: func(aura *Aura, sim *Simulation) {
character.PseudoStats.DamageTakenMultiplier *= 0.6
},
OnExpire: func(aura *Aura, sim *Simulation) {
character.PseudoStats.DamageTakenMultiplier /= 0.6
},
})
}).AttachMultiplicativePseudoStatBuff(&character.PseudoStats.DamageTakenMultiplier, 0.6)
}

var GuardianSpiritAuraTag = "GuardianSpirit"
Expand Down Expand Up @@ -974,13 +963,7 @@ func GuardianSpiritAura(character *Character, actionTag int32) *Aura {
Tag: GuardianSpiritAuraTag,
ActionID: actionID,
Duration: GuardianSpiritDuration,
OnGain: func(aura *Aura, sim *Simulation) {
character.PseudoStats.HealingTakenMultiplier *= 1.4
},
OnExpire: func(aura *Aura, sim *Simulation) {
character.PseudoStats.HealingTakenMultiplier /= 1.4
},
})
}).AttachMultiplicativePseudoStatBuff(&character.PseudoStats.HealingTakenMultiplier, 1.4)
}

var RallyingCryAuraTag = "RallyingCry"
Expand Down Expand Up @@ -1069,6 +1052,46 @@ func registerShatteringThrowCD(agent Agent, numShatteringThrows int32) {
numShatteringThrows)
}

const SkullBannerAuraTag = "SkullBanner"
const SkullBannerDuration = time.Second * 10
const SkullBannerCD = time.Minute * 3

func registerSkullBannerCD(agent Agent, numSkullBanners int32) {
if numSkullBanners == 0 {
return
}

sbAura := SkullBannerAura(agent.GetCharacter(), -1)

registerExternalConsecutiveCDApproximation(
agent,
externalConsecutiveCDApproximation{
ActionID: ActionID{SpellID: 114207, Tag: -1},
AuraTag: SkullBannerAuraTag,
CooldownPriority: CooldownPriorityDefault,
AuraDuration: SkullBannerDuration,
AuraCD: SkullBannerCD,
Type: CooldownTypeDPS,

ShouldActivate: func(sim *Simulation, character *Character) bool {
return true
},
AddAura: func(sim *Simulation, character *Character) {
sbAura.Activate(sim)
},
},
numSkullBanners)
}

func SkullBannerAura(character *Character, actionTag int32) *Aura {
return character.GetOrRegisterAura(Aura{
Label: "Skull Banner",
Tag: SkullBannerAuraTag,
ActionID: ActionID{SpellID: 114206, Tag: actionTag},
Duration: SkullBannerDuration,
}).AttachMultiplicativePseudoStatBuff(&character.PseudoStats.CritDamageMultiplier, 1.2)
}

var ManaTideTotemActionID = ActionID{SpellID: 16190}
var ManaTideTotemAuraTag = "ManaTideTotem"

Expand Down Expand Up @@ -1119,11 +1142,5 @@ func ManaTideTotemAura(character *Character, actionTag int32) *Aura {
Tag: ManaTideTotemAuraTag,
ActionID: actionID,
Duration: ManaTideTotemDuration,
OnGain: func(aura *Aura, sim *Simulation) {
aura.Unit.EnableDynamicStatDep(sim, dep)
},
OnExpire: func(aura *Aura, sim *Simulation) {
aura.Unit.DisableDynamicStatDep(sim, dep)
},
})
}).AttachStatDependency(dep)
}
26 changes: 0 additions & 26 deletions sim/core/character.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ type Character struct {
bonusOHDps float64
bonusRangedDps float64

spellCritMultiplier float64

professions [2]proto.Profession

glyphs [6]int32
Expand Down Expand Up @@ -126,7 +124,6 @@ func NewCharacter(party *Party, partyIndex int, player *proto.Player) Character

majorCooldownManager: newMajorCooldownManager(player.Cooldowns),
}
character.spellCritMultiplier = character.DefaultCritMultiplier()
character.GCD = character.NewTimer()
character.RotationTimer = character.NewTimer()

Expand Down Expand Up @@ -374,18 +371,6 @@ func (character *Character) GetBaseStats() stats.Stats {
// https://github.com/TheGroxEmpire/TBC_DPS_Warrior_Sim/issues/30
// TODO "primaryModifiers" could be modelled as a PseudoStat, since they're unit-specific. "secondaryModifiers" apply to a specific set of spells.
func (character *Character) calculateCritMultiplier(normalCritDamage float64, primaryModifiers float64, secondaryModifiers float64) float64 {
if character.HasMetaGemEquipped(34220) ||
character.HasMetaGemEquipped(32409) ||
character.HasMetaGemEquipped(41285) ||
character.HasMetaGemEquipped(41376) ||
character.HasMetaGemEquipped(41398) ||
character.HasMetaGemEquipped(52291) ||
character.HasMetaGemEquipped(52297) ||
character.HasMetaGemEquipped(68778) ||
character.HasMetaGemEquipped(68779) ||
character.HasMetaGemEquipped(68780) {
primaryModifiers *= 1.03
}
return 1.0 + (normalCritDamage*primaryModifiers-1.0)*(1.0+secondaryModifiers)
}
func (character *Character) CritMultiplier(primaryModifiers float64, secondaryModifiers float64) float64 {
Expand All @@ -395,17 +380,6 @@ func (character *Character) DefaultCritMultiplier() float64 {
return character.CritMultiplier(1, 0)
}

func (character *Character) SetDefaultSpellCritMultiplier(spellCritMultiplier float64) {
if character.Env != nil {
panic("Spell crit multiplier must be set during construction!")
}
character.spellCritMultiplier = spellCritMultiplier
}

func (character *Character) DefaultSpellCritMultiplier() float64 {
return character.spellCritMultiplier
}

func (character *Character) AddRaidBuffs(_ *proto.RaidBuffs) {
}
func (character *Character) AddPartyBuffs(partyBuffs *proto.PartyBuffs) {
Expand Down
6 changes: 6 additions & 0 deletions sim/core/item_effects.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,9 @@ func NewSimpleStatDefensiveTrinketEffect(itemID int32, bonus stats.Stats, durati
}
}, nil)
}

// Applies 3% Crit Damage effect
// https://www.wowhead.com/mop-classic/spell=44797/3-increased-critical-effect
func ApplyMetaGemCriticalDamageEffect(agent Agent) {
agent.GetCharacter().PseudoStats.CritDamageMultiplier *= 1.03
}
2 changes: 1 addition & 1 deletion sim/core/pet.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func NewPet(name string, owner *Character, baseStats stats.Stats, statInheritanc
enabledOnStart: enabledOnStart,
isGuardian: isGuardian,
}
pet.spellCritMultiplier = pet.DefaultCritMultiplier()

pet.GCD = pet.NewTimer()
pet.RotationTimer = pet.NewTimer()

Expand Down
2 changes: 1 addition & 1 deletion sim/core/spell.go
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ func (spell *Spell) ExpectedTickDamageFromCurrentSnapshot(sim *Simulation, targe
}

func (spell *Spell) CritDamageMultiplier() float64 {
return (spell.CritMultiplier-1)*(spell.CritMultiplierAdditive+1) + 1
return ((spell.CritMultiplier*spell.Unit.PseudoStats.CritDamageMultiplier)-1)*(spell.CritMultiplierAdditive+1) + 1
}

// Time until either the cast is finished or GCD is ready again, whichever is longer
Expand Down
2 changes: 2 additions & 0 deletions sim/core/stats/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ type PseudoStats struct {
SchoolDamageDealtMultiplier [SchoolLen]float64 // For specific spell schools (arcane, fire, shadow, etc).
DotDamageMultiplierAdditive float64 // All periodic damage
HealingDealtMultiplier float64 // All non-shield healing
CritDamageMultiplier float64 // All multiplicative crit damage

// Important when unit is attacker or target
BlockDamageReduction float64
Expand Down Expand Up @@ -484,6 +485,7 @@ func NewPseudoStats() PseudoStats {
SchoolDamageDealtMultiplier: NewSchoolFloatArray(),
DotDamageMultiplierAdditive: 1,
HealingDealtMultiplier: 1,
CritDamageMultiplier: 1,

BlockDamageReduction: 0.3,

Expand Down
17 changes: 7 additions & 10 deletions sim/core/test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,15 @@ var FullRaidBuffs = &proto.RaidBuffs{

// Major Mana Replenishment
ManaTideTotemCount: 1, // Shamans
}

var FullPartyBuffs = &proto.PartyBuffs{
//BraidedEterniumChain: true,
// ManaTideTotems: 1,
}
var FullIndividualBuffs = &proto.IndividualBuffs{
// BlessingOfMight: true,
// BlessingOfSanctuary: true,
// BlessingOfWisdom: true,
// JudgementsOfTheWise: true,
// Crit Damage %
SkullBannerCount: 1, // Warrior
}

var FullPartyBuffs = &proto.PartyBuffs{}

var FullIndividualBuffs = &proto.IndividualBuffs{}

var FullDebuffs = &proto.Debuffs{
WeakenedBlows: true,
PhysicalVulnerability: true,
Expand All @@ -102,6 +98,7 @@ var FullDebuffs = &proto.Debuffs{
SporeCloud: true,
Slow: true,
MindNumbingPoison: true,
CurseOfEnfeeblement: true,
}

func NewDefaultTarget() *proto.Target {
Expand Down
6 changes: 6 additions & 0 deletions ui/core/components/inputs/buffs_debuffs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export const TricksOfTheTrade = makeTristateIndividualBuffInput({
});
export const UnholyFrenzy = makeMultistateIndividualBuffInput({ actionId: ActionId.fromSpellId(49016), numStates: 11, fieldName: 'unholyFrenzyCount' });
export const ShatteringThrow = makeMultistateIndividualBuffInput({ actionId: ActionId.fromSpellId(64382), numStates: 11, fieldName: 'shatteringThrowCount' });
export const Skullbanner = makeMultistateRaidBuffInput({ actionId: ActionId.fromSpellId(114207), numStates: 11, fieldName: 'skullBannerCount' });

///////////////////////////////////////////////////////////////////////////
// DEBUFFS
Expand Down Expand Up @@ -220,6 +221,11 @@ export const RAID_BUFFS_CONFIG = [
] as PickerStatOptions[];

export const RAID_BUFFS_MISC_CONFIG = [
{
config: Skullbanner,
picker: IconPicker,
stats: [Stat.StatAttackPower, Stat.StatRangedAttackPower, Stat.StatSpellPower],
},
{
config: ManaTideTotem,
picker: IconPicker,
Expand Down
7 changes: 7 additions & 0 deletions ui/core/proto_utils/action_id.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,13 @@ export class ActionId {
name += ` (self)`;
}
break;
case 'Skull Banner':
if (tag === -1) {
name += ' (raid)';
} else {
name += ` (self)`;
}
break;
case 'Envenom':
case 'Eviscerate':
case 'Expose Armor':
Expand Down
Loading
Loading