void cMapDrawer::drawShroud() { set_trans_blender(0,0,0,128); BITMAP *temp = create_bitmap(32,32); int iDrawX=0; int iDrawY=42; int cll=-1; int tile=-1; int iPl = player->getId(); for (int iStartX = camera->getX(); iStartX < camera->getEndX(); iStartX++) { iDrawY=42; tile=-1; // new row for (int iStartY=camera->getY(); iStartY < camera->getEndY(); iStartY++) { cll = iCellMake(iStartX, iStartY); if (DEBUGGING) { if (mapUtils->isCellVisibleForPlayerId(iPl, cll)) { // do nothing } else { rectfill(bmp_screen, iDrawX, iDrawY, iDrawX+32, iDrawY+32, makecol(0,0,0)); } } else { if (mapUtils->isCellVisibleForPlayerId(iPl, cll)) { // Visible stuff, now check for not visible stuff. When found, assign the proper border // of shroud to it. int above = CELL_ABOVE(cll); int under = CELL_UNDER(cll); int left = CELL_LEFT(cll); int right = CELL_RIGHT(cll); bool a, u, l, r; a=u=l=r=true; if (above > -1) { if (mapUtils->isCellVisibleForPlayerId(iPl, above)) { a = false; // visible } } else { a = false; } if (under > -1) { if (mapUtils->isCellVisibleForPlayerId(iPl, under)) { u = false; // visible } } else { u = false; } if (left > -1) { if (mapUtils->isCellVisibleForPlayerId(iPl, left)) { l = false; // visible } } else { l = false; } if (right > -1) { if (mapUtils->isCellVisibleForPlayerId(iPl, right)) { r = false; // visible } } else { r = false; } int t=-1; // tile id to draw... (x axis) // when above is not visible then change this border tile if (a == true && u == false && l == false && r == false) t = 3; if (a == false && u == true && l == false && r == false) t = 7; if (a == false && u == false && l == true && r == false) t = 9; if (a == false && u == false && l == false && r == true) t = 5; // corners if (a == true && u == false && l == true && r == false) t = 2; if (a == true && u == false && l == false && r == true) t = 4; if (a == false && u == true && l == true && r == false) t = 8; if (a == false && u == true && l == false && r == true) t = 6; // 3 connections if (a == true && u == true && l == true && r == false) t = 10; if (a == true && u == true && l == false && r == true) t = 12; if (a == true && u == false && l == true && r == true) t = 11; if (a == false && u == true && l == true && r == true) t = 13; if (a == true && u == true && l == true && r == true) t=1; tile = t - 1; if (tile > -1) { // Draw cell masked_blit((BITMAP *)gfxdata[SHROUD].dat, bmp_screen, tile * 32, 0, iDrawX, iDrawY, 32, 32); clear_to_color(temp, makecol(255,0,255)); masked_blit((BITMAP *)gfxdata[SHROUD_SHADOW].dat, temp, tile * 32, 0, 0, 0, 32, 32); draw_trans_sprite(bmp_screen, temp, iDrawX, iDrawY); // alfont_textprintf(bmp_screen, game_font, iDrawX,iDrawY, makecol(255,255,255), "%d", tile); } } else { // NOT VISIBLE, DO NOT DRAW A THING THEN! // alfont_textprintf(bmp_screen, game_font, iDrawX,iDrawY, makecol(255,255,255), "%d", tile); // Except when there is a building here, that should not be visible ;) // if (map.cell[cll].id[1] > -1 || map.cell[cll].id[0] > -1 || map.cell[cll].id[2] > -1 || map.cell[cll].id[3] > -1) masked_blit((BITMAP *)gfxdata[SHROUD].dat, bmp_screen, 0, 0, iDrawX, iDrawY, 32, 32); } } iDrawY+=32; } iDrawX+=32; } destroy_bitmap(temp); }
/* This function (as well as prim_tileable) make use of the somewhat unclean practice of storing ints as pointers. I've been informed that this may cause problems with 64-bit stuff. However, hopefully it will be okay, since the only values stored are positive. If it does break, let me know, and I'll go cry in a corner for a while before I get up the strength to re-code it. */ void prim(gint pos, gchar *maz, guint x, guint y) { GSList *front_cells=NULL; guint current; gint up, down, left, right; /* Not unsigned, because macros return -1. */ guint progress=0, max_progress; char d, i; guint c=0; gint rnd = mvals.seed; g_rand_set_seed (gr, rnd); gimp_progress_init (_("Constructing maze using Prim's Algorithm")); /* OUT is zero, so we should be already initalized. */ max_progress=x*y/4; /* Starting position has already been determined by the calling function. */ maz[pos]=IN; /* For now, repeating everything four times seems manageable. But when Gimp is extended to drawings in n-dimensional space instead of 2D, this will require a bit of a re-write. */ /* Add frontier. */ up=CELL_UP(pos); down=CELL_DOWN(pos); left=CELL_LEFT(pos); right=CELL_RIGHT(pos); if (up >= 0) { maz[up]=FRONTIER; front_cells=g_slist_append(front_cells,GINT_TO_POINTER(up)); } if (down >= 0) { maz[down]=FRONTIER; front_cells=g_slist_append(front_cells,GINT_TO_POINTER(down)); } if (left >= 0) { maz[left]=FRONTIER; front_cells=g_slist_append(front_cells,GINT_TO_POINTER(left)); } if (right >= 0) { maz[right]=FRONTIER; front_cells=g_slist_append(front_cells,GINT_TO_POINTER(right)); } /* While frontier is not empty do the following... */ while(g_slist_length(front_cells) > 0) { /* Remove one cell at random from frontier and place it in IN. */ current = g_rand_int_range (gr, 0, g_slist_length(front_cells)); pos = GPOINTER_TO_INT(g_slist_nth(front_cells,current)->data); front_cells=g_slist_remove(front_cells,GINT_TO_POINTER(pos)); maz[pos]=IN; /* If the cell has any neighbors in OUT, remove them from OUT and place them in FRONTIER. */ up=CELL_UP(pos); down=CELL_DOWN(pos); left=CELL_LEFT(pos); right=CELL_RIGHT(pos); d=0; if (up>=0) { switch (maz[up]) { case OUT: maz[up]=FRONTIER; front_cells=g_slist_prepend(front_cells, GINT_TO_POINTER(up)); break; case IN: d=1; break; default: ; } } if (down>=0) { switch (maz[down]) { case OUT: maz[down]=FRONTIER; front_cells=g_slist_prepend(front_cells, GINT_TO_POINTER(down)); break; case IN: d=d|2; break; default: ; } } if (left>=0) { switch (maz[left]) { case OUT: maz[left]=FRONTIER; front_cells=g_slist_prepend(front_cells, GINT_TO_POINTER(left)); break; case IN: d=d|4; break; default: ; } } if (right>=0) { switch (maz[right]) { case OUT: maz[right]=FRONTIER; front_cells=g_slist_prepend(front_cells, GINT_TO_POINTER(right)); break; case IN: d=d|8; break; default: ; } } /* The cell is guaranteed to have at least one neighbor in IN (otherwise it would not have been in FRONTIER); pick one such neighbor at random and connect it to the new cell (ie knock out a wall). */ if (!d) { g_warning("maze: prim: Lack of neighbors.\n" "seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n", mvals.seed, x, y, mvals.multiple, mvals.offset); break; } c=0; do { rnd = (rnd * mvals.multiple + mvals.offset); i = 3 & (rnd / d); if (++c > 100) { /* Break and try to salvage something */ i=99; /* if it looks like we're going to be */ break; /* here forever... */ } } while ( !(d & ( 1 << i) ) ); switch (i) { case 0: maz[WALL_UP(pos)]=IN; break; case 1: maz[WALL_DOWN(pos)]=IN; break; case 2: maz[WALL_LEFT(pos)]=IN; break; case 3: maz[WALL_RIGHT(pos)]=IN; break; case 99: break; default: g_warning("maze: prim: Going in unknown direction.\n" "i: %d, d: %d, seed: %d, mw: %d, mh: %d, mult: %d, offset: %d\n", i, d, mvals.seed, x, y, mvals.multiple, mvals.offset); } if (progress++ % PRIMS_PROGRESS_UPDATE) gimp_progress_update ((double) progress / (double) max_progress); } /* while front_cells */ g_slist_free(front_cells); } /* prim */