Ejemplo n.º 1
0
        public void Run()
        {
            string[] scripts = this.buildTargets.GetScriptsToCompile(this.scriptName);
            //BuildSourceFilesCollection partitionedScripts = this.buildTargets.GetSourceFiles(scripts);
            TES5GlobalVariables globalVariables = this.esmAnalyzer.GlobalVariables;

            foreach (var buildTarget in this.buildTargets)
            {
                Dictionary <string, TES5GlobalScope> scriptsScopes = new Dictionary <string, TES5GlobalScope>();
                foreach (var buildScript in scripts)
                {
                    string scriptName = Path.GetFileNameWithoutExtension(buildScript);
                    string sourcePath = buildTarget.GetSourceFromPath(scriptName);
                    //string outputPath = buildTarget.GetTranspileToPath(scriptName);
                    TES5GlobalScope globalScope = buildTarget.BuildScope(sourcePath, globalVariables);
                    scriptsScopes.Add(scriptName, globalScope);
                }

                TES5MultipleScriptsScope multipleScriptsScope = new TES5MultipleScriptsScope(scriptsScopes.Values, globalVariables);
                foreach (var buildScript in scripts)
                {
                    string          scriptName  = Path.GetFileNameWithoutExtension(buildScript);
                    string          sourcePath  = buildTarget.GetSourceFromPath(scriptName);
                    string          outputPath  = buildTarget.GetTranspileToPath(scriptName);
                    TES5GlobalScope globalScope = buildTarget.BuildScope(sourcePath, globalVariables);
                    buildTarget.Transpile(sourcePath, outputPath, globalScope, multipleScriptsScope);
                }
            }
        }
        /*
         * Extracts implicit reference from calls.
         * Returns a reference from calls like:
         * Enable
         * Disable
         * Activate
         * GetInFaction whatsoever
         */
        public ITES5Referencer ExtractImplicitReference(TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope, TES5LocalScope localScope)
        {
            ITES5Type type = globalScope.ScriptHeader.BasicScriptType;

            if (type == TES5BasicType.T_OBJECTREFERENCE || type == TES5BasicType.T_ACTOR)//Change:  WTM:  Added Actor here.
            {
                return(CreateReferenceToSelf(globalScope));
            }
            else if (type == TES5BasicType.T_ACTIVEMAGICEFFECT)
            {
                TES5SelfReference self = CreateReferenceToSelf(globalScope);
                return(this.objectCallFactory.CreateObjectCall(self, "GetTargetActor", multipleScriptsScope));
            }
            else if (type == TES5BasicType.T_QUEST)
            {
                //todo - this should not be done like this
                //we should actually not try to extract the implicit reference on the non-reference oblivion functions like "stopQuest"
                //think of this line as a hacky way to just get code forward.
                return(CreateReferenceToSelf(globalScope));
            }
            else if (type == TES5BasicType.T_TOPICINFO)
            {
                /*
                 * TIF Fragments
                 */
                return(this.CreateReadReference("akSpeakerRef", globalScope, multipleScriptsScope, localScope));
            }

            throw new ConversionException("Cannot extract implicit reference - unknown basic script type.");
        }
Ejemplo n.º 3
0
        private void InferenceTypeOfCalledObject(TES5ObjectCall objectCall, TES5MultipleScriptsScope multipleScriptsScope)
        {
            ITES5Type inferencableType = objectCall.AccessedObject.TES5Type.NativeType;

            /*
             * Check if we have something to inference inside the code, not some static class or method call return
             */
            if (objectCall.AccessedObject.ReferencesTo != null)
            {
                //this is not "exactly" nice solution, but its enough. For now.
                ITES5Type inferenceType = TES5InheritanceGraphAnalyzer.FindTypeByMethod(objectCall);
                if (inferencableType == null)
                {
                    throw new ConversionException("Cannot inference a null type");
                }

                if (inferencableType == inferenceType)
                {
                    return; //We already have the good type.
                }

                if (this.InferenceType(objectCall.AccessedObject.ReferencesTo, inferenceType, multipleScriptsScope))
                {
                    return;
                }
            }
        }
Ejemplo n.º 4
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);
            }
            }
        }
Ejemplo n.º 5
0
 /*
  * Inference the type by analyzing the object call.
  * Please note: It is not able to analyze calls to another scripts, but those weren"t used in oblivion anyways
  */
 public void InferenceObjectByMethodCall(TES5ObjectCall objectCall, TES5MultipleScriptsScope multipleScriptsScope)
 {
     this.InferenceTypeOfCalledObject(objectCall, multipleScriptsScope);
     if (objectCall.Arguments != null)
     {
         this.InferenceTypeOfMethodArguments(objectCall, multipleScriptsScope);
     }
 }
Ejemplo n.º 6
0
        /*
         * Try to inference variable"s type with type.
         *
         *
         *  Needed for proxifying the properties to other scripts
         *  - Will return true if inferencing succeeded, false otherwise.
         * @throws ConversionException
         */
        private bool InferenceType(ITES5VariableOrProperty variable, ITES5Type type, TES5MultipleScriptsScope multipleScriptsScope)
        {
            if (!TES5InheritanceGraphAnalyzer.IsExtending(type, variable.TES5Type.NativeType))
            {
                return(false);
            }

            variable.TES5Type = type;
            return(true);
        }
        public TES5ObjectProperty CreateObjectProperty(TES5MultipleScriptsScope multipleScriptsScope, ITES5Referencer reference, string propertyName)
        {
            ITES5VariableOrProperty referencesTo = reference.ReferencesTo;

            this.typeInferencer.InferenceVariableByReferenceEdid(referencesTo, multipleScriptsScope);
            TES5Property       remoteProperty = multipleScriptsScope.GetPropertyFromScript(referencesTo.TES5Type.OriginalName, propertyName);
            TES5ObjectProperty objectProperty = new TES5ObjectProperty(reference, remoteProperty);

            return(objectProperty);
        }
Ejemplo n.º 8
0
        private void CreateActiveStateBlock(TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope, out TES5State state, out TES5EventCodeBlock onUpdate)
        {
            state = CreateState("ActiveState", false);
            TES5EventCodeBlock onBeginState = CreateEventCodeBlock("OnBeginState");

            onBeginState.CodeScope.CodeChunks.Add(this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), "OnUpdate", multipleScriptsScope));
            state.AddBlock(onBeginState);
            onUpdate = CreateEventCodeBlock("OnUpdate");
            state.AddBlock(onUpdate);
        }
Ejemplo n.º 9
0
        private void InferenceTypeOfMethodArguments(TES5ObjectCall objectCall, TES5MultipleScriptsScope multipleScriptsScope)
        {
            /*
             * Inference the arguments
             */
            int       argumentIndex = 0;
            ITES5Type calledOnType  = objectCall.AccessedObject.TES5Type.NativeType;

            foreach (ITES5Value argument in objectCall.Arguments)
            {
                /*
                 * Get the argument type according to TES5Inheritance graph.
                 */
                ITES5Type argumentTargetType = TES5InheritanceGraphAnalyzer.FindTypeByMethodParameter(calledOnType, objectCall.FunctionName, argumentIndex);
                if (argument.TES5Type != argumentTargetType)
                {
                    /*
                     * todo - maybe we should move getReferencesTo() to TES5Value and make all of the rest TES5Values just have null references as they do not reference anything? :)
                     */
                    ITES5Referencer referencerArgument = argument as ITES5Referencer;
                    if (referencerArgument != null && TES5InheritanceGraphAnalyzer.IsExtending(argumentTargetType, argument.TES5Type.NativeType))
                    { //HACKY!
                        this.InferenceType(referencerArgument.ReferencesTo, argumentTargetType, multipleScriptsScope);
                    }
                    else
                    {
                        //So there"s one , one special case where we actually have to cast a var from one to another even though they are not ,,inheriting" from themselves, because they are primitives.
                        //Scenario: there"s an T_INT argument, and we feed it with a T_FLOAT variable reference. It won"t work :(
                        //We need to cast it on call level ( NOT inference it ) to make it work and not break other possible scenarios ( more specifically, when a float would be inferenced to int and there"s a
                        //float assigment somewhere in the code )
                        if (argumentTargetType == TES5BasicType.T_INT && argument.TES5Type == TES5BasicType.T_FLOAT)
                        {
                            TES5Castable argumentCastable = argument as TES5Castable;
                            if (argumentCastable != null)
                            { //HACKY! When we"ll clean up this interface, it will dissapear :)
                                argumentCastable.ManualCastTo = argumentTargetType;
                            }
                        }
                        else if (
                            !TES5InheritanceGraphAnalyzer.IsExtending(argument.TES5Type, argumentTargetType) &&
                            !TES5InheritanceGraphAnalyzer.IsNumberTypeOrBoolAndInt(argument.TES5Type, argumentTargetType) &&
                            !(argument is TES5None && TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(argumentTargetType, (new TES5None()).TES5Type)))
                        {
                            bool expected = objectCall.AccessedObject.TES5Type.OriginalName == "TES4TimerHelper" && objectCall.FunctionName == "LegacySay";
                            throw new ConversionException("Argument type mismatch at " + objectCall.FunctionName + " index " + argumentIndex + ".  Expected " + argumentTargetType.OriginalName + ".  Found " + argument.TES5Type.OriginalName + ".", expected: expected);
                        }
                    }
                }
                argumentIndex++;
            }
        }
Ejemplo n.º 10
0
        private void CreateActivationStates(TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope, out TES5BlockList blocks, out TES5EventCodeBlock onUpdate)
        {
            TES5State activeState;

            CreateActiveStateBlock(globalScope, multipleScriptsScope, out activeState, out onUpdate);
            TES5State          inactiveState = CreateInactiveStateBlock();
            TES5EventCodeBlock onCellAttach  = CreateEventCodeBlock("OnCellAttach");

            onCellAttach.CodeScope.AddChunk(objectCallFactory.CreateGotoState("ActiveState", globalScope, multipleScriptsScope));
            TES5EventCodeBlock onCellDetach = CreateEventCodeBlock("OnCellDetach");

            onCellDetach.CodeScope.AddChunk(objectCallFactory.CreateGotoState("InactiveState", globalScope, multipleScriptsScope));
            blocks = new TES5BlockList()
            {
                activeState, inactiveState, onCellAttach, onCellDetach
            };
        }
        /*
         * Extracts implicit reference from calls.
         * Returns a reference from calls like:
         * Enable
         * Disable
         * Activate
         * GetInFaction whatsoever
         */
        public ITES5Referencer ExtractImplicitReference(TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope, TES5LocalScope localScope)
        {
            ITES5Type type = globalScope.ScriptHeader.ScriptType.NativeType;

            if (type == TES5BasicType.T_ACTIVEMAGICEFFECT)
            {
                TES5SelfReference self = CreateReferenceToSelf(globalScope);
                return(this.objectCallFactory.CreateObjectCall(self, "GetTargetActor"));
            }
            if (type == TES5BasicType.T_QUEST)
            {
                //todo - this should not be done like this
                //we should actually not try to extract the implicit reference on the non-reference oblivion functions like "stopQuest"
                //think of this line as a hacky way to just get code forward.
                return(CreateReferenceToSelf(globalScope));
            }
            if (type == TES5BasicType.T_TOPICINFO)
            {
                //TIF Fragments
                return(this.CreateReadReference("akSpeakerRef", globalScope, multipleScriptsScope, localScope));
            }
            //WTM:  Change:  I made this the new default result instead of the previous algorithm of exhaustively listing types and throwing an exception if no type matches.
            return(CreateReferenceToSelf(globalScope));
        }
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5LocalScope           localScope           = codeScope.LocalScope;
            TES4FunctionArguments    functionArguments    = function.Arguments;
            ITES5Referencer          fameReference        = this.referenceFactory.CreateReadReference("Fame", globalScope, multipleScriptsScope, localScope);
            TES5ObjectCallArguments  fameArguments        = new TES5ObjectCallArguments();
            TES5ArithmeticExpression arithmeticExpression = TES5ExpressionFactory.CreateArithmeticExpression(fameReference, TES5ArithmeticExpressionOperator.OPERATOR_ADD, new TES5Integer(((TES4Integer)functionArguments[0]).IntValue));

            fameArguments.Add(arithmeticExpression);
            return(this.objectCallFactory.CreateObjectCall(this.referenceFactory.CreateReference("Fame", globalScope, multipleScriptsScope, localScope), "SetValue", multipleScriptsScope, fameArguments));
        }
