diff --git a/proto/common.proto b/proto/common.proto index 972678fef..f896f32b2 100644 --- a/proto/common.proto +++ b/proto/common.proto @@ -478,7 +478,7 @@ message PetMiscConsumes { bool juju_flurry = 1; } -// NextIndex: 31 +// NextIndex: 25 enum WeaponImbue { // Weapon Oils WeaponImbueUnknown = 0; @@ -488,6 +488,7 @@ enum WeaponImbue { LesserWizardOil = 14; WizardOil = 20; BrilliantWizardOil = 2; + BlessedWizardOil = 24; MinorManaOil = 15; LesserManaOil = 16; @@ -497,6 +498,7 @@ enum WeaponImbue { SolidSharpeningStone = 17; DenseSharpeningStone = 3; ElementalSharpeningStone = 4; + ConsecratedSharpeningStone = 23; // Weightstones SolidWeightstone = 18; diff --git a/sim/core/consumes.go b/sim/core/consumes.go index 5a2c2cc7a..781684d85 100644 --- a/sim/core/consumes.go +++ b/sim/core/consumes.go @@ -104,6 +104,10 @@ func addImbueStats(character *Character, imbue proto.WeaponImbue, isMh bool, sha stats.SpellPower: 36, stats.SpellCrit: 1 * SpellCritRatingPerCritChance, }) + case proto.WeaponImbue_BlessedWizardOil: + if character.CurrentTarget.MobType == proto.MobType_MobTypeUndead { + character.PseudoStats.MobTypeSpellPower += 60 + } // Mana Oils case proto.WeaponImbue_MinorManaOil: @@ -122,48 +126,67 @@ func addImbueStats(character *Character, imbue proto.WeaponImbue, isMh bool, sha // Sharpening Stones case proto.WeaponImbue_SolidSharpeningStone: - weapon := character.AutoAttacks.MH() - if !isMh { - weapon = character.AutoAttacks.OH() + if !character.PseudoStats.FeralCombatEnabled { + weapon := character.AutoAttacks.MH() + if !isMh { + weapon = character.AutoAttacks.OH() + } + weapon.BaseDamageMin += 6 + weapon.BaseDamageMax += 6 } - weapon.BaseDamageMin += 6 - weapon.BaseDamageMax += 6 case proto.WeaponImbue_DenseSharpeningStone: - weapon := character.AutoAttacks.MH() - if !isMh { - weapon = character.AutoAttacks.OH() + if !character.PseudoStats.FeralCombatEnabled { + weapon := character.AutoAttacks.MH() + if !isMh { + weapon = character.AutoAttacks.OH() + } + weapon.BaseDamageMin += 8 + weapon.BaseDamageMax += 8 } - weapon.BaseDamageMin += 8 - weapon.BaseDamageMax += 8 case proto.WeaponImbue_ElementalSharpeningStone: - character.AddStats(stats.Stats{ - stats.MeleeCrit: 2 * CritRatingPerCritChance, - }) - character.AddBonusRangedCritRating(-2.0) + if !character.PseudoStats.FeralCombatEnabled { + character.AddStats(stats.Stats{ + stats.MeleeCrit: 2 * CritRatingPerCritChance, + }) + character.AddBonusRangedCritRating(-2.0) + } + case proto.WeaponImbue_ConsecratedSharpeningStone: + if character.CurrentTarget.MobType == proto.MobType_MobTypeUndead { + character.PseudoStats.MobTypeAttackPower += 100 + } // Weightstones case proto.WeaponImbue_SolidWeightstone: - weapon := character.AutoAttacks.MH() - if !isMh { - weapon = character.AutoAttacks.OH() + if !character.PseudoStats.FeralCombatEnabled { + weapon := character.AutoAttacks.MH() + if !isMh { + weapon = character.AutoAttacks.OH() + } + weapon.BaseDamageMin += 6 + weapon.BaseDamageMax += 6 } - weapon.BaseDamageMin += 6 - weapon.BaseDamageMax += 6 case proto.WeaponImbue_DenseWeightstone: - weapon := character.AutoAttacks.MH() - if !isMh { - weapon = character.AutoAttacks.OH() + if !character.PseudoStats.FeralCombatEnabled { + weapon := character.AutoAttacks.MH() + if !isMh { + weapon = character.AutoAttacks.OH() + } + weapon.BaseDamageMin += 8 + weapon.BaseDamageMax += 8 } - weapon.BaseDamageMin += 8 - weapon.BaseDamageMax += 8 - // Windfury case proto.WeaponImbue_Windfury: - ApplyWindfury(character) + if !character.PseudoStats.FeralCombatEnabled { + ApplyWindfury(character) + } case proto.WeaponImbue_ShadowOil: - registerShadowOil(character, isMh, shadowOilIcd) + if !character.PseudoStats.FeralCombatEnabled { + registerShadowOil(character, isMh, shadowOilIcd) + } case proto.WeaponImbue_FrostOil: - registerFrostOil(character, isMh) + if !character.PseudoStats.FeralCombatEnabled { + registerFrostOil(character, isMh) + } } } } diff --git a/sim/druid/balance/TestP1Balance.results b/sim/druid/balance/TestP1Balance.results index b228fac7b..a0c2ef80b 100644 --- a/sim/druid/balance/TestP1Balance.results +++ b/sim/druid/balance/TestP1Balance.results @@ -138,6 +138,13 @@ dps_results: { tps: 166.49676 } } +dps_results: { + key: "TestP1Balance-Phase1-AllItems-SymbolsofUnendingLife" + value: { + dps: 203.49367 + tps: 216.16517 + } +} dps_results: { key: "TestP1Balance-Phase1-AllItems-Warlord'sSanctuary" value: { diff --git a/sim/druid/feral/TestP1Feral.results b/sim/druid/feral/TestP1Feral.results index e73c53c5a..9667f3b4a 100644 --- a/sim/druid/feral/TestP1Feral.results +++ b/sim/druid/feral/TestP1Feral.results @@ -138,6 +138,13 @@ dps_results: { tps: 321.74031 } } +dps_results: { + key: "TestP1Feral-Phase1-AllItems-SymbolsofUnendingLife" + value: { + dps: 531.73841 + tps: 377.53427 + } +} dps_results: { key: "TestP1Feral-Phase1-AllItems-Warlord'sSanctuary" value: { diff --git a/sim/druid/item_sets_pve.go b/sim/druid/item_sets_pve.go index a6a159690..6e6301ae3 100644 --- a/sim/druid/item_sets_pve.go +++ b/sim/druid/item_sets_pve.go @@ -170,3 +170,25 @@ var ItemSetStormrageRaiment = core.NewItemSet(core.ItemSet{ }, }, }) + +var ItemSetSymbolsOfUnendingLife = core.NewItemSet(core.ItemSet{ + Name: "Symbols of Unending Life", + Bonuses: map[int32]core.ApplyEffect{ + // (3) Set : Your finishing moves now refund 30 energy on a Miss, Dodge, Block, or Parry. + 3: func(agent core.Agent) { + c := agent.GetCharacter() + actionID := core.ActionID{SpellID: 26107} + energyMetrics := c.NewEnergyMetrics(actionID) + core.MakeProcTriggerAura(&c.Unit, core.ProcTrigger{ + Name: "Symbols of Unending Life Finisher Bonus", + Callback: core.CallbackOnSpellHitDealt, + Outcome: core.OutcomeMiss | core.OutcomeDodge | core.OutcomeBlock | core.OutcomeParry, + Handler: func(sim *core.Simulation, spell *core.Spell, _ *core.SpellResult) { + if spell.SpellCode == SpellCode_DruidFerociousBite || spell.SpellCode == SpellCode_DruidRip { + c.AddEnergy(sim, 30, energyMetrics) + } + }, + }) + }, + }, +}) diff --git a/sim/druid/items.go b/sim/druid/items.go index 2813e12bb..64b1a83e6 100644 --- a/sim/druid/items.go +++ b/sim/druid/items.go @@ -1,15 +1,18 @@ package druid import ( + "time" + "github.com/wowsims/classic/sim/core" ) -// Totem Item IDs +// Item IDs const ( - WolfsheadHelm = 8345 - IdolOfFerocity = 22397 - IdolOfTheMoon = 23197 - IdolOfBrutality = 23198 + WolfsheadHelm = 8345 + IdolOfFerocity = 22397 + IdolOfTheMoon = 23197 + IdolOfBrutality = 23198 + RuneOfMetamorphosis = 19340 ) func init() { @@ -44,5 +47,50 @@ func init() { // Implemented in maul.go and swipe.go }) + // https://www.wowhead.com/classic/item=19340/rune-of-metamorphosis + // Use: Decreases the mana cost of all Druid shapeshifting forms by 100% for 20 sec. (5 Min Cooldown) + core.NewItemEffect(RuneOfMetamorphosis, func(agent core.Agent) { + druid := agent.(DruidAgent).GetDruid() + + actionID := core.ActionID{SpellID: 23724} + duration := time.Second * 20 + cooldown := time.Minute * 5 + + buffAura := druid.GetOrRegisterAura(core.Aura{ + ActionID: actionID, + Label: "Metamorphosis Rune", + Duration: duration, + OnGain: func(aura *core.Aura, sim *core.Simulation) { + druid.CatForm.Cost.Multiplier -= 100 + //druid.BearForm.Cost.Multiplier -= 100 + //druid.MoonkinForm.Cost.Multiplier -= 100 + }, + OnExpire: func(aura *core.Aura, sim *core.Simulation) { + druid.CatForm.Cost.Multiplier += 100 + //druid.BearForm.Cost.Multiplier += 100 + //druid.MoonkinForm.Cost.Multiplier += 100 + }, + }) + + spell := druid.GetOrRegisterSpell(core.SpellConfig{ + ActionID: actionID, + Flags: core.SpellFlagNoOnCastComplete | core.SpellFlagOffensiveEquipment, + Cast: core.CastConfig{ + CD: core.Cooldown{ + Timer: druid.NewTimer(), + Duration: cooldown, + }, + }, + ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + buffAura.Activate(sim) + }, + }) + + druid.AddMajorCooldown(core.MajorCooldown{ + Spell: spell, + Type: core.CooldownTypeDPS, + }) + }) + core.AddEffectsToTest = true } diff --git a/ui/core/components/inputs/consumables.ts b/ui/core/components/inputs/consumables.ts index eed7b082a..838372ad2 100644 --- a/ui/core/components/inputs/consumables.ts +++ b/ui/core/components/inputs/consumables.ts @@ -39,6 +39,7 @@ import { MultiIconPicker, MultiIconPickerConfig, MultiIconPickerItemConfig } fro import { DeadlyPoisonWeaponImbue, InstantPoisonWeaponImbue, WoundPoisonWeaponImbue } from './rogue_imbues'; import { FlametongueWeaponImbue, FrostbrandWeaponImbue, RockbiterWeaponImbue, WindfuryWeaponImbue } from './shaman_imbues'; import { ActionInputConfig, ItemStatOption, PickerStatOptions, StatOptions } from './stat_options'; +import { FeralDruid } from '../../proto/druid'; export interface ConsumableInputConfig extends ActionInputConfig { value: T; @@ -806,7 +807,9 @@ export const makeMp5ConsumeInput = makeConsumeInputFactory({ consumesFieldName: export const Windfury: ConsumableInputConfig = { actionId: () => ActionId.fromSpellId(10614), value: WeaponImbue.Windfury, - showWhen: player => player.getFaction() === Faction.Horde, + showWhen: player => { + return (player.getFaction() === Faction.Horde) && !player.isSpec(Spec.SpecFeralDruid) + }, }; // Other Imbues @@ -852,6 +855,16 @@ export const MinorWizardOil = (slot: ItemSlot): ConsumableInputConfig => { + return { + actionId: () => ActionId.fromItemId(23123), + value: WeaponImbue.BlessedWizardOil, + showWhen: player => { + const weapon = player.getEquippedItem(slot); + return !weapon || isWeapon(weapon.item.weaponType); + }, + }; +}; // Mana Oils // Original lvl 45 but not obtainable in Phase 3 @@ -887,13 +900,23 @@ export const MinorManaOil = (slot: ItemSlot): ConsumableInputConfig }; // Sharpening Stones +export const ConsecratedSharpeningStone = (slot: ItemSlot): ConsumableInputConfig => { + return { + actionId: () => ActionId.fromItemId(23122), + value: WeaponImbue.ConsecratedSharpeningStone, + showWhen: player => { + const weapon = player.getEquippedItem(slot); + return !weapon || isWeapon(weapon.item.weaponType); + }, + }; +}; export const ElementalSharpeningStone = (slot: ItemSlot): ConsumableInputConfig => { return { actionId: () => ActionId.fromItemId(18262), value: WeaponImbue.ElementalSharpeningStone, showWhen: player => { const weapon = player.getEquippedItem(slot); - return !weapon || isWeapon(weapon.item.weaponType); + return (!weapon || isWeapon(weapon.item.weaponType)) && !player.isSpec(Spec.SpecFeralDruid); }, }; }; @@ -903,7 +926,7 @@ export const DenseSharpeningStone = (slot: ItemSlot): ConsumableInputConfig { const weapon = player.getEquippedItem(slot); - return !weapon || isSharpWeaponType(weapon.item.weaponType); + return (!weapon || isSharpWeaponType(weapon.item.weaponType)) && !player.isSpec(Spec.SpecFeralDruid); }, }; }; @@ -913,7 +936,7 @@ export const SolidSharpeningStone = (slot: ItemSlot): ConsumableInputConfig { const weapon = player.getEquippedItem(slot); - return !weapon || isSharpWeaponType(weapon.item.weaponType); + return (!weapon || isSharpWeaponType(weapon.item.weaponType)) && !player.isSpec(Spec.SpecFeralDruid); }, }; }; @@ -925,7 +948,7 @@ export const DenseWeightstone = (slot: ItemSlot): ConsumableInputConfig { const weapon = player.getEquippedItem(slot); - return !weapon || isBluntWeaponType(weapon.item.weaponType); + return (!weapon || isBluntWeaponType(weapon.item.weaponType)) && !player.isSpec(Spec.SpecFeralDruid); }, }; }; @@ -935,7 +958,7 @@ export const SolidWeightstone = (slot: ItemSlot): ConsumableInputConfig { const weapon = player.getEquippedItem(slot); - return !weapon || isBluntWeaponType(weapon.item.weaponType); + return (!weapon || isBluntWeaponType(weapon.item.weaponType)) && !player.isSpec(Spec.SpecFeralDruid); }, }; }; @@ -947,7 +970,7 @@ export const ShadowOil = (slot: ItemSlot): ConsumableInputConfig => value: WeaponImbue.ShadowOil, showWhen: player => { const weapon = player.getEquippedItem(slot); - return !weapon || isWeapon(weapon.item.weaponType); + return (!weapon || isWeapon(weapon.item.weaponType)) && !player.isSpec(Spec.SpecFeralDruid); }, }; }; @@ -957,7 +980,7 @@ export const FrostOil = (slot: ItemSlot): ConsumableInputConfig => value: WeaponImbue.FrostOil, showWhen: player => { const weapon = player.getEquippedItem(slot); - return !weapon || isWeapon(weapon.item.weaponType); + return (!weapon || isWeapon(weapon.item.weaponType)) && !player.isSpec(Spec.SpecFeralDruid); }, }; }; @@ -980,11 +1003,13 @@ const CONSUMABLES_IMBUES = (slot: ItemSlot): ConsumableStatOption[] { config: WizardOil(slot), stats: [Stat.StatSpellPower] }, { config: LesserWizardOil(slot), stats: [Stat.StatSpellPower] }, { config: MinorWizardOil(slot), stats: [Stat.StatSpellPower] }, + { config: BlessedWizardOil(slot), stats: [Stat.StatHealingPower, Stat.StatSpellPower] }, - { config: BrilliantManaOil(slot), stats: [Stat.StatHealingPower, Stat.StatSpellPower] }, - { config: LesserManaOil(slot), stats: [Stat.StatHealingPower, Stat.StatSpellPower] }, - { config: MinorManaOil(slot), stats: [Stat.StatHealingPower, Stat.StatSpellPower] }, + { config: BrilliantManaOil(slot), stats: [Stat.StatMP5, Stat.StatHealingPower] }, + { config: LesserManaOil(slot), stats: [Stat.StatMP5] }, + { config: MinorManaOil(slot), stats: [Stat.StatMP5] }, + { config: ConsecratedSharpeningStone(slot), stats: [Stat.StatAttackPower] }, { config: ElementalSharpeningStone(slot), stats: [Stat.StatAttackPower] }, { config: DenseSharpeningStone(slot), stats: [Stat.StatAttackPower] }, { config: SolidSharpeningStone(slot), stats: [Stat.StatAttackPower] }, diff --git a/ui/core/proto_utils/utils.ts b/ui/core/proto_utils/utils.ts index f127c3927..1b7a7418c 100644 --- a/ui/core/proto_utils/utils.ts +++ b/ui/core/proto_utils/utils.ts @@ -1340,7 +1340,6 @@ export const classToEligibleWeaponTypes: Record { weaponType: WeaponType.WeaponTypeMace, canUseTwoHand: true }, { weaponType: WeaponType.WeaponTypeOffHand }, { weaponType: WeaponType.WeaponTypeStaff, canUseTwoHand: true }, - { weaponType: WeaponType.WeaponTypePolearm, canUseTwoHand: true }, // Added to SoD on 2024-07-10 ], [Class.ClassHunter]: [ { weaponType: WeaponType.WeaponTypeAxe, canUseTwoHand: true }, diff --git a/ui/core/sim_ui.tsx b/ui/core/sim_ui.tsx index 928ac0a93..0adfc1c88 100644 --- a/ui/core/sim_ui.tsx +++ b/ui/core/sim_ui.tsx @@ -227,9 +227,9 @@ export abstract class SimUI extends Component { if (config.simStatus.status == LaunchStatus.Unlaunched) { statusStr = 'This sim is a WORK IN PROGRESS. It is not fully developed and should not be used for general purposes.'; } else if (config.simStatus.status == LaunchStatus.Alpha) { - statusStr = 'This sim is in ALPHA status. New runes and items may not yet be functional and further testing is needed.'; + statusStr = 'This sim is in ALPHA status. Some items may not yet be functional and further testing is needed.'; } else { - statusStr = `This sim is in BETA status. New runes and items should be mostly functional.`; + statusStr = `This sim is in BETA status. Items should be mostly functional.`; } if (statusStr) { config.knownIssues = [statusStr].concat(config.knownIssues || []); diff --git a/ui/feral_druid/apls/p2.apl.json b/ui/feral_druid/apls/p2.apl.json index 9f09615ca..8f541fb0b 100644 --- a/ui/feral_druid/apls/p2.apl.json +++ b/ui/feral_druid/apls/p2.apl.json @@ -1,19 +1,23 @@ { "type": "TypeAPL", "prepullActions": [ - {"action":{"castSpell":{"spellId":{"spellId":17392,"rank":4}}},"doAtValue":{"const":{"val":"-1.5s"}}} + {"action":{"castSpell":{"spellId":{"spellId":17392,"rank":4}}},"doAtValue":{"const":{"val":"-1.0s"}}}, + {"action":{"castSpell":{"spellId":{"spellId":9846,"rank":4}}},"doAtValue":{"const":{"val":"-3.5s"}}} ], "priorityList": [ {"action":{"condition":{"and":{"vals":[{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":17392,"rank":4}}},"rhs":{"const":{"val":"1.0"}}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":9907,"rank":4}}},"rhs":{"const":{"val":"1.0"}}}}]}},"castSpell":{"spellId":{"spellId":17392,"rank":4}}}}, + {"action":{"condition":{"and":{"vals":[{"auraIsActive":{"auraId":{"spellId":768}}},{"spellIsKnown":{"spellId":{"spellId":13494}}},{"not":{"val":{"auraIsActive":{"auraId":{"spellId":13494}}}}},{"cmp":{"op":"OpLt","lhs":{"currentTime":{}},"rhs":{"const":{"val":"90.0"}}}}]}},"castSpell":{"spellId":{"spellId":13494}}}}, {"action":{"condition":{"auraIsActive":{"auraId":{"spellId":768}}},"autocastOtherCooldowns":{}}}, + {"action":{"condition":{"and":{"vals":[{"auraIsKnown":{"auraId":{"spellId":17061,"rank":5}}},{"cmp":{"op":"OpGe","lhs":{"currentMana":{}},"rhs":{"spellCurrentCost":{"spellId":{"spellId":768}}}}},{"gcdIsReady":{}},{"and":{"vals":[{"auraIsKnown":{"auraId":{"spellId":16870}}},{"auraIsActive":{"auraId":{"spellId":16870}}},{"cmp":{"op":"OpLt","lhs":{"currentEnergy":{}},"rhs":{"const":{"val":"27.8"}}}}]}}]}},"cancelAura":{"auraId":{"spellId":768}}}}, {"action":{"condition":{"and":{"vals":[{"cmp":{"op":"OpEq","lhs":{"currentComboPoints":{}},"rhs":{"const":{"val":"5.0"}}}},{"not":{"val":{"auraIsActive":{"auraId":{"spellId":16870}}}}},{"cmp":{"op":"OpLt","lhs":{"math":{"op":"OpAdd","lhs":{"currentEnergy":{}},"rhs":{"const":{"val":"20.2"}}}},"rhs":{"math":{"op":"OpAdd","lhs":{"spellCurrentCost":{"spellId":{"spellId":9830,"rank":5}}},"rhs":{"spellCurrentCost":{"spellId":{"spellId":22829,"rank":4}}}}}}}]}},"castSpell":{"spellId":{"spellId":22829,"rank":4}}}}, {"action":{"castSpell":{"spellId":{"spellId":9830,"rank":5}}}}, {"action":{"condition":{"and":{"vals":[{"auraIsKnown":{"auraId":{"spellId":17061,"rank":5}}},{"cmp":{"op":"OpGe","lhs":{"currentMana":{}},"rhs":{"spellCurrentCost":{"spellId":{"spellId":768}}}}},{"cmp":{"op":"OpGt","lhs":{"timeToEnergyTick":{}},"rhs":{"const":{"val":"1.02"}}}}]}},"castSpell":{"spellId":{"spellId":9850,"rank":5}}}}, {"action":{"condition":{"and":{"vals":[{"auraIsKnown":{"auraId":{"spellId":17061,"rank":5}}},{"cmp":{"op":"OpGe","lhs":{"currentMana":{}},"rhs":{"spellCurrentCost":{"spellId":{"spellId":768}}}}},{"gcdIsReady":{}},{"or":{"vals":[{"and":{"vals":[{"cmp":{"op":"OpLt","lhs":{"currentComboPoints":{}},"rhs":{"const":{"val":"5.0"}}}},{"cmp":{"op":"OpLt","lhs":{"math":{"op":"OpAdd","lhs":{"currentEnergy":{}},"rhs":{"const":{"val":"20.2"}}}},"rhs":{"spellCurrentCost":{"spellId":{"spellId":9830,"rank":5}}}}}]}},{"and":{"vals":[{"cmp":{"op":"OpEq","lhs":{"currentComboPoints":{}},"rhs":{"const":{"val":"5.0"}}}},{"cmp":{"op":"OpLt","lhs":{"math":{"op":"OpAdd","lhs":{"currentEnergy":{}},"rhs":{"const":{"val":"20.2"}}}},"rhs":{"spellCurrentCost":{"spellId":{"spellId":22829,"rank":4}}}}}]}},{"and":{"vals":[{"auraIsKnown":{"auraId":{"spellId":16870}}},{"auraIsActive":{"auraId":{"spellId":16870}}},{"cmp":{"op":"OpLt","lhs":{"currentEnergy":{}},"rhs":{"const":{"val":"27.8"}}}}]}}]}}]}},"cancelAura":{"auraId":{"spellId":768}}}}, - {"action":{"condition":{"and":{"vals":[{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":17392,"rank":4}}},"rhs":{"const":{"val":"8.0"}}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":9907,"rank":4}}},"rhs":{"const":{"val":"8.0"}}}}]}},"castSpell":{"spellId":{"spellId":17392,"rank":4}}}}, + {"action":{"condition":{"and":{"vals":[{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":17392,"rank":4}}},"rhs":{"const":{"val":"14.0"}}}},{"cmp":{"op":"OpLe","lhs":{"auraRemainingTime":{"sourceUnit":{"type":"CurrentTarget"},"auraId":{"spellId":9907,"rank":4}}},"rhs":{"const":{"val":"14.0"}}}}]}},"castSpell":{"spellId":{"spellId":17392,"rank":4}}}}, {"action":{"condition":{"not":{"val":{"auraIsActive":{"auraId":{"spellId":768}}}}},"castSpell":{"spellId":{"itemId":10646}}}}, {"action":{"condition":{"and":{"vals":[{"not":{"val":{"auraIsActive":{"auraId":{"spellId":768}}}}},{"cmp":{"op":"OpLe","lhs":{"math":{"op":"OpAdd","lhs":{"currentMana":{}},"rhs":{"const":{"val":"1500.0"}}}},"rhs":{"math":{"op":"OpDiv","lhs":{"currentMana":{}},"rhs":{"currentManaPercent":{}}}}}}]}},"castSpell":{"spellId":{"itemId":12662}}}}, {"action":{"condition":{"and":{"vals":[{"not":{"val":{"auraIsActive":{"auraId":{"spellId":768}}}}},{"cmp":{"op":"OpLe","lhs":{"math":{"op":"OpAdd","lhs":{"currentMana":{}},"rhs":{"const":{"val":"2250.0"}}}},"rhs":{"math":{"op":"OpDiv","lhs":{"currentMana":{}},"rhs":{"currentManaPercent":{}}}}}}]}},"castSpell":{"spellId":{"otherId":"OtherActionPotion"}}}}, + {"action":{"condition":{"and":{"vals":[{"not":{"val":{"auraIsActive":{"auraId":{"spellId":768}}}}},{"cmp":{"op":"OpLe","lhs":{"currentManaPercent":{}},"rhs":{"const":{"val":"80%"}}}},{"not":{"val":{"or":{"vals":[{"and":{"vals":[{"spellIsKnown":{"spellId":{"itemId":12662}}},{"spellIsReady":{"spellId":{"itemId":12662}}}]}},{"and":{"vals":[{"spellIsKnown":{"spellId":{"otherId":"OtherActionPotion"}}},{"spellIsReady":{"spellId":{"otherId":"OtherActionPotion"}}}]}}]}}}}]}},"castSpell":{"spellId":{"spellId":23724}}}}, {"action":{"condition":{"and":{"vals":[{"not":{"val":{"auraIsActive":{"auraId":{"spellId":768}}}}},{"cmp":{"op":"OpLe","lhs":{"currentManaPercent":{}},"rhs":{"const":{"val":"40%"}}}},{"cmp":{"op":"OpGe","lhs":{"remainingTime":{}},"rhs":{"const":{"val":"20.0"}}}},{"not":{"val":{"or":{"vals":[{"and":{"vals":[{"spellIsKnown":{"spellId":{"itemId":12662}}},{"spellIsReady":{"spellId":{"itemId":12662}}}]}},{"and":{"vals":[{"spellIsKnown":{"spellId":{"otherId":"OtherActionPotion"}}},{"spellIsReady":{"spellId":{"otherId":"OtherActionPotion"}}}]}}]}}}}]}},"castSpell":{"spellId":{"spellId":29166}}}}, {"action":{"condition":{"not":{"val":{"auraIsActive":{"auraId":{"spellId":768}}}}},"castSpell":{"spellId":{"spellId":768}}}} ] diff --git a/ui/feral_druid/gear_sets/p2.bis.gear.json b/ui/feral_druid/gear_sets/p2.bis.gear.json index 0fe424a64..b31a1abc3 100644 --- a/ui/feral_druid/gear_sets/p2.bis.gear.json +++ b/ui/feral_druid/gear_sets/p2.bis.gear.json @@ -4,7 +4,7 @@ {"id":12927}, {"id":18541,"enchant":849}, {"id":22877,"enchant":1891}, - {"id":19587,"enchant":1885}, + {"id":19146,"enchant":1885}, {"id":15063,"enchant":1887}, {"id":13252}, {"id":15062,"enchant":1508}, diff --git a/ui/feral_druid/gear_sets/p3.bis.gear.json b/ui/feral_druid/gear_sets/p3.bis.gear.json new file mode 100644 index 000000000..791f72dfd --- /dev/null +++ b/ui/feral_druid/gear_sets/p3.bis.gear.json @@ -0,0 +1,19 @@ +{"items": [ + {"id":8345,"enchant":1508}, + {"id":19377}, + {"id":16551}, + {"id":19436,"enchant":849}, + {"id":16549,"enchant":1891}, + {"id":19587,"enchant":1885}, + {"id":16555,"enchant":1887}, + {"id":19163}, + {"id":16552,"enchant":1508}, + {"id":19381,"enchant":1887}, + {"id":17063}, + {"id":19432}, + {"id":19406}, + {"id":13965}, + {"id":9449,"enchant":34}, + {}, + {} +]} \ No newline at end of file diff --git a/ui/feral_druid/presets.ts b/ui/feral_druid/presets.ts index ccc1fb1d3..8075b52ee 100644 --- a/ui/feral_druid/presets.ts +++ b/ui/feral_druid/presets.ts @@ -26,6 +26,7 @@ import { SavedTalents } from '../core/proto/ui.js'; import P2APL from './apls/p2.apl.json'; import P2BISGear from './gear_sets/p2.bis.gear.json'; import P2PreBISGear from './gear_sets/p2.pre-bis.gear.json'; +import P3BISGear from './gear_sets/p3.bis.gear.json'; // Preset options for this spec. // Eventually we will import these values for the raid sim too, so its good to @@ -37,9 +38,10 @@ import P2PreBISGear from './gear_sets/p2.pre-bis.gear.json'; export const GearP2BIS = PresetUtils.makePresetGear('P2 BiS', P2BISGear); export const GearP2PreBIS = PresetUtils.makePresetGear('P2 Pre-BiS', P2PreBISGear); +export const GearP3BIS = PresetUtils.makePresetGear('P3 BiS', P3BISGear) export const GearPresets = { - [Phase.Phase2]: [GearP2BIS, GearP2PreBIS], + [Phase.Phase2]: [GearP2PreBIS, GearP2BIS, GearP3BIS], }; export const DefaultGear = GearP2BIS; @@ -91,7 +93,7 @@ export const DefaultConsumes = Consumes.create({ attackPowerBuff: AttackPowerBuff.JujuMight, defaultConjured: Conjured.ConjuredDemonicRune, defaultPotion: Potions.MajorManaPotion, - dragonBreathChili: false, + dragonBreathChili: true, flask: Flask.FlaskOfDistilledWisdom, food: Food.FoodGrilledSquid, strengthBuff: StrengthBuff.JujuPower, @@ -104,10 +106,10 @@ export const DefaultRaidBuffs = RaidBuffs.create({ battleShout: TristateEffect.TristateEffectImproved, divineSpirit: true, giftOfTheWild: TristateEffect.TristateEffectImproved, - graceOfAirTotem: TristateEffect.TristateEffectImproved, leaderOfThePack: true, manaSpringTotem: TristateEffect.TristateEffectRegular, strengthOfEarthTotem: TristateEffect.TristateEffectImproved, + powerWordFortitude: TristateEffect.TristateEffectImproved, }); export const DefaultIndividualBuffs = IndividualBuffs.create({ @@ -125,7 +127,7 @@ export const DefaultIndividualBuffs = IndividualBuffs.create({ export const DefaultDebuffs = Debuffs.create({ curseOfRecklessness: true, exposeArmor: TristateEffect.TristateEffectImproved, - faerieFire: true, + faerieFire: false, sunderArmor: true, }); diff --git a/ui/feral_druid/sim.ts b/ui/feral_druid/sim.ts index 85061e5ba..bba0563a0 100644 --- a/ui/feral_druid/sim.ts +++ b/ui/feral_druid/sim.ts @@ -16,7 +16,9 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecFeralDruid, { cssClass: 'feral-druid-sim-ui', cssScheme: 'druid', // List any known bugs / issues here and they'll be shown on the site. - knownIssues: [], + knownIssues: [ + "The Enchant Gloves - Minor Haste enchant doesn't have its EP of 16.50 show up properly", + ], warnings: [], // All stats for which EP should be calculated.