Пример #1
0
        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);
            }
        }
Пример #2
0
        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();
            }
        }
Пример #3
0
        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];
            }
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        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];
            }
        }
Пример #6
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;
                    }
                }
            }
        }
Пример #7
0
        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);
            }
        }