From e9e2205cbc240f6a094f2f69c6d96a01297889e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Hillerstr=C3=B6m?= Date: Wed, 25 Dec 2024 16:05:27 +0100 Subject: [PATCH] Add APL values for max hp, max mana and current AP --- package.json | 6 +++ proto/apl.proto | 11 +++- sim/core/apl_value.go | 8 +++ sim/core/apl_values_resources.go | 50 +++++++++++++++++++ sim/core/apl_values_stats.go | 26 ++++++++++ .../individual_sim_ui/apl_values.ts | 27 ++++++++++ 6 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 sim/core/apl_values_stats.go diff --git a/package.json b/package.json index daa78f26c..d751a9b5d 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,12 @@ "name": "classic", "version": "0.1.0", "private": true, + "engines": { + "node": ">=20" + }, + "volta": { + "node": "20.13.1" + }, "scripts": { "build": "bazel build //...", "test": "bazel test //...", diff --git a/proto/apl.proto b/proto/apl.proto index e26d3f1fa..f9968cf39 100644 --- a/proto/apl.proto +++ b/proto/apl.proto @@ -82,7 +82,7 @@ message APLAction { } } -// NextIndex: 74 +// NextIndex: 78 message APLValue { oneof value { // Operators @@ -106,13 +106,18 @@ message APLValue { // Resource values APLValueCurrentHealth current_health = 26; APLValueCurrentHealthPercent current_health_percent = 27; + APLValueMaxHealth max_health = 76; APLValueCurrentMana current_mana = 11; APLValueCurrentManaPercent current_mana_percent = 12; + APLValueMaxMana max_mana = 75; APLValueCurrentRage current_rage = 14; APLValueCurrentEnergy current_energy = 15; APLValueCurrentComboPoints current_combo_points = 16; APLValueTimeToEnergyTick time_to_energy_tick = 66; APLValueEnergyThreshold energy_threshold = 72; + + // Stats + APLValueCurrentAttackPower current_attack_power = 77; // GCD values APLValueGCDIsReady gcd_is_ready = 17; @@ -374,12 +379,14 @@ message APLValueCurrentHealth { message APLValueCurrentHealthPercent { UnitReference source_unit = 1; } +message APLValueMaxHealth {} message APLValueCurrentMana { UnitReference source_unit = 1; } message APLValueCurrentManaPercent { UnitReference source_unit = 1; } +message APLValueMaxMana {} message APLValueCurrentRage {} message APLValueCurrentEnergy {} message APLValueCurrentComboPoints {} @@ -388,6 +395,8 @@ message APLValueEnergyThreshold { int32 threshold = 1; } +message APLValueCurrentAttackPower {} + message APLValueGCDIsReady {} message APLValueGCDTimeToReady {} diff --git a/sim/core/apl_value.go b/sim/core/apl_value.go index 3c75cf6e0..860d7336d 100644 --- a/sim/core/apl_value.go +++ b/sim/core/apl_value.go @@ -99,10 +99,14 @@ func (rot *APLRotation) newAPLValue(config *proto.APLValue) APLValue { return rot.newValueCurrentHealth(config.GetCurrentHealth()) case *proto.APLValue_CurrentHealthPercent: return rot.newValueCurrentHealthPercent(config.GetCurrentHealthPercent()) + case *proto.APLValue_MaxHealth: + return rot.newValueMaxHealth(config.GetMaxHealth()) case *proto.APLValue_CurrentMana: return rot.newValueCurrentMana(config.GetCurrentMana()) case *proto.APLValue_CurrentManaPercent: return rot.newValueCurrentManaPercent(config.GetCurrentManaPercent()) + case *proto.APLValue_MaxMana: + return rot.newValueMaxMana(config.GetMaxMana()) case *proto.APLValue_CurrentRage: return rot.newValueCurrentRage(config.GetCurrentRage()) case *proto.APLValue_CurrentEnergy: @@ -114,6 +118,10 @@ func (rot *APLRotation) newAPLValue(config *proto.APLValue) APLValue { case *proto.APLValue_EnergyThreshold: return rot.newValueEnergyThreshold(config.GetEnergyThreshold()) + // Stats + case *proto.APLValue_CurrentAttackPower: + return rot.newValueCurrentAttackPower(config.GetCurrentAttackPower()) + // GCD case *proto.APLValue_GcdIsReady: return rot.newValueGCDIsReady(config.GetGcdIsReady()) diff --git a/sim/core/apl_values_resources.go b/sim/core/apl_values_resources.go index 4588c4cc7..a2c21fb02 100644 --- a/sim/core/apl_values_resources.go +++ b/sim/core/apl_values_resources.go @@ -63,6 +63,31 @@ func (value *APLValueCurrentHealthPercent) String() string { return fmt.Sprintf("Current Health %%") } +type APLValueMaxHealth struct { + DefaultAPLValueImpl + unit *Unit +} + +func (rot *APLRotation) newValueMaxHealth(_ *proto.APLValueMaxHealth) APLValue { + unit := rot.unit + if !unit.HasHealthBar() { + rot.ValidationWarning("%s does not use Health", unit.Label) + return nil + } + return &APLValueMaxHealth{ + unit: unit, + } +} +func (value *APLValueMaxHealth) Type() proto.APLValueType { + return proto.APLValueType_ValueTypeFloat +} +func (value *APLValueMaxHealth) GetFloat(_ *Simulation) float64 { + return value.unit.MaxHealth() +} +func (value *APLValueMaxHealth) String() string { + return "Max Health" +} + type APLValueCurrentMana struct { DefaultAPLValueImpl unit UnitReference @@ -119,6 +144,31 @@ func (value *APLValueCurrentManaPercent) String() string { return fmt.Sprintf("Current Mana %%") } +type APLValueMaxMana struct { + DefaultAPLValueImpl + unit *Unit +} + +func (rot *APLRotation) newValueMaxMana(_ *proto.APLValueMaxMana) APLValue { + unit := rot.unit + if !unit.HasManaBar() { + rot.ValidationWarning("%s does not use Mana", unit.Label) + return nil + } + return &APLValueMaxMana{ + unit: unit, + } +} +func (value *APLValueMaxMana) Type() proto.APLValueType { + return proto.APLValueType_ValueTypeFloat +} +func (value *APLValueMaxMana) GetFloat(_ *Simulation) float64 { + return value.unit.MaxMana() +} +func (value *APLValueMaxMana) String() string { + return "Max Mana" +} + type APLValueCurrentRage struct { DefaultAPLValueImpl unit *Unit diff --git a/sim/core/apl_values_stats.go b/sim/core/apl_values_stats.go new file mode 100644 index 000000000..a90df48ba --- /dev/null +++ b/sim/core/apl_values_stats.go @@ -0,0 +1,26 @@ +package core + +import ( + "github.com/wowsims/classic/sim/core/proto" + "github.com/wowsims/classic/sim/core/stats" +) + +type APLValueCurrentAttackPower struct { + DefaultAPLValueImpl + unit *Unit +} + +func (rot *APLRotation) newValueCurrentAttackPower(_ *proto.APLValueCurrentAttackPower) APLValue { + return &APLValueCurrentAttackPower{ + unit: rot.unit, + } +} +func (value *APLValueCurrentAttackPower) Type() proto.APLValueType { + return proto.APLValueType_ValueTypeFloat +} +func (value *APLValueCurrentAttackPower) GetFloat(_ *Simulation) float64 { + return value.unit.GetStat(stats.AttackPower) +} +func (value *APLValueCurrentAttackPower) String() string { + return "Current Attack Power" +} diff --git a/ui/core/components/individual_sim_ui/apl_values.ts b/ui/core/components/individual_sim_ui/apl_values.ts index 6b933fb64..e1333aa65 100644 --- a/ui/core/components/individual_sim_ui/apl_values.ts +++ b/ui/core/components/individual_sim_ui/apl_values.ts @@ -19,6 +19,7 @@ import { APLValueCompare, APLValueCompare_ComparisonOperator as ComparisonOperator, APLValueConst, + APLValueCurrentAttackPower, APLValueCurrentComboPoints, APLValueCurrentEnergy, APLValueCurrentHealth, @@ -40,6 +41,8 @@ import { APLValueMath, APLValueMath_MathOperator as MathOperator, APLValueMax, + APLValueMaxHealth, + APLValueMaxMana, APLValueMin, APLValueNot, APLValueNumberTargets, @@ -611,6 +614,13 @@ const valueKindFactories: { [f in NonNullable]: ValueKindConfig]: ValueKindConfig, _isPrepull: boolean) => player.getClass() !== Class.ClassRogue && player.getClass() !== Class.ClassWarrior, }), + maxMana: inputBuilder({ + label: 'Max Mana', + submenu: ['Resources'], + shortDescription: 'Maximum amount of Mana.', + newValue: APLValueMaxMana.create, + fields: [], + includeIf: (player: Player, _isPrepull: boolean) => player.getClass() !== Class.ClassRogue && player.getClass() !== Class.ClassWarrior, + }), currentRage: inputBuilder({ label: 'Rage', submenu: ['Resources'], @@ -673,6 +691,15 @@ const valueKindFactories: { [f in NonNullable]: ValueKindConfig, _isPrepull: boolean) => player.getClass() === Class.ClassRogue || player.getClass() === Class.ClassDruid, }), + // Stats + currentAttackPower: inputBuilder({ + label: 'Current Attack Power', + submenu: ['Stats'], + shortDescription: 'Current Attack Power includuing temporary bonuses.', + newValue: APLValueCurrentAttackPower.create, + fields: [], + }), + // GCD gcdIsReady: inputBuilder({ label: 'GCD Is Ready',