/* Fear Pathing generation utility. (c) 2005 Father Nitwit */ #include "../common/types.h" #include "../zone/map.h" #include "../common/rdtsc.h" #include "quadtree.h" #include "apathing.h" #include #include #include #include #include bool load_paths_from_db(MYSQL *m, Map *map, const char *zone, list &db_paths, list &end_points) { char query[512]; sprintf(query, "SELECT x,y,z,gridid FROM grid_entries,zone " "WHERE zone.zoneidnumber=zoneid AND short_name='%s' " "ORDER BY gridid,number", zone); if(mysql_query(m, query) != 0) { printf("Unable to query: %s\n", mysql_error(m)); return(false); } MYSQL_RES *res = mysql_store_result(m); if(res == NULL) { printf("Unable to store res: %s\n", mysql_error(m)); return(false); } MYSQL_ROW row; PathNode *cur = NULL, *last = NULL, *first = NULL; PathGraph *g = NULL; int cur_g = -1,last_g = -1; // int lid = 0; while((row = mysql_fetch_row(res))) { last = cur; cur = new PathNode; // cur->load_id = lid++; cur->x = atof(row[0]); cur->y = atof(row[1]); cur->z = atof(row[2]); cur_g = Strings::ToInt(row[3]); if(cur_g != last_g) { if(g != NULL) { //if we have a first and last node for this path //and they are not the same node, try to connect them. if(first != NULL && last != NULL && first != last && last->Dist2(first) < ENDPOINT_CONNECT_MAX_DISTANCE*ENDPOINT_CONNECT_MAX_DISTANCE) { if(CheckLOS(map, last, first)) g->add_edge(last, first); } #ifdef LINK_PATH_ENDPOINTS if(first != last && last != NULL) end_points.push_back(last); #endif db_paths.push_back(g); } g = new PathGraph(); first = cur; last_g = cur_g; last = NULL; } g->nodes.push_back(cur); #ifdef LINK_PATH_ENDPOINTS //this is a begining point if(last == NULL) end_points.push_back(cur); #endif if(last != NULL) { #ifdef SPLIT_INVALID_PATHS if(CheckLOS(map, last, cur)) { g->edges.push_back(new PathEdge(last, cur)); } else { //no LOS, split the path into two load_split_paths++; last_g = -1; //tell this thing to start over } #else g->edges.push_back(new PathEdge(last, cur)); #endif } } //handle the last active path if(g != NULL) { if(first != NULL && cur->Dist2(first) < ENDPOINT_CONNECT_MAX_DISTANCE*ENDPOINT_CONNECT_MAX_DISTANCE) { if(CheckLOS(map, cur, first)) g->add_edge(cur, first); } db_paths.push_back(g); } mysql_free_result(res); return(true); } bool load_spawns_from_db(MYSQL *m, const char *zone, list &db_spawns) { char query[512]; sprintf(query, "SELECT x,y,z FROM spawn2 " "WHERE zone='%s'", zone); if(mysql_query(m, query) != 0) { printf("Unable to query: %s\n", mysql_error(m)); return(false); } MYSQL_RES *res = mysql_store_result(m); if(res == NULL) { printf("Unable to store res: %s\n", mysql_error(m)); return(false); } MYSQL_ROW row; PathNode *cur = NULL; while((row = mysql_fetch_row(res))) { cur = new PathNode; cur->x = atof(row[0]); cur->y = atof(row[1]); cur->z = atof(row[2]); db_spawns.push_back(cur); } mysql_free_result(res); return(true); } bool load_doors_from_db(MYSQL *m, const char *zone, list &db_spawns) { char query[512]; sprintf(query, "SELECT pos_x,pos_y,pos_z FROM doors " "WHERE zone='%s'", zone); if(mysql_query(m, query) != 0) { printf("Unable to query: %s\n", mysql_error(m)); return(false); } MYSQL_RES *res = mysql_store_result(m); if(res == NULL) { printf("Unable to store res: %s\n", mysql_error(m)); return(false); } MYSQL_ROW row; PathNode *cur = NULL; while((row = mysql_fetch_row(res))) { cur = new PathNode; cur->x = atof(row[0]); cur->y = atof(row[1]); cur->z = atof(row[2]); //TODO: it would be nice if we could get to the middle of these //doors, not the edge of them which I assume these points are db_spawns.push_back(cur); } mysql_free_result(res); return(true); } bool load_hints_from_db(MYSQL *m, const char *zone, list &db_spawns) { char query[512]; sprintf(query, "SELECT x,y,z,forced,disjoint FROM fear_hints " "WHERE zone='%s'", zone); if(mysql_query(m, query) != 0) { printf("Unable to query: %s\n", mysql_error(m)); return(false); } MYSQL_RES *res = mysql_store_result(m); if(res == NULL) { printf("Unable to store res: %s\n", mysql_error(m)); return(false); } MYSQL_ROW row; PathNode *cur = NULL; while((row = mysql_fetch_row(res))) { cur = new PathNode; cur->x = atof(row[0]); cur->y = atof(row[1]); cur->z = atof(row[2]); cur->forced = Strings::ToInt(row[3])?true:false; cur->disjoint = Strings::ToInt(row[4])?true:false; db_spawns.push_back(cur); } mysql_free_result(res); return(true); } bool load_settings_from_db(MYSQL *m, const char *zone) { char query[512]; sprintf(query, "SELECT use_doors, min_fix_z, max_fear_distance, image_scale, split_invalid_paths," " link_path_endpoints, end_distance, split_long_min, split_long_step, same_dist, node_combine_dist," " grid_combine_dist, close_all_los, cross_count, cross_min_length, cross_max_z_diff, cross_combine_dist," " second_link_dist, link_max_dist, link_count" " FROM fear_settings" " WHERE zone='%s'", zone); if(mysql_query(m, query) != 0) { // printf("Unable to query: %s\n", mysql_error(m)); return(false); } MYSQL_RES *res = mysql_store_result(m); if(res == NULL) { // printf("Unable to store res: %s\n", mysql_error(m)); return(false); } MYSQL_ROW row; int r = 0; if((row = mysql_fetch_row(res))) { INCLUDE_DOORS = Strings::ToInt(row[r++])?true:false; MIN_FIX_Z = atof(row[r++]); FEAR_MAXIMUM_DISTANCE = atof(row[r++]); IMAGE_SCALE = Strings::ToInt(row[r++]); SPLIT_INVALID_PATHS = Strings::ToInt(row[r++])?true:false; LINK_PATH_ENDPOINTS = Strings::ToInt(row[r++])?true:false; ENDPOINT_CONNECT_MAX_DISTANCE = atof(row[r++]); SPLIT_LINE_LENGTH = atof(row[r++]); SPLIT_LINE_INTERVAL = atof(row[r++]); CLOSE_ENOUGH = atof(row[r++]); CLOSE_ENOUGH_COMBINE = atof(row[r++]); MERGE_MIN_SECOND_DIST = atof(row[r++]); COMBINE_CHECK_ALL_LOS = Strings::ToInt(row[r++])?true:false; CROSS_REDUCE_COUNT = Strings::ToInt(row[r++]); CROSS_MIN_LENGTH = atof(row[r++]); CROSS_MAX_Z_DIFF = atof(row[r++]); CLOSE_ENOUGH_CROSS = atof(row[r++]); SPAWN_MIN_SECOND_DIST = atof(row[r++]); MAX_LINK_SPAWN_DIST = atof(row[r++]); int sc = Strings::ToInt(row[r++]); SPAWN_LINK_TWICE = sc >= 2?true:false; SPAWN_LINK_THRICE = sc >= 3?true:false; mysql_free_result(res); return(true); } mysql_free_result(res); return(false); }