//------------------------------------------------------------------------- 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; }
//----------------------------------------------------------------------------- // 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); } }
//----------------------------------------------- //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; } }