1fc8401b0dbaaea1b9f838ae0b276ddfc63bbede
[supertux.git] / tools / tilemanager / Tile.cs
1 using System;
2 using System.Collections;
3 using System.IO;
4 using System.Drawing;
5 using Lisp;
6
7 public class ImageRegion {
8     public String ImageFile;
9     public Rectangle Region;
10 }
11
12 public class Tile {
13     public int ID;
14     public bool Solid;
15     public bool UniSolid;
16     public bool Ice;
17     public bool Water;
18     public bool Slope;
19     public bool Hidden;
20     public bool Hurts;
21     public bool FullBox;
22     public bool Brick;
23     public bool Coin;
24     public bool Goal;
25     public int NextTile;
26     public int Data;
27     public float AnimFps;
28     public string EditorImage;
29     public ArrayList Images = new ArrayList();
30
31     public Tile() {
32         ID = -1;
33         NextTile = -1;
34         AnimFps = 1;
35     }
36
37     public void Write(LispWriter writer) {
38         writer.StartList("tile");
39         writer.Write("id", ID);
40
41         if(Images.Count > 0) {
42             writer.StartList("images");
43             foreach(ImageRegion region in Images) {
44                 if(region.Region.Width != 0) {
45                     writer.WriteVerbatimLine(
46                             String.Format("(region \"{0}\" {1} {2} {3} {4})",
47                                 region.ImageFile, region.Region.Left,
48                                 region.Region.Top, region.Region.Width,
49                                 region.Region.Height));
50                 } else {
51                     writer.WriteVerbatimLine(
52                             "\"" + region.ImageFile + "\"");
53                 }
54             }
55             writer.EndList("images");
56         } else {
57             Console.WriteLine("no images on tile " + ID);
58         }
59         
60         if(Solid)
61             writer.Write("solid", true);
62         if(UniSolid)
63             writer.Write("unisolid", true);
64         if(Ice)
65             writer.Write("ice", true);
66         if(Water)
67             writer.Write("water", true);
68         if(Slope)
69             writer.Write("slope-type", Data);
70         if(Hurts)
71             writer.Write("hurts", true);
72         if(Hidden)
73             writer.Write("hidden", true);
74         if(Coin)
75             writer.Write("coin", true);
76         if(FullBox)
77             writer.Write("fullbox", true);
78         if(Brick)
79             writer.Write("brick", true);
80         if(NextTile >= 0)
81             writer.Write("next-tile", NextTile);
82         if(Goal)
83             writer.Write("goal", true);
84         if(EditorImage != null)
85             writer.Write("editor-images", EditorImage);
86         if(Data != 0)
87             writer.Write("data", Data);
88         if(Images.Count > 1) {
89             if(AnimFps == 1.0)
90               AnimFps = 40;
91             writer.Write("anim-fps", AnimFps);
92         }
93         writer.EndList("tile");
94     }
95
96     public void Parse(Lisp.Parser parser) {
97         int d = parser.Depth;
98         while(parser.Parse() && parser.Depth >= d) {
99             if(parser.Depth == d+1) {
100                 if(parser.Type != Parser.LispType.SYMBOL)
101                     throw new Exception("expected SYMBOL");
102                 string symbol = parser.SymbolValue;
103                 parser.Parse();
104                 switch(symbol) {
105                     case "id":
106                         ID = parser.IntegerValue;
107                     break;
108                     case "images":
109                         ParseTileImages(parser);
110                         break;
111                     case "editor-images":
112                         EditorImage = parser.StringValue;
113                         break;
114                     case "solid":
115                         Solid = parser.BoolValue;
116                         break;
117                     case "unisolid":
118                         UniSolid = parser.BoolValue;
119                         break;
120                     case "ice":
121                         Ice = parser.BoolValue;
122                         break;
123                     case "water":
124                         Water = parser.BoolValue;
125                         break;
126                     case "slope-type":
127                         Slope = true;
128                         Data = parser.IntegerValue;
129                         break;
130                     case "anim-fps":
131                         AnimFps = parser.FloatValue;
132                         break;
133                     case "hurts":
134                         Hurts = parser.BoolValue;
135                         break;
136                     case "hidden":
137                         Hidden = parser.BoolValue;
138                         break;
139                     case "data":
140                         Data = parser.IntegerValue;
141                         break;
142                     case "next-tile":
143                         NextTile = parser.IntegerValue;
144                         break;
145                     case "brick":
146                         Brick = parser.BoolValue;
147                         break;
148                     case "fullbox":
149                         FullBox = parser.BoolValue;
150                         break;
151                     case "coin":
152                         Coin = parser.BoolValue;
153                         break;
154                     case "goal":
155                         Goal = parser.BoolValue;
156                         break;
157                     default:
158                         Console.WriteLine("Unknown tile element " + symbol);
159                         break;
160                 }
161             }
162         }
163     }
164
165     private void ParseTileImages(Lisp.Parser parser) {
166         if(parser.Type == Parser.LispType.END_LIST)
167             return;
168
169         int d = parser.Depth;
170         do {
171             ImageRegion region = new ImageRegion();
172             if(parser.Type == Parser.LispType.STRING) {
173                 region.ImageFile = parser.StringValue;
174             } else if(parser.Type == Parser.LispType.START_LIST) {
175                 ParseImageRegion(parser, region);
176             } else {
177                 throw new Exception("unexpected lisp data: " + parser.Type);
178             }
179             Images.Add(region);
180         } while(parser.Parse() && parser.Depth >= d);
181     }
182
183     private void ParseImageRegion(Lisp.Parser parser, ImageRegion region) {
184         parser.Parse();
185         if(parser.Type != Parser.LispType.SYMBOL)
186             throw new Exception("expected symbol");
187         if(parser.SymbolValue != "region")
188             throw new Exception("expected region symbol");
189         parser.Parse();
190         if(parser.Type != Parser.LispType.STRING)
191             throw new Exception("expected string");
192         region.ImageFile = parser.StringValue;
193
194         parser.Parse();
195         if(parser.Type != Parser.LispType.INTEGER)
196             throw new Exception("expected integer");
197         region.Region.X = parser.IntegerValue;
198
199         parser.Parse();
200         if(parser.Type != Parser.LispType.INTEGER)
201             throw new Exception("expected integer");
202         region.Region.Y = parser.IntegerValue;
203
204         parser.Parse();
205         if(parser.Type != Parser.LispType.INTEGER)
206             throw new Exception("expected integer");
207         region.Region.Width = parser.IntegerValue;
208
209         parser.Parse();                                    
210         if(parser.Type != Parser.LispType.INTEGER)
211             throw new Exception("expected integer");
212         region.Region.Height = parser.IntegerValue;
213
214         parser.Parse();
215         if(parser.Type != Parser.LispType.END_LIST)
216             throw new Exception("expected END_LIST");
217     }
218 }
219