diff --git a/PandoraPlus/MVVM/ViewModel/EngineViewModel.cs b/PandoraPlus/MVVM/ViewModel/EngineViewModel.cs index 3865042..e7ff927 100644 --- a/PandoraPlus/MVVM/ViewModel/EngineViewModel.cs +++ b/PandoraPlus/MVVM/ViewModel/EngineViewModel.cs @@ -81,11 +81,12 @@ public EngineViewModel(IModInfoProvider modinfoProvider) CultureInfo.CurrentCulture = culture; preloadTask = Task.Run(Engine.PreloadAsync); - } public async Task LoadAsync() { - List modInfos = new List(); + + + List modInfos = new List(); #if DEBUG modInfos = await modinfoProvider?.GetInstalledMods("C:\\Games\\Skyrim Modding\\Creation Tools\\Skyrim.Behavior.Tool\\PandoraTEST\\Pandora_Engine\\mod")!; #endif @@ -112,7 +113,7 @@ public async Task LoadAsync() modInfos = modInfos.OrderBy(m => m.Priority == 0).ThenBy(m => m.Priority).ToList(); foreach(var modInfo in modInfos) { Mods.Add(modInfo); } - + await WriteLogBoxLine("Mods loaded."); } public void Exit(object? p) @@ -212,6 +213,18 @@ private async void LaunchEngine(object? parameter) await preloadTask; List activeMods = GetActiveModsByPriority(); + IModInfo? baseModInfo = Mods.Where(m => m.Code == "pandora").FirstOrDefault(); + + if (baseModInfo == null) { await WriteLogBoxLine("FATAL ERROR: Pandora Base does not exist. Ensure the engine was installed properly and data is not corrupted."); return; } + if (!baseModInfo.Active) + { + baseModInfo.Active = true; + activeMods.Add(baseModInfo); + } + baseModInfo.Priority = uint.MaxValue; + + + Stopwatch timer = Stopwatch.StartNew(); await Task.Run(async() => { await Engine.LaunchAsync(activeMods); }); diff --git a/PandoraPlus/Nemesis_Engine/mod/colis/magicbehavior/#0077.txt b/PandoraPlus/Nemesis_Engine/mod/colis/magicbehavior/#0077.txt deleted file mode 100644 index 050031a..0000000 --- a/PandoraPlus/Nemesis_Engine/mod/colis/magicbehavior/#0077.txt +++ /dev/null @@ -1,202 +0,0 @@ - - - staggerStop - MRh_Equipped_Event - shoutStop - shoutStart - moveStop - moveStart - SneakStop - SneakStart - turnStop - turnLeft - turnRight - FootLeft - FootRight - SprintStop - SprintStart - staggerStart - MRh_SpellAimedStart - MRh_SpellAimedConcentrationStart - MRh_SpellSelfConcentrationStart - MRh_SpellSelfStart - MRh_WardStart - MRh_SpellReady_Event - MRh_PreChargeOut - MRh_SpellRelease_Event - MRh_WinStart - MRh_WinEnd - MRh_SpellFire_Event - MRh_PreAimedConcentrationOut - MRh_PreSelfConOut - MRh_PreWardLoopOut - wardAbsorb - WardFXRecoilEnd - shoutRelease - Voice_SpellFire_Event - MLh_SpellAimedStart - MLh_SpellReady_Event - MLh_PreChargeOut - MLh_SpellRelease_Event - MLh_PreAimedOut - MLh_WinStart - MLh_WinEnd - MLh_Equipped_Event - MLh_SpellFire_Event - MLh_SpellAimedConcentrationStart - MLh_SpellSelfConcentrationStart - MLh_PreSelfConOut - MLh_SpellSelfStart - MLh_WardStart - MLh_PreWardLoopOut - DualMagic_SpellSelfStart - DualMagic_SpellAimedStart - DualMagic_SpellAimedConcentrationStart - DualMagic_SpellSelfConcentrationStart - DualMagic_WardStart - MLh_PreAimedConcentrationOut - MRhIdle_end - MagicCastStop - MLh_Ready - MRh_Ready - M2h_Ready - FootScuffLeft - FootScuffRight - StfMagic_PreChargeOut - bashExit - bashStart - bashPowerStart - blockStop - bashRelease - HitFrame - SoundPlay.NPCHumanCombatShieldBash - preHitFrame - StaffBashExit - StaffBashStart - StaffBashRelease - MRh_PreAimedCon_to_MRh_AimedCon - MRh_SpellTelekinesisStart - MLh_SpellTelekinesisStart - CyclicFreeze - CyclicCrossBlend - tailCombatState - tailSneakIdle - tailSneakLocomotion - tailCombatIdle - tailCombatLocomotion - BeginCastRight - BeginCastLeft - CastStop - testMagic - BeginCastVoice - NPCshoutStart - bowZoomStart - Event00 - SoundPlay.WPNBowZoomIn - bowReset - arrowDetach - attackStop - SneakSprintStartRoll - - Collision_Start - Collision_Add - Collision_Remove - Collision_ClearTargets - Collision_AttackEnd - Collision_AttackStart - - - - - blendDefault - blendMove1stP - blendMoveStop - blendMoveStart - IsPlayer - TurnDelta - TurnDeltaDamped - IsNPC - IsFirstPerson - iSyncTurnState - bMotionDriven - IsInCastStateDamped - Direction - SpeedSampled - IsInCastState - 1stPRot - 1stPRotDamped - i1stPerson - iSyncSprintState - iIsInSneak - iSyncIdleLocomotion - bMRh_Ready - staggerMagnitude - IsStaggering - IsAttackReady - IsCastingRight - blendFast - iWeaponReady - IsShouting - iState - iState_NPCDefault - iState_NPCSneaking - InDualMagicState - iDualMagicState - bMLh_Ready - IsCastingLeft - CastBlendDamped - iLeftHandType - iRightHandType - iState_NPCSneaking - TurnMin - IsCastingDual - RotMax - Speed - MagicLeftActive - IsAttacking - iState_NPCMagic - iState_NPCMagicCasting - testInt - SpeedDamped - AimHeadingCurrent - AimPitchCurrent - camerafromx - camerafromy - camerafromz - AimHeadingMax - AimPitchMax - AllowMagicModify - AimGainOn - AimGainOff - bDisableInterp - IsSneaking - bAimActive - MagicAimOffsetHeading - MagicAimOffsetPitch - bHeadTrackSpine - NotCasting - bWantCastLeft - bWantCastRight - bWantCastVoice - CastBlend - CastBlendGain - bowZoomAmt - ZoomAcc - TimeDelta - iWantBlock01 - bowZoom - Pitch - BowAimOffsetHeading - BowAimOffsetPitch - bVoiceReady - - - LeftArm - UpperBody - ExcludeRootAndCamera - Hands - MRhFavorBoneSwitch - MLhFavorBoneSwitch - RightArm - - diff --git a/PandoraPlus/PandoraPlus.csproj b/PandoraPlus/PandoraPlus.csproj index 9f60458..b5b9a0a 100644 --- a/PandoraPlus/PandoraPlus.csproj +++ b/PandoraPlus/PandoraPlus.csproj @@ -65,7 +65,6 @@ - @@ -84,15 +83,6 @@ - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - PreserveNewest @@ -123,6 +113,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/PandoraPlus/Pandora_Engine/mod/pandora/info.ini b/PandoraPlus/Pandora_Engine/mod/pandora/info.ini index 215baac..099b8de 100644 --- a/PandoraPlus/Pandora_Engine/mod/pandora/info.ini +++ b/PandoraPlus/Pandora_Engine/mod/pandora/info.ini @@ -1,5 +1,5 @@ -name=Pandora Base -author=Shikyo Kira & Monitor144hz +name=Pandora Base (REQUIRED) +author=Monitor144hz site=null auto=null hidden=true \ No newline at end of file diff --git a/PandoraPlus/Nemesis_Engine/mod/evfmgo/magicbehavior/#0077.txt b/PandoraPlus/Pandora_Engine/mod/pandora/magicbehavior/#0077.txt similarity index 98% rename from PandoraPlus/Nemesis_Engine/mod/evfmgo/magicbehavior/#0077.txt rename to PandoraPlus/Pandora_Engine/mod/pandora/magicbehavior/#0077.txt index 93f8646..7802b3a 100644 --- a/PandoraPlus/Nemesis_Engine/mod/evfmgo/magicbehavior/#0077.txt +++ b/PandoraPlus/Pandora_Engine/mod/pandora/magicbehavior/#0077.txt @@ -97,9 +97,6 @@ arrowDetach attackStop SneakSprintStartRoll - - PIE - @@ -134,7 +131,11 @@ IsShouting iState iState_NPCDefault + + iState_NPCSneaking + iState_NPCSneaking + InDualMagicState iDualMagicState bMLh_Ready diff --git a/PandoraPlus/Nemesis_Engine/mod/tdmv/magicbehavior/#0077.txt b/PandoraPlus/Pandora_Engine/mod/pandora/magicmountedbehavior/#0071.txt similarity index 91% rename from PandoraPlus/Nemesis_Engine/mod/tdmv/magicbehavior/#0077.txt rename to PandoraPlus/Pandora_Engine/mod/pandora/magicmountedbehavior/#0071.txt index c21560a..778eb88 100644 --- a/PandoraPlus/Nemesis_Engine/mod/tdmv/magicbehavior/#0077.txt +++ b/PandoraPlus/Pandora_Engine/mod/pandora/magicmountedbehavior/#0071.txt @@ -1,11 +1,9 @@ - - + + staggerStop MRh_Equipped_Event shoutStop shoutStart - moveStop - moveStart SneakStop SneakStart turnStop @@ -91,15 +89,15 @@ BeginCastVoice NPCshoutStart bowZoomStart - Event00 SoundPlay.WPNBowZoomIn bowReset arrowDetach attackStop SneakSprintStartRoll + MC_shoutStart - + blendDefault blendMove1stP blendMoveStop @@ -120,7 +118,6 @@ i1stPerson iSyncSprintState iIsInSneak - iSyncIdleLocomotion bMRh_Ready staggerMagnitude IsStaggering @@ -131,7 +128,11 @@ IsShouting iState iState_NPCDefault + iState_NPCSneaking + + iState_NPCSneaking + InDualMagicState iDualMagicState bMLh_Ready @@ -180,19 +181,11 @@ Pitch BowAimOffsetHeading BowAimOffsetPitch - bVoiceReady - - tdmHeadtrackingBehavior - TDM_LockRotation - - + LeftArm - UpperBody - ExcludeRootAndCamera - Hands MRhFavorBoneSwitch MLhFavorBoneSwitch RightArm - + \ No newline at end of file diff --git a/PandoraPlus/Patch/Patchers/Skyrim/AnimSetData/AnimSetDataManager.cs b/PandoraPlus/Patch/Patchers/Skyrim/AnimSetData/AnimSetDataManager.cs index e1f20fe..d211c75 100644 --- a/PandoraPlus/Patch/Patchers/Skyrim/AnimSetData/AnimSetDataManager.cs +++ b/PandoraPlus/Patch/Patchers/Skyrim/AnimSetData/AnimSetDataManager.cs @@ -78,6 +78,7 @@ public void SplitAnimSetDataSingleFile() public void MergeAnimSetDataSingleFile() { if (outputAnimSetDataSingleFile.Exists) { outputAnimSetDataSingleFile.Delete(); } + if (outputAnimSetDataSingleFile.Directory != null && !outputAnimSetDataSingleFile.Directory.Exists) { outputAnimSetDataSingleFile.Directory.Create(); } using (var writeStream = outputAnimSetDataSingleFile.OpenWrite()) { diff --git a/PandoraPlus/Patch/Patchers/Skyrim/Hkx/PackFileCache.cs b/PandoraPlus/Patch/Patchers/Skyrim/Hkx/PackFileCache.cs index 4dea47e..f804a5c 100644 --- a/PandoraPlus/Patch/Patchers/Skyrim/Hkx/PackFileCache.cs +++ b/PandoraPlus/Patch/Patchers/Skyrim/Hkx/PackFileCache.cs @@ -10,7 +10,7 @@ namespace Pandora.Patch.Patchers.Skyrim.Hkx; public class PackFileCache { private Dictionary pathMap = new Dictionary(StringComparer.OrdinalIgnoreCase); - + private static readonly FileInfo PreviousOutputFile = new FileInfo(Directory.GetCurrentDirectory() + "\\Pandora_Engine\\PreviousOutput.txt"); public PackFile LoadPackFile(FileInfo file) { @@ -92,13 +92,35 @@ public PackFileCharacter LoadPackFileCharacter(FileInfo file, Project project) public void DeletePackFileOutput() { - lock (pathMap) + if (!PreviousOutputFile.Exists) { return; } + + using (FileStream readStream = PreviousOutputFile.OpenRead()) + { + using (StreamReader reader = new StreamReader(readStream)) + { + string? expectedLine; + while((expectedLine = reader.ReadLine()) != null) + { + FileInfo file = new FileInfo(expectedLine); + if (!file.Exists) { continue; } + + file.Delete(); + } + } + } + } + + public void SavePackFileOutput(IEnumerable packFiles) + { + using (FileStream readStream = PreviousOutputFile.OpenWrite()) { - foreach (var packFile in pathMap.Values) + using (StreamWriter writer = new StreamWriter(readStream)) { - lock (packFile) + foreach(PackFile packFile in packFiles) { - if (packFile.OutputHandle.Exists) { packFile.OutputHandle.Delete(); } + if (!packFile.ExportSuccess || !packFile.OutputHandle.Exists) { continue; } + + writer.WriteLine(packFile.OutputHandle.FullName); } } } diff --git a/PandoraPlus/Patch/Patchers/Skyrim/Hkx/PackFileValidator.cs b/PandoraPlus/Patch/Patchers/Skyrim/Hkx/PackFileValidator.cs index 156d08c..e9446bf 100644 --- a/PandoraPlus/Patch/Patchers/Skyrim/Hkx/PackFileValidator.cs +++ b/PandoraPlus/Patch/Patchers/Skyrim/Hkx/PackFileValidator.cs @@ -49,7 +49,7 @@ public bool ValidateEventsAndVariables(PackFileGraph graph) //reverse is necessary so that validator doesn't remove the original element if a duplicate is found - var uniqueEventNames = new HashSet(StringComparer.OrdinalIgnoreCase); + var uniqueEventNames = new HashSet(); var uniqueVariableNames = new HashSet(StringComparer.OrdinalIgnoreCase); eventIndices.Clear(); diff --git a/PandoraPlus/Patch/Patchers/Skyrim/Nemesis/NemesisAssembler.cs b/PandoraPlus/Patch/Patchers/Skyrim/Nemesis/NemesisAssembler.cs index 7aae612..59df42e 100644 --- a/PandoraPlus/Patch/Patchers/Skyrim/Nemesis/NemesisAssembler.cs +++ b/PandoraPlus/Patch/Patchers/Skyrim/Nemesis/NemesisAssembler.cs @@ -34,11 +34,11 @@ public class NemesisAssembler : IAssembler //animdata and animsetdata deviate fr List packFiles = new List(); - private DirectoryInfo engineFolder = new DirectoryInfo(Directory.GetCurrentDirectory() + "\\Pandora_Engine"); + private static readonly DirectoryInfo engineFolder = new DirectoryInfo(Directory.GetCurrentDirectory() + "\\Pandora_Engine"); - private DirectoryInfo templateFolder = new DirectoryInfo(Directory.GetCurrentDirectory() + "\\Pandora_Engine\\Skyrim\\Template"); + private static readonly DirectoryInfo templateFolder = new DirectoryInfo(Directory.GetCurrentDirectory() + "\\Pandora_Engine\\Skyrim\\Template"); - private DirectoryInfo outputFolder = new DirectoryInfo($"{Directory.GetCurrentDirectory()}\\meshes"); + private static readonly DirectoryInfo outputFolder = new DirectoryInfo($"{Directory.GetCurrentDirectory()}\\meshes"); private ProjectManager projectManager; @@ -85,7 +85,7 @@ public void GetPostMessages(StringBuilder builder) public async Task LoadResourcesAsync() { var animSetDataTask = Task.Run(() => { animSetDataManager.SplitAnimSetDataSingleFile(); }); - projectManager.LoadTrackedProjects(); + await Task.Run(projectManager.LoadTrackedProjects); await Task.Run(() => { animDataManager.SplitAnimationDataSingleFile(projectManager); }); await animSetDataTask; @@ -112,10 +112,12 @@ public async Task ApplyPatchesAsync() { var animSetDataTask = Task.Run(() => { animSetDataManager.MergeAnimSetDataSingleFile(); }); - await Task.Run(() => { projectManager.ApplyPatchesParallel(); }); + var animDataTask = Task.Run(() => { animDataManager.MergeAnimDataSingleFile(); }); + await projectManager.ApplyPatchesParallel(); + await animDataTask; await animSetDataTask; @@ -173,7 +175,7 @@ public void ForwardReplaceEdit(PackFile packFile, XMatch match, PackFileChangeSe break; case XmlNodeType.Element: //packFile.Editor.QueueReplaceElement(lookup.LookupPath(node), (XElement)newNodes[i - separatorIndex - 1]); - changeSet.AddChange(new ReplaceElementChange(lookup.LookupPath(node), (XElement)newNode)); + changeSet.AddChange(new ReplaceElementChange(lookup.LookupPath(newNode), (XElement)newNode)); //lock (packFile.edits) packFile.edits.AddChange(new ReplaceElementChange(lookup.LookupPath(node), (XElement)newNodes[i - separatorIndex - 1],modInfo)); break; default: diff --git a/PandoraPlus/Patch/Patchers/Skyrim/ProjectManager.cs b/PandoraPlus/Patch/Patchers/Skyrim/ProjectManager.cs index 0ba3581..c582b45 100644 --- a/PandoraPlus/Patch/Patchers/Skyrim/ProjectManager.cs +++ b/PandoraPlus/Patch/Patchers/Skyrim/ProjectManager.cs @@ -91,26 +91,7 @@ public void GetFNISInfo(StringBuilder builder) - public async Task LoadTrackedProjectsAsync() - { - FileInfo projectList = new FileInfo($"{templateFolder.FullName}\\vanilla_projectpaths.txt"); - List projectLoadTasks = new List(); - string? expectedLine = null; - List projectPaths = new List(); - using (var readStream = projectList.OpenRead()) - { - using (var streamReader = new StreamReader(readStream)) - { - while ((expectedLine = streamReader.ReadLine()) != null) - { - if (String.IsNullOrWhiteSpace(expectedLine)) continue; - projectPaths.Add(expectedLine); - } - } - } - Parallel.ForEach(projectPaths, projectFilePath => { LoadProject(projectFilePath); }); - } public void LoadTrackedProjects() { FileInfo projectList = new FileInfo($"{templateFolder.FullName}\\vanilla_projectpaths.txt"); @@ -132,7 +113,6 @@ public void LoadTrackedProjects() { LoadProject(projectPath); } - } public void ExtractProjects() { @@ -260,12 +240,12 @@ public void ApplyPatches() } - public void ApplyPatchesParallel() + public async Task ApplyPatchesParallel() { #if DEBUG Debug.WriteLine("Export Started! "); #endif - packFileCache.DeletePackFileOutput(); + Task deleteOutputTask = Task.Run(packFileCache.DeletePackFileOutput); try { Parallel.ForEach(projectMap.Values, project => { fnisParser.ScanProjectAnimlist(project); }); @@ -285,8 +265,11 @@ public void ApplyPatchesParallel() //#if DEBUG || DEBUGRELEASE // foreach(PackFile packFile in ActivePackFiles) { Debug.WriteLine(packFile.UniqueName); } //#endif + await deleteOutputTask; Parallel.ForEach(ActivePackFiles, packFile => { CompleteExportSuccess = packFile.Export(); }); + packFileCache.SavePackFileOutput(ActivePackFiles); + } } }