static Vector3 GetPlayerPosition()
{
	CCopyEntity *pPlayer = GetPlayerEntity();
	if( pPlayer )
		return pPlayer->GetWorldPosition();
	else
		return Vector3(0,0,0);
}
Exemple #2
0
void CBE_Enemy::SearchPlayer(CCopyEntity* pCopyEnt, short& rsMode,
							  Vector3& rvDesiredDirection, float* pfSqDistToPlayer)
{

	// ========= enable the following 2 lines to use enemy observation mode ==========
//	rsMode = CEnemyState::STATE_SEARCH;
//	return;


	Vector3 vStart, vMyselfToPlayer;
	CCopyEntity* pPlayer = SinglePlayerInfo().GetCurrentPlayerBaseEntity()->GetPlayerCopyEntity();

	vStart = pCopyEnt->GetWorldPosition() + pCopyEnt->GetDirection() * 1.42f;
	vMyselfToPlayer = pPlayer->GetWorldPosition() - vStart;

	// chehck the distance to the player
	float fSqDist = Vec3LengthSq( vMyselfToPlayer );
	if( pfSqDistToPlayer )
		*pfSqDistToPlayer = fSqDist;
	if( 40000 < fSqDist )
	{	// too far from the player
		rsMode = CEnemyState::STATE_SEARCH;
		return;
	}

	if( !CheckRayToPlayer(pCopyEnt) )
	{
		rsMode = CEnemyState::STATE_SEARCH;	// there is an obstacle between the player
		return;
	}

	// set 'rvDesiredDirection' - unit vector pointing at the target(player)
	Vec3Normalize( vMyselfToPlayer, vMyselfToPlayer );
	rvDesiredDirection = vMyselfToPlayer;

	float fDotProduct = Vec3Dot( pCopyEnt->GetDirection(), vMyselfToPlayer );

	// 'fDotProduct' ranges from -1 through 1
	if( 0 < fDotProduct )
	{	//the player is visible from this entity
		rsMode = CEnemyState::STATE_ATTACK;	// move to attack mode
	}
	else
	{
		if( fSqDist < 400.0f )
			rsMode = CEnemyState::STATE_ATTACK;	// close enough to hear the player
		else
			rsMode = CEnemyState::STATE_SEARCH;
	}
}
Exemple #3
0
void CES_Search::Act( CCopyEntity& rEntity, CBE_Enemy& rBaseEntity, float dt )
{
	// first, get the extra data of 'pCopyEnt'
	SBE_EnemyExtraData* pExtraData = rBaseEntity.GetExtraData( rEntity.iExtraDataIndex );

	short& rsCurrentState = rEntity.s1;
	float& rfSensoringInterval	= rEntity.f1;
	Vector3& rvDesiredDirection  = rEntity.v1;
	float fSqDistToPlayer;

	rfSensoringInterval += dt;

	if( 0.32f <= rfSensoringInterval )
	{
		rfSensoringInterval = 0;

		// check if the player is in a visible position and update 'rvDesiredDirection' and 'rsMode'
		short sSearchResult = 0;
		rBaseEntity.SearchPlayer( &rEntity, sSearchResult, rvDesiredDirection, &fSqDistToPlayer );

		if( sSearchResult == STATE_ATTACK )
		{	// the player is in sight - engage
			rsCurrentState = STATE_ATTACK;
			rBaseEntity.UpdateDesiredYawAndPitch( &rEntity, rvDesiredDirection );
			pExtraData->vLastCheckedDirectionToPlayer = rvDesiredDirection;
			pExtraData->fLastCheckedSqDistToPlayer    = fSqDistToPlayer;
			pExtraData->vLastCheckedPlayerPosition = rvDesiredDirection * (float)sqrt(fSqDistToPlayer);
			return;
		}
		else
		{	// lost sight of the player
			if( pExtraData->vLastCheckedPlayerPosition != Vector3(0,0,0) )
			{
				Vector3 vDir = pExtraData->vLastCheckedPlayerPosition - rEntity.GetWorldPosition();
				Vec3Normalize( rvDesiredDirection, vDir );
			}
		}
	}

	rBaseEntity.SearchManeuver(&rEntity,pExtraData);
}
Exemple #4
0
void EntityManager::InitEntity( boost::shared_ptr<CCopyEntity> pNewCopyEntPtr,
							 CCopyEntity *pParent,
							 BaseEntity *pBaseEntity,
							 CActorDesc* pPhysActorDesc )
{
	CCopyEntity* pNewCopyEnt = pNewCopyEntPtr.get();

	// Mark the entity as in use
	pNewCopyEnt->inuse = true;

	pNewCopyEnt->m_pSelf = pNewCopyEntPtr;

	pNewCopyEnt->pBaseEntity = pBaseEntity;
	BaseEntity& rBaseEntity = (*pBaseEntity);

	pNewCopyEnt->m_pStage = m_pStage;

	// set id and increment the counter
	pNewCopyEnt->m_ID = m_EntityIDConter++;

	// z-sort is disabled by default initialization
	// Entities that have translucent polygons have to turn on their copy entities'
	// 'BETYPE_USE_ZSORT' in InitCopyEntity()
	if( pNewCopyEnt->m_TypeID == CCopyEntityTypeID::ALPHA_ENTITY )
	{
		// For alpha entity, always use the  z-sorting
		pNewCopyEnt->RaiseEntityFlags( BETYPE_USE_ZSORT );
	}
	else
	{
		// Otherwise, disable z-sorting by default
		pNewCopyEnt->ClearEntityFlags( BETYPE_USE_ZSORT );
	}

	// set the glare type
	if( rBaseEntity.m_EntityFlag & BETYPE_GLARESOURCE )
	{
		pNewCopyEnt->RaiseEntityFlags( BETYPE_GLARESOURCE );
	}
	else if( rBaseEntity.m_EntityFlag & BETYPE_GLAREHINDER )
	{
		pNewCopyEnt->RaiseEntityFlags( BETYPE_GLAREHINDER );
	}

	// update world aabb
	pNewCopyEnt->world_aabb.TransformCoord( pNewCopyEnt->local_aabb, pNewCopyEnt->GetWorldPosition() );


	// link the new copy-entity to the top of 'm_pEntityInUse'
	if( m_pEntityInUse )
		pNewCopyEnt->SetNext( m_pEntityInUse );
	else
		pNewCopyEnt->SetNextToNull(); // first entity in the link list

	m_pEntityInUse = pNewCopyEntPtr;


	// set the created time of the entity
	pNewCopyEnt->m_CreatedTime = m_pStage->GetElapsedTime();

	// set parent entity
	pNewCopyEnt->m_pParent = pParent;
	if( pNewCopyEnt->m_pParent )
	{
		// 'pNewCopyEnt' is being created as a child of another copy entity
		pNewCopyEnt->m_pParent->AddChild( pNewCopyEnt->m_pSelf );	// establish link from the parent to this entity
	}

//	LOG_PRINT( "linking a copy entity of " + rBaseEntity.GetNameString() + " to the tree" );

	// link the new copy-entity to the entity-tree
	Link( pNewCopyEnt );

	// update light information
	if( pNewCopyEnt->Lighting() )
	{
		pNewCopyEnt->ClearLights();
//		UpdateLightInfo( pNewCopyEnt );

		pNewCopyEnt->sState |= CESTATE_LIGHT_INFORMATION_INVALID;
	}

	// create object for physics simulation
	if( pNewCopyEnt->GetEntityFlags() & BETYPE_RIGIDBODY )
	{
		CActor *pPhysActor = NULL;
		if( pPhysActorDesc )
		{
			pPhysActorDesc->WorldPose = pNewCopyEnt->GetWorldPose();// * pNewCopyEnt->GetActorLocalPose();
			pPhysActorDesc->BodyDesc.LinearVelocity = pNewCopyEnt->Velocity();

			// each entity has its own actor desc
			pPhysActor = m_pStage->GetPhysicsScene()->CreateActor( *pPhysActorDesc );
		}
		else if( pBaseEntity->GetPhysicsActorDesc().IsValid() )
		{
			// actor desc is defined by entity attributes
			CActorDesc actor_desc = pBaseEntity->GetPhysicsActorDesc();
			actor_desc.WorldPose = pNewCopyEnt->GetWorldPose();
			actor_desc.BodyDesc.LinearVelocity = pNewCopyEnt->Velocity();
//			pNewCopyEnt->pPhysicsActor = m_pStage->GetPhysicsScene()->CreateActor( actor_desc );
			pPhysActor = m_pStage->GetPhysicsScene()->CreateActor( actor_desc );
		}

		if( pPhysActor )
		{
			pNewCopyEnt->m_vecpPhysicsActor.resize( 1 );
			pNewCopyEnt->m_vecpPhysicsActor[0] = pPhysActor;
			pPhysActor->m_pFrameworkData = pNewCopyEnt;
		}
	}

	// When all the basic properties are copied, InitCopyEntity() is called to 
	// do additional initialization specific to each base entity.
	rBaseEntity.InitCopyEntity( pNewCopyEnt );
}
Exemple #5
0
/**
 Update all the entities cerrently existing in the stage.
 This function must be called once per frame.
 - Basic steps
   - 1. Call BaseEntity::UpdateBaseEntity( dt ) for each base entity
   - 2. Save positions of copy entities
   - 3. Run physics simulator
   - 4. Remove terminated entities from the active list
   - 5. Call CCopyEntity::Act() for each copy entity except for child entities
   - 6. Update link to the entity tree node if an entity has changed its position in Act()
   TODO: Do 5 & 6 in a single loop to update link for each entity right after is Act().
         Current code does this in separate loops.
 */
