Skip to content

Commit

Permalink
Merge pull request #4111 from NerdEgghead/master
Browse files Browse the repository at this point in the history
Implemented APL wrapper for Feral DPS legacy rotation.
  • Loading branch information
NerdEgghead authored Dec 26, 2023
2 parents 95aacde + ff47acd commit da73fd7
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 5 deletions.
10 changes: 8 additions & 2 deletions proto/apl.proto
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ message APLListItem {
APLAction action = 3; // The action to be performed.
}

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

Expand Down Expand Up @@ -74,6 +74,9 @@ message APLAction {
APLActionCancelAura cancel_aura = 10;
APLActionTriggerICD trigger_icd = 11;
APLActionItemSwap item_swap = 17;

// Class or Spec-specific actions
APLActionCatOptimalRotationAction cat_optimal_rotation_action = 18;
}
}

Expand Down Expand Up @@ -261,6 +264,9 @@ message APLActionItemSwap {
SwapSet swap_set = 1;
}

message APLActionCatOptimalRotationAction {
}

///////////////////////////////////////////////////////////////////////////
// VALUES
///////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -510,4 +516,4 @@ message APLValueWarlockShouldRecastDrainSoul {
}
message APLValueWarlockShouldRefreshCorruption {
UnitReference target_unit = 1;
}
}
60 changes: 60 additions & 0 deletions sim/druid/feral/apl_values.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,63 @@ func (value *APLValueCatNewSavageRoarDuration) GetDuration(_ *core.Simulation) t
func (value *APLValueCatNewSavageRoarDuration) String() string {
return "New Savage Roar Duration()"
}

func (cat *FeralDruid) NewAPLAction(rot *core.APLRotation, config *proto.APLAction) core.APLActionImpl {
switch config.Action.(type) {
case *proto.APLAction_CatOptimalRotationAction:
return cat.newActionCatOptimalRotationAction(rot, config.GetCatOptimalRotationAction())
default:
return nil
}
}

type APLActionCatOptimalRotationAction struct {
cat *FeralDruid
lastAction time.Duration
}

func (impl *APLActionCatOptimalRotationAction) GetInnerActions() []*core.APLAction { return nil }
func (impl *APLActionCatOptimalRotationAction) GetAPLValues() []core.APLValue { return nil }
func (impl *APLActionCatOptimalRotationAction) Finalize(*core.APLRotation) {}
func (impl *APLActionCatOptimalRotationAction) GetNextAction(*core.Simulation) *core.APLAction {
return nil
}

func (cat *FeralDruid) newActionCatOptimalRotationAction(_ *core.APLRotation, _ *proto.APLActionCatOptimalRotationAction) core.APLActionImpl {
return &APLActionCatOptimalRotationAction{
cat: cat,
}
}

func (action *APLActionCatOptimalRotationAction) IsReady(sim *core.Simulation) bool {
return sim.CurrentTime > action.lastAction
}

func (action *APLActionCatOptimalRotationAction) Execute(sim *core.Simulation) {
cat := action.cat

// If a melee swing resulted in an Omen proc, then schedule the
// next player decision based on latency.
if cat.Talents.OmenOfClarity && cat.ClearcastingAura.RemainingDuration(sim) == cat.ClearcastingAura.Duration {
// Kick gcd loop, also need to account for any gcd 'left'
// otherwise it breaks gcd logic
kickTime := max(cat.NextGCDAt(), sim.CurrentTime+cat.latency)
cat.NextRotationAction(sim, kickTime)
}

if cat.GCD.IsReady(sim) && (cat.rotationAction == nil || sim.CurrentTime >= cat.rotationAction.NextActionAt) {
cat.OnGCDReady(sim)
}

cat.OnEnergyGain(sim)
action.lastAction = sim.CurrentTime
}

func (action *APLActionCatOptimalRotationAction) Reset(*core.Simulation) {
action.cat.usingHardcodedAPL = true
action.lastAction = core.DurationFromSeconds(-100)
}

func (action *APLActionCatOptimalRotationAction) String() string {
return "Execute Optimal Cat Action()"
}
2 changes: 2 additions & 0 deletions sim/druid/feral/feral.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ type FeralDruid struct {
bleedAura *core.Aura
lastShift time.Duration
ripRefreshPending bool
usingHardcodedAPL bool

rotationAction *core.PendingAction
}
Expand Down Expand Up @@ -120,4 +121,5 @@ func (cat *FeralDruid) Reset(sim *core.Simulation) {
cat.readyToShift = false
cat.waitingForTick = false
cat.berserkUsed = false
cat.rotationAction = nil
}
4 changes: 2 additions & 2 deletions sim/druid/feral/rotation.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

func (cat *FeralDruid) OnEnergyGain(sim *core.Simulation) {
if cat.IsUsingAPL {
if cat.IsUsingAPL && !cat.usingHardcodedAPL {
return
}

Expand All @@ -25,7 +25,7 @@ func (cat *FeralDruid) OnEnergyGain(sim *core.Simulation) {
}

func (cat *FeralDruid) OnGCDReady(sim *core.Simulation) {
if cat.IsUsingAPL {
if cat.IsUsingAPL && !cat.usingHardcodedAPL {
return
}

Expand Down
20 changes: 19 additions & 1 deletion ui/core/components/individual_sim_ui/apl_actions.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import {
Class,
Spec,
} from '../../proto/common.js';

import {
APLAction,

Expand All @@ -22,6 +27,8 @@ import {
APLActionItemSwap,
APLActionItemSwap_SwapSet as ItemSwapSet,

APLActionCatOptimalRotationAction,

APLValue,
} from '../../proto/apl.js';

Expand Down Expand Up @@ -561,4 +568,15 @@ const actionKindFactories: {[f in NonNullable<APLActionKind>]: ActionKindConfig<
itemSwapSetFieldConfig('swapSet'),
],
}),
};

// Class/spec specific actions
['catOptimalRotationAction']: inputBuilder({
label: 'Optimal Rotation Action',
submenu: ['Feral Druid'],
shortDescription: 'Executes optimized Feral DPS rotation using hardcoded legacy algorithm.',
includeIf: (player: Player<any>, isPrepull: boolean) => player.spec == Spec.SpecFeralDruid,
newValue: () => APLActionCatOptimalRotationAction.create(),
fields: [
],
}),
};

0 comments on commit da73fd7

Please sign in to comment.