Skip to content

Commit

Permalink
Merge pull request #3685 from wowsims/apl
Browse files Browse the repository at this point in the history
Implement Scheduled Actions for APL
  • Loading branch information
jimmyt857 authored Sep 16, 2023
2 parents a03e60d + 3a31ca0 commit 32d3daf
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 91 deletions.
72 changes: 42 additions & 30 deletions proto/apl.proto
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,32 @@ message APLListItem {
APLAction action = 3; // The action to be performed.
}

// NextIndex: 15
// NextIndex: 16
message APLAction {
APLValue condition = 1; // If set, action will only execute if value is true or != 0.

oneof action {
APLActionSequence sequence = 2;
APLActionResetSequence reset_sequence = 5;
APLActionStrictSequence strict_sequence = 6;

// Casting
APLActionCastSpell cast_spell = 3;
APLActionMultidot multidot = 8;
APLActionMultishield multishield = 12;
APLActionAutocastOtherCooldowns autocast_other_cooldowns = 7;

// Timing
APLActionWait wait = 4;
APLActionWaitUntil wait_until = 14;
APLActionSchedule schedule = 15;

// Sequences
APLActionSequence sequence = 2;
APLActionResetSequence reset_sequence = 5;
APLActionStrictSequence strict_sequence = 6;

// Misc
APLActionAutocastOtherCooldowns autocast_other_cooldowns = 7;
APLActionChangeTarget change_target = 9;
APLActionActivateAura activate_aura = 13;
APLActionCancelAura cancel_aura = 10;
APLActionTriggerICD trigger_icd = 11;
APLActionWait wait = 4;
APLActionWaitUntil wait_until = 14;
}
}

