Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle a few more cases of spells failing during prepull #3844

Merged
merged 1 commit into from
Oct 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading