Skip to content

Commit

Permalink
implement off GCD apl
Browse files Browse the repository at this point in the history
  • Loading branch information
Adamrch committed Oct 8, 2024
1 parent 028e512 commit f2aa238
Show file tree
Hide file tree
Showing 33 changed files with 2,094 additions and 1,434 deletions.
18 changes: 17 additions & 1 deletion proto/apl.proto
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ message APLListItem {
APLAction action = 3; // The action to be performed.
}

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

Expand All @@ -56,7 +56,9 @@ message APLAction {
// Timing
APLActionWait wait = 4;
APLActionWaitUntil wait_until = 14;
APLActionRelativeSchedule relative_schedule = 24;
APLActionSchedule schedule = 15;
APLActionPeriodicSchedule periodic_schedule = 25;

// Sequences
APLActionSequence sequence = 2;
Expand Down Expand Up @@ -219,13 +221,27 @@ message APLActionWaitUntil {
APLValue condition = 1;
}

message APLActionRelativeSchedule {
// relative time compared to current time, e.g. '1s'
string schedule = 1;

APLAction inner_action = 2;
}

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

APLAction inner_action = 2;
}

message APLActionPeriodicSchedule {
// Comma-separated list of starttime and period e.g. '1s, 3s' for every 3 seconds starting at 1 seconds
string schedule = 1;

APLAction inner_action = 2;
}

