public static void ApplyBaseAttack(ISimulationData data, SimulationSampleSet sampleSet, IEntity target) { float min = GetMinDamage(data); float max = GetMaxDamage(data); bool isCritical = ApplyCritical(data, ref min, ref max); float damage = data.Random(min, max); ApplyDamage(data, target, damage); sampleSet.AddDamage(D3DamageType.Physical, damage, isCritical); }
public static void ApplyRunningSkills(ISimulationData data, SimulationSampleSet set) { // Save the selection to restore after we are done SkillCombo currentSkill = data.SelectedSkill; IList<SkillCombo> runningSkills = data.GetRunningSkills(); foreach (SkillCombo skill in runningSkills) { if (data.CurrentTime - skill.LastTrigger > 1.0f) { // Select the skill and execute it data.SelectedSkill = skill; ExecuteSkillRunning(data, set); set.AddStat(SimulationStat.RunningExecutions); } } data.SelectedSkill = currentSkill; }
public static void ApplyRegen(ISimulationData data, SimulationSampleSet sampleSet) { // Resources float primaryMax = data.AttributeSet.GetValue(D3Attribute.PrimaryResource); float secondaryMax = data.AttributeSet.GetValue(D3Attribute.SecondaryResource); float primaryRegen = data.AttributeSet.GetValue(D3Attribute.PrimaryResourceRegen); float secondaryRegen = data.AttributeSet.GetValue(D3Attribute.SecondaryResourceRegen); primaryRegen = data.Character.AddValue(D3EntityAttribute.PrimaryResource, primaryRegen, primaryMax); secondaryRegen = data.Character.AddValue(D3EntityAttribute.SecondaryResource, secondaryRegen, secondaryMax); sampleSet.AddStat(SimulationStat.PrimaryResourceRegen, primaryRegen); sampleSet.AddStat(SimulationStat.SecondaryResourceRegen, secondaryRegen); // Life float lifeMax = data.AttributeSet.GetValue(D3Attribute.Life); float lifeRegen = data.AttributeSet.GetValue(D3Attribute.LifeRegen); lifeRegen = data.Character.AddValue(D3EntityAttribute.Life, lifeRegen, lifeMax); sampleSet.AddStat(SimulationStat.LifeRegen, lifeRegen); }
public SimulationSampleSet Simulate(ISimulationData data) { AttributeSet skillAttributes = SimulateShared.GetSkillAttributes(data, this.skillName, this.runeName); if (skillAttributes == null) { return null; } var set = new SimulationSampleSet { Name = this.Name }; SimulateShared.DeductSkillInitialCost(data); float lastRegen = 0; while (data.CurrentTime < data.MaxTime) { // Apply Regeneration while (data.CurrentTime - lastRegen > 1.0f) { SimulateShared.ApplyRegen(data, set); lastRegen += 1.0f; } // Update the targets and running skills data.UpdateTargets(set); data.UpdateSkills(); // Process running skills SimulateShared.ApplyRunningSkills(data, set); // Check if we have enough resources to perform the action ExecuteSkillResult result = SimulateShared.ExecuteSkill(data, set); switch (result) { case ExecuteSkillResult.Cooldown: { set.AddStat(SimulationStat.DelayCooldown, TestInterval); break; } case ExecuteSkillResult.Running: { set.AddStat(SimulationStat.DelayRunning, TestInterval); break; } case ExecuteSkillResult.InsufficientResources: { set.AddStat(SimulationStat.DelayResource, TestInterval); break; } case ExecuteSkillResult.InsufficientTime: { set.AddStat(SimulationStat.DelayTime, TestInterval); break; } case ExecuteSkillResult.Success: { // We are done continue; } default: { throw new NotImplementedException(); } } // The skill was not executed so pass some time data.CurrentTime += TestInterval; } return set; }
public static void ApplySkillAttack(ISimulationData data, SimulationSampleSet sampleSet, IEntity target, bool isPrimary) { float skillMultiplier = data.SelectedSkill.GetValue(D3SkillAttribute.DmgBonusPrimary) / 100.0f; if (!isPrimary) { float secondaryMultiplier = data.SelectedSkill.GetValue(D3SkillAttribute.DmgBonusSecondary) / 100.0f; if (secondaryMultiplier > 0.0f) { skillMultiplier = secondaryMultiplier; } } float min = GetMinDamage(data) * skillMultiplier; float max = GetMaxDamage(data) * skillMultiplier; bool isCritical = ApplyCritical(data, ref min, ref max); float damage = data.Random(min, max); ApplyDamage(data, target, damage); sampleSet.AddDamage(D3DamageType.Physical, damage, isCritical); }
public static void FinalizeAction(ISimulationData data, SimulationSampleSet sampleSet) { float actionTime = GetActionTime(data); data.CurrentTime += actionTime; sampleSet.AddStat(SimulationStat.ActionTime, actionTime); sampleSet.AddStat(SimulationStat.DelayTime, data.MainData.Generic.ActionDelay); sampleSet.AddStat(SimulationStat.Actions); }
// Similar to ExecuteSkill but for running effects public static void ExecuteSkillRunning(ISimulationData data, SimulationSampleSet set) { int targetMax = GetSkillTargetCount(data); IList<IEntity> targets = data.PickRandomTargets(targetMax); for (int i = 0; i < targets.Count; i++) { IEntity target = targets[i]; ApplySkillAttack(data, set, target, i == 0); } data.SelectedSkill.LastTrigger = data.CurrentTime; }
public static ExecuteSkillResult ExecuteSkill(ISimulationData data, SimulationSampleSet set) { // try to perform action if (data.IsRunning(data.SelectedSkill)) { return ExecuteSkillResult.Running; } if (data.IsOnCooldown(data.SelectedSkill)) { return ExecuteSkillResult.Cooldown; } if (!CheckSufficientResource(data)) { return ExecuteSkillResult.InsufficientResources; } if (!CanExecuteAction(data)) { return ExecuteSkillResult.InsufficientTime; } int targetMax = GetSkillTargetCount(data); IList<IEntity> targets = data.PickRandomTargets(targetMax); for (int i = 0; i < targets.Count; i++) { IEntity target = targets[i]; ApplySkillAttack(data, set, target, i == 0); } data.SelectedSkill.LastTrigger = data.CurrentTime; ApplySkillCooldown(data); ApplySkillRunning(data); // Cost is only once per action DeductSkillCost(data); FinalizeAction(data, set); return ExecuteSkillResult.Success; }