Example #1
0
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5LocalScope        localScope        = codeScope.LocalScope;
            TES4FunctionArguments functionArguments = function.Arguments;
            string          arg0String      = functionArguments[0].StringValue;
            ITES5Referencer targetReference = this.referenceFactory.CreateReadReference(arg0String, globalScope, multipleScriptsScope, localScope);
            var             arg0Type        = targetReference.TES5Type;
            string          functionName;
            ITES5Referencer baseReference;

            if (TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(arg0Type, TES5BasicType.T_ACTORBASE))
            {
                functionName  = "GetActorOwner";
                baseReference = targetReference;
            }
            else if (TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(arg0Type, TES5BasicType.T_ACTOR))
            {
                functionName  = "GetActorOwner";
                baseReference = this.objectCallFactory.CreateGetActorBase(targetReference);
            }
            else if (TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(arg0Type, TES5BasicType.T_FACTION))
            {
                functionName  = "GetFactionOwner";
                baseReference = targetReference;
            }
            else
            {
                throw new ConversionException(function.FunctionCall.FunctionName + " should be called with either an ActorBase or a Faction.");
            }
            TES5ObjectCall           owner      = this.objectCallFactory.CreateObjectCall(calledOn, functionName);
            TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(owner, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, baseReference);

            return(expression);
        }
Example #2
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;
                }
            }
        }
Example #3
0
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5LocalScope        localScope        = codeScope.LocalScope;
            TES4FunctionArguments functionArguments = function.Arguments;

            //todo Refactor - add floating point vars .
            if (functionArguments.Count == 1)
            {
                TES5StaticReference calledOnRef = TES5StaticReferenceFactory.Debug;
                return(this.objectCallFactory.CreateObjectCall(calledOnRef, "MessageBox", this.objectCallArgumentsFactory.CreateArgumentList(functionArguments, codeScope, globalScope, multipleScriptsScope)));
            }
            else
            {
                string[]             stringArguments  = functionArguments.Select(v => v.StringValue).ToArray();
                string               edid             = messageBoxData.GetEDID(stringArguments);
                IEnumerable <string> messageArguments = (new string[] { edid }).Concat(functionArguments.Select(a => a.StringValue));
                this.metadataLogService.WriteLine("ADD_MESSAGE", messageArguments);
                Nullable <int> tes5FormIDNullable = messageBoxData.GetTES5FormID(edid);
                TES5Property   messageBoxProperty = TES5PropertyFactory.ConstructWithTES5FormID(edid, TES5BasicType.T_MESSAGE, edid, tes5FormIDNullable);
                globalScope.AddProperty(messageBoxProperty);
                ITES5Referencer messageBoxReference = TES5ReferenceFactory.CreateReferenceToVariableOrProperty(messageBoxProperty);
                TES5ObjectCall  messageBoxShow      = this.objectCallFactory.CreateObjectCall(messageBoxReference, "Show");
                ITES5Referencer messageBoxResult    = this.referenceFactory.CreateReadReference(TES5ReferenceFactory.MESSAGEBOX_VARIABLE_CONST, globalScope, multipleScriptsScope, localScope);
                return(TES5VariableAssignationFactory.CreateAssignation(messageBoxResult, messageBoxShow));
            }
        }
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            //GetInCell checks if a cell name starts with the argument string:  https://cs.elderscrolls.com/index.php?title=GetInCell
            //The below will probably not always work.
            TES4FunctionArguments functionArguments    = function.Arguments;
            ITES4StringValue      apiToken             = functionArguments[0];
            string                  cellName           = apiToken.StringValue;
            TES5ObjectCall          getParentCell      = this.objectCallFactory.CreateObjectCall(calledOn, "GetParentCell", multipleScriptsScope);
            TES5ObjectCall          getParentCellName  = this.objectCallFactory.CreateObjectCall(getParentCell, "GetName", multipleScriptsScope);
            int                     length             = cellName.Length;
            TES5ObjectCallArguments substringArguments = new TES5ObjectCallArguments()
            {
                getParentCellName,
                new TES5Integer(0),
                new TES5Integer(length)
            };
            TES5ObjectCall   substring          = this.objectCallFactory.CreateObjectCall(TES5StaticReference.StringUtil, "Substring", multipleScriptsScope, substringArguments);
            TES4LoadedRecord cellRecord         = ESMAnalyzer._instance().FindInTES4Collection(cellName, false);
            string           cellNameWithSpaces = cellRecord.GetSubrecordTrim("FULL");

            if (cellNameWithSpaces == null)
            {
                cellNameWithSpaces = cellName;
            }
            TES5String cellNameTES5String = new TES5String(cellNameWithSpaces);

            return(TES5ExpressionFactory.CreateComparisonExpression(substring, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, cellNameTES5String));
        }
