// 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; }
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; }
/// <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) { }
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(); }
public bool ShieldWeild(OffHand offHand) { if (offHand.Type == "SHIELD") { return(true); } else { return(false); } }
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; }
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"); } }
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 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 }, };
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 }, };
//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(); } }
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)); }
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); }
protected IConditionBuilder OffHandAttackWith(Tags tags) => Condition.AttackWith(AttackDamageHand.OffHand).And(OffHand.Has(tags));
/// <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)); } }