Beispiel #1
0
    // Use this for initialization
    void Start()
    {
        mainText.text = "";
        Weapon  Axe    = new Weapon(4, 0, 0, "axe");
        OffHand none   = new OffHand(0, 0, "nothing", "NONE");
        OffHand shield = new OffHand(1, 3, "shield", "SHIELD");
        Warrior player = new Warrior(10, 10, 10, "Fjeldulf", Axe, shield);
        Warrior Gundar = new Warrior(10, 10, 5, "Gundar", Axe, shield);
        //Warrior orc1 = new Warrior(5, 10, 5, "Orc", Axe, none);

        List <Warrior> orcs = new List <Warrior>();

        for (int i = 0; i < 3; i++)
        {
            orcs.Add(new Warrior(5, 5, 5, "Orc", Axe, none));
        }
        GroupCombatStart(player, orcs);
        //PrintNewline(player.Name + " died after slaying " + orcsSlain + " orcs");
        // for (int i = 0; 0 < player.Hp; i++)
        // {
        //     Warrior orci = new
        // }
        //CombatStart(player, orc1);
        //CombatStart(player, Gundar);
    }
        private AdvancedSolverSettings(int level, int totalPoints, ISet <SkillNode> @checked, ISet <SkillNode> crossed,
                                       ISet <SkillNode> subsetTree, ISet <SkillNode> initialTree, int iterations,
                                       Dictionary <string, float> initialAttributes,
                                       Dictionary <string, Tuple <float, double> > attributeConstraints, Dictionary <PseudoAttribute, Tuple <float, double> > pseudoAttributeConstraints,
                                       WeaponClass weaponClass, Tags tags, OffHand offHand)
            : base(level, totalPoints, @checked, crossed, subsetTree, initialTree, iterations)
        {
            WeaponClass                = weaponClass;
            Tags                       = tags;
            OffHand                    = offHand;
            AttributeConstraints       = attributeConstraints ?? new Dictionary <string, Tuple <float, double> >();
            PseudoAttributeConstraints = pseudoAttributeConstraints ?? new Dictionary <PseudoAttribute, Tuple <float, double> >();
            InitialAttributes          = initialAttributes ?? new Dictionary <string, float>();

            if (AttributeConstraints.Values.Any(tuple => tuple.Item2 < 0 || tuple.Item2 > 1))
            {
                throw new ArgumentException("Weights need to be between 0 and 1", "attributeConstraints");
            }
            if (AttributeConstraints.Values.Any(t => t.Item1 <= 0))
            {
                throw new ArgumentException("Target values need to be greater zero", "attributeConstraints");
            }
            if (PseudoAttributeConstraints.Values.Any(tuple => tuple.Item2 < 0 || tuple.Item2 > 1))
            {
                throw new ArgumentException("Weights need to be between 0 and 1", "pseudoAttributeConstraints");
            }
            if (PseudoAttributeConstraints.Values.Any(t => t.Item1 <= 0))
            {
                throw new ArgumentException("Target values need to be greater zero", "pseudoAttributeConstraints");
            }
        }
        /// <summary>
        /// Creates new AdvancesSolverSettings.
        /// </summary>
        /// <param name="baseSettings">Base settings to copy.</param>
        /// <param name="totalPoints">Maximum for points spent in the result tree. (>= 0)</param>
        /// <param name="initialAttributes">Starting attributes of stats that calculations are based on.</param>
        /// <param name="attributeConstraints">The attribute constraints the solver should try to fullfill.</param>
        /// <param name="pseudoAttributeConstraints">The pseudo attribute constraints the solver should try to fullfill.</param>
        /// <param name="weaponClass">WeaponClass used for pseudo attribute calculation.</param>
        /// <param name="tags">Tags used for pseudo attribute calculation.</param>
        /// <param name="offHand">OffHand used for pseudo attribute calculation.</param>
        public AdvancedSolverSettings(SolverSettings baseSettings,
            int totalPoints,
            Dictionary<string, float> initialAttributes,
            Dictionary<string, Tuple<float, double>> attributeConstraints,
            Dictionary<PseudoAttribute, Tuple<float, double>> pseudoAttributeConstraints,
            WeaponClass weaponClass, Tags tags, OffHand offHand)
            : base(baseSettings)
        {
            if (totalPoints < 0) throw new ArgumentOutOfRangeException(nameof(totalPoints), totalPoints, "must be >= 0");

            TotalPoints = totalPoints;
            WeaponClass = weaponClass;
            Tags = tags;
            OffHand = offHand;
            AttributeConstraints = attributeConstraints ?? new Dictionary<string, Tuple<float, double>>();
            PseudoAttributeConstraints = pseudoAttributeConstraints ?? new Dictionary<PseudoAttribute, Tuple<float, double>>();
            InitialAttributes = initialAttributes ?? new Dictionary<string, float>();

            if (AttributeConstraints.Values.Any(tuple => tuple.Item2 < 0 || tuple.Item2 > 1))
                throw new ArgumentException("Weights need to be between 0 and 1", "attributeConstraints");
            if (AttributeConstraints.Values.Any(t => t.Item1 <= 0))
                throw new ArgumentException("Target values need to be greater zero", "attributeConstraints");
            if (PseudoAttributeConstraints.Values.Any(tuple => tuple.Item2 < 0 || tuple.Item2 > 1))
                throw new ArgumentException("Weights need to be between 0 and 1", "pseudoAttributeConstraints");
            if (PseudoAttributeConstraints.Values.Any(t => t.Item1 <= 0))
                throw new ArgumentException("Target values need to be greater zero", "pseudoAttributeConstraints");
        }
 public ConditionSettings(Tags tags, OffHand offHand, string[] keystones, WeaponClass weaponClass)
 {
     if (keystones == null) throw new ArgumentNullException("keystones");
     Tags = tags;
     OffHand = offHand;
     Keystones = keystones;
     WeaponClass = weaponClass;
 }
Beispiel #5
0
 public void EquipOffHand(OffHand offHand)
 {
     if (offHand != null)
     {
         offHand.UnEquip(this);
     }
     this.offHand.Equip(this);
 }
        }                                            // .OHPrimaryBonus .OHResourceBonus .OHBonus (powerfist: min max damage, armguard: block, tome: skill damage, orb: resist, lasso: hit,
                                                     //powder: dodge)

        public EquipSet(Head equippedHead, Outfit equippedOutfit, Amulet equippedAmulet, Accessory equippedAccessory, Weapon equippedWeapon, OffHand equippedOffHand)
        {
            EquippedHead      = equippedHead;
            EquippedOutfit    = equippedOutfit;
            EquippedAmulet    = equippedAmulet;
            EquippedAccessory = equippedAccessory;
            EquippedWeapon    = equippedWeapon;
            EquippedOffHand   = equippedOffHand;
        }
