Exemplo n.º 1
0
        /*
         * Add initial code to the blocks and return the scope in which conversion should occur
         * Sometimes, we want to add a bit of code before the converted code, or want to encapsulate whole converted code
         * with a branch or so - this is a place to do it.
         *
         *
         *
         *  Scope in which we want for conversion to happen
         */
        public TES5CodeScope AddInitialCode(TES5MultipleScriptsScope multipleScriptsScope, TES5GlobalScope globalScope, TES5EventCodeBlock eventCodeBlock)
        {
            switch (eventCodeBlock.BlockName)
            {
            case "OnUpdate":
            {
                if (globalScope.ScriptHeader.BasicScriptType == TES5BasicType.T_QUEST)
                {
                    TES5Branch branch = TES5BranchFactory.CreateSimpleBranch(TES5ExpressionFactory.CreateComparisonExpression(this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), "IsRunning", multipleScriptsScope, new TES5ObjectCallArguments()), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Bool(false)), eventCodeBlock.CodeScope.LocalScope);
                    //Even though we"d like this script to not do anything at this time, it seems like sometimes condition races, so we"re putting it into a loop anyways but with early return bailout
                    branch.MainBranch.CodeScope.AddChunk(this.objectCallFactory.CreateRegisterForSingleUpdate(globalScope, multipleScriptsScope));
                    branch.MainBranch.CodeScope.AddChunk(new TES5Return());
                    eventCodeBlock.AddChunk(branch);
                    return(eventCodeBlock.CodeScope);
                }

                /*else if (globalScope.ScriptHeader.BasicScriptType== TES5BasicType.T_OBJECTREFERENCE)
                 * {
                 *  TES5LocalScope localScope = eventCodeBlock.CodeScope.LocalScope;
                 *  TES5Branch branch = TES5BranchFactory.CreateSimpleBranch(TES5ExpressionFactory.CreateComparisonExpression(this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), "GetParentCell", multipleScriptsScope, new TES5ObjectCallArguments()), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToPlayer(), "GetParentCell", multipleScriptsScope, new TES5ObjectCallArguments())), localScope);
                 *  eventCodeBlock.AddChunk(branch);
                 *  return branch.MainBranch.CodeScope;
                 * }*/
                else
                {
                    return(eventCodeBlock.CodeScope);
                }
            }

            default:
            {
                return(eventCodeBlock.CodeScope);
            }
            }
        }
