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 void write(BuildTarget target, BuildTracker buildTracker, ProgressWriter progressWriter) { Dictionary <string, TES5Target> scripts = buildTracker.GetBuiltScripts(target.GetTargetName()); 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")) { string mapFileName = Path.GetFileNameWithoutExtension(mapFilePath); jointScripts.AddNewListIfNotContainsKey(mapFileName); } /* * Group the fragments together */ foreach (var script in scripts.Values) { 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]), int.Parse(parts[4]))); } foreach (var kvp in jointScripts) { var resultingFragmentName = kvp.Key; var subfragmentsTrees = kvp.Value; connectedQuestFragments.Add(this.QFFragmentFactory.JoinQFFragments(target, resultingFragmentName, subfragmentsTrees)); } Write(connectedQuestFragments, progressWriter); }
public void write(BuildTarget target, BuildTracker buildTracker, ProgressWriter progressWriter) { Write(buildTracker.GetBuiltScripts(target.GetTargetName()).Values, progressWriter); }
public void Write(IBuildTarget target, BuildTracker buildTracker, ProgressWriter progressWriter) { Write(buildTracker.GetBuiltScripts(target.Name).Values, progressWriter); }
private static void WriteTranspiled(BuildTargetAdvancedCollection buildTargets, BuildTracker buildTracker) { ProgressWriter progressWriter = new ProgressWriter("Writing Transpiled Scripts", buildTargets.Sum(bt => buildTracker.GetBuiltScripts(bt.Name).Count)); //WTM: Change: Added: Transpile QF first since some transpilation will be done while writing. //Types will be inferenced like TES4PublicanBloatedFloatOrmil, and if Standalone gets written first, those files will be incorrect. //The below OrderBy statement puts QF first. foreach (var buildTarget in buildTargets.OrderBy(bt => !bt.IsQF())) { buildTarget.Write(buildTracker, progressWriter); } progressWriter.WriteLast(); }