diff --git a/proto/apl.proto b/proto/apl.proto index dadb792ca4..d17be22e16 100644 --- a/proto/apl.proto +++ b/proto/apl.proto @@ -76,7 +76,7 @@ message APLAction { } } -// NextIndex: 61 +// NextIndex: 64 message APLValue { oneof value { // Operators @@ -135,6 +135,7 @@ message APLValue { APLValueSpellCPM spell_cpm = 42; APLValueSpellIsChanneling spell_is_channeling = 56; APLValueSpellChanneledTicks spell_channeled_ticks = 57; + APLValueSpellCurrentCost spell_current_cost = 62; // Aura values APLValueAuraIsActive aura_is_active = 22; @@ -156,10 +157,12 @@ message APLValue { // Properties APLValueChannelClipDelay channel_clip_delay = 58; + APLValueFrontOfTarget front_of_target = 63; // Class or Spec-specific values APLValueTotemRemainingTime totem_remaining_time = 49; APLValueCatExcessEnergy cat_excess_energy = 52; + APLValueCatNewSavageRoarDuration cat_new_savage_roar_duration = 61; APLValueWarlockShouldRecastDrainSoul warlock_should_recast_drain_soul = 59; APLValueWarlockShouldRefreshCorruption warlock_should_refresh_corruption = 60; } @@ -402,6 +405,9 @@ message APLValueSpellChannelTime { } message APLValueChannelClipDelay { } +message APLValueFrontOfTarget { +} + message APLValueSpellTravelTime { ActionID spell_id = 1; } @@ -414,6 +420,9 @@ message APLValueSpellIsChanneling { message APLValueSpellChanneledTicks { ActionID spell_id = 1; } +message APLValueSpellCurrentCost { + ActionID spell_id = 1; +} message APLValueAuraIsActive { UnitReference source_unit = 2; @@ -469,6 +478,8 @@ message APLValueTotemRemainingTime { } message APLValueCatExcessEnergy { } +message APLValueCatNewSavageRoarDuration { +} message APLValueWarlockShouldRecastDrainSoul { } message APLValueWarlockShouldRefreshCorruption { diff --git a/sim/core/apl_values_properties.go b/sim/core/apl_values_properties.go index 4c2e5a702c..d73bfa5b01 100644 --- a/sim/core/apl_values_properties.go +++ b/sim/core/apl_values_properties.go @@ -25,3 +25,23 @@ func (value *APLValueChannelClipDelay) GetDuration(sim *Simulation) time.Duratio func (value *APLValueChannelClipDelay) String() string { return "Channel Clip Delay()" } + +type APLValueFrontOfTarget struct { + DefaultAPLValueImpl + unit *Unit +} + +func (rot *APLRotation) newValueFrontOfTarget(config *proto.APLValueFrontOfTarget) APLValue { + return &APLValueFrontOfTarget{ + unit: rot.unit, + } +} +func (value *APLValueFrontOfTarget) Type() proto.APLValueType { + return proto.APLValueType_ValueTypeBool +} +func (value *APLValueFrontOfTarget) GetBool(sim *Simulation) bool { + return value.unit.PseudoStats.InFrontOfTarget +} +func (value *APLValueFrontOfTarget) String() string { + return "Front of Target()" +} diff --git a/sim/core/apl_values_spell.go b/sim/core/apl_values_spell.go index aca1e8cb85..af2e37cddb 100644 --- a/sim/core/apl_values_spell.go +++ b/sim/core/apl_values_spell.go @@ -227,3 +227,28 @@ func (value *APLValueSpellChanneledTicks) GetInt(_ *Simulation) int32 { func (value *APLValueSpellChanneledTicks) String() string { return fmt.Sprintf("ChanneledTicks(%s)", value.spell.ActionID) } + +type APLValueSpellCurrentCost struct { + DefaultAPLValueImpl + spell *Spell +} + +func (rot *APLRotation) newValueSpellCurrentCost(config *proto.APLValueSpellCurrentCost) APLValue { + spell := rot.GetAPLSpell(config.SpellId) + if spell == nil { + return nil + } + return &APLValueSpellCurrentCost{ + spell: spell, + } +} +func (value *APLValueSpellCurrentCost) Type() proto.APLValueType { + return proto.APLValueType_ValueTypeFloat +} +func (value *APLValueSpellCurrentCost) GetFloat(_ *Simulation) float64 { + spell := value.spell + return spell.ApplyCostModifiers(spell.DefaultCast.Cost) +} +func (value *APLValueSpellCurrentCost) String() string { + return fmt.Sprintf("CurrentCost(%s)", value.spell.ActionID) +} diff --git a/sim/druid/feral/apl_values.go b/sim/druid/feral/apl_values.go index c8c76d8a94..0846b1afda 100644 --- a/sim/druid/feral/apl_values.go +++ b/sim/druid/feral/apl_values.go @@ -11,6 +11,8 @@ func (cat *FeralDruid) NewAPLValue(rot *core.APLRotation, config *proto.APLValue switch config.Value.(type) { case *proto.APLValue_CatExcessEnergy: return cat.newValueCatExcessEnergy(rot, config.GetCatExcessEnergy()) + case *proto.APLValue_CatNewSavageRoarDuration: + return cat.newValueCatNewSavageRoarDuration(rot, config.GetCatNewSavageRoarDuration()) default: return nil } @@ -67,3 +69,24 @@ func (value *APLValueCatExcessEnergy) GetFloat(sim *core.Simulation) float64 { func (value *APLValueCatExcessEnergy) String() string { return "Cat Excess Energy()" } + +type APLValueCatNewSavageRoarDuration struct { + core.DefaultAPLValueImpl + cat *FeralDruid +} + +func (cat *FeralDruid) newValueCatNewSavageRoarDuration(rot *core.APLRotation, config *proto.APLValueCatNewSavageRoarDuration) core.APLValue { + return &APLValueCatNewSavageRoarDuration{ + cat: cat, + } +} +func (value *APLValueCatNewSavageRoarDuration) Type() proto.APLValueType { + return proto.APLValueType_ValueTypeDuration +} +func (value *APLValueCatNewSavageRoarDuration) GetDuration(sim *core.Simulation) time.Duration { + cat := value.cat + return cat.SavageRoarDurationTable[cat.ComboPoints()] +} +func (value *APLValueCatNewSavageRoarDuration) String() string { + return "New Savage Roar Duration()" +} diff --git a/ui/core/components/character_stats.tsx b/ui/core/components/character_stats.tsx index c67e16974b..63b70f20b5 100644 --- a/ui/core/components/character_stats.tsx +++ b/ui/core/components/character_stats.tsx @@ -353,7 +353,6 @@ export class CharacterStats extends Component { return [ Spec.SpecDeathknight, Spec.SpecEnhancementShaman, - Spec.SpecFeralDruid, Spec.SpecRetributionPaladin, Spec.SpecRogue, Spec.SpecWarrior diff --git a/ui/core/components/individual_sim_ui/apl_values.ts b/ui/core/components/individual_sim_ui/apl_values.ts index 6752da6149..1143277884 100644 --- a/ui/core/components/individual_sim_ui/apl_values.ts +++ b/ui/core/components/individual_sim_ui/apl_values.ts @@ -52,7 +52,9 @@ import { APLValueSpellCPM, APLValueSpellIsChanneling, APLValueSpellChanneledTicks, + APLValueSpellCurrentCost, APLValueChannelClipDelay, + APLValueFrontOfTarget, APLValueAuraIsActive, APLValueAuraIsActiveWithReactionTime, APLValueAuraRemainingTime, @@ -72,6 +74,7 @@ import { APLValueCatExcessEnergy, APLValueWarlockShouldRecastDrainSoul, APLValueWarlockShouldRefreshCorruption, + APLValueCatNewSavageRoarDuration, } from '../../proto/apl.js'; import { EventID } from '../../typed_event.js'; @@ -543,6 +546,13 @@ const valueKindFactories: {[f in NonNullable]: ValueKindConfigTrue if facing from of target', + newValue: APLValueFrontOfTarget.create, + fields: [], + }), // Resources 'currentHealth': inputBuilder({ @@ -725,6 +735,15 @@ const valueKindFactories: {[f in NonNullable]: ValueKindConfig]: ValueKindConfig, isPrepull: boolean) => player.spec == Spec.SpecFeralDruid, + fields: [ + ], + }), 'warlockShouldRecastDrainSoul': inputBuilder({ label: 'Should Recast Drain Soul', submenu: ['Warlock'], @@ -989,7 +1017,7 @@ const valueKindFactories: {[f in NonNullable]: ValueKindConfigTrue if the current Corruption has expired, or should be refreshed to get a better snapshot.', - newValue: APLValueWarlockShouldRecastDrainSoul.create, + newValue: APLValueWarlockShouldRefreshCorruption.create, includeIf: (player: Player, isPrepull: boolean) => player.getClass() == Class.ClassWarlock, fields: [ AplHelpers.unitFieldConfig('targetUnit', 'targets'), diff --git a/ui/scss/core/components/detailed_results/_timeline.scss b/ui/scss/core/components/detailed_results/_timeline.scss index 789f829edd..deadfcd057 100644 --- a/ui/scss/core/components/detailed_results/_timeline.scss +++ b/ui/scss/core/components/detailed_results/_timeline.scss @@ -212,7 +212,7 @@ $combo-points-color: #ffa07a; position: absolute; bottom: 0; left: 0; - width: 100%; + width: 10px; background-color: yellow; } .rotation-timeline-cast {