Exemple #1
0
 private static SurvivalStatHazardCondition GetCurrentСondition(IConditionsModule сonditionModule,
                                                                SurvivalStatType statType)
 {
     return(сonditionModule.Items
            .OfType <SurvivalStatHazardCondition>()
            .SingleOrDefault(x => x.Type == statType));
 }
Exemple #2
0
        private static void ThrowExceptionIfArgumentsInvalid(IConditionsModule currentСondition,
                                                             SurvivalStat stat,
                                                             IEnumerable <SurvivalStatKeySegment> keyPoints,
                                                             ISurvivalRandomSource survivalRandomSource)
        {
            if (currentСondition == null)
            {
                throw new ArgumentNullException(nameof(currentСondition));
            }

            if (stat == null)
            {
                throw new ArgumentNullException(nameof(stat));
            }

            if (keyPoints == null)
            {
                throw new ArgumentNullException(nameof(keyPoints));
            }

            if (survivalRandomSource == null)
            {
                throw new ArgumentNullException(nameof(survivalRandomSource));
            }
        }
        private static IEnumerable <ITacticalAct> CalcActsFromEquipments(
            IEnumerable <Equipment?> equipments,
            IConditionsModule сondition,
            IEnumerable <IPerk> perks)
        {
            if (equipments is null)
            {
                yield break;
            }

            foreach (var equipment in equipments)
            {
                if (equipment is null)
                {
                    continue;
                }

                foreach (var actScheme in equipment.Acts)
                {
                    var act = CreateTacticalAct(actScheme, equipment, сondition, perks);

                    yield return(act);
                }
            }
        }
        private static void CalcSurvivalHazardOnTacticalAct(IConditionsModule сondition,
                                                            ref int toHitModifierValue,
                                                            ref int efficientModifierValue)
        {
            var greaterSurvivalEffect = сondition.Items.OfType <SurvivalStatHazardCondition>()
                                        .OrderByDescending(x => x.Level).FirstOrDefault();

            if (greaterSurvivalEffect == null)
            {
                return;
            }

            var effecientDebuffRule = greaterSurvivalEffect.GetRules()
                                      .FirstOrDefault(x => x.RollType == RollEffectType.Efficient);

            var toHitDebuffRule = greaterSurvivalEffect.GetRules()
                                  .FirstOrDefault(x => x.RollType == RollEffectType.ToHit);

            if (effecientDebuffRule != null)
            {
                efficientModifierValue += -1;
            }

            if (toHitDebuffRule != null)
            {
                toHitModifierValue += -1;
            }
        }
Exemple #5
0
        /// <summary>
        /// Обновление эффекта модуля выживания.
        /// </summary>
        /// <param name="currentCondition"> Текущий список условий. </param>
        /// <param name="stat"> Характеристика, на которую влияет эффект. </param>
        /// <param name="keySegments">
        /// Ключевые сегменты, которые были пересечены при изменении характеристики.
        /// <param name="survivalRandomSource"> Источник рандома выживания. </param>
        public static void UpdateSurvivalСondition(
            [NotNull] IConditionsModule currentCondition,
            [NotNull] SurvivalStat stat,
            [NotNull] SurvivalStatKeySegment[] keySegments,
            [NotNull] ISurvivalRandomSource survivalRandomSource,
            [MaybeNull] IPlayerEventLogService?playerEventLogService)
        {
            ThrowExceptionIfArgumentsInvalid(currentCondition, stat, keySegments, survivalRandomSource);

            // Эффект выставляем на основе текущего ключевого сегмента, в которое попадает значение характеристики выживания.
            // Если текущее значение не попадает ни в один сегмент, то эффект сбрасывается.

            var currentSegments = keySegments.CalcIntersectedSegments(stat.ValueShare);

            // Если попадаем на стык с двумя сегментами, просто берём первый.
            // Иногда это будет давать более сильный штрафной эффект,
            // но пока не понятно, как по другому сделать отрезки.
            var currentSegment = currentSegments.FirstOrDefault();

            var statType             = stat.Type;
            var currentTypeСondition = GetCurrentСondition(currentCondition, statType);

            if (currentTypeСondition != null)
            {
                // Эффект уже существует. Изменим его уровень.
                // Или удалим, если текущее значение не попадает ни в один из сегментов.
                if (currentSegment == null)
                {
                    currentCondition.Remove(currentTypeСondition);
                }
                else
                {
                    currentTypeСondition.Level = currentSegment.Level;
                }
            }
            else
            {
                if (currentSegment != null)
                {
                    // Создаём эффект
                    var newEffect = new SurvivalStatHazardCondition(
                        statType,
                        currentSegment.Level,
                        survivalRandomSource)
                    {
                        PlayerEventLogService = playerEventLogService
                    };

                    currentCondition.Add(newEffect);
                }
            }
        }
        public CombatActModule(
            ITacticalActScheme defaultActScheme,
            IEquipmentModule equipmentModule,
            IConditionsModule сonditionsModule,
            IEvolutionModule evolutionModule)
        {
            IsActive = true;

            _defaultActScheme = defaultActScheme;
            _equipmentModule  = equipmentModule;
            _сonditionsModule = сonditionsModule;
            _evolutionModule  = evolutionModule;
        }
