public static Session ToSession(this Combat combat, Session defaultValues)
		{
			if (combat == null)
				return null;

			var target = combat.Targets.OrderBy(t => t.DamageDone).Last().Character;
			int additionalTargetNumber = combat.Targets.Count(t => t.Character == null || !t.Character.IsPlayer) - 1;

			Session session = new Session
			{
				Duration = combat.Duration,
				Name = $"{target}{(additionalTargetNumber > 0 ? $" (+{additionalTargetNumber})" : "")}, {combat.Duration.ToString("0.###", CultureInfo.InvariantCulture)}s, {combat.Dps.ToString("0.###", CultureInfo.InvariantCulture)}dps"
			};

			foreach (var ability in combat.Abilities.Where(a => a.Targets.Any(t => t.DamageDone > 0 && t.Character != combat.Player)))
			{
				var sessionAbility = new SessionAbility { Id = ability.Id };

				// not in db
				if (sessionAbility.Ability == null)
					continue;

				var hittingActions = ability.Activations.SelectMany(activation => activation.Actions.Where(a => a.Amount > 0 && !a.IsCritical)).ToList();
				var criticalActions = ability.Activations.SelectMany(activation => activation.Actions.Where(a => a.Amount > 0 && a.IsCritical)).ToList();
				int maximumCritical = criticalActions.Count > 0 ? criticalActions.Max(aa => aa.Amount) : 0;
				int maximum = hittingActions.Count > 0 ? hittingActions.Max(aa => aa.Amount) : 0;
				int minimum = hittingActions.Count > 0 ? hittingActions.Min(aa => aa.Amount) : 0;
				int average = hittingActions.Count > 0 ? (int) hittingActions.Average(aa => aa.Amount) : 0;
				double surge = maximum > 0 && maximumCritical > 0 ? (maximumCritical - maximum) / (double) maximum : 0;
				
				sessionAbility.Activations = ability.Activations.Count;
				sessionAbility.Info =
						$"Activations: {ability.Activations.Count}\n" +
						$"Total hits: {ability.Activations.Sum(a => a.Actions.Count)}\n" +
						$"Hits per activation: {(double) ability.Activations.Sum(a => a.Actions.Count)/ability.Activations.Count} [{string.Join("/", ability.Activations.Select(a => a.Actions.Count).Distinct().OrderBy(n => n))}]\n" +
						$"Maximum critical hit damage: {maximumCritical}\n" +
						$"Surge: {surge:P}\n" +
						$"Maximum hit damage: {maximum}\n" +
						$"Minimum hit damage: {minimum}\n" +
						$"Average hit damage: {average}\n" +
						$"Total Damage: {ability.Targets.Sum(t => t.DamageDone)}";

				var abilityDefauls = defaultValues?.Abilities.FirstOrDefault(a => a.Id == ability.Id);
				if (abilityDefauls != null)
				{
					sessionAbility.SurgeBonus = abilityDefauls.SurgeBonus;
					sessionAbility.Autocrit = abilityDefauls.Autocrit;
					sessionAbility.DamageMultiplier = abilityDefauls.DamageMultiplier;
					sessionAbility.ArmorReduction = abilityDefauls.ArmorReduction;
					sessionAbility.ForceOffHand = abilityDefauls.ForceOffHand;
				}

				session.Abilities.Add(sessionAbility);
			}
			session.Abilities.Sort((a1, a2) => string.CompareOrdinal(a1.Ability.Name, a2.Ability.Name));
			return session;
		}
		private void SaveAsDefault()
		{
			var ability = _defaultValues.Abilities.FirstOrDefault(a => a.Ability.NameId == _sessionAbility.Ability.NameId);
			if (ability == null)
			{
				ability = new SessionAbility {Id = _sessionAbility.Ability.NameId};
				_defaultValues.Abilities.Add(ability);
			}
			ability.SurgeBonus = SurgeBonus;
			ability.Autocrit = Autocrit;
			ability.DamageMultiplier = DamageMultiplier;
			ability.ArmorReduction = ArmorReduction;
			ability.ForceOffHand = ForceOffHand;
		}
		public SessionAbilityViewModel(SessionAbility sessionAbility, Configuration configuration, Session defaultValues)
		{
			_sessionAbility = sessionAbility;
			_configuration = configuration;
			_defaultValues = defaultValues;
			UpdateCanForceOffHand();
			configuration.DualWieldUpdated += UpdateCanForceOffHand;
			SaveAsDefaultCommand = new CommandHandler(SaveAsDefault);
		}
Beispiel #4
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;
		}