Example #5
0
 //WTM:  Change:  Added
 private static bool CanConvertGetItemCountSpecialCases(TES5ObjectCall value1ObjectCall, TES5ComparisonExpressionOperator op, TES5Integer value2Integer)
 {
     if (op == TES5ComparisonExpressionOperator.OPERATOR_EQUAL && value2Integer.IntValue == 1)//Special cases
     {
         //I checked the meaning of these scripts, and ContainsItem is a suitable replacement.
         if (value1ObjectCall.AccessedObject.Name == "MethredhelsChestRef_p" && ((TES5Reference)value1ObjectCall.Arguments[0]).Name == "TG01AmantiusDiary_p")
         {
             return(true);
         }                                                                                                                                                                    //TES4methredhelscript.psc
         else if (value1ObjectCall.AccessedObject is TES5SelfReference)
         {
             if (
                 ((TES5Reference)value1ObjectCall.Arguments[0]).Name == "Dark07RoderickPoison_p" || //TES4dark07cabinetscript.psc
                 ((TES5Reference)value1ObjectCall.Arguments[0]).Name == "Dark09Finger_p"            //TES4dark09deskscript.psc
                 )
             {
                 return(true);
             }
         }
         else if (value1ObjectCall.AccessedObject.Name == "TG03MyvrynasCupboardRef_p" && ((TES5Reference)value1ObjectCall.Arguments[0]).Name == "TG03LlathasasBust_p")
         {
             return(true);
         }                                                                                                                                                                             //TES4hieronymuslexscript.psc and tif__010034a3.psc
         //TES4orumgangcourier1script.psc:  functionality of fake Skooma rock explained here:  https://en.uesp.net/wiki/Oblivion:Camonna_Tong_Thug
         //Skooma is added to the fake rock if the rock has zero or one Skooma bottles, reaching a maximum of two bottles.
         //If I use ContainsItem, the rock will only reach a maximum of one bottle.
         //If I use GetItemCount, the rock will apparently fill infinitely.
         //I'll need to check this later.  @INCONSISTENCE
     }
     return(false);
 }
Example #6
0
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5LocalScope        localScope        = codeScope.LocalScope;
            TES4FunctionArguments functionArguments = function.Arguments;
            int arg;

            switch (((TES4Integer)functionArguments[1]).IntValue)
            {
            case 0:
            {
                arg = 0;
                break;
            }

            case 1:
            {
                arg = 1000;
                break;
            }

            default:
            {
                throw new ConversionException("SetPCFactionMurder/SetPCFactionAttack argument unknown");
            }
            }

            TES5ObjectCallArguments constantArgument = new TES5ObjectCallArguments()
            {
                new TES5Integer(arg)
            };
            ITES5Referencer faction     = this.referenceFactory.CreateReadReference(functionArguments[0].StringValue, globalScope, multipleScriptsScope, localScope);
            TES5ObjectCall  newFunction = this.objectCallFactory.CreateObjectCall(faction, "SetCrimeGoldViolent", constantArgument);

            return(newFunction);
        }
Example #7
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 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);
        }
Example #9
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);
     }
 }
