Beispiel #1
0
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;
	}
Beispiel #4
0
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();
	}
}
Beispiel #5
0
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();
		}
	}
}
Beispiel #6
0
//------------------------------------------------------------------------
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(&params)==0)
				SetDefaultParticleParams(&params);

			//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();
		}
	}
}
Beispiel #7
0
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;
}