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; }
/// <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 { } }
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; }
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; }
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()); } } }
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(); }
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); }
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; }
/// <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; }
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(); }
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; }