diff --git a/proto/apl.proto b/proto/apl.proto index b2e809addd..24d2042c13 100644 --- a/proto/apl.proto +++ b/proto/apl.proto @@ -83,6 +83,8 @@ message APLValue { APLValueSpellIsReady spell_is_ready = 20; APLValueSpellTimeToReady spell_time_to_ready = 21; APLValueSpellCastTime spell_cast_time = 35; + APLValueSpellChannelTime spell_channel_time = 36; + APLValueSpellTravelTime spell_travel_time = 37; // Aura values APLValueAuraIsActive aura_is_active = 22; @@ -240,6 +242,12 @@ message APLValueSpellTimeToReady { message APLValueSpellCastTime { ActionID spell_id = 1; } +message APLValueSpellChannelTime { + ActionID spell_id = 1; +} +message APLValueSpellTravelTime { + ActionID spell_id = 1; +} message APLValueAuraIsActive { ActionID aura_id = 1; diff --git a/sim/core/apl_value.go b/sim/core/apl_value.go index 7d925524f7..ed51bd46de 100644 --- a/sim/core/apl_value.go +++ b/sim/core/apl_value.go @@ -116,6 +116,10 @@ func (rot *APLRotation) newAPLValue(config *proto.APLValue) APLValue { return rot.newValueSpellTimeToReady(config.GetSpellTimeToReady()) case *proto.APLValue_SpellCastTime: return rot.newValueSpellCastTime(config.GetSpellCastTime()) + case *proto.APLValue_SpellChannelTime: + return rot.newValueSpellChannelTime(config.GetSpellChannelTime()) + case *proto.APLValue_SpellTravelTime: + return rot.newValueSpellTravelTime(config.GetSpellTravelTime()) // Auras case *proto.APLValue_AuraIsActive: diff --git a/sim/core/apl_values_spell.go b/sim/core/apl_values_spell.go index 52ec236562..e3a6d9fc8f 100644 --- a/sim/core/apl_values_spell.go +++ b/sim/core/apl_values_spell.go @@ -97,3 +97,47 @@ func (value *APLValueSpellCastTime) Type() proto.APLValueType { func (value *APLValueSpellCastTime) GetDuration(sim *Simulation) time.Duration { return value.spell.Unit.ApplyCastSpeedForSpell(value.spell.DefaultCast.CastTime, value.spell) } + +type APLValueSpellChannelTime struct { + defaultAPLValueImpl + spell *Spell +} + +func (rot *APLRotation) newValueSpellChannelTime(config *proto.APLValueSpellChannelTime) APLValue { + unit := rot.unit + spell := unit.aplGetSpell(config.SpellId) + if spell == nil { + return nil + } + return &APLValueSpellChannelTime{ + spell: spell, + } +} +func (value *APLValueSpellChannelTime) Type() proto.APLValueType { + return proto.APLValueType_ValueTypeDuration +} +func (value *APLValueSpellChannelTime) GetDuration(sim *Simulation) time.Duration { + return value.spell.Unit.ApplyCastSpeedForSpell(value.spell.DefaultCast.ChannelTime, value.spell) +} + +type APLValueSpellTravelTime struct { + defaultAPLValueImpl + spell *Spell +} + +func (rot *APLRotation) newValueSpellTravelTime(config *proto.APLValueSpellTravelTime) APLValue { + unit := rot.unit + spell := unit.aplGetSpell(config.SpellId) + if spell == nil { + return nil + } + return &APLValueSpellTravelTime{ + spell: spell, + } +} +func (value *APLValueSpellTravelTime) Type() proto.APLValueType { + return proto.APLValueType_ValueTypeDuration +} +func (value *APLValueSpellTravelTime) GetDuration(sim *Simulation) time.Duration { + return time.Duration(float64(time.Second) * value.spell.Unit.DistanceFromTarget / value.spell.MissileSpeed) +} diff --git a/ui/core/components/individual_sim_ui/apl_values.ts b/ui/core/components/individual_sim_ui/apl_values.ts index 09bb3ecd76..64888b4e4f 100644 --- a/ui/core/components/individual_sim_ui/apl_values.ts +++ b/ui/core/components/individual_sim_ui/apl_values.ts @@ -36,6 +36,8 @@ import { APLValueNumberTargets, APLValueSpellCastTime, APLValueCurrentNonDeathRuneCount, + APLValueSpellTravelTime, + APLValueSpellChannelTime, } from '../../proto/apl.js'; import { EventID, TypedEvent } from '../../typed_event.js'; @@ -464,7 +466,7 @@ const valueTypeFactories: Record, ValueTypeConfig ], }), ['currentRuneActive']: inputBuilder({ - label: 'Rune Ready', + label: 'Rune Is Ready', submenu: ['Resources', 'Runes'], shortDescription: 'Is the rune of a certain slot currently available.', newValue: APLValueCurrentRuneActive.create, @@ -473,7 +475,7 @@ const valueTypeFactories: Record, ValueTypeConfig ], }), ['currentRuneDeath']: inputBuilder({ - label: 'Rune Death', + label: 'Rune Is Death', submenu: ['Resources', 'Runes'], shortDescription: 'Is the rune of a certain slot currently converted to Death.', newValue: APLValueCurrentRuneDeath.create, @@ -556,6 +558,24 @@ const valueTypeFactories: Record, ValueTypeConfig AplHelpers.actionIdFieldConfig('spellId', 'castable_spells'), ], }), + ['spellChannelTime']: inputBuilder({ + label: 'Channel Time', + submenu: ['Spell'], + shortDescription: 'Amount of time to channel the spell including any haste and spell cast time adjustments.', + newValue: APLValueSpellChannelTime.create, + fields: [ + AplHelpers.actionIdFieldConfig('spellId', 'castable_spells'), + ], + }), + ['spellTravelTime']: inputBuilder({ + label: 'Travel Time', + submenu: ['Spell'], + shortDescription: 'Amount of time for the spell to travel to the target.', + newValue: APLValueSpellTravelTime.create, + fields: [ + AplHelpers.actionIdFieldConfig('spellId', 'castable_spells'), + ], + }), // Auras ['auraIsActive']: inputBuilder({