// Creates attack from gem. public static AttackSkill Create(Item gem, Computation compute) { return(new AttackSkill(gem, compute)); }
public AttackSource(string name, AttackSkill skill, Weapon weapon, Computation compute) { Name = name; Compute = compute; if (weapon == null) // Spells get damage from gem local attributes. { Nature = new DamageNature(skill.Nature); foreach (var attr in skill.Local) { Damage damage = Damage.Create(skill.Nature, attr.Key, attr.Value); if (damage != null) { Deals.Add(damage); } } if (skill.Gem.Properties.TryGetValue("Cast Time: # sec", 0, out CastTime)) { APS = 1 / CastTime; } else { APS = CastTime = 1; // Spell without Cast Time has cast time of 1 second. } if (!skill.Gem.Properties.TryGetValue("Critical Strike Chance: #%", 0, out CriticalChance)) { CriticalChance = 0; // Spell without Critical Strike Chance has none. } Local = new AttributeSet(); // No local weapon attributes. } else { if ((skill.Nature.WeaponType & weapon.Nature.WeaponType) == 0) // Skill can't be used. // Override weapon type and form of skill with actual weapon (client shows damage of unuseable skills as well). { Nature = new DamageNature(skill.Nature) { Form = weapon.Nature.Form, WeaponHand = weapon.Hand, WeaponType = weapon.Nature.WeaponType } } ; else // Narrow down weapon type and form of skill gem to actual weapon (e.g. Frenzy). { Nature = new DamageNature(skill.Nature) { Form = skill.Nature.ChooseWeaponForm(weapon.Nature), // XXX: Choose between melee or projectile form according to weapon. WeaponHand = weapon.Hand, WeaponType = skill.Nature.WeaponType & weapon.Nature.WeaponType } }; // XXX: If source has no form, but skill has form defined, then force form of skill. // This happens in form transition from melee to projectile with skills like Spectral Throw. if (Nature.Form == DamageForm.Any && skill.Nature.Form != DamageForm.Any) { Nature.Form = skill.Nature.Form; } foreach (Damage damage in weapon.Deals) { Deals.Add(new Damage(damage) { Form = Nature.Form, Source = Nature.Source, WeaponHand = Nature.WeaponHand, WeaponType = Nature.WeaponType }); } foreach (Damage.Added added in weapon.Added) { if (weapon.Is(added.Hand)) // Added damage may require specific hand. { added.Apply(this, 100); } } APS = weapon.Attributes["Attacks per Second: #"][0]; if (weapon.Attributes.ContainsKey("Critical Strike Chance: #%")) { CriticalChance = weapon.Attributes["Critical Strike Chance: #%"][0]; } else { CriticalChance = 0; // Weapon without Critical Strike Chance has none. } Local = weapon.Attributes; } }
// Creates damage multiplier. public static More Create(KeyValuePair <string, List <float> > attr, Computation compute) { Match m = ReMoreBase.Match(attr.Key); if (m.Success) { return(new More(attr.Value[0] - 100)); } else { m = ReMoreBaseType.Match(attr.Key); if (m.Success) { return(new More(m.Groups[1].Value, attr.Value[0] - 100)); } else { m = ReMoreSimple.Match(attr.Key); if (m.Success) { return(new More(m.Groups[2].Value, m.Groups[1].Value == "more" ? attr.Value[0] : -attr.Value[0])); } else { m = ReMoreAll.Match(attr.Key); if (m.Success) { return(new More(m.Groups[1].Value == "more" ? attr.Value[0] : -attr.Value[0])); } else { m = ReMoreWhen.Match(attr.Key); if (m.Success) { return(new More(m.Groups[1].Value, attr.Value[0])); } else { m = ReMoreWith.Match(attr.Key); if (m.Success) { return new More(m.Groups[1].Value, attr.Value[0]) { Source = DamageSource.Attack } } ; else { if (compute.IsDualWielding && attr.Key == "When Dual Wielding, Deals #% Damage from each Weapon combined") { return(new More(attr.Value[0] - 100)); } } } } } } } return(null); }