public static void Save(string funcName, string dataDir, string cacheDir) { // Argument Checks if (string.IsNullOrEmpty(dataDir)) { throw new ArgumentNullException("dataDir"); } if (string.IsNullOrEmpty(cacheDir)) { throw new ArgumentNullException("cacheDir"); } // Save Sets try { script.Call(funcName, dataDir, CacheDir, ID); } catch (Exception ex) { LuaTerminal.LogError($"ERROR: {ex.Message}"); } // Generate new Editor Cache string editorCachePath = Path.Combine( CacheDir, EditorCache.FileName); if (File.Exists(editorCachePath)) { File.Delete(editorCachePath); } EditorCache.Save(editorCachePath, true); }
public static bool EvaluateCondition(string condition) { try { var s = new Script(); string txt = $"return ({condition.Replace("!=", "~=")})"; return(s.DoString(txt).Boolean); } catch (Exception ex) { LuaTerminal.LogError($"ERROR: {ex.Message}"); return(false); } }
public static bool EvaluateObjectCondition(SetObject obj, SetObjectType template, string condition) { try { var s = new Script(); for (int i = 0; i < template.Parameters.Count; ++i) { var param = template.Parameters[i]; s.Globals[param.Name] = obj.Parameters[i].Data; } string txt = $"return ({condition.Replace("!=", "~=")})"; return(s.DoString(txt).Boolean); } catch (Exception ex) { LuaTerminal.LogError($"ERROR: {ex.Message}"); return(false); } }
public static void Repack(string path, string inDir, string hashID = null, bool includeSubDirs = false, bool generateList = false, uint?splitCount = 0xA00000) { // Figure out what type of archive to use Archive arc = null; switch (Types.CurrentDataType) { case Types.DataTypes.Forces: arc = new ForcesArchive(); break; // TODO: Add LW Support case Types.DataTypes.LW: throw new NotImplementedException( "Could not repack, LW archives are not yet supported!"); case Types.DataTypes.Gens: case Types.DataTypes.SU: arc = new GensArchive(); break; case Types.DataTypes.Storybook: arc = new SBArchive(); break; // TODO: Add Colors Support case Types.DataTypes.Colors: throw new NotImplementedException( "Could not repack, Colors archives are not yet supported!"); // TODO: Add 06 Support case Types.DataTypes.S06: throw new NotImplementedException( "Could not repack, '06 archives are not yet supported!"); case Types.DataTypes.Shadow: case Types.DataTypes.Heroes: arc = new ONEArchive(); break; // TODO: Add SA2 Support case Types.DataTypes.SA2: throw new NotImplementedException( "Could not repack, SA2 archives are not yet supported!"); default: throw new Exception( "Could not repack, game type has not been set!"); } // Generate the archive arc.AddDirectory(inDir, includeSubDirs); if (arc is GensArchive gensArc) { gensArc.Save(path, generateList, splitCount); } else if (arc is ForcesArchive forcesArc) { forcesArc.Save(path, splitCount); } else { arc.Save(path, true); } // Hashes if (!string.IsNullOrEmpty(hashID) && Stage.EditorCache != null) { // Get splits list var arcSplits = new List <string>(); try { var arcFileList = arc.GetSplitArchivesList(path); arcSplits.AddRange(arcFileList); } catch { arcSplits.Add(path); } // Get new hashes for (int i = 0; i < arcSplits.Count; ++i) { arcSplits[i] = Helpers.GetFileHash(arcSplits[i]); } // Update editor cache hashes if (Stage.EditorCache.ArcHashes.ContainsKey(hashID)) { Stage.EditorCache.ArcHashes[hashID] = arcSplits; } else { Stage.EditorCache.ArcHashes.Add(hashID, arcSplits); } } LuaTerminal.Log((string.IsNullOrEmpty(hashID)) ? "Successfully repacked!" : $"Successfully repacked \"{hashID}\"!"); }
// Methods public static void Extract(string path, string outDir, string hashID = null) { // Figure out what type of archive to use Archive arc = null; switch (Types.CurrentDataType) { case Types.DataTypes.Forces: arc = new ForcesArchive(); break; // TODO: Add LW Support case Types.DataTypes.LW: throw new NotImplementedException( "Could not unpack, LW archives are not yet supported!"); case Types.DataTypes.Gens: case Types.DataTypes.SU: arc = new GensArchive(); break; case Types.DataTypes.Storybook: arc = new SBArchive(); break; // TODO: Add Colors Support case Types.DataTypes.Colors: throw new NotImplementedException( "Could not unpack, Colors archives are not yet supported!"); case Types.DataTypes.S06: arc = new S06Archive(); break; case Types.DataTypes.Shadow: case Types.DataTypes.Heroes: arc = new ONEArchive(); break; // TODO: Add SA2 Support case Types.DataTypes.SA2: throw new NotImplementedException( "Could not unpack, SA2 archives are not yet supported!"); default: throw new Exception( "Could not unpack, game type has not been set!"); } // Hashes bool hashesMatch = false; if (!string.IsNullOrEmpty(hashID) && Stage.EditorCache != null) { var editorCache = Stage.EditorCache; // Get splits list var arcSplits = new List <string>(); hashesMatch = true; try { var arcFileList = arc.GetSplitArchivesList(path); arcSplits.AddRange(arcFileList); } catch { arcSplits.Add(path); } // Check hashes var splitHashes = new List <string>(); var splitCacheHashes = (editorCache.ArcHashes.ContainsKey( hashID)) ? editorCache.ArcHashes[hashID] : null; if (splitCacheHashes != null && splitCacheHashes.Count != arcSplits.Count) { hashesMatch = false; } for (int i = 0; i < arcSplits.Count; ++i) { string file = arcSplits[i]; string arcHash = Helpers.GetFileHash(file); splitHashes.Add(arcHash); if (hashesMatch && (splitCacheHashes == null || splitCacheHashes[i] != arcHash)) { hashesMatch = false; } } // Update editor cache hashes if (splitCacheHashes == null) { Stage.EditorCache.ArcHashes.Add( hashID, splitHashes); } else if (!hashesMatch) { Stage.EditorCache.ArcHashes[ hashID] = splitHashes; } if (hashesMatch) { LuaTerminal.LogWarning(string.Format( "{0} \"{1}\", as it hasn't changed since it was last unpacked.", "WARNING: Skipped", hashID)); } else { LuaTerminal.Log($"Extracting \"{hashID}\"..."); } } // Extract the archive if (!hashesMatch) { if (Directory.Exists(outDir)) { Directory.Delete(outDir, true); } arc.Load(path); arc.Extract(outDir); LuaTerminal.Log((string.IsNullOrEmpty(hashID)) ? "Successfully unpacked!" : $"Successfully unpacked \"{hashID}\"!"); } }
public static VPModel LoadModel(string path, string resDir = null, bool isTerrain = false, bool loadMats = false, string group = null, bool nonEditable = true, GensTerrainInstanceInfo instInfo = null, bool spawnInstance = true) { // Figure out what type of model to use Model mdl; switch (Types.CurrentDataType) { case Types.DataTypes.Forces: case Types.DataTypes.LW: case Types.DataTypes.Gens: case Types.DataTypes.SU: mdl = new GensModel(); break; // TODO: Add Storybook Support case Types.DataTypes.Storybook: throw new NotImplementedException( "Could not load, Storybook terrain is not yet supported!"); // TODO: Add Colors Support case Types.DataTypes.Colors: throw new NotImplementedException( "Could not load, Colors terrain is not yet supported!"); // TODO: Add 06 Support case Types.DataTypes.S06: throw new NotImplementedException( "Could not load, '06 terrain is not yet supported!"); // TODO: Add Heroes/Shadow Support case Types.DataTypes.Shadow: case Types.DataTypes.Heroes: throw new NotImplementedException( "Could not load, Heroes/Shadow terrain is not yet supported!"); // TODO: Add SA2 Support case Types.DataTypes.SA2: throw new NotImplementedException( "Could not load, SA2 terrain is not yet supported!"); default: throw new Exception( "Could not load, game type has not been set!"); } // Get some information about the model string dir = Path.GetDirectoryName(path); string shortName = Path.GetFileNameWithoutExtension(path); Dictionary <string, VPModel> dict = null; VPObjectInstance instance = null; // Load the model if (mdl.GetType() == typeof(GensModel)) { if (isTerrain) { // Terrain Instance Info Program.MainUIInvoke(() => { dict = GetTerrainGroup(group, true); }); if (spawnInstance) { instance = (instInfo == null) ? new VPObjectInstance(shortName) : new VPObjectInstance(instInfo.TransformMatrix, instInfo.FileName); } // Don't bother loading the model again if we've // already loaded a model with the same name. if (dict.ContainsKey(shortName)) { if (spawnInstance) { Program.MainUIInvoke(() => { AddTerrainInstance(shortName, instance, group); }); } return(dict[shortName]); } } else { dict = Objects; } } // Model if (dict == null) { return(null); } if (dict.ContainsKey(shortName)) { LuaTerminal.LogWarning(string.Format( "WARNING: Skipped model \"{0}\" as a model with that {1}", shortName, "name has already been loaded!")); return(dict[shortName]); } else { mdl.Load(path); mdl.Name = shortName; } // Materials if (loadMats) { bool useResDirs = string.IsNullOrEmpty(resDir); var matExt = Types.MaterialExtension; foreach (var mesh in mdl.Meshes) { string pth = (useResDirs) ? null : Path.Combine(resDir, $"{mesh.MaterialName}{matExt}"); if (!useResDirs && File.Exists(pth)) { var mat = LoadMaterial(pth, mesh.MaterialName, nonEditable); if (mat != null) { continue; } } GetMaterial(mesh.MaterialName, nonEditable); } } VPModel vpMdl = null; Program.MainUIInvoke(() => { if (isTerrain) { vpMdl = (spawnInstance) ? AddModelInstance(mdl, instance, dict) : AddModel(mdl, dict); } else { vpMdl = AddObjectModel(mdl, shortName); } }); return(vpMdl); }
public static GensTerrainList LoadTerrainList(string path, string groupsDir, string resDir, bool nonEditable = true) { // Terrain List GUI.ChangeLoadStatus("Terrain List"); string dir = Path.GetDirectoryName(path); var terrainList = new GensTerrainList(); terrainList.Load(path); // Terrain Groups int groupCount = terrainList.GroupEntries.Length; GUI.ShowProgress(); for (int i = 0; i < groupCount; ++i) { // Update UI GUI.ChangeProgress((int)((i / (float)groupCount) * 100)); GUI.ChangeLoadStatus($"Terrain Group {i + 1}/{groupCount}"); // Get the path to the terrain group var groupEntry = terrainList.GroupEntries[i]; string groupDir = Path.Combine(groupsDir, groupEntry.FileName); string groupPath = Path.Combine(dir, $"{groupEntry.FileName}{GensTerrainGroup.Extension}"); // Ensure the group exists if (!File.Exists(groupPath)) { LuaTerminal.LogWarning(string.Format( "WARNING: Terrain group \"{0}\" was skipped {1}", groupEntry.FileName, "because it was not found!")); continue; } // Load the group var group = new GensTerrainGroup(); group.Load(groupPath); Dictionary <string, VPModel> terrainGroup = null; Program.MainUIInvoke(() => { terrainGroup = GetTerrainGroup(groupEntry.FileName, true); }); // Terrain Instances for (int i2 = 0; i2 < group.InstanceInfos.Length; ++i2) { var infoEntry = group.InstanceInfos[i2]; for (int i3 = 0; i3 < infoEntry.FileNames.Length; ++i3) { string infoPath = Path.Combine(groupDir, string.Format("{0}{1}", infoEntry.FileNames[i3], GensTerrainInstanceInfo.Extension)); if (!File.Exists(infoPath)) { LuaTerminal.LogWarning(string.Format( "WARNING: Terrain instance {0} was skipped {1}", infoEntry.FileNames[i3], "because it was not found!")); continue; } var info = new GensTerrainInstanceInfo(); info.Load(infoPath); var instance = new VPObjectInstance(info.TransformMatrix, info.FileName); // Terrain Model if (terrainGroup.ContainsKey(info.ModelFileName)) { bool success = false; Program.MainUIInvoke(new Action(() => { success = AddInstance(info.ModelFileName, instance, terrainGroup); })); continue; } string modelPath = Path.Combine(groupDir, string.Format("{0}{1}", info.ModelFileName, GensModel.TerrainExtension)); if (!File.Exists(modelPath)) { LuaTerminal.LogWarning(string.Format( "WARNING: Terrain model \"{0}\" was skipped {1}", info.ModelFileName, "because it was not found!")); continue; } var mdl = new GensModel(); mdl.Load(modelPath); mdl.Name = info.ModelFileName; // Materials var matExt = Types.MaterialExtension; foreach (var mesh in mdl.Meshes) { LoadMaterial(Path.Combine(resDir, $"{mesh.MaterialName}{matExt}"), mesh.MaterialName, nonEditable); } Program.MainUIInvoke(() => { AddModelInstance(mdl, instance, terrainGroup); }); } } } GUI.HideProgress(); return(terrainList); }
public static int LoadTexture(string path, string name = null) { // Don't bother loading this texture again if we've already loaded it name = (string.IsNullOrEmpty(name)) ? Path.GetFileNameWithoutExtension(path) : name; if (Textures.ContainsKey(name)) { return(Textures[name]); } // Figure out what type of texture to use Texture tex; switch (Types.CurrentDataType) { case Types.DataTypes.Forces: case Types.DataTypes.LW: case Types.DataTypes.Gens: case Types.DataTypes.SU: case Types.DataTypes.S06: tex = new DDS(); break; // TODO: Add Storybook Support case Types.DataTypes.Storybook: throw new NotImplementedException( "Could not load, Storybook textures are not yet supported!"); // TODO: Add Colors Support case Types.DataTypes.Colors: throw new NotImplementedException( "Could not load, Colors textures are not yet supported!"); // TODO: Add Heroes/Shadow Support case Types.DataTypes.Shadow: case Types.DataTypes.Heroes: throw new NotImplementedException( "Could not load, Heroes/Shadow textures are not yet supported!"); // TODO: Add SA2 Support case Types.DataTypes.SA2: throw new NotImplementedException( "Could not load, SA2 textures are not yet supported!"); default: throw new Exception( "Could not load, game type has not been set!"); } // Load Texture try { int texID = -1; tex.Load(path); Program.MainUIInvoke(() => { texID = AddTexture(name, tex); }); return(texID); } catch (Exception ex) { LuaTerminal.LogError($"ERROR: {ex.Message}"); return(-1); } }
// Methods public static void Load(string dataDir, string stageID, GameEntry game) { Data.Clear(); // Throw exceptions if necessary if (!Directory.Exists(dataDir)) { throw new DirectoryNotFoundException( $"Cannot load stage from \"{dataDir}\". Data Directory not found!"); } if (string.IsNullOrEmpty(stageID)) { throw new ArgumentNullException("stageID", "Cannot load stage. Invalid Stage ID!"); } GameType = game; ID = stageID; DataDir = dataDir; var resDir = new AssetDirectory(game.ResourcesDir); Data.ModelDirectories.Add(resDir); Data.ResourceDirectories.Add(resDir); // Make cache directory CacheDir = Path.Combine(Program.StartupPath, Program.CachePath, stageID); string editorCachePath = Path.Combine( CacheDir, EditorCache.FileName); Directory.CreateDirectory(CacheDir); // Load Editor Cache bool cacheExists = File.Exists(editorCachePath); EditorCache = new EditorCache() { GameType = game.Name, }; if (cacheExists) { var editorCache = new EditorCache(); editorCache.Load(editorCachePath); if (editorCache.GameType == game.Name) { EditorCache = editorCache; } } // Lua Script string pth = Path.Combine(Program.StartupPath, Program.ScriptsPath, LuaScript.GamesDir, $"{game.ShortName}{LuaScript.Extension}"); if (script == null || scriptPath != pth) { script = new LuaScript(); scriptPath = pth; try { script.DoScript(scriptPath); var canAddSetLayer = script.GetValue("CanAddSetLayer"); SceneView.CanAddLayer = (canAddSetLayer != null && canAddSetLayer.GetType() == typeof(bool)) ? (bool)canAddSetLayer : false; } catch (Exception ex) { LuaTerminal.LogError($"ERROR: {ex.Message}"); } } // Unpack/Load var unpackStopWatch = System.Diagnostics.Stopwatch.StartNew(); try { script.Call("Load", dataDir, CacheDir, stageID); } catch (Exception ex) { LuaTerminal.LogError($"ERROR: {ex.Message}, {ex.StackTrace}"); } unpackStopWatch.Stop(); Console.WriteLine("Done unpacking! Time: {0}(ms).", unpackStopWatch.ElapsedMilliseconds); // Generate new Editor Cache if (cacheExists) { File.Delete(editorCachePath); } EditorCache.Save(editorCachePath, true); // TODO: Remove this line //CurrentSetLayer = Sets[0]; }