bool CBaseGrabHandler::SetGrab(SmartScriptTable &rParams) { ScriptHandle id; id.n = 0; rParams->GetValue("entityId",id); rParams->GetValue("holdPos",m_grabStats.lHoldPos); rParams->GetValue("followSpeed",m_grabStats.followSpeed); m_grabStats.collisionFlags = 0; rParams->GetValue("collisionFlags",m_grabStats.collisionFlags); m_grabStats.grabDelay = 0.0f; rParams->GetValue("grabDelay",m_grabStats.grabDelay); m_grabStats.throwDelay = 0.0f; m_grabStats.maxDelay = m_grabStats.grabDelay; m_grabStats.entityGrabSpot = Vec3 (0.0f, 0.0f, 0.0f); rParams->GetValue("entityGrabSpot",m_grabStats.entityGrabSpot); m_grabStats.boneGrabOffset = Vec3 (0.0f, 0.0f, 0.0f); rParams->GetValue("boneGrabOffset",m_grabStats.boneGrabOffset); // NOTE Dez 12, 2006: <pvl> the following code was formerly in CBaseGrabHandler::StartGrab(). if (m_grabStats.grabId<1) { IEntity *pGrab = gEnv->pEntitySystem->GetEntity((EntityId)id.n); if (pGrab) { float heavyness(0.0f); float volume(0.0f); if (!m_pActor->CanPickUpObject(pGrab,heavyness, volume)) return false; m_grabStats.grabId = (EntityId)id.n; m_grabStats.additionalRotation = (m_pActor->GetEntity()->GetRotation().GetInverted() * pGrab->GetRotation()).GetNormalized(); //if there is still a link to remove if (m_grabStats.dropId>0) { // NOTE Dez 14, 2006: <pvl> switch collision detection back // on for the object to be dropped IgnoreCollision(m_grabStats.dropId,m_grabStats.collisionFlags,false); m_grabStats.dropId = 0; } IgnoreCollision(m_grabStats.grabId,m_grabStats.collisionFlags,true); return true; } } else { assert (0); } return false; }
void CBaseGrabHandler::Update(float frameTime) { //we have to restore the grabbed object collision flag at some point after the throw. if(m_grabStats.dropId>0) { m_grabStats.resetFlagsDelay -= frameTime; if(m_grabStats.resetFlagsDelay<0.001f) { IgnoreCollision(m_grabStats.dropId,m_grabStats.collisionFlags,false); m_grabStats.dropId = 0; } } if(m_grabStats.grabId<1) return; if(m_pActor->GetHealth()<=0) { StartDrop(); return; } IEntity *pGrab = gEnv->pEntitySystem->GetEntity(m_grabStats.grabId); if(pGrab) { bool grabbing(m_grabStats.grabDelay>0.001f); if(!grabbing || m_grabStats.usingAnimation) UpdatePosVelRot(frameTime); } else { //in case the grabber lost the grabbed object, reset the ignore collision flags // FIXME Dez 14, 2006: <pvl> the following should be done by // calling IgnoreCollisions() but that function requires // id of the grabbed object => needs refactoring IPhysicalEntity *pActorPhys = m_pActor->GetEntity()->GetPhysics(); if(pActorPhys) { pe_action_update_constraint uc; uc.bRemove = 1; pActorPhys->Action(&uc); } } // TODO Sep 13, 2007: <pvl> I strongly suspect releaseIKTime is redundant now. // NOTE Sep 13, 2007: <pvl> note that all timeouts are dodgy here since there's // no guarantee that the grabbing/throwing animation starts playing immediately // after the grabbing command is issued. if(m_grabStats.releaseIKTime>0.001f && m_grabStats.grabDelay < 0.001f) m_grabStats.releaseIKTime -= frameTime; }