public override bool ApplyInstant(FormationUnit performer, FormationUnit target, Effect effect) { if (target == null) { return(false); } float moveChance = effect.IntegerParams[EffectIntParams.Chance].HasValue ? (float)effect.IntegerParams[EffectIntParams.Chance].Value / 100 : 1; moveChance -= target.Character.GetSingleAttribute(AttributeType.Move).ModifiedValue; if (performer != null && performer.Character is Hero) { moveChance += performer.Character.GetSingleAttribute(AttributeType.MoveChance).ModifiedValue; } moveChance = Mathf.Clamp(moveChance, 0, 0.95f); if (RandomSolver.CheckSuccess(moveChance)) { target.Pull(PullParam); return(true); } return(false); }
public static void ExecuteSkill(FormationUnit performerUnit, FormationUnit targetUnit, CombatSkill skill, SkillArtInfo artInfo) { SkillResult.Skill = skill; SkillResult.ArtInfo = artInfo; var target = targetUnit.Character; var performer = performerUnit.Character; ApplyConditions(performerUnit, targetUnit, skill); if (skill.Move != null && !performerUnit.CombatInfo.IsImmobilized) { if (skill.Move.Pullforward > 0) { performerUnit.Pull(skill.Move.Pullforward, false); } else if (skill.Move.Pushback > 0) { performerUnit.Push(skill.Move.Pushback, false); } } if (skill.Category == SkillCategory.Heal || skill.Category == SkillCategory.Support) { #region Heal if (skill.Heal != null) { float initialHeal = RandomSolver.Next(skill.Heal.MinAmount, skill.Heal.MaxAmount + 1) * (1 + performer.GetSingleAttribute(AttributeType.HpHealPercent).ModifiedValue); if (skill.IsCritValid) { float critChance = performer[AttributeType.CritChance].ModifiedValue + skill.CritMod / 100; if (RandomSolver.CheckSuccess(critChance)) { int critHeal = target.Heal(initialHeal * 1.5f, true); targetUnit.OverlaySlot.UpdateOverlay(); SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, critHeal, SkillResultType.CritHeal)); ApplyEffects(performerUnit, targetUnit, skill); if (targetUnit.Character.IsMonster == false) { DarkestDungeonManager.Data.Effects["crit_heal_stress_heal"].ApplyIndependent(targetUnit); } return; } } int heal = target.Heal(initialHeal, true); targetUnit.OverlaySlot.UpdateOverlay(); SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, heal, SkillResultType.Heal)); ApplyEffects(performerUnit, targetUnit, skill); } else { SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, SkillResultType.Utility)); ApplyEffects(performerUnit, targetUnit, skill); } #endregion } else { #region Damage float accuracy = skill.Accuracy + performer.Accuracy; float hitChance = Mathf.Clamp(accuracy - target.Dodge, 0, 0.95f); float roll = (float)RandomSolver.NextDouble(); if (target.BattleModifiers != null && target.BattleModifiers.CanBeHit == false) { roll = float.MaxValue; } if (roll > hitChance) { if (!(skill.CanMiss == false || (target.BattleModifiers != null && target.BattleModifiers.CanBeMissed == false))) { if (roll > Mathf.Min(accuracy, 0.95f)) { SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, SkillResultType.Miss)); } else { SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, SkillResultType.Dodge)); } ApplyEffects(performerUnit, targetUnit, skill); return; } } float initialDamage = performer is Hero? Mathf.Lerp(performer.MinDamage, performer.MaxDamage, (float)RandomSolver.NextDouble()) * (1 + skill.DamageMod) : Mathf.Lerp(skill.DamageMin, skill.DamageMax, (float)RandomSolver.NextDouble()) * performer.DamageMod; int damage = Mathf.CeilToInt(initialDamage * (1 - target.Protection)); if (damage < 0) { damage = 0; } if (target.BattleModifiers != null && target.BattleModifiers.CanBeDamagedDirectly == false) { damage = 0; } if (skill.IsCritValid) { float critChance = performer.GetSingleAttribute(AttributeType.CritChance).ModifiedValue + skill.CritMod; if (RandomSolver.CheckSuccess(critChance)) { int critDamage = target.TakeDamage(damage * 1.5f); targetUnit.OverlaySlot.UpdateOverlay(); if (target.HasZeroHealth) { SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, critDamage, true, SkillResultType.Crit)); } else { SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, critDamage, SkillResultType.Crit)); } ApplyEffects(performerUnit, targetUnit, skill); if (targetUnit.Character.IsMonster == false) { DarkestDungeonManager.Data.Effects["Stress 2"].ApplyIndependent(targetUnit); } return; } } damage = target.TakeDamage(damage); targetUnit.OverlaySlot.UpdateOverlay(); if (target.HasZeroHealth) { SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, damage, true, SkillResultType.Hit)); } else { SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, damage, SkillResultType.Hit)); } ApplyEffects(performerUnit, targetUnit, skill); #endregion } }
public override bool ApplyQueued(FormationUnit performer, FormationUnit target, Effect effect) { if (target == null) { return(false); } if (target.Party.Units.Count < 2) { return(false); } if (IsPartyShuffle) { foreach (var unit in target.Party.Units) { float moveChance = effect.IntegerParams[EffectIntParams.Chance].HasValue ? (float)effect.IntegerParams[EffectIntParams.Chance].Value / 100 : 1; moveChance -= unit.Character.GetSingleAttribute(AttributeType.Move).ModifiedValue; if (performer != null && performer.Character is Hero) { moveChance += performer.Character.GetSingleAttribute(AttributeType.MoveChance).ModifiedValue; } moveChance = Mathf.Clamp(moveChance, 0, 0.95f); if (RandomSolver.CheckSuccess(moveChance)) { var shuffleTargets = unit.Party.Units.FindAll(shuffle => shuffle != unit); var shuffleRoll = shuffleTargets[RandomSolver.Next(shuffleTargets.Count)]; if (shuffleRoll.Rank < unit.Rank) { unit.Pull(unit.Rank - shuffleRoll.Rank); } else { unit.Push(shuffleRoll.Rank - unit.Rank); } return(true); } } return(true); } else { float moveChance = effect.IntegerParams[EffectIntParams.Chance].HasValue ? (float)effect.IntegerParams[EffectIntParams.Chance].Value / 100 : 1; moveChance -= target.Character.GetSingleAttribute(AttributeType.Move).ModifiedValue; if (performer != null && performer.Character is Hero) { moveChance += performer.Character.GetSingleAttribute(AttributeType.MoveChance).ModifiedValue; } moveChance = Mathf.Clamp(moveChance, 0, 0.95f); if (RandomSolver.CheckSuccess(moveChance)) { var shuffleTargets = target.Party.Units.FindAll(unit => unit != target); var shuffleRoll = shuffleTargets[RandomSolver.Next(shuffleTargets.Count)]; if (shuffleRoll.Rank < target.Rank) { target.Pull(target.Rank - shuffleRoll.Rank); } else { target.Push(shuffleRoll.Rank - target.Rank); } return(true); } RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.MoveResist); return(false); } }