1 /* NetHack may be freely redistributed.  See license for details. */
2 
3 #include "vulture_sdl.h" /* XXX this must be the first include,
4                              no idea why but it won't compile otherwise */
5 
6 extern "C" {
7 #include "hack.h"
8 }
9 
10 #include "vulture_types.h"
11 #include "vulture_tile.h"
12 #include "vulture_tileconfig.h"
13 #include "vulture_gen.h"
14 #include "vulture_opt.h"
15 
16 #include <vector>
17 
18 class tmp_tile {
19 public:
tmp_tile()20 	tmp_tile() : filename(""), ptr_type(0), ptr_num(0), hs_x(0), hs_y(0) {};
21 
22   std::string filename;
23 	int ptr_type, ptr_num;
24 	int hs_x, hs_y;
25 };
26 
27 
28 std::vector< std::vector<std::string> > tilenames(NUM_TILETYPES);
29 int tmp_wallstyles[V_WALL_STYLE_MAX][8];
30 int tmp_flooredges[V_FLOOR_EDGE_MAX][12];
31 std::vector<tmp_tile> tmp_gametiles[NUM_TILETYPES];
32 tmp_tile deftiles[NUM_TILETYPES];
33 
34 /* things that get used by vulture later */
35 struct walls walls_full[V_WALL_STYLE_MAX];
36 struct walls walls_half[V_WALL_STYLE_MAX];
37 struct fedges flooredges[V_FLOOR_EDGE_MAX];
38 struct fstyles floorstyles[V_FLOOR_STYLE_MAX];
39 int vulture_typecount[NUM_TILETYPES];
40 int glassgems[CLR_MAX];
41 
42 /* names for the various tiletypes */
43 static std::vector<std::string> typenames(NUM_TILETYPES);
44 static std::vector<std::string> floorstylenames(V_FLOOR_STYLE_MAX);
45 static std::vector<std::string> wallstylenames(V_WALL_STYLE_MAX);
46 static std::vector<std::string> edgestylenames(V_FLOOR_EDGE_MAX);
47 
48 /* the enum for the misc tiles starts at MISCTILEOFFSET so that the enumerated
49 * names can be used diretly in the code; here however this means we need to
50 * subtract MISCTILEOFFSET everywhere to get usable array indices */
51 static std::vector<std::string> miscnames(MISCTILECOUNT);
52 static std::vector<std::string> cursornames(V_CURSOR_MAX);
53 
54 
55 static void init_typenames();
56 static void init_floortilenames();
57 static void init_wallstylenames();
58 static void init_miscnames();
59 static void init_curnames();
60 static void init_objnames();
61 static void init_monnames();
62 static void init_explnames();
63 
64 
65 /* parse the configuration file and prepare the data arrays needed by the rest of vulture
66 * This function is the only one that should be called from outside */
vulture_parse_tileconf(FILE * fp,gametiles ** gt_ptr)67 void vulture_parse_tileconf(FILE *fp, gametiles **gt_ptr)
68 {
69 	int i, j, tilenum, loadnum;
70 	int typeoffset[NUM_TILETYPES];
71 	vulture_tile *tile;
72 	char messagebuf[512];
73 	gametiles *game_tiles;
74 
75 
76 	/* init the names for all types of tiles */
77 	init_typenames();
78 	init_floortilenames();
79 	init_wallstylenames();
80 	init_miscnames();
81 	init_curnames();
82 	init_objnames(); /* init TT_OBJECT and TT_OBJICON */
83 	init_monnames(); /* init TT_MONSTER, TT_STATUE and TT_FIGURINE */
84 	init_explnames();/* TT_EXPL */
85 	edgestylenames[V_FLOOR_EDGE_COBBLESTONE] = "COBBLESTONE";
86 
87 	vulture_typecount[TT_MISC] = MISCTILECOUNT;
88 	tilenames[TT_MISC] = miscnames;
89 	vulture_typecount[TT_CURSOR] = V_CURSOR_MAX;
90 	tilenames[TT_CURSOR] = cursornames;
91 
92 	vulture_typecount[TT_WALL] = 0;
93 	vulture_typecount[TT_FLOOR] = 0;
94 	vulture_typecount[TT_EDGE] = 0;
95 
96 	for (i = 0; i < NUM_TILETYPES; i++)
97 		tmp_gametiles[i].resize(vulture_typecount[i]);
98 
99 	/* tell the lexer about the input file and start the parser */
100 	yyrestart(fp);
101 	yyparse();
102 
103 	/* the config has now been read and we know how many tiles of each type
104 	* there are, so offsets into the final tile array can be computed */
105 	typeoffset[0] = 0;
106 	for (i = 1; i < NUM_TILETYPES; i++)
107 		typeoffset[i] = typeoffset[i-1] + vulture_typecount[i-1];
108 
109 
110 	*gt_ptr = new gametiles[GAMETILECOUNT];
111 	game_tiles = *gt_ptr;
112 
113 	/* build gametiles from the info in tmp_gametiles */
114 	for (i = 0; i < NUM_TILETYPES; i++)
115 	{
116 		for (j = 0; j < vulture_typecount[i]; j++)
117 		{
118 			tilenum = typeoffset[i] + j;
119 
120 			/* use given tile */
121 			if (!tmp_gametiles[i][j].filename.empty() &&
122 			    tmp_gametiles[i][j].ptr_type == -1 && tmp_gametiles[i][j].ptr_num == -1) {
123 				game_tiles[tilenum].filename = tmp_gametiles[i][j].filename;
124 				game_tiles[tilenum].ptr = -1;
125 				game_tiles[tilenum].hs_x = tmp_gametiles[i][j].hs_x;
126 				game_tiles[tilenum].hs_y = tmp_gametiles[i][j].hs_y;
127 			}
128 			/* redirect to another tile */
129 			else if (tmp_gametiles[i][j].ptr_type != 0 || tmp_gametiles[i][j].ptr_num != 0)
130 			{
131 				game_tiles[tilenum].filename = "";
132 				game_tiles[tilenum].ptr = typeoffset[tmp_gametiles[i][j].ptr_type] + tmp_gametiles[i][j].ptr_num;
133 				game_tiles[tilenum].hs_x = 0;
134 				game_tiles[tilenum].hs_y = 0;
135 			}
136 			/* use default tile */
137 			else if (tmp_gametiles[i][j].filename.empty() &&
138 					tmp_gametiles[i][j].ptr_type == 0 &&
139 					tmp_gametiles[i][j].ptr_num == 0)
140 			{
141 				game_tiles[tilenum].ptr = typeoffset[deftiles[i].ptr_type] + deftiles[i].ptr_num;
142 				game_tiles[tilenum].hs_x = deftiles[i].hs_x;
143 				game_tiles[tilenum].hs_y = deftiles[i].hs_y;
144 			}
145 		}
146 	}
147 
148 
149 	if (vulture_opts.debug)
150 	{
151 		/* validate all the tiles. this must be done in a separate loop as there may be
152 		* forward references which won't work until gametiles is fully initialized */
153 		for (i = 0; i < NUM_TILETYPES; i++)
154 		{
155 			for (j = 0; j < vulture_typecount[i]; j++)
156 			{
157 				tilenum = typeoffset[i] + j;
158 				loadnum = tilenum;
159 				if (game_tiles[tilenum].filename.empty() && game_tiles[tilenum].ptr != -1)
160 					loadnum = game_tiles[tilenum].ptr;
161 
162 				tile = vulture_load_tile(loadnum);
163 				if (!tile) {
164 					if (!game_tiles[tilenum].filename.empty())
165 						snprintf(messagebuf, sizeof(messagebuf), "%s.%s: \"%s\" cannot be loaded",
166 								typenames[i].c_str(), (tilenames[i][j]).c_str(), game_tiles[tilenum].filename.c_str());
167 					else
168 						snprintf(messagebuf, sizeof(messagebuf), "%s.%s: invalid redirection",
169 								typenames[i].c_str(), tilenames[i][j].c_str());
170 
171 					if (iflags.window_inited == TRUE)
172 						pline(messagebuf);
173 					else
174 						printf("Tile config: %s\n", messagebuf);
175 
176 					vulture_write_log(V_LOG_NOTE, __FILE__, __LINE__, "Tile config: %s\n", messagebuf);
177 				}
178 				else
179 				{
180 					SDL_FreeSurface(tile->graphic);
181 					free(tile);
182 				}
183 			}
184 		}
185 	}
186 
187 	/* special fixup for V_MISC_PLAYER_INVIS: it does not have a tile image,
188 	* nor should it redirect as it is handled specially */
189 	game_tiles[V_MISC_PLAYER_INVIS].ptr = -1;
190 
191 
192 	/* build wall arrays */
193 	for (i = 0; i < V_WALL_STYLE_MAX; i++)
194 	{
195 		walls_full[i].west = tmp_wallstyles[i][0] + typeoffset[TT_WALL];
196 		walls_full[i].north = tmp_wallstyles[i][1] + typeoffset[TT_WALL];
197 		walls_full[i].south = tmp_wallstyles[i][2] + typeoffset[TT_WALL];
198 		walls_full[i].east = tmp_wallstyles[i][3] + typeoffset[TT_WALL];
199 
200 		walls_half[i].west = tmp_wallstyles[i][4] + typeoffset[TT_WALL];
201 		walls_half[i].north = tmp_wallstyles[i][5] + typeoffset[TT_WALL];
202 		walls_half[i].south = tmp_wallstyles[i][6] + typeoffset[TT_WALL];
203 		walls_half[i].east = tmp_wallstyles[i][7] + typeoffset[TT_WALL];
204 	}
205 
206 
207 	for (i = 0; i < V_FLOOR_EDGE_MAX; i++)
208 		for (j = 0; j < 12; j++)
209 			flooredges[i].dir[j] = tmp_flooredges[i][j] + typeoffset[TT_EDGE];
210 
211 
212 	for (i = 0; i < V_FLOOR_STYLE_MAX; i++)
213 		for (j = 0; j < (floorstyles[i].x * floorstyles[i].y); j++)
214 			floorstyles[i].array[j] = floorstyles[i].array[j] + typeoffset[TT_FLOOR];
215 }
216 
217 
218 /* the following functions are called by the parser */
219 
vulture_get_tiletype_from_name(char * name)220 int vulture_get_tiletype_from_name(char* name)
221 {
222 	int i;
223 	for (i = 0; i < NUM_TILETYPES; i++)
224 		if (typenames[i] == name)
225 			return i;
226 
227 	yyerror("invalid tile type");
228 	return -1;
229 }
230 
231 
vulture_get_wallstyle_from_name(char * name)232 int vulture_get_wallstyle_from_name(char *name)
233 {
234 	int i;
235 	for (i = 0; i < V_WALL_STYLE_MAX; i++)
236 		if (wallstylenames[i] == name)
237 			return i;
238 
239 	yyerror("invalid wall style name");
240 	return -1;
241 }
242 
243 
vulture_get_edgestyle_from_name(char * name)244 int vulture_get_edgestyle_from_name(char *name)
245 {
246 	int i;
247 	for (i = 0; i < V_FLOOR_EDGE_MAX; i++)
248 		if (edgestylenames[i] == name)
249 			return i;
250 
251 	yyerror("invalid edge style name");
252 	return -1;
253 }
254 
255 
vulture_get_floorstyle_from_name(char * name)256 int vulture_get_floorstyle_from_name(char *name)
257 {
258 	int i;
259 	for (i = 0; i < V_FLOOR_STYLE_MAX; i++)
260 		if (floorstylenames[i] == name)
261 			return i;
262 
263 	yyerror("invalid floor style name");
264 	return -1;
265 }
266 
267 
vulture_get_tile_index(int type,char * name,int allow_expand)268 int vulture_get_tile_index(int type, char * name, int allow_expand)
269 {
270 	int i, index;
271 
272 	if (type >= NUM_TILETYPES)
273 		yyerror("invalid tile type");
274 
275 	index = -1;
276 	for (i = 0; i < vulture_typecount[type]; i++)
277 		if (tilenames[type][i] == name)
278 			index = i;
279 
280 	if (index == -1) {
281 		if ((type == TT_WALL || type == TT_FLOOR || type == TT_EDGE) && allow_expand) {
282 			index = vulture_typecount[type];
283 
284 			vulture_typecount[type]++;
285 			tilenames[type].resize(vulture_typecount[type]);
286 			tmp_gametiles[type].resize(vulture_typecount[type]);
287 
288 			tilenames[type][index] = name;
289 		}
290 	}
291 
292 	return index;
293 }
294 
295 
vulture_add_tile(int tiletype,char * tilename,char * filename,int xoffset,int yoffset)296 void vulture_add_tile(int tiletype, char *tilename, char *filename, int xoffset, int yoffset)
297 {
298 	int tilenum = vulture_get_tile_index(tiletype, tilename, 1);
299 
300 	if (tilenum == -1)
301 		return;
302 
303 	tmp_gametiles[tiletype][tilenum].filename = filename;
304 	tmp_gametiles[tiletype][tilenum].ptr_type = -1;
305 	tmp_gametiles[tiletype][tilenum].ptr_num = -1;
306 	tmp_gametiles[tiletype][tilenum].hs_x = xoffset;
307 	tmp_gametiles[tiletype][tilenum].hs_y = yoffset;
308 }
309 
310 
vulture_redirect_tile(int tiletype,char * tilename,int redir_tiletype,char * redir_tilename)311 void vulture_redirect_tile(int tiletype, char *tilename, int redir_tiletype, char *redir_tilename)
312 {
313 	int src, dst;
314 
315 	dst = vulture_get_tile_index(redir_tiletype, redir_tilename, 1);
316 	if (dst == -1)
317 		return;
318 
319 	if (strcmp("default", tilename) == 0)
320 	{
321 		deftiles[tiletype].filename = "";
322 		deftiles[tiletype].ptr_type = redir_tiletype;
323 		deftiles[tiletype].ptr_num = dst;
324 		deftiles[tiletype].hs_x = 0;
325 		deftiles[tiletype].hs_y = 0;
326 	}
327 	else
328 	{
329 		src = vulture_get_tile_index(tiletype, tilename, 1);
330 		if (src == -1)
331 			return;
332 
333 		tmp_gametiles[tiletype][src].filename = "";
334 		tmp_gametiles[tiletype][src].ptr_type = redir_tiletype;
335 		tmp_gametiles[tiletype][src].ptr_num = dst;
336 		tmp_gametiles[tiletype][src].hs_x = 0;
337 		tmp_gametiles[tiletype][src].hs_y = 0;
338 	}
339 }
340 
341 
vulture_setup_wallstyle(int style_id,char * full_w,char * full_n,char * full_s,char * full_e,char * half_w,char * half_n,char * half_s,char * half_e)342 void vulture_setup_wallstyle(int style_id, char * full_w, char * full_n, char * full_s, char * full_e,
343 								char * half_w, char * half_n, char * half_s, char * half_e)
344 {
345 	int i;
346 
347 	tmp_wallstyles[style_id][0] = vulture_get_tile_index(TT_WALL, full_w, 0);
348 	tmp_wallstyles[style_id][1] = vulture_get_tile_index(TT_WALL, full_n, 0);
349 	tmp_wallstyles[style_id][2] = vulture_get_tile_index(TT_WALL, full_s, 0);
350 	tmp_wallstyles[style_id][3] = vulture_get_tile_index(TT_WALL, full_e, 0);
351 	tmp_wallstyles[style_id][4] = vulture_get_tile_index(TT_WALL, half_w, 0);
352 	tmp_wallstyles[style_id][5] = vulture_get_tile_index(TT_WALL, half_n, 0);
353 	tmp_wallstyles[style_id][6] = vulture_get_tile_index(TT_WALL, half_s, 0);
354 	tmp_wallstyles[style_id][7] = vulture_get_tile_index(TT_WALL, half_e, 0);
355 
356 	for (i = 0; i < 8; i++)
357 		if (tmp_wallstyles[style_id][i] == -1)
358 			yyerror("all given walltiles must be defined");
359 }
360 
361 
vulture_setup_edgestyle(int style_id,char * edge01,char * edge02,char * edge03,char * edge04,char * edge05,char * edge06,char * edge07,char * edge08,char * edge09,char * edge10,char * edge11,char * edge12)362 void vulture_setup_edgestyle(int style_id, char *edge01, char *edge02, char *edge03, char *edge04,
363 								char *edge05, char *edge06, char *edge07, char *edge08,
364 								char *edge09, char *edge10, char *edge11, char *edge12)
365 {
366 	int i;
367 
368 	tmp_flooredges[style_id][0] = vulture_get_tile_index(TT_EDGE, edge01, 0);
369 	tmp_flooredges[style_id][1] = vulture_get_tile_index(TT_EDGE, edge02, 0);
370 	tmp_flooredges[style_id][2] = vulture_get_tile_index(TT_EDGE, edge03, 0);
371 	tmp_flooredges[style_id][3] = vulture_get_tile_index(TT_EDGE, edge04, 0);
372 	tmp_flooredges[style_id][4] = vulture_get_tile_index(TT_EDGE, edge05, 0);
373 	tmp_flooredges[style_id][5] = vulture_get_tile_index(TT_EDGE, edge06, 0);
374 	tmp_flooredges[style_id][6] = vulture_get_tile_index(TT_EDGE, edge07, 0);
375 	tmp_flooredges[style_id][7] = vulture_get_tile_index(TT_EDGE, edge08, 0);
376 	tmp_flooredges[style_id][8] = vulture_get_tile_index(TT_EDGE, edge09, 0);
377 	tmp_flooredges[style_id][9] = vulture_get_tile_index(TT_EDGE, edge10, 0);
378 	tmp_flooredges[style_id][10] = vulture_get_tile_index(TT_EDGE, edge11, 0);
379 	tmp_flooredges[style_id][11] = vulture_get_tile_index(TT_EDGE, edge12, 0);
380 
381 	for (i = 0; i < 12; i++)
382 		if (tmp_flooredges[style_id][i] == -1)
383 			yyerror("all given edge tiles must be defined");
384 }
385 
386 
vulture_setup_floorstyle(int style_id,int x,int y,int * tilearray)387 void vulture_setup_floorstyle(int style_id, int x, int y, int *tilearray)
388 {
389 	floorstyles[style_id].x = x;
390 	floorstyles[style_id].y = y;
391 	floorstyles[style_id].array = tilearray;
392 }
393 
394 
395 
396 
397 
init_typenames()398 static void init_typenames()
399 {
400 	typenames[TT_OBJECT] = "object";
401 	typenames[TT_OBJICON] = "objicon";
402 	typenames[TT_MONSTER] = "monster";
403 	typenames[TT_STATUE] = "statue";
404 	typenames[TT_FIGURINE] = "figurine";
405 	typenames[TT_MISC] = "misc";
406 	typenames[TT_EXPL] = "explosion";
407 	typenames[TT_EDGE] = "edge";
408 	typenames[TT_FLOOR] = "floor";
409 	typenames[TT_WALL] = "wall";
410 	typenames[TT_CURSOR] = "cursor";
411 }
412 
413 
init_floortilenames()414 static void init_floortilenames()
415 {
416 	tilenames[TT_FLOOR].resize(FLOTILECOUNT);
417 
418 	floorstylenames[V_FLOOR_COBBLESTONE] = "COBBLESTONE";
419 	floorstylenames[V_FLOOR_ROUGH] = "ROUGH";
420 	floorstylenames[V_FLOOR_CERAMIC] = "CERAMIC";
421 	floorstylenames[V_FLOOR_LAVA] = "LAVA";
422 	floorstylenames[V_FLOOR_WATER] = "WATER";
423 	floorstylenames[V_FLOOR_ICE] = "ICE";
424 	floorstylenames[V_FLOOR_MURAL] = "MURAL";
425 	floorstylenames[V_FLOOR_MURAL2] = "MURAL2";
426 	floorstylenames[V_FLOOR_CARPET] = "CARPET";
427 	floorstylenames[V_FLOOR_MOSS_COVERED] = "MOSS_COVERED";
428 	floorstylenames[V_FLOOR_MARBLE] = "MARBLE";
429 	floorstylenames[V_FLOOR_ROUGH_LIT] = "ROUGH_LIT";
430 	floorstylenames[V_FLOOR_AIR] = "AIR";
431 	floorstylenames[V_FLOOR_DARK] = "DARK";
432 }
433 
434 
init_wallstylenames()435 static void init_wallstylenames()
436 {
437 	tilenames[TT_WALL].resize(WALTILECOUNT);
438 
439 	wallstylenames[V_WALL_BRICK] = "BRICK";
440 	wallstylenames[V_WALL_BRICK_BANNER] = "BRICK_BANNER";
441 	wallstylenames[V_WALL_BRICK_PAINTING] = "BRICK_PAINTING";
442 	wallstylenames[V_WALL_BRICK_POCKET] = "BRICK_POCKET";
443 	wallstylenames[V_WALL_BRICK_PILLAR] = "BRICK_PILLAR";
444 	wallstylenames[V_WALL_MARBLE] = "MARBLE";
445 	wallstylenames[V_WALL_VINE_COVERED] = "VINE_COVERED";
446 	wallstylenames[V_WALL_STUCCO] = "STUCCO";
447 	wallstylenames[V_WALL_ROUGH] = "ROUGH";
448 	wallstylenames[V_WALL_DARK] = "DARK";
449 	wallstylenames[V_WALL_LIGHT] = "LIGHT";
450 }
451 
452 
init_curnames()453 static void init_curnames()
454 {
455 	tilenames[TT_CURSOR].resize(CURTILECOUNT);
456 
457 	cursornames[V_CURSOR_NORMAL] = "NORMAL";
458 	cursornames[V_CURSOR_SCROLLRIGHT] = "SCROLLRIGHT";
459 	cursornames[V_CURSOR_SCROLLLEFT] = "SCROLLLEFT";
460 	cursornames[V_CURSOR_SCROLLUP] = "SCROLLUP";
461 	cursornames[V_CURSOR_SCROLLDOWN] = "SCROLLDOWN";
462 	cursornames[V_CURSOR_SCROLLUPLEFT] = "SCROLLUPLEFT";
463 	cursornames[V_CURSOR_SCROLLUPRIGHT] = "SCROLLUPRIGHT";
464 	cursornames[V_CURSOR_SCROLLDOWNLEFT] = "SCROLLDOWNLEFT";
465 	cursornames[V_CURSOR_SCROLLDOWNRIGHT] = "SCROLLDOWNRIGHT";
466 	cursornames[V_CURSOR_TARGET_GREEN] = "TARGET_GREEN";
467 	cursornames[V_CURSOR_TARGET_RED] = "TARGET_RED";
468 	cursornames[V_CURSOR_TARGET_INVALID] = "TARGET_INVALID";
469 	cursornames[V_CURSOR_TARGET_HELP] = "TARGET_HELP";
470 	cursornames[V_CURSOR_HOURGLASS] = "HOURGLASS";
471 	cursornames[V_CURSOR_OPENDOOR] = "OPENDOOR";
472 	cursornames[V_CURSOR_STAIRS] = "STAIRS";
473 	cursornames[V_CURSOR_GOBLET] = "GOBLET";
474 }
475 
476 
init_miscnames()477 static void init_miscnames()
478 {
479 	tilenames[TT_MISC].resize(MISCTILECOUNT);
480 
481 	miscnames[V_MISC_PLAYER_INVIS - MISCTILEOFFSET] = ""; /* make it impossible to assign a tile to V_MISC_PLAYER_INVIS */
482 	miscnames[V_MISC_FLOOR_NOT_VISIBLE - MISCTILEOFFSET] = "FLOOR_NOT_VISIBLE";
483 	miscnames[V_MISC_DOOR_WOOD_BROKEN - MISCTILEOFFSET] = "DOOR_WOOD_BROKEN";
484 	miscnames[V_MISC_HDOOR_WOOD_CLOSED - MISCTILEOFFSET] = "HDOOR_WOOD_CLOSED";
485 	miscnames[V_MISC_VDOOR_WOOD_CLOSED - MISCTILEOFFSET] = "VDOOR_WOOD_CLOSED";
486 	miscnames[V_MISC_VDOOR_WOOD_OPEN - MISCTILEOFFSET] = "VDOOR_WOOD_OPEN";
487 	miscnames[V_MISC_HDOOR_WOOD_OPEN - MISCTILEOFFSET] = "HDOOR_WOOD_OPEN";
488 	miscnames[V_MISC_TRAP_BEAR - MISCTILEOFFSET] = "TRAP_BEAR";
489 	miscnames[V_MISC_GRAVE - MISCTILEOFFSET] = "GRAVE";
490 	miscnames[V_MISC_ALTAR - MISCTILEOFFSET] = "ALTAR";
491 	miscnames[V_MISC_FOUNTAIN - MISCTILEOFFSET] = "FOUNTAIN";
492 	miscnames[V_MISC_STAIRS_UP - MISCTILEOFFSET] = "STAIRS_UP";
493 	miscnames[V_MISC_STAIRS_DOWN - MISCTILEOFFSET] = "STAIRS_DOWN";
494 	miscnames[V_MISC_SINK - MISCTILEOFFSET] = "SINK";
495 	miscnames[V_MISC_GAS_TRAP - MISCTILEOFFSET] = "GAS_TRAP";
496 	miscnames[V_MISC_TRAP_PIT - MISCTILEOFFSET] = "TRAP_PIT";
497 	miscnames[V_MISC_TRAP_POLYMORPH - MISCTILEOFFSET] = "TRAP_POLYMORPH";
498 	miscnames[V_MISC_TREE - MISCTILEOFFSET] = "TREE";
499 	miscnames[V_MISC_TRAP_MAGIC - MISCTILEOFFSET] = "TRAP_MAGIC";
500 	miscnames[V_MISC_TRAP_DOOR - MISCTILEOFFSET] = "TRAP_DOOR";
501 	miscnames[V_MISC_TRAP_WATER - MISCTILEOFFSET] = "TRAP_WATER";
502 	miscnames[V_MISC_TRAP_TELEPORTER - MISCTILEOFFSET] = "TRAP_TELEPORTER";
503 	miscnames[V_MISC_UNMAPPED_AREA - MISCTILEOFFSET] = "UNMAPPED_AREA";
504 	miscnames[V_MISC_HILITE_PET - MISCTILEOFFSET] = "HILITE_PET";
505 	miscnames[V_MISC_BARS - MISCTILEOFFSET] = "BARS";
506 	miscnames[V_MISC_THRONE - MISCTILEOFFSET] = "THRONE";
507 	miscnames[V_MISC_TRAP_ANTI_MAGIC - MISCTILEOFFSET] = "TRAP_ANTI_MAGIC";
508 	miscnames[V_MISC_TRAP_ARROW - MISCTILEOFFSET] = "TRAP_ARROW";
509 	miscnames[V_MISC_TRAP_FIRE - MISCTILEOFFSET] = "TRAP_FIRE";
510 	miscnames[V_MISC_ROLLING_BOULDER_TRAP - MISCTILEOFFSET] = "ROLLING_BOULDER_TRAP";
511 	miscnames[V_MISC_TRAP_SLEEPGAS - MISCTILEOFFSET] = "TRAP_SLEEPGAS";
512 	miscnames[V_MISC_ZAP_SLANT_RIGHT - MISCTILEOFFSET] = "ZAP_SLANT_RIGHT";
513 	miscnames[V_MISC_ZAP_SLANT_LEFT - MISCTILEOFFSET] = "ZAP_SLANT_LEFT";
514 	miscnames[V_MISC_ZAP_HORIZONTAL - MISCTILEOFFSET] = "ZAP_HORIZONTAL";
515 	miscnames[V_MISC_ZAP_VERTICAL - MISCTILEOFFSET] = "ZAP_VERTICAL";
516 	miscnames[V_MISC_LADDER_UP - MISCTILEOFFSET] = "LADDER_UP";
517 	miscnames[V_MISC_LADDER_DOWN - MISCTILEOFFSET] = "LADDER_DOWN";
518 	miscnames[V_MISC_RESIST_SPELL_1 - MISCTILEOFFSET] = "RESIST_SPELL_1";
519 	miscnames[V_MISC_RESIST_SPELL_2 - MISCTILEOFFSET] = "RESIST_SPELL_2";
520 	miscnames[V_MISC_RESIST_SPELL_3 - MISCTILEOFFSET] = "RESIST_SPELL_3";
521 	miscnames[V_MISC_RESIST_SPELL_4 - MISCTILEOFFSET] = "RESIST_SPELL_4";
522 	miscnames[V_MISC_WEB_TRAP - MISCTILEOFFSET] = "WEB_TRAP";
523 	miscnames[V_MISC_DART_TRAP - MISCTILEOFFSET] = "DART_TRAP";
524 	miscnames[V_MISC_FALLING_ROCK_TRAP - MISCTILEOFFSET] = "FALLING_ROCK_TRAP";
525 	miscnames[V_MISC_SQUEAKY_BOARD - MISCTILEOFFSET] = "SQUEAKY_BOARD";
526 	miscnames[V_MISC_MAGIC_PORTAL - MISCTILEOFFSET] = "MAGIC_PORTAL";
527 	miscnames[V_MISC_SPIKED_PIT - MISCTILEOFFSET] = "SPIKED_PIT";
528 	miscnames[V_MISC_HOLE - MISCTILEOFFSET] = "HOLE";
529 	miscnames[V_MISC_LEVEL_TELEPORTER - MISCTILEOFFSET] = "LEVEL_TELEPORTER";
530 	miscnames[V_MISC_MAGIC_TRAP - MISCTILEOFFSET] = "MAGIC_TRAP";
531 	miscnames[V_MISC_DIGBEAM - MISCTILEOFFSET] = "DIGBEAM";
532 	miscnames[V_MISC_FLASHBEAM - MISCTILEOFFSET] = "FLASHBEAM";
533 	miscnames[V_MISC_BOOMLEFT - MISCTILEOFFSET] = "BOOMLEFT";
534 	miscnames[V_MISC_BOOMRIGHT - MISCTILEOFFSET] = "BOOMRIGHT";
535 	miscnames[V_MISC_HCDBRIDGE - MISCTILEOFFSET] = "HCDBRIDGE";
536 	miscnames[V_MISC_VCDBRIDGE - MISCTILEOFFSET] = "VCDBRIDGE";
537 	miscnames[V_MISC_VODBRIDGE - MISCTILEOFFSET] = "VODBRIDGE";
538 	miscnames[V_MISC_HODBRIDGE - MISCTILEOFFSET] = "HODBRIDGE";
539 	miscnames[V_MISC_CLOUD - MISCTILEOFFSET] = "CLOUD";
540 	miscnames[V_MISC_OFF_MAP - MISCTILEOFFSET] = "OFF_MAP";
541 	miscnames[V_MISC_FLOOR_HIGHLIGHT - MISCTILEOFFSET] = "FLOOR_HIGHLIGHT";
542 	miscnames[V_MISC_LAND_MINE - MISCTILEOFFSET] = "LAND_MINE";
543 	miscnames[V_MISC_LAWFUL_PRIEST - MISCTILEOFFSET] = "LAWFUL_PRIEST";
544 	miscnames[V_MISC_CHAOTIC_PRIEST - MISCTILEOFFSET] = "CHAOTIC_PRIEST";
545 	miscnames[V_MISC_NEUTRAL_PRIEST - MISCTILEOFFSET] = "NEUTRAL_PRIEST";
546 	miscnames[V_MISC_UNALIGNED_PRIEST - MISCTILEOFFSET] = "UNALIGNED_PRIEST";
547 #if defined(REINCARNATION)
548 	miscnames[V_MISC_ROGUE_LEVEL_A - MISCTILEOFFSET] = "ROGUE_LEVEL_A";
549 	miscnames[V_MISC_ROGUE_LEVEL_B - MISCTILEOFFSET] = "ROGUE_LEVEL_B";
550 	miscnames[V_MISC_ROGUE_LEVEL_C - MISCTILEOFFSET] = "ROGUE_LEVEL_C";
551 	miscnames[V_MISC_ROGUE_LEVEL_D - MISCTILEOFFSET] = "ROGUE_LEVEL_D";
552 	miscnames[V_MISC_ROGUE_LEVEL_E - MISCTILEOFFSET] = "ROGUE_LEVEL_E";
553 	miscnames[V_MISC_ROGUE_LEVEL_F - MISCTILEOFFSET] = "ROGUE_LEVEL_F";
554 	miscnames[V_MISC_ROGUE_LEVEL_G - MISCTILEOFFSET] = "ROGUE_LEVEL_G";
555 	miscnames[V_MISC_ROGUE_LEVEL_H - MISCTILEOFFSET] = "ROGUE_LEVEL_H";
556 	miscnames[V_MISC_ROGUE_LEVEL_I - MISCTILEOFFSET] = "ROGUE_LEVEL_I";
557 	miscnames[V_MISC_ROGUE_LEVEL_J - MISCTILEOFFSET] = "ROGUE_LEVEL_J";
558 	miscnames[V_MISC_ROGUE_LEVEL_K - MISCTILEOFFSET] = "ROGUE_LEVEL_K";
559 	miscnames[V_MISC_ROGUE_LEVEL_L - MISCTILEOFFSET] = "ROGUE_LEVEL_L";
560 	miscnames[V_MISC_ROGUE_LEVEL_M - MISCTILEOFFSET] = "ROGUE_LEVEL_M";
561 	miscnames[V_MISC_ROGUE_LEVEL_N - MISCTILEOFFSET] = "ROGUE_LEVEL_N";
562 	miscnames[V_MISC_ROGUE_LEVEL_O - MISCTILEOFFSET] = "ROGUE_LEVEL_O";
563 	miscnames[V_MISC_ROGUE_LEVEL_P - MISCTILEOFFSET] = "ROGUE_LEVEL_P";
564 	miscnames[V_MISC_ROGUE_LEVEL_Q - MISCTILEOFFSET] = "ROGUE_LEVEL_Q";
565 	miscnames[V_MISC_ROGUE_LEVEL_R - MISCTILEOFFSET] = "ROGUE_LEVEL_R";
566 	miscnames[V_MISC_ROGUE_LEVEL_S - MISCTILEOFFSET] = "ROGUE_LEVEL_S";
567 	miscnames[V_MISC_ROGUE_LEVEL_T - MISCTILEOFFSET] = "ROGUE_LEVEL_T";
568 	miscnames[V_MISC_ROGUE_LEVEL_U - MISCTILEOFFSET] = "ROGUE_LEVEL_U";
569 	miscnames[V_MISC_ROGUE_LEVEL_V - MISCTILEOFFSET] = "ROGUE_LEVEL_V";
570 	miscnames[V_MISC_ROGUE_LEVEL_W - MISCTILEOFFSET] = "ROGUE_LEVEL_W";
571 	miscnames[V_MISC_ROGUE_LEVEL_X - MISCTILEOFFSET] = "ROGUE_LEVEL_X";
572 	miscnames[V_MISC_ROGUE_LEVEL_Y - MISCTILEOFFSET] = "ROGUE_LEVEL_Y";
573 	miscnames[V_MISC_ROGUE_LEVEL_Z - MISCTILEOFFSET] = "ROGUE_LEVEL_Z";
574 #endif
575 	miscnames[V_MISC_ENGULF_FIRE_VORTEX - MISCTILEOFFSET] = "ENGULF_FIRE_VORTEX";
576 	miscnames[V_MISC_ENGULF_FOG_CLOUD - MISCTILEOFFSET] = "ENGULF_FOG_CLOUD";
577 	miscnames[V_MISC_ENGULF_AIR_ELEMENTAL - MISCTILEOFFSET] = "ENGULF_AIR_ELEMENTAL";
578 	miscnames[V_MISC_ENGULF_STEAM_VORTEX - MISCTILEOFFSET] = "ENGULF_STEAM_VORTEX";
579 	miscnames[V_MISC_ENGULF_PURPLE_WORM - MISCTILEOFFSET] = "ENGULF_PURPLE_WORM";
580 	miscnames[V_MISC_ENGULF_JUIBLEX - MISCTILEOFFSET] = "ENGULF_JUIBLEX";
581 	miscnames[V_MISC_ENGULF_OCHRE_JELLY - MISCTILEOFFSET] = "ENGULF_OCHRE_JELLY";
582 	miscnames[V_MISC_ENGULF_LURKER_ABOVE - MISCTILEOFFSET] = "ENGULF_LURKER_ABOVE";
583 	miscnames[V_MISC_ENGULF_TRAPPER - MISCTILEOFFSET] = "ENGULF_TRAPPER";
584 	miscnames[V_MISC_ENGULF_DUST_VORTEX - MISCTILEOFFSET] = "ENGULF_DUST_VORTEX";
585 	miscnames[V_MISC_ENGULF_ICE_VORTEX - MISCTILEOFFSET] = "ENGULF_ICE_VORTEX";
586 	miscnames[V_MISC_ENGULF_ENERGY_VORTEX - MISCTILEOFFSET] = "ENGULF_ENERGY_VORTEX";
587 	miscnames[V_MISC_WARNLEV_1 - MISCTILEOFFSET] = "WARNLEV_1";
588 	miscnames[V_MISC_WARNLEV_2 - MISCTILEOFFSET] = "WARNLEV_2";
589 	miscnames[V_MISC_WARNLEV_3 - MISCTILEOFFSET] = "WARNLEV_3";
590 	miscnames[V_MISC_WARNLEV_4 - MISCTILEOFFSET] = "WARNLEV_4";
591 	miscnames[V_MISC_WARNLEV_5 - MISCTILEOFFSET] = "WARNLEV_5";
592 	miscnames[V_MISC_WARNLEV_6 - MISCTILEOFFSET] = "WARNLEV_6";
593 	miscnames[V_MISC_INVISIBLE_MONSTER - MISCTILEOFFSET] = "INVISIBLE_MONSTER";
594 	miscnames[V_MISC_STINKING_CLOUD - MISCTILEOFFSET] = "STINKING_CLOUD";
595 #ifdef VULTURE_SLASHEM
596 	miscnames[V_MISC_TOILET - MISCTILEOFFSET] = "TOILET";
597 #endif
598 }
599 
600 
init_objnames()601 static void init_objnames()
602 {
603 	int i;
604 	char *c, *nameptr;
605 	int unnamed_cnt[MAXOCLASSES];
606 	char buffer[64];
607 
608 	static const char *objclassnames[] = { 0,
609 			"Illegal objects", "Weapons", "Armor", "Rings", "Amulets",
610 			"Tools", "Comestibles", "Potions", "Scrolls", "Spellbooks",
611 			"Wands", "Coins", "Gems", "Boulders/Statues", "Iron balls",
612 			"Chains", "Venoms"
613 	};
614 
615 	memset(unnamed_cnt, 0, MAXOCLASSES * sizeof(int));
616 
617 	tilenames[TT_OBJECT].resize(OBJTILECOUNT);
618 	vulture_typecount[TT_OBJECT] = OBJTILECOUNT;
619 
620 	for(i = 0; !i || objects[i].oc_class != ILLOBJ_CLASS; i++) {
621 		buffer[0] = '\0';
622 		buffer[40] = '\0';
623 
624 		if (!obj_descr[i].oc_name)
625 		{
626 			unnamed_cnt[(int)objects[i].oc_class]++;
627 			snprintf(buffer, 40, "%3.3s unnamed %d",
628 					objclassnames[(int)objects[i].oc_class], unnamed_cnt[(int)objects[i].oc_class]);
629 		}
630 		else
631 		{
632 			nameptr = (char*)obj_descr[i].oc_name;
633 
634 			switch (objects[i].oc_class)
635 			{
636 				case WAND_CLASS:
637 					snprintf(buffer, 40, "WAN_%s", nameptr); break;
638 				case RING_CLASS:
639 					snprintf(buffer, 40, "RIN_%s", nameptr); break;
640 				case POTION_CLASS:
641 					snprintf(buffer, 40, "POT_%s", nameptr); break;
642 				case SPBOOK_CLASS:
643 					snprintf(buffer, 40, "SPE_%s", nameptr); break;
644 				case SCROLL_CLASS:
645 					snprintf(buffer, 40, "SCR_%s", nameptr); break;
646 				case AMULET_CLASS:
647 					if(objects[i].oc_material == PLASTIC)
648 						snprintf(buffer, 40, "FAKE_AMULET_OF_YENDOR");
649 					else
650 						snprintf(buffer, 40, "%s", obj_descr[i].oc_name); break;
651 				case GEM_CLASS:
652 					if (objects[i].oc_material == GLASS)
653 					{
654 						switch (objects[i].oc_color)
655 						{
656 							case CLR_WHITE:  snprintf(buffer, 40, "GEM_WHITE_GLASS"); break;
657 							case CLR_BLUE:   snprintf(buffer, 40, "GEM_BLUE_GLASS");  break;
658 							case CLR_RED:    snprintf(buffer, 40, "GEM_RED_GLASS");   break;
659 							case CLR_BROWN:  snprintf(buffer, 40, "GEM_BROWN_GLASS"); break;
660 							case CLR_ORANGE: snprintf(buffer, 40, "GEM_ORANGE_GLASS");break;
661 							case CLR_YELLOW: snprintf(buffer, 40, "GEM_YELLOW_GLASS");break;
662 							case CLR_BLACK:  snprintf(buffer, 40, "GEM_BLACK_GLASS"); break;
663 							case CLR_GREEN:  snprintf(buffer, 40, "GEM_GREEN_GLASS"); break;
664 							case CLR_MAGENTA:snprintf(buffer, 40, "GEM_VIOLET_GLASS");break;
665 						}
666 						glassgems[objects[i].oc_color] = i;
667 					}
668 					else
669 						snprintf(buffer, 40, "%s", nameptr); break;
670 					break;
671 				default:
672 					snprintf(buffer, 40, "%s", nameptr); break;
673 			}
674 		}
675 
676 		for (c = buffer; *c; c++) {
677 			if (*c >= 'a' && *c <= 'z') *c -= (char)('a' - 'A');
678 			else if ((*c < 'A' || *c > 'Z') && !isdigit(*c)) *c = '_';
679 		}
680 
681 		tilenames[TT_OBJECT][i] = buffer;
682 	}
683 
684 	/* fix up the slime mold as it's name varies and we can't count on it being called "slime mold" */
685 	tilenames[TT_OBJECT][SLIME_MOLD] = "SLIME_MOLD";
686 
687 	vulture_typecount[TT_OBJICON] = vulture_typecount[TT_OBJECT];
688 	tilenames[TT_OBJICON] = tilenames[TT_OBJECT];
689 }
690 
691 
692 
init_monnames()693 static void init_monnames()
694 {
695 	char * c;
696 	int i;
697 	char buffer[64];
698 
699 	tilenames[TT_MONSTER].resize(MONTILECOUNT);
700 	vulture_typecount[TT_MONSTER] = MONTILECOUNT;
701 
702 	for (i = 0; mons[i].mlet; i++) {
703 		if (mons[i].mlet == S_HUMAN && !strncmp(mons[i].mname, "were", 4))
704 			snprintf(buffer, 64, "PM_HUMAN_%s", mons[i].mname);
705 		else
706 			snprintf(buffer, 64, "PM_%s", mons[i].mname);
707 
708 		for (c = buffer; *c; c++) {
709 			if (*c >= 'a' && *c <= 'z') *c -= (char)('a' - 'A');
710 			else if (*c < 'A' || *c > 'Z') *c = '_';
711 		}
712 
713 		tilenames[TT_MONSTER][i] = buffer;
714 	}
715 
716 	vulture_typecount[TT_STATUE] = vulture_typecount[TT_MONSTER];
717 	tilenames[TT_STATUE] = tilenames[TT_MONSTER];
718 
719 	vulture_typecount[TT_FIGURINE] = vulture_typecount[TT_MONSTER];
720 	tilenames[TT_FIGURINE] = tilenames[TT_MONSTER];
721 }
722 
723 
724 
init_explnames()725 static void init_explnames()
726 {
727 	int i, j;
728 	char buffer[64];
729 	const char * explosion_names[] = {"DARK", "NOXIOUS", "MUDDY", "WET",
730 	                                  "MAGICAL", "FIERY", "FROSTY"};
731 
732 	tilenames[TT_EXPL].resize(EXPL_MAX * 9);
733 	vulture_typecount[TT_EXPL] = EXPL_MAX * 9;
734 
735 	for (i = 0; i < EXPL_MAX; i++) {
736 		for (j = 0; j < 9; j++) {
737 			snprintf(buffer, 64, "%s_%d", explosion_names[i], j+1);
738 			tilenames[TT_EXPL][i*9+j] = buffer;
739 		}
740 	}
741 }
742 
743