public override void execute(Data data)
    {
        int duration = Duration;



        int currentSleepStat;

        if (data is GameData)
        {
            currentSleepStat = ((GameData)data).CharacterData.PC.statSleep;
        }
        else
        {
            currentSleepStat = data["PC.statSleep"];
        }

        Activity sleepActivity = GameManager.Instance.ActivityLibrary["sleep"];

        //https://stackoverflow.com/questions/17944/how-to-round-up-the-result-of-integer-division
        int requiredSleepSeconds = (1000000 - currentSleepStat - 1) / sleepActivity.statSleep + 1;
        int maximumSleepSeconds  = Mathb.CeilToInt(requiredSleepSeconds * MaxSleepFactor);

        if (!String.IsNullOrEmpty(AlarmTimeRef))
        {
            int alarmTime = data[AlarmTimeRef];
            duration = GameManager.Instance.timeSecondsTils(alarmTime);

            if (!String.IsNullOrEmpty(AlarmActivatedRef))
            {
                bool alarmActivated = data[AlarmActivatedRef];
                if (!alarmActivated)
                {
                    duration = -1;
                }
            }
        }

        if (duration > maximumSleepSeconds)
        {
            duration = BER2.Util.Randomness.Random.Range(requiredSleepSeconds, maximumSleepSeconds);
        }

        if (duration < 0)
        {
            duration = requiredSleepSeconds;//= 3600; // TODO: calculate required sleep
        }
        CommandsCollection sleepCommands = SleepCommandList(duration);

        sleepCommands.execute();
        return;
    }
    public int remainingCooldown(Interrupt interrupt)
    {
        string key = interrupt.id;

        if (!ContainsKey(key))
        {
            return(0);
        }

        DateTime now = GameManager.Instance.GameData.WorldData.DateTime;

        TimeSpan timeSpan = this[key].CooldownTil - now;

        int totalSeconds = Mathb.Max((int)timeSpan.TotalSeconds, 0);

        return(totalSeconds);
    }