Example #10
0
        public List <ITES5CodeChunk> GenerateObjectiveHandling(ITES5CodeBlock codeBlock, TES5GlobalScope globalScope, List <int> stageMap)
        {
            TES5LocalVariable     castedToQuest   = new TES5LocalVariable("__temp", TES5BasicType.T_QUEST);
            TES5Reference         referenceToTemp = TES5ReferenceFactory.CreateReferenceToVariable(castedToQuest);
            List <ITES5CodeChunk> result          = new List <ITES5CodeChunk>()
            {
                TES5VariableAssignationFactory.CreateAssignation(referenceToTemp, TES5ReferenceFactory.CreateReferenceToSelf(globalScope))
            };
            TES5LocalScope localScope = codeBlock.CodeScope.LocalScope;

            localScope.AddVariable(castedToQuest);
            int i = 0;

            foreach (var stageTargetState in stageMap)
            {
                TES5Integer targetIndex = new TES5Integer(i);
                if (stageTargetState != 0)
                {
                    //Should be visible
                    TES5ObjectCallArguments displayedArguments = new TES5ObjectCallArguments()
                    {
                        targetIndex
                    };
                    TES5ObjectCall           isObjectiveDisplayed = new TES5ObjectCall(referenceToTemp, "IsObjectiveDisplayed", displayedArguments);
                    TES5ComparisonExpression expression           = TES5ExpressionFactory.CreateComparisonExpression(isObjectiveDisplayed, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Integer(0));
                    TES5ObjectCallArguments  arguments            = new TES5ObjectCallArguments()
                    {
                        targetIndex, new TES5Integer(1)
                    };
                    TES5ObjectCall showTheObjective = new TES5ObjectCall(referenceToTemp, "SetObjectiveDisplayed", arguments);
                    TES5Branch     branch           = TES5BranchFactory.CreateSimpleBranch(expression, localScope);
                    branch.MainBranch.CodeScope.AddChunk(showTheObjective);
                    result.Add(branch);
                }
                else
                {
                    TES5ObjectCallArguments displayedArguments = new TES5ObjectCallArguments()
                    {
                        targetIndex
                    };
                    TES5ObjectCall           isObjectiveDisplayed = new TES5ObjectCall(referenceToTemp, "IsObjectiveDisplayed", displayedArguments);
                    TES5ComparisonExpression expression           = TES5ExpressionFactory.CreateComparisonExpression(isObjectiveDisplayed, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Integer(1));
                    TES5ObjectCallArguments  arguments            = new TES5ObjectCallArguments()
                    {
                        targetIndex, new TES5Integer(1)
                    };
                    TES5ObjectCall completeTheObjective = new TES5ObjectCall(referenceToTemp, "SetObjectiveCompleted", arguments);
                    TES5Branch     branch = TES5BranchFactory.CreateSimpleBranch(expression, localScope);
                    branch.MainBranch.CodeScope.AddChunk(completeTheObjective);
                    result.Add(branch);
                }

                ++i;
            }

            return(result);
        }
Example #11
0
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES4FunctionArguments   functionArguments = function.Arguments;
            TES5ObjectCallArguments callArguments     = new TES5ObjectCallArguments();
            TES5ObjectCall          dummyX            = this.objectCallFactory.CreateObjectCall(calledOn, "GetPositionX", multipleScriptsScope);
            TES5ObjectCall          dummyY            = this.objectCallFactory.CreateObjectCall(calledOn, "GetPositionY", multipleScriptsScope);
            TES5ObjectCall          dummyZ            = this.objectCallFactory.CreateObjectCall(calledOn, "GetPositionZ", multipleScriptsScope);

            ITES5Value[] argList;
            switch ((functionArguments[0].StringValue).ToLower())
            {
            case "x":
            {
                argList = new ITES5Value[]
                {
                    this.valueFactory.CreateValue(functionArguments[1], codeScope, globalScope, multipleScriptsScope),
                    dummyY,
                    dummyZ
                };
                break;
            }

            case "y":
            {
                argList = new ITES5Value[]
                {
                    dummyX,
                    this.valueFactory.CreateValue(functionArguments[1], codeScope, globalScope, multipleScriptsScope),
                    dummyZ
                };
                break;
            }

            case "z":
            {
                argList = new ITES5Value[]
                {
                    dummyX,
                    dummyY,
                    this.valueFactory.CreateValue(functionArguments[1], codeScope, globalScope, multipleScriptsScope)
                };
                break;
            }

            default:
            {
                throw new ConversionException("setPos can handle only X,Y,Z parameters.");
            }
            }

            foreach (var argListC in argList)
            {
                callArguments.Add(argListC);
            }

            return(this.objectCallFactory.CreateObjectCall(calledOn, "SetPosition", multipleScriptsScope, callArguments));
        }
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5LocalScope           localScope        = codeScope.LocalScope;
            TES4FunctionArguments    functionArguments = function.Arguments;
            TES5ObjectCall           functionThis      = this.objectCallFactory.CreateObjectCall(calledOn, "GetWorldSpace");
            ITES5Referencer          argument          = this.referenceFactory.CreateReadReference(functionArguments[0].StringValue, globalScope, multipleScriptsScope, localScope);
            TES5ComparisonExpression expression        = TES5ExpressionFactory.CreateComparisonExpression(functionThis, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, argument);

            return(expression);
        }
