void unpack_client_server_entity_data (entity *en) { if (get_comms_model () == COMMS_MODEL_SERVER) { unpack_local_entity_data (en, get_local_entity_type (en), PACK_MODE_UPDATE_ENTITY); transmit_entity_comms_message (ENTITY_COMMS_UPDATE, en); } else { ASSERT (get_comms_model () == COMMS_MODEL_CLIENT); unpack_local_entity_data (en, get_local_entity_type (en), PACK_MODE_UPDATE_ENTITY); } }
void kill_client_server_entity_sound_type (entity *en, entity_sub_types type) { entity *spec, *next; sound_effect *raw; spec = get_local_entity_first_child (en, LIST_TYPE_SPECIAL_EFFECT); while (spec) { next = get_local_entity_child_succ (spec, LIST_TYPE_SPECIAL_EFFECT); if (get_local_entity_type (spec) == ENTITY_TYPE_SOUND_EFFECT) { raw = get_local_entity_data (spec); if (raw->eff.sub_type == type) { // // "kill" sound // kill_client_server_entity (spec); } } spec = next; } }
int get_local_entity_sound_type_valid (entity *en, entity_sub_types type) { entity *spec; sound_effect *raw; spec = get_local_entity_first_child (en, LIST_TYPE_SPECIAL_EFFECT); while (spec) { if (get_local_entity_type (spec) == ENTITY_TYPE_SOUND_EFFECT) { raw = get_local_entity_data (spec); if (raw->eff.sub_type == type) { return (raw->valid_sound_effect); } } spec = get_local_entity_child_succ (spec, LIST_TYPE_SPECIAL_EFFECT); } return FALSE; }
entity *get_local_force_entity (entity_sides side) { entity *force; if (!get_session_entity ()) { return NULL; } force = get_local_entity_first_child (get_session_entity (), LIST_TYPE_FORCE); while (force) { debug_assert (get_local_entity_type (force) == ENTITY_TYPE_FORCE); if (get_local_entity_int_value (force, INT_TYPE_SIDE) == side) { return force; } force = get_local_entity_child_succ (force, LIST_TYPE_FORCE); } return NULL; }
void update_destroy_entity_statistics (entity *en) { ASSERT (en); entity_count--; entity_type_stats[get_local_entity_type (en)].count--; }
void inc_player_log_kills (int side, player_log_type *log, entity *victim) { ASSERT (victim); if (victim == get_gunship_entity ()) { inc_player_log_deaths (side, log); } else { if (get_local_entity_int_value (victim, INT_TYPE_SIDE) != get_global_gunship_side ()) { switch (get_local_entity_type (victim)) { case ENTITY_TYPE_FIXED_WING: case ENTITY_TYPE_HELICOPTER: { inc_player_log_air_kills (side, log); break; } case ENTITY_TYPE_ANTI_AIRCRAFT: case ENTITY_TYPE_ROUTED_VEHICLE: { inc_player_log_ground_kills (side, log); break; } case ENTITY_TYPE_SHIP_VEHICLE: { inc_player_log_sea_kills (side, log); break; } case ENTITY_TYPE_BRIDGE: case ENTITY_TYPE_CITY_BUILDING: case ENTITY_TYPE_SCENIC: case ENTITY_TYPE_SITE: case ENTITY_TYPE_SITE_UPDATABLE: { inc_player_log_fixed_kills (side, log); break; } default: { break; } } } else { inc_player_log_friendly_kills (side, 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; } }
entity *get_player_task (entity *en) { if (!en) { en = get_pilot_entity (); } ASSERT (en); ASSERT (get_local_entity_type (en) == ENTITY_TYPE_PILOT); return get_local_entity_parent (en, LIST_TYPE_PLAYER_TASK); }
void assess_aircraft_damage_level (entity *en, int old_damage_level, int new_damage_level) { switch (get_local_entity_type (en)) { case ENTITY_TYPE_FIXED_WING: { assess_fixed_wing_damage_level (en, old_damage_level, new_damage_level); break; } case ENTITY_TYPE_HELICOPTER: { break; } } }
int pause_local_entity_sound_type (entity *en, entity_sub_types type, float delay) { entity *spec; sound_effect *raw; int count; count = 0; spec = get_local_entity_first_child (en, LIST_TYPE_SPECIAL_EFFECT); while (spec) { if (get_local_entity_type (spec) == ENTITY_TYPE_SOUND_EFFECT) { raw = get_local_entity_data (spec); if (raw->eff.sub_type == type) { // // "pause" sound // if (raw->valid_sound_effect) { raw->valid_sound_effect = FALSE; raw->valid_effect_lifetime = delay; count ++; } } } spec = get_local_entity_child_succ (spec, LIST_TYPE_SPECIAL_EFFECT); } return count; }
void destroy_client_server_sound_effects (entity *en) { entity *spec, *next; spec = get_local_entity_first_child (en, LIST_TYPE_SPECIAL_EFFECT); while (spec) { next = get_local_entity_child_succ (spec, LIST_TYPE_SPECIAL_EFFECT); if (get_local_entity_type (spec) == ENTITY_TYPE_SOUND_EFFECT) { destroy_client_server_entity_family (spec); } spec = next; } }
static entity *create_local (entity_types type, int index, char *pargs) { char name [STRING_TYPE_KEYSITE_NAME_MAX_LENGTH]; entity *group, *force, *sector, *en; keysite *raw; //////////////////////////////////////// // // VALIDATE // //////////////////////////////////////// validate_local_create_entity_index (index); #if DEBUG_MODULE debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_CREATE, NULL, type, index); #endif en = get_free_entity (index); if (en) { //////////////////////////////////////// // // MALLOC ENTITY DATA // //////////////////////////////////////// set_local_entity_type (en, type); raw = malloc_fast_mem (sizeof (keysite)); set_local_entity_data (en, raw); //////////////////////////////////////// // // INITIALISE ALL ENTITY DATA TO 'WORKING' DEFAULT VALUES // // DO NOT USE ACCESS FUNCTIONS // // DO NOT USE RANDOM VALUES // //////////////////////////////////////// memset (raw, 0, sizeof (keysite)); sprintf (name, "KEYSITE %d", (int) en % 100); strncpy (raw->keysite_name, name, STRING_TYPE_KEYSITE_NAME_MAX_LENGTH); // // fixed // raw->position.x = MID_MAP_X; raw->position.y = MID_MAP_Y; raw->position.z = MID_MAP_Z; raw->alive = TRUE; raw->keysite_usable_state = KEYSITE_STATE_USABLE; raw->in_use = FALSE; raw->object_index = OBJECT_3D_INVALID_OBJECT_INDEX; raw->side = ENTITY_SIDE_NEUTRAL; raw->supplies.ammo_supply_level = 0.0; raw->supplies.fuel_supply_level = 0.0; raw->assign_timer = frand1 () * KEYSITE_TASK_ASSIGN_TIMER; // SERVER ONLY - OK TO USE RANDOM raw->sleep = frand1 () * KEYSITE_UPDATE_SLEEP_TIMER; // SERVER ONLY - OK TO USE RANDOM //////////////////////////////////////// // // OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES // //////////////////////////////////////// set_local_entity_attributes (en, pargs); //////////////////////////////////////// // // CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN // //////////////////////////////////////// ASSERT (raw->side != ENTITY_SIDE_NEUTRAL); ASSERT (entity_sub_type_keysite_valid (raw->sub_type)); ASSERT (keysite_database [raw->sub_type].minimum_efficiency < 1.0); // the following is currently required for the campaign to progress properly... ASSERT (keysite_database [raw->sub_type].repairable == keysite_database [raw->sub_type].troop_insertion_target); //////////////////////////////////////// // // RESOLVE DEFAULT VALUES // //////////////////////////////////////// update_keysite_cargo (en, raw->supplies.ammo_supply_level, ENTITY_SUB_TYPE_CARGO_AMMO, CARGO_AMMO_SIZE); update_keysite_cargo (en, raw->supplies.fuel_supply_level, ENTITY_SUB_TYPE_CARGO_FUEL, CARGO_FUEL_SIZE); //////////////////////////////////////// // // BUILD COMPONENTS // //////////////////////////////////////// //////////////////////////////////////// // // LINK INTO SYSTEM // //////////////////////////////////////// force = get_local_entity_parent (en, LIST_TYPE_KEYSITE_FORCE); debug_assert (get_local_entity_type (force) == ENTITY_TYPE_FORCE); ASSERT (force); sector = get_local_sector_entity (&raw->position); ASSERT (sector); insert_local_entity_into_parents_child_list (en, LIST_TYPE_KEYSITE_FORCE, force, NULL); insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, sector, NULL); insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL); set_local_entity_int_value (sector, INT_TYPE_KEYSITE_COUNT, get_local_entity_int_value (sector, INT_TYPE_KEYSITE_COUNT) + 1); if (raw->in_use) { update_imap_sector_side (en, TRUE); update_imap_importance_level (en, TRUE); update_keysite_distance_to_friendly_base (en, raw->side); } //////////////////////////////////////// // // CREATE SUB ENTITIES // //////////////////////////////////////// // for site buildings group = create_local_entity ( ENTITY_TYPE_GROUP, ENTITY_INDEX_DONT_CARE, ENTITY_ATTR_PARENT (LIST_TYPE_BUILDING_GROUP, en), ENTITY_ATTR_VEC3D (VEC3D_TYPE_POSITION, raw->position.x, raw->position.y, raw->position.z), ENTITY_ATTR_INT_VALUE (INT_TYPE_ENTITY_SUB_TYPE, ENTITY_SUB_TYPE_GROUP_BUILDINGS), ENTITY_ATTR_END ); #if DEBUG_MODULE { int sx, sz; get_x_sector (sx, raw->position.x); get_z_sector (sz, raw->position.z); debug_log ("KS_CREAT: Side %s creating keysite %s (type %d) index %d at %f, %f (%d, %d)", entity_side_short_names [raw->side], raw->keysite_name, raw->sub_type, get_local_entity_index (en), raw->position.x, raw->position.z, sx, sz); } #endif } return (en); }
static void kill_local (entity *en) { person *raw; int losses; entity *task, *destroy_task, *group; //////////////////////////////////////// // // PRE-AMBLE // //////////////////////////////////////// #if DEBUG_MODULE >= 2 debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en); #endif if (!get_local_entity_int_value (en, INT_TYPE_ALIVE)) { return; } raw = get_local_entity_data (en); //////////////////////////////////////// // // VALIDATE // //////////////////////////////////////// //////////////////////////////////////// // // KILL // //////////////////////////////////////// // must be done before alive flag set to FALSE remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en); set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE); // update person object damage_person_3d_object (en); group = get_local_entity_parent (en, LIST_TYPE_MEMBER); ASSERT (group); // // group losses // losses = get_local_entity_int_value (group, INT_TYPE_LOSSES); losses ++; set_local_entity_int_value (group, INT_TYPE_LOSSES, losses); //////////////////////////////////////// // // DESTROY COMPONENTS // //////////////////////////////////////// if (get_comms_model () == COMMS_MODEL_SERVER) { //////////////////////////////////////// // // SEND NOTIFY MESSAGES // //////////////////////////////////////// // // // task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT); while (task) { destroy_task = task; task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT); if (get_local_entity_type (destroy_task) == ENTITY_TYPE_TASK) { #if DEBUG_MODULE debug_log ("PS_DSTRY: killing person, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]); #endif notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en); } } // // Release landing lock (if any) // //release_mobile_entity_landing_locks (en); } //////////////////////////////////////// // // UNLINK FROM SYSTEM // //////////////////////////////////////// // // person // // // vehicle // unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT); unlink_local_entity_children (en, LIST_TYPE_LAUNCHED_WEAPON); delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER); delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER); // gunship_target_link // member_link // view_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE); // // mobile // // // kill weapon sound effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN); //unlink_local_entity_children (en, LIST_TYPE_SPECIAL_EFFECT); unlink_local_entity_children (en, LIST_TYPE_TARGET); delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK); // sector_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET); set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_DEAD); // // Notify Campaign Screen // notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group); // // Notify the GROUP that the mobile has been killed (N.B. must be done AFTER mobile is unlinked from member list) // if (get_comms_model () == COMMS_MODEL_SERVER) { notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en); } //////////////////////////////////////// // // SPECIAL EFFECTS // //////////////////////////////////////// set_local_entity_float_value (en, FLOAT_TYPE_DEATH_TIMER, calculate_mobile_death_timer_value (en)); if (get_comms_model () == COMMS_MODEL_SERVER) { create_client_server_object_killed_explosion_effect (en); } }
int resume_local_entity_sound_type (entity *en, entity_sub_types type) { entity *spec; sound_effect *raw; int count; count = 0; spec = get_local_entity_first_child (en, LIST_TYPE_SPECIAL_EFFECT); while (spec) { if (get_local_entity_type (spec) == ENTITY_TYPE_SOUND_EFFECT) { raw = get_local_entity_data (spec); if (raw->eff.sub_type == type) { // // "unpause" sound // if (!raw->valid_sound_effect) { // // set flag and start playing // raw->valid_sound_effect = TRUE; if (en == get_session_entity ()) { play_local_entity_sound (en, &main_vp, 0); } else { vec3d *position; viewpoint *vp; float range; vp = &main_vp; position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); range = get_approx_3d_range (&vp->position, position); play_local_entity_sound (en, vp, range); } if (!get_local_entity_parent (spec, LIST_TYPE_UPDATE)) { insert_local_entity_into_parents_child_list (spec, LIST_TYPE_UPDATE, get_update_entity (), NULL); } count ++; } } } spec = get_local_entity_child_succ (spec, LIST_TYPE_SPECIAL_EFFECT); } return count; }
void pack_local_keysite_data (pack_modes mode) { entity *en, *landing_en; landing *landing_raw; keysite *raw; ASSERT (mode != PACK_MODE_UPDATE_ENTITY); if (mode == PACK_MODE_BROWSE_SESSION) { return; } en = get_local_entity_list (); while (en) { if (get_local_entity_type (en) == ENTITY_TYPE_KEYSITE) { // // pack keysite data // pack_entity_safe_ptr (en); raw = (keysite *) get_local_entity_data (en); pack_float_value (en, FLOAT_TYPE_AMMO_SUPPLY_LEVEL, raw->supplies.ammo_supply_level); pack_float_value (en, FLOAT_TYPE_FUEL_SUPPLY_LEVEL, raw->supplies.fuel_supply_level); pack_float_value (en, FLOAT_TYPE_KEYSITE_STRENGTH, raw->keysite_strength); pack_float_value (en, FLOAT_TYPE_KEYSITE_MAXIMUM_STRENGTH, raw->keysite_maximum_strength); pack_int_value (en, INT_TYPE_ALIVE, raw->alive); pack_int_value (en, INT_TYPE_SIDE, raw->side); pack_int_value (en, INT_TYPE_IN_USE, raw->in_use); pack_int_value (en, INT_TYPE_KEYSITE_ID, raw->keysite_id); pack_int_value (en, INT_TYPE_KEYSITE_USABLE_STATE, raw->keysite_usable_state); pack_list_root (en, LIST_TYPE_UNASSIGNED_TASK, &raw->unassigned_task_root); pack_list_root (en, LIST_TYPE_ASSIGNED_TASK, &raw->assigned_task_root); pack_list_root (en, LIST_TYPE_COMPLETED_TASK, &raw->completed_task_root); // pack_list_root (en, LIST_TYPE_KEYSITE_GROUP, &raw->keysite_group_root); pack_list_root (en, LIST_TYPE_DIVISION_HEADQUARTERS, &raw->division_headquarters_root); if (raw->campaign_objective_link.parent) { pack_int_value (en, INT_TYPE_VALID, TRUE); pack_list_link (en, LIST_TYPE_CAMPAIGN_OBJECTIVE, &raw->campaign_objective_link); } else { pack_int_value (en, INT_TYPE_VALID, FALSE); } #if DEBUG_MODULE debug_log ("KS_PACK: packing up keysite %s", raw->keysite_name); #endif if (mode == PACK_MODE_SERVER_SESSION) { pack_float_value (en, FLOAT_TYPE_REPAIR_TIMER, raw->repair_timer); pack_float_value (en, FLOAT_TYPE_SLEEP, raw->sleep); pack_float_value (en, FLOAT_TYPE_ASSIST_TIMER, raw->assist_timer); pack_float_value (en, FLOAT_TYPE_ASSIGN_TIMER, raw->assign_timer); // // pack landing data // landing_en = get_local_entity_first_child (en, LIST_TYPE_LANDING_SITE); while (landing_en) { landing_raw = (landing *) get_local_entity_data (landing_en); pack_int_value (landing_en, INT_TYPE_RESERVED_LANDING_SITES, landing_raw->reserved_landing_sites); //pack_int_value (en, INT_TYPE_FREE_LANDING_SITES, landing_raw->free_landing_sites); pack_int_value (landing_en, INT_TYPE_LANDING_LOCK, landing_raw->landing_lock); pack_int_value (landing_en, INT_TYPE_LANDED_LOCK, landing_raw->landed_lock); pack_int_value (landing_en, INT_TYPE_TAKEOFF_LOCK, landing_raw->takeoff_lock); pack_list_root (landing_en, LIST_TYPE_TAKEOFF_QUEUE, &landing_raw->takeoff_queue_root); #if DEBUG_MODULE debug_log ("KS_PACK: packing up %s landing entity, reserved %d, free %d, locks (landing %d, landed %d, takeoff %d)", entity_sub_type_landing_names [landing_raw->sub_type], landing_raw->reserved_landing_sites, landing_raw->free_landing_sites, landing_raw->landing_lock, landing_raw->landed_lock, landing_raw->takeoff_lock ); #endif landing_en = get_local_entity_child_succ (landing_en, LIST_TYPE_LANDING_SITE); } } } en = get_local_entity_succ (en); } }
void unpack_local_site_updatable_data (pack_modes mode) { site_updatable *raw; entity *en; int count, alive; if ((mode != PACK_MODE_SERVER_SESSION) && (mode != PACK_MODE_CLIENT_SESSION)) { return; } // // RLE encoded // debug_log ("RLE SITE UPDATEABLE"); en = get_local_entity_list (); count = unpack_int_value (NULL, INT_TYPE_LENGTH); alive = unpack_int_value (NULL, INT_TYPE_ALIVE); #if DEBUG_MODULE debug_log ("SU_PACK: unpacking count %d, alive %d", count, alive); #endif while (en) { if (get_local_entity_type (en) == ENTITY_TYPE_SITE_UPDATABLE) { if (count == 0) { count = unpack_int_value (NULL, INT_TYPE_LENGTH); alive = unpack_int_value (NULL, INT_TYPE_ALIVE); #if DEBUG_MODULE debug_log ("SU_PACK: unpacking count %d, alive %d", count, alive); #endif } count --; raw = get_local_entity_data (en); if (!alive) { delete_local_entity_from_parents_child_list (en, LIST_TYPE_UPDATE); // must be done BEFORE alive flag set, and BEFORE shape changed // subtract_local_entity_importance_from_keysite (en); raw->fix.object_3d_shape = get_3d_object_destroyed_object_index (raw->fix.object_3d_shape); } raw->fix.alive = alive; } en = get_local_entity_succ (en); } }
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); }
void unpack_local_keysite_data (pack_modes mode) { entity *en, *landing_en; landing *landing_raw; keysite *raw; int side, landing_lock, landed_lock, takeoff_lock, in_use, index; ASSERT (mode != PACK_MODE_UPDATE_ENTITY); if (mode == PACK_MODE_BROWSE_SESSION) { return; } en = get_local_entity_list (); while (en) { if (get_local_entity_type (en) == ENTITY_TYPE_KEYSITE) { // // unpack keysite // index = unpack_entity_safe_index (); raw = (keysite *) get_local_entity_data (en); raw->supplies.ammo_supply_level = unpack_float_value (en, FLOAT_TYPE_AMMO_SUPPLY_LEVEL); raw->supplies.fuel_supply_level = unpack_float_value (en, FLOAT_TYPE_FUEL_SUPPLY_LEVEL); raw->keysite_strength = unpack_float_value (en, FLOAT_TYPE_KEYSITE_STRENGTH); raw->keysite_maximum_strength = unpack_float_value (en, FLOAT_TYPE_KEYSITE_MAXIMUM_STRENGTH); raw->alive = unpack_int_value (en, INT_TYPE_ALIVE); side = unpack_int_value (en, INT_TYPE_SIDE); if (side != raw->side) { // // update I-Maps (remove old side) // if (raw->in_use) { update_imap_sector_side (en, FALSE); if (mode == PACK_MODE_SERVER_SESSION) { update_imap_importance_level (en, FALSE); } } // // change side of keysite buildings // change_local_keysite_building_sides (en, (entity_sides) side); // // place into other sides force // delete_local_entity_from_parents_child_list (en, LIST_TYPE_KEYSITE_FORCE); insert_local_entity_into_parents_child_list (en, LIST_TYPE_KEYSITE_FORCE, get_local_force_entity ((entity_sides) side), NULL); if (mode == PACK_MODE_SERVER_SESSION) { // Must be done after removed from force update_imap_distance_to_friendly_base ((entity_sides) raw->side); } // // switch sides // raw->side = side; // // update I-Maps (add new side) // if (raw->in_use) { update_imap_sector_side (en, TRUE); if (mode == PACK_MODE_SERVER_SESSION) { update_imap_importance_level (en, TRUE); update_keysite_distance_to_friendly_base (en, (entity_sides) side); } } } in_use = unpack_int_value (en, INT_TYPE_IN_USE); raw->keysite_id = unpack_int_value (en, INT_TYPE_KEYSITE_ID); raw->keysite_usable_state = unpack_int_value (en, INT_TYPE_KEYSITE_USABLE_STATE); if (raw->in_use != in_use) { // // Update I-Maps (in use flag changed) // raw->in_use = in_use; update_imap_sector_side (en, in_use); if (mode == PACK_MODE_SERVER_SESSION) { update_imap_importance_level (en, in_use); if (in_use) { update_keysite_distance_to_friendly_base (en, (entity_sides) side); } else { update_imap_distance_to_friendly_base ((entity_sides) side); } } } unpack_list_root (en, LIST_TYPE_UNASSIGNED_TASK, &raw->unassigned_task_root); unpack_list_root (en, LIST_TYPE_ASSIGNED_TASK, &raw->assigned_task_root); unpack_list_root (en, LIST_TYPE_COMPLETED_TASK, &raw->completed_task_root); // unpack_list_root (en, LIST_TYPE_KEYSITE_GROUP, &raw->keysite_group_root); unpack_list_root (en, LIST_TYPE_DIVISION_HEADQUARTERS, &raw->division_headquarters_root); if (unpack_int_value (en, INT_TYPE_VALID)) { unpack_list_link (en, LIST_TYPE_CAMPAIGN_OBJECTIVE, &raw->campaign_objective_link); } #if DEBUG_MODULE debug_log ("KS_PACK: unpacking keysite %s", raw->keysite_name); #endif if (mode == PACK_MODE_SERVER_SESSION) { raw->repair_timer = unpack_float_value (en, FLOAT_TYPE_REPAIR_TIMER); raw->sleep = unpack_float_value (en, FLOAT_TYPE_SLEEP); raw->assist_timer = unpack_float_value (en, FLOAT_TYPE_ASSIST_TIMER); raw->assign_timer = unpack_float_value (en, FLOAT_TYPE_ASSIGN_TIMER); // // unpack landing data // landing_en = get_local_entity_first_child (en, LIST_TYPE_LANDING_SITE); while (landing_en) { landing_raw = (landing *) get_local_entity_data (landing_en); landing_raw->reserved_landing_sites = unpack_int_value (landing_en, INT_TYPE_RESERVED_LANDING_SITES); //landing_raw->free_landing_sites = unpack_int_value (en, INT_TYPE_FREE_LANDING_SITES); landing_raw->free_landing_sites = landing_raw->total_landing_sites; landing_lock = unpack_int_value (landing_en, INT_TYPE_LANDING_LOCK); landed_lock = unpack_int_value (landing_en, INT_TYPE_LANDED_LOCK); takeoff_lock = unpack_int_value (landing_en, INT_TYPE_TAKEOFF_LOCK); #if DEBUG_MODULE debug_log ("KS_PACK: %s (%d) unpacking %s landing entity, reserved %d, free %d, locks (saved :landing %d, landed %d, takeoff %d, calc landing %d, landed %d, takeoff %d)", raw->keysite_name, get_local_entity_index (en), entity_sub_type_landing_names [landing_raw->sub_type], landing_raw->reserved_landing_sites, landing_raw->free_landing_sites, landing_lock, landed_lock, takeoff_lock, landing_raw->landing_lock, landing_raw->landed_lock, landing_raw->takeoff_lock); if (landing_raw->landing_lock != landing_lock) { debug_log ("KS_PACK: %s %s landing entity needs landing_lock repairing", raw->keysite_name, entity_sub_type_landing_names [landing_raw->sub_type]); } if (landing_raw->landed_lock != landed_lock) { debug_log ("KS_PACK: %s %s landing entity needs landed_lock repairing", raw->keysite_name, entity_sub_type_landing_names [landing_raw->sub_type]); } if (landing_raw->takeoff_lock != takeoff_lock) { debug_log ("KS_PACK: %s %s landing entity needs takeoff_lock repairing", raw->keysite_name, entity_sub_type_landing_names [landing_raw->sub_type]); } #endif unpack_list_root (landing_en, LIST_TYPE_TAKEOFF_QUEUE, &landing_raw->takeoff_queue_root); landing_en = get_local_entity_child_succ (landing_en, LIST_TYPE_LANDING_SITE); } } } en = get_local_entity_succ (en); } }
static void kill_local (entity *en) { int losses; entity *task, *group, *keysite, *destroy_task; ship_vehicle *raw; //////////////////////////////////////// // // PRE-AMBLE // //////////////////////////////////////// #if DEBUG_MODULE >= 2 debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en); #endif if (!get_local_entity_int_value (en, INT_TYPE_ALIVE)) { return; } raw = (ship_vehicle *) get_local_entity_data (en); group = get_local_entity_parent (en, LIST_TYPE_MEMBER); ASSERT (group); keysite = NULL; if (tacview_is_logging()) write_tacview_unit_event(en, TACVIEW_UNIT_DESTROYED, NULL); // // update force info // remove_from_force_info (get_local_force_entity ((entity_sides) raw->vh.mob.side), en); //////////////////////////////////////// // // VALIDATE // //////////////////////////////////////// //////////////////////////////////////// // // DESTROY COMPONENTS // //////////////////////////////////////// if (get_comms_model () == COMMS_MODEL_SERVER) { task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT); while (task) { destroy_task = task; task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT); if (destroy_task->type == ENTITY_TYPE_TASK) { #if DEBUG_MODULE debug_log ("SH_DSTRY: killing ship, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]); #endif notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE); } } // // Release landing lock (if any) // release_mobile_entity_landing_locks (en); //////////////////////////////////////// // // UNLINK FROM SYSTEM // //////////////////////////////////////// // // Destroy keysite entity if ship is carrier // keysite = get_local_entity_first_child (en, LIST_TYPE_MOVEMENT_DEPENDENT); while (keysite) { if (get_local_entity_type (keysite) == ENTITY_TYPE_KEYSITE) { break; } keysite = get_local_entity_child_succ (keysite, LIST_TYPE_MOVEMENT_DEPENDENT); } } // // ship_vehicle // // // vehicle // unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT); unlink_local_entity_children (en, LIST_TYPE_MOVEMENT_DEPENDENT); delete_local_entity_from_parents_child_list (en, LIST_TYPE_MEMBER); delete_local_entity_from_parents_child_list (en, LIST_TYPE_MOVEMENT_DEPENDENT); delete_local_entity_from_parents_child_list (en, LIST_TYPE_FOLLOWER); // gunship_target_link // member_link // view_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TAKEOFF_QUEUE); // // mobile // // // kill weapon sound effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_CHAIN_GUN); // // kill engine sound effects // kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING1); kill_local_entity_sound_type (en, ENTITY_SUB_TYPE_EFFECT_SOUND_ENGINE_LOOPING2); unlink_local_entity_children (en, LIST_TYPE_TARGET); delete_local_entity_from_parents_child_list (en, LIST_TYPE_PADLOCK); // sector_link delete_local_entity_from_parents_child_list (en, LIST_TYPE_TARGET); // update_link set_local_entity_int_value (en, INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_STOPPED); //////////////////////////////////////// // // KILL // //////////////////////////////////////// // must be done before alive flag set remove_mobile_values_from_sector (get_local_entity_parent (en, LIST_TYPE_SECTOR), en); set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE); damage_ship_3d_object (en); // // group losses // losses = get_local_entity_int_value (group, INT_TYPE_LOSSES); losses ++; set_local_entity_int_value (group, INT_TYPE_LOSSES, losses); // // task losses // task = get_local_group_primary_task (group); if (task) { losses = get_local_entity_int_value (task, INT_TYPE_LOSSES); losses ++; set_local_entity_int_value (task, INT_TYPE_LOSSES, losses); } // // Notify Campaign Screen // notify_campaign_screen (CAMPAIGN_SCREEN_GROUP_REMOVE_MEMBER, group); if (get_comms_model () == COMMS_MODEL_SERVER) { // // Notify the GROUP that the mobile has been killed (N.B. must be done AFTER mobile is unlinked from member list) // notify_local_entity (ENTITY_MESSAGE_MOBILE_KILLED, group, en); // // Kill the keysite if ship is the carrier (N.B. must be done AFTER ships alive flag cleared) // if (keysite) { kill_client_server_entity (keysite); } } //////////////////////////////////////// // // SPECIAL EFFECTS // //////////////////////////////////////// if (get_comms_model () == COMMS_MODEL_SERVER) { create_client_server_object_killed_explosion_effect (en); } #if LANDING_ROUTE_CHECK destroy_debug_entity_landing_route_check (en); #endif ///////////////////////////////////////////////////////////////// // // SPECIAL_EFFECT_HOOK FOR BEING_DESTROYED // ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// // // ///////////////////////////////////////////////////////////////// }
static void pack_local_data (entity *en, pack_modes mode) { ASSERT ((mode >= 0) && (mode < NUM_PACK_MODES)); switch (mode) { //////////////////////////////////////// case PACK_MODE_SERVER_SESSION: case PACK_MODE_CLIENT_SESSION: //////////////////////////////////////// { routed_vehicle *raw; raw = (routed_vehicle *) get_local_entity_data (en); pack_entity_type (get_local_entity_type (en)); pack_entity_safe_ptr (en); // // pack vehicle data // pack_vehicle_data (en, &raw->vh, mode); ///////////////////////////////////////////////////////////////// if ((raw->vh.mob.velocity == 0.0) && (raw->desired_velocity == 0.0)) { pack_int_value (en, INT_TYPE_VALID, TRUE); } else { pack_int_value (en, INT_TYPE_VALID, FALSE); pack_float_value (en, FLOAT_TYPE_LOW_VELOCITY, raw->vh.mob.velocity); pack_float_value (en, FLOAT_TYPE_DESIRED_VELOCITY, raw->desired_velocity); } ///////////////////////////////////////////////////////////////// // // pack routed data // ///////////////////////////////////////////////////////////////// if ((raw->sub_waypoint_count == 0) && (raw->waypoint_next_index == 0) && (raw->waypoint_this_index == 0)) { pack_int_value (en, INT_TYPE_VALID, FALSE); } else { pack_int_value (en, INT_TYPE_VALID, TRUE); pack_int_value (en, INT_TYPE_SUB_WAYPOINT_COUNT, raw->sub_waypoint_count); pack_int_value (en, INT_TYPE_WAYPOINT_NEXT_INDEX, raw->waypoint_next_index); pack_int_value (en, INT_TYPE_WAYPOINT_THIS_INDEX, raw->waypoint_this_index); } ///////////////////////////////////////////////////////////////// // sub_waypoint_list reconstructed locally // // spin through special effects link and pack up local only smoke trails // pack_routed_vehicle_meta_smoke_lists (en, mode); pack_mobile_local_sound_effects (en, mode); break; } //////////////////////////////////////// case PACK_MODE_BROWSE_SESSION: //////////////////////////////////////// { break; } //////////////////////////////////////// case PACK_MODE_UPDATE_ENTITY: //////////////////////////////////////// { routed_vehicle *raw; raw = (routed_vehicle *) get_local_entity_data (en); pack_vec3d (en, VEC3D_TYPE_POSITION, &raw->vh.mob.position); pack_attitude_matrix (en, raw->vh.mob.attitude); pack_int_value (en, INT_TYPE_SUB_WAYPOINT_COUNT, raw->sub_waypoint_count); break; } } }
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; }
entity *add_group_to_division (entity *group, entity *specified_division) { entity_sides side; int count, max_count, group_type, keysite_type, division_type, main_division_type; entity *en, *force, *keysite, *division; vec3d *group_pos; ASSERT (group); ASSERT (get_comms_model () == COMMS_MODEL_SERVER); ASSERT (!get_local_entity_parent (group, LIST_TYPE_DIVISION)); group_type = get_local_entity_int_value (group, INT_TYPE_ENTITY_SUB_TYPE); group_pos = get_local_entity_vec3d_ptr (group, VEC3D_TYPE_POSITION); if (specified_division) { division = specified_division; } else { side = (entity_sides) get_local_entity_int_value (group, INT_TYPE_SIDE); force = get_local_force_entity (side); ASSERT (force); division_type = group_database [group_type].default_group_division; ASSERT (entity_sub_type_division_valid (division_type)); main_division_type = division_database [division_type].default_group_division; ASSERT (entity_sub_type_division_valid (main_division_type)); // // Find the keysite the company should be attached to // keysite = NULL; if (get_local_entity_int_value (group, INT_TYPE_GROUP_LIST_TYPE) == LIST_TYPE_KEYSITE_GROUP) { keysite = get_local_entity_parent (group, LIST_TYPE_KEYSITE_GROUP); if (!keysite) { keysite = get_closest_keysite (NUM_ENTITY_SUB_TYPE_KEYSITES, side, group_pos, 1.0 * KILOMETRE, NULL, NULL); } ASSERT (keysite); keysite_type = get_local_entity_int_value (keysite, INT_TYPE_ENTITY_SUB_TYPE); if ((keysite_type == ENTITY_SUB_TYPE_KEYSITE_AIRBASE) || (keysite_type == ENTITY_SUB_TYPE_KEYSITE_ANCHORAGE)) { // // Use keysite landed at // } else { // // Find nearest keysite (below) // keysite = NULL; } } else { if (group_database [group_type].movement_type == MOVEMENT_TYPE_SEA) { // // Find nearest carrier // keysite = get_closest_keysite (ENTITY_SUB_TYPE_KEYSITE_ANCHORAGE, side, group_pos, 0.0, NULL, NULL); } } if (!keysite) { // // Find nearest airbase // keysite = get_closest_keysite (ENTITY_SUB_TYPE_KEYSITE_AIRBASE, side, group_pos, 0.0, NULL, NULL); if (!keysite) { // // Find nearest military base // keysite = get_closest_keysite (ENTITY_SUB_TYPE_KEYSITE_MILITARY_BASE, side, group_pos, 0.0, NULL, NULL); if (!keysite) { // // Find nearest FARP // keysite = get_closest_keysite (ENTITY_SUB_TYPE_KEYSITE_FARP, side, group_pos, 0.0, NULL, NULL); } } } ASSERT (keysite); // // Check all companies at this keysite to see if they have vacancies.... // max_count = group_database [group_type].maximum_groups_per_division; division = get_local_entity_first_child (keysite, LIST_TYPE_DIVISION_HEADQUARTERS); while (division) { if (get_local_entity_int_value (division, INT_TYPE_ENTITY_SUB_TYPE) == division_type) { if (max_count == 0) { break; } count = 0; en = get_local_entity_first_child (division, LIST_TYPE_DIVISION); while (en) { ASSERT (get_local_entity_type (en) == ENTITY_TYPE_GROUP); count ++; en = get_local_entity_child_succ (en, LIST_TYPE_DIVISION); } if (count < max_count) { break; } } division = get_local_entity_child_succ (division, LIST_TYPE_DIVISION_HEADQUARTERS); } if (division) { // // found an existing division with space available // } else { // // create a new division // entity *main_division; max_count = division_database [division_type].maximum_groups_per_division; main_division = get_local_entity_first_child (force, LIST_TYPE_DIVISION); while (main_division) { if (get_local_entity_int_value (main_division, INT_TYPE_ENTITY_SUB_TYPE) == main_division_type) { // // check division for vacancies // if (max_count == 0) { break; } count = 0; en = get_local_entity_first_child (main_division, LIST_TYPE_DIVISION); while (en) { ASSERT (get_local_entity_type (en) == ENTITY_TYPE_DIVISION); if (get_local_entity_int_value (en, INT_TYPE_ENTITY_SUB_TYPE) == division_type) { count ++; } en = get_local_entity_child_succ (en, LIST_TYPE_DIVISION); } if (count < max_count) { break; } } main_division = get_local_entity_child_succ (main_division, LIST_TYPE_DIVISION); } if (main_division) { // // found an existing division with space available // } else { // // create a new division // main_division = create_new_division (main_division_type, side, force, NULL, FALSE); } ASSERT (main_division); division = create_new_division (division_type, side, main_division, keysite, FALSE); } } ASSERT (division); set_client_server_entity_parent (group, LIST_TYPE_DIVISION, division); return division; }
static void pack_local_data (entity *en, pack_modes mode) { ASSERT ((mode >= 0) && (mode < NUM_PACK_MODES)); switch (mode) { //////////////////////////////////////// case PACK_MODE_SERVER_SESSION: case PACK_MODE_CLIENT_SESSION: //////////////////////////////////////// { sound_effect *raw; int loop; raw = get_local_entity_data (en); if (effect_database [raw->eff.sub_type].constructed_locally) { return; } if (mode == PACK_MODE_SERVER_SESSION) { if (get_local_entity_type (raw->eff.special_effect_link.parent) == ENTITY_TYPE_SESSION) { return; } } pack_entity_type (get_local_entity_type (en)); pack_entity_safe_ptr (en); // // pack effect data // pack_effect_data (en, &raw->eff, mode); // // pack sound effect data // pack_int_value (en, INT_TYPE_SOUND_EFFECT_SEQUENCE_COUNT, raw->sound_effect_sequence_count); for (loop = 0; loop < raw->sound_effect_sequence_count; loop ++) { pack_int_value (en, INT_TYPE_SOUND_EFFECT_INDEX, raw->effect_index [loop]); } pack_float_value (en, FLOAT_TYPE_AMPLIFICATION, raw->amplification); pack_float_value (en, FLOAT_TYPE_EFFECT_LIFETIME, raw->effect_lifetime); pack_float_value (en, FLOAT_TYPE_VALID_EFFECT_LIFETIME, raw->valid_effect_lifetime); // sound_effect_data pack_int_value (en, INT_TYPE_SOUND_CHANNEL, raw->sound_channel); pack_int_value (en, INT_TYPE_SOUND_LOCALITY, raw->sound_locality); pack_int_value (en, INT_TYPE_VALID_SOUND_EFFECT, raw->valid_sound_effect); pack_int_value (en, INT_TYPE_SOUND_EFFECT_LOOPING, raw->looping); pack_int_value (en, INT_TYPE_SOUND_EFFECT_PANNING, raw->panning); if (get_local_entity_parent (en, LIST_TYPE_UPDATE)) { pack_int_value (en, INT_TYPE_VALID, TRUE); } else { pack_int_value (en, INT_TYPE_VALID, FALSE); } #if DEBUG_MODULE debug_log ("SE_PACK: Packed %d - Sub-type %d", get_local_entity_safe_index (en), raw->eff.sub_type); #endif break; } //////////////////////////////////////// case PACK_MODE_BROWSE_SESSION: //////////////////////////////////////// { break; } //////////////////////////////////////// case PACK_MODE_UPDATE_ENTITY: //////////////////////////////////////// { break; } } }
void pack_local_city_building_data (pack_modes mode) { entity *en; city_building *raw; int city_building_pack_size, city_building_count, city_building_alive, count; if ((mode != PACK_MODE_SERVER_SESSION) && (mode != PACK_MODE_CLIENT_SESSION)) { return; } debug_log ("RLE CITY BLOCK"); city_building_pack_size = 0; city_building_count = 0; city_building_alive = TRUE; count = 0; en = get_local_entity_list (); while (en) { if (get_local_entity_type (en) == ENTITY_TYPE_CITY_BUILDING) { count ++; raw = get_local_entity_data (en); if (city_building_alive == raw->fix.alive) { city_building_count ++; } else { pack_int_value (NULL, INT_TYPE_LENGTH, city_building_count); city_building_pack_size += NUM_LENGTH_BITS; pack_int_value (NULL, INT_TYPE_ALIVE, city_building_alive); city_building_pack_size += NUM_ALIVE_BITS; city_building_alive = raw->fix.alive; city_building_count = 1; } } en = get_local_entity_succ (en); } pack_int_value (NULL, INT_TYPE_LENGTH, city_building_count); city_building_pack_size += NUM_LENGTH_BITS; pack_int_value (NULL, INT_TYPE_ALIVE, city_building_alive); city_building_pack_size += NUM_ALIVE_BITS; //debug_log ("CB_PACK: packing %d city_building took %d bytes (%d bits)", count, city_building_pack_size / 8, city_building_pack_size); }
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 pack_local_site_updatable_data (pack_modes mode) { entity *en; site_updatable *raw; int pack_size, count, alive, total; if ((mode != PACK_MODE_SERVER_SESSION) && (mode != PACK_MODE_CLIENT_SESSION)) { return; } debug_log ("RLE SITE UPDATEABLE"); pack_size = 0; count = 0; alive = TRUE; total = 0; en = get_local_entity_list (); while (en) { if (get_local_entity_type (en) == ENTITY_TYPE_SITE_UPDATABLE) { total ++; raw = get_local_entity_data (en); if (alive == raw->fix.alive) { count ++; } else { pack_int_value (NULL, INT_TYPE_LENGTH, count); pack_size += NUM_LENGTH_BITS; pack_int_value (NULL, INT_TYPE_ALIVE, alive); pack_size += NUM_ALIVE_BITS; #if DEBUG_MODULE debug_log ("SU_PACK: packing count %d, alive %d", count, alive); #endif alive = raw->fix.alive; count = 1; } } en = get_local_entity_succ (en); } pack_int_value (NULL, INT_TYPE_LENGTH, count); pack_size += NUM_LENGTH_BITS; pack_int_value (NULL, INT_TYPE_ALIVE, alive); pack_size += NUM_ALIVE_BITS; #if DEBUG_MODULE debug_log ("SU_PACK: packing count %d, alive %d", count, alive); #endif //debug_log ("SU_PACK: packing %d entities took %d bytes (%d bits)", total, pack_size / 8, pack_size); }
static entity *create_local (entity_types type, int index, char *pargs) { entity *en; routed_vehicle *raw; entity_sub_types group_sub_type; float heading; vec3d *face_normal; //////////////////////////////////////// // // VALIDATE // //////////////////////////////////////// validate_local_create_entity_index (index); #if DEBUG_MODULE debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_CREATE, NULL, type, index); #endif en = get_free_entity (index); if (en) { //////////////////////////////////////// // // MALLOC ENTITY DATA // //////////////////////////////////////// set_local_entity_type (en, type); raw = malloc_fast_mem (sizeof (routed_vehicle)); set_local_entity_data (en, raw); //////////////////////////////////////// // // INITIALISE ALL ENTITY DATA TO 'WORKING' DEFAULT VALUES // // DO NOT USE ACCESS FUNCTIONS // // DO NOT USE RANDOM VALUES // //////////////////////////////////////// memset (raw, 0, sizeof (routed_vehicle)); // // mobile // raw->vh.mob.sub_type = ENTITY_SUB_TYPE_UNINITIALISED; raw->vh.mob.position.x = MID_MAP_X; raw->vh.mob.position.y = MID_MAP_Y; raw->vh.mob.position.z = MID_MAP_Z; get_identity_matrix3x3 (raw->vh.mob.attitude); raw->vh.mob.alive = TRUE; raw->vh.mob.side = ENTITY_SIDE_UNINITIALISED; raw->vh.operational_state = OPERATIONAL_STATE_UNKNOWN; // // vehicle // raw->vh.object_3d_shape = OBJECT_3D_INVALID_OBJECT_INDEX; raw->vh.weapon_config_type = WEAPON_CONFIG_TYPE_UNINITIALISED; raw->vh.selected_weapon = ENTITY_SUB_TYPE_WEAPON_NO_WEAPON; raw->vh.weapon_vector.x = 0.0; raw->vh.weapon_vector.y = 0.0; raw->vh.weapon_vector.z = 1.0; raw->vh.weapon_to_target_vector.x = 0.0; raw->vh.weapon_to_target_vector.y = 0.0; raw->vh.weapon_to_target_vector.z = -1.0; raw->vh.loading_door_state = VEHICLE_LOADING_DOORS_OPEN_FLOAT_VALUE; // // routed // //////////////////////////////////////// // // OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES // //////////////////////////////////////// set_local_entity_attributes (en, pargs); //////////////////////////////////////// // // CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN // //////////////////////////////////////// ASSERT (raw->vh.member_link.parent); ASSERT (get_local_entity_type (raw->vh.member_link.parent) == ENTITY_TYPE_GROUP); //////////////////////////////////////// // // RESOLVE DEFAULT VALUES // //////////////////////////////////////// raw->sub_route = NULL; // // side // if (raw->vh.mob.side == ENTITY_SIDE_UNINITIALISED) { raw->vh.mob.side = get_local_entity_int_value (raw->vh.member_link.parent, INT_TYPE_SIDE); } ASSERT (raw->vh.mob.side != ENTITY_SIDE_NEUTRAL); // // sub_type // if (raw->vh.mob.sub_type == ENTITY_SUB_TYPE_UNINITIALISED) { group_sub_type = get_local_entity_int_value (raw->vh.member_link.parent, INT_TYPE_ENTITY_SUB_TYPE); if (raw->vh.mob.side == ENTITY_SIDE_BLUE_FORCE) { raw->vh.mob.sub_type = group_database[group_sub_type].default_blue_force_sub_type; } else { raw->vh.mob.sub_type = group_database[group_sub_type].default_red_force_sub_type; } } ASSERT (entity_sub_type_vehicle_valid (raw->vh.mob.sub_type)); // // 3D shape // if (raw->vh.object_3d_shape == OBJECT_3D_INVALID_OBJECT_INDEX) { raw->vh.object_3d_shape = vehicle_database[raw->vh.mob.sub_type].default_3d_shape; } // // weapon config // if (raw->vh.weapon_config_type == WEAPON_CONFIG_TYPE_UNINITIALISED) { raw->vh.weapon_config_type = vehicle_database[raw->vh.mob.sub_type].default_weapon_config_type; } ASSERT (weapon_config_type_valid (raw->vh.weapon_config_type)); // // damage levels // raw->vh.damage_level = vehicle_database[raw->vh.mob.sub_type].initial_damage_level; // // radar dish rotation (ok to use a random number as this is for visual effect only) // raw->vh.radar_rotation_state = frand1 (); //////////////////////////////////////// // // BUILD COMPONENTS // //////////////////////////////////////// // // 3D object // raw->vh.inst3d = construct_3d_object (raw->vh.object_3d_shape); set_routed_vehicle_id_number (en); set_initial_rotation_angle_of_routed_vehicle_wheels (raw->vh.inst3d); // // align with terrain // get_3d_terrain_point_data (raw->vh.mob.position.x, raw->vh.mob.position.z, &raw->vh.terrain_info); heading = get_heading_from_attitude_matrix (raw->vh.mob.attitude); face_normal = get_3d_terrain_point_data_normal (&raw->vh.terrain_info); get_3d_transformation_matrix_from_face_normal_and_heading (raw->vh.mob.attitude, face_normal, heading); // // weapon config // raw->vh.weapon_package_status_array = malloc_fast_mem (SIZE_WEAPON_PACKAGE_STATUS_ARRAY); memset (raw->vh.weapon_package_status_array, 0, SIZE_WEAPON_PACKAGE_STATUS_ARRAY); load_local_entity_weapon_config (en); // // update force info // add_to_force_info (get_local_force_entity (raw->vh.mob.side), en); //////////////////////////////////////// // // LINK INTO SYSTEM // //////////////////////////////////////// insert_local_entity_into_parents_child_list (en, LIST_TYPE_MEMBER, raw->vh.member_link.parent, raw->vh.member_link.child_pred); // // insert into LIST_TYPE_MEMBER before LIST_TYPE_VIEW // insert_local_entity_into_parents_child_list (en, LIST_TYPE_VIEW, get_camera_entity (), get_local_entity_view_list_pred (en)); insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, get_local_sector_entity (&raw->vh.mob.position), NULL); insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL); } return (en); }
void update_aircraft_decoy_release (entity *en) { aircraft *raw; int chaff_available, flare_available, chaff_released, flare_released; float range, velocity, time_to_impact; entity_sub_types weapon_sub_type; entity *persuer; vec3d *target_position, *weapon_position; ASSERT (en); #ifdef DEBUG if (get_comms_model () == COMMS_MODEL_CLIENT) { ASSERT (en == get_gunship_entity ()); } #endif raw = get_local_entity_data (en); //////////////////////////////////////// // // update timer // //////////////////////////////////////// raw->decoy_release_timer -= get_delta_time (); if (raw->decoy_release_timer >= 0.0) { return; } raw->decoy_release_timer = 2.0 + frand1 (); //////////////////////////////////////// // // validate // //////////////////////////////////////// if (en == get_gunship_entity ()) { if (!get_global_auto_counter_measures ()) { return; } } else if (get_local_entity_int_value (en, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI) { return; } if (!get_local_entity_int_value (en, INT_TYPE_AIRBORNE_AIRCRAFT)) { return; } persuer = get_local_entity_first_child (en, LIST_TYPE_TARGET); if (!persuer) { return; } chaff_available = get_local_entity_weapon_available (en, ENTITY_SUB_TYPE_WEAPON_CHAFF); flare_available = get_local_entity_weapon_available (en, ENTITY_SUB_TYPE_WEAPON_FLARE); if (!(chaff_available || flare_available)) { return; } //////////////////////////////////////// // // check all persuers // //////////////////////////////////////// target_position = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); chaff_released = FALSE; flare_released = FALSE; while (persuer) { if (get_local_entity_type (persuer) == ENTITY_TYPE_WEAPON) { if (get_local_entity_int_value (persuer, INT_TYPE_WEAPON_GUIDANCE_TYPE) != WEAPON_GUIDANCE_TYPE_NONE) { weapon_sub_type = get_decoy_type_for_weapon (persuer); if (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_CHAFF) { if (chaff_available) { if (!chaff_released) { weapon_position = get_local_entity_vec3d_ptr (persuer, VEC3D_TYPE_POSITION); range = get_approx_3d_range (weapon_position, target_position); velocity = get_local_entity_float_value (persuer, FLOAT_TYPE_VELOCITY); time_to_impact = range / max (velocity, 1.0); if (time_to_impact < 10.0) { launch_client_server_weapon (en, ENTITY_SUB_TYPE_WEAPON_CHAFF); chaff_released = TRUE; if (flare_released) { break; } } } } } else if (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_FLARE) { if (flare_available) { if (!flare_released) { weapon_position = get_local_entity_vec3d_ptr (persuer, VEC3D_TYPE_POSITION); range = get_approx_3d_range (weapon_position, target_position); velocity = get_local_entity_float_value (persuer, FLOAT_TYPE_VELOCITY); time_to_impact = range / max (velocity, 1.0); if (time_to_impact < 10.0) { launch_client_server_weapon (en, ENTITY_SUB_TYPE_WEAPON_FLARE); flare_released = TRUE; if (chaff_released) { break; } } } } } } } persuer = get_local_entity_child_succ (persuer, LIST_TYPE_TARGET); } }
void unpack_local_city_building_data (pack_modes mode) { city_building *raw; entity *destroy_en, *en; int city_building_count, city_building_alive; if ((mode != PACK_MODE_SERVER_SESSION) && (mode != PACK_MODE_CLIENT_SESSION)) { return; } // // RLE encoded // debug_log ("RLE CITY BLOCK"); en = get_local_entity_list (); city_building_count = unpack_int_value (NULL, INT_TYPE_LENGTH); city_building_alive = unpack_int_value (NULL, INT_TYPE_ALIVE); while (en) { destroy_en = en; en = get_local_entity_succ (en); if (get_local_entity_type (destroy_en) == ENTITY_TYPE_CITY_BUILDING) { if (city_building_count == 0) { city_building_count = unpack_int_value (NULL, INT_TYPE_LENGTH); city_building_alive = unpack_int_value (NULL, INT_TYPE_ALIVE); } city_building_count --; raw = get_local_entity_data (destroy_en); raw->fix.alive = city_building_alive; if (!city_building_alive) { raw->fix.object_3d_shape = get_3d_object_destroyed_object_index (raw->fix.object_3d_shape); } } } }
void set_camera_mode (camera *raw, camera_modes mode, int auto_edit) { ASSERT (raw); /* if ((mode >= 0) && (mode < NUM_CAMERA_MODES)) { debug_log ("Setting camera mode to %s", camera_mode_names[mode]); }*/ // Jabberwock 031009 - Satellite view - only satellite view for sites if (get_local_entity_type (raw->external_view_entity) == ENTITY_TYPE_KEYSITE) { mode = CAMERA_MODE_SATELLITE; auto_edit = 0; } // Jabberwock 031009 ends if (auto_edit) { if (!raw->auto_edit) { set_status_message (get_trans ("Auto-action camera"), STATUS_MESSAGE_TYPE_CAMERA); } } else { const char *s; s = get_camera_mode_name (mode); if (s) { set_status_message (get_trans (s), STATUS_MESSAGE_TYPE_CAMERA); } } switch (mode) { //////////////////////////////////////// case CAMERA_MODE_CHASE: //////////////////////////////////////// { reset_chase_camera (raw); break; } //////////////////////////////////////// case CAMERA_MODE_END_OF_MISSION: //////////////////////////////////////// { reset_end_of_mission_camera (raw); break; } //////////////////////////////////////// case CAMERA_MODE_DROP: //////////////////////////////////////// { reset_drop_camera (raw); break; } //////////////////////////////////////// case CAMERA_MODE_STATIC: //////////////////////////////////////// { reset_static_camera (raw); break; } // Jabberwock 031009 Satellite view case CAMERA_MODE_SATELLITE: //////////////////////////////////////// { reset_satellite_camera (raw); break; } // Jabberwock 031009 ends //////////////////////////////////////// case CAMERA_MODE_EJECT: //////////////////////////////////////// { reset_eject_camera (raw); break; } //////////////////////////////////////// case CAMERA_MODE_FLY_BY: //////////////////////////////////////// { reset_fly_by_camera (raw); break; } //////////////////////////////////////// case CAMERA_MODE_CINEMATIC: //////////////////////////////////////// { reset_cinematic_camera (raw); break; } //////////////////////////////////////// case CAMERA_MODE_BUILDING: //////////////////////////////////////// { reset_building_camera (raw); break; } //////////////////////////////////////// case CAMERA_MODE_WEAPON: //////////////////////////////////////// { if (weapon_camera_valid (raw)) { reset_weapon_camera (raw); } else { mode = CAMERA_MODE_CHASE; reset_chase_camera (raw); } break; } //////////////////////////////////////// case CAMERA_MODE_WEAPON_EXPLOSION: //////////////////////////////////////// { reset_weapon_explosion_camera (raw); break; } //////////////////////////////////////// case CAMERA_MODE_DEBRIEFING: //////////////////////////////////////// { if (debriefing_camera_valid (raw)) { reset_debriefing_camera (raw); } else { mode = CAMERA_MODE_CHASE; reset_chase_camera (raw); } break; } //////////////////////////////////////// case CAMERA_MODE_RECOGNITION_GUIDE_TOP_VIEW: //////////////////////////////////////// { if (recognition_guide_top_view_camera_valid (raw)) { reset_recognition_guide_top_view_camera (raw); } else { mode = CAMERA_MODE_CHASE; reset_chase_camera (raw); } break; } //////////////////////////////////////// case CAMERA_MODE_RECOGNITION_GUIDE_SIDE_VIEW: //////////////////////////////////////// { if (recognition_guide_side_view_camera_valid (raw)) { reset_recognition_guide_side_view_camera (raw); } else { mode = CAMERA_MODE_CHASE; reset_chase_camera (raw); } break; } //////////////////////////////////////// case CAMERA_MODE_RECOGNITION_GUIDE_FRONT_VIEW: //////////////////////////////////////// { if (recognition_guide_front_view_camera_valid (raw)) { reset_recognition_guide_front_view_camera (raw); } else { mode = CAMERA_MODE_CHASE; reset_chase_camera (raw); } break; } //////////////////////////////////////// case CAMERA_MODE_RECOGNITION_GUIDE_3D_VIEW: //////////////////////////////////////// { if (recognition_guide_3d_view_camera_valid (raw)) { reset_recognition_guide_3d_view_camera (raw); } else { mode = CAMERA_MODE_CHASE; reset_chase_camera (raw); } break; } //////////////////////////////////////// case CAMERA_MODE_FREE: //////////////////////////////////////// { { mode = CAMERA_MODE_FREE; reset_free_camera (raw); } break; } //////////////////////////////////////// default: //////////////////////////////////////// { debug_fatal ("Invalid camera mode = %d", mode); break; } } raw->camera_mode = mode; raw->auto_edit = auto_edit; }