Ejemplo n.º 13
0
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES4FunctionArguments   functionArguments = function.Arguments;
            ITES4StringValue        argument0         = functionArguments[0];
            TES5ObjectCallArguments functionArgs      = new TES5ObjectCallArguments()
            {
                this.valueFactory.CreateValue(argument0, codeScope, globalScope, multipleScriptsScope),
                new TES5Bool(true)
            };

            return(this.objectCallFactory.CreateObjectCall(calledOn, "SetAlpha", functionArgs));
        }
        public void execute(string buildPath = Build.DEFAULT_BUILD_PATH, bool skipParsing = false, string mode = "strict")
        {
            set_time_limit(10800); // 3 hours is the maximum for this command. Need more? You really screwed something, full suite for all Oblivion vanilla data takes 20 minutes. :)
            float threshold;

            switch (mode)
            {
            case "sloppy":
            {
                threshold = 0.5f;
                break;
            }

            case "normal":
            {
                threshold = 0.85f;
                break;
            }

            case "strict":
            default:
            {
                threshold = 0.95f;
                break;
            }

            case "perfect":
            {
                threshold = 1;
                break;
            }
            }

            if (!skipParsing)
            {
                SyntaxErrorCleanParser parser = new SyntaxErrorCleanParser(new TES4ObscriptCodeGrammar());
                //parser = new Parser(new TES4OBScriptGrammar());
                TES4ToTES5ASTTIFFragmentConverter converter = TES4ToTES5ASTTIFFragmentConverterFactory.GetConverter(new Build(buildPath));
                string   inputFolder = "./Fragments/TIF/fragments/";
                string   outputFolder = "./Fragments/TIF/PapyrusFragments/";
                string[] scandir = Directory.GetFiles(inputFolder);
                int      success = 0, total = 0;
                Dictionary <string, TES5MultipleScriptsScope> ASTTable = new Dictionary <string, TES5MultipleScriptsScope>();
                Console.WriteLine("Lexing and parsing..");
                int totalNumber = scandir.Length;
                foreach (var scriptPath in scandir)
                {
                    if (!scriptPath.EndsWith(".txt"))
                    {
                        continue;
                    }

                    if ((total % 10) == 0)
                    {
                        Console.WriteLine(total + "/" + totalNumber + "...");
                    }

                    string scriptFileName   = scriptPath.Substring(0, scriptPath.Length - 4);
                    string outputScriptPath = scriptFileName + ".psc";
                    total++;
                    try
                    {
                        Console.WriteLine(scriptFileName + "...");
                        FragmentLexer               lexer        = new FragmentLexer();
                        ArrayTokenStream            tokens       = lexer.lex(File.ReadAllText(path));
                        TES4VariableDeclarationList variableList = this.fragmentsReferencesBuilder.buildVariableDeclarationList(inputFolder + scriptFileName + ".references");
                        TES5MultipleScriptsScope    AST          = (TES5MultipleScriptsScope)parser.ParseWithFixLogic(tokens);
                        ASTTable[scriptPath] = AST;
                        TES5Target TES5AST      = converter.convert(scriptFileName, variableList, AST);
                        string     outputScript = TES5AST.output();
                        File.WriteAllText(outputFolder + outputScriptPath, outputScript);
                        Process.Start("lua", "\"Utilities/beautifier.lua\" \"" + outputFolder + outputScriptPath + "\"");
                        success++;
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(scriptPath + "\r\n" + e.GetType().FullName + ":  " + e.Message + "\r\n");
                        continue;
                    }
                }

                float successRate = (float)success / total;
                if (successRate < threshold)
                {
                    float percent = (float)Math.Round(successRate * 100);
                    Console.WriteLine("ERROR: Build failed on parsing step in " + mode + " mode. The rate is " + success + "/" + total + " (" + percent + " %)");
                    return;
                }

                Console.WriteLine("Parsing in " + mode + " mode succedeed (rate " + success + "/" + total + ").  Copying Skyrim scripts and parsed papyrus fragments to build folder...");
            }

            Console.WriteLine("Build in " + mode + " mode succeeded!");
        }
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5LocalScope        localScope        = codeScope.LocalScope;
            TES4FunctionArguments functionArguments = function.Arguments;
            //This has to be a write-action reference, not a read reference!
            ITES5Referencer         fameReference = this.referenceFactory.CreateReference("Fame", globalScope, multipleScriptsScope, localScope);
            TES5ObjectCallArguments fameArguments = new TES5ObjectCallArguments()
            {
                this.valueFactory.CreateValue(functionArguments[0], codeScope, globalScope, multipleScriptsScope)
            };
            TES5ObjectCall newFunction = this.objectCallFactory.CreateObjectCall(fameReference, "SetValue", fameArguments);

            return(newFunction);
        }
        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);
        }
        public void Modify(TES4CodeBlock block, TES5BlockList blockList, TES5EventCodeBlock newBlock, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5FunctionScope blockFunctionScope = newBlock.FunctionScope;

            switch (block.BlockType.ToLower())
            {
            case "gamemode":
            case "scripteffectupdate":
            {
                TES5ObjectCall function = this.objectCallFactory.CreateRegisterForSingleUpdate(globalScope, multipleScriptsScope);
                newBlock.AddChunk(function);
                if (globalScope.ScriptHeader.BasicScriptType == TES5BasicType.T_QUEST)
                {
                    TES5EventCodeBlock onInitBlock = TES5BlockFactory.CreateOnInit();
                    onInitBlock.AddChunk(function);
                    blockList.Add(onInitBlock);
                }
                break;
            }

            case "onactivate":
            {
                TES5EventCodeBlock onInitBlock = TES5BlockFactory.CreateOnInit();
                TES5ObjectCall     function    = this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), "BlockActivation", multipleScriptsScope);
                onInitBlock.AddChunk(function);
                blockList.Add(onInitBlock);
                break;
            }

            case "onactorequip":
            {
                SetUpBranch(block, newBlock, blockFunctionScope, TES5LocalVariableParameterMeaning.CONTAINER, globalScope, multipleScriptsScope);
                break;
            }

            case "ontriggeractor":
            {
                TES4BlockParameterList   parameterList                = block.BlockParameterList;
                TES5LocalScope           localScope                   = newBlock.CodeScope.LocalScope;
                TES5LocalVariable        activator                    = localScope.GetVariableWithMeaning(TES5LocalVariableParameterMeaning.ACTIVATOR);
                TES5LocalVariable        castedToActor                = new TES5LocalVariable("akAsActor", TES5BasicType.T_ACTOR);
                TES5Reference            referenceToCastedVariable    = TES5ReferenceFactory.CreateReferenceToVariable(castedToActor);
                TES5Reference            referenceToNonCastedVariable = TES5ReferenceFactory.CreateReferenceToVariable(activator);
                TES5ComparisonExpression expression                   = TES5ExpressionFactory.CreateComparisonExpression(referenceToCastedVariable, TES5ComparisonExpressionOperator.OPERATOR_NOT_EQUAL, new TES5None());
                TES5CodeScope            newCodeScope                 = TES5CodeScopeFactory.CreateCodeScopeRoot(blockFunctionScope);
                newCodeScope.LocalScope.AddVariable(castedToActor);
                newCodeScope.AddChunk(TES5VariableAssignationFactory.CreateAssignation(referenceToCastedVariable, referenceToNonCastedVariable));
                TES5CodeScope outerBranchCode;
                if (parameterList != null)
                {
                    //NOT TESTED
                    List <TES4BlockParameter> parameterListVariableList = parameterList.Parameters;
                    ITES5Referencer           targetActor     = this.referenceFactory.CreateReadReference(parameterListVariableList[0].BlockParameter, globalScope, multipleScriptsScope, localScope);
                    TES5ComparisonExpression  interExpression = TES5ExpressionFactory.CreateComparisonExpression(TES5ReferenceFactory.CreateReferenceToVariable(activator), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, targetActor);
                    //TES5CodeScope interBranchCode = PHPFunction.Deserialize<TES5CodeScope>(PHPFunction.Serialize(newBlock.CodeScope));//WTM:  Change:  Why serialize and then deserialize?
                    TES5CodeScope interBranchCode = newBlock.CodeScope;
                    outerBranchCode = TES5CodeScopeFactory.CreateCodeScopeRoot(blockFunctionScope);
                    interBranchCode.LocalScope.ParentScope = outerBranchCode.LocalScope;
                    outerBranchCode.AddChunk(new TES5Branch(new TES5SubBranch(interExpression, interBranchCode)));
                }
                else
                {
                    //outerBranchCode = PHPFunction.Deserialize<TES5CodeScope>(PHPFunction.Serialize(newBlock.CodeScope));//WTM:  Change:  Why serialize and then deserialize?
                    outerBranchCode = newBlock.CodeScope;
                    outerBranchCode.LocalScope.ParentScope = newCodeScope.LocalScope;
                }

                newCodeScope.AddChunk(new TES5Branch(new TES5SubBranch(expression, outerBranchCode)));
                newBlock.CodeScope = newCodeScope;
                break;
            }

            case "onadd":
            {
                SetUpBranch(block, newBlock, blockFunctionScope, "akNewContainer", globalScope, multipleScriptsScope);
                break;
            }

            case "ondrop":
            {
                SetUpBranch(block, newBlock, blockFunctionScope, "akOldContainer", globalScope, multipleScriptsScope);
                break;
            }

            case "onpackagestart":
            {
                SetUpBranch(block, newBlock, blockFunctionScope, "akNewPackage", globalScope, multipleScriptsScope);
                break;
            }

            case "onpackagedone":
            case "onpackagechange":
            case "onpackageend":
            {
                SetUpBranch(block, newBlock, blockFunctionScope, "akOldPackage", globalScope, multipleScriptsScope);
                break;
            }

            case "onalarm":
            {
                //@INCONSISTENCE - We don"t account for alarm type.
                TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), "IsAlarmed", multipleScriptsScope), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Bool(true));
                SetUpBranch(blockFunctionScope, newBlock, expression);
                break;
            }

            /*
             *
             * case "onalarm":
             * {
             *
             * this.skyrimGroupEventName = "onhit";
             *
             * if (this.eventArgs[1] != 3) {
             *  //Nothing eelse is supported really..
             *  this.omit = true;
             *  break;
             * }
             *
             * branch = new TES4ConditionalBranch();
             * expression = new TES4Expression();
             * leftConstant = new TES4Constant("akAggressor", "ObjectReference");
             * //actionConstant        = new TES4Constant(this.eventArgs[1],"Package");
             * actionConstant = TES4Factories.createReference(this.eventArgs[2], this);
             *
             * expression.left_side = leftConstant;
             * expression.right_side = actionConstant;
             * expression.comparision_operator = TES4Expression.COMPARISION_OPERATOR_EQUAL;
             *
             * codeBlock = new TES4CodeBlock();
             * codeBlock.chunks = this.chunks;
             *
             * branch.ifs[] = array(
             *  "rawExpression" => "SCRIPT_GENERATED",
             *  "expression" => expression,
             *  "codeBlock" => codeBlock
             * );
             * this.chunks = new TES4ChunkContainer();
             * this.chunks.parent = this;
             * this.chunks.addChunk(branch);
             *
             * break;
             * }
             */
            case "onequip":
            case "onunequip":
            {
                SetUpBranch(block, newBlock, blockFunctionScope, "akActor", globalScope, multipleScriptsScope);
                break;
            }
            }
        }
        private void SetUpBranch(TES4CodeBlock block, TES5EventCodeBlock newBlock, TES5FunctionScope blockFunctionScope, ITES5VariableOrProperty variable, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES4BlockParameterList parameterList = block.BlockParameterList;

            if (parameterList == null)
            {
                return;
            }
            List <TES4BlockParameter> parameterListVariableList = parameterList.Parameters;
            TES4BlockParameter        tesEquippedTarget         = parameterListVariableList[0];
            TES5LocalScope            localScope   = newBlock.CodeScope.LocalScope;
            ITES5Referencer           newContainer = this.referenceFactory.CreateReadReference(tesEquippedTarget.BlockParameter, globalScope, multipleScriptsScope, localScope);
            TES5ComparisonExpression  expression   = TES5ExpressionFactory.CreateComparisonExpression(TES5ReferenceFactory.CreateReferenceToVariable(variable), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, newContainer);

            SetUpBranch(blockFunctionScope, newBlock, expression);
        }