message APLActionSequence {
string name = 1;

Expand Down
16 changes: 16 additions & 0 deletions sim/core/apl_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package core

import (
"fmt"
"time"

"github.com/wowsims/sod/sim/core/proto"
)
Expand All @@ -26,6 +27,10 @@ func (action *APLAction) Execute(sim *Simulation) {
action.impl.Execute(sim)
}

func (action *APLAction) ExecuteOffGCD(sim *Simulation, offGCDTime time.Duration) {
action.impl.ExecuteOffGCD(sim, offGCDTime)
}

// Returns this Action, along with all inner Actions.
func (action *APLAction) GetAllActions() []*APLAction {
actions := action.impl.GetInnerActions()
Expand Down Expand Up @@ -90,9 +95,15 @@ type APLActionImpl interface {
// Whether this action is available to be used right now.
IsReady(*Simulation) bool

// Whether this action is available Even during GCD
IsOffGCDAction() bool

// Performs the action.
Execute(*Simulation)

// Performs the action off GCD at the given time
ExecuteOffGCD(*Simulation, time.Duration)

// Called only while this action is controlling the rotation.
GetNextAction(sim *Simulation) *APLAction

Expand All @@ -109,6 +120,7 @@ func (impl defaultAPLActionImpl) GetAPLValues() []APLValue { return
func (impl defaultAPLActionImpl) Finalize(*APLRotation) {}
func (impl defaultAPLActionImpl) Reset(*Simulation) {}
func (impl defaultAPLActionImpl) GetNextAction(*Simulation) *APLAction { return nil }
func (impl defaultAPLActionImpl) IsOffGCDAction() bool { return false }

func (rot *APLRotation) newAPLAction(config *proto.APLAction) *APLAction {
if config == nil {
Expand Down Expand Up @@ -155,8 +167,12 @@ func (rot *APLRotation) newAPLActionImpl(config *proto.APLAction) APLActionImpl
return rot.newActionWait(config.GetWait())
case *proto.APLAction_WaitUntil:
return rot.newActionWaitUntil(config.GetWaitUntil())
case *proto.APLAction_RelativeSchedule:
return rot.newActionRelativeSchedule(config.GetRelativeSchedule())
case *proto.APLAction_Schedule:
return rot.newActionSchedule(config.GetSchedule())
case *proto.APLAction_PeriodicSchedule:
return rot.newActionPeriodicSchedule(config.GetPeriodicSchedule())

// Sequences
case *proto.APLAction_Sequence:
Expand Down
78 changes: 74 additions & 4 deletions sim/core/apl_actions_casting.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@ package core

import (
"fmt"
"time"

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

type APLActionCastSpell struct {
defaultAPLActionImpl
spell *Spell
target UnitReference
spell *Spell
target UnitReference
offGCD bool
offGCDTime time.Duration
offGCDTimeExe time.Duration
}

func (rot *APLRotation) newActionCastSpell(config *proto.APLActionCastSpell) APLActionImpl {
Expand All @@ -27,11 +31,53 @@ func (rot *APLRotation) newActionCastSpell(config *proto.APLActionCastSpell) APL
}
}
func (action *APLActionCastSpell) IsReady(sim *Simulation) bool {
return action.spell.CanCast(sim, action.target.Get()) && (!action.spell.Flags.Matches(SpellFlagMCD) || action.spell.Unit.GCD.IsReady(sim) || action.spell.DefaultCast.GCD == 0)
action.offGCD = false
ready := action.spell.CanCast(sim, action.target.Get()) && (!action.spell.Flags.Matches(SpellFlagMCD) || action.spell.Unit.GCD.IsReady(sim) || action.spell.DefaultCast.GCD == 0)

if !ready && (action.spell.DefaultCast.GCD == 0) && action.spell.CD.Timer != nil && (action.spell.CD.Timer.TimeToReady(sim) < 1500*time.Millisecond) && action.offGCDTimeExe != action.spell.CD.Timer.ReadyAt() {
//if sim.Log != nil {
// sim.Log("APLActionCastSpell IsReady offGCD")
//}
ready = true
action.offGCD = true
action.offGCDTime = action.spell.CD.Timer.ReadyAt()
}
return ready
}
func (action *APLActionCastSpell) IsOffGCDAction() bool {
return action.spell.DefaultCast.GCD == 0
}
func (action *APLActionCastSpell) Execute(sim *Simulation) {
action.spell.Cast(sim, action.target.Get())
if action.offGCD {
// Used when using APLActionCastSpell as an unnested action
action.offGCDTimeExe = action.offGCDTime
offGCDTimeExe := action.offGCDTimeExe
//if sim.Log != nil {
// sim.Log("APLActionCastSpell Execute Scheduling delayed off GCD action for %f", offGCDTimeExe)
//}
StartDelayedAction(sim, DelayedActionOptions{
DoAt: offGCDTimeExe,
OnAction: func(s *Simulation) {
if action.spell.CanCast(sim, action.target.Get()) {
action.spell.Cast(sim, action.target.Get())
}
},
})
} else {
action.spell.Cast(sim, action.target.Get())
}
}

func (action *APLActionCastSpell) ExecuteOffGCD(sim *Simulation, time time.Duration) {
//if sim.Log != nil {
// sim.Log("APLActionCastSpell ExecuteOffGCD Scheduling delayed off GCD action for %f", time)
//}
// Used when using APLActionCastSpell as a nested action (e.g. within a sequence)
action.offGCD = true
action.offGCDTime = time
action.Execute(sim) // Default to Execute unless impletented for this APL Action
}

func (action *APLActionCastSpell) String() string {
return fmt.Sprintf("Cast Spell(%s)", action.spell.ActionID)
}
Expand Down Expand Up @@ -82,6 +128,9 @@ func (action *APLActionChannelSpell) GetAPLValues() []APLValue {
func (action *APLActionChannelSpell) IsReady(sim *Simulation) bool {
return action.spell.CanCast(sim, action.target.Get())
}
func (action *APLActionChannelSpell) IsOffGCDAction() bool {
return false
}
func (action *APLActionChannelSpell) Execute(sim *Simulation) {
action.spell.Cast(sim, action.target.Get())

Expand All @@ -95,6 +144,9 @@ func (action *APLActionChannelSpell) Execute(sim *Simulation) {
action.spell.Unit.Rotation.allowChannelRecastOnInterrupt = action.allowRecast
}
}
func (action *APLActionChannelSpell) ExecuteOffGCD(sim *Simulation, time time.Duration) {
action.Execute(sim) // Default to Execute unless impletented for this APL Action
}
func (action *APLActionChannelSpell) String() string {
return fmt.Sprintf("Channel Spell(%s, interruptIf=%s)", action.spell.ActionID, action.interruptIf)
}
Expand Down Expand Up @@ -167,9 +219,15 @@ func (action *APLActionMultidot) IsReady(sim *Simulation) bool {
}
return false
}
func (action *APLActionMultidot) IsOffGCDAction() bool {
return false
}
func (action *APLActionMultidot) Execute(sim *Simulation) {
action.spell.Cast(sim, action.nextTarget)
}
func (action *APLActionMultidot) ExecuteOffGCD(sim *Simulation, time time.Duration) {
action.Execute(sim) // Default to Execute unless impletented for this APL Action
}
func (action *APLActionMultidot) String() string {
return fmt.Sprintf("Multidot(%s)", action.spell.ActionID)
}
Expand Down Expand Up @@ -228,9 +286,15 @@ func (action *APLActionMultishield) IsReady(sim *Simulation) bool {
}
return false
}
func (action *APLActionMultishield) IsOffGCDAction() bool {
return false
}
func (action *APLActionMultishield) Execute(sim *Simulation) {
action.spell.Cast(sim, action.nextTarget)
}
func (action *APLActionMultishield) ExecuteOffGCD(sim *Simulation, time time.Duration) {
action.Execute(sim) // Default to Execute unless impletented for this APL Action
}
func (action *APLActionMultishield) String() string {
return fmt.Sprintf("Multishield(%s)", action.spell.ActionID)
}
Expand Down Expand Up @@ -259,10 +323,16 @@ func (action *APLActionAutocastOtherCooldowns) IsReady(sim *Simulation) bool {
// true even for MCDs which do not require the GCD.
return action.nextReadyMCD != nil && action.character.GCD.IsReady(sim)
}
func (action *APLActionAutocastOtherCooldowns) IsOffGCDAction() bool {
return false
}
func (action *APLActionAutocastOtherCooldowns) Execute(sim *Simulation) {
action.nextReadyMCD.tryActivateHelper(sim, action.character)
action.character.UpdateMajorCooldowns()
}
func (action *APLActionAutocastOtherCooldowns) ExecuteOffGCD(sim *Simulation, time time.Duration) {
action.Execute(sim) // Default to Execute unless impletented for this APL Action
}
func (action *APLActionAutocastOtherCooldowns) String() string {
return "Autocast Other Cooldowns"
}
Loading

0 comments on commit f2aa238

Please sign in to comment.