DIFF

Hit_MeatBones.c

class Hit_MeatBones : EffBulletImpactBase
{
	float m_ScalingByDistance;
	
	void Hit_MeatBones()
	{
		SetEnterParticle(ParticleList.IMPACT_MEATBONES_ENTER);
		SetExitParticle(ParticleList.IMPACT_MEATBONES_EXIT);
		SetRicochetParticle(ParticleList.IMPACT_MEATBONES_RICOCHET);
		
		m_AngledEnter = 10;
		m_EnterSplashCoef = 0.002;
		m_ExitSplashCoef = 0.006;
		m_ScalingByDistance = 0.05;
		
		MIN_SCALING_PARAM = 0.2;
	}
	
	override float CalculateStoppingForce(float in_speedf, float out_speedf, string ammoType, float weight)
	{
		if ( m_ImpactType == ImpactTypes.MELEE )
		{
			return 400;
		}
		
		float projectile_weight_coef = weight / DEFAULT_PROJECTILE_WEIGHT;
		
		float stopping_force = in_speedf * projectile_weight_coef;
		
		if (m_DirectHit)
		{
			/*
			// TO DO: Doesn't work because IsAlive() is false, even when it shouldn't be.
			if ( m_DirectHit.IsMan()  &&  m_componentIndex == SURVIVOR_HEAD  &&  m_DirectHit.IsAlive() ) // Is the victim a survivor?
			{
				stopping_force = stopping_force * 2;
			}
			*/
			
			/*
			// TO DO: Doesn't work. Need to recognize a zombie somehow
			else if ( m_DirectHit.IsInherited(DayZCreatureAIType)  &&  m_componentIndex == INFECTED_HEAD ) // Is the victim a survivor that's hit in the head?
			{
				stopping_force = stopping_force * 2;
			}*/
		}
		
		return stopping_force;
	}

	override void Event_OnStarted()
	{
		super.Event_OnStarted();
		
		if (m_ImpactType != ImpactTypes.MELEE)
		{
			vector in_speed = m_InSpeed * (-1); // Compiler demands to have this variable
			
			BloodSplatGround( GetPosition(), in_speed , 0.5 );
			
			if (m_OutSpeed.Length() > 0)
			{
				BloodSplatGround( m_ExitPos, m_OutSpeed, 0.8  );
			}
		}
	}
	
	void BloodSplatGround( vector start_pos, vector speed_vector, float decay_coef )
	{
		vector pos = start_pos;
		float power = m_StoppingForce;
		float upscale = 1;
		float rnd_offset = 0.5;
		float rnd_offset_2 = rnd_offset * 0.5;
		
		while (power > 200)
		{
			pos = pos + ( speed_vector * 0.001 );
			pos = pos + Vector( rnd_offset_2 - Math.RandomFloat( 0, rnd_offset ), 0, rnd_offset_2 - Math.RandomFloat( 0, rnd_offset ) );
			pos[1] = g_Game.SurfaceY(pos[0], pos[2]);
			
			EffectParticle eff = new BloodSplatter();
			eff.SetAutodestroy(true);
			SEffectManager.PlayInWorld(eff, pos);
			
			Particle blood = eff.GetParticle(); // TO DO: Handle particle changes inside the Effect instance itself! Not here!

			vector ori = g_Game.GetSurfaceOrientation(pos[0], pos[2]);
						
			blood.SetOrientation(ori);
			blood.ScaleParticleParam(EmitorParam.SIZE, upscale);
			
			Particle blood_chunks = ParticleManager.GetInstance().PlayInWorld(ParticleList.BLOOD_SURFACE_CHUNKS, pos);
			blood_chunks.SetOrientation(ori);
			
			power = power * decay_coef;
			upscale = upscale + Math.RandomFloat(0.1, 1);			
			
			BloodSplatWall();
		}
	}
	
	void BloodSplatWall()
	{
		// Commented out due to age rating process :(
		
		/*
		if (m_OutSpeed.Length() > 0)
		{
			Object projected_surface;
			vector hit_pos;
			vector hit_normal;
			float hit_fraction; 
			DayZPhysics.RayCastBullet(m_ExitPos, m_ExitPos + m_OutSpeed, PhxInteractionLayers.BUILDING, m_Object, projected_surface, hit_pos, hit_normal, hit_fraction);
			
			hit_normal = hit_normal.VectorToAngles();
			hit_normal[1] = hit_normal[1] + 90;
			
			EffectParticle eff = new BloodSplatter();
			eff.SetAutodestroy(true);
			SEffectManager.PlayInWorld(eff, hit_pos);
			Particle blood = eff.GetParticle();
			blood.SetOrientation(hit_normal);
		}
		*/
	}
	
	override void OnEnterCalculations( Particle p )
	{
		// Calculate particle's size based on bullet's speed
		float velocity_min = MIN_SCALING_PARAM + (m_StoppingForce * m_EnterSplashCoef);
		float velocity_max = MIN_SCALING_PARAM + (m_StoppingForce * m_EnterSplashCoef);
		float size = MIN_SCALING_PARAM + ( m_StoppingForce * m_EnterSplashCoef);
		float birth_rate = MIN_SCALING_PARAM + (m_StoppingForce * m_EnterSplashCoef/2);
		
		if ( m_AmmoType == "Bullet_12GaugePellets" )
		{
			birth_rate *= 0.5;
			velocity_min *= 2;
			velocity_max *= 2;
		}
		
		// Additional size increase by distance from camera
		vector camera_pos = g_Game.GetCurrentCameraPosition();
		float distance = vector.Distance(camera_pos, m_Pos);
		float scaling_by_distance = (distance*1.2) * m_ScalingByDistance;
		
		// Now scale down the above size increase by player's zoom-in value
		float current_FOV = Camera.GetCurrentFOV();
		float config_FOV = GetDayZGame().GetUserFOVFromConfig();
		float FOV_scale = current_FOV / config_FOV;
		scaling_by_distance = scaling_by_distance * FOV_scale;

		if (scaling_by_distance > 5)
			scaling_by_distance = 5;
		
		size = size + scaling_by_distance;
		velocity_min = velocity_min + scaling_by_distance;
		velocity_max = velocity_max + scaling_by_distance;
		
		if (velocity_min < MIN_SCALING_PARAM)
			velocity_min = MIN_SCALING_PARAM;
		
		if (velocity_max < MIN_SCALING_PARAM * 2)
			velocity_max = MIN_SCALING_PARAM * 2;
		
		if (size < MIN_SCALING_PARAM)
			size = MIN_SCALING_PARAM;
		
		if (birth_rate < MIN_SCALING_PARAM)
			birth_rate = MIN_SCALING_PARAM;
		
		p.ScaleParticleParam(EmitorParam.VELOCITY, velocity_min);
		p.ScaleParticleParam(EmitorParam.VELOCITY_RND, velocity_max);
		p.ScaleParticleParam(EmitorParam.SIZE, size);
		p.ScaleParticleParam(EmitorParam.BIRTH_RATE, birth_rate);
	}
	
	override void OnExitCalculations(Particle p, float outSpeedf)
	{
		float velocity_rnd = outSpeedf * m_ExitSplashCoef;
		float birth_rate_rnd_def = outSpeedf * m_ExitSplashCoef;
		float size = outSpeedf * m_ExitSplashCoef;
		
		if (velocity_rnd < MIN_SCALING_PARAM)
			velocity_rnd = MIN_SCALING_PARAM;
		
		if (size < MIN_SCALING_PARAM)
			size = MIN_SCALING_PARAM;
		
		if (size > 1)
			size = 1;
		
		if (birth_rate_rnd_def < MIN_SCALING_PARAM)
			birth_rate_rnd_def = MIN_SCALING_PARAM;
		
		p.ScaleParticleParam(EmitorParam.VELOCITY_RND, velocity_rnd);
		p.ScaleParticleParam(EmitorParam.BIRTH_RATE, birth_rate_rnd_def);
		p.ScaleParticleParam(EmitorParam.SIZE, size);
	}
}