Ejemplo n.º 19
0
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5LocalScope           localScope        = codeScope.LocalScope;
            TES4FunctionArguments    functionArguments = function.Arguments;
            ITES5Referencer          argument          = this.referenceFactory.CreateReadReference(functionArguments[0].StringValue, globalScope, multipleScriptsScope, localScope);
            TES5ComparisonExpression expression        = TES5ExpressionFactory.CreateComparisonExpression(calledOn, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, argument);

            return(expression);
        }
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5LocalScope          localScope        = codeScope.LocalScope;
            TES4FunctionArguments   functionArguments = function.Arguments;
            ITES5Referencer         newCalledOn       = this.referenceFactory.CreateReadReference(functionArguments[0].StringValue, globalScope, multipleScriptsScope, localScope);
            TES5ObjectCallArguments arguments         = new TES5ObjectCallArguments();
            TES5Bool force;

            if (functionArguments.Count == 1)
            {
                force = new TES5Bool(false);
            }
            else
            {
                force = new TES5Bool(((TES4Integer)functionArguments[1]).IntValue == 1);
            }
            arguments.Add(force);
            return(this.objectCallFactory.CreateObjectCall(newCalledOn, "ForceActive", multipleScriptsScope, arguments));
        }
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5LocalScope localScope = codeScope.LocalScope;
            //@INCONSISTENCE - Will only check for scripted effects
            //In oblivion, this is checking for a spell which targeted a given actor
            //In Skyrim you can check for effects only.
            TES5ObjectCallArguments newArgs = new TES5ObjectCallArguments()
            {
                this.referenceFactory.CreateReference("EffectSEFF", TES5BasicType.T_MAGICEFFECT, globalScope, multipleScriptsScope, localScope)
            };

            return(this.objectCallFactory.CreateObjectCall(calledOn, "HasMagicEffect", newArgs));
        }
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES4FunctionArguments functionArguments = function.Arguments;
            TES5LocalScope        localScope        = codeScope.LocalScope;
            ITES5Referencer       newCalledOn       = this.referenceFactory.CreateReadReference(functionArguments.Pop(0).StringValue, globalScope, multipleScriptsScope, localScope);
            const string          functionName      = "AddToMap";

            return(this.objectCallFactory.CreateObjectCall(newCalledOn, functionName, this.objectCallArgumentsFactory.CreateArgumentList(functionArguments, codeScope, globalScope, multipleScriptsScope)));
        }
        public override ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5LocalScope              localScope         = codeScope.LocalScope;
            TES4FunctionArguments       functionArguments  = function.Arguments;
            TES5ObjectCallArguments     convertedArguments = new TES5ObjectCallArguments();
            Dictionary <string, string> actorValueMap      = ActorValueMap.Map;
            ITES4StringValue            firstArg           = functionArguments[0];
            string firstArgString      = firstArg.StringValue;
            string firstArgStringLower = firstArgString.ToLower();

            switch (firstArgStringLower)
            {
            case "strength":
            case "intelligence":
            case "willpower":
            case "agility":
            case "endurance":
            case "personality":
            case "luck":
            {
                if (!TES5PlayerReference.EqualsPlayer(calledOn.Name))
                {
                    //We can"t convert those.. and shouldn"t be any, too.
                    throw new ConversionException("[" + TES4FunctionName + "] Cannot set attributes on non-player");
                }

                const string functionName = "SetValue";
                calledOn = this.referenceFactory.CreateReference(TES5ReferenceFactory.TES4Attr + PHPFunction.UCWords(firstArgStringLower), globalScope, multipleScriptsScope, localScope);
                ITES4StringValue secondArg = functionArguments[1];
                convertedArguments.Add(this.valueFactory.CreateValue(secondArg, codeScope, globalScope, multipleScriptsScope));
                return(CreateObjectCall(calledOn, functionName, multipleScriptsScope, convertedArguments));
            }

            case "speed":
            {
                const string     functionName = "ForceMovementSpeed";
                ITES4StringValue secondArg    = functionArguments[1];
                convertedArguments.Add(this.valueFactory.CreateValue(secondArg, codeScope, globalScope, multipleScriptsScope));
                return(CreateObjectCall(calledOn, functionName, multipleScriptsScope, convertedArguments));
            }

            case "fatigue":
            case "armorer":
            case "security":
            case "acrobatics":
            case "mercantile":
            case "mysticism":     //It doesn"t exist in Skyrim - defaulting to Illusion..
            case "blade":
            case "blunt":
            case "encumbrance":
            case "spellabsorbchance":
            case "resistfire":
            case "resistfrost":
            case "resistdisease":
            case "resistmagic":
            case "resistpoison":
            case "resistshock":
            {
                convertedArguments.Add(new TES5String(actorValueMap[firstArgStringLower]));
                ITES4StringValue secondArg = functionArguments[1];
                convertedArguments.Add(this.valueFactory.CreateValue(secondArg, codeScope, globalScope, multipleScriptsScope));
                return(CreateObjectCall(calledOn, TES5FunctionName, multipleScriptsScope, convertedArguments));
            }

            case "aggression":
            {
                ITES4StringValue     secondArg            = functionArguments[1];
                object               secondArgObject      = secondArg.Data;
                Nullable <int>       secondArgNullableInt = secondArgObject as Nullable <int>;
                AST.Value.ITES5Value convertedArgument2;
                if (secondArgNullableInt != null)
                {        //WTM:  Change:  This apparently went unnoticed in the PHP version.  The second argument is not always an integer.  Sometimes its a variable reference.
                    //But the value of the variable will not be properly scaled to the values below, so the converted script may operate incorrectly.
                    int   secondArgInt = secondArgNullableInt.Value;
                    float newValue;
                    if (secondArgInt == 0)
                    {
                        newValue = 0;
                    }
                    else if (secondArgInt > 0 && secondArgInt < 50)
                    {
                        newValue = 1;
                    }
                    else if (secondArgInt >= 50 && secondArgInt < 80)
                    {
                        newValue = 2;
                    }
                    else
                    {
                        newValue = 3;
                    }
                    convertedArgument2 = new TES5Float(newValue);
                }
                else
                {
                    convertedArgument2 = this.valueFactory.CreateValue(secondArg, codeScope, globalScope, multipleScriptsScope);
                }

                convertedArguments.Add(new TES5String(firstArgString));
                convertedArguments.Add(convertedArgument2);
                return(CreateObjectCall(calledOn, TES5FunctionName, multipleScriptsScope, convertedArguments));
            }

            case "confidence":
            {
                ITES4StringValue secondArg = functionArguments[1];
                int   secondArgData        = (int)secondArg.Data;
                float newValue;
                if (secondArgData == 0)
                {
                    newValue = 0;
                }
                else if (secondArgData > 0 && secondArgData < 30)
                {
                    newValue = 1;
                }
                else if (secondArgData >= 30 && secondArgData < 70)
                {
                    newValue = 2;
                }
                else if (secondArgData >= 70 && secondArgData < 99)
                {
                    newValue = 3;
                }
                else
                {
                    newValue = 4;
                }

                convertedArguments.Add(new TES5String(firstArgString));
                convertedArguments.Add(new TES5Float(newValue));
                return(CreateObjectCall(calledOn, TES5FunctionName, multipleScriptsScope, convertedArguments));
            }

            default:
            {
                convertedArguments.Add(new TES5String(firstArgString));
                ITES4StringValue secondArg = functionArguments[1];
                convertedArguments.Add(this.valueFactory.CreateValue(secondArg, codeScope, globalScope, multipleScriptsScope));
                return(CreateObjectCall(calledOn, TES5FunctionName, multipleScriptsScope, convertedArguments));
            }
            }
        }
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            const string          functionName      = "playGamebryoAnimation";
            TES4FunctionArguments functionArguments = function.Arguments;
            //this function does not use strings for the names, so i cant really understand what is it.
            //todo refactor
            TES5ObjectCallArguments convertedArguments = new TES5ObjectCallArguments();
            ITES4StringValue        firstArg           = functionArguments[0];

            convertedArguments.Add(new TES5String(firstArg.StringValue));

            /*
             * secondArg = functionArguments.getValue(1);
             *
             * if (secondArg && secondArg.getData() != 0) {
             *  convertedArguments.add(new TES5Integer(1));
             * }*/
            convertedArguments.Add(new TES5Bool(true));
            return(this.objectCallFactory.CreateObjectCall(calledOn, functionName, convertedArguments));
        }
 private void SetUpBranch(TES4CodeBlock block, TES5EventCodeBlock newBlock, TES5FunctionScope blockFunctionScope, TES5LocalVariableParameterMeaning variable, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
 {
     SetUpBranch(block, newBlock, blockFunctionScope, newBlock.CodeScope.LocalScope.GetVariableWithMeaning(variable), globalScope, multipleScriptsScope);
 }
Ejemplo n.º 26
0
 public abstract ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope);
