Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion proto/common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ message PetMiscConsumes {
bool juju_flurry = 1;
}

// NextIndex: 31
// NextIndex: 25
enum WeaponImbue {
// Weapon Oils
WeaponImbueUnknown = 0;
Expand All @@ -488,6 +488,7 @@ enum WeaponImbue {
LesserWizardOil = 14;
WizardOil = 20;
BrilliantWizardOil = 2;
BlessedWizardOil = 24;

MinorManaOil = 15;
LesserManaOil = 16;
Expand All @@ -497,6 +498,7 @@ enum WeaponImbue {
SolidSharpeningStone = 17;
DenseSharpeningStone = 3;
ElementalSharpeningStone = 4;
ConsecratedSharpeningStone = 23;

// Weightstones
SolidWeightstone = 18;
Expand Down
79 changes: 51 additions & 28 deletions sim/core/consumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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)
}
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions sim/druid/balance/TestP1Balance.results
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
7 changes: 7 additions & 0 deletions sim/druid/feral/TestP1Feral.results
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
22 changes: 22 additions & 0 deletions sim/druid/item_sets_pve.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
},
})
},
},
})
58 changes: 53 additions & 5 deletions sim/druid/items.go
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're running into an error with Moonkin Form, you may need to add

if druid.MoonkinForm != nil {
  ...
}

},
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
}
47 changes: 36 additions & 11 deletions ui/core/components/inputs/consumables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> extends ActionInputConfig<T> {
value: T;
Expand Down Expand Up @@ -806,7 +807,9 @@ export const makeMp5ConsumeInput = makeConsumeInputFactory({ consumesFieldName:
export const Windfury: ConsumableInputConfig<WeaponImbue> = {
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
Expand Down Expand Up @@ -852,6 +855,16 @@ export const MinorWizardOil = (slot: ItemSlot): ConsumableInputConfig<WeaponImbu
},
};
};
export const BlessedWizardOil = (slot: ItemSlot): ConsumableInputConfig<WeaponImbue> => {
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
Expand Down Expand Up @@ -887,13 +900,23 @@ export const MinorManaOil = (slot: ItemSlot): ConsumableInputConfig<WeaponImbue>
};

// Sharpening Stones
export const ConsecratedSharpeningStone = (slot: ItemSlot): ConsumableInputConfig<WeaponImbue> => {
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<WeaponImbue> => {
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);
},
};
};
Expand All @@ -903,7 +926,7 @@ export const DenseSharpeningStone = (slot: ItemSlot): ConsumableInputConfig<Weap
value: WeaponImbue.DenseSharpeningStone,
showWhen: player => {
const weapon = player.getEquippedItem(slot);
return !weapon || isSharpWeaponType(weapon.item.weaponType);
return (!weapon || isSharpWeaponType(weapon.item.weaponType)) && !player.isSpec(Spec.SpecFeralDruid);
},
};
};
Expand All @@ -913,7 +936,7 @@ export const SolidSharpeningStone = (slot: ItemSlot): ConsumableInputConfig<Weap
value: WeaponImbue.SolidSharpeningStone,
showWhen: player => {
const weapon = player.getEquippedItem(slot);
return !weapon || isSharpWeaponType(weapon.item.weaponType);
return (!weapon || isSharpWeaponType(weapon.item.weaponType)) && !player.isSpec(Spec.SpecFeralDruid);
},
};
};
Expand All @@ -925,7 +948,7 @@ export const DenseWeightstone = (slot: ItemSlot): ConsumableInputConfig<WeaponIm
value: WeaponImbue.DenseWeightstone,
showWhen: player => {
const weapon = player.getEquippedItem(slot);
return !weapon || isBluntWeaponType(weapon.item.weaponType);
return (!weapon || isBluntWeaponType(weapon.item.weaponType)) && !player.isSpec(Spec.SpecFeralDruid);
},
};
};
Expand All @@ -935,7 +958,7 @@ export const SolidWeightstone = (slot: ItemSlot): ConsumableInputConfig<WeaponIm
value: WeaponImbue.SolidWeightstone,
showWhen: player => {
const weapon = player.getEquippedItem(slot);
return !weapon || isBluntWeaponType(weapon.item.weaponType);
return (!weapon || isBluntWeaponType(weapon.item.weaponType)) && !player.isSpec(Spec.SpecFeralDruid);
},
};
};
Expand All @@ -947,7 +970,7 @@ export const ShadowOil = (slot: ItemSlot): ConsumableInputConfig<WeaponImbue> =>
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);
},
};
};
Expand All @@ -957,7 +980,7 @@ export const FrostOil = (slot: ItemSlot): ConsumableInputConfig<WeaponImbue> =>
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);
},
};
};
Expand All @@ -980,11 +1003,13 @@ const CONSUMABLES_IMBUES = (slot: ItemSlot): ConsumableStatOption<WeaponImbue>[]
{ 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] },
Expand Down
Loading
Loading