public override TES5Target Transpile(string sourcePath, string outputPath, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES4CodeChunks ast = ParseOrGetFromCache(sourcePath); TES4FragmentTarget fragmentTarget = new TES4FragmentTarget(ast, outputPath); TES5Target convertedScript = this.converter.Convert(fragmentTarget, globalScope, multipleScriptsScope); return convertedScript; }
public override TES5Target Transpile(string sourcePath, string outputPath, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES4Script script = ParseOrGetFromCache(sourcePath); TES4Target tes4Target = new TES4Target(script, outputPath); TES5Target target = this.converter.Convert(tes4Target, globalScope, multipleScriptsScope); return(target); }
public static void GenerateINFOAddTopicScripts(ESMAnalyzer esmAnalyzer, BuildTracker buildTracker, IBuildTarget tifBuildTarget) { TES5TypeInferencer typeInferencer = new TES5TypeInferencer(esmAnalyzer); TES5ObjectCallFactory objectCallFactory = new TES5ObjectCallFactory(typeInferencer); TES4TopicsToTES5GlobalVariableFinder globalVariableFinder = new TES4TopicsToTES5GlobalVariableFinder(); TES5GlobalVariables globalVariables = esmAnalyzer.GlobalVariables; var builtTIFs = buildTracker.GetBuiltScripts(BuildTargetFactory.TIFName); foreach (TES4Record infoRecord in esmAnalyzer.GetRecords().Where(r => r.RecordType == TES4RecordType.INFO)) { TES4SubrecordData[] names = infoRecord.GetSubrecords("NAME").ToArray(); if (names.Any()) { string fragment0Name = TES5FragmentFactory.GetFragmentName(0); string nameTES5FormIDHex = (infoRecord.FormID + 0x01000000).ToString("x8"); string scriptName = TES5ReferenceFactory.tif_Prefix + "_" + nameTES5FormIDHex; TES5Script? infoTIF = builtTIFs.Where(s => s.Key == scriptName).Select(s => s.Value.Script).FirstOrDefault(); TES5FunctionCodeBlock fragment0; if (infoTIF != null) { fragment0 = infoTIF.BlockList.Blocks.OfType <TES5FunctionCodeBlock>().Where(b => b.BlockName == fragment0Name).First(); } else { TES5ScriptHeader scriptHeader = TES5ScriptHeaderFactory.GetFromCacheOrConstructByBasicType(scriptName, TES5BasicType.T_TOPICINFO, TES5TypeFactory.TES4_Prefix, true); TES5GlobalScope globalScope = new TES5GlobalScope(scriptHeader); TES5FunctionScope functionScope = new TES5FunctionScope(fragment0Name); functionScope.AddParameter(new TES5SignatureParameter("akSpeakerRef", TES5BasicType.T_OBJECTREFERENCE, true)); TES5LocalScope localScope = new TES5LocalScope(functionScope); TES5CodeScope codeScope = TES5CodeScopeFactory.CreateCodeScope(localScope); fragment0 = new TES5FunctionCodeBlock(functionScope, codeScope, TES5VoidType.Instance, false, true); TES5BlockList blockList = new TES5BlockList() { fragment0 }; infoTIF = new TES5Script(globalScope, blockList, true); string outputPath = tifBuildTarget.GetTranspileToPath(scriptName); TES5Target target = new TES5Target(infoTIF, outputPath); buildTracker.RegisterBuiltScript(tifBuildTarget, target); } foreach (TES4SubrecordData name in names) { int formID = infoRecord.ExpandBytesIntoFormID(name); TES4Record addedTopic = esmAnalyzer.GetRecordByFormID(formID); Tuple <int, string>?globalVariable = globalVariableFinder.GetGlobalVariableNullable(addedTopic.FormID); string globalVariableEditorID = globalVariable != null ? globalVariable.Item2 : globalVariableFinder.GetGlobalVariableEditorID(addedTopic.GetEditorID()); Nullable <int> globalVariableTES5FormID = globalVariable != null ? globalVariable.Item1 : (Nullable <int>)null; TES5Property topicAddedProperty = TES5PropertyFactory.ConstructWithTES5FormID(globalVariableEditorID, TES5BasicType.T_GLOBALVARIABLE, globalVariableEditorID, globalVariableTES5FormID); infoTIF.GlobalScope.AddPropertyIfNotExists(topicAddedProperty); TES5Reference topicAddedReference = TES5ReferenceFactory.CreateReferenceToVariableOrProperty(topicAddedProperty); fragment0.AddChunk(objectCallFactory.CreateObjectCall(topicAddedReference, "SetValueInt", new TES5ObjectCallArguments() { new TES5Integer(1) })); } } } }
public void Write(IBuildTarget target, BuildTracker buildTracker, ProgressWriter progressWriter) { var scripts = buildTracker.GetBuiltScripts(target.Name).Values; List <TES5Target> connectedQuestFragments = new List <TES5Target>(); Dictionary <string, List <QuestStageScript> > jointScripts = new Dictionary <string, List <QuestStageScript> >(); /* * Scan manually for .map files in the QF scripts folder * Reason is that in case we"ve got a quest with no fragments to anything whatsoever, we"ll have to go * through it too ( just with empty subfragments trees ), to generate the objective handlings */ string sourcePath = target.GetSourcePath(); foreach (var mapFilePath in Directory.EnumerateFiles(sourcePath, "*.map") .Concat(Directory.EnumerateFiles(sourcePath, "*.map2"))) { string mapFileName = Path.GetFileNameWithoutExtension(mapFilePath); jointScripts.AddNewListIfNotContainsKey(mapFileName); } /* * Group the fragments together */ foreach (var script in scripts) { string[] parts = script.Script.ScriptHeader.OriginalScriptName.Split('_'); if (parts.Length < 3) { //Not able to categorize, probably wrong name of the fragment. continue; } string baseName = parts[0] + "_" + parts[1] + "_" + parts[2]; jointScripts.AddNewListIfNotContainsKeyAndAddValueToList(baseName, new QuestStageScript(script, int.Parse(parts[3], CultureInfo.InvariantCulture), int.Parse(parts[4], CultureInfo.InvariantCulture))); } const string joiningQFFragments = "Joining QF Fragments..."; progressWriter.Write(joiningQFFragments); foreach (var kvp in jointScripts) { var resultingFragmentName = kvp.Key; var subfragmentsTrees = kvp.Value; TES5Target joinedQF = this.QFFragmentFactory.JoinQFFragments(target, resultingFragmentName, subfragmentsTrees); connectedQuestFragments.Add(joinedQF); } progressWriter.ClearByPreviousProgress(joiningQFFragments); //WTM: Note: Subtract total scripts and add back connected quest fragments. int totalAddend = -scripts.Count + connectedQuestFragments.Count; progressWriter.ModifyTotalAndWrite(totalAddend); Write(connectedQuestFragments, progressWriter); }
public TES5Target Convert(TES5FragmentType fragmentType, TES4FragmentTarget fragmentTarget, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES5FunctionCodeBlock fragment = CreateFragment(fragmentType, 0, globalScope, multipleScriptsScope, fragmentTarget.CodeChunks); TES5BlockList blockList = new TES5BlockList() { fragment }; TES5Script script = new TES5Script(globalScope, blockList, true); TES5Target target = new TES5Target(script, fragmentTarget.OutputPath); return(target); }
/* * The script to be converted * The script"s global scope * The scope under which we"re converting * * @throws ConversionException */ public TES5Target Convert(TES4Target target, bool isStandalone, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES4Script script = target.Script; TES4BlockList?parsedBlockList = script.BlockList; Dictionary <string, List <ITES5CodeBlock> > createdBlocks = new Dictionary <string, List <ITES5CodeBlock> >(); if (parsedBlockList != null) { TES5EventCodeBlock?onUpdateBlockOfNonQuestOrAME = null; foreach (TES4CodeBlock block in parsedBlockList.Blocks) { TES5BlockList newBlockList = this.blockFactory.CreateBlock(block, globalScope, multipleScriptsScope, ref onUpdateBlockOfNonQuestOrAME); foreach (ITES5CodeBlock newBlock in newBlockList.Blocks) { createdBlocks.AddNewListIfNotContainsKeyAndAddValueToList(newBlock.BlockName, newBlock); } } } TES5BlockList blockList = new TES5BlockList(); foreach (var createdBlock in createdBlocks) { var blockType = createdBlock.Key; var blocks = createdBlock.Value; if (blocks.Count > 1) { foreach (TES5CodeBlock block in CombineRepeatedEventCodeBlockNames(blocks, blockType, isStandalone, globalScope)) { blockList.Add(block); } } else { ITES5CodeBlock block = blocks[0]; blockList.Add(block); } } TES5Target result = new TES5Target(new TES5Script(globalScope, blockList, false), target.OutputPath); return(result); }
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!"); }
/* * The script to be converted * The script"s global scope * The scope under which we"re converting * * @throws ConversionException */ public TES5Target Convert(TES4Target target, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { TES4Script script = target.Script; TES5BlockList blockList = new TES5BlockList(); TES4BlockList parsedBlockList = script.BlockList; Dictionary <string, List <ITES5CodeBlock> > createdBlocks = new Dictionary <string, List <ITES5CodeBlock> >(); if (parsedBlockList != null) { foreach (TES4CodeBlock block in parsedBlockList.Blocks) { TES5BlockList newBlockList = this.blockFactory.CreateBlock(block, globalScope, multipleScriptsScope); foreach (ITES5CodeBlock newBlock in newBlockList.Blocks) { createdBlocks.AddNewListIfNotContainsKeyAndAddValueToList(newBlock.BlockName, newBlock); } } } //todo encapsulate it to a different class. bool isStandalone = target.OutputPath.Contains(Path.DirectorySeparatorChar + "Standalone" + Path.DirectorySeparatorChar); foreach (var createdBlock in createdBlocks) { var blockType = createdBlock.Key; var blocks = createdBlock.Value; if (blocks.Count > 1) { List <TES5FunctionCodeBlock> functions = new List <TES5FunctionCodeBlock>(); int i = 1; TES5ObjectCallArguments localScopeArguments = null; foreach (TES5CodeBlock block in blocks) { TES5FunctionScope newFunctionScope = new TES5FunctionScope(blockType + "_" + i.ToString()); foreach (var variable in block.FunctionScope.Variables.Values) { newFunctionScope.AddVariable(variable); } TES5FunctionCodeBlock function = new TES5FunctionCodeBlock(newFunctionScope, block.CodeScope, new TES5VoidType(), isStandalone); functions.Add(function); if (localScopeArguments == null) { localScopeArguments = new TES5ObjectCallArguments(); foreach (var variable in block.FunctionScope.Variables.Values) { localScopeArguments.Add(TES5ReferenceFactory.CreateReferenceToVariable(variable)); } } ++i; } //Create the proxy block. ITES5CodeBlock lastBlock = blocks.Last(); TES5EventCodeBlock proxyBlock = TES5BlockFactory.CreateEventCodeBlock(blockType, /* * //WTM: Change: block was used below, but block is out of scope. The PHP must have been using the last defined block from above. * //WTM: Change: PHP called "clone" below, but I'm not sure if this is necessary or would even operate the same in C#. */ lastBlock.FunctionScope); foreach (var function in functions) { blockList.Add(function); TES5ObjectCall functionCall = this.objectCallFactory.CreateObjectCall(TES5ReferenceFactory.CreateReferenceToSelf(globalScope), function.BlockName, multipleScriptsScope, localScopeArguments, false // hacky. ); proxyBlock.AddChunk(functionCall); } blockList.Add(proxyBlock); } else { ITES5CodeBlock block = blocks[0]; blockList.Add(block); } } TES5Target result = new TES5Target(new TES5Script(globalScope, blockList), target.OutputPath); return(result); }
/* * Joins N QF subfragments into one QF fragment that can be properly binded into Skyrim VM * @throws ConversionException */ public TES5Target JoinQFFragments(IBuildTarget target, string resultingFragmentName, List <QuestStageScript> subfragmentsTrees) { int tes4FormID = GetTES4FormID(resultingFragmentName); StageMap stageMap = StageMapBuilder.Build(target, resultingFragmentName, esmAnalyzer, tes4FormID); /* * We need script fragment for objective handling for each stage, so when parsing the script fragments, * we"ll be marking them there, and intersecting this with stage. * This will give us an array of stages which don"t have script fragment, but will need it anyways * for objective handling. */ TES5ScriptHeader resultingScriptHeader = TES5ScriptHeaderFactory.GetFromCacheOrConstructByBasicType(resultingFragmentName, TES5BasicType.T_QUEST, TES5TypeFactory.TES4_Prefix, true); TES5GlobalScope resultingGlobalScope = new TES5GlobalScope(resultingScriptHeader); string[] referenceAliases = ReferenceAliasBuilder.Build(target, resultingFragmentName, esmAnalyzer, tes4FormID).ToArray(); foreach (string propertyName in referenceAliases) { resultingGlobalScope.AddProperty(TES5PropertyFactory.ConstructWithoutFormID(propertyName, TES5BasicType.T_REFERENCEALIAS, propertyName)); } List <QuestStageBlock> questStageBlocks = new List <QuestStageBlock>(); HashSet <int> implementedStages = new HashSet <int>(); HashSet <string> propertiesNamesDeclared = new HashSet <string>(); foreach (var subfragment in subfragmentsTrees) { TES5Target subfragmentsTree = subfragment.Script; TES5Script subfragmentScript = subfragmentsTree.Script; TES5GlobalScope subfragmentGlobalScope = subfragmentScript.GlobalScope; foreach (TES5Property subfragmentProperty in subfragmentGlobalScope.Properties) { /* * Move over the properties to the new global scope */ if (propertiesNamesDeclared.Add(subfragmentProperty.Name)) { resultingGlobalScope.AddProperty(subfragmentProperty); } else { if (subfragmentProperty.IsPlayerRef) { continue; } //WTM: Change: I don't think renaming these properties actually helps anything. /* * string propertyName = GeneratePropertyName(subfragmentScript.ScriptHeader, subfragmentProperty); * subfragmentProperty.Rename(propertyName); * if (!propertiesNamesDeclared.Add(subfragmentProperty.Name)) * { * throw new ConversionException(nameof(propertiesNamesDeclared) + " already contained property " + subfragmentProperty.Name + "."); * } */ //WTM: Change: I'm trying to unify properties and include extended type declarations. TES5Property existingProperty = resultingGlobalScope.GetPropertyByName(subfragmentProperty.Name); if (TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(existingProperty.TES5Type, subfragmentProperty.TES5Type)) { continue; } if (TES5InheritanceGraphAnalyzer.IsExtending(subfragmentProperty.TES5Type, existingProperty.TES5Type)) { existingProperty.TES5Type = subfragmentProperty.TES5Type; continue; } if (TES5InheritanceGraphAnalyzer.IsExtending(existingProperty.TES5Type, subfragmentProperty.TES5Type.NativeType)) { subfragmentProperty.TES5Type.NativeType = existingProperty.TES5Type.NativeType; existingProperty.TES5Type = subfragmentProperty.TES5Type; continue; } throw new ConversionException("Types were not compatible for property " + subfragmentProperty.Name + ": " + subfragmentProperty.TES5Type.Value + " should extend " + existingProperty.TES5Type.Value + " (" + existingProperty.TES5Type.NativeType.Value + ")."); } } List <ITES5CodeBlock> subfragmentBlocks = subfragmentScript.BlockList.Blocks; if (subfragmentBlocks.Count != 1) { throw new ConversionException("Wrong QF fragment, actual function count: " + subfragmentBlocks.Count + ".."); } ITES5CodeBlock subfragmentBlock = subfragmentBlocks[0]; if (subfragmentBlock.FunctionScope.BlockName != TES5FragmentFactory.GetFragmentName(0)) { throw new ConversionException("Wrong QF fragment funcname, actual function name: " + subfragmentBlock.FunctionScope.BlockName + "."); } string newFragmentFunctionName = TES5FragmentFactory.GetFragmentName(subfragment.Stage, subfragment.LogIndex); subfragmentBlock.FunctionScope.Rename(newFragmentFunctionName); List <int>?stageMapOfStage = stageMap.TryGetStageTargetsMap(subfragment.Stage); if (stageMapOfStage != null) { var objectiveCodeChunks = objectiveHandlingFactory.GenerateObjectiveHandling(subfragmentBlock, resultingGlobalScope, stageMapOfStage); foreach (var newCodeChunk in objectiveCodeChunks) { subfragmentBlock.AddChunk(newCodeChunk); } } questStageBlocks.Add(new QuestStageBlock(subfragment.Stage, subfragment.LogIndex, subfragmentBlock)); implementedStages.Add(subfragment.Stage); } /* * Diff to find stages which we still need to mark */ int[] nonDoneStages = stageMap.StageIDs.Where(stageID => !implementedStages.Contains(stageID)).ToArray(); foreach (int nonDoneStage in nonDoneStages) { TES5FunctionCodeBlock fragment = objectiveHandlingFactory.CreateEnclosedFragment(resultingGlobalScope, nonDoneStage, stageMap.GetStageTargetsMap(nonDoneStage)); questStageBlocks.Add(new QuestStageBlock(nonDoneStage, 0, fragment)); } this.mappedTargetsLogService.WriteScriptName(resultingFragmentName); foreach (var kvp in stageMap.MappedTargetsIndex) { var originalTargetIndex = kvp.Key; var mappedTargetIndexes = kvp.Value; this.mappedTargetsLogService.WriteLine(originalTargetIndex, mappedTargetIndexes); } TES5BlockList resultingBlockList = new TES5BlockList(questStageBlocks.OrderBy(b => b.StageID).ThenBy(b => b.LogIndex).Select(b => b.CodeBlock)); TES5Script resultingTree = new TES5Script(resultingGlobalScope, resultingBlockList, true); string outputPath = target.GetTranspileToPath(resultingFragmentName); return(new TES5Target(resultingTree, outputPath)); }
/* * Joins N QF subfragments into one QF fragment that can be properly binded into Skyrim VM * @throws ConversionException */ public TES5Target JoinQFFragments(BuildTarget target, string resultingFragmentName, List <QuestStageScript> subfragmentsTrees) { StageMap stageMap = BuildStageMap(target, resultingFragmentName); /* * We need script fragment for objective handling for each stage, so when parsing the script fragments, * we"ll be marking them there, and intersecting this with stage. * This will give us an array of stages which don"t have script fragment, but will need it anyways * for objective handling. */ TES5ScriptHeader resultingScriptHeader = new TES5ScriptHeader(resultingFragmentName, TES5BasicType.T_QUEST, "", true); TES5BlockList resultingBlockList = new TES5BlockList(); TES5GlobalScope resultingGlobalScope = new TES5GlobalScope(resultingScriptHeader); /* * Add ReferenceAlias"es * At some point, we might port the conversion so it doesn"t use the directly injected property, * but instead has a map to aliases and we"ll map accordingly and have references point to aliases instead */ string sourcePath = target.GetSourceFromPath(resultingFragmentName); string scriptName = Path.GetFileNameWithoutExtension(sourcePath); string aliasesFile = Path.Combine(Path.GetDirectoryName(sourcePath), scriptName + ".aliases"); string[] aliasesLines = File.ReadAllLines(aliasesFile); Dictionary <string, bool> aliasesDeclared = new Dictionary <string, bool>(); foreach (var alias in aliasesLines) { string trimmedAlias = alias.Trim(); if (trimmedAlias == "") { continue; } try { aliasesDeclared.Add(trimmedAlias, true); } catch (ArgumentException) { continue; } resultingGlobalScope.AddProperty(new TES5Property(trimmedAlias, TES5BasicType.T_REFERENCEALIAS, trimmedAlias)); } Dictionary <int, bool> implementedStages = new Dictionary <int, bool>(); Dictionary <string, bool> propertiesNamesDeclared = new Dictionary <string, bool>(); foreach (var subfragment in subfragmentsTrees) { TES5Target subfragmentsTree = subfragment.Script; TES5Script subfragmentScript = subfragmentsTree.Script; TES5GlobalScope subfragmentGlobalScope = subfragmentScript.GlobalScope; foreach (TES5Property subfragmentProperty in subfragmentGlobalScope.Properties) { /* * Move over the properties to the new global scope */ string propertyName; if (propertiesNamesDeclared.ContainsKey(subfragmentProperty.Name)) { propertyName = GeneratePropertyName(subfragmentScript.ScriptHeader, subfragmentProperty); subfragmentProperty.Rename(propertyName); } else { propertyName = subfragmentProperty.Name; } propertiesNamesDeclared.Add(propertyName, true); resultingGlobalScope.AddProperty(subfragmentProperty); //WTM: Note: See QF_FGD03Viranus_0102d154. Since ViranusDontonREF is present in multiple of the original fragments, //ViranusDontonREF gets renamed by the above. So multiple ViranusDontonREF variables are output. //Below I tried not renaming, assuming instead that variables with matching names and types within a set of fragments were intended to be the same variable. //It had OK results, but I'm leaving it commented for now. /*string propertyNameWithSuffix = subfragmentProperty.PropertyNameWithSuffix; * TES5Property existingProperty = resultingGlobalScope.Properties.Where(p => p.PropertyNameWithSuffix == propertyNameWithSuffix).FirstOrDefault(); * if (existingProperty != null && TES5InheritanceGraphAnalyzer.isExtending(subfragmentProperty.PropertyType, existingProperty.PropertyType)) * { * existingProperty.PropertyType = subfragmentProperty.PropertyType; * } * else * { * bool add = true; * if (existingProperty != null) * { * if (TES5InheritanceGraphAnalyzer.isExtending(existingProperty.PropertyType, subfragmentProperty.PropertyType)) * { * add = false; * } * else * { * string generatedPropertyName = generatePropertyName(subfragmentScript.ScriptHeader, subfragmentProperty, i); * subfragmentProperty.Rename(generatedPropertyName); * } * } * if (add) * { * resultingGlobalScope.Add(subfragmentProperty); * } * }*/ } List <ITES5CodeBlock> subfragmentBlocks = subfragmentScript.BlockList.Blocks; if (subfragmentBlocks.Count != 1) { throw new ConversionException("Wrong QF fragment, actual function count: " + subfragmentBlocks.Count + ".."); } ITES5CodeBlock subfragmentBlock = subfragmentBlocks[0]; if (subfragmentBlock.FunctionScope.BlockName != "Fragment_0") { throw new ConversionException("Wrong QF fragment funcname, actual function name: " + subfragmentBlock.FunctionScope.BlockName + ".."); } string newFragmentFunctionName = "Fragment_" + subfragment.Stage.ToString(); if (subfragment.LogIndex != 0) { newFragmentFunctionName += "_" + subfragment.LogIndex; } subfragmentBlock.FunctionScope.Rename(newFragmentFunctionName); var objectiveCodeChunks = this.objectiveHandlingFactory.GenerateObjectiveHandling(subfragmentBlock, resultingGlobalScope, stageMap.GetStageTargetsMap(subfragment.Stage)); foreach (var newCodeChunk in objectiveCodeChunks) { subfragmentBlock.AddChunk(newCodeChunk); } resultingBlockList.Add(subfragmentBlock); implementedStages[subfragment.Stage] = true; } /* * Diff to find stages which we still need to mark */ int[] nonDoneStages = stageMap.StageIDs.Where(stageID => !implementedStages.ContainsKey(stageID)).ToArray(); foreach (int nonDoneStage in nonDoneStages) { TES5FunctionCodeBlock fragment = this.objectiveHandlingFactory.CreateEnclosedFragment(resultingGlobalScope, nonDoneStage, stageMap.GetStageTargetsMap(nonDoneStage)); resultingBlockList.Add(fragment); } this.mappedTargetsLogService.WriteScriptName(resultingFragmentName); foreach (var kvp in stageMap.MappedTargetsIndex) { var originalTargetIndex = kvp.Key; var mappedTargetIndexes = kvp.Value; this.mappedTargetsLogService.WriteLine(originalTargetIndex, mappedTargetIndexes); } TES5Script resultingTree = new TES5Script(resultingGlobalScope, resultingBlockList); string outputPath = target.GetTranspileToPath(resultingFragmentName); return(new TES5Target(resultingTree, outputPath)); }
public QuestStageScript(TES5Target script, int stage, int logIndex) { this.Script = script; this.Stage = stage; this.LogIndex = logIndex; }
public void RegisterBuiltScript(BuildTarget buildTarget, TES5Target script) { this.builtScripts[buildTarget.GetTargetName()][script.Script.ScriptHeader.OriginalScriptName] = script; }