private Rule GetUpdateRule()
        {
            // Once a node is reached during pathfinding, start traveling to the next node.

            //   If the distance between the player and the current node is less than 0.4 meters away (1)
            // OR
            //   the number of nodes is 2 or greater (2), the player is between the current node and the next node (3), and the player is in line of sight of the next node (4),
            // start traveling to the next node. (5)

            Element position = Element.Part <V_PositionOf>(new V_EventPlayer());

            Rule rule = new Rule(Constants.INTERNAL_ELEMENT + "Pathfinder: Update", RuleEvent.OngoingPlayer);

            rule.Conditions = new Condition[] {
                new Condition(
                    Element.Part <V_CountOf>(Path.GetVariable()),
                    Operators.GreaterThan,
                    0
                    ),
                new Condition(
                    Element.Part <V_Or>(
                        // (1)
                        new V_Compare(
                            Element.Part <V_DistanceBetween>(
                                NextPosition(new V_EventPlayer()),
                                position
                                ),
                            Operators.LessThan,
                            new V_Number(MoveToNext)
                            ),
                        Element.Part <V_And>(
                            // (2)
                            new V_Compare(
                                Element.Part <V_CountOf>(Path.GetVariable()),
                                Operators.Equal,
                                new V_Number(2)
                                ),
                            Element.Part <V_And>(
                                // (3)
                                IsBetween(position, PositionAt(new V_EventPlayer(), 0), PositionAt(new V_EventPlayer(), 1)),
                                // (4)
                                Element.Part <V_IsInLineOfSight>(position + new V_Vector(0, 1.5, 0), PositionAt(new V_EventPlayer(), 1) + new V_Vector(0, 1.5, 0))
                                )
                            )
                        )
                    )
            };

            rule.Actions = ArrayBuilder <Element> .Build(
                LastUpdate.SetVariable(new V_TotalTimeElapsed()),

                Next(), // (5)

                DistanceToNext.SetVariable(Element.Part <V_DistanceBetween>(Element.Part <V_PositionOf>(new V_EventPlayer()), NextPosition(new V_EventPlayer()))),
                A_Wait.MinimumWait,
                new A_LoopIfConditionIsTrue()
                );

            return(rule);
        }
        private Rule GetStartRule(DeltinScript deltinScript)
        {
            var condition = new Condition(
                Element.Part <V_CountOf>(Path.GetVariable()),
                Operators.GreaterThan,
                0
                );

            Element eventPlayer    = new V_EventPlayer();
            Element eventPlayerPos = Element.Part <V_PositionOf>(eventPlayer);

            TranslateRule rule = new TranslateRule(deltinScript, Constants.INTERNAL_ELEMENT + "Pathfinder: Move", RuleEvent.OngoingPlayer);

            rule.ActionSet.AddAction(Element.Part <A_If>(
                                         Element.Part <V_And>(
                                             Element.Part <V_CountOf>(Path.GetVariable()) >= 2,
                                             IsBetween(eventPlayerPos, NextPosition(eventPlayer), PositionAt(eventPlayer, 1))
                                             )
                                         ));
            rule.ActionSet.AddAction(Next());
            rule.ActionSet.AddAction(new A_End());

            rule.ActionSet.AddAction(ArrayBuilder <Element> .Build
                                     (
                                         LastUpdate.SetVariable(new V_TotalTimeElapsed()),
                                         DistanceToNext.SetVariable(Element.Part <V_DistanceBetween>(Element.Part <V_PositionOf>(new V_EventPlayer()), NextPosition(new V_EventPlayer()))),
                                         // Element.Part<A_StartFacing>(
                                         //     new V_EventPlayer(),
                                         //     Element.Part<V_DirectionTowards>(
                                         //         new V_EyePosition(),
                                         //         NextPosition()
                                         //     ),
                                         //     new V_Number(700),
                                         //     EnumData.GetEnumValue(Relative.ToWorld),
                                         //     EnumData.GetEnumValue(FacingRev.DirectionAndTurnRate)
                                         // ),

                                         // Move to the next node.
                                         Element.Part <A_StartThrottleInDirection>(
                                             new V_EventPlayer(),
                                             Element.Part <V_DirectionTowards>(
                                                 new V_EyePosition(),
                                                 NextPosition(new V_EventPlayer()) // Because of ThrottleRev this will be reevaluated so 'Start Throttle In Direction' only needs to run once.
                                                 ),
                                             new V_Number(1),
                                             EnumData.GetEnumValue(Relative.ToWorld),
                                             EnumData.GetEnumValue(ThrottleBehavior.ReplaceExistingThrottle),
                                             EnumData.GetEnumValue(ThrottleRev.DirectionAndMagnitude)
                                             )
                                     ));

            var result = rule.GetRule();

            result.Conditions = new Condition[] { condition };
            return(result);
        }