void damage_hydraulics(int damaging) { if (damaging) { hydraulic_pressure = 0.65 + (sfrand1() * 0.1); // lose some hydraulics pressure immediately // lock cyclic in a random position damaged_lock_x_pos = sfrand1() * 50.0; damaged_lock_y_pos = 25.0 + sfrand1() * 50.0; hydraulic_pressure_loss_rate = hydraulic_pressure * frand1() * (MAX_HYDRAULICS_LOSS_RATE - MIN_HYDRAULICS_LOSS_RATE) + MIN_HYDRAULICS_LOSS_RATE; } else { hydraulic_pressure = 1.0; hydraulic_pressure_loss_rate = 0.0; } }
int set_initial_rotation_angle_of_routed_vehicle_wheels (object_3d_instance *inst3d) { object_3d_sub_object_search_data search; int depth; float ang; // // vary wheel start positions (ok to use a random number as this is for visual effect only) // ASSERT (inst3d); // // fixed wheels // depth = 0; while (TRUE) { search.search_depth = depth; search.search_object = inst3d; search.sub_object_index = OBJECT_3D_SUB_OBJECT_FIXED_WHEEL; if (find_object_3d_sub_object (&search) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { ang = sfrand1() * PI; search.result_sub_object->relative_pitch = ang; } else { break; } depth++; } // // steerable wheels // depth = 0; while (TRUE) { search.search_depth = depth; search.search_object = inst3d; search.sub_object_index = OBJECT_3D_SUB_OBJECT_STEERABLE_WHEEL; if (find_object_3d_sub_object (&search) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { ang = sfrand1() * PI; search.result_sub_object->relative_pitch = ang; } else { break; } depth++; } return TRUE; }
void dynamics_damage_model (unsigned int damage, int random) { dynamics_damage_types damage_array [NUM_DYNAMIC_DAMAGES]; int count; dynamics_damage_types this_damage; if (!get_session_entity ()) { return; } if (get_local_entity_int_value (get_gunship_entity (), INT_TYPE_INVULNERABLE_FROM_COLLISIONS)) { // if invulnerable only allow damage/use of fire extinguisher damage = damage & DYNAMICS_DAMAGE_FIRE_EXTINGUISHER; } if (random) { damage_array [0] = DYNAMICS_DAMAGE_NONE; this_damage = DYNAMICS_DAMAGE_NONE; count = 1; while (this_damage < NUM_DYNAMICS_DAMAGE_TYPES) { if (damage & this_damage) { damage_array [count] = this_damage; count ++; } this_damage = this_damage << 1; } damage = damage_array [rand16 () % count]; #if DYNAMICS_DEBUG debug_log ("DYNAMICS: randomly selecting damage %d", damage); #endif } notify_avionics_of_dynamics_fault (damage); this_damage = DYNAMICS_DAMAGE_NONE; while (this_damage < NUM_DYNAMICS_DAMAGE_TYPES) { if ((damage & this_damage) && (!(current_flight_dynamics->dynamics_damage & this_damage))) { switch (this_damage) { case DYNAMICS_DAMAGE_NONE: { #if DYNAMICS_DEBUG debug_log ("DYNAMICS: no damage"); #endif current_flight_dynamics->dynamics_damage = DYNAMICS_DAMAGE_NONE; current_flight_dynamics->main_blade_pitch.damaged = FALSE; current_flight_dynamics->main_rotor_roll_angle.damaged = FALSE; current_flight_dynamics->main_rotor_pitch_angle.damaged = FALSE; current_flight_dynamics->main_rotor_rpm.damaged = FALSE; current_flight_dynamics->tail_blade_pitch.damaged = FALSE; current_flight_dynamics->tail_rotor_rpm.damaged = FALSE; current_flight_dynamics->left_engine_torque.damaged = FALSE; current_flight_dynamics->left_engine_rpm.damaged = FALSE; current_flight_dynamics->right_engine_torque.damaged = FALSE; current_flight_dynamics->right_engine_rpm.damaged = FALSE; current_flight_dynamics->cross_coupling_effect.damaged = FALSE; current_flight_dynamics->input_data.cyclic_x.damaged = FALSE; current_flight_dynamics->input_data.cyclic_y.damaged = FALSE; current_flight_dynamics->input_data.cyclic_x_trim.damaged = FALSE; current_flight_dynamics->input_data.cyclic_y_trim.damaged = FALSE; break; } case DYNAMICS_DAMAGE_MAIN_ROTOR: { //#if DYNAMICS_DEBUG debug_log ("DYNAMICS: main rotor damage"); //#endif current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_MAIN_ROTOR; current_flight_dynamics->main_blade_pitch.damaged = TRUE; current_flight_dynamics->main_rotor_roll_angle.damaged = TRUE; current_flight_dynamics->main_rotor_pitch_angle.damaged = TRUE; current_flight_dynamics->main_rotor_rpm.damaged = TRUE; set_client_server_entity_int_value (get_gunship_entity (), INT_TYPE_MAIN_ROTOR_DAMAGED, TRUE); play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_MAIN_ROTOR_DAMAGED); set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE); set_current_flight_dynamics_auto_pilot (FALSE); break; } case DYNAMICS_DAMAGE_TAIL_ROTOR: { //#if DYNAMICS_DEBUG debug_log ("DYNAMICS: tail rotor damage"); //#endif current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_TAIL_ROTOR; current_flight_dynamics->tail_blade_pitch.damaged = TRUE; current_flight_dynamics->tail_rotor_rpm.damaged = TRUE; current_flight_dynamics->cross_coupling_effect.damaged = TRUE; set_client_server_entity_int_value (get_gunship_entity (), INT_TYPE_TAIL_ROTOR_DAMAGED, TRUE); play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_TAIL_ROTOR_DAMAGED); set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE); set_current_flight_dynamics_auto_pilot (FALSE); break; } case DYNAMICS_DAMAGE_LEFT_ENGINE: { //#if DYNAMICS_DEBUG debug_log ("DYNAMICS: left engine damage"); //#endif current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_LEFT_ENGINE; current_flight_dynamics->left_engine_torque.damaged = TRUE; current_flight_dynamics->left_engine_rpm.damaged = TRUE; play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_LEFT_ENGINE_FAILURE); set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE); set_current_flight_dynamics_auto_pilot (FALSE); break; } case DYNAMICS_DAMAGE_RIGHT_ENGINE: { //#if DYNAMICS_DEBUG debug_log ("DYNAMICS: right engine damage"); //#endif current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_RIGHT_ENGINE; current_flight_dynamics->right_engine_torque.damaged = TRUE; current_flight_dynamics->right_engine_rpm.damaged = TRUE; play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_RIGHT_ENGINE_FAILURE); set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE); set_current_flight_dynamics_auto_pilot (FALSE); break; } case DYNAMICS_DAMAGE_LEFT_ENGINE_FIRE: { //#if DYNAMICS_DEBUG debug_log ("DYNAMICS: left engine fire damage"); //#endif current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_LEFT_ENGINE_FIRE; play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_LEFT_ENGINE_FIRE); set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE); set_current_flight_dynamics_auto_pilot (FALSE); break; } case DYNAMICS_DAMAGE_RIGHT_ENGINE_FIRE: { //#if DYNAMICS_DEBUG debug_log ("DYNAMICS: right engine fire damage"); //#endif current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_RIGHT_ENGINE_FIRE; play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_RIGHT_ENGINE_FIRE); set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE); set_current_flight_dynamics_auto_pilot (FALSE); break; } case DYNAMICS_DAMAGE_LOW_HYDRAULICS: { //#if DYNAMICS_DEBUG debug_log ("DYNAMICS: LOW HYDRAULICS damage"); //#endif current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_LOW_HYDRAULICS; current_flight_dynamics->input_data.cyclic_x.damaged = TRUE; current_flight_dynamics->input_data.cyclic_y.damaged = TRUE; if (sfrand1 () < 0.0) { play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_HYDRAULIC_PRESSURE_FAILURE); } else { play_client_server_cpg_message (get_gunship_entity (), 0.5, 1.0, SPEECH_CATEGORY_CPG_SYSTEMS, 1.0, SPEECH_CPG_CONTROL_SYSTEMS_DAMAGED); } set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE); set_current_flight_dynamics_auto_pilot (FALSE); break; } case DYNAMICS_DAMAGE_STABILISER: { //#if DYNAMICS_DEBUG debug_log ("DYNAMICS: STABILISER damage"); //#endif current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_STABILISER; set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE); set_current_flight_dynamics_auto_pilot (FALSE); if (sfrand1 () < 0.0) { play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_STABILISER_DAMAGED); } else { play_client_server_cpg_message (get_gunship_entity (), 0.5, 1.0, SPEECH_CATEGORY_CPG_SYSTEMS, 1.0, SPEECH_CPG_CONTROL_SYSTEMS_DAMAGED); } break; } case DYNAMICS_DAMAGE_FUEL_LEAK: { //#if DYNAMICS_DEBUG debug_log ("DYNAMICS: FUEL_LEAK damage"); //#endif current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_FUEL_LEAK; play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_FUEL_LEAK); break; } case DYNAMICS_DAMAGE_LOW_OIL_PRESSURE: { //#if DYNAMICS_DEBUG debug_log ("DYNAMICS: LOW_OIL_PRESSURE damage"); //#endif current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_LOW_OIL_PRESSURE; current_flight_dynamics->input_data.cyclic_y.damaged = TRUE; if (sfrand1 () < 0.0) { play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_LOW_ENGINE_OIL_PRESSURE); } else { play_client_server_cpg_message (get_gunship_entity (), 0.5, 1.0, SPEECH_CATEGORY_CPG_SYSTEMS, 1.0, SPEECH_CPG_CONTROL_SYSTEMS_DAMAGED); } set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE); set_current_flight_dynamics_auto_pilot (FALSE); break; } case DYNAMICS_DAMAGE_HIGH_OIL_PRESSURE: { //#if DYNAMICS_DEBUG debug_log ("DYNAMICS: HIGH_OIL_PRESSURE damage"); //#endif current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_HIGH_OIL_PRESSURE; current_flight_dynamics->input_data.collective.damaged = TRUE; if (sfrand1 () < 0.0) { play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_HIGH_ENGINE_OIL_TEMPERATURE); } else { play_client_server_cpg_message (get_gunship_entity (), 0.5, 1.0, SPEECH_CATEGORY_CPG_SYSTEMS, 1.0, SPEECH_CPG_CONTROL_SYSTEMS_DAMAGED); } set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE); set_current_flight_dynamics_auto_pilot (FALSE); break; } case DYNAMICS_DAMAGE_AVIONICS: { //#if DYNAMICS_DEBUG debug_log ("DYNAMICS: AVIONICS damage"); //#endif current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_AVIONICS; break; } case DYNAMICS_DAMAGE_FIRE_EXTINGUISHER: { //#if DYNAMICS_DEBUG debug_log ("DYNAMICS: FIRE_EXTINGUISHER damage"); //#endif current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_FIRE_EXTINGUISHER; break; } case DYNAMICS_DAMAGE_UNDERCARRIAGE: { //#if DYNAMICS_DEBUG debug_log ("DYNAMICS: UNDERCARRIAGE damage"); //#endif current_flight_dynamics->dynamics_damage |= DYNAMICS_DAMAGE_UNDERCARRIAGE; current_flight_dynamics->undercarriage_state.damaged = TRUE; play_client_server_warning_message (get_gunship_entity (), SPEECH_SYSTEM_GEAR_DAMAGED); break; } default: { debug_fatal ("DYNAMICS: unknown damage %d", this_damage); } } } this_damage = this_damage << 1; } }
void update_collective_pressure_inputs (void) { current_flight_dynamics->input_data.collective.delta = current_flight_dynamics->input_data.collective.value; switch (get_global_collective_input ()) { case KEYBOARD_INPUT: case MOUSE_INPUT: { if (current_flight_dynamics->input_data.collective_input_pressure & COLLECTIVE_PRESSURE_BACKWARD) { current_flight_dynamics->input_data.collective_pressure.value = min (0.0f, current_flight_dynamics->input_data.collective_pressure.value); current_flight_dynamics->input_data.collective_pressure.value -= 5.0 * get_delta_time (); } else if (current_flight_dynamics->input_data.collective_input_pressure & COLLECTIVE_PRESSURE_FORWARD) { current_flight_dynamics->input_data.collective_pressure.value = max (0.0f, current_flight_dynamics->input_data.collective_pressure.value); current_flight_dynamics->input_data.collective_pressure.value += 5.0 * get_delta_time (); } else { current_flight_dynamics->input_data.collective_pressure.value = 0.0; } current_flight_dynamics->input_data.collective_pressure.value = bound (current_flight_dynamics->input_data.collective_pressure.value, current_flight_dynamics->input_data.collective_pressure.min, current_flight_dynamics->input_data.collective_pressure.max); break; } case THROTTLE_INPUT: { int joyval; float input; // 030418 loke // implemented multiple joystick device selection if (command_line_collective_joystick_index == -1) { joyval = get_joystick_axis (current_flight_dynamics->input_data.cyclic_joystick_device_index, JOYSTICK_DEFAULT_AXIS_THROTTLE); } else { joyval = get_joystick_axis (command_line_collective_joystick_index, command_line_collective_joystick_axis); } if (non_linear_collective) { input = 0.5 + ((float) joyval ) / ((float) JOYSTICK_AXIS_MAXIMUM - (float) JOYSTICK_AXIS_MINIMUM); if (input < command_line_collective_zone_1_limit) { // start variable percentage at zone1 by GCsDriver 08-12-2007 input *= command_line_collective_percentage_at_zone1 * zone_1_scale; input -= command_line_collective_percentage_at_zone1; // 0% -> -60 // original //input *= 60.0 * zone_1_scale; //input -= 60.0; // 0% -> -60 } else if (input < command_line_collective_zone_2_limit) { // find amount over limit input -= command_line_collective_zone_1_limit; input *= (100.0-command_line_collective_percentage_at_zone1) * zone_2_scale; // original //input -= command_line_collective_zone_1_limit; //input *= 40.0 * zone_2_scale; } else { // find amount over limit input -= command_line_collective_zone_2_limit; input *= 20.0 * zone_3_scale; input += (100.0-command_line_collective_percentage_at_zone1); // 100% -> +40 // original //input -= command_line_collective_zone_2_limit; //input *= 20.0 * zone_3_scale; //input += 40.0; // 100% -> +40 // end variable percentage at zone1 by GCsDriver 08-12-2007 } } else input = (float) (120.0 * (float) joyval ) / ((float) JOYSTICK_AXIS_MAXIMUM - (float) JOYSTICK_AXIS_MINIMUM); if ((current_flight_dynamics->auto_hover != HOVER_HOLD_STABLE) && (current_flight_dynamics->auto_hover != HOVER_HOLD_ALTITUDE_LOCK)) { if (get_current_dynamics_options (DYNAMICS_OPTIONS_REVERSE_THROTTLE_INPUT)) { current_flight_dynamics->input_data.collective.value = (float) 60.0 - input; } else { current_flight_dynamics->input_data.collective.value = (float) 60.0 + input; } } break; } } // recalculate collective position if (current_flight_dynamics->input_data.collective_pressure.value) { current_flight_dynamics->input_data.collective.value += 10.0 * current_flight_dynamics->input_data.collective_pressure.value * get_delta_time (); } else { // restore } if (current_flight_dynamics->input_data.collective.damaged) { current_flight_dynamics->input_data.collective.value += (get_model_delta_time ()) * (7.5 * sfrand1 () * current_flight_dynamics->input_data.collective.delta); } current_flight_dynamics->input_data.collective.value = bound (current_flight_dynamics->input_data.collective.value, current_flight_dynamics->input_data.collective.min, current_flight_dynamics->input_data.collective.max); current_flight_dynamics->input_data.collective.delta -= current_flight_dynamics->input_data.collective.value; current_flight_dynamics->input_data.collective.delta *= -1.0; }
int create_downwash_effect_component(downwash_component *this_downwash_component, downwash_types downwash_type, vec3d *position, int *entity_index_list, float main_rotor_radius, float main_rotor_rpm, float min_altitude) { int loop, count, terrain_type, trail_type; short int quadrant_x, quadrant_z; unsigned char alpha_percentage; float lifetime, lifetime_min, lifetime_max, scale_min, scale_max, scale, angle, radius, relative_radius, height, altitude, half_altitude, main_rotor_radius_minus_altitude; vec3d pos, offset, iv; terrain_3d_point_data terrain_info; entity *new_entity; memset (&terrain_info, 0, sizeof (terrain_3d_point_data)); count = this_downwash_component->trail_count; if ( count < 1 ) { return 0; } // Xhit: This is the altitude of the helicopter relative to the ground level. (030328) altitude = position->y - min_altitude; half_altitude = (altitude / 2.0); main_rotor_radius_minus_altitude = main_rotor_radius - altitude; scale_min = this_downwash_component->scale_min; scale_max = this_downwash_component->scale_max; lifetime_min = this_downwash_component->lifetime_min; lifetime_max = this_downwash_component->lifetime_max; // Xhit: initialising quadrant variables (030328) quadrant_x = 1; quadrant_z = 1; // // create smoke trails // for ( loop = 0 ; loop < count ; loop ++ ) { lifetime = lifetime_min + fabs( ( lifetime_max - lifetime_min ) * sfrand1() ); angle = frand1() * PI_OVER_TWO; relative_radius = main_rotor_radius * frand1(); scale = relative_radius + scale_min; if(scale > scale_max) scale = scale_max; switch(downwash_type) { case DOWNWASH_TYPE_LAND: case DOWNWASH_TYPE_LAND_DUAL_ROTORS: { //Xhit: If altitude bigger than main rotor radius then the smoke should be centered beneath the helicopter. (030328) if(altitude >= main_rotor_radius) { radius = relative_radius; height = (half_altitude * (radius / main_rotor_radius) + half_altitude) * frand1(); }else { radius = relative_radius + main_rotor_radius_minus_altitude; height = (half_altitude * ((radius - main_rotor_radius_minus_altitude) / main_rotor_radius) + half_altitude + scale ) * frand1(); } break; } case DOWNWASH_TYPE_WATER: case DOWNWASH_TYPE_WATER_DUAL_ROTORS: { if(altitude >= main_rotor_radius) { radius = relative_radius; }else { radius = relative_radius + main_rotor_radius_minus_altitude; } // Xhit: Changed to 2 instead of main_rotor_radius so smoke is created just over water level (030515) height = 2 * frand1(); break; } default: { debug_fatal("DOWNWASH : trying to create an unrecogniseable downwash effect"); break; } } //Xhit: If main rotor(s) only (not displaced main rotors) then. (030328) if((this_downwash_component->create_in_all_quadrants) && (loop < 4)) { //Xhit: This cryptical thing is to determine in which quadrant this sprite is going to be created. (030328) // ^z // | // 1|0 x // -+---> // 3|2 // // loop = 0 -> x= 1, z= 1; loop = 1 -> x= -1, z= 1; // loop = 2 -> x= 1, z= -1; loop = 3 -> x= -1, z= -1; quadrant_x = 1 | -(loop & 1); quadrant_z = 1 | -(loop & 2); offset.x = quadrant_x * radius * ( cos ( angle ) ); offset.y = height; offset.z = quadrant_z * radius * ( sin ( angle ) ); }else //Xhit: If scattered downwash effect and if the heli got more than one main rotor (on different axis) then // add two more trails at the sides of the heli. (030328) if((this_downwash_component->create_in_all_quadrants) && (loop >= 4) && (count == 6)) { //Xhit: loop = 4 -> x= 1; loop = 5 -> x= -1; (030328) quadrant_x = 1 | -(loop & 1); relative_radius = main_rotor_radius * frand1(); offset.x = quadrant_x * radius; offset.y = height; offset.z = frand1() * (main_rotor_radius / 2); }else { debug_fatal("DOWNWASH : trying to create an unrecogniseable downwash effect"); } pos.x = position->x + offset.x ; pos.z = position->z + offset.z; //Xhit: This is necessary if it's going to work on tilting terrain. (030328) get_3d_terrain_point_data (pos.x, pos.z, &terrain_info); pos.y = get_3d_terrain_point_data_elevation (&terrain_info); pos.y = pos.y + offset.y; bound_position_to_map_volume( &pos ); //Xhit: Decide which trail type is going to be used, this makes mapping to type of downwash effect fast. (030328) terrain_type = get_3d_terrain_point_data_type(&terrain_info); trail_type = get_terrain_surface_type(terrain_type) + SMOKE_LIST_TYPE_DOWNWASH_START; #if DEBUG_MODULE debug_log("DOWNWASH.C: terrain_type: %d, trail_type: %d", terrain_type, trail_type); #endif iv.x = pos.x - position->x; iv.y = relative_radius; iv.z = pos.z - position->z; //Xhit: If heli on ground then let the dust-smoke fade in according to increasing main_rotor_rpm // otherwise set it according to the altitude of the heli (higher = less dust smoke) (030328) if(altitude < 1.0) { alpha_percentage = (unsigned char)(main_rotor_rpm); }else { //Xhit: "+ 1.0" is to guarantee that alpha_percentage > 0. (030328) alpha_percentage = (unsigned char)((1.0 - (altitude / (DOWNWASH_EFFECT_MAX_ALTITUDE + 1.0))) * 100); } new_entity = create_local_entity ( ENTITY_TYPE_SMOKE_LIST, entity_index_list[ loop ], ENTITY_ATTR_INT_VALUE (INT_TYPE_ENTITY_SUB_TYPE, ENTITY_SUB_TYPE_EFFECT_SMOKE_LIST_DOWNWASH), ENTITY_ATTR_INT_VALUE (INT_TYPE_SMOKE_TYPE, trail_type), ENTITY_ATTR_INT_VALUE (INT_TYPE_COLOUR_ALPHA, alpha_percentage), ENTITY_ATTR_FLOAT_VALUE (FLOAT_TYPE_GENERATOR_LIFETIME, this_downwash_component->generator_lifetime), ENTITY_ATTR_FLOAT_VALUE (FLOAT_TYPE_FREQUENCY, this_downwash_component->frequency), ENTITY_ATTR_FLOAT_VALUE (FLOAT_TYPE_SMOKE_LIFETIME, lifetime), ENTITY_ATTR_FLOAT_VALUE (FLOAT_TYPE_SCALE, scale), ENTITY_ATTR_VEC3D (VEC3D_TYPE_INITIAL_VELOCITY, iv.x, iv.y, iv.z), ENTITY_ATTR_VEC3D (VEC3D_TYPE_POSITION, pos.x, pos.y, pos.z), ENTITY_ATTR_END ); entity_index_list[ loop ] = get_local_entity_index( new_entity ); } return count; }
void damage_primary_hydralics_only(void) { hydraulic_pressure *= 0.75 + (sfrand1() * 0.1); // lose some hydraulics pressure }
void update_cyclic_pressure_inputs (void) { float trim_x, trim_y; if (!current_flight_dynamics) { return; } if (hydraulic_pressure_loss_rate && hydraulic_pressure > 0.0) { hydraulic_pressure -= hydraulic_pressure_loss_rate * get_delta_time(); if (hydraulic_pressure < 0.0) hydraulic_pressure = 0.0; } trim_x = current_flight_dynamics->input_data.cyclic_x_trim.value; trim_y = current_flight_dynamics->input_data.cyclic_y_trim.value; if (trim_button_held) { current_flight_dynamics->input_data.cyclic_x.value = current_flight_dynamics->input_data.cyclic_x_trim.value; current_flight_dynamics->input_data.cyclic_y.value = current_flight_dynamics->input_data.cyclic_y_trim.value; } else switch (get_global_cyclic_input ()) { case KEYBOARD_INPUT: case MOUSE_INPUT: { if (current_flight_dynamics->input_data.cyclic_input_pressure & CYCLIC_PRESSURE_LEFT) { current_flight_dynamics->input_data.cyclic_horizontal_pressure.value = min (0.0f, current_flight_dynamics->input_data.cyclic_horizontal_pressure.value); current_flight_dynamics->input_data.cyclic_x.value = min ((current_flight_dynamics->input_data.cyclic_x.value) / 2.0f, current_flight_dynamics->input_data.cyclic_x.value); current_flight_dynamics->input_data.cyclic_horizontal_pressure.value -= MODEL_FRAME_RATE * get_model_delta_time (); if ((current_flight_dynamics->auto_hover == HOVER_HOLD_NORMAL) || (current_flight_dynamics->auto_hover == HOVER_HOLD_STABLE)) { set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE); set_current_flight_dynamics_auto_pilot (FALSE); } } else if (current_flight_dynamics->input_data.cyclic_input_pressure & CYCLIC_PRESSURE_RIGHT) { current_flight_dynamics->input_data.cyclic_horizontal_pressure.value = max (0.0f, current_flight_dynamics->input_data.cyclic_horizontal_pressure.value); current_flight_dynamics->input_data.cyclic_x.value = max ((current_flight_dynamics->input_data.cyclic_x.value) / 2.0f, current_flight_dynamics->input_data.cyclic_x.value); current_flight_dynamics->input_data.cyclic_horizontal_pressure.value += MODEL_FRAME_RATE * get_model_delta_time (); if ((current_flight_dynamics->auto_hover == HOVER_HOLD_NORMAL) || (current_flight_dynamics->auto_hover == HOVER_HOLD_STABLE)) { set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE); set_current_flight_dynamics_auto_pilot (FALSE); } } else { if (fabs (current_flight_dynamics->input_data.cyclic_horizontal_pressure.value) < 1.0) { current_flight_dynamics->input_data.cyclic_horizontal_pressure.value = 0.0; } else { current_flight_dynamics->input_data.cyclic_horizontal_pressure.value -= ((MODEL_FRAME_RATE * get_model_delta_time ()) / 2.0) * (current_flight_dynamics->input_data.cyclic_horizontal_pressure.value); } } if (current_flight_dynamics->input_data.cyclic_input_pressure & CYCLIC_PRESSURE_BACKWARD) { current_flight_dynamics->input_data.cyclic_vertical_pressure.value = min (0.0f, current_flight_dynamics->input_data.cyclic_vertical_pressure.value); current_flight_dynamics->input_data.cyclic_y.value = min (current_flight_dynamics->input_data.cyclic_y.value / 2.0f, current_flight_dynamics->input_data.cyclic_y.value); current_flight_dynamics->input_data.cyclic_vertical_pressure.value -= MODEL_FRAME_RATE * get_model_delta_time (); if ((current_flight_dynamics->auto_hover == HOVER_HOLD_NORMAL) || (current_flight_dynamics->auto_hover == HOVER_HOLD_STABLE)) { set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE); set_current_flight_dynamics_auto_pilot (FALSE); } } else if (current_flight_dynamics->input_data.cyclic_input_pressure & CYCLIC_PRESSURE_FORWARD) { current_flight_dynamics->input_data.cyclic_vertical_pressure.value = max (0.0f, current_flight_dynamics->input_data.cyclic_vertical_pressure.value); current_flight_dynamics->input_data.cyclic_y.value = max (current_flight_dynamics->input_data.cyclic_y.value / 2.0f, current_flight_dynamics->input_data.cyclic_y.value); current_flight_dynamics->input_data.cyclic_vertical_pressure.value += MODEL_FRAME_RATE * get_model_delta_time (); if ((current_flight_dynamics->auto_hover == HOVER_HOLD_NORMAL) || (current_flight_dynamics->auto_hover == HOVER_HOLD_STABLE)) { set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE); set_current_flight_dynamics_auto_pilot (FALSE); } } else { if (fabs (current_flight_dynamics->input_data.cyclic_vertical_pressure.value) < 1.0) { current_flight_dynamics->input_data.cyclic_vertical_pressure.value = 0.0; } else { current_flight_dynamics->input_data.cyclic_vertical_pressure.value -= ((MODEL_FRAME_RATE * get_model_delta_time ()) / 2.0) * (current_flight_dynamics->input_data.cyclic_vertical_pressure.value); } } // limit pressure inputs current_flight_dynamics->input_data.cyclic_horizontal_pressure.value = bound ( current_flight_dynamics->input_data.cyclic_horizontal_pressure.value, current_flight_dynamics->input_data.cyclic_horizontal_pressure.min, current_flight_dynamics->input_data.cyclic_horizontal_pressure.max ); current_flight_dynamics->input_data.cyclic_vertical_pressure.value = bound (current_flight_dynamics->input_data.cyclic_vertical_pressure.value, current_flight_dynamics->input_data.cyclic_vertical_pressure.min, current_flight_dynamics->input_data.cyclic_vertical_pressure.max ); // recalculate cyclic position if (current_flight_dynamics->input_data.cyclic_horizontal_pressure.value) { current_flight_dynamics->input_data.cyclic_x.value += (MODEL_FRAME_RATE * get_model_delta_time ()) * current_flight_dynamics->input_data.cyclic_horizontal_pressure.value; //current_flight_dynamics->input_data.cyclic_x.value += (MODEL_FRAME_RATE * get_model_delta_time ()) * (current_flight_dynamics->input_data.cyclic_horizontal_pressure.value);// + current_flight_dynamics->input_data.cyclic_x_trim.value); } else { // restore x //Werewolf: Removed old debug code, removed redundant multiplications if (get_global_cyclic_input () == KEYBOARD_INPUT) { if (get_current_dynamics_options (DYNAMICS_OPTIONS_KEYBOARD_ASSISTANCE)) { current_flight_dynamics->input_data.cyclic_x.value += ((1.0 / 16.0) * MODEL_FRAME_RATE * get_model_delta_time ()) * (current_flight_dynamics->input_data.cyclic_x_trim.value - current_flight_dynamics->input_data.cyclic_x.value); } else { current_flight_dynamics->input_data.cyclic_x.value += ((3.0 / 4.0) * MODEL_FRAME_RATE * get_model_delta_time ()) * (current_flight_dynamics->input_data.cyclic_x_trim.value - current_flight_dynamics->input_data.cyclic_x.value); } } else if (get_global_cyclic_input () == MOUSE_INPUT) { if (fabs (current_flight_dynamics->input_data.cyclic_x.value) < 5.0) { current_flight_dynamics->input_data.cyclic_x.value *= 0.8; } } } if (current_flight_dynamics->input_data.cyclic_vertical_pressure.value) { //current_flight_dynamics->input_data.cyclic_y.value += (MODEL_FRAME_RATE * get_model_delta_time ()) * (current_flight_dynamics->input_data.cyclic_vertical_pressure.value + current_flight_dynamics->input_data.cyclic_y_trim.value); current_flight_dynamics->input_data.cyclic_y.value += (MODEL_FRAME_RATE * get_model_delta_time ()) * (current_flight_dynamics->input_data.cyclic_vertical_pressure.value);// + current_flight_dynamics->input_data.cyclic_y_trim.value); } else { // restore y if (get_global_cyclic_input () == KEYBOARD_INPUT) { if (get_current_dynamics_options (DYNAMICS_OPTIONS_KEYBOARD_ASSISTANCE)) { current_flight_dynamics->input_data.cyclic_y.value += ((1.0 / 16.0) * MODEL_FRAME_RATE * get_model_delta_time ()) * (current_flight_dynamics->input_data.cyclic_y_trim.value - current_flight_dynamics->input_data.cyclic_y.value); } else { current_flight_dynamics->input_data.cyclic_y.value += ((3.0 / 4.0) * MODEL_FRAME_RATE * get_model_delta_time ()) * (current_flight_dynamics->input_data.cyclic_y_trim.value - current_flight_dynamics->input_data.cyclic_y.value); } } else if (get_global_cyclic_input () == MOUSE_INPUT) { if (fabs (current_flight_dynamics->input_data.cyclic_y.value) < 5.0) { debug_fatal ("CYCLIC: code with delta time"); current_flight_dynamics->input_data.cyclic_y.value *= 0.8; } } } break; } case JOYSTICK_INPUT: { int joyval; float input; // 030418 loke // implemented multiple joystick device selection // x if (command_line_cyclic_joystick_index == -1) { joyval = get_joystick_axis (current_flight_dynamics->input_data.cyclic_joystick_device_index, JOYSTICK_DEFAULT_AXIS_ROLL); } else { joyval = get_joystick_axis (command_line_cyclic_joystick_index, command_line_cyclic_joystick_x_axis); } if (command_line_nonlinear_cyclic) { // in non-linear mode it uses a curve described by f(x) = x*x + x // gives a not so sensitive control around centre input = (2.0 * (float) joyval ) / ((float) JOYSTICK_AXIS_MAXIMUM - (float) JOYSTICK_AXIS_MINIMUM); if (input >= 0) input *= input; else input *= -input; input += input; input *= 50; } else input = (float) (200.0 * (float) joyval ) / ((float) JOYSTICK_AXIS_MAXIMUM - (float) JOYSTICK_AXIS_MINIMUM); if (fabs (input) < command_line_dynamics_cyclic_dead_zone) { input = 0.0; } current_flight_dynamics->input_data.cyclic_x.value = input; //ataribaby 1/1/2009 allow trim with ALT HOLD if (current_flight_dynamics->auto_hover == HOVER_HOLD_NONE || current_flight_dynamics->auto_hover == HOVER_HOLD_ALTITUDE_LOCK) current_flight_dynamics->input_data.cyclic_x.value += current_flight_dynamics->input_data.cyclic_x_trim.value; // y if (command_line_cyclic_joystick_index == -1) { joyval = get_joystick_axis (current_flight_dynamics->input_data.cyclic_joystick_device_index, JOYSTICK_DEFAULT_AXIS_PITCH); } else { joyval = get_joystick_axis (command_line_cyclic_joystick_index, command_line_cyclic_joystick_y_axis); } if (command_line_nonlinear_cyclic) { // in non-linear mode it uses a curve described by f(x) = x*x + x // gives a not so sensitive control around centre input = -2.0 * ((float) joyval ) / ((float) JOYSTICK_AXIS_MAXIMUM - (float) JOYSTICK_AXIS_MINIMUM); if (input >= 0) input *= input; else input *= -input; input += input; input *= 50.0; } else input = -(float) (200.0 * joyval) / (JOYSTICK_AXIS_MAXIMUM - JOYSTICK_AXIS_MINIMUM); if (fabs (input) < command_line_dynamics_cyclic_dead_zone) { input = 0.0; } current_flight_dynamics->input_data.cyclic_y.value = input; //ataribaby 1/1/2009 allow trim with ALT HOLD if (current_flight_dynamics->auto_hover == HOVER_HOLD_NONE || current_flight_dynamics->auto_hover == HOVER_HOLD_ALTITUDE_LOCK) current_flight_dynamics->input_data.cyclic_y.value += current_flight_dynamics->input_data.cyclic_y_trim.value; /* debug_log ("CYCLIC: x %f, y %f", ((float) fabs (200.0 * get_joystick_axis(current_flight_dynamics->input_data.cyclic_joystick_device_index, JOYSTICK_DEFAULT_AXIS_ROLL) / (JOYSTICK_AXIS_MAXIMUM - JOYSTICK_AXIS_MINIMUM)), ((float) fabs (200.0 * get_joystick_axis(current_flight_dynamics->input_data.cyclic_joystick_device_index, JOYSTICK_DEFAULT_AXIS_PITCH)) / (JOYSTICK_AXIS_MAXIMUM - JOYSTICK_AXIS_MINIMUM))); */ { // 030418 loke // implemented multiple joystick device selection int joystick_x_pos, joystick_y_pos; if (command_line_cyclic_joystick_index == -1) { joystick_x_pos = get_joystick_axis (current_flight_dynamics->input_data.cyclic_joystick_device_index, JOYSTICK_DEFAULT_AXIS_ROLL); joystick_y_pos = get_joystick_axis (current_flight_dynamics->input_data.cyclic_joystick_device_index, JOYSTICK_DEFAULT_AXIS_PITCH); } else { joystick_x_pos = get_joystick_axis (command_line_cyclic_joystick_index, command_line_cyclic_joystick_x_axis); joystick_y_pos = get_joystick_axis (command_line_cyclic_joystick_index, command_line_cyclic_joystick_y_axis); } if (((float) fabs (200.0 * joystick_x_pos) / (JOYSTICK_AXIS_MAXIMUM - JOYSTICK_AXIS_MINIMUM) > 10.0) || ((float) fabs (200.0 * joystick_y_pos) / (JOYSTICK_AXIS_MAXIMUM - JOYSTICK_AXIS_MINIMUM) > 10.0)) { if ((current_flight_dynamics->auto_hover == HOVER_HOLD_NORMAL) || (current_flight_dynamics->auto_hover == HOVER_HOLD_STABLE)) { set_current_flight_dynamics_auto_hover (HOVER_HOLD_NONE); set_current_flight_dynamics_auto_pilot (FALSE); } } } break; } } // // DEBUG - to get the coolie hat working // #if 0 { joystick_hat_position coolie_position; coolie_position = get_joystick_hat( &joystick_devices [current_flight_dynamics->input_data.cyclic_joystick_device_index], 0 ); switch( coolie_position ) { case HAT_CENTERED: debug_log ("CYCLIC: coolie centered"); break; case HAT_UP: debug_log ("CYCLIC: coolie up"); break; case HAT_LEFT: debug_log ("CYCLIC: coolie left"); break; case HAT_DOWN: debug_log ("CYCLIC: coolie down"); break; case HAT_RIGHT: debug_log ("CYCLIC: coolie right"); break; case HAT_LEFTUP: debug_log ("CYCLIC: coolie left+up"); break; case HAT_LEFTDOWN: debug_log ("CYCLIC: coolie left+down"); break; case HAT_RIGHTUP: debug_log ("CYCLIC: coolie right+up"); break; case HAT_RIGHTDOWN: debug_log ("CYCLIC: coolie right+down"); break; default: debug_log ("CYCLIC: coolie is on fire"); } } #endif // // Damaged hydraulics // if (current_flight_dynamics->input_data.cyclic_x.damaged) { current_flight_dynamics->input_data.cyclic_x.value *= hydraulic_pressure; current_flight_dynamics->input_data.cyclic_x.value += damaged_lock_x_pos * (1.0 - hydraulic_pressure); } if (current_flight_dynamics->input_data.cyclic_y.damaged) { current_flight_dynamics->input_data.cyclic_y.value *= hydraulic_pressure; current_flight_dynamics->input_data.cyclic_y.value += damaged_lock_y_pos * (1.0 - hydraulic_pressure); } // // Damaged Stabaliser // if (current_flight_dynamics->input_data.cyclic_x_trim.damaged) current_flight_dynamics->input_data.cyclic_x_trim.value += (MODEL_FRAME_RATE * get_model_delta_time ()) * (0.5 * sfrand1 () * current_flight_dynamics->input_data.cyclic_x_trim.value); if (current_flight_dynamics->input_data.cyclic_y_trim.damaged) current_flight_dynamics->input_data.cyclic_y_trim.value += (MODEL_FRAME_RATE * get_model_delta_time ()) * (0.5 * sfrand1 () * current_flight_dynamics->input_data.cyclic_y_trim.value); // limit cyclic position current_flight_dynamics->input_data.cyclic_x.value = bound ( //current_flight_dynamics->input_data.cyclic_x.value + current_flight_dynamics->input_data.cyclic_x_trim.value, current_flight_dynamics->input_data.cyclic_x.value, current_flight_dynamics->input_data.cyclic_x.min, current_flight_dynamics->input_data.cyclic_x.max ); current_flight_dynamics->input_data.cyclic_y.value = bound ( //current_flight_dynamics->input_data.cyclic_y.value + current_flight_dynamics->input_data.cyclic_y_trim.value, current_flight_dynamics->input_data.cyclic_y.value, current_flight_dynamics->input_data.cyclic_y.min, current_flight_dynamics->input_data.cyclic_y.max ); }
void update_3d_rain ( env_3d *env, float time, matrix3x3 view_attitude ) { int start_raindrop_number, end_raindrop_number, total_raindrop_number, start_snowdrop_number, end_snowdrop_number, total_snowdrop_number, creation_allowed, count; float displacement_magnitude, snow_displacement_magnitude, snow_fall_displacement, weather_t; vec3d distance_moved, rain_displacement, snow_drift_displacement, rain_streak_displacement, creation_vector; // // Calculate how many rain drops we should have. This is a linear scale, from 0, to TOTAL_3D_RAINDROPS. // DRY = 0 // LIGHT_RAIN = TOTAL_3D_RAINDROPS / 2 // HEAVY_RAIN = TOTAL_3D_RAINDROPS // if ( visual_3d_vp ) { if ( visual_3d_vp->position.y > get_cloud_3d_base_height () ) { creation_allowed = FALSE; } else { creation_allowed = TRUE; } } else { creation_allowed = FALSE; } start_raindrop_number = number_of_weather_particles_allowed[env->weathermode].number_of_raindrops; start_snowdrop_number = number_of_weather_particles_allowed[env->weathermode].number_of_snowdrops; end_raindrop_number = number_of_weather_particles_allowed[env->target_weathermode].number_of_raindrops; end_snowdrop_number = number_of_weather_particles_allowed[env->target_weathermode].number_of_snowdrops; weather_t = env->weather_targetdistance; if ( weather_t == 0 ) { total_raindrop_number = start_raindrop_number; total_snowdrop_number = start_snowdrop_number; } else if ( weather_t == 1 ) { total_raindrop_number = end_raindrop_number; total_snowdrop_number = end_snowdrop_number; } else { total_raindrop_number = start_raindrop_number + ( ( ( float ) ( end_raindrop_number - start_raindrop_number ) ) * weather_t ); total_snowdrop_number = start_snowdrop_number + ( ( ( float ) ( end_snowdrop_number - start_snowdrop_number ) ) * weather_t ); } // // Special snow flag stuff // if ( special_snow_flag ) { /* if ( visual_3d_vp ) { int x, z; int near_snow; float old_rain_total; near_snow = FALSE; for ( z = -1; z <= 1; z++ ) { for ( x = -1; x <= 1; x++ ) { float x_pos, z_pos; x_pos = visual_3d_vp->x + x * TERRAIN_3D_SECTOR_SIDE_LENGTH; z_pos = visual_3d_vp->z + z * TERRAIN_3D_SECTOR_SIDE_LENGTH; x_pos = bound ( x_pos, terrain_3d_min_map_x, terrain_3d_max_map_x ); z_pos = bound ( z_pos, terrain_3d_min_map_z, terrain_3d_max_map_z ); get_terrain_3d_types_in_sector ( x_pos, z_pos ); if ( terrain_types_in_sector[TERRAIN_TYPE_ALTERED_LAND3] ) { near_snow = TRUE; } } } if ( near_snow ) { old_rain_total = total_raindrop_number; total_raindrop_number = old_rain_total * 0.0; total_snowdrop_number = old_rain_total * 1.0; } } */ } // // // rain_3d_delta_time = time - time_rain_last_updated; time_rain_last_updated = time; // // Calculate the distance moved by each raindrop. // distance_moved.x = rain_3d_wind_direction.x * rain_3d_wind_speed * rain_3d_delta_time; distance_moved.y = rain_3d_wind_direction.y * rain_3d_wind_speed * rain_3d_delta_time; distance_moved.z = rain_3d_wind_direction.z * rain_3d_wind_speed * rain_3d_delta_time; rain_displacement.x = distance_moved.x; rain_displacement.y = distance_moved.y + ( rain_3d_speed * rain_3d_delta_time ); rain_displacement.z = distance_moved.z; // // Calculate the distance moved by each snowdrop. // snow_drift_displacement.x = distance_moved.x; snow_drift_displacement.y = distance_moved.y; snow_drift_displacement.z = distance_moved.z; snow_fall_displacement = ( rain_3d_speed / 4 ) * rain_3d_delta_time; snow_displacement_magnitude = get_3d_vector_magnitude ( &snow_drift_displacement ); // // Calculate the 'streak' effect - this is now NOT framerate related // rain_streak_displacement = rain_displacement; displacement_magnitude = get_3d_vector_magnitude ( &rain_streak_displacement ); if ( displacement_magnitude != 0 ) { displacement_magnitude = 1.5 / displacement_magnitude; rain_streak_displacement.x *= displacement_magnitude; rain_streak_displacement.y *= displacement_magnitude; rain_streak_displacement.z *= displacement_magnitude; } else { // // Put artificial streaking in there ( game paused ) // rain_streak_displacement.x = rain_3d_wind_direction.x * rain_3d_wind_speed * 0.05; rain_streak_displacement.y = rain_3d_wind_direction.y * rain_3d_wind_speed * 0.05 + ( rain_3d_speed * 0.05 ); rain_streak_displacement.z = rain_3d_wind_direction.z * rain_3d_wind_speed * 0.05; displacement_magnitude = get_3d_vector_magnitude ( &rain_streak_displacement ); if ( displacement_magnitude != 0 ) { displacement_magnitude = 1.5 / displacement_magnitude; rain_streak_displacement.x *= displacement_magnitude; rain_streak_displacement.y *= displacement_magnitude; rain_streak_displacement.z *= displacement_magnitude; } } // // Remove any raindrops that have strayed out of the area of effect // creation_vector.x = rain_3d_wind_direction.x * rain_3d_wind_speed * 0.5; creation_vector.y = rain_3d_wind_direction.y * rain_3d_wind_speed * 0.5 + ( rain_3d_speed * 0.5 ); creation_vector.z = rain_3d_wind_direction.z * rain_3d_wind_speed * 0.5; normalise_any_3d_vector ( &creation_vector ); for ( count = 0; count < TOTAL_3D_RAINDROPS; count++ ) { switch ( rain_3d_drops[count].type ) { case RAINDROP_RAIN: { vec3d rel; // // Update the rain position // rain_3d_drops[count].current_position.x -= rain_displacement.x; rain_3d_drops[count].current_position.y -= rain_displacement.y; rain_3d_drops[count].current_position.z -= rain_displacement.z; rel.x = rain_3d_drops[count].current_position.x - visual_3d_vp->x; rel.y = rain_3d_drops[count].current_position.y - visual_3d_vp->y; rel.z = rain_3d_drops[count].current_position.z - visual_3d_vp->z; if ( ( rel.x > RAINDROPS_AREA_WIDTH ) || ( rel.x < ( -RAINDROPS_AREA_WIDTH ) ) || ( rel.y > RAINDROPS_AREA_HEIGHT ) || ( rel.y < ( -RAINDROPS_AREA_HEIGHT ) ) || ( rel.z > RAINDROPS_AREA_DEPTH ) || ( rel.z < ( -RAINDROPS_AREA_DEPTH ) ) ) { rain_3d_raindrops_valid--; rain_3d_drops[count].type = RAINDROP_INVALID; } break; } case RAINDROP_SNOW: { vec3d snow_noise, rel; float relative_speed; // // Update the rain position // snow_noise.x = sfrand1 () * rain_3d_delta_time; //0.1 ;//snow_displacement_magnitude; snow_noise.y = sfrand1 () * rain_3d_delta_time; //0.1 ;//snow_displacement_magnitude; snow_noise.z = sfrand1 () * rain_3d_delta_time; //0.1 ;//snow_displacement_magnitude; relative_speed = rain_3d_drops[count].relative_speed; rain_3d_drops[count].current_position.x -= ( snow_drift_displacement.x + snow_noise.x ); rain_3d_drops[count].current_position.y -= ( snow_drift_displacement.y ); rain_3d_drops[count].current_position.z -= ( snow_drift_displacement.z + snow_noise.x ); rain_3d_drops[count].current_position.y -= ( snow_fall_displacement * relative_speed ); rel.x = rain_3d_drops[count].current_position.x - visual_3d_vp->x; rel.y = rain_3d_drops[count].current_position.y - visual_3d_vp->y; rel.z = rain_3d_drops[count].current_position.z - visual_3d_vp->z; if ( ( rel.x > SNOWDROPS_AREA_WIDTH ) || ( rel.x < ( -SNOWDROPS_AREA_WIDTH ) ) || ( rel.y > SNOWDROPS_AREA_HEIGHT ) || ( rel.y < ( -SNOWDROPS_AREA_HEIGHT ) ) || ( rel.z > SNOWDROPS_AREA_DEPTH ) || ( rel.z < ( -SNOWDROPS_AREA_DEPTH ) ) ) { rain_3d_snowdrops_valid--; rain_3d_drops[count].type = RAINDROP_INVALID; } break; } } if ( ( rain_3d_drops[count].type == RAINDROP_INVALID ) && ( creation_allowed ) ) { if ( rain_3d_raindrops_valid < total_raindrop_number ) { float x, y, z, creation_distance; // // Generate a new rain drop randomly // z = ( ( frand1 () * 0.8 ) + 0.2 ) * ( RAINDROPS_AREA_DEPTH / 5 ); x = sfrand1 () * ( RAINDROPS_AREA_WIDTH / 5 ); y = sfrand1 () * ( RAINDROPS_AREA_HEIGHT / 5 ); x *= z / 50; y *= z / 50; // // Now project along the motion vector // creation_distance = frand1 () * 8; x += creation_vector.x * creation_distance; y += creation_vector.y * creation_distance; z += creation_vector.z * creation_distance; // // Rotate this back into the view coordinate system // rain_3d_drops[count].current_position.x = x * view_attitude[0][0] + y * view_attitude[1][0] + z * view_attitude[2][0]; rain_3d_drops[count].current_position.y = x * view_attitude[0][1] + y * view_attitude[1][1] + z * view_attitude[2][1]; rain_3d_drops[count].current_position.z = x * view_attitude[0][2] + y * view_attitude[1][2] + z * view_attitude[2][2]; rain_3d_drops[count].current_position.x += visual_3d_vp->x; rain_3d_drops[count].current_position.y += visual_3d_vp->y; rain_3d_drops[count].current_position.z += visual_3d_vp->z; rain_3d_drops[count].type = RAINDROP_RAIN; rain_3d_raindrops_valid++; } else if ( rain_3d_snowdrops_valid < total_snowdrop_number ) { float x, y, z, creation_distance; // // Generate a new snowdrop // z = ( ( frand1 () * 0.8 ) + 0.2 ) * ( SNOWDROPS_AREA_DEPTH / 5 ); x = sfrand1 () * ( SNOWDROPS_AREA_WIDTH / 5 ); y = sfrand1 () * ( SNOWDROPS_AREA_HEIGHT / 5 ); x *= z / 50; y *= z / 50; // // Now project along the motion vector // creation_distance = frand1 () * 8; x += creation_vector.x * creation_distance; y += creation_vector.y * creation_distance; z += creation_vector.z * creation_distance; // // Rotate this back into the view coordinate system // rain_3d_drops[count].current_position.x = x * view_attitude[0][0] + y * view_attitude[1][0] + z * view_attitude[2][0]; rain_3d_drops[count].current_position.y = x * view_attitude[0][1] + y * view_attitude[1][1] + z * view_attitude[2][1]; rain_3d_drops[count].current_position.z = x * view_attitude[0][2] + y * view_attitude[1][2] + z * view_attitude[2][2]; rain_3d_drops[count].current_position.x += visual_3d_vp->x; rain_3d_drops[count].current_position.y += visual_3d_vp->y; rain_3d_drops[count].current_position.z += visual_3d_vp->z; rain_3d_drops[count].relative_speed = ( frand1() * 0.5 ) + 0.5; rain_3d_drops[count].type = RAINDROP_SNOW; rain_3d_snowdrops_valid++; } } } // // Now calculate the predicted positions for rendering // for ( count = 0; count < TOTAL_3D_RAINDROPS; count++ ) { if ( rain_3d_drops[count].type == RAINDROP_RAIN ) { rain_3d_drops[count].predicted_position.x = rain_3d_drops[count].current_position.x - rain_streak_displacement.x; rain_3d_drops[count].predicted_position.y = rain_3d_drops[count].current_position.y - rain_streak_displacement.y; rain_3d_drops[count].predicted_position.z = rain_3d_drops[count].current_position.z - rain_streak_displacement.z; } } }