/// <summary> /// Расчитывает эффективность умения с учётом поглощения броней. /// </summary> /// <param name="targetActor"> Целевой актёр. </param> /// <param name="tacticalActRoll"> Результат броска исходной эфективности действия. </param> /// <returns> Возвращает числовое значение эффективности действия. </returns> private DamageEfficientCalc CalcEfficient(IActor targetActor, CombatActRoll tacticalActRoll) { var damageEfficientCalcResult = new DamageEfficientCalc(); var actApRank = GetActApRank(tacticalActRoll.CombatAct); damageEfficientCalcResult.ActApRank = actApRank; var armorRank = GetArmorRank(targetActor, tacticalActRoll.CombatAct); damageEfficientCalcResult.ArmorRank = armorRank; var actEfficientArmorBlocked = tacticalActRoll.Efficient; var rankDiff = actApRank - armorRank; if (armorRank != null && rankDiff < 10) { var factArmorSaveRoll = RollArmorSave(); damageEfficientCalcResult.FactArmorSaveRoll = factArmorSaveRoll; var successArmorSaveRoll = GetSuccessArmorSave(targetActor, tacticalActRoll.CombatAct); damageEfficientCalcResult.SuccessArmorSaveRoll = successArmorSaveRoll; if (factArmorSaveRoll >= successArmorSaveRoll) { damageEfficientCalcResult.TargetSuccessfullUsedArmor = true; var armorAbsorbtion = GetArmorAbsorbtion(targetActor, tacticalActRoll.CombatAct); damageEfficientCalcResult.ArmorAbsorbtion = armorAbsorbtion; actEfficientArmorBlocked = AbsorbActEfficient(actEfficientArmorBlocked, armorAbsorbtion); } } damageEfficientCalcResult.ActEfficientArmorBlocked = actEfficientArmorBlocked; return(damageEfficientCalcResult); }
/// <summary> /// Производит попытку нанесения урона целевову актёру с учётом обороны и брони. /// </summary> /// <param name="actor"> Актёр, который совершил действие. </param> /// <param name="targetActor"> Цель использования действия. </param> /// <param name="combatActRoll"> Эффективность действия. </param> private void DamageActor(IActor actor, IActor targetActor, CombatActRoll combatActRoll, ISectorMap map) { var targetIsDeadLast = targetActor.Person.CheckIsDead(); var offence = combatActRoll.CombatAct.Stats.Offence; if (offence is null) { throw new InvalidOperationException(); } var offenceType = offence.Type; var usedDefences = GetCurrentDefences(targetActor, offenceType); var prefferedDefenceItem = HitHelper.CalcPreferredDefense(usedDefences); var successToHitRoll = HitHelper.CalcSuccessToHit(prefferedDefenceItem); var factToHitRoll = _actUsageRandomSource.RollToHit(combatActRoll.CombatAct.ToHit); if (factToHitRoll >= successToHitRoll) { ProcessSuccessfullHit(actor, targetActor, combatActRoll, targetIsDeadLast, successToHitRoll, factToHitRoll, map); } else { ProcessFailedHit(actor, targetActor, combatActRoll, prefferedDefenceItem, successToHitRoll, factToHitRoll); } }
/// <summary> /// Возвращает случайное значение эффективность действия. /// </summary> /// <param name="act"> Соверщённое действие. </param> /// <returns> Возвращает выпавшее значение эффективности. </returns> private CombatActRoll GetActEfficient(ICombatAct act) { var rolledEfficient = _actUsageRandomSource.RollEfficient(act.Efficient); var roll = new CombatActRoll(act, rolledEfficient); return(roll); }
/// <inheritdoc /> public void ProcessActUsage(IActor actor, IAttackTarget target, CombatActRoll tacticalActRoll, ISectorMap map) { if (tacticalActRoll is null) { throw new ArgumentNullException(nameof(tacticalActRoll)); } UseOnStaticObject((IStaticObject)target, tacticalActRoll); }
/// <summary> /// Применяет действие на предмет, на который можно подействовать (сундук/дверь/камень). /// </summary> /// <param name="target"> Цель использования действия. </param> /// <param name="tacticalActRoll"> Эффективность действия. </param> private static void UseOnStaticObject(IAttackTarget target, CombatActRoll tacticalActRoll) { if (target is null) { throw new ArgumentNullException(nameof(target)); } target.TakeDamage(tacticalActRoll.Efficient); }