void send_pilot_joined_message (entity *en) { int player_count; char text [200]; // // Client now joined in..... send system message to other players // player_count = get_session_pilot_count (); if (player_count == 1) { sprintf (text, "%s %s - 1 %s", get_local_entity_string (en, STRING_TYPE_PILOTS_NAME), get_trans ("joined"), get_trans ("player connected")); } else { sprintf (text, "%s %s - %d %s", get_local_entity_string (en, STRING_TYPE_PILOTS_NAME), get_trans ("joined"), player_count, get_trans ("players connected")); } send_text_message (en, NULL, MESSAGE_TEXT_SYSTEM_NEW_PILOT, text); server_log (text); // Jabberwock Server log }
void set_pilot_entity (entity *en) { comms_data_flow_types store_data_flow; if (en) { debug_log ("PILOT: Setting pilot_entity to %s", get_local_entity_string (en, STRING_TYPE_PILOTS_NAME)); ASSERT (pilot_entity == NULL); ASSERT (get_local_entity_type (en) == ENTITY_TYPE_PILOT); pilot_entity = en; // turn on NEXT button now Pilot entity has arrived if (get_comms_model () == COMMS_MODEL_CLIENT) { set_display_gunship_buttons (FALSE, "ENGAGE"); // turn on only the gunship_next button set_ui_object_drawable (gunship_screen_next_button, TRUE); } //-- Werewolf else { // If we're the server, remember our player name. This will be sent out in the heartbeat packets. net_set_hostname( get_local_entity_string (en, STRING_TYPE_PILOTS_NAME) ); } //-- Werewolf } else if (pilot_entity) { debug_log ("PILOT: Setting pilot_entity to NULL"); ASSERT (pilot_entity); // // Program MUST be in TX mode otherwise clients pilot will not be destroyed on the server // store_data_flow = get_comms_data_flow (); set_comms_data_flow (COMMS_DATA_FLOW_TX); destroy_client_server_entity (pilot_entity); set_comms_data_flow (store_data_flow); pilot_entity = NULL; } }
void dump_guide_stack (entity *group) { entity *guide, *task; debug_filtered_log ("GUIDE STACK:-"); debug_filtered_log ("-------------"); guide = get_local_entity_first_child (group, LIST_TYPE_GUIDE_STACK); while (guide) { task = get_local_entity_parent (guide, LIST_TYPE_GUIDE); ASSERT (task); debug_filtered_log ("Task %s (%d) - Guide (%d) - Valid Members %d", get_local_entity_string (task, STRING_TYPE_FULL_NAME), get_local_entity_index (task), get_local_entity_index (guide), get_local_entity_int_value (guide, INT_TYPE_VALID_GUIDE_MEMBERS)); guide = get_local_entity_child_succ (guide, LIST_TYPE_GUIDE_STACK); } }
void send_pilot_quit_message (entity *en) { int player_count; char text [200]; // // Client now joined in..... send system message to other players // player_count = get_session_pilot_count () - 1; if (player_count == 1) { sprintf (text, "%s %s - 1 %s", get_local_entity_string (en, STRING_TYPE_PILOTS_NAME), get_trans ("quit"), get_trans ("player connected")); } else { sprintf (text, "%s %s - %d %s", get_local_entity_string (en, STRING_TYPE_PILOTS_NAME), get_trans ("quit"), player_count, get_trans ("players connected")); } send_text_message (en, NULL, MESSAGE_TEXT_SYSTEM_NEW_PILOT, text); server_log (text); // Jabberwock Server log if ((command_line_pause_server) && (player_count <= 1)) // 040220 Jabberwock Pause server, changed to <=1 by Werewolf { force_pause_acceleration(); server_log ("Server paused"); } }
static void dedicated_server_build_player_list (void) { entity *force, *pilot; entity_sides side; rgb_colour col; ui_object_destroy_list_items (player_list); force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE); while (force) { pilot = get_local_entity_first_child (force, LIST_TYPE_PILOT); while (pilot) { if (pilot != get_pilot_entity ()) { side = (entity_sides) get_local_entity_int_value (pilot, INT_TYPE_SIDE); col.r = 255; col.g = 255; col.b = 255; col.a = 255; add_to_pop_up_list (get_local_entity_string (pilot, STRING_TYPE_PILOTS_NAME), player_list, NULL, 0, UI_FONT_ARIAL_16, col); } pilot = get_local_entity_child_succ (pilot, LIST_TYPE_PILOT); } force = get_local_entity_child_succ (force, LIST_TYPE_FORCE); } }
void reset_cinematic_camera (camera *raw) { entity *en; object_3d_instance *inst3d; int num_moving_cameras, num_static_cameras, attempts; // // pre-amble // ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; inst3d = get_local_entity_ptr_value (en, PTR_TYPE_INSTANCE_3D_OBJECT); // // select 3D camera // raw->cinematic_camera_index = OBJECT_3D_INVALID_CAMERA_INDEX; if (inst3d) { num_moving_cameras = get_number_of_3d_object_cameras (inst3d, OBJECT_3D_CAMERA_SCENIC_MOVING); num_static_cameras = get_number_of_3d_object_cameras (inst3d, OBJECT_3D_CAMERA_SCENIC_STATIC); if ((num_moving_cameras > 0) && (num_static_cameras > 0)) { if (frand1 () < 0.333) { raw->cinematic_camera_index = OBJECT_3D_CAMERA_SCENIC_MOVING; } else { raw->cinematic_camera_index = OBJECT_3D_CAMERA_SCENIC_STATIC; } } else if (num_moving_cameras > 0) { raw->cinematic_camera_index = OBJECT_3D_CAMERA_SCENIC_MOVING; } else if (num_static_cameras > 0) { raw->cinematic_camera_index = OBJECT_3D_CAMERA_SCENIC_STATIC; } } switch (raw->cinematic_camera_index) { //////////////////////////////////////// case OBJECT_3D_INVALID_CAMERA_INDEX: //////////////////////////////////////// { raw->cinematic_camera_depth = 0; raw->cinematic_camera_lifetime = (frand1 () * 2.0) + 2.0; raw->cinematic_camera_heading = rad (45.0) * ((float) (rand16 () % 8)); raw->cinematic_camera_pitch = rad (-45.0) * ((float) (rand16 () % 2)); #if DEBUG_MODULE debug_log ( "CINEMATIC CAMERA is INVALID (object = %s, moving cameras = %d, static cameras = %d, depth = %d, lifetime = %.2f, heading = %.2f, pitch = %.2f)", get_local_entity_string (en, STRING_TYPE_FULL_NAME), num_moving_cameras, num_static_cameras, raw->cinematic_camera_depth, raw->cinematic_camera_lifetime, deg (raw->cinematic_camera_heading), deg (raw->cinematic_camera_pitch) ); #endif break; } //////////////////////////////////////// case OBJECT_3D_CAMERA_SCENIC_MOVING: //////////////////////////////////////// { // // try and prevent using the same moving camera twice in succession // if (num_moving_cameras > 1) { attempts = 10; while (attempts--) { raw->cinematic_camera_depth = rand16 () % num_moving_cameras; if (raw->cinematic_camera_depth != raw->cinematic_camera_previous_moving_depth) { break; } } } else { raw->cinematic_camera_depth = 0; } raw->cinematic_camera_previous_moving_depth = raw->cinematic_camera_depth; raw->cinematic_camera_lifetime = get_object_3d_camera_lifetime (inst3d, raw->cinematic_camera_index, raw->cinematic_camera_depth); #if DEBUG_MODULE debug_log ( "CINEMATIC CAMERA is MOVING (object = %s, moving cameras = %d, static cameras = %d, depth = %d, lifetime = %.2f)", get_local_entity_string (en, STRING_TYPE_FULL_NAME), num_moving_cameras, num_static_cameras, raw->cinematic_camera_depth, raw->cinematic_camera_lifetime ); #endif ASSERT (raw->cinematic_camera_lifetime > 0.0); break; } //////////////////////////////////////// case OBJECT_3D_CAMERA_SCENIC_STATIC: //////////////////////////////////////// { // // try and prevent using the same static camera twice in succession // if (num_static_cameras > 1) { attempts = 10; while (attempts--) { raw->cinematic_camera_depth = rand16 () % num_static_cameras; if (raw->cinematic_camera_depth != raw->cinematic_camera_previous_static_depth) { break; } } } else { raw->cinematic_camera_depth = 0; } raw->cinematic_camera_previous_static_depth = raw->cinematic_camera_depth; raw->cinematic_camera_lifetime = (frand1 () * 2.0) + 2.0; #if DEBUG_MODULE debug_log ( "CINEMATIC CAMERA is STATIC (object = %s, moving cameras = %d, static cameras = %d, depth = %d, lifetime = %.2f)", get_local_entity_string (en, STRING_TYPE_FULL_NAME), num_moving_cameras, num_static_cameras, raw->cinematic_camera_depth, raw->cinematic_camera_lifetime ); #endif } } raw->cinematic_camera_timer = 0.0; // // motion vector // get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector); }
int set_local_division_name (entity *en, char *s) { int division_type, division_id; char extension [10], id_string [10]; entity *group; ASSERT (en); ASSERT (s); if (get_local_entity_type (en) == ENTITY_TYPE_DIVISION) { division_id = get_local_entity_int_value (en, INT_TYPE_DIVISION_ID); } else { ASSERT (get_local_entity_type (en) == ENTITY_TYPE_GROUP); division_id = 1; group = en; while (get_local_entity_child_succ (group, LIST_TYPE_DIVISION)) { division_id ++; group = get_local_entity_child_succ (group, LIST_TYPE_DIVISION); } if (!get_local_entity_int_value (en, INT_TYPE_AIRCRAFT_GROUP)) { set_local_entity_int_value (en, INT_TYPE_GROUP_CALLSIGN, division_id); } } sprintf (id_string, "%d", division_id); // // Specify extension after number (bloody English language) // get_number_extension (division_id, extension); strcat (id_string, extension); // // Store result // division_type = get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE); if (get_local_entity_type (en) == ENTITY_TYPE_DIVISION) { sprintf (s, division_database [division_type].full_name, id_string); } else { switch (group_database [division_type].platoon_id_type) { case PLATOON_ID_NONE: { sprintf (s, group_database [division_type].platoon_name); break; } case PLATOON_ID_NUMBER: { sprintf (s, group_database [division_type].platoon_name, id_string); break; } case PLATOON_ID_LETTER: { sprintf (s, group_database [division_type].platoon_name, ((division_id - 1) + 'A')); break; } case PLATOON_ID_CALLSIGN: { strcpy (s, get_local_entity_string (en, STRING_TYPE_GROUP_CALLSIGN)); break; } case PLATOON_ID_KEYSITE: { entity *keysite, *division; if (get_local_entity_type (en) == ENTITY_TYPE_GROUP) { division = get_local_entity_parent (en, LIST_TYPE_DIVISION); } else { division = en; } keysite = get_local_entity_parent (division, LIST_TYPE_DIVISION_HEADQUARTERS); ASSERT (keysite); sprintf (s, group_database [division_type].platoon_name, get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME)); break; } default: { debug_fatal ("Invalid Platoon Id Type %d", group_database [division_type].platoon_id_type); } } } return TRUE; }
void group_return_to_base (entity *en) { entity *wp, *guide, *last_wp, *best_wp, *obj_wp, *current_wp; vec3d *pos, *wp_pos, *last_pos, normal; float d, range, best_range; int s, sub_type; debug_log ("GROUP: sending group %s (%d) home... ", get_local_entity_string (en, STRING_TYPE_FULL_NAME), get_local_entity_index (en)); // // Abort all engage tasks // terminate_all_engage_tasks (en); // // Find group position // pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); // // find objective wp, and last wp position // obj_wp = NULL; guide = get_local_group_primary_guide (en); ASSERT (guide); current_wp = get_local_entity_parent (guide, LIST_TYPE_CURRENT_WAYPOINT); ASSERT (current_wp); wp = current_wp; while (get_local_entity_child_succ (wp, LIST_TYPE_WAYPOINT)) { wp = get_local_entity_child_succ (wp, LIST_TYPE_WAYPOINT); sub_type = get_local_entity_int_value (wp, INT_TYPE_ENTITY_SUB_TYPE); if (waypoint_database [sub_type].objective_waypoint) { obj_wp = wp; } } last_wp = wp; last_pos = get_local_entity_vec3d_ptr (last_wp, VEC3D_TYPE_POSITION); if (current_wp == last_wp) { return; } // // Check each waypoint after the objective waypoint (if obj_wp is NULL then the group has already passed the objective wp // or there isn't one) // if (!obj_wp) { obj_wp = current_wp; } // // Find vector of group to last wp // normal.x = last_pos->x - pos->x; normal.y = 0.0; normal.z = last_pos->z - pos->z; if (normalise_any_3d_vector (&normal) == 0.0) { return; } // // Test sign of last position // d = ((last_pos->x * normal.x) + (last_pos->z * normal.z)) - ((pos->x * normal.x) + (pos->z * normal.z)); s = sign (d); // // find closest waypoint heading back towards the last waypoint // wp = get_local_entity_child_succ (obj_wp, LIST_TYPE_WAYPOINT); ASSERT (wp); best_wp = last_wp; best_range = FLT_MAX; while (wp) { wp_pos = get_local_entity_vec3d_ptr (wp, VEC3D_TYPE_POSITION); d = ((wp_pos->x * normal.x) + (wp_pos->z * normal.z)) - ((pos->x * normal.x) + (pos->z * normal.z)); if (sign (d) == s) { range = get_2d_range (wp_pos, pos); if (range < best_range) { best_wp = wp; best_range = range; } } wp = get_local_entity_child_succ (wp, LIST_TYPE_WAYPOINT); } // // set guide to best waypoint // set_guide_new_waypoint (guide, best_wp); }
aircraft_fire_result aircraft_fire_weapon (entity *en, unsigned int check_flags) { entity *target; aircraft *raw; vec3d *target_pos, en_pos; int loal_mode = FALSE; ASSERT (en); raw = (aircraft *) get_local_entity_data (en); // // Fire suppressed // if (check_flags & AIRCRAFT_FIRE_SUPPRESSED) { if (get_local_entity_int_value (get_session_entity (), INT_TYPE_SUPPRESS_AI_FIRE)) { return AIRCRAFT_FIRE_SUPPRESSED; } } // // check weapon // if (check_flags & AIRCRAFT_FIRE_NO_WEAPON) { if (get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON) == ENTITY_SUB_TYPE_WEAPON_NO_WEAPON) { debug_log ("AC_WPN: Fire Weapon Error - NO WEAPON"); return AIRCRAFT_FIRE_NO_WEAPON; } } // // weapon system_ready // if (check_flags & AIRCRAFT_FIRE_WEAPON_SYSTEM_NOT_READY) { if (!get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON_SYSTEM_READY)) { debug_log ("AC_WPN: Fire Weapon Error - WEAPON SYSTEM NOT READY"); return AIRCRAFT_FIRE_WEAPON_SYSTEM_NOT_READY; } } // debug_log("%s: %d", get_sub_type_name(en), get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON)); // // find target // if (check_flags & AIRCRAFT_FIRE_NO_TARGET) { target = get_local_entity_parent (en, LIST_TYPE_TARGET); if (!target) { debug_log ("AC_WPN: Fire Weapon Error - NO TARGET"); return AIRCRAFT_FIRE_NO_TARGET; } } // // line of sight checks // if (check_flags & AIRCRAFT_FIRE_NO_LOS) { int criteria; if (get_local_entity_int_value (target, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI) { criteria = MOBILE_LOS_CHECK_ALL; } else { criteria = MOBILE_LOS_CHECK_COURSE_TERRAIN; } get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &en_pos); target_pos = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION); en_pos.y -= (get_local_entity_float_value (en, FLOAT_TYPE_CENTRE_OF_GRAVITY_TO_GROUND_DISTANCE) + 2.0); if (!check_position_line_of_sight (en, target, &en_pos, target_pos, (mobile_los_check_criteria) criteria)) { if (get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON) == ENTITY_SUB_TYPE_WEAPON_AGM114L_LONGBOW_HELLFIRE && get_2d_range(&en_pos, target_pos) > weapon_database[ENTITY_SUB_TYPE_WEAPON_AGM114L_LONGBOW_HELLFIRE].min_range_loal) { debug_log("AC_WPN: Switching to LOAL mode to fire at target without LOS ((Aircraft %s (%d), Target %s (%d))", get_local_entity_string (en, STRING_TYPE_FULL_NAME), get_local_entity_index (en), get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_index (target)); loal_mode = TRUE; } else { debug_log ("AC_WPN: Fire Weapon Error - NO LOS (Aircraft %s (%d), Target %s (%d))", get_local_entity_string (en, STRING_TYPE_FULL_NAME), get_local_entity_index (en), get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_index (target)); return AIRCRAFT_FIRE_NO_LOS; } } } // // Play Speech // play_aircraft_weapon_launched_speech (en, raw->selected_weapon); // // Fire weapon // set_local_entity_int_value(en, INT_TYPE_LOCK_ON_AFTER_LAUNCH, loal_mode); launch_client_server_weapon (en, raw->selected_weapon); return AIRCRAFT_FIRE_OK; }
void create_force_campaign_objectives (entity *force) { entity *keysite, *target_force, **list; int loop, count, side, target_side; float highest, *rating; ASSERT (get_comms_model () == COMMS_MODEL_SERVER); ASSERT (get_session_entity ()); ASSERT (force); side = get_local_entity_int_value (force, INT_TYPE_SIDE); // // count up potential objective keysites // count = 0; target_force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE); while (target_force) { if (target_force != force) { keysite = get_local_entity_first_child (target_force, LIST_TYPE_KEYSITE_FORCE); while (keysite) { if (get_local_entity_int_value (keysite, INT_TYPE_POTENTIAL_CAMPAIGN_OBJECTIVE)) { if (get_local_entity_int_value (keysite, INT_TYPE_IN_USE)) { count ++; } } keysite = get_local_entity_child_succ (keysite, LIST_TYPE_KEYSITE_FORCE); } } target_force = get_local_entity_child_succ (target_force, LIST_TYPE_FORCE); } if (count == 0) { debug_fatal ("SETUP: No potential campaign objectives for side %s", entity_side_short_names [side]); } // // construct the list and rate each keysite according to sector importance // list = malloc_heap_mem (sizeof (entity *) * count); rating = malloc_heap_mem (sizeof (float) * count); highest = 0.0; count = 0; target_force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE); while (target_force) { if (target_force != force) { target_side = get_local_entity_int_value (target_force, INT_TYPE_SIDE); keysite = get_local_entity_first_child (target_force, LIST_TYPE_KEYSITE_FORCE); while (keysite) { if (get_local_entity_int_value (keysite, INT_TYPE_POTENTIAL_CAMPAIGN_OBJECTIVE)) { if (get_local_entity_int_value (keysite, INT_TYPE_IN_USE)) { float actual_range; vec3d *pos; list [count] = keysite; pos = get_local_entity_vec3d_ptr (keysite, VEC3D_TYPE_POSITION); get_closest_keysite (NUM_ENTITY_SUB_TYPE_KEYSITES, target_side, pos, 1.0 * KILOMETRE, &actual_range, keysite); rating [count] = actual_range; highest = max (highest, rating [count]); count ++; } } keysite = get_local_entity_child_succ (keysite, LIST_TYPE_KEYSITE_FORCE); } } target_force = get_local_entity_child_succ (target_force, LIST_TYPE_FORCE); } // // Normalise ratings // if (highest == 0.0) { debug_fatal ("SETUP: No sector importance for side %s", entity_side_short_names [side]); } for (loop = 0; loop < count; loop ++) { rating [loop] = rating [loop] / highest; } // // obligatory random factor // for (loop = 0; loop < count; loop ++) { rating [loop] += frand1 (); } // // sort the list // quicksort_entity_list (list, count, rating); // // now find the best N targets and link them into the force // count = min (count, NUMBER_OF_CAMPAIGN_OBJECTIVES_PER_SIDE); for (loop = 0; loop < count; loop ++) { insert_local_entity_into_parents_child_list (list [loop], LIST_TYPE_CAMPAIGN_OBJECTIVE, force, NULL); debug_log ("Side %s Objective :- %s (%s)", entity_side_short_names [side], get_local_entity_string (list [loop], STRING_TYPE_KEYSITE_NAME), get_local_entity_string (list [loop], STRING_TYPE_FULL_NAME)); } free_mem (list); free_mem (rating); }
entity *push_task_onto_group_task_stack (entity *group, entity *task, unsigned int valid_members) { entity *task_parent, *guide; list_types list_type; #ifdef DEBUG unsigned int total_members, member_number; #endif ASSERT (get_comms_model () == COMMS_MODEL_SERVER); ASSERT (group); #ifdef DEBUG total_members = 0; // // Check not already on stack // guide = get_local_entity_first_child (task, LIST_TYPE_GUIDE); while (guide) { if (get_local_entity_parent (guide, LIST_TYPE_GUIDE_STACK) == group) { member_number = get_local_entity_int_value (guide, INT_TYPE_VALID_GUIDE_MEMBERS); total_members |= member_number; } guide = get_local_entity_child_succ (guide, LIST_TYPE_GUIDE); } // // A TASK may be on the stack many times, but any one member should not have the same task duplicated // e.g. ENGAGE tasks may be duplicated many times, but their guide "valid_members" should all be exclusive // if (valid_members & total_members) { debug_filtered_log ("Trying to assign task %s (%d) to group %s - members %d", get_local_entity_string (task, STRING_TYPE_FULL_NAME), get_local_entity_index (task), get_local_entity_string (group, STRING_TYPE_FULL_NAME), valid_members); debug_filtered_log (""); dump_guide_stack (group); debug_fatal ("ASSIGN: Task %s already on Group %s guide stack", get_local_entity_string (task, STRING_TYPE_FULL_NAME), get_local_entity_string (group, STRING_TYPE_FULL_NAME)); } #endif // // create guide entity for task // guide = create_client_server_guide_entity (task, NULL, valid_members); attach_group_to_guide_entity (group, guide); // // remove task and group from lists (must be done AFTER guide is created and attached) // list_type = get_local_task_list_type (task); if (list_type == LIST_TYPE_UNASSIGNED_TASK) { task_parent = get_local_entity_parent (task, list_type); if (task_parent) { delete_local_entity_from_parents_child_list (task, list_type); // // add task to assigned task list, if not already on it. // insert_local_entity_into_parents_child_list (task, LIST_TYPE_ASSIGNED_TASK, task_parent, NULL); transmit_entity_comms_message (ENTITY_COMMS_SWITCH_LIST, task, LIST_TYPE_UNASSIGNED_TASK, task_parent, LIST_TYPE_ASSIGNED_TASK); } } return guide; }
entity *create_engage_task (entity *group, entity *objective, entity *originator, int expire) { entity *force_en, *new_task; force *force_raw; vec3d *pos; entity_sides side; float expire_time; formation_types original_formation; ASSERT (group); ASSERT (get_local_entity_int_value (group, INT_TYPE_ENGAGE_ENEMY)); ASSERT (objective); #if DEBUG_MODULE debug_log ("ENGAGE: Trying to engage against %s (%d)", get_local_entity_string (objective, STRING_TYPE_FULL_NAME), get_local_entity_index (objective)); #endif ASSERT ((get_local_entity_int_value (objective, INT_TYPE_IDENTIFY_AIRCRAFT)) || (get_local_entity_int_value (objective, INT_TYPE_IDENTIFY_VEHICLE)) || (get_local_entity_int_value (objective, INT_TYPE_IDENTIFY_FIXED))); if (get_local_entity_int_value (get_session_entity (), INT_TYPE_SUPPRESS_AI_FIRE)) { return NULL; } force_en = get_local_force_entity ((entity_sides)get_local_entity_int_value (group, INT_TYPE_SIDE)); force_raw = (force*) get_local_entity_data (force_en); if (expire) { expire_time = (2.0 * ONE_MINUTE) + (frand1 () * ONE_MINUTE); } else { // // Max time for ENGAGE - stops attackers hanging around target area for too long (especially if they can NEVER get to their target) // expire_time = (15.0 * ONE_MINUTE) + (frand1 () * 5.0 * ONE_MINUTE); } new_task = NULL; // // Create engage task to expire in task_time seconds - debug // side = (entity_sides) get_local_entity_int_value (group, INT_TYPE_SIDE); pos = get_local_entity_vec3d_ptr (objective, VEC3D_TYPE_POSITION); ASSERT (get_local_entity_first_child (group, LIST_TYPE_MEMBER)); original_formation = FORMATION_ROW_LEFT; new_task = create_task (ENTITY_SUB_TYPE_TASK_ENGAGE, side, (movement_types) get_local_entity_int_value (group, INT_TYPE_MOVEMENT_TYPE), NULL, NULL, originator, TRUE, expire_time, 0.0, objective, task_database [ENTITY_SUB_TYPE_TASK_ENGAGE].task_priority, pos, objective, ENTITY_SUB_TYPE_WAYPOINT_TARGET, original_formation, &terminator_point, NULL, NUM_ENTITY_SUB_TYPE_WAYPOINTS, FORMATION_NONE); #if DEBUG_MODULE debug_log ("ENGAGE: Created Engage task against %s (%d)", get_local_entity_string (objective, STRING_TYPE_FULL_NAME), get_local_entity_index (objective)); #endif return new_task; }
int check_position_line_of_sight (entity *source, entity *target, vec3d *source_position, vec3d *target_position, mobile_los_check_criteria criteria) { entity *collision_en; vec3d increment, collision_point, normal, #if LINE_DEBUG_MODULE old_position, #endif check_position, direction; float target_range, collision_distance, number_of_terrain_checks, terrain_elevation; terrain_3d_point_data terrain_info; ASSERT (source); ASSERT (target); ASSERT (source_position); ASSERT (target_position); direction.x = target_position->x - source_position->x; direction.y = target_position->y - source_position->y; direction.z = target_position->z - source_position->z; target_range = sqrt ((direction.x * direction.x) + (direction.z * direction.z)); normalise_3d_vector (&direction); //////////////////////////////////////////////////////////////// // COARSE line of sight check with terrain //////////////////////////////////////////////////////////////// if (criteria & MOBILE_LOS_CHECK_COURSE_TERRAIN) { number_of_terrain_checks = target_range / LOS_COARSE_CHECK_DISTANCE; increment.x = direction.x * LOS_COARSE_CHECK_DISTANCE; increment.y = direction.y * LOS_COARSE_CHECK_DISTANCE; increment.z = direction.z * LOS_COARSE_CHECK_DISTANCE; check_position = *source_position; memset (&terrain_info, 0, sizeof (terrain_3d_point_data)); while (number_of_terrain_checks > 1.0) { #if LINE_DEBUG_MODULE old_position = check_position; #endif check_position.x += increment.x; check_position.y += increment.y; check_position.z += increment.z; get_3d_terrain_point_data (check_position.x, check_position.z, &terrain_info); terrain_elevation = get_3d_terrain_point_data_elevation (&terrain_info); if (terrain_elevation > check_position.y) { #if TEXT_DEBUG_MODULE debug_log ("MB_TGT: (%s -> %s) failed COURSE terrain LOS", get_local_entity_string (source, STRING_TYPE_FULL_NAME), get_local_entity_string (target, STRING_TYPE_FULL_NAME)); #endif return FALSE; } #if LINE_DEBUG_MODULE create_debug_3d_line (&old_position, &check_position, sys_col_yellow, 10.0); #endif number_of_terrain_checks --; } } //////////////////////////////////////////////////////////////// // SOURCE END FINE line of sight check with terrain //////////////////////////////////////////////////////////////// if (criteria & MOBILE_LOS_CHECK_SOURCE_END_TERRAIN) { number_of_terrain_checks = target_range / LOS_FINE_CHECK_DISTANCE_SOURCE_END; number_of_terrain_checks = min (number_of_terrain_checks, LOS_NUMBER_OF_FINE_CHECKS_SOURCE_END); increment.x = direction.x * LOS_FINE_CHECK_DISTANCE_SOURCE_END; increment.y = direction.y * LOS_FINE_CHECK_DISTANCE_SOURCE_END; increment.z = direction.z * LOS_FINE_CHECK_DISTANCE_SOURCE_END; check_position = *source_position; while (number_of_terrain_checks > 1.0) { #if LINE_DEBUG_MODULE old_position = check_position; #endif check_position.x += increment.x; check_position.y += increment.y; check_position.z += increment.z; get_3d_terrain_point_data (check_position.x, check_position.z, &terrain_info); terrain_elevation = get_3d_terrain_point_data_elevation (&terrain_info); if (terrain_elevation > check_position.y) { #if TEXT_DEBUG_MODULE debug_log ("MB_TGT: (%s -> %s) failed FINE terrain LOS (source end)", get_local_entity_string (source, STRING_TYPE_FULL_NAME), get_local_entity_string (target, STRING_TYPE_FULL_NAME)); #endif return FALSE; } #if LINE_DEBUG_MODULE create_debug_3d_line (&old_position, &check_position, sys_col_yellow, 10.0); #endif number_of_terrain_checks --; } } //////////////////////////////////////////////////////////////// // TARGET END FINE line of sight check with terrain //////////////////////////////////////////////////////////////// if (criteria & MOBILE_LOS_CHECK_TARGET_END_TERRAIN) { number_of_terrain_checks = target_range / LOS_FINE_CHECK_DISTANCE_TARGET_END; number_of_terrain_checks = min (number_of_terrain_checks, LOS_NUMBER_OF_FINE_CHECKS_TARGET_END); increment.x = direction.x * LOS_FINE_CHECK_DISTANCE_TARGET_END; increment.y = direction.y * LOS_FINE_CHECK_DISTANCE_TARGET_END; increment.z = direction.z * LOS_FINE_CHECK_DISTANCE_TARGET_END; check_position = *target_position; while (number_of_terrain_checks > 1.0) { #if LINE_DEBUG_MODULE old_position = check_position; #endif check_position.x -= increment.x; check_position.y -= increment.y; check_position.z -= increment.z; get_3d_terrain_point_data (check_position.x, check_position.z, &terrain_info); terrain_elevation = get_3d_terrain_point_data_elevation (&terrain_info); if (terrain_elevation > check_position.y) { #if TEXT_DEBUG_MODULE debug_log ("MB_TGT: (%s -> %s) failed FINE terrain LOS (target end)", get_local_entity_string (source, STRING_TYPE_FULL_NAME), get_local_entity_string (target, STRING_TYPE_FULL_NAME)); #endif return FALSE; } #if LINE_DEBUG_MODULE create_debug_3d_line (&old_position, &check_position, sys_col_yellow, 10.0); #endif number_of_terrain_checks --; } } //////////////////////////////////////////////////////////////// // SOURCE END line of sight check with objects //////////////////////////////////////////////////////////////// if (criteria & MOBILE_LOS_CHECK_SOURCE_END_OBJECTS) { check_position.x = source_position->x + (direction.x * LOS_OBJECT_CHECK_DISTANCE_TARGET_END); check_position.y = source_position->y + (direction.y * LOS_OBJECT_CHECK_DISTANCE_TARGET_END); check_position.z = source_position->z + (direction.z * LOS_OBJECT_CHECK_DISTANCE_TARGET_END); collision_en = get_line_of_sight_collision_entity ( source, target, source_position, &check_position, &collision_point, &normal ); if (collision_en) { #if TEXT_DEBUG_MODULE debug_log ("MB_TGT: (%s -> %s) failed OBJECT LOS with %s (source end)", get_local_entity_string (source, STRING_TYPE_FULL_NAME), get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_type_name (collision_en)); #endif return FALSE; } } //////////////////////////////////////////////////////////////// // TARGET END line of sight check with objects //////////////////////////////////////////////////////////////// if (criteria & MOBILE_LOS_CHECK_TARGET_END_OBJECTS) { check_position.x = target_position->x - (direction.x * LOS_OBJECT_CHECK_DISTANCE_TARGET_END); check_position.y = target_position->y - (direction.y * LOS_OBJECT_CHECK_DISTANCE_TARGET_END); check_position.z = target_position->z - (direction.z * LOS_OBJECT_CHECK_DISTANCE_TARGET_END); collision_en = get_line_of_sight_collision_entity ( source, target, target_position, &check_position, &collision_point, &normal ); if (collision_en) { collision_distance = get_sqr_3d_range (&collision_point, target_position); if (collision_distance > (LOS_OBJECT_EXCLUDE_DISTANCE_TARGET_END * LOS_OBJECT_EXCLUDE_DISTANCE_TARGET_END)) { #if TEXT_DEBUG_MODULE debug_log ("MB_TGT: (%s -> %s) failed OBJECT LOS with %s (target end)", get_local_entity_string (source, STRING_TYPE_FULL_NAME), get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_type_name (collision_en)); #endif return FALSE; } } } return TRUE; }
void repair_landing_entity_locks (pack_modes mode) { entity *en, *guide, *group, *keysite, *landing, *task; int landing_flag; if (mode != PACK_MODE_SERVER_SESSION) { return; } en = get_local_entity_list (); while (en) { landing_flag = FALSE; // debug if (get_local_entity_type (en) != ENTITY_TYPE_GROUP) // debug { if ((get_local_entity_int_value (en, INT_TYPE_IDENTIFY_AIRCRAFT)) || (get_local_entity_int_value (en, INT_TYPE_IDENTIFY_VEHICLE))) { guide = get_local_entity_parent (en, LIST_TYPE_FOLLOWER); if (guide) { task = get_local_entity_parent (guide, LIST_TYPE_GUIDE); if (task) { switch (get_local_entity_int_value (task, INT_TYPE_ENTITY_SUB_TYPE)) { case ENTITY_SUB_TYPE_TASK_LANDING: { // // LANDING // landing = get_local_entity_parent (task, LIST_TYPE_ASSIGNED_TASK); ASSERT (landing); #if DEBUG_MODULE debug_log ("EN_SESSN: LOCK_REPAIRING: %s landing lock for %s (%d) locks (total %d, free %d, landing %d, landed %d takeoff %d)", get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME), get_local_entity_type_name (en), get_local_entity_index (en), get_local_entity_int_value (landing, INT_TYPE_TOTAL_LANDING_SITES), get_local_entity_int_value (landing, INT_TYPE_FREE_LANDING_SITES), get_local_entity_int_value (landing, INT_TYPE_LANDING_LOCK), get_local_entity_int_value (landing, INT_TYPE_LANDED_LOCK), get_local_entity_int_value (landing, INT_TYPE_TAKEOFF_LOCK)); #endif notify_local_entity (ENTITY_MESSAGE_LOCK_LANDING_ROUTE, landing, en); landing_flag = TRUE; break; } case ENTITY_SUB_TYPE_TASK_LANDING_HOLDING: { // // LANDING HOLDING // landing_flag = TRUE; break; } case ENTITY_SUB_TYPE_TASK_TAKEOFF: { landing = get_local_entity_parent (task, LIST_TYPE_ASSIGNED_TASK); keysite = get_local_entity_parent (landing, LIST_TYPE_LANDING_SITE); #if DEBUG_MODULE debug_log ("EN_SESSN: LOCK_REPAIRING: %s takeoff lock for %s (%d) total %d, free %d, locks (landing %d, landed %d takeoff %d)", get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME), get_local_entity_type_name (en), get_local_entity_index (en), get_local_entity_int_value (landing, INT_TYPE_TOTAL_LANDING_SITES), get_local_entity_int_value (landing, INT_TYPE_FREE_LANDING_SITES), get_local_entity_int_value (landing, INT_TYPE_LANDING_LOCK), get_local_entity_int_value (landing, INT_TYPE_LANDED_LOCK), get_local_entity_int_value (landing, INT_TYPE_TAKEOFF_LOCK)); #endif notify_local_entity (ENTITY_MESSAGE_LOCK_TAKEOFF_ROUTE, landing, en); break; } } } } // // LANDED // if ((get_local_entity_int_value (en, INT_TYPE_LANDED)) || (landing_flag)) { group = get_local_entity_parent (en, LIST_TYPE_MEMBER); keysite = get_local_entity_parent (group, LIST_TYPE_KEYSITE_GROUP); if (get_local_entity_type (keysite) != ENTITY_TYPE_KEYSITE) { ASSERT (get_local_entity_type (en) == ENTITY_TYPE_SHIP_VEHICLE); ASSERT (get_local_entity_type (keysite) == ENTITY_TYPE_FORCE); #if DEBUG_MODULE debug_log ("LANDING: %s. Not repairing locks", get_local_entity_string (en, STRING_TYPE_FULL_NAME)); #endif } else { landing = get_local_entity_landing_entity (keysite, group_database [get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE)].default_landing_type); #if DEBUG_MODULE debug_log ("EN_SESSN: LOCK_REPAIRING: %s landed site lock for %s (%d) total %d, free %d, locks (landing %d, landed %d takeoff %d)", get_local_entity_string (keysite, STRING_TYPE_KEYSITE_NAME), get_local_entity_type_name (en), get_local_entity_index (en), get_local_entity_int_value (landing, INT_TYPE_TOTAL_LANDING_SITES), get_local_entity_int_value (landing, INT_TYPE_FREE_LANDING_SITES), get_local_entity_int_value (landing, INT_TYPE_LANDING_LOCK), get_local_entity_int_value (landing, INT_TYPE_LANDED_LOCK), get_local_entity_int_value (landing, INT_TYPE_TAKEOFF_LOCK)); #endif notify_local_entity (ENTITY_MESSAGE_LOCK_LANDING_SITE, landing, en); } } } } en = get_local_entity_succ (en); } }
aircraft_fire_result aircraft_fire_weapon (entity *en, unsigned int check_flags) { entity *target; aircraft *raw; vec3d *target_pos, en_pos; ASSERT (en); raw = get_local_entity_data (en); // // Fire suppressed // if (check_flags & AIRCRAFT_FIRE_SUPPRESSED) { if (get_local_entity_int_value (get_session_entity (), INT_TYPE_SUPPRESS_AI_FIRE)) { return AIRCRAFT_FIRE_SUPPRESSED; } } // // check weapon // if (check_flags & AIRCRAFT_FIRE_NO_WEAPON) { if (get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON) == ENTITY_SUB_TYPE_WEAPON_NO_WEAPON) { debug_log ("AC_WPN: Fire Weapon Error - NO WEAPON"); return AIRCRAFT_FIRE_NO_WEAPON; } } // // weapon system_ready // if (check_flags & AIRCRAFT_FIRE_WEAPON_SYSTEM_NOT_READY) { if (!get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON_SYSTEM_READY)) { debug_log ("AC_WPN: Fire Weapon Error - WEAPON SYSTEM NOT READY"); return AIRCRAFT_FIRE_WEAPON_SYSTEM_NOT_READY; } } // // find target // if (check_flags & AIRCRAFT_FIRE_NO_TARGET) { target = get_local_entity_parent (en, LIST_TYPE_TARGET); if (!target) { debug_log ("AC_WPN: Fire Weapon Error - NO TARGET"); return AIRCRAFT_FIRE_NO_TARGET; } } // // line of sight checks // if (check_flags & AIRCRAFT_FIRE_NO_LOS) { int criteria; if (get_local_entity_int_value (target, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI) { criteria = MOBILE_LOS_CHECK_ALL; } else { criteria = MOBILE_LOS_CHECK_COURSE_TERRAIN; } get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &en_pos); target_pos = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION); en_pos.y -= (get_local_entity_float_value (en, FLOAT_TYPE_CENTRE_OF_GRAVITY_TO_GROUND_DISTANCE) + 2.0); if (!check_position_line_of_sight (en, target, &en_pos, target_pos, criteria)) { debug_log ("AC_WPN: Fire Weapon Error - NO LOS (Aircraft %s (%d), Target %s (%d))", get_local_entity_string (en, STRING_TYPE_FULL_NAME), get_local_entity_index (en), get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_index (target)); return AIRCRAFT_FIRE_NO_LOS; } } // // Play Speech // play_aircraft_weapon_launched_speech (en, raw->selected_weapon); // // Fire weapon // launch_client_server_weapon (en, raw->selected_weapon); return AIRCRAFT_FIRE_OK; }
int update_pilot_high_score_table (void) { int count, num_pilots; entity *force_en, *pilot_en; pilot_score_type *full_table; // // clear table // debug_log ("PILOT: Updating High Score Table"); initialise_pilot_high_score_table (); num_pilots = 0; // // count up player pilots // ASSERT (get_session_entity ()); force_en = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE); while (force_en) { pilot_en = get_local_entity_first_child (force_en, LIST_TYPE_PILOT); while (pilot_en) { num_pilots ++; pilot_en = get_local_entity_child_succ (pilot_en, LIST_TYPE_PILOT); } force_en = get_local_entity_child_succ (force_en, LIST_TYPE_FORCE); } if (num_pilots == 0) { return 0; } // // create arrays of player pilots and their scores // full_table = (pilot_score_type *) malloc_fast_mem (sizeof (pilot_score_type) * num_pilots); count = 0; force_en = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE); while (force_en) { pilot_en = get_local_entity_first_child (force_en, LIST_TYPE_PILOT); while (pilot_en) { full_table [count].kills = get_local_entity_int_value (pilot_en, INT_TYPE_KILLS); full_table [count].side = (entity_sides) get_local_entity_int_value (pilot_en, INT_TYPE_SIDE); full_table [count].valid = TRUE; strcpy (full_table [count].name, get_local_entity_string (pilot_en, STRING_TYPE_PILOTS_NAME)); debug_log ("PILOT: Adding %s (kills %d) to High Score Table", full_table [count].name, full_table [count].kills); count ++; pilot_en = get_local_entity_child_succ (pilot_en, LIST_TYPE_PILOT); } force_en = get_local_entity_child_succ (force_en, LIST_TYPE_FORCE); } ASSERT (count == num_pilots); // // quicksort the list // qs_table (full_table, 0, num_pilots - 1); // // add first n items to the high score table // count = min (num_pilots, NUM_TABLE_ENTRIES); memcpy (pilot_high_score_table, full_table, sizeof (pilot_score_type) * count); free_mem (full_table); return count; }
int assign_task_to_group (entity *group, entity *task_en, unsigned int valid_members) { int sites_required; entity_sub_types sub_type, group_type; entity *force, *landing, *end_keysite, *start_keysite, *guide, *member; vec3d *pos; task *task_raw; debug_assert (get_comms_model () == COMMS_MODEL_SERVER); ASSERT (task_en); ASSERT (group); ASSERT (!(get_local_group_primary_task (group) && (get_local_entity_int_value (task_en, INT_TYPE_PRIMARY_TASK)))); task_raw = ( task * ) get_local_entity_data (task_en); group_type = get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE); member = get_local_entity_first_child (group, LIST_TYPE_MEMBER); // don't if no members or if the group is a CARRIER if (!member) { return FALSE; } if (get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE) == ENTITY_SUB_TYPE_GROUP_ASSAULT_SHIP) { if (task_raw->sub_type != ENTITY_SUB_TYPE_TASK_ENGAGE) { return FALSE; } } // // check for invalid tasks // switch (task_raw->sub_type) { case ENTITY_SUB_TYPE_TASK_LANDING: case ENTITY_SUB_TYPE_TASK_LANDING_HOLDING: case ENTITY_SUB_TYPE_TASK_TAKEOFF: case ENTITY_SUB_TYPE_TASK_TAKEOFF_HOLDING: { #ifdef DEBUG debug_fatal ("ASSIGN: Invalid task type (%s) for assign_task_to_group", get_local_entity_string (task_en, STRING_TYPE_FULL_NAME)); #endif return FALSE; } } // // Create route // if (get_local_entity_int_value (group, INT_TYPE_GROUP_LIST_TYPE) == LIST_TYPE_KEYSITE_GROUP) { start_keysite = get_local_entity_parent (group, LIST_TYPE_KEYSITE_GROUP); } else { // start_keysite = get_closest_keysite (NUM_ENTITY_SUB_TYPE_KEYSITES, task_raw->side, get_local_entity_vec3d_ptr (group, VEC3D_TYPE_POSITION), 1.0 * KILOMETRE, NULL); start_keysite = NULL; } pos = get_local_entity_vec3d_ptr (task_en, VEC3D_TYPE_STOP_POSITION); force = get_local_force_entity ( ( entity_sides ) get_local_entity_int_value (task_en, INT_TYPE_SIDE) ); sub_type = group_database [group_type].default_landing_type; landing = NULL; end_keysite = NULL; if (get_local_entity_int_value (task_en, INT_TYPE_ASSESS_LANDING)) { ASSERT (start_keysite); end_keysite = ( entity * ) get_local_entity_ptr_value (task_en, PTR_TYPE_RETURN_KEYSITE); if (end_keysite) { // // check end keysite has suitble free landing sites // if (start_keysite != end_keysite) { // // if end keysite == start keysite then keysite MUST have enough sites because the aircraft are already there // sites_required = get_local_group_member_count (group); if (get_keysite_landing_sites_available (end_keysite, sub_type) < sites_required) { // // END keysite was specified - but no free landing sites for this group // return FALSE; } } } else { // // No END keysite specified so return to start keysite // end_keysite = start_keysite; set_local_entity_ptr_value (task_en, PTR_TYPE_RETURN_KEYSITE, end_keysite); } ASSERT (end_keysite); landing = get_local_entity_landing_entity (end_keysite, group_database [get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE)].default_landing_type); } if (create_generic_waypoint_route (group, task_en, end_keysite, NULL, NULL, NULL, 0)) { #if DEBUG_MODULE debug_log ("ASSIGN: group %s (%d) assigned to task %s (%d)", get_local_entity_string (group, STRING_TYPE_FULL_NAME), get_local_entity_index (group), get_local_entity_string (task_en, STRING_TYPE_FULL_NAME), get_local_entity_index (task_en)); #endif // // Assign task // guide = push_task_onto_group_task_stack (group, task_en, valid_members); assign_task_to_group_members (group, guide, valid_members); return TRUE; } 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); }
void interpolate_entity_position (entity *en) { vec3d new_position, *motion_vector, *position; connection_list_type *connection; float delta_time; if ((!command_line_comms_interpolate_gunships) || (get_local_entity_int_value (en, INT_TYPE_LANDED))) { return; } position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); motion_vector = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_MOTION_VECTOR); if (get_comms_model () == COMMS_MODEL_CLIENT) { connection = get_connection_list_item (get_server_id ()); } else { connection = get_gunships_connection_list_item (en); } if (connection) { delta_time = (float) (get_system_time () - connection->interpolation_time) / TIME_1_SECOND; new_position.x = position->x + motion_vector->x * delta_time; new_position.y = position->y + motion_vector->y * delta_time; new_position.z = position->z + motion_vector->z * delta_time; set_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &new_position); if (get_comms_model () == COMMS_MODEL_SERVER) { connection->interpolation_time = get_system_time (); } #if DEBUG_MODULE debug_log ("SERVER: interpolating entity %s (%d) old [%f, %f, %f], new [%f, %f, %f], motion_vector [%f, %f, %f], deltatime %f", get_local_entity_string (en, STRING_TYPE_FULL_NAME), get_local_entity_index (en), position->x, position->y, position->z, new_position.x, new_position.y, new_position.z, motion_vector->x, motion_vector->y, motion_vector->z, delta_time); #endif } }
static void draw_chat_send_button (ui_object *obj, void *arg) { entity *current_target; rgb_colour *col; static const char *text; static char s [256]; sprintf (s, "%s: ", get_trans ("SEND TO")); current_target = get_local_entity_safe_ptr (get_ui_object_item_number (obj)); if (current_target) { switch (get_local_entity_type (current_target)) { case ENTITY_TYPE_SESSION: { strcat (s, get_trans ("CHAT_TARGET_ALL")); break; } case ENTITY_TYPE_FORCE: { strcat (s, get_local_entity_string (current_target, STRING_TYPE_FORCE_NAME)); break; } case ENTITY_TYPE_PILOT: { strcat (s, get_local_entity_string (current_target, STRING_TYPE_PILOTS_NAME)); break; } default: { current_target = NULL; build_chat_target_list (); break; } } } set_ui_object_text (obj, s); if (current_target) { text = get_ui_object_text (chat_current_text); if (text) { if (strlen (text) > 0) { set_ingame_ui_object_mouse_over_properties (obj); set_ui_object_notify_on (obj, NOTIFY_TYPE_BUTTON_DOWN); return; } } } set_ui_object_notify_on (obj, NOTIFY_TYPE_NONE); set_ui_object_highlightable (obj, FALSE); col = &ui_ingame_dead_text_colour; set_ui_object_font_colour (obj, col->r, col->g, col->b, col->a); }
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 comms_process_data (void) { session_list_data_type *current_session; connection_list_type *this_connection, *connection; char *received_data; int planner_event, frame_id, packet_id, receive_flag, received_size; GUID received_id = 0; entity *member; send_types send_type; packet_types type; // receive all packets in queue current_session = get_current_game_session (); received_size = MAX_RECEIVE_SIZE; connection = get_connection_list_head (); while (connection) { this_connection = connection; connection = connection->next; send_type = SEND_TYPE_GROUP; while (send_type >= SEND_TYPE_PERSONAL) { receive_flag = TRUE; while (receive_flag) { type = process_packet_list (send_type, this_connection, &received_id, &received_data, &received_size); switch (type) { /////////////////////////////////////////////////////////////////////////////////////////////// // // System packets, used internally // /////////////////////////////////////////////////////////////////////////////////////////////// case PACKET_TYPE_INVALID: { receive_flag = FALSE; if (get_comms_model () == COMMS_MODEL_SERVER) { if (this_connection->packet_rerequested > command_line_comms_packet_rerequest_limit) { debug_log ("COMM_MAN: REJECTING CONNECTION. CONNECTION TOO BAD (re-request limit %d reached)", command_line_comms_packet_rerequest_limit); send_packet (this_connection->connection_id, PACKET_TYPE_SERVER_REJECTED, NULL, 0, SEND_TYPE_PERSONAL); } } break; } case PACKET_TYPE_RESEND_PACKET: { send_types resend_send_type; frame_id = get_list_item (received_data, int); packet_id = get_list_item (received_data, int); resend_send_type = get_list_item (received_data, send_types); #if DEBUG_MODULE if (this_connection->pilot_entity) { debug_log ("COMMS MAN: received RESEND PACKET for frame %d packet %d from %s (dpid %d)", frame_id, packet_id, get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME), received_id); } else { debug_log ("COMMS MAN: received RESEND PACKET by unknown (pdid %d)", received_id); } #endif resend_packet (received_id, frame_id, packet_id, resend_send_type); break; } /////////////////////////////////////////////////////////////////////////////////////////////// // // Packets for initialisation and joining // /////////////////////////////////////////////////////////////////////////////////////////////// case PACKET_TYPE_SESSION_QUERY: { char *ptr; int server_version_number, player_count, size; connection_list_type *new_connection; if (get_comms_model () == COMMS_MODEL_SERVER) { #if DEBUG_MODULE if (this_connection->pilot_entity) { debug_log ("COMMS MAN: RECEIVED SESSION QUERY from %s (dpid %d)", get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME), received_id); } else { debug_log ("COMMS MAN: RECEIVED SESSION QUERY from %d", received_id); } #endif new_connection = get_connection_list_item (received_id); if (!new_connection->already_sent_query_data) { new_connection->already_sent_query_data = TRUE; while (TRUE) { ptr = new_connection->connection_receive_buffer; size = 0; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Check both client and server are running same campaign data // server_version_number = get_local_entity_int_value (get_session_entity (), INT_TYPE_VERSION_NUMBER); quick_set_list_item (ptr, int, server_version_number); size += sizeof (int); // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // map details quick_set_list_item (ptr, int, NUM_MAP_X_SECTORS); quick_set_list_item (ptr, int, NUM_MAP_Z_SECTORS); quick_set_list_item (ptr, int, SECTOR_SIDE_LENGTH); size += sizeof (int) * 3; // data path strcpy (ptr, current_session->data_path); ptr += strlen (current_session->data_path) + 1; size += strlen (current_session->data_path) + 1; // population_placement filename if (population_placement_filename) { strcpy (ptr, population_placement_filename); ptr += strlen (population_placement_filename) + 1; size += strlen (population_placement_filename) + 1; } else { strcpy (ptr, "\0"); ptr += strlen ("\0") + 1; size += strlen ("\0") + 1; } // // side_data filename if (side_data_filename) { strcpy (ptr, side_data_filename); ptr += strlen (side_data_filename) + 1; size += strlen (side_data_filename) + 1; } else { strcpy (ptr, "\0"); ptr += strlen ("\0") + 1; size += strlen ("\0") + 1; } // campaign_population filename if (campaign_population_filename) { strcpy (ptr, campaign_population_filename); ptr += strlen (campaign_population_filename) + 1; size += strlen (campaign_population_filename) + 1; } else { strcpy (ptr, "\0"); ptr += strlen ("\0") + 1; size += strlen ("\0") + 1; } // // planner position and zoom // // quick_set_list_item (ptr, float, planner_map_data.centre_map_x); // quick_set_list_item (ptr, float, planner_map_data.centre_map_z); // size += sizeof (float) * 2; // quick_set_list_item (ptr, int, planner_map_data.map_zoom); // size += sizeof (int); // // Pilots // player_count = get_number_of_connected_players (); quick_set_list_item (ptr, int, player_count); size += sizeof (int); // // // #if DEBUG_MODULE debug_log ("COMM_MAN: sending data path %s, population placement %s, side data %s, campaign_pop file %s", current_session->data_path, population_placement_filename, side_data_filename, campaign_population_filename); #endif new_connection->connection_receive_buffer_size -= size; if (!pack_session (ptr, &new_connection->connection_receive_buffer_size, PACK_MODE_BROWSE_SESSION)) { break; } new_connection->connection_receive_buffer_size *= 2; #if DEBUG_MODULE debug_log ("COMMS MAN: Browse: connection_receive_buffer too small, mallocing to %d", new_connection->connection_receive_buffer_size); #endif free_mem (new_connection->connection_receive_buffer); new_connection->connection_receive_buffer = malloc_heap_mem (new_connection->connection_receive_buffer_size); } // // // send_packet (received_id, PACKET_TYPE_SESSION_INFO, new_connection->connection_receive_buffer, new_connection->connection_receive_buffer_size + size, SEND_TYPE_PERSONAL); /* { FILE *test_ptr; test_ptr = fopen ("out.txt", "wb"); fwrite (new_connection->connection_receive_buffer, 1, new_connection->connection_receive_buffer_size + size, test_ptr); fclose (test_ptr); } */ } else { debug_log ("COMM_MAN: not resending query data"); } } break; } case PACKET_TYPE_CONNECTION_VALIDATION: { debug_log ("COMM_MAN: received CONNECTION_VALIDATION, sending RESPONSE"); send_packet (received_id, PACKET_TYPE_CONNECTION_RESPONSE, NULL, 0, SEND_TYPE_PERSONAL); break; } case PACKET_TYPE_CONNECTION_RESPONSE: { connection_list_type *connection; connection = get_connection_list_item (received_id); connection->validation_count = 0; debug_log ("COMM_MAN: received CONNECTION_RESPONSE, connection still alive"); break; } case PACKET_TYPE_SESSION_INFO: { entity *force, *pilot; int client_version_number, server_version_number; int size, x_size, z_size, sector_size, player_count, loop; char *ptr, warzone_ffp_filename [256], temp_campaign_population_filename [256], temp_population_placement_filename [256], temp_side_data_filename [256], buffer [128]; session_data = FALSE; reinitialise_entity_system (); ptr = received_data; size = 0; set_ui_object_redraw (gunships_screen, TRUE); ui_force_update (); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Check both client and server are running same campaign data // client_version_number = get_global_version_number (); server_version_number = get_list_item (ptr, int); size += sizeof (int); if (client_version_number != server_version_number) { debug_fatal ("COMM_MAN: Incorrect version. Server Version No. %d, Client Version No. %d", server_version_number, client_version_number); } // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // map details x_size = get_list_item (ptr, int); z_size = get_list_item (ptr, int); sector_size = get_list_item (ptr, int); size += (sizeof (int) * 3); set_entity_world_map_size (x_size, z_size, sector_size); // data path strncpy (current_session->data_path, ptr, sizeof (current_session->data_path)); ptr += strlen (current_session->data_path) + 1; size += strlen (current_session->data_path) + 1; // population_placement_filename strncpy (temp_population_placement_filename, ptr, sizeof (temp_population_placement_filename)); ptr += strlen (temp_population_placement_filename) + 1; size += strlen (temp_population_placement_filename) + 1; if (population_placement_filename) { free_mem (population_placement_filename); } if (strlen (temp_population_placement_filename) > 0) { population_placement_filename = (char *) malloc_heap_mem (strlen (temp_population_placement_filename) + 1); sprintf (population_placement_filename, "%s", temp_population_placement_filename); } else { population_placement_filename = NULL; } // side_data filename strncpy (temp_side_data_filename, ptr, sizeof (temp_side_data_filename)); ptr += strlen (temp_side_data_filename) + 1; size += strlen (temp_side_data_filename) + 1; if (side_data_filename) { free_mem (side_data_filename); } if (strlen (temp_side_data_filename) > 0) { side_data_filename = (char *) malloc_heap_mem (strlen (temp_side_data_filename) + 1); sprintf (side_data_filename, "%s", temp_side_data_filename); } else { side_data_filename = NULL; } // campaign_population_filename strncpy (temp_campaign_population_filename, ptr, sizeof (temp_campaign_population_filename)); ptr += strlen (temp_campaign_population_filename) + 1; size += strlen (temp_campaign_population_filename) + 1; if (campaign_population_filename) { free_mem (campaign_population_filename); } if (strlen (temp_campaign_population_filename) > 0) { campaign_population_filename = (char *) malloc_heap_mem (strlen (temp_campaign_population_filename) + 1); sprintf (campaign_population_filename, "%s", temp_campaign_population_filename); } else { campaign_population_filename = NULL; } // // // player_count = get_list_item (ptr, int); size += sizeof (int); // // // received_size -= size; #if DEBUG_MODULE debug_log ("COMM_MAN: data path %s population placement filename %s, side data filename %s", current_session->data_path, population_placement_filename, side_data_filename); debug_log ("COMM_MAN: campaign data path = %s", current_session->data_path); #endif // // check we have the correct warzone locally // sprintf (warzone_ffp_filename, "%s\\terrain\\terrain.ffp", current_session->data_path); if (!file_exist (warzone_ffp_filename)) { add_to_pop_up_list_with_word_wrap (get_trans ("UNRECOGNISED_WARZONE"), session_info_list, NULL, 0, UI_FONT_ARIAL_10, sys_col_white); //add_to_pop_up_list (get_trans ("Server using unrecognised warzone"), session_info_list, NULL, 0, UI_FONT_ARIAL_10, sys_col_white); break; } // // // create_local_only_entities (PACK_MODE_BROWSE_SESSION); if (unpack_session (ptr, received_size, PACK_MODE_BROWSE_SESSION)) { debug_fatal ("COMMS MAN: browse: received size overflow"); } #if DEBUG_MODULE if (this_connection->pilot_entity) { debug_log ("COMMS MAN: received SESSION INFO from %s (dpid %d) (setting server id)", get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME), received_id); } else { debug_log ("COMMS MAN: RECEIVED SESSION INFO from %d", received_id); } debug_log ("COMMS MAN: session info: time of day = %f", get_local_entity_float_value (get_session_entity (), FLOAT_TYPE_TIME_OF_DAY)); debug_log ("COMMS MAN: map dimensions %d, %d, sector size %d", x_size, z_size, sector_size); #endif set_ui_object_drawable (session_screen_next_button, TRUE); // // Display game info // ui_object_destroy_list_items (session_info_list); if (get_local_entity_int_value (get_session_entity (), INT_TYPE_CAMPAIGN_REQUIRES_APACHE_HAVOC)) { // campaign requires apache havoc to be installed // check it is... if (!get_global_apache_havoc_installed ()) { add_to_pop_up_list_with_word_wrap (get_trans ("REQUIRES_APACHE_HAVOC"), session_info_list, NULL, 0, UI_FONT_ARIAL_10, sys_col_white); set_ui_object_drawable (session_screen_next_button, FALSE); break; } } loop = 3; sprintf (buffer, "%s : %d", get_trans ("Players"), player_count); add_to_pop_up_list_with_word_wrap (buffer, session_info_list, NULL, 0, UI_FONT_ARIAL_10, sys_col_white); force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE); while (force) { pilot = get_local_entity_first_child (force, LIST_TYPE_PILOT); while (pilot) { { rgb_colour col; sprintf (buffer, "%2d ", loop - 2); strncat (buffer, get_local_entity_string (pilot, STRING_TYPE_PILOTS_NAME), 64); switch (get_local_entity_int_value (pilot, INT_TYPE_SIDE)) { case ENTITY_SIDE_BLUE_FORCE: { col.r = 120; col.g = 158; col.b = 255; col.a = 255; break; } case ENTITY_SIDE_RED_FORCE: { col.r = 255; col.g = 120; col.b = 80; col.a = 255; break; } default: { col = ui_colour_white; break; } } add_to_pop_up_list_with_word_wrap (buffer, session_info_list, NULL, 0, UI_FONT_ARIAL_10, col); loop ++; } pilot = get_local_entity_child_succ (pilot, LIST_TYPE_PILOT); } force = get_local_entity_child_succ (force, LIST_TYPE_FORCE); } set_server_id (received_id); // // destroy all entities created by browse info // reinitialise_entity_system (); break; } case PACKET_TYPE_CLIENT_PILOT_REQUEST: { connection_list_type *new_connection; client_pilot_request_data pilot_data; entity *new_pilot; int index; ASSERT (get_comms_model () == COMMS_MODEL_SERVER); // #if DEBUG_MODULE debug_log ("COMMS MAN: RECEIVED PILOT REQUEST from %d", received_id); // #endif // // unpack name // memcpy (&pilot_data, (client_pilot_request_data *) received_data, sizeof (client_pilot_request_data)); new_pilot = create_new_pilot_entity ( pilot_data.name, pilot_data.side, pilot_data.rank, pilot_data.sub_type, pilot_data.unique_id, pilot_data.difficulty ); ASSERT (new_pilot); index = get_local_entity_safe_index (new_pilot); new_connection = get_connection_list_item (received_id); transmit_entity_comms_message (ENTITY_COMMS_PILOT_REQUEST_ACCEPTED, NULL, received_id, index); new_connection->pilot_entity = new_pilot; break; } case PACKET_TYPE_CLIENT_GUNSHIP_REQUEST: { connection_list_type *new_connection; client_gunship_request_data pilot_data; int index_number, buffer [2]; if (get_comms_model () == COMMS_MODEL_SERVER) { // #if DEBUG_MODULE if (this_connection->pilot_entity) { debug_log ("COMMS MAN: RECEIVED GUNSHIP REQUEST from %s (dpid %d)", get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME), received_id); } else { debug_log ("COMMS MAN: RECEIVED GUNSHIP REQUEST from %d", received_id); } // #endif memcpy (&pilot_data, (client_gunship_request_data *) received_data, sizeof (client_gunship_request_data)); index_number = pilot_data.gunship_index; ASSERT (index_number != ENTITY_INDEX_DONT_CARE); member = get_local_entity_safe_ptr (index_number); if (!member) { // #if DEBUG_MODULE if (this_connection->pilot_entity) { debug_log ("COMMS MAN: REFUSING GUNSHIP FOR PLAYER %s (dpid %d) for helicopter %d", get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME), received_id, pilot_data.gunship_index); } else { debug_log ("COMMS MAN: Refusing gunship for player %d to helicopter %d", received_id, pilot_data.gunship_index); } // #endif send_packet (received_id, PACKET_TYPE_GUNSHIP_REQUEST_REFUSED, NULL, 0, SEND_TYPE_PERSONAL); break; } new_connection = get_connection_list_item (received_id); // // send acceptance // buffer [0] = index_number; // #if DEBUG_MODULE debug_log ("COMMS MAN: sending gunship request accepted for gunship %d pilot id %d", index_number, received_id); // #endif send_packet (received_id, PACKET_TYPE_GUNSHIP_REQUEST_ACCEPTED, (void *) &buffer, 4, SEND_TYPE_PERSONAL); new_connection->gunship_number = pilot_data.gunship_index; new_connection->gunship_entity = member; } break; } case PACKET_TYPE_CLIENT_CAMPAIGN_DATA_REQUEST: { connection_list_type *new_connection; int index_number; if (get_comms_model () == COMMS_MODEL_SERVER) { #if DEBUG_MODULE if (this_connection->pilot_entity) { debug_log ("COMMS MAN: RECEIVED JOIN REQUEST by %s (dpid %d)", get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME), received_id); } else { debug_log ("COMMS MAN: received JOIN REQUEST by %d", received_id); } #endif // // flush group send buffer // send_comms_data (); // // pack mission data into packet // new_connection = get_connection_list_item (received_id); // // Store entity data // while (pack_session (new_connection->connection_receive_buffer, &new_connection->connection_receive_buffer_size, PACK_MODE_CLIENT_SESSION)) { new_connection->connection_receive_buffer_size *= 2; #if DEBUG_MODULE debug_log ("COMMS MAN: Mission data: connection_receive_buffer too small, mallocing to %d", new_connection->connection_receive_buffer_size); #endif free_mem (new_connection->connection_receive_buffer); new_connection->connection_receive_buffer = malloc_heap_mem (new_connection->connection_receive_buffer_size); memset (new_connection->connection_receive_buffer, 0, new_connection->connection_receive_buffer_size); } // add frame id index_number = get_group_frame_id (); memcpy (&new_connection->connection_receive_buffer [new_connection->connection_receive_buffer_size], (void *) &index_number, sizeof (int)); new_connection->connection_receive_buffer_size += sizeof (int); send_packet (received_id, PACKET_TYPE_MISSION_DATA, new_connection->connection_receive_buffer, new_connection->connection_receive_buffer_size, SEND_TYPE_PERSONAL); memset (new_connection->connection_receive_buffer, 0, new_connection->connection_receive_buffer_size); // // send group frame id // SDL_Delay (100); index_number = get_group_frame_id (); //send_packet (received_id, PACKET_TYPE_FRAME_ID, (void *) &index_number, 4, SEND_TYPE_PERSONAL); zero_average_pack_size (); } break; } case PACKET_TYPE_CLIENT_FRAME_ID: { int loop1, loop2, index_number; stub_packet_type *stub_packet; connection_list_type *new_connection; index_number = get_list_item (received_data, int); new_connection = get_connection_list_item (received_id); //#if DEBUG_MODULE if (new_connection) { debug_log ("COMMS MAN: received CLIENT FRAME ID (%d) by %d %s", index_number, received_id, direct_play_get_player_name (received_id)); } //#endif // // send all packets between when the client started to join and when it actually joined. // for (loop1 = index_number; loop1 < get_group_frame_id () - 1; loop1 ++) { //#if DEBUG_MODULE debug_log ("COMMS MAN: sending packet %d frame %d to recently joined client", loop1, 0); //#endif stub_packet = resend_packet (received_id, loop1, 1, SEND_TYPE_GROUP); ASSERT (stub_packet); for (loop2 = 2; loop2 <= stub_packet->packet->number_of_packets; loop2 ++) { //#if DEBUG_MODULE debug_log ("COMMS MAN: sending packet %d frame %d to recently joined client", loop1, loop2); //#endif stub_packet = resend_packet (received_id, loop1, loop2, SEND_TYPE_GROUP); } } break; } case PACKET_TYPE_GUNSHIP_REQUEST_REFUSED: { // #if DEBUG_MODULE debug_log ("COMMS MAN: Gunship refused"); // #endif set_server_response (SERVER_RESPONSE_REFUSE); break; } case PACKET_TYPE_GUNSHIP_REQUEST_ACCEPTED: { entity *gunship; int index_number; // #if DEBUG_MODULE debug_log ("COMMS MAN: received GUNSHIP ACCEPTED by %d", received_id); // #endif // // set gunship // index_number = get_list_item (received_data, int); ASSERT (get_pilot_entity ()); gunship = get_local_entity_safe_ptr (index_number); debug_filtered_log ("COMM_MAN: setting gunship"); planner_event = FALSE; if (get_event_stack_head_function() == ingame_screen_set_events) { pop_event (ingame_screen_set_events); planner_event = TRUE; } assign_entity_to_user (gunship); if (planner_event) { push_event (ingame_screen_set_events, "ingame screen events"); } debug_filtered_log ("COMM_MAN: gunship set"); //////////////////////////////////////////////////////////////////////// break; } case PACKET_TYPE_PILOT_REQUEST_ACCEPTED: { int index_number; ASSERT (get_comms_model () == COMMS_MODEL_CLIENT); // #if DEBUG_MODULE debug_log ("COMMS MAN: received PILOT ACCEPTED by %d", received_id); // #endif index_number = get_list_item (received_data, int); set_pilot_entity (get_local_entity_safe_ptr (index_number)); break; } case PACKET_TYPE_MISSION_DATA: { #if DEBUG_MODULE debug_log ("COMMS MAN: received MISSION DATA by %d", received_id); #endif set_mouse_graphic_off (); // // LOAD TERRAIN DATA // load_3d_terrain_game_data (); initialise_population_name_database (); load_route_data (); // might need to send what route filename to load... // // Initialise stuff // create_local_only_entities (PACK_MODE_CLIENT_SESSION); ///////////////////////////////////////////////////////////////// if (strstr ((char*) stoupper (side_data_filename), "SID")) { read_sector_side_file (side_data_filename); } else if (strstr ((char*) stoupper (side_data_filename), "DAT")) { load_ai_sector_data (side_data_filename); } ///////////////////////////////////////////////////////////////// deinitialise_formation_database (); initialise_formation_database (); deinitialise_formation_component_database (); initialise_formation_component_database (); if (unpack_session (received_data, received_size - 4, PACK_MODE_CLIENT_SESSION)) { debug_fatal ("COMMS MAN: received size overflow"); } /* force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE); while (force) { create_frontline (force); force = get_local_entity_child_succ (force, LIST_TYPE_FORCE); } */ { int index_number; connection_list_type *new_connection; received_data += received_size - 4; index_number = get_list_item (received_data, int); new_connection = get_connection_list_item (received_id); new_connection->receive_group_frame_id = index_number; send_packet (get_server_id (), PACKET_TYPE_CLIENT_FRAME_ID, (void *) &index_number, 4, SEND_TYPE_PERSONAL); } session_data = TRUE; //direct_play_join_group (); set_gunship_waiting_for_connection ( FALSE ); zero_average_pack_size (); set_mouse_graphic_on (); break; } case PACKET_TYPE_FRAME_ID: { int index_number; connection_list_type *new_connection; index_number = get_list_item (received_data, int); #if DEBUG_MODULE debug_log ("COMMS MAN: received FRAME ID (%d) by %d", index_number, received_id); #endif new_connection = get_connection_list_item (received_id); new_connection->receive_group_frame_id = index_number; send_packet (get_server_id (), PACKET_TYPE_CLIENT_FRAME_ID, (void *) &index_number, 4, SEND_TYPE_PERSONAL); break; } /////////////////////////////////////////////////////////////////////////////////////////////// // // In game packets // /////////////////////////////////////////////////////////////////////////////////////////////// case PACKET_TYPE_AI_DATA: { int //padding, data_size; #if DEBUG_MODULE >= 2 debug_log ("COMMS MAN: received AI DATA by %d", received_id); #endif if (get_comms_model () == COMMS_MODEL_CLIENT) { ASSERT (session_data); } data_size = get_list_item (received_data, int); //debug //padding = get_list_item (received_data, int); //end open_unpack_buffer (received_data, received_size); process_received_entity_comms_messages (); ASSERT (!get_unpack_buffer_overflow ()); close_unpack_buffer (); //debug //padding = get_list_item (received_data, int); //end memset (received_data, 0, this_connection->connection_receive_buffer_size); break; } case PACKET_TYPE_END_GAME: { debug_log ("COMMS MAN: received END GAME from %d", received_id); if (get_comms_model () == COMMS_MODEL_SERVER) { if (this_connection->gunship_entity) { set_client_server_entity_int_value (this_connection->gunship_entity, INT_TYPE_PLAYER, ENTITY_PLAYER_AI); } if (this_connection->pilot_entity) { debug_log (" from %s ", get_local_entity_string (this_connection->pilot_entity, STRING_TYPE_PILOTS_NAME)); } unregister_connection (received_id); } else { if (received_id == get_server_id ()) { //setup_campaign_over_screen (get_local_force_entity (get_global_gunship_side ()), CAMPAIGN_RESULT_STALEMATE); start_game_exit (GAME_EXIT_KICKOUT, FALSE); } } receive_flag = FALSE; break; } case PACKET_TYPE_SERVER_REJECTED: { debug_log ("COMMS MAN: received SERVER REJECTED (server id %d)", received_id); //setup_campaign_over_screen (get_local_force_entity (get_global_gunship_side ()), CAMPAIGN_RESULT_SERVER_REJECTED); start_game_exit (GAME_EXIT_KICKOUT, FALSE); break; } default: { debug_fatal ("ERROR: Data Exchange, unknown packet type %d", type); break; } } } send_type --; } } }
unsigned int assign_engage_tasks_to_group (entity *group, unsigned int valid_members) { entity *task, *guide, *target, *member, *single_member, *persuer, **guide_list; unsigned int member_number; int best_count, best_guide, loop, criteria, task_count, *assigned_count; float range, *priority; vec3d *member_pos, *target_pos; ASSERT (group); ASSERT (get_comms_model () == COMMS_MODEL_SERVER); if (!valid_members) { return valid_members; } // // count up engage tasks // task_count = 0; guide = get_local_entity_first_child (group, LIST_TYPE_GUIDE_STACK); while (guide) { if (get_local_entity_int_value (guide, INT_TYPE_VALID_GUIDE_MEMBERS) == TASK_ASSIGN_NO_MEMBERS) { task = get_local_entity_parent (guide, LIST_TYPE_GUIDE); ASSERT (task); ASSERT (get_local_entity_int_value (task, INT_TYPE_ENTITY_SUB_TYPE) == ENTITY_SUB_TYPE_TASK_ENGAGE); if (get_local_entity_int_value (task, INT_TYPE_TASK_TERMINATED) == TASK_TERMINATED_IN_PROGRESS) { task_count ++; } } guide = get_local_entity_child_succ (guide, LIST_TYPE_GUIDE_STACK); } #if DEBUG_MODULE debug_log ("ENGAGE: =========================="); debug_log ("ENGAGE: %d suitable tasks", task_count); #endif if (task_count == 0) { return valid_members; } ////////////////////////////////////////////////////////////////// // // prioritize engage tasks // ////////////////////////////////////////////////////////////////// // // get target priority // guide_list = (entity * *) malloc_fast_mem (sizeof (entity *) * task_count); priority = (float *) malloc_fast_mem (sizeof (float) * task_count); assigned_count = (int *) malloc_fast_mem (sizeof (int) * task_count); #if DEBUG_MODULE debug_log ("ENGAGE: ======RAW LIST======"); #endif single_member = NULL; // check if we have a single member, if so assign that member to single_member for (member = get_local_entity_first_child (group, LIST_TYPE_MEMBER); member; member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER)) { member_number = (1 << get_local_entity_int_value (member, INT_TYPE_GROUP_MEMBER_NUMBER)); if (member_number & valid_members) { if (single_member) // we already have a valid member, so there is more than one { single_member = NULL; break; } else single_member = member; } } loop = 0; guide = get_local_entity_first_child (group, LIST_TYPE_GUIDE_STACK); while (guide) { if (get_local_entity_int_value (guide, INT_TYPE_VALID_GUIDE_MEMBERS) == TASK_ASSIGN_NO_MEMBERS) { task = get_local_entity_parent (guide, LIST_TYPE_GUIDE); ASSERT (task); ASSERT (get_local_entity_int_value (task, INT_TYPE_ENTITY_SUB_TYPE) == ENTITY_SUB_TYPE_TASK_ENGAGE); if (get_local_entity_int_value (task, INT_TYPE_TASK_TERMINATED) == TASK_TERMINATED_IN_PROGRESS) { target = get_local_entity_parent (task, LIST_TYPE_TASK_DEPENDENT); ASSERT (target); if (!target) { notify_local_entity (ENTITY_MESSAGE_TASK_TERMINATED, task, group, TASK_TERMINATED_ABORTED); free_mem (guide_list); free_mem (priority); free_mem (assigned_count); return valid_members; } guide_list [loop] = guide; if (get_local_entity_int_value (group, INT_TYPE_AIRCRAFT_GROUP)) { priority [loop] = get_local_entity_float_value (target, FLOAT_TYPE_TARGET_PRIORITY_AIR_ATTACK); } else { priority [loop] = get_local_entity_float_value (target, FLOAT_TYPE_TARGET_PRIORITY_GROUND_ATTACK); } #if DEBUG_MODULE debug_log ("ENGAGE: (%d) Target : %s, Priority %f", loop, get_local_entity_string (target, STRING_TYPE_FULL_NAME), priority [loop]); #endif loop ++; } } guide = get_local_entity_child_succ (guide, LIST_TYPE_GUIDE_STACK); } ASSERT (loop == task_count); // // sort the tasks according to their priority // quicksort_entity_list (guide_list, task_count, priority); #if DEBUG_MODULE debug_log ("ENGAGE: ======SORTED======"); for (loop = 0; loop < task_count; loop ++) { task = get_local_entity_parent (guide_list [loop], LIST_TYPE_GUIDE); target = get_local_entity_parent (task, LIST_TYPE_TASK_DEPENDENT); debug_log ("ENGAGE: (%d) Target : %s (%d), Priority %f", loop, get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_index (target), priority [loop]); } #endif // // consider other entities attacking the same targets // memset (assigned_count, 0, sizeof (int) * task_count); for (loop = 0; loop < task_count; loop ++) { task = get_local_entity_parent (guide_list [loop], LIST_TYPE_GUIDE); target = get_local_entity_parent (task, LIST_TYPE_TASK_DEPENDENT); persuer = get_local_entity_first_child (target, LIST_TYPE_TARGET); while (persuer) { assigned_count [loop] ++; persuer = get_local_entity_child_succ (persuer, LIST_TYPE_TARGET); } } ////////////////////////////////////////////////////////////////// // // assign new engage tasks // // for each member, run through the task list (most important first) // try to assign one member per task, but as tasks run out group members can "team-up" // ////////////////////////////////////////////////////////////////// member = get_local_entity_first_child (group, LIST_TYPE_MEMBER); while ((member) && (valid_members)) { // // Only assign AI entities to ENGAGE tasks // if (get_local_entity_int_value (member, INT_TYPE_PLAYER) == ENTITY_PLAYER_AI) { if (get_local_entity_int_value (member, INT_TYPE_ENGAGE_ENEMY)) { member_number = (1 << get_local_entity_int_value (member, INT_TYPE_GROUP_MEMBER_NUMBER)); if (member_number & valid_members) { member_pos = get_local_entity_vec3d_ptr (member, VEC3D_TYPE_POSITION); if (get_local_entity_int_value (member, INT_TYPE_IDENTIFY_AIRCRAFT)) { criteria = BEST_WEAPON_CRITERIA_MINIMAL; } else { criteria = BEST_WEAPON_RANGE_CHECK | BEST_WEAPON_LOS_CHECK; } best_guide = -1; best_count = INT_MAX; for (loop = 0; loop < task_count; loop ++) { if (assigned_count [loop] < best_count) { guide = guide_list [loop]; task = get_local_entity_parent (guide, LIST_TYPE_GUIDE); target = get_local_entity_parent (task, LIST_TYPE_TASK_DEPENDENT); if (target == member) { // // Don't try to attack yourself ! // continue; } // // Range Check // if (criteria & BEST_WEAPON_RANGE_CHECK) { // range handled by weapon selection range = 0.0; } else { target_pos = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION); range = get_sqr_2d_range (target_pos, member_pos); } if (range < MAX_ENGAGE_RANGE) { // // Weapon Check // if (get_best_weapon_for_target (member, target, criteria) != ENTITY_SUB_TYPE_WEAPON_NO_WEAPON) { best_count = assigned_count [loop]; best_guide = loop; } } } } if (best_guide != -1) { guide = guide_list [best_guide]; task = get_local_entity_parent (guide, LIST_TYPE_GUIDE); if (assign_new_task_to_group_member (group, member, task, NULL)) { valid_members &= (~member_number); assigned_count [best_guide] ++; #if DEBUG_MODULE debug_log ("ENGAGE: Assigning %s (%d) to target %s (%d)", get_local_entity_string (member, STRING_TYPE_FULL_NAME), get_local_entity_index (member), get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_index (target)); #endif } } else { #if DEBUG_MODULE debug_log ("ENGAGE: Couldn't assign %s (%d) to engage task", get_local_entity_string (member, STRING_TYPE_FULL_NAME), get_local_entity_index (member)); #endif } } } } member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER); } free_mem (guide_list); free_mem (priority); free_mem (assigned_count); return valid_members; }
int assign_group_callsign (entity *en) { int start_position, side, index; index = 0; if (get_comms_model () != COMMS_MODEL_SERVER) { return index; } if (get_local_entity_int_value (en, INT_TYPE_AIRCRAFT_GROUP)) { index = get_local_entity_index (en) % NUM_GROUP_CALLSIGNS; start_position = index; side = get_local_entity_int_value (en, INT_TYPE_SIDE); while (group_callsign_names [index].side [side]) { index = (++ index) % NUM_GROUP_CALLSIGNS; if (index == start_position) { debug_log ("GROUP: WARNING: reusing group callsign %s for group %s", group_callsign_names [index].callsign, get_local_entity_string (en, STRING_TYPE_FULL_NAME)); break; } } group_callsign_names [index].side [side] ++; } return index; }
void build_chat_target_list (void) { ui_object *new_item; entity *force, *pilot, *current_target; static char s [128]; current_target = get_local_entity_safe_ptr (get_ui_object_item_number (chat_send_button)); ui_object_destroy_list_items (chat_target_list); sprintf (s, "%s", get_trans ("Side")); new_item = add_to_pop_up_list (s, chat_target_list, NULL, ENTITY_INDEX_DONT_CARE, UI_FONT_ARIAL_16, ui_ingame_dead_text_colour); // // All // ASSERT (get_session_entity ()); sprintf (s, "%s", get_trans ("CHAT_TARGET_ALL")); new_item = add_to_pop_up_list (s, chat_target_list, NULL, get_local_entity_safe_index (get_session_entity ()), UI_FONT_ARIAL_16, ui_ingame_live_text_colour); set_ingame_ui_object_mouse_over_properties (new_item); if (get_session_entity () == current_target) { set_ui_object_state (new_item, UI_OBJECT_STATE_ON); } // // Sides // force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE); while (force) { sprintf (s, "%s", get_local_entity_string (force, STRING_TYPE_FORCE_NAME)); new_item = add_to_pop_up_list (s, chat_target_list, NULL, get_local_entity_safe_index (force), UI_FONT_ARIAL_16, ui_ingame_live_text_colour); set_ingame_ui_object_mouse_over_properties (new_item); if (force == current_target) { set_ui_object_state (new_item, UI_OBJECT_STATE_ON); } force = get_local_entity_child_succ (force, LIST_TYPE_FORCE); } // // Sides // sprintf (s, "%s", get_trans ("UI_PILOTS")); new_item = add_to_pop_up_list (s, chat_target_list, NULL, ENTITY_INDEX_DONT_CARE, UI_FONT_ARIAL_16, ui_ingame_dead_text_colour); force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE); while (force) { pilot = get_local_entity_first_child (force, LIST_TYPE_PILOT); while (pilot) { if (pilot != get_pilot_entity ()) { sprintf (s, "%s", get_local_entity_string (pilot, STRING_TYPE_PILOTS_NAME)); new_item = add_to_pop_up_list (s, chat_target_list, NULL, get_local_entity_safe_index (pilot), UI_FONT_ARIAL_16, ui_ingame_live_text_colour); set_ingame_ui_object_mouse_over_properties (new_item); if (pilot == current_target) { set_ui_object_state (new_item, UI_OBJECT_STATE_ON); } } pilot = get_local_entity_child_succ (pilot, LIST_TYPE_PILOT); } force = get_local_entity_child_succ (force, LIST_TYPE_FORCE); } }
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; }
void show_weapon_loading_page (entity *group, int force_update) { gunship_types type; int loop; entity *en, *pilot, *member; ui_object *new_item; ASSERT (group); // // Reconstruct List // if (force_update) { ui_object_destroy_list_items (page_member_list); set_ui_object_vslider_virtual_position (get_ui_object_vslider (page_member_area), 0.0); set_ui_object_item_number (page_member_list, ENTITY_INDEX_DONT_CARE); member = get_local_entity_first_child (group, LIST_TYPE_MEMBER); ASSERT (member); while (member) { sprintf (buffer, "1-%d %s", get_local_entity_int_value (member, INT_TYPE_GROUP_MEMBER_ID), get_local_entity_string (member, STRING_TYPE_SHORT_DISPLAY_NAME)); pilot = get_local_entity_first_child (member, LIST_TYPE_AIRCREW); if (pilot) { sprintf (buffer, "1-%d %s (%s)", get_local_entity_int_value (member, INT_TYPE_GROUP_MEMBER_ID), get_local_entity_string (member, STRING_TYPE_SHORT_DISPLAY_NAME), get_local_entity_string (pilot, STRING_TYPE_PILOTS_NAME)); } if (get_local_entity_int_value (member, INT_TYPE_GUNSHIP_TYPE) < NUM_GUNSHIP_TYPES) { new_item = add_to_pop_up_list (buffer, page_member_list, NULL, get_local_entity_safe_index (member), UI_FONT_ARIAL_14, ui_ingame_live_text_colour); set_ui_mouse_over_entity_function (new_item); set_ui_object_notify_on (new_item, NOTIFY_TYPE_BUTTON_DOWN); } else { new_item = add_to_pop_up_list (buffer, page_member_list, NULL, get_local_entity_safe_index (member), UI_FONT_ARIAL_14, ui_ingame_dead_text_colour); set_ui_object_notify_on (new_item, NOTIFY_TYPE_NONE); } if (member == get_gunship_entity ()) { set_ui_object_state (new_item, UI_OBJECT_STATE_ON); set_ui_object_item_number (page_member_list, get_local_entity_safe_index (member)); } member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER); } resize_pop_up_list (page_member_list); } // // Show weapon loading page // for (loop = 0; loop < NUM_GUNSHIP_TYPES; loop ++) { set_ui_object_drawable (weapon_loading_page [loop], FALSE); set_ui_object_item_number (weapon_loading_page [loop], ENTITY_INDEX_DONT_CARE); } en = get_local_entity_safe_ptr (get_ui_object_item_number (page_member_list)); ASSERT (en); type = get_local_entity_int_value (en, INT_TYPE_GUNSHIP_TYPE); if (get_local_entity_int_value (en, INT_TYPE_GUNSHIP_TYPE) < NUM_GUNSHIP_TYPES) { weapon_loading_update_currently_selected_weapons (en); set_ui_object_drawable (weapon_loading_page [type], TRUE); set_ui_object_item_number (weapon_loading_page [type], get_local_entity_safe_index (en)); } // // Default payload list // rebuild_default_payload_list (en); display_campaign_page (CAMPAIGN_PAGE_WEAPON_LOADING, get_local_entity_safe_index (group), TRUE); }
int amalgamate_groups (entity *receiving_group, entity *donating_group) { entity *this_member, *member; int group_type, group_kills, group_losses, donating_group_count, receiving_group_count; ASSERT (get_comms_model () == COMMS_MODEL_SERVER); // check both groups are not doing any tasks ASSERT (get_local_entity_int_value (receiving_group, INT_TYPE_GROUP_MODE) == GROUP_MODE_IDLE); ASSERT (get_local_entity_int_value (donating_group, INT_TYPE_GROUP_MODE) == GROUP_MODE_IDLE); // check group type are the same group_type = get_local_entity_int_value (receiving_group, INT_TYPE_ENTITY_SUB_TYPE); if (group_type != get_local_entity_int_value (donating_group, INT_TYPE_ENTITY_SUB_TYPE)) { return FALSE; } ASSERT (group_database [group_type].amalgamate); ASSERT (get_local_entity_int_value (donating_group, INT_TYPE_SIDE) == get_local_entity_int_value (receiving_group, INT_TYPE_SIDE)); donating_group_count = get_local_entity_int_value (donating_group, INT_TYPE_MEMBER_COUNT); receiving_group_count = get_local_entity_int_value (receiving_group, INT_TYPE_MEMBER_COUNT); if ((donating_group_count + receiving_group_count) <= group_database [group_type].maximum_member_count) { #ifdef DEBUG //#if DEBUG_MODULE if ((get_local_entity_parent (donating_group, LIST_TYPE_KEYSITE_GROUP)) && (get_local_entity_parent (receiving_group, LIST_TYPE_KEYSITE_GROUP))) { ASSERT (get_local_entity_type (get_local_entity_parent (donating_group, LIST_TYPE_KEYSITE_GROUP)) == get_local_entity_type (get_local_entity_parent (receiving_group, LIST_TYPE_KEYSITE_GROUP))); } debug_log ("GROUP: amalgamating group %s %d (count %d) with group %s %d (count %d)", entity_sub_type_group_names [group_type], get_local_entity_index (donating_group), donating_group_count, entity_sub_type_group_names [group_type], get_local_entity_index (receiving_group), receiving_group_count); member = get_local_entity_first_child (donating_group, LIST_TYPE_MEMBER); while (member) { debug_log ("GROUP: donating group member %s (%d)", get_local_entity_string (member, STRING_TYPE_FULL_NAME), get_local_entity_index (member)); ASSERT (get_local_entity_int_value (member, INT_TYPE_OPERATIONAL_STATE) == OPERATIONAL_STATE_LANDED); member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER); } member = get_local_entity_first_child (receiving_group, LIST_TYPE_MEMBER); while (member) { debug_log ("GROUP: receiving group member %s (%d)", get_local_entity_string (member, STRING_TYPE_FULL_NAME), get_local_entity_index (member)); ASSERT (get_local_entity_int_value (member, INT_TYPE_OPERATIONAL_STATE) == OPERATIONAL_STATE_LANDED); member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER); } //#endif #endif member = get_local_entity_first_child (donating_group, LIST_TYPE_MEMBER); while (member) { this_member = member; member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER); set_client_server_entity_parent (this_member, LIST_TYPE_MEMBER, receiving_group); } group_kills = get_local_entity_int_value (receiving_group, INT_TYPE_KILLS); group_losses = get_local_entity_int_value (receiving_group, INT_TYPE_LOSSES); group_kills += get_local_entity_int_value (donating_group, INT_TYPE_KILLS); group_losses += get_local_entity_int_value (donating_group, INT_TYPE_LOSSES); if (get_local_entity_int_value (receiving_group, INT_TYPE_KILLS) != group_kills) { set_client_server_entity_int_value (receiving_group, INT_TYPE_KILLS, group_kills); } if (get_local_entity_int_value (receiving_group, INT_TYPE_LOSSES) != group_losses) { set_client_server_entity_int_value (receiving_group, INT_TYPE_LOSSES, group_losses); } // // renumber the group members // set_group_member_numbers (receiving_group); // // place empty donating group on free list // ASSERT (get_local_entity_int_value (donating_group, INT_TYPE_MEMBER_COUNT) == 0); kill_client_server_group_entity (donating_group); #ifdef DEBUG { vec3d *pos1, *test_pos; float amalgamate_max_range = 10 * KILOMETRE; member = get_local_entity_first_child (receiving_group, LIST_TYPE_MEMBER); ASSERT (member); pos1 = get_local_entity_vec3d_ptr (member, VEC3D_TYPE_POSITION); member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER); while (member) { test_pos = get_local_entity_vec3d_ptr (member, VEC3D_TYPE_POSITION); if (get_2d_range (pos1, test_pos) > amalgamate_max_range) { debug_log ("GROUP: WARNING: Amalgamated group with members (%s (%d) and %s (%d)) %f apart -------------------------", get_local_entity_string (get_local_entity_first_child (receiving_group, LIST_TYPE_MEMBER), STRING_TYPE_FULL_NAME), get_local_entity_index (get_local_entity_first_child (receiving_group, LIST_TYPE_MEMBER)), get_local_entity_string (member, STRING_TYPE_FULL_NAME), get_local_entity_index (member), get_2d_range (pos1, test_pos)); } member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER); } } #endif return TRUE; } return FALSE; }
void show_base_page (entity *base, int force_update) { entity *previous; vec3d *pos; int x, z; char s [128]; ASSERT (base); ASSERT (get_local_entity_type (base) == ENTITY_TYPE_KEYSITE); if (force_update) { previous = NULL; } else { previous = get_local_entity_safe_ptr (get_ui_object_item_number (campaign_page [CAMPAIGN_PAGE_BASE])); } pos = get_local_entity_vec3d_ptr (base, VEC3D_TYPE_POSITION); ASSERT (pos); // // NAME // set_ui_object_text (base_page_title, get_local_entity_string (base, STRING_TYPE_KEYSITE_NAME)); // // TYPE // set_ui_object_text (base_page_type_box, get_trans (get_local_entity_string (base, STRING_TYPE_FULL_NAME))); // // LOCATION // get_x_sector (x, pos->x); get_z_sector (z, pos->z); sprintf (s, "[%03d, %03d]", x, z); set_ui_object_text (base_page_sector_box, s); // // 3D WINDOW // set_ui_object_item_number (page_3d_area, get_local_entity_index (base)); if (base != previous) { page_3d_heading = 0.0; page_3d_pitch = (PI * 0.25); page_3d_distance = max (50.0, get_local_entity_float_value (base, FLOAT_TYPE_RECON_DISTANCE)); } // // 2D MAP // set_ui_object_item_number (page_map_area, get_local_entity_index (base)); if (base != previous) { page_map_dimensions.x = pos->x; page_map_dimensions.z = pos->z; page_map_dimensions.subject_entity = base; } // display_campaign_page (CAMPAIGN_PAGE_BASE, get_local_entity_index (base), TRUE); }
void assess_group_supplies (entity *en) { entity *keysite, *force; group *raw; float required, level; raw = get_local_entity_data (en); if (get_local_entity_int_value (en, INT_TYPE_RESUPPLY_SOURCE) == RESUPPLY_SOURCE_GROUP) { // // Check if Group needs to request Supplies via Mission... // if (raw->supplies.ammo_supply_level < 100.0) { force = get_local_force_entity (get_local_entity_int_value (en, INT_TYPE_SIDE)); #if DEBUG_MODULE || DEBUG_SUPPLY debug_log ("GROUP: SUPPLY_INFO: ground group %s low on ammo, requesting Supply mission", get_local_entity_string (en, STRING_TYPE_FULL_NAME)); #endif notify_local_entity (ENTITY_MESSAGE_FORCE_LOW_ON_SUPPLIES, force, en, ENTITY_SUB_TYPE_CARGO_AMMO); } else if (raw->supplies.fuel_supply_level < 100.0) { force = get_local_force_entity (get_local_entity_int_value (en, INT_TYPE_SIDE)); #if DEBUG_MODULE || DEBUG_SUPPLY debug_log ("GROUP: SUPPLY_INFO: ground group %s low on fuel, requesting Supply mission", get_local_entity_string (en, STRING_TYPE_FULL_NAME)); #endif notify_local_entity (ENTITY_MESSAGE_FORCE_LOW_ON_SUPPLIES, force, en, ENTITY_SUB_TYPE_CARGO_FUEL); } } else if (get_local_entity_int_value (en, INT_TYPE_RESUPPLY_SOURCE) == RESUPPLY_SOURCE_KEYSITE) { // // check all group is landed. If so refuel/rearm group via keysite supplies // if (get_local_entity_int_value (en, INT_TYPE_GROUP_MODE) == GROUP_MODE_IDLE) { if (raw->supplies.ammo_supply_level < 100.0) { // // re-arm // keysite = get_local_entity_parent (en, LIST_TYPE_KEYSITE_GROUP); if ((!keysite) || (get_local_entity_type (keysite) != ENTITY_TYPE_KEYSITE)) { keysite = get_closest_keysite (NUM_ENTITY_SUB_TYPE_KEYSITES, raw->side, get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION), 1.0 * KILOMETRE, NULL, NULL); } ASSERT (keysite); level = get_local_entity_float_value (keysite, FLOAT_TYPE_AMMO_SUPPLY_LEVEL); required = 100.0 - (raw->supplies.ammo_supply_level * AMMO_USAGE_ACCELERATOR); required = bound (required, 0.0, level); level -= required; set_client_server_entity_float_value (keysite, FLOAT_TYPE_AMMO_SUPPLY_LEVEL, level); set_client_server_entity_float_value (en, FLOAT_TYPE_AMMO_SUPPLY_LEVEL, raw->supplies.ammo_supply_level + required); #if DEBUG_MODULE || DEBUG_SUPPLY debug_log ("GROUP: SUPPLY_INFO: Air group %s members landed, rearming group (now ammo = %f, fuel = %f) from keysite %s (%d) (now ammo = %f, fuel = %f)", get_local_entity_string (en, STRING_TYPE_FULL_NAME), get_local_entity_float_value (en, FLOAT_TYPE_AMMO_SUPPLY_LEVEL), get_local_entity_float_value (en, FLOAT_TYPE_FUEL_SUPPLY_LEVEL), get_local_entity_string (keysite, STRING_TYPE_FULL_NAME), get_local_entity_index (keysite), get_local_entity_float_value (keysite, FLOAT_TYPE_AMMO_SUPPLY_LEVEL), get_local_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL)); #endif } if (raw->supplies.fuel_supply_level < 100.0) { // // re-fuel // keysite = get_local_entity_parent (en, LIST_TYPE_KEYSITE_GROUP); if ((!keysite) || (get_local_entity_type (keysite) != ENTITY_TYPE_KEYSITE)) { keysite = get_closest_keysite (NUM_ENTITY_SUB_TYPE_KEYSITES, raw->side, get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION), 1.0 * KILOMETRE, NULL, NULL); } ASSERT (keysite); level = get_local_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL); required = 100.0 - (raw->supplies.fuel_supply_level * FUEL_USAGE_ACCELERATOR); required = bound (required, 0.0, level); level -= required; set_client_server_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL, level); set_client_server_entity_float_value (en, FLOAT_TYPE_FUEL_SUPPLY_LEVEL, raw->supplies.fuel_supply_level + required); #if DEBUG_MODULE || DEBUG_SUPPLY debug_log ("GROUP: SUPPLY_INFO: Air group %s members landed, refuelling group (now ammo = %f, fuel = %f) from keysite %s (%d) (now ammo = %f, fuel = %f)", get_local_entity_string (en, STRING_TYPE_FULL_NAME), get_local_entity_float_value (en, FLOAT_TYPE_AMMO_SUPPLY_LEVEL), get_local_entity_float_value (en, FLOAT_TYPE_FUEL_SUPPLY_LEVEL), get_local_entity_string (keysite, STRING_TYPE_FULL_NAME), get_local_entity_index (keysite), get_local_entity_float_value (keysite, FLOAT_TYPE_AMMO_SUPPLY_LEVEL), get_local_entity_float_value (keysite, FLOAT_TYPE_FUEL_SUPPLY_LEVEL)); #endif } } } }