Beispiel #1
0
entity *free_flight_auto_assign_gunship (void)
{
	vec3d
		*pos;

	entity
		*force,
		*new_task,
		*group,
		*member,
		**gunship_list,
		*en;

	entity_sub_types
		sub_type;

	int
		c,
		index,
		count;

	//
	// Auto assign a helicopter for free flight
	//

	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	ASSERT (get_game_type () == GAME_TYPE_FREE_FLIGHT);

	ASSERT (get_pilot_entity ());

	if (get_gunship_entity ())
	{
		return NULL;
	}

	force = get_local_entity_parent (get_pilot_entity (), LIST_TYPE_PILOT);

	ASSERT (force);

	//
	// Count up candidates
	//

	count = 0;

	en = get_local_entity_first_child (force, LIST_TYPE_AIR_REGISTRY);

	while (en)
	{
		if (get_local_entity_int_value (en, INT_TYPE_GROUP_MODE) == GROUP_MODE_IDLE)
		{
			member = get_local_entity_first_child (en, LIST_TYPE_MEMBER);

			while (member)
			{
				sub_type = get_local_entity_int_value (member, INT_TYPE_ENTITY_SUB_TYPE);

				if ((sub_type == ENTITY_SUB_TYPE_AIRCRAFT_RAH66_COMANCHE) || (sub_type == ENTITY_SUB_TYPE_AIRCRAFT_KA52_HOKUM_B))
				{
					if (get_local_entity_suitable_for_player (member, get_pilot_entity ()))
					{
						count ++;
					}
				}

				member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER);
			}
		}

		en = get_local_entity_child_succ (en, LIST_TYPE_AIR_REGISTRY);
	}

	if (count == 0)
	{
		return NULL;
	}

	//
	// Create list of candidates
	//

	gunship_list = safe_malloc (sizeof (entity *) * count);

	count = 0;

	en = get_local_entity_first_child (force, LIST_TYPE_AIR_REGISTRY);

	while (en)
	{
		if (get_local_entity_int_value (en, INT_TYPE_GROUP_MODE) == GROUP_MODE_IDLE)
		{
			member = get_local_entity_first_child (en, LIST_TYPE_MEMBER);

			while (member)
			{
				sub_type = get_local_entity_int_value (member, INT_TYPE_ENTITY_SUB_TYPE);

				if ((sub_type == ENTITY_SUB_TYPE_AIRCRAFT_RAH66_COMANCHE) || (sub_type == ENTITY_SUB_TYPE_AIRCRAFT_KA52_HOKUM_B))
				{
					if (get_local_entity_suitable_for_player (member, get_pilot_entity ()))
					{
						gunship_list [count] = member;

						count ++;
					}
				}

				member = get_local_entity_child_succ (member, LIST_TYPE_MEMBER);
			}
		}

		en = get_local_entity_child_succ (en, LIST_TYPE_AIR_REGISTRY);
	}

	//
	// Pick one...
	//

	ASSERT (count > 0);

	index = rand16 () % count;

	for (c = 0; c < count; c ++)
	{
		en = gunship_list [index];

		group = get_local_entity_parent (en, LIST_TYPE_MEMBER);

		pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION);

		new_task = create_user_task (en, ENTITY_SUB_TYPE_TASK_FREE_FLIGHT, pos, NULL, NULL);

		set_assign_create_waypoint_route (FALSE);

		if (assign_primary_task_to_group (group, new_task))
		{
			set_gunship_entity (en);

			set_view_mode (VIEW_MODE_COCKPIT_PANEL_LEVEL_AHEAD);

			safe_free (gunship_list);

			initialise_free_flight_screen_map_page_objects ();

			return en;
		}
		else
		{
			debug_log ("FLIGHT: can't assign user to Created task");

			destroy_client_server_entity (new_task);
		}

		set_assign_create_waypoint_route (TRUE);

		index ++;

		if (index == count)
		{
			index = 0;
		}
	}

	safe_free (gunship_list);

	return NULL;
}
Beispiel #2
0
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;
	}
}
Beispiel #3
0
void update_person_animation (entity *en)
{
	person
		*raw;

	int
		wrapped,
		state;

	float
		frequency,
		remainder;

	ASSERT( en );

	raw = (person *) get_local_entity_data (en);

	//update character animation

	get_keyframed_animation_state (raw->person_animation_state, &state, &remainder);

	if (get_local_entity_int_value (en, INT_TYPE_ALIVE))
	{
		if (state != PERSON_ANIM_NONE)
		{
			frequency = 1.0 / person_animation_database[state].duration;

			wrapped = update_entity_simple_keyframed_value (en, &remainder, frequency);

			if ( (wrapped) && (!person_animation_database[state].repeat) )
			{
				int
					state_selector;

				// set new animation that isn't same as previous
				state_selector = rand16 () % 4;

				switch ( state_selector )
				{

					case 0: state = ( state == PERSON_ANIM_STAND1 ) ? PERSON_ANIM_STAND2 : PERSON_ANIM_STAND1; break;
					case 1: state = ( state == PERSON_ANIM_STAND2 ) ? PERSON_ANIM_STAND3 : PERSON_ANIM_STAND2; break;
					case 2: state = ( state == PERSON_ANIM_STAND3 ) ? PERSON_ANIM_STAND4 : PERSON_ANIM_STAND3; break;
					case 3: state = ( state == PERSON_ANIM_STAND4 ) ? PERSON_ANIM_STAND1 : PERSON_ANIM_STAND4; break;
				}
				
				remainder = 0.0;
		
				raw->person_animation_state = state + remainder;

				ASSERT ( raw->person_animation_state < NUM_PERSON_ANIMS );
			}
			else
			{
				raw->person_animation_state = state + remainder;

				ASSERT ( raw->person_animation_state < NUM_PERSON_ANIMS );
			}
		}
	}
	else
	{
		raw->person_animation_state += 1.4 * get_entity_movement_delta_time ();

		if (raw->person_animation_state >= 1.0)
		{
			raw->person_animation_state = 1.0;
		}
	}
}
Beispiel #4
0
static void play_aircraft_weapon_launched_speech (entity *en, int weapon_type)
{
	weapon_launch_wingman_speech_types
		weapon_class;

	int
		speech_index;
	
	ASSERT (en);
	
	ASSERT (get_comms_model () == COMMS_MODEL_SERVER);

	speech_index = -1;

	if (get_local_entity_int_value (en, INT_TYPE_PLAYER) == ENTITY_PLAYER_AI)
	{
		weapon_class = weapon_database [weapon_type].weapon_launched_wingman_speech;

		switch (weapon_class)
		{
			case WEAPON_LAUNCH_WINGMAN_SPEECH_CANNON:
			{
				if (rand16 () & 0x01)
				{
					speech_index = SPEECH_WINGMAN_FIRING_CANNON;
				}
				else
				{
					speech_index = SPEECH_WINGMAN_ENGAGING_WITH_CANNON;
				}

				break;
			}
			case WEAPON_LAUNCH_WINGMAN_SPEECH_ROCKET:
			{
				if (rand16 () & 0x01)
				{
					speech_index = SPEECH_WINGMAN_FIRING_ROCKETS;
				}
				else
				{
					speech_index = SPEECH_WINGMAN_ROCKETS_AWAY;
				}

				break;
			}
			case WEAPON_LAUNCH_WINGMAN_SPEECH_MISSILE:
			{
				if (rand16 () & 0x01)
				{
					speech_index = SPEECH_WINGMAN_LAUNCHING_MISSILE;
				}
				else
				{
					speech_index = SPEECH_WINGMAN_MISSILE_AWAY;
				}

				break;
			}
			default:
			{
				return;
			}
		}

		ASSERT (speech_index != -1);

		play_client_server_wingman_message
		(
			en,
			1.0,
			1.5,
			SPEECH_CATEGORY_FIRING,
			4.0,
			SPEECH_INTRODUCTION_SOMETIMES,
			SPEECH_ARRAY_WINGMAN_MESSAGES,
			speech_index
		);
	}
}
Beispiel #5
0
void takeDamage(int dam)
{
    // we've been hit with `dam' units of energy.

    int s = GET_SHIELD_ENERGY;
    uchar i, j, m;

    for (i = 1; i < 11; ++i)
    {
        // shake the ship
        for (j = 0; j < 200; ++j) setWide(i & 1);
    }
    
    // absorption of shields
    dam -= s;
    if (dam <= 0)
    {
        // if some left, give back to shields
        SET_SHIELD_ENERGY(-dam);
        messageCode(MSG_CODE_SHIELDS_OK);
    }
    else
    {
        // residual damage goes to operations
        int di[L_COUNT-2];
        int dv;
        int dm;

        if (s > 0)
        {
            SET_SHIELD_ENERGY(0);
            messageCode(MSG_CODE_SHIELDS_GONE);
            alertsound();
        }

        /* allocate the damage randomly to each operation (not shields).
         * generate n-1 random numbers (mod dam+1).
         * take the smallest and allocate this damage (will be <= dam)
         * then take the next smallest and allocate this much minus previous
         * give any remaining amount to the last
         */

        dm = dam + 1;

        // generate n-1 partitions of the damage value
        for (i = 0; i < L_COUNT-2; ++i)
        {
            uint r = rand16();
            uint q = r/(uint)dm;
            di[i] = r - q*dm;
        }

        dm = 0;
        for (i = 1; i < L_COUNT-1; ++i)
        {
            // find min partition
            m = 0;
            for (j = 1; j < L_COUNT-2; ++j)
                if (di[j] < di[m]) m = j;
            
            // take damage to operations i
            dv = (di[m] - dm) >> 3; // amount of operational units
            dm = di[m];
            subop(i, dv);
            di[m] = 0x7fff;
        }

        // remainder of total damage and last partition to last operation
        subop(L_COUNT-1, dam - dm);
    }
}
Beispiel #6
0
void reset_cinematic_camera (camera *raw)
{
	entity
		*en;

	object_3d_instance
		*inst3d;

	int
		num_moving_cameras,
		num_static_cameras,
		attempts;

	//
	// pre-amble
	//

	ASSERT (raw);

	ASSERT (raw->external_view_entity);

	en = raw->external_view_entity;

	inst3d = get_local_entity_ptr_value (en, PTR_TYPE_INSTANCE_3D_OBJECT);

	//
	// select 3D camera
	//

	raw->cinematic_camera_index = OBJECT_3D_INVALID_CAMERA_INDEX;

	if (inst3d)
	{
		num_moving_cameras = get_number_of_3d_object_cameras (inst3d, OBJECT_3D_CAMERA_SCENIC_MOVING);

		num_static_cameras = get_number_of_3d_object_cameras (inst3d, OBJECT_3D_CAMERA_SCENIC_STATIC);

		if ((num_moving_cameras > 0) && (num_static_cameras > 0))
		{
			if (frand1 () < 0.333)
			{
				raw->cinematic_camera_index = OBJECT_3D_CAMERA_SCENIC_MOVING;
			}
			else
			{
				raw->cinematic_camera_index = OBJECT_3D_CAMERA_SCENIC_STATIC;
			}
		}
		else if (num_moving_cameras > 0)
		{
			raw->cinematic_camera_index = OBJECT_3D_CAMERA_SCENIC_MOVING;
		}
		else if (num_static_cameras > 0)
		{
			raw->cinematic_camera_index = OBJECT_3D_CAMERA_SCENIC_STATIC;
		}
	}

	switch (raw->cinematic_camera_index)
	{
		////////////////////////////////////////
		case OBJECT_3D_INVALID_CAMERA_INDEX:
		////////////////////////////////////////
		{
			raw->cinematic_camera_depth = 0;

			raw->cinematic_camera_lifetime = (frand1 () * 2.0) + 2.0;

			raw->cinematic_camera_heading = rad (45.0) * ((float) (rand16 () % 8));

			raw->cinematic_camera_pitch = rad (-45.0) * ((float) (rand16 () % 2));

			#if DEBUG_MODULE

			debug_log
			(
				"CINEMATIC CAMERA is INVALID (object = %s, moving cameras = %d, static cameras = %d, depth = %d, lifetime = %.2f, heading = %.2f, pitch = %.2f)",
				get_local_entity_string (en, STRING_TYPE_FULL_NAME),
				num_moving_cameras,
				num_static_cameras,
		  		raw->cinematic_camera_depth,
				raw->cinematic_camera_lifetime,
				deg (raw->cinematic_camera_heading),
				deg (raw->cinematic_camera_pitch)
			);

			#endif

			break;
		}
		////////////////////////////////////////
		case OBJECT_3D_CAMERA_SCENIC_MOVING:
		////////////////////////////////////////
		{
			//
			// try and prevent using the same moving camera twice in succession
			//

			if (num_moving_cameras > 1)
			{
				attempts = 10;

				while (attempts--)
				{
					raw->cinematic_camera_depth = rand16 () % num_moving_cameras;

					if (raw->cinematic_camera_depth != raw->cinematic_camera_previous_moving_depth)
					{
						break;
					}
				}
			}
			else
			{
				raw->cinematic_camera_depth = 0;
			}

			raw->cinematic_camera_previous_moving_depth = raw->cinematic_camera_depth;

			raw->cinematic_camera_lifetime = get_object_3d_camera_lifetime (inst3d, raw->cinematic_camera_index, raw->cinematic_camera_depth);

			#if DEBUG_MODULE

			debug_log
			(
				"CINEMATIC CAMERA is MOVING (object = %s, moving cameras = %d, static cameras = %d, depth = %d, lifetime = %.2f)",
				get_local_entity_string (en, STRING_TYPE_FULL_NAME),
				num_moving_cameras,
				num_static_cameras,
		  		raw->cinematic_camera_depth,
				raw->cinematic_camera_lifetime
			);

			#endif

			ASSERT (raw->cinematic_camera_lifetime > 0.0);

			break;
		}
		////////////////////////////////////////
		case OBJECT_3D_CAMERA_SCENIC_STATIC:
		////////////////////////////////////////
		{
			//
			// try and prevent using the same static camera twice in succession
			//

			if (num_static_cameras > 1)
			{
				attempts = 10;

				while (attempts--)
				{
					raw->cinematic_camera_depth = rand16 () % num_static_cameras;

					if (raw->cinematic_camera_depth != raw->cinematic_camera_previous_static_depth)
					{
						break;
					}
				}
			}
			else
			{
				raw->cinematic_camera_depth = 0;
			}

			raw->cinematic_camera_previous_static_depth = raw->cinematic_camera_depth;

			raw->cinematic_camera_lifetime = (frand1 () * 2.0) + 2.0;

			#if DEBUG_MODULE

			debug_log
			(
				"CINEMATIC CAMERA is STATIC (object = %s, moving cameras = %d, static cameras = %d, depth = %d, lifetime = %.2f)",
				get_local_entity_string (en, STRING_TYPE_FULL_NAME),
				num_moving_cameras,
				num_static_cameras,
		  		raw->cinematic_camera_depth,
				raw->cinematic_camera_lifetime
			);

			#endif
		}
	}

	raw->cinematic_camera_timer = 0.0;

	//
	// motion vector
	//

	get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector);
}
Beispiel #7
0
time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
{
  struct dhcp_context *context;
  struct dhcp_lease *lease;
  struct slaac_address *slaac;
  time_t next_event = 0;
  
  for (context = daemon->ra_contexts; context; context = context->next)
    if ((context->flags & CONTEXT_RA_NAME))
      break;

  /* nothing configured */
  if (!context)
    return 0;

  while (ping_id == 0)
    ping_id = rand16();

  if (map_rebuild)
    {
      map_rebuild = 0;
      build_subnet_map();
    }

  for (lease = leases; lease; lease = lease->next)
    for (slaac = lease->slaac_address; slaac; slaac = slaac->next)
      {
	/* confirmed or given up? */
	if (slaac->backoff == 0 || slaac->ping_time == 0)
	  continue;
	
	if (difftime(slaac->ping_time, now) <= 0.0)
	  {
	    struct ping_packet *ping;
	    struct sockaddr_in6 addr;
 
	    save_counter(0);
	    ping = expand(sizeof(struct ping_packet));
	    ping->type = ICMP6_ECHO_REQUEST;
	    ping->code = 0;
	    ping->identifier = ping_id;
	    ping->sequence_no = slaac->backoff;
	    
	    memset(&addr, 0, sizeof(addr));
#ifdef HAVE_SOCKADDR_SA_LEN
	    addr.sin6_len = sizeof(struct sockaddr_in6);
#endif
	    addr.sin6_family = AF_INET6;
	    addr.sin6_port = htons(IPPROTO_ICMPV6);
	    addr.sin6_addr = slaac->addr;
	    
	    if (sendto(daemon->icmp6fd, daemon->outpacket.iov_base, save_counter(0), 0,
		       (struct sockaddr *)&addr,  sizeof(addr)) == -1 &&
		errno == EHOSTUNREACH)
	      slaac->ping_time = 0; /* Give up */ 
	    else
	      {
		slaac->ping_time += (1 << (slaac->backoff - 1)) + (rand16()/21785); /* 0 - 3 */
		if (slaac->backoff > 4)
		  slaac->ping_time += rand16()/4000; /* 0 - 15 */
		if (slaac->backoff < 12)
		  slaac->backoff++;
	      }
	  }
	
	if (slaac->ping_time != 0 &&
	    (next_event == 0 || difftime(next_event, slaac->ping_time) >= 0.0))
	  next_event = slaac->ping_time;
      }

  return next_event;
}
Beispiel #8
0
/*
 * Generate and munge a 64bit number.
 */
u64 rand64(void)
{
	unsigned long r = 0;

	switch (rnd() % 8) {

	/* 8-bit ranges */
	case 0:	r = RAND_BYTE();
		break;

	/* 16-bit ranges */
	case 1:	r = rand16();
		break;

	/* 32-bit ranges. */
	case 2:	r = rand32();
		break;

	/* 33:64-bit ranges. */
	case 3:	r = rand_single_bit(64);
		break;
	case 4:	r = randbits(64);
		break;
	case 5:	r = (0ULL | rnd()) << 32 | rnd();
		break;
	case 6:	r = rept_byte();
		break;

	/* Sometimes pick a not-so-random number. */
	case 7:	return get_interesting_value();
	}

	/* limit the size */
	switch (rnd() % 4) {
	case 0: r &= 0x000000ffffffffffULL;
		break;
	case 1: r &= 0x0000ffffffffffffULL;
		break;
	case 2: r &= 0x00ffffffffffffffULL;
		break;
	default: /* no limiting. */
		break;
	}

	/* Sometimes invert the generated number. */
	if (ONE_IN(25))
		r = ~r;

	/* increase distribution in MSB */
	if (ONE_IN(10)) {
		unsigned int i;
		unsigned int rounds;

		rounds = rnd() % 4;
		for (i = 0; i < rounds; i++)
			r |= (1UL << ((__WORDSIZE - 1) - (rnd() % 8)));
	}

	/* Sometimes flip sign */
	if (ONE_IN(25))
		r = ~r + 1;

	return r;
}
Beispiel #9
0
/**
  * \param PrivateKey Must IKE_DH_SCALAR_CONTIKIECC_LEN bytes long
  */
void ecc_gen_private_key ( NN_DIGIT* PrivateKey )
{
	srand(NULL);
	NN_UINT order_digit_len, order_bit_len;
	bool done = FALSE;
	uint8_t ri;
	NN_DIGIT digit_mask;

	order_bit_len = NN_Bits ( param.r, NUMWORDS );
	order_digit_len = NN_Digits ( param.r, NUMWORDS );

	while ( !done )
	{
		//PrivateKey[] = { 323FA316 9D8E9C65 93F59476 BC142000 AB5BE0E2 49C43426 };
		/*
		PrivateKey[24] = 0x0;
		PrivateKey[23] = 0x32;
		PrivateKey[22] = 0x3F;
		PrivateKey[21] = 0xA3;
		PrivateKey[20] = 0x16;
		PrivateKey[19] = 0x9D;
		PrivateKey[18] = 0x8E;
		PrivateKey[17] = 0x9C;
		PrivateKey[16] = 0x65;
		PrivateKey[15] = 0x93;
		PrivateKey[14] = 0xF5;
		PrivateKey[13] = 0x94;
		PrivateKey[12] = 0x76;
		PrivateKey[11] = 0xBC;
		PrivateKey[10] = 0x14;
		PrivateKey[9] = 0x20;
		PrivateKey[8] = 0x00;
		PrivateKey[7] = 0xAB;
		PrivateKey[6] = 0x5B;
		PrivateKey[5] = 0xE0;
		PrivateKey[4] = 0xE2;
		PrivateKey[3] = 0x49;
		PrivateKey[2] = 0xC4;
		PrivateKey[1] = 0x34;
		PrivateKey[0] = 0x26;
		*/

		for ( ri = 0; ri < order_digit_len; ri++ )
		{
#ifdef THIRTYTWO_BIT_PROCESSOR
			PrivateKey[ri] = rand32();
#else
			PrivateKey[ri] = rand16();
#endif
		}

		for ( ri = order_digit_len; ri < NUMWORDS; ri++ )
		{
			PrivateKey[ri] = 0;
		}

		if ( order_bit_len % NN_DIGIT_BITS != 0 )
		{
			digit_mask = MAX_NN_DIGIT >> ( NN_DIGIT_BITS - order_bit_len % NN_DIGIT_BITS );
			PrivateKey[order_digit_len - 1] = PrivateKey[order_digit_len - 1] & digit_mask;
		}

		NN_ModSmall ( PrivateKey, param.r, NUMWORDS );

		if ( NN_Zero ( PrivateKey, NUMWORDS ) != 1 )
			done = TRUE;
	}
Beispiel #10
0
void play_vehicle_shot_at_speech (entity *victim, entity *aggressor)
{
	entity_sides
		victim_side,
		aggressor_side;

	int
		val,
		speech_index;

	vec3d
		*pos;

	ASSERT (victim);

	ASSERT (aggressor);

	pos = get_local_entity_vec3d_ptr (victim, VEC3D_TYPE_POSITION);

	ASSERT (pos);

	victim_side = get_local_entity_int_value (victim, INT_TYPE_SIDE);

	aggressor_side = get_local_entity_int_value (aggressor, INT_TYPE_SIDE);

	if (aggressor_side == victim_side)
	{
		//
		// FRIENDLY FIRE
		//

		////////////////////////////////////
		//
		// victims speech
		//
		////////////////////////////////////
		
		////////////////////////////////////
		//
		// Aggressors speech
		//
		////////////////////////////////////

		if (get_local_entity_int_value (aggressor, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI)
		{
			//
			// PLAY_SPEECH (CPG)
			//

			if (rand16 () & 1)
			{
				speech_index = SPEECH_CPG_FRIENDLY_FIRE1;
			}
			else
			{
				speech_index = SPEECH_CPG_FRIENDLY_FIRE2;
			}

			play_client_server_cpg_message
			(
				aggressor,
				1.0,
				3.0,
				SPEECH_CATEGORY_ATTACKING_TARGETS,
				12.0,
				speech_index
			);
		}
	}
	else
	{
		////////////////////////////////////
		//
		// victims speech
		//
		////////////////////////////////////

		val = get_speech_random_value
				(
					vehicle_hit_comments,
					num_vehicle_hit_comments [victim_side],
					last_vehicle_hit_comment [victim_side]
				);

		speech_index = vehicle_hit_comments [val].speech_index;
	
		get_speech_sector_coordinates (pos);

		// PLAY_SPEECH (GC)
		//
		// [GC Introduction],
		// (We are pinned down by enemy fire) | (we are taking heavy fire, requesting ariel assistance)
		// location

		play_client_server_speech
		(
			get_session_entity (),
			victim,
			victim_side,
			ENTITY_SUB_TYPE_EFFECT_SOUND_RADIO_MESSAGE,
			SOUND_LOCALITY_RADIO,
			0.0,
			1.0,
			45.0,
			SPEECH_ORIGINATOR_GROUND_CONTROLLER,
			SPEECH_CATEGORY_UNDER_ATTACK,
			300.0,
			SPEECH_ARRAY_GC_MESSAGES, SPEECH_GC_INTRODUCTION,
			SPEECH_ARRAY_GC_MESSAGES, speech_index,
			SPEECH_ARRAY_NUMBERS, speech_sector_coordinates [0],
			SPEECH_ARRAY_NUMBERS, speech_sector_coordinates [1],
			SPEECH_ARRAY_NUMBERS, speech_sector_coordinates [2],
			SPEECH_ARRAY_NUMBERS, speech_sector_coordinates [3],
			SPEECH_ARRAY_NUMBERS, speech_sector_coordinates [4],
			SPEECH_ARRAY_NUMBERS, speech_sector_coordinates [5],
			-1
		);

		////////////////////////////////////
		//
		// Aggressors speech
		//
		////////////////////////////////////

		if (get_local_entity_int_value (aggressor, INT_TYPE_IDENTIFY_AIRCRAFT))
		{
			if (get_local_entity_int_value (aggressor, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI)
			{
				//
				// PLAY_SPEECH (CPG)
				//

				play_client_server_cpg_message
				(
					aggressor,
					0.4,
					3.0,
					SPEECH_CATEGORY_ATTACKING_TARGETS,
					12.0,
					SPEECH_CPG_TARGET_HIT
				);
			}
			else
			{
				//
				// PLAY_SPEECH (WINGMAN)
				//

				play_client_server_wingman_message
				(
					aggressor,
					0.4,
					3.0,
					SPEECH_CATEGORY_ATTACKING_TARGETS, 12.0,
					SPEECH_INTRODUCTION_SOMETIMES,
					SPEECH_ARRAY_WINGMAN_MESSAGES, SPEECH_WINGMAN_TARGET_HIT
				);
			}
		}
	}
}
Beispiel #11
0
void play_vehicle_destroyed_speech (entity *victim, entity *aggressor)
{
	entity_sides
		victim_side,
		aggressor_side;

	int
		val,
		array_type,
		speech_index;

	ASSERT (victim);

	ASSERT (aggressor);

	victim_side = get_local_entity_int_value (victim, INT_TYPE_SIDE);

	aggressor_side = get_local_entity_int_value (aggressor, INT_TYPE_SIDE);

	if (victim_side == aggressor_side)
	{
		//
		// FRIENDLY FIRE
		//

		if (get_local_entity_int_value (aggressor, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI)
		{
			// PLAY_SPEECH (CPG)
			//
			// (Hold your fire, we're hitting friendlies) | (Cease fire, we're hitting our own guys)

			if (rand16 () & 1)
			{
				speech_index = SPEECH_CPG_FRIENDLY_FIRE1;
			}
			else
			{
				speech_index = SPEECH_CPG_FRIENDLY_FIRE2;
			}

			play_client_server_cpg_message
			(
				aggressor,
				1.0,
				3.0,
				SPEECH_CATEGORY_ATTACKING_TARGETS,
				8.0,
				speech_index
			);
		}
	}
	else
	{
		if (get_local_entity_int_value (aggressor, INT_TYPE_IDENTIFY_AIRCRAFT))
		{
			if (get_local_entity_int_value (aggressor, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI)
			{
				// PLAY_SPEECH (CPG)
				//
				// (Target destroyed) | (Enemy armour destroyed) | (Good Kill) | etc

				val = get_speech_random_value
						(
							vehicle_destroyed_cpg_comments,
							num_vh_destroyed_cpg_comments [aggressor_side],
							last_vh_destroyed_cpg_comment [aggressor_side]
						);

				speech_index = vehicle_destroyed_cpg_comments [val].speech_index;
	
				play_client_server_cpg_message
				(
					aggressor,
					0.4,
					3.0,
					SPEECH_CATEGORY_ATTACKING_TARGETS, 10.0,
					speech_index
				);
			}
			else
			{
				// PLAY_SPEECH (WINGMAN)
				//
				// (Target destroyed) | (Enemy armour destroyed) | (Good Kill) | etc

				val = get_speech_random_value
						(
							vehicle_destroyed_wingman_comments,
							num_vh_destroyed_wingman_comments [aggressor_side],
							last_vh_destroyed_wingman_comment [aggressor_side]
						);

				array_type = vehicle_destroyed_wingman_comments [val].array_type;
				speech_index = vehicle_destroyed_wingman_comments [val].speech_index;
	
				play_client_server_wingman_message
				(
					aggressor,
					0.4,
					3.0,
					SPEECH_CATEGORY_ATTACKING_TARGETS, 10.0,
					vehicle_destroyed_wingman_comments [val].introduction,
					array_type, speech_index
				);
			}
		}
	}
}
Beispiel #12
0
CCM_FUNC static THD_FUNCTION(ThreadKnock, arg)
{
  (void)arg;
  chRegSetThreadName("Knock");

  q15_t* knockDataPtr;
  size_t knockDataSize;

  float32_t maxValue = 0;
  uint32_t maxIndex = 0;
  uint16_t i;

  /* ADC 3 Ch1 Offset. -2048 */
  ADC3->OFR1 = ADC_OFR1_OFFSET1_EN | ((1 << 26) & ADC_OFR1_OFFSET1_CH) | (2048 & 0xFFF);
  dacPutChannelX(&DACD1, 0, 2048); // This sets the offset for the knock ADC opamp.

  chThdSleepMilliseconds(200);
  adcStartConversion(&ADCD3, &adcgrpcfg_knock, samples_knock, ADC_GRP2_BUF_DEPTH);

  /* Initialize the CFFT/CIFFT module */
  arm_rfft_fast_instance_f32 S1;
  arm_rfft_fast_init_f32(&S1, FFT_SIZE);

  while (TRUE)
  {
    while (!recvFreeSamples(&knockMb, (void*)&knockDataPtr, &knockDataSize))
      chThdSleepMilliseconds(2);

    /* Copy and convert ADC samples */
    for (i=0; i<FFT_SIZE*2; i+=4)
    {
      /* Hann Window */
      float32_t multiplier = (1.0 - arm_cos_f32((2.0*PI*(float32_t)i)/(((float32_t)FFT_SIZE*2.0)-1.0)));
      input[i] = multiplier*(float32_t)knockDataPtr[i];
      input[i+1] = multiplier*(float32_t)knockDataPtr[i+1];
      input[i+2] = multiplier*(float32_t)knockDataPtr[i+2];
      input[i+3] = multiplier*(float32_t)knockDataPtr[i+3];
    }

    /* Process the data through the RFFT module */
    arm_rfft_fast_f32(&S1, input, output, 0);

    /* Process the data through the Complex Magnitude Module for
    calculating the magnitude at each bin */
    arm_cmplx_mag_f32(output, mag_knock, FFT_SIZE/2); // Calculate magnitude, outputs q2.14
    arm_max_f32(mag_knock, FFT_SIZE/2, &maxValue, &maxIndex); // Find max magnitude

    // Convert 2.14 to 8 Bits unsigned
    for (i=0; i < sizeof(output_knock); i++)
    {
      uint16_t tmp = (mag_knock[i]/16384);
      if (tmp > 0xFF)
        tmp = 0xFF;
      output_knock[i] = tmp; // 8 bits minus the 2 fractional bits
    }

    sensors_data.knock_freq = settings.knockFreq;

    if (settings.sensorsInput == SENSORS_INPUT_TEST) {
        sensors_data.knock_value = rand16(0, 255);
        continue;
      }

    sensors_data.knock_value = calculateKnockIntensity(
                settings.knockFreq,
                settings.knockRatio,
                FFT_FREQ,
                output_knock,
                sizeof(output_knock));
  }
  return;
}
Beispiel #13
0
CCM_FUNC static THD_FUNCTION(ThreadADC, arg)
{
  (void)arg;
  chRegSetThreadName("Sensors");

  adcsample_t * sensorsDataPtr;
  size_t n;
  uint16_t i, pos;
  uint32_t an[3] = {0, 0, 0};
  median_t an1, an2, an3;
  uint8_t row, col;

  chThdSleepMilliseconds(250);
  timcapEnable(&TIMCAPD3);
  chVTSet(&vt_freqin, FREQIN_INTERVAL, freqinVTHandler, NULL);
  adcStartConversion(&ADCD1, &adcgrpcfg_sensors, samples_sensors, ADC_GRP1_BUF_DEPTH);

  median_init(&an1, 0 , an1_buffer, ADC_GRP1_BUF_DEPTH/2);
  median_init(&an2, 0 , an2_buffer, ADC_GRP1_BUF_DEPTH/2);
  median_init(&an3, 0 , an3_buffer, ADC_GRP1_BUF_DEPTH/2);

  while (TRUE)
  {
    while (!recvFreeSamples(&sensorsMb, (void*)&sensorsDataPtr, &n))
      chThdSleepMilliseconds(5);

    an[0]= 0;
    an[1]= 0;
    an[2]= 0;

    /* Filtering and adding */
    for (i = 0; i < (n/ADC_GRP1_NUM_CHANNELS); i++)
    {
      pos = i * ADC_GRP1_NUM_CHANNELS;
      an[0] += median_filter(&an1, sensorsDataPtr[pos]);
      an[1] += median_filter(&an2, sensorsDataPtr[pos+1]);
      an[2] += median_filter(&an3, sensorsDataPtr[pos+2]);
    }

    /* Averaging */
    an[0] /= (n/ADC_GRP1_NUM_CHANNELS);
    an[1] /= (n/ADC_GRP1_NUM_CHANNELS);
    an[2] /= (n/ADC_GRP1_NUM_CHANNELS);

    /* Convert to milliVolts */
    an[0] *= VBAT_RATIO;
    an[1] *= AN_RATIO;
    an[2] *= AN_RATIO;

    sensors_data.an1 = an[0];
    sensors_data.an2 = an[1];
    sensors_data.an3 = an[2];

    /* Analog/Digital Sensors */
    if (settings.sensorsInput == SENSORS_INPUT_DIRECT) {
        sensors_data.tps = calculateTpFromMillivolt(settings.tpsMinV, settings.tpsMaxV, sensors_data.an2);
        sensors_data.rpm = calculateFreqWithRatio(sensors_data.freq1, settings.rpmMult);
        sensors_data.spd = calculateFreqWithRatio(sensors_data.freq2, settings.spdMult);
    }
    else if (settings.sensorsInput == SENSORS_INPUT_TEST) {
        sensors_data.tps = rand16(0, 200);
        sensors_data.rpm = rand16(10, 18000);
        sensors_data.spd = rand16(5, 10000);
    }

    /* AFR */
    if (settings.afrInput == AFR_INPUT_AN) {
        sensors_data.afr = calculateAFRFromMillivolt(settings.AfrMinVal, settings.AfrMaxVal, sensors_data.an3);
    }
    else if (settings.afrInput == AFR_INPUT_TEST) {
        sensors_data.afr = rand16(11000, 16000) / 100;
    }

    if (dbg_sensors) {
        chprintf(DBG_STREAM,"->[SENSORS] TPS mV/PCT: %06u/%04u\r\n", sensors_data.an2, sensors_data.tps);
        chprintf(DBG_STREAM,"->[SENSORS] RMP Hz/Mult/Val: %06u/%.4f/%04u\r\n", sensors_data.freq1, settings.rpmMult, sensors_data.rpm);
        chprintf(DBG_STREAM,"->[SENSORS] SPD Hz/Mult/Val: %06u/%.4f/%04u\r\n", sensors_data.freq2, settings.spdMult, sensors_data.spd);
    }

    if (findCell(sensors_data.tps/2, sensors_data.rpm, &row, &col))
    {
      sensors_data.cell.row = row;
      sensors_data.cell.col = col;
      if (dbg_sensors) {
          chprintf(DBG_STREAM,"->[SENSORS] Row:Value/Col:Value: %02u:%05u/%02u:%05u\r\n", row, tableRows[row], col, tableColumns[col]*100);
      }

      if ((settings.functions & FUNC_RECORD)  && sensors_data.rpm != 0)
      {
          /* Average */
          tableAFR[row][col] = tableAFR[row][col] == 0 ? sensors_data.afr : ((uint16_t)sensors_data.afr+(uint16_t)tableAFR[row][col])/2;
          /* Peaks */
          tableKnock[row][col] = sensors_data.knock_value > tableKnock[row][col] ? sensors_data.knock_value : tableKnock[row][col];
      }
    }
  }
  return;
}