int CBoidObject::GetGeometrySurfaceType() { if(m_object) { ISurfaceType *pSurfaceType = gEnv->pEntitySystem->GetBreakableManager()->GetFirstSurfaceType(m_object); if(pSurfaceType) return pSurfaceType->GetId(); } else { IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_entity); if(pEntity) { IStatObj *pStatObj = pEntity->GetStatObj(0|ENTITY_SLOT_ACTUAL); if(pStatObj) { ISurfaceType *pSurfaceType = gEnv->pEntitySystem->GetBreakableManager()->GetFirstSurfaceType(pStatObj); if(pSurfaceType) return pSurfaceType->GetId(); } } } return 0; }
//CGameRules::IHitInfo virtual void OnHit(const HitInfo &hitInfo) { if(GetPortBool(&m_actInfo, EIP_Enable) == false) return; EntityId shooter = GetPortEntityId(&m_actInfo, EIP_ShooterId); if(shooter != 0 && shooter != hitInfo.shooterId) return; EntityId target = GetPortEntityId(&m_actInfo, EIP_TargetId); if(target != 0 && target != hitInfo.targetId) return; IEntitySystem *pEntitySys = gEnv->pEntitySystem; IEntity *pTempEntity; // check weapon match const string &weapon = GetPortString(&m_actInfo, EIP_Weapon); if(weapon.empty() == false) { pTempEntity = pEntitySys->GetEntity(hitInfo.weaponId); if(pTempEntity == 0 || weapon.compare(pTempEntity->GetClass()->GetName()) != 0) return; } // check ammo match const string &ammo = GetPortString(&m_actInfo, EIP_Ammo); if(ammo.empty() == false) { pTempEntity = pEntitySys->GetEntity(hitInfo.projectileId); if(pTempEntity == 0 || ammo.compare(pTempEntity->GetClass()->GetName()) != 0) return; } ActivateOutput(&m_actInfo, EOP_ShooterId, hitInfo.shooterId); ActivateOutput(&m_actInfo, EOP_TargetId, hitInfo.targetId); ActivateOutput(&m_actInfo, EOP_WeaponId, hitInfo.weaponId); ActivateOutput(&m_actInfo, EOP_ProjectileId, hitInfo.projectileId); ActivateOutput(&m_actInfo, EOP_HitPos, hitInfo.pos); ActivateOutput(&m_actInfo, EOP_HitDir, hitInfo.dir); ActivateOutput(&m_actInfo, EOP_HitNormal, hitInfo.normal); ActivateOutput(&m_actInfo, EOP_Damage, hitInfo.damage); ISurfaceType *pSurface = g_pGame->GetGameRules()->GetHitMaterial(hitInfo.material); ActivateOutput(&m_actInfo, EOP_Material, string(pSurface ? pSurface->GetName() : "")); const char *hitType = ""; if(CGameRules *pGR = g_pGame->GetGameRules()) hitType = pGR->GetHitType(hitInfo.type); ActivateOutput(&m_actInfo, EOP_HitType, string(hitType)); }
int FindSurfaceIdByName(const char* surfaceTypeName) { CRY_ASSERT(surfaceTypeName != NULL); ISurfaceType* pSurfaceType = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeManager()->GetSurfaceTypeByName(surfaceTypeName); if (pSurfaceType != NULL) { return (int)pSurfaceType->GetId(); } return -1; }
void CBoidObject::Physicalize( SBoidContext &bc ) { pe_params_particle ppart; //ppart.gravity = Vec3(0,0,0); ppart.flags = particle_traceable | particle_no_roll | pef_never_affect_triggers | pef_log_collisions; ppart.mass = 0; ppart.size = max(bc.fBoidRadius,0.01f); ppart.thickness = max(bc.fBoidThickness,0.01f); ppart.gravity = Vec3(0,0,0); ppart.kAirResistance = 0.0f; if(m_object) { IMaterial* pMat = m_object->GetIMaterial(); if(pMat->GetSubMtlCount() > 0) { ppart.surface_idx = pMat->GetSubMtl(0)->GetSurfaceTypeId(); } else { ppart.surface_idx = pMat->GetSurfaceTypeId(); } } else { // just like in GetGeometrySurfaceType() ppart.surface_idx = 0; IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_entity); if (pEntity) { IStatObj *pStatObj = pEntity->GetStatObj(0|ENTITY_SLOT_ACTUAL); if (pStatObj) { ISurfaceType *pSurfaceType = gEnv->pEntitySystem->GetBreakableManager()->GetFirstSurfaceType(pStatObj); if (pSurfaceType) ppart.surface_idx = pSurfaceType->GetId(); } } } IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_entity); if (pEntity) { SEntityPhysicalizeParams params; params.pParticle = &ppart; params.type = PE_PARTICLE; pEntity->Physicalize(params); m_pPhysics = pEntity->GetPhysics(); } }
void SMikeBulletParams::CacheMaterialIds() { if (m_covertedIndexes) return; m_covertedIndexes = true; for (TBurnSurfaceIndexMap::iterator burnIt = m_burnSurfaceIndices.begin(); burnIt != m_burnSurfaceIndices.end(); ++burnIt) { ISurfaceType* pSurfaceType = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeManager()->GetSurfaceTypeByName(burnIt->first.m_materialTypeName.c_str()); if (pSurfaceType) { burnIt->first.m_materialTypeId = pSurfaceType->GetId(); } } }
//------------------------------------------------------------------------ void CBullet::HandleEvent(const SGameObjectEvent &event) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); CProjectile::HandleEvent(event); if (event.event == eGFE_OnCollision) { if (m_destroying) return; EventPhysCollision *pCollision = reinterpret_cast<EventPhysCollision *>(event.ptr); if (!pCollision) return; IEntity *pTarget = pCollision->iForeignData[1]==PHYS_FOREIGN_ID_ENTITY ? (IEntity*)pCollision->pForeignData[1]:0; //Only process hits that have a target if(pTarget) { Vec3 dir(0, 0, 0); if (pCollision->vloc[0].GetLengthSquared() > 1e-6f) dir = pCollision->vloc[0].GetNormalized(); CGameRules *pGameRules = g_pGame->GetGameRules(); IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_ownerId); bool ok = true; if(!gEnv->bMultiplayer && pActor && pActor->IsPlayer()) { IActor* pAITarget = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTarget->GetId()); if(pAITarget && pTarget->GetAI() && pTarget->GetAI()->IsFriendly(pActor->GetEntity()->GetAI(), false)) { pGameRules->SetEntityToIgnore(pTarget->GetId()); ok = false; } } if(ok) { HitInfo hitInfo(m_ownerId, pTarget->GetId(), m_weaponId, (float)m_damage, 0.0f, pGameRules->GetHitMaterialIdFromSurfaceId(pCollision->idmat[1]), pCollision->partid[1], m_hitTypeId, pCollision->pt, dir, pCollision->n); hitInfo.remote = IsRemote(); hitInfo.projectileId = GetEntityId(); hitInfo.bulletType = m_pAmmoParams->bulletType; pGameRules->ClientHit(hitInfo); // Notify AI if (gEnv->pAISystem && !gEnv->bMultiplayer) { static int htMelee = pGameRules->GetHitTypeId("melee"); if (m_ownerId && m_hitTypeId != htMelee) { ISurfaceType *pSurfaceType = pGameRules->GetHitMaterial(hitInfo.material); const ISurfaceType::SSurfaceTypeAIParams* pParams = pSurfaceType ? pSurfaceType->GetAIParams() : 0; const float radius = pParams ? pParams->fImpactRadius : 2.5f; const float soundRadius = pParams ? pParams->fImpactSoundRadius : 20.0f; // Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc) EntityId ownerId = m_ownerId; if (pActor && pActor->GetLinkedVehicle() && pActor->GetLinkedVehicle()->GetEntityId()) ownerId = pActor->GetLinkedVehicle()->GetEntityId(); SAIStimulus stim(AISTIM_BULLET_HIT, 0, ownerId, 0, pCollision->pt, ZERO, radius); gEnv->pAISystem->RegisterStimulus(stim); SAIStimulus stimSound(AISTIM_SOUND, AISOUND_COLLISION_LOUD, ownerId, 0, pCollision->pt, ZERO, soundRadius, AISTIMPROC_FILTER_LINK_WITH_PREVIOUS); gEnv->pAISystem->RegisterStimulus(stimSound); } } } } else { // Notify AI // The above case only catches entity vs. entity hits, the AI is interested in all hits. if (gEnv->pAISystem && !gEnv->bMultiplayer) { CGameRules *pGameRules = g_pGame->GetGameRules(); static int htMelee = pGameRules->GetHitTypeId("melee"); if (m_ownerId && m_hitTypeId != htMelee) { int material = pGameRules->GetHitMaterialIdFromSurfaceId(pCollision->idmat[1]); ISurfaceType *pSurfaceType = pGameRules->GetHitMaterial(material); const ISurfaceType::SSurfaceTypeAIParams* pParams = pSurfaceType ? pSurfaceType->GetAIParams() : 0; const float radius = pParams ? pParams->fImpactRadius : 2.5f; const float soundRadius = pParams ? pParams->fImpactSoundRadius : 20.0f; // Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc) EntityId ownerId = m_ownerId; IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_ownerId); if (pActor && pActor->GetLinkedVehicle() && pActor->GetLinkedVehicle()->GetEntityId()) ownerId = pActor->GetLinkedVehicle()->GetEntityId(); SAIStimulus stim(AISTIM_BULLET_HIT, 0, ownerId, 0, pCollision->pt, ZERO, radius); gEnv->pAISystem->RegisterStimulus(stim); SAIStimulus stimSound(AISTIM_SOUND, AISOUND_COLLISION_LOUD, ownerId, 0, pCollision->pt, ZERO, soundRadius, AISTIMPROC_FILTER_LINK_WITH_PREVIOUS); gEnv->pAISystem->RegisterStimulus(stimSound); } } } if (pCollision->pEntity[0]->GetType() == PE_PARTICLE) { float bouncy, friction; uint32 pierceabilityMat; gEnv->pPhysicalWorld->GetSurfaceParameters(pCollision->idmat[1], bouncy, friction, pierceabilityMat); pierceabilityMat&=sf_pierceable_mask; pe_params_particle params; if(pCollision->pEntity[0]->GetParams(¶ms)==0) SetDefaultParticleParams(¶ms); //Under water trail Vec3 pos=pCollision->pt; if ((pCollision->idmat[1] == CBullet::m_waterMaterialId) && (pCollision->pEntity[1]!=gEnv->pPhysicalWorld->AddGlobalArea() || !gEnv->p3DEngine->GetVisAreaFromPos(pos))) { //Reduce drastically bullet velocity (to be able to see the trail effect) //pe_params_particle pparams; //if(m_pPhysicalEntity->GetParams(&pparams)==0) //SetDefaultParticleParams(&pparams); //pparams.velocity = 25.0f; //m_pPhysicalEntity->SetParams(&pparams); if(m_trailUnderWaterId<0) { //Check terrain/against water level float terrainHeight = gEnv->p3DEngine->GetTerrainElevation(pCollision->pt.x,pCollision->pt.y); float waterLevel = gEnv->p3DEngine->GetWaterLevel(&(pCollision->pt)); if(waterLevel>terrainHeight) { TrailEffect(true,true); return; } } } if (pierceabilityMat<=params.iPierceability || pCollision->idCollider==-1) //Do not destroy if collides water Destroy(); } } }
void SAmmoParams::CacheResources() const { CItemResourceCache& resourceCache = g_pGame->GetGameSharedParametersStorage()->GetItemResourceCache(); if(resourceCache.AreClassResourcesCached(pEntityClass)) return; CItemParticleEffectCache& particleCache = resourceCache.GetParticleEffectCache(); CItemMaterialAndTextureCache& materialCache = resourceCache.GetMaterialsAndTextureCache(); resourceCache.GetAmmoGeometryCache().CacheGeometry(fpGeometryName.c_str(), true); if (!material_name.empty() && (surfaceTypeId == -1)) { ISurfaceType* pSurfaceType = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeByName(material_name.c_str()); if (pSurfaceType) surfaceTypeId = pSurfaceType->GetId(); } if(pCollision) { pCollision->PreCacheLevelResources(particleCache); } if(pExplosions) { //t count = ARRAY_COUNT(pExplosions); for(int i = 0; i < m_explosion_count; ++i) { pExplosions[i]->PreCacheLevelResources(particleCache); } } if (pTrail) { pTrail->PreCacheLevelResources(particleCache); } if (pTrailUnderWater) { pTrailUnderWater->PreCacheLevelResources(particleCache); } if (pWhiz) { pWhiz->PreCacheLevelResources(); } if (pRicochet) { pRicochet->PreCacheLevelResources(); } if (pLTagParams) { pLTagParams->m_ricochet.PreCacheLevelResources(particleCache, materialCache); pLTagParams->m_sticky.PreCacheLevelResources(particleCache, materialCache); } if (pMikeBulletParams) { pMikeBulletParams->PreCacheLevelResources(particleCache); } if (pHomingParams) { pHomingParams->PreCacheLevelResources(particleCache); } if(pKvoltParams) { pKvoltParams->PreCacheLevelResources(particleCache); } if (pBulletTimeParams) { pBulletTimeParams->PreCacheLevelResources(resourceCache); } if (pLightningBoltParams) { pLightningBoltParams->PreCacheLevelResources(materialCache, particleCache); } if (pC4ExplosiveParams) { pC4ExplosiveParams->PreCacheLevelResources(resourceCache); } if (pElectricProjectileParams) { pElectricProjectileParams->PreCacheLevelResources(particleCache); } resourceCache.CachedResourcesForClassDone(pEntityClass); }
//------------------------------------------------------------------------ void CCannonBall::HandleEvent(const SGameObjectEvent &event) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); BaseClass::HandleEvent(event); if (event.event == eGFE_OnCollision) { if (CheckAnyProjectileFlags(ePFlag_destroying)) return; EventPhysCollision *pCollision = reinterpret_cast<EventPhysCollision *>(event.ptr); if (!pCollision) return; float finalDamage = GetFinalDamage(pCollision->pt); if (finalDamage <= 0.0f) m_alive = false; IEntity *pTarget = pCollision->iForeignData[1]==PHYS_FOREIGN_ID_ENTITY ? (IEntity*)pCollision->pForeignData[1]:0; CGameRules *pGameRules = g_pGame->GetGameRules(); const int hitMatId = pCollision->idmat[1]; Vec3 hitDir(ZERO); if (pCollision->vloc[0].GetLengthSquared() > 1e-6f) { hitDir = pCollision->vloc[0].GetNormalized(); } const bool bProcessCollisionEvent = ProcessCollisionEvent(pTarget); if (bProcessCollisionEvent) { //================================= Process Hit ===================================== //Only process hits that have a target if(pTarget) { if(FilterFriendlyAIHit(pTarget) == false) { ProcessHit(*pGameRules, *pCollision, *pTarget, finalDamage, hitMatId, hitDir); } } //====================================~ Process Hit ====================================== //==================================== Notify AI ====================================== if (gEnv->pAISystem) { if (gEnv->pEntitySystem->GetEntity(m_ownerId)) { ISurfaceType *pSurfaceType = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceType(hitMatId); const ISurfaceType::SSurfaceTypeAIParams* pParams = pSurfaceType ? pSurfaceType->GetAIParams() : 0; const float radius = pParams ? pParams->fImpactRadius : 2.5f; const float soundRadius = pParams ? pParams->fImpactSoundRadius : 20.0f; SAIStimulus stim(AISTIM_BULLET_HIT, 0, m_ownerId, pTarget ? pTarget->GetId() : 0, pCollision->pt, pCollision->vloc[0].GetNormalizedSafe(ZERO), radius); gEnv->pAISystem->RegisterStimulus(stim); SAIStimulus stimSound(AISTIM_SOUND, AISTIM_BULLET_HIT, m_ownerId, 0, pCollision->pt, ZERO, soundRadius); gEnv->pAISystem->RegisterStimulus(stim); } } //=========================================~ Notify AI =============================== } //========================================= Surface Pierceability ============================== if (pCollision->pEntity[0]->GetType() == PE_PARTICLE) { const SPierceabilityParams& pierceabilityParams = m_pAmmoParams->pierceabilityParams; //If collided water if( s_materialLookup.IsMaterial( pCollision->idmat[1], CProjectile::SMaterialLookUp::eType_Water ) ) { if(pierceabilityParams.DestroyOnWaterImpact()) { DestroyAtHitPosition(pCollision->pt); } else { EmitUnderwaterTracer(pCollision->pt, pCollision->pt + (pCollision->vloc[0].GetNormalizedSafe() * 100.0f)); } } else if (m_pAmmoParams->bounceableBullet == 0) { float bouncy, friction; uint32 pierceabilityMat; gEnv->pPhysicalWorld->GetSurfaceParameters(pCollision->idmat[1], bouncy, friction, pierceabilityMat); pierceabilityMat &= sf_pierceable_mask; const bool terrainHit = (pCollision->idCollider == -1); bool thouShallNotPass = terrainHit; if (!CheckAnyProjectileFlags(ePFlag_ownerIsPlayer)) thouShallNotPass = thouShallNotPass || pierceabilityParams.DestroyOnImpact(pierceabilityMat); if (!thouShallNotPass) HandlePierceableSurface(pCollision, pTarget, hitDir, bProcessCollisionEvent); const bool destroy = thouShallNotPass || ShouldDestroyCannonBall(); if (destroy) { DestroyAtHitPosition(pCollision->pt); } } } } }
bool CScriptSurfaceTypesLoader::LoadSurfaceTypes( const char *sFolder,bool bReload ) { { if (!gEnv->p3DEngine) return false; I3DEngine *pEngine = gEnv->p3DEngine; ISurfaceTypeEnumerator *pEnum = pEngine->GetMaterialManager()->GetSurfaceTypeManager()->GetEnumerator(); if (pEnum) { for (ISurfaceType *pSurfaceType = pEnum->GetFirst(); pSurfaceType; pSurfaceType = pEnum->GetNext()) { SmartScriptTable mtlTable(gEnv->pScriptSystem); gEnv->pScriptSystem->SetGlobalValue( pSurfaceType->GetName(),mtlTable ); SmartScriptTable aiTable(gEnv->pScriptSystem); mtlTable->SetValue("AI",aiTable); aiTable->SetValue( "fImpactRadius",5.0f ); aiTable->SetValue( "fFootStepRadius",15.0f ); aiTable->SetValue( "proneMult",0.2f ); aiTable->SetValue( "crouchMult",0.5f ); aiTable->SetValue( "movingMult",2.5f ); } pEnum->Release(); } } return true; // Do not load surface types from script anymore. m_root = GetISystem()->CreateXmlNode("SurfaceTypes"); IScriptSystem *pScriptSystem = gEnv->pScriptSystem; ////////////////////////////////////////////////////////////////////////// // Make sure Materials table exist. ////////////////////////////////////////////////////////////////////////// SmartScriptTable mtlTable; if (!pScriptSystem->GetGlobalValue("Materials", mtlTable) || bReload) { mtlTable = pScriptSystem->CreateTable(); pScriptSystem->SetGlobalValue("Materials", mtlTable); } ICryPak *pIPak = gEnv->pCryPak; ISurfaceTypeManager *pSurfaceManager = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeManager(); if (!bReload) stl::push_back_unique( m_folders,sFolder ); string searchFolder = string(sFolder) + "/";; string searchFilter = searchFolder + "mat_*.lua"; gEnv->pScriptSystem->ExecuteFile(searchFolder+"common.lua", false, bReload); _finddata_t fd; intptr_t fhandle; fhandle = pIPak->FindFirst( searchFilter,&fd ); if (fhandle != -1) { do { // Skip back folders. if (fd.attrib & _A_SUBDIR) // skip if directory. continue; char name[_MAX_PATH]; _splitpath( fd.name,NULL,NULL,name,NULL ); if (strlen(name) == 0) continue; if (bReload) { ISurfaceType *pSurfaceType = pSurfaceManager->GetSurfaceTypeByName(name); if (pSurfaceType) { pSurfaceType->Load( pSurfaceType->GetId() ); continue; } } ISurfaceType *pSurfaceType = new CScriptSurfaceType( this,name,searchFolder+fd.name,0 ); if (pSurfaceManager->RegisterSurfaceType( pSurfaceType )) m_surfaceTypes.push_back(pSurfaceType); else pSurfaceType->Release(); } while (pIPak->FindNext( fhandle,&fd ) == 0); pIPak->FindClose(fhandle); } if (m_root) { m_root->saveToFile( "SurfaceTypes.xml" ); } return true; }