Skip to content

Commit

Permalink
Merge pull request #3172 from Horatio27/t10_snapshot_enh
Browse files Browse the repository at this point in the history
Added Fire Elemental Section to holds new inputs
Added Enh T10 (4pc) snapshotting input.
Added Bonus Spell power input
  • Loading branch information
Horatio27 authored Jun 18, 2023
2 parents 695814a + 3f037fa commit 9bde2c5
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 21 deletions.
6 changes: 6 additions & 0 deletions proto/shaman.proto
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,12 @@ message ShamanTotems {

// If set will use fire totems as an MCD instead of manually controlling when to place them.
bool use_fire_mcd = 9;

// Bonus spell power for fire elemental snapshotting.
int32 bonus_spellpower = 10;

// Snapshot fire elemental using Tier 10 4 set bonus.
bool enh_tier_ten_bonus = 11;
}

enum ShamanShield {
Expand Down
8 changes: 7 additions & 1 deletion sim/shaman/fire_elemental_pet.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type FireElemental struct {
shamanOwner *Shaman
}

func (shaman *Shaman) NewFireElemental() *FireElemental {
func (shaman *Shaman) NewFireElemental(bonusSpellPower float64) *FireElemental {
fireElemental := &FireElemental{
Pet: core.NewPet("Greater Fire Elemental", &shaman.Character, fireElementalPetBaseStats, shaman.fireElementalStatInheritance(), nil, false, true),
shamanOwner: shaman,
Expand All @@ -44,6 +44,12 @@ func (shaman *Shaman) NewFireElemental() *FireElemental {
AutoSwingMelee: true,
})
fireElemental.AddStatDependency(stats.Intellect, stats.SpellCrit, core.CritRatingPerCritChance/212)

if bonusSpellPower > 0 {
fireElemental.AddStat(stats.SpellPower, float64(bonusSpellPower)*0.5218)
fireElemental.AddStat(stats.AttackPower, float64(bonusSpellPower)*4.45)
}

fireElemental.OnPetEnable = fireElemental.enable
fireElemental.OnPetDisable = fireElemental.disable

Expand Down
19 changes: 16 additions & 3 deletions sim/shaman/fire_elemental_totem.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,17 +63,30 @@ func (shaman *Shaman) registerFireElementalTotem() {

//Enh has 1.5seconds GCD also, so just going to wait the normal 1.5 instead of using the dynamic Spell GCD
var castWindow = 1550 * time.Millisecond

enhTier10Aura := shaman.GetAura("Maelstrom Power")

shaman.AddMajorCooldown(core.MajorCooldown{
Spell: shaman.FireElementalTotem,
Type: core.CooldownTypeUnknown,
ShouldActivate: func(sim *core.Simulation, character *core.Character) bool {
success := shaman.fireElementalSnapShot.CanSnapShot(sim, castWindow)

if (sim.Encounter.Duration <= 120*time.Second && sim.CurrentTime >= 10*time.Second) || (sim.Encounter.Duration > 120*time.Second && sim.CurrentTime >= 20*time.Second) {
success := false
if enhTier10Aura != nil && shaman.Totems.EnhTierTenBonus {
if enhTier10Aura.IsActive() {
success = shaman.fireElementalSnapShot.CanSnapShot(sim, enhTier10Aura.RemainingDuration(sim))
}
} else if sim.CurrentTime > 1*time.Second && shaman.fireElementalSnapShot == nil {
success = true
} else if sim.Encounter.Duration <= 120*time.Second && sim.CurrentTime >= 10*time.Second {
success = true
} else if sim.Encounter.Duration > 120*time.Second && sim.CurrentTime >= 20*time.Second {
success = true
} else if shaman.fireElementalSnapShot != nil {
success = shaman.fireElementalSnapShot.CanSnapShot(sim, castWindow)
}

if success {
if success && shaman.fireElementalSnapShot != nil {
shaman.castFireElemental = true
shaman.fireElementalSnapShot.ActivateMajorCooldowns(sim)
shaman.fireElementalSnapShot.ResetProcTrackers()
Expand Down
16 changes: 14 additions & 2 deletions sim/shaman/shaman.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,13 @@ func NewShaman(character core.Character, talents string, totems *proto.ShamanTot
if selfBuffs.Shield == proto.ShamanShield_WaterShield {
shaman.AddStat(stats.MP5, 100)
}
shaman.FireElemental = shaman.NewFireElemental()

// When using the tier bonus for snapshotting we do not use the bonus spell
if totems.EnhTierTenBonus {
totems.BonusSpellpower = 0
}

shaman.FireElemental = shaman.NewFireElemental(float64(totems.BonusSpellpower))
return shaman
}

Expand Down Expand Up @@ -217,6 +223,8 @@ func (shaman *Shaman) AddPartyBuffs(partyBuffs *proto.PartyBuffs) {
}

func (shaman *Shaman) Initialize() {
enableSnapshot := shaman.Totems.BonusSpellpower == 0

shaman.registerChainLightningSpell()
shaman.registerFeralSpirit()
shaman.registerFireElementalTotem()
Expand All @@ -242,7 +250,7 @@ func (shaman *Shaman) Initialize() {

shaman.registerBloodlustCD()

if shaman.Totems.UseFireElemental {
if shaman.Totems.UseFireElemental && enableSnapshot {
shaman.fireElementalSnapShot = core.NewSnapshotManager(shaman.GetCharacter())
shaman.setupProcTrackers()
}
Expand Down Expand Up @@ -392,6 +400,10 @@ func (shaman *Shaman) setupProcTrackers() {
}

func (shaman *Shaman) setupFireElementalCooldowns() {
if shaman.fireElementalSnapShot == nil {
return
}

shaman.fireElementalSnapShot.ClearMajorCooldowns()

// blood fury (orc)
Expand Down
78 changes: 78 additions & 0 deletions ui/core/components/fire_elemental_inputs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { IndividualSimUI } from "../individual_sim_ui";
import { Player } from "../player";
import { ShamanTotems } from "../proto/shaman";
import { ShamanSpecs } from "../proto_utils/utils";
import { EventID } from "../typed_event";
import { ContentBlock } from "./content_block";
import { IconPicker } from "./icon_picker";
import * as InputHelpers from '../components/input_helpers.js';
import { ActionId } from '../proto_utils/action_id.js';
import { Input } from "./input";
import { NumberPicker } from "./number_picker";
import { BooleanPicker } from "./boolean_picker";

export function FireElementalSection(parentElem: HTMLElement, simUI: IndividualSimUI<ShamanSpecs>): ContentBlock {
let contentBlock = new ContentBlock(parentElem, 'fire-elemental-settings', {
header: {title: 'Fire Elemental'}
});

let fireElementalIconContainer = Input.newGroupContainer();
fireElementalIconContainer.classList.add('fire-elemental-icon-container');

contentBlock.bodyElement.appendChild(fireElementalIconContainer);

const fireElementalBooleanIconInput = InputHelpers.makeBooleanIconInput<ShamanSpecs, ShamanTotems, Player<ShamanSpecs>>({
getModObject: (player: Player<ShamanSpecs>) => player,
getValue: (player: Player<ShamanSpecs>) => player.getRotation().totems || ShamanTotems.create(),
setValue: (eventID: EventID, player: Player<ShamanSpecs>, newVal: ShamanTotems) => {
const newRotation = player.getRotation();
newRotation.totems = newVal;
player.setRotation(eventID, newRotation);
},
changeEmitter: (player: Player<ShamanSpecs>) => player.rotationChangeEmitter,
}, ActionId.fromSpellId(2894), "useFireElemental");

new IconPicker(fireElementalIconContainer, simUI.player, fireElementalBooleanIconInput);

new NumberPicker(contentBlock.bodyElement, simUI.player, {
positive: true,
label: "Bonus Spellpower",
labelTooltip: "Bonus Spellpower to snapshot Fire Elemental with. Will prioritize dropping Fire Elemental if greater then 0",
inline: true,
getValue: (player: Player<ShamanSpecs>) => player.getRotation().totems?.bonusSpellpower || 0,
setValue: (eventID: EventID, player: Player<ShamanSpecs>, newVal: number) => {
const newRotation = player.getRotation();

if (newRotation.totems){
newRotation.totems.bonusSpellpower = newVal
}

player.setRotation(eventID, newRotation);
},
changedEvent: (player: Player<ShamanSpecs>) => player.rotationChangeEmitter,
})

new BooleanPicker(contentBlock.bodyElement, simUI.player, {
label: "Use Tier 10 (4pc)",
labelTooltip: "Will use Tier 10 (4pc) to snapshot Fire Elemental.",
inline: true,
getValue: (player: Player<ShamanSpecs>) => player.getRotation().totems?.enhTierTenBonus || false,
setValue: (eventID: EventID, player: Player<ShamanSpecs>, newVal: boolean) => {
const newRotation = player.getRotation();

if (newRotation.totems){
newRotation.totems.enhTierTenBonus = newVal
}

player.setRotation(eventID, newRotation);
},
changedEvent: (player: Player<ShamanSpecs>) => player.currentStatsEmitter,
showWhen: (player: Player<ShamanSpecs>) => {
const hasBonus = player.getCurrentStats().sets.includes('Frost Witch\'s Battlegear (4pc)');
return hasBonus
}
})


return contentBlock;
}
30 changes: 17 additions & 13 deletions ui/core/components/totem_inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
FireTotem,
WaterTotem,
ShamanTotems,
EnhancementShaman,
} from '../proto/shaman.js';
import { Spec } from '../proto/common.js';
import { ActionId } from '../proto_utils/action_id.js';
Expand All @@ -30,7 +31,7 @@ export function TotemsSection(parentElem: HTMLElement, simUI: IndividualSimUI<Sh
totemDropdownGroup.classList.add('totem-dropdowns-container', 'icon-group');

let fireElementalContainer = document.createElement('div');
fireElementalContainer.classList.add('fire-elemental-inputs-container');
fireElementalContainer.classList.add('fire-elemental-input-container');

contentBlock.bodyElement.appendChild(totemDropdownGroup);
contentBlock.bodyElement.appendChild(fireElementalContainer);
Expand Down Expand Up @@ -130,18 +131,21 @@ export function TotemsSection(parentElem: HTMLElement, simUI: IndividualSimUI<Sh
},
});

const fireElementalBooleanIconInput = InputHelpers.makeBooleanIconInput<ShamanSpecs, ShamanTotems, Player<ShamanSpecs>>({
getModObject: (player: Player<ShamanSpecs>) => player,
getValue: (player: Player<ShamanSpecs>) => player.getRotation().totems || ShamanTotems.create(),
setValue: (eventID: EventID, player: Player<ShamanSpecs>, newVal: ShamanTotems) => {
const newRotation = player.getRotation();
newRotation.totems = newVal;
player.setRotation(eventID, newRotation);
},
changeEmitter: (player: Player<Spec.SpecEnhancementShaman>) => player.rotationChangeEmitter,
}, ActionId.fromSpellId(2894), "useFireElemental");

new IconPicker(fireElementalContainer, simUI.player, fireElementalBooleanIconInput);
// Enchancement Shaman uses the Fire Elemental Inputs with custom inputs.
if (simUI.player.spec != Spec.SpecEnhancementShaman){
const fireElementalBooleanIconInput = InputHelpers.makeBooleanIconInput<ShamanSpecs, ShamanTotems, Player<ShamanSpecs>>({
getModObject: (player: Player<ShamanSpecs>) => player,
getValue: (player: Player<ShamanSpecs>) => player.getRotation().totems || ShamanTotems.create(),
setValue: (eventID: EventID, player: Player<ShamanSpecs>, newVal: ShamanTotems) => {
const newRotation = player.getRotation();
newRotation.totems = newVal;
player.setRotation(eventID, newRotation);
},
changeEmitter: (player: Player<Spec.SpecEnhancementShaman>) => player.rotationChangeEmitter,
}, ActionId.fromSpellId(2894), "useFireElemental");

new IconPicker(fireElementalContainer, simUI.player, fireElementalBooleanIconInput);
}

return contentBlock;
}
4 changes: 3 additions & 1 deletion ui/enhancement_shaman/sim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import * as OtherInputs from '../core/components/other_inputs.js';

import * as ShamanInputs from './inputs.js';
import * as Presets from './presets.js';
import { FireElementalSection } from '../core/components/fire_elemental_inputs.js';

export class EnhancementShamanSimUI extends IndividualSimUI<Spec.SpecEnhancementShaman> {
constructor(parentElem: HTMLElement, player: Player<Spec.SpecEnhancementShaman>) {
Expand Down Expand Up @@ -136,7 +137,8 @@ export class EnhancementShamanSimUI extends IndividualSimUI<Spec.SpecEnhancement
],
},
customSections: [
TotemsSection
TotemsSection,
FireElementalSection
],
encounterPicker: {
// Whether to include 'Execute Duration (%)' in the 'Encounter' section of the settings tab.
Expand Down
14 changes: 14 additions & 0 deletions ui/scss/core/components/_fire_elemental_inputs.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.fire-elemental-settings {
.input-root {
label {
width: 60%;
padding-right: .5rem;
}

input:not(.form-check-input),
select,
.picker-group {
min-width: 40%;
}
}
}
2 changes: 1 addition & 1 deletion ui/scss/core/components/_totem_inputs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
grid-template-columns: repeat(4, minmax(0, 1fr));
}

.fire-elemental-inputs-container {
.fire-elemental-input-container {
display: flex;
}
}

0 comments on commit 9bde2c5

Please sign in to comment.