/// <summary>
        /// Извлечение всех оборон актёра, способных противостоять указанному типу урона.
        /// Включая DivineDefence, противодействующий всем типам урона.
        /// </summary>
        /// <param name="targetActor"> Целевой актёр. </param>
        /// <param name="offenceType"> Тип урона. </param>
        /// <returns> Возвращает набор оборон. </returns>
        private static IEnumerable <PersonDefenceItem> GetCurrentDefences(IActor targetActor, OffenseType offenceType)
        {
            var defenceType = HitHelper.GetDefence(offenceType);

            return(targetActor.Person.CombatStats.DefenceStats.Defences
                   .Where(x => x.Type == defenceType || x.Type == DefenceType.DivineDefence));
        }
Пример #2
0
        /// <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="actor"> Актёр, который совершил действие. </param>
        /// <param name="targetActor"> Цель использования действия. </param>
        /// <param name="tacticalActRoll"> Эффективность действия. </param>
        private void DamageActor(IActor actor, IActor targetActor, TacticalActRoll tacticalActRoll)
        {
            var targetIsDeadLast = targetActor.Person.Survival.IsDead;

            var offenceType  = tacticalActRoll.TacticalAct.Stats.Offence.Type;
            var usedDefences = GetCurrentDefences(targetActor, offenceType);

            var prefferedDefenceItem = HitHelper.CalcPreferredDefense(usedDefences);
            var successToHitRoll     = HitHelper.CalcSuccessToHit(prefferedDefenceItem);
            var factToHitRoll        = _actUsageRandomSource.RollToHit();

            if (factToHitRoll >= successToHitRoll)
            {
                int actEfficient = CalcEfficient(targetActor, tacticalActRoll);

                if (actEfficient <= 0)
                {
                    return;
                }

                targetActor.TakeDamage(actEfficient);

                if (EquipmentDurableService != null && targetActor.Person.EquipmentCarrier != null)
                {
                    var damagedEquipment = GetDamagedEquipment(targetActor);

                    // может быть null, если нет брони вообще
                    if (damagedEquipment != null)
                    {
                        EquipmentDurableService.UpdateByUse(damagedEquipment, targetActor.Person);
                    }
                }

                if (!targetIsDeadLast && targetActor.Person.Survival.IsDead)
                {
                    CountTargetActorDefeat(actor, targetActor);
                }
            }
            else
            {
                if (prefferedDefenceItem != null)
                {
                    targetActor.ProcessDefence(prefferedDefenceItem,
                                               successToHitRoll,
                                               factToHitRoll);
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Производит попытку нанесения урона целевову актёру с учётом обороны и брони.
        /// </summary>
        /// <param name="actor"> Актёр, который совершил действие. </param>
        /// <param name="targetActor"> Цель использования действия. </param>
        /// <param name="tacticalActRoll"> Эффективность действия. </param>
        private void DamageActor(IActor actor, IActor targetActor, TacticalActRoll tacticalActRoll)
        {
            var targetIsDeadLast = targetActor.Person.CheckIsDead();

            var offenceType  = tacticalActRoll.TacticalAct.Stats.Offence.Type;
            var usedDefences = GetCurrentDefences(targetActor, offenceType);

            var prefferedDefenceItem = HitHelper.CalcPreferredDefense(usedDefences);
            var successToHitRoll     = HitHelper.CalcSuccessToHit(prefferedDefenceItem);
            var factToHitRoll        = _actUsageRandomSource.RollToHit(tacticalActRoll.TacticalAct.ToHit);

            if (factToHitRoll >= successToHitRoll)
            {
                ProcessSuccessfullHit(actor, targetActor, tacticalActRoll, targetIsDeadLast, successToHitRoll,
                                      factToHitRoll);
            }
            else
            {
                ProcessFailedHit(actor, targetActor, prefferedDefenceItem, successToHitRoll, factToHitRoll);
            }
        }
        /// <summary>
        /// Производит попытку нанесения урона целевову актёру с учётом обороны и брони.
        /// </summary>
        /// <param name="actor"> Актёр, который совершил действие. </param>
        /// <param name="targetActor"> Цель использования действия. </param>
        /// <param name="tacticalActRoll"> Эффективность действия. </param>
        private void DamageActor(IActor actor, IActor targetActor, TacticalActRoll tacticalActRoll)
        {
            var targetIsDeadLast = targetActor.Person.CheckIsDead();

            var offenceType  = tacticalActRoll.TacticalAct.Stats.Offence.Type;
            var usedDefences = GetCurrentDefences(targetActor, offenceType);

            var prefferedDefenceItem = HitHelper.CalcPreferredDefense(usedDefences);
            var successToHitRoll     = HitHelper.CalcSuccessToHit(prefferedDefenceItem);
            var factToHitRoll        = _actUsageRandomSource.RollToHit(tacticalActRoll.TacticalAct.ToHit);

            if (factToHitRoll >= successToHitRoll)
            {
                var damageEfficientCalcResult = CalcEfficient(targetActor, tacticalActRoll);
                var actEfficient = damageEfficientCalcResult.ResultEfficient;

                ProcessSuccessfulAttackEvent(
                    actor,
                    targetActor,
                    damageEfficientCalcResult,
                    successToHitRoll,
                    factToHitRoll);

                if (actEfficient <= 0)
                {
                    return;
                }

                targetActor.TakeDamage(actEfficient);

                CountTargetActorAttack(actor, targetActor, tacticalActRoll.TacticalAct);

                if (EquipmentDurableService != null && targetActor.Person.EquipmentCarrier != null)
                {
                    var damagedEquipment = GetDamagedEquipment(targetActor);

                    // может быть null, если нет брони вообще
                    if (damagedEquipment != null)
                    {
                        EquipmentDurableService.UpdateByUse(damagedEquipment, targetActor.Person);
                    }
                }

                if (!targetIsDeadLast && targetActor.Person.CheckIsDead())
                {
                    CountTargetActorDefeat(actor, targetActor);
                }
            }
            else
            {
                if (prefferedDefenceItem != null)
                {
                    // Это промах, потому что целевой актёр увернулся.
                    ProcessAttackDodgeEvent(actor,
                                            targetActor,
                                            prefferedDefenceItem,
                                            successToHitRoll,
                                            factToHitRoll);
                }
                else
                {
                    // Это промах чистой воды.
                    ProcessPureMissEvent(actor,
                                         targetActor,
                                         successToHitRoll,
                                         factToHitRoll);
                }
            }
        }