private void GetRoomAndSpawnID(WScene scene, out byte room, out byte spawn) { room = 0; spawn = 0; Selection <WDOMNode> selected = null; if (scene.World.CurrentMode is ActorMode) { ActorMode mode = scene.World.CurrentMode as ActorMode; selected = mode.EditorSelection; } if (selected != null && selected.PrimarySelectedObject is SpawnPoint) { SpawnPoint spawn_pt = (SpawnPoint)selected.PrimarySelectedObject; room = spawn_pt.Room; spawn = spawn_pt.SpawnIndex; } else { room = GetRoomNumberFromSceneName(scene.Name); } }
public override void PopulateDefaultProperties() { Name = "Link"; EnemyNumber = -1; Event = null; Unknown4 = -1; Unknown6 = -1; // Try to assign the room index automatically if this is a room spawn. WDOMNode cur_object = this; while (cur_object.Parent != null) { cur_object = cur_object.Parent; } WScene scene = cur_object as WScene; if (scene is WRoom) { WRoom room = scene as WRoom; Room = room.RoomIndex; } // Automatically assign it the first unused spawn ID in this scene. List <int> possibleSpawnIDs = Enumerable.Range(0, 256).ToList(); List <SpawnPoint> otherSpawns = scene.GetChildrenOfType <SpawnPoint>(); foreach (var spawn in otherSpawns) { if (spawn == this) { continue; } possibleSpawnIDs.Remove(spawn.SpawnID); } if (possibleSpawnIDs.Count == 0) { SpawnID = 255; } else { SpawnID = possibleSpawnIDs.First(); } }
public void LoadFromDirectory(string inPath, string sourcePath) { if (!Directory.Exists(inPath)) { throw new ArgumentException("Cannot load map from non-existant directory", "filePath"); } m_mapName = Path.GetFileName(inPath); m_savePath = Path.GetFullPath(sourcePath); Console.WriteLine("Loading map {0}...", m_mapName); // Sort them alphabetically so we always load the Stage last. List <string> sortedScenes = new List <string>(Directory.GetDirectories(inPath)); sortedScenes.Sort(); WStage stage = null; foreach (var sceneFolder in sortedScenes) { string sceneName = Path.GetFileName(sceneFolder); WScene scene = null; if (sceneName.ToLower().StartsWith("room")) // { string roomNumberStr = sceneName.Substring(4); int roomNumber; if (int.TryParse(roomNumberStr, out roomNumber)) { scene = new WRoom(m_world, roomNumber); } else { Console.WriteLine("Unknown Room Number for Room: \"{0}\", Skipping!", sceneName); } } else if (string.Compare(sceneName, "Stage", true) == 0) { stage = new WStage(m_world); scene = stage; } else { Console.WriteLine("Unknown Map Folder: {0}", sceneFolder); } if (scene != null) { m_sceneList.Add(scene); scene.Load(sceneFolder); } } // Now that we've loaded all of the data, we'll do some post processing. if (stage != null) { List <WRoom> allRooms = new List <WRoom>(); foreach (var scene in m_sceneList) { if (scene is WRoom) { allRooms.Add((WRoom)scene); } } stage.PostLoadProcessing(inPath, allRooms); } if (m_sceneList.Count > 0) { FocusedScene = m_sceneList[m_sceneList.Count - 1]; } }
public void ExportToStream(EndianBinaryWriter writer, WScene scene) { // Build a dictionary which lists unique FourCC's and a list of all relevant actors. var actorCategories = new Dictionary <string, List <WActorNode> >(); foreach (var child in scene) { WActorNode actor = child as WActorNode; if (actor != null) { string fixedFourCC = ChunkHeader.LayerToFourCC(actor.FourCC, actor.Layer); if (!actorCategories.ContainsKey(fixedFourCC)) { actorCategories[fixedFourCC] = new List <WActorNode>(); } actorCategories[fixedFourCC].Add(actor); } } // Create a chunk header for each one. var chunkHeaders = new List <ChunkHeader>(); foreach (var kvp in actorCategories) { ChunkHeader header = new ChunkHeader(); header.FourCC = kvp.Key; header.ElementCount = kvp.Value.Count; chunkHeaders.Add(header); } long chunkStart = writer.BaseStream.Position; // Write the Header writer.Write(chunkHeaders.Count); for (int i = 0; i < chunkHeaders.Count; i++) { writer.Write((int)0); // Dummy Placeholder values for the Chunk Header. writer.Write((int)0); writer.Write((int)0); } // For each chunk, write the data for that chunk. Before writing the data, get the current offset and update the header. List <WActorNode>[] dictionaryData = new List <WActorNode> [actorCategories.Count]; actorCategories.Values.CopyTo(dictionaryData, 0); for (int i = 0; i < chunkHeaders.Count; i++) { ChunkHeader header = chunkHeaders[i]; chunkHeaders[i] = new ChunkHeader(header.FourCC, header.ElementCount, (int)(writer.BaseStream.Position - chunkStart)); List <WActorNode> actors = dictionaryData[i]; foreach (var actor in actors) { MapActorDescriptor template = m_sActorDescriptors.Find(x => x.FourCC == actor.FourCC); if (template == null) { Console.WriteLine("Unsupported FourCC (\"{0}\") for exporting!", actor.FourCC); continue; } WriteActorToChunk(actor, template, writer); } } // Now that we've written every actor to file we can go back and re-write the headers now that we know their offsets. writer.BaseStream.Position = chunkStart + 0x4; // 0x4 is the offset to the Chunk Headers foreach (var header in chunkHeaders) { writer.WriteFixedString(header.FourCC, 4); // FourCC writer.Write(header.ElementCount); // Number of Entries writer.Write(header.ChunkOffset); // Offset from start of file. } // Seek to the end of the file, and then pad us to 32-byte alignment. writer.BaseStream.Seek(0, SeekOrigin.End); int delta = WMath.Pad32Delta(writer.BaseStream.Position); for (int i = 0; i < delta; i++) { writer.Write((byte)0xFF); } }
public void LoadFromDirectory(string inPath, string sourcePath) { if (!Directory.Exists(inPath)) { throw new ArgumentException("Cannot load map from non-existant directory", "filePath"); } m_mapName = Path.GetFileName(inPath); m_savePath = Path.GetFullPath(sourcePath); Console.WriteLine("Loading map {0}...", m_mapName); // Sort them alphabetically to guarantee rooms are in order, then move the Stage folder to the start of the list so we always load it first. List <string> sortedScenes = new List <string>(Directory.GetDirectories(inPath)); sortedScenes.Sort(); var stageFolder = sortedScenes[sortedScenes.Count - 1]; sortedScenes.RemoveAt(sortedScenes.Count - 1); sortedScenes.Insert(0, stageFolder); WStage stage = null; foreach (var sceneFolder in sortedScenes) { string sceneName = Path.GetFileName(sceneFolder); VirtualFilesystemDirectory src_dir = new VirtualFilesystemDirectory(sceneFolder); src_dir.ImportFromDisk(sceneFolder); WScene scene = null; if (sceneName.ToLower().StartsWith("room")) // { string roomNumberStr = sceneName.Substring(4); int roomNumber; if (int.TryParse(roomNumberStr, out roomNumber)) { scene = new WRoom(m_world, roomNumber); scene.SourceDirectory = src_dir; } else { Console.WriteLine("Unknown Room Number for Room: \"{0}\", Skipping!", sceneName); } } else if (string.Compare(sceneName, "Stage", true) == 0) { stage = new WStage(m_world); scene = stage; scene.SourceDirectory = src_dir; } else { Console.WriteLine("Unknown Map Folder: {0}", sceneFolder); } if (scene != null) { m_sceneList.Add(scene); scene.Load(sceneFolder); } } // Now that we've loaded all of the data, we'll do some post processing. if (stage != null) { List <WRoom> allRooms = new List <WRoom>(); foreach (var scene in m_sceneList) { if (scene is WRoom) { allRooms.Add((WRoom)scene); } } stage.PostLoadProcessing(inPath, allRooms); } if (m_sceneList.Count > 1) { // Default to selecting the second item in the list, which will be the lowest-numbered room. FocusedScene = m_sceneList[1]; } else if (m_sceneList.Count > 0) { // If no rooms are loaded, select the stage by default instead. FocusedScene = m_sceneList[0]; } }
private void GetRoomAndSpawnID(WScene scene, out int room, out int spawn) { room = 0; spawn = 0; Selection <WDOMNode> selected = null; if (scene.World.CurrentMode is ActorMode) { ActorMode mode = scene.World.CurrentMode as ActorMode; selected = mode.EditorSelection; } room = GetRoomNumberFromSceneName(scene.Name); if (selected != null && selected.PrimarySelectedObject is SpawnPoint) { // If the user has a spawn point selected, spawn the player at that spawn point. SpawnPoint spawn_pt = (SpawnPoint)selected.PrimarySelectedObject; room = spawn_pt.Room; spawn = spawn_pt.SpawnID; } else if (selected != null && selected.PrimarySelectedObject != null) { // If the user has something besides a spawn point selected, spawn the player at the first spawn point in the room that the selected object is in. WDOMNode cur_object = selected.PrimarySelectedObject; while (cur_object.Parent != null) { cur_object = cur_object.Parent; } WRoom room_node; if (cur_object is WRoom) { room_node = cur_object as WRoom; } else { // A stage entity is selected. Use whatever spawn point is physically closest to the selected entity, regardless of what scene that spawn is in. List <SpawnPoint> allSpawnPts = new List <SpawnPoint>(); foreach (WScene scn in scene.World.Map.SceneList) { allSpawnPts.AddRange(scn.GetChildrenOfType <SpawnPoint>()); } SpawnPoint closestSpawnPt = allSpawnPts.OrderBy(spawnPt => (spawnPt.Transform.Position - selected.PrimarySelectedObject.Transform.Position).Length).First(); room = closestSpawnPt.Room; spawn = closestSpawnPt.SpawnID; return; } SpawnPoint spawn_pt = room_node.GetChildrenOfType <SpawnPoint>().FirstOrDefault(); if (spawn_pt != null) { room = spawn_pt.Room; spawn = spawn_pt.SpawnID; } else { WStage stage = room_node.World.Map.SceneList.First(x => x.GetType() == typeof(WStage)) as WStage; spawn_pt = stage.GetChildrenOfType <SpawnPoint>().FirstOrDefault(x => x.Room == room_node.RoomIndex); if (spawn_pt != null) { room = spawn_pt.Room; spawn = spawn_pt.SpawnID; } } } }
public void ExportToStream(EndianBinaryWriter writer, WScene scene) { // Build a dictionary which lists unique FourCC's and a list of all relevant actors. var actorCategories = new Dictionary <FourCC, List <SerializableDOMNode> >(); foreach (var child in scene) { var groupNode = child as WDOMGroupNode; if (groupNode == null) { continue; } // If this is an ACTR, SCOB, or TRES group node, we have to dig into it to get the layers. if (groupNode.FourCC == FourCC.ACTR || groupNode.FourCC == FourCC.SCOB || groupNode.FourCC == FourCC.TRES) { foreach (var layer in groupNode.Children) { foreach (var obj in layer.Children) { var actor = obj as SerializableDOMNode; if (actor != null) { AddObjectToDictionary(actor, actorCategories); } } } } else { foreach (var obj in groupNode.Children) { var actor = obj as SerializableDOMNode; if (actor != null) { AddObjectToDictionary(actor, actorCategories); } } } } // Create a chunk header for each one. var chunkHeaders = new List <ChunkHeader>(); foreach (var kvp in actorCategories) { ChunkHeader header = new ChunkHeader(); header.FourCC = kvp.Key; header.ElementCount = kvp.Value.Count; chunkHeaders.Add(header); } long chunkStart = writer.BaseStream.Position; // Write the Header writer.Write(chunkHeaders.Count); for (int i = 0; i < chunkHeaders.Count; i++) { writer.Write((int)0); // Dummy Placeholder values for the Chunk Header. writer.Write((int)0); writer.Write((int)0); } // For each chunk, write the data for that chunk. Before writing the data, get the current offset and update the header. List <SerializableDOMNode>[] dictionaryData = new List <SerializableDOMNode> [actorCategories.Count]; actorCategories.Values.CopyTo(dictionaryData, 0); for (int i = 0; i < chunkHeaders.Count; i++) { ChunkHeader header = chunkHeaders[i]; chunkHeaders[i] = new ChunkHeader(header.FourCC, header.ElementCount, (int)(writer.BaseStream.Position - chunkStart)); List <SerializableDOMNode> actors = dictionaryData[i]; foreach (var actor in actors) { MapActorDescriptor template = Globals.ActorDescriptors.Find(x => x.FourCC == actor.FourCC); if (template == null) { Console.WriteLine("Unsupported FourCC (\"{0}\") for exporting!", actor.FourCC); continue; } actor.PreSave(); actor.Save(writer); //WriteActorToChunk(actor, template, writer); } } // Now that we've written every actor to file we can go back and re-write the headers now that we know their offsets. writer.BaseStream.Position = chunkStart + 0x4; // 0x4 is the offset to the Chunk Headers foreach (var header in chunkHeaders) { writer.WriteFixedString(FourCCConversion.GetStringFromEnum(header.FourCC), 4); // FourCC writer.Write(header.ElementCount); // Number of Entries writer.Write(header.ChunkOffset); // Offset from start of file. } // Seek to the end of the file, and then pad us to 32-byte alignment. writer.BaseStream.Seek(0, SeekOrigin.End); int delta = WMath.Pad32Delta(writer.BaseStream.Position); for (int i = 0; i < delta; i++) { writer.Write(0xFF); } }