Beispiel #7
0
 /// <summary>
 /// Returns whether the given OffHand has the given string as an alias.
 /// (case insensitive)
 /// </summary>
 public static bool HasAlias(this OffHand offHand, string alias)
 {
     if (alias == null)
     {
         return(false);
     }
     alias = alias.ToLowerInvariant();
     return(Aliases[offHand].Any(s => s == alias));
 }
 public EquipSet() //Creates a "blank" equipment set
 {
     EquippedHead      = new Head();
     EquippedOutfit    = new Outfit();
     EquippedAmulet    = new Amulet();
     EquippedAccessory = new Accessory();
     EquippedWeapon    = new Weapon();
     EquippedOffHand   = new OffHand();
 }
 /// <summary>
 /// Creates new AdvancesSolverSettings.
 /// </summary>
 /// <param name="baseSettings">Base settings to copy.</param>
 /// <param name="initialAttributes">Starting attributes of stats that calculations are based on.</param>
 /// <param name="attributeConstraints">The attribute constraints the solver should try to fullfill.</param>
 /// <param name="pseudoAttributeConstraints">The pseudo attribute constraints the solver should try to fullfill.</param>
 /// <param name="weaponClass">WeaponClass used for pseudo attribute calculation.</param>
 /// <param name="tags">Tags used for pseudo attribute calculation.</param>
 /// <param name="offHand">OffHand used for pseudo attribute calculation.</param>
 public AdvancedSolverSettings(SolverSettings baseSettings,
                               Dictionary <string, float> initialAttributes,
                               Dictionary <string, Tuple <float, double> > attributeConstraints,
                               Dictionary <PseudoAttribute, Tuple <float, double> > pseudoAttributeConstraints,
                               WeaponClass weaponClass, Tags tags, OffHand offHand)
     : this(baseSettings.Level, baseSettings.TotalPoints, baseSettings.Checked, baseSettings.Crossed,
            baseSettings.SubsetTree, baseSettings.InitialTree, baseSettings.Iterations, initialAttributes,
            attributeConstraints, pseudoAttributeConstraints, weaponClass, tags, offHand)
 {
 }
Beispiel #10
0
            public Warrior(int hp, int attack, int defence, string name, Weapon weapon, OffHand offhand)
            {
                Hp              = hp;
                AttackTrue      = attack;
                DefenceTrue     = defence;
                Name            = name;
                EquippedWeapon  = weapon;
                EquippedOffHand = offhand;

                UpdateStats();
            }
Beispiel #11
0
 public bool ShieldWeild(OffHand offHand)
 {
     if (offHand.Type == "SHIELD")
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
Beispiel #12
0
 public ConditionSettings(Tags tags, OffHand offHand, string[] keystones, WeaponClass weaponClass)
 {
     if (keystones == null)
     {
         throw new ArgumentNullException("keystones");
     }
     Tags        = tags;
     OffHand     = offHand;
     Keystones   = keystones;
     WeaponClass = weaponClass;
 }
Beispiel #13
0
 public void Dispose()
 {
     Armor.Dispose();
     MainHand.Dispose();
     OffHand.Dispose();
     Ring.Dispose();
     Ring2.Dispose();
     Amulet.Dispose();
     Helm.Dispose();
     Gloves.Dispose();
     Boots.Dispose();
     Belt.Dispose();
     Flasks.ForEach(vm => vm.Dispose());
     TreeJewels.ForEach(vm => vm.Dispose());
     ItemJewels.Values.Flatten().ForEach(vm => vm.Dispose());
 }
        private AdvancedSolverSettings(int level, int totalPoints, HashSet<ushort> @checked, HashSet<ushort> crossed,
            HashSet<ushort> subsetTree, HashSet<ushort> initialTree, Dictionary<string, float> initialAttributes,
            Dictionary<string, Tuple<float, double>> attributeConstraints, Dictionary<PseudoAttribute, Tuple<float, double>> pseudoAttributeConstraints,
            WeaponClass weaponClass, Tags tags, OffHand offHand)
            : base(level, totalPoints, @checked, crossed, subsetTree, initialTree)
        {
            WeaponClass = weaponClass;
            Tags = tags;
            OffHand = offHand;
            AttributeConstraints = attributeConstraints ?? new Dictionary<string, Tuple<float, double>>();
            PseudoAttributeConstraints = pseudoAttributeConstraints ?? new Dictionary<PseudoAttribute, Tuple<float, double>>();
            InitialAttributes = initialAttributes ?? new Dictionary<string, float>();

            if (AttributeConstraints.Values.Any(tuple => tuple.Item2 < 0 || tuple.Item2 > 1))
                throw new ArgumentException("Weights need to be between 0 and 1", "attributeConstraints");
            if (AttributeConstraints.Values.Any(t => t.Item1 <= 0))
                throw new ArgumentException("Target values need to be greater zero", "attributeConstraints");
            if (PseudoAttributeConstraints.Values.Any(tuple => tuple.Item2 < 0 || tuple.Item2 > 1))
                throw new ArgumentException("Weights need to be between 0 and 1", "pseudoAttributeConstraints");
            if (PseudoAttributeConstraints.Values.Any(t => t.Item1 <= 0))
                throw new ArgumentException("Target values need to be greater zero", "pseudoAttributeConstraints");
        }
        /// <summary>
        /// Creates new AdvancesSolverSettings.
        /// </summary>
        /// <param name="baseSettings">Base settings to copy.</param>
        /// <param name="totalPoints">Maximum for points spent in the result tree. (>= 0)</param>
        /// <param name="initialAttributes">Starting attributes of stats that calculations are based on.</param>
        /// <param name="attributeConstraints">The attribute constraints the solver should try to fullfill.</param>
        /// <param name="pseudoAttributeConstraints">The pseudo attribute constraints the solver should try to fullfill.</param>
        /// <param name="weaponClass">WeaponClass used for pseudo attribute calculation.</param>
        /// <param name="tags">Tags used for pseudo attribute calculation.</param>
        /// <param name="offHand">OffHand used for pseudo attribute calculation.</param>
        public AdvancedSolverSettings(SolverSettings baseSettings,
                                      int totalPoints,
                                      Dictionary <string, float> initialAttributes,
                                      Dictionary <string, Tuple <float, double> > attributeConstraints,
                                      Dictionary <PseudoAttribute, Tuple <float, double> > pseudoAttributeConstraints,
                                      WeaponClass weaponClass, Tags tags, OffHand offHand)
            : base(baseSettings)
        {
            if (totalPoints < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(totalPoints), totalPoints, "must be >= 0");
            }

            TotalPoints                = totalPoints;
            WeaponClass                = weaponClass;
            Tags                       = tags;
            OffHand                    = offHand;
            AttributeConstraints       = attributeConstraints ?? new Dictionary <string, Tuple <float, double> >();
            PseudoAttributeConstraints = pseudoAttributeConstraints ?? new Dictionary <PseudoAttribute, Tuple <float, double> >();
            InitialAttributes          = initialAttributes ?? new Dictionary <string, float>();

            if (AttributeConstraints.Values.Any(tuple => tuple.Item2 < 0 || tuple.Item2 > 1))
            {
                throw new ArgumentException("Weights need to be between 0 and 1", "attributeConstraints");
            }
            if (AttributeConstraints.Values.Any(t => t.Item1 <= 0))
            {
                throw new ArgumentException("Target values need to be greater zero", "attributeConstraints");
            }
            if (PseudoAttributeConstraints.Values.Any(tuple => tuple.Item2 < 0 || tuple.Item2 > 1))
            {
                throw new ArgumentException("Weights need to be between 0 and 1", "pseudoAttributeConstraints");
            }
            if (PseudoAttributeConstraints.Values.Any(t => t.Item1 <= 0))
            {
                throw new ArgumentException("Target values need to be greater zero", "pseudoAttributeConstraints");
            }
        }