Example #13
0
        public TES5ObjectCall CreateObjectCall(ITES5Referencer callable, string functionName, TES5MultipleScriptsScope multipleScriptsScope, TES5ObjectCallArguments arguments = null, bool inference = true)
        {
            TES5ObjectCall objectCall = new TES5ObjectCall(callable, functionName, arguments);

            if (inference)
            {
                this.typeInferencer.InferenceObjectByMethodCall(objectCall, multipleScriptsScope);
            }
            return(objectCall);
        }
Example #14
0
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5LocalScope          localScope = codeScope.LocalScope;
            TES5ObjectCallArguments arguments  = new TES5ObjectCallArguments();
            ITES5Referencer         loc        = this.referenceFactory.CreateReadReference("SEWorldLocation", globalScope, multipleScriptsScope, localScope);

            arguments.Add(loc);
            TES5ObjectCall exp = this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToPlayer(), "IsInLocation", multipleScriptsScope, arguments);

            return(exp);
        }
Example #15
0
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5LocalScope           localScope                 = codeScope.LocalScope;
            TES4FunctionArguments    functionArguments          = function.Arguments;
            ITES5Referencer          functionArgument0Reference = this.referenceFactory.CreateReadReference(functionArguments[0].StringValue, globalScope, multipleScriptsScope, localScope);
            TES5ObjectCall           leftParentCell             = this.objectCallFactory.CreateObjectCall(calledOn, "GetParentCell");
            TES5ObjectCall           rightParentCell            = this.objectCallFactory.CreateObjectCall(functionArgument0Reference, "GetParentCell");
            TES5ComparisonExpression expression                 = TES5ExpressionFactory.CreateComparisonExpression(leftParentCell, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, rightParentCell);

            return(expression);
        }
Example #16
0
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES4FunctionArguments   functionArguments = function.Arguments;
            TES5ObjectCallArguments constantArgument  = new TES5ObjectCallArguments()
            {
                new TES5Bool(((TES4Integer)functionArguments[0]).IntValue == 1)
            };
            TES5ObjectCall newFunction = this.objectCallFactory.CreateObjectCall(calledOn, "SetOpen", multipleScriptsScope, constantArgument);

            return(newFunction);
        }
