public void RestoreState(IStateSnippet savedState) { var state = (ActiveDiseaseSnippet)savedState; Disease = (DiseaseDefinitionBase)Activator.CreateInstance(state.DiseaseType); _isDiseaseActivated = state.IsDiseaseActivated; _isSelfHealActive = state.IsSelfHealActive; _diseaseStartTime = state.DiseaseStartTime; IsTreated = state.IsTreated; ComputeDisease(); if (state.TreatedStageLevel.HasValue) { Invert(); } else { TreatedStage = null; } _isChainInverted = state.IsChainInverted; if (state.ChildStates["ChangedVitals"] != null) { var o = (ChangedVitalsInfoSnippet)state.ChildStates["ChangedVitals"]; if (!o.IsEmpty) { if (_changedVitals == null) { _changedVitals = new ChangedVitalsInfo(); } _changedVitals.RestoreState(state.ChildStates["ChangedVitals"]); } } if (state.ChildStates["ChangedCritialStage"] != null) { var o = (ChangedVitalsInfoSnippet)state.ChildStates["ChangedCritialStage"]; if (!o.IsEmpty) { if (_changedCritialStage == null) { _changedCritialStage = new ChangedVitalsInfo(); } _changedCritialStage.RestoreState(state.ChildStates["ChangedCritialStage"]); } } Disease.RestoreState(state.ChildStates["Treatments"]); Refresh(_gc.WorldTime.Value); }
public void InvertBack() { if (_isSelfHealActive) { return; } if (!_isChainInverted) { return; } _isChainInverted = false; // Treatment failed TreatedStage = null; // Get the active stage var activeStage = GetActiveStage(_gc.WorldTime.Value); // Do not revert healthy stage if (activeStage == null || activeStage.Level == DiseaseLevels.HealthyStage) { _isChainInverted = false; return; } Disease.OnResumeDisease(); // Re-calculate disease begin time so that our current disease state will appear unchanged after time inverse var startCounting = false; var timeOffset = TimeSpan.FromSeconds(0); // Let's work with chain copy to avoid strange behavior var chainCopy = Disease.Stages.ToList(); // Remove healing stage chainCopy.Remove(chainCopy.Last()); // Get time offset that equals the sum of durations of all the stages after the active one foreach (var stage in chainCopy) { if (startCounting) { timeOffset += stage.StageDuration; } if (stage == activeStage) { startCounting = true; } } // New disease start time is a current time minus stages offset var timeOverall = _gc.WorldTime.Value - timeOffset; DiseaseStartTime = timeOverall; // Reverse the chain chainCopy.Reverse(); // Recompute timing for all stages foreach (var stage in chainCopy) { if (stage.Level == DiseaseLevels.Critical) { if (_changedCritialStage != null) { stage.StageDuration = _changedCritialStage.InitialStageDuration; } } ComputeStageTiming(timeOverall, stage); if (_changedVitals != null) { if (_changedVitals.Level == stage.Level) { stage.TargetBloodPressureTop = _changedVitals.InitialBloodPressureTop; stage.TargetBloodPressureBottom = _changedVitals.InitialBloodPressureBottom; stage.TargetBodyTemperature = _changedVitals.InitialBodyTemperature; stage.TargetHeartRate = _changedVitals.InitialHeartRate; stage.StageDuration = _changedVitals.InitialStageDuration; } } timeOverall = stage.WillEndAt.Value; } // Swap active disease chains Disease.SwapChain(chainCopy); _changedVitals = null; _changedCritialStage = null; Events.NotifyAll(l => l.DiseaseReActivated(Disease)); }
public void Invert() { if (_isSelfHealActive) { return; } if (_isChainInverted) { return; } _isChainInverted = true; // Get the active stage var activeStage = GetActiveStage(_gc.WorldTime.Value); if (activeStage == null) { _isChainInverted = false; return; } // Treatment is started TreatedStage = activeStage; // Re-calculate disease begin time so that our current disease state will appear unchanged after time inverse var startCounting = false; var timeOffset = TimeSpan.FromSeconds(0); var healthState = _gc.Health.Status; // Let's work with chain copy to avoid strange behavior var chainCopy = Disease.Stages.ToList(); // Get time offset that equals the sum of durations of all the stages after the active one foreach (var stage in chainCopy) { if (stage.Level == DiseaseLevels.Critical) { _changedCritialStage = new ChangedVitalsInfo { Level = DiseaseLevels.Critical, InitialStageDuration = stage.StageDuration }; stage.StageDuration = TimeSpan.FromMinutes(1); } if (stage.Level == activeStage.Level) { _changedVitals = new ChangedVitalsInfo { Level = stage.Level, InitialStageDuration = stage.StageDuration }; if (stage.Level != DiseaseLevels.Critical) { stage.StageDuration = TimeSpan.FromMinutes(Helpers.RollDice(7, 14)); } } if (startCounting) { timeOffset += stage.StageDuration; } if (stage == activeStage) { startCounting = true; } } // New disease start time is a current time minus stages offset var timeOverall = _gc.WorldTime.Value.AddMinutes(-1) - timeOffset; DiseaseStartTime = timeOverall; // Reverse the chain chainCopy.Reverse(); // Add healthy stage chainCopy.Add(HealthyStageFactory.Get(DiseaseLevels.HealthyStage, (int)Disease.Stages.First().StageDuration.TotalHours)); // Recompute timing for all stages foreach (var stage in chainCopy) { ComputeStageTiming(timeOverall, stage); if (stage.Level == activeStage.Level) { _changedVitals.InitialBloodPressureBottom = stage.TargetBloodPressureBottom; _changedVitals.InitialBloodPressureTop = stage.TargetBloodPressureTop; _changedVitals.InitialBodyTemperature = stage.TargetBodyTemperature; _changedVitals.InitialHeartRate = stage.TargetHeartRate; stage.TargetBloodPressureTop = healthState.BloodPressureTop; stage.TargetBloodPressureBottom = healthState.BloodPressureBottom; stage.TargetBodyTemperature = healthState.BodyTemperature; stage.TargetHeartRate = healthState.HeartRate; } timeOverall = stage.WillEndAt.Value; } // Swap active disease chains Disease.SwapChain(chainCopy); }