Beispiel #16
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?")
     },
 };
Beispiel #17
0
 protected override IEnumerable <MatcherData> CreateCollection() =>
 new FormAndStatMatcherCollection(_modifierBuilder, ValueFactory)
 {
     // attributes
     // offense
     // - damage
     {
         @"adds # to # ({DamageTypeMatchers}) damage",
         BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]), Reference.AsDamageType.Damage.WithHits
     },
     {
         @"adds # to # ({DamageTypeMatchers}) damage to unarmed attacks",
         BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]),
         Reference.AsDamageType.Damage.WithSkills(DamageSource.Attack),
         And(Not(MainHand.HasItem), With(Keyword.Melee))
     },
     {
         @"adds # to # ({DamageTypeMatchers}) damage to spells",
         BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]),
         Reference.AsDamageType.Damage.WithSkills(DamageSource.Spell)
     },
     {
         @"# to # additional ({DamageTypeMatchers}) damage",
         BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]), Reference.AsDamageType.Damage.WithHits
     },
     {
         @"adds # maximum ({DamageTypeMatchers}) damage",
         BaseAdd, Value.MaximumOnly, Reference.AsDamageType.Damage.WithHits
     },
     { "deal no ({DamageTypeMatchers}) damage", TotalOverride, 0, Reference.AsDamageType.Damage },
     // - conversion and gain
     {
         "(gain )?#% of ({DamageTypeMatchers}) damage (gained |added )?as (extra )?({DamageTypeMatchers}) damage",
         BaseAdd, Value, References[0].AsDamageType.Damage.WithHitsAndAilments
         .GainAs(References[1].AsDamageType.Damage.WithHitsAndAilments)
     },
     {
         "gain #% of ({DamageTypeMatchers}) damage as extra damage of a random element",
         BaseAdd, Value, Reference.AsDamageType.Damage.WithHitsAndAilments
         .GainAs(RandomElement.Damage.WithHitsAndAilments)
     },
     {
         "gain #% of wand ({DamageTypeMatchers}) damage as extra ({DamageTypeMatchers}) damage",
         BaseAdd, Value,
         References[0].AsDamageType.Damage.With(AttackDamageHand.MainHand)
         .GainAs(References[1].AsDamageType.Damage.With(AttackDamageHand.MainHand))
         .WithCondition(MainHand.Has(Tags.Wand)),
         References[0].AsDamageType.Damage.With(AttackDamageHand.OffHand)
         .GainAs(References[1].AsDamageType.Damage.With(AttackDamageHand.OffHand))
         .WithCondition(OffHand.Has(Tags.Wand))
     },
     {
         "#% of ({DamageTypeMatchers}) damage converted to ({DamageTypeMatchers}) damage",
         BaseAdd, Value, References[0].AsDamageType.Damage.WithHitsAndAilments
         .ConvertTo(References[1].AsDamageType.Damage.WithHitsAndAilments)
     },
     // - penetration
     {
         "damage penetrates #% (of enemy )?({DamageTypeMatchers}) resistances?",
         BaseAdd, Value, Reference.AsDamageType.Penetration
     },
     {
         "damage (?<inner>with .*|dealt by .*) penetrates #% ({DamageTypeMatchers}) resistances?",
         BaseAdd, Value, Reference.AsDamageType.Penetration, "${inner}"
     },
     {
         "penetrate #% ({DamageTypeMatchers}) resistances?",
         BaseAdd, Value, Reference.AsDamageType.Penetration
     },
     // - crit
     { @"\+#% critical strike chance", BaseAdd, Value, CriticalStrike.Chance },
     {
         "no critical strike multiplier, no damage multiplier for ailments from critical strikes",
         TotalOverride, 0, CriticalStrike.Multiplier
     },
     { "never deal critical strikes", TotalOverride, 0, CriticalStrike.Chance },
     // - speed
     // - projectiles
     { "skills fire an additional projectile", BaseAdd, 1, Projectile.Count },
     { "pierces # additional targets", BaseAdd, Value, Projectile.PierceCount },
     { "projectiles pierce an additional target", BaseAdd, 1, Projectile.PierceCount },
     { "projectiles pierce # (additional )?targets", BaseAdd, Value, Projectile.PierceCount },
     {
         "projectiles pierce all nearby targets",
         TotalOverride, double.PositiveInfinity, Projectile.PierceCount, Enemy.IsNearby
     },
     { @"skills chain \+# times", BaseAdd, Value, Projectile.ChainCount },
     // - other
     { "your hits can't be evaded", TotalOverride, 100, Stat.ChanceToHit },
     // defense
     // - life, mana, defences
     { "maximum life becomes #", TotalOverride, Value, Life },
     { "removes all mana", TotalOverride, 0, Mana },
     { "converts all evasion rating to armour", TotalOverride, 100, Evasion.ConvertTo(Armour) },
     { "cannot evade enemy attacks", TotalOverride, 0, Evasion.Chance },
     { @"\+# evasion rating", BaseAdd, Value, Evasion },
     // - resistances
     { "immune to ({DamageTypeMatchers}) damage", TotalOverride, 100, Reference.AsDamageType.Resistance },
     { @"\+#% elemental resistances", BaseAdd, Value, Elemental.Resistance },
     { @"\+?#% physical damage reduction", BaseAdd, Value, Physical.Resistance },
     // - leech
     {
         "life leech is applied to energy shield instead",
         TotalOverride, (int)Pool.EnergyShield, Life.Leech.TargetPool
     },
     { "gain life from leech instantly", TotalOverride, 1, Life.InstantLeech },
     { "leech #% of damage as life", BaseAdd, Value, Life.Leech.Of(Damage) },
     // - block
     {
         "#% of block chance applied to spells",
         BaseAdd, Value.PercentOf(Block.AttackChance), Block.SpellChance
     },
     // - other
     {
         "chaos damage does not bypass energy shield",
         TotalOverride, 100, Chaos.DamageTakenFrom(EnergyShield).Before(Life)
     },
     {
         "#% of chaos damage does not bypass energy shield",
         BaseAdd, Value, Chaos.DamageTakenFrom(EnergyShield).Before(Life)
     },
     {
         "#% of physical damage bypasses energy shield",
         BaseSubtract, Value, Physical.DamageTakenFrom(EnergyShield).Before(Life)
     },
     {
         "you take #% reduced extra damage from critical strikes",
         PercentReduce, Value, CriticalStrike.ExtraDamageTaken
     },
     {
         "you take no extra damage from critical strikes",
         PercentLess, 100, CriticalStrike.ExtraDamageTaken
     },
     // regen and recharge
     // (need to be FormAndStatMatcher because they also exist with flat values)
     {
         "#%( of)? ({PoolStatMatchers}) regenerated per second",
         BaseAdd, Value, Reference.AsPoolStat.Regen.Percent
     },
     {
         "#% of ({PoolStatMatchers}) and ({PoolStatMatchers}) regenerated per second",
         BaseAdd, Value, References[0].AsPoolStat.Regen.Percent, References[1].AsPoolStat.Regen.Percent
     },
     {
         "regenerate #%( of)?( their| your)? ({PoolStatMatchers}) per second",
         BaseAdd, Value, Reference.AsPoolStat.Regen.Percent
     },
     {
         "# ({PoolStatMatchers}) regenerated per second", BaseAdd, Value,
         Reference.AsPoolStat.Regen
     },
     {
         "#% faster start of energy shield recharge", PercentIncrease, Value,
         EnergyShield.Recharge.Start
     },
     { "life regeneration has no effect", PercentLess, 100, Life.Regen },
     {
         "life regeneration is applied to energy shield instead",
         TotalOverride, (int)Pool.EnergyShield, Life.Regen.TargetPool
     },
     // gain (need to be FormAndStatMatcher because they also exist with flat values)
     {
         "#% of ({PoolStatMatchers}) gained",
         BaseAdd, Value.PercentOf(Reference.AsStat), Reference.AsPoolStat.Gain
     },
     {
         "recover #% of( their)? ({PoolStatMatchers})",
         BaseAdd, Value.PercentOf(Reference.AsStat), Reference.AsPoolStat.Gain
     },
     {
         "removes #% of ({PoolStatMatchers})",
         BaseSubtract, Value.PercentOf(Reference.AsStat), Reference.AsPoolStat.Gain
     },
     { @"\+# ({PoolStatMatchers}) gained", BaseAdd, Value, Reference.AsPoolStat.Gain },
     { @"gain \+# ({PoolStatMatchers})", BaseAdd, Value, Reference.AsPoolStat.Gain },
     // charges
     {
         "#% chance to gain a power, frenzy or endurance charge",
         BaseAdd, Value / 3,
         Charge.Power.ChanceToGain, Charge.Frenzy.ChanceToGain, Charge.Endurance.ChanceToGain
     },
     {
         "(?<!chance to |when you )gain an? ({ChargeTypeMatchers})",
         BaseAdd, 100, Reference.AsChargeType.ChanceToGain
     },
     // skills
     // traps, mines, totems
     {
         "detonating mines is instant",
         TotalOverride, double.PositiveInfinity, Stat.CastRate, With(Skills.DetonateMines)
     },
     // minions
     // buffs
     {
         "(?<!while |chance to )you have ({BuffMatchers})",
         TotalOverride, 1, Reference.AsBuff.NotAsBuffOn(Self)
     },
     {
         "(?<!while |chance to )gain ({BuffMatchers})",
         TotalOverride, 1, Reference.AsBuff.On(Self)
     },
     {
         "you can have one additional curse",
         BaseAdd, 1, Buff.CurseLimit
     },
     {
         "enemies can have # additional curse",
         BaseAdd, Value, Buff.CurseLimit.For(Enemy)
     },
     { "unaffected by curses", PercentLess, 100, Buffs(targets: Self).With(Keyword.Curse).Effect },
     { "grants fortify", TotalOverride, 1, Buff.Fortify.On(Self) },
     { "gain elemental conflux", TotalOverride, 1, Buff.Conflux.Elemental.On(Self) },
     // flags
     // ailments
     { "causes bleeding", TotalOverride, 100, Ailment.Bleed.Chance },
     { "always poison", TotalOverride, 100, Ailment.Poison.Chance },
     {
         "(you )?can afflict an additional ignite on an enemy",
         BaseAdd, 1, Ailment.Ignite.InstancesOn(Enemy).Maximum
     },
     { "(you are )?immune to ({AilmentMatchers})", TotalOverride, 100, Reference.AsAilment.Avoidance },
     { "cannot be ({AilmentMatchers})", TotalOverride, 100, Reference.AsAilment.Avoidance },
     {
         "cannot be ({AilmentMatchers}) or ({AilmentMatchers})",
         TotalOverride, 100, References[0].AsAilment.Avoidance, References[1].AsAilment.Avoidance
     },
     {
         "(immune to|cannot be affected by) elemental ailments",
         TotalOverride, 100, Ailment.Elemental.Select(a => a.Avoidance)
     },
     {
         "poison you inflict with critical strikes deals #% more damage",
         PercentMore, Value, CriticalStrike.Multiplier.With(Ailment.Poison)
     },
     // stun
     { "(you )?cannot be stunned", TotalOverride, 100, Effect.Stun.Avoidance },
     // item quantity/quality
     // range and area of effect
     // other
     { "knocks back enemies", TotalOverride, 100, Effect.Knockback.Chance },
 };