Example #17
0
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES5LocalScope        localScope        = codeScope.LocalScope;
            TES4FunctionArguments functionArguments = function.Arguments;
            //Made in post-analysis
            TES5ObjectCall           race         = this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToPlayer(globalScope), "GetRace");
            ITES5Referencer          checkAgainst = this.referenceFactory.CreateReadReference(functionArguments[0].StringValue, globalScope, multipleScriptsScope, localScope);
            TES5ComparisonExpression expression   = TES5ExpressionFactory.CreateComparisonExpression(race, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, checkAgainst);

            return(expression);
        }
        public TES5CodeChunkCollection CreateCodeChunkCollection(TES5FunctionScope functionScope, TES5GlobalScope globalScope)
        {
            TES5CodeChunkCollection collection = new TES5CodeChunkCollection();

            if (functionScope.BlockName == "OnUpdate")
            {
                TES5ObjectCall function = this.objectCallFactory.CreateRegisterForSingleUpdate(globalScope);
                collection.Add(function);
            }
            collection.Add(new TES5Return());
            return(collection);
        }
        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("Infamy", globalScope, multipleScriptsScope, localScope);
            TES5ObjectCallArguments  fameArguments        = new TES5ObjectCallArguments();
            TES5ArithmeticExpression arithmeticExpression = TES5ExpressionFactory.CreateArithmeticExpression(fameReference, TES5ArithmeticExpressionOperator.OPERATOR_ADD, new TES5Integer(((TES4Integer)functionArguments[0]).IntValue));

            fameArguments.Add(arithmeticExpression);
            TES5ObjectCall newFunction = this.objectCallFactory.CreateObjectCall(this.referenceFactory.CreateReference("Infamy", globalScope, multipleScriptsScope, localScope), "SetValue", fameArguments);

            return(newFunction);
        }
Example #20
0
        private void InferenceTypeOfMethodArguments(TES5ObjectCall objectCall)
        {
            /*
             * Inference the arguments
             */
            int argumentIndex = 0;

            foreach (ITES5Value argument in objectCall.Arguments)
            {
                InferenceTypeOfMethodArgument(objectCall, argument, argumentIndex);
                argumentIndex++;
            }
        }
Example #21
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++;
            }
        }
Example #22
0
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            const string          functionName      = "SetCombatStyle";
            TES4FunctionArguments functionArguments = function.Arguments;

            if (functionArguments.Count == 0)
            {
                return(logUnknownFunctionFactory.CreateLogCall(function));
            }
            TES5ObjectCall          getActorBase = this.objectCallFactory.CreateGetActorBase(calledOn);
            TES5ObjectCallArguments newArguments = this.objectCallArgumentsFactory.CreateArgumentList(functionArguments, codeScope, globalScope, multipleScriptsScope);

            return(this.objectCallFactory.CreateObjectCall(getActorBase, functionName, newArguments));
        }
Example #23
0
        public TES5ObjectCall CreateObjectCall(ITES5Referencer callable, string functionName, TES5ObjectCallArguments?arguments = null, bool inference = true)
        {
            if (arguments == null)
            {
                arguments = new TES5ObjectCallArguments();
            }
            TES5ObjectCall objectCall = new TES5ObjectCall(callable, functionName, arguments);

            if (inference)
            {
                this.typeInferencer.InferenceObjectByMethodCall(objectCall);
            }
            return(objectCall);
        }
        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 ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            ITES5Referencer         newCalledOn   = TES5StaticReference.Game;
            const string            functionName  = "SetInChargen";
            bool                    argumentBool  = ((TES4Integer)function.Arguments[0]).IntValue == 1;
            ITES5Value              argumentValue = new TES5Bool(argumentBool);
            TES5ObjectCallArguments arguments     = new TES5ObjectCallArguments()
            {
                argumentValue, argumentValue, argumentValue
            };
            TES5ObjectCall newFunction = this.objectCallFactory.CreateObjectCall(newCalledOn, functionName, multipleScriptsScope, arguments);

            return(newFunction);
        }
Example #26
0
        private TES5FunctionCodeBlock GetGetArmorRatingOfWornFormFunctionCodeBlock(ITES5Referencer calledOn, TES5CodeScope codeScope)
        {
            TES5FunctionCodeBlock  functionCodeBlock = new TES5FunctionCodeBlock(new TES5FunctionScope(functionName), TES5CodeScopeFactory.CreateCodeScope(codeScope.LocalScope), TES5BasicType.T_INT, false, false);
            TES5SignatureParameter slotMaskParameter = new TES5SignatureParameter("slotMask", TES5BasicType.T_INT, true);

            functionCodeBlock.FunctionScope.AddParameter(slotMaskParameter);
            TES5ObjectCall    getWornForm      = GetGetWornFormObjectCall(calledOn, TES5ReferenceFactory.CreateReferenceToVariableOrProperty(slotMaskParameter));
            TES5LocalVariable wornFormVariable = new TES5LocalVariable("wornForm", TES5BasicType.T_ARMOR);

            functionCodeBlock.CodeScope.AddVariable(wornFormVariable);
            TES5Reference wornFormVariableReference = TES5ReferenceFactory.CreateReferenceToVariableOrProperty(wornFormVariable);

            functionCodeBlock.AddChunk(TES5VariableAssignationFactory.CreateAssignation(wornFormVariableReference, getWornForm));
            functionCodeBlock.AddChunk(new TES5Return(objectCallFactory.CreateObjectCall(wornFormVariableReference, "GetArmorRating")));
            return(functionCodeBlock);
        }
