/// <summary>
        /// Check if we should progress the current sickness.  Progress if it we are due.
        /// </summary>
        /// <param name="sicknessAffliction">A sickness of the player</param>
        private void CheckSicknessProgression(SicknessAffliction sicknessAffliction)
        {
            Sickness sickness = sicknessAffliction.Sickness;

            // Check if we are already at the final stage of a sickness
            if (sicknessAffliction.CurrentStage < sickness.SicknessStages.Count)
            {
                // Loop on each stage of the sickness to see if we have now reached the stage
                // Makes the sickness progress
                int totalSecondCount = 0;
                for (int stage = 0; stage < sickness.SicknessStages.Count; stage++)
                {
                    // If the stage is isn't reached yet, we check if it's time to progress toward it
                    if (stage > (int)sicknessAffliction.CurrentStage - 1)
                    {
                        // Check if it's time to progress to the new stage
                        if ((startedTime - sicknessAffliction.ContractedTime) > totalSecondCount)
                        {
                            // It's time to progress to the new stage
                            ScheduleStageSymptom(sicknessAffliction, stage);
                        }
                        else
                        {
                            // It's not time yet, no point checking for further stages
                            break;
                        }
                    }

                    totalSecondCount += sickness.SicknessStages[stage].SecondsBeforeNextStage;
                }
            }
        }
        /// <summary>
        /// Check if we should trigger due symptoms
        /// </summary>
        private void CheckSymptomOccurence(SicknessAffliction sicknessAffliction, LivingHealthMasterBase playerHealth)
        {
            Sickness sickness = sicknessAffliction.Sickness;

            // Loop on each reached stage to see if a symptom should trigger
            for (int stage = 0; stage < sickness.SicknessStages.Count; stage++)
            {
                if (stage < sicknessAffliction.CurrentStage)
                {
                    float?stageNextOccurence = sicknessAffliction.GetStageNextOccurence(stage);
                    if ((stageNextOccurence != null) && (startedTime > stageNextOccurence))
                    {
                        SicknessStage sicknessStage = sickness.SicknessStages[stage];

                        // Since many symptoms need to be called within the main thread, we invoke it
                        sicknessManager.blockingCollectionSymptoms.Add(new SymptomManifestation(sicknessAffliction, stage, playerHealth));

                        if (sicknessStage.RepeatSymptom)
                        {
                            ScheduleStageSymptom(sicknessAffliction, stage);
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Check if the player already is infected by this sickness
 /// </summary>
 /// <param name="sickness"></param>
 /// <returns>True if the player already has this sickness active</returns>
 public bool HasSickness(Sickness sickness)
 {
     lock (sicknessAfflictions)
     {
         return(sicknessAfflictions.Exists(p => p.Sickness == sickness));
     }
 }
 /// <summary>
 /// Remove a sickness from the player, healing him.
 /// </summary>
 /// <param name="sickness">The sickness to remove</param>
 public void Remove(Sickness sickness)
 {
     lock (sicknessAfflictions)
     {
         sicknessAfflictions.Remove(sicknessAfflictions.Find(p => p.Sickness == sickness));
     }
 }
        /// <summary>
        /// Add a sickness to the player
        /// </summary>
        /// <param name="sickness">The sickness to add</param>
        /// <param name="contractedTime">The time at which the player contracted the sickness</param>
        public void Add(Sickness sickness, float contractedTime)
        {
            sicknessAfflictions.Add(new SicknessAffliction(sickness, contractedTime));

            // Register the player as a sick player
            SicknessManager.Instance.RegisterSickPlayer(this);
        }
        /// <summary>
        /// Schedule the next occurence of the symptom of a particular stage
        /// </summary>
        /// <param name="sicknessAffliction">A sickness afflicting a player</param>
        /// <param name="stage">The stage for which the symptom must be scheduled</param>
        private void ScheduleStageSymptom(SicknessAffliction sicknessAffliction, int stage)
        {
            Sickness      sickness      = sicknessAffliction.Sickness;
            SicknessStage sicknessStage = sickness.SicknessStages[stage];

            if (sicknessStage.RepeatMaxDelay < sicknessStage.RepeatMinDelay)
            {
                Logger.LogError($"Sickness: {sickness.SicknessName}. Repeatable sickness symptoms should always have a RepeatMaxDelay ({sicknessStage.RepeatMaxDelay}) >= RepeatMinDelay ({sicknessStage.RepeatMinDelay})", Category.Health);
                return;
            }

            if (sicknessStage.RepeatMinDelay < 5)
            {
                Logger.LogError($"Sickness: {sickness.SicknessName}. Repeatable sickness symptoms should have a RepeatMinDelay ({sicknessStage.RepeatMinDelay}) >= 5.  Think of the server performance.", Category.Health);
                return;
            }

            sicknessAffliction.ScheduleStageNextOccurence(stage, startedTime + random.Next((int)sicknessStage.RepeatMinDelay, (int)sicknessStage.RepeatMaxDelay));
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="sicknessToAdd">The sickness to create</param>
 /// <param name="sicknessContractedTime">The time at which the player contracted the sickness.</param>
 public SicknessAffliction(Sickness sicknessToAdd, float sicknessContractedTime)
 {
     ContractedTime     = sicknessContractedTime;
     Sickness           = sicknessToAdd;
     stageNextOccurence = new List <float?>();
 }