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 TES5ObjectCallArguments CreateArgumentList(TES4FunctionArguments arguments, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES5ObjectCallArguments list = new TES5ObjectCallArguments(); if (arguments == null) { return(list); } list.AddRange(arguments.Select(a => this.valueFactory.CreateValue(a, codeScope, globalScope, multipleScriptsScope))); return(list); }
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 = TES5StaticReference.Debug; return(this.objectCallFactory.CreateObjectCall(calledOnRef, "MessageBox", multipleScriptsScope, this.objectCallArgumentsFactory.CreateArgumentList(functionArguments, codeScope, globalScope, multipleScriptsScope))); } else { string edid = NameTransformer.GetEscapedName(string.Join("", functionArguments.Select(v => v.StringValue)), TES5TypeFactory.TES4Prefix + "MessageBox_", true);//WTM: Change: PHPFunction.MD5(PHPFunction.Serialize(functionArguments.getValues())) IEnumerable <string> messageArguments = (new string[] { edid }).Concat(functionArguments.Select(a => a.StringValue)); this.metadataLogService.WriteLine("ADD_MESSAGE", messageArguments); ITES5Referencer messageBoxResult = this.referenceFactory.CreateReadReference(TES5ReferenceFactory.MESSAGEBOX_VARIABLE_CONST, globalScope, multipleScriptsScope, localScope); ITES5Referencer reference = this.referenceFactory.CreateReadReference(edid, globalScope, multipleScriptsScope, localScope); return(TES5VariableAssignationFactory.CreateAssignation(messageBoxResult, this.objectCallFactory.CreateObjectCall(reference, "show", 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)); } }