Exemplo n.º 2
0
        /*
         * Add initial code to the blocks and return the scope in which conversion should occur
         * Sometimes, we want to add a bit of code before the converted code, or want to encapsulate whole converted code
         * with a branch or so - this is a place to do it.
         *
         *
         *
         *  Scope in which we want for conversion to happen
         */
        public TES5CodeScope AddInitialCode(TES5GlobalScope globalScope, TES5EventCodeBlock eventCodeBlock)
        {
            if (eventCodeBlock.BlockName == "OnUpdate")
            {
                if (globalScope.ScriptHeader.ScriptType.NativeType == TES5BasicType.T_QUEST)
                {
                    //Even though we"d like this script to not do anything at this time, it seems like sometimes condition races, so we"re putting it into a loop anyways but with early return bailout
                    TES5Branch branch = TES5BranchFactory.CreateSimpleBranch(TES5ExpressionFactory.CreateComparisonExpression(this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), "IsRunning", new TES5ObjectCallArguments()), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Bool(false)), eventCodeBlock.CodeScope.LocalScope);
                    if (!globalScope.QuestHasOnUpdateRegisterForSingleUpdate)//WTM:  Change:  Added
                    {
                        //If quest has RegisterForSingleUpdate already, preventing adding it again.
                        //Previously, RegisterForSingleUpdate was being called multiple times in OnUpdate because of how CombineRepeatedEventCodeBlockNames splits multiple OnUpdate methods into separate functions.
                        //See TES4tutorialscript.psc for an example.
                        globalScope.QuestHasOnUpdateRegisterForSingleUpdate = true;
                        branch.MainBranch.CodeScope.AddChunk(this.objectCallFactory.CreateRegisterForSingleUpdate(globalScope));
                    }
                    branch.MainBranch.CodeScope.AddChunk(new TES5Return());
                    eventCodeBlock.AddChunk(branch);
                    return(eventCodeBlock.CodeScope);
                }

                /*else if (globalScope.ScriptHeader.BasicScriptType == TES5BasicType.T_OBJECTREFERENCE)
                 * {
                 *  TES5LocalScope localScope = eventCodeBlock.CodeScope.LocalScope;
                 *  TES5Branch branch = TES5BranchFactory.CreateSimpleBranch(TES5ExpressionFactory.CreateComparisonExpression(this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), "GetParentCell", multipleScriptsScope, new TES5ObjectCallArguments()), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToPlayer(), "GetParentCell", multipleScriptsScope, new TES5ObjectCallArguments())), localScope);
                 *  eventCodeBlock.AddChunk(branch);
                 *  return branch.MainBranch.CodeScope;
                 * }*/
            }
            return(eventCodeBlock.CodeScope);
        }
        public TES5CodeChunkCollection CreateCodeChunk(TES4VariableAssignation chunk, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5CodeChunkCollection codeChunkCollection = new TES5CodeChunkCollection();
            string          referenceName = chunk.Reference.StringValue;
            ITES5Referencer reference     = this.referenceFactory.CreateReference(referenceName, globalScope, multipleScriptsScope, codeScope.LocalScope);
            ITES5Value      value         = this.valueFactory.CreateValue(chunk.Value, codeScope, globalScope, multipleScriptsScope);

            if (reference.TES5Type == TES5BasicType.T_GLOBALVARIABLE)
            { //if the reference is in reality a global variable, we will need to convert it by creating a Reference.SetValue(value); call
                //Object call creation
                TES5ObjectCallArguments objectCallArguments = new TES5ObjectCallArguments()
                {
                    value
                };
                TES5ObjectCall objectCall = this.objectCallFactory.CreateObjectCall(reference, "SetValue", objectCallArguments);
                codeChunkCollection.Add(objectCall);
            }
            else
            {
                if (reference.ReferencesTo == null)
                {
                    throw new NullableException(nameof(reference.ReferencesTo));
                }
                if (!reference.ReferencesTo.TES5Type.IsPrimitive && value.TES5Type.IsPrimitive)
                {
                    //Hacky!
                    TES5IntegerOrFloat?valueNumber = value as TES5IntegerOrFloat;
                    if (valueNumber != null && valueNumber.ConvertedIntValue == 0)
                    {
                        value = new TES5None();
                    }
                }

                TES5VariableAssignation assignation = TES5VariableAssignationFactory.CreateAssignation(reference, value);
                this.typeInferencer.InferenceObjectByAssignation(reference, value);
                codeChunkCollection.Add(assignation);
                //post analysis.
                //Todo - rethink the prefix here
                ITES5Referencer?referencerValue = value as ITES5Referencer;
                if (referencerValue != null && referencerValue.Name == TES5Property.AddPropertyNameSuffix(TES5ReferenceFactory.MESSAGEBOX_VARIABLE_CONST))
                {
                    /*
                     * Create block:
                     * variable = this.TES4_MESSAGEBOX_RESULT; ; assignation
                     * if(variable != -1) ; branch, expression
                     *   this.TES4_MESSAGEBOX_RESULT = -1; ; reassignation
                     * endIf
                     */
                    TES5Integer negativeOne                = new TES5Integer(-1);
                    TES5ComparisonExpression expression    = TES5ExpressionFactory.CreateComparisonExpression(reference, TES5ComparisonExpressionOperator.OPERATOR_NOT_EQUAL, negativeOne);
                    TES5VariableAssignation  reassignation = TES5VariableAssignationFactory.CreateAssignation(referencerValue, negativeOne);
                    TES5Branch branch = TES5BranchFactory.CreateSimpleBranch(expression, codeScope.LocalScope);
                    branch.MainBranch.CodeScope.AddChunk(reassignation);
                    codeChunkCollection.Add(branch);
                }
            }

            return(codeChunkCollection);
        }