Example #27
0
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES4FunctionArguments functionArguments = function.Arguments;
            TES5ObjectCall        startSneaking     = this.objectCallFactory.CreateObjectCall(calledOn, "StartSneaking", multipleScriptsScope);

            if (((TES4Integer)functionArguments[0]).IntValue == 0)
            {
                //WTM:  Change:  Since StartSneaking toggles sneaking, we check if the TES4 code wants the user to stop sneaking.
                //If so, if the user is sneaking, call StartSneaking, which actually stops sneaking if already sneaking.
                TES5ObjectCall           isSneaking          = this.objectCallFactory.CreateObjectCall(calledOn, "IsSneaking", multipleScriptsScope);
                TES5ComparisonExpression playerIsNotSneaking = TES5ExpressionFactory.CreateComparisonExpression(isSneaking, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Bool(true));
                TES5Branch branch = TES5BranchFactory.CreateSimpleBranch(playerIsNotSneaking, codeScope.LocalScope);
                branch.MainBranch.CodeScope.AddChunk(startSneaking);
                return(branch);
            }
            return(startSneaking);
        }
Example #28
0
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            //WTM:  Added:  This is to prevent these Papyrus messages:

            /*
             * Actor is dead, cannot start combat.
             * Actor has no AI process, cannot start combat. [I might need to use Actor.IsAIEnabled or even Actor.EnableAI(True).]
             */
            TES5ObjectCall           isDeadCall        = this.objectCallFactory.CreateObjectCall(calledOn, "IsDead");
            TES5ComparisonExpression isNotDead         = TES5ExpressionFactory.CreateComparisonExpression(isDeadCall, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Bool(false));
            TES4FunctionArguments    functionArguments = function.Arguments;
            TES5ObjectCallArguments  newArguments      = this.objectCallArgumentsFactory.CreateArgumentList(functionArguments, codeScope, globalScope, multipleScriptsScope);
            TES5ObjectCall           startCombatCall   = this.objectCallFactory.CreateObjectCall(calledOn, "StartCombat", newArguments);
            TES5Branch ifNotDeadStartCombat            = TES5BranchFactory.CreateSimpleBranch(isNotDead, codeScope.LocalScope);

            ifNotDeadStartCombat.MainBranch.CodeScope.AddChunk(startCombatCall);
            return(ifNotDeadStartCombat);
        }
        public List <ITES5CodeChunk> GenerateObjectiveHandling(ITES5CodeBlock codeBlock, TES5GlobalScope globalScope, List <int> stageMap)
        {
            List <ITES5CodeChunk> result = new List <ITES5CodeChunk>();

            //WTM:  Change:
            if (!stageMap.Any())
            {
                return(result);
            }
            TES5LocalVariable       castedToQuest        = new TES5LocalVariable("__temp", TES5BasicType.T_QUEST);//WTM:  Note:  Why is this variable even necessary?
            TES5Reference           referenceToTemp      = TES5ReferenceFactory.CreateReferenceToVariableOrProperty(castedToQuest);
            TES5SelfReference       questSelfReference   = TES5ReferenceFactory.CreateReferenceToSelf(globalScope);
            TES5VariableAssignation tempQuestAssignation = TES5VariableAssignationFactory.CreateAssignation(referenceToTemp, questSelfReference);

            result.Add(tempQuestAssignation);
            TES5LocalScope localScope = codeBlock.CodeScope.LocalScope;

            localScope.AddVariable(castedToQuest);
            int i = 0;

            foreach (var stageTargetState in stageMap)
            {
                TES5Integer             targetIndex        = new TES5Integer(i);
                TES5ObjectCallArguments displayedArguments = new TES5ObjectCallArguments()
                {
                    targetIndex
                };
                TES5ObjectCall           isObjectiveDisplayed         = objectCallFactory.CreateObjectCall(referenceToTemp, "IsObjectiveDisplayed", displayedArguments, inference: false);
                int                      isObjectiveDisplayedArgument = stageTargetState != 0 ? 0 : 1;
                TES5ComparisonExpression expression = TES5ExpressionFactory.CreateComparisonExpression(isObjectiveDisplayed, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Integer(isObjectiveDisplayedArgument));
                TES5ObjectCallArguments  arguments  = new TES5ObjectCallArguments()
                {
                    targetIndex, new TES5Integer(1)
                };
                string         setObjectiveFunction   = stageTargetState != 0 ? "SetObjectiveDisplayed" : "SetObjectiveCompleted";
                TES5ObjectCall setObjectiveObjectCall = objectCallFactory.CreateObjectCall(referenceToTemp, setObjectiveFunction, arguments, inference: false);
                TES5Branch     branch = TES5BranchFactory.CreateSimpleBranch(expression, localScope);
                branch.MainBranch.CodeScope.AddChunk(setObjectiveObjectCall);
                result.Add(branch);
                ++i;
            }

            return(result);
        }
        public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope)
        {
            TES4FunctionArguments functionArguments = function.Arguments;
            ITES4StringValue      apiToken          = functionArguments[0];
            string       cellEditorID = apiToken.StringValue;
            string       locationPropertyNameWithoutSuffix = cellEditorID + "Location";
            string       locationPropertyNameWithSuffix    = TES5Property.AddPropertyNameSuffix(locationPropertyNameWithoutSuffix);
            TES5Property?locationProperty = globalScope.TryGetPropertyByName(locationPropertyNameWithSuffix);

            if (locationProperty == null)
            {
                int tes5LocationFormID;
                if (cellToLocationFinder.TryGetLocationFormID(cellEditorID, out tes5LocationFormID))
                {
                    locationProperty = TES5PropertyFactory.ConstructWithTES5FormID(locationPropertyNameWithoutSuffix, TES5BasicType.T_LOCATION, null, tes5LocationFormID);
                    globalScope.AddProperty(locationProperty);
                }
                else
                {
                    TES5ObjectCall getParentCell      = this.objectCallFactory.CreateObjectCall(calledOn, "GetParentCell");
                    TES5ObjectCall getParentCellName  = this.objectCallFactory.CreateObjectCall(getParentCell, "GetName");
                    TES4Record     cellRecord         = this.esmAnalyzer.GetRecordByEDIDInTES4Collection(cellEditorID);
                    string?        cellNameWithSpaces = cellRecord.TryGetSubrecordTrim("FULL");
                    if (cellNameWithSpaces == null || cellNameWithSpaces.IndexOf("Dummy", StringComparison.OrdinalIgnoreCase) != -1)
                    {
                        cellNameWithSpaces = cellEditorID;
                    }
                    TES5String cellNameTES5String         = new TES5String(cellNameWithSpaces);
                    TES5ObjectCallArguments findArguments = new TES5ObjectCallArguments()
                    {
                        getParentCellName,
                        cellNameTES5String
                    };
                    TES5ObjectCall substring = this.objectCallFactory.CreateObjectCall(TES5StaticReferenceFactory.StringUtil, "Find", findArguments);
                    return(TES5ExpressionFactory.CreateComparisonExpression(substring, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Integer(0)));
                }
            }
            TES5Reference locationReference = TES5ReferenceFactory.CreateReferenceToVariableOrProperty(locationProperty);

            return(this.objectCallFactory.CreateObjectCall(calledOn, "IsInLocation", new TES5ObjectCallArguments()
            {
                locationReference
            }));
        }