Ejemplo n.º 27
0
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES4FunctionArguments functionArguments = function.Arguments;
            string functionName = function.FunctionCall.FunctionName;
            TES5ObjectCallArguments methodArguments = new TES5ObjectCallArguments()
            {
                new TES5Bool(true)//override different behaviour
            };
            ITES4StringValue lockAsOwnerBool = functionArguments.GetOrNull(1);
            bool             newLockBool     = lockAsOwnerBool != null && (int)lockAsOwnerBool.Data == 1;

            methodArguments.Add(new TES5Bool(newLockBool));
            return(this.objectCallFactory.CreateObjectCall(calledOn, functionName, multipleScriptsScope, methodArguments));
        }
Ejemplo n.º 28
0
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES4FunctionArguments functionArguments = function.Arguments;
            TES5ObjectCall        functionThis      = this.objectCallFactory.CreateObjectCall(this.objectCallFactory.CreateGetActorBase(calledOn, multipleScriptsScope), "GetSex", multipleScriptsScope);
            int operand;

            switch ((functionArguments[0].StringValue).ToLower())
            {
            case "male":
            {
                operand = 0;
                break;
            }

            case "female":
            {
                operand = 1;
                break;
            }

            default:
            {
                throw new ConversionException("GetIsSex used with unknown gender.");
            }
            }

            TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(functionThis, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Integer(operand));

            return(expression);
        }
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5LocalScope localScope = codeScope.LocalScope;

            return(this.referenceFactory.CreateReadReference(TES5ReferenceFactory.MESSAGEBOX_VARIABLE_CONST, globalScope, multipleScriptsScope, localScope));
        }
Ejemplo n.º 30
0
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            const string          functionName      = "QueryStat";
            ITES5Referencer       newCalledOn       = TES5StaticReferenceFactory.Game;
            TES4FunctionArguments functionArguments = function.Arguments;
            int    oldArgValue = (int)functionArguments.Single().Data;
            string newArgValue = statMap[oldArgValue];
            TES4FunctionArguments tes4Arguments = new TES4FunctionArguments()
            {
                new TES4String(newArgValue)
            };
            TES5ObjectCallArguments tes5Arguments = objectCallArgumentsFactory.CreateArgumentList(tes4Arguments, codeScope, globalScope, multipleScriptsScope);

            return(objectCallFactory.CreateObjectCall(newCalledOn, functionName, tes5Arguments));
        }