From 92cb9264369d2ac21be4e57dcc5a4e1c8d288d29 Mon Sep 17 00:00:00 2001 From: rosenrusinov Date: Tue, 18 Jul 2023 22:18:33 +0200 Subject: [PATCH] add apl support to palading spells and enable it for retribution --- sim/paladin/avengers_shield.go | 2 +- sim/paladin/avenging_wrath.go | 2 +- sim/paladin/consecration.go | 2 +- sim/paladin/crusader_strike.go | 2 +- sim/paladin/divine_plea.go | 1 + sim/paladin/divine_protection.go | 1 + sim/paladin/divine_storm.go | 2 +- sim/paladin/exorcism.go | 4 ++-- sim/paladin/hammer_of_the_righteous.go | 2 +- sim/paladin/hammer_of_wrath.go | 5 ++++- sim/paladin/hand_of_reckoning.go | 2 +- sim/paladin/holy_shield.go | 1 + sim/paladin/holy_wrath.go | 2 +- sim/paladin/judgement.go | 4 ++-- sim/paladin/protection/rotation.go | 4 ++++ sim/paladin/retribution/rotation.go | 7 +++++-- sim/paladin/shield_of_righteousness.go | 2 +- sim/paladin/soc.go | 1 + sim/paladin/sor.go | 1 + sim/paladin/sov.go | 1 + ui/core/launched_sims.ts | 2 +- ui/retribution_paladin/presets.ts | 26 +++++++++++++++++++++++++- ui/retribution_paladin/sim.ts | 3 +++ 23 files changed, 61 insertions(+), 18 deletions(-) diff --git a/sim/paladin/avengers_shield.go b/sim/paladin/avengers_shield.go index 548afc757a..e2a8a8ae16 100644 --- a/sim/paladin/avengers_shield.go +++ b/sim/paladin/avengers_shield.go @@ -17,7 +17,7 @@ func (paladin *Paladin) registerAvengersShieldSpell() { ActionID: core.ActionID{SpellID: 48827}, SpellSchool: core.SpellSchoolHoly, ProcMask: core.ProcMaskMeleeMHSpecial, - Flags: core.SpellFlagMeleeMetrics, + Flags: core.SpellFlagMeleeMetrics | core.SpellFlagAPL, ManaCost: core.ManaCostOptions{ BaseCost: 0.26, diff --git a/sim/paladin/avenging_wrath.go b/sim/paladin/avenging_wrath.go index 42ef88b7fd..b853e05f08 100644 --- a/sim/paladin/avenging_wrath.go +++ b/sim/paladin/avenging_wrath.go @@ -31,7 +31,7 @@ func (paladin *Paladin) RegisterAvengingWrathCD() { paladin.AvengingWrath = paladin.RegisterSpell(core.SpellConfig{ ActionID: actionID, - Flags: core.SpellFlagNoOnCastComplete, + Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagAPL, ManaCost: core.ManaCostOptions{ BaseCost: 0.08, diff --git a/sim/paladin/consecration.go b/sim/paladin/consecration.go index 7cf4f966d2..386c6f77a1 100644 --- a/sim/paladin/consecration.go +++ b/sim/paladin/consecration.go @@ -19,7 +19,7 @@ func (paladin *Paladin) registerConsecrationSpell() { ActionID: core.ActionID{SpellID: 48819}, SpellSchool: core.SpellSchoolHoly, ProcMask: core.ProcMaskEmpty, - Flags: core.SpellFlagMeleeMetrics, + Flags: core.SpellFlagMeleeMetrics | core.SpellFlagAPL, ManaCost: core.ManaCostOptions{ BaseCost: 0.22, diff --git a/sim/paladin/crusader_strike.go b/sim/paladin/crusader_strike.go index b00bbcfea9..1f877a998b 100644 --- a/sim/paladin/crusader_strike.go +++ b/sim/paladin/crusader_strike.go @@ -15,7 +15,7 @@ func (paladin *Paladin) registerCrusaderStrikeSpell() { ActionID: core.ActionID{SpellID: 35395}, SpellSchool: core.SpellSchoolPhysical, ProcMask: core.ProcMaskMeleeMHSpecial, - Flags: core.SpellFlagMeleeMetrics | core.SpellFlagIncludeTargetBonusDamage, + Flags: core.SpellFlagMeleeMetrics | core.SpellFlagIncludeTargetBonusDamage | core.SpellFlagAPL, ManaCost: core.ManaCostOptions{ BaseCost: 0.05, diff --git a/sim/paladin/divine_plea.go b/sim/paladin/divine_plea.go index ddcaeee40c..5edf245467 100644 --- a/sim/paladin/divine_plea.go +++ b/sim/paladin/divine_plea.go @@ -39,6 +39,7 @@ func (paladin *Paladin) registerDivinePleaSpell() { paladin.DivinePlea = paladin.RegisterSpell(core.SpellConfig{ ActionID: actionID, SpellSchool: core.SpellSchoolHoly, + Flags: core.SpellFlagAPL, Cast: core.CastConfig{ DefaultCast: core.Cast{ diff --git a/sim/paladin/divine_protection.go b/sim/paladin/divine_protection.go index dfc4babc48..b0a61d0a3b 100644 --- a/sim/paladin/divine_protection.go +++ b/sim/paladin/divine_protection.go @@ -28,6 +28,7 @@ func (paladin *Paladin) registerDivineProtectionSpell() { paladin.DivineProtection = paladin.RegisterSpell(core.SpellConfig{ ActionID: actionID, + Flags: core.SpellFlagAPL, Cast: core.CastConfig{ CD: core.Cooldown{ diff --git a/sim/paladin/divine_storm.go b/sim/paladin/divine_storm.go index 13be4ead4a..5a2c74f31a 100644 --- a/sim/paladin/divine_storm.go +++ b/sim/paladin/divine_storm.go @@ -17,7 +17,7 @@ func (paladin *Paladin) registerDivineStormSpell() { ActionID: core.ActionID{SpellID: 53385}, SpellSchool: core.SpellSchoolPhysical, ProcMask: core.ProcMaskMeleeMHSpecial, - Flags: core.SpellFlagMeleeMetrics | core.SpellFlagIncludeTargetBonusDamage, + Flags: core.SpellFlagMeleeMetrics | core.SpellFlagIncludeTargetBonusDamage | core.SpellFlagAPL, ManaCost: core.ManaCostOptions{ BaseCost: 0.12, diff --git a/sim/paladin/exorcism.go b/sim/paladin/exorcism.go index 099f4caec0..9e44483b3f 100644 --- a/sim/paladin/exorcism.go +++ b/sim/paladin/exorcism.go @@ -12,7 +12,7 @@ func (paladin *Paladin) registerExorcismSpell() { ActionID: core.ActionID{SpellID: 48801}, SpellSchool: core.SpellSchoolHoly, ProcMask: core.ProcMaskSpellDamage, - Flags: core.SpellFlagMeleeMetrics, + Flags: core.SpellFlagMeleeMetrics | core.SpellFlagAPL, ManaCost: core.ManaCostOptions{ BaseCost: 0.08, @@ -29,7 +29,7 @@ func (paladin *Paladin) registerExorcismSpell() { }, ModifyCast: func(sim *core.Simulation, spell *core.Spell, cast *core.Cast) { if paladin.CurrentMana() >= cast.Cost { - castTime := time.Duration(float64(cast.CastTime) * spell.CastTimeMultiplier) + castTime := paladin.ApplyCastSpeedForSpell(cast.CastTime, spell) if castTime > 0 { paladin.AutoAttacks.StopMeleeUntil(sim, sim.CurrentTime+castTime, false) } diff --git a/sim/paladin/hammer_of_the_righteous.go b/sim/paladin/hammer_of_the_righteous.go index e8d8fe3ab1..7d84c49cd0 100644 --- a/sim/paladin/hammer_of_the_righteous.go +++ b/sim/paladin/hammer_of_the_righteous.go @@ -15,7 +15,7 @@ func (paladin *Paladin) registerHammerOfTheRighteousSpell() { ActionID: core.ActionID{SpellID: 53595}, SpellSchool: core.SpellSchoolHoly, ProcMask: core.ProcMaskMeleeMHSpecial, - Flags: core.SpellFlagMeleeMetrics, + Flags: core.SpellFlagMeleeMetrics | core.SpellFlagAPL, ManaCost: core.ManaCostOptions{ BaseCost: 0.06, diff --git a/sim/paladin/hammer_of_wrath.go b/sim/paladin/hammer_of_wrath.go index aabf92e464..941f8eb365 100644 --- a/sim/paladin/hammer_of_wrath.go +++ b/sim/paladin/hammer_of_wrath.go @@ -12,7 +12,7 @@ func (paladin *Paladin) registerHammerOfWrathSpell() { ActionID: core.ActionID{SpellID: 48806}, SpellSchool: core.SpellSchoolHoly, ProcMask: core.ProcMaskMeleeMHSpecial, - Flags: core.SpellFlagMeleeMetrics, + Flags: core.SpellFlagMeleeMetrics | core.SpellFlagAPL, ManaCost: core.ManaCostOptions{ BaseCost: 0.12 * core.TernaryFloat64(paladin.HasMajorGlyph(proto.PaladinMajorGlyph_GlyphOfHammerOfWrath), 0, 1), @@ -28,6 +28,9 @@ func (paladin *Paladin) registerHammerOfWrathSpell() { Duration: time.Second * 6, }, }, + ExtraCastCondition: func(sim *core.Simulation, target *core.Unit) bool { + return sim.IsExecutePhase20() + }, BonusCritRating: 25 * float64(paladin.Talents.SanctifiedWrath) * core.CritRatingPerCritChance, DamageMultiplierAdditive: 1 + diff --git a/sim/paladin/hand_of_reckoning.go b/sim/paladin/hand_of_reckoning.go index 9b56a41042..37e6df5472 100644 --- a/sim/paladin/hand_of_reckoning.go +++ b/sim/paladin/hand_of_reckoning.go @@ -16,7 +16,7 @@ func (paladin *Paladin) registerHandOfReckoningSpell() { ActionID: core.ActionID{SpellID: 67485}, // 62124 is the "taunt" part SpellSchool: core.SpellSchoolHoly, ProcMask: core.ProcMaskSpellDamage, - Flags: core.SpellFlagMeleeMetrics, + Flags: core.SpellFlagMeleeMetrics | core.SpellFlagAPL, ManaCost: core.ManaCostOptions{ BaseCost: 0.03, diff --git a/sim/paladin/holy_shield.go b/sim/paladin/holy_shield.go index c1d7fef6f0..65ae5d8af1 100644 --- a/sim/paladin/holy_shield.go +++ b/sim/paladin/holy_shield.go @@ -55,6 +55,7 @@ func (paladin *Paladin) registerHolyShieldSpell() { paladin.HolyShield = paladin.RegisterSpell(core.SpellConfig{ ActionID: actionID, SpellSchool: core.SpellSchoolHoly, + Flags: core.SpellFlagAPL, ManaCost: core.ManaCostOptions{ BaseCost: 0.10, diff --git a/sim/paladin/holy_wrath.go b/sim/paladin/holy_wrath.go index aa8ce0a5af..40b1c67c2e 100644 --- a/sim/paladin/holy_wrath.go +++ b/sim/paladin/holy_wrath.go @@ -14,7 +14,7 @@ func (paladin *Paladin) registerHolyWrathSpell() { ActionID: core.ActionID{SpellID: 48817}, SpellSchool: core.SpellSchoolHoly, ProcMask: core.ProcMaskSpellDamage, - Flags: core.SpellFlagMeleeMetrics, + Flags: core.SpellFlagMeleeMetrics | core.SpellFlagAPL, ManaCost: core.ManaCostOptions{ BaseCost: 0.20, diff --git a/sim/paladin/judgement.go b/sim/paladin/judgement.go index 464bd7a66d..7e9cf91474 100644 --- a/sim/paladin/judgement.go +++ b/sim/paladin/judgement.go @@ -20,7 +20,7 @@ func (paladin *Paladin) registerJudgementOfWisdomSpell(cdTimer *core.Timer) { ActionID: core.ActionID{SpellID: 53408}, SpellSchool: core.SpellSchoolHoly, ProcMask: core.ProcMaskEmpty, - Flags: SpellFlagPrimaryJudgement, + Flags: SpellFlagPrimaryJudgement | core.SpellFlagAPL, ManaCost: core.ManaCostOptions{ BaseCost: 0.05, @@ -58,7 +58,7 @@ func (paladin *Paladin) registerJudgementOfLightSpell(cdTimer *core.Timer) { ActionID: core.ActionID{SpellID: 20271}, SpellSchool: core.SpellSchoolHoly, ProcMask: core.ProcMaskEmpty, - Flags: SpellFlagPrimaryJudgement, + Flags: SpellFlagPrimaryJudgement | core.SpellFlagAPL, ManaCost: core.ManaCostOptions{ BaseCost: 0.05, diff --git a/sim/paladin/protection/rotation.go b/sim/paladin/protection/rotation.go index eedd77b52e..b129a3eebd 100644 --- a/sim/paladin/protection/rotation.go +++ b/sim/paladin/protection/rotation.go @@ -9,6 +9,10 @@ import ( ) func (prot *ProtectionPaladin) OnGCDReady(sim *core.Simulation) { + if prot.IsUsingAPL { + return + } + prot.SelectedRotation(sim) if prot.GCD.IsReady(sim) { diff --git a/sim/paladin/retribution/rotation.go b/sim/paladin/retribution/rotation.go index 718384f8a9..18ef77ab8e 100644 --- a/sim/paladin/retribution/rotation.go +++ b/sim/paladin/retribution/rotation.go @@ -42,6 +42,10 @@ func (ret *RetributionPaladin) OnAutoAttack(sim *core.Simulation, spell *core.Sp } func (ret *RetributionPaladin) OnGCDReady(sim *core.Simulation) { + if ret.IsUsingAPL { + return + } + ret.SelectedRotation(sim) if ret.GCD.IsReady(sim) { ret.DoNothing() // this means we had nothing to do and we are ok @@ -303,8 +307,7 @@ func (ret *RetributionPaladin) mainRotation(sim *core.Simulation) { func (ret *RetributionPaladin) checkConsecrationClipping(sim *core.Simulation) bool { if ret.AvoidClippingConsecration { - // TODO: sim.Duration is the wrong value to check - return sim.CurrentTime+ret.Consecration.AOEDot().TickLength*4 <= sim.Duration + return ret.Consecration.AOEDot().TickLength*4 <= sim.GetRemainingDuration() } else { // If we're not configured to check, always return success. return true diff --git a/sim/paladin/shield_of_righteousness.go b/sim/paladin/shield_of_righteousness.go index f074673de3..e5c8eab113 100644 --- a/sim/paladin/shield_of_righteousness.go +++ b/sim/paladin/shield_of_righteousness.go @@ -17,7 +17,7 @@ func (paladin *Paladin) registerShieldOfRighteousnessSpell() { ActionID: core.ActionID{SpellID: 61411}, SpellSchool: core.SpellSchoolHoly, ProcMask: core.ProcMaskMeleeMHSpecial, - Flags: core.SpellFlagMeleeMetrics, + Flags: core.SpellFlagMeleeMetrics | core.SpellFlagAPL, ManaCost: core.ManaCostOptions{ BaseCost: 0.06, diff --git a/sim/paladin/soc.go b/sim/paladin/soc.go index 9570357c5f..0025ded0a3 100644 --- a/sim/paladin/soc.go +++ b/sim/paladin/soc.go @@ -159,6 +159,7 @@ func (paladin *Paladin) registerSealOfCommandSpellAndAura() { ActionID: auraActionID, // Seal of Command self buff. SpellSchool: core.SpellSchoolHoly, ProcMask: core.ProcMaskEmpty, + Flags: core.SpellFlagAPL, ManaCost: core.ManaCostOptions{ BaseCost: 0.14, diff --git a/sim/paladin/sor.go b/sim/paladin/sor.go index 5b2a1ad87b..a4af165dc1 100644 --- a/sim/paladin/sor.go +++ b/sim/paladin/sor.go @@ -106,6 +106,7 @@ func (paladin *Paladin) registerSealOfRighteousnessSpellAndAura() { paladin.SealOfRighteousness = paladin.RegisterSpell(core.SpellConfig{ ActionID: auraActionID, // Seal of Righteousness self buff. SpellSchool: core.SpellSchoolHoly, + Flags: core.SpellFlagAPL, ManaCost: core.ManaCostOptions{ BaseCost: 0.14, diff --git a/sim/paladin/sov.go b/sim/paladin/sov.go index aae722cd26..58a679a380 100644 --- a/sim/paladin/sov.go +++ b/sim/paladin/sov.go @@ -204,6 +204,7 @@ func (paladin *Paladin) registerSealOfVengeanceSpellAndAura() { paladin.SealOfVengeance = paladin.RegisterSpell(core.SpellConfig{ ActionID: auraActionID, // Seal of Vengeance self buff. SpellSchool: core.SpellSchoolHoly, + Flags: core.SpellFlagAPL, ManaCost: core.ManaCostOptions{ BaseCost: 0.14, diff --git a/ui/core/launched_sims.ts b/ui/core/launched_sims.ts index b67aca573a..011e49268d 100644 --- a/ui/core/launched_sims.ts +++ b/ui/core/launched_sims.ts @@ -52,7 +52,7 @@ export const aplLaunchStatuses: Record = { [Spec.SpecRogue]: LaunchStatus.Alpha, [Spec.SpecHolyPaladin]: LaunchStatus.Unlaunched, [Spec.SpecProtectionPaladin]: LaunchStatus.Unlaunched, - [Spec.SpecRetributionPaladin]: LaunchStatus.Unlaunched, + [Spec.SpecRetributionPaladin]: LaunchStatus.Alpha, [Spec.SpecHealingPriest]: LaunchStatus.Unlaunched, [Spec.SpecShadowPriest]: LaunchStatus.Alpha, [Spec.SpecSmitePriest]: LaunchStatus.Unlaunched, diff --git a/ui/retribution_paladin/presets.ts b/ui/retribution_paladin/presets.ts index b4018b3b5c..b4a812e07b 100644 --- a/ui/retribution_paladin/presets.ts +++ b/ui/retribution_paladin/presets.ts @@ -8,8 +8,9 @@ import { ItemSpec } from '../core/proto/common.js'; import { Potions } from '../core/proto/common.js'; import { Spec } from '../core/proto/common.js'; import { Faction } from '../core/proto/common.js'; -import { SavedTalents } from '../core/proto/ui.js'; +import { SavedRotation, SavedTalents } from '../core/proto/ui.js'; import { Player } from '../core/player.js'; +import { APLRotation } from '../core/proto/apl.js'; import { PaladinAura as PaladinAura, @@ -265,3 +266,26 @@ export const P5_PRESET = { {"id":50455} ]}`), }; + +export const ROTATION_PRESET_BASIC_APL = { + name: 'Basic APL', + rotation: SavedRotation.create({ + specRotationOptionsJson: RetributionPaladinRotation.toJsonString(DefaultRotation), + rotation: APLRotation.fromJsonString(`{ + "enabled": true, + "prepullActions": [ + {"action":{"castSpell":{"spellId":{"otherId":"OtherActionPotion"}}},"doAt":"-1s"} + ], + "priorityList": [ + {"action":{"autocastOtherCooldowns":{}}}, + {"action":{"castSpell":{"spellId":{"spellId":67485}}}}, + {"action":{"castSpell":{"spellId":{"spellId":48806}}}}, + {"action":{"castSpell":{"spellId":{"spellId":53408}}}}, + {"action":{"castSpell":{"spellId":{"spellId":35395}}}}, + {"action":{"castSpell":{"spellId":{"spellId":53385}}}}, + {"action":{"condition":{"auraIsActive":{"auraId":{"spellId":53488}}},"castSpell":{"spellId":{"spellId":48801}}}}, + {"action":{"condition":{"cmp":{"op":"OpGt","lhs":{"remainingTime":{}},"rhs":{"const":{"val":"4s"}}}},"castSpell":{"spellId":{"spellId":48819}}}} + ] + }`), + }), + }; \ No newline at end of file diff --git a/ui/retribution_paladin/sim.ts b/ui/retribution_paladin/sim.ts index ddf40bb009..ec98c1f240 100644 --- a/ui/retribution_paladin/sim.ts +++ b/ui/retribution_paladin/sim.ts @@ -197,6 +197,9 @@ export class RetributionPaladinSimUI extends IndividualSimUI