public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES4FunctionArguments functionArguments = function.Arguments; int arg0 = (int)functionArguments.Pop(0).Data; string functionName; switch (arg0) { case 0: { functionName = "SheatheWeapon"; break; } case 1: { functionName = "DrawWeapon"; break; } default: { throw new ConversionException("Unknown setAlert value, must be 0 or 1"); } } TES5ObjectCallArguments newArguments = this.objectCallArgumentsFactory.CreateArgumentList(functionArguments, codeScope, globalScope, multipleScriptsScope); return(this.objectCallFactory.CreateObjectCall(calledOn, functionName, newArguments)); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES4FunctionArguments functionArguments = function.Arguments; string arg0 = functionArguments.Pop(0).StringValue; string arg0Upper = arg0.ToUpper(); if (arg0Upper != "X" && arg0Upper != "Y" && arg0Upper != "Z") { throw new ConversionException("getPos can handle only X,Y,Z parameters."); } string functionName = "GetPosition" + arg0Upper; return(this.objectCallFactory.CreateObjectCall(calledOn, functionName, this.objectCallArgumentsFactory.CreateArgumentList(functionArguments, codeScope, globalScope, multipleScriptsScope))); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES4FunctionArguments functionArguments = function.Arguments; string arg0 = functionArguments.Pop(0).StringValue; string arg0Lower = arg0.ToLower(); if (arg0Lower != "x" && arg0Lower != "y" && arg0Lower != "z") { throw new ConversionException("getAngle can handle only X,Y,Z parameters."); } string functionName = "GetAngle" + PHPFunction.UCWords(arg0); TES5ObjectCallArguments newArguments = this.objectCallArgumentsFactory.CreateArgumentList(functionArguments, codeScope, globalScope, multipleScriptsScope); return(this.objectCallFactory.CreateObjectCall(calledOn, functionName, multipleScriptsScope, newArguments)); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES5LocalScope localScope = codeScope.LocalScope; TES4FunctionArguments functionArguments = function.Arguments; string newCalledOnString = functionArguments.Pop(0).StringValue; ITES5Referencer newCalledOn = this.referenceFactory.CreateReadReference(newCalledOnString, globalScope, multipleScriptsScope, localScope); if (!TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(newCalledOn.TES5Type, TES5BasicType.T_ACTORBASE)) { if (TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(newCalledOn.TES5Type, TES5BasicType.T_ACTOR)) { newCalledOn = this.objectCallFactory.CreateGetActorBase(newCalledOn); } else { throw new ConversionException(newFunctionName + " should be called with an ActorBase. Instead, it was called with " + newCalledOnString + " (" + newCalledOn.TES5Type.OriginalName + " : " + newCalledOn.TES5Type.NativeType.Name + ")."); } } return(this.objectCallFactory.CreateObjectCall(newCalledOn, this.newFunctionName, this.objectCallArgumentsFactory.CreateArgumentList(functionArguments, codeScope, globalScope, multipleScriptsScope))); }
public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES5LocalScope localScope = codeScope.LocalScope; TES4FunctionArguments functionArguments = function.Arguments; string questName = functionArguments.Pop(0).StringValue; ITES5Referencer newCalledOn = this.referenceFactory.CreateReadReference(questName, globalScope, multipleScriptsScope, localScope); /* * Basically, there are some ugly mechanics in Oblivion. * Two quests ( FGInterimConversation and Arena* quest group ) are repeadetely started and stopped * However, Skyrim does not support this - once 0x13A byte is marked in a TESQuest, it won"t allow * to be started again. Hence, we need to call a Papyrus endpoint to stop the quest and * reset this field, and be able to reset the quest completely. */ TES5CodeChunkCollection codeChunks = new TES5CodeChunkCollection(); codeChunks.Add(this.objectCallFactory.CreateObjectCall(newCalledOn, "Stop", this.objectCallArgumentsFactory.CreateArgumentList(functionArguments, codeScope, globalScope, multipleScriptsScope))); if (questName == "FGInterimConversation" || questName == "ArenaIC" || questName == "ArenaICGrandChampion" || questName == "ArenaAggression" || questName == "ArenaAnnouncer" || questName == "ArenaDisqualification" || questName == "Arena") { codeChunks.Add(this.objectCallFactory.CreateObjectCall(newCalledOn, "PrepareForReinitializing", new TES5ObjectCallArguments())); } return(codeChunks); }
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 ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES4FunctionArguments functionArguments = function.Arguments; string messageString = functionArguments[0].StringValue; MatchCollection messageMatches = Regex.Matches(messageString, @"%([ +-0]*[1-9]*\.[0-9]+[ef]|g)"); if (messageMatches.Cast <Match>().Any(m => m.Success)) { //Pack the printf syntax //TODO - Perhaps we can use sprintf? ITES4StringValue arg0 = functionArguments.Pop(0); if (!(arg0 is TES4String)) { //hacky throw new ConversionException("Cannot transform printf like syntax to concat on string loaded dynamically"); } int i = 0; int caret = 0; //Example call: You have %.2f apples and %g boxes in your inventory, applesCount, boxesCount ITES5Value[] variablesArray = functionArguments.Select(a => this.valueFactory.CreateValue(a, codeScope, globalScope, multipleScriptsScope)).ToArray(); List <TES5String> stringsList = new List <TES5String>(); //Target: "You have ", " apples and ", " boxes in your inventory" bool startWithVariable = false; //Pretty ugly. Basically, if we start with a vairable, it should be pushed first from the variable stack and then string comes, instead of string , variable , and so on [...] while (caret < messageString.Length) { int stringBeforeStart = caret; //Set the start on the caret. Match match = i < messageMatches.Count ? messageMatches[i] : null; if (match != null) { int stringBeforeEnd = match.Index; int length = stringBeforeEnd - stringBeforeStart; if (caret == 0 && length == 0) { startWithVariable = true; } if (length > 0) { stringsList.Add(new TES5String(messageString.Substring(stringBeforeStart, length))); caret += length; } caret += match.Length; } else { stringsList.Add(new TES5String(messageString.Substring(stringBeforeStart))); caret = messageString.Length; } ++i; } List <ITES5Value> combinedValues = new List <ITES5Value>(); Stack <TES5String> stringsStack = new Stack <TES5String>(stringsList.Select(kvp => kvp).Reverse()); Stack <ITES5Value> variablesStack = new Stack <ITES5Value>(variablesArray.Select(kvp => kvp).Reverse()); if (startWithVariable) { if (variablesStack.Any()) { combinedValues.Add(variablesStack.Pop()); } } while (stringsStack.Any()) { combinedValues.Add(stringsStack.Pop()); if (variablesStack.Any()) { combinedValues.Add(variablesStack.Pop()); } } calledOn = TES5StaticReference.Debug; TES5ObjectCallArguments arguments = new TES5ObjectCallArguments() { TES5PrimitiveValueFactory.createConcatenatedValue(combinedValues) }; return(this.objectCallFactory.CreateObjectCall(calledOn, "Notification", multipleScriptsScope, arguments)); } else { calledOn = TES5StaticReference.Debug; TES5ObjectCallArguments arguments = new TES5ObjectCallArguments() { this.valueFactory.CreateValue(functionArguments[0], codeScope, globalScope, multipleScriptsScope) }; return(this.objectCallFactory.CreateObjectCall(calledOn, "Notification", multipleScriptsScope, arguments)); } }
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.Pop(0).StringValue, globalScope, multipleScriptsScope, localScope); TES5ObjectCallArguments newArguments = this.objectCallArgumentsFactory.CreateArgumentList(functionArguments, codeScope, globalScope, multipleScriptsScope); /*if (this.newFunctionName.Equals("SetStage", System.StringComparison.OrdinalIgnoreCase))//Useful for logging when stages get set * { * return new TES5CodeChunkCollection() * { * this.objectCallFactory.CreateObjectCall(newCalledOn, this.newFunctionName, newArguments), * this.objectCallFactory.CreateObjectCall(TES5StaticReferenceFactory.Debug, "MessageBox", new TES5ObjectCallArguments() { new TES5String("Setting "+newCalledOn.Name+" -> " + string.Join(", ", newArguments.Select(a=>a.Output.Single().Replace("\"", "q")))) }) * }; * }*/ return(this.objectCallFactory.CreateObjectCall(newCalledOn, this.newFunctionName, newArguments)); }