示例#1
0
 protected override IEnumerable <MatcherData> CreateCollection() =>
 new ValueConversionMatcherCollection(_modifierBuilder, ValueFactory)
 {
     // action
     { "for each enemy you've killed recently", Kill.CountRecently },
     {
         "per enemy killed by you or your totems recently",
         Kill.CountRecently + Kill.By(Entity.Totem).CountRecently
     },
     { "for each hit you've blocked recently", Block.CountRecently },
     { "for each corpse consumed recently", Action.ConsumeCorpse.CountRecently },
     // equipment
     { "for each type of golem you have summoned", Golems.Count(s => s.HasInstance) },
     { "for each magic item you have equipped", Equipment.Count(e => e.Has(FrameType.Magic)) },
     // stats
     { "per # ({StatMatchers})", PerStat(stat: Reference.AsStat, divideBy: Value) },
     { "per # ({StatMatchers}) ceiled", PerStatCeiled(stat: Reference.AsStat, divideBy: Value) },
     { "per ({StatMatchers})", PerStat(stat: Reference.AsStat) },
     { "per grand spectrum", PerStat(stat: Stat.GrandSpectrumJewelsSocketed) },
     { "per level", PerStat(Self.Level) },
     // buffs
     { "per buff on you", Buffs(target: Self).ExceptFrom(Skill.BloodRage, Skill.MoltenShell).Count() },
     { "per curse on you", Buffs(target: Self).With(Keyword.Curse).Count() },
     { "for each curse on that enemy,", Buffs(target: Enemy).With(Keyword.Curse).Count() },
     // ailments
     { "for each poison on the enemy", Ailment.Poison.InstancesOn(Enemy).Value },
     { "per poison on enemy", Ailment.Poison.InstancesOn(Enemy).Value },
     // skills
     { "for each zombie you own", Skill.RaiseZombie.Instances.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 totem", Totems.CombinedInstances.Value },
 };
示例#2
0
 protected override IEnumerable <MatcherData> CreateCollection() =>
 new ConditionMatcherCollection(_modifierBuilder)
 {
     // generic
     { "on ({ActionMatchers})", Reference.AsAction.On },
     {
         "when you ({ActionMatchers}) a rare or unique enemy",
         And(Enemy.IsRareOrUnique, Reference.AsAction.On)
     },
     {
         "when you ({ActionMatchers}) a ({AilmentMatchers}) enemy",
         And(References[1].AsAilment.IsOn(Enemy), References[0].AsAction.On)
     },
     // kill
     { "on ({KeywordMatchers}) kill", And(With(Reference.AsKeyword), Kill.On) },
     { "when you kill an enemy", Kill.On },
     { "if you or your totems kill an enemy", Or(Kill.On, Kill.By(Entity.Totem).On) },
     // hit
     { "when you are hit", Hit.By(Enemy).On },
     { "with hits", Hit.On },
     { "for each enemy hit by your attacks", And(With(Keyword.Attack), Hit.On) },
     {
         "when you or your totems hit an enemy with a spell",
         And(With(Keyword.Spell), Hit.On.Or(Hit.By(Entity.Totem).On))
     },
     // critical strike
     { "critical strikes have a", CriticalStrike.On },
     { "when you deal a critical strike", CriticalStrike.On },
     { "if you get a critical strike", CriticalStrike.On },
     // skill cast
     { "when you place a totem", Totems.Cast.On },
     { "when you use a warcry", Skills[Keyword.Warcry].Cast.On },
     // block
     { "when they block", Block.On },
     { "when you block", Block.On },
     // other
     { "when you stun an enemy", Action.Stun.On },
     { "after spending( a total of)? # mana", Action.SpendMana(Value).On },
     { "when you gain a ({ChargeTypeMatchers})", Reference.AsChargeType.GainAction.On },
     { "you gain", Condition.True },     // may be left over at the end, does nothing
     { "you", Condition.True },
     // unique
     {
         "when your trap is triggered by an enemy",
         Action.Unique("When your Trap is triggered by an Enemy").On
     },
     {
         "when your mine is detonated targeting an enemy",
         Action.Unique("When your Mine is detonated targeting an Enemy").On
     },
 };     // add
 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
示例#4
0
 protected override IEnumerable <MatcherData> CreateCollection() =>
 new ConditionMatcherCollection(_modifierBuilder)
 {
     // actions
     // - generic
     { "on ({ActionMatchers})", Reference.AsAction.On() },
     { "if you've ({ActionMatchers}) recently", Reference.AsAction.Recently },
     { "if you haven't ({ActionMatchers}) recently", Not(Reference.AsAction.Recently) },
     {
         "when you ({ActionMatchers}) a rare or unique enemy",
         And(Reference.AsAction.Against(Enemy).On(), Enemy.IsRareOrUnique)
     },
     // - kill
     { "on ({KeywordMatchers}) kill", Kill.On(Reference.AsKeyword) },
     { "when you kill an enemy,", Kill.Against(Enemy).On() },
     {
         "if you've killed a maimed enemy recently",
         And(Kill.Against(Enemy).Recently, Buff.Maim.IsOn(Enemy))
     },
     {
         "if you've killed a bleeding enemy recently",
         And(Kill.Against(Enemy).Recently, Ailment.Bleed.IsOn(Enemy))
     },
     {
         "if you've killed a cursed enemy recently",
         And(Kill.Against(Enemy).Recently, Buffs(target: Enemy).With(Keyword.Curse).Any())
     },
     {
         "if you or your totems have killed recently",
         Or(Kill.Recently, Kill.By(Entity.Totem).Recently)
     },
     { "if you or your totems kill an enemy", Or(Kill.On(), Kill.By(Entity.Totem).On()) },
     // - block
     { "when they block", Block.On() },
     { "when you block", Block.On() },
     {
         "if you've blocked a hit from a unique enemy recently",
         And(Block.Against(Enemy).Recently, Enemy.IsUnique)
     },
     // - hit
     { "(from|with) hits", Hit.On() },
     { "hits deal", Hit.On() },
     { "when you are hit", Hit.Taken.On() },
     { "if you've been hit recently", Hit.Taken.Recently },
     { "if you haven't been hit recently", Not(Hit.Taken.Recently) },
     { "if you were damaged by a hit recently", Hit.Taken.Recently },
     { "if you've taken no damage from hits recently", Not(Hit.Taken.Recently) },
     // - other
     { "if you've taken a savage hit recently", Action.SavageHit.Taken.Recently },
     { "when you deal a critical strike", CriticalStrike.On() },
     { "if you've crit in the past # seconds", CriticalStrike.InPastXSeconds(Value) },
     { "if you've shattered an enemy recently", Action.Shatter.Against(Enemy).Recently },
     { "when you stun an enemy", Effect.Stun.On() },
     { "after spending # mana", Action.SpendMana(Value).On() },
     { "if you have consumed a corpse recently", Action.ConsumeCorpse.Recently },
     { "when you gain a ({ChargeTypeMatchers})", Reference.AsChargeType.GainAction.On() },
     // damage
     // - by item tag
     { "with weapons", Damage.With(Tags.Weapon) },
     { "weapon", Damage.With(Tags.Weapon) },
     { "with bows", Damage.With(Tags.Bow) },
     { "bow", Damage.With(Tags.Bow) },
     { "with swords", Damage.With(Tags.Sword) },
     { "with claws", Damage.With(Tags.Claw) },
     { "claw", Damage.With(Tags.Claw) },
     { "with daggers", Damage.With(Tags.Dagger) },
     { "with wands", Damage.With(Tags.Wand) },
     { "wand", Damage.With(Tags.Wand) },
     { "with axes", Damage.With(Tags.Axe) },
     { "with staves", Damage.With(Tags.Staff) },
     { "with maces", Or(Damage.With(Tags.Mace), Damage.With(Tags.Sceptre)) },
     { "with one handed weapons", Damage.With(Tags.OneHandWeapon) },
     {
         "with one handed melee weapons",
         And(Damage.With(Tags.OneHandWeapon), Not(Damage.With(Tags.Ranged)))
     },
     { "with two handed weapons", Damage.With(Tags.TwoHandWeapon) },
     {
         "with two handed melee weapons",
         And(Damage.With(Tags.TwoHandWeapon), Not(Damage.With(Tags.Ranged)))
     },
     // - by item slot
     { "with the main-hand weapon", Damage.With(ItemSlot.MainHand) },
     { "with main hand", Damage.With(ItemSlot.MainHand) },
     { "with off hand", Damage.With(ItemSlot.OffHand) },
     // - by source
     { "attacks have", Damage.With(Source.Attack) },
     { "with attacks", Damage.With(Source.Attack) },
     { "from damage over time", Damage.With(Source.DamageOverTime) },
     // - by ailment
     { "with ({AilmentMatchers})", Damage.With(Reference.AsAilment) },
     { "with ailments", Ailment.All.Any(Damage.With) },
     // action and damage combinations
     // - by item tag
     { "if you get a critical strike with a bow", And(CriticalStrike.On(), Damage.With(Tags.Bow)) },
     { "if you get a critical strike with a staff", And(CriticalStrike.On(), Damage.With(Tags.Staff)) },
     { "critical strikes with daggers have a", And(CriticalStrike.On(), Damage.With(Tags.Dagger)) },
     // - by item slot
     // - by source
     { "for each enemy hit by your attacks", And(Hit.Against(Enemy).On(), Damage.With(Source.Attack)) },
     // - by ailment
     { "with hits and ailments", Or(Hit.On(), Ailment.All.Any(Damage.With)) },
     {
         "poison you inflict with critical strikes deals",
         And(Damage.With(Ailment.Poison), CriticalStrike.On())
     },
     // equipment
     { "while unarmed", Not(MainHand.HasItem) },
     { "while wielding a staff", MainHand.Has(Tags.Staff) },
     { "while wielding a dagger", MainHand.Has(Tags.Dagger) },
     { "while wielding a bow", MainHand.Has(Tags.Bow) },
     { "while wielding a sword", MainHand.Has(Tags.Sword) },
     { "while wielding a claw", MainHand.Has(Tags.Claw) },
     { "while wielding an axe", MainHand.Has(Tags.Axe) },
     { "while wielding a mace", Or(MainHand.Has(Tags.Mace), MainHand.Has(Tags.Sceptre)) },
     { "while wielding a melee weapon", And(MainHand.Has(Tags.Weapon), Not(MainHand.Has(Tags.Ranged))) },
     { "while wielding a one handed weapon", MainHand.Has(Tags.OneHandWeapon) },
     { "while wielding a two handed weapon", MainHand.Has(Tags.TwoHandWeapon) },
     { "while dual wielding", OffHand.Has(Tags.Weapon) },
     { "while holding a shield", OffHand.Has(Tags.Shield) },
     { "while dual wielding or holding a shield", Or(OffHand.Has(Tags.Weapon), OffHand.Has(Tags.Shield)) },
     { "with shields", OffHand.Has(Tags.Shield) },
     { "from equipped shield", And(Condition.BaseValueComesFrom(OffHand), OffHand.Has(Tags.Shield)) },
     { "with # corrupted items equipped", Equipment.Count(e => e.IsCorrupted) >= Value },
     // stats
     // - pool
     { "when on low life", Life.IsLow },
     { "when not on low life", Not(Life.IsLow) },
     { "while no mana is reserved", Mana.Reservation.Value == 0 },
     { "while energy shield is full", EnergyShield.IsFull },
     { "while on full energy shield", EnergyShield.IsFull },
     { "while not on full energy shield", Not(EnergyShield.IsFull) },
     { "if energy shield recharge has started recently", EnergyShield.Recharge.StartedRecently },
     // - charges
     { "while you have no ({ChargeTypeMatchers})", Reference.AsChargeType.Amount.Value == 0 },
     {
         "while (at maximum|on full) ({ChargeTypeMatchers})",
         Reference.AsChargeType.Amount.Value == Reference.AsChargeType.Amount.Maximum.Value
     },
     // - flags
     { "while you have ({FlagMatchers})", Reference.AsFlagStat.IsSet },
     { "during onslaught", Flag.Onslaught.IsSet },
     { "while phasing", Flag.Phasing.IsSet },
     // - other
     { "if you have # primordial jewels,", Stat.PrimordialJewelsSocketed.Value >= Value },
     // - on enemy
     { "(against enemies )?that are on low life", Enemy.Stat(Life).IsLow },
     { "(against enemies )?that are on full life", Enemy.Stat(Life).IsFull },
     { "against rare and unique enemies", Enemy.IsRareOrUnique },
     // buffs
     { "while you have fortify", Buff.Fortify.IsOn(Self) },
     { "if you've taunted an enemy recently", Buff.Taunt.Action.Recently },
     { "enemies you taunt( deal| take)?", And(For(Enemy), Buff.Taunt.IsOn(Enemy)) },
     { "enemies you curse (take|have)", And(For(Enemy), Buffs(Self, Enemy).With(Keyword.Curse).Any()) },
     { "(against|from) blinded enemies", Buff.Blind.IsOn(Enemy) },
     { "from taunted enemies", Buff.Taunt.IsOn(Enemy) },
     {
         "you and allies affected by your auras have",
         Or(For(Entity.ModifierSource), And(For(Ally), Buffs(target: Ally).With(Keyword.Aura).Any()))
     },
     {
         "you and allies deal while affected by auras you cast",
         Or(For(Entity.ModifierSource), And(For(Ally), Buffs(target: Ally).With(Keyword.Aura).Any()))
     },
     // buff and damage combinations
     {
         "bleeding you inflict on maimed enemies deals",
         And(Damage.With(Ailment.Bleed), Buff.Maim.IsOn(Enemy))
     },
     // ailments
     { "while ({AilmentMatchers})", Reference.AsAilment.IsOn(Self) },
     { "(against|from) ({AilmentMatchers}) enemies", Reference.AsAilment.IsOn(Enemy) },
     {
         "against frozen, shocked or ignited enemies",
         Or(Ailment.Freeze.IsOn(Enemy), Ailment.Shock.IsOn(Enemy), Ailment.Ignite.IsOn(Enemy))
     },
     { "enemies which are ({AilmentMatchers})", Reference.AsAilment.IsOn(Enemy) },
     {
         "against enemies( that are)? affected by elemental ailments",
         Ailment.Elemental.Any(a => a.IsOn(Enemy))
     },
     {
         "against enemies( that are)? affected by no elemental ailments",
         Not(Ailment.Elemental.Any(a => a.IsOn(Enemy)))
     },
     // ground effects
     { "while on consecrated ground", Ground.Consecrated.IsOn(Self) },
     // other effects
     { "against burning enemies", Fire.DamageOverTimeIsOn(Enemy) },
     // skills
     // - by keyword
     { "vaal( skill)?", With(Skills[Keyword.Vaal]) },
     { "({KeywordMatchers})", With(Skills[Reference.AsKeyword]) },
     {
         "({KeywordMatchers}) and ({KeywordMatchers})",
         Or(With(Skills[References[0].AsKeyword]), With(Skills[References[1].AsKeyword]))
     },
     { "(with|of|for|from) ({KeywordMatchers})( skills)?", With(Skills[Reference.AsKeyword]) },
     { "({KeywordMatchers}) skills (have|deal)", With(Skills[Reference.AsKeyword]) },
     // - by damage type
     { "with ({DamageTypeMatchers}) skills", With(Skills[Reference.AsDamageType]) },
     // - by item slot
     { "skills (in|from) your ({ItemSlotMatchers})(can have| have)?", With(Skills[Reference.AsItemSlot]) },
     // - by single skill
     { "({SkillMatchers})('|s)?( fires| has a| have a| has| deals| gain)?", With(Reference.AsSkill) },
     { "(dealt by) ({SkillMatchers})", With(Reference.AsSkill) },
     // - cast recently/in past x seconds
     { "if you've cast a spell recently", Skills[Keyword.Spell].Cast.Recently },
     { "if you've attacked recently", Skills[Keyword.Attack].Cast.Recently },
     { "if you've used a movement skill recently", Skills[Keyword.Movement].Cast.Recently },
     { "if you've used a warcry recently", Skills[Keyword.Warcry].Cast.Recently },
     {
         "if you've used a ({DamageTypeMatchers}) skill in the past # seconds",
         Skills[Reference.AsDamageType].Cast.InPastXSeconds(Value)
     },
     // skill and action combinations
     {
         "projectiles have against targets they pierce",
         And(Projectile.Pierce.On(), With(Skills[Keyword.Projectile]))
     },
     // traps and mines
     { "with traps", With(Traps) },
     { "with mines", With(Mines) },
     { "traps and mines (deal|have a)", Or(With(Traps), With(Mines)) },
     { "from traps and mines", Or(With(Traps), With(Mines)) },
     { "for throwing traps", With(Traps) },
     { "if you detonated mines recently", Skill.DetonateMines.Cast.Recently },
     { "if you've placed a mine or thrown a trap recently", Or(Traps.Cast.Recently, Mines.Cast.Recently) },
     // totems
     { "totems", For(Entity.Totem) },
     { "totems (fire|gain|have)", With(Totems) },
     { "(spells cast|attacks used|skills used) by totems (have a|have)", With(Totems) },
     { "of totem skills that cast an aura", With(Skills[Keyword.Totem, Keyword.Aura]) },
     { "while you have a totem", Totems.Any(s => s.HasInstance) },
     { "if you've summoned a totem recently", Totems.Cast.Recently },
     { "when you place a totem", Totems.Cast.On() },
     // minions
     { "minions", For(Entity.Minion) },
     { "minions (deal|have|gain)", For(Entity.Minion) },
     { "you and your minions have", For(Entity.Minion, Entity.ModifierSource) },
     { "golem", For(Entity.Minion.With(Keyword.Golem)) },
     { "golems have", For(Entity.Minion.With(Keyword.Golem)) },
     { "spectres have", For(Entity.Minion.From(Skill.RaiseSpectre)) },
     {
         // Technically this would be separate for each minion summoned by that skill, but DPS will
         // only be calculated for a single minion anyway.
         "golems summoned in the past # seconds deal",
         With(Golems.Where(s => s.Cast.InPastXSeconds(Value)))
     },
     { "if you Summoned a golem in the past # seconds", Golems.Cast.InPastXSeconds(Value) },
     // flasks
     { "while using a flask", Flask.IsAnyActive },
     { "during any flask effect", Flask.IsAnyActive },
     // other
     { "while leeching", Condition.WhileLeeching },
     { "(you )?gain", Condition.True },     // may be left over at the end, does nothing
     // unique
     {
         "when your trap is triggered by an enemy",
         Condition.Unique("When your Trap is triggered by an Enemy")
     },
     {
         "when your mine is detonated targeting an enemy",
         Condition.Unique("When your Mine is detonated targeting an Enemy")
     },
     {
         "if you've killed an enemy affected by your damage over time recently",
         Condition.Unique("Have you recently killed an Enemy affected by your Damage over Time?")
     },
 };
 protected override IEnumerable <MatcherData> CreateCollection() =>
 new ValueConversionMatcherCollection(_modifierBuilder)
 {
     // action
     { "for each enemy you've killed recently", Kill.CountRecently },
     {
         "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 #%",
         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 # ({StatMatchers})", PerStat(stat: Reference.AsStat, divideBy: Value) },
     { "per # ({StatMatchers}) ceiled", PerStatCeiled(stat: Reference.AsStat, divideBy: Value) },
     { "per ({StatMatchers})", PerStat(stat: Reference.AsStat) },
     {
         "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) },
     // buffs
     { "per buff on you", Buffs(targets: Self).Count() },
     { "per curse on you", Buffs(targets: Self).With(Keyword.Curse).Count() },
     { "for each curse on that enemy,", Buffs(targets: Enemy).With(Keyword.Curse).Count() },
     // ailments
     { "for each poison on the enemy", Ailment.Poison.InstancesOn(Enemy).Value },
     { "per poison on enemy", Ailment.Poison.InstancesOn(Enemy).Value },
     {
         @"per poison affecting enemy, up to \+#%",
         CappedMultiplier(Ailment.Poison.InstancesOn(Enemy).Value, Value)
     },
     // skills
     { "for each zombie you own", Skills.RaiseZombie.Instances.Value },
     { "for each 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 },
     {
         "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 totem", Totems.CombinedInstances.Value },
     // unique
     {
         "for each poison you have inflicted recently",
         Stat.Unique("# of Poisons inflicted Recently", typeof(int)).Value
     },
     {
         "for each remaining chain",
         Projectile.ChainCount.Value -
         Stat.Unique("# of times the Active Skill has Chained", typeof(int)).Value
     },
     {
         "for each of your mines detonated recently, up to #%",
         CappedMultiplier(Stat.Unique("# of Mines Detonated Recently", typeof(int)).Value, Value)
     },
     {
         "for each of your traps triggered recently, up to #%",
         CappedMultiplier(Stat.Unique("# of Traps Triggered Recently", typeof(int)).Value, Value)
     },
 };     // add
示例#6
0
 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 #%",
         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 #%? ({StatMatchers})(?! leech)", PerStat(stat: Reference.AsStat, divideBy: Value) },
     { "per # ({StatMatchers}) ceiled", PerStatCeiled(stat: Reference.AsStat, divideBy: Value) },
     { "per ({StatMatchers})(?! leech)", PerStat(stat: Reference.AsStat) },
     {
         "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 one hundred nearby enemies", Enemy.CountNearby / 100 },
     { @"per nearby enemy, up to \+#%", CappedMultiplier(Enemy.CountNearby, Value) },
     // buffs
     { "per buff on you", Buffs(targets: Self).Count() },
     { "per curse on you", Buffs(targets: Self).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 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 },
     { "for each golem you have summoned", Golems.CombinedInstances.Value },
     { "for each type of golem you have summoned", Golems.CombinedInstances.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 totem", Totems.CombinedInstances.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("# of times the Active Skill has Chained"))
     },
     {
         "for each of your mines detonated recently, up to #%",
         CappedMultiplier(Stat.UniqueAmount("# of Mines Detonated Recently"), Value)
     },
     {
         "for each of your traps triggered recently, up to #%",
         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)
     },
 };     // add
 protected override IReadOnlyList <MatcherData> CreateCollection() =>
 new ConditionMatcherCollection(_modifierBuilder)
 {
     // generic
     { "on ({ActionMatchers})", Reference.AsAction.On },
     {
         "on ({KeywordMatchers}) ({ActionMatchers})",
         And(Condition.WithPart(References[0].AsKeyword), References[1].AsAction.On)
     },
     { "when you ({ActionMatchers}) an enemy", Reference.AsAction.On },
     {
         "when you ({ActionMatchers}) a rare or unique enemy",
         And(Enemy.IsRareOrUnique, Reference.AsAction.On)
     },
     {
         "when projectile ({ActionMatchers}) a rare or unique enemy",
         And(Enemy.IsRareOrUnique, Condition.WithPart(Keyword.Projectile), Reference.AsAction.On)
     },
     {
         "(when you|on) ({ActionMatchers}) a ({AilmentMatchers}) enemy",
         And(References[1].AsAilment.IsOn(Enemy), References[0].AsAction.On)
     },
     // kill
     { "if you or your totems kill an enemy", Or(Kill.On, Kill.By(Entity.Totem).On) },
     // hit
     { "when hit", Hit.By(Enemy).On },
     { "when you are hit", Hit.By(Enemy).On },
     { "with hits", Hit.On },
     { "for each enemy hit by (your )?attacks", And(With(Keyword.Attack), Hit.On) },
     {
         "when you or your totems hit an enemy with a spell",
         And(With(Keyword.Spell), Hit.On.Or(Hit.By(Entity.Totem).On))
     },
     { "on hit no more than once every # seconds", Hit.On },
     // critical strike
     { "critical strikes have a", CriticalStrike.On },
     { "when you deal a critical strike", CriticalStrike.On },
     { "if you get a critical strike", CriticalStrike.On },
     { "when you take a critical strike", CriticalStrike.By(Enemy).On },
     // skill cast
     { "when you place a totem", Totems.Cast.On },
     { "when you summon a totem", Totems.Cast.On },
     { "when you use a warcry", Skills[Keyword.Warcry].Cast.On },
     { "when you use a fire skill", Skills[Fire].Cast.On },
     // block
     { "when they block", Block.On },
     { "when you block", Block.On },
     // other
     {
         "when you stun an enemy with a melee hit",
         And(Condition.WithPart(Keyword.Melee), Effect.Stun.InflictionAction.On)
     },
     {
         "when you stun with melee damage",
         And(Condition.WithPart(Keyword.Melee), Effect.Stun.InflictionAction.On)
     },
     { "after spending( a total of)? # mana", Action.SpendMana(Value).On },
     { "when you gain a ({ChargeTypeMatchers})", Reference.AsChargeType.GainAction.On },
     { "you gain", Condition.True },     // may be left over at the end, does nothing
     { "you", Condition.True },
     { "grants", Condition.True },
     // unique
     {
         "when your trap is triggered by an enemy",
         Action.Unique("When your Trap is triggered by an Enemy").On
     },
     {
         "when your mine is detonated targeting an enemy",
         Action.Unique("When your Mine is detonated targeting an Enemy").On
     },
     {
         "on use",
         Action.Unique("When your use the Flask").On
     },
     { "when you gain Adrenaline", Action.Unique("When you gain Adrenaline").On },
     { "when you block attack damage", Action.Unique("Block.Attack").On },
     { "when you block spell damage", Action.Unique("Block.Spell").On },
     { "(every|each) second(, up to a maximum of #)?", Action.Unique("Interval.OneSecond").On },
     { "every 2 seconds(, up to a maximum of #)?", Action.Unique("Interval.TwoSeconds").On },
     { "after channelling for # seconds?", Action.Unique("PeriodOfChannelling").On },
 };     // add