int get_closest_side_road_node (entity_sides side, vec3d *pos, float error) { int loop, best_node = 0; float range, best_range; ASSERT (pos); ASSERT (road_node_positions); best_range = 99999999; for (loop = 0; loop < total_number_of_road_nodes; loop ++) { // if (road_nodes [loop].side_aware & side) { if (road_nodes [loop].number_of_links > 0) { range = get_approx_2d_range (&road_node_positions [loop], pos); if (range < best_range) { best_range = range; best_node = loop; if (range <= error) { return best_node; } } } } } #if LANDING_DEBUG >= 3 debug_log ("ROAD ROUTE: closest node to %f, %f is node %d at %f, %f", x, z, best_node, road_node_positions [best_node].x, road_node_positions [best_node].z); #endif return best_node; }
int debug_engage_targets_in_area (entity *group, vec3d *target_point, float radius, unsigned int target_type) { // // Engages all targets in area, regardless of side // int sx, sz, min_sector_x, max_sector_x, min_sector_z, max_sector_z; entity *new_task, *objective, *target_sector; entity_sides side; sector *raw; float range, temp_x, temp_z; vec3d *pos; new_task = NULL; temp_x = target_point->x - radius; temp_z = target_point->z - radius; get_x_sector (min_sector_x, temp_x); get_z_sector (min_sector_z, temp_z); temp_x = target_point->x + radius; temp_z = target_point->z + radius; get_x_sector (max_sector_x, temp_x); get_z_sector (max_sector_z, temp_z); min_sector_x = bound (min_sector_x, MIN_MAP_X_SECTOR, MAX_MAP_X_SECTOR); max_sector_x = bound (max_sector_x, MIN_MAP_X_SECTOR, MAX_MAP_X_SECTOR); min_sector_z = bound (min_sector_z, MIN_MAP_Z_SECTOR, MAX_MAP_Z_SECTOR); max_sector_z = bound (max_sector_z, MIN_MAP_Z_SECTOR, MAX_MAP_Z_SECTOR); side = (entity_sides) get_local_entity_int_value (group, INT_TYPE_SIDE); for (sz = min_sector_z; sz <= max_sector_z; sz ++) { for (sx = min_sector_x; sx <= max_sector_x; sx ++) { target_sector = get_local_raw_sector_entity (sx, sz); raw = (sector *) get_local_entity_data (target_sector); // // search for viable targets // objective = raw->sector_root.first_child; while (objective) { // // criteria for target is that it is a valid target, and not in your group // if (get_local_entity_int_value (objective, INT_TYPE_TARGET_TYPE) == target_type) { if (get_local_entity_int_value (objective, INT_TYPE_ALIVE)) { if ((!get_local_entity_int_value (objective, INT_TYPE_IDENTIFY_MOBILE)) || (get_local_entity_parent (objective, LIST_TYPE_MEMBER) != group)) { pos = get_local_entity_vec3d_ptr (objective, VEC3D_TYPE_POSITION); range = get_approx_2d_range (target_point, pos); if (range <= radius) { new_task = create_engage_task (group, objective, group, FALSE); if (new_task) { assign_task_to_group (group, new_task, TASK_ASSIGN_NO_MEMBERS); } } } } } objective = get_local_entity_child_succ (objective, LIST_TYPE_SECTOR); } } } if (assign_engage_tasks_to_group (group, TASK_ASSIGN_ALL_MEMBERS) != TASK_ASSIGN_ALL_MEMBERS) { return TRUE; } else { return FALSE; } }
int assess_group_task_locality_factor (entity *group_en, entity *task_en, float *return_distance) { entity *keysite, *member; vec3d *pos1, *pos2; float eta, distance, cruise_speed; // // locality // assess if group could get to end position quick enough, using first members cruise speed. // if (return_distance) { *return_distance = 0.0; } member = get_local_entity_first_child (group_en, LIST_TYPE_MEMBER); if (!member) { return FALSE; } pos1 = get_local_entity_vec3d_ptr (member, VEC3D_TYPE_POSITION); // get task start position, either keysite it is assigned to or the tasks start pos (NB. might actually be its end point) keysite = get_local_entity_parent (task_en, LIST_TYPE_UNASSIGNED_TASK); if ((keysite) && (get_local_entity_type (keysite) == ENTITY_TYPE_KEYSITE)) { pos2 = get_local_entity_vec3d_ptr (keysite, VEC3D_TYPE_POSITION); } else { pos2 = get_local_entity_vec3d_ptr (task_en, VEC3D_TYPE_START_POSITION); } distance = get_approx_2d_range (pos1, pos2); cruise_speed = get_local_entity_float_value (member, FLOAT_TYPE_CRUISE_VELOCITY); eta = distance / cruise_speed; #if DEBUG_MODULE debug_log ("GROUP: en %s (%d) task %s (%d), speed = %f, distance = %f. ETA = %f sec, expire time %f sec", get_local_entity_string (member, STRING_TYPE_FULL_NAME), get_local_entity_index (member), get_local_entity_string (task_en, STRING_TYPE_FULL_NAME), get_local_entity_index (task_en), cruise_speed, distance, eta, get_local_entity_float_value (task_en, FLOAT_TYPE_EXPIRE_TIMER)); #endif if (eta > get_local_entity_float_value (task_en, FLOAT_TYPE_EXPIRE_TIMER)) { #if DEBUG_MODULE debug_log ("GROUP: task %s (%d) group %s (%d), rejected, too far away.", get_local_entity_string (task_en, STRING_TYPE_FULL_NAME), get_local_entity_index (task_en), get_local_entity_string (group_en, STRING_TYPE_FULL_NAME), get_local_entity_index (group_en)); #endif return FALSE; } if (return_distance) { *return_distance = distance; } return TRUE; }
entity *get_closest_waypoint (entity *task, vec3d *pos, float min_range, float *actual_range) { float best_range, range; vec3d *waypoint_pos; entity *closest_waypoint = NULL, *current_waypoint; best_range = 99999999; current_waypoint = get_local_entity_first_child (task, LIST_TYPE_WAYPOINT); while (current_waypoint) { waypoint_pos = get_local_entity_vec3d_ptr (current_waypoint, VEC3D_TYPE_POSITION); range = get_approx_2d_range (waypoint_pos, pos); if (actual_range) { *actual_range = range; } if (range <= min_range) { #if LANDING_DEBUG >= 2 debug_log ("AI_MISC: EARLY OUT: found waypoint %d (type %d) range %f", current_waypoint, entity_sub_type_waypoint_names [get_local_entity_int_value (current_waypoint, INT_TYPE_ENTITY_SUB_TYPE)], range); #endif return current_waypoint; } if (range < best_range) { best_range = range; closest_waypoint = current_waypoint; #if LANDING_DEBUG debug_log ("AI_MISC: found waypoint %d (type %d) range %f", current_keysite, entity_sub_type_waypoint_names [get_local_entity_int_value (current_waypoint, INT_TYPE_ENTITY_SUB_TYPE)], range); #endif } current_waypoint = get_local_entity_child_succ (current_waypoint, LIST_TYPE_WAYPOINT); } if ( closest_waypoint ) { waypoint_pos = get_local_entity_vec3d_ptr (closest_waypoint, VEC3D_TYPE_POSITION); best_range = get_2d_range (waypoint_pos, pos); } if (actual_range) { *actual_range = best_range; } return closest_waypoint; }
entity *get_closest_free_landing_site (entity_sub_types sub_type, entity *force, vec3d *pos, float min_range, float *actual_range, int sites_required) { int sites_available; float best_range, range; vec3d *landing_pos; entity *closest_landing = NULL, *current_keysite, *current_landing; best_range = 99999999; current_keysite = get_local_entity_first_child (force, LIST_TYPE_KEYSITE_FORCE); while (current_keysite) { if (get_local_entity_int_value (current_keysite, INT_TYPE_IN_USE)) { if (get_local_entity_int_value (current_keysite, INT_TYPE_KEYSITE_USABLE_STATE) == KEYSITE_STATE_USABLE) { current_landing = get_local_entity_first_child (current_keysite, LIST_TYPE_LANDING_SITE); while (current_landing) { if (get_local_entity_int_value (current_landing, INT_TYPE_ENTITY_SUB_TYPE) == sub_type) { sites_available = get_local_entity_int_value (current_landing, INT_TYPE_FREE_LANDING_SITES) - get_local_entity_int_value (current_landing, INT_TYPE_RESERVED_LANDING_SITES); if (sites_available >= sites_required) { landing_pos = get_local_entity_vec3d_ptr (current_landing, VEC3D_TYPE_POSITION); range = get_approx_2d_range (landing_pos, pos); #if DEBUG_MODULE debug_log ("AI_MISC: assessing keysite %s range %f", get_local_entity_string (current_keysite, STRING_TYPE_KEYSITE_NAME), range); #endif if (range <= min_range) { #if LANDING_DEBUG >= 2 debug_log ("AI_MISC: EARLY OUT: found key landing site type %d range %f, total %d, free %d, reserved %d", get_local_entity_int_value (current_landing, INT_TYPE_ENTITY_SUB_TYPE), range, get_local_entity_int_value (current_landing, INT_TYPE_TOTAL_LANDING_SITES), get_local_entity_int_value (current_landing, INT_TYPE_FREE_LANDING_SITES), get_local_entity_int_value (current_landing, INT_TYPE_RESERVED_LANDING_SITES)); #endif if (actual_range) { *actual_range = range; } return current_landing; } if (range < best_range) { best_range = range; closest_landing = current_landing; #if LANDING_DEBUG debug_log ("AI_MISC: found %s landing site type %d range %f, total %d, free %d, reserved %d", get_local_entity_string (current_keysite, STRING_TYPE_KEYSITE_NAME), get_local_entity_int_value (current_landing, INT_TYPE_ENTITY_SUB_TYPE), range, get_local_entity_int_value (current_landing, INT_TYPE_TOTAL_LANDING_SITES), get_local_entity_int_value (current_landing, INT_TYPE_FREE_LANDING_SITES), get_local_entity_int_value (current_landing, INT_TYPE_RESERVED_LANDING_SITES)); #endif } } } current_landing = get_local_entity_child_succ (current_landing, LIST_TYPE_LANDING_SITE); } } } current_keysite = get_local_entity_child_succ (current_keysite, LIST_TYPE_KEYSITE_FORCE); } if (actual_range) { *actual_range = best_range; } // // DEBUG // if (!closest_landing) { debug_log ("AI_MISC: FAILED GET CLOSEST LANDING_SITE !!!!!!!!!!!!"); debug_log (" searching for %d %s landing sites", sites_required, entity_sub_type_landing_names [sub_type]); current_keysite = get_local_entity_first_child (force, LIST_TYPE_KEYSITE_FORCE); while (current_keysite) { current_landing = get_local_entity_first_child (current_keysite, LIST_TYPE_LANDING_SITE); while (current_landing) { landing_pos = get_local_entity_vec3d_ptr (current_landing, VEC3D_TYPE_POSITION); range = get_approx_2d_range (landing_pos, pos); debug_log (" found %s landing site type %s use %d, range %f, total %d, free %d, reserved %d", get_local_entity_string (current_keysite, STRING_TYPE_KEYSITE_NAME), entity_sub_type_landing_names [get_local_entity_int_value (current_landing, INT_TYPE_ENTITY_SUB_TYPE)], get_local_entity_int_value (current_keysite, INT_TYPE_IN_USE), range, get_local_entity_int_value (current_landing, INT_TYPE_TOTAL_LANDING_SITES), get_local_entity_int_value (current_landing, INT_TYPE_FREE_LANDING_SITES), get_local_entity_int_value (current_landing, INT_TYPE_RESERVED_LANDING_SITES)); current_landing = get_local_entity_child_succ (current_landing, LIST_TYPE_LANDING_SITE); } current_keysite = get_local_entity_child_succ (current_keysite, LIST_TYPE_KEYSITE_FORCE); } { int sites_available; float best_range, range; vec3d *landing_pos; entity *closest_landing = NULL, *current_keysite, *current_landing; best_range = 99999999; current_keysite = get_local_entity_first_child (force, LIST_TYPE_KEYSITE_FORCE); while (current_keysite) { if (get_local_entity_int_value (current_keysite, INT_TYPE_IN_USE)) { if (get_local_entity_int_value (current_keysite, INT_TYPE_KEYSITE_USABLE_STATE) == KEYSITE_STATE_USABLE) { current_landing = get_local_entity_first_child (current_keysite, LIST_TYPE_LANDING_SITE); while (current_landing) { if (get_local_entity_int_value (current_landing, INT_TYPE_ENTITY_SUB_TYPE) == sub_type) { sites_available = get_local_entity_int_value (current_landing, INT_TYPE_FREE_LANDING_SITES) - get_local_entity_int_value (current_landing, INT_TYPE_RESERVED_LANDING_SITES); if (sites_available >= sites_required) { landing_pos = get_local_entity_vec3d_ptr (current_landing, VEC3D_TYPE_POSITION); range = get_approx_2d_range (landing_pos, pos); if (range <= min_range) { if (actual_range) { *actual_range = range; } debug_log ("AI_MISC: found keysite %s", get_local_entity_string (current_keysite, STRING_TYPE_KEYSITE_NAME)); } if (range < best_range) { best_range = range; closest_landing = current_landing; } } } current_landing = get_local_entity_child_succ (current_landing, LIST_TYPE_LANDING_SITE); } } } current_keysite = get_local_entity_child_succ (current_keysite, LIST_TYPE_KEYSITE_FORCE); } if (actual_range) { *actual_range = best_range; } //debug_log ("AI_MISC: found keysite %s", get_local_entity_string (current_keysite, STRING_TYPE_KEYSITE_NAME)); } } // // END // //ASSERT (closest_landing); return closest_landing; }
entity *get_closest_halfway_waypoint (entity *task, vec3d *pos, float min_range, float *actual_range) { float best_range, range; vec3d *waypoint_pos1, *waypoint_pos2, mid_pos; entity *closest_waypoint = NULL, *waypoint1, *waypoint2; best_range = 99999999; waypoint1 = get_local_entity_first_child (task, LIST_TYPE_WAYPOINT); waypoint2 = get_local_entity_child_succ (waypoint1, LIST_TYPE_WAYPOINT); while (waypoint2) { waypoint_pos1 = get_local_entity_vec3d_ptr (waypoint1, VEC3D_TYPE_POSITION); waypoint_pos2 = get_local_entity_vec3d_ptr (waypoint2, VEC3D_TYPE_POSITION); mid_pos.x = waypoint_pos1->x + ( ( waypoint_pos2->x - waypoint_pos1->x ) / 2 ); mid_pos.y = waypoint_pos1->y + ( ( waypoint_pos2->y - waypoint_pos1->y ) / 2 ); mid_pos.z = waypoint_pos1->z + ( ( waypoint_pos2->z - waypoint_pos1->z ) / 2 ); range = get_approx_2d_range (&mid_pos, pos); if (range < best_range) { best_range = range; closest_waypoint = waypoint1; } waypoint1 = waypoint2; waypoint2 = get_local_entity_child_succ (waypoint2, LIST_TYPE_WAYPOINT); } if ( closest_waypoint ) { waypoint1 = closest_waypoint; waypoint2 = get_local_entity_child_succ (waypoint1, LIST_TYPE_WAYPOINT); waypoint_pos1 = get_local_entity_vec3d_ptr (waypoint1, VEC3D_TYPE_POSITION); waypoint_pos2 = get_local_entity_vec3d_ptr (waypoint2, VEC3D_TYPE_POSITION); mid_pos.x = waypoint_pos1->x + ( ( waypoint_pos2->x - waypoint_pos1->x ) / 2 ); mid_pos.y = waypoint_pos1->y + ( ( waypoint_pos2->y - waypoint_pos1->y ) / 2 ); mid_pos.z = waypoint_pos1->z + ( ( waypoint_pos2->z - waypoint_pos1->z ) / 2 ); best_range = get_2d_range (&mid_pos, pos); } if (actual_range) { *actual_range = best_range; } return ( closest_waypoint ); }