// select thoughts from pool of available
    private List <Thought> SelectThoughts()
    {
        // get all available thoughts
        List <Thought> availableThoughts = new List <Thought>();

        foreach (Thought thought in gameManager.profile.thoughts)
        {
            for (int i = 0; i < thought.Availability(runState); i++)
            {
                availableThoughts.Add(thought);
            }
        }
        // associated thoughts are extra likely - TODO: tune, maybe use different scheme?
        if (runState.CurrentActivity())
        {
            foreach (Thought thought in runState.CurrentActivity().associatedThoughts)
            {
                for (int i = 0; i < thought.Availability(runState); i++)
                {
                    availableThoughts.Add(thought);
                }
            }
        }

        // if none available, return special filler thought
        if (availableThoughts.Count == 0)
        {
            // right now it's called "Nothing"
            Thought fallBack = Object.FindObjectOfType <Nothing>();
            Debug.Assert(fallBack);
            return(new List <Thought> {
                fallBack
            });
        }
        // select <=3 randomly (without repeat)
        List <Thought> offeredThoughts = new List <Thought>();

        while (offeredThoughts.Count < 3 && availableThoughts.Count > 0)
        {
            int     r = Random.Range(0, availableThoughts.Count);
            Thought t = availableThoughts[r];
            availableThoughts.Remove(t);
            offeredThoughts.Add(t);
        }
        return(offeredThoughts);
    }
    // functions for gameplay parameters that depend on runState (emotions, etc.)
    public float PlatformMinForwardSpeed(RunState runState)
    {
        if (thoughtMenu.currentThought != null)
        {
            return(0);
        }
        Activity activity = runState.CurrentActivity();

        if (runState.timeSteps == 0 || runState.CurrentActivityPlatform().isSongDone)
        {
            return(1.5f);
        }
        // set the forward speed slow enough to allow finishing the song
        float songDuration = ((float)activity.song.Length() * activity.tempoIncrement) + 2;

        return((float)(runState.CurrentActivityPlatform().length - 2) / songDuration);
    }
    void Update()
    {
        RunState     runState = runManager.runState;
        EmotionState e        = runState.emotions;
        // fill meters
        List <int> values = new List <int> {
            runState.energy, e.despair, e.anxiety, e.frustration
        };
        int        emoCap = emotionMeterCap;
        List <int> caps   = new List <int> {
            gameManager.profile.energyCap, emoCap, emoCap, emoCap
        };
        List <GameObject> meters = new List <GameObject> {
            energyMeter, despairMeter, anxietyMeter, frustrationMeter
        };

        for (int i = 0; i < meters.Count; i++)
        {
            // Find filler image (meters must have a child called "Filler")
            Image fillerImage = meters[i].transform.Find("Filler").GetComponent <Image>();
            fillerImage.type       = Image.Type.Filled;
            fillerImage.fillMethod = Image.FillMethod.Horizontal;
            float newFillAmount = Mathf.Min(1, (float)values[i] / (float)caps[i]);
            // activate change markers
            Transform increaseMarker = meters[i].transform.Find("IncreaseMarker");
            if (increaseMarker)
            {
                if (newFillAmount > fillerImage.fillAmount)
                {
                    increaseMarker.GetComponent <FadeImage>().Reset();
                }
            }
            // set filler image fill amount
            fillerImage.fillAmount = newFillAmount;

            // color gray and draw X if being suppressed
            EmotionType emotionType = EmotionType.None;
            if (meters[i] == anxietyMeter)
            {
                emotionType = EmotionType.anxiety;
            }
            if (meters[i] == frustrationMeter)
            {
                emotionType = EmotionType.frustration;
            }
            if (meters[i] == despairMeter)
            {
                emotionType = EmotionType.despair;
            }
            Activity activity = runState.CurrentActivity();
            if (activity && runState.IsSuppressed(emotionType))
            {
                fillerImage.color = new Color(.4f, .4f, .4f);
                Image XMark = meters[i].transform.Find("XMark").GetComponent <Image>();
                if (gameManager.showSuppressionTutorial)
                {
                    tutorialManager.ActivateSuppressionTutorial();
                }
                // XMark.color = emotionFillColors[emotionType];
                XMark.enabled = true;
            }
            else if (emotionType != EmotionType.None)
            {
                fillerImage.color = emotionFillColors[emotionType];
                Image XMark = meters[i].transform.Find("XMark").GetComponent <Image>();
                XMark.enabled = false;
            }
            // set text (meters must have a child called "Text")
            Transform textObject = meters[i].transform.Find("Text");
            if (textObject)
            {
                textObject.GetComponent <TextMeshProUGUI>().text = values[i].ToString();
            }
        }
        ;
        // rotate timer wheel (must have a child called "Disc")
        Transform disc           = timerWheel.transform.Find("Disc");
        float     targetRotation = 345 - ((float)runState.timeSteps / 15f * 360f) % 360;

        if (System.Math.Abs(disc.localRotation.eulerAngles.z - targetRotation) > System.Math.Abs(timeRotationStep))
        {
            disc.Rotate(new Vector3(0, 0, timeRotationStep));
        }
        // update the score display
        Transform scoreText = scoreDisplay.transform.Find("Text");

        if (scoreText)
        {
            scoreText.GetComponent <TextMeshProUGUI>().text = runState.score.ToString();
        }
        Transform scoreMultiplierText = scoreDisplay.transform.Find("MultiplierText");

        if (scoreMultiplierText)
        {
            string multiplierString = runState.scoreMultiplier.ToString() + "x";
            scoreMultiplierText.GetComponent <TextMeshProUGUI>().text  = multiplierString;
            scoreMultiplierText.GetComponent <TextMeshProUGUI>().color = new Color(0, 0, 0);
            if (runState.scoreMultiplier < 1)
            {
                scoreMultiplierText.GetComponent <TextMeshProUGUI>().color = new Color(255, 0, 0);
            }
            if (runState.scoreMultiplier > 1)
            {
                scoreMultiplierText.GetComponent <TextMeshProUGUI>().color = new Color(0, 255, 0);
            }
        }
        Transform comboText = comboCounter.transform.Find("Text");

        if (comboText)
        {
            string comboString = "x" + runState.rhythmCombo.ToString();
            if (comboString != comboText.GetComponent <TextMeshProUGUI>().text)
            {
                comboText.GetComponent <FadeTMPro>().Reset();
            }
            comboText.GetComponent <TextMeshProUGUI>().text = comboString;
        }
    }