Example #1
0
 public TileAnimationCommand(Layer layer, Location tileLocation, AnimatedTile animatedTile)
 {
     m_layer = layer;
     m_tileLocation = tileLocation;
     m_animatedTile = animatedTile;
     m_oldTile = null;
     m_description = "Set animated tile at " + tileLocation;
 }
Example #2
0
        /// <summary>
        /// Clones this AnimatedTile for the given Layer
        /// </summary>
        /// <param name="layer">Layer to assign the new tile to</param>
        /// <returns>Cloned AnimatedTile instance</returns>
        public override Tile Clone(Layer layer)
        {
            List <StaticTile> tileFrames = new List <StaticTile>(m_tileFrames.Length);

            foreach (StaticTile tileFrame in m_tileFrames)
            {
                tileFrames.Add((StaticTile)tileFrame.Clone(layer));
            }

            Tile tileClone = new AnimatedTile(layer, tileFrames.ToArray(), m_frameInterval);

            tileClone.Properties.CopyFrom(Properties);

            return(tileClone);
        }
        public static void setMapTilesheet(Map map, TileSheet tilesheet, int tileX, int tileY, string layer, int whichTileSheet = 0, int index = 0, AnimatedTile animations = null)
        {
            try
            {
                if (!tilesheet.Id.Contains("zCWF"))
                {
                    index = 0;
                }
                Tile tile    = map.GetLayer(layer).Tiles[tileX, tileY];
                Tile newTile = null;
                if (animations != null)
                {
                    List <StaticTile> statics = new List <StaticTile>();
                    for (int i = 0; i < animations.Frames; i++)
                    {
                        statics.Add(new StaticTile(map.GetLayer(layer), tilesheet, BlendMode.Alpha, (i * (animations.Floor ? 2 : 1)) + (tile.TileIndex - index)));
                    }
                    newTile = new xTile.Tiles.AnimatedTile(map.GetLayer(layer), statics.ToArray(), animations.Length);
                    foreach (var p in tile.Properties)
                    {
                        newTile.Properties.Add(p);
                    }

                    PyTK.PyUtils.setDelayedAction(200, () => map.GetLayer(layer).Tiles[tileX, tileY] = newTile);
                }
                else
                {
                    newTile = new StaticTile(map.GetLayer(layer), tilesheet, BlendMode.Alpha, tile.TileIndex - index);
                    foreach (var p in tile.Properties)
                    {
                        newTile.Properties.Add(p);
                    }

                    PyTK.PyUtils.setDelayedAction(200, () => map.GetLayer(layer).Tiles[tileX, tileY] = newTile);
                }
            }
            catch
            {
            }
        }
