Skip to content

Commit

Permalink
add nibelung survivability configuration (wowsims#3927)
Browse files Browse the repository at this point in the history
* add nibelung survivability configuration

* better
  • Loading branch information
lime-green authored Oct 20, 2023
1 parent a0943a1 commit 0921081
Show file tree
Hide file tree
Showing 20 changed files with 72 additions and 13 deletions.
2 changes: 2 additions & 0 deletions proto/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ message Player {

// Items/enchants/gems/etc to include in the database.
SimDatabase database = 35;

double nibelung_average_casts = 43;
}

message Party {
Expand Down
1 change: 1 addition & 0 deletions proto/ui.proto
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ message SavedSettings {
bool in_front_of_target = 11;
double distance_from_target = 12;
HealingModel healing_model = 13;
double nibelung_average_casts = 15;
}

message SavedTalents {
Expand Down
9 changes: 8 additions & 1 deletion sim/common/wotlk/nibelung.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,14 @@ func MakeNibelungTriggerAura(agent core.Agent, isHeroic bool) {
for _, petAgent := range character.PetAgents {
if valkyr, ok := petAgent.(*ValkyrPet); ok && !valkyr.IsEnabled() {
valkyr.registerSmite(isHeroic)
valkyr.EnableWithTimeout(sim, petAgent, valkyrAura.Duration)

averageCasts := character.NibelungAverageCasts
duration := min(time.Duration(averageCasts/16*30)*time.Second, time.Second*30)
valkyrAura.Duration = max(duration, time.Millisecond*250)

if averageCasts > 0 {
valkyr.EnableWithTimeout(sim, petAgent, valkyrAura.Duration)
}
break
}
}
Expand Down
9 changes: 5 additions & 4 deletions sim/core/character.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,11 @@ func NewCharacter(party *Party, partyIndex int, player *proto.Player) Character

StatDependencyManager: stats.NewStatDependencyManager(),

ReactionTime: max(0, time.Duration(player.ReactionTimeMs)*time.Millisecond),
ChannelClipDelay: max(0, time.Duration(player.ChannelClipDelayMs)*time.Millisecond),
DistanceFromTarget: player.DistanceFromTarget,
IsUsingAPL: player.Rotation != nil && player.Rotation.Type == proto.APLRotation_TypeAPL,
ReactionTime: max(0, time.Duration(player.ReactionTimeMs)*time.Millisecond),
ChannelClipDelay: max(0, time.Duration(player.ChannelClipDelayMs)*time.Millisecond),
DistanceFromTarget: player.DistanceFromTarget,
NibelungAverageCasts: player.NibelungAverageCasts,
IsUsingAPL: player.Rotation != nil && player.Rotation.Type == proto.APLRotation_TypeAPL,
},

Name: player.Name,
Expand Down
3 changes: 3 additions & 0 deletions sim/core/unit.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ type Unit struct {
// for calculating spell travel time for certain spells.
DistanceFromTarget float64

// How many casts on average a Valkyr will get off during its lifetime.
NibelungAverageCasts float64

// Environment in which this Unit exists. This will be nil until after the
// construction phase.
Env *Environment
Expand Down
1 change: 1 addition & 0 deletions ui/balance_druid/presets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,5 @@ export const OtherDefaults = {
distanceFromTarget: 18,
profession1: Profession.Engineering,
profession2: Profession.Tailoring,
nibelungAverageCasts: 11,
};
1 change: 1 addition & 0 deletions ui/balance_druid/sim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export class BalanceDruidSimUI extends IndividualSimUI<Spec.SpecBalanceDruid> {
OtherInputs.TankAssignment,
OtherInputs.ReactionTime,
OtherInputs.DistanceFromTarget,
OtherInputs.nibelungAverageCasts,
],
},
encounterPicker: {
Expand Down
2 changes: 2 additions & 0 deletions ui/core/components/individual_sim_ui/settings_tab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ export class SettingsTab extends SimTab {
inFrontOfTarget: player.getInFrontOfTarget(),
distanceFromTarget: player.getDistanceFromTarget(),
healingModel: player.getHealingModel(),
nibelungAverageCasts: player.getNibelungAverageCasts(),
cooldowns: aplLaunchStatuses[simUI.player.spec] == LaunchStatus.Unlaunched ? player.getCooldowns() : undefined,
rotationJson: aplLaunchStatuses[simUI.player.spec] == LaunchStatus.Unlaunched ? JSON.stringify(player.specTypeFunctions.rotationToJson(player.getRotation())) : undefined,
});
Expand All @@ -420,6 +421,7 @@ export class SettingsTab extends SimTab {
simUI.player.setInFrontOfTarget(eventID, newSettings.inFrontOfTarget);
simUI.player.setDistanceFromTarget(eventID, newSettings.distanceFromTarget);
simUI.player.setHealingModel(eventID, newSettings.healingModel || HealingModel.create());
simUI.player.setNibelungAverageCasts(eventID, newSettings.nibelungAverageCasts)
if (aplLaunchStatuses[simUI.player.spec] == LaunchStatus.Unlaunched) {
simUI.player.setCooldowns(eventID, newSettings.cooldowns || Cooldowns.create());
if (newSettings.rotationJson) {
Expand Down
27 changes: 19 additions & 8 deletions ui/core/components/other_inputs.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { BooleanPicker } from '../components/boolean_picker.js';
import { EnumPicker } from '../components/enum_picker.js';
import { UnitReference } from '../proto/common.js';
import { Player } from '../player.js';
import { Sim } from '../sim.js';
import { EventID, TypedEvent } from '../typed_event.js';
import { emptyUnitReference } from '../proto_utils/utils.js';
import { APLRotation_Type } from '../proto/apl.js';
import {BooleanPicker} from '../components/boolean_picker.js';
import {EnumPicker} from '../components/enum_picker.js';
import {ItemSlot, UnitReference} from '../proto/common.js';
import {Player} from '../player.js';
import {Sim} from '../sim.js';
import {EventID} from '../typed_event.js';
import {emptyUnitReference} from '../proto_utils/utils.js';

export function makeShow1hWeaponsSelector(parent: HTMLElement, sim: Sim): BooleanPicker<Sim> {
return new BooleanPicker<Sim>(parent, sim, {
Expand Down Expand Up @@ -127,6 +126,18 @@ export const DistanceFromTarget = {
},
};

export const nibelungAverageCasts = {
type: 'number' as const,
label: "Nibelung's Valkyr Survival (in # of casts)",
labelTooltip: 'Number of casts of Nibelung\'s summoned Valkyrs get out before they die (max 16)',
changedEvent: (player: Player<any>) => player.changeEmitter,
getValue: (player: Player<any>) => player.getNibelungAverageCasts(),
setValue: (eventID: EventID, player: Player<any>, newValue: number) => {
player.setNibelungAverageCasts(eventID, newValue);
},
showWhen: (player: Player<any>) => [49992, 50648].includes(player.getEquippedItem(ItemSlot.ItemSlotMainHand)?.id || 0)
}

export const TankAssignment = {
type: 'enum' as const,
extraCssClasses: [
Expand Down
2 changes: 2 additions & 0 deletions ui/core/individual_sim_ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export interface OtherDefaults {
profession2?: Profession,
distanceFromTarget?: number,
channelClipDelay?: number,
nibelungAverageCasts?: number,
}

export interface IndividualSimUIConfig<SpecType extends Spec> {
Expand Down Expand Up @@ -428,6 +429,7 @@ export abstract class IndividualSimUI<SpecType extends Spec> extends SimUI {
this.player.setProfession2(eventID, this.individualConfig.defaults.other?.profession2 || Profession.Jewelcrafting);
this.player.setDistanceFromTarget(eventID, this.individualConfig.defaults.other?.distanceFromTarget || 0);
this.player.setChannelClipDelay(eventID, this.individualConfig.defaults.other?.channelClipDelay || 0);
this.player.setNibelungAverageCasts(eventID, this.individualConfig.defaults.other?.nibelungAverageCasts || 11);

if (this.isWithinRaidSim) {
this.sim.raid.setTargetDummies(eventID, 0);
Expand Down
16 changes: 16 additions & 0 deletions ui/core/player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ export class Player<SpecType extends Spec> {
private channelClipDelay: number = 0;
private inFrontOfTarget: boolean = false;
private distanceFromTarget: number = 0;
private nibelungAverageCasts: number = 11;
private healingModel: HealingModel = HealingModel.create();
private healingEnabled: boolean = false;

Expand Down Expand Up @@ -935,6 +936,19 @@ export class Player<SpecType extends Spec> {
this.distanceFromTarget = newDistanceFromTarget;
this.distanceFromTargetChangeEmitter.emit(eventID);
}

getNibelungAverageCasts(): number {
return this.nibelungAverageCasts;
}

setNibelungAverageCasts(eventID: EventID, newnibelungAverageCasts: number) {
if (newnibelungAverageCasts == this.nibelungAverageCasts)
return;

this.nibelungAverageCasts = Math.min(newnibelungAverageCasts, 16);
this.miscOptionsChangeEmitter.emit(eventID);
}

setDefaultHealingParams(hm: HealingModel) {
var boss = this.sim.encounter.primaryTarget;
var dualWield = boss.dualWield;
Expand Down Expand Up @@ -1324,6 +1338,7 @@ export class Player<SpecType extends Spec> {
distanceFromTarget: this.getDistanceFromTarget(),
healingModel: this.getHealingModel(),
database: forExport ? SimDatabase.create() : this.toDatabase(),
nibelungAverageCasts: this.getNibelungAverageCasts(),
}),
(aplIsLaunched || (forSimming && aplRotation.type == APLRotationType.TypeAPL))
? this.specTypeFunctions.rotationCreate()
Expand Down Expand Up @@ -1384,6 +1399,7 @@ export class Player<SpecType extends Spec> {
this.setChannelClipDelay(eventID, proto.channelClipDelayMs);
this.setInFrontOfTarget(eventID, proto.inFrontOfTarget);
this.setDistanceFromTarget(eventID, proto.distanceFromTarget);
this.setNibelungAverageCasts(eventID, proto.nibelungAverageCasts);
this.setHealingModel(eventID, proto.healingModel || HealingModel.create());
this.setSpecOptions(eventID, this.specTypeFunctions.optionsFromPlayer(proto));

Expand Down
4 changes: 4 additions & 0 deletions ui/core/proto_utils/equipped_item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ export class EquippedItem {
return Item.clone(this._item);
}

get id(): number {
return this._item.id;
}

get enchant(): Enchant | null {
// Make a defensive copy
return this._enchant ? Enchant.clone(this._enchant) : null;
Expand Down
1 change: 1 addition & 0 deletions ui/elemental_shaman/presets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ export const OtherDefaults = {
distanceFromTarget: 20,
profession1: Profession.Engineering,
profession2: Profession.Tailoring,
nibelungAverageCasts: 11,
}

export const DefaultConsumes = Consumes.create({
Expand Down
1 change: 1 addition & 0 deletions ui/elemental_shaman/sim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ export class ElementalShamanSimUI extends IndividualSimUI<Spec.SpecElementalSham
inputs: [
ShamanInputs.InThunderstormRange,
OtherInputs.TankAssignment,
OtherInputs.nibelungAverageCasts,
],
},
customSections: [
Expand Down
1 change: 1 addition & 0 deletions ui/mage/presets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,4 +227,5 @@ export const OtherDefaults = {
distanceFromTarget: 20,
profession1: Profession.Engineering,
profession2: Profession.Tailoring,
nibelungAverageCasts: 11,
};
1 change: 1 addition & 0 deletions ui/mage/sim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ export class MageSimUI extends IndividualSimUI<Spec.SpecMage> {
OtherInputs.ReactionTime,
OtherInputs.DistanceFromTarget,
OtherInputs.TankAssignment,
OtherInputs.nibelungAverageCasts,
],
},
encounterPicker: {
Expand Down
1 change: 1 addition & 0 deletions ui/shadow_priest/presets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,5 @@ export const OtherDefaults = {
channelClipDelay: 100,
profession1: Profession.Engineering,
profession2: Profession.Tailoring,
nibelungAverageCasts: 11,
};
1 change: 1 addition & 0 deletions ui/shadow_priest/sim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ export class ShadowPriestSimUI extends IndividualSimUI<Spec.SpecShadowPriest> {
inputs: [
OtherInputs.TankAssignment,
OtherInputs.ChannelClipDelay,
OtherInputs.nibelungAverageCasts,
],
},
encounterPicker: {
Expand Down
1 change: 1 addition & 0 deletions ui/warlock/presets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,5 @@ export const OtherDefaults = {
profession1: Profession.Engineering,
profession2: Profession.Tailoring,
channelClipDelay: 150,
nibelungAverageCasts: 11,
};
1 change: 1 addition & 0 deletions ui/warlock/sim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export class WarlockSimUI extends IndividualSimUI<Spec.SpecWarlock> {
OtherInputs.DistanceFromTarget,
OtherInputs.TankAssignment,
OtherInputs.ChannelClipDelay,
OtherInputs.nibelungAverageCasts,
WarlockInputs.NewDPBehaviour,
],
},
Expand Down

0 comments on commit 0921081

Please sign in to comment.