Skip to content

Commit

Permalink
Merge pull request #3844 from wowsims/apl
Browse files Browse the repository at this point in the history
Handle a few more cases of spells failing during prepull
  • Loading branch information
jimmyt857 authored Oct 8, 2023
2 parents 5916a25 + c2fc0c0 commit 21ef4cf
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 40 deletions.
37 changes: 17 additions & 20 deletions sim/core/cast.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,19 @@ func (cast *Cast) EffectiveTime() time.Duration {
type CastFunc func(*Simulation, *Unit)
type CastSuccessFunc func(*Simulation, *Unit) bool

func (spell *Spell) castFailureHelper(sim *Simulation, message string, vals ...interface{}) bool {
func (spell *Spell) castFailureHelper(sim *Simulation, gracefulFailure bool, message string, vals ...interface{}) bool {
reason := fmt.Sprintf(spell.ActionID.String()+" failed to cast: "+message, vals...)
if sim.CurrentTime < 0 && spell.Unit.IsUsingAPL {
spell.Unit.Rotation.ValidationWarning(reason)
return false
} else if gracefulFailure {
if sim.Log != nil && !spell.Flags.Matches(SpellFlagNoLogs) {
spell.Unit.Log(sim, reason)
}
return false
} else {
panic(reason)
}
panic(reason)
}

func (spell *Spell) makeCastFunc(config CastConfig) CastSuccessFunc {
Expand All @@ -90,19 +96,13 @@ func (spell *Spell) makeCastFunc(config CastConfig) CastSuccessFunc {

if spell.ExtraCastCondition != nil {
if !spell.ExtraCastCondition(sim, target) {
if sim.Log != nil {
sim.Log("Failed cast because of extra condition")
}
return false
return spell.castFailureHelper(sim, true, "extra spell condition")
}
}

if spell.Cost != nil {
if !spell.Cost.MeetsRequirement(spell) {
if sim.Log != nil && !spell.Flags.Matches(SpellFlagNoLogs) {
spell.Cost.LogCostFailure(sim, spell)
}
return false
return spell.castFailureHelper(sim, true, spell.Cost.CostFailureReason(sim, spell))
}
}

Expand All @@ -119,26 +119,26 @@ func (spell *Spell) makeCastFunc(config CastConfig) CastSuccessFunc {
if config.CD.Timer != nil {
// By panicking if spell is on CD, we force each sim to properly check for their own CDs.
if !spell.CD.IsReady(sim) {
return spell.castFailureHelper(sim, "still on cooldown for %s, curTime = %s", spell.CD.TimeToReady(sim), sim.CurrentTime)
return spell.castFailureHelper(sim, false, "still on cooldown for %s, curTime = %s", spell.CD.TimeToReady(sim), sim.CurrentTime)
}
spell.CD.Set(sim.CurrentTime + spell.CurCast.CastTime + spell.CD.Duration)
}

if config.SharedCD.Timer != nil {
// By panicking if spell is on CD, we force each sim to properly check for their own CDs.
if !spell.SharedCD.IsReady(sim) {
return spell.castFailureHelper(sim, "still on shared cooldown for %s, curTime = %s", spell.SharedCD.TimeToReady(sim), sim.CurrentTime)
return spell.castFailureHelper(sim, false, "still on shared cooldown for %s, curTime = %s", spell.SharedCD.TimeToReady(sim), sim.CurrentTime)
}
spell.SharedCD.Set(sim.CurrentTime + spell.CurCast.CastTime + spell.SharedCD.Duration)
}

// By panicking if spell is on CD, we force each sim to properly check for their own CDs.
if spell.CurCast.GCD != 0 && !spell.Unit.GCD.IsReady(sim) {
return spell.castFailureHelper(sim, "GCD on cooldown for %s, curTime = %s", spell.Unit.GCD.TimeToReady(sim), sim.CurrentTime)
return spell.castFailureHelper(sim, false, "GCD on cooldown for %s, curTime = %s", spell.Unit.GCD.TimeToReady(sim), sim.CurrentTime)
}

if hc := spell.Unit.Hardcast; hc.Expires > sim.CurrentTime {
return spell.castFailureHelper(sim, "casting/channeling %v for %s, curTime = %s", hc.ActionID, hc.Expires-sim.CurrentTime, sim.CurrentTime)
return spell.castFailureHelper(sim, false, "casting/channeling %v for %s, curTime = %s", hc.ActionID, hc.Expires-sim.CurrentTime, sim.CurrentTime)
}

if effectiveTime := spell.CurCast.EffectiveTime(); effectiveTime != 0 {
Expand Down Expand Up @@ -210,17 +210,14 @@ func (spell *Spell) makeCastFuncSimple() CastSuccessFunc {
return func(sim *Simulation, target *Unit) bool {
if spell.ExtraCastCondition != nil {
if !spell.ExtraCastCondition(sim, target) {
if sim.Log != nil {
sim.Log("Failed cast because of extra condition")
}
return false
return spell.castFailureHelper(sim, true, "extra spell condition")
}
}

if spell.CD.Timer != nil {
// By panicking if spell is on CD, we force each sim to properly check for their own CDs.
if !spell.CD.IsReady(sim) {
return spell.castFailureHelper(sim, "still on cooldown for %s, curTime = %s", spell.CD.TimeToReady(sim), sim.CurrentTime)
return spell.castFailureHelper(sim, false, "still on cooldown for %s, curTime = %s", spell.CD.TimeToReady(sim), sim.CurrentTime)
}

spell.CD.Set(sim.CurrentTime + spell.CD.Duration)
Expand All @@ -229,7 +226,7 @@ func (spell *Spell) makeCastFuncSimple() CastSuccessFunc {
if spell.SharedCD.Timer != nil {
// By panicking if spell is on CD, we force each sim to properly check for their own CDs.
if !spell.SharedCD.IsReady(sim) {
return spell.castFailureHelper(sim, "still on shared cooldown for %s, curTime = %s", spell.SharedCD.TimeToReady(sim), sim.CurrentTime)
return spell.castFailureHelper(sim, false, "still on shared cooldown for %s, curTime = %s", spell.SharedCD.TimeToReady(sim), sim.CurrentTime)
}

spell.SharedCD.Set(sim.CurrentTime + spell.SharedCD.Duration)
Expand Down
7 changes: 3 additions & 4 deletions sim/core/energy.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package core

import (
"fmt"
"time"

"github.com/wowsims/wotlk/sim/core/proto"
Expand Down Expand Up @@ -202,10 +203,8 @@ func (ec *EnergyCost) MeetsRequirement(spell *Spell) bool {
spell.CurCast.Cost = spell.ApplyCostModifiers(spell.CurCast.Cost)
return spell.Unit.CurrentEnergy() >= spell.CurCast.Cost
}
func (ec *EnergyCost) LogCostFailure(sim *Simulation, spell *Spell) {
spell.Unit.Log(sim,
"Failed casting %s, not enough energy. (Current Energy = %0.03f, Energy Cost = %0.03f)",
spell.ActionID, spell.Unit.CurrentEnergy(), spell.CurCast.Cost)
func (ec *EnergyCost) CostFailureReason(sim *Simulation, spell *Spell) string {
return fmt.Sprintf("not enough energy (Current Energy = %0.03f, Energy Cost = %0.03f)", spell.Unit.CurrentEnergy(), spell.CurCast.Cost)
}
func (ec *EnergyCost) SpendCost(sim *Simulation, spell *Spell) {
if spell.CurCast.Cost > 0 {
Expand Down
7 changes: 3 additions & 4 deletions sim/core/focus.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package core

import (
"fmt"
"time"

"github.com/wowsims/wotlk/sim/core/proto"
Expand Down Expand Up @@ -122,10 +123,8 @@ func (fc *FocusCost) MeetsRequirement(spell *Spell) bool {
spell.CurCast.Cost = max(0, spell.CurCast.Cost*spell.Unit.PseudoStats.CostMultiplier)
return spell.Unit.CurrentFocus() >= spell.CurCast.Cost
}
func (fc *FocusCost) LogCostFailure(sim *Simulation, spell *Spell) {
spell.Unit.Log(sim,
"Failed casting %s, not enough focus. (Current Focus = %0.03f, Focus Cost = %0.03f)",
spell.ActionID, spell.Unit.CurrentFocus(), spell.CurCast.Cost)
func (fc *FocusCost) CostFailureReason(sim *Simulation, spell *Spell) string {
return fmt.Sprintf("not enough focus (Current Focus = %0.03f, Focus Cost = %0.03f)", spell.Unit.CurrentFocus(), spell.CurCast.Cost)
}
func (fc *FocusCost) SpendCost(sim *Simulation, spell *Spell) {
spell.Unit.SpendFocus(sim, spell.CurCast.Cost, fc.ResourceMetrics)
Expand Down
7 changes: 3 additions & 4 deletions sim/core/mana.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package core

import (
"fmt"
"math"
"time"

Expand Down Expand Up @@ -322,10 +323,8 @@ func (mc *ManaCost) MeetsRequirement(spell *Spell) bool {
spell.CurCast.Cost = spell.ApplyCostModifiers(spell.CurCast.Cost)
return spell.Unit.CurrentMana() >= spell.CurCast.Cost
}
func (mc *ManaCost) LogCostFailure(sim *Simulation, spell *Spell) {
spell.Unit.Log(sim,
"Failed casting %s, not enough mana. (Current Mana = %0.03f, Mana Cost = %0.03f)",
spell.ActionID, spell.Unit.CurrentMana(), spell.CurCast.Cost)
func (mc *ManaCost) CostFailureReason(sim *Simulation, spell *Spell) string {
return fmt.Sprintf("not enough mana (Current Mana = %0.03f, Mana Cost = %0.03f)", spell.Unit.CurrentMana(), spell.CurCast.Cost)
}
func (mc *ManaCost) SpendCost(sim *Simulation, spell *Spell) {
if spell.CurCast.Cost > 0 {
Expand Down
8 changes: 4 additions & 4 deletions sim/core/rage.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package core

import (
"fmt"

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

Expand Down Expand Up @@ -223,10 +225,8 @@ func (rc *RageCost) MeetsRequirement(spell *Spell) bool {
spell.CurCast.Cost = spell.ApplyCostModifiers(spell.CurCast.Cost)
return spell.Unit.CurrentRage() >= spell.CurCast.Cost
}
func (rc *RageCost) LogCostFailure(sim *Simulation, spell *Spell) {
spell.Unit.Log(sim,
"Failed casting %s, not enough rage. (Current Rage = %0.03f, Rage Cost = %0.03f)",
spell.ActionID, spell.Unit.CurrentRage(), spell.CurCast.Cost)
func (rc *RageCost) CostFailureReason(sim *Simulation, spell *Spell) string {
return fmt.Sprintf("not enough rage (Current Rage = %0.03f, Rage Cost = %0.03f)", spell.Unit.CurrentRage(), spell.CurCast.Cost)
}
func (rc *RageCost) SpendCost(sim *Simulation, spell *Spell) {
if spell.CurCast.Cost > 0 {
Expand Down
4 changes: 2 additions & 2 deletions sim/core/runic_power.go
Original file line number Diff line number Diff line change
Expand Up @@ -844,8 +844,8 @@ func (rc *RuneCostImpl) MeetsRequirement(spell *Spell) bool {
return true
}

func (rc *RuneCostImpl) LogCostFailure(sim *Simulation, spell *Spell) {
spell.Unit.Log(sim, "Failed casting %s, not enough RP or runes.", spell.ActionID)
func (rc *RuneCostImpl) CostFailureReason(sim *Simulation, spell *Spell) string {
return "not enough RP or runes"
}

func (rc *RuneCostImpl) SpendCost(sim *Simulation, spell *Spell) {
Expand Down
4 changes: 2 additions & 2 deletions sim/core/spell.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,8 +591,8 @@ type SpellCost interface {
// requirements to cast the spell.
MeetsRequirement(*Spell) bool

// Logs a message for when the cast fails due to lack of resources.
LogCostFailure(*Simulation, *Spell)
// Returns a message for when the cast fails due to lack of resources.
CostFailureReason(*Simulation, *Spell) string

// Subtracts the resources used from a cast from the Unit.
SpendCost(*Simulation, *Spell)
Expand Down

0 comments on commit 21ef4cf

Please sign in to comment.