visibility determination
[vrlugburz] / src / level.c
index 6867e64..5f7f77b 100644 (file)
@@ -12,6 +12,9 @@ static int detect_cell_tile(struct level *lvl, int x, int y, int *rot);
 
 int init_level(struct level *lvl, int xsz, int ysz)
 {
+       int i, j;
+       struct cell *cell;
+
        memset(lvl, 0, sizeof *lvl);
 
        if(!(lvl->cells = calloc(xsz * ysz, sizeof *lvl->cells))) {
@@ -22,6 +25,18 @@ int init_level(struct level *lvl, int xsz, int ysz)
        lvl->height = ysz;
        lvl->cell_size = DEF_CELL_SIZE;
        lvl->px = lvl->py = -1;
+
+       lvl->visdist = 4;
+
+       /* assign cell coordinates */
+       cell = lvl->cells;
+       for(i=0; i<ysz; i++) {
+               for(j=0; j<xsz; j++) {
+                       cell->x = j;
+                       cell->y = i;
+                       cell++;
+               }
+       }
        return 0;
 }
 
@@ -40,6 +55,7 @@ int load_level(struct level *lvl, const char *fname)
        struct cell *cell;
        float *vecptr;
        const char *str;
+       char *tset_path;
 
        if(!(ts = ts_load(fname))) {
                fprintf(stderr, "failed to load level: %s\n", fname);
@@ -63,9 +79,7 @@ int load_level(struct level *lvl, const char *fname)
 
        lvl->fname = strdup(fname);
        if((lvl->dirname = malloc(strlen(fname) + 1))) {
-#ifndef LEVEL_EDITOR
                path_dir(lvl->fname, lvl->dirname);
-#endif
        }
 
        lvl->cell_size = ts_get_attr_num(ts, "cellsize", DEF_CELL_SIZE);
@@ -76,7 +90,9 @@ int load_level(struct level *lvl, const char *fname)
        }
 
        if((str = ts_get_attr_str(ts, "tileset", 0))) {
-               lvl->tset = get_tileset(str);
+               tset_path = alloca(strlen(str) + strlen(lvl->dirname) + 2);
+               combine_path(lvl->dirname, str, tset_path);
+               lvl->tset = get_tileset(tset_path);
        }
 
        iter = ts->child_list;
@@ -102,21 +118,22 @@ int load_level(struct level *lvl, const char *fname)
        cell = lvl->cells;
        for(i=0; i<lvl->height; i++) {
                for(j=0; j<lvl->width; j++) {
+                       node = (struct ts_node*)cell->next;
+                       cell->next = 0;
+
                        if(cell->type == CELL_SOLID) {
                                cell++;
                                continue;
                        }
 
-                       node = (struct ts_node*)cell->next;
-                       cell->next = 0;
-
                        if((tiletype = tile_type(ts_get_attr_str(node, "tiletype", 0))) == -1) {
                                /* no tile-type specified, try to guess */
                                tiletype = detect_cell_tile(lvl, j, i, &cell->tilerot);
                        }
 
-                       cell->tile = get_tile(lvl->tset, tiletype);
-
+                       if(lvl->tset) {
+                               cell->tile = get_tile(lvl->tset, tiletype);
+                       }
                        cell++;
                }
        }
@@ -209,7 +226,7 @@ err:
 
 #ifndef LEVEL_EDITOR
 
-static int get_cell_type(struct level *lvl, int x, int y)
+int get_cell_type(struct level *lvl, int x, int y)
 {
        if(x < 0 || x >= lvl->width || y < 0 || y >= lvl->height) {
                return CELL_SOLID;
@@ -225,7 +242,6 @@ static int detect_cell_tile(struct level *lvl, int x, int y, int *rot)
        bit = 0;
        for(i=0; i<3; i++) {
                for(j=0; j<3; j++) {
-                       if(i == 1 && j == 1) continue;
                        if(get_cell_type(lvl, x + j - 1, y + i - 1) == CELL_SOLID) {
                                adj |= 1 << bit;
                        }
@@ -243,56 +259,75 @@ static int detect_cell_tile(struct level *lvl, int x, int y, int *rot)
                 */
                return TILE_OPEN;
 
-       case 0555:      /* N-S corridor */
-               *rot = 1;
-       case 0707:      /* W-E corridor */
-               return TILE_STR;
+       case 0745:
+       case 0645:
+       case 0741:
+       case 0641:
+               return TILE_CORNER;
+
+       case 0744:
+       case 0644:
+       case 0740:
+       case 0640:
+               return TILE_OPENCORNER;
 
-       case 0745:      /* S-E corner */
+       case 0715:
+       case 0315:
+       case 0714:
+       case 0314:
                *rot = 1;
-       case 0715:      /* S-W corner */
                return TILE_CORNER;
-       case 0547:      /* N-E corner */
-               *rot = 2;
+
+       case 0711:
+       case 0311:
+       case 0710:
+       case 0310:
+               *rot = 1;
+               return TILE_OPENCORNER;
+
+       case 0547:
+       case 0147:
+       case 0546:
+       case 0146:
+               *rot = 3;
                return TILE_CORNER;
-       case 0517:      /* N-W corner */
+
+       case 0447:
+       case 0047:
+       case 0446:
+       case 0046:
                *rot = 3;
+               return TILE_OPENCORNER;
+
+       case 0517:
+       case 0417:
+       case 0513:
+       case 0413:
+               *rot = 2;
                return TILE_CORNER;
 
+       case 0117:
+       case 0017:
+       case 0113:
+       case 0013:
+               *rot = 2;
+               return TILE_OPENCORNER;
+
        case 0507:      /* N tee */
                *rot = 3;
+               return TILE_TEE;
        case 0515:      /* W tee */
+               *rot = 2;
                return TILE_TEE;
        case 0705:      /* S tee */
                *rot = 1;
                return TILE_TEE;
        case 0545:      /* E tee */
-               *rot = 2;
                return TILE_TEE;
 
        case 0505:      /* cross */
                return TILE_CROSS;
 
-       case 0700:      /* S stropen */
-       case 0701:
-       case 0704:
-               return TILE_STROPEN;
-       case 0444:      /* E stropen */
-       case 0445:
-       case 0544:
-               *rot = 1;
-               return TILE_STROPEN;
-       case 0007:      /* N stropen */
-       case 0407:
-       case 0107:
-               *rot = 2;
-               return TILE_STROPEN;
-       case 0111:      /* W stropen */
-       case 0511:
-       case 0115:
-               *rot = 3;
-               return TILE_STROPEN;
-
        case 0404:      /* E str2open */
                return TILE_STR2OPEN;
        case 0005:      /* N str2open */
@@ -304,6 +339,31 @@ static int detect_cell_tile(struct level *lvl, int x, int y, int *rot)
        case 0500:      /* S str2open */
                *rot = 3;
                return TILE_STR2OPEN;
+
+       default:
+               if((adj & 0222) == 0200) {
+                       return TILE_STROPEN;
+               }
+               if((adj & 0222) == 0002) {
+                       *rot = 2;
+                       return TILE_STROPEN;
+               }
+               if((adj & 0070) == 0040) {
+                       *rot = 3;
+                       return TILE_STROPEN;
+               }
+               if((adj & 0070) == 0010) {
+                       *rot = 1;
+                       return TILE_STROPEN;
+               }
+
+               if((adj & 0070) == 0050) {
+                       *rot = 1;                       /* straight N-S */
+                       return TILE_STR;
+               }
+               if((adj & 0202) == 0202) {
+                       return TILE_STR;        /* straight E-W */
+               }
        }
 
        return TILE_OPEN;