private void UpdateBad(double now)
        {
            previousRunningTime = 0;
            switch (durationState)
            {
            case DurationState.off:
                if (waitDuration > 0)
                {
                    startAfter    = now + waitDuration;
                    durationState = DurationState.preRun;
                }
                break;

            case DurationState.preRun:
                if (now > startAfter)
                {
                    doneAfter = now + duration;
                    if (allowedDowntime > 0)
                    {
                        failAfter     = now + allowedDowntime;
                        durationState = DurationState.preReset;
                    }
                    else
                    {
                        durationState = allowReset ? DurationState.off : DurationState.failed;
                    }
                }
                break;

            case DurationState.running:
                if (allowedDowntime > 0)
                {
                    failAfter     = now + allowedDowntime;
                    durationState = DurationState.preReset;
                    break;
                }
                durationState = allowReset ? DurationState.off : DurationState.failed;
                break;

            case DurationState.preReset:
                if (now > failAfter)
                {
                    durationState = allowReset ? DurationState.off : DurationState.failed;
                }
                break;
            }

            if (durationState == DurationState.failed)
            {
                SetFailed();
            }
        }
        protected override void OnLoad(ConfigNode node)
        {
            base.OnLoad(node);

            duration        = ConfigNodeUtil.ParseValue(node, "duration", 0.0);
            allowedDowntime = ConfigNodeUtil.ParseValue(node, "allowedDowntime", 0.0);
            waitDuration    = ConfigNodeUtil.ParseValue(node, "waitDuration", 0.0);
            allowReset      = ConfigNodeUtil.ParseValue(node, "allowReset", true);
            durationType    = Lib.ConfigEnum(node, "durationType", DurationType.countdown);

            doneAfter           = ConfigNodeUtil.ParseValue(node, "doneAfter", 0.0);
            failAfter           = ConfigNodeUtil.ParseValue(node, "failAfter", 0.0);
            startAfter          = ConfigNodeUtil.ParseValue(node, "startAfter", 0.0);
            accumulatedDuration = ConfigNodeUtil.ParseValue(node, "accumulatedDuration", 0.0);
            durationState       = Lib.ConfigEnum(node, "durationState", DurationState.off);
        }
        private void UpdateGood(double now)
        {
            switch (durationState)
            {
            case DurationState.off:
            case DurationState.preRun:
                durationState = DurationState.running;
                doneAfter     = now + duration;
                break;

            case DurationState.preReset:
                durationState = DurationState.running;
                break;

            case DurationState.running:
                switch (durationType)
                {
                case DurationType.countdown:
                    if (now > doneAfter)
                    {
                        durationState = DurationState.done;
                    }
                    break;

                case DurationType.accumulating:
                    if (previousRunningTime != 0)
                    {
                        accumulatedDuration += now - previousRunningTime;
                    }
                    if (accumulatedDuration > duration)
                    {
                        durationState = DurationState.done;
                    }
                    break;
                }
                break;
            }
            previousRunningTime = now;

            if (durationState == DurationState.done)
            {
                SetComplete();
            }
        }