TAttachedEffectId CEffectsController::AttachParticleEffect(const char *effectName, const int targetSlot, const char *helperName, const SEffectAttachParams &attachParams) { CRY_ASSERT(m_pOwnerEntity); IParticleEffect* pParticleEffect = gEnv->pParticleManager->FindEffect(effectName); return AttachParticleEffect(pParticleEffect, targetSlot, helperName, attachParams); }
//------------------------------------------------------------------------ void CVehicleDamageBehaviorDetachPart::OnDamageEvent(EVehicleDamageBehaviorEvent event, const SVehicleDamageBehaviorEventParams& behaviorParams) { if (event == eVDBE_Repair) return; if (!m_detachedEntityId && behaviorParams.componentDamageRatio >= 1.0f) { CVehiclePartBase* pPart = (CVehiclePartBase*)m_pVehicle->GetPart(m_partName.c_str()); if (!pPart || !pPart->GetStatObj()) return; if (max(1.f-behaviorParams.randomness, pPart->GetDetachProbability()) < cry_random(0.0f, 1.0f)) return; IEntity* pDetachedEntity = SpawnDetachedEntity(); if (!pDetachedEntity) return; m_detachedEntityId = pDetachedEntity->GetId(); const Matrix34& partWorldTM = pPart->GetWorldTM(); pDetachedEntity->SetWorldTM(partWorldTM); MovePartToTheNewEntity(pDetachedEntity, pPart); SEntityPhysicalizeParams physicsParams; physicsParams.mass = pPart->GetMass(); physicsParams.type = PE_RIGID; physicsParams.nSlot = 0; pDetachedEntity->Physicalize(physicsParams); IPhysicalEntity* pPhysics = pDetachedEntity->GetPhysics(); if (pPhysics) { pe_params_part params; params.flagsOR = geom_collides|geom_floats; params.flagsColliderAND = ~geom_colltype3; params.flagsColliderOR = geom_colltype0; pPhysics->SetParams(¶ms); pe_action_add_constraint ac; ac.flags = constraint_inactive|constraint_ignore_buddy; ac.pBuddy = m_pVehicle->GetEntity()->GetPhysics(); ac.pt[0].Set(0,0,0); pPhysics->Action(&ac); // after 1s, remove the constraint again m_pVehicle->SetTimer(-1, 1000, this); // set the impulse const Vec3& velocity = m_pVehicle->GetStatus().vel; Vec3 baseForce = m_pVehicle->GetEntity()->GetWorldTM().TransformVector(pPart->GetDetachBaseForce()); baseForce *= cry_random(6.0f, 10.0f); pe_action_impulse actionImpulse; actionImpulse.impulse = physicsParams.mass * (velocity + baseForce); actionImpulse.angImpulse = physicsParams.mass * Vec3(cry_random(-1.0f,1.0f), cry_random(-1.0f,1.0f), cry_random(-1.0f,1.0f)); actionImpulse.iApplyTime = 1; pPhysics->Action(&actionImpulse); } // copy vehicle's material to new entity (fixes detaching parts from vehicles with different paints), // or specify the destroyed material if it exists IStatObj* pExternalStatObj = pPart->GetExternalGeometry(false); // Get undamaged external geometry (if any) IMaterial *pMaterial = pExternalStatObj ? pExternalStatObj->GetMaterial() : m_pVehicle->GetEntity()->GetMaterial(); if(event == eVDBE_VehicleDestroyed || event == eVDBE_Hit) { if (pExternalStatObj) { if (IStatObj* pStatObj = pPart->GetExternalGeometry(true)) // Try to get the destroyed, external geometry material pMaterial = pStatObj->GetMaterial(); } else if (m_pVehicle->GetDestroyedMaterial()) // If there is no external geometry, try the vehicle's destroyed material { pMaterial = m_pVehicle->GetDestroyedMaterial(); } } pDetachedEntity->SetMaterial(pMaterial); AttachParticleEffect(pDetachedEntity, m_pEffect); if (m_notifyMovement) { SVehicleMovementEventParams params; params.iValue = pPart->GetIndex(); m_pVehicle->GetMovement()->OnEvent(IVehicleMovement::eVME_PartDetached, params); } } }