Exemple #7
0
        public CombatActModule(
            IEnumerable <ITacticalActScheme> defaultActSchemes,
            IEquipmentModule equipmentModule,
            IConditionsModule сonditionsModule,
            IEvolutionModule evolutionModule)
        {
            IsActive = true;

            _defaultActSchemes = defaultActSchemes;
            _equipmentModule   = equipmentModule;
            _сonditionsModule  = сonditionsModule;
            _evolutionModule   = evolutionModule;
        }
        private static IEnumerable <ITacticalAct> CalcActs(ITacticalActScheme defaultActScheme,
                                                           IEnumerable <Equipment?> equipments,
                                                           IConditionsModule сonditionModule,
                                                           IEnumerable <IPerk> perks)
        {
            var defaultAct = CreateTacticalAct(defaultActScheme, null, сonditionModule, perks);

            yield return(defaultAct);

            var equipmentActs = CalcActsFromEquipments(equipments, сonditionModule, perks);

            foreach (var act in equipmentActs)
            {
                yield return(act);
            }
        }
        private static void AddDiseaseEffectForSymptom(
            IConditionsModule сonditionModule,
            IDisease disease,
            DiseaseSymptom symptom)
        {
            var currentSymptomEffect = сonditionModule.Items.OfType <DiseaseSymptomCondition>()
                                       .SingleOrDefault(x => x.Symptom == symptom);

            if (currentSymptomEffect is null)
            {
                // При создании эффекта уже фиксируется болезнь, которая его удерживает.
                currentSymptomEffect = new DiseaseSymptomCondition(disease, symptom);
                сonditionModule.Add(currentSymptomEffect);
            }
            else
            {
                currentSymptomEffect.HoldDisease(disease);
            }
        }
        private static void UpdatePowerDown(
            IConditionsModule сonditionModule,
            IDisease disease,
            DiseaseSymptom[] symptoms,
            float currentPower,
            float symptomPowerSegment)
        {
            var activeSymptomCount = (int)Math.Floor(currentPower / symptomPowerSegment);

            // Начинаем снимать все эффекты, которые за пределами количества.

            var symptomLowerIndex = activeSymptomCount;

            for (var i = symptomLowerIndex; i < symptoms.Length; i++)
            {
                var currentSymptom = symptoms[i];
                RemoveDiseaseEffectForSimptom(сonditionModule, disease, currentSymptom);
            }
        }
        private static ITacticalAct CreateTacticalAct([NotNull] ITacticalActScheme scheme,
                                                      [MaybeNull] Equipment?equipment,
                                                      [NotNull] IConditionsModule сonditionModule,
                                                      [NotNull] IEnumerable <IPerk> perks)
        {
            var toHitModifierValue      = 0;
            var efficientModifierValue  = 0;
            var efficientRollUnmodified = scheme.Stats?.Efficient ?? new Roll(1, 1);

            CalcSurvivalHazardOnTacticalAct(сonditionModule, ref toHitModifierValue, ref efficientModifierValue);
            CalcPerksBonusesOnTacticalAct(perks, equipment, ref toHitModifierValue, ref efficientModifierValue);

            var toHitRoll = CreateTacticalActRoll(6, 1, toHitModifierValue);

            var efficientRoll = CreateTacticalActRoll(efficientRollUnmodified.Dice,
                                                      efficientRollUnmodified.Count,
                                                      efficientModifierValue);

            return(new TacticalAct(scheme, efficientRoll, toHitRoll, equipment));
        }
        private static void RemoveDiseaseEffectForSimptom(
            IConditionsModule сonditionModule,
            IDisease disease,
            DiseaseSymptom symptom)
        {
            var currentSymptomEffect = сonditionModule.Items.OfType <DiseaseSymptomCondition>()
                                       .SingleOrDefault(x => x.Symptom == symptom);

            if (currentSymptomEffect is null)
            {
                // Просто игнорируем этот эффект.
                // Ткущий метод может вызываться несколько раз и для симптомов, которые ушли в предыдущих итерациях.
                return;
            }

            currentSymptomEffect.ReleaseDisease(disease);

            if (!currentSymptomEffect.Diseases.Any())
            {
                сonditionModule.Remove(currentSymptomEffect);
            }
        }
        private static void UpdatePowerUp(IConditionsModule сonditionModule, IDisease disease,
                                          DiseaseSymptom[] symptoms,
                                          float currentPower, float symptomPowerSegment)
        {
            if (currentPower <= 0.25f)
            {
                // Симптомы начинаю проявляться после 25% силы болезни.
                return;
            }

            // Рассчитываем количество симптомов, которые должны быть при текущей силе болезни.

            var activeSymptomCount = (int)Math.Ceiling((currentPower - 0.25f) / symptomPowerSegment);

            // Начинаем проверять, есть ли эффекты на все эти симптомы
            // или добавлены ли болезни симптомов в список болезней эффектов.

            for (var i = 0; i < activeSymptomCount; i++)
            {
                var currentSymptom = symptoms[i];
                AddDiseaseEffectForSymptom(сonditionModule, disease, currentSymptom);
            }
        }
 public DiseaseModule(IConditionsModule сonditionModule)
 {
     _сonditionModule = сonditionModule ?? throw new ArgumentNullException(nameof(сonditionModule));
 }
Exemple #15
0
        private void UpdateAlert(IConditionsModule conditionsModule, GameTime gameTime)
        {
            var conditionRectangles = conditionsModule.Items.Select((x, index) => new
            {
                UiRect = new Rectangle(index * (ICON_SIZE + ICON_SPACING) - ICON_SPACING + _screenX, _screenY,
                                       ICON_SIZE, ICON_SIZE),
                Condition = x,
                IconIndex = index
            });

            var criticalConditions = conditionRectangles
                                     .Where(x => x.Condition is SurvivalStatHazardCondition survivalStatHazardCondition &&
                                            survivalStatHazardCondition.Level == SurvivalStatHazardLevel.Max);

            _alertedConditions.Clear();

            const int ALERT_SOUND_COUNT = 3;

            if (_alertCounter < ALERT_DELAY_DURATION_SECONDS + ALERT_VISIBLE_DURATION_SECONDS)
            {
                _alertCounter += gameTime.ElapsedGameTime.TotalSeconds;

                if (_alertCounter < ALERT_VISIBLE_DURATION_SECONDS)
                {
                    var t = _alertCounter / ALERT_VISIBLE_DURATION_SECONDS;

                    var visiblilitySin = Math.Sin(t * Math.PI * 2 * 3);
                    if (visiblilitySin > 0)
                    {
                        foreach (var criticalCondition in criticalConditions)
                        {
                            _alertedConditions.Add(criticalCondition.Condition);
                        }
                    }

                    if (visiblilitySin > 0 && _alertedConditions.Any() &&
                        _alertSoundEffect.State != SoundState.Playing && _alertIterationIndex < ALERT_SOUND_COUNT)
                    {
                        _alertIterationIndex++;

                        _alertSoundEffect.Play();
                    }
                }
            }
            else
            {
                _alertCounter = 0;
            }

            if (criticalConditions.Any() && _alertIterationIndex < ALERT_SOUND_COUNT)
            {
                _soundtrackManager.PlaySilence();
            }
            else
            {
                _soundtrackManager.PlayBackgroundTrack();
            }

            if (!criticalConditions.Any())
            {
                _alertIterationIndex = 0;
            }
        }