Beispiel #18
0
 protected override IReadOnlyList <MatcherData> CreateCollection() =>
 new FormAndStatMatcherCollection(_modifierBuilder, ValueFactory)
 {
     // attributes
     // offense
     // - damage
     {
         @"adds # to # ({DamageTypeMatchers}) damage",
         BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]), Reference.AsDamageType.Damage.WithHits
     },
     {
         @"# to # added ({DamageTypeMatchers}) damage",
         BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]), Reference.AsDamageType.Damage.WithHits
     },
     {
         "# to # ({DamageTypeMatchers}) damage",
         BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]), Reference.AsDamageType.Damage.WithHits
     },
     {
         @"adds # to # ({DamageTypeMatchers}) damage to attacks",
         BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]),
         Reference.AsDamageType.Damage.WithSkills(DamageSource.Attack)
     },
     {
         @"adds # to # ({DamageTypeMatchers}) damage to unarmed attacks",
         BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]),
         Reference.AsDamageType.Damage.WithSkills(DamageSource.Attack).With(Keyword.Melee),
         Not(MainHand.HasItem)
     },
     {
         @"adds # to # ({DamageTypeMatchers}) damage to bow attacks",
         BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]),
         Reference.AsDamageType.Damage.WithSkills(DamageSource.Attack).With(Keyword.Melee),
         MainHand.Has(Tags.Bow)
     },
     {
         @"adds # to # ({DamageTypeMatchers}) damage to spells",
         BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]),
         Reference.AsDamageType.Damage.WithSkills(DamageSource.Spell)
     },
     {
         @"adds # to # ({DamageTypeMatchers}) damage to spells and attacks",
         BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]),
         Reference.AsDamageType.Damage.WithSkills(DamageSource.Spell),
         Reference.AsDamageType.Damage.WithSkills(DamageSource.Attack)
     },
     {
         @"# to # additional ({DamageTypeMatchers}) damage",
         BaseAdd, ValueFactory.FromMinAndMax(Values[0], Values[1]), Reference.AsDamageType.Damage.WithHits
     },
     {
         @"adds # maximum ({DamageTypeMatchers}) damage",
         BaseAdd, Value.MaximumOnly, Reference.AsDamageType.Damage.WithHits
     },
     { "deal no ({DamageTypeMatchers}) damage", TotalOverride, 0, Reference.AsDamageType.Damage },
     {
         @"explosion deals (base )?({DamageTypeMatchers}) damage equal to #% of the (corpse|monster)'s maximum life",
         BaseSet, Value.AsPercentage *Life.For(Enemy).Value,
         Reference.AsDamageType.Damage.WithSkills(DamageSource.Secondary)
     },
     {
         @"explosion deals # to # base ({DamageTypeMatchers}) damage",
         BaseSet, ValueFactory.FromMinAndMax(Values[0], Values[1]),
         Reference.AsDamageType.Damage.WithSkills(DamageSource.Secondary)
     },
     {
         "deals # to # base ({DamageTypeMatchers}) damage",
         BaseSet, ValueFactory.FromMinAndMax(Values[0], Values[1]),
         Reference.AsDamageType.Damage.WithSkills(DamageSource.Spell)
     },
     // - damage taken
     {
         "cold damage taken increased by chill effect",
         PercentIncrease, 100 * (Ailment.ChillEffect.Value - 1),
         Cold.Damage.Taken.With(DamageSource.OverTime)
     },
     // - damage taken as
     // - conversion and gain
     {
         "(gain )?#% of ({DamageTypeMatchers}) damage (gained |added )?as (extra )?({DamageTypeMatchers}) damage",
         BaseAdd, Value, References[0].AsDamageType.Damage.WithHitsAndAilments
         .GainAs(References[1].AsDamageType.Damage.WithHitsAndAilments)
     },
     {
         "gain #% of ({DamageTypeMatchers}) damage as extra damage of a random element",
         BaseAdd, Value, Reference.AsDamageType.Damage.WithHitsAndAilments
         .GainAs(RandomElement.Damage.WithHitsAndAilments)
     },
     {
         "gain #% of wand ({DamageTypeMatchers}) damage as extra ({DamageTypeMatchers}) damage",
         BaseAdd, Value,
         References[0].AsDamageType.Damage.With(AttackDamageHand.MainHand)
         .GainAs(References[1].AsDamageType.Damage.With(AttackDamageHand.MainHand))
         .WithCondition(MainHand.Has(Tags.Wand)),
         References[0].AsDamageType.Damage.With(AttackDamageHand.OffHand)
         .GainAs(References[1].AsDamageType.Damage.With(AttackDamageHand.OffHand))
         .WithCondition(OffHand.Has(Tags.Wand))
     },
     {
         "#% of ({DamageTypeMatchers}) damage converted to ({DamageTypeMatchers}) damage",
         BaseAdd, Value, References[0].AsDamageType.Damage.WithHitsAndAilments
         .ConvertTo(References[1].AsDamageType.Damage.WithHitsAndAilments)
     },
     {
         "({DamageTypeMatchers}) spells have #% of ({DamageTypeMatchers}) damage converted to ({DamageTypeMatchers}) damage",
         BaseAdd, Value, References[1].AsDamageType.Damage.With(DamageSource.Spell)
         .ConvertTo(References[2].AsDamageType.Damage.With(DamageSource.Spell)),
         With(References[0].AsDamageType)
     },
     // - penetration
     {
         "damage penetrates #% (of enemy )?({DamageTypeMatchers}) resistances?",
         BaseAdd, Value, Reference.AsDamageType.Penetration
     },
     {
         "damage (?<inner>with .*|dealt by .*) penetrates #% ({DamageTypeMatchers}) resistances?",
         BaseAdd, Value, Reference.AsDamageType.Penetration, "${inner}"
     },
     {
         "penetrates? #% ({DamageTypeMatchers}) resistances?",
         BaseAdd, Value, Reference.AsDamageType.Penetration
     },
     {
         "({KeywordMatchers}) damage penetrates #% ({DamageTypeMatchers}) resistances?",
         BaseAdd, Value, References[1].AsDamageType.Penetration.With(References[0].AsKeyword)
     },
     {
         "({KeywordMatchers}) damage (?<inner>with .*|dealt by .*) penetrates #% ({DamageTypeMatchers}) resistances?",
         BaseAdd, Value, References[1].AsDamageType.Penetration.With(References[1].AsKeyword), "${inner}"
     },
     {
         "hits ignore enemy monster ({DamageTypeMatchers}) resistance",
         TotalOverride, 1, Reference.AsDamageType.IgnoreResistance
     },
     // - exposure
     {
         @"(?<damageType>({DamageTypeMatchers})) exposure applies #% to \k<damageType> resistance",
         BaseSet, Value, Reference.AsDamageType.Exposure
     },
     // - crit
     { @"\+#% critical strike chance", BaseAdd, Value, CriticalStrike.Chance },
     {
         "no critical strike multiplier, no damage multiplier for ailments from critical strikes",
         TotalOverride, 0, CriticalStrike.Multiplier
     },
     { "never deal critical strikes", TotalOverride, 0, CriticalStrike.Chance },
     // - speed
     { "actions are #% slower", PercentLess, Value, Stat.ActionSpeed },
     { @"\+# seconds to attack time", BaseAdd, Value, Stat.BaseCastTime.With(DamageSource.Attack) },
     // - projectiles
     { "fires # additional projectiles", BaseAdd, Value, Projectile.Count },
     { "fires # additional arrows", BaseAdd, Value, Projectile.Count, With(Keyword.Attack) },
     { "fires an additional projectile", BaseAdd, 1, Projectile.Count },
     { "fires an additional arrow", BaseAdd, 1, Projectile.Count, With(Keyword.Attack) },
     { "skills fire an additional projectile", BaseAdd, 1, Projectile.Count },
     { "skills fire # additional projectiles", BaseAdd, Value, Projectile.Count },
     { "supported skills fire # additional projectiles", BaseAdd, Value, Projectile.Count },
     { "pierces # additional targets", BaseAdd, Value, Projectile.PierceCount },
     { "projectiles pierce an additional target", BaseAdd, 1, Projectile.PierceCount },
     { "arrows pierce an additional target", BaseAdd, 1, Projectile.PierceCount, With(Keyword.Attack) },
     { "projectiles pierce # (additional )?targets", BaseAdd, Value, Projectile.PierceCount },
     {
         "arrows pierce # (additional )?targets",
         BaseAdd, Value, Projectile.PierceCount, With(Keyword.Attack)
     },
     {
         "projectiles from supported skills pierce # additional targets", BaseAdd, Value,
         Projectile.PierceCount
     },
     {
         "projectiles pierce all nearby targets",
         TotalOverride, double.PositiveInfinity, Projectile.PierceCount, Enemy.IsNearby
     },
     {
         "projectiles pierce all targets",
         TotalOverride, double.PositiveInfinity, Projectile.PierceCount
     },
     { @"chains \+# times", BaseAdd, Value, Projectile.ChainCount },
     { @"(supported )?skills chain \+# times", BaseAdd, Value, Projectile.ChainCount },
     // - other
     { "your hits can't be evaded", TotalOverride, 100, Stat.ChanceToHit },
     { "can't be evaded", TotalOverride, 100, Stat.ChanceToHit },
     // defense
     // - life, mana, defences
     { "maximum life becomes #", TotalOverride, Value, Life },
     { "removes all mana", TotalOverride, 0, Mana },
     { "converts all evasion rating to armour", TotalOverride, 100, Evasion.ConvertTo(Armour) },
     { "cannot evade enemy attacks", TotalOverride, 0, Evasion.Chance },
     { @"\+# evasion rating", BaseAdd, Value, Evasion },
     // - resistances
     { "immune to ({DamageTypeMatchers}) damage", TotalOverride, 100, Reference.AsDamageType.Resistance },
     { @"\+#% elemental resistances", BaseAdd, Value, Elemental.Resistance },
     { @"\+?#% physical damage reduction", BaseAdd, Value, Physical.Resistance },
     // - leech
     {
         "leech energy shield instead of life",
         TotalOverride, 100, Life.Leech.Of(Damage).ConvertTo(EnergyShield.Leech.Of(Damage))
     },
     { "gain life from leech instantly", TotalOverride, 1, Life.Leech.IsInstant },
     { "leech #% of damage as life", BaseAdd, Value, Life.Leech.Of(Damage) },
     { "cannot leech mana", TotalOverride, 0, Mana.Leech.Of(Damage) },
     // - block
     {
         "#% of block chance applied to spells",
         BaseAdd, Value.PercentOf(Block.AttackChance), Block.SpellChance
     },
     // - other
     {
         "chaos damage does not bypass energy shield",
         TotalOverride, 100, Chaos.DamageTakenFrom(EnergyShield).Before(Life)
     },
     {
         "#% of chaos damage does not bypass energy shield",
         BaseAdd, Value, Chaos.DamageTakenFrom(EnergyShield).Before(Life)
     },
     {
         "#% of physical damage bypasses energy shield",
         BaseSubtract, Value, Physical.DamageTakenFrom(EnergyShield).Before(Life)
     },
     {
         "you take #% reduced extra damage from critical strikes",
         PercentReduce, Value, CriticalStrike.ExtraDamageTaken
     },
     {
         "you take no extra damage from critical strikes",
         PercentLess, 100, CriticalStrike.ExtraDamageTaken
     },
     // regen and recharge
     // (need to be FormAndStatMatcher because they also exist with flat values)
     {
         "#%( of)? ({PoolStatMatchers}) regenerated per second",
         BaseAdd, Value, Reference.AsPoolStat.Regen.Percent
     },
     {
         "#% of ({PoolStatMatchers}) and ({PoolStatMatchers}) regenerated per second",
         BaseAdd, Value, References[0].AsPoolStat.Regen.Percent, References[1].AsPoolStat.Regen.Percent
     },
     {
         "regenerate #%( of)?( their| your)? ({PoolStatMatchers}) per second",
         BaseAdd, Value, Reference.AsPoolStat.Regen.Percent
     },
     {
         "# ({PoolStatMatchers}) regenerated per second", BaseAdd, Value,
         Reference.AsPoolStat.Regen
     },
     {
         "#% faster start of energy shield recharge", PercentIncrease, Value,
         EnergyShield.Recharge.Start
     },
     { "life regeneration has no effect", PercentLess, 100, Life.Regen },
     {
         "life regeneration is applied to energy shield instead",
         TotalOverride, (int)Pool.EnergyShield, Life.Regen.TargetPool
     },
     // gain (need to be FormAndStatMatcher because they also exist with flat values)
     {
         "#% of ({PoolStatMatchers}) gained",
         BaseAdd, Value.PercentOf(Reference.AsStat), Reference.AsPoolStat.Gain
     },
     {
         "recover #% of( their)? ({PoolStatMatchers})",
         BaseAdd, Value.PercentOf(Reference.AsStat), Reference.AsPoolStat.Gain
     },
     {
         "removes #% of ({PoolStatMatchers})",
         BaseSubtract, Value.PercentOf(Reference.AsStat), Reference.AsPoolStat.Gain
     },
     { @"\+# ({PoolStatMatchers}) gained", BaseAdd, Value, Reference.AsPoolStat.Gain },
     { @"gain \+# ({PoolStatMatchers})", BaseAdd, Value, Reference.AsPoolStat.Gain },
     { "replenishes energy shield by #% of armour", BaseAdd, Value.PercentOf(Armour), EnergyShield.Gain },
     {
         "recover ({PoolStatMatchers}) equal to #% of your evasion rating",
         BaseAdd, Value.PercentOf(Evasion), Reference.AsPoolStat.Gain
     },
     // charges
     {
         "#% chance to gain a power, frenzy or endurance charge",
         BaseAdd, Value / 3,
         Charge.Power.ChanceToGain, Charge.Frenzy.ChanceToGain, Charge.Endurance.ChanceToGain
     },
     {
         "(?<!chance to |when you )gain an? ({ChargeTypeMatchers})",
         BaseAdd, 100, Reference.AsChargeType.ChanceToGain
     },
     {
         "(?<!chance to |when you )gain a power or frenzy charge",
         BaseAdd, 50, Charge.Power.ChanceToGain, Charge.Frenzy.ChanceToGain
     },
     // skills
     { "base duration is # seconds", BaseSet, Value, Stat.Duration },
     { @"\+# seconds to base duration", BaseAdd, Value, Stat.Duration },
     { "base secondary duration is # seconds", BaseSet, Value, Stat.SecondaryDuration },
     {
         "#% increased duration(?! of)",
         PercentIncrease, Value, ApplyOnce(Stat.Duration, Stat.SecondaryDuration)
     },
     {
         "#% reduced duration(?! of)", PercentReduce, Value, ApplyOnce(Stat.Duration, Stat.SecondaryDuration)
     },
     { "skills cost no mana", TotalOverride, 0, Mana.Cost },
     { "you can cast an additional brand", BaseAdd, 1, Skills[Keyword.Brand].CombinedInstances },
     // traps, mines, totems
     { "trap lasts # seconds", BaseSet, Value, Stat.Trap.Duration },
     { "mine lasts # seconds", BaseSet, Value, Stat.Mine.Duration },
     { "totem lasts # seconds", BaseSet, Value, Stat.Totem.Duration },
     {
         "detonating mines is instant",
         TotalOverride, 0, Stat.BaseCastTime, With(Skills.DetonateMines)
     },
     // minions
     { "can summon up to # golem at a time", BaseSet, Value, Golems.CombinedInstances.Maximum },
     // buffs
     {
         "(?<!while |chance to )you have ({BuffMatchers})",
         TotalOverride, 1, Reference.AsBuff.NotAsBuffOn(Self)
     },
     {
         "(?<!while |chance to )gain ({BuffMatchers})",
         TotalOverride, 1, Reference.AsBuff.On(Self)
     },
     {
         "you can have one additional curse",
         BaseAdd, 1, Buff.CurseLimit
     },
     {
         "enemies can have # additional curse",
         BaseAdd, Value, Buff.CurseLimit.For(Enemy)
     },
     { "you can apply an additional curse", BaseAdd, 1, Buff.CurseLimit.For(Enemy) },
     { "unaffected by curses", PercentLess, 100, Buffs(targets: Self).With(Keyword.Curse).Effect },
     {
         "unaffected by ({SkillMatchers})",
         PercentLess, 100, Reference.AsSkill.Buff.EffectOn(Self).For(Entity.Any)
     },
     { "immun(e|ity) to curses", TotalOverride, 0, Buffs(targets: Self).With(Keyword.Curse).On },
     {
         "monsters are hexproof",
         TotalOverride, 0, Buffs(Self, Enemy).With(Keyword.Curse).On, Flag.IgnoreHexproof.IsSet.Not
     },
     { "grants? fortify", TotalOverride, 1, Buff.Fortify.On(Self) },
     { "gain elemental conflux", TotalOverride, 1, Buff.Conflux.Elemental.On(Self) },
     { "creates consecrated ground", TotalOverride, 1, Buff.Conflux.Elemental.On(Self) },
     { "(?<!chance to )impale enemies", TotalOverride, 100, Buff.Impale.Chance },
     { "({BuffMatchers}) lasts # seconds", BaseSet, Value, Reference.AsBuff.Duration },
     {
         "supported auras do not affect you",
         TotalOverride, 0, Skills.ModifierSourceSkill.Buff.EffectOn(Self)
     },
     { "totems cannot gain ({BuffMatchers})", TotalOverride, 0, Reference.AsBuff.On(Entity.Totem) },
     // flags
     // ailments
     { "causes bleeding", TotalOverride, 100, Ailment.Bleed.Chance },
     { "bleed is applied", TotalOverride, 100, Ailment.Bleed.Chance },
     { "always poison", TotalOverride, 100, Ailment.Poison.Chance },
     { "always ({AilmentMatchers}) enemies", TotalOverride, 100, Reference.AsAilment.Chance },
     { "cannot cause bleeding", TotalOverride, 0, Ailment.Bleed.Chance },
     { "cannot ignite", TotalOverride, 0, Ailment.Ignite.Chance },
     { "cannot (apply|inflict) shock", TotalOverride, 0, Ailment.Shock.Chance },
     { "cannot inflict elemental ailments", TotalOverride, 0, Ailment.Elemental.Select(s => s.Chance) },
     {
         "(you )?can afflict an additional ignite on an enemy",
         BaseAdd, 1, Ailment.Ignite.InstancesOn(Enemy).Maximum
     },
     { "(you are )?immune to ({AilmentMatchers})", TotalOverride, 100, Reference.AsAilment.Avoidance },
     { "cannot be ({AilmentMatchers})", TotalOverride, 100, Reference.AsAilment.Avoidance },
     {
         "cannot be ({AilmentMatchers}) or ({AilmentMatchers})",
         TotalOverride, 100, References[0].AsAilment.Avoidance, References[1].AsAilment.Avoidance
     },
     {
         "(immune to|cannot be affected by|immunity to) elemental ailments",
         TotalOverride, 100, Ailment.Elemental.Select(a => a.Avoidance)
     },
     {
         "poison you inflict with critical strikes deals #% more damage",
         PercentMore, Value, CriticalStrike.Multiplier.With(Ailment.Poison)
     },
     // stun
     { "(you )?cannot be stunned", TotalOverride, 100, Effect.Stun.Avoidance },
     { "additional #% chance to be stunned", BaseAdd, Value, Effect.Stun.Chance.For(Entity.OpponentOfSelf) },
     // item quantity/quality
     // range and area of effect
     // other
     { "knocks back enemies", TotalOverride, 100, Effect.Knockback.Chance },
     { "knocks enemies back", TotalOverride, 100, Effect.Knockback.Chance },
     { "knockback(?! distance)", TotalOverride, 100, Effect.Knockback.Chance },
 };