Example #4
0
        public Map Load(Stream stream)
        {
            ReadHeader(stream);

            MphdRecord mphdRecord = null;
            string[] authorLines = null;
            Color[] colourMap = null;
            BlockRecord[] blockRecords = null;
            AnimationRecord[] animationRecords = null;
            Image imageSource = null;
            short[][] layers = new short[8][];

            Dictionary<string, Chunk> chunks = MapChunks(stream);

            if (!chunks.ContainsKey("MPHD"))
                throw new Exception("Header chunk MPHD missing");
            Chunk mphdChunk = chunks["MPHD"];
            mphdRecord = ReadChunkMPHD(stream, mphdChunk);

            if (mphdRecord.BlockDepth == 8)
            {
                if (!chunks.ContainsKey("CMAP"))
                    throw new Exception("Colour map chuck CMAP is required for 8bit graphics blocks");
                Chunk cmapChunk = chunks["CMAP"];
                colourMap = ReadChunkCMAP(stream, cmapChunk);
            }

            if (chunks.ContainsKey("ATHR"))
                authorLines = ReadChunkATHR(stream, chunks["ATHR"]);

            if (!chunks.ContainsKey("BKDT"))
                throw new Exception("Block data chunk BKDT missing");
            Chunk bkdtChunk = chunks["BKDT"];
            blockRecords = ReadChunkBKDT(stream, bkdtChunk, mphdRecord);

            // optional ?
            if (chunks.ContainsKey("ANDT"))
            {
                Chunk andtChunk = chunks["ANDT"];
                animationRecords = ReadChunkANDT(stream, andtChunk, mphdRecord);
            }

            if (!chunks.ContainsKey("BGFX"))
                throw new Exception("Block graphics chunk BGFX missing");
            Chunk bgfxChunk = chunks["BGFX"];
            imageSource = ReadChunkBGFX(stream, bgfxChunk, mphdRecord, colourMap);

            if (!chunks.ContainsKey("BODY"))
                throw new Exception("Body chunk BODY missing");
            Chunk bodyChunk = chunks["BODY"];
            layers[0] = ReadChunkLayer(stream, bodyChunk, mphdRecord);

            // additional layers
            for (int layer = 1; layer <= 7; layer++)
            {
                string chunkId = "LYR" + layer;
                if (chunks.ContainsKey(chunkId))
                {
                    Chunk layerChuck = chunks[chunkId];
                    layers[layer] = ReadChunkLayer(stream, layerChuck, mphdRecord);
                }
            }

            // new map
            Map map = new Map();

            // attach ATHR lines as description
            if (authorLines != null)
            {
                StringBuilder stringBuilder = new StringBuilder();
                foreach (string authorLine in authorLines)
                    stringBuilder.AppendLine(authorLine);
                map.Description = stringBuilder.ToString();
            }

            // prompt user to save tilesheet image source
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.CheckPathExists = true;
            saveFileDialog.Filter = "Portable Network Geaphics (*.png)|*.png";
            saveFileDialog.OverwritePrompt = true;
            saveFileDialog.Title = "Save tile sheet image source as";
            saveFileDialog.ValidateNames = true;
            if (saveFileDialog.ShowDialog() == DialogResult.Cancel)
                throw new Exception("Mappy FMAP file import aborted");

            string tileSheetImageSource = saveFileDialog.FileName;

            imageSource.Save(tileSheetImageSource, ImageFormat.Png);

            // determine global tile size
            xTile.Dimensions.Size tileSize = new xTile.Dimensions.Size(mphdRecord.BlockWidth, mphdRecord.BlockHeight);

            // add tilesheet
            TileSheet tileSheet = new TileSheet("BGFX", map, tileSheetImageSource,
                new xTile.Dimensions.Size(1, mphdRecord.NumBlockGfx), tileSize);
            map.AddTileSheet(tileSheet);

            // determine global map size
            xTile.Dimensions.Size mapSize = new xTile.Dimensions.Size(mphdRecord.MapWidth, mphdRecord.MapHeight);

            // create layers
            for (int layerIndex = 0; layerIndex < 8; layerIndex++)
            {
                if (layers[layerIndex] == null)
                    continue;

                string layerId = layerIndex == 0 ? "BODY" : "LYR" + layerIndex;
                Layer layer = new Layer(layerId, map, mapSize, tileSize);
                map.AddLayer(layer);
                for (int tileY = 0; tileY < mapSize.Height; tileY++)
                {
                    for (int tileX = 0; tileX < mapSize.Width; tileX++)
                    {
                        int layerOffset = tileY * mapSize.Width + tileX;
                        int tileIndex = layers[layerIndex][layerOffset];
                        if (tileIndex >= 0)
                        {
                            layer.Tiles[tileX, tileY] = new StaticTile(layer, tileSheet, BlendMode.Alpha, tileIndex);
                        }
                        else
                        {
                            AnimationRecord animationRecord = animationRecords[-tileIndex - 1];
                            StaticTile[] tileFrames = new StaticTile[animationRecord.Frames.Length];

                            for (int frameIndex = 0; frameIndex < animationRecord.Frames.Length; frameIndex++)
                                tileFrames[frameIndex] = new StaticTile(layer, tileSheet, BlendMode.Alpha, animationRecord.Frames[frameIndex]);

                            // process loop types
                            switch (animationRecord.Type)
                            {
                                case 2: // LOOPR: loop backward
                                    Array.Reverse(tileFrames);
                                    break;
                                case 5: // PPFF -+
                                case 6: // PPRR  | - different states for ping-pong animation
                                case 7: // PPRF  | - treat all the same
                                case 8: // PPFR -+
                                    StaticTile[] pingPongFrames = new StaticTile[tileFrames.Length * 2 - 1];
                                    Array.Copy(tileFrames, pingPongFrames, tileFrames.Length);
                                    Array.Copy(tileFrames, 0, pingPongFrames, tileFrames.Length, tileFrames.Length - 1);
                                    Array.Reverse(pingPongFrames, tileFrames.Length, tileFrames.Length - 1);
                                    tileFrames = pingPongFrames;
                                    break;
                                default: // treat all other cases as LOOPF
                                    // 0 = NONE
                                    // 1 = LOOPF: loop forward
                                    // 3 = ONCE, 4 = ONCEH: one-off animations
                                    // 9 = ONCES: one-off animations
                                    break;
                            }

                            AnimatedTile animatedTile = new AnimatedTile(layer, tileFrames, (long)animationRecord.Delay * 20);
                            layer.Tiles[tileX, tileY] = animatedTile;
                        }
                    }
                }
            }

            return map;
        }
