diff --git a/sim/core/cast.go b/sim/core/cast.go index a5a4e4308c..42f5993ec9 100644 --- a/sim/core/cast.go +++ b/sim/core/cast.go @@ -17,7 +17,6 @@ type Hardcast struct { ActionID ActionID OnComplete func(*Simulation, *Unit) Target *Unit - Pushback float64 } // Input for constructing the CastSpell function for a spell. @@ -98,12 +97,15 @@ func (unit *Unit) applySpellPushback() { return } - if hc := aura.Unit.Hardcast; aura.Unit.IsCasting(sim) && sim.Roll(0, 1.0) > spell.PushbackReduction { - // Do spell pushback - pushback := DurationFromSeconds(max(0.2, hc.Pushback)) - aura.Unit.Hardcast.Pushback -= 0.2 - + if hc := aura.Unit.Hardcast; aura.Unit.IsCasting(sim) { hcSpell := aura.Unit.GetSpell(hc.ActionID) + // Caster avoided the pushback + if sim.Roll(0, 1.0) <= hcSpell.PushbackReduction { + return + } + + // Do spell pushback + pushback := DurationFromSeconds(sim.Roll(0.5, 1.0) * unit.PseudoStats.SpellPushbackMultiplier) if hcSpell.Flags.Matches(SpellFlagChanneled) { newExpires := max(sim.CurrentTime, hc.Expires-pushback) @@ -268,7 +270,6 @@ func (spell *Spell) makeCastFunc(config CastConfig) CastSuccessFunc { spell.Unit.Hardcast = Hardcast{ Expires: sim.CurrentTime + spell.CurCast.CastTime, ActionID: spell.ActionID, - Pushback: 1.0, OnComplete: func(sim *Simulation, target *Unit) { spell.LastCastAt = sim.CurrentTime diff --git a/sim/core/stats/stats.go b/sim/core/stats/stats.go index 2fa33f0bcb..0394296996 100644 --- a/sim/core/stats/stats.go +++ b/sim/core/stats/stats.go @@ -506,6 +506,8 @@ type PseudoStats struct { ArmorMultiplier float64 // Major/minor/special multiplicative armor modifiers HealingTakenMultiplier float64 + + SpellPushbackMultiplier float64 // Multiplier for the amount of spell pushback taken on a hit } func NewPseudoStats() PseudoStats { @@ -543,17 +545,19 @@ func NewPseudoStats() PseudoStats { ArmorMultiplier: 1, - HealingTakenMultiplier: 1, - UnarmedSkill: 0, - DaggersSkill: 0, - SwordsSkill: 0, - MacesSkill: 0, - AxesSkill: 0, - TwoHandedSwordsSkill: 0, - TwoHandedMacesSkill: 0, - TwoHandedAxesSkill: 0, - PolearmsSkill: 0, - StavesSkill: 0, + HealingTakenMultiplier: 1, + SpellPushbackMultiplier: 1, + + UnarmedSkill: 0, + DaggersSkill: 0, + SwordsSkill: 0, + MacesSkill: 0, + AxesSkill: 0, + TwoHandedSwordsSkill: 0, + TwoHandedMacesSkill: 0, + TwoHandedAxesSkill: 0, + PolearmsSkill: 0, + StavesSkill: 0, BowsSkill: 0, GunsSkill: 0, diff --git a/sim/shaman/earth_shield.go b/sim/shaman/earth_shield.go index 918081674e..b08265df51 100644 --- a/sim/shaman/earth_shield.go +++ b/sim/shaman/earth_shield.go @@ -1,71 +1,68 @@ package shaman -// import ( -// "time" +import "github.com/wowsims/sod/sim/core/proto" -// "github.com/wowsims/sod/sim/core" -// "github.com/wowsims/sod/sim/core/proto" -// ) +func (shaman *Shaman) registerEarthShieldSpell() { + if !shaman.HasRune(proto.ShamanRune_RuneLegsEarthShield) { + return + } -// func (shaman *Shaman) registerEarthShieldSpell() { -// if !shaman.HasRune(proto.ShamanRune_RuneLegsEarthShield) { -// return -// } + shaman.PseudoStats.SpellPushbackMultiplier *= 0.70 -// actionID := core.ActionID{SpellID: 49284} -// spCoeff := 0.286 + // actionID := core.ActionID{SpellID: 49284} + // spCoeff := 0.286 -// icd := core.Cooldown{ -// Timer: shaman.NewTimer(), -// Duration: time.Millisecond * 3500, -// } + // icd := core.Cooldown{ + // Timer: shaman.NewTimer(), + // Duration: time.Millisecond * 3500, + // } -// shaman.EarthShield = shaman.RegisterSpell(core.SpellConfig{ -// ActionID: actionID, -// SpellSchool: core.SpellSchoolNature, -// DefenseType: core.DefenseTypeMagic, -// ProcMask: core.ProcMaskEmpty, -// Flags: core.SpellFlagHelpful | core.SpellFlagAPL | SpellFlagShaman, + // shaman.EarthShield = shaman.RegisterSpell(core.SpellConfig{ + // ActionID: actionID, + // SpellSchool: core.SpellSchoolNature, + // DefenseType: core.DefenseTypeMagic, + // ProcMask: core.ProcMaskEmpty, + // Flags: core.SpellFlagHelpful | core.SpellFlagAPL | SpellFlagShaman, -// Cast: core.CastConfig{ -// DefaultCast: core.Cast{ -// GCD: core.GCDDefault, -// }, -// }, + // Cast: core.CastConfig{ + // DefaultCast: core.Cast{ + // GCD: core.GCDDefault, + // }, + // }, -// Hot: core.DotConfig{ -// Aura: core.Aura{ -// Label: "Earth Shield", -// ActionID: core.ActionID{SpellID: 379}, -// OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { -// if !result.Landed() { -// return -// } -// if !icd.IsReady(sim) { -// return -// } -// icd.Use(sim) -// shaman.EarthShield.Hot(result.Target).ManualTick(sim) -// }, -// OnExpire: func(aura *core.Aura, sim *core.Simulation) { -// }, -// }, -// NumberOfTicks: 6 + shaman.Talents.ImprovedEarthShield, -// TickLength: time.Minute*10 + 1, // tick length longer than expire time. -// OnSnapshot: func(sim *core.Simulation, target *core.Unit, dot *core.Dot, _ bool) { -// dot.SnapshotBaseDamage = 377 + dot.Spell.HealingPower(target)*spCoeff -// dot.SnapshotAttackerMultiplier = dot.Spell.CasterHealingMultiplier() -// }, -// OnTick: func(sim *core.Simulation, target *core.Unit, dot *core.Dot) { -// dot.CalcAndDealPeriodicSnapshotHealing(sim, target, dot.OutcomeTick) -// }, -// }, + // Hot: core.DotConfig{ + // Aura: core.Aura{ + // Label: "Earth Shield", + // ActionID: core.ActionID{SpellID: 379}, + // OnSpellHitTaken: func(aura *core.Aura, sim *core.Simulation, spell *core.Spell, result *core.SpellResult) { + // if !result.Landed() { + // return + // } + // if !icd.IsReady(sim) { + // return + // } + // icd.Use(sim) + // shaman.EarthShield.Hot(result.Target).ManualTick(sim) + // }, + // OnExpire: func(aura *core.Aura, sim *core.Simulation) { + // }, + // }, + // NumberOfTicks: 6 + shaman.Talents.ImprovedEarthShield, + // TickLength: time.Minute*10 + 1, // tick length longer than expire time. + // OnSnapshot: func(sim *core.Simulation, target *core.Unit, dot *core.Dot, _ bool) { + // dot.SnapshotBaseDamage = 377 + dot.Spell.HealingPower(target)*spCoeff + // dot.SnapshotAttackerMultiplier = dot.Spell.CasterHealingMultiplier() + // }, + // OnTick: func(sim *core.Simulation, target *core.Unit, dot *core.Dot) { + // dot.CalcAndDealPeriodicSnapshotHealing(sim, target, dot.OutcomeTick) + // }, + // }, -// DamageMultiplier: 1 -// ThreatMultiplier: 1, + // DamageMultiplier: 1 + // ThreatMultiplier: 1, -// ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { -// spell.Hot(target).Apply(sim) -// }, -// }) -// } + // ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + // spell.Hot(target).Apply(sim) + // }, + // }) +} diff --git a/sim/shaman/runes.go b/sim/shaman/runes.go index 8fe2d0b34c..f21f86b8d4 100644 --- a/sim/shaman/runes.go +++ b/sim/shaman/runes.go @@ -41,6 +41,7 @@ func (shaman *Shaman) ApplyRunes() { // Legs shaman.applyAncestralGuidance() shaman.applyWayOfEarth() + shaman.registerEarthShieldSpell() // Feet shaman.applyAncestralAwakening()