631 lines
20 KiB
C
631 lines
20 KiB
C
/* NetHack 3.6 tilemap.c $NHDT-Date: 1454498706 2016/02/03 11:25:06 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.27 $ */
|
|
/* NetHack may be freely redistributed. See license for details. */
|
|
|
|
/*
|
|
* This source file is compiled twice:
|
|
* once without TILETEXT defined to make tilemap.{o,obj},
|
|
* then again with it defined to produce tiletxt.{o,obj}.
|
|
*/
|
|
|
|
#include "hack.h"
|
|
|
|
const char *FDECL(tilename, (int, int));
|
|
void NDECL(init_tilemap);
|
|
void FDECL(process_substitutions, (FILE *));
|
|
boolean FDECL(acceptable_tilename, (int, const char *, const char *));
|
|
|
|
#if defined(MICRO) || defined(WIN32)
|
|
#undef exit
|
|
#if !defined(MSDOS) && !defined(WIN32)
|
|
extern void FDECL(exit, (int));
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(WIN32)
|
|
#define STATUES_LOOK_LIKE_MONSTERS
|
|
#endif
|
|
|
|
#define MON_GLYPH 1
|
|
#define OBJ_GLYPH 2
|
|
#define OTH_GLYPH 3 /* fortunately unnecessary */
|
|
|
|
#define EXTRA_SCROLL_DESCR_COUNT ((SCR_BLANK_PAPER - SCR_STINKING_CLOUD) - 1)
|
|
|
|
/* note that the ifdefs here should be the opposite sense from monst.c/
|
|
* objects.c/rm.h
|
|
*/
|
|
|
|
struct conditionals {
|
|
int sequence, predecessor;
|
|
const char *name;
|
|
} conditionals[] = {
|
|
#ifndef CHARON /* not supported yet */
|
|
{ MON_GLYPH, PM_HELL_HOUND, "Cerberus" },
|
|
#endif
|
|
/* commented out in monst.c at present */
|
|
{ MON_GLYPH, PM_SHOCKING_SPHERE, "beholder" },
|
|
{ MON_GLYPH, PM_BABY_SILVER_DRAGON, "baby shimmering dragon" },
|
|
{ MON_GLYPH, PM_SILVER_DRAGON, "shimmering dragon" },
|
|
{ MON_GLYPH, PM_JABBERWOCK, "vorpal jabberwock" },
|
|
{ MON_GLYPH, PM_VAMPIRE_LORD, "vampire mage" },
|
|
#ifndef CHARON /* not supported yet */
|
|
{ MON_GLYPH, PM_CROESUS, "Charon" },
|
|
#endif
|
|
#ifndef MAIL
|
|
{ MON_GLYPH, PM_FAMINE, "mail daemon" },
|
|
#endif
|
|
/* commented out in monst.c at present */
|
|
{ MON_GLYPH, PM_SHAMAN_KARNOV, "Earendil" },
|
|
{ MON_GLYPH, PM_SHAMAN_KARNOV, "Elwing" },
|
|
/* commented out in monst.c at present */
|
|
{ MON_GLYPH, PM_CHROMATIC_DRAGON, "Goblin King" },
|
|
{ MON_GLYPH, PM_NEANDERTHAL, "High-elf" },
|
|
/* objects commented out in objects.c at present */
|
|
{ OBJ_GLYPH, SILVER_DRAGON_SCALE_MAIL, "shimmering dragon scale mail" },
|
|
{ OBJ_GLYPH, SILVER_DRAGON_SCALES, "shimmering dragon scales" },
|
|
/* allow slime mold to look like slice of pizza, since we
|
|
* don't know what a slime mold should look like when renamed anyway
|
|
*/
|
|
#ifndef MAIL
|
|
{ OBJ_GLYPH, SCR_STINKING_CLOUD + EXTRA_SCROLL_DESCR_COUNT, "stamped / mail" },
|
|
#endif
|
|
{ 0, 0, 0 }
|
|
};
|
|
|
|
/*
|
|
* Some entries in glyph2tile[] should be substituted for on various levels.
|
|
* The tiles used for the substitute entries will follow the usual ones in
|
|
* other.til in the order given here, which should have every substitution
|
|
* for the same set of tiles grouped together. You will have to change
|
|
* more code in process_substitutions()/substitute_tiles() if the sets
|
|
* overlap in the future.
|
|
*/
|
|
struct substitute {
|
|
int first_glyph, last_glyph;
|
|
const char *sub_name; /* for explanations */
|
|
const char *level_test;
|
|
} substitutes[] = { { GLYPH_CMAP_OFF + S_vwall, GLYPH_CMAP_OFF + S_trwall,
|
|
"mine walls", "In_mines(plev)" },
|
|
{ GLYPH_CMAP_OFF + S_vwall, GLYPH_CMAP_OFF + S_trwall,
|
|
"gehennom walls", "In_hell(plev)" },
|
|
{ GLYPH_CMAP_OFF + S_vwall, GLYPH_CMAP_OFF + S_trwall,
|
|
"knox walls", "Is_knox(plev)" },
|
|
{ GLYPH_CMAP_OFF + S_vwall, GLYPH_CMAP_OFF + S_trwall,
|
|
"sokoban walls", "In_sokoban(plev)" } };
|
|
|
|
#ifdef TILETEXT
|
|
|
|
/*
|
|
* entry is the position of the tile within the monsters/objects/other set
|
|
*/
|
|
const char *
|
|
tilename(set, entry)
|
|
int set, entry;
|
|
{
|
|
int i, j, condnum, tilenum;
|
|
static char buf[BUFSZ];
|
|
|
|
/* Note: these initializers don't do anything except guarantee that
|
|
we're linked properly.
|
|
*/
|
|
monst_init();
|
|
objects_init();
|
|
(void) def_char_to_objclass(']');
|
|
|
|
condnum = tilenum = 0;
|
|
|
|
for (i = 0; i < NUMMONS; i++) {
|
|
if (set == MON_GLYPH && tilenum == entry)
|
|
return mons[i].mname;
|
|
tilenum++;
|
|
while (conditionals[condnum].sequence == MON_GLYPH
|
|
&& conditionals[condnum].predecessor == i) {
|
|
if (set == MON_GLYPH && tilenum == entry)
|
|
return conditionals[condnum].name;
|
|
condnum++;
|
|
tilenum++;
|
|
}
|
|
}
|
|
if (set == MON_GLYPH && tilenum == entry)
|
|
return "invisible monster";
|
|
|
|
tilenum = 0; /* set-relative number */
|
|
for (i = 0; i < NUM_OBJECTS; i++) {
|
|
/* prefer to give the description - that's all the tile's
|
|
* appearance should reveal */
|
|
if (set == OBJ_GLYPH && tilenum == entry) {
|
|
if (!obj_descr[i].oc_descr)
|
|
return obj_descr[i].oc_name;
|
|
if (!obj_descr[i].oc_name)
|
|
return obj_descr[i].oc_descr;
|
|
|
|
Sprintf(buf, "%s / %s", obj_descr[i].oc_descr,
|
|
obj_descr[i].oc_name);
|
|
return buf;
|
|
}
|
|
|
|
tilenum++;
|
|
while (conditionals[condnum].sequence == OBJ_GLYPH
|
|
&& conditionals[condnum].predecessor == i) {
|
|
if (set == OBJ_GLYPH && tilenum == entry)
|
|
return conditionals[condnum].name;
|
|
condnum++;
|
|
tilenum++;
|
|
}
|
|
}
|
|
|
|
tilenum = 0; /* set-relative number */
|
|
for (i = 0; i < (MAXPCHARS - MAXEXPCHARS); i++) {
|
|
if (set == OTH_GLYPH && tilenum == entry) {
|
|
if (*defsyms[i].explanation) {
|
|
return defsyms[i].explanation;
|
|
} else {
|
|
Sprintf(buf, "cmap %d", tilenum);
|
|
return buf;
|
|
}
|
|
}
|
|
tilenum++;
|
|
while (conditionals[condnum].sequence == OTH_GLYPH
|
|
&& conditionals[condnum].predecessor == i) {
|
|
if (set == OTH_GLYPH && tilenum == entry)
|
|
return conditionals[condnum].name;
|
|
condnum++;
|
|
tilenum++;
|
|
}
|
|
}
|
|
/* explosions */
|
|
tilenum = MAXPCHARS - MAXEXPCHARS;
|
|
i = entry - tilenum;
|
|
if (i < (MAXEXPCHARS * EXPL_MAX)) {
|
|
if (set == OTH_GLYPH) {
|
|
static const char *explosion_types[] = {
|
|
/* hack.h */
|
|
"dark", "noxious", "muddy", "wet", "magical", "fiery",
|
|
"frosty"
|
|
};
|
|
Sprintf(buf, "explosion %s %d", explosion_types[i / MAXEXPCHARS],
|
|
i % MAXEXPCHARS);
|
|
return buf;
|
|
}
|
|
}
|
|
tilenum += (MAXEXPCHARS * EXPL_MAX);
|
|
|
|
i = entry - tilenum;
|
|
if (i < (NUM_ZAP << 2)) {
|
|
if (set == OTH_GLYPH) {
|
|
Sprintf(buf, "zap %d %d", i / 4, i % 4);
|
|
return buf;
|
|
}
|
|
}
|
|
tilenum += (NUM_ZAP << 2);
|
|
|
|
i = entry - tilenum;
|
|
if (i < WARNCOUNT) {
|
|
if (set == OTH_GLYPH) {
|
|
Sprintf(buf, "warning %d", i);
|
|
return buf;
|
|
}
|
|
}
|
|
tilenum += WARNCOUNT;
|
|
|
|
for (i = 0; i < SIZE(substitutes); i++) {
|
|
j = entry - tilenum;
|
|
if (j <= substitutes[i].last_glyph - substitutes[i].first_glyph) {
|
|
if (set == OTH_GLYPH) {
|
|
Sprintf(buf, "sub %s %d", substitutes[i].sub_name, j);
|
|
return buf;
|
|
}
|
|
}
|
|
tilenum += substitutes[i].last_glyph - substitutes[i].first_glyph + 1;
|
|
}
|
|
|
|
Sprintf(buf, "unknown %d %d", set, entry);
|
|
return buf;
|
|
}
|
|
|
|
#else /* TILETEXT */
|
|
|
|
#define TILE_FILE "tile.c"
|
|
|
|
#ifdef AMIGA
|
|
#define SOURCE_TEMPLATE "NH:src/%s"
|
|
#else
|
|
#ifdef MAC
|
|
#define SOURCE_TEMPLATE ":src:%s"
|
|
#else
|
|
#define SOURCE_TEMPLATE "../src/%s"
|
|
#endif
|
|
#endif
|
|
|
|
short tilemap[MAX_GLYPH];
|
|
|
|
#ifdef STATUES_LOOK_LIKE_MONSTERS
|
|
int lastmontile, lastobjtile, lastothtile, laststatuetile;
|
|
#else
|
|
int lastmontile, lastobjtile, lastothtile;
|
|
#endif
|
|
|
|
/* Number of tiles for invisible monsters */
|
|
#define NUM_INVIS_TILES 1
|
|
|
|
/*
|
|
* set up array to map glyph numbers to tile numbers
|
|
*
|
|
* assumes tiles are numbered sequentially through monsters/objects/other,
|
|
* with entries for all supported compilation options
|
|
*
|
|
* "other" contains cmap and zaps (the swallow sets are a repeated portion
|
|
* of cmap), as well as the "flash" glyphs for the new warning system
|
|
* introduced in 3.3.1.
|
|
*/
|
|
void
|
|
init_tilemap()
|
|
{
|
|
int i, j, condnum, tilenum;
|
|
int corpsetile, swallowbase;
|
|
|
|
for (i = 0; i < MAX_GLYPH; i++) {
|
|
tilemap[i] = -1;
|
|
}
|
|
|
|
corpsetile = NUMMONS + NUM_INVIS_TILES + CORPSE;
|
|
swallowbase = NUMMONS + NUM_INVIS_TILES + NUM_OBJECTS + S_sw_tl;
|
|
|
|
/* add number compiled out */
|
|
for (i = 0; conditionals[i].sequence; i++) {
|
|
switch (conditionals[i].sequence) {
|
|
case MON_GLYPH:
|
|
corpsetile++;
|
|
swallowbase++;
|
|
break;
|
|
case OBJ_GLYPH:
|
|
if (conditionals[i].predecessor < CORPSE)
|
|
corpsetile++;
|
|
swallowbase++;
|
|
break;
|
|
case OTH_GLYPH:
|
|
if (conditionals[i].predecessor < S_sw_tl)
|
|
swallowbase++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
condnum = tilenum = 0;
|
|
for (i = 0; i < NUMMONS; i++) {
|
|
tilemap[GLYPH_MON_OFF + i] = tilenum;
|
|
tilemap[GLYPH_PET_OFF + i] = tilenum;
|
|
tilemap[GLYPH_DETECT_OFF + i] = tilenum;
|
|
tilemap[GLYPH_RIDDEN_OFF + i] = tilenum;
|
|
tilemap[GLYPH_BODY_OFF + i] = corpsetile;
|
|
j = GLYPH_SWALLOW_OFF + 8 * i;
|
|
tilemap[j] = swallowbase;
|
|
tilemap[j + 1] = swallowbase + 1;
|
|
tilemap[j + 2] = swallowbase + 2;
|
|
tilemap[j + 3] = swallowbase + 3;
|
|
tilemap[j + 4] = swallowbase + 4;
|
|
tilemap[j + 5] = swallowbase + 5;
|
|
tilemap[j + 6] = swallowbase + 6;
|
|
tilemap[j + 7] = swallowbase + 7;
|
|
tilenum++;
|
|
while (conditionals[condnum].sequence == MON_GLYPH
|
|
&& conditionals[condnum].predecessor == i) {
|
|
condnum++;
|
|
tilenum++;
|
|
}
|
|
}
|
|
tilemap[GLYPH_INVISIBLE] = tilenum++;
|
|
lastmontile = tilenum - 1;
|
|
|
|
for (i = 0; i < NUM_OBJECTS; i++) {
|
|
tilemap[GLYPH_OBJ_OFF + i] = tilenum;
|
|
tilenum++;
|
|
while (conditionals[condnum].sequence == OBJ_GLYPH
|
|
&& conditionals[condnum].predecessor == i) {
|
|
condnum++;
|
|
tilenum++;
|
|
}
|
|
}
|
|
lastobjtile = tilenum - 1;
|
|
|
|
for (i = 0; i < (MAXPCHARS - MAXEXPCHARS); i++) {
|
|
tilemap[GLYPH_CMAP_OFF + i] = tilenum;
|
|
tilenum++;
|
|
while (conditionals[condnum].sequence == OTH_GLYPH
|
|
&& conditionals[condnum].predecessor == i) {
|
|
condnum++;
|
|
tilenum++;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < (MAXEXPCHARS * EXPL_MAX); i++) {
|
|
tilemap[GLYPH_EXPLODE_OFF + i] = tilenum;
|
|
tilenum++;
|
|
while (conditionals[condnum].sequence == OTH_GLYPH
|
|
&& conditionals[condnum].predecessor == (i + MAXPCHARS)) {
|
|
condnum++;
|
|
tilenum++;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < NUM_ZAP << 2; i++) {
|
|
tilemap[GLYPH_ZAP_OFF + i] = tilenum;
|
|
tilenum++;
|
|
while (conditionals[condnum].sequence == OTH_GLYPH
|
|
&& conditionals[condnum].predecessor == (i + MAXEXPCHARS)) {
|
|
condnum++;
|
|
tilenum++;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < WARNCOUNT; i++) {
|
|
tilemap[GLYPH_WARNING_OFF + i] = tilenum;
|
|
tilenum++;
|
|
}
|
|
|
|
#ifndef STATUES_LOOK_LIKE_MONSTERS
|
|
/* statue patch: statues still use the same glyph as in vanilla */
|
|
|
|
for (i = 0; i < NUMMONS; i++) {
|
|
tilemap[GLYPH_STATUE_OFF + i] = tilemap[GLYPH_OBJ_OFF + STATUE];
|
|
}
|
|
#endif
|
|
|
|
lastothtile = tilenum - 1;
|
|
|
|
#ifdef STATUES_LOOK_LIKE_MONSTERS
|
|
/* skip over the substitutes to get to the grayscale statues */
|
|
for (i = 0; i < SIZE(substitutes); i++) {
|
|
tilenum += substitutes[i].last_glyph - substitutes[i].first_glyph + 1;
|
|
}
|
|
|
|
/* statue patch: statues look more like the monster */
|
|
condnum = 0; /* doing monsters again, so reset */
|
|
for (i = 0; i < NUMMONS; i++) {
|
|
tilemap[GLYPH_STATUE_OFF + i] = tilenum;
|
|
tilenum++;
|
|
while (conditionals[condnum].sequence == MON_GLYPH
|
|
&& conditionals[condnum].predecessor == i) {
|
|
condnum++;
|
|
tilenum++;
|
|
}
|
|
}
|
|
laststatuetile = tilenum - 1;
|
|
#endif
|
|
}
|
|
|
|
const char *prolog[] = { "", "", "void", "substitute_tiles(plev)",
|
|
"d_level *plev;", "{", "\tint i;", "" };
|
|
|
|
const char *epilog[] = { "}" };
|
|
|
|
/* write out the substitutions in an easily-used form. */
|
|
void
|
|
process_substitutions(ofp)
|
|
FILE *ofp;
|
|
{
|
|
int i, j, k, span, start;
|
|
|
|
fprintf(ofp, "\n\n");
|
|
|
|
j = 0; /* unnecessary */
|
|
span = -1;
|
|
for (i = 0; i < SIZE(substitutes); i++) {
|
|
if (i == 0 || substitutes[i].first_glyph != substitutes[j].first_glyph
|
|
|| substitutes[i].last_glyph != substitutes[j].last_glyph) {
|
|
j = i;
|
|
span++;
|
|
fprintf(ofp, "short std_tiles%d[] = { ", span);
|
|
for (k = substitutes[i].first_glyph;
|
|
k < substitutes[i].last_glyph; k++)
|
|
fprintf(ofp, "%d, ", tilemap[k]);
|
|
fprintf(ofp, "%d };\n", tilemap[substitutes[i].last_glyph]);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < SIZE(prolog); i++) {
|
|
fprintf(ofp, "%s\n", prolog[i]);
|
|
}
|
|
j = -1;
|
|
span = -1;
|
|
start = lastothtile + 1;
|
|
for (i = 0; i < SIZE(substitutes); i++) {
|
|
if (i == 0 || substitutes[i].first_glyph != substitutes[j].first_glyph
|
|
|| substitutes[i].last_glyph != substitutes[j].last_glyph) {
|
|
if (i != 0) { /* finish previous span */
|
|
fprintf(ofp, "\t} else {\n");
|
|
fprintf(ofp, "\t\tfor (i = %d; i <= %d; i++)\n",
|
|
substitutes[j].first_glyph,
|
|
substitutes[j].last_glyph);
|
|
fprintf(ofp, "\t\t\tglyph2tile[i] = std_tiles%d[i - %d];\n",
|
|
span, substitutes[j].first_glyph);
|
|
fprintf(ofp, "\t}\n\n");
|
|
}
|
|
j = i;
|
|
span++;
|
|
}
|
|
if (i != j)
|
|
fprintf(ofp, "\t} else ");
|
|
fprintf(ofp, "\tif (%s) {\n", substitutes[i].level_test);
|
|
fprintf(ofp, "\t\tfor (i = %d; i <= %d; i++)\n",
|
|
substitutes[i].first_glyph, substitutes[i].last_glyph);
|
|
fprintf(ofp, "\t\t\tglyph2tile[i] = %d + i - %d;\n", start,
|
|
substitutes[i].first_glyph);
|
|
start += substitutes[i].last_glyph - substitutes[i].first_glyph + 1;
|
|
}
|
|
/* finish last span */
|
|
fprintf(ofp, "\t} else {\n");
|
|
fprintf(ofp, "\t\tfor (i = %d; i <= %d; i++)\n",
|
|
substitutes[j].first_glyph, substitutes[j].last_glyph);
|
|
fprintf(ofp, "\t\t\tglyph2tile[i] = std_tiles%d[i - %d];\n", span,
|
|
substitutes[j].first_glyph);
|
|
fprintf(ofp, "\t}\n\n");
|
|
|
|
for (i = 0; i < SIZE(epilog); i++) {
|
|
fprintf(ofp, "%s\n", epilog[i]);
|
|
}
|
|
|
|
fprintf(ofp, "\nint total_tiles_used = %d;\n", start);
|
|
lastothtile = start - 1;
|
|
}
|
|
|
|
int
|
|
main()
|
|
{
|
|
register int i;
|
|
char filename[30];
|
|
FILE *ofp;
|
|
|
|
init_tilemap();
|
|
|
|
/*
|
|
* create the source file, "tile.c"
|
|
*/
|
|
Sprintf(filename, SOURCE_TEMPLATE, TILE_FILE);
|
|
if (!(ofp = fopen(filename, "w"))) {
|
|
perror(filename);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
fprintf(ofp,
|
|
"/* This file is automatically generated. Do not edit. */\n");
|
|
fprintf(ofp, "\n#include \"hack.h\"\n\n");
|
|
fprintf(ofp, "short glyph2tile[MAX_GLYPH] = {\n");
|
|
|
|
for (i = 0; i < MAX_GLYPH; i++) {
|
|
fprintf(ofp, "%2d,%c", tilemap[i], (i % 12) ? ' ' : '\n');
|
|
}
|
|
fprintf(ofp, "%s};\n", (i % 12) ? "\n" : "");
|
|
|
|
process_substitutions(ofp);
|
|
|
|
fprintf(ofp, "\n#define MAXMONTILE %d\n", lastmontile);
|
|
fprintf(ofp, "#define MAXOBJTILE %d\n", lastobjtile);
|
|
fprintf(ofp, "#define MAXOTHTILE %d\n", lastothtile);
|
|
|
|
fprintf(ofp, "\n/*tile.c*/\n");
|
|
|
|
fclose(ofp);
|
|
exit(EXIT_SUCCESS);
|
|
/*NOTREACHED*/
|
|
return 0;
|
|
}
|
|
|
|
#endif /* TILETEXT */
|
|
|
|
struct {
|
|
int idx;
|
|
const char *betterlabel;
|
|
const char *expectedlabel;
|
|
} altlabels[] = {
|
|
{0, "dark part of a room", "dark part of a room"},
|
|
{1, "vertical wall", "wall"},
|
|
{2, "horizontal wall", "wall"},
|
|
{3, "top left corner wall", "wall"},
|
|
{4, "top right corner wall", "wall"},
|
|
{5, "bottom left corner wall", "wall"},
|
|
{6, "bottom right corner wall", "wall"},
|
|
{7, "cross wall", "wall"},
|
|
{8, "tuwall", "wall"},
|
|
{9, "tdwall", "wall"},
|
|
{10, "tlwall", "wall"},
|
|
{11, "trwall", "wall"},
|
|
{12, "no door", "doorway"},
|
|
{13, "vertical open door", "open door"},
|
|
{14, "horizontal open door", "open door"},
|
|
{15, "vertical closed door", "closed door"},
|
|
{16, "horizontal closed door", "closed door"},
|
|
{17, "iron bars", "iron bars"},
|
|
{18, "tree", "tree"},
|
|
{19, "room", "floor of a room"},
|
|
{20, "darkroom", "dark part of a room"},
|
|
{21, "corridor", "corridor"},
|
|
{22, "lit corridor", "lit corridor"},
|
|
{23, "up stairs", "staircase up"},
|
|
{24, "down stairs", "staircase down"},
|
|
{25, "up ladder", "ladder up"},
|
|
{26, "down ladder", "ladder down"},
|
|
{27, "altar", "altar"},
|
|
{28, "grave", "grave"},
|
|
{29, "throne", "opulent throne"},
|
|
{30, "sink", "sink"},
|
|
{31, "fountain", "fountain"},
|
|
{32, "pool", "water"},
|
|
{33, "ice", "ice"},
|
|
{34, "lava", "molten lava"},
|
|
{35, "vertical open drawbridge", "lowered drawbridge"},
|
|
{36, "horizontal open drawbridge", "lowered drawbridge"},
|
|
{37, "vertical closed drawbridge", "raised drawbridge"},
|
|
{38, "horizontal closed drawbridge", "raised drawbridge"},
|
|
{39, "air", "air"},
|
|
{40, "cloud", "cloud"},
|
|
{41, "water", "water"},
|
|
{42, "arrow trap", "arrow trap"},
|
|
{43, "dart trap", "dart trap"},
|
|
{44, "falling rock trap", "falling rock trap"},
|
|
{45, "squeaky board", "squeaky board"},
|
|
{46, "bear trap", "bear trap"},
|
|
{47, "land mine", "land mine"},
|
|
{48, "rolling boulder trap", "rolling boulder trap"},
|
|
{49, "sleeping gas trap", "sleeping gas trap"},
|
|
{50, "rust trap", "rust trap"},
|
|
{51, "fire trap", "fire trap"},
|
|
{52, "pit", "pit"},
|
|
{53, "spiked pit", "spiked pit"},
|
|
{54, "hole", "hole"},
|
|
{55, "trap door", "trap door"},
|
|
{56, "teleportation trap", "teleportation trap"},
|
|
{57, "level teleporter", "level teleporter"},
|
|
{58, "magic portal", "magic portal"},
|
|
{59, "web", "web"},
|
|
{60, "statue trap", "statue trap"},
|
|
{61, "magic trap", "magic trap"},
|
|
{62, "anti magic trap", "anti-magic field"},
|
|
{63, "polymorph trap", "polymorph trap"},
|
|
{64, "vibrating square", "vibrating square"},
|
|
{65, "vertical beam", "wall"},
|
|
{66, "horizontal beam", "wall"},
|
|
{67, "left slant beam", "wall"},
|
|
{68, "right slant beam", "wall"},
|
|
{69, "dig beam", "cmap 69"},
|
|
{70, "flash beam", "cmap 70"},
|
|
{71, "boom left", "cmap 71"},
|
|
{72, "boom right", "cmap 72"},
|
|
{73, "shield1", "cmap 73"},
|
|
{74, "shield2", "cmap 74"},
|
|
{75, "shield3", "cmap 75"},
|
|
{76, "shield4", "cmap 76"},
|
|
{77, "poison cloud", "poison cloud"},
|
|
{78, "valid position", "valid position"},
|
|
{79, "swallow top left", "cmap 79"},
|
|
{80, "swallow top center", "cmap 80"},
|
|
{81, "swallow top right", "cmap 81"},
|
|
{82, "swallow middle left", "cmap 82"},
|
|
{83, "swallow middle right", "cmap 83"},
|
|
{84, "swallow bottom left ", "cmap 84"},
|
|
{85, "swallow bottom center", "cmap 85"},
|
|
{86, "swallow bottom right", "cmap 86"},
|
|
{87, "explosion top left", "explosion dark 0"},
|
|
{88, "explosion top centre", "explosion dark 1"},
|
|
{89, "explosion top right", "explosion dark 2"},
|
|
{90, "explosion middle left", "explosion dark 3"},
|
|
{91, "explosion middle center", "explosion dark 4"},
|
|
{92, "explosion middle right", "explosion dark 5"},
|
|
{93, "explosion bottom left", "explosion dark 6"},
|
|
{94, "explosion bottom center", "explosion dark 7"},
|
|
{95, "explosion bottom right", "explosion dark 8"},
|
|
};
|
|
|
|
boolean
|
|
acceptable_tilename(idx, encountered, expected)
|
|
int idx;
|
|
const char *encountered, *expected;
|
|
{
|
|
if (idx >= 0 && idx < SIZE(altlabels)) {
|
|
if (!strcmp(altlabels[idx].expectedlabel, expected)) {
|
|
if (!strcmp(altlabels[idx].betterlabel, encountered))
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|