diff --git a/proto/api.proto b/proto/api.proto index 199873c585..82afc071cd 100644 --- a/proto/api.proto +++ b/proto/api.proto @@ -94,7 +94,7 @@ message Raid { Debuffs debuffs = 5; // Players who will be tanking mobs. - repeated RaidTarget tanks = 4; + repeated UnitReference tanks = 4; // Staggers Stormstrike casts across Enhance Shaman to maximize charge usage. bool stagger_stormstrikes = 3; @@ -364,7 +364,7 @@ message StatWeightsRequest { Debuffs debuffs = 9; Encounter encounter = 4; SimOptions sim_options = 5; - repeated RaidTarget tanks = 8; + repeated UnitReference tanks = 8; repeated Stat stats_to_weigh = 6; repeated PseudoStat pseudo_stats_to_weigh = 10; diff --git a/proto/common.proto b/proto/common.proto index 5cc8d8428e..8abf1d7f06 100644 --- a/proto/common.proto +++ b/proto/common.proto @@ -758,9 +758,26 @@ message SimGem { repeated double stats = 4; } -message RaidTarget { +message UnitReference { + enum Type { + Unknown = 0; + Player = 1; + Target = 2; + Pet = 3; + } + + // The type of unit being referenced. + Type type = 2; + + // Index of the player/target/pet/etc depending on value of type. + int32 index = 3; + + // Reference to the owner, only used iff this is a pet. + UnitReference owner = 4; + // Raid index of the player to target. A value of -1 indicates no target. - int32 target_index = 1; + // TODO: Delete this after 2 months (on or after 9/19/2023) + int32 target_index = 1 [deprecated = true]; } // ID for actions that aren't spells or items. diff --git a/proto/deathknight.proto b/proto/deathknight.proto index d6438189ae..689f877ac2 100644 --- a/proto/deathknight.proto +++ b/proto/deathknight.proto @@ -281,7 +281,7 @@ message Deathknight { bool precast_ghoul_frenzy = 3; bool precast_horn_of_winter = 4; - RaidTarget unholy_frenzy_target = 5; + UnitReference unholy_frenzy_target = 5; bool drw_pesti_apply = 6; @@ -332,7 +332,7 @@ message TankDeathknight { message Options { double starting_runic_power = 1; - RaidTarget unholy_frenzy_target = 2; + UnitReference unholy_frenzy_target = 2; double defensive_delay = 3; } Options options = 3; diff --git a/proto/druid.proto b/proto/druid.proto index f78bdb3192..34e00e34bf 100644 --- a/proto/druid.proto +++ b/proto/druid.proto @@ -206,7 +206,7 @@ message BalanceDruid { Rotation rotation = 1; message Options { - RaidTarget innervate_target = 1; + UnitReference innervate_target = 1; } Options options = 3; } @@ -254,7 +254,7 @@ message FeralDruid { Rotation rotation = 1; message Options { - RaidTarget innervate_target = 1; + UnitReference innervate_target = 1; int32 latency_ms = 2; bool assume_bleed_active = 4; } @@ -271,7 +271,7 @@ message FeralTankDruid { Rotation rotation = 1; message Options { - RaidTarget innervate_target = 1; + UnitReference innervate_target = 1; double starting_rage = 2; } Options options = 3; @@ -283,7 +283,7 @@ message RestorationDruid { Rotation rotation = 1; message Options { - RaidTarget innervate_target = 1; + UnitReference innervate_target = 1; } Options options = 3; } diff --git a/proto/mage.proto b/proto/mage.proto index 18319d6963..1d5ba495e8 100644 --- a/proto/mage.proto +++ b/proto/mage.proto @@ -201,7 +201,7 @@ message Mage { // Number of Evocation ticks to use. If 0, use all of them. int32 evocation_ticks = 2; int32 focus_magic_percent_uptime = 3; - RaidTarget focus_magic_target = 4; + UnitReference focus_magic_target = 4; int32 reaction_time_ms = 5; } Options options = 3; diff --git a/proto/priest.proto b/proto/priest.proto index 0cf2d5dc32..75115170a6 100644 --- a/proto/priest.proto +++ b/proto/priest.proto @@ -166,7 +166,7 @@ message ShadowPriest { Armor armor = 2; bool use_mind_blast = 4; bool use_shadow_word_death = 5; - RaidTarget power_infusion_target = 6; + UnitReference power_infusion_target = 6; } Options options = 3; } @@ -184,7 +184,7 @@ message SmitePriest { message Options { bool use_inner_fire = 3; bool use_shadowfiend = 1; - RaidTarget power_infusion_target = 2; + UnitReference power_infusion_target = 2; } Options options = 3; } @@ -217,7 +217,7 @@ message HealingPriest { message Options { bool use_inner_fire = 3; bool use_shadowfiend = 1; - RaidTarget power_infusion_target = 2; + UnitReference power_infusion_target = 2; // Number of times for rapture to proc each minute, ie when a PWS is fully absorbed. double raptures_per_minute = 4; diff --git a/proto/rogue.proto b/proto/rogue.proto index 1fcbd0f4e6..6147dcf3ab 100644 --- a/proto/rogue.proto +++ b/proto/rogue.proto @@ -208,7 +208,7 @@ message Rogue { Rotation rotation = 1; message Options { - RaidTarget tricks_of_the_trade_target = 1; + UnitReference tricks_of_the_trade_target = 1; enum PoisonImbue { NoPoison = 0; InstantPoison = 1; diff --git a/proto/ui.proto b/proto/ui.proto index 179ddeeab4..be077674de 100644 --- a/proto/ui.proto +++ b/proto/ui.proto @@ -255,7 +255,7 @@ message IndividualSimSettings { SimSettings settings = 5; RaidBuffs raid_buffs = 1; Debuffs debuffs = 8; - repeated RaidTarget tanks = 7; + repeated UnitReference tanks = 7; PartyBuffs party_buffs = 2; Player player = 3; Encounter encounter = 4; diff --git a/sim/core/environment.go b/sim/core/environment.go index d4f4237f13..ad5a6f0225 100644 --- a/sim/core/environment.go +++ b/sim/core/environment.go @@ -98,7 +98,7 @@ func (env *Environment) construct(raidProto *proto.Raid, encounterProto *proto.E if targetProto.TankIndex >= 0 && targetProto.TankIndex < int32(len(raidProto.Tanks)) { raidTargetProto := raidProto.Tanks[targetProto.TankIndex] if raidTargetProto != nil { - raidTarget := env.Raid.GetPlayerFromRaidTarget(raidTargetProto) + raidTarget := env.Raid.GetPlayerFromUnitReference(raidTargetProto) if raidTarget != nil { target.CurrentTarget = &raidTarget.GetCharacter().Unit } diff --git a/sim/core/raid.go b/sim/core/raid.go index 5b7446b86a..4a502b284f 100644 --- a/sim/core/raid.go +++ b/sim/core/raid.go @@ -377,21 +377,23 @@ func (raid Raid) GetPlayerFromUnit(unit *Unit) Agent { return nil } -func (raid Raid) GetPlayerFromRaidTarget(raidTarget *proto.RaidTarget) Agent { - if raidTarget == nil { +func (raid Raid) GetPlayerFromUnitReference(ref *proto.UnitReference) Agent { + if ref == nil { return nil } - raidIndex := raidTarget.TargetIndex - partyIndex := int(raidIndex / 5) - if partyIndex < 0 || partyIndex >= len(raid.Parties) { - return nil - } + if ref.Type == proto.UnitReference_Player { + raidIndex := ref.Index + partyIndex := int(raidIndex / 5) + if partyIndex < 0 || partyIndex >= len(raid.Parties) { + return nil + } - party := raid.Parties[partyIndex] - for _, player := range party.Players { - if player.GetCharacter().Index == raidIndex { - return player + party := raid.Parties[partyIndex] + for _, player := range party.Players { + if player.GetCharacter().Index == raidIndex { + return player + } } } diff --git a/sim/core/test_generators.go b/sim/core/test_generators.go index 47df7e892c..d76289ce90 100644 --- a/sim/core/test_generators.go +++ b/sim/core/test_generators.go @@ -509,7 +509,7 @@ func FullCharacterTestSuiteGenerator(config CharacterSuiteConfig) TestGenerator defaultRaid := SinglePlayerRaidProto(defaultPlayer, FullPartyBuffs, FullRaidBuffs, FullDebuffs) if config.IsTank { - defaultRaid.Tanks = append(defaultRaid.Tanks, &proto.RaidTarget{TargetIndex: 0}) + defaultRaid.Tanks = append(defaultRaid.Tanks, &proto.UnitReference{Type: proto.UnitReference_Player, Index: 0}) } if config.IsHealer { defaultRaid.TargetDummies = 1 diff --git a/sim/deathknight/deathknight.go b/sim/deathknight/deathknight.go index 568104b708..ad0eb86c3c 100644 --- a/sim/deathknight/deathknight.go +++ b/sim/deathknight/deathknight.go @@ -24,7 +24,7 @@ type DeathknightInputs struct { IsDps bool NewDrw bool - UnholyFrenzyTarget *proto.RaidTarget + UnholyFrenzyTarget *proto.UnitReference StartingRunicPower float64 PrecastGhoulFrenzy bool diff --git a/sim/deathknight/dps/dps_deathknight_test.go b/sim/deathknight/dps/dps_deathknight_test.go index 447b4d97c5..82f5ab020d 100644 --- a/sim/deathknight/dps/dps_deathknight_test.go +++ b/sim/deathknight/dps/dps_deathknight_test.go @@ -215,7 +215,7 @@ var frostDesyncRotation = &proto.Deathknight_Rotation{ } var deathKnightOptions = &proto.Deathknight_Options{ - UnholyFrenzyTarget: &proto.RaidTarget{TargetIndex: 0}, + UnholyFrenzyTarget: &proto.UnitReference{Type: proto.UnitReference_Player, Index: 0}, DrwPestiApply: true, StartingRunicPower: 0, PetUptime: 1, diff --git a/sim/deathknight/unholy_frenzy.go b/sim/deathknight/unholy_frenzy.go index da5ff52035..771b853504 100644 --- a/sim/deathknight/unholy_frenzy.go +++ b/sim/deathknight/unholy_frenzy.go @@ -17,7 +17,7 @@ func (dk *Deathknight) registerUnholyFrenzyCD() { unholyFrenzyTarget = &dk.Character } - unholyFrenzyTargetAgent := dk.Party.Raid.GetPlayerFromRaidTarget(dk.Inputs.UnholyFrenzyTarget) + unholyFrenzyTargetAgent := dk.Party.Raid.GetPlayerFromUnitReference(dk.Inputs.UnholyFrenzyTarget) if unholyFrenzyTargetAgent != nil { unholyFrenzyTarget = unholyFrenzyTargetAgent.GetCharacter() } diff --git a/sim/druid/balance/balance.go b/sim/druid/balance/balance.go index 8c2c9e2a72..19f7d38443 100644 --- a/sim/druid/balance/balance.go +++ b/sim/druid/balance/balance.go @@ -33,7 +33,7 @@ func NewBalanceDruid(character core.Character, options *proto.Player) *BalanceDr Rotation: balanceOptions.Rotation, } - moonkin.SelfBuffs.InnervateTarget = &proto.RaidTarget{TargetIndex: -1} + moonkin.SelfBuffs.InnervateTarget = &proto.UnitReference{} if balanceOptions.Options.InnervateTarget != nil { moonkin.SelfBuffs.InnervateTarget = balanceOptions.Options.InnervateTarget } diff --git a/sim/druid/druid.go b/sim/druid/druid.go index cf00f18541..492003be47 100644 --- a/sim/druid/druid.go +++ b/sim/druid/druid.go @@ -109,7 +109,7 @@ type Druid struct { } type SelfBuffs struct { - InnervateTarget *proto.RaidTarget + InnervateTarget *proto.UnitReference } func (druid *Druid) GetCharacter() *core.Character { diff --git a/sim/druid/feral/feral.go b/sim/druid/feral/feral.go index 03532ffe7e..f37ddead48 100644 --- a/sim/druid/feral/feral.go +++ b/sim/druid/feral/feral.go @@ -34,7 +34,7 @@ func NewFeralDruid(character core.Character, options *proto.Player) *FeralDruid latency: time.Duration(core.MaxInt32(feralOptions.Options.LatencyMs, 1)) * time.Millisecond, } - cat.SelfBuffs.InnervateTarget = &proto.RaidTarget{TargetIndex: -1} + cat.SelfBuffs.InnervateTarget = &proto.UnitReference{} if feralOptions.Options.InnervateTarget != nil { cat.SelfBuffs.InnervateTarget = feralOptions.Options.InnervateTarget } diff --git a/sim/druid/feral/feral_test.go b/sim/druid/feral/feral_test.go index 7c3fd4f659..780cb0b067 100644 --- a/sim/druid/feral/feral_test.go +++ b/sim/druid/feral/feral_test.go @@ -148,7 +148,7 @@ var StandardGlyphs = &proto.Glyphs{ var PlayerOptionsMonoCat = &proto.Player_FeralDruid{ FeralDruid: &proto.FeralDruid{ Options: &proto.FeralDruid_Options{ - InnervateTarget: &proto.RaidTarget{TargetIndex: -1}, // no Innervate + InnervateTarget: &proto.UnitReference{}, // no Innervate LatencyMs: 100, AssumeBleedActive: true, }, @@ -177,7 +177,7 @@ var PlayerOptionsMonoCat = &proto.Player_FeralDruid{ var PlayerOptionsMonoCatNoBleed = &proto.Player_FeralDruid{ FeralDruid: &proto.FeralDruid{ Options: &proto.FeralDruid_Options{ - InnervateTarget: &proto.RaidTarget{TargetIndex: -1}, // no Innervate + InnervateTarget: &proto.UnitReference{}, // no Innervate LatencyMs: 100, AssumeBleedActive: false, }, @@ -206,7 +206,7 @@ var PlayerOptionsMonoCatNoBleed = &proto.Player_FeralDruid{ var PlayerOptionsFlowerCatAoe = &proto.Player_FeralDruid{ FeralDruid: &proto.FeralDruid{ Options: &proto.FeralDruid_Options{ - InnervateTarget: &proto.RaidTarget{TargetIndex: -1}, // no Innervate + InnervateTarget: &proto.UnitReference{}, // no Innervate LatencyMs: 100, AssumeBleedActive: false, }, diff --git a/sim/druid/innervate.go b/sim/druid/innervate.go index 7d67ea6140..0a80e48a3d 100644 --- a/sim/druid/innervate.go +++ b/sim/druid/innervate.go @@ -7,7 +7,7 @@ import ( // Returns the time to wait before the next action, or 0 if innervate is on CD // or disabled. func (druid *Druid) registerInnervateCD() { - innervateTargetAgent := druid.Party.Raid.GetPlayerFromRaidTarget(druid.SelfBuffs.InnervateTarget) + innervateTargetAgent := druid.Party.Raid.GetPlayerFromUnitReference(druid.SelfBuffs.InnervateTarget) if innervateTargetAgent == nil { return } diff --git a/sim/druid/restoration/restoration.go b/sim/druid/restoration/restoration.go index f635e74c85..98841723eb 100644 --- a/sim/druid/restoration/restoration.go +++ b/sim/druid/restoration/restoration.go @@ -32,7 +32,7 @@ func NewRestorationDruid(character core.Character, options *proto.Player) *Resto Rotation: restoOptions.Rotation, } - resto.SelfBuffs.InnervateTarget = &proto.RaidTarget{TargetIndex: -1} + resto.SelfBuffs.InnervateTarget = &proto.UnitReference{} if restoOptions.Options.InnervateTarget != nil { resto.SelfBuffs.InnervateTarget = restoOptions.Options.InnervateTarget } diff --git a/sim/druid/restoration/restoration_test.go b/sim/druid/restoration/restoration_test.go index c5dab2d644..cb5639eaa1 100644 --- a/sim/druid/restoration/restoration_test.go +++ b/sim/druid/restoration/restoration_test.go @@ -57,7 +57,7 @@ var FullConsumes = &proto.Consumes{ var PlayerOptionsStandard = &proto.Player_RestorationDruid{ RestorationDruid: &proto.RestorationDruid{ Options: &proto.RestorationDruid_Options{ - InnervateTarget: &proto.RaidTarget{TargetIndex: 0}, // self innervate + InnervateTarget: &proto.UnitReference{Type: proto.UnitReference_Player, Index: 0}, // self innervate }, Rotation: &proto.RestorationDruid_Rotation{}, }, diff --git a/sim/druid/tank/tank.go b/sim/druid/tank/tank.go index d8a86fb5e8..0646a23dbb 100644 --- a/sim/druid/tank/tank.go +++ b/sim/druid/tank/tank.go @@ -33,7 +33,7 @@ func NewFeralTankDruid(character core.Character, options *proto.Player) *FeralTa Options: tankOptions.Options, } - bear.SelfBuffs.InnervateTarget = &proto.RaidTarget{TargetIndex: -1} + bear.SelfBuffs.InnervateTarget = &proto.UnitReference{} if tankOptions.Options.InnervateTarget != nil { bear.SelfBuffs.InnervateTarget = tankOptions.Options.InnervateTarget } diff --git a/sim/druid/tank/tank_test.go b/sim/druid/tank/tank_test.go index 7e013976c9..3fbf643bc5 100644 --- a/sim/druid/tank/tank_test.go +++ b/sim/druid/tank/tank_test.go @@ -79,7 +79,7 @@ var StandardGlyphs = &proto.Glyphs{ var PlayerOptionsDefault = &proto.Player_FeralTankDruid{ FeralTankDruid: &proto.FeralTankDruid{ Options: &proto.FeralTankDruid_Options{ - InnervateTarget: &proto.RaidTarget{TargetIndex: -1}, // no Innervate + InnervateTarget: &proto.UnitReference{}, // no Innervate StartingRage: 20, }, Rotation: &proto.FeralTankDruid_Rotation{ diff --git a/sim/mage/focus_magic.go b/sim/mage/focus_magic.go index b7a44262d8..4aac78b819 100644 --- a/sim/mage/focus_magic.go +++ b/sim/mage/focus_magic.go @@ -20,7 +20,7 @@ func (mage *Mage) applyFocusMagic() { return } - focusMagicTargetAgent := mage.Party.Raid.GetPlayerFromRaidTarget(mage.Options.FocusMagicTarget) + focusMagicTargetAgent := mage.Party.Raid.GetPlayerFromUnitReference(mage.Options.FocusMagicTarget) if focusMagicTargetAgent == nil { return } else if focusMagicTargetAgent.GetCharacter() == mage.GetCharacter() { diff --git a/sim/priest/healing/healing_priest.go b/sim/priest/healing/healing_priest.go index 4495b8f6b9..f1e43ff1b4 100644 --- a/sim/priest/healing/healing_priest.go +++ b/sim/priest/healing/healing_priest.go @@ -51,7 +51,7 @@ func NewHealingPriest(character core.Character, options *proto.Player) *HealingP Options: healingOptions.Options, } - hpriest.SelfBuffs.PowerInfusionTarget = &proto.RaidTarget{TargetIndex: -1} + hpriest.SelfBuffs.PowerInfusionTarget = &proto.UnitReference{} if hpriest.Talents.PowerInfusion && hpriest.Options.PowerInfusionTarget != nil { hpriest.SelfBuffs.PowerInfusionTarget = hpriest.Options.PowerInfusionTarget } diff --git a/sim/priest/power_infusion.go b/sim/priest/power_infusion.go index 83a4dc7d20..e073894b63 100644 --- a/sim/priest/power_infusion.go +++ b/sim/priest/power_infusion.go @@ -13,7 +13,7 @@ func (priest *Priest) registerPowerInfusionCD() { actionID := core.ActionID{SpellID: 10060, Tag: priest.Index} - powerInfusionTargetAgent := priest.Party.Raid.GetPlayerFromRaidTarget(priest.SelfBuffs.PowerInfusionTarget) + powerInfusionTargetAgent := priest.Party.Raid.GetPlayerFromUnitReference(priest.SelfBuffs.PowerInfusionTarget) if powerInfusionTargetAgent == nil { return } diff --git a/sim/priest/priest.go b/sim/priest/priest.go index ca933766d6..90e0fff7b4 100644 --- a/sim/priest/priest.go +++ b/sim/priest/priest.go @@ -88,7 +88,7 @@ type SelfBuffs struct { UseShadowfiend bool UseInnerFire bool - PowerInfusionTarget *proto.RaidTarget + PowerInfusionTarget *proto.UnitReference } func (priest *Priest) GetCharacter() *core.Character { diff --git a/sim/priest/shadow/shadow_priest.go b/sim/priest/shadow/shadow_priest.go index 3cebcb8e6e..e2665ae0c2 100644 --- a/sim/priest/shadow/shadow_priest.go +++ b/sim/priest/shadow/shadow_priest.go @@ -41,7 +41,7 @@ func NewShadowPriest(character core.Character, options *proto.Player) *ShadowPri options: shadowOptions.Options, } - spriest.SelfBuffs.PowerInfusionTarget = &proto.RaidTarget{TargetIndex: -1} + spriest.SelfBuffs.PowerInfusionTarget = &proto.UnitReference{} if spriest.Talents.PowerInfusion && shadowOptions.Options.PowerInfusionTarget != nil { spriest.SelfBuffs.PowerInfusionTarget = shadowOptions.Options.PowerInfusionTarget } diff --git a/sim/priest/smite/smite_priest.go b/sim/priest/smite/smite_priest.go index 1631ed34d8..bb08670cea 100644 --- a/sim/priest/smite/smite_priest.go +++ b/sim/priest/smite/smite_priest.go @@ -41,7 +41,7 @@ func NewSmitePriest(character core.Character, options *proto.Player) *SmitePries allowedHFDelay: time.Millisecond * time.Duration(smiteOptions.Rotation.AllowedHolyFireDelayMs), } - spriest.SelfBuffs.PowerInfusionTarget = &proto.RaidTarget{TargetIndex: -1} + spriest.SelfBuffs.PowerInfusionTarget = &proto.UnitReference{} if spriest.Talents.PowerInfusion && smiteOptions.Options.PowerInfusionTarget != nil { spriest.SelfBuffs.PowerInfusionTarget = smiteOptions.Options.PowerInfusionTarget } diff --git a/sim/raid_bench_test.go b/sim/raid_bench_test.go index 75b71d313f..65280c0ce2 100644 --- a/sim/raid_bench_test.go +++ b/sim/raid_bench_test.go @@ -22,9 +22,7 @@ var castersWithElemental = &proto.Party{ Type: proto.BalanceDruid_Rotation_Default, }, Options: &proto.BalanceDruid_Options{ - InnervateTarget: &proto.RaidTarget{ - TargetIndex: 0, - }, + InnervateTarget: &proto.UnitReference{}, }, }, }, @@ -128,8 +126,9 @@ var castersWithResto = &proto.Party{ Type: proto.BalanceDruid_Rotation_Default, }, Options: &proto.BalanceDruid_Options{ - InnervateTarget: &proto.RaidTarget{ - TargetIndex: 6, + InnervateTarget: &proto.UnitReference{ + Type: proto.UnitReference_Player, + Index: 6, }, }, }, diff --git a/sim/rogue/tricks_of_the_trade.go b/sim/rogue/tricks_of_the_trade.go index debaf88873..783a69454b 100644 --- a/sim/rogue/tricks_of_the_trade.go +++ b/sim/rogue/tricks_of_the_trade.go @@ -15,7 +15,7 @@ func (rogue *Rogue) registerTricksOfTheTradeSpell() { hasGlyph := rogue.HasMajorGlyph(proto.RogueMajorGlyph_GlyphOfTricksOfTheTrade) if rogue.Options.TricksOfTheTradeTarget != nil { - targetAgent := rogue.Env.Raid.GetPlayerFromRaidTarget(rogue.Options.TricksOfTheTradeTarget) + targetAgent := rogue.Env.Raid.GetPlayerFromUnitReference(rogue.Options.TricksOfTheTradeTarget) if targetAgent != nil { target := targetAgent.GetCharacter() rogue.TricksOfTheTradeAura = core.TricksOfTheTradeAura(target, rogue.Index, hasGlyph) diff --git a/ui/balance_druid/inputs.ts b/ui/balance_druid/inputs.ts index 55e0ed96a6..8883250be8 100644 --- a/ui/balance_druid/inputs.ts +++ b/ui/balance_druid/inputs.ts @@ -1,6 +1,5 @@ -import { RaidTarget } from '../core/proto/common.js'; +import { UnitReference, UnitReference_Type as UnitType } from '../core/proto/common.js'; import { Spec } from '../core/proto/common.js'; -import { NO_TARGET } from '../core/proto_utils/utils.js'; import { ActionId } from '../core/proto_utils/action_id.js'; import { Player } from '../core/player.js'; import { EventID, TypedEvent } from '../core/typed_event.js'; @@ -27,11 +26,12 @@ export const SelfInnervate = InputHelpers.makeSpecOptionsBooleanIconInput) => player.getSpecOptions().innervateTarget?.targetIndex != NO_TARGET, + getValue: (player: Player) => player.getSpecOptions().innervateTarget?.type == UnitType.Player, setValue: (eventID: EventID, player: Player, newValue: boolean) => { const newOptions = player.getSpecOptions(); - newOptions.innervateTarget = RaidTarget.create({ - targetIndex: newValue ? 0 : NO_TARGET, + newOptions.innervateTarget = UnitReference.create({ + type: newValue ? UnitType.Player : UnitType.Unknown, + index: 0, }); player.setSpecOptions(eventID, newOptions); }, diff --git a/ui/balance_druid/presets.ts b/ui/balance_druid/presets.ts index 1563e57547..68fe225428 100644 --- a/ui/balance_druid/presets.ts +++ b/ui/balance_druid/presets.ts @@ -9,7 +9,7 @@ import { PartyBuffs, Potions, RaidBuffs, - RaidTarget, Spec, + UnitReference, Spec, TristateEffect } from '../core/proto/common.js'; import { SavedRotation, SavedTalents } from '../core/proto/ui.js'; @@ -26,7 +26,6 @@ import { } from '../core/proto/druid.js'; import * as Tooltips from '../core/constants/tooltips.js'; -import { NO_TARGET } from "../core/proto_utils/utils"; import { Player } from "../core/player"; import { APLRotation } from '../core/proto/apl.js'; @@ -94,9 +93,7 @@ export const DefaultRotation = BalanceDruidRotation.create({ }); export const DefaultOptions = BalanceDruidOptions.create({ - innervateTarget: RaidTarget.create({ - targetIndex: NO_TARGET, - }), + innervateTarget: UnitReference.create(), }); export const DefaultConsumes = Consumes.create({ diff --git a/ui/core/components/detailed_results/results_filter.ts b/ui/core/components/detailed_results/results_filter.ts index 50d4314350..b9fdadc066 100644 --- a/ui/core/components/detailed_results/results_filter.ts +++ b/ui/core/components/detailed_results/results_filter.ts @@ -1,6 +1,6 @@ import { SimResult, SimResultFilter } from '../../proto_utils/sim_result.js'; import { EventID, TypedEvent } from '../../typed_event.js'; -import { UnitPicker } from '../../components/unit_picker.js'; +import { UnitPicker, UnitValueConfig } from '../../components/unit_picker.js'; import { ResultComponent, ResultComponentConfig, SimResultData } from './result_component.js'; @@ -11,13 +11,6 @@ interface FilterData { target: number, }; -interface UnitFilterOption { - iconUrl: string, - text: string, - color: string, - value: number, -}; - export class ResultsFilter extends ResultComponent { private readonly currentFilter: FilterData; @@ -80,7 +73,7 @@ export class ResultsFilter extends ResultComponent { this.changeEmitter.emit(eventID); } - private getUnitOptions(eventID: EventID, simResult: SimResult, isPlayer: boolean): Array { + private getUnitOptions(eventID: EventID, simResult: SimResult, isPlayer: boolean): Array> { const allUnitsOption = { iconUrl: '', text: isPlayer ? 'All Players' : 'All Targets', diff --git a/ui/core/components/other_inputs.ts b/ui/core/components/other_inputs.ts index 52e2eec85d..3865d2ee49 100644 --- a/ui/core/components/other_inputs.ts +++ b/ui/core/components/other_inputs.ts @@ -1,10 +1,10 @@ import { BooleanPicker } from '../components/boolean_picker.js'; import { EnumPicker } from '../components/enum_picker.js'; -import { RaidTarget } from '../proto/common.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 { emptyRaidTarget } from '../proto_utils/utils.js'; +import { emptyUnitReference } from '../proto_utils/utils.js'; export function makeShow1hWeaponsSelector(parent: HTMLElement, sim: Sim): BooleanPicker { return new BooleanPicker(parent, sim, { @@ -108,14 +108,14 @@ export const TankAssignment = { { name: 'Tank 4', value: 3 }, ], changedEvent: (player: Player) => player.getRaid()!.tanksChangeEmitter, - getValue: (player: Player) => (player.getRaid()?.getTanks() || []).findIndex(tank => RaidTarget.equals(tank, player.makeRaidTarget())), + getValue: (player: Player) => (player.getRaid()?.getTanks() || []).findIndex(tank => UnitReference.equals(tank, player.makeUnitReference())), setValue: (eventID: EventID, player: Player, newValue: number) => { const newTanks = []; if (newValue != -1) { for (let i = 0; i < newValue; i++) { - newTanks.push(emptyRaidTarget()); + newTanks.push(emptyUnitReference()); } - newTanks.push(player.makeRaidTarget()); + newTanks.push(player.makeUnitReference()); } player.getRaid()!.setTanks(eventID, newTanks); }, @@ -135,7 +135,7 @@ export const IncomingHps = { healingModel.hps = newValue; player.setHealingModel(eventID, healingModel); }, - enableWhen: (player: Player) => (player.getRaid()?.getTanks() || []).find(tank => RaidTarget.equals(tank, player.makeRaidTarget())) != null, + enableWhen: (player: Player) => (player.getRaid()?.getTanks() || []).find(tank => UnitReference.equals(tank, player.makeUnitReference())) != null, }; export const HealingCadence = { @@ -154,7 +154,7 @@ export const HealingCadence = { healingModel.cadenceSeconds = newValue; player.setHealingModel(eventID, healingModel); }, - enableWhen: (player: Player) => (player.getRaid()?.getTanks() || []).find(tank => RaidTarget.equals(tank, player.makeRaidTarget())) != null, + enableWhen: (player: Player) => (player.getRaid()?.getTanks() || []).find(tank => UnitReference.equals(tank, player.makeUnitReference())) != null, }; export const HealingCadenceVariation = { @@ -173,7 +173,7 @@ export const HealingCadenceVariation = { healingModel.cadenceVariation = newValue; player.setHealingModel(eventID, healingModel); }, - enableWhen: (player: Player) => (player.getRaid()?.getTanks() || []).find(tank => RaidTarget.equals(tank, player.makeRaidTarget())) != null, + enableWhen: (player: Player) => (player.getRaid()?.getTanks() || []).find(tank => UnitReference.equals(tank, player.makeUnitReference())) != null, }; export const BurstWindow = { @@ -191,7 +191,7 @@ export const BurstWindow = { healingModel.burstWindow = newValue; player.setHealingModel(eventID, healingModel); }, - enableWhen: (player: Player) => (player.getRaid()?.getTanks() || []).find(tank => RaidTarget.equals(tank, player.makeRaidTarget())) != null, + enableWhen: (player: Player) => (player.getRaid()?.getTanks() || []).find(tank => UnitReference.equals(tank, player.makeUnitReference())) != null, }; export const HpPercentForDefensives = { diff --git a/ui/core/components/raid_target_picker.ts b/ui/core/components/raid_target_picker.ts index af26a11d23..493c37ac86 100644 --- a/ui/core/components/raid_target_picker.ts +++ b/ui/core/components/raid_target_picker.ts @@ -2,10 +2,10 @@ import { Input, InputConfig } from '../components/input.js'; import { Player } from '../player.js'; import { Raid } from '../raid.js'; import { EventID, TypedEvent } from '../typed_event.js'; -import { RaidTarget } from '../proto/common.js'; -import { emptyRaidTarget, cssClassForClass } from '../proto_utils/utils.js'; +import { UnitReference } from '../proto/common.js'; +import { emptyUnitReference, cssClassForClass } from '../proto_utils/utils.js'; -export interface RaidTargetPickerConfig extends InputConfig { +export interface UnitReferencePickerConfig extends InputConfig { noTargetLabel: string, compChangeEmitter: TypedEvent, } @@ -16,25 +16,25 @@ interface OptionElemOptions { } // Dropdown menu for selecting a player. -export class RaidTargetPicker extends Input { - private readonly config: RaidTargetPickerConfig; +export class UnitReferencePicker extends Input { + private readonly config: UnitReferencePickerConfig; private readonly raid: Raid; private curPlayer: Player | null; - private curRaidTarget: RaidTarget; + private curUnitReference: UnitReference; private currentOptions: Array; private readonly buttonElem: HTMLElement; private readonly dropdownElem: HTMLElement; - constructor(parent: HTMLElement, raid: Raid, modObj: ModObject, config: RaidTargetPickerConfig) { + constructor(parent: HTMLElement, raid: Raid, modObj: ModObject, config: UnitReferencePickerConfig) { super(parent, 'raid-target-picker-root', modObj, config); this.rootElem.classList.add('dropdown'); this.config = config; this.raid = raid; - this.curPlayer = this.raid.getPlayerFromRaidTarget(config.getValue(modObj)); - this.curRaidTarget = this.getInputValue(); + this.curPlayer = this.raid.getPlayerFromUnitReference(config.getValue(modObj)); + this.curUnitReference = this.getInputValue(); this.rootElem.innerHTML = ` extends Input { this.dropdownElem.innerHTML = ''; this.currentOptions.forEach(option => this.dropdownElem.appendChild(this.makeOption(option))); - const prevRaidTarget = this.curRaidTarget; - this.curRaidTarget = this.getInputValue(); - if (!RaidTarget.equals(prevRaidTarget, this.curRaidTarget)) { + const prevUnitReference = this.curUnitReference; + this.curUnitReference = this.getInputValue(); + if (!UnitReference.equals(prevUnitReference, this.curUnitReference)) { this.inputChanged(eventID); } else { - this.setInputValue(this.curRaidTarget); + this.setInputValue(this.curUnitReference); } } private makeOption(data: OptionElemOptions): HTMLElement { - const option = RaidTargetPicker.makeOptionElem(data); + const option = UnitReferencePicker.makeOptionElem(data); option.addEventListener('click', event => { event.preventDefault(); this.curPlayer = data.player; - this.curRaidTarget = this.getInputValue(); + this.curUnitReference = this.getInputValue(); this.inputChanged(TypedEvent.nextEventID()); }); @@ -99,52 +99,24 @@ export class RaidTargetPicker extends Input { return this.buttonElem; } - getInputValue(): RaidTarget { + getInputValue(): UnitReference { if (this.curPlayer) { - return this.curPlayer.makeRaidTarget(); + return this.curPlayer.makeUnitReference(); } else { - return emptyRaidTarget(); + return emptyUnitReference(); } } - setInputValue(newValue: RaidTarget) { - this.curRaidTarget = RaidTarget.clone(newValue); - this.curPlayer = this.raid.getPlayerFromRaidTarget(this.curRaidTarget); + setInputValue(newValue: UnitReference) { + this.curUnitReference = UnitReference.clone(newValue); + this.curPlayer = this.raid.getPlayerFromUnitReference(this.curUnitReference); const optionData = this.currentOptions.find(optionData => optionData.player == this.curPlayer); if (optionData) - this.buttonElem.innerHTML = RaidTargetPicker.makeOptionElem({ player: optionData.player }).outerHTML; + this.buttonElem.innerHTML = UnitReferencePicker.makeOptionElem({ player: optionData.player }).outerHTML; } - // static makeOptionElem(data: RaidTargetElemOption): HTMLElement { - // const optionContainer = document.createElement('div'); - // optionContainer.classList.add('dropdown-option-container'); - - // const option = document.createElement('div'); - // option.classList.add('raid-target-picker-option'); - // optionContainer.appendChild(option); - // if (data.isDropdown) { - // option.classList.add('dropdown-option'); - // } - - // if (data.iconUrl) { - // const icon = document.createElement('img'); - // icon.src = data.iconUrl; - // icon.classList.add('raid-target-picker-icon'); - // option.appendChild(icon); - // } - - // if (data.text) { - // const label = document.createElement('span'); - // label.textContent = data.text; - // label.classList.add('raid-target-picker-label'); - // option.appendChild(label); - // } - - // return optionContainer; - // } - static makeOptionElem(data: OptionElemOptions): HTMLElement { const classCssClass = data.player ? cssClassForClass(data.player.getClass()) : ''; let playerFragment = document.createElement('fragment'); diff --git a/ui/core/components/unit_picker.ts b/ui/core/components/unit_picker.ts index da94b6ec81..76b32ef0db 100644 --- a/ui/core/components/unit_picker.ts +++ b/ui/core/components/unit_picker.ts @@ -25,14 +25,14 @@ export class UnitPicker extends DropdownPicker { if (unitConfig.iconUrl) { const icon = document.createElement('img'); icon.src = unitConfig.iconUrl; - icon.classList.add('unit-filter-icon'); + icon.classList.add('unit-picker-item-icon'); button.appendChild(icon); } if (unitConfig.text) { const label = document.createElement('span'); label.textContent = unitConfig.text; - label.classList.add('unit-filter-label'); + label.classList.add('unit-picker-item-label'); button.appendChild(label); } } diff --git a/ui/core/individual_sim_ui.ts b/ui/core/individual_sim_ui.ts index 2ccc11d954..d4600b3861 100644 --- a/ui/core/individual_sim_ui.ts +++ b/ui/core/individual_sim_ui.ts @@ -533,7 +533,7 @@ export abstract class IndividualSimUI extends SimUI { this.sim.applyDefaults(eventID, tankSpec, healingSpec); if (tankSpec) { - this.sim.raid.setTanks(eventID, [this.player.makeRaidTarget()]); + this.sim.raid.setTanks(eventID, [this.player.makeUnitReference()]); } else { this.sim.raid.setTanks(eventID, []); } diff --git a/ui/core/player.ts b/ui/core/player.ts index 58d4f11b4d..f949ecbdaf 100644 --- a/ui/core/player.ts +++ b/ui/core/player.ts @@ -13,7 +13,7 @@ import { Profession, PseudoStat, Race, - RaidTarget, + UnitReference, RangedWeaponType, SimDatabase, SimEnchant, @@ -23,6 +23,7 @@ import { Stat, UnitStats, WeaponType, + UnitReference_Type, } from './proto/common.js'; import { AuraStats as AuraStatsProto, @@ -67,13 +68,13 @@ import { canEquipEnchant, canEquipItem, classColors, - emptyRaidTarget, + emptyUnitReference, enchantAppliesToItem, getTalentTree, getTalentTreeIcon, getMetaGemEffectEP, isTankSpec, - newRaidTarget, + newUnitReference, raceToFaction, specToClass, specToEligibleRaces, @@ -1052,11 +1053,11 @@ export class Player { }); } - makeRaidTarget(): RaidTarget { + makeUnitReference(): UnitReference { if (this.party == null) { - return emptyRaidTarget(); + return emptyUnitReference(); } else { - return newRaidTarget(this.getRaidIndex()); + return newUnitReference(this.getRaidIndex()); } } @@ -1120,6 +1121,20 @@ export class Player { this.aplRotation = proto.rotation || APLRotation.create(); this.rotationChangeEmitter.emit(eventID); + + const options = this.getSpecOptions(); + for (let key in options) { + if ((options[key] as any)?.['targetIndex']) { + const targetIndex = (options[key] as any)['targetIndex'] as number; + if (targetIndex == -1) { + (options[key] as any) = UnitReference.create(); + } else { + (options[key] as any) = UnitReference.create({type: UnitReference_Type.Player, index: targetIndex}); + } + this.setSpecOptions(eventID, options); + break; + } + } }); } diff --git a/ui/core/proto_utils/action_id.ts b/ui/core/proto_utils/action_id.ts index f20e71d4a6..a104f777d7 100644 --- a/ui/core/proto_utils/action_id.ts +++ b/ui/core/proto_utils/action_id.ts @@ -3,7 +3,6 @@ import { ActionID as ActionIdProto } from '../proto/common.js'; import { ResourceType } from '../proto/api.js'; import { OtherAction } from '../proto/common.js'; import { IconData } from '../proto/ui.js'; -import { NO_TARGET } from '../proto_utils/utils.js'; import { UIItem as Item, } from '../proto/ui.js'; @@ -325,7 +324,7 @@ export class ActionId { case 'Focus Magic': case 'Mana Tide Totem': case 'Power Infusion': - if (this.tag != NO_TARGET) { + if (this.tag != -1) { if (this.tag === playerIndex) { name += ` (self)`; } else { diff --git a/ui/core/proto_utils/utils.ts b/ui/core/proto_utils/utils.ts index 5821939191..6b6ac5b4a7 100644 --- a/ui/core/proto_utils/utils.ts +++ b/ui/core/proto_utils/utils.ts @@ -7,7 +7,7 @@ import { sum } from '../utils.js'; import { Player } from '../proto/api.js'; import { ResourceType } from '../proto/api.js'; -import { ArmorType } from '../proto/common.js'; +import { ArmorType, UnitReference_Type } from '../proto/common.js'; import { Class } from '../proto/common.js'; import { EnchantType } from '../proto/common.js'; import { HandType } from '../proto/common.js'; @@ -15,7 +15,7 @@ import { ItemSlot } from '../proto/common.js'; import { ItemType } from '../proto/common.js'; import { Race } from '../proto/common.js'; import { Faction } from '../proto/common.js'; -import { RaidTarget } from '../proto/common.js'; +import { UnitReference } from '../proto/common.js'; import { RangedWeaponType } from '../proto/common.js'; import { Spec } from '../proto/common.js'; import { Stat } from '../proto/common.js'; @@ -1882,16 +1882,15 @@ export function canEquipEnchant(enchant: Enchant, spec: Spec): boolean { return true; } -export const NO_TARGET = -1; - -export function newRaidTarget(raidIndex: number): RaidTarget { - return RaidTarget.create({ - targetIndex: raidIndex, +export function newUnitReference(raidIndex: number): UnitReference { + return UnitReference.create({ + type: UnitReference_Type.Player, + index: raidIndex, }); } -export function emptyRaidTarget(): RaidTarget { - return newRaidTarget(NO_TARGET); +export function emptyUnitReference(): UnitReference { + return UnitReference.create(); } // Makes a new set of assignments with everything 0'd out. diff --git a/ui/core/raid.ts b/ui/core/raid.ts index 4b9d9f025e..ad3b037c41 100644 --- a/ui/core/raid.ts +++ b/ui/core/raid.ts @@ -1,11 +1,8 @@ -import { Class } from './proto/common.js'; +import { Class, UnitReference_Type } from './proto/common.js'; import { Debuffs } from './proto/common.js'; -import { RaidTarget } from './proto/common.js'; +import { UnitReference } from './proto/common.js'; import { Raid as RaidProto } from './proto/api.js'; -import { RaidStats as RaidStatsProto } from './proto/api.js'; import { RaidBuffs } from './proto/common.js'; -import { Spec } from './proto/common.js'; -import { NO_TARGET } from './proto_utils/utils.js'; import { Party, MAX_PARTY_SIZE } from './party.js'; import { Player } from './player.js'; @@ -19,7 +16,7 @@ export const MAX_NUM_PARTIES = 8; export class Raid { private buffs: RaidBuffs = RaidBuffs.create(); private debuffs: Debuffs = Debuffs.create(); - private tanks: Array = []; + private tanks: Array = []; private targetDummies: number = 0; private numActiveParties: number = 5; @@ -95,11 +92,11 @@ export class Raid { return party.getPlayer(index % MAX_PARTY_SIZE); } - getPlayerFromRaidTarget(raidTarget: RaidTarget): Player | null { - if (raidTarget.targetIndex == NO_TARGET) { - return null; + getPlayerFromUnitReference(raidTarget: UnitReference): Player | null { + if (raidTarget.type == UnitReference_Type.Player) { + return this.getPlayer(raidTarget.index); } else { - return this.getPlayer(raidTarget.targetIndex); + return null; } } @@ -169,17 +166,17 @@ export class Raid { this.debuffsChangeEmitter.emit(eventID); } - getTanks(): Array { + getTanks(): Array { // Make a defensive copy - return this.tanks.map(tank => RaidTarget.clone(tank)); + return this.tanks.map(tank => UnitReference.clone(tank)); } - setTanks(eventID: EventID, newTanks: Array) { - if (this.tanks.length == newTanks.length && this.tanks.every((tank, i) => RaidTarget.equals(tank, newTanks[i]))) + setTanks(eventID: EventID, newTanks: Array) { + if (this.tanks.length == newTanks.length && this.tanks.every((tank, i) => UnitReference.equals(tank, newTanks[i]))) return; // Make a defensive copy - this.tanks = newTanks.map(tank => RaidTarget.clone(tank)); + this.tanks = newTanks.map(tank => UnitReference.clone(tank)); this.tanksChangeEmitter.emit(eventID); } @@ -228,6 +225,10 @@ export class Raid { fromProto(eventID: EventID, proto: RaidProto) { TypedEvent.freezeAllAndDo(() => { + if (proto.tanks) { + proto.tanks = proto.tanks.map(tank => (tank.type == 0 && tank.targetIndex != -1) ? UnitReference.create({type: UnitReference_Type.Player, index: tank.targetIndex}) : tank); + } + if (proto.buffs) { if (proto.buffs.demonicPact > 0 && proto.buffs.demonicPactSp == 0) { proto.buffs.demonicPactSp = proto.buffs.demonicPact; diff --git a/ui/core/sim.ts b/ui/core/sim.ts index eca6a8ff2d..3b7ee387b9 100644 --- a/ui/core/sim.ts +++ b/ui/core/sim.ts @@ -1,7 +1,7 @@ -import { ArmorType, SimDatabase } from './proto/common.js'; +import { ArmorType, SimDatabase, UnitReference_Type } from './proto/common.js'; import { Faction } from './proto/common.js'; import { Profession } from './proto/common.js';; -import { RaidTarget } from './proto/common.js'; +import { UnitReference } from './proto/common.js'; import { Stat, PseudoStat } from './proto/common.js'; import { RangedWeaponType, WeaponType } from './proto/common.js'; import { BulkSimRequest, BulkSimResult, BulkSettings, Raid as RaidProto } from './proto/api.js'; @@ -328,8 +328,8 @@ export class Sim { console.warn('Trying to get stat weights without a party!'); return StatWeightsResult.create(); } else { - const tanks = this.raid.getTanks().map(tank => tank.targetIndex).includes(player.getRaidIndex()) - ? [RaidTarget.create({ targetIndex: 0 })] + const tanks = this.raid.getTanks().map(tank => tank.index).includes(player.getRaidIndex()) + ? [UnitReference.create({ type: UnitReference_Type.Player, index: 0 })] : []; const request = StatWeightsRequest.create({ player: player.toProto(), diff --git a/ui/deathknight/inputs.ts b/ui/deathknight/inputs.ts index 89c8f3d339..fe738a5388 100644 --- a/ui/deathknight/inputs.ts +++ b/ui/deathknight/inputs.ts @@ -1,4 +1,5 @@ -import { ItemSlot, RaidTarget, Spec } from '../core/proto/common.js'; +import { ItemSlot, Spec } from '../core/proto/common.js'; +import { UnitReference, UnitReference_Type as UnitType } from '../core/proto/common.js'; import { ActionId } from '../core/proto_utils/action_id.js'; import { @@ -22,7 +23,6 @@ import { import * as InputHelpers from '../core/components/input_helpers.js'; import { Player } from '../core/player'; import { EventID, TypedEvent } from '../core/typed_event'; -import { NO_TARGET } from '../core/proto_utils/utils.js'; // Configuration for spec-specific UI elements on the settings tab. // These don't need to be in a separate file but it keeps things cleaner. @@ -34,11 +34,12 @@ export const SelfUnholyFrenzy = InputHelpers.makeSpecOptionsBooleanInput) => player.getSpecOptions().unholyFrenzyTarget?.targetIndex != NO_TARGET, + getValue: (player: Player) => player.getSpecOptions().unholyFrenzyTarget?.type == UnitType.Player, setValue: (eventID: EventID, player: Player, newValue: boolean) => { const newOptions = player.getSpecOptions(); - newOptions.unholyFrenzyTarget = RaidTarget.create({ - targetIndex: newValue ? 0 : NO_TARGET, + newOptions.unholyFrenzyTarget = UnitReference.create({ + type: newValue ? UnitType.Player : UnitType.Unknown, + index: 0, }); player.setSpecOptions(eventID, newOptions); }, diff --git a/ui/deathknight/presets.ts b/ui/deathknight/presets.ts index 53508617c5..cac0ea1c2e 100644 --- a/ui/deathknight/presets.ts +++ b/ui/deathknight/presets.ts @@ -9,12 +9,11 @@ import { Glyphs, PetFood, Potions, - RaidTarget, + UnitReference, Spec } from '../core/proto/common.js'; import { SavedRotation, SavedTalents } from '../core/proto/ui.js'; import { Player } from '../core/player.js'; -import { NO_TARGET } from '../core/proto_utils/utils.js'; import { Deathknight_Options as DeathKnightOptions, @@ -155,9 +154,7 @@ export const DefaultUnholyOptions = DeathKnightOptions.create({ petUptime: 1, precastGhoulFrenzy: false, precastHornOfWinter: true, - unholyFrenzyTarget: RaidTarget.create({ - targetIndex: NO_TARGET, // In an individual sim the 0-indexed player is ourself. - }), + unholyFrenzyTarget: UnitReference.create(), diseaseDowntime: 2, }); @@ -196,9 +193,7 @@ export const DefaultFrostOptions = DeathKnightOptions.create({ startingRunicPower: 0, petUptime: 1, precastHornOfWinter: true, - unholyFrenzyTarget: RaidTarget.create({ - targetIndex: NO_TARGET, // In an individual sim the 0-indexed player is ourself. - }), + unholyFrenzyTarget: UnitReference.create(), diseaseDowntime: 0, }); @@ -221,9 +216,7 @@ export const DefaultBloodOptions = DeathKnightOptions.create({ startingRunicPower: 0, petUptime: 1, precastHornOfWinter: true, - unholyFrenzyTarget: RaidTarget.create({ - targetIndex: NO_TARGET, // In an individual sim the 0-indexed player is ourself. - }), + unholyFrenzyTarget: UnitReference.create(), diseaseDowntime: 0, }); diff --git a/ui/feral_druid/inputs.ts b/ui/feral_druid/inputs.ts index 21bf1b0957..9f2c94e515 100644 --- a/ui/feral_druid/inputs.ts +++ b/ui/feral_druid/inputs.ts @@ -1,6 +1,5 @@ -import { RaidTarget, SpellSchool } from '../core/proto/common.js'; +import { UnitReference, UnitReference_Type as UnitType } from '../core/proto/common.js'; import { Spec } from '../core/proto/common.js'; -import { NO_TARGET } from '../core/proto_utils/utils.js'; import { ActionId } from '../core/proto_utils/action_id.js'; import { Player } from '../core/player.js'; import { EventID, TypedEvent } from '../core/typed_event.js'; @@ -26,11 +25,12 @@ export const SelfInnervate = InputHelpers.makeSpecOptionsBooleanIconInput) => player.getSpecOptions().innervateTarget?.targetIndex != NO_TARGET, + getValue: (player: Player) => player.getSpecOptions().innervateTarget?.type == UnitType.Player, setValue: (eventID: EventID, player: Player, newValue: boolean) => { const newOptions = player.getSpecOptions(); - newOptions.innervateTarget = RaidTarget.create({ - targetIndex: newValue ? 0 : NO_TARGET, + newOptions.innervateTarget = UnitReference.create({ + type: newValue ? UnitType.Player : UnitType.Unknown, + index: 0, }); player.setSpecOptions(eventID, newOptions); }, diff --git a/ui/feral_tank_druid/presets.ts b/ui/feral_tank_druid/presets.ts index d3a4e31f96..19051d4989 100644 --- a/ui/feral_tank_druid/presets.ts +++ b/ui/feral_tank_druid/presets.ts @@ -6,10 +6,9 @@ import { EquipmentSpec } from '../core/proto/common.js'; import { Potions } from '../core/proto/common.js'; import { Conjured } from '../core/proto/common.js'; import { Explosive } from '../core/proto/common.js'; -import { RaidTarget } from '../core/proto/common.js'; +import { UnitReference } from '../core/proto/common.js'; import { Glyphs } from '../core/proto/common.js'; import { SavedTalents } from '../core/proto/ui.js'; -import { NO_TARGET } from '../core/proto_utils/utils.js'; import { FeralTankDruid_Rotation as DruidRotation, @@ -48,9 +47,7 @@ export const DefaultRotation = DruidRotation.create({ }); export const DefaultOptions = DruidOptions.create({ - innervateTarget: RaidTarget.create({ - targetIndex: NO_TARGET, - }), + innervateTarget: UnitReference.create(), startingRage: 20, }); diff --git a/ui/feral_tank_druid/sim.ts b/ui/feral_tank_druid/sim.ts index 3b6dc6ef6d..a7fa19216e 100644 --- a/ui/feral_tank_druid/sim.ts +++ b/ui/feral_tank_druid/sim.ts @@ -7,9 +7,8 @@ import { Consumes } from '../core/proto/common.js'; import { Encounter } from '../core/proto/common.js'; import { ItemSlot } from '../core/proto/common.js'; import { MobType } from '../core/proto/common.js'; -import { RaidTarget } from '../core/proto/common.js'; +import { UnitReference } from '../core/proto/common.js'; import { Spec } from '../core/proto/common.js'; -import { NO_TARGET } from '../core/proto_utils/utils.js'; import { Stat, PseudoStat } from '../core/proto/common.js'; import { TristateEffect } from '../core/proto/common.js' import { Stats } from '../core/proto_utils/stats.js'; diff --git a/ui/healing_priest/inputs.ts b/ui/healing_priest/inputs.ts index 64e2f12cbb..4632ca8ad7 100644 --- a/ui/healing_priest/inputs.ts +++ b/ui/healing_priest/inputs.ts @@ -1,6 +1,5 @@ -import { RaidTarget } from '../core/proto/common.js'; +import { UnitReference, UnitReference_Type as UnitType } from '../core/proto/common.js'; import { Spec } from '../core/proto/common.js'; -import { NO_TARGET } from '../core/proto_utils/utils.js'; import { ActionId } from '../core/proto_utils/action_id.js'; import { Player } from '../core/player.js'; import { EventID, TypedEvent } from '../core/typed_event.js'; @@ -23,11 +22,12 @@ export const SelfPowerInfusion = InputHelpers.makeSpecOptionsBooleanIconInput) => player.getSpecOptions().powerInfusionTarget?.targetIndex != NO_TARGET, + getValue: (player: Player) => player.getSpecOptions().powerInfusionTarget?.type == UnitType.Player, setValue: (eventID: EventID, player: Player, newValue: boolean) => { const newOptions = player.getSpecOptions(); - newOptions.powerInfusionTarget = RaidTarget.create({ - targetIndex: newValue ? 0 : NO_TARGET, + newOptions.powerInfusionTarget = UnitReference.create({ + type: newValue ? UnitType.Player : UnitType.Unknown, + index: 0, }); player.setSpecOptions(eventID, newOptions); }, diff --git a/ui/healing_priest/presets.ts b/ui/healing_priest/presets.ts index 3bf866b507..9511f732a2 100644 --- a/ui/healing_priest/presets.ts +++ b/ui/healing_priest/presets.ts @@ -10,11 +10,10 @@ import { Faction } from '../core/proto/common.js'; import { RaidBuffs } from '../core/proto/common.js'; import { IndividualBuffs } from '../core/proto/common.js'; import { Debuffs } from '../core/proto/common.js'; -import { RaidTarget } from '../core/proto/common.js'; +import { UnitReference } from '../core/proto/common.js'; import { TristateEffect } from '../core/proto/common.js'; import { SavedTalents } from '../core/proto/ui.js'; import { Player } from '../core/player.js'; -import { NO_TARGET } from '../core/proto_utils/utils.js'; import { HealingPriest_Rotation as Rotation, @@ -91,9 +90,7 @@ export const DefaultOptions = Options.create({ useShadowfiend: true, rapturesPerMinute: 5, - powerInfusionTarget: RaidTarget.create({ - targetIndex: NO_TARGET, // In an individual sim the 0-indexed player is ourself. - }), + powerInfusionTarget: UnitReference.create(), }); export const DefaultConsumes = Consumes.create({ diff --git a/ui/healing_priest/sim.ts b/ui/healing_priest/sim.ts index 7e20e509e9..e64825f16f 100644 --- a/ui/healing_priest/sim.ts +++ b/ui/healing_priest/sim.ts @@ -7,7 +7,7 @@ import { Consumes } from '../core/proto/common.js'; import { Encounter } from '../core/proto/common.js'; import { ItemSlot } from '../core/proto/common.js'; import { MobType } from '../core/proto/common.js'; -import { RaidTarget } from '../core/proto/common.js'; +import { UnitReference } from '../core/proto/common.js'; import { Spec } from '../core/proto/common.js'; import { Stat } from '../core/proto/common.js'; import { TristateEffect } from '../core/proto/common.js' diff --git a/ui/mage/presets.ts b/ui/mage/presets.ts index f8a91d2cbe..54ddb94070 100644 --- a/ui/mage/presets.ts +++ b/ui/mage/presets.ts @@ -8,10 +8,9 @@ import { ItemSpec } from '../core/proto/common.js'; import { Potions } from '../core/proto/common.js'; import { Spec } from '../core/proto/common.js'; import { Faction } from '../core/proto/common.js'; -import { RaidTarget } from '../core/proto/common.js'; +import { UnitReference } from '../core/proto/common.js'; import { SavedRotation, SavedTalents } from '../core/proto/ui.js'; import { Player } from '../core/player.js'; -import { NO_TARGET } from '../core/proto_utils/utils'; import { Mage, @@ -130,9 +129,7 @@ export const DefaultFFBOptions = MageOptions.create({ export const DefaultFireOptions = MageOptions.create({ armor: ArmorType.MoltenArmor, focusMagicPercentUptime: 99, - focusMagicTarget: RaidTarget.create({ - targetIndex: NO_TARGET, - }), + focusMagicTarget: UnitReference.create(), reactionTimeMs: 300, igniteMunching: true, }); @@ -151,9 +148,7 @@ export const DefaultFrostRotation = MageRotation.create({ export const DefaultFrostOptions = MageOptions.create({ armor: ArmorType.MoltenArmor, - focusMagicTarget: RaidTarget.create({ - targetIndex: NO_TARGET, - }), + focusMagicTarget: UnitReference.create(), reactionTimeMs: 300, }); @@ -176,9 +171,7 @@ export const DefaultArcaneRotation = MageRotation.create({ export const DefaultArcaneOptions = MageOptions.create({ armor: ArmorType.MoltenArmor, focusMagicPercentUptime: 99, - focusMagicTarget: RaidTarget.create({ - targetIndex: NO_TARGET, - }), + focusMagicTarget: UnitReference.create(), reactionTimeMs: 300, }); diff --git a/ui/protection_warrior/sim.ts b/ui/protection_warrior/sim.ts index 31e6cec730..49ccdbba69 100644 --- a/ui/protection_warrior/sim.ts +++ b/ui/protection_warrior/sim.ts @@ -7,7 +7,7 @@ import { Consumes } from '../core/proto/common.js'; import { Encounter } from '../core/proto/common.js'; import { ItemSlot } from '../core/proto/common.js'; import { MobType } from '../core/proto/common.js'; -import { RaidTarget } from '../core/proto/common.js'; +import { UnitReference } from '../core/proto/common.js'; import { Spec } from '../core/proto/common.js'; import { Stat, PseudoStat } from '../core/proto/common.js'; import { TristateEffect } from '../core/proto/common.js' diff --git a/ui/raid/assignments_picker.ts b/ui/raid/assignments_picker.ts index 96e7f80c7a..69d6243e68 100644 --- a/ui/raid/assignments_picker.ts +++ b/ui/raid/assignments_picker.ts @@ -1,11 +1,11 @@ import { Component } from '../core/components/component.js'; -import { RaidTargetPicker } from '../core/components/raid_target_picker.js'; +import { UnitReferencePicker } from '../core/components/raid_target_picker.js'; import { Player } from '../core/player.js'; import { EventID, TypedEvent } from '../core/typed_event.js'; -import { Class, RaidTarget, Spec } from '../core/proto/common.js'; -import { emptyRaidTarget } from '../core/proto_utils/utils.js'; +import { Class, UnitReference, Spec } from '../core/proto/common.js'; +import { emptyUnitReference } from '../core/proto_utils/utils.js'; import { RaidSimUI } from './raid_sim_ui.js'; @@ -33,7 +33,7 @@ export class AssignmentsPicker extends Component { interface AssignmentTargetPicker { player: Player, - targetPicker: RaidTargetPicker>, + targetPicker: UnitReferencePicker>, targetPlayer: Player | null; }; @@ -77,7 +77,7 @@ abstract class AssignedBuffPicker extends Component { let sourceElem = document.createElement('div'); sourceElem.classList.add('raid-target-picker-root'); sourceElem.appendChild( - RaidTargetPicker.makeOptionElem({ player: sourcePlayer, isDropdown: false }) + UnitReferencePicker.makeOptionElem({ player: sourcePlayer, isDropdown: false }) ); row.appendChild(sourceElem); @@ -85,24 +85,24 @@ abstract class AssignedBuffPicker extends Component { arrow.classList.add('assigned-buff-arrow', 'fa', 'fa-arrow-right'); row.appendChild(arrow); - const raidTargetPicker: RaidTargetPicker> | null = new RaidTargetPicker>(row, this.raidSimUI.sim.raid, sourcePlayer, { + const raidTargetPicker: UnitReferencePicker> | null = new UnitReferencePicker>(row, this.raidSimUI.sim.raid, sourcePlayer, { extraCssClasses: ['assigned-buff-target-picker'], noTargetLabel: 'Unassigned', compChangeEmitter: this.raidSimUI.sim.raid.compChangeEmitter, changedEvent: (player: Player) => player.specOptionsChangeEmitter, getValue: (player: Player) => this.getPlayerValue(player), - setValue: (eventID: EventID, player: Player, newValue: RaidTarget) => this.setPlayerValue(eventID, player, newValue), + setValue: (eventID: EventID, player: Player, newValue: UnitReference) => this.setPlayerValue(eventID, player, newValue), }); const targetPickerData = { player: sourcePlayer, targetPicker: raidTargetPicker!, - targetPlayer: this.raidSimUI.sim.raid.getPlayerFromRaidTarget(raidTargetPicker!.getInputValue()), + targetPlayer: this.raidSimUI.sim.raid.getPlayerFromUnitReference(raidTargetPicker!.getInputValue()), }; raidTargetPicker!.changeEmitter.on(eventID => { - targetPickerData.targetPlayer = this.raidSimUI.sim.raid.getPlayerFromRaidTarget(raidTargetPicker!.getInputValue()); + targetPickerData.targetPlayer = this.raidSimUI.sim.raid.getPlayerFromUnitReference(raidTargetPicker!.getInputValue()); }); return targetPickerData; @@ -112,8 +112,8 @@ abstract class AssignedBuffPicker extends Component { abstract getTitle(): string; abstract getSourcePlayers(): Array>; - abstract getPlayerValue(player: Player): RaidTarget; - abstract setPlayerValue(eventID: EventID, player: Player, newValue: RaidTarget): void; + abstract getPlayerValue(player: Player): UnitReference; + abstract setPlayerValue(eventID: EventID, player: Player, newValue: UnitReference): void; } class InnervatesPicker extends AssignedBuffPicker { @@ -125,11 +125,11 @@ class InnervatesPicker extends AssignedBuffPicker { return this.raidSimUI.getActivePlayers().filter(player => player.isClass(Class.ClassDruid)); } - getPlayerValue(player: Player): RaidTarget { - return (player as Player).getSpecOptions().innervateTarget || emptyRaidTarget(); + getPlayerValue(player: Player): UnitReference { + return (player as Player).getSpecOptions().innervateTarget || emptyUnitReference(); } - setPlayerValue(eventID: EventID, player: Player, newValue: RaidTarget) { + setPlayerValue(eventID: EventID, player: Player, newValue: UnitReference) { const newOptions = (player as Player).getSpecOptions(); newOptions.innervateTarget = newValue; player.setSpecOptions(eventID, newOptions); @@ -145,11 +145,11 @@ class PowerInfusionsPicker extends AssignedBuffPicker { return this.raidSimUI.getActivePlayers().filter(player => player.isClass(Class.ClassPriest) && player.getTalents().powerInfusion); } - getPlayerValue(player: Player): RaidTarget { - return (player as Player).getSpecOptions().powerInfusionTarget || emptyRaidTarget(); + getPlayerValue(player: Player): UnitReference { + return (player as Player).getSpecOptions().powerInfusionTarget || emptyUnitReference(); } - setPlayerValue(eventID: EventID, player: Player, newValue: RaidTarget) { + setPlayerValue(eventID: EventID, player: Player, newValue: UnitReference) { const newOptions = (player as Player).getSpecOptions(); newOptions.powerInfusionTarget = newValue; player.setSpecOptions(eventID, newOptions); @@ -165,11 +165,11 @@ class TricksOfTheTradesPicker extends AssignedBuffPicker { return this.raidSimUI.getActivePlayers().filter(player => player.isClass(Class.ClassRogue)); } - getPlayerValue(player: Player): RaidTarget { - return (player as Player).getSpecOptions().tricksOfTheTradeTarget || emptyRaidTarget(); + getPlayerValue(player: Player): UnitReference { + return (player as Player).getSpecOptions().tricksOfTheTradeTarget || emptyUnitReference(); } - setPlayerValue(eventID: EventID, player: Player, newValue: RaidTarget) { + setPlayerValue(eventID: EventID, player: Player, newValue: UnitReference) { const newOptions = (player as Player).getSpecOptions(); newOptions.tricksOfTheTradeTarget = newValue; player.setSpecOptions(eventID, newOptions); @@ -185,11 +185,11 @@ class UnholyFrenzyPicker extends AssignedBuffPicker { return this.raidSimUI.getActivePlayers().filter(player => player.isClass(Class.ClassDeathknight) && player.getTalents().hysteria); } - getPlayerValue(player: Player): RaidTarget { - return (player as Player).getSpecOptions().unholyFrenzyTarget || emptyRaidTarget(); + getPlayerValue(player: Player): UnitReference { + return (player as Player).getSpecOptions().unholyFrenzyTarget || emptyUnitReference(); } - setPlayerValue(eventID: EventID, player: Player, newValue: RaidTarget) { + setPlayerValue(eventID: EventID, player: Player, newValue: UnitReference) { const newOptions = (player as Player).getSpecOptions(); newOptions.unholyFrenzyTarget = newValue; player.setSpecOptions(eventID, newOptions); @@ -205,11 +205,11 @@ class FocusMagicsPicker extends AssignedBuffPicker { return this.raidSimUI.getActivePlayers().filter(player => player.isClass(Class.ClassMage)); } - getPlayerValue(player: Player): RaidTarget { - return (player as Player).getSpecOptions().focusMagicTarget || emptyRaidTarget(); + getPlayerValue(player: Player): UnitReference { + return (player as Player).getSpecOptions().focusMagicTarget || emptyUnitReference(); } - setPlayerValue(eventID: EventID, player: Player, newValue: RaidTarget) { + setPlayerValue(eventID: EventID, player: Player, newValue: UnitReference) { const newOptions = (player as Player).getSpecOptions(); newOptions.focusMagicTarget = newValue; player.setSpecOptions(eventID, newOptions); diff --git a/ui/raid/import_export.ts b/ui/raid/import_export.ts index d75cf23104..e906c18a9c 100644 --- a/ui/raid/import_export.ts +++ b/ui/raid/import_export.ts @@ -13,9 +13,10 @@ import { MobType, Profession, Race, - RaidTarget, + UnitReference, Spec, Target as TargetProto, + UnitReference_Type, } from '../core/proto/common'; import { nameToClass, professionNames, raceNames } from '../core/proto_utils/names'; import { @@ -376,7 +377,7 @@ export class RaidWCLImporter extends Importer { const sourcePlayer = wclPlayers.find(player => player.id == event.sourceID); const targetPlayer = wclPlayers.find(player => player.id == event.targetID); if (sourcePlayer && targetPlayer && sourcePlayer.player.getClass() == spell.class) { - const specOptions = spell.applyFunc(sourcePlayer.player, targetPlayer.toRaidTarget()); + const specOptions = spell.applyFunc(sourcePlayer.player, targetPlayer.toUnitReference()); sourcePlayer.player.setSpecOptions(eventID, specOptions); console.log(`Inferring player ${sourcePlayer.name} is targeting ${targetPlayer.name} with ${spell.name} from cast event`); } @@ -510,7 +511,7 @@ export class RaidWCLImporter extends Importer { raid.parties[partyIdx].players[positionInParty] = playerProto; if (isTankSpec(playerToSpec(playerProto))) { - raid.tanks.push(player.toRaidTarget()); + raid.tanks.push(player.toUnitReference()); } }); @@ -606,9 +607,10 @@ class WCLSimPlayer { return matchingPresets[presetIdx]; } - public toRaidTarget(): RaidTarget { - return RaidTarget.create({ - targetIndex: this.raidIndex, + public toUnitReference(): UnitReference { + return UnitReference.create({ + type: UnitReference_Type.Player, + index: this.raidIndex, }); } @@ -691,30 +693,30 @@ const professionSpells: Array<{ id: number, name: string, profession: Profession { id: 50305, name: 'Skinning', profession: Profession.Skinning }, ]; -const externalCDSpells: Array<{ id: number, name: string, class: Class, applyFunc: (player: Player, raidTarget: RaidTarget) => SpecOptions }> = [ +const externalCDSpells: Array<{ id: number, name: string, class: Class, applyFunc: (player: Player, raidTarget: UnitReference) => SpecOptions }> = [ { - id: 29166, name: 'Innervate', class: Class.ClassDruid, applyFunc: (player: Player, raidTarget: RaidTarget) => { + id: 29166, name: 'Innervate', class: Class.ClassDruid, applyFunc: (player: Player, raidTarget: UnitReference) => { const options = player.getSpecOptions() as SpecOptions; options.innervateTarget = raidTarget; return options; } }, { - id: 10060, name: 'Power Infusion', class: Class.ClassPriest, applyFunc: (player: Player, raidTarget: RaidTarget) => { + id: 10060, name: 'Power Infusion', class: Class.ClassPriest, applyFunc: (player: Player, raidTarget: UnitReference) => { const options = player.getSpecOptions() as SpecOptions; options.powerInfusionTarget = raidTarget; return options; } }, { - id: 57933, name: 'Tricks of the Trade', class: Class.ClassRogue, applyFunc: (player: Player, raidTarget: RaidTarget) => { + id: 57933, name: 'Tricks of the Trade', class: Class.ClassRogue, applyFunc: (player: Player, raidTarget: UnitReference) => { const options = player.getSpecOptions() as SpecOptions; options.tricksOfTheTradeTarget = raidTarget; return options; } }, { - id: 49016, name: 'Unholy Frenzy', class: Class.ClassDeathknight, applyFunc: (player: Player, raidTarget: RaidTarget) => { + id: 49016, name: 'Unholy Frenzy', class: Class.ClassDeathknight, applyFunc: (player: Player, raidTarget: UnitReference) => { const options = player.getSpecOptions() as SpecOptions; options.unholyFrenzyTarget = raidTarget; return options; diff --git a/ui/raid/raid_picker.ts b/ui/raid/raid_picker.ts index 5cc68ae608..0e97f9f7d9 100644 --- a/ui/raid/raid_picker.ts +++ b/ui/raid/raid_picker.ts @@ -13,7 +13,7 @@ import { Glyphs } from '../core/proto/common.js'; import { cssClassForClass, playerToSpec } from '../core/proto_utils/utils.js'; import { isTankSpec } from '../core/proto_utils/utils.js'; import { specToClass } from '../core/proto_utils/utils.js'; -import { newRaidTarget } from '../core/proto_utils/utils.js'; +import { newUnitReference } from '../core/proto_utils/utils.js'; import { EventID, TypedEvent } from '../core/typed_event.js'; import { formatDeltaTextElem } from '../core/utils.js'; import { getEnumValues } from '../core/utils.js'; @@ -704,13 +704,13 @@ class NewPlayerPicker extends Component { function applyNewPlayerAssignments(eventID: EventID, newPlayer: Player, raid: Raid) { if (isTankSpec(newPlayer.spec)) { const tanks = raid.getTanks(); - const emptyIdx = tanks.findIndex(tank => raid.getPlayerFromRaidTarget(tank) == null); + const emptyIdx = tanks.findIndex(tank => raid.getPlayerFromUnitReference(tank) == null); if (emptyIdx == -1) { if (tanks.length < 3) { - raid.setTanks(eventID, tanks.concat([newPlayer.makeRaidTarget()])); + raid.setTanks(eventID, tanks.concat([newPlayer.makeUnitReference()])); } } else { - tanks[emptyIdx] = newPlayer.makeRaidTarget(); + tanks[emptyIdx] = newPlayer.makeUnitReference(); raid.setTanks(eventID, tanks); } } @@ -718,15 +718,15 @@ function applyNewPlayerAssignments(eventID: EventID, newPlayer: Player, rai // Spec-specific assignments. For most cases, default to buffing self. if (newPlayer.spec == Spec.SpecBalanceDruid) { const newOptions = newPlayer.getSpecOptions() as BalanceDruidOptions; - newOptions.innervateTarget = newRaidTarget(newPlayer.getRaidIndex()); + newOptions.innervateTarget = newUnitReference(newPlayer.getRaidIndex()); newPlayer.setSpecOptions(eventID, newOptions); } else if (newPlayer.spec == Spec.SpecSmitePriest) { const newOptions = newPlayer.getSpecOptions() as SmitePriestOptions; - newOptions.powerInfusionTarget = newRaidTarget(newPlayer.getRaidIndex()); + newOptions.powerInfusionTarget = newUnitReference(newPlayer.getRaidIndex()); newPlayer.setSpecOptions(eventID, newOptions); } else if (newPlayer.spec == Spec.SpecMage) { const newOptions = newPlayer.getSpecOptions() as MageOptions; - newOptions.focusMagicTarget = newRaidTarget(newPlayer.getRaidIndex()); + newOptions.focusMagicTarget = newUnitReference(newPlayer.getRaidIndex()); newPlayer.setSpecOptions(eventID, newOptions); } } diff --git a/ui/raid/tanks_picker.ts b/ui/raid/tanks_picker.ts index bbffc8b2b3..93838e24c9 100644 --- a/ui/raid/tanks_picker.ts +++ b/ui/raid/tanks_picker.ts @@ -1,11 +1,11 @@ import { Component } from '../core/components/component'; -import { RaidTargetPicker } from '../core/components/raid_target_picker'; +import { UnitReferencePicker } from '../core/components/raid_target_picker'; import { Raid } from '../core/raid'; import { EventID } from '../core/typed_event'; -import { RaidTarget } from '../core/proto/common'; -import { emptyRaidTarget } from '../core/proto_utils/utils'; +import { UnitReference } from '../core/proto/common'; +import { emptyUnitReference } from '../core/proto_utils/utils'; import { RaidSimUI } from './raid_sim_ui'; @@ -30,18 +30,18 @@ export class TanksPicker extends Component { labelElem.classList.add('tank-picker-label', 'form-label'); row.appendChild(labelElem); - new RaidTargetPicker(row, raid, raid, { + new UnitReferencePicker(row, raid, raid, { extraCssClasses: ['tank-picker'], noTargetLabel: 'Unassigned', compChangeEmitter: raid.compChangeEmitter, changedEvent: (raid: Raid) => raid.tanksChangeEmitter, - getValue: (raid: Raid) => raid.getTanks()[i] || emptyRaidTarget(), - setValue: (eventID: EventID, raid: Raid, newValue: RaidTarget) => { + getValue: (raid: Raid) => raid.getTanks()[i] || emptyUnitReference(), + setValue: (eventID: EventID, raid: Raid, newValue: UnitReference) => { const tanks = raid.getTanks(); for (let j = 0; j < i; j++) { if (!tanks[j]) { - tanks.push(emptyRaidTarget()); + tanks.push(emptyUnitReference()); } } tanks[i] = newValue; diff --git a/ui/restoration_druid/inputs.ts b/ui/restoration_druid/inputs.ts index ad96d74185..e44dea933d 100644 --- a/ui/restoration_druid/inputs.ts +++ b/ui/restoration_druid/inputs.ts @@ -1,6 +1,5 @@ -import { RaidTarget } from '../core/proto/common.js'; +import { UnitReference, UnitReference_Type as UnitType } from '../core/proto/common.js'; import { Spec } from '../core/proto/common.js'; -import { NO_TARGET } from '../core/proto_utils/utils.js'; import { ActionId } from '../core/proto_utils/action_id.js'; import { Player } from '../core/player.js'; import { EventID, TypedEvent } from '../core/typed_event.js'; @@ -21,11 +20,12 @@ export const SelfInnervate = InputHelpers.makeSpecOptionsBooleanIconInput) => player.getSpecOptions().innervateTarget?.targetIndex != NO_TARGET, + getValue: (player: Player) => player.getSpecOptions().innervateTarget?.type == UnitType.Player, setValue: (eventID: EventID, player: Player, newValue: boolean) => { const newOptions = player.getSpecOptions(); - newOptions.innervateTarget = RaidTarget.create({ - targetIndex: newValue ? 0 : NO_TARGET, + newOptions.innervateTarget = UnitReference.create({ + type: newValue ? UnitType.Player : UnitType.Unknown, + index: 0, }); player.setSpecOptions(eventID, newOptions); }, diff --git a/ui/restoration_druid/presets.ts b/ui/restoration_druid/presets.ts index 630dca62c9..c01dafa6c3 100644 --- a/ui/restoration_druid/presets.ts +++ b/ui/restoration_druid/presets.ts @@ -9,7 +9,7 @@ import { PartyBuffs, Potions, RaidBuffs, - RaidTarget, + UnitReference, TristateEffect } from '../core/proto/common.js'; import { SavedTalents } from '../core/proto/ui.js'; @@ -22,7 +22,6 @@ import { } from '../core/proto/druid.js'; import * as Tooltips from '../core/constants/tooltips.js'; -import { NO_TARGET } from "../core/proto_utils/utils"; // Preset options for this spec. // Eventually we will import these values for the raid sim too, so its good to @@ -63,9 +62,7 @@ export const DefaultRotation = RestorationDruidRotation.create({ }); export const DefaultOptions = RestorationDruidOptions.create({ - innervateTarget: RaidTarget.create({ - targetIndex: NO_TARGET, - }), + innervateTarget: UnitReference.create(), }); export const DefaultConsumes = Consumes.create({ diff --git a/ui/scss/core/components/_unit_picker.scss b/ui/scss/core/components/_unit_picker.scss index 71ef8357c5..4b67736995 100644 --- a/ui/scss/core/components/_unit_picker.scss +++ b/ui/scss/core/components/_unit_picker.scss @@ -11,12 +11,12 @@ height: 30px; } -.unit-filter-icon { +.unit-picker-item-icon { margin: 2px; height: 25px; } -.unit-filter-label { +.unit-picker-item-label { font-size: 14px; margin: 2px; } diff --git a/ui/shadow_priest/sim.ts b/ui/shadow_priest/sim.ts index e08539f32a..691aaf8f99 100644 --- a/ui/shadow_priest/sim.ts +++ b/ui/shadow_priest/sim.ts @@ -7,7 +7,7 @@ import { Consumes } from '../core/proto/common.js'; import { Encounter } from '../core/proto/common.js'; import { ItemSlot } from '../core/proto/common.js'; import { MobType } from '../core/proto/common.js'; -import { RaidTarget } from '../core/proto/common.js'; +import { UnitReference } from '../core/proto/common.js'; import { Spec } from '../core/proto/common.js'; import { Stat } from '../core/proto/common.js'; import { TristateEffect } from '../core/proto/common.js' diff --git a/ui/smite_priest/inputs.ts b/ui/smite_priest/inputs.ts index 4018e0dee6..97ea4aa9f6 100644 --- a/ui/smite_priest/inputs.ts +++ b/ui/smite_priest/inputs.ts @@ -1,6 +1,5 @@ -import { RaidTarget } from '../core/proto/common.js'; +import { UnitReference, UnitReference_Type as UnitType } from '../core/proto/common.js'; import { Spec } from '../core/proto/common.js'; -import { NO_TARGET } from '../core/proto_utils/utils.js'; import { ActionId } from '../core/proto_utils/action_id.js'; import { Player } from '../core/player.js'; import { EventID, TypedEvent } from '../core/typed_event.js'; @@ -16,11 +15,12 @@ export const SelfPowerInfusion = InputHelpers.makeSpecOptionsBooleanIconInput) => player.getSpecOptions().powerInfusionTarget?.targetIndex != NO_TARGET, + getValue: (player: Player) => player.getSpecOptions().powerInfusionTarget?.type == UnitType.Player, setValue: (eventID: EventID, player: Player, newValue: boolean) => { const newOptions = player.getSpecOptions(); - newOptions.powerInfusionTarget = RaidTarget.create({ - targetIndex: newValue ? 0 : NO_TARGET, + newOptions.powerInfusionTarget = UnitReference.create({ + type: newValue ? UnitType.Player : UnitType.Unknown, + index: 0, }); player.setSpecOptions(eventID, newOptions); }, diff --git a/ui/smite_priest/presets.ts b/ui/smite_priest/presets.ts index 7d69e13f97..8a4ecae4ec 100644 --- a/ui/smite_priest/presets.ts +++ b/ui/smite_priest/presets.ts @@ -9,11 +9,10 @@ import { Faction } from '../core/proto/common.js'; import { RaidBuffs } from '../core/proto/common.js'; import { IndividualBuffs } from '../core/proto/common.js'; import { Debuffs } from '../core/proto/common.js'; -import { RaidTarget } from '../core/proto/common.js'; +import { UnitReference } from '../core/proto/common.js'; import { TristateEffect } from '../core/proto/common.js'; import { SavedTalents } from '../core/proto/ui.js'; import { Player } from '../core/player.js'; -import { NO_TARGET } from '../core/proto_utils/utils.js'; import { SmitePriest_Rotation as Rotation, @@ -55,9 +54,7 @@ export const DefaultOptions = Options.create({ useInnerFire: true, useShadowfiend: true, - powerInfusionTarget: RaidTarget.create({ - targetIndex: NO_TARGET, // In an individual sim the 0-indexed player is ourself. - }), + powerInfusionTarget: UnitReference.create(), }); export const DefaultConsumes = Consumes.create({ diff --git a/ui/smite_priest/sim.ts b/ui/smite_priest/sim.ts index 705399e277..53c0fbc38d 100644 --- a/ui/smite_priest/sim.ts +++ b/ui/smite_priest/sim.ts @@ -7,7 +7,7 @@ import { Consumes } from '../core/proto/common.js'; import { Encounter } from '../core/proto/common.js'; import { ItemSlot } from '../core/proto/common.js'; import { MobType } from '../core/proto/common.js'; -import { RaidTarget } from '../core/proto/common.js'; +import { UnitReference } from '../core/proto/common.js'; import { Spec } from '../core/proto/common.js'; import { Stat } from '../core/proto/common.js'; import { TristateEffect } from '../core/proto/common.js' diff --git a/ui/warlock/inputs.ts b/ui/warlock/inputs.ts index d67a270958..1521cdb7b1 100644 --- a/ui/warlock/inputs.ts +++ b/ui/warlock/inputs.ts @@ -11,8 +11,7 @@ import { Warlock_Options_Summon as Summon, } from '../core/proto/warlock.js'; -import { RaidTarget, Spec, Glyphs, Debuffs, IndividualBuffs, RaidBuffs, ItemSwap, ItemSlot } from '../core/proto/common.js'; -import { NO_TARGET } from '../core/proto_utils/utils.js'; +import { UnitReference, Spec, Glyphs, Debuffs, IndividualBuffs, RaidBuffs, ItemSwap, ItemSlot } from '../core/proto/common.js'; import { ActionId } from '../core/proto_utils/action_id.js'; import { Player } from '../core/player.js'; import { EventID, TypedEvent } from '../core/typed_event.js'; diff --git a/ui/warrior/sim.ts b/ui/warrior/sim.ts index 5b2b75789b..cd1c0c573e 100644 --- a/ui/warrior/sim.ts +++ b/ui/warrior/sim.ts @@ -7,7 +7,7 @@ import { Consumes } from '../core/proto/common.js'; import { Encounter } from '../core/proto/common.js'; import { ItemSlot } from '../core/proto/common.js'; import { MobType } from '../core/proto/common.js'; -import { RaidTarget } from '../core/proto/common.js'; +import { UnitReference } from '../core/proto/common.js'; import { Spec } from '../core/proto/common.js'; import { Stat, PseudoStat } from '../core/proto/common.js'; import { TristateEffect } from '../core/proto/common.js'