2 using System.Collections;
7 public class ImageRegion {
8 public String ImageFile;
9 public Rectangle Region;
12 public class Attribute {
13 /// <summary>solid tile that is indestructible by Tux</summary>
14 public const int SOLID = 0x0001;
15 /// <summary>uni-directional solid tile</summary>
16 public const int UNISOLID = 0x0002;
17 /// <summary>a brick that can be destroyed by jumping under it</summary>
18 public const int BRICK = 0x0004;
19 /// <summary>the level should be finished when touching a goaltile.</summary>
21 /// if <see cref="Data">data</see> is 0 then the endsequence should be
22 /// triggered, if <see cref="Data">data</see> is 1 then we can finish
23 /// the level instantly.
25 public const int GOAL = 0x0008;
26 /// <summary>slope tile</summary>
27 public const int SLOPE = 0x0010;
28 /// <summary>Bonusbox, content is stored in <see cref="Data">data</see></summary>
29 public const int FULLBOX = 0x0020;
30 /// <summary>Tile is a coin</summary>
31 public const int COIN = 0x0040;
32 /// <summary>an ice brick that makes tux sliding more than usual</summary>
33 public const int ICE = 0x0100;
34 /// <summary>a water tile in which tux starts to swim</summary>
35 public const int WATER = 0x0200;
36 /// <summary>a tile that hurts the player if he touches it</summary>
37 public const int HURTS = 0x0400;
38 /// <summary>for lava: WATER, HURTS, FIRE</summary>
39 public const int FIRE = 0x0800;
42 // TODO: Find out why are worldmap tile attributes stored in data(s)
44 public const int WORLDMAP_NORTH = 0x0001;
45 public const int WORLDMAP_SOUTH = 0x0002;
46 public const int WORLDMAP_EAST = 0x0004;
47 public const int WORLDMAP_WEST = 0x0008;
49 public const int WORLDMAP_STOP = 0x0010;
56 public int Attributes;
59 public string EditorImage;
60 public ArrayList Images = new ArrayList();
68 public bool HasAttribute (int Attrib)
70 return (Attributes & Attrib) != 0;
73 public void SetAttribute (int Attrib, bool Value)
78 Attributes &= (~Attrib); //NOTE: "~" stands for bitwise negation
81 public void Write(LispWriter writer) {
82 writer.StartList("tile");
83 writer.Write("id", ID);
85 if(Images.Count > 0) {
86 writer.StartList("images");
87 foreach(ImageRegion region in Images) {
88 if(region.Region.Width != 0) {
89 writer.WriteVerbatimLine(
90 String.Format("(region \"{0}\" {1} {2} {3} {4})",
91 region.ImageFile, region.Region.Left,
92 region.Region.Top, region.Region.Width,
93 region.Region.Height));
95 writer.WriteVerbatimLine(
96 "\"" + region.ImageFile + "\"");
99 writer.EndList("images");
101 Console.WriteLine("no images on tile " + ID);
104 if(HasAttribute(Attribute.SOLID))
105 writer.Write("solid", true);
106 if(HasAttribute(Attribute.UNISOLID))
107 writer.Write("unisolid", true);
108 if(HasAttribute(Attribute.ICE))
109 writer.Write("ice", true);
110 if(HasAttribute(Attribute.WATER))
111 writer.Write("water", true);
112 if(HasAttribute(Attribute.SLOPE))
113 writer.Write("slope-type", Data);
114 if(HasAttribute(Attribute.HURTS))
115 writer.Write("hurts", true);
116 if(HasAttribute(Attribute.COIN))
117 writer.Write("coin", true);
118 if(HasAttribute(Attribute.FULLBOX))
119 writer.Write("fullbox", true);
120 if(HasAttribute(Attribute.BRICK))
121 writer.Write("brick", true);
122 if(HasAttribute(Attribute.GOAL))
123 writer.Write("goal", true);
126 writer.Write("hidden", true);
128 writer.Write("next-tile", NextTile);
129 if(EditorImage != null)
130 writer.Write("editor-images", EditorImage);
132 writer.Write("data", Data);
133 if(Images.Count > 1) {
136 writer.Write("anim-fps", AnimFps);
138 writer.EndList("tile");
141 public void Parse(Lisp.Parser parser) {
142 int d = parser.Depth;
143 while(parser.Parse() && parser.Depth >= d) {
144 if(parser.Depth == d+1) {
145 if(parser.Type != Parser.LispType.SYMBOL)
146 throw new Exception("expected SYMBOL");
147 string symbol = parser.SymbolValue;
151 ID = parser.IntegerValue;
154 ParseTileImages(parser);
156 case "editor-images":
157 EditorImage = parser.StringValue;
160 AnimFps = parser.FloatValue;
163 Data = parser.IntegerValue;
166 NextTile = parser.IntegerValue;
169 Hidden = parser.BoolValue;
172 SetAttribute(Attribute.SOLID, parser.BoolValue);
175 SetAttribute(Attribute.UNISOLID, parser.BoolValue);
178 SetAttribute(Attribute.ICE, parser.BoolValue);
181 SetAttribute(Attribute.WATER, parser.BoolValue);
184 SetAttribute(Attribute.SLOPE, true);
185 Data = parser.IntegerValue;
188 SetAttribute(Attribute.HURTS, parser.BoolValue);
191 SetAttribute(Attribute.BRICK, parser.BoolValue);
194 SetAttribute(Attribute.FULLBOX, parser.BoolValue);
197 SetAttribute(Attribute.COIN, parser.BoolValue);
200 SetAttribute(Attribute.GOAL, parser.BoolValue);
203 Console.WriteLine("Unknown tile element " + symbol);
210 private void ParseTileImages(Lisp.Parser parser) {
211 if(parser.Type == Parser.LispType.END_LIST)
214 int d = parser.Depth;
216 ImageRegion region = new ImageRegion();
217 if(parser.Type == Parser.LispType.STRING) {
218 region.ImageFile = parser.StringValue;
219 } else if(parser.Type == Parser.LispType.START_LIST) {
220 ParseImageRegion(parser, region);
222 throw new Exception("unexpected lisp data: " + parser.Type);
225 } while(parser.Parse() && parser.Depth >= d);
228 private void ParseImageRegion(Lisp.Parser parser, ImageRegion region) {
230 if(parser.Type != Parser.LispType.SYMBOL)
231 throw new Exception("expected symbol");
232 if(parser.SymbolValue != "region")
233 throw new Exception("expected region symbol");
235 if(parser.Type != Parser.LispType.STRING)
236 throw new Exception("expected string");
237 region.ImageFile = parser.StringValue;
240 if(parser.Type != Parser.LispType.INTEGER)
241 throw new Exception("expected integer");
242 region.Region.X = parser.IntegerValue;
245 if(parser.Type != Parser.LispType.INTEGER)
246 throw new Exception("expected integer");
247 region.Region.Y = parser.IntegerValue;
250 if(parser.Type != Parser.LispType.INTEGER)
251 throw new Exception("expected integer");
252 region.Region.Width = parser.IntegerValue;
255 if(parser.Type != Parser.LispType.INTEGER)
256 throw new Exception("expected integer");
257 region.Region.Height = parser.IntegerValue;
260 if(parser.Type != Parser.LispType.END_LIST)
261 throw new Exception("expected END_LIST");