Expand Down Expand Up @@ -153,20 +158,6 @@ message APLValue {
// ACTIONS
///////////////////////////////////////////////////////////////////////////

message APLActionSequence {
string name = 1;

repeated APLAction actions = 2;
}

message APLActionResetSequence {
string sequence_name = 1;
}

message APLActionStrictSequence {
repeated APLAction actions = 1;
}

message APLActionCastSpell {
ActionID spell_id = 1;
UnitReference target = 2;
Expand All @@ -187,6 +178,35 @@ message APLActionMultishield {
message APLActionAutocastOtherCooldowns {
}

message APLActionWait {
APLValue duration = 1;
}

message APLActionWaitUntil {
APLValue condition = 1;
}

message APLActionSchedule {
// Comma-separated list of times, e.g. '0s, 30s, 60s'
string schedule = 1;

APLAction inner_action = 2;
}

message APLActionSequence {
string name = 1;

repeated APLAction actions = 2;
}

message APLActionResetSequence {
string sequence_name = 1;
}

message APLActionStrictSequence {
repeated APLAction actions = 1;
}

message APLActionChangeTarget {
UnitReference new_target = 1;
}
Expand All @@ -203,14 +223,6 @@ message APLActionTriggerICD {
ActionID aura_id = 1;
}

message APLActionWait {
APLValue duration = 1;
}

message APLActionWaitUntil {
APLValue condition = 1;
}

///////////////////////////////////////////////////////////////////////////
// VALUES
///////////////////////////////////////////////////////////////////////////
Expand Down
29 changes: 19 additions & 10 deletions sim/core/apl_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,7 @@ func (rot *APLRotation) newAPLActionImpl(config *proto.APLAction) APLActionImpl
}

switch config.Action.(type) {
case *proto.APLAction_Sequence:
return rot.newActionSequence(config.GetSequence())
case *proto.APLAction_ResetSequence:
return rot.newActionResetSequence(config.GetResetSequence())
case *proto.APLAction_StrictSequence:
return rot.newActionStrictSequence(config.GetStrictSequence())
// Casting
case *proto.APLAction_CastSpell:
return rot.newActionCastSpell(config.GetCastSpell())
case *proto.APLAction_Multidot:
Expand All @@ -146,6 +141,24 @@ func (rot *APLRotation) newAPLActionImpl(config *proto.APLAction) APLActionImpl
return rot.newActionMultishield(config.GetMultishield())
case *proto.APLAction_AutocastOtherCooldowns:
return rot.newActionAutocastOtherCooldowns(config.GetAutocastOtherCooldowns())

// Timing
case *proto.APLAction_Wait:
return rot.newActionWait(config.GetWait())
case *proto.APLAction_WaitUntil:
return rot.newActionWaitUntil(config.GetWaitUntil())
case *proto.APLAction_Schedule:
return rot.newActionSchedule(config.GetSchedule())

// Sequences
case *proto.APLAction_Sequence:
return rot.newActionSequence(config.GetSequence())
case *proto.APLAction_ResetSequence:
return rot.newActionResetSequence(config.GetResetSequence())
case *proto.APLAction_StrictSequence:
return rot.newActionStrictSequence(config.GetStrictSequence())

// Misc
case *proto.APLAction_ChangeTarget:
return rot.newActionChangeTarget(config.GetChangeTarget())
case *proto.APLAction_ActivateAura:
Expand All @@ -154,10 +167,6 @@ func (rot *APLRotation) newAPLActionImpl(config *proto.APLAction) APLActionImpl
return rot.newActionCancelAura(config.GetCancelAura())
case *proto.APLAction_TriggerIcd:
return rot.newActionTriggerICD(config.GetTriggerIcd())
case *proto.APLAction_Wait:
return rot.newActionWait(config.GetWait())
case *proto.APLAction_WaitUntil:
return rot.newActionWaitUntil(config.GetWaitUntil())
default:
return nil
}
Expand Down
60 changes: 60 additions & 0 deletions sim/core/apl_actions_core.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package core

import (
"fmt"
"strings"
"time"

"github.com/wowsims/wotlk/sim/core/proto"
Expand Down Expand Up @@ -298,3 +299,62 @@ func (action *APLActionWaitUntil) GetNextAction(sim *Simulation) *APLAction {
func (action *APLActionWaitUntil) String() string {
return fmt.Sprintf("WaitUntil(%s)", action.condition)
}

type APLActionSchedule struct {
defaultAPLActionImpl
innerAction *APLAction

timings []time.Duration
nextTimingIdx int
}

func (rot *APLRotation) newActionSchedule(config *proto.APLActionSchedule) APLActionImpl {
innerAction := rot.newAPLAction(config.InnerAction)
if innerAction == nil {
return nil
}

timingStrs := strings.Split(config.Schedule, ",")
if len(timingStrs) == 0 {
return nil
}

timings := make([]time.Duration, len(timingStrs))
valid := true
for i, timingStr := range timingStrs {
if durVal, err := time.ParseDuration(strings.TrimSpace(timingStr)); err == nil {
timings[i] = durVal
} else {
rot.ValidationWarning("Invalid duration value '%s'", strings.TrimSpace(timingStr))
valid = false
}
}
if !valid {
return nil
}

return &APLActionSchedule{
innerAction: innerAction,
timings: timings,
}
}
func (action *APLActionSchedule) Reset(*Simulation) {
action.nextTimingIdx = 0
}
func (action *APLActionSchedule) GetInnerActions() []*APLAction {
return []*APLAction{action.innerAction}
}
func (action *APLActionSchedule) IsReady(sim *Simulation) bool {
return action.nextTimingIdx < len(action.timings) &&
sim.CurrentTime >= action.timings[action.nextTimingIdx] &&
action.innerAction.IsReady(sim)
}

func (action *APLActionSchedule) Execute(sim *Simulation) {
action.nextTimingIdx++
action.innerAction.Execute(sim)
}

func (action *APLActionSchedule) String() string {
return fmt.Sprintf("Schedule(%s, %s)", action.timings, action.innerAction)
}
Loading

0 comments on commit 32d3daf

Please sign in to comment.