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