예제 #1
0
//-------------------------------------------------------------------------
IMPLEMENT_RMI(CC4Projectile, ClStickToEntity)
{
	if(IEntity *pEntity = gEnv->pEntitySystem->GetEntity(params.targetId))
	{
		Matrix34 localMatrix;
		localMatrix.SetRotation33(Matrix33(params.localRotation));
		localMatrix.SetTranslation(params.localCollisonPos);
		StickToEntity(pEntity,localMatrix);
	}

	return true;
}
예제 #2
0
//-----------------------------------------------------------------------------
// Purpose: Called to see if we should attach to the victim
// Input  : *pOther - the victim
//-----------------------------------------------------------------------------
void CWeaponStriderBuster::BusterTouch( CBaseEntity *pOther )
{
	// Attempt to stick to the entity
	StickToEntity( pOther );
}
void CStickyProjectile::Stick(const SStickParams& stickParams)
{
	if(!gEnv->bServer && ((m_flags&eSF_HandleLocally)==0))
		return;

	// Must have physics.
	if(!stickParams.m_pTarget)
		return;

	// Don't stick to Breakables.
	if(ISurfaceType *pSurfaceType = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceType(stickParams.m_targetMatId))
	{
		if (pSurfaceType->GetBreakability() == 1)
			return;
	}

	// Ignore water collision
	if ( CProjectile::GetMaterialLookUp().IsMaterial( stickParams.m_targetMatId, CProjectile::SMaterialLookUp::eType_Water ) )
		return;

	// Don't stick to particles type physics.
	const int peType = stickParams.m_pTarget->GetType();
	if( peType == PE_PARTICLE )
		return;

	const int iForiegnData = stickParams.m_pTarget->GetiForeignData();
	IEntity* pTargetEntity = iForiegnData==PHYS_FOREIGN_ID_ENTITY ? (IEntity*)stickParams.m_pTarget->GetForeignData(PHYS_FOREIGN_ID_ENTITY) : NULL;
	if( pTargetEntity )
	{
		const EntityId targetEntityId = pTargetEntity->GetId();

		// Don't stick to owner.
		if(targetEntityId==stickParams.m_ownerId)
			return;

		//Do not attach to other projectiles
		if(g_pGame->GetWeaponSystem()->GetProjectile(targetEntityId))
			return;

		// Do Stick.
		if(!StickToEntity(stickParams, pTargetEntity))
			return;
	}
	else
	{
		// Without an entity, we expect the object to not be moving. So if it isn't the terrain or a static, then don't stick to it.
		if( iForiegnData!=PHYS_FOREIGN_ID_TERRAIN && iForiegnData!=PHYS_FOREIGN_ID_STATIC )
			return;

		// Do Stick.
		if(!StickToStatic(stickParams))
			return;
	}

	//////////////////////////////////////////////////////////////////////////

	IEntity* pProjectileEntity = stickParams.m_pProjectile->GetEntity();
	if(CWeapon* pWeapon = stickParams.m_pProjectile->GetWeapon())
	{
		pWeapon->OnProjectileCollided( pProjectileEntity->GetId(), stickParams.m_pTarget, stickParams.m_stickPosition );
	}

	if((m_flags&eSF_HandleLocally)==0)
	{
		CHANGED_NETWORK_STATE(stickParams.m_pProjectile, eEA_GameServerStatic);
	}

	SendHitInfo(stickParams.m_pProjectile, pTargetEntity);

	IPhysicalEntity* pPhysEnt = pProjectileEntity->GetPhysics();
	if(((m_flags&eSF_IsStuck)!=0) && pPhysEnt)
	{
		pe_params_part pp;
		pp.flagsAND = ~geom_colltype_explosion;
		pp.flagsColliderAND = ~geom_colltype_solid;
		pp.mass = 0.0f;
		pPhysEnt->SetParams(&pp);
	}
}
예제 #4
0
//-----------------------------------------------
//This function is only executed on the server
void CC4Projectile::Stick(EventPhysCollision *pCollision)
{
	assert(pCollision);
	int trgId = 1;
	IPhysicalEntity *pTarget = pCollision->pEntity[trgId];

	if(pTarget == GetEntity()->GetPhysics())
	{
		trgId = 0;
		pTarget = pCollision->pEntity[trgId];
	}

	//Do not stick to breakable glass
	if(ISurfaceType *pSurfaceType = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceType(pCollision->idmat[trgId]))
	{
		if(pSurfaceType->GetBreakability()==1)
		{
			m_notStick = true;
			return;
		}
	}

	IEntity *pTargetEntity = pTarget ? gEnv->pEntitySystem->GetEntityFromPhysics(pTarget) : 0;

	if(pTarget && (!pTargetEntity || (pTargetEntity->GetId() != m_ownerId)))
	{
		//Special cases
		if(pTargetEntity)
		{
			//Stick to actors using a character attachment
			CActor *pActor = static_cast<CActor *>(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTargetEntity->GetId()));

			//Not in MP
			if(pActor && gEnv->bMultiplayer)
			{
				m_notStick = true;
				return;
			}

			if(pActor && pActor->GetHealth()>0)
			{
				if(pActor->GetActorSpecies()!=eGCT_HUMAN)
				{
					m_notStick = true;
					return;
				}

				if(StickToCharacter(true,pTargetEntity))
				{
					GetGameObject()->SetAspectProfile(eEA_Physics, ePT_None);
					m_stuck = true;
				}

				m_notStick = true;
				return;
			}

			//Do not stick to small objects...
			if(!pActor)
			{
				pe_params_part pPart;
				pPart.ipart = 0;

				if(pTarget->GetParams(&pPart) && pPart.pPhysGeom && pPart.pPhysGeom->V<0.15f)
				{
					m_notStick = true;
					return;
				}
			}

		}
		else if(pTarget->GetType()==PE_LIVING)
		{
			m_notStick = true;
			return;
		}

		if(!pTargetEntity)
			StickToStaticObject(pCollision,pTarget);
		else
		{
			//Do not attach to items
			if(g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pTargetEntity->GetId()))
			{
				m_notStick = true;
				return;
			}

			Matrix34 mat = pTargetEntity->GetWorldTM();
			mat.Invert();
			Vec3 pos = mat.TransformPoint(pCollision->pt);
			mat.SetIdentity();
			mat.SetRotation33(Matrix33::CreateOrientation(-pCollision->n,GetEntity()->GetWorldTM().TransformVector(Vec3(0,0,1)),gf_PI));
			mat.SetTranslation(pos);

			//Dephysicalize and stick
			GetGameObject()->SetAspectProfile(eEA_Physics, ePT_None);

			StickToEntity(pTargetEntity,mat);

			if(gEnv->bMultiplayer)
			{
				Quat rot(Matrix33::CreateOrientation(-pCollision->n,GetEntity()->GetWorldTM().TransformVector(Vec3(0,0,1)),gf_PI*0.5f));
				GetGameObject()->InvokeRMI(CC4Projectile::ClStickToEntity(),ProjectileStickToEntity(pTargetEntity->GetId(),pos,rot),eRMI_ToAllClients);
			}
		}

		m_stuck = true;
	}
}