protected override IReadOnlyList <MatcherData> CreateCollection() =>
 new ValueConversionMatcherCollection(_modifierBuilder)
 {
     // action
     { "for each enemy you've killed recently", Kill.CountRecently },
     { "per enemy killed recently, up to #%", CappedMultiplier(Kill.CountRecently, Value) },
     {
         "per enemy killed by you or your totems recently",
         Kill.CountRecently + Kill.By(Entity.Totem).CountRecently
     },
     {
         "for each enemy you or your minions have killed recently, up to #%( per second)?",
         CappedMultiplier(Kill.CountRecently + Kill.By(Entity.Minion).CountRecently, Value)
     },
     { "for each hit you've blocked recently", Block.CountRecently },
     { "for each corpse consumed recently", Action.ConsumeCorpse.CountRecently },
     // equipment
     { "for each magic item( you have)? equipped", Equipment.Count(e => e.Has(FrameType.Magic)) },
     // stats
     { "per # accuracy rating", PerStat(Stat.Accuracy.With(AttackDamageHand.MainHand)) },
     { "per #%? ({StatMatchers})(?! leech)", PerStat(stat: Reference.AsStat, divideBy: Value) },
     {
         "per # ({StatMatchers}), up to #%",
         CappedMultiplier((Reference.AsStat.Value / Values[0]).Floor(), Values[1])
     },
     { "per # ({StatMatchers}) ceiled", PerStatCeiled(stat: Reference.AsStat, divideBy: Value) },
     { "per ({StatMatchers})(?! leech)", PerStat(stat: Reference.AsStat) },
     { "per ({StatMatchers}), up to #%", CappedMultiplier(Reference.AsStat.Value, Value) },
     {
         "per # ({StatMatchers}) on helmet",
         PerStat(Reference.AsStat.ValueFor(NodeType.Base, new ModifierSource.Local.Item(ItemSlot.Helm)),
                 divideBy: Value)
     },
     {
         "per # ({StatMatchers}) on body armour",
         PerStat(
             Reference.AsStat.ValueFor(NodeType.Base, new ModifierSource.Local.Item(ItemSlot.BodyArmour)),
             divideBy: Value)
     },
     { "per grand spectrum", PerStat(stat: Stat.GrandSpectrumJewelsSocketed) },
     { "per level", PerStat(Stat.Level) },
     { "per (stage|fuse charge)", PerStat(Stat.SkillStage) },
     { "for each (stage|blade)", PerStat(Stat.SkillStage) },
     { @"per stage, up to \+#", CappedMultiplier(Stat.SkillStage.Value, Value) },
     { "per stage after the first", PerStatAfterFirst(Stat.SkillStage) },
     {
         "per ({ChargeTypeMatchers}) removed",
         Reference.AsChargeType.Amount.Value - Reference.AsChargeType.Amount.Minimum.Value
     },
     {
         "when placed, (?<inner>.*) per stage",
         Stat.BannerStage.Value, Flag.IsBannerPlanted, "${inner}"
     },
     { "per nearby enemy", Enemy.CountNearby },
     { "per one hundred nearby enemies", Enemy.CountNearby / 100 },
     { @"per nearby enemy, up to \+#%?", CappedMultiplier(Enemy.CountNearby, Value) },
     {
         "per # unreserved maximum mana, up to #%",
         CappedMultiplier(((Mana.Value - Mana.Reservation.Value) / Values[0]).Floor(), Values[1])
     },
     {
         "per # mana spent recently, up to #%",
         CappedMultiplier(Action.SpendMana(Values[0]).CountRecently, Values[1])
     },
     {
         "per # additional melee range",
         PerStat(Stat.Range.With(AttackDamageHand.MainHand).ValueFor(NodeType.BaseAdd), Value)
     },
     // buffs
     { "per buff on you", Buffs(targets: Self).Count() },
     { "per curse on you", Buffs(targets: Self).With(Keyword.Curse).Count() },
     { "per curse on enemy", Buffs(targets: Enemy).With(Keyword.Curse).Count() },
     { "for each curse on that enemy,", Buffs(targets: Enemy).With(Keyword.Curse).Count() },
     { "for each impale on enemy", Buff.Impale.StackCount.For(Enemy).Value },
     // ailments
     { "for each poison on the enemy", Ailment.Poison.InstancesOn(Enemy).Value },
     { "per poison on enemy", Ailment.Poison.InstancesOn(Enemy).Value },
     { "per poison on you", Ailment.Poison.InstancesOn(Self).Value },
     { "per poison(?= affecting enemies)", Ailment.Poison.InstancesOn(Enemy).Value },
     {
         @"per poison affecting enemy, up to \+#%",
         CappedMultiplier(Ailment.Poison.InstancesOn(Enemy).Value, Value)
     },
     {
         "for each poison on the enemy, up to #",
         CappedMultiplier(Ailment.Poison.InstancesOn(Enemy).Value, Value)
     },
     { "per elemental ailment on the enemy", Ailment.Elemental.Count(b => b.IsOn(Enemy)) },
     // skills
     { "for each zombie you own", Skills.RaiseZombie.Instances.Value },
     { "for each raised zombie", Skills.RaiseZombie.Instances.Value },
     { "for each summoned golem", Golems.CombinedInstances.Value },
     { "per summoned golem", Golems.CombinedInstances.Value },
     { "for each golem you have summoned", Golems.CombinedInstances.Value },
     { "for each type of golem you have summoned", Golems.CombinedInstances.Value },
     {
         "per minion, up to #%",
         CappedMultiplier(Skills[Keyword.Minion].CombinedInstances.Value, Value)
     },
     {
         "for each skill you've used Recently, up to #%",
         CappedMultiplier(AllSkills.Cast.CountRecently, Value)
     },
     // traps, mines, totems
     { "for each trap", Traps.CombinedInstances.Value },
     { "for each mine", Mines.CombinedInstances.Value },
     { "for each trap and mine you have", Traps.CombinedInstances.Value + Mines.CombinedInstances.Value },
     { "(per|for each) totem", Totems.CombinedInstances.Value },
     {
         "each mine( from supported skills)? applies (?<inner>.*) to( hits against)? enemies near it, up to( a maximum of)? #%",
         CappedMultiplier(MineAura(), Value),
         "${inner}"
     },
     {
         "each mine (?<inner>.*) to( hits against)? enemies near it, up to( a maximum of)? # to #",
         CappedMultiplier(MineAura(), ValueFactory.FromMinAndMax(Values[0], Values[1])),
         "${inner}"
     },
     // jewels
     {
         "(per|for every) # ({AttributeStatMatchers}) (allocated|(from|on) allocated passives) in radius",
         PerStat(PassiveTree.AllocatedInModifierSourceJewelRadius(Reference.AsStat), Value)
     },
     {
         "(per|for every) # ({AttributeStatMatchers}) (from|on) unallocated passives in radius",
         PerStat(PassiveTree.UnallocatedInModifierSourceJewelRadius(Reference.AsStat), Value)
     },
     // unique
     {
         "for each poison you have inflicted recently",
         Stat.UniqueAmount("# of Poisons inflicted Recently")
     },
     {
         "for each remaining chain",
         AtLeastZero(Projectile.ChainCount.Value - Stat.UniqueAmount("Projectile.ChainedCount"))
     },
     { "per chain", Stat.UniqueAmount("Projectile.ChainedCount") },
     { "for each enemy pierced", Stat.UniqueAmount("Projectile.PiercedCount") },
     {
         "for each (of your mines|mine) detonated recently, up to #%( per second)?",
         CappedMultiplier(Stat.UniqueAmount("# of Mines Detonated Recently"), Value)
     },
     {
         "for each (of your traps|trap) triggered recently, up to #%( per second)?",
         CappedMultiplier(Stat.UniqueAmount("# of Traps Triggered Recently"), Value)
     },
     {
         "for each time you've blocked in the past 10 seconds",
         Stat.UniqueAmount("# of times blocked in the past 10 seconds")
     },
     {
         "for each endurance charge lost recently, up to #%",
         CappedMultiplier(Stat.UniqueAmount("# of Endurance Charges lost recently"), Value)
     },
     {
         "for each nearby corpse, (?<inner>.*) up to #%? per second",
         CappedMultiplier(Stat.UniqueAmount("# of nearby Corpses"), Value), "${inner}"
     },
     {
         "for each prior mine in detonation sequence",
         CappedMultiplier(
             Stat.UniqueAmount("# of prior mines in detonation sequence"),
             Mines.CombinedInstances.Maximum.Value)
     },
     {
         "for every # prior mines in detonation sequence",
         CappedMultiplier(
             (Stat.UniqueAmount("# of prior mines in detonation sequence") / Value).Floor(),
             Mines.CombinedInstances.Maximum.Value)
     },
 };     // add
 private GivenStatCollection CreateCollection() => Expand(new GivenStatCollection(_modifierBuilder, ValueFactory)
 {
     // passive points
     { BaseSet, Stat.PassivePoints.Maximum, Stat.Level.Value - 1 },
     { BaseAdd, Stat.PassivePoints.Maximum, 22 },
     { BaseSet, Stat.AscendancyPassivePoints.Maximum, 8 },
     // pools
     { BaseSet, Life, CharacterClassBased(_characterBaseStats.Life, "Life") },
     { BaseSet, Mana, CharacterClassBased(_characterBaseStats.Mana, "Mana") },
     { BaseSet, Mana.Regen.Percent, 1.75 },
     // other basic stats
     { BaseSet, Attribute.Strength, CharacterClassBased(_characterBaseStats.Strength, "Strength") },
     { BaseSet, Attribute.Dexterity, CharacterClassBased(_characterBaseStats.Dexterity, "Dexterity") },
     { BaseSet, Attribute.Intelligence, CharacterClassBased(_characterBaseStats.Intelligence, "Intelligence") },
     { BaseSet, Evasion, 53 },
     { BaseSet, Stat.Accuracy, -2 }, // 0 at level 1 with no dexterity
     { BaseSet, CriticalStrike.Multiplier, 150 },
     { BaseAdd, Ground.Consecrated.AddStat(Life.Regen), 6 },
     // resistances
     { BaseSet, AnyDamageType.DamageReduction.Maximum, 90 },
     { BaseSet, AnyDamageType.DamageReductionIncludingArmour.Maximum, 90 },
     // traps, mines and totems
     { BaseSet, Traps.CombinedInstances.Maximum, 15 },
     { BaseSet, Mines.CombinedInstances.Maximum, 15 },
     { BaseSet, Totems.CombinedInstances.Maximum, 1 },
     { BaseSet, Stat.Totem.BaseTime, 0.6 },
     { BaseSet, Stat.Trap.BaseTime, 0.5 },
     { BaseSet, Stat.Mine.BaseTime, 0.3 },
     // rage
     { BaseSet, Charge.Rage.Amount.Maximum, 50 },
     { BaseSet, Charge.RageEffect, 1 },
     {
         PercentIncrease, Damage.WithSkills(DamageSource.Attack),
         Charge.Rage.Amount.Value * Charge.RageEffect.Value
     },
     {
         PercentIncrease, Stat.CastRate.With(DamageSource.Attack),
         PerStat(Charge.Rage.Amount, 2) * Charge.RageEffect.Value
     },
     { PercentIncrease, Stat.MovementSpeed, PerStat(Charge.Rage.Amount, 5) * Charge.RageEffect.Value },
     { BaseSubtract, Life.Regen.Percent, 0.1 * Charge.Rage.Amount.Value * Charge.RageEffect.Value },
     // unarmed
     {
         BaseSet, Stat.Range,
         CharacterClassBased(_characterBaseStats.UnarmedRange, "UnarmedRange"), Not(MainHand.HasItem)
     },
     { BaseSet, CriticalStrike.Chance.With(AttackDamageHand.MainHand), 0, Not(MainHand.HasItem) },
     {
         BaseSet, Stat.BaseCastTime.With(AttackDamageHand.MainHand),
         CharacterClassBased(_characterBaseStats.UnarmedAttackTime, "UnarmedAttackTime") / 1000,
         Not(MainHand.HasItem)
     },
     {
         BaseSet, Physical.Damage.WithSkills.With(AttackDamageHand.MainHand),
         Stat.CharacterClass.Value.Select(
             c => UnarmedPhysicalDamage((CharacterClass)(int)c.Single),
             c => $"{c}.UnarmedPhysicalDamage"),
         Not(MainHand.HasItem)
     },
     { BaseSet, MainHand.ItemClass, (double)ItemClass.Unarmed, Not(MainHand.HasItem) },
     // buff configuration
     { TotalOverride, Buff.Onslaught.On(Self), 1, Condition.Unique("Onslaught.ExplicitlyActive") },
     { TotalOverride, Buff.UnholyMight.On(Self), 1, Condition.Unique("UnholyMight.ExplicitlyActive") },
     { TotalOverride, Buff.Fortify.On(Self), 1, Condition.Unique("Fortify.ExplicitlyActive") },
     { TotalOverride, Buff.Tailwind.On(Self), 1, Condition.Unique("Tailwind.ExplicitlyActive") },
     { TotalOverride, Buff.Infusion.On(Self), 1, Condition.Unique("Infusion.ExplicitlyActive") },
     { TotalOverride, Buff.Elusive.On(Self), 1, Condition.Unique("Elusive.ExplicitlyActive") },
     { PercentReduce, Buff.Elusive.Effect, 20 * Stat.UniqueAmount("Elusive.SecondsOfDecay", 2.5) },
     // character class connections
     {
         TotalOverride, PassiveTree.ConnectsToClass(CharacterClass.Scion), 1,
         Stat.CharacterClass.Value.Eq((int)CharacterClass.Scion)
     },
     {
         TotalOverride, PassiveTree.ConnectsToClass(CharacterClass.Marauder), 1,
         Stat.CharacterClass.Value.Eq((int)CharacterClass.Marauder)
     },
     {
         TotalOverride, PassiveTree.ConnectsToClass(CharacterClass.Ranger), 1,
         Stat.CharacterClass.Value.Eq((int)CharacterClass.Ranger)
     },
     {
         TotalOverride, PassiveTree.ConnectsToClass(CharacterClass.Witch), 1,
         Stat.CharacterClass.Value.Eq((int)CharacterClass.Witch)
     },
     {
         TotalOverride, PassiveTree.ConnectsToClass(CharacterClass.Duelist), 1,
         Stat.CharacterClass.Value.Eq((int)CharacterClass.Duelist)
     },
     {
         TotalOverride, PassiveTree.ConnectsToClass(CharacterClass.Templar), 1,
         Stat.CharacterClass.Value.Eq((int)CharacterClass.Templar)
     },
     {
         TotalOverride, PassiveTree.ConnectsToClass(CharacterClass.Shadow), 1,
         Stat.CharacterClass.Value.Eq((int)CharacterClass.Shadow)
     },
 });
Beispiel #3
0
    // Start is called before the first frame update

    public Player()
    {
        roundManager   = new RoundManager();
        ascendancyTree = new AscendancyTree();
        passiveTree    = new PassiveTree();
    }