Skip to content

Commit

Permalink
[core] focus and energy ticks are not using PAs, but an advance()-lik…
Browse files Browse the repository at this point in the history
…e system

[dk] ghouls now use the regular focus bar, and regular spell casting
  • Loading branch information
vigo2 committed Oct 15, 2023
1 parent ac1a9a8 commit 1b8c39d
Show file tree
Hide file tree
Showing 22 changed files with 2,726 additions and 2,785 deletions.
57 changes: 29 additions & 28 deletions sim/core/energy.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ type energyBar struct {
cumulativeEnergyDecisionThresholds []int

onEnergyGain func(*Simulation, bool)
tickAction *PendingAction

nextEnergyTick time.Duration

// Multiplies energy regen from ticks.
EnergyTickMultiplier float64
Expand Down Expand Up @@ -149,7 +150,7 @@ func (eb *energyBar) CurrentEnergy() float64 {
}

func (eb *energyBar) NextEnergyTickAt() time.Duration {
return eb.tickAction.NextActionAt
return eb.nextEnergyTick
}

func (eb *energyBar) addEnergyInternal(sim *Simulation, amount float64, metrics *ResourceMetrics) bool {
Expand Down Expand Up @@ -201,7 +202,8 @@ func (eb *energyBar) ResetEnergyTick(sim *Simulation) {
crossedThreshold := eb.addEnergyInternal(sim, partialTickAmount, eb.regenMetrics)
eb.onEnergyGain(sim, crossedThreshold)

eb.newTickAction(sim, false, sim.CurrentTime)
eb.nextEnergyTick = sim.CurrentTime + EnergyTickDuration
sim.RescheduleTask(eb.nextEnergyTick)
}

func (eb *energyBar) AddComboPoints(sim *Simulation, pointsToAdd int32, metrics *ResourceMetrics) {
Expand All @@ -223,29 +225,16 @@ func (eb *energyBar) SpendComboPoints(sim *Simulation, metrics *ResourceMetrics)
eb.comboPoints = 0
}

func (eb *energyBar) newTickAction(sim *Simulation, randomTickTime bool, startAt time.Duration) {
if eb.tickAction != nil {
eb.tickAction.Cancel(sim)
}

nextTickDuration := EnergyTickDuration
if randomTickTime {
nextTickDuration = time.Duration(sim.RandomFloat("Energy Tick") * float64(EnergyTickDuration))
func (eb *energyBar) RunTask(sim *Simulation) time.Duration {
if sim.CurrentTime < eb.nextEnergyTick {
return eb.nextEnergyTick
}

pa := &PendingAction{
NextActionAt: startAt + nextTickDuration,
Priority: ActionPriorityRegen,
}
pa.OnAction = func(sim *Simulation) {
crossedThreshold := eb.addEnergyInternal(sim, EnergyPerTick*eb.EnergyTickMultiplier, eb.regenMetrics)
eb.onEnergyGain(sim, crossedThreshold)
crossedThreshold := eb.addEnergyInternal(sim, EnergyPerTick*eb.EnergyTickMultiplier, eb.regenMetrics)
eb.onEnergyGain(sim, crossedThreshold)

pa.NextActionAt = sim.CurrentTime + EnergyTickDuration
sim.AddPendingAction(pa)
}
eb.tickAction = pa
sim.AddPendingAction(pa)
eb.nextEnergyTick = sim.CurrentTime + EnergyTickDuration
return eb.nextEnergyTick
}

func (eb *energyBar) reset(sim *Simulation) {
Expand All @@ -255,13 +244,27 @@ func (eb *energyBar) reset(sim *Simulation) {

eb.currentEnergy = eb.maxEnergy
eb.comboPoints = 0
eb.newTickAction(sim, true, sim.Environment.PrepullStartTime())

if eb.unit.Type != PetUnit {
eb.enable(sim, sim.Environment.PrepullStartTime())
}
}

func (eb *energyBar) enable(sim *Simulation, startAt time.Duration) {
sim.AddTask(eb)
eb.nextEnergyTick = startAt + time.Duration(sim.RandomFloat("Energy Tick")*float64(EnergyTickDuration))
sim.RescheduleTask(eb.nextEnergyTick)

if eb.cumulativeEnergyDecisionThresholds != nil && sim.Log != nil {
eb.unit.Log(sim, "[DEBUG] APL Energy decision thresholds: %v", eb.energyDecisionThresholds)
}
}

func (eb *energyBar) disable(sim *Simulation) {
eb.nextEnergyTick = NeverExpires
sim.RemoveTask(eb)
}

type EnergyCostOptions struct {
Cost float64

Expand Down Expand Up @@ -293,13 +296,11 @@ 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) CostFailureReason(sim *Simulation, spell *Spell) string {
func (ec *EnergyCost) CostFailureReason(_ *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 {
spell.Unit.SpendEnergy(sim, spell.CurCast.Cost, ec.ResourceMetrics)
}
spell.Unit.SpendEnergy(sim, spell.CurCast.Cost, ec.ResourceMetrics)
}
func (ec *EnergyCost) IssueRefund(sim *Simulation, spell *Spell) {
if ec.Refund > 0 {
Expand Down
62 changes: 33 additions & 29 deletions sim/core/focus.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ type focusBar struct {
currentFocus float64

onFocusGain OnFocusGain
tickAction *PendingAction

nextFocusTick time.Duration
}

func (unit *Unit) EnableFocusBar(regenMultiplier float64, onFocusGain OnFocusGain) {
Expand Down Expand Up @@ -60,16 +61,15 @@ func (fb *focusBar) AddFocus(sim *Simulation, amount float64, actionID ActionID)
}
}

func (fb *focusBar) SpendFocus(sim *Simulation, amount float64, metrics *ResourceMetrics) {
func (fb *focusBar) SpendFocus(sim *Simulation, amount float64, actionID ActionID) {
if amount < 0 {
panic("Trying to spend negative focus!")
}

newFocus := fb.currentFocus - amount
metrics.AddEvent(-amount, -amount)

if sim.Log != nil {
fb.unit.Log(sim, "Spent %0.3f focus from %s (%0.3f --> %0.3f).", amount, metrics.ActionID, fb.currentFocus, newFocus)
fb.unit.Log(sim, "Spent %0.3f focus from %s (%0.3f --> %0.3f).", amount, actionID, fb.currentFocus, newFocus)
}

fb.currentFocus = newFocus
Expand All @@ -82,56 +82,60 @@ func (fb *focusBar) reset(sim *Simulation) {

fb.currentFocus = MaxFocus

pa := &PendingAction{
Priority: ActionPriorityRegen,
NextActionAt: tickDuration,
if fb.unit.Type != PetUnit {
fb.enable(sim)
}
pa.OnAction = func(sim *Simulation) {
fb.AddFocus(sim, fb.focusPerTick, ActionID{OtherID: proto.OtherAction_OtherActionFocusRegen})
}

pa.NextActionAt = sim.CurrentTime + tickDuration
sim.AddPendingAction(pa)
}
fb.tickAction = pa
sim.AddPendingAction(pa)
func (fb *focusBar) enable(sim *Simulation) {
sim.AddTask(fb)
fb.nextFocusTick = sim.CurrentTime + tickDuration
sim.RescheduleTask(fb.nextFocusTick)
}

func (fb *focusBar) Cancel(sim *Simulation) {
if fb.tickAction != nil {
fb.tickAction.Cancel(sim)
fb.tickAction = nil
func (fb *focusBar) disable(sim *Simulation) {
fb.nextFocusTick = NeverExpires
sim.RemoveTask(fb)
}

func (fb *focusBar) RunTask(sim *Simulation) time.Duration {
if sim.CurrentTime < fb.nextFocusTick {
return fb.nextFocusTick
}

fb.AddFocus(sim, fb.focusPerTick, ActionID{OtherID: proto.OtherAction_OtherActionFocusRegen})

fb.nextFocusTick = sim.CurrentTime + tickDuration
return fb.nextFocusTick
}

type FocusCostOptions struct {
Cost float64
Cost float64
Refund float64
}
type FocusCost struct {
Refund float64
ResourceMetrics *ResourceMetrics
Refund float64
}

func newFocusCost(spell *Spell, options FocusCostOptions) *FocusCost {
spell.DefaultCast.Cost = options.Cost

return &FocusCost{
ResourceMetrics: spell.Unit.NewFocusMetrics(spell.ActionID),
Refund: options.Refund,
}
}

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) CostFailureReason(sim *Simulation, spell *Spell) string {
func (fc *FocusCost) CostFailureReason(_ *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)
spell.Unit.SpendFocus(sim, spell.CurCast.Cost, spell.ActionID)
}
func (fc *FocusCost) IssueRefund(sim *Simulation, spell *Spell) {
}

func (spell *Spell) FocusMetrics() *ResourceMetrics {
return spell.Cost.(*FocusCost).ResourceMetrics
if fc.Refund > 0 {
spell.Unit.AddFocus(sim, fc.Refund*spell.CurCast.Cost, spell.ActionID)
}
}
7 changes: 6 additions & 1 deletion sim/core/pet.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ func (pet *Pet) Enable(sim *Simulation, petAgent PetAgent) {
}

sim.addTracker(&pet.auraTracker)

if pet.HasFocusBar() {
pet.focusBar.enable(sim)
}
}

// Helper for enabling a pet that will expire after a certain duration.
Expand Down Expand Up @@ -230,7 +234,7 @@ func (pet *Pet) Disable(sim *Simulation) {
}

pet.CancelGCDTimer(sim)
pet.focusBar.Cancel(sim)
pet.focusBar.disable(sim)
pet.AutoAttacks.CancelAutoSwing(sim)
pet.enabled = false
pet.DoNothing() // mark it is as doing nothing now.
Expand All @@ -247,6 +251,7 @@ func (pet *Pet) Disable(sim *Simulation) {
pet.OnPetDisable(sim)
}

pet.auraTracker.minExpires = NeverExpires
sim.removeTracker(&pet.auraTracker)

if sim.Log != nil {
Expand Down
Loading

0 comments on commit 1b8c39d

Please sign in to comment.