Skip to content

Commit

Permalink
Merge pull request #3260 from wowsims/apl
Browse files Browse the repository at this point in the history
Implement multidotting and more values for APL
  • Loading branch information
jimmyt857 committed Jul 7, 2023
2 parents a910df5 + aeae39a commit 118759f
Show file tree
Hide file tree
Showing 15 changed files with 497 additions and 12 deletions.
1 change: 1 addition & 0 deletions proto/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ message ComputeStatsRequest {
}
message AuraStats {
ActionID id = 1;
int32 max_stacks = 2;
}
message SpellStats {
ActionID id = 1;
Expand Down
46 changes: 45 additions & 1 deletion proto/apl.proto
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ message APLAction {
APLActionStrictSequence strict_sequence = 6;

APLActionCastSpell cast_spell = 3;
APLActionMultidot multidot = 8;
APLActionAutocastOtherCooldowns autocast_other_cooldowns = 7;
APLActionWait wait = 4;
}
Expand Down Expand Up @@ -55,6 +56,20 @@ message APLValue {
APLValueCurrentEnergy current_energy = 15;
APLValueCurrentComboPoints current_combo_points = 16;

// GCD values
APLValueGCDIsReady gcd_is_ready = 17;
APLValueGCDTimeToReady gcd_time_to_ready = 18;

// Spell values
APLValueSpellCanCast spell_can_cast = 19;
APLValueSpellIsReady spell_is_ready = 20;
APLValueSpellTimeToReady spell_time_to_ready = 21;

// Aura values
APLValueAuraIsActive aura_is_active = 22;
APLValueAuraRemainingTime aura_remaining_time = 23;
APLValueAuraNumStacks aura_num_stacks = 24;

// Dot values
APLValueDotIsActive dot_is_active = 6;
APLValueDotRemainingTime dot_remaining_time = 13;
Expand Down Expand Up @@ -88,6 +103,12 @@ message APLActionCastSpell {
ActionID spell_id = 1;
}

message APLActionMultidot {
ActionID spell_id = 1;
int32 max_dots = 2;
APLValue max_overlap = 3;
}

message APLActionAutocastOtherCooldowns {
}

Expand Down Expand Up @@ -148,9 +169,32 @@ message APLValueCurrentRage {}
message APLValueCurrentEnergy {}
message APLValueCurrentComboPoints {}

message APLValueGCDIsReady {}
message APLValueGCDTimeToReady {}

message APLValueSpellCanCast {
ActionID spell_id = 1;
}
message APLValueSpellIsReady {
ActionID spell_id = 1;
}
message APLValueSpellTimeToReady {
ActionID spell_id = 1;
}

message APLValueAuraIsActive {
ActionID aura_id = 1;
}
message APLValueAuraRemainingTime {
ActionID aura_id = 1;
}
message APLValueAuraNumStacks {
ActionID aura_id = 1;
}

message APLValueDotIsActive {
ActionID spell_id = 1;
}
message APLValueDotRemainingTime {
ActionID spell_id = 1;
}
}
2 changes: 2 additions & 0 deletions sim/core/apl_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ func (unit *Unit) newAPLActionImpl(config *proto.APLAction) APLActionImpl {
return unit.newActionStrictSequence(config.GetStrictSequence())
case *proto.APLAction_CastSpell:
return unit.newActionCastSpell(config.GetCastSpell())
case *proto.APLAction_Multidot:
return unit.newActionMultidot(config.GetMultidot())
case *proto.APLAction_AutocastOtherCooldowns:
return unit.newActionAutocastOtherCooldowns(config.GetAutocastOtherCooldowns())
case *proto.APLAction_Wait:
Expand Down
43 changes: 43 additions & 0 deletions sim/core/apl_actions_core.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,49 @@ func (action *APLActionCastSpell) Execute(sim *Simulation) {
action.spell.Cast(sim, action.spell.Unit.CurrentTarget)
}

type APLActionMultidot struct {
spell *Spell
maxDots int32
maxOverlap APLValue

nextTarget *Unit
}

func (unit *Unit) newActionMultidot(config *proto.APLActionMultidot) APLActionImpl {
spell := unit.aplGetMultidotSpell(config.SpellId)
maxOverlap := unit.coerceTo(unit.newAPLValue(config.MaxOverlap), proto.APLValueType_ValueTypeDuration)
if maxOverlap == nil {
maxOverlap = unit.newValueConst(&proto.APLValueConst{Val: "0ms"})
}

return &APLActionMultidot{
spell: spell,
maxDots: MinInt32(config.MaxDots, unit.Env.GetNumTargets()),
maxOverlap: maxOverlap,
}
}
func (action *APLActionMultidot) GetInnerActions() []*APLAction { return nil }
func (action *APLActionMultidot) Finalize() {}
func (action *APLActionMultidot) Reset(*Simulation) {
action.nextTarget = nil
}
func (action *APLActionMultidot) IsReady(sim *Simulation) bool {
maxOverlap := action.maxOverlap.GetDuration(sim)

for i := int32(0); i < action.maxDots; i++ {
target := sim.Encounter.TargetUnits[i]
dot := action.spell.Dot(target)
if (!dot.IsActive() || dot.RemainingDuration(sim) < maxOverlap) && action.spell.CanCast(sim, target) {
action.nextTarget = target
return true
}
}
return false
}
func (action *APLActionMultidot) Execute(sim *Simulation) {
action.spell.Cast(sim, action.nextTarget)
}

type APLActionAutocastOtherCooldowns struct {
character *Character

Expand Down
22 changes: 22 additions & 0 deletions sim/core/apl_value.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,28 @@ func (unit *Unit) newAPLValue(config *proto.APLValue) APLValue {
case *proto.APLValue_CurrentComboPoints:
return unit.newValueCurrentComboPoints(config.GetCurrentComboPoints())

// GCD
case *proto.APLValue_GcdIsReady:
return unit.newValueGCDIsReady(config.GetGcdIsReady())
case *proto.APLValue_GcdTimeToReady:
return unit.newValueGCDTimeToReady(config.GetGcdTimeToReady())

// Spells
case *proto.APLValue_SpellCanCast:
return unit.newValueSpellCanCast(config.GetSpellCanCast())
case *proto.APLValue_SpellIsReady:
return unit.newValueSpellIsReady(config.GetSpellIsReady())
case *proto.APLValue_SpellTimeToReady:
return unit.newValueSpellTimeToReady(config.GetSpellTimeToReady())

// Auras
case *proto.APLValue_AuraIsActive:
return unit.newValueAuraIsActive(config.GetAuraIsActive())
case *proto.APLValue_AuraRemainingTime:
return unit.newValueAuraRemainingTime(config.GetAuraRemainingTime())
case *proto.APLValue_AuraNumStacks:
return unit.newValueAuraNumStacks(config.GetAuraNumStacks())

// Dots
case *proto.APLValue_DotIsActive:
return unit.newValueDotIsActive(config.GetDotIsActive())
Expand Down
77 changes: 77 additions & 0 deletions sim/core/apl_values_aura.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package core

import (
"time"

"github.com/wowsims/wotlk/sim/core/proto"
)

func (unit *Unit) aplGetAura(auraId *proto.ActionID) *Aura {
return unit.GetAuraByID(ProtoToActionID(auraId))
}

type APLValueAuraIsActive struct {
defaultAPLValueImpl
aura *Aura
}

func (unit *Unit) newValueAuraIsActive(config *proto.APLValueAuraIsActive) APLValue {
aura := unit.aplGetAura(config.AuraId)
if aura == nil {
return nil
}
return &APLValueAuraIsActive{
aura: aura,
}
}
func (value *APLValueAuraIsActive) Type() proto.APLValueType {
return proto.APLValueType_ValueTypeBool
}
func (value *APLValueAuraIsActive) GetBool(sim *Simulation) bool {
return value.aura.IsActive()
}

type APLValueAuraRemainingTime struct {
defaultAPLValueImpl
aura *Aura
}

func (unit *Unit) newValueAuraRemainingTime(config *proto.APLValueAuraRemainingTime) APLValue {
aura := unit.aplGetAura(config.AuraId)
if aura == nil {
return nil
}
return &APLValueAuraRemainingTime{
aura: aura,
}
}
func (value *APLValueAuraRemainingTime) Type() proto.APLValueType {
return proto.APLValueType_ValueTypeDuration
}
func (value *APLValueAuraRemainingTime) GetDuration(sim *Simulation) time.Duration {
return value.aura.RemainingDuration(sim)
}

type APLValueAuraNumStacks struct {
defaultAPLValueImpl
aura *Aura
}

func (unit *Unit) newValueAuraNumStacks(config *proto.APLValueAuraNumStacks) APLValue {
aura := unit.aplGetAura(config.AuraId)
if aura == nil {
return nil
}
if aura.MaxStacks == 0 {
return nil
}
return &APLValueAuraNumStacks{
aura: aura,
}
}
func (value *APLValueAuraNumStacks) Type() proto.APLValueType {
return proto.APLValueType_ValueTypeInt
}
func (value *APLValueAuraNumStacks) GetInt(sim *Simulation) int32 {
return value.aura.GetStacks()
}
8 changes: 8 additions & 0 deletions sim/core/apl_values_core.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ func (unit *Unit) aplGetDot(spellId *proto.ActionID) *Dot {
}
}

func (unit *Unit) aplGetMultidotSpell(spellId *proto.ActionID) *Spell {
spell := unit.GetSpell(ProtoToActionID(spellId))
if spell == nil || spell.CurDot() == nil {
return nil
}
return spell
}

type APLValueDotIsActive struct {
defaultAPLValueImpl
dot *Dot
Expand Down
41 changes: 41 additions & 0 deletions sim/core/apl_values_gcd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package core

import (
"time"

"github.com/wowsims/wotlk/sim/core/proto"
)

type APLValueGCDIsReady struct {
defaultAPLValueImpl
unit *Unit
}

func (unit *Unit) newValueGCDIsReady(config *proto.APLValueGCDIsReady) APLValue {
return &APLValueGCDIsReady{
unit: unit,
}
}
func (value *APLValueGCDIsReady) Type() proto.APLValueType {
return proto.APLValueType_ValueTypeBool
}
func (value *APLValueGCDIsReady) GetBool(sim *Simulation) bool {
return value.unit.GCD.IsReady(sim)
}

type APLValueGCDTimeToReady struct {
defaultAPLValueImpl
unit *Unit
}

func (unit *Unit) newValueGCDTimeToReady(config *proto.APLValueGCDTimeToReady) APLValue {
return &APLValueGCDTimeToReady{
unit: unit,
}
}
func (value *APLValueGCDTimeToReady) Type() proto.APLValueType {
return proto.APLValueType_ValueTypeDuration
}
func (value *APLValueGCDTimeToReady) GetDuration(sim *Simulation) time.Duration {
return value.unit.GCD.TimeToReady(sim)
}
74 changes: 74 additions & 0 deletions sim/core/apl_values_spell.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package core

import (
"time"

"github.com/wowsims/wotlk/sim/core/proto"
)

func (unit *Unit) aplGetSpell(spellId *proto.ActionID) *Spell {
return unit.GetSpell(ProtoToActionID(spellId))
}

type APLValueSpellCanCast struct {
defaultAPLValueImpl
spell *Spell
}

func (unit *Unit) newValueSpellCanCast(config *proto.APLValueSpellCanCast) APLValue {
spell := unit.aplGetSpell(config.SpellId)
if spell == nil {
return nil
}
return &APLValueSpellCanCast{
spell: spell,
}
}
func (value *APLValueSpellCanCast) Type() proto.APLValueType {
return proto.APLValueType_ValueTypeBool
}
func (value *APLValueSpellCanCast) GetBool(sim *Simulation) bool {
return value.spell.CanCast(sim, value.spell.Unit.CurrentTarget)
}

type APLValueSpellIsReady struct {
defaultAPLValueImpl
spell *Spell
}

func (unit *Unit) newValueSpellIsReady(config *proto.APLValueSpellIsReady) APLValue {
spell := unit.aplGetSpell(config.SpellId)
if spell == nil {
return nil
}
return &APLValueSpellIsReady{
spell: spell,
}
}
func (value *APLValueSpellIsReady) Type() proto.APLValueType {
return proto.APLValueType_ValueTypeBool
}
func (value *APLValueSpellIsReady) GetBool(sim *Simulation) bool {
return value.spell.IsReady(sim)
}

type APLValueSpellTimeToReady struct {
defaultAPLValueImpl
spell *Spell
}

func (unit *Unit) newValueSpellTimeToReady(config *proto.APLValueSpellTimeToReady) APLValue {
spell := unit.aplGetSpell(config.SpellId)
if spell == nil {
return nil
}
return &APLValueSpellTimeToReady{
spell: spell,
}
}
func (value *APLValueSpellTimeToReady) Type() proto.APLValueType {
return proto.APLValueType_ValueTypeDuration
}
func (value *APLValueSpellTimeToReady) GetDuration(sim *Simulation) time.Duration {
return value.spell.TimeToReady(sim)
}
8 changes: 8 additions & 0 deletions sim/core/aura.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,14 @@ func (at *auraTracker) GetAura(label string) *Aura {
}
return nil
}
func (at *auraTracker) GetAuraByID(actionID ActionID) *Aura {
for _, aura := range at.auras {
if aura.ActionID.SameAction(actionID) {
return aura
}
}
return nil
}
func (at *auraTracker) HasAura(label string) bool {
aura := at.GetAura(label)
return aura != nil
Expand Down
Loading

0 comments on commit 118759f

Please sign in to comment.