Ejemplo n.º 1
0
        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);

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

            isBetween.Setup();
            rule.ActionSet.AddAction(Next());
            isBetween.Finish();

            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);
        }
        public void Get()
        {
            var firstNode = ClosestNodeToPosition(Nodes, position);

            Assign();

            current = actionSet.VarCollection.Assign("Dijkstra: Current", actionSet.IsGlobal, true);
            IndexReference distances = actionSet.VarCollection.Assign("Dijkstra: Distances", actionSet.IsGlobal, false);

            unvisited = actionSet.VarCollection.Assign("Dijkstra: Unvisited", actionSet.IsGlobal, false);
            IndexReference connectedSegments = actionSet.VarCollection.Assign("Dijkstra: Connected Segments", actionSet.IsGlobal, true);
            IndexReference neighborIndex     = actionSet.VarCollection.Assign("Dijkstra: Neighbor Index", actionSet.IsGlobal, true);
            IndexReference neighborDistance  = actionSet.VarCollection.Assign("Dijkstra: Distance", actionSet.IsGlobal, true);

            parentArray = actionSet.VarCollection.Assign("Dijkstra: Parent Array", actionSet.IsGlobal, false);

            // Set the current variable as the first node.
            actionSet.AddAction(current.SetVariable(firstNode));
            SetInitialDistances(actionSet, distances, (Element)current.GetVariable());
            SetInitialUnvisited(actionSet, Nodes, unvisited);

            WhileBuilder whileBuilder = new WhileBuilder(actionSet, LoopCondition());

            whileBuilder.Setup();

            // Get neighboring indexes
            actionSet.AddAction(connectedSegments.SetVariable(GetConnectedSegments(
                                                                  Nodes,
                                                                  Segments,
                                                                  (Element)current.GetVariable(),
                                                                  reversed
                                                                  )));

            // Loop through neighboring indexes
            ForeachBuilder forBuilder = new ForeachBuilder(actionSet, connectedSegments.GetVariable());

            forBuilder.Setup();

            actionSet.AddAction(ArrayBuilder <Element> .Build(
                                    // Get the index from the segment data
                                    neighborIndex.SetVariable(
                                        Element.TernaryConditional(
                                            new V_Compare(
                                                current.GetVariable(),
                                                Operators.NotEqual,
                                                Node1(forBuilder.IndexValue)
                                                ),
                                            Node1(forBuilder.IndexValue),
                                            Node2(forBuilder.IndexValue)
                                            )
                                        ),

                                    // Get the distance between the current and the neighbor index.
                                    neighborDistance.SetVariable(
                                        Element.Part <V_DistanceBetween>(
                                            Nodes[(Element)neighborIndex.GetVariable()],
                                            Nodes[(Element)current.GetVariable()]
                                            ) + ((Element)distances.GetVariable())[(Element)current.GetVariable()]
                                        )
                                    ));

            // Set the current neighbor's distance if the new distance is less than what it is now.
            IfBuilder ifBuilder = new IfBuilder(actionSet,
                                                (Element)neighborDistance.GetVariable()
                                                <
                                                WorkingDistance((Element)distances.GetVariable(), (Element)neighborIndex.GetVariable())
                                                );

            ifBuilder.Setup();

            actionSet.AddAction(distances.SetVariable((Element)neighborDistance.GetVariable(), null, (Element)neighborIndex.GetVariable()));
            actionSet.AddAction(parentArray.SetVariable((Element)current.GetVariable() + 1, null, (Element)neighborIndex.GetVariable()));

            ifBuilder.Finish();
            forBuilder.Finish();

            actionSet.AddAction(ArrayBuilder <Element> .Build(
                                    // Add the current to the visited array.
                                    unvisited.SetVariable(Element.Part <V_RemoveFromArray>(unvisited.GetVariable(), current.GetVariable())),

                                    // Set the current node as the smallest unvisited.
                                    current.SetVariable(LowestUnvisited(Nodes, (Element)distances.GetVariable(), (Element)unvisited.GetVariable()))
                                    ));

            whileBuilder.Finish();

            GetResult();

            actionSet.AddAction(ArrayBuilder <Element> .Build(
                                    current.SetVariable(-1),
                                    distances.SetVariable(-1),
                                    connectedSegments.SetVariable(-1),
                                    neighborIndex.SetVariable(-1),
                                    neighborDistance.SetVariable(-1),
                                    parentArray.SetVariable(-1)
                                    ));

            Reset();
        }