Beispiel #19
0
        //The narrative script
        public void ReadPage(Page CurrentPage, Page PageFrom, Warrior player)
        {
            if (PageFrom == CurrentPage.PageA)
            {
                Console.WriteLine(CurrentPage.IntroTextA);
            }
            if (PageFrom == CurrentPage.PageB)
            {
                Console.WriteLine(CurrentPage.IntroTextB);
            }
            if (PageFrom == CurrentPage.PageC)
            {
                Console.WriteLine(CurrentPage.IntroTextC);
            }
            Sleep(1);
            Console.WriteLine(CurrentPage.Text);
            Sleep(2);
            if (CurrentPage.ItemPickup.Name == "shield")
            {
                player.EquippedOffHand = CurrentPage.ItemPickup;
                PrintNewline("You have picked up a " + CurrentPage.ItemPickup.Name + "!");
                OffHand none = new OffHand(0, 0, "nothing", "NONE");
                CurrentPage.ItemPickup = none;
                Sleep(2);
            }

            if (GroupAlive(CurrentPage.CombatEncounter))
            {
                GroupCombatStart(player, CurrentPage.CombatEncounter);
            }
            if (player.Alive())
            {
                if (CurrentPage.PageNumber == 4)
                {
                    PrintNewline("You are victorious, well played!");
                    Console.ReadLine();
                }
                else
                {
                    string t = Console.ReadLine();
                    switch (t)
                    {
                    case "a":
                        ReadPage(CurrentPage.DestA, CurrentPage, player);
                        break;

                    case "b":
                        ReadPage(CurrentPage.DestB, CurrentPage, player);
                        break;

                    case "c":
                        ReadPage(CurrentPage.DestC, CurrentPage, player);
                        break;

                    default:
                        ReadPage(CurrentPage, CurrentPage, player);
                        break;
                    }
                }
            }
            else
            {
                PrintNewline("Game Over...");
                Console.ReadLine();
            }
        }
