public static FocusFilterStorage GetFocusTouch(AiBehaviourController controller)
    {
        const float timeSortScale     = 1.0f;
        const float distanceSortScale = 1.0f;

        const string storageName = "touchStorage";
        const string focusName   = "touchFocus";

        StimuliStorage storage = controller.GetBlackboardValue <StimuliStorage>(storageName)?.value;

        if (storage == null)
        {
            return(null);
        }

        GenericBlackboard.InitializeMethod <FocusFilterStorage> initializeMethod =
            () => new FocusFilterStorage(controller.transform, storage, distanceSortScale, timeSortScale);
        return(controller.InitBlackboardValue(focusName, initializeMethod).value);
    }
    /*public const int awarenessEnemy = 0;
     * public const int awarenessUnknown = 1;
     *
     * public const int awarenessWantsToTalk = 2;*/
    #endregion

    // TODO setup attention utility params
    public static FocusPriority GetFocusPriority(AiBehaviourController controller)
    {
        // check if focus was already created and if soo return it
        FocusPriority focusPriority = (FocusPriority)controller.GetBlackboardValue <FocusOwned>("priorityFocus")?.value;

        if (focusPriority != null)
        {
            return(focusPriority);
        }

        // otherwise create a new one
        FocusOwned CreatePriorityFocusDelegate()
        => new FocusPriority(controller.transform);

        focusPriority = (FocusPriority)controller.InitBlackboardValue("priorityFocus", CreatePriorityFocusDelegate).value;

        focusPriority.SetSustainUtility(0.1f);

        // prepare partial focuses
        FocusOwned enemyFocus = GetFocusEnemy(controller);
        FocusOwned painFocus  = GetFocusPain(controller);
        FocusOwned touchFocus = GetFocusTouch(controller);
        FocusOwned noiseFocus = GetFocusNoise(controller);

        if (enemyFocus != null)
        {
            /// enemy
            AttentionMode CreateAttentionMode() => focusPriority.AddAttentionMode(new AttentionMode(enemyFocus));

            AttentionMode attentionMode = controller.InitBlackboardValue("attentionEnemy", CreateAttentionMode).value;

            AttentionUtility attentionUtility = new AttentionUtility()
            {
                attackTime   = 0.5f,
                attackPeek   = 1.0f,
                sustainValue = 0.5f,
            };
            attentionMode.SetUtility(() => attentionMode.focus.HasTarget() ? attentionUtility.GetUtility(attentionMode.activeTime) : 0);
        }

        // noise
        if (noiseFocus != null)
        {
            /// enemy
            AttentionMode CreateAttentionMode() => focusPriority.AddAttentionMode(new AttentionMode(noiseFocus));

            AttentionMode attentionMode = controller.InitBlackboardValue("attentionNoise", CreateAttentionMode).value;

            AttentionUtility attentionUtility = new AttentionUtility()
            {
                attackTime   = 0.25f,
                attackPeek   = 0.85f,
                sustainValue = 0.45f,
            };
            attentionMode.SetUtility(() => attentionMode.hadTarget ? attentionUtility.GetUtility(attentionMode.activeTime) : 0);
        }

        // pain
        if (painFocus != null)
        {
            /// enemy
            AttentionMode CreateAttentionMode() => focusPriority.AddAttentionMode(new AttentionMode(painFocus));

            AttentionMode attentionMode = controller.InitBlackboardValue("attentionPain", CreateAttentionMode).value;

            AttentionUtility attentionUtility = new AttentionUtility()
            {
                attackTime   = 0.45f,
                attackPeek   = 0.8f,
                sustainValue = 0.4f,
            };
            attentionMode.SetUtility(() => attentionMode.focus.HasTarget() ? attentionUtility.GetUtility(attentionMode.activeTime) : 0);;
        }

        // touch
        if (touchFocus != null)
        {
            /// enemy
            AttentionMode CreateAttentionMode() => focusPriority.AddAttentionMode(new AttentionMode(touchFocus));

            AttentionMode attentionMode = controller.InitBlackboardValue("attentionTouch", CreateAttentionMode).value;

            AttentionUtility attentionUtility = new AttentionUtility()
            {
                attackTime   = 0.25f,
                attackPeek   = 0.65f,
                sustainValue = 0.3f,
            };
            attentionMode.SetUtility(() => attentionMode.hadTarget ? attentionUtility.GetUtility(attentionMode.activeTime) : 0);
        }

        // idle
        {
            /// enemy
            AttentionMode CreateAttentionMode() => focusPriority.AddAttentionMode(new AttentionMode());

            AttentionMode attentionMode = controller.InitBlackboardValue("attentionIdle", CreateAttentionMode).value;

            attentionMode.SetUtility(() => 0.15f);
        }

        return(focusPriority);
    }
 public static AttentionMode GetAttentionIdle(AiBehaviourController controller)
 {
     return(controller.GetBlackboardValue <AttentionMode>("attentionIdle").value);
 }