{"TotalCount":89,"Files":[{"Ident":"utopia.npbehavesbox","Path":"BehaviorTree/Composite/Parallel.cs","FileName":"Parallel.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"using System.Collections.Generic;\nusing Sandbox.Diagnostics;\n\nnamespace NPBehave\n{\n    public class Parallel : Composite\n    {\n        public enum Policy\n        {\n            One,\n            All,\n        }\n\n        // public enum Wait\n        // {\n        //     NEVER,\n        //     ON_FAILURE,\n        //     ON_SUCCESS,\n        //     BOTH\n        // }\n\n        // private Wait waitForPendingChildrenRule;\n        private Policy _failurePolicy;\n        private Policy _successPolicy;\n        private int _childrenCount = 0;\n        private int _runningCount = 0;\n        private int _succeededCount = 0;\n        private int _failedCount = 0;\n        private Dictionary\u003CNode, bool\u003E _childrenResults;\n        private bool _successState;\n        private bool _childrenAborted;\n\n        public Parallel(Policy successPolicy, Policy failurePolicy, /*Wait waitForPendingChildrenRule,*/ params Node[] children) : base(\u0022Parallel\u0022, children)\n        {\n            _successPolicy = successPolicy;\n            _failurePolicy = failurePolicy;\n            // this.waitForPendingChildrenRule = waitForPendingChildrenRule;\n            _childrenCount = children.Length;\n            _childrenResults = new Dictionary\u003CNode, bool\u003E();\n        }\n\n        protected override void DoStart()\n        {\n            foreach (Node child in Children)\n            {\n                Assert.AreEqual(child.CurrentState, State.Inactive);\n            }\n\n            _childrenAborted = false;\n            _runningCount = 0;\n            _succeededCount = 0;\n            _failedCount = 0;\n            foreach (Node child in Children)\n            {\n                _runningCount\u002B\u002B;\n                child.Start();\n            }\n        }\n\n        protected override void DoStop()\n        {\n            Assert.True(_runningCount \u002B _succeededCount \u002B _failedCount == _childrenCount);\n\n            foreach (Node child in Children)\n            {\n                if (child.IsActive)\n                {\n                    child.Stop();\n                }\n            }\n        }\n\n        protected override void DoChildStopped(Node child, bool result)\n        {\n            _runningCount--;\n            if (result)\n            {\n                _succeededCount\u002B\u002B;\n            }\n            else\n            {\n                _failedCount\u002B\u002B;\n            }\n            _childrenResults[child] = result;\n\n            bool allChildrenStarted = _runningCount \u002B _succeededCount \u002B _failedCount == _childrenCount;\n            if (allChildrenStarted)\n            {\n                if (_runningCount == 0)\n                {\n                    if (!_childrenAborted) // if children got aborted because rule was evaluated previously, we don\u0027t want to override the successState \n                    {\n                        if (_failurePolicy == Policy.One \u0026\u0026 _failedCount \u003E 0)\n                        {\n                            _successState = false;\n                        }\n                        else if (_successPolicy == Policy.One \u0026\u0026 _succeededCount \u003E 0)\n                        {\n                            _successState = true;\n                        }\n                        else if (_successPolicy == Policy.All \u0026\u0026 _succeededCount == _childrenCount)\n                        {\n                            _successState = true;\n                        }\n                        else\n                        {\n                            _successState = false;\n                        }\n                    }\n                    Stopped(_successState);\n                }\n                else if (!_childrenAborted)\n                {\n                    Assert.False(_succeededCount == _childrenCount);\n                    Assert.False(_failedCount == _childrenCount);\n\n                    if (_failurePolicy == Policy.One \u0026\u0026 _failedCount \u003E 0/* \u0026\u0026 waitForPendingChildrenRule != Wait.ON_FAILURE \u0026\u0026 waitForPendingChildrenRule != Wait.BOTH*/)\n                    {\n                        _successState = false;\n                        _childrenAborted = true;\n                    }\n                    else if (_successPolicy == Policy.One \u0026\u0026 _succeededCount \u003E 0/* \u0026\u0026 waitForPendingChildrenRule != Wait.ON_SUCCESS \u0026\u0026 waitForPendingChildrenRule != Wait.BOTH*/)\n                    {\n                        _successState = true;\n                        _childrenAborted = true;\n                    }\n\n                    if (_childrenAborted)\n                    {\n                        foreach (Node currentChild in Children)\n                        {\n                            if (currentChild.IsActive)\n                            {\n                                currentChild.Stop();\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        public override void StopLowerPriorityChildrenForChild(Node abortForChild, bool immediateRestart)\n        {\n            if (immediateRestart)\n            {\n                Assert.False(abortForChild.IsActive);\n                if (_childrenResults[abortForChild])\n                {\n                    _succeededCount--;\n                }\n                else\n                {\n                    _failedCount--;\n                }\n                _runningCount\u002B\u002B;\n                abortForChild.Start();\n            }\n            else\n            {\n                throw new Exception(\u0022On Parallel Nodes all children have the same priority, thus the method does nothing if you pass false to \u0027immediateRestart\u0027!\u0022);\n            }\n        }\n    }\n}\n"},{"Ident":"utopia.npbehavesbox","Path":"BehaviorTree/Composite/RandomSequence.cs","FileName":"RandomSequence.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"using System.Collections;\nusing Sandbox.Diagnostics;\n\nnamespace NPBehave\n{\n    public class RandomSequence : Composite\n    {\n        static System.Random _rng = new System.Random();\n\n\n#if DEBUG\n        static public void DebugSetSeed( int seed )\n        {\n            _rng = new System.Random( seed );\n        }\n#endif\n\n        private int _currentIndex = -1;\n        private int[] _randomizedOrder;\n\n        public RandomSequence(params Node[] children) : base(\u0022Random Sequence\u0022, children)\n        {\n            _randomizedOrder = new int[children.Length];\n            for (int i = 0; i \u003C Children.Length; i\u002B\u002B)\n            {\n                _randomizedOrder[i] = i;\n            }\n        }\n\n        protected override void DoStart()\n        {\n            foreach (Node child in Children)\n            {\n                Assert.AreEqual(child.CurrentState, State.Inactive);\n            }\n\n            _currentIndex = -1;\n\n            // Shuffling\n            int n = _randomizedOrder.Length;\n            while (n \u003E 1)\n            {\n                int k = _rng.Next(n--);\n                (_randomizedOrder[n], _randomizedOrder[k]) = (_randomizedOrder[k], _randomizedOrder[n]);\n            }\n\n            ProcessChildren();\n        }\n\n        protected override void DoStop()\n        {\n            Children[_randomizedOrder[_currentIndex]].Stop();\n        }\n\n\n        protected override void DoChildStopped(Node child, bool result)\n        {\n            if (result)\n            {\n                ProcessChildren();\n            }\n            else\n            {\n                Stopped(false);\n            }\n        }\n\n        private void ProcessChildren()\n        {\n            if (\u002B\u002B_currentIndex \u003C Children.Length)\n            {\n                if (IsStopRequested)\n                {\n                    Stopped(false);\n                }\n                else\n                {\n                    Children[_randomizedOrder[_currentIndex]].Start();\n                }\n            }\n            else\n            {\n                Stopped(true);\n            }\n        }\n\n        public override void StopLowerPriorityChildrenForChild(Node abortForChild, bool immediateRestart)\n        {\n            int indexForChild = 0;\n            bool found = false;\n            foreach (Node currentChild in Children)\n            {\n                if (currentChild == abortForChild)\n                {\n                    found = true;\n                }\n                else if (!found)\n                {\n                    indexForChild\u002B\u002B;\n                }\n                else if (found \u0026\u0026 currentChild.IsActive)\n                {\n                    if (immediateRestart)\n                    {\n                        _currentIndex = indexForChild - 1;\n                    }\n                    else\n                    {\n                        _currentIndex = Children.Length;\n                    }\n                    currentChild.Stop();\n                    break;\n                }\n            }\n        }\n\n        public override string ToString()\n        {\n            return $\u0022{base.ToString()}[{_currentIndex}]\u0022;\n        }\n    }\n}\n"},{"Ident":"utopia.npbehavesbox","Path":"BehaviorTree/Decorator/Succeeder.cs","FileName":"Succeeder.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"namespace NPBehave\n{\n    public class Succeeder : Decorator\n    {\n        public Succeeder(Node decoratee) : base(\u0022Succeeder\u0022, decoratee)\n        {\n        }\n\n        protected override void DoStart()\n        {\n            Decoratee.Start();\n        }\n\n        protected override void DoStop()\n        {\n            Decoratee.Stop();\n        }\n\n        protected override void DoChildStopped(Node child, bool result)\n        {\n            Stopped(true);\n        }\n    }\n}"},{"Ident":"utopia.npbehavesbox","Path":"Code/BehaviorTree/Exception.cs","FileName":"Exception.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"using System;\n\nnamespace NPBehave\n{\n    public class Exception : System.Exception\n    {\n        public Exception(string message) : base(message)\n        {\n        }\n    }\n}"},{"Ident":"utopia.npbehavesbox","Path":"Code/BehaviorTree/Decorator/Repeater.cs","FileName":"Repeater.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"namespace NPBehave\n{\n    public class Repeater : Decorator\n    {\n        private int _loopCount = -1;\n        private int _currentLoop;\n\n        /// \u003Cparam name=\u0022loopCount\u0022\u003Enumber of times to execute the decoratee. Set to -1 to repeat forever, be careful with endless loops!\u003C/param\u003E\n        /// \u003Cparam name=\u0022decoratee\u0022\u003EDecorated Node\u003C/param\u003E\n        public Repeater(int loopCount, Node decoratee) : base(\u0022Repeater\u0022, decoratee)\n        {\n            _loopCount = loopCount;\n        }\n\n        /// \u003Cparam name=\u0022decoratee\u0022\u003EDecorated Node, repeated forever\u003C/param\u003E\n        public Repeater(Node decoratee) : base(\u0022Repeater\u0022, decoratee)\n        {\n        }\n\n        protected override void DoStart()\n        {\n            if (_loopCount != 0)\n            {\n                _currentLoop = 0;\n                Decoratee.Start();\n            }\n            else\n            {\n                Stopped(true);\n            }\n        }\n\n        protected override void DoStop()\n        {\n            Clock.RemoveTimer(RestartDecoratee);\n            \n            if (Decoratee.IsActive)\n            {\n                Decoratee.Stop();\n            }\n            else\n            {\n                Stopped(false);\n            }\n        }\n\n        protected override void DoChildStopped(Node child, bool result)\n        {\n            if (result)\n            {\n                if (IsStopRequested || (_loopCount \u003E 0 \u0026\u0026 \u002B\u002B_currentLoop \u003E= _loopCount))\n                {\n                    Stopped(true);\n                }\n                else\n                {\n                    Clock.AddTimer(0, 0, RestartDecoratee);\n                }\n            }\n            else\n            {\n                Stopped(false);\n            }\n        }\n\n        protected void RestartDecoratee()\n        {\n            Decoratee.Start();\n        }\n    }\n}"},{"Ident":"utopia.npbehavesbox","Path":"BehaviorTree/Composite/Selector.cs","FileName":"Selector.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"using System.Collections;\nusing Sandbox.Diagnostics;\n\nnamespace NPBehave\n{\n    public class Selector : Composite\n    {\n        private int _currentIndex = -1;\n\n        public Selector(params Node[] children) : base(\u0022Selector\u0022, children)\n        {\n        }\n\n\t\t#if DEBUG\n\t    public override string DebugIcon =\u003E \u0022rule\u0022;\n\t\t#endif\n        protected override void DoStart()\n        {\n            foreach (Node child in Children)\n            {\n                Assert.AreEqual(child.CurrentState, State.Inactive);\n            }\n\n            _currentIndex = -1;\n\n            ProcessChildren();\n        }\n\n        protected override void DoStop()\n        {\n            Children[_currentIndex].Stop();\n        }\n\n        protected override void DoChildStopped(Node child, bool result)\n        {\n            if (result)\n            {\n                Stopped(true);\n            }\n            else\n            {\n                ProcessChildren();\n            }\n        }\n\n        private void ProcessChildren()\n        {\n            if (\u002B\u002B_currentIndex \u003C Children.Length)\n            {\n                if (IsStopRequested)\n                {\n                    Stopped(false);\n                }\n                else\n                {\n                    Children[_currentIndex].Start();\n                }\n            }\n            else\n            {\n                Stopped(false);\n            }\n        }\n\n        public override void StopLowerPriorityChildrenForChild(Node abortForChild, bool immediateRestart)\n        {\n            int indexForChild = 0;\n            bool found = false;\n            foreach (Node currentChild in Children)\n            {\n                if (currentChild == abortForChild)\n                {\n                    found = true;\n                }\n                else if (!found)\n                {\n                    indexForChild\u002B\u002B;\n                }\n                else if (found \u0026\u0026 currentChild.IsActive)\n                {\n                    if (immediateRestart)\n                    {\n                        _currentIndex = indexForChild - 1;\n                    }\n                    else\n                    {\n                        _currentIndex = Children.Length;\n                    }\n                    currentChild.Stop();\n                    break;\n                }\n            }\n        }\n\n        public override string ToString()\n        {\n            return $\u0022{base.ToString()}[{_currentIndex}]\u0022;\n        }\n    }\n}\n"},{"Ident":"utopia.npbehavesbox","Path":"BehaviorTree/Decorator/BlackboardCondition.cs","FileName":"BlackboardCondition.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"namespace NPBehave\n{\n    public class BlackboardCondition : ObservingDecorator\n    {\n        private string _key;\n        private object _value;\n        private Operator _op;\n\n        public string Key\n        {\n            get\n            {\n                return _key;\n            }\n        }\n\n        public object Value\n        {\n            get\n            {\n                return _value;\n            }\n        }\n\n        public Operator Operator\n        {\n            get\n            {\n                return _op;\n            }\n        }\n        \n        #if DEBUG\n\t    public override string DebugIcon =\u003E \u0022quiz\u0022;\n\t    public override string ComputedLabel\n\t    {\n\t\t    get\n\t\t    {\n\t\t\t    return $\u0022{Key} {OperatorToString(Operator)} {Value}\u0022;\n\t\t    }\n\t    }\n\n\t    public string OperatorToString( Operator _op )\n\t    {\n\t\t    return _op switch\n\t\t    {\n\t\t\t    Operator.IsSet =\u003E \u0022?=\u0022,\n\t\t\t    Operator.IsNotSet =\u003E \u0022?!=\u0022,\n\t\t\t    Operator.IsEqual =\u003E \u0022==\u0022,\n\t\t\t    Operator.IsNotEqual =\u003E \u0022!=\u0022,\n\t\t\t    Operator.IsGreaterOrEqual =\u003E \u0022\u003E=\u0022,\n\t\t\t    Operator.IsGreater =\u003E \u0022\u003E\u0022,\n\t\t\t    Operator.IsSmallerOrEqual =\u003E \u0022\u003C=\u0022,\n\t\t\t    Operator.IsSmaller =\u003E \u0022\u003C\u0022,\n\t\t\t    Operator.AlwaysTrue =\u003E \u0022ALWAYS_TRUE\u0022,\n\t\t\t    _ =\u003E $\u0022\u003C{_op}\u003E\u0022\n\t\t    };\n\t    }\n\n\n#endif\n\n        public BlackboardCondition(string key, Operator op, object value, Stops stopsOnChange, Node decoratee) : base(\u0022BlackboardCondition\u0022, stopsOnChange, decoratee)\n        {\n            _op = op;\n            _key = key;\n            _value = value;\n            StopsOnChange = stopsOnChange;\n        }\n        \n        public BlackboardCondition(string key, Operator op, Stops stopsOnChange, Node decoratee) : base(\u0022BlackboardCondition\u0022, stopsOnChange, decoratee)\n        {\n            _op = op;\n            _key = key;\n            StopsOnChange = stopsOnChange;\n        }\n\n\n        protected override void StartObserving()\n        {\n            RootNode.Blackboard.AddObserver(_key, OnValueChanged);\n        }\n\n        protected override void StopObserving()\n        {\n            RootNode.Blackboard.RemoveObserver(_key, OnValueChanged);\n        }\n\n        private void OnValueChanged(Blackboard.Type type, object newValue)\n        {\n            Evaluate();\n        }\n\n        protected override bool IsConditionMet()\n        {\n            if (_op == Operator.AlwaysTrue)\n            {\n                return true;\n            }\n\n            if (!RootNode.Blackboard.IsSet(_key))\n            {\n                return _op == Operator.IsNotSet;\n            }\n\n            object o = RootNode.Blackboard.Get(_key);\n\n            switch (_op)\n            {\n                case Operator.IsSet: return true;\n                case Operator.IsEqual: return Equals(o, _value);\n                case Operator.IsNotEqual: return !Equals(o, _value);\n\n                case Operator.IsGreaterOrEqual:\n                    if (o is float)\n                    {\n                        return (float)o \u003E= (float)_value;\n                    }\n                    else if (o is int)\n                    {\n                        return (int)o \u003E= (int)_value;\n                    }\n                    else\n                    {\n                        Log.Error( $\u0022Type not compareable: {o.GetType()}\u0022 );\n                        return false;\n                    }\n\n                case Operator.IsGreater:\n                    if (o is float)\n                    {\n                        return (float)o \u003E (float)_value;\n                    }\n                    else if (o is int)\n                    {\n                        return (int)o \u003E (int)_value;\n                    }\n                    else\n                    {\n\t                    Log.Error( $\u0022Type not compareable: {o.GetType()}\u0022 );\n                        return false;\n                    }\n\n                case Operator.IsSmallerOrEqual:\n                    if (o is float)\n                    {\n                        return (float)o \u003C= (float)_value;\n                    }\n                    else if (o is int)\n                    {\n                        return (int)o \u003C= (int)_value;\n                    }\n                    else\n                    {\n\t                    Log.Error( $\u0022Type not compareable: {o.GetType()}\u0022 );\n                        return false;\n                    }\n\n                case Operator.IsSmaller:\n                    if (o is float)\n                    {\n                        return (float)o \u003C (float)_value;\n                    }\n                    else if (o is int)\n                    {\n                        return (int)o \u003C (int)_value;\n                    }\n                    else\n                    {\n\t                    Log.Error( $\u0022Type not compareable: {o.GetType()}\u0022 );\n                        return false;\n                    }\n\n                default: return false;\n            }\n        }\n\n        public override string ToString()\n        {\n            return $\u0022({_op}) {_key} ? {_value}\u0022;\n        }\n    }\n}\n"},{"Ident":"utopia.npbehavesbox","Path":"BehaviorTree/Decorator/Condition.cs","FileName":"Condition.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"using System;\n\nnamespace NPBehave\n{\n    public class Condition : ObservingDecorator\n    {\n        private Func\u003Cbool\u003E _condition;\n        private float _checkInterval;\n        private float _checkVariance;\n\n        public Condition(Func\u003Cbool\u003E condition, Node decoratee) : base(\u0022Condition\u0022, Stops.None, decoratee)\n        {\n            _condition = condition;\n            _checkInterval = 0.0f;\n            _checkVariance = 0.0f;\n        }\n\n        public Condition(Func\u003Cbool\u003E condition, Stops stopsOnChange, Node decoratee) : base(\u0022Condition\u0022, stopsOnChange, decoratee)\n        {\n            _condition = condition;\n            _checkInterval = 0.0f;\n            _checkVariance = 0.0f;\n        }\n\n        public Condition(Func\u003Cbool\u003E condition, Stops stopsOnChange, float checkInterval, float randomVariance, Node decoratee) : base(\u0022Condition\u0022, stopsOnChange, decoratee)\n        {\n            _condition = condition;\n            _checkInterval = checkInterval;\n            _checkVariance = randomVariance;\n        }\n\n        protected override void StartObserving()\n        {\n            RootNode.Clock.AddTimer(_checkInterval, _checkVariance, -1, Evaluate);\n        }\n\n        protected override void StopObserving()\n        {\n            RootNode.Clock.RemoveTimer(Evaluate);\n        }\n\n        protected override bool IsConditionMet()\n        {\n            return _condition();\n        }\n    }\n}"},{"Ident":"utopia.npbehavesbox","Path":"BehaviorTree/Decorator/Decorator.cs","FileName":"Decorator.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"namespace NPBehave\n{\n\n    public abstract class Decorator : Container\n    {\n        protected Node Decoratee;\n\n        public Decorator(string name, Node decoratee) : base(name)\n        {\n            Decoratee = decoratee;\n            Decoratee.SetParent(this);\n        }\n\n        public override void SetRoot(Root rootNode)\n        {\n            base.SetRoot(rootNode);\n            Decoratee.SetRoot(rootNode);\n        }\n\n\n#if DEBUG\n\n\t    public override string DebugIcon =\u003E \u0022brush\u0022;\n\t    public override Node[] DebugChildren\n        {\n            get\n            {\n                return new Node[] { Decoratee };\n            }\n        }\n#endif\n\n        public override void ParentCompositeStopped(Composite composite)\n        {\n            base.ParentCompositeStopped(composite);\n            Decoratee.ParentCompositeStopped(composite);\n        }\n    }\n}\n"},{"Ident":"utopia.npbehavesbox","Path":"BehaviorTree/Decorator/ObservingDecorator.cs","FileName":"ObservingDecorator.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"using System.Collections;\nusing Sandbox.Diagnostics;\n\nnamespace NPBehave\n{\n    public abstract class ObservingDecorator : Decorator\n    {\n        protected Stops StopsOnChange;\n        private bool _isObserving;\n\n        public ObservingDecorator(string name, Stops stopsOnChange, Node decoratee) : base(name, decoratee)\n        {\n            StopsOnChange = stopsOnChange;\n            _isObserving = false;\n        }\n\n        protected override void DoStart()\n        {\n            if (StopsOnChange != Stops.None)\n            {\n                if (!_isObserving)\n                {\n                    _isObserving = true;\n                    StartObserving();\n                }\n            }\n\n            if (!IsConditionMet())\n            {\n                Stopped(false);\n            }\n            else\n            {\n                Decoratee.Start();\n            }\n        }\n\n        protected override void DoStop()\n        {\n            Decoratee.Stop();\n        }\n\n        protected override void DoChildStopped(Node child, bool result)\n        {\n            Assert.AreNotEqual(((Node)this).CurrentState, State.Inactive);\n            if (StopsOnChange is Stops.None or Stops.Self)\n            {\n                if (_isObserving)\n                {\n                    _isObserving = false;\n                    StopObserving();\n                }\n            }\n            Stopped(result);\n        }\n\n        protected override void DoParentCompositeStopped(Composite parentComposite)\n        {\n            if (_isObserving)\n            {\n                _isObserving = false;\n                StopObserving();\n            }\n        }\n\n        protected void Evaluate()\n        {\n            if (IsActive \u0026\u0026 !IsConditionMet())\n            {\n                if (StopsOnChange is Stops.Self or Stops.Both or Stops.ImmediateRestart)\n                {\n                    // Debug.Log( this.key \u002B \u0022 stopped self \u0022);\n                    Stop();\n                }\n            }\n            else if (!IsActive \u0026\u0026 IsConditionMet())\n            {\n                if (StopsOnChange == Stops.LowerPriority || StopsOnChange == Stops.Both || StopsOnChange == Stops.ImmediateRestart || StopsOnChange == Stops.LowerPriorityImmediateRestart)\n                {\n                    // Debug.Log( this.key \u002B \u0022 stopped other \u0022);\n                    Container parentNode = ParentNode;\n                    Node childNode = this;\n                    while (parentNode != null \u0026\u0026 !(parentNode is Composite))\n                    {\n                        childNode = parentNode;\n                        parentNode = parentNode.ParentNode;\n                    }\n                    Assert.NotNull(parentNode, \u0022NTBtrStops is only valid when attached to a parent composite\u0022);\n                    Assert.NotNull(childNode);\n                    if (parentNode is Parallel)\n                    {\n                        Assert.True(StopsOnChange == Stops.ImmediateRestart, \u0022On Parallel Nodes all children have the same priority, thus Stops.LOWER_PRIORITY or Stops.BOTH are unsupported in this context!\u0022);\n                    }\n\n                    if (StopsOnChange == Stops.ImmediateRestart || StopsOnChange == Stops.LowerPriorityImmediateRestart)\n                    {\n                        if (_isObserving)\n                        {\n                            _isObserving = false;\n                            StopObserving();\n                        }\n                    }\n\n                    ((Composite)parentNode)?.StopLowerPriorityChildrenForChild(childNode, StopsOnChange is Stops.ImmediateRestart or Stops.LowerPriorityImmediateRestart);\n                }\n            }\n        }\n\n        protected abstract void StartObserving();\n\n        protected abstract void StopObserving();\n\n        protected abstract bool IsConditionMet();\n\n    }\n}\n"},{"Ident":"utopia.npbehavesbox","Path":"BehaviorTree/Decorator/TimeMin.cs","FileName":"TimeMin.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"using Sandbox.Diagnostics;\n\nnamespace NPBehave\n{\n    public class TimeMin : Decorator\n    {\n        private float _limit = 0.0f;\n        private float _randomVariation;\n        private bool _waitOnFailure = false;\n        private bool _isLimitReached = false;\n        private bool _isDecorateeDone = false;\n        private bool _isDecorateeSuccess = false;\n\n        public TimeMin(float limit, Node decoratee) : base(\u0022TimeMin\u0022, decoratee)\n        {\n            _limit = limit;\n            _randomVariation = _limit * 0.05f;\n            _waitOnFailure = false;\n            Assert.True(limit \u003E 0f, \u0022limit has to be set\u0022);\n        }\n\n        public TimeMin(float limit, bool waitOnFailure, Node decoratee) : base(\u0022TimeMin\u0022, decoratee)\n        {\n            _limit = limit;\n            _randomVariation = _limit * 0.05f;\n            _waitOnFailure = waitOnFailure;\n            Assert.True(limit \u003E 0f, \u0022limit has to be set\u0022);\n        }\n\n        public TimeMin(float limit, float randomVariation, bool waitOnFailure, Node decoratee) : base(\u0022TimeMin\u0022, decoratee)\n        {\n            _limit = limit;\n            _randomVariation = randomVariation;\n            _waitOnFailure = waitOnFailure;\n            Assert.True(limit \u003E 0f, \u0022limit has to be set\u0022);\n        }\n\n        protected override void DoStart()\n        {\n            _isDecorateeDone = false;\n            _isDecorateeSuccess = false;\n            _isLimitReached = false;\n            Clock.AddTimer(_limit, _randomVariation, 0, TimeoutReached);\n            Decoratee.Start();\n        }\n\n        protected override void DoStop()\n        {\n            if (Decoratee.IsActive)\n            {\n                Clock.RemoveTimer(TimeoutReached);\n                _isLimitReached = true;\n                Decoratee.Stop();\n            }\n            else\n            {\n                Clock.RemoveTimer(TimeoutReached);\n                Stopped(false);\n            }\n        }\n\n        protected override void DoChildStopped(Node child, bool result)\n        {\n            _isDecorateeDone = true;\n            _isDecorateeSuccess = result;\n            if (_isLimitReached || (!result \u0026\u0026 !_waitOnFailure))\n            {\n                Clock.RemoveTimer(TimeoutReached);\n                Stopped(_isDecorateeSuccess);\n            }\n            else\n            {\n                Assert.True(Clock.HasTimer(TimeoutReached));\n            }\n        }\n\n        private void TimeoutReached()\n        {\n            _isLimitReached = true;\n            if (_isDecorateeDone)\n            {\n                Stopped(_isDecorateeSuccess);\n            }\n            else\n            {\n                Assert.True(Decoratee.IsActive);\n            }\n        }\n    }\n}\n"},{"Ident":"utopia.npbehavesbox","Path":"UnitTests/LibraryTest.cs","FileName":"LibraryTest.cs","PackageType":"library","CodeKind":"UnitTest","AssetVersionId":72229,"Code":"using Sandbox;\r\n\r\n[TestClass]\r\npublic partial class LibraryTests\r\n{\r\n\t[TestMethod]\r\n\tpublic void SceneTest()\r\n\t{\r\n\t\tvar scene = new Scene();\r\n\t\tusing ( scene.Push() )\r\n\t\t{\r\n\t\t\tvar go = new GameObject();\r\n\r\n\t\t\tAssert.AreEqual( 1, scene.Directory.GameObjectCount );\r\n\t\t}\r\n\t}\r\n\r\n}\r\n"},{"Ident":"utopia.npbehavesbox","Path":"BehaviorTree/Composite/RandomSelector.cs","FileName":"RandomSelector.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"using System.Collections;\nusing Sandbox.Diagnostics;\n\n\nnamespace NPBehave\n{\n    public class RandomSelector : Composite\n    {\n        static System.Random _rng = new System.Random();\n\n#if DEBUG\n        static public void DebugSetSeed( int seed )\n        {\n            _rng = new System.Random( seed );\n        }\n#endif\n\n        private int _currentIndex = -1;\n        private int[] _randomizedOrder;\n\n        public RandomSelector(params Node[] children) : base(\u0022Random Selector\u0022, children)\n        {\n            _randomizedOrder = new int[children.Length];\n            for (int i = 0; i \u003C Children.Length; i\u002B\u002B)\n            {\n                _randomizedOrder[i] = i;\n            }\n        }\n\n\n        protected override void DoStart()\n        {\n            foreach (Node child in Children)\n            {\n                Assert.AreEqual(child.CurrentState, State.Inactive);\n            }\n\n            _currentIndex = -1;\n\n            // Shuffling\n            int n = _randomizedOrder.Length;\n            while (n \u003E 1)\n            {\n                int k = _rng.Next(n--);\n                (_randomizedOrder[n], _randomizedOrder[k]) = (_randomizedOrder[k], _randomizedOrder[n]);\n            }\n\n            ProcessChildren();\n        }\n\n\n\n        protected override void DoStop()\n        {\n            Children[_randomizedOrder[_currentIndex]].Stop();\n        }\n\n        protected override void DoChildStopped(Node child, bool result)\n        {\n            if (result)\n            {\n                Stopped(true);\n            }\n            else\n            {\n                ProcessChildren();\n            }\n        }\n\n        private void ProcessChildren()\n        {\n            if (\u002B\u002B_currentIndex \u003C Children.Length)\n            {\n                if (IsStopRequested)\n                {\n                    Stopped(false);\n                }\n                else\n                {\n                    Children[_randomizedOrder[_currentIndex]].Start();\n                }\n            }\n            else\n            {\n                Stopped(false);\n            }\n        }\n\n        public override void StopLowerPriorityChildrenForChild(Node abortForChild, bool immediateRestart)\n        {\n            int indexForChild = 0;\n            bool found = false;\n            foreach (Node currentChild in Children)\n            {\n                if (currentChild == abortForChild)\n                {\n                    found = true;\n                }\n                else if (!found)\n                {\n                    indexForChild\u002B\u002B;\n                }\n                else if (found \u0026\u0026 currentChild.IsActive)\n                {\n                    if (immediateRestart)\n                    {\n                        _currentIndex = indexForChild - 1;\n                    }\n                    else\n                    {\n                        _currentIndex = Children.Length;\n                    }\n                    currentChild.Stop();\n                    break;\n                }\n            }\n        }\n\n        public override string ToString()\n        {\n            return $\u0022{base.ToString()}[{_currentIndex}]\u0022;\n        }\n    }\n}\n"},{"Ident":"utopia.npbehavesbox","Path":"BehaviorTree/Debugger.cs","FileName":"Debugger.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"using System.Collections.Generic;\nusing Sandbox;\n\nnamespace NPBehave\n{\n    public class Debugger : Component\n    {\n        public Root BehaviorTree;\n\n        private static Blackboard _customGlobalStats = null;\n        public static Blackboard CustomGlobalStats\n        {\n            get \n            {\n                if (_customGlobalStats == null)\n                {\n                    _customGlobalStats = SandboxContext.GetSharedBlackboard(\u0022_GlobalStats\u0022);;\n                }\n                return _customGlobalStats;\n            }\n        }\n\n        private Blackboard _customStats = null;\n        public Blackboard CustomStats\n        {\n            get \n            {\n                if (_customStats == null)\n                {\n                    _customStats = new Blackboard(CustomGlobalStats, SandboxContext.GetClock());\n                }\n                return _customStats;\n            }\n        }\n\n        public void DebugCounterInc(string key)\n        {\n            if (!CustomStats.IsSet(key))\n            {\n                CustomStats[key] = 0;\n            }\n            CustomStats[key] = CustomStats.Get\u003Cint\u003E(key) \u002B 1;\n        }\n\n        public void DebugCounterDec(string key)\n        {\n            if (!CustomStats.IsSet(key))\n            {\n                CustomStats[key] = 0;\n            }\n            CustomStats[key] = CustomStats.Get\u003Cint\u003E(key) - 1;\n        }\n\n        public static void GlobalDebugCounterInc(string key)\n        {\n            if (!CustomGlobalStats.IsSet(key))\n            {\n                CustomGlobalStats[key] = 0;\n            }\n            CustomGlobalStats[key] = CustomGlobalStats.Get\u003Cint\u003E(key) \u002B 1;\n        }\n\n        public static void GlobalDebugCounterDec(string key)\n        {\n            if (!CustomGlobalStats.IsSet(key))\n            {\n                CustomGlobalStats[key] = 0;\n            }\n            CustomGlobalStats[key] = CustomGlobalStats.Get\u003Cint\u003E(key) - 1;\n        }\n\n    }\n}\n"},{"Ident":"utopia.npbehavesbox","Path":"BehaviorTree/Decorator/Inverter.cs","FileName":"Inverter.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"namespace NPBehave\n{\n    public class Inverter : Decorator\n    {\n        public Inverter(Node decoratee) : base(\u0022Inverter\u0022, decoratee)\n        {\n        }\n\n        protected override void DoStart()\n        {\n            Decoratee.Start();\n        }\n\n        protected override void DoStop()\n        {\n            Decoratee.Stop();\n        }\n\n        protected override void DoChildStopped(Node child, bool result)\n        {\n            Stopped(!result);\n        }\n    }\n}"},{"Ident":"utopia.npbehavesbox","Path":"BehaviorTree/Stops.cs","FileName":"Stops.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"namespace NPBehave\n{\n    public enum Stops\n    {\n\t    /// \u003Csummary\u003E\n\t    /// The decorator will only check it\u0027s condition once it is started and will never stop any running nodes.\n\t    /// \u003C/summary\u003E\n        None,\n\t    /// \u003Csummary\u003E\n\t    /// The decorator will check it\u0027s condition once it is started and if it is met,\n\t    /// it will observe the blackboard for changes.\n\t    /// Once the condition is no longer met, it will stop itself allowing the parent composite to proceed with it\u0027s next node.\n\t    /// \u003C/summary\u003E\n        Self,\n\t    \n\t    /// \u003Csummary\u003E\n\t    /// The decorator will check it\u0027s condition once it is started and if it\u0027s not met, it will observe the blackboard for changes.\n\t    /// Once the condition is met, it will stop the lower priority node allowing the parent composite to proceed with it\u0027s next node\n\t    /// \u003C/summary\u003E\n        LowerPriority,\n\t    \n\t    /// \u003Csummary\u003E\n\t    /// The decorator will stop both: self and lower priority nodes.\n\t    /// \u003C/summary\u003E\n        Both,\n\t    \n\t    /// \u003Csummary\u003E\n\t    /// The decorator will check it\u0027s condition once it is started and if it\u0027s not met, it will observe the blackboard for changes.\n\t    /// Once the condition is met, it will stop the lower priority node and order the parent composite to restart the Decorator immediately.\n\t    /// \u003C/summary\u003E\n        ImmediateRestart,\n\t    \n\t    /// \u003Csummary\u003E\n\t    /// The decorator will check it\u0027s condition once it is started and if it\u0027s not met, it will observe the blackboard for changes.\n\t    /// Once the condition is met, it will stop the lower priority node and order the parent composite to restart the Decorator immediately.\n\t    /// As in BOTH it will also stop itself as soon as the condition is no longer met.\n\t    /// \u003C/summary\u003E\n        LowerPriorityImmediateRestart\n    }\n}\n"},{"Ident":"utopia.npbehavesbox","Path":"BehaviorTree/Task/Action.cs","FileName":"Action.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"using Sandbox.Diagnostics;\n\nnamespace NPBehave\n{\n    public class Action : Task\n    {\n        public enum Result\n        {\n            Success,\n            Failed,\n            Blocked,\n            Progress\n        }\n\n        public enum Request\n        {\n            Start,\n            Update,\n            Cancel,\n        }\n\n        private System.Func\u003Cbool\u003E _singleFrameFunc = null;\n        private System.Func\u003Cbool, Result\u003E _multiFrameFunc = null;\n        private System.Func\u003CRequest, Result\u003E _multiFrameFunc2 = null;\n        private System.Action _action = null;\n        private bool _bWasBlocked = false;\n\n        public Action(System.Action action) : base(\u0022Action\u0022)\n        {\n            _action = action;\n        }\n\n        public Action(System.Func\u003Cbool, Result\u003E multiframeFunc) : base(\u0022Action\u0022)\n        {\n            _multiFrameFunc = multiframeFunc;\n        }\n\n        public Action(System.Func\u003CRequest, Result\u003E multiframeFunc2) : base(\u0022Action\u0022)\n        {\n            _multiFrameFunc2 = multiframeFunc2;\n        }\n\n\n        public Action(System.Func\u003Cbool\u003E singleFrameFunc) : base(\u0022Action\u0022)\n        {\n            _singleFrameFunc = singleFrameFunc;\n        }\n\n        protected override void DoStart()\n        {\n            if (_action != null)\n            {\n                _action.Invoke();\n                Stopped(true);\n            }\n            else if (_multiFrameFunc != null)\n            {\n                Result result = _multiFrameFunc.Invoke(false);\n                if ( result == Result.Progress )\n                {\n                    RootNode.Clock.AddUpdateObserver( OnUpdateFunc );\n                }\n                else if ( result == Result.Blocked )\n                {\n                    _bWasBlocked = true;\n                    RootNode.Clock.AddUpdateObserver( OnUpdateFunc );\n                }\n                else\n                {\n                    Stopped(result == Result.Success);\n                }\n            }\n            else if (_multiFrameFunc2 != null)\n            {\n                Result result = _multiFrameFunc2.Invoke(Request.Start);\n                if (result == Result.Progress)\n                {\n                    RootNode.Clock.AddUpdateObserver(OnUpdateFunc2);\n                }\n                else if ( result == Result.Blocked )\n                {\n                    _bWasBlocked = true;\n                    RootNode.Clock.AddUpdateObserver( OnUpdateFunc2 );\n                }\n                else\n                {\n                    Stopped(result == Result.Success);\n                }\n            }\n            else if (_singleFrameFunc != null)\n            {\n                Stopped(_singleFrameFunc.Invoke());\n            }\n        }\n\n        private void OnUpdateFunc()\n        {\n            Result result = _multiFrameFunc.Invoke(false);\n            if (result != Result.Progress \u0026\u0026 result != Result.Blocked)\n            {\n                RootNode.Clock.RemoveUpdateObserver(OnUpdateFunc);\n                Stopped(result == Result.Success);\n            }\n        }\n\n        private void OnUpdateFunc2()\n        {\n            Result result = _multiFrameFunc2.Invoke( _bWasBlocked ? Request.Start : Request.Update);\n\n            if ( result == Result.Blocked )\n            {\n                _bWasBlocked = true;\n            }\n            else if ( result == Result.Progress )\n            {\n                _bWasBlocked = false;\n            }\n            else\n            {\n                RootNode.Clock.RemoveUpdateObserver( OnUpdateFunc2 );\n                Stopped( result == Result.Success );\n            }\n        }\n\n        protected override void DoStop()\n        {\n            if (_multiFrameFunc != null)\n            {\n                Result result = _multiFrameFunc.Invoke(true);\n                Assert.AreNotEqual(result, Result.Progress, \u0022The Task has to return Result.SUCCESS, Result.FAILED/BLOCKED after beeing cancelled!\u0022);\n                RootNode.Clock.RemoveUpdateObserver(OnUpdateFunc);\n                Stopped(result == Result.Success);\n            }\n            else if (_multiFrameFunc2 != null)\n            {\n                Result result = _multiFrameFunc2.Invoke(Request.Cancel);\n                Assert.AreNotEqual(result, Result.Progress, \u0022The Task has to return Result.SUCCESS or Result.FAILED/BLOCKED after beeing cancelled!\u0022);\n                RootNode.Clock.RemoveUpdateObserver(OnUpdateFunc2);\n                Stopped(result == Result.Success);\n            }\n            else\n            {\n                Assert.True(false, $\u0022DoStop called for a single frame action on {this}\u0022 );\n            }\n        }\n    }\n}\n"},{"Ident":"utopia.npbehavesbox","Path":"Samples/NPBehaveExampleHelloWorldAI.cs","FileName":"NPBehaveExampleHelloWorldAI.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"using NPBehave;\r\n\r\nnamespace Sandbox.Samples;\r\n\r\npublic class NPBehaveExampleHelloWorldAI : Component\r\n{\r\n\tprivate Root _behaviorTree;\r\n\r\n\tvoid Start()\r\n\t{\r\n\t\t_behaviorTree = new Root(\r\n\t\t\tnew Sequence(\r\n\t\t\t\tnew Action(() =\u003E Log.Info(\u0022Hello, World!\u0022))\r\n\t\t\t)\r\n\t\t);\r\n\t\t_behaviorTree.Start();\r\n\t}\r\n}\r\n"},{"Ident":"utopia.npbehavesbox","Path":"Code/BehaviorTree/Blackboard.cs","FileName":"Blackboard.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"using System.Collections.Generic;\n\nnamespace NPBehave\n{\n    public class Blackboard\n    {\n        public enum Type\n        {\n            Add,\n            Remove,\n            Change\n        }\n        private struct Notification\n        {\n            public string Key;\n            public Type Type;\n            public object Value;\n            public Notification(string key, Type type, object value)\n            {\n                Key = key;\n                Type = type;\n                Value = value;\n            }\n        }\n\n        private Clock _clock;\n        private Dictionary\u003Cstring, object\u003E _data = new Dictionary\u003Cstring, object\u003E();\n        private Dictionary\u003Cstring, List\u003CSystem.Action\u003CType, object\u003E\u003E\u003E _observers = new Dictionary\u003Cstring, List\u003CSystem.Action\u003CType, object\u003E\u003E\u003E();\n        private bool _isNotifiyng = false;\n        private Dictionary\u003Cstring, List\u003CSystem.Action\u003CType, object\u003E\u003E\u003E _addObservers = new Dictionary\u003Cstring, List\u003CSystem.Action\u003CType, object\u003E\u003E\u003E();\n        private Dictionary\u003Cstring, List\u003CSystem.Action\u003CType, object\u003E\u003E\u003E _removeObservers = new Dictionary\u003Cstring, List\u003CSystem.Action\u003CType, object\u003E\u003E\u003E();\n        private List\u003CNotification\u003E _notifications = new List\u003CNotification\u003E();\n        private List\u003CNotification\u003E _notificationsDispatch = new List\u003CNotification\u003E();\n        private Blackboard _parentBlackboard;\n        private HashSet\u003CBlackboard\u003E _children = new HashSet\u003CBlackboard\u003E();\n\n        public Blackboard(Blackboard parent, Clock clock)\n        {\n            _clock = clock;\n            _parentBlackboard = parent;\n        }\n        public Blackboard(Clock clock)\n        {\n            _parentBlackboard = null;\n            _clock = clock;\n        }\n\n        public void Enable()\n        {\n\t        _parentBlackboard?._children.Add(this);\n        }\n\n        public void Disable()\n        {\n\t        _parentBlackboard?._children.Remove(this);\n            if (_clock != null)\n            {\n                _clock.RemoveTimer(NotifiyObservers);\n            }\n        }\n\n        public object this[string key]\n        {\n            get\n            {\n                return Get(key);\n            }\n            set\n            {\n                Set(key, value);\n            }\n        }\n\n        public void Set(string key)\n        {\n            if (!IsSet(key))\n            {\n                Set(key, null);\n            }\n        }\n\n        public void Set(string key, object value)\n        {\n            if (_parentBlackboard != null \u0026\u0026 _parentBlackboard.IsSet(key))\n            {\n                _parentBlackboard.Set(key, value);\n            }\n            else\n            {\n                if (_data.TryAdd(key, value))\n                {\n\t                _notifications.Add(new Notification(key, Type.Add, value));\n                    _clock.AddTimer(0f, 0, NotifiyObservers);\n                }\n                else\n                {\n                    if ((_data[key] == null \u0026\u0026 value != null) || (_data[key] != null \u0026\u0026 !_data[key].Equals(value)))\n                    {\n                        _data[key] = value;\n                        _notifications.Add(new Notification(key, Type.Change, value));\n                        _clock.AddTimer(0f, 0, NotifiyObservers);\n                    }\n                }\n            }\n        }\n\n        public void Unset(string key)\n        {\n            if (_data.ContainsKey(key))\n            {\n                _data.Remove(key);\n                _notifications.Add(new Notification(key, Type.Remove, null));\n                _clock.AddTimer(0f, 0, NotifiyObservers);\n            }\n        }\n\n        public T Get\u003CT\u003E(string key)\n        {\n            object result = Get(key);\n            if (result == null)\n            {\n                return default(T);\n            }\n            return (T)result;\n        }\n\n        public object Get(string key)\n        {\n\t        return _data.TryGetValue(key, out var value) ? value : _parentBlackboard?.Get(key);\n        }\n\n        public bool IsSet(string key)\n        {\n            return _data.ContainsKey(key) || (_parentBlackboard != null \u0026\u0026 _parentBlackboard.IsSet(key));\n        }\n\n        public void AddObserver(string key, System.Action\u003CType, object\u003E observer)\n        {\n            List\u003CSystem.Action\u003CType, object\u003E\u003E observers = GetObserverList(_observers, key);\n            if (!_isNotifiyng)\n            {\n                if (!observers.Contains(observer))\n                {\n                    observers.Add(observer);\n                }\n            }\n            else\n            {\n                if (!observers.Contains(observer))\n                {\n                    List\u003CSystem.Action\u003CType, object\u003E\u003E addObservers = GetObserverList(_addObservers, key);\n                    if (!addObservers.Contains(observer))\n                    {\n                        addObservers.Add(observer);\n                    }\n                }\n\n                List\u003CSystem.Action\u003CType, object\u003E\u003E removeObservers = GetObserverList(_removeObservers, key);\n                if (removeObservers.Contains(observer))\n                {\n                    removeObservers.Remove(observer);\n                }\n            }\n        }\n\n        public void RemoveObserver(string key, System.Action\u003CType, object\u003E observer)\n        {\n            List\u003CSystem.Action\u003CType, object\u003E\u003E observers = GetObserverList(_observers, key);\n            if (!_isNotifiyng)\n            {\n                if (observers.Contains(observer))\n                {\n                    observers.Remove(observer);\n                }\n            }\n            else\n            {\n                List\u003CSystem.Action\u003CType, object\u003E\u003E removeObservers = GetObserverList(_removeObservers, key);\n                if (!removeObservers.Contains(observer))\n                {\n                    if (observers.Contains(observer))\n                    {\n                        removeObservers.Add(observer);\n                    }\n                }\n\n                List\u003CSystem.Action\u003CType, object\u003E\u003E addObservers = GetObserverList(_addObservers, key);\n                if (addObservers.Contains(observer))\n                {\n                    addObservers.Remove(observer);\n                }\n            }\n        }\n\n\n#if DEBUG\n        public List\u003Cstring\u003E Keys\n        {\n            get\n            {\n                if (_parentBlackboard != null)\n                {\n                    List\u003Cstring\u003E keys = this._parentBlackboard.Keys;\n                    keys.AddRange(_data.Keys);\n                    return keys;\n                }\n                else\n                {\n                    return new List\u003Cstring\u003E(_data.Keys);\n                }\n            }\n        }\n\n        public int NumObservers\n        {\n            get\n            {\n                int count = 0;\n                foreach (var key in _observers.Keys)\n                {\n                    count \u002B= _observers[key].Count;\n                }\n                return count;\n            }\n        }\n#endif\n\n\n        private void NotifiyObservers()\n        {\n            if (_notifications.Count == 0)\n            {\n                return;\n            }\n\n            _notificationsDispatch.Clear();\n            _notificationsDispatch.AddRange(_notifications);\n            foreach (Blackboard child in _children)\n            {\n                child._notifications.AddRange(_notifications);\n                child._clock.AddTimer(0f, 0, child.NotifiyObservers);\n            }\n            _notifications.Clear();\n\n            _isNotifiyng = true;\n            foreach (Notification notification in _notificationsDispatch)\n            {\n                if (!_observers.ContainsKey(notification.Key))\n                {\n                    //                Debug.Log(\u00221 do not notify for key:\u0022 \u002B notification.key \u002B \u0022 value: \u0022 \u002B notification.value);\n                    continue;\n                }\n\n                List\u003CSystem.Action\u003CType, object\u003E\u003E observers = GetObserverList(_observers, notification.Key);\n                foreach (System.Action\u003CType, object\u003E observer in observers)\n                {\n                    if (_removeObservers.TryGetValue( notification.Key, out List\u003CSystem.Action\u003CType, object\u003E\u003E value ) \u0026\u0026 value.Contains(observer))\n                    {\n                        continue;\n                    }\n                    observer(notification.Type, notification.Value);\n                }\n            }\n\n            foreach (string key in _addObservers.Keys)\n            {\n                GetObserverList(_observers, key).AddRange(_addObservers[key]);\n            }\n            foreach (string key in _removeObservers.Keys)\n            {\n                foreach (System.Action\u003CType, object\u003E action in _removeObservers[key])\n                {\n                    GetObserverList(_observers, key).Remove(action);\n                }\n            }\n            _addObservers.Clear();\n            _removeObservers.Clear();\n\n            _isNotifiyng = false;\n        }\n\n        private List\u003CSystem.Action\u003CType, object\u003E\u003E GetObserverList(Dictionary\u003Cstring, List\u003CSystem.Action\u003CType, object\u003E\u003E\u003E target, string key)\n        {\n            List\u003CSystem.Action\u003CType, object\u003E\u003E observers;\n            if (target.TryGetValue(key, out var value))\n            {\n                observers = value;\n            }\n            else\n            {\n                observers = new List\u003CSystem.Action\u003CType, object\u003E\u003E();\n                target[key] = observers;\n            }\n            return observers;\n        }\n    }\n}\n"},{"Ident":"utopia.npbehavesbox","Path":"Code/BehaviorTree/Debugger.cs","FileName":"Debugger.cs","PackageType":"library","CodeKind":"Game","AssetVersionId":72229,"Code":"using System.Collections.Generic;\nusing Sandbox;\n\nnamespace NPBehave\n{\n    public class Debugger : Component\n    {\n        public Root BehaviorTree;\n\n        private static Blackboard _customGlobalStats = null;\n        public static Blackboard CustomGlobalStats\n        {\n            get \n            {\n                if (_customGlobalStats == null)\n                {\n                    _customGlobalStats = SandboxContext.GetSharedBlackboard(\u0022_GlobalStats\u0022);;\n                }\n                return _customGlobalStats;\n            }\n        }\n\n        private Blackboard _customStats = null;\n        public Blackboard CustomStats\n        {\n            get \n            {\n                if (_customStats == null)\n                {\n                    _customStats = new Blackboard(CustomGlobalStats, SandboxContext.GetClock());\n                }\n                return _customStats;\n            }\n        }\n\n        public void DebugCounterInc(string key)\n        {\n            if (!CustomStats.IsSet(key))\n            {\n                CustomStats[key] = 0;\n            }\n            CustomStats[key] = CustomStats.Get\u003Cint\u003E(key) \u002B 1;\n        }\n\n        public void DebugCounterDec(string key)\n        {\n            if (!CustomStats.IsSet(key))\n            {\n                CustomStats[key] = 0;\n            }\n            CustomStats[key] = CustomStats.Get\u003Cint\u003E(key) - 1;\n        }\n\n        public static void GlobalDebugCounterInc(string key)\n        {\n            if (!CustomGlobalStats.IsSet(key))\n            {\n                CustomGlobalStats[key] = 0;\n            }\n            CustomGlobalStats[key] = CustomGlobalStats.Get\u003Cint\u003E(key) \u002B 1;\n        }\n\n        public static void GlobalDebugCounterDec(string key)\n        {\n            if (!CustomGlobalStats.IsSet(key))\n            {\n                CustomGlobalStats[key] = 0;\n            }\n            CustomGlobalStats[key] = CustomGlobalStats.Get\u003Cint\u003E(key) - 1;\n        }\n\n    }\n}\n"}]}