void GravityGun::Update( float dt )
{
    if( !IsWeaponSelected() )
        return;

//	Vector3 vOwnerMuzzlePos = rWeaponSystem.m_vMuzzlePosition + rWeaponSystem.m_vMuzzleDirection * 0.25f
//		                                                      + rWeaponSystem.m_vMuzzleDir_Up * 0.90f;

    Vector3 vOwnerMuzzlePos = m_MuzzleEndWorldPose.vPosition;

    CCopyEntity *pTarget = m_Target.GetRawPtr();
    if( pTarget )
    {
        // calc the translation from the center of the target to the muzzle position
        Vector3 vDist = vOwnerMuzzlePos - pTarget->GetWorldPosition();

        float fDistSq = Vec3LengthSq(vDist);
        if( m_fMaxRange * m_fMaxRange < fDistSq )
        {
            m_iHoldingTargetToggle = 0;
//			m_pTarget->pPhysicsActor->SetAllowFreezing( true );
            m_Target.Reset();
            return;
        }

        STrace tr;
        tr.bvType = BVTYPE_DOT;
        tr.vStart = vOwnerMuzzlePos;
        Vector3 vGoal = pTarget->GetWorldPosition();
        tr.vGoal = vGoal;
        tr.sTraceType = TRACETYPE_IGNORE_NOCLIP_ENTITIES;
        /*
        		CTrace tr;
        		tr.BVType    = BVTYPE_DOT;
        		tr.vStart    = &vOwnerMuzzlePos;
        		tr.vGoal     = &pTarget->GetWorldPosition();
        		tr.TypeFlags = CTrace::FLAG_IGNORE_NOCLIP_ENTITIES;//TRACETYPE_IGNORE_NOCLIP_ENTITIES;
        */
        // check trace
        CStageSharedPtr pStage = m_pStage.lock();
        if( pStage )
            pStage->ClipTrace( tr );

        if( tr.pTouchedEntity != pTarget )
        {
            // found an obstacle between the player and the target object
            // - unable to hold the target any more
            m_iHoldingTargetToggle = 0;
//			m_pTarget->pPhysicsActor->SetAllowFreezing( true );
            m_Target.Reset();
            return;
        }

        if( fDistSq < m_fGraspRange * m_fGraspRange || m_aTriggerState[1] == 1 )
        {
            // the gravity gun is holding the target object

            // account for the target object's size so that it does not bump into the shooter
            float fDist = sqrtf(fDistSq);
            Vector3 vDir = vDist / fDist;		// normalization
            fDist -= ( pTarget->fRadius + 0.2f );
            vDist = vDir * fDist;

            // calc relative velocity
            Vector3 vRVel = pTarget->Velocity() - m_vMuzzleEndVelocity;

            Vector3 vForce;
//			vForce = m_fPosGain * vDist - m_fSpeedGain * vRVel;
//			m_pTarget->ApplyWorldImpulse( vForce, m_pTarget->GetWorldPosition());


            if( 6.0f < fDist )
                vForce = vDir * 6.0f * 2.5f;
            else if( fDist < 0.6f )
                vForce = vDir * fDist * 8.0f;
            else
//				vForce = vDir * fDist * 2.5f;
                vForce = vDir * ( fDist * 2.0f + 3.0f );

            vForce += m_vMuzzleEndVelocity;

            physics::CActor *pPhysicsActor = pTarget->GetPrimaryPhysicsActor();
            if( pPhysicsActor )
                pPhysicsActor->SetLinearVelocity( vForce );

            /*			Vector3 vPos = m_pTarget->pPhysicsActor->GetPosition();
            			Vector3 vVel = m_pTarget->pPhysicsActor->GetVelocity();
            			SmoothCD( vPos, vPos + vDist, vVel, 0.25f, dt );

            			if( 12.0f * 12.0f < Vec3LengthSq(vVel) )
            			{
            				Vec3Normalize( vVel, vVel );
            				vVel *= 12.0f;
            			}
            			m_pTarget->pPhysicsActor->SetVelocity( vVel );
            */
            return;
        }
        else
        {
            // lost control of the target
            m_iHoldingTargetToggle = 0;

            ReleaseObject();

            return;
        }
    }
}
Exemple #2
0
void CBE_Enemy::OnDestroyed( CCopyEntity* pCopyEnt )
{
	// explosion - usu. done by texture animation
	CCopyEntityDesc explosion;
	explosion.pBaseEntityHandle = &m_Explosion;
	explosion.SetWorldPose( pCopyEnt->GetWorldPose() );
	explosion.vVelocity  = Vector3(0,0,0);

	this->m_pStage->CreateEntity( explosion );

	// avoid overlaps with fragment entities
	pCopyEnt->bNoClip = true;

	LOG_PRINT( " An enemy entity destroyed - velocity: " + to_string(pCopyEnt->Velocity()) );

	CCopyEntity* pFragEntity;
//	MsgBoxFmt( "%s destroyed - creating %d fragments", pCopyEnt->GetName().c_str(), m_iNumFragments );
	const int num_fragments = m_iNumFragments;
	for(int i=0; i<num_fragments; i++)
	{
		const Fragment& frag = m_aFragment[i];

		CCopyEntityDesc& rFrag = explosion;	// reuse desc object
		rFrag.pBaseEntityHandle = &m_aFragment[i].BaseEntity;

		rFrag.SetWorldPosition( pCopyEnt->GetWorldPose() * frag.vOffset );
//		D3DXVec3TransformCoord( &vWorldFragmentOffset, &m_avFragmentOffset[i], &pCopyEnt->GetOrientation() );
//		rFrag.vPosition  = pCopyEnt->GetWorldPosition() + vWorldFragmentOffset;

		rFrag.SetWorldOrient( pCopyEnt->GetWorldPose().matOrient );

//BSPStageBase	rFrag.vVelocity  = pCopyEnt->Velocity() * 0.3f + vWorldFragmentOffset * 20.0f
//BSPStageBase			         + Vector3( RangedRand(-10.0f,10.0f), RangedRand(-8.0f,8.0f), RangedRand(-10.0f,10.0f) );

		rFrag.vVelocity = Vec3RandDir() * RangedRand( frag.InitVelocity.min, frag.InitVelocity.max )
//		rFrag.vVelocity = Vec3RandDir() * RangedRand( 15.5f, 35.0f )
				        + pCopyEnt->Velocity();

		pFragEntity = this->m_pStage->CreateEntity( rFrag );
		if( pFragEntity )
		{
			physics::CActor *pPhysicsActor = pFragEntity->GetPrimaryPhysicsActor();
			if( pPhysicsActor )
			{
				pPhysicsActor->SetAngularVelocity( Vec3RandDir() * RangedRand( 0.5f, 8.0f ) );
			}
		}
	}

/*
	int num_items = m_vecRewardItem.size();
	float f = 0, rand_val;
	for(i=0; i<m_iNumFragments; i++)
	{
		rand_val = GetRangedRand( 0.0f, 1.0f );
		f += m_vecRewardItem[i].m_fProbability;

		if( rand_val < f )
		{
		}
	}
	*/

	// leave a life item
//			m_pStage->CreateEntity( "s_Life", pCopyEnt->GetWorldPosition(),
//				Vector3(0,0,0), Vector3(0,0,1) );
}
bool GravityGun::HandleInput( int input_code, int input_type, float fParam )
{
    Vector3 vOwnerMuzzlePos = m_MuzzleEndWorldPose.vPosition;

    switch( input_code )
    {
    case ACTION_ATK_FIRE:
        if( input_type == ITYPE_KEY_PRESSED )
        {
            m_aTriggerState[0] = 1;

            CCopyEntity *pTarget = m_Target.GetRawPtr();
            if( pTarget )
            {
                physics::CActor *pPhysicsActor = pTarget->GetPrimaryPhysicsActor();
                Vector3 vDist = vOwnerMuzzlePos - pTarget->GetWorldPosition();

                float fDistSq = Vec3LengthSq(vDist);
                if( fDistSq < m_fGraspRange * m_fGraspRange )
                {
                    Vector3 vImpulse = m_MuzzleEndLocalPose.matOrient.GetColumn(2) * m_fPower;

                    // shoot object
//					pTarget->ApplyWorldImpulse( vImpulse, m_pTarget->GetWorldPosition() );
                    pPhysicsActor->SetLinearVelocity( vImpulse );

                    // release object
//					m_pTarget->pPhysicsActor->SetAllowFreezing( true );
                    m_Target.Reset();
                    m_iHoldingTargetToggle = 0;
                    return true;
                }
            }
        }
        else if( input_type == ITYPE_KEY_RELEASED )
        {
            m_aTriggerState[0] = 0;
            return true;
        }
        break;

    case ACTION_ATK_RAISEWEAPON:
    case ACTION_ATK_UNLOCK_TRIGGER_SAFETY:
        if( input_type == ITYPE_KEY_PRESSED )
        {
            m_aTriggerState[1] = 1;

            // the owner pulled the second trigger
            m_iHoldingTargetToggle = ~m_iHoldingTargetToggle;

            CCopyEntity *pTarget = m_Target.GetRawPtr();
            if( !pTarget )
            {
                // trigger is pulled and the gravity gun is not holding any object right now
                // - check if there is an object in the aim direction
                return GraspObjectInAimDirection();
            }
            else
            {
                // trigger is pulled when the gun is holding an object
                // - release the object
                ReleaseObject();
                return true;
            }
        }
        else if( input_type == ITYPE_KEY_RELEASED )
        {
            m_aTriggerState[1] = 0;
            return true;
        }
        break;
    default:
        break;
    }

    return false;
}