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); }
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); } }