void respond_to_player_task_assign_request (entity *pilot, entity *task, entity *mobile) { entity *group; ASSERT (pilot); ASSERT (mobile); ASSERT (task); ASSERT (get_comms_model () == COMMS_MODEL_SERVER); group = get_local_entity_parent (mobile, LIST_TYPE_MEMBER); if ((!get_local_entity_first_child (task, LIST_TYPE_GUIDE)) && (!get_local_group_primary_task (group))) { if (assign_primary_task_to_group (group, task)) { transmit_entity_comms_message (ENTITY_COMMS_TASK_ASSIGN_RESULT, pilot, task, mobile); return; } } else { if (get_local_group_primary_task (group)) { transmit_entity_comms_message (ENTITY_COMMS_TASK_ASSIGN_RESULT, pilot, task, mobile); return; } } transmit_entity_comms_message (ENTITY_COMMS_TASK_ASSIGN_RESULT, pilot, NULL, NULL); }
entity *free_flight_auto_assign_gunship (void) { vec3d *pos; entity *force, *new_task, *group, *member, **gunship_list, *en; entity_sub_types sub_type; int c, index, count; // // Auto assign a helicopter for free flight // ASSERT (get_comms_model () == COMMS_MODEL_SERVER); ASSERT (get_game_type () == GAME_TYPE_FREE_FLIGHT); ASSERT (get_pilot_entity ()); if (get_gunship_entity ()) { return NULL; } force = get_local_entity_parent (get_pilot_entity (), LIST_TYPE_PILOT); ASSERT (force); // // Count up candidates // count = 0; en = get_local_entity_first_child (force, LIST_TYPE_AIR_REGISTRY); while (en) { if (get_local_entity_int_value (en, INT_TYPE_GROUP_MODE) == GROUP_MODE_IDLE) { member = get_local_entity_first_child (en, LIST_TYPE_MEMBER); while (member) { sub_type = get_local_entity_int_value (member, INT_TYPE_ENTITY_SUB_TYPE); if ((sub_type == ENTITY_SUB_TYPE_AIRCRAFT_RAH66_COMANCHE) || (sub_type == ENTITY_SUB_TYPE_AIRCRAFT_KA52_HOKUM_B)) { if (get_local_entity_suitable_for_player (member, get_pilot_entity ())) { count ++; } } member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER); } } en = get_local_entity_child_succ (en, LIST_TYPE_AIR_REGISTRY); } if (count == 0) { return NULL; } // // Create list of candidates // gunship_list = safe_malloc (sizeof (entity *) * count); count = 0; en = get_local_entity_first_child (force, LIST_TYPE_AIR_REGISTRY); while (en) { if (get_local_entity_int_value (en, INT_TYPE_GROUP_MODE) == GROUP_MODE_IDLE) { member = get_local_entity_first_child (en, LIST_TYPE_MEMBER); while (member) { sub_type = get_local_entity_int_value (member, INT_TYPE_ENTITY_SUB_TYPE); if ((sub_type == ENTITY_SUB_TYPE_AIRCRAFT_RAH66_COMANCHE) || (sub_type == ENTITY_SUB_TYPE_AIRCRAFT_KA52_HOKUM_B)) { if (get_local_entity_suitable_for_player (member, get_pilot_entity ())) { gunship_list [count] = member; count ++; } } member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER); } } en = get_local_entity_child_succ (en, LIST_TYPE_AIR_REGISTRY); } // // Pick one... // ASSERT (count > 0); index = rand16 () % count; for (c = 0; c < count; c ++) { en = gunship_list [index]; group = get_local_entity_parent (en, LIST_TYPE_MEMBER); pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); new_task = create_user_task (en, ENTITY_SUB_TYPE_TASK_FREE_FLIGHT, pos, NULL, NULL); set_assign_create_waypoint_route (FALSE); if (assign_primary_task_to_group (group, new_task)) { set_gunship_entity (en); set_view_mode (VIEW_MODE_COCKPIT_PANEL_LEVEL_AHEAD); safe_free (gunship_list); initialise_free_flight_screen_map_page_objects (); return en; } else { debug_log ("FLIGHT: can't assign user to Created task"); destroy_client_server_entity (new_task); } set_assign_create_waypoint_route (TRUE); index ++; if (index == count) { index = 0; } } safe_free (gunship_list); return NULL; }
int create_group_emergency_transfer_task (entity *en) { entity *landing, *new_keysite, *new_task; int side, landing_type, sites_required; vec3d *pos; ASSERT (en); ASSERT (get_comms_model () == COMMS_MODEL_SERVER); side = get_local_entity_int_value (en, INT_TYPE_SIDE); pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); group_terminate_all_tasks (en); sites_required = get_local_group_member_count (en); landing_type = group_database [get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE)].default_landing_type; landing = get_closest_free_landing_site (landing_type, get_local_force_entity (side), pos, 0.0, NULL, sites_required); if (landing) { // // Found new keysite // new_keysite = get_local_entity_parent (landing, LIST_TYPE_LANDING_SITE); if (landing_type == ENTITY_SUB_TYPE_LANDING_HELICOPTER) { new_task = create_transfer_task (side, ENTITY_SUB_TYPE_TASK_TRANSFER_HELICOPTER, 10.0, new_keysite, new_keysite); } else { new_task = create_transfer_task (side, ENTITY_SUB_TYPE_TASK_TRANSFER_FIXED_WING, 10.0, new_keysite, new_keysite); } ASSERT (new_task); if (!assign_primary_task_to_group (en, new_task)) { // // Failed to assign transfer task // ai_log ("(TRANSFER) Failed to assign Emergency Transfer to %s", get_local_entity_string (en, STRING_TYPE_FULL_NAME)); group_kill_all_members (en); return FALSE; } else { ai_log ("(TRANSFER) Successfully assigned Emergency Transfer to %s", get_local_entity_string (en, STRING_TYPE_FULL_NAME)); return TRUE; } } else { // // Failed to find alternate keysite // ai_log ("(TRANSFER) Failed to find Emergency Transfer keysite for %s", get_local_entity_string (en, STRING_TYPE_FULL_NAME)); group_kill_all_members (en); return FALSE; } }
void assign_keysite_tasks (entity *keysite, task_category_types category) { entity *task, *group, *force, **task_list; float *sort_order; int loop, task_type, task_count, assign_count, group_type, keysite_type, non_critical_task_count; static int idle_group_count [NUM_ENTITY_SUB_TYPE_GROUPS]; ASSERT (keysite); ASSERT (get_comms_model () == COMMS_MODEL_SERVER); task = get_local_entity_first_child (keysite, LIST_TYPE_UNASSIGNED_TASK); if (!task) { return; } keysite_type = get_local_entity_int_value (keysite, INT_TYPE_ENTITY_SUB_TYPE); force = get_local_entity_parent (keysite, LIST_TYPE_KEYSITE_FORCE); ASSERT (force); // // Count tasks at keysite // task_count = 0; task = get_local_entity_first_child (keysite, LIST_TYPE_UNASSIGNED_TASK); while (task) { if (get_local_entity_int_value (task, INT_TYPE_TASK_CATEGORY) == category) { task_count ++; } task = get_local_entity_child_succ (task, LIST_TYPE_UNASSIGNED_TASK); } if (task_count == 0) { return; } // // Count up number of idle groups across the map (air registry only) // memset (idle_group_count, 0, sizeof (int) * NUM_ENTITY_SUB_TYPE_GROUPS); group = get_local_entity_first_child (force, LIST_TYPE_AIR_REGISTRY); while (group) { if (get_local_entity_int_value (group, INT_TYPE_GROUP_MODE) == GROUP_MODE_IDLE) { group_type = get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE); idle_group_count [group_type] ++; } group = get_local_entity_child_succ (group, LIST_TYPE_AIR_REGISTRY); } // // Sort tasks // ASSERT (task_count > 0); task_list = ( entity * * ) malloc_fast_mem (sizeof (entity *) * task_count); sort_order = ( float * ) malloc_fast_mem (sizeof (float) * task_count); task_count = 0; task = get_local_entity_first_child (keysite, LIST_TYPE_UNASSIGNED_TASK); while (task) { if (get_local_entity_int_value (task, INT_TYPE_TASK_CATEGORY) == category) { task_list [task_count] = task; sort_order [task_count] = get_local_entity_float_value (task, FLOAT_TYPE_TASK_PRIORITY); if (get_local_entity_int_value (task, INT_TYPE_CRITICAL_TASK)) { sort_order [task_count] *= 2.0; } task_count ++; } task = get_local_entity_child_succ (task, LIST_TYPE_UNASSIGNED_TASK); } quicksort_entity_list (task_list, task_count, sort_order); // // Assign tasks // assign_count = max (keysite_database [keysite_type].assign_task_count, 1u); non_critical_task_count = keysite_database [keysite_type].reserve_task_count; for (loop = 0; loop < task_count; loop ++) { if (assign_count == 0) { break; } task = task_list [loop]; // // Check for player lock // if (get_local_entity_parent (task, LIST_TYPE_PILOT_LOCK)) { continue; } // // Reserve non-critical tasks for player // if (!get_local_entity_int_value (task, INT_TYPE_CRITICAL_TASK)) { if (get_local_entity_float_value (task, FLOAT_TYPE_EXPIRE_TIMER) > KEYSITE_TASK_ASSIGN_TIMER) { if (non_critical_task_count > 0) { non_critical_task_count --; continue; } } } task_type = get_local_entity_int_value (task, INT_TYPE_ENTITY_SUB_TYPE); group = get_suitable_registered_group (task, idle_group_count); if (group) { if (assign_primary_task_to_group (group, task)) { ai_log ("ASSIGN: (%d/%d) Assigned group %s (%d) to task %s (%d) from keysite %s (%s)", assign_count, keysite_database [keysite_type].assign_task_count, entity_sub_type_group_names [get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE)], get_local_entity_index (group), entity_sub_type_task_names [task_type], get_local_entity_index (task), get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME), entity_side_short_names [get_local_entity_int_value (keysite, INT_TYPE_SIDE)]); // // Only Assign n tasks per keysite // assign_count --; } else { #if DEBUG_MODULE debug_log ("ASSIGN: not assigning group %s (%d) to task %s (%d) from keysite %s", entity_sub_type_group_names [get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE)], get_local_entity_index (group), entity_sub_type_task_names [task_type], get_local_entity_index (task), get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME)); #endif } } } free_mem (task_list); free_mem (sort_order); }