Skip to content

Commit

Permalink
Multidot implemented for APL
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmyt857 committed Jul 7, 2023
1 parent a70e9c1 commit aeae39a
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 23 deletions.
3 changes: 2 additions & 1 deletion proto/apl.proto
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ message APLActionCastSpell {

message APLActionMultidot {
ActionID spell_id = 1;
int32 max_dots = 2;
int32 max_dots = 2;
APLValue max_overlap = 3;
}

message APLActionAutocastOtherCooldowns {
Expand Down
32 changes: 15 additions & 17 deletions sim/core/apl_actions_core.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package core

import (
"time"

"github.com/wowsims/wotlk/sim/core/proto"
)

Expand Down Expand Up @@ -31,25 +29,24 @@ func (action *APLActionCastSpell) Execute(sim *Simulation) {
}

type APLActionMultidot struct {
spell *Spell
maxDots int32
refreshWindow time.Duration
spell *Spell
maxDots int32
maxOverlap APLValue

nextTarget *Unit
}

func (unit *Unit) newActionMultidot(config *proto.APLActionMultidot) APLActionImpl {
spell := unit.aplGetMultidotSpell(config.SpellId)

refreshWindow := time.Duration(0)
canRollover := false
if canRollover {
refreshWindow = time.Second*3
maxOverlap := unit.coerceTo(unit.newAPLValue(config.MaxOverlap), proto.APLValueType_ValueTypeDuration)
if maxOverlap == nil {
maxOverlap = unit.newValueConst(&proto.APLValueConst{Val: "0ms"})
}

return &APLActionMultidot{
spell: spell,
maxDots: MinInt32(config.MaxDots, unit.Env.GetNumTargets()),
refreshWindow: refreshWindow,
spell: spell,
maxDots: MinInt32(config.MaxDots, unit.Env.GetNumTargets()),
maxOverlap: maxOverlap,
}
}
func (action *APLActionMultidot) GetInnerActions() []*APLAction { return nil }
Expand All @@ -58,11 +55,12 @@ func (action *APLActionMultidot) Reset(*Simulation) {
action.nextTarget = nil
}
func (action *APLActionMultidot) IsReady(sim *Simulation) bool {
for i := 0; i < action.maxDots; i++ {
target := sim.Encounter.GetTarget(i)
maxOverlap := action.maxOverlap.GetDuration(sim)

for i := int32(0); i < action.maxDots; i++ {
target := sim.Encounter.TargetUnits[i]
dot := action.spell.Dot(target)
shouldPreserveSnapshot := dot.
if dot.IsActive() && dot.RemainingDuration(sim) < time.Second*3 {
if (!dot.IsActive() || dot.RemainingDuration(sim) < maxOverlap) && action.spell.CanCast(sim, target) {
action.nextTarget = target
return true
}
Expand Down
38 changes: 37 additions & 1 deletion ui/core/components/individual_sim_ui/apl_actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
APLActionSequence,
APLActionResetSequence,
APLActionStrictSequence,
APLActionMultidot,
APLActionAutocastOtherCooldowns,
APLActionWait,
APLValue,
Expand Down Expand Up @@ -261,6 +262,32 @@ export const actionTypeFactories: Record<NonNullable<APLActionType>, ActionTypeC
actionListFieldConfig('actions'),
],
}),
['multidot']: inputBuilder({
label: 'Multi Dot',
shortDescription: 'Keeps a DoT active on multiple targets by casting the specified spell.',
newValue: () => APLActionMultidot.create({
maxDots: 3,
maxOverlap: {
value: {
oneofKind: 'const',
const: {
val: '0ms',
},
},
},
}),
fields: [
AplHelpers.actionIdFieldConfig('spellId', 'dot_spells'),
AplHelpers.numberFieldConfig('maxDots', {
label: 'Max Dots',
labelTooltip: 'Maximum number of DoTs to simultaneously apply.',
}),
AplValues.valueFieldConfig('maxOverlap', {
label: 'Overlap',
labelTooltip: 'Maximum amount of time before a DoT expires when it may be refreshed.',
}),
],
}),
['autocastOtherCooldowns']: inputBuilder({
label: 'Autocast Other Cooldowns',
submenu: ['Misc'],
Expand All @@ -278,7 +305,16 @@ export const actionTypeFactories: Record<NonNullable<APLActionType>, ActionTypeC
label: 'Wait',
submenu: ['Misc'],
shortDescription: 'Pauses the GCD for a specified amount of time.',
newValue: APLActionWait.create,
newValue: () => APLActionWait.create({
duration: {
value: {
oneofKind: 'const',
const: {
val: '1000ms',
},
},
},
}),
fields: [
AplValues.valueFieldConfig('duration'),
],
Expand Down
22 changes: 20 additions & 2 deletions ui/core/components/individual_sim_ui/apl_helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Player } from '../../player.js';
import { EventID, TypedEvent } from '../../typed_event.js';
import { bucket } from '../../utils.js';
import { AdaptiveStringPicker } from '../string_picker.js';
import { NumberPicker } from '../number_picker.js';
import { DropdownPicker, DropdownPickerConfig, DropdownValueConfig, TextDropdownPicker } from '../dropdown_picker.js';
import { Input, InputConfig } from '../input.js';
import { ActionID } from '../../proto/common.js';
Expand Down Expand Up @@ -118,6 +119,9 @@ export interface APLPickerBuilderFieldConfig<T, F extends keyof T> {
field: F,
newValue: () => T[F],
factory: (parent: HTMLElement, player: Player<any>, config: InputConfig<Player<any>, T[F]>) => Input<Player<any>, T[F]>

label?: string,
labelTooltip?: string,
}

export interface APLPickerBuilderConfig<T> extends InputConfig<Player<any>, T> {
Expand Down Expand Up @@ -155,6 +159,9 @@ export class APLPickerBuilder<T> extends Input<Player<any>, T> {
return {
...fieldConfig,
picker: fieldConfig.factory(builder.rootElem, builder.modObject, {
label: fieldConfig.label,
labelTooltip: fieldConfig.labelTooltip,
inline: true,
changedEvent: (player: Player<any>) => player.rotationChangeEmitter,
getValue: () => {
const source = builder.getSourceValue();
Expand Down Expand Up @@ -190,22 +197,33 @@ export class APLPickerBuilder<T> extends Input<Player<any>, T> {
}
}

export function actionIdFieldConfig(field: string, actionIdSet: ACTION_ID_SET): APLPickerBuilderFieldConfig<any, any> {
export function actionIdFieldConfig(field: string, actionIdSet: ACTION_ID_SET, options?: Partial<APLPickerBuilderFieldConfig<any, any>>): APLPickerBuilderFieldConfig<any, any> {
return {
field: field,
newValue: () => ActionID.create(),
factory: (parent, player, config) => new APLActionIDPicker(parent, player, {
...config,
actionIdSet: actionIdSet,
}),
...(options || {}),
};
}

export function numberFieldConfig(field: string, options?: Partial<APLPickerBuilderFieldConfig<any, any>>): APLPickerBuilderFieldConfig<any, any> {
return {
field: field,
newValue: () => 0,
factory: (parent, player, config) => new NumberPicker(parent, player, config),
...(options || {}),
};
}

export function stringFieldConfig(field: string): APLPickerBuilderFieldConfig<any, any> {
export function stringFieldConfig(field: string, options?: Partial<APLPickerBuilderFieldConfig<any, any>>): APLPickerBuilderFieldConfig<any, any> {
return {
field: field,
newValue: () => '',
factory: (parent, player, config) => new AdaptiveStringPicker(parent, player, config),
...(options || {}),
};
}

Expand Down
3 changes: 2 additions & 1 deletion ui/core/components/individual_sim_ui/apl_values.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,12 @@ function comparisonOperatorFieldConfig(field: string): AplHelpers.APLPickerBuild
};
}

export function valueFieldConfig(field: string): AplHelpers.APLPickerBuilderFieldConfig<any, any> {
export function valueFieldConfig(field: string, options?: Partial<AplHelpers.APLPickerBuilderFieldConfig<any, any>>): AplHelpers.APLPickerBuilderFieldConfig<any, any> {
return {
field: field,
newValue: APLValue.create,
factory: (parent, player, config) => new APLValuePicker(parent, player, config),
...(options || {}),
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,19 @@
flex-direction: column;
}

.apl-picker-builder-root {
.form-label {
margin: 0 1px 0 5px;
}
}

.apl-value-picker-root {
* {
font-size: calc(var(--bs-btn-font-size) - 0.2rem);
}

.form-label {
margin: 0;
margin: 0 1px 0 5px;
}
}

Expand Down

0 comments on commit aeae39a

Please sign in to comment.