/* TODO networking */ void update_game(TCOD_map_t map) { if (w_key) if (TCOD_map_is_walkable(map, x, y-1)) y -= vy * TCOD_sys_get_last_frame_length(); if (a_key) if (TCOD_map_is_walkable(map, x-1, y)) x -= vx * TCOD_sys_get_last_frame_length(); if (s_key) if (TCOD_map_is_walkable(map, x, y+1)) y += vy * TCOD_sys_get_last_frame_length(); if (d_key) if (TCOD_map_is_walkable(map, x+1, y)) x += vx * TCOD_sys_get_last_frame_length(); }
light *getNearestLight(int x, int y) { light *lght = DYNAMIC_LIGHTS; while (lght != NULL) { if (lght->lightMap && TCOD_map_is_walkable(lght->lightMap, x, y)) { return lght; } lght = lght->next; } return NULL; }
int isPositionLit(int x, int y) { light *lght = DYNAMIC_LIGHTS; while (lght != NULL) { if (lght->lightMap && TCOD_map_is_walkable(lght->lightMap, x, y)) { return 1; } lght = lght->next; } return 0; }
float _actorPathCallback(int xFrom, int yFrom, int xTo, int yTo, void *userData) { character *actor = userData, *ptr = getActors(); if (!TCOD_map_is_walkable(actor->fov, xTo, yTo) || !TCOD_map_is_walkable(getLevelMap(), xTo, yTo)) { return 0; } while (ptr) { if (ptr == actor) { ptr = ptr->next; continue; } if (!isEnemy(getWorld(), actor->entityId, ptr->entityId) && (xTo == ptr->x && yTo == ptr->y)) { return 0; } ptr = ptr->next; } return 1; }
void uiInput() { int nx = 0, ny = 0; if (MENU_CALLBACK) { if (MENU_ITEM_INDEX) { if (isTCODCharPressed(TCODK_UP)) { MENU_ITEM_INDEX--; } } if (MENU_ITEM_INDEX < MENU_ITEM_COUNT - 1) { if (isTCODCharPressed(TCODK_DOWN)) { MENU_ITEM_INDEX++; } } if (isTCODCharPressed(TCODK_ENTER)) { MENU_CALLBACK(MENU_ITEM_INDEX, MENU_ITEMS[MENU_ITEM_INDEX]); MENU_CALLBACK = NULL; MENU_ITEMS[0] = NULL; } } else if (CURSOR.map) { if (isTCODCharPressed(TCODK_DOWN)) { ny = 1; } else if (isTCODCharPressed(TCODK_UP)) { ny = -1; } else if (isTCODCharPressed(TCODK_LEFT)) { nx = -1; } else if (isTCODCharPressed(TCODK_RIGHT)) { nx = 1; } else if (isTCODCharPressed(TCODK_ENTER)) { CURSOR.callback(CURSOR.x, CURSOR.y); CURSOR.map = NULL; } if ((nx || ny) && TCOD_map_is_walkable(CURSOR.map, CURSOR.x + nx, CURSOR.y + ny)) { CURSOR.x += nx; CURSOR.y += ny; } } }
/* Returns whether or not a player can walk on a tile */ bool is_walkable(map_t *m, int x, int y) { return(TCOD_map_is_walkable(m->fov, x, y) && (x >= 0) && (x < m->width) && (y >= 0) && (y < m->height)); }
/* compute a Dijkstra grid */ void TCOD_dijkstra_compute (TCOD_dijkstra_t dijkstra, int root_x, int root_y) { dijkstra_t * data = (dijkstra_t*)dijkstra; /* map size data */ unsigned int mx = data->width; unsigned int my = data->height; unsigned int mmax = data->nodes_max; /* encode the root coords in one integer */ unsigned int root = (root_y * mx) + root_x; /* some stuff to walk through the nodes table */ unsigned int index = 0; /* the index of the first node in queue */ unsigned int last_index = 1; /* total nb of registered queue indices */ unsigned int * nodes = data->nodes; /* table of nodes to which the indices above apply */ /* ok, here's the order of node processing: W, S, E, N, NW, NE, SE, SW */ static int dx[8] = { -1, 0, 1, 0, -1, 1, 1, -1 }; static int dy[8] = { 0, -1, 0, 1, -1, -1, 1, 1 }; /* and distances for each index */ int dd[8] = { 100, 100, 100, 100, data->diagonal_cost, data->diagonal_cost, data->diagonal_cost, data->diagonal_cost }; /* if diagonal_cost is 0, disallow diagonal moves */ int imax = (data->diagonal_cost == 0 ? 4 : 8); /* aight, now set the distances table and set everything to infinity */ unsigned int * distances = data->distances; TCOD_IFNOT(data != NULL) return; TCOD_IFNOT((unsigned)root_x < (unsigned)mx && (unsigned)root_y < (unsigned)my) return; memset(distances,0xFFFFFFFF,mmax*sizeof(int)); /* data for root node is known... */ distances[root] = 0; nodes[index] = root; /*set starting note to root */ /* and the loop */ do { /* coordinates of currently processed node */ unsigned int x = nodes[index] % mx; unsigned int y = nodes[index] / mx; /* check adjacent nodes */ int i; for(i=0;i<imax;i++) { /* checked node's coordinates */ unsigned int tx = x + dx[i]; unsigned int ty = y + dy[i]; if ((unsigned)tx < (unsigned)mx && (unsigned)ty < (unsigned)my ) { /* otherwise, calculate distance, ... */ unsigned int dt = distances[nodes[index]], new_node; float userDist = 0.0f; if ( data->map ) dt += dd[i]; else { /* distance given by the user callback */ userDist=data->func(x,y,tx,ty,data->user_data); dt += (unsigned int)(userDist*dd[i]); } /* ..., encode coordinates, ... */ new_node = (ty * mx) + tx; /* and check if the node's eligible for queuing */ if (distances[new_node] > dt) { unsigned int j; /* if not walkable, don't process it */ if (data->map && !TCOD_map_is_walkable(data->map,tx,ty)) continue; else if ( data->func && userDist <= 0.0f ) continue; distances[new_node] = dt; /* set processed node's distance */ /* place the processed node in the queue before the last queued node with greater distance */ j = last_index - 1; while (distances[nodes[j]] >= distances[new_node]) { /* this ensures that if the node has been queued previously, but with a higher distance, it's removed */ if (nodes[j] == new_node) { int k = j; while ((unsigned)k <= last_index) { nodes[k] = nodes[k+1]; k++; } last_index--; } else nodes[j+1] = nodes[j]; j--; } last_index++; /* increase total indices count */ nodes[j+1] = new_node; /* and finally put the node where it belongs in the queue */ } } } } while (mmax > ++index); }
/* check if a cell is walkable (from the pathfinder point of view) */ static float TCOD_path_walk_cost(TCOD_path_data_t *path, int xFrom, int yFrom, int xTo, int yTo) { if ( path->map ) return TCOD_map_is_walkable(path->map,xTo,yTo) ? 1.0f : 0.0f; return path->func(xFrom,yFrom,xTo,yTo,path->user_data); }
bool TCODMap::isWalkable(int x, int y) const { return TCOD_map_is_walkable(data,x,y) != 0; }
void _drawDynamicLight(light *lght) { int x, y, penalty, r_tint, g_tint, b_tint; float distMod, alpha; character *player = getPlayer(); TCOD_map_t levelMap = getLevelMap(); if (!lght->lightMap) { return; } TCOD_map_clear(lght->lightMap, 0, 0); if (!lght->fuel) { return; } for (y = lght->y - 32; y < lght->y + 32; y++) { for (x = lght->x - 32; x < lght->x + 32; x++) { if (x < 0 || x >= WINDOW_WIDTH || y < 0 || y >= WINDOW_HEIGHT) { continue; } if (TCOD_map_is_in_fov(lght->fov, x, y)) { if (lght->fuel < lght->size) { penalty = lght->size - lght->fuel; } else { penalty = 0; } distMod = lght->size - (distanceFloat(lght->x, lght->y, x, y) + penalty); if (distMod <= 0) { TCOD_map_set_properties(lght->lightMap, x, y, 0, 0); } else { TCOD_map_set_properties(lght->lightMap, x, y, 1, 1); } if (isPositionWalkable(x, y)) { distMod -= getRandomFloat(0, lght->flickerRate); } if (distMod < 0) { distMod = 0; } else if (distMod > lght->size / 2) { distMod = lght->size / 2; } alpha = (distMod / (float) lght->size); alpha *= lght->sizeMod; if (lght->noTint) { r_tint = 1; g_tint = 1; b_tint = 1; } else { if (!TCOD_map_is_walkable(levelMap, x, y)) { r_tint = 55 + RED_SHIFT; g_tint = 55; b_tint = 55; if (alpha > .45) { alpha = .45; } } else { r_tint = lght->r_tint + RED_SHIFT; g_tint = lght->g_tint; b_tint = lght->b_tint; alpha = clipFloat(alpha, 0, lght->brightness); } } if (!player || TCOD_map_is_in_fov(player->fov, x, y)) { drawCharBackEx(DYNAMIC_LIGHT_CONSOLE, x, y, TCOD_color_RGB(r_tint, g_tint, b_tint), TCOD_BKGND_ADDALPHA(alpha)); } } } } }