Beispiel #20
0
 protected IConditionBuilder OffHandAttackWith(Tags tags) =>
 OffHandAttack.And(OffHand.Has(tags));
 protected override GestureResult OffHandCheck(Body body)
 {
     return(OffHand.InRegion(body, OffHandRegion, true));
 }
 /// <summary>
 /// Creates new AdvancesSolverSettings.
 /// </summary>
 /// <param name="baseSettings">Base settings to copy.</param>
 /// <param name="initialAttributes">Starting attributes of stats that calculations are based on.</param>
 /// <param name="attributeConstraints">The attribute constraints the solver should try to fullfill.</param>
 /// <param name="pseudoAttributeConstraints">The pseudo attribute constraints the solver should try to fullfill.</param>
 /// <param name="weaponClass">WeaponClass used for pseudo attribute calculation.</param>
 /// <param name="tags">Tags used for pseudo attribute calculation.</param>
 /// <param name="offHand">OffHand used for pseudo attribute calculation.</param>
 public AdvancedSolverSettings(SolverSettings baseSettings,
     Dictionary<string, float> initialAttributes,
     Dictionary<string, Tuple<float, double>> attributeConstraints,
     Dictionary<PseudoAttribute, Tuple<float, double>> pseudoAttributeConstraints,
     WeaponClass weaponClass, Tags tags, OffHand offHand)
     : this(baseSettings.Level, baseSettings.TotalPoints, baseSettings.Checked, baseSettings.Crossed,
         baseSettings.SubsetTree, baseSettings.InitialTree, initialAttributes,
         attributeConstraints, pseudoAttributeConstraints, weaponClass, tags, offHand)
 { }
 protected override GestureResult OffHandCheck(Body body)
 {
     return(OffHand.IsIdle(body));
 }