void EntityManager::UpdateAllEntities( float dt )
{
	CCopyEntity *pEntity = NULL;
	CCopyEntity *pPrevEntity = NULL;
	CCopyEntity *pTouchedEnt = NULL;

	ONCE( LOG_PRINT( " - updating base entities" ) );

	size_t i, num_base_entities = m_vecpBaseEntity.size();
	for( i=0; i<num_base_entities; i++ )
	{
		m_vecpBaseEntity[i]->UpdateBaseEntity( dt );
	}

	// save the current entity positions
	for( pEntity = m_pEntityInUse.get();
	     pEntity != NULL;
	     pEntity = pEntity->m_pNextRawPtr )
	{
		pEntity->PrevPosition() = pEntity->GetWorldPosition();
	}

	// run physics simulator
	// entity position may be modified in this call
	UpdatePhysics( dt );

	ONCE( LOG_PRINT( " - updated physics" ) );

	// remove terminated entities from the active entity list
	ReleaseTerminatedEntities();

	ONCE( LOG_PRINT( " - removed terminated entities from the active entity list" ) );

	// update active entities
	for( pEntity = this->m_pEntityInUse.get(), pPrevEntity = NULL;
		 pEntity != NULL;
		 pPrevEntity = pEntity, pEntity = pEntity->m_pNextRawPtr )
	{
		// before updating pEntity, check if it has been terminated.
		if( !pEntity->inuse )
			continue;

		// set the results of physics simulation to
		// pose, velocity and angular velocity of the entity
//		if( pEntity->pPhysicsActor && pEntity->GetEntityFlags() & BETYPE_USE_PHYSSIM_RESULTS )
		if( 0 < pEntity->m_vecpPhysicsActor.size() && pEntity->GetEntityFlags() & BETYPE_USE_PHYSSIM_RESULTS )
			pEntity->UpdatePhysics();

		if( pEntity->sState & CESTATE_ATREST )
			continue;

		if( !pEntity->m_pParent || !pEntity->m_pParent->inuse )
		{
			// 'pEntity' has no parent or its parent is already terminated
			pEntity->pBaseEntity->Act( pEntity );
		}

		if( !pEntity->inuse )
			continue; // terminated in its own update routine

		UpdateEntityAfterMoving( pEntity );

		// deal with entities touched during this frame
		for(int i=0; i<pEntity->vecpTouchedEntity.size(); i++)
		{
			pTouchedEnt = pEntity->vecpTouchedEntity[i];
			pEntity->pBaseEntity->Touch( pEntity, pTouchedEnt );

			if( pTouchedEnt )
				pTouchedEnt->pBaseEntity->Touch( pTouchedEnt, pEntity );
		}

		// clear touched entities for the next frame
		pEntity->vecpTouchedEntity.clear();
	}

	ONCE( LOG_PRINT( " - updated active entities" ) );

	// unlink and link the entity in the entity tree if it changed its position
/*
	for( pEntity = m_pEntityInUse.get();
		 pEntity != NULL;
		 pPrevEntity = pEntity, pEntity = pEntity->m_pNextRawPtr )
	{
		if( !pEntity->inuse )
			continue;

		UpdateEntityAfterMoving();
	}
*/
}
Exemple #6
0
bool CBE_Enemy::CheckRayToPlayer( CCopyEntity* pCopyEnt )
{
	CCopyEntity* pPlayer = SinglePlayerInfo().GetCurrentPlayerBaseEntity()->GetPlayerCopyEntity();
///	CCopyEntity* pPlayer = PlayerShip.GetPlayerCopyEntity();
	STrace tr;
	Vector3 vCurrentPos = pCopyEnt->GetWorldPosition();
	Vector3 vGoal       = pPlayer->GetWorldPosition();
	tr.vStart        = vCurrentPos;
	tr.vGoal         = vGoal;
	tr.bvType        = BVTYPE_DOT;
	tr.fRadius       = 0;
	tr.pSourceEntity = pCopyEnt;
	tr.sTraceType    = TRACETYPE_IGNORE_NOCLIP_ENTITIES;
	Vector3 vDirToPlayer = vGoal - vCurrentPos;
	Vec3Normalize( vDirToPlayer, vDirToPlayer );	// normalization
	short sRadarPenetrationCount = 2;
	short sRadarState = ERS_NOT_IN_SOLID;

	while( 0 <= sRadarPenetrationCount )
	{
		if( sRadarState == ERS_NOT_IN_SOLID )
		{	// check trace to the player
//			tr.vStart = vCurrentPos;
//			vGoal  =  &pPlayer->GetWorldPosition();
			tr.in_solid = false;
			tr.fFraction = 1.0f;
			this->m_pStage->ClipTrace( tr );

			vCurrentPos = tr.vEnd;

			if( tr.fFraction < 1.0f )	// hit something
			{
				if( tr.pTouchedEntity == pPlayer )
					return true;	// player is in a visible position
				else
				{	// hit static geometry or another entity
					sRadarState = ERS_IN_SOLID;
					vCurrentPos += vDirToPlayer * 0.01f;	// put 'vCurrentPos' in solid region
					sRadarPenetrationCount--;
					continue;
				}
			}
			else // i.e. tr.fFraction == 1.0f
			{	// no hit - an exception. trace should at least hit the player
				return false;
			}
		}
		else // i.e. sRadarState == ERS_IN_SOLID
		{
			vCurrentPos += vDirToPlayer * CBE_ENEMY_RADAR_PENETRATION_CALC_STEP;
			tr.vEnd = vCurrentPos;
			tr.fFraction = 1.0f;
			tr.in_solid = false;
			m_pStage->CheckPosition( tr );

			if( tr.in_solid )
			{	// proceeding inside the material
				sRadarPenetrationCount--;
				continue;
			}
			else
			{	// penetrated through the material

				// move a little forward so that 'vCurrentPos' can safely get out of the wall
				vCurrentPos += vDirToPlayer * 0.05f;
				sRadarState = ERS_NOT_IN_SOLID;
				continue;
			}
		}
	}

	// player is not visible to this enemy entity
	return false;
}
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;
        }
    }
}
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;
}