X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=tools%2Ftilemanager%2FTile.cs;h=a082fb9299adf2f1ef97ee9d614dafddcab37a83;hb=e449041f97af574103b20cca6d45c06d71677a98;hp=d85d9ed2906fb687ed7eca55d7fd35079b7df646;hpb=7af002362d894832570cffcda1afbd5bafee06eb;p=supertux.git diff --git a/tools/tilemanager/Tile.cs b/tools/tilemanager/Tile.cs index d85d9ed29..a082fb929 100644 --- a/tools/tilemanager/Tile.cs +++ b/tools/tilemanager/Tile.cs @@ -1,3 +1,4 @@ +// $Id$ using System; using System.Collections; using System.IO; @@ -9,80 +10,124 @@ public class ImageRegion { public Rectangle Region; } +public class Attribute { + /// solid tile that is indestructible by Tux + public const int SOLID = 0x0001; + /// uni-directional solid tile + public const int UNISOLID = 0x0002; + /// a brick that can be destroyed by jumping under it + public const int BRICK = 0x0004; + /// the level should be finished when touching a goaltile. + /// + /// if data is 0 then the endsequence should be + /// triggered, if data is 1 then we can finish + /// the level instantly. + /// + public const int GOAL = 0x0008; + /// slope tile + public const int SLOPE = 0x0010; + /// Bonusbox, content is stored in data + public const int FULLBOX = 0x0020; + /// Tile is a coin + public const int COIN = 0x0040; + /// an ice brick that makes tux sliding more than usual + public const int ICE = 0x0100; + /// a water tile in which tux starts to swim + public const int WATER = 0x0200; + /// a tile that hurts the player if he touches it + public const int HURTS = 0x0400; + /// for lava: WATER, HURTS, FIRE + public const int FIRE = 0x0800; + + + // TODO: Find out why are worldmap tile attributes stored in data(s) + // worldmap flags + public const int WORLDMAP_NORTH = 0x0001; + public const int WORLDMAP_SOUTH = 0x0002; + public const int WORLDMAP_EAST = 0x0004; + public const int WORLDMAP_WEST = 0x0008; + + public const int WORLDMAP_STOP = 0x0010; +} + public class Tile { - public int ID; - public bool Solid; - public bool UniSolid; - public bool Ice; - public bool Water; - public bool Slope; - public bool Hidden; - public bool Hurts; - public bool FullBox; - public bool Brick; - public bool Coin; - public bool Goal; - public int NextTile; - public int Data; - public float AnimFps; - public string EditorImage; - public ArrayList Images = new ArrayList(); - - public Tile() { - ID = -1; - NextTile = -1; - AnimFps = 1; - } + public int ID; + public bool Hidden; + public int NextTile; + public int Attributes; + public int Data; + public float AnimFps; + public string OneWayString; + public ArrayList Images = new ArrayList(); + public ArrayList EditorImages = new ArrayList(); + + public Tile() { + ID = -1; + NextTile = -1; + AnimFps = 1; + } + + public bool HasAttribute (int Attrib) + { + return (Attributes & Attrib) != 0; + } + + public void SetAttribute (int Attrib, bool Value) + { + if (Value) + Attributes |= Attrib; + else + Attributes &= (~Attrib); //NOTE: "~" stands for bitwise negation + } + + public bool HasWMAttribute (int Attrib) + { + return (Data & Attrib) != 0; + } + + public void SetWMAttribute (int Attrib, bool Value) + { + if (Value) + Data |= Attrib; + else + Data &= (~Attrib); //NOTE: "~" stands for bitwise negation + } public void Write(LispWriter writer) { writer.StartList("tile"); writer.Write("id", ID); - if(Images.Count > 0) { - writer.StartList("images"); - foreach(ImageRegion region in Images) { - if(region.Region.Width != 0) { - writer.WriteVerbatimLine( - String.Format("(region \"{0}\" {1} {2} {3} {4})", - region.ImageFile, region.Region.Left, - region.Region.Top, region.Region.Width, - region.Region.Height)); - } else { - writer.WriteVerbatimLine( - "\"" + region.ImageFile + "\""); - } - } - writer.EndList("images"); - } else { - Console.WriteLine("no images on tile " + ID); - } + WriteTileImages(writer, "images", Images); - if(Solid) + if(HasAttribute(Attribute.SOLID)) writer.Write("solid", true); - if(UniSolid) + if(HasAttribute(Attribute.UNISOLID)) writer.Write("unisolid", true); - if(Ice) + if(HasAttribute(Attribute.ICE)) writer.Write("ice", true); - if(Water) + if(HasAttribute(Attribute.WATER)) writer.Write("water", true); - if(Slope) + if(HasAttribute(Attribute.SLOPE)) writer.Write("slope-type", Data); - if(Hurts) + if(HasAttribute(Attribute.HURTS)) writer.Write("hurts", true); - if(Hidden) - writer.Write("hidden", true); - if(Coin) + if(HasAttribute(Attribute.FIRE)) + writer.Write("fire", true); + if(HasAttribute(Attribute.COIN)) writer.Write("coin", true); - if(FullBox) + if(HasAttribute(Attribute.FULLBOX)) writer.Write("fullbox", true); - if(Brick) + if(HasAttribute(Attribute.BRICK)) writer.Write("brick", true); + if(HasAttribute(Attribute.GOAL)) + writer.Write("goal", true); + + if(Hidden) + writer.Write("hidden", true); if(NextTile >= 0) writer.Write("next-tile", NextTile); - if(Goal) - writer.Write("goal", true); - if(EditorImage != null) - writer.Write("editor-images", EditorImage); + if(EditorImages != null) + WriteTileImages(writer, "editor-images", EditorImages); if(Data != 0) writer.Write("data", Data); if(Images.Count > 1) { @@ -90,6 +135,9 @@ public class Tile { AnimFps = 40; writer.Write("anim-fps", AnimFps); } + if(!String.IsNullOrEmpty(OneWayString)) { + writer.Write("one-way", OneWayString); + } writer.EndList("tile"); } @@ -98,7 +146,7 @@ public class Tile { while(parser.Parse() && parser.Depth >= d) { if(parser.Depth == d+1) { if(parser.Type != Parser.LispType.SYMBOL) - throw new Exception("expected SYMBOL"); + throw new Exception("expected SYMBOL at single tile deserialization level, but found \"" + parser.StringValue + "\""); string symbol = parser.SymbolValue; parser.Parse(); switch(symbol) { @@ -106,53 +154,76 @@ public class Tile { ID = parser.IntegerValue; break; case "images": - ParseTileImages(parser); + ParseTileImages(parser, Images); break; case "editor-images": - EditorImage = parser.StringValue; + ParseTileImages(parser, EditorImages); + break; + case "anim-fps": + AnimFps = parser.FloatValue; + break; + case "one-way": + OneWayString = parser.StringValue; + break; + case "data": + Data = parser.IntegerValue; + break; + case "next-tile": + NextTile = parser.IntegerValue; + break; + case "hidden": + Hidden = parser.BoolValue; break; case "solid": - Solid = parser.BoolValue; + SetAttribute(Attribute.SOLID, parser.BoolValue); break; case "unisolid": - UniSolid = parser.BoolValue; + SetAttribute(Attribute.UNISOLID, parser.BoolValue); break; case "ice": - Ice = parser.BoolValue; + SetAttribute(Attribute.ICE, parser.BoolValue); break; case "water": - Water = parser.BoolValue; + SetAttribute(Attribute.WATER, parser.BoolValue); break; case "slope-type": - Slope = true; + SetAttribute(Attribute.SLOPE, true); Data = parser.IntegerValue; break; - case "anim-fps": - AnimFps = parser.FloatValue; - break; case "hurts": - Hurts = parser.BoolValue; + SetAttribute(Attribute.HURTS, parser.BoolValue); break; - case "hidden": - Hidden = parser.BoolValue; - break; - case "data": - Data = parser.IntegerValue; - break; - case "next-tile": - NextTile = parser.IntegerValue; + case "fire": + SetAttribute(Attribute.FIRE, parser.BoolValue); break; case "brick": - Brick = parser.BoolValue; + SetAttribute(Attribute.BRICK, parser.BoolValue); break; case "fullbox": - FullBox = parser.BoolValue; + SetAttribute(Attribute.FULLBOX, parser.BoolValue); break; case "coin": - Coin = parser.BoolValue; + SetAttribute(Attribute.COIN, parser.BoolValue); break; case "goal": - Goal = parser.BoolValue; + SetAttribute(Attribute.GOAL, parser.BoolValue); + break; + + //Worldmap attributes section - these are stored in Data + case "north": + SetWMAttribute(Attribute.WORLDMAP_NORTH, parser.BoolValue); + break; + case "south": + SetWMAttribute(Attribute.WORLDMAP_SOUTH, parser.BoolValue); + break; + case "west": + SetWMAttribute(Attribute.WORLDMAP_WEST, parser.BoolValue); + break; + case "east": + SetWMAttribute(Attribute.WORLDMAP_EAST, parser.BoolValue); + break; + case "stop": + SetWMAttribute(Attribute.WORLDMAP_STOP, parser.BoolValue); break; default: Console.WriteLine("Unknown tile element " + symbol); @@ -162,7 +233,7 @@ public class Tile { } } - private void ParseTileImages(Lisp.Parser parser) { + private void ParseTileImages(Lisp.Parser parser, ArrayList ImagesList) { if(parser.Type == Parser.LispType.END_LIST) return; @@ -176,10 +247,31 @@ public class Tile { } else { throw new Exception("unexpected lisp data: " + parser.Type); } - Images.Add(region); + ImagesList.Add(region); } while(parser.Parse() && parser.Depth >= d); } + private void WriteTileImages(LispWriter writer, string ListName, ArrayList ImagesList) { + if(ImagesList.Count > 0) { + writer.StartList(ListName); + foreach(ImageRegion region in ImagesList) { + if(region.Region.Width != 0) { + writer.WriteVerbatimLine( + String.Format("(region \"{0}\" {1} {2} {3} {4})", + region.ImageFile, region.Region.Left, + region.Region.Top, region.Region.Width, + region.Region.Height)); + } else { + writer.WriteVerbatimLine( + "\"" + region.ImageFile + "\""); + } + } + writer.EndList(ListName); + } else { + Console.WriteLine("no images on tile " + ID); + } + } + private void ParseImageRegion(Lisp.Parser parser, ImageRegion region) { parser.Parse(); if(parser.Type != Parser.LispType.SYMBOL)