Beispiel #24
0
        public void Run()
        {
            Weapon  Axe    = new Weapon(4, 0, 0, "axe");
            OffHand none   = new OffHand(0, 0, "nothing", "NONE");
            OffHand shield = new OffHand(1, 3, "shield", "SHIELD");
            Warrior player = new Warrior(15, 15, 10, "Fjeldulf", Axe, none);
            Warrior Gundar = new Warrior(10, 5, 10, "Gundar", Axe, shield);

            Warrior orc1 = new Warrior(5, 10, 5, "Orc", Axe, none);
            Page    p1   = new Page(1, "You enter Start room", "You come from Shield room", "You come from Orc room", "kys f*****g nigger");
            Page    p2   = new Page(2, "You enter Shield room", "You come from Start room ", "You come from Orc room", "kys f*****g nigger");
            Page    p3   = new Page(3, "You enter Orc room", "You come from Start room", "You come from Shield room", "kys f*****g nigger");
            Page    p4   = new Page(4, "You enter Victory room", "You come from Orc room", "You come from B", "kys f*****g nigger");

            List <Warrior> emptyshit = new List <Warrior>();
            List <Warrior> orcs      = new List <Warrior>();

            for (int i = 0; i < 3; i++)
            {
                orcs.Add(new Warrior(5, 5, 5, "Orc", Axe, none));
            }

            p1.PageA           = p2;
            p1.PageB           = p3;
            p1.DestA           = p2;
            p1.DestB           = p3;
            p1.ItemPickup      = none;
            p1.CombatEncounter = emptyshit;

            p2.PageA           = p1;
            p2.PageB           = p3;
            p2.DestA           = p1;
            p2.DestB           = p3;
            p2.ItemPickup      = shield;
            p2.CombatEncounter = emptyshit;

            p3.PageA           = p1;
            p3.PageB           = p2;
            p3.PageC           = p4;
            p3.DestA           = p1;
            p3.DestB           = p2;
            p3.DestC           = p4;
            p3.ItemPickup      = none;
            p3.CombatEncounter = orcs;

            p4.PageA           = p3;
            p4.PageB           = p4;
            p4.DestA           = p3;
            p4.ItemPickup      = none;
            p4.CombatEncounter = emptyshit;



            // GroupCombatStart(player, orcs);
            // Sleep(2);
            // PrintNewline(player.Name + " died after slaying " + orcsSlain + " orcs");
            // for (int i = 0; 0 < player.Hp; i++)
            // {
            //     Warrior orci = new
            // }
            //CombatStart(player, orc1);
            //CombatStart(player, Gundar);


            //string t = Console.ReadLine();
            ReadPage(p1, p1, player);
        }
Beispiel #25
0
 protected IConditionBuilder OffHandAttackWith(Tags tags) =>
 Condition.AttackWith(AttackDamageHand.OffHand).And(OffHand.Has(tags));
Beispiel #26
0
 /// <summary>
 /// Starts the tracking of Pseudo-attributes(to display in stat calculations).
 /// </summary>
 /// <param name="pseudoAttributeConstraints">The pseudo attribute constraints.</param>
 public void StartTracking(Dictionary <string, Tuple <float, double> > attributeConstraints, Dictionary <PseudoAttribute, Tuple <float, double> > pseudoAttributeConstraints, WeaponClass primaryWeapon, OffHand offHandType, Tags tags)
 {
     PseudoCalcGlobals.PrimaryWeapon = primaryWeapon;
     PseudoCalcGlobals.OffHandType   = offHandType;
     PseudoCalcGlobals.Tags          = tags;
     foreach (PseudoAttribute Attribute in pseudoAttributeConstraints.Keys)//Don't need target value and weight
     {
         Add(Attribute.Name, new PseudoStat(Attribute.Attributes));
     }
 }