public ScopeGroup GetRootScope(IndexedVar var, ParsingData parseData, Element target = null)
        {
            if (target == null)
            {
                target = new V_EventPlayer();
            }

            IndexedVar root = GetRoot(var, parseData, target);

            root.DefaultTarget = target;

            ScopeGroup typeScope = new ScopeGroup(parseData.VarCollection);

            typeScope.This = root;

            for (int i = 0; i < DefinedVars.Length; i++)
            {
                IndexedVar newVar = root.CreateChild(typeScope, DefinedVars[i].VariableName, Element.IntToElement(i), DefinedVars[i]);
                newVar.DefaultTarget = target;
                if (DefinedVars[i].Type != null)
                {
                    newVar.Type = parseData.GetDefinedType(DefinedVars[i].Type, DefinedVars[i].Location);
                }
                newVar.AccessLevel = DefinedVars[i].AccessLevel;
            }

            for (int i = 0; i < MethodNodes.Length; i++)
            {
                UserMethod method = new UserMethod(typeScope, MethodNodes[i]);
                method.RegisterParameters(parseData);
                method.AccessLevel = MethodNodes[i].AccessLevel;
            }

            return(typeScope);
        }
        private void AsyncLock()
        {
            V_EventPlayer eventPlayer = new V_EventPlayer();

            ActionSet.AddAction(Element.Part <A_While>(
                                    Element.Part <V_Or>(
                                        Element.Part <V_And>(
                                            // The subroutine is executing on a global context,
                                            new V_Compare(eventPlayer, Operators.Equal, new V_Null()),
                                            // ...and the subroutine is running.
                                            GlobalRunning.GetVariable()
                                            ),
                                        // OR
                                        Element.Part <V_And>(
                                            // The subroutine is executing on a player context,
                                            new V_Compare(eventPlayer, Operators.NotEqual, new V_Null()),
                                            // ...and the subroutine is running on the player context.
                                            PlayerRunning.GetVariable(eventPlayer)
                                            )
                                        )
                                    ));

            // While the above while is running, wait.
            ActionSet.AddAction(A_Wait.MinimumWait);
            ActionSet.AddAction(new A_End());

            // When it ends, set the context to true.
            ActionSet.AddAction(PlayerRunning.SetVariable(true, eventPlayer)); // Shouldn't do anything on a global context.
            ActionSet.AddAction(Element.Part <A_If>(new V_Compare(eventPlayer, Operators.Equal, new V_Null())));
            ActionSet.AddAction(GlobalRunning.SetVariable(true));
        }
Example #3
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);
        }
Example #4
0
        public override void Translate(ActionSet actionSet)
        {
            WorkshopVariable variable;
            Element          target;
            Element          start;

            // Existing variable being used in for.
            if (VariableResolve != null)
            {
                VariableElements elements = VariableResolve.ParseElements(actionSet);
                variable = elements.IndexReference.WorkshopVariable;
                target   = elements.Target;
                start    = (Element)InitialResolveValue?.Parse(actionSet) ?? new V_Number(0);
            }
            // New variable being use in for.
            else
            {
                actionSet.IndexAssigner.Add(actionSet.VarCollection, DefinedVariable, actionSet.IsGlobal, null);
                variable = ((IndexReference)actionSet.IndexAssigner[DefinedVariable]).WorkshopVariable;
                target   = new V_EventPlayer();
                start    = (Element)DefinedVariable.InitialValue?.Parse(actionSet) ?? new V_Number(0);
            }

            Element stop = (Element)Stop.Parse(actionSet);
            Element step = (Element)Step.Parse(actionSet);

            // Global
            if (variable.IsGlobal)
            {
                actionSet.AddAction(Element.Part <A_ForGlobalVariable>(
                                        variable,
                                        start, stop, step
                                        ));
            }
            // Player
            else
            {
                actionSet.AddAction(Element.Part <A_ForPlayerVariable>(
                                        target,
                                        variable,
                                        start, stop, step
                                        ));
            }

            // Translate the block.
            Block.Translate(actionSet.Indent());

            // Resolve continues.
            ResolveContinues(actionSet);

            // Cap the for.
            actionSet.AddAction(new A_End());

            // Resolve breaks.
            ResolveBreaks(actionSet);
        }
Example #5
0
        public override Element GetVariable(Element targetPlayer = null)
        {
            if (targetPlayer != null && !(targetPlayer is V_EventPlayer))
            {
                throw new Exception($"{nameof(targetPlayer)} must be null or EventPlayer.");
            }

            if (targetPlayer == null)
            {
                targetPlayer = new V_EventPlayer();
            }

            if (Reference == null)
            {
                throw new ArgumentNullException(nameof(Reference));
            }

            if (Reference is Element == false)
            {
                throw new Exception("Reference is not an element, can't get the variable.");
            }

            return((Element)Reference);
        }
Example #6
0
        public virtual Element SetVariable(Element value, Element targetPlayer = null, Element setAtIndex = null)
        {
            Element element;

            if (targetPlayer == null)
            {
                targetPlayer = new V_EventPlayer();
            }

            if (setAtIndex == null)
            {
                if (Index != -1)
                {
                    if (IsGlobal)
                    {
                        element = Element.Part <A_SetGlobalVariableAtIndex>(VariableAsWorkshop, new V_Number(Index), value);
                    }
                    else
                    {
                        element = Element.Part <A_SetPlayerVariableAtIndex>(targetPlayer, VariableAsWorkshop, new V_Number(Index), value);
                    }
                }
                else
                {
                    if (IsGlobal)
                    {
                        element = Element.Part <A_SetGlobalVariable>(VariableAsWorkshop, value);
                    }
                    else
                    {
                        element = Element.Part <A_SetPlayerVariable>(targetPlayer, VariableAsWorkshop, value);
                    }
                }
            }
            else
            {
                if (Index != -1)
                {
                    if (IsGlobal)
                    {
                        element = Element.Part <A_SetGlobalVariableAtIndex>(VariableAsWorkshop, new V_Number(Index),
                                                                            Element.Part <V_Append>(
                                                                                Element.Part <V_Append>(
                                                                                    Element.Part <V_ArraySlice>(GetVariable(targetPlayer), new V_Number(0), setAtIndex),
                                                                                    value),
                                                                                Element.Part <V_ArraySlice>(GetVariable(targetPlayer), Element.Part <V_Add>(setAtIndex, new V_Number(1)), new V_Number(9999))));
                    }
                    else
                    {
                        element = Element.Part <A_SetPlayerVariableAtIndex>(targetPlayer, VariableAsWorkshop, new V_Number(Index),
                                                                            Element.Part <V_Append>(
                                                                                Element.Part <V_Append>(
                                                                                    Element.Part <V_ArraySlice>(GetVariable(targetPlayer), new V_Number(0), setAtIndex),
                                                                                    value),
                                                                                Element.Part <V_ArraySlice>(GetVariable(targetPlayer), Element.Part <V_Add>(setAtIndex, new V_Number(1)), new V_Number(9999))));
                    }
                }
                else
                {
                    if (IsGlobal)
                    {
                        element = Element.Part <A_SetGlobalVariableAtIndex>(VariableAsWorkshop, setAtIndex, value);
                    }
                    else
                    {
                        element = Element.Part <A_SetPlayerVariableAtIndex>(targetPlayer, VariableAsWorkshop, setAtIndex, value);
                    }
                }
            }

            return(element);
        }
        void ParseStatement(DeltinScriptParser.StatementContext statementContext)
        {
            #region Method
            if (statementContext.GetChild(0) is DeltinScriptParser.MethodContext)
            {
                Actions.Add(ParseMethod(statementContext.GetChild(0) as DeltinScriptParser.MethodContext, false));
                return;
            }
            #endregion

            #region Variable set

            if (statementContext.STATEMENT_OPERATION() != null)
            {
                DefinedVar variable;
                Element    target;
                Element    index     = null;
                string     operation = statementContext.STATEMENT_OPERATION().GetText();

                Element value;

                value = ParseExpression(statementContext.expr(1) as DeltinScriptParser.ExprContext);

                /*  Format if the variable has an expression beforehand (sets the target player)
                 *               expr(0)           .ChildCount
                 *                 v                   v
                 *  Statement (    v                   v          ) | Operation | Set to variable
                 *             Variable to set (       v         )
                 *                 ^            expr | . | expr
                 *                 ^                   ^
                 *               expr(0)          .GetChild(1) == '.'                               */
                if (statementContext.expr(0).ChildCount == 3 &&
                    statementContext.expr(0).GetChild(1).GetText() == ".")
                {
                    /*  Get Variable:  .expr(0)              .expr(1)
                     *                   v                     v  .expr(1) (if the value to be set is an array)
                     *  Statement (      v                     v      v    ) | Operation | Set to variable
                     *             Variable to set (           v      v  )
                     *                   ^          expr | . | expr | []
                     *                   ^           ^
                     *  Get  Target:  .expr(0)    .expr(0)                                            */

                    variable = DefinedVar.GetVar(statementContext.expr(0).expr(1).GetChild(0).GetText(),
                                                 statementContext.expr(0).expr(1).start);
                    target = ParseExpression(statementContext.expr(0).expr(0));

                    // Get the index if the variable has []
                    var indexExpression = statementContext.expr(0).expr(1).expr(1);
                    if (indexExpression != null)
                    {
                        index = ParseExpression(indexExpression);
                    }
                }
                else
                {
                    /*               .expr(0)             .expr(1)
                     *                  v                   v
                     *  Statement (     v                   v  ) | Operation | Set to variable
                     *             Variable to set (expr) | []
                     */
                    variable = DefinedVar.GetVar(statementContext.expr(0).GetChild(0).GetText(),
                                                 statementContext.expr(0).start);
                    target = new V_EventPlayer();

                    // Get the index if the variable has []
                    var indexExpression = statementContext.expr(0).expr(1);
                    if (indexExpression != null)
                    {
                        index = ParseExpression(indexExpression);
                    }
                }

                switch (operation)
                {
                case "+=":
                    value = Element.Part <V_Add>(variable.GetVariable(target, index), value);
                    break;

                case "-=":
                    value = Element.Part <V_Subtract>(variable.GetVariable(target, index), value);
                    break;

                case "*=":
                    value = Element.Part <V_Multiply>(variable.GetVariable(target, index), value);
                    break;

                case "/=":
                    value = Element.Part <V_Divide>(variable.GetVariable(target, index), value);
                    break;

                case "^=":
                    value = Element.Part <V_RaiseToPower>(variable.GetVariable(target, index), value);
                    break;

                case "%=":
                    value = Element.Part <V_Modulo>(variable.GetVariable(target, index), value);
                    break;
                }

                Actions.Add(variable.SetVariable(value, target, index));
                return;
            }

            #endregion

            #region for

            if (statementContext.GetChild(0) is DeltinScriptParser.ForContext)
            {
                /*
                 * CreateInitialSkip = true;
                 *
                 * if (SkipCountIndex == -1)
                 *  SkipCountIndex = Assign();
                 */

                // The action the for loop starts on.
                // +1 for the counter reset.
                int forActionStartIndex = Actions.Count() + 1;

                // The target array in the for statement.
                Element forArrayElement = ParseExpression(statementContext.@for().expr());

                // Use skipIndex with Get/SetIVarAtIndex to get the bool to determine if the loop is running.
                Var isBoolRunningSkipIf = Var.AssignVar(IsGlobal);
                // Insert the SkipIf at the start of the rule.
                Actions.Insert(0,
                               Element.Part <A_SkipIf>
                               (
                                   // Condition
                                   isBoolRunningSkipIf.GetVariable(),
                                   // Number of actions
                                   new V_Number(forActionStartIndex)
                               )
                               );

                // Create the for's temporary variable.
                DefinedVar forTempVar = Var.AssignDefinedVar(
                    name: statementContext.@for().PART().GetText(),
                    isGlobal: IsGlobal,
                    token: statementContext.@for().start
                    );

                // Reset the counter.
                Actions.Add(forTempVar.SetVariable(new V_Number(0)));

                // Parse the for's block.
                ParseBlock(statementContext.@for().block());

                // Take the variable out of scope.
                forTempVar.OutOfScope();

                // Add the for's finishing elements
                //Actions.Add(SetIVarAtIndex(skipIndex, new V_Number(forActionStartIndex))); // Sets how many variables to skip in the next iteraction.
                Actions.Add(isBoolRunningSkipIf.SetVariable(new V_True())); // Enables the skip.

                Actions.Add(forTempVar.SetVariable(                         // Indent the index by 1.
                                Element.Part <V_Add>
                                (
                                    forTempVar.GetVariable(),
                                    new V_Number(1)
                                )
                                ));

                Actions.Add(Element.Part <A_Wait>(new V_Number(0.06), WaitBehavior.IgnoreCondition)); // Add the Wait() required by the workshop.
                Actions.Add(Element.Part <A_LoopIf>(                                                  // Loop if the for condition is still true.
                                Element.Part <V_Compare>
                                (
                                    forTempVar.GetVariable(),
                                    Operators.LessThan,
                                    Element.Part <V_CountOf>(forArrayElement)
                                )
                                ));
                Actions.Add(isBoolRunningSkipIf.SetVariable(new V_False()));
                return;
            }

            #endregion

            #region if

            if (statementContext.GetChild(0) is DeltinScriptParser.IfContext)
            {
                /*
                 * Syntax after parse:
                 *
                 * If:
                 *  Skip If (Not (expr))
                 *  (body)
                 *  Skip - Only if there is if-else or else statements.
                 * Else if:
                 *  Skip If (Not (expr))
                 *  (body)
                 *  Skip - Only if there is more if-else or else statements.
                 * Else:
                 *  (body)
                 *
                 */

                // Add dummy action, create after body is created.
                int skipIfIndex = Actions.Count();
                Actions.Add(null);

                // Parse the if body.
                ParseBlock(statementContext.@if().block());

                // Determines if the "Skip" action after the if block will be created.
                // Only if there is if-else or else statements.
                bool addIfSkip = statementContext.@if().else_if().Count() > 0 || statementContext.@if().@else() != null;

                // Create the inital "SkipIf" action now that we know how long the if's body is.
                // Add one to the body length if a Skip action is going to be added.
                Actions.RemoveAt(skipIfIndex);
                Actions.Insert(skipIfIndex, Element.Part <A_SkipIf>(Element.Part <V_Not>(ParseExpression(statementContext.@if().expr())), new V_Number(Actions.Count - skipIfIndex + (addIfSkip ? 1 : 0))));

                // Create the "Skip" dummy action.
                int skipIndex = -1;
                if (addIfSkip)
                {
                    skipIndex = Actions.Count();
                    Actions.Add(null);
                }

                // Parse else-ifs
                var   skipIfContext = statementContext.@if().else_if();
                int[] skipIfData    = new int[skipIfContext.Length]; // The index where the else if's "Skip" action is.
                for (int i = 0; i < skipIfContext.Length; i++)
                {
                    // Create the dummy action.
                    int skipIfElseIndex = Actions.Count();
                    Actions.Add(null);

                    // Parse the else-if body.
                    ParseBlock(skipIfContext[i].block());

                    // Determines if the "Skip" action after the else-if block will be created.
                    // Only if there is additional if-else or else statements.
                    bool addIfElseSkip = i < skipIfContext.Length - 1 || statementContext.@if().@else() != null;

                    // Create the "Skip If" action.
                    Actions.RemoveAt(skipIfElseIndex);
                    Actions.Insert(skipIfElseIndex, Element.Part <A_SkipIf>(Element.Part <V_Not>(ParseExpression(skipIfContext[i].expr())), new V_Number(Actions.Count - skipIfElseIndex + (addIfElseSkip ? 1 : 0))));

                    // Create the "Skip" dummy action.
                    if (addIfElseSkip)
                    {
                        skipIfData[i] = Actions.Count();
                        Actions.Add(null);
                    }
                }

                // Parse else body.
                if (statementContext.@if().@else() != null)
                {
                    ParseBlock(statementContext.@if().@else().block());
                }

                // Replace dummy skip with real skip now that we know the length of the if, if-else, and else's bodies.
                // Replace if's dummy.
                if (skipIndex != -1)
                {
                    Actions.RemoveAt(skipIndex);
                    Actions.Insert(skipIndex, Element.Part <A_Skip>(new V_Number(Actions.Count - skipIndex)));
                }

                // Replace else-if's dummy.
                for (int i = 0; i < skipIfData.Length; i++)
                {
                    if (skipIfData[i] != 0)
                    {
                        Actions.RemoveAt(skipIfData[i]);
                        Actions.Insert(skipIfData[i], Element.Part <A_Skip>(new V_Number(Actions.Count - skipIfData[i])));
                    }
                }

                return;
            }

            #endregion

            throw new Exception($"What's a {statementContext.GetChild(0)} ({statementContext.GetChild(0).GetType()})?");
        }
        public Element GetVariable(Element targetPlayer = null, Element getAiIndex = null)
        {
            Element element;

            if (targetPlayer == null)
            {
                targetPlayer = new V_EventPlayer();
            }

            if (getAiIndex == null)
            {
                if (IsInArray)
                {
                    if (IsGlobal)
                    {
                        element = Element.Part <V_ValueInArray>(Element.Part <V_GlobalVariable>(Variable), new V_Number(Index));
                    }
                    else
                    {
                        element = Element.Part <V_ValueInArray>(Element.Part <V_PlayerVariable>(targetPlayer, Variable), new V_Number(Index));
                    }
                }
                else
                {
                    if (IsGlobal)
                    {
                        element = Element.Part <V_GlobalVariable>(Variable);
                    }
                    else
                    {
                        element = Element.Part <V_PlayerVariable>(targetPlayer, Variable);
                    }
                }
            }
            else
            {
                if (IsInArray)
                {
                    if (IsGlobal)
                    {
                        element = Element.Part <V_ValueInArray>(Element.Part <V_ValueInArray>(Element.Part <V_GlobalVariable>(Variable)), new V_Number(Index));
                    }
                    else
                    {
                        element = Element.Part <V_ValueInArray>(Element.Part <V_ValueInArray>(Element.Part <V_PlayerVariable>(targetPlayer, Variable)), new V_Number(Index));
                    }
                }
                else
                {
                    if (IsGlobal)
                    {
                        element = Element.Part <V_ValueInArray>(Element.Part <V_GlobalVariable>(Variable), getAiIndex);
                    }
                    else
                    {
                        element = Element.Part <V_ValueInArray>(Element.Part <V_PlayerVariable>(targetPlayer, Variable), getAiIndex);
                    }
                }
            }

            return(element);
        }
        protected override MethodResult Get()
        {
            var eventPlayer = new V_EventPlayer();

            IndexedVar a      = TranslateContext.VarCollection.AssignVar(Scope, "AngleOfVectors: a", TranslateContext.IsGlobal, null);
            IndexedVar b      = TranslateContext.VarCollection.AssignVar(Scope, "AngleOfVectors: b", TranslateContext.IsGlobal, null);
            IndexedVar c      = TranslateContext.VarCollection.AssignVar(Scope, "AngleOfVectors: c", TranslateContext.IsGlobal, null);
            IndexedVar ab     = TranslateContext.VarCollection.AssignVar(Scope, "AngleOfVectors: ab", TranslateContext.IsGlobal, null);
            IndexedVar bc     = TranslateContext.VarCollection.AssignVar(Scope, "AngleOfVectors: bc", TranslateContext.IsGlobal, null);
            IndexedVar abVec  = TranslateContext.VarCollection.AssignVar(Scope, "AngleOfVectors: abVec", TranslateContext.IsGlobal, null);
            IndexedVar bcVec  = TranslateContext.VarCollection.AssignVar(Scope, "AngleOfVectors: bcVec", TranslateContext.IsGlobal, null);
            IndexedVar abNorm = TranslateContext.VarCollection.AssignVar(Scope, "AngleOfVectors: abNorm", TranslateContext.IsGlobal, null);
            IndexedVar bcNorm = TranslateContext.VarCollection.AssignVar(Scope, "AngleOfVectors: bcNorm", TranslateContext.IsGlobal, null);

            Element zeroVec = Element.Part <V_Vector>(new V_Number(0), new V_Number(0), new V_Number(0));

            Element[] actions = ArrayBuilder <Element> .Build
                                (
                // Save A
                a.SetVariable((Element)Parameters[0], eventPlayer),
                // Save B
                b.SetVariable((Element)Parameters[1], eventPlayer),
                // save C
                c.SetVariable((Element)Parameters[2], eventPlayer),

                // get ab
                // ab[3] = { b[0] - a[0], b[1] - a[1], b[2] - a[2] };
                ab.SetVariable(
                    Element.Part <V_Vector>
                    (
                        Element.Part <V_Subtract>(Element.Part <V_XOf>(b.GetVariable()), Element.Part <V_XOf>(a.GetVariable())),
                        Element.Part <V_Subtract>(Element.Part <V_YOf>(b.GetVariable()), Element.Part <V_YOf>(a.GetVariable())),
                        Element.Part <V_Subtract>(Element.Part <V_ZOf>(b.GetVariable()), Element.Part <V_ZOf>(a.GetVariable()))
                    ), eventPlayer),

                // get bc
                // bc[3] = { c[0] - b[0], c[1] - b[1], c[2] - b[2] };
                bc.SetVariable(
                    Element.Part <V_Vector>
                    (
                        Element.Part <V_Subtract>(Element.Part <V_XOf>(c.GetVariable()), Element.Part <V_XOf>(b.GetVariable())),
                        Element.Part <V_Subtract>(Element.Part <V_YOf>(c.GetVariable()), Element.Part <V_YOf>(b.GetVariable())),
                        Element.Part <V_Subtract>(Element.Part <V_ZOf>(c.GetVariable()), Element.Part <V_ZOf>(b.GetVariable()))
                    ), eventPlayer),

                // get abVec
                // abVec = sqrt(ab[0] * ab[0] + ab[1] * ab[1] + ab[2] * ab[2]);
                abVec.SetVariable(
                    Element.Part <V_DistanceBetween>
                    (
                        ab.GetVariable(),
                        zeroVec
                    ), eventPlayer),

                // get bcVec
                // bcVec = sqrt(bc[0] * bc[0] + bc[1] * bc[1] + bc[2] * bc[2]);
                bcVec.SetVariable(
                    Element.Part <V_DistanceBetween>
                    (
                        bc.GetVariable(),
                        zeroVec
                    ), eventPlayer),

                // get abNorm
                // abNorm[3] = {ab[0] / abVec, ab[1] / abVec, ab[2] / abVec};
                abNorm.SetVariable(
                    Element.Part <V_Vector>
                    (
                        Element.Part <V_Divide>(Element.Part <V_XOf>(ab.GetVariable()), abVec.GetVariable()),
                        Element.Part <V_Divide>(Element.Part <V_YOf>(ab.GetVariable()), abVec.GetVariable()),
                        Element.Part <V_Divide>(Element.Part <V_ZOf>(ab.GetVariable()), abVec.GetVariable())
                    ), eventPlayer),

                // get bcNorm
                // bcNorm[3] = {bc[0] / bcVec, bc[1] / bcVec, bc[2] / bcVec};
                bcNorm.SetVariable(
                    Element.Part <V_Vector>
                    (
                        Element.Part <V_Divide>(Element.Part <V_XOf>(bc.GetVariable()), bcVec.GetVariable()),
                        Element.Part <V_Divide>(Element.Part <V_YOf>(bc.GetVariable()), bcVec.GetVariable()),
                        Element.Part <V_Divide>(Element.Part <V_ZOf>(bc.GetVariable()), bcVec.GetVariable())
                    ), eventPlayer)
                                );

            Element result = Element.Part <V_Divide>
                             (
                Element.Part <V_Multiply>
                (
                    Element.Part <V_ArccosineInRadians>
                    (
                        // get res
                        // res = abNorm[0] * bcNorm[0] + abNorm[1] * bcNorm[1] + abNorm[2] * bcNorm[2];
                        //target.SetVariable(
                        Element.Part <V_Add>
                        (
                            Element.Part <V_Add>
                            (
                                Element.Part <V_Multiply>(Element.Part <V_XOf>(abNorm.GetVariable()), Element.Part <V_XOf>(bcNorm.GetVariable())),
                                Element.Part <V_Multiply>(Element.Part <V_YOf>(abNorm.GetVariable()), Element.Part <V_YOf>(bcNorm.GetVariable()))
                            ),
                            Element.Part <V_Multiply>(Element.Part <V_ZOf>(abNorm.GetVariable()), Element.Part <V_ZOf>(bcNorm.GetVariable()))
                        )
                    ),
                    new V_Number(180)
                ),
                new V_Number(Math.PI)
                             );

            return(new MethodResult(actions, result));
        }
        static MethodResult AngleOfVectors(bool isGlobal, VarCollection varCollection, object[] parameters)
        {
            var eventPlayer = new V_EventPlayer();

            Var a      = varCollection.AssignVar("AngleOfVectors: a", isGlobal);
            Var b      = varCollection.AssignVar("AngleOfVectors: b", isGlobal);
            Var c      = varCollection.AssignVar("AngleOfVectors: c", isGlobal);
            Var ab     = varCollection.AssignVar("AngleOfVectors: ab", isGlobal);
            Var bc     = varCollection.AssignVar("AngleOfVectors: bc", isGlobal);
            Var abVec  = varCollection.AssignVar("AngleOfVectors: abVec", isGlobal);
            Var bcVec  = varCollection.AssignVar("AngleOfVectors: bcVec", isGlobal);
            Var abNorm = varCollection.AssignVar("AngleOfVectors: abNorm", isGlobal);
            Var bcNorm = varCollection.AssignVar("AngleOfVectors: bcNorm", isGlobal);

            Element zeroVec = Element.Part <V_Vector>(new V_Number(0), new V_Number(0), new V_Number(0));

            return(new MethodResult
                   (
                       new Element[]
            {
                // Save A
                a.SetVariable((Element)parameters[0], eventPlayer),
                // Save B
                b.SetVariable((Element)parameters[1], eventPlayer),
                // save C
                c.SetVariable((Element)parameters[2], eventPlayer),

                // get ab
                // ab[3] = { b[0] - a[0], b[1] - a[1], b[2] - a[2] };
                ab.SetVariable(
                    Element.Part <V_Vector>
                    (
                        Element.Part <V_Subtract>(Element.Part <V_XOf>(b.GetVariable()), Element.Part <V_XOf>(a.GetVariable())),
                        Element.Part <V_Subtract>(Element.Part <V_YOf>(b.GetVariable()), Element.Part <V_YOf>(a.GetVariable())),
                        Element.Part <V_Subtract>(Element.Part <V_ZOf>(b.GetVariable()), Element.Part <V_ZOf>(a.GetVariable()))
                    ), eventPlayer),

                // get bc
                // bc[3] = { c[0] - b[0], c[1] - b[1], c[2] - b[2] };
                bc.SetVariable(
                    Element.Part <V_Vector>
                    (
                        Element.Part <V_Subtract>(Element.Part <V_XOf>(c.GetVariable()), Element.Part <V_XOf>(b.GetVariable())),
                        Element.Part <V_Subtract>(Element.Part <V_YOf>(c.GetVariable()), Element.Part <V_YOf>(b.GetVariable())),
                        Element.Part <V_Subtract>(Element.Part <V_ZOf>(c.GetVariable()), Element.Part <V_ZOf>(b.GetVariable()))
                    ), eventPlayer),

                // get abVec
                // abVec = sqrt(ab[0] * ab[0] + ab[1] * ab[1] + ab[2] * ab[2]);
                abVec.SetVariable(
                    Element.Part <V_DistanceBetween>
                    (
                        ab.GetVariable(),
                        zeroVec
                    ), eventPlayer),

                // get bcVec
                // bcVec = sqrt(bc[0] * bc[0] + bc[1] * bc[1] + bc[2] * bc[2]);
                bcVec.SetVariable(
                    Element.Part <V_DistanceBetween>
                    (
                        bc.GetVariable(),
                        zeroVec
                    ), eventPlayer),

                // get abNorm
                // abNorm[3] = {ab[0] / abVec, ab[1] / abVec, ab[2] / abVec};
                abNorm.SetVariable(
                    Element.Part <V_Vector>
                    (
                        Element.Part <V_Divide>(Element.Part <V_XOf>(ab.GetVariable()), abVec.GetVariable()),
                        Element.Part <V_Divide>(Element.Part <V_YOf>(ab.GetVariable()), abVec.GetVariable()),
                        Element.Part <V_Divide>(Element.Part <V_ZOf>(ab.GetVariable()), abVec.GetVariable())
                    ), eventPlayer),

                // get bcNorm
                // bcNorm[3] = {bc[0] / bcVec, bc[1] / bcVec, bc[2] / bcVec};
                bcNorm.SetVariable(
                    Element.Part <V_Vector>
                    (
                        Element.Part <V_Divide>(Element.Part <V_XOf>(bc.GetVariable()), bcVec.GetVariable()),
                        Element.Part <V_Divide>(Element.Part <V_YOf>(bc.GetVariable()), bcVec.GetVariable()),
                        Element.Part <V_Divide>(Element.Part <V_ZOf>(bc.GetVariable()), bcVec.GetVariable())
                    ), eventPlayer),
            },
                       // get res
                       // res = abNorm[0] * bcNorm[0] + abNorm[1] * bcNorm[1] + abNorm[2] * bcNorm[2];
                       //target.SetVariable(
                       Element.Part <V_Add>
                       (
                           Element.Part <V_Add>
                           (
                               Element.Part <V_Multiply>(Element.Part <V_XOf>(abNorm.GetVariable()), Element.Part <V_XOf>(bcNorm.GetVariable())),
                               Element.Part <V_Multiply>(Element.Part <V_YOf>(abNorm.GetVariable()), Element.Part <V_YOf>(bcNorm.GetVariable()))
                           ),
                           Element.Part <V_Multiply>(Element.Part <V_ZOf>(abNorm.GetVariable()), Element.Part <V_ZOf>(bcNorm.GetVariable()))
                       ),
                       CustomMethodType.MultiAction_Value
                   ));
        }