Example #5
0
        private bool AnimationsMatch(AnimatedTile animatedTile1, AnimatedTile animatedTile2)
        {
            if (animatedTile1.FrameInterval != animatedTile2.FrameInterval)
                return false;
            if (animatedTile1.TileFrames.Length != animatedTile2.TileFrames.Length)
                return false;

            for (int index = 0; index < animatedTile1.TileFrames.Length; index++)
            {
                StaticTile tileFrame1 = animatedTile1.TileFrames[index];
                StaticTile tileFrame2 = animatedTile2.TileFrames[index];
                if (tileFrame1.TileSheet != tileFrame2.TileSheet)
                    return false;
                if (tileFrame1.TileIndex != tileFrame2.TileIndex)
                    return false;
            }

            return true;
        }
Example #6
0
        private void WriteChunkLayer(Stream stream, Layer layer, string chunkId, AnimatedTile[] animatedTiles)
        {
            // BODY or LYR1 .. LYR7
            WriteSequence(stream, chunkId);

            // size is array of shorts
            int layerWidth = layer.LayerWidth;
            int layerHeight = layer.LayerHeight;
            WriteMsb(stream, (long)(layerWidth * layerHeight * 2));

            for (int tileY = 0; tileY < layerHeight; tileY++)
            {
                for (int tileX = 0; tileX < layerWidth; tileX++)
                {
                    Tile tile = layer.Tiles[tileX, tileY];
                    if (tile == null)
                        WriteLsb(stream, (short)0);
                    else if (tile is StaticTile)
                        WriteLsb(stream, (short)(tile.TileIndex * 32));
                    else if (tile is AnimatedTile)
                    {
                        if (animatedTiles == null)
                            WriteLsb(stream, (short)0);
                        else
                        {
                            AnimatedTile animatedTile = (AnimatedTile)tile;
                            int animationIndex = -1;
                            for (int listIndex = 0; listIndex < animatedTiles.Length; listIndex++)
                            {
                                if (AnimationsMatch(animatedTile, animatedTiles[listIndex]))
                                {
                                    animationIndex = listIndex;
                                    break;
                                }
                            }
                            if (animationIndex < 0)
                                WriteLsb(stream, (short)0);
                            else
                            {
                                short animationOffset = (short)((animationIndex - animatedTiles.Length) * AnimationRecord.SIZE);
                                WriteLsb(stream, animationOffset);
                            }
                        }
                    }
                    else
                        throw new Exception("Unknown tile type: " + tile.GetType());
                }
            }
        }
Example #7
0
        private void OnDialogApply(object sender, EventArgs eventArgs)
        {
            List<StaticTile> tileFrames = new List<StaticTile>();
            foreach (ListViewItem listViewItem in m_animationListView.Items)
                tileFrames.Add((StaticTile)listViewItem.Tag);
            AnimatedTile animatedTile = new AnimatedTile(
                m_layer, tileFrames.ToArray(), (long)m_frameIntervalTextbox.Value);

            // copy anim tile-level properties
            Tile oldTile = m_layer.Tiles[m_tileLocation];
            if (oldTile != null)
                animatedTile.Properties.CopyFrom(oldTile.Properties);

            Command command = new TileAnimationCommand(m_layer, m_tileLocation, animatedTile);
            CommandHistory.Instance.Do(command);

            MarkAsApplied();
        }
Example #8
0
        private void StoreAnimatedTile(Stream stream, AnimatedTile animatedTile)
        {
            StoreInt32(stream, (int)animatedTile.FrameInterval);
            StoreInt32(stream, animatedTile.TileFrames.Count());

            TileSheet prevTileSheet = null;
            foreach (StaticTile tileFrame in animatedTile.TileFrames)
            {
                TileSheet tileSheet = tileFrame.TileSheet;
                if (tileSheet != prevTileSheet)
                {
                    stream.WriteByte((byte)'T');
                    StoreString(stream, tileSheet.Id);
                    prevTileSheet = tileSheet;
                }
                stream.WriteByte((byte)'S');
                StoreStaticTile(stream, tileFrame);
            }

            StoreProperties(stream, animatedTile);
        }
Example #9
0
        private AnimatedTile LoadAnimatedTile(Stream stream, Layer layer)
        {
            long frameInterval = LoadInt32(stream);
            int tileFrameCount = LoadInt32(stream);
            List<StaticTile> tileFrames = new List<StaticTile>(tileFrameCount);

            Map map = layer.Map;
            TileSheet tileSheet = null;
            while(tileFrameCount > 0)
            {
                char ch = (char)stream.ReadByte();
                if (ch == 'T')
                {
                    string tileSheetId = LoadString(stream);
                    tileSheet = map.GetTileSheet(tileSheetId);
                }
                else if (ch == 'S')
                {
                    tileFrames.Add(LoadStaticTile(stream, layer, tileSheet));
                    --tileFrameCount;
                }
                else
                    throw new Exception("Expected character byte 'T' or 'S'");
            }

            AnimatedTile animatedTile = new AnimatedTile(layer, tileFrames.ToArray(), frameInterval);

            LoadProperties(stream, animatedTile);

            return animatedTile;
        }
Example #10
0
        /// <summary>
        /// Clones this AnimatedTile for the given Layer
        /// </summary>
        /// <param name="layer">Layer to assign the new tile to</param>
        /// <returns>Cloned AnimatedTile instance</returns>
        public override Tile Clone(Layer layer)
        {
            List<StaticTile> tileFrames = new List<StaticTile>(m_tileFrames.Length);
            foreach (StaticTile tileFrame in m_tileFrames)
                tileFrames.Add((StaticTile)tileFrame.Clone(layer));

            Tile tileClone = new AnimatedTile(layer, tileFrames.ToArray(), m_frameInterval);
            tileClone.Properties.CopyFrom(Properties);

            return tileClone;
        }
Example #11
0
        private void StoreAnimatedTile(AnimatedTile animatedTile, XmlWriter xmlWriter)
        {
            xmlWriter.WriteStartElement("Animated");
            xmlWriter.WriteAttributeString("Interval", animatedTile.FrameInterval.ToString());

            xmlWriter.WriteStartElement("Frames");
            TileSheet tileSheet = null;
            foreach (StaticTile tileFrame in animatedTile.TileFrames)
            {
                if (tileSheet != tileFrame.TileSheet)
                {
                    xmlWriter.WriteStartElement("TileSheet");
                    xmlWriter.WriteAttributeString("Ref", tileFrame.TileSheet.Id);
                    xmlWriter.WriteEndElement();

                    tileSheet = tileFrame.TileSheet;
                }
                StoreStaticTile(tileFrame, xmlWriter);
            }
            xmlWriter.WriteEndElement(); // Frames

            if (animatedTile.Properties.Count > 0)
                StoreProperties(animatedTile, xmlWriter);

            xmlWriter.WriteEndElement();
        }
Example #12
0
        private AnimatedTile LoadAnimatedTile(XmlHelper xmlHelper, Layer layer, TileSheet tileSheet)
        {
            int frameInterval = xmlHelper.GetIntAttribute("Interval");

            xmlHelper.AdvanceStartElement("Frames");

            Map map = layer.Map;
            List<StaticTile> tileFrames = new List<StaticTile>();

            while (xmlHelper.AdvanceNode() != XmlNodeType.EndElement)
            {
                if (xmlHelper.XmlReader.Name == "Static")
                    tileFrames.Add(LoadStaticTile(xmlHelper, layer, tileSheet));
                else if (xmlHelper.XmlReader.Name == "TileSheet")
                {
                    string tileSheetRef = xmlHelper.GetAttribute("Ref");
                    tileSheet = map.GetTileSheet(tileSheetRef);
                }
            }

            AnimatedTile animatedTile
                = new AnimatedTile(layer, tileFrames.ToArray(), frameInterval);

            // end of this element or optional props
            if (xmlHelper.AdvanceNode() != XmlNodeType.EndElement)
                LoadProperties(xmlHelper, animatedTile);

            return animatedTile;
        }