Skip to content

Commit

Permalink
Merge pull request #291 from InDebt/movement
Browse files Browse the repository at this point in the history
Port and extend movement APL from SoD
  • Loading branch information
InDebt authored May 3, 2024
2 parents 6ff6b10 + 63dc968 commit 4ba9cc4
Show file tree
Hide file tree
Showing 40 changed files with 4,476 additions and 4,006 deletions.
21 changes: 18 additions & 3 deletions 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: 21
// NextIndex: 23
message APLAction {
APLValue condition = 1; // If set, action will only execute if value is true or != 0.

Expand Down Expand Up @@ -70,6 +70,8 @@ message APLAction {
APLActionCancelAura cancel_aura = 10;
APLActionTriggerICD trigger_icd = 11;
APLActionItemSwap item_swap = 17;
APLActionMove move = 21;
APLActionMoveDuration move_duration = 22;

// Class or Spec-specific actions
APLActionCatOptimalRotationAction cat_optimal_rotation_action = 18;
Expand All @@ -79,7 +81,7 @@ message APLAction {
}
}

// NextIndex: 72
// NextIndex: 73
message APLValue {
oneof value {
// Operators
Expand Down Expand Up @@ -117,6 +119,9 @@ message APLValue {
APLValueCurrentSolarEnergy current_solar_energy = 68;
APLValueCurrentLunarEnergy current_lunar_energy = 69;

// Unit values
APLValueUnitIsMoving unit_is_moving = 72;

// Rune Resource values
APLValueCurrentRuneCount current_rune_count = 29;
APLValueCurrentNonDeathRuneCount current_non_death_rune_count = 34;
Expand Down Expand Up @@ -284,6 +289,14 @@ message APLActionCatOptimalRotationAction {
bool allow_aoe_berserk = 10;
}

message APLActionMove {
APLValue range_from_target = 1;
}

message APLActionMoveDuration {
APLValue duration = 1;
}

message APLActionCustomRotation {
}

Expand Down Expand Up @@ -373,7 +386,9 @@ message APLValueBossSpellIsCasting {
UnitReference target_unit = 1;
ActionID spell_id = 2;
}

message APLValueUnitIsMoving {
UnitReference source_unit = 1;
}
message APLValueCurrentHealth {
UnitReference source_unit = 1;
}
Expand Down
1 change: 1 addition & 0 deletions proto/common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,7 @@ enum OtherAction {
OtherActionPotion = 17; // Used by APL to generically refer to either the prepull or combat potion.
OtherActionSolarEnergyGain = 18; // For balance druid solar energy
OtherActionLunarEnergyGain = 19; // For balance druid lunar energy
OtherActionMove = 20; // Used by movement to be able to show it in timeline
}

message ActionID {
Expand Down
3 changes: 2 additions & 1 deletion sim/core/apl.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ func (apl *APLRotation) DoNextAction(sim *Simulation) {
i := 0
apl.inLoop = true

apl.unit.UpdatePosition(sim)
for nextAction := apl.getNextAction(sim); nextAction != nil; i, nextAction = i+1, apl.getNextAction(sim) {
if i > 1000 {
panic(fmt.Sprintf("[USER_ERROR] Infinite loop detected, current action:\n%s", nextAction))
Expand All @@ -244,7 +245,7 @@ func (apl *APLRotation) DoNextAction(sim *Simulation) {

// Schedule the next rotation evaluation based on either the GCD or reaction time
if apl.unit.RotationTimer.IsReady(sim) {
nextEvaluation := max(apl.unit.NextGCDAt(), sim.CurrentTime + apl.unit.ReactionTime)
nextEvaluation := max(apl.unit.NextGCDAt(), sim.CurrentTime+apl.unit.ReactionTime)
apl.unit.WaitUntil(sim, nextEvaluation)
}
}
Expand Down
5 changes: 4 additions & 1 deletion sim/core/apl_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,10 @@ func (rot *APLRotation) newAPLActionImpl(config *proto.APLAction) APLActionImpl
return rot.newActionTriggerICD(config.GetTriggerIcd())
case *proto.APLAction_ItemSwap:
return rot.newActionItemSwap(config.GetItemSwap())

case *proto.APLAction_Move:
return rot.newActionMove(config.GetMove())
case *proto.APLAction_MoveDuration:
return rot.newActionMoveDuration(config.GetMoveDuration())
case *proto.APLAction_CustomRotation:
return rot.newActionCustomRotation(config.GetCustomRotation())

Expand Down
64 changes: 64 additions & 0 deletions sim/core/apl_actions_misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,34 @@ func (action *APLActionItemSwap) String() string {
return fmt.Sprintf("Item Swap(%s)", action.swapSet)
}

type APLActionMove struct {
defaultAPLActionImpl
unit *Unit
moveRange APLValue
}

func (rot *APLRotation) newActionMove(config *proto.APLActionMove) APLActionImpl {
return &APLActionMove{
unit: rot.unit,
moveRange: rot.newAPLValue(config.RangeFromTarget),
}
}
func (action *APLActionMove) IsReady(sim *Simulation) bool {
isPrepull := sim.CurrentTime < 0
return !action.unit.Moving && (action.moveRange.GetFloat(sim) != action.unit.DistanceFromTarget || isPrepull) && action.unit.Hardcast.Expires < sim.CurrentTime
}
func (action *APLActionMove) Execute(sim *Simulation) {
moveRange := action.moveRange.GetFloat(sim)
if sim.Log != nil {
action.unit.Log(sim, "Moving to %s", moveRange)
}

action.unit.MoveTo(moveRange, sim)
}
func (action *APLActionMove) String() string {
return fmt.Sprintf("Move(%s)", action.moveRange)
}

type APLActionCustomRotation struct {
defaultAPLActionImpl
unit *Unit
Expand Down Expand Up @@ -192,3 +220,39 @@ func (action *APLActionCustomRotation) Execute(sim *Simulation) {
func (action *APLActionCustomRotation) String() string {
return "Custom Rotation()"
}

type APLActionMoveDuration struct {
defaultAPLActionImpl
unit *Unit
moveDuration APLValue
}

func (rot *APLRotation) newActionMoveDuration(config *proto.APLActionMoveDuration) APLActionImpl {
return &APLActionMoveDuration{
unit: rot.unit,
moveDuration: rot.newAPLValue(config.Duration),
}
}

func (action *APLActionMoveDuration) Execute(sim *Simulation) {
action.unit.MoveDuration(action.moveDuration.GetDuration(sim), sim)
}

func (action *APLActionMoveDuration) IsReady(sim *Simulation) bool {

// only alow us to move if we're not already moving or movement action is running out this step
if action.unit.Moving && action.unit.movementAction.NextActionAt != sim.CurrentTime {
return false
}

if action.moveDuration.GetDuration(sim) == time.Duration(0) {
return false
}

// check current casting state
return (action.unit.Hardcast.Expires < sim.CurrentTime || action.unit.Hardcast.CanMove) && action.unit.ChanneledDot == nil
}

func (action *APLActionMoveDuration) String() string {
return "MoveDuration()"
}
4 changes: 2 additions & 2 deletions sim/core/apl_actions_sequences.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (action *APLActionSequence) Execute(sim *Simulation) {
action.curIdx++
queueAction.OnAction = oldFunc
}
action.unit.SetRotationTimer(sim, queueAction.NextActionAt + time.Duration(1))
action.unit.SetRotationTimer(sim, queueAction.NextActionAt+time.Duration(1))
}

action.unit.Rotation.inSequence = false
Expand Down Expand Up @@ -195,7 +195,7 @@ func (action *APLActionStrictSequence) GetNextAction(sim *Simulation) *APLAction
},
}
sim.AddPendingAction(pa)
action.unit.SetRotationTimer(sim, pa.NextActionAt + time.Duration(1))
action.unit.SetRotationTimer(sim, pa.NextActionAt+time.Duration(1))
}

return nextAction
Expand Down
4 changes: 4 additions & 0 deletions sim/core/apl_value.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ func (rot *APLRotation) newAPLValue(config *proto.APLValue) APLValue {
case *proto.APLValue_RuneSlotCooldown:
return rot.newValueRuneSlotCooldown(config.GetRuneSlotCooldown())

//Unit
case *proto.APLValue_UnitIsMoving:
return rot.newValueCharacterIsMoving(config.GetUnitIsMoving())

// GCD
case *proto.APLValue_GcdIsReady:
return rot.newValueGCDIsReady(config.GetGcdIsReady())
Expand Down
29 changes: 29 additions & 0 deletions sim/core/apl_values_unit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package core

import (
"github.com/wowsims/cata/sim/core/proto"
)

type APLValueUnitIsMoving struct {
DefaultAPLValueImpl
unit UnitReference
}

func (rot *APLRotation) newValueCharacterIsMoving(config *proto.APLValueUnitIsMoving) APLValue {
unit := rot.GetSourceUnit(config.SourceUnit)
if unit.Get() == nil {
return nil
}
return &APLValueUnitIsMoving{
unit: unit,
}
}
func (value *APLValueUnitIsMoving) Type() proto.APLValueType {
return proto.APLValueType_ValueTypeBool
}
func (value *APLValueUnitIsMoving) GetBool(sim *Simulation) bool {
return value.unit.Get().Moving
}
func (value *APLValueUnitIsMoving) String() string {
return "Is Moving"
}
Loading

0 comments on commit 4ba9cc4

Please sign in to comment.