int _find_iterate_line (uint8_t sx, uint8_t y, uint8_t* heatmap) { for (int dx=0; dx < MAP_WIDTH; dx++) { if (vtile(sx-dx,y) && heatmap[y * MAP_WIDTH + (sx-dx)] ) return (sx-dx); if (vtile(sx+dx,y) && heatmap[y * MAP_WIDTH + (sx+dx)] ) return (sx+dx); } return -1; }
int update_heatmap(struct t_map* map, uint8_t* hm, uint8_t x, uint8_t y) { int r = 0; //if (can_see_entity(map,me,target)) heatmap[(target->y) * MAP_WIDTH + (target->x)] = 2; //new tile uint8_t h_add [ HEATMAP_SIZE]; memset(h_add,0,sizeof(uint8_t) * HEATMAP_SIZE); if ( vtile(x,y)&& ((tflags[map->sq[y * MAP_WIDTH + x].type] & TF_SOLID) == 0) ) { r = heatmap_add(hm,x,y,2); if (r != 0) return 1; } for (int i=0; i < HEATMAP_SIZE; i++) { if (hm[i] == 2) { uint8_t y = (i / MAP_WIDTH); uint8_t x = (i % MAP_WIDTH); hm[i] = 1; r = spread_heatmap(map,x,y,hm); if (r != 0) return 1; } } for (int i=0; i < HEATMAP_SIZE; i++) { if ( hm[i] && (map->aidata.e_viewarr[i] >= 3) ) hm[i] = 0; } return 0; }
int open_door (struct t_map* map, struct t_map_entity* who, uint8_t x, uint8_t y) { if (!vtile(x,y)) return -1; // not a valid space if ((abs(who->x - x) > 1) || (abs(who->y - y) > 1)) return -3; //out of reach if (map->sq[y * MAP_WIDTH+x].type != TT_DOOR_CLOSED) return -2; //not a closed door map->sq[y * MAP_WIDTH+x].type = TT_DOOR_OPEN; return 8; }
int find_closest_on_heatmap(uint8_t sx, uint8_t sy, uint8_t* heatmap, uint8_t* o_x, uint8_t* o_y) { for ( int dy = 0; dy < MAP_HEIGHT; dy++) { if (vtile(0,sy-dy)) { int r = _find_iterate_line(sx,(sy-dy),heatmap); if (r != -1) {*o_x = r; *o_y = (sy-dy); return 0;} } if (vtile(0,sy+dy)) { int r = _find_iterate_line(sx,(sy+dy),heatmap); if (r != -1) {*o_x = r; *o_y = (sy+dy); return 0;} } } *o_x = 255; *o_y = 255; return 0; }
int find_closest_on_hm_with_path(struct t_map* map, uint8_t sx, uint8_t sy, uint8_t* heatmap, uint8_t* viewarr, uint8_t* o_x, uint8_t* o_y) { uint16_t temp_patharr [ HEATMAP_SIZE ]; memset(temp_patharr, 255, sizeof temp_patharr); temp_patharr [sy * MAP_WIDTH + sx] = 0; struct pqueue_t* pq = pq_create(); pq_push(pq, (void*)((size_t)sy * MAP_WIDTH + sx + 1),0); // create a queue, set the source area to zero. //assumes the rest is already filled with 0xFFFF while (pq_size(pq)) { // while not empty int yx = (int)(size_t)(pq_pop(pq,NULL)) - 1; int x = (yx % MAP_WIDTH); int y = (yx / MAP_WIDTH); if (heatmap[yx]) { pq_destroy(pq); *o_y = y; *o_x = x; return 0; } int dir=0; //x and y now contain element with lowest priority for (dir=0; dir < MD_COUNT; dir++) { // for all neighbors int nx = x + movediff[dir][0]; int ny = y + movediff[dir][1]; if (!vtile(nx,ny)) continue; //this should be a valid tile! int cost = getcost(map,NULL,nx,ny,viewarr); if (cost == -1) continue; if (dir % 2) { cost = (cost * 3) / 2; } int alt = temp_patharr[y * MAP_WIDTH + x] + cost; if (alt < temp_patharr[ny * MAP_WIDTH + nx]) { temp_patharr[ny * MAP_WIDTH + nx] = alt; pq_push (pq, (void*) (ny * MAP_WIDTH + nx + 1), alt); } } } pq_destroy(pq); *o_x = 255; *o_y = 255; return 0; }
int spread_heatmap(struct t_map* map, uint8_t x, uint8_t y, uint8_t* heatmap) { enum movedirections md = 0; uint8_t dx = x, dy = y; int r = 0; for (md = 0; md < MD_COUNT; md++) { dx = x + movediff[md][0]; dy = y + movediff[md][1]; if ( (vtile(dx,dy)) && ((tflags[map->sq[dy * MAP_WIDTH + dx].type] & TF_SOLID) == 0) && (heatmap_exists(heatmap,dx,dy) == 0) ) heatmap_add(heatmap,dx,dy,2); //new tile. } heatmap_add(heatmap,x,y,1); return 0; }
int main(int argc, char** argv) { try { if (argc < 2) { std::clog << "usage: vtile-edit /path/to/tile.vector.mvt [--set-version version]" << std::endl; return -1; } std::string vtile(argv[1]); mapnik::util::file input(vtile); if (!input.is_open()) { std::clog << std::string("failed to open ") + vtile << "\n"; return -1; } unsigned version = 0; bool clean_empty = false; if (argc > 2) { for (int i = 2; i < argc; i++) { std::string flag = argv[i]; if (flag == "--set-version") { version = std::stoi(argv[i + 1]); } if (flag == "--clean-empty") { clean_empty = true; } } } std::string message(input.data().get(), input.size()); bool is_zlib = mapnik::vector_tile_impl::is_zlib_compressed(message); bool is_gzip = mapnik::vector_tile_impl::is_gzip_compressed(message); if (is_zlib || is_gzip) { if (is_zlib) { std::cout << "message: zlib compressed\n"; } else if (is_gzip) { std::cout << "message: gzip compressed\n"; } std::string uncompressed; mapnik::vector_tile_impl::zlib_decompress(message,uncompressed); message = uncompressed; } vector_tile::Tile tile; tile.ParseFromString(message); for (int j=0;j<tile.layers_size(); ++j) { auto layer = tile.mutable_layers(j); std::clog << "layer: " << layer->name() << std::endl; if (version != 0) { std::clog << "old version: " << layer->version() << std::endl; if (version != layer->version()) { layer->set_version(version); } std::clog << "new version: " << layer->version() << std::endl; } if (clean_empty) { std::clog << "Cleaning empty features" << std::endl; for (int i = 0; i < layer->features_size(); ++i) { auto feature = layer->mutable_features(i); if (feature->geometry_size() == 0 && !feature->has_raster()) { layer->mutable_features()->DeleteSubrange(i,1); --i; } } if (layer->features_size() == 0) { tile.mutable_layers()->DeleteSubrange(j,1); --j; } } } // Serialize std::string output; tile.SerializeToString(&output); // Recompress bool gzip = true; if (is_zlib || is_gzip) { if (is_zlib) { gzip = false; std::cout << "message: zlib compressing\n"; } else if (is_gzip) { gzip = true; std::cout << "message: gzip compressing\n"; } std::string compressed; mapnik::vector_tile_impl::zlib_compress(output,compressed,gzip); output = compressed; } std::ofstream file(vtile); file << output; std::clog << "wrote to: " << vtile << std::endl; } catch (std::exception const& ex) { std::clog << "error: " << ex.what() << "\n"; return -1; } return 0; }
int draw_map(struct t_map* map, struct t_map_entity* persp, bool show_vis, bool show_fov, bool show_targets, bool show_heatmaps, bool hl_persp) { int cs = curs_set(0); int x,y; getsyx(y,x); wmove(mapwindow,0,0); for (int iy=0; iy< MAP_HEIGHT; iy++) { for (int ix=0; ix < MAP_WIDTH; ix++) { chtype tilech = mapchar[map->sq[iy*(MAP_WIDTH)+ix].type]; int tilevis = 1; tilevis = map->aidata.p_viewarr[iy * MAP_WIDTH + ix]; if (!show_vis && (tilevis<1)) tilevis = 1; chtype tileflags = 0; switch (tilevis) { case 1: tileflags = CP_BLUE; break; case 2: tileflags = CP_LIGHTGRAY; break; case 3: case 4: tileflags = CP_WHITE; break; default: break; } if (tilevis) mvwaddch(mapwindow,iy,ix, tileflags | tilech ); else if (dbgmode) mvwaddch (mapwindow,iy,ix,' '); } } if (show_heatmaps) { for (int yx=0; yx < HEATMAP_SIZE; yx++) { uint8_t y = yx / MAP_WIDTH; uint8_t x = yx % MAP_WIDTH; uint8_t m = map->aidata.e_hm[yx]; if (m) mvwaddch(mapwindow,y,x,'&' | ( (m > 2) ? CP_RED : ((m == 2) ? CP_GREEN : CP_YELLOW) ) ) ; } } for (int i=0; i < MAX_ENTITIES; i++) { if (map->ent[i].type == ET_NONE) continue; if ((map->ent[i].aidata) != NULL) { if (show_targets) { if (vtile(map->ent[i].aidata->dx,map->ent[i].aidata->dy)) mvwaddch(mapwindow,map->ent[i].aidata->dy,map->ent[i].aidata->dx,'%' | CP_PURPLE); } if (show_fov && (map->aidata.p_viewarr[map->ent[i].y * MAP_WIDTH + map->ent[i].x] >= 3)) { // if we can see the entity, that means we can see what direction it is currently looking at. // the next tile in that direction will be redrawn with a cyan color. uint8_t vx = map->ent[i].x + movediff[map->ent[i].aidata->viewdir][0]; uint8_t vy = map->ent[i].y + movediff[map->ent[i].aidata->viewdir][1]; if (vtile(vx,vy)) { chtype t = mvwinch(mapwindow,vy,vx); // we strip the original character of all previous attributes, // except the "alternate charset" one. chtype fcol = 0; switch(map->ent[i].aidata->task) { case AIT_WORKING: fcol = CP_BLUE; break; case AIT_PATROLLING: fcol = CP_CYAN; break; case AIT_CHECKING_OUT: case AIT_LOOKING_FOR: fcol = CP_YELLOW; break; case AIT_PLEASE_LEAVE: case AIT_PURSUING: case AIT_ATTACKING: fcol = CP_RED; break; case AIT_FLEEING: fcol = CP_MAGENTA; break; default: fcol = CP_GREEN; break; } mvwaddch(mapwindow,vy,vx,(t & (A_ALTCHARSET | A_CHARTEXT)) | fcol); } } } } for (int i= (MAX_ENTITIES - 1); i >= 0; i--) { if (map->ent[i].type == ET_NONE) continue; int ex = map->ent[i].x; int ey = map->ent[i].y; if ( (persp == NULL) || (map->ent[i].flags & EF_ALWAYSVISIBLE) || ((map->aidata.p_viewarr[ey * (MAP_WIDTH) + ex] >= 3) ) ) { int highlight = (hl_persp) && (&map->ent[i] == persp); mvwaddch(mapwindow,ey,ex,entchar(&map->ent[i]) | (highlight ? A_REVERSE : 0) ); } } wnoutrefresh(mapwindow); setsyx(y,x); curs_set(cs); doupdate(); return 0; }