private static SurvivalStatHazardCondition GetCurrentСondition(IConditionsModule сonditionModule, SurvivalStatType statType) { return(сonditionModule.Items .OfType <SurvivalStatHazardCondition>() .SingleOrDefault(x => x.Type == statType)); }
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; } }
/// <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; }
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)); }
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; } }