//------------------------------------------------------------------------ void CProjectile::Launch(const Vec3 &pos, const Vec3 &dir, const Vec3 &velocity, float speedScale) { Matrix34 worldTM=Matrix34(Matrix33::CreateRotationVDir(dir.GetNormalizedSafe())); worldTM.SetTranslation(pos); GetEntity()->SetWorldTM(worldTM); //Must set velocity after position, if not velocity could be reseted for PE_RIGID SetVelocity(pos, dir, velocity, speedScale); m_initial_pos = pos; m_initial_dir = dir; m_initial_vel = velocity; m_last = pos; // Attach effect when fired (not first update) if (m_trailEffectId<0) TrailEffect(true); IAIObject* pAI = 0; if ((pAI = GetEntity()->GetAI()) != NULL && pAI->GetAIType() == AIOBJECT_GRENADE) { IEntity *pOwnerEntity = gEnv->pEntitySystem->GetEntity(m_ownerId); if (pOwnerEntity && pOwnerEntity->GetAI()) { pe_status_dynamics dyn; pe_status_dynamics dynProj; if (pOwnerEntity->GetAI()->GetProxy() && pOwnerEntity->GetPhysics() && pOwnerEntity->GetPhysics()->GetStatus(&dyn) && GetEntity()->GetPhysics()->GetStatus(&dynProj)) { Vec3 ownerVel( dyn.v); Vec3 grenadeDir(dynProj.v.GetNormalizedSafe()); // Trigger the signal at the predicted landing position. Vec3 predictedPos = pos; float dummySpeed; if (GetWeapon()) GetWeapon()->PredictProjectileHit(pOwnerEntity->GetPhysics(), pos, dir, velocity, speedScale * m_pAmmoParams->speed, predictedPos, dummySpeed); /* bool res = pOwnerEntity->GetAI()->GetProxy()->GetSecWeapon()->PredictProjectileHit( pOwnerEntity->GetPhysics(), GetEntity()->GetPos(), grenadeDir, ownerVel, 1, predictedPos, speed);*/ gEnv->pAISystem->GrenadeEvent(predictedPos, 0.0f, AIGE_GRENADE_THROWN, GetEntity(), pOwnerEntity); // Inform the AI that sees the throw /* IAIObject* pOwnerAI = pOwnerEntity->GetAI(); AutoAIObjectIter it(gEnv->pAISystem->GetFirstAIObjectInRange(IAISystem::OBJFILTER_TYPE, AIOBJECT_PUPPET, predictedPos, 20.0f, false)); for(; it->GetObject(); it->Next()) { IAIObject* pAI = it->GetObject(); if (!pAI->IsEnabled()) continue; if (pOwnerAI && !pOwnerAI->IsHostile(pAI,false)) continue; // Only sense grenades that are on front of the AI and visible when thrown. // Another signal is sent when the grenade hits the ground. Vec3 delta = GetEntity()->GetPos() - pAI->GetPos(); // grenade to AI float dist = delta.NormalizeSafe(); const float thr = cosf(DEG2RAD(160.0f)); if (delta.Dot(pAI->GetViewDir()) > thr) { ray_hit hit; static const int objTypes = ent_static | ent_terrain | ent_rigid | ent_sleeping_rigid; static const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any; int res = gEnv->pPhysicalWorld->RayWorldIntersection(pAI->GetPos(), delta*dist, objTypes, flags, &hit, 1); if (!res || hit.dist > dist*0.9f) { IAISignalExtraData* pEData = gEnv->pAISystem->CreateSignalExtraData(); // no leak - this will be deleted inside SendAnonymousSignal pEData->point = predictedPos; pEData->nID = pOwnerEntity->GetId(); pEData->iValue = 1; gEnv->pAISystem->SendSignal(SIGNALFILTER_SENDER, 1, "OnGrenadeDanger", pAI, pEData); } } } */ } } } }
//------------------------------------------------------------------------ void CProjectile::Launch(const Vec3 &pos, const Vec3 &dir, const Vec3 &velocity, float speedScale) { m_destroying = false; GetGameObject()->EnablePhysicsEvent(true, eEPE_OnCollisionLogged); // Only for bullets m_hitPoints = m_pAmmoParams->hitPoints; m_hitListener = false; if(m_hitPoints>0) { //Only projectiles with hit points are hit listeners g_pGame->GetGameRules()->AddHitListener(this); m_hitListener = true; m_noBulletHits = m_pAmmoParams->noBulletHits; } Matrix34 worldTM=Matrix34(Matrix33::CreateRotationVDir(dir.GetNormalizedSafe())); worldTM.SetTranslation(pos); GetEntity()->SetWorldTM(worldTM); //Must set velocity after position, if not velocity could be reseted for PE_RIGID SetVelocity(pos, dir, velocity, speedScale); m_initial_pos = pos; m_initial_dir = dir; m_initial_vel = velocity; m_last = pos; // Attach effect when fired (not first update) if(m_trailEffectId<0) TrailEffect(true); IAIObject *pAI = 0; if((pAI = GetEntity()->GetAI()) != NULL && pAI->GetAIType() == AIOBJECT_GRENADE) { IEntity *pOwnerEntity = gEnv->pEntitySystem->GetEntity(m_ownerId); pe_status_dynamics dyn; pe_status_dynamics dynProj; if(pOwnerEntity->GetPhysics() && pOwnerEntity->GetPhysics()->GetStatus(&dyn) && GetEntity()->GetPhysics()->GetStatus(&dynProj)) { // Vec3 ownerVel(dyn.v); Vec3 grenadeDir(dynProj.v.GetNormalizedSafe()); // Trigger the signal at the predicted landing position. Vec3 predictedPos = pos; float dummySpeed; if(GetWeapon()) GetWeapon()->PredictProjectileHit(pOwnerEntity->GetPhysics(), pos, dir, velocity, speedScale * m_pAmmoParams->speed, predictedPos, dummySpeed); // Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc) EntityId ownerId = pOwnerEntity->GetId(); IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(ownerId); if(pActor && pActor->GetLinkedVehicle() && pActor->GetLinkedVehicle()->GetEntityId()) ownerId = pActor->GetLinkedVehicle()->GetEntityId(); SAIStimulus stim(AISTIM_GRENADE, AIGRENADE_THROWN, ownerId, GetEntityId(), predictedPos, ZERO, 20.0f); gEnv->pAISystem->RegisterStimulus(stim); } } }