public SessionViewModel(Session session, Configuration configuration, Session defaultValues)
		{
			Session = session;
			Abilities = new ObservableCollection<SessionAbilityViewModel>();
			foreach (var sessionAbility in session.Abilities)
			{
				var ability = new SessionAbilityViewModel(sessionAbility, configuration, defaultValues);
				ability.SessionAbilityUpdated += OnSessionUpdated;
				Abilities.Add(ability);
			}
		}
		public SessionAbilityViewModel(SessionAbility sessionAbility, Configuration configuration, Session defaultValues)
		{
			_sessionAbility = sessionAbility;
			_configuration = configuration;
			_defaultValues = defaultValues;
			UpdateCanForceOffHand();
			configuration.DualWieldUpdated += UpdateCanForceOffHand;
			SaveAsDefaultCommand = new CommandHandler(SaveAsDefault);
		}
Example #3
0
		public static void FillParameters(this Expression expression, Configuration configuration)
		{
			if (expression == null || configuration == null)
				return;

			expression.Parameters[LevelParameterName] = configuration.Level;
			expression.Parameters[AccuracyParameterName] = configuration.AccuracyPoints;
			expression.Parameters[AlacrityParameterName] = configuration.AlacrityPoints;
			expression.Parameters[CriticalParameterName] = configuration.CriticalPoints;
			expression.Parameters[MasteryParameterName] = configuration.BuffedMasteryPoints;
			expression.Parameters[PowerParameterName] = configuration.PowerPoints;
			expression.Parameters[SpellPowerParameterName] = configuration.MainHand.Power + configuration.OffHand.Power;
		}
Example #4
0
		public static double? Evaluate(this Expression expression, Configuration configuration)
		{
			if (expression != null)
			{
				expression.FillParameters(configuration);
				var result = expression.Evaluate() as IConvertible;
				return result != null ? Convert.ToDouble(result) : 0;
			}

			return null;
		}
		public ConfigurationViewModel(Configuration configuration)
		{
			_configuration = configuration;
			CorrectionViewModel = new CorrectionViewModel(configuration);
			SetMainHandCommand = new CommandHandler(p =>
			{
				int rating = int.Parse(p.ToString());
				MainHandMin = _minDamage[rating];
				MainHandMax = _maxDamage[rating];
				MainHandPower = _power[rating];
			});
			SetOffHandCommand = new CommandHandler(p =>
			{
				int rating = int.Parse(p.ToString());
				OffHandMin = _minDamage[rating];
				OffHandMax = _maxDamage[rating];
				OffHandPower = _power[rating];
			});
		}
Example #6
0
		public static double CalculateDps(Session session, Configuration configuration)
		{
			lock (Lock)
			{
				if (session == null)
					return 0;

				return session.Abilities.Sum
				(
					a => GetAbilityDamage(configuration, a, session.EnergyKineticDamageReduction, session.ElementalInternalDamageReduction, session.DefenseChance)
					* a.Activations
					* a.DamageMultiplier
					* (a.Ability.IgnoresAlacrity ? 1 : 1 + configuration.Alacrity)
				)
				/ session.Duration;
			}
		}
Example #7
0
		private static ConfigurationCorrection FindHighestDpsCorrection(Session session, Configuration configuration, ConfigurationCorrection correction, int budget, int step, int lastStep)
		{
			// ncalc is not thread-safe, we need lock here since we're using static instance of formulas
			lock (Lock)
			{
				correction.Dps = 0;
				var range = (lastStep + 1) * 2 + 1;
				var al = Math.Max(correction.AlacrityPoints - lastStep - 1, 0);
				var pw = Math.Max(correction.PowerPoints - lastStep - 1, 0);
				var cr = Math.Max(correction.CriticalPoints - lastStep - 1, 0);
				var ac = Math.Max(correction.AccuracyPoints - lastStep - 1, 0);

				for 
				(
					configuration.PowerPoints = pw;
					configuration.PowerPoints <= Math.Min(budget, pw + range);
					configuration.PowerPoints += step
				)
				{
					for 
					(
						configuration.CriticalPoints = cr;
						configuration.CriticalPoints <= Math.Min(budget - configuration.PowerPoints, cr + range);
						configuration.CriticalPoints += step
					)
					{
						for 
						(
							configuration.AlacrityPoints = al;
							configuration.AlacrityPoints <= Math.Min(budget - configuration.PowerPoints - configuration.CriticalPoints, al + range);
							configuration.AlacrityPoints += step
						)
						{
							for 
							(
								configuration.AccuracyPoints = ac;
								configuration.AccuracyPoints <= Math.Min(budget - configuration.PowerPoints - configuration.CriticalPoints - configuration.AlacrityPoints, ac + range);
								configuration.AccuracyPoints += step
							)
							{
								configuration.AugmentMasteryPoints = budget - configuration.PowerPoints - configuration.CriticalPoints - configuration.AlacrityPoints - configuration.AccuracyPoints;
								var dps = CalculateDps(session, configuration);

								if (correction.Dps < dps)
								{
									correction.Dps = dps;
									correction.AccuracyPoints = configuration.AccuracyPoints;
									correction.CriticalPoints = configuration.CriticalPoints;
									correction.MasteryPoints = configuration.AugmentMasteryPoints;
									correction.AlacrityPoints = configuration.AlacrityPoints;
									correction.PowerPoints = configuration.PowerPoints;
								}
							}
						}
					}
				}
				if (step == 1)
					return correction;

				return FindHighestDpsCorrection(session, configuration, correction, budget, Math.Max(step / 2, 1), step);
			}
		}
Example #8
0
		private static double GetAbilityDamage(Configuration configuration, SessionAbility ability, double energyKineticReduction, double internalElementalReduction, double defenseChance)
		{
			double damage = 
			(
				from token in ability.Ability.GetAbilityTokenDamageList(configuration, DamageRange.Average, ability.ForceOffHand)
				let tokenDamage = token.Sum
				(
					action =>
					{
						var modifier = Math.Min(1 - internalElementalReduction, 1);
						if (action.DamageType == DamageType.Kinetic || action.DamageType == DamageType.Energy)
							modifier = Math.Min(1, action.IsOffHand ? configuration.OffHandAccuracy : configuration.Accuracy)
							* Math.Min(1 - Math.Min(defenseChance, 1 + defenseChance - (action.IsOffHand ? configuration.OffHandAccuracy : configuration.Accuracy)), 1)
							* Math.Min(1 + ability.ArmorReduction - energyKineticReduction, 1);
						return action.Damage * modifier;
					}
				)
				select 
					tokenDamage
					* token.Multiplier
			).Sum();

			damage = damage 
				+ damage * ability.Autocrit * (configuration.Surge + ability.SurgeBonus) * (1 + configuration.Critical)
				+ damage * (1 - ability.Autocrit) * configuration.Critical * (configuration.Surge + ability.SurgeBonus);

			return damage;
		}
Example #9
0
		private static double GetActionDamage(Action action, Configuration configuration, DamageRange range, bool offHand = false, bool forcedOffhand = false)
		{
			var hand = offHand ? configuration.OffHand : configuration.MainHand;
			double damage = 0;

			if (action.Type == ActionType.WeaponDamage)
			{
				damage += (1 + action.AmountModifierPercent) * hand.Multiplier
					* (range == DamageRange.Minimum
						? hand.DamageMin : 
						(range == DamageRange.Maximum
							? hand.DamageMax
							: hand.DamageAvg));
			}
			if (!forcedOffhand)
			{
				damage += action.Coefficient * (action.Type == ActionType.WeaponDamage ? configuration.BonusDamage : configuration.SpellBonusDamage)
					+ (range == DamageRange.Minimum
						? action.StandardHealthPercentMin : 
						(range == DamageRange.Maximum
							? action.StandardHealthPercentMax
							: action.StandardHealthPercentAvg))
					* configuration.StandardDamage;
			}
			return damage;
		}
Example #10
0
		private static List<TokenDamage> GetAbilityTokenDamageList(this Ability ability, Configuration configuration, DamageRange range, bool forceOffhand = false)
		{
			lock (Lock)
			{
				if (ability == null)
					return null;

				var damage = new List<TokenDamage>();

				foreach (var token in ability.Tokens.Where(t => t.Type == TokenType.Damage && t.Coefficients.Count > 0))
				{
					// Main hand
					var mainHandActions = token.Coefficients.Where(a => a.IgnoreDualWieldModifier).ToList();
					if (mainHandActions.Count == 0)
						mainHandActions = token.Coefficients;

					var tokenDamage = new TokenDamage { Multiplier = token.Multiplier };
					tokenDamage.AddRange(mainHandActions.Select(action => new ActionDamage(false, GetActionDamage(action, configuration, range),
						action.DamageType == DamageType.Weapon ? configuration.MainHand.DamageType : action.DamageType)));

					// Offhand (only for weapon damage type)
					if (configuration.DualWield)
					{
						var offHandActions = token.Coefficients.Where(a => !a.IgnoreDualWieldModifier && a.Type == ActionType.WeaponDamage).ToList();

						if (offHandActions.Count > 0)
							tokenDamage.AddRange(offHandActions.Select(action => new ActionDamage(true, GetActionDamage(action, configuration, range, true),
								action.DamageType == DamageType.Weapon ? configuration.OffHand.DamageType : action.DamageType)));
						else if (forceOffhand)
						{
							tokenDamage.AddRange(mainHandActions.Where(a => a.Type == ActionType.WeaponDamage).Select(action => 
								new ActionDamage(true, GetActionDamage(action, configuration, range, true, true),
								action.DamageType == DamageType.Weapon ? configuration.OffHand.DamageType : action.DamageType)));
						}
					}

					damage.Add(tokenDamage);
				}

				return damage;
			}
		}
Example #11
0
		public static double GetAbilityDamageMax(this Ability ability, Configuration configuration, bool forceOffhand = false)
		{
			return ability?.GetAbilityTokenDamageList(configuration, DamageRange.Maximum, forceOffhand).Sum(d => d.Sum(t => t.Damage) * d.Multiplier) ?? 0;
		}