Пример #1
0
        public override IWorkshopTree Get(ActionSet actionSet, IWorkshopTree[] parameterValues)
        {
            // Setup the continue skip.
            ContinueSkip continueSkip = actionSet.ContinueSkip;

            continueSkip.Setup(actionSet);

            IndexReference result = actionSet.VarCollection.Assign($"_conditionTestResult", actionSet.IsGlobal, true);

            continueSkip.SetSkipCount(actionSet, continueSkip.GetSkipCount(actionSet) + 3);
            actionSet.AddAction(ArrayBuilder <Element> .Build(
                                    // This will continue at (0) if the rule loops.
                                    new A_LoopIfConditionIsFalse(),
                                    // Set the result to true.
                                    result.SetVariable(new V_True()),
                                    Element.Part <A_Skip>(new V_Number(1)),

                                    // The rule will loop back here (0) if false.
                                    result.SetVariable(new V_False())
                                    ));
            continueSkip.ResetSkipCount(actionSet);

            if (TestingIfTrue)
            {
                return(result.GetVariable());
            }
            else
            {
                return(Element.Part <V_Not>(result.GetVariable()));
            }
        }
Пример #2
0
        public override IWorkshopTree Get(ActionSet actionSet, IWorkshopTree[] parameterValues)
        {
            if (parameterValues[0] is V_Number n)
            {
                V_Number[] indexes = new V_Number[n.Value < 0 ? 0 : (int)n.Value];
                for (int i = 0; i < indexes.Length; i++)
                {
                    indexes[i] = new V_Number(i);
                }
                return(Element.CreateArray(indexes));
            }
            else
            {
                IndexReference array  = actionSet.VarCollection.Assign("_foreachArrayBuilder", actionSet.IsGlobal, false);
                IndexReference length = actionSet.VarCollection.Assign("_foreachArrayBuilderLength", actionSet.IsGlobal, true);
                IndexReference i      = actionSet.VarCollection.Assign("_foreachArrayBuilderIndex", actionSet.IsGlobal, true);

                actionSet.AddAction(ArrayBuilder <Element> .Build(
                                        length.SetVariable((Element)parameterValues[0]),
                                        array.SetVariable(new V_EmptyArray()),
                                        i.SetVariable(0),
                                        Element.Part <A_While>((Element)i.GetVariable() < (Element)length.GetVariable()),
                                        array.SetVariable((Element)i.GetVariable(), null, (Element)i.GetVariable()),
                                        i.ModifyVariable(Operation.Add, 1),
                                        new A_End()
                                        ));

                return(array.GetVariable());
            }
        }
        public void EndRecursiveLoop()
        {
            // Pop the object store array.
            if (_builder.Controller.Attributes.IsInstance)
            {
                actionSet.AddAction(_objectStore.ModifyVariable(Operation.RemoveFromArrayByIndex, Element.CountOf(_objectStore.GetVariable()) - 1));
            }

            // Pop the parameters.
            _builder.ParameterHandler.Pop(_builder.ActionSet);

            // Restart the method from the specified position if there are any elements in the continue array.
            actionSet.AddAction(Element.SkipIf(Element.Compare(
                                                   Element.CountOf(_continueArray.GetVariable()),
                                                   Operator.Equal,
                                                   Element.Num(0)
                                                   ), Element.Num(3)));

            // Store the next continue and pop the continue array.
            actionSet.AddAction(_nextContinue.SetVariable(Element.LastOf(_continueArray.GetVariable())));
            actionSet.AddAction(_continueArray.ModifyVariable(Operation.RemoveFromArrayByIndex, Element.CountOf(_continueArray.GetVariable()) - 1));

            // Mark the end of the method.
            actionSet.AddAction(_endOfMethod);
            actionSet.AddAction(Element.End());

            // Reset nextContinue.
            actionSet.AddAction(_nextContinue.SetVariable(0));
        }
 override protected Element LoopCondition()
 {
     return(Element.Part <V_ArrayContains>(
                unvisited.GetVariable(),
                finalNode.GetVariable()
                ));
 }
 override protected Element LoopCondition()
 {
     return(Element.Part <V_IsTrueForAny>(
                closestNodesToPlayers.GetVariable(),
                Element.Part <V_ArrayContains>(
                    unvisited.GetVariable(),
                    new V_ArrayElement()
                    )
                ));
 }
Пример #6
0
        protected IWorkshopTree RenderModel(ActionSet actionSet, Model model, Element visibleTo, Element location, Element rotation, Element scale, IWorkshopTree reevaluation, bool getEffectIDs)
        {
            IndexReference effects = null;

            if (getEffectIDs)
            {
                effects = actionSet.VarCollection.Assign("_modelEffects", actionSet.IsGlobal, true);
                actionSet.AddAction(effects.SetVariable(new V_EmptyArray()));
            }

            for (int i = 0; i < model.Lines.Length; i++)
            {
                CreateLine(actionSet, model.Lines[i], visibleTo, location, rotation, scale, reevaluation);

                // Get the last created effect and append it to the store array.
                if (effects != null)
                {
                    actionSet.AddAction(effects.ModifyVariable(Operation.AppendToArray, new V_LastCreatedEntity()));
                }

                // Add a wait every 12 effects to prevent high server load.
                if (i % 10 == 0)
                {
                    actionSet.AddAction(A_Wait.MinimumWait);
                }
            }

            return(effects?.GetVariable());
        }
Пример #7
0
        private void SetInitialUnvisited()
        {
            // Create an array counting up to the number of values in the nodeArray array.
            // For example, if nodeArray has 6 variables unvisitedVar will be set to [0, 1, 2, 3, 4, 5].

            // Empty the unvisited array.
            actionSet.AddAction(unvisited.SetVariable(new V_EmptyArray()));

            IndexReference current = actionSet.VarCollection.Assign("unvisitedBuilder", actionSet.IsGlobal, assignExtended);

            actionSet.AddAction(current.SetVariable(0));

            // While current < the count of the node array.
            actionSet.AddAction(Element.Part <A_While>((Element)current.GetVariable() < Element.Part <V_CountOf>(Nodes)));

            // If there can be null nodes, make sure the node is not null.
            if (resolveInfo.PotentiallyNullNodes)
            {
                actionSet.AddAction(Element.Part <A_If>(new V_Compare(Nodes[current.Get()], Operators.NotEqual, new V_Null())));
            }

            actionSet.AddAction(unvisited.ModifyVariable(Operation.AppendToArray, (Element)current.GetVariable()));

            // End the if.
            if (resolveInfo.PotentiallyNullNodes)
            {
                actionSet.AddAction(new A_End());
            }

            actionSet.AddAction(current.ModifyVariable(Operation.Add, 1));

            // End the while.
            actionSet.AddAction(new A_End());
        }
Пример #8
0
 protected override void EndLoop()
 {
     actionSet.AddAction(chosenDestination.SetVariable(Element.Part <V_IndexOfArrayValue>(potentialDestinations.GetVariable(), current.GetVariable())));
     actionSet.AddAction(Element.Part <A_If>(new V_Compare(chosenDestination.GetVariable(), Operators.NotEqual, new V_Number(-1))));
     actionSet.AddAction(Element.Part <A_Break>());
     actionSet.AddAction(Element.Part <A_End>());
 }
        private static Element ContainParameter(ActionSet actionSet, string name, IWorkshopTree value)
        {
            IndexReference containParameter = actionSet.VarCollection.Assign(name, actionSet.IsGlobal, true);

            actionSet.AddAction(containParameter.SetVariable((Element)value));
            return((Element)containParameter.GetVariable());
        }
        protected override void New(ActionSet actionSet, NewClassInfo newClassInfo)
        {
            Element index = (Element)newClassInfo.ObjectReference.GetVariable();

            if (newClassInfo.AdditionalParameterData.Length > 0)
            {
                // Get the pathmap data.
                PathMap pathMap = (PathMap)newClassInfo.AdditionalParameterData[0];

                IndexReference nodes    = actionSet.VarCollection.Assign("_tempNodes", actionSet.IsGlobal, false);
                IndexReference segments = actionSet.VarCollection.Assign("_tempSegments", actionSet.IsGlobal, false);

                actionSet.AddAction(nodes.SetVariable(new V_EmptyArray()));
                actionSet.AddAction(segments.SetVariable(new V_EmptyArray()));

                foreach (var node in pathMap.Nodes)
                {
                    actionSet.AddAction(nodes.ModifyVariable(operation: Operation.AppendToArray, value: node.ToVector()));
                }
                foreach (var segment in pathMap.Segments)
                {
                    actionSet.AddAction(segments.ModifyVariable(operation: Operation.AppendToArray, value: segment.AsWorkshopData()));
                }

                actionSet.AddAction(Nodes.SetVariable((Element)nodes.GetVariable(), index: index));
                actionSet.AddAction(Segments.SetVariable((Element)segments.GetVariable(), index: index));
            }
            else
            {
                actionSet.AddAction(Nodes.SetVariable(new V_EmptyArray(), index: index));
                actionSet.AddAction(Segments.SetVariable(new V_EmptyArray(), index: index));
            }
        }
        /// <summary>Looks at a player's future nodes.</summary>
        public Element IsTravelingToNode(ActionSet actionSet, Element targetPlayer, Element node)
        {
            IndexReference result = actionSet.VarCollection.Assign("Lookahead: Result", actionSet.IsGlobal, true);

            actionSet.AddAction(result.SetVariable(new V_False()));

            IndexReference look = actionSet.VarCollection.Assign("Pathfind: Lookahead", actionSet.IsGlobal, true);

            actionSet.AddAction(look.SetVariable(Current.Get(targetPlayer)));

            // Get the path.
            actionSet.AddAction(Element.Part <A_While>(Element.Part <V_And>(new V_Compare(
                                                                                look.GetVariable(),
                                                                                Operators.GreaterThanOrEqual,
                                                                                new V_Number(0)
                                                                                ), !result.Get())));

            //Element currentNode = PathmapInstance.Nodes.Get()[PathmapReference.Get(targetPlayer)][look.Get()];

            actionSet.AddAction(result.SetVariable(new V_Compare(look.Get(), Operators.Equal, node)));

            actionSet.AddAction(look.SetVariable(ParentArray.Get(targetPlayer)[look.Get()] - 1));
            actionSet.AddAction(new A_End());

            return(result.Get());
        }
Пример #12
0
        protected override void GetResult()
        {
            /*
             |  |
             +--+--+--+
             |
             */

            IndexReference newParentArray = actionSet.VarCollection.Assign("Pathfinder: New parent array", actionSet.IsGlobal, false);

            // Flip the parent array.
            IndexReference backTracker = actionSet.VarCollection.Assign("Pathfinder: Backtracker", actionSet.IsGlobal, assignExtended);

            actionSet.AddAction(backTracker.SetVariable(current.Get()));

            // Get the path.
            actionSet.AddAction(Element.Part <A_While>(new V_Compare(
                                                           backTracker.GetVariable(),
                                                           Operators.GreaterThanOrEqual,
                                                           new V_Number(0)
                                                           )));

            Element next = parentArray.Get()[backTracker.Get()] - 1;

            actionSet.AddAction(newParentArray.SetVariable(index: next, value: backTracker.Get() + 1));

            actionSet.AddAction(backTracker.SetVariable(next));
            actionSet.AddAction(A_Wait.MinimumWait); // TODO: Should there be a minwait here?
            actionSet.AddAction(new A_End());

            actionSet.AddAction(parentArray.SetVariable(newParentArray.Get()));

            resolveInfo.Pathfind(actionSet, player, pathmapObject, parentArray.Get(), parentAttributeInfo.Get(), Nodes[current.Get()]);
        }
Пример #13
0
        public override IWorkshopTree Get(ActionSet actionSet, IWorkshopTree[] parameterValues)
        {
            if (parameterValues[0] is V_Array ar)
            {
                if (ar.ParameterValues.All(element => element is V_Number))
                {
                    return(new V_Number(ar.ParameterValues.Average(element => ((V_Number)element).Value)));
                }
                else if (ar.ParameterValues.All(element => ((Element)element).ConstantSupported <Vertex>()))
                {
                    Vertex sum_ = new Vertex();
                    foreach (IWorkshopTree vert in ar.ParameterValues)
                    {
                        sum_ += (Vertex)((Element)vert).GetConstant();
                    }
                    return((sum_ / ar.ParameterValues.Length).ToVector());
                }
                else
                {
                    Element sum_ = (Element)ar.ParameterValues[0];
                    for (int i = 1; i < ar.ParameterValues.Length; i++)
                    {
                        sum_ += (Element)ar.ParameterValues[i];
                    }
                    return(sum_ / ar.ParameterValues.Length);
                }
            }
            else if (parameterValues[0] is V_EmptyArray)
            {
                return(new V_Number(0));
            }
            else
            {
                IndexReference array = actionSet.VarCollection.Assign("_arrayToAverage", actionSet.IsGlobal, true);
                IndexReference sum   = actionSet.VarCollection.Assign("_sumOfAverageArray", actionSet.IsGlobal, true);

                actionSet.AddAction(array.SetVariable((Element)parameterValues[0]));
                actionSet.AddAction(sum.SetVariable(0));
                ForeachBuilder builder = new ForeachBuilder(actionSet, array.GetVariable());
                actionSet.AddAction(sum.ModifyVariable(Operation.Add, builder.IndexValue));
                builder.Finish();
                return((Element)sum.GetVariable() / Element.Part <V_CountOf>(array.GetVariable()));
            }
        }
        public void StartRecursiveLoop()
        {
            // Create the recursive loop.
            actionSet.AddAction(Element.While(Element.True()));

            // Create the continue skip action.
            _continueAt = new SkipStartMarker(actionSet);
            _continueAt.SetSkipCount((Element)_nextContinue.GetVariable());
            actionSet.AddAction(_continueAt);
        }
Пример #15
0
        public override IWorkshopTree Get(ActionSet actionSet, IWorkshopTree[] parameterValues, object[] additionalParameterData)
        {
            Element player = (Element)parameterValues[0];

            IndexReference originalHero = actionSet.VarCollection.Assign("isAI_originalHero", actionSet.IsGlobal, true);
            IndexReference isAI         = actionSet.VarCollection.Assign("isAI_originalHero", actionSet.IsGlobal, true);

            actionSet.AddAction(ArrayBuilder <Element> .Build
                                (
                                    originalHero.SetVariable(Element.Part <V_HeroOf>(player)),
                                    Element.Part <A_SkipIf>(Element.Part <V_Compare>(originalHero.GetVariable(), EnumData.GetEnumValue(Operators.NotEqual), new V_Null()), new V_Number(2)),
                                    isAI.SetVariable(new V_False()),
                                    Element.Part <A_Skip>(new V_Number(4)),
                                    Element.Part <A_ForcePlayerHero>(player, EnumData.GetEnumValue(Hero.Ashe)),
                                    isAI.SetVariable(Element.Part <V_Compare>(Element.Part <V_HeroOf>(player), EnumData.GetEnumValue(Operators.NotEqual), EnumData.GetEnumValue(Hero.Ashe))),
                                    Element.Part <A_ForcePlayerHero>(player, originalHero.GetVariable()),
                                    Element.Part <A_StopForcingHero>(player)
                                ));

            return(isAI.GetVariable());
        }
Пример #16
0
 protected override Element LoopCondition()
 {
     if (Destination == null)
     {
         return(Element.Part <V_CountOf>(unvisited.GetVariable()) > 0);
     }
     else
     {
         return(Element.Part <V_ArrayContains>(
                    unvisited.GetVariable(),
                    finalNode.GetVariable()
                    ));
     }
 }
        public override IWorkshopTree Get(ActionSet actionSet, IWorkshopTree[] parameterValues)
        {
            IndexReference destinationStore = actionSet.VarCollection.Assign("_pathfindDestinationStore", actionSet.IsGlobal, true);

            actionSet.AddAction(destinationStore.SetVariable((Element)parameterValues[1]));

            DijkstraNormal algorithm = new DijkstraNormal(
                actionSet, (Element)actionSet.CurrentObject, (Element)parameterValues[0], (Element)destinationStore.GetVariable()
                );

            algorithm.Get();

            return(Element.Part <V_Append>(algorithm.finalPath.GetVariable(), destinationStore.GetVariable()));
        }
        override protected void Assign()
        {
            closestNodesToPlayers = actionSet.VarCollection.Assign("Dijkstra: Closest nodes", actionSet.IsGlobal, false);
            actionSet.AddAction(closestNodesToPlayers.SetVariable(Element.Part <V_EmptyArray>()));

            ForeachBuilder getClosestNodes = new ForeachBuilder(actionSet, players);

            actionSet.AddAction(closestNodesToPlayers.SetVariable(
                                    Element.Part <V_Append>(
                                        closestNodesToPlayers.GetVariable(),
                                        ClosestNodeToPosition(Nodes, getClosestNodes.IndexValue)
                                        )
                                    ));

            getClosestNodes.Finish();
        }
        public void Init()
        {
            // Create the array used for continuing after a recursive call.
            _continueArray = varCollection.Assign("_" + name + "_recursiveContinue", isGlobal, false);
            _nextContinue  = varCollection.Assign("_" + name + "_nextContinue", isGlobal, true);
            actionSet.InitialSet().AddAction(_continueArray.SetVariable(Element.EmptyArray()));

            if (_builder.Controller.Attributes.RecursiveRequiresObjectStack)
            {
                _objectStore = varCollection.Assign("_" + name + "_objectStack", isGlobal, false);
                actionSet.AddAction(_objectStore.SetVariable(Element.CreateArray(actionSet.CurrentObject)));

                _builder.ModifySet(actionSet => actionSet.New(Element.LastOf(_objectStore.GetVariable())).PackThis());
            }
            _builder.ModifySet(actionSet => actionSet.New(true));
        }
        protected void Backtrack(Element destination, IndexReference finalPath)
        {
            actionSet.AddAction(current.SetVariable(destination));
            actionSet.AddAction(finalPath.SetVariable(new V_EmptyArray()));

            // Get the path.
            actionSet.AddAction(Element.Part <A_While>(new V_Compare(
                                                           current.GetVariable(),
                                                           Operators.GreaterThanOrEqual,
                                                           new V_Number(0)
                                                           )));

            // !WAIT actionSet.AddAction(A_Wait.MinimumWait);

            Element next  = Nodes[(Element)current.GetVariable()];
            Element array = (Element)finalPath.GetVariable();
            Element first;
            Element second;

            if (!reversed)
            {
                first  = next;
                second = array;
            }
            else
            {
                first  = array;
                second = next;
            }

            // For debugging generated path.
            // actionSet.AddAction(Element.Part<A_CreateEffect>(
            //     Element.Part<V_AllPlayers>(),
            //     EnumData.GetEnumValue(Effect.Orb),
            //     EnumData.GetEnumValue(Color.SkyBlue),
            //     next,
            //     new V_Number(0.5),
            //     EnumData.GetEnumValue(EffectRev.VisibleTo)
            // ));

            actionSet.AddAction(ArrayBuilder <Element> .Build(
                                    finalPath.SetVariable(Element.Part <V_Append>(first, second)),
                                    current.SetVariable(Element.Part <V_ValueInArray>(parentArray.GetVariable(), current.GetVariable()) - 1)
                                    ));
            actionSet.AddAction(new A_End());
        }
        override protected void GetResult()
        {
            ForeachBuilder assignPlayerPaths = new ForeachBuilder(actionSet, players);

            assignPlayerPaths.Setup();

            IndexReference finalPath = actionSet.VarCollection.Assign("Dijkstra: Final Path", actionSet.IsGlobal, false);

            Backtrack(
                Element.Part <V_ValueInArray>(
                    closestNodesToPlayers.GetVariable(),
                    assignPlayerPaths.Index
                    ),
                finalPath
                );
            Pathfind(actionSet, pathfinderInfo, (Element)finalPath.GetVariable(), assignPlayerPaths.IndexValue, position);
            assignPlayerPaths.Finish();
        }
        private static void SetInitialUnvisited(ActionSet actionSet, Element nodeArray, IndexReference unvisitedVar)
        {
            // Create an array counting up to the number of values in the nodeArray array.
            // For example, if nodeArray has 6 variables unvisitedVar will be set to [0, 1, 2, 3, 4, 5].

            // Empty the unvisited array.
            actionSet.AddAction(unvisitedVar.SetVariable(new V_EmptyArray()));

            IndexReference current = actionSet.VarCollection.Assign("unvisitedBuilder", actionSet.IsGlobal, true);

            actionSet.AddAction(current.SetVariable(0));

            WhileBuilder unvisitedBuilder = new WhileBuilder(actionSet, (Element)current.GetVariable() < Element.Part <V_CountOf>(nodeArray));

            unvisitedBuilder.Setup();

            actionSet.AddAction(unvisitedVar.ModifyVariable(Operation.AppendToArray, (Element)current.GetVariable()));

            actionSet.AddAction(current.ModifyVariable(Operation.Add, 1));
            unvisitedBuilder.Finish();
        }
Пример #23
0
        protected IWorkshopTree RenderText(
            ActionSet actionSet,
            string text, FontFamily font, double quality,
            Element visibleTo, Element location, Element rotation, Element scale, IWorkshopTree effectRev, bool getIds, double angleRound)
        {
            quality = Math.Max(10 - quality, 0.1);

            Model model = Model.ImportString(text, font, quality, angleRound);

            IndexReference effects = null;

            if (getIds)
            {
                effects = actionSet.VarCollection.Assign("_modelEffects", actionSet.IsGlobal, true);
                actionSet.AddAction(effects.SetVariable(new V_EmptyArray()));
            }

            RenderModel(actionSet, model, visibleTo, location, rotation, scale, effectRev, getIds);

            return(effects?.GetVariable());
        }
        protected void Backtrack(Element destination, IndexReference finalPath)
        {
            actionSet.AddAction(current.SetVariable(destination));
            actionSet.AddAction(finalPath.SetVariable(new V_EmptyArray()));

            // Get the path.
            WhileBuilder backtrack = new WhileBuilder(actionSet, new V_Compare(
                                                          current.GetVariable(),
                                                          Operators.NotEqual,
                                                          new V_Number(-1)
                                                          ));

            backtrack.Setup();

            Element next  = Nodes[(Element)current.GetVariable()];
            Element array = (Element)finalPath.GetVariable();
            Element first;
            Element second;

            if (!reversed)
            {
                first  = next;
                second = array;
            }
            else
            {
                first  = array;
                second = next;
            }

            actionSet.AddAction(ArrayBuilder <Element> .Build(
                                    finalPath.SetVariable(Element.Part <V_Append>(first, second)),
                                    current.SetVariable(Element.Part <V_ValueInArray>(parentArray.GetVariable(), current.GetVariable()) - 1)
                                    ));
            backtrack.Finish();
        }
Пример #25
0
        public void Get()
        {
            var firstNode = GetClosestNode(actionSet, Nodes, Source);

            Assign();

            current   = actionSet.VarCollection.Assign("Dijkstra: Current", actionSet.IsGlobal, assignExtended);
            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, assignExtended);
            IndexReference neighborIndex     = actionSet.VarCollection.Assign("Dijkstra: Neighbor Index", actionSet.IsGlobal, assignExtended);
            IndexReference neighborDistance  = actionSet.VarCollection.Assign("Dijkstra: Distance", actionSet.IsGlobal, assignExtended);

            parentArray = GetParentArray();
            if (useAttributes)
            {
                parentAttributeInfo = GetParentAttributeArray();
            }

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

            actionSet.AddAction(Element.Part <A_While>(LoopCondition()));

            // Invoke LoopStart
            OnLoop.Invoke(actionSet);

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

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

            // Invoke OnConnectLoop
            OnConnectLoop.Invoke(actionSet);

            actionSet.AddAction(ArrayBuilder <Element> .Build(
                                    // Get the index from the segment data
                                    neighborIndex.SetVariable(
                                        Element.Part <V_FirstOf>(Element.Part <V_FilteredArray>(
                                                                     BothNodes(forBuilder.IndexValue),
                                                                     new V_Compare(
                                                                         new V_ArrayElement(),
                                                                         Operators.NotEqual,
                                                                         current.GetVariable()
                                                                         )
                                                                     ))
                                        ),

                                    // 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.
            actionSet.AddAction(Element.Part <A_If>(Element.Part <V_Or>(
                                                        new V_Compare(
                                                            ((Element)distances.GetVariable())[(Element)neighborIndex.GetVariable()],
                                                            Operators.Equal,
                                                            new V_Number(0)
                                                            ),
                                                        (Element)neighborDistance.GetVariable() < ((Element)distances.GetVariable())[(Element)neighborIndex.GetVariable()]
                                                        )));

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

            if (useAttributes)
            {
                if (!reverseAttributes)
                {
                    actionSet.AddAction(parentAttributeInfo.SetVariable(
                                            value: Element.TernaryConditional(
                                                new V_Compare(
                                                    current.GetVariable(),
                                                    Operators.Equal,
                                                    Node1(forBuilder.IndexValue)
                                                    ),
                                                Node2Attribute(forBuilder.IndexValue),
                                                Node1Attribute(forBuilder.IndexValue)
                                                ),
                                            index: neighborIndex.Get()
                                            ));
                }
                else
                {
                    actionSet.AddAction(parentAttributeInfo.SetVariable(
                                            value: Element.TernaryConditional(
                                                new V_Compare(
                                                    current.GetVariable(),
                                                    Operators.Equal,
                                                    Node1(forBuilder.IndexValue)
                                                    ),
                                                Node1Attribute(forBuilder.IndexValue),
                                                Node2Attribute(forBuilder.IndexValue)
                                                ),
                                            index: neighborIndex.Get()
                                            ));
                }
            }

            // End the if.
            actionSet.AddAction(new A_End());
            // End the for.
            forBuilder.Finish();

            // Remove the current node from the unvisited array.
            actionSet.AddAction(unvisited.ModifyVariable(Operation.RemoveFromArrayByValue, (Element)current.GetVariable()));
            EndLoop();
            actionSet.AddAction(current.SetVariable(LowestUnvisited(Nodes, (Element)distances.GetVariable(), (Element)unvisited.GetVariable())));

            actionSet.AddAction(new A_End());

            GetResult();

            actionSet.AddAction(ArrayBuilder <Element> .Build(
                                    current.SetVariable(0),
                                    distances.SetVariable(0),
                                    connectedSegments.SetVariable(0),
                                    neighborIndex.SetVariable(0),
                                    neighborDistance.SetVariable(0),
                                    parentArray.SetVariable(0),
                                    parentAttributeInfo.SetVariable(0)
                                    ));
        }
Пример #26
0
        protected void Backtrack(Element startNode, IndexReference finalPath, IndexReference finalPathAttributes, bool reversePath = false)
        {
            actionSet.AddAction(current.SetVariable(startNode));
            actionSet.AddAction(finalPath.SetVariable(new V_EmptyArray()));

            // Get the path.
            actionSet.AddAction(Element.Part <A_While>(new V_Compare(
                                                           current.GetVariable(),
                                                           Operators.GreaterThanOrEqual,
                                                           new V_Number(0)
                                                           )));

            Element nextNode      = Nodes[(Element)current.GetVariable()];
            Element nextAttribute = ((Element)parentAttributeInfo.GetVariable())[(Element)current.GetVariable()];

            // For debugging generated path.
            // actionSet.AddAction(Element.Part<A_CreateEffect>(
            //     Element.Part<V_AllPlayers>(),
            //     EnumData.GetEnumValue(Effect.Orb),
            //     EnumData.GetEnumValue(Color.SkyBlue),
            //     next,
            //     new V_Number(0.5),
            //     EnumData.GetEnumValue(EffectRev.VisibleTo)
            // ));

            if (!reversePath)
            {
                // Add the current node to the final path.
                actionSet.AddAction(finalPath.ModifyVariable(Operation.AppendToArray, nextNode));
                // Add the current attribute to the final path attributes.
                if (useAttributes)
                {
                    actionSet.AddAction(finalPathAttributes.ModifyVariable(Operation.AppendToArray, nextAttribute));
                }
            }
            else
            {
                // Insert the current node to the final path.
                actionSet.AddAction(finalPath.SetVariable(Element.Part <V_Append>(nextNode, finalPath.GetVariable())));
                // Insert the current attribute to the final path attributes.
                actionSet.AddAction(finalPathAttributes.SetVariable(Element.Part <V_Append>(nextAttribute, finalPathAttributes.GetVariable())));
            }

            actionSet.AddAction(current.SetVariable(Element.Part <V_ValueInArray>(parentArray.GetVariable(), current.GetVariable()) - 1));
            actionSet.AddAction(new A_End());
        }
        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();
        }
        public SubroutineCatalogItem Initiate()
        {
            // Setup the subroutine element.
            Subroutine subroutine = _deltinScript.SubroutineCollection.NewSubroutine(_context.ElementName);

            // Create the rule.
            _subroutineRule = new TranslateRule(_deltinScript, subroutine, _context.RuleName, _context.VariableGlobalDefault);

            // Setup the return handler.
            _actionSet = _subroutineRule.ActionSet
                         .ContainVariableAssigner()
                         .SetThisTypeLinker(_context.TypeLinker)
                         .New(_context.Controller.Attributes.IsRecursive);

            // Create the function builder.
            var controller = _context.Controller;

            // Create the parameter handlers.
            _parameterHandler = controller.CreateParameterHandler(_actionSet, null);

            // If the subroutine is an object function inside a class, create a variable to store the class object.
            if (controller.Attributes.IsInstance)
            {
                _objectStore = _actionSet.VarCollection.Assign(_context.ObjectStackName, true, !controller.Attributes.IsRecursive);

                // Set the objectStore as an empty array if the subroutine is recursive.
                if (controller.Attributes.IsRecursive)
                {
                    // Initialize as empty array.
                    _actionSet.InitialSet().AddAction(_objectStore.SetVariable(Element.EmptyArray()));

                    // Add to assigner with the last of the objectStore stack being the object instance.
                    _context.ContainingType?.AddObjectVariablesToAssigner(_actionSet.ToWorkshop, Element.LastOf(_objectStore.GetVariable()), _actionSet.IndexAssigner);

                    // Set the actionSet.
                    _actionSet = _actionSet.New(Element.LastOf(_objectStore.Get())).PackThis().New(_objectStore.CreateChild(Element.CountOf(_objectStore.Get()) - 1));
                }
                else
                {
                    // Add to assigner with the objectStore being the object instance.
                    _context.ContainingType?.AddObjectVariablesToAssigner(_actionSet.ToWorkshop, _objectStore.GetVariable(), _actionSet.IndexAssigner);

                    // Set the actionSet.
                    _actionSet = _actionSet.New(_objectStore.Get()).PackThis().New(_objectStore);
                }
            }

            _functionBuilder = new WorkshopFunctionBuilder(_actionSet, controller);
            _functionBuilder.ModifySet(a => a.PackThis()); // TODO: is this required?
            _functionBuilder.SetupReturnHandler();
            _parameterHandler.AddParametersToAssigner(_actionSet.IndexAssigner);

            // Done.
            return(Result = new SubroutineCatalogItem(
                       subroutine: subroutine,
                       parameterHandler: _parameterHandler,
                       objectStack: _objectStore,
                       returnHandler: _functionBuilder.ReturnHandler));
        }
        public void Complete()
        {
            _functionBuilder.Controller.Build(_functionBuilder.ActionSet);
            _functionBuilder.ReturnHandler?.ApplyReturnSkips();

            if (_context.Controller.Attributes.IsRecursive)
            {
                _parameterHandler.Pop(_actionSet);

                // Pop object array.
                if (_context.Controller.Attributes.IsInstance)
                {
                    _actionSet.AddAction(_objectStore.ModifyVariable(Operation.RemoveFromArrayByIndex, Element.CountOf(_objectStore.GetVariable()) - 1));
                }
            }

            // Add the subroutine.
            Rule translatedRule = _subroutineRule.GetRule();

            _deltinScript.WorkshopRules.Add(translatedRule);
        }
        public override IWorkshopTree Get(ActionSet actionSet, IWorkshopTree[] parameterValues)
        {
            IndexReference destinationStore = actionSet.VarCollection.Assign("_pathfindDestinationStore", actionSet.IsGlobal, true);

            actionSet.AddAction(destinationStore.SetVariable((Element)parameterValues[1]));

            DijkstraMultiSource algorithm = new DijkstraMultiSource(
                actionSet, actionSet.Translate.DeltinScript.SetupPathfinder(), (Element)actionSet.CurrentObject, (Element)parameterValues[0], (Element)destinationStore.GetVariable()
                );

            algorithm.Get();

            return(null);
        }