void vParticleOperator_ColorFade::Simulate( vParticle *parent )
{
	Vector colorOld = parent->GetCurrentColor();
	float imp = GetImpulse( parent );
	Vector colorNew = Lerp( imp, colorOld, colort );
	parent->SetCurrentColor( colorNew );
}
void RPG_Explosion::Apply()
{
  hkpWorld* world = vHavokPhysicsModule::GetInstance()->GetPhysicsWorld();

  // get collidables
  world->markForRead();

  m_phantom->ensureDeterministicOrder();
  hkArray<hkpCollidable*>& collidables = m_phantom->getOverlappingCollidables();

  world->unmarkForRead();

  // apply impulses
  world->markForWrite();

  const int numCollidables = collidables.getSize();
  for ( int i = 0; i < numCollidables; ++i )
  {
    hkpRigidBody* rb = hkpGetRigidBody( collidables[i] );

    // Ignore other phantoms and fixed rigid bodies.
    if ( (rb != HK_NULL) && !rb->isFixed() )
    {
      hkVector4 const& position = rb->getPosition();
      hkVector4 const impulse = GetImpulse(position);
      rb->applyLinearImpulse(impulse);
    }
  }

  world->unmarkForWrite();
}
void vParticleOperator_SizeMultiply::Simulate( vParticle *parent )
{
	float sizeOld = parent->GetCurrentSize();
	float imp = GetImpulse( parent );
	float sizeNew = sizeOld * Lerp( imp, 1.0f, sizet );
	parent->SetCurrentSize( sizeNew );
}
void vParticleOperator_RotationAnimate::Simulate( vParticle *parent )
{
	float rot = parent->flAngle;
	float imp = GetImpulse( parent );
	float rotnew = rot + imp * mult;
	parent->flAngle = rotnew;
}
void vParticleOperator_SizeFade::Simulate( vParticle *parent )
{
	float sizeOld = parent->GetCurrentSize();
	float imp = GetImpulse( parent );
	float sizeNew = Lerp( imp, sizeOld, sizet );
	parent->SetCurrentSize( sizeNew );
}
void vParticleOperator_AlphaFade::Simulate( vParticle *parent )
{
	float alphaOld = parent->GetCurrentAlpha();
	float imp = GetImpulse( parent );
	float alphaNew = Lerp( imp, alphaOld, alphat );
	parent->SetCurrentAlpha( alphaNew );
}
void vParticleOperator_SizeMultiplyXY::Simulate( vParticle *parent )
{
	float sizeOldx = parent->GetCurrentSizeX();
	float sizeOldy = parent->GetCurrentSizeY();
	float imp = GetImpulse( parent );
	float sizeNewx = sizeOldx * Lerp( imp, 1.0f, sizet_x );
	float sizeNewy = sizeOldy * Lerp( imp, 1.0f, sizet_y );
	parent->SetCurrentSize( sizeNewx, sizeNewy );
}
void vParticleOperator_WorldRotationForce::Simulate( vParticle *parent )
{
	QAngle cur = MainViewAngles();

	Vector2D force( AngleDiff( cur.y, last.y ), AngleDiff( last.x, cur.x ) );
	force *= GetImpulse( parent ) * vParticle::GetRelativeScale() * str;

	float rainHack = CFrameTimeHelper::GetFrameTime() - (1.0f/60.0f);
	force += force * rainHack * -20.0f;

	last = cur;

	parent->vecVelocity += force;
}
void vParticleOperator_GravityRotational::Simulate( vParticle *parent )
{
	int vx, vy, w, t;
	vgui::surface()->GetFullscreenViewport( vx, vy, w, t );

	Vector2D gravity_center( w * centerN.x, t * centerN.y );
	Vector2D delta = parent->vecPos - gravity_center;

	Vector2D accel = delta * vParticle::GetRelativeScale() * GetImpulse( parent ) * amt;

	float speedMult = 1.0f;

	parent->vecVelocity += accel;
	parent->vecVelocity *= speedMult;
}
void vParticleOperator_GravityWorld::Simulate( vParticle *parent )
{
	float dot_z = DotProduct( MainViewForward(), Vector( 0, 0, -1 ) );
	float rotation_dir = Sign( dot_z );

	int vx, vy, w, t;
	vgui::surface()->GetFullscreenViewport( vx, vy, w, t );

	Vector screen;
	if ( ScreenTransform( MainViewOrigin() + Vector( 0, 0, 100 ), screen ) )
		ScreenTransform( MainViewOrigin() - Vector( 0, 0, 100 ), screen );

	screen *= Vector( 0.5f, -0.5f, 0 );
	screen += Vector( 0.5f, 0.5f, 0 );

	Vector2D gravity_center( w * screen.x, t * screen.y );
	Vector2D delta = parent->vecPos - gravity_center;

	float screenLength = delta.NormalizeInPlace();
	delta *= rotation_dir * -1.0f;

	Vector2D accel = delta * vParticle::GetRelativeScale() * GetImpulse( parent ) * amt;

	float speedMult = 1.0f;

	if ( rotation_dir > 0 )
	{
		float drag = RemapValClamped( rotation_dir, 0.5f, 1, 1, 0.00001f );
		ScaleByFrametime( drag );

		speedMult = RemapValClamped( (screenLength/vParticle::GetRelativeScale()), 0, 1000, 0, 1 ) * (1.0f - drag) + drag;
	}

	parent->vecVelocity += accel;
	parent->vecVelocity *= speedMult;
}
void vParticleOperator_RotationFade::Simulate( vParticle *parent )
{
	float imp = GetImpulse( parent );
	parent->flAngle = Lerp( imp, rotmin, rotmax );
}
void vParticleOperator_Gravity::Simulate( vParticle *parent )
{
	float multiplier = vParticle::GetRelativeScale();
	parent->vecVelocity += GetImpulse( parent ) * gravity * multiplier;
}
/*
============
ImpulseCommands
============
*/
void CBasePlayer::ImpulseCommands()
{
	TraceResult	tr;// UNDONE: kill me! This is temporary for PreAlpha CDs

				   // Handle use events
	PlayerUse();

	int iImpulse = GetImpulse();
	switch( iImpulse )
	{
	case 99:
		{

			bool bOn;

			if( !gmsgLogo )
			{
				bOn = true;
				//TODO: figure out why this is done here. - Solokiller
				gmsgLogo = REG_USER_MSG( "Logo", 1 );
			}
			else
			{
				bOn = false;
			}

			ASSERT( gmsgLogo > 0 );
			// send "health" update message
			MESSAGE_BEGIN( MSG_ONE, gmsgLogo, NULL, this );
			WRITE_BYTE( bOn );
			MESSAGE_END();

			if( !bOn )
				gmsgLogo = 0;
			break;
		}
	case 100:
		// temporary flashlight for level designers
		if( FlashlightIsOn() )
		{
			FlashlightTurnOff();
		}
		else
		{
			FlashlightTurnOn();
		}
		break;

	case	201:// paint decal

		if( gpGlobals->time < m_flNextDecalTime )
		{
			// too early!
			break;
		}

		UTIL_MakeVectors( GetViewAngle() );
		UTIL_TraceLine( GetAbsOrigin() + GetViewOffset(), GetAbsOrigin() + GetViewOffset() + gpGlobals->v_forward * 128, ignore_monsters, ENT( pev ), &tr );

		if( tr.flFraction != 1.0 )
		{// line hit something, so paint a decal
			m_flNextDecalTime = gpGlobals->time + decalfrequency.value;
			auto pCan = static_cast<CSprayCan*>( UTIL_CreateNamedEntity( "spray_can" ) );
			pCan->CreateSprayCan( this );
		}

		break;

	default:
		// check all of the cheat impulse commands now
		CheatImpulseCommands( iImpulse );
		break;
	}

	SetImpulse( 0 );
}