public SecondaryAttributes( Health health, CriticalStrike criticalStrike, Hit hit, Dodge dodge, Parry parry, Defense defense, BlockDamage blockDamage, MeleeAttackPower meleeAttackPower, RangedAttackPower rangedAttackPower, ArmorAmount armor, WeaponSkills weaponSkills) { Health = health; CriticalStrike = criticalStrike; Hit = hit; Dodge = dodge; Parry = parry; Defense = defense; BlockDamage = blockDamage; MeleeAttackPower = meleeAttackPower; RangedAttackPower = rangedAttackPower; Armor = armor; WeaponSkills = weaponSkills; }
/// <summary> /// Calculate secondary attributes from primary attributes. /// i.e. How much critical strike chance does the characters agility provide? /// </summary> public override SecondaryAttributes CalculateSecondaryAttributes(PrimaryAttributes primaryAttributes) { // (Source: https://rankedboost.com/world-of-warcraft/classic-stats/) // 2 Melee Attack Power per 1 point of Strength. var meleeAttackPower = new MeleeAttackPower(primaryAttributes.Strength.Value * 2); // Block 1 Damage for every 20 points of Strength. var blockDamage = new BlockDamage(primaryAttributes.Strength.Value / 20); // 2 Armor for every 1 point of Agility. var armor = new ArmorAmount(primaryAttributes.Agility.Value / 2); // 1% Critical Strike Chance for every 20 points of Agility. var criticalStrike = new CriticalStrike(primaryAttributes.Agility.Value / 20); // 1 Ranged Attack Power per 1 point of Agility. var rangedAttackPower = new RangedAttackPower(primaryAttributes.Agility.Value); // 1% Dodge per 20 point of Agility. var dodge = new Dodge(primaryAttributes.Agility.Value / 20); // 5% base chance to Parry. (Source: https://worldofwarcraft.fandom.com/et/wiki/Parry) var parry = new Parry(5); // 10 Health for every 1 point of Stamina. var health = new Health((int)primaryAttributes.Stamina.Value / 10); var attributes = new SecondaryAttributes( health, criticalStrike, Hit.Zero, dodge, parry, Defense.Zero, blockDamage, meleeAttackPower, rangedAttackPower, armor, new WeaponSkills()); return(attributes); }
public WhiteAttackTable( Miss missChance, Dodge dodgeChance, Parry parryChance, GlancingBlow glancingBlowChance, CrushingBlow crushingBlowChance, Block blockChance, CriticalStrike criticalStrikeChance) { var chances = new List <Rating> { missChance, dodgeChance, parryChance, glancingBlowChance, crushingBlowChance, blockChance, criticalStrikeChance }; _ranges = CalculateAttackTableRanges(chances); }
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 IReadOnlyList <MatcherData> CreateCollection() => new ConditionMatcherCollection(_modifierBuilder) { // generic { "on ({ActionMatchers})", Reference.AsAction.On }, { "on ({KeywordMatchers}) ({ActionMatchers})", And(Condition.WithPart(References[0].AsKeyword), References[1].AsAction.On) }, { "when you ({ActionMatchers}) an enemy", Reference.AsAction.On }, { "when you ({ActionMatchers}) a rare or unique enemy", And(Enemy.IsRareOrUnique, Reference.AsAction.On) }, { "when projectile ({ActionMatchers}) a rare or unique enemy", And(Enemy.IsRareOrUnique, Condition.WithPart(Keyword.Projectile), Reference.AsAction.On) }, { "(when you|on) ({ActionMatchers}) a ({AilmentMatchers}) enemy", And(References[1].AsAilment.IsOn(Enemy), References[0].AsAction.On) }, // kill { "if you or your totems kill an enemy", Or(Kill.On, Kill.By(Entity.Totem).On) }, // hit { "when hit", Hit.By(Enemy).On }, { "when you are hit", Hit.By(Enemy).On }, { "with hits", Hit.On }, { "for each enemy hit by (your )?attacks", And(With(Keyword.Attack), Hit.On) }, { "when you or your totems hit an enemy with a spell", And(With(Keyword.Spell), Hit.On.Or(Hit.By(Entity.Totem).On)) }, { "on hit no more than once every # seconds", Hit.On }, // critical strike { "critical strikes have a", CriticalStrike.On }, { "when you deal a critical strike", CriticalStrike.On }, { "if you get a critical strike", CriticalStrike.On }, { "when you take a critical strike", CriticalStrike.By(Enemy).On }, // skill cast { "when you place a totem", Totems.Cast.On }, { "when you summon a totem", Totems.Cast.On }, { "when you use a warcry", Skills[Keyword.Warcry].Cast.On }, { "when you use a fire skill", Skills[Fire].Cast.On }, // block { "when they block", Block.On }, { "when you block", Block.On }, // other { "when you stun an enemy with a melee hit", And(Condition.WithPart(Keyword.Melee), Effect.Stun.InflictionAction.On) }, { "when you stun with melee damage", And(Condition.WithPart(Keyword.Melee), Effect.Stun.InflictionAction.On) }, { "after spending( a total of)? # mana", Action.SpendMana(Value).On }, { "when you gain a ({ChargeTypeMatchers})", Reference.AsChargeType.GainAction.On }, { "you gain", Condition.True }, // may be left over at the end, does nothing { "you", Condition.True }, { "grants", Condition.True }, // unique { "when your trap is triggered by an enemy", Action.Unique("When your Trap is triggered by an Enemy").On }, { "when your mine is detonated targeting an enemy", Action.Unique("When your Mine is detonated targeting an Enemy").On }, { "on use", Action.Unique("When your use the Flask").On }, { "when you gain Adrenaline", Action.Unique("When you gain Adrenaline").On }, { "when you block attack damage", Action.Unique("Block.Attack").On }, { "when you block spell damage", Action.Unique("Block.Spell").On }, { "(every|each) second(, up to a maximum of #)?", Action.Unique("Interval.OneSecond").On }, { "every 2 seconds(, up to a maximum of #)?", Action.Unique("Interval.TwoSeconds").On }, { "after channelling for # seconds?", Action.Unique("PeriodOfChannelling").On }, }; // add
private static CurrentSpell SwordMCommands(Player warrior) { ConsoleKeyInfo enter = new ConsoleKeyInfo(); Console.Clear(); var counter = 1; while (enter.Key != ConsoleKey.Enter) { if (enter.Key == ConsoleKey.DownArrow) { counter++; } else if (enter.Key == ConsoleKey.UpArrow) { counter--; } GameTitle.GetTitle(); string actionSelect = $"SELECT ACTION FOR {warrior.Name}"; string levelUpCrit = $"CRITICAL STRIKE-- LOSE THIS TURN AND HAVE 30% CHANCE FOR 2X CRITICAL STRIKE FOR EACH ACTION YOUR SWORDMASTER DOES UNTIL END OF GAME"; string mirrorImage = $"MIRROR IMAGE-- YOUR OPONENT LOSES 1 TURN, YOU DEAL {warrior.Damage} TO HIM, COOLDOWN: 3"; string bladeSlash = $"BLADESLASH-- DAMAGE:{warrior.Damage * 2} NO COOLDOWN"; string windFury = $"WINDFURY-- DAMAGE:{warrior.Damage * 5} COOLDOWN: 4"; Console.WriteLine("{0}", actionSelect); switch (counter) { case 1: Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("{0,2}", "-> " + levelUpCrit); Console.WriteLine("{0,2}", mirrorImage); Console.WriteLine("{0,2}", bladeSlash); Console.WriteLine("{0,2}", windFury); break; case 2: Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("{0,2}", levelUpCrit); Console.WriteLine("{0,2}", "-> " + mirrorImage); Console.WriteLine("{0,2}", bladeSlash); Console.WriteLine("{0,2}", windFury); break; case 3: Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("{0,2}", levelUpCrit); Console.WriteLine("{0,2}", mirrorImage); Console.WriteLine("{0,2}", "-> " + bladeSlash); Console.WriteLine("{0,2}", windFury); break; case 4: Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("{0,2}", levelUpCrit); Console.WriteLine("{0,2}", mirrorImage); Console.WriteLine("{0,2}", bladeSlash); Console.WriteLine("{0,2}", "-> " + windFury); break; default: if (counter == 5) { counter = 1; Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("{0,2}", "-> " + levelUpCrit); Console.WriteLine("{0,2}", mirrorImage); Console.WriteLine("{0,2}", bladeSlash); Console.WriteLine("{0,2}", windFury); break; } else if (counter == 0) { counter = 4; Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("{0,2}", levelUpCrit); Console.WriteLine("{0,2}", mirrorImage); Console.WriteLine("{0,2}", bladeSlash); Console.WriteLine("{0,2}", "-> " + windFury); break; } break; } enter = Console.ReadKey(); Console.Clear(); } var currentSpell = new CurrentSpell(); switch (counter) { case 1: var criticalStrike = new CriticalStrike(); currentSpell = criticalStrike.TurnOnCrit(warrior); break; case 2: var mirrorImage = new MirrorImage(); currentSpell = mirrorImage.GetMirrorImage(warrior); break; case 3: var slash = new BladeSlash(); currentSpell = slash.GetSlash(warrior); break; default: var windfury = new Windfury(); currentSpell = windfury.GetWindFury(warrior); break; } return(currentSpell); }