int CScriptBind_Boids::OnPickup(IFunctionHandler *pH, SmartScriptTable flockEntity, SmartScriptTable boidEntity, bool bPickup, float fThrowSpeed)
{
	CFlock* flock = GetFlock(flockEntity);
	IEntity* pBoidEntity = GetEntity(boidEntity);

	if (flock != NULL && pBoidEntity != NULL)
	{
		CBoidObject* pBoidObject = NULL;

		for (int i = 0; i < flock->GetBoidsCount(); ++i)
		{
			if (flock->GetBoid(i)->GetId() == pBoidEntity->GetId())
			{
				pBoidObject = flock->GetBoid(i);
				break;
			}
		}

		if (pBoidObject != NULL)
		{
			pBoidObject->OnPickup(bPickup, fThrowSpeed);
		}
	}

	return pH->EndFunction();
}
int CScriptBind_Boids::CanPickup(IFunctionHandler *pH, SmartScriptTable flockEntity, SmartScriptTable boidEntity)
{
	CFlock* flock = GetFlock(flockEntity);
	IEntity* pBoidEntity = GetEntity(boidEntity);

	if (flock != NULL && pBoidEntity != NULL)
	{
		CBoidObject* pBoidObject = NULL;

		for (int i = 0; i < flock->GetBoidsCount(); ++i)
		{
			if (flock->GetBoid(i)->GetId() == pBoidEntity->GetId())
			{
				pBoidObject = flock->GetBoid(i);
				break;
			}
		}

		if (pBoidObject != NULL)
		{
			SBoidContext bc;
			flock->GetBoidSettings(bc);

			return pH->EndFunction((pBoidObject->IsDead() && bc.bPickableWhenDead) || (!pBoidObject->IsDead() && bc.bPickableWhenAlive));
		}
	}
	return pH->EndFunction(0);
}
Exemple #3
0
void CFlock::UpdateBoidCollisions()
{
	if(!m_bc.avoidObstacles)
		return;
	const int numberOfChecks = 5;

	CTimeValue now = gEnv->pTimer->GetFrameStartTime();
	int checked = 0;

	// rough check
	if(m_BoidCollisionMap.size() != m_boids.size())
	{
		m_BoidCollisionMap.clear();
		for (Boids::iterator it = m_boids.begin(),itEnd = m_boids.end(); it != itEnd; ++it)
			m_BoidCollisionMap.insert(std::make_pair(now,*it));
	}

	for (TTimeBoidMap::iterator it = m_BoidCollisionMap.begin(),itEnd = m_BoidCollisionMap.end(); 
				it != itEnd && checked < numberOfChecks; ++it)
{
		CBoidObject* pBoid = it->second;
		if(pBoid && pBoid->ShouldUpdateCollisionInfo(now))
	{
			pBoid->UpdateCollisionInfo();
			m_BoidCollisionMap.erase(it);
			m_BoidCollisionMap.insert(std::make_pair(now,pBoid));
			it = m_BoidCollisionMap.begin();
			++checked;
		}
	}
}
Exemple #4
0
void CFlock::OnBoidHit( EntityId nBoidId,SmartScriptTable &hit )
{
	int num = (int)m_boids.size();
	for (int i = 0; i < num; i++)
	{
		CBoidObject *boid = m_boids[i];
		if (boid->m_entity == nBoidId)
		{
			Vec3 pos = boid->m_pos;
			Vec3 force = Vec3(1,1,1);
			float damage = 1.0f;
			hit->GetValue("pos", pos);
			hit->GetValue("dir", force);
			hit->GetValue("damage", damage);

			boid->Kill( pos,force*damage );

			break;
		}
	}
}
Exemple #5
0
void CFlock::SetPos( const Vec3& pos )
{
	Vec3 ofs = pos - m_origin;
	m_origin = pos;
	m_bc.flockPos = m_origin;
	for (Boids::iterator it = m_boids.begin(); it != m_boids.end(); ++it)
	{
		CBoidObject *boid = *it;
		boid->m_pos += ofs;
		boid->OnFlockMove( m_bc );
	}
	// Update bounding box of flock entity.
	if (m_pEntity)
	{
		//float s = m_bc.MaxAttractDistance;
//		float s = 1;
		//m_pEntity->SetBBox( pos-Vec3(s,s,s),pos+Vec3(s,s,s) );
		//m_pEntity->ForceRegisterInSectors();
	}
	RegisterAIEventListener(true);
}
Exemple #6
0
void CFlock::UpdateBoidCollisions()
{
	if(!m_bc.avoidObstacles)
		return;
	const int numberOfChecks = 5;
	
	CTimeValue now = gEnv->pTimer->GetFrameStartTime();
	int checked = 0;

	// rough check
	if(m_BoidCollisionMap.size() != m_boids.size())
	{
		m_BoidCollisionMap.clear();
		m_BoidCollisionMap.reserve( m_boids.size() );

		for (Boids::iterator it = m_boids.begin(),itEnd = m_boids.end(); it != itEnd; ++it)
		{
			m_BoidCollisionMap.push_back( SBoidCollisionTime( now, *it ) );
		}

		std::sort( m_BoidCollisionMap.begin(), m_BoidCollisionMap.end(), FSortBoidByTime() );
	}
	
	for (TTimeBoidMap::iterator it = m_BoidCollisionMap.begin(),itEnd = m_BoidCollisionMap.end(); 
				it != itEnd && checked < numberOfChecks; ++it)
	{
		CBoidObject* pBoid = it->m_pBoid;
		if(pBoid && pBoid->ShouldUpdateCollisionInfo(now))
		{
			pBoid->UpdateCollisionInfo();
			it->m_time = now;
			++checked;
		}
	}	
	std::sort( m_BoidCollisionMap.begin(), m_BoidCollisionMap.end(), FSortBoidByTime() );
}
Exemple #7
0
void CFlock::UpdateAvgBoidPos(float dt)
{
	m_lastUpdatePosTimePassed += dt;
	if(m_lastUpdatePosTimePassed < 0.5f + Boid::Frand()/4.f)
		return;

	m_lastUpdatePosTimePassed = 0;

	m_avgBoidPos.zero();
	int n=0;

	for (Boids::iterator it = m_boids.begin(),itEnd = m_boids.end(); it != itEnd; ++it)
	{
		CBoidObject* pBoid = (*it);
		if(pBoid && !pBoid->IsDead())
		{
			m_avgBoidPos += pBoid->GetPos();
			++n;
		}
	}
	if(n)
		m_avgBoidPos /= float(n);

}
Exemple #8
0
bool CFlock::CreateEntities()
{
	if (!m_e_flocks)
		return false;

	SEntitySpawnParams spawnParams;
	spawnParams.pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("Boid");
	if (!spawnParams.pClass)
		return false;
	
	spawnParams.nFlags = ENTITY_FLAG_CLIENT_ONLY | ENTITY_FLAG_NO_SAVE | ENTITY_FLAG_NO_PROXIMITY | m_nBoidEntityFlagsAdd;
	spawnParams.sName = m_boidEntityName;

	m_modelCgf = PathUtil::ReplaceExtension(m_model,"cgf");

	bool bHasCgfFile = gEnv->pCryPak->IsFileExist(m_modelCgf) && m_bc.animationMaxDistanceSq > 0;

	if(!bHasCgfFile)
		m_bc.animationMaxDistanceSq = 0;

	bool bAnyCreated = false;

	for (Boids::iterator it = m_boids.begin();  it != m_boids.end(); ++it)
	{
		CBoidObject *boid = *it;/*m_boids[i]*/;

		if (boid->m_dead || boid->m_dying)
			continue;

		spawnParams.vPosition = boid->m_pos;
		spawnParams.vScale = Vec3(boid->m_scale,boid->m_scale,boid->m_scale);
		spawnParams.id = 0;
		IEntity *pBoidEntity = gEnv->pEntitySystem->SpawnEntity( spawnParams );
		if (!pBoidEntity)
		{
			//delete boid;
			//it = m_boids.erase(it);
			continue;
		}
		boid->m_noentity = false;
		boid->m_entity = pBoidEntity->GetId();

		CBoidObjectProxyPtr pBoidObjectProxy = ComponentCreateAndRegister_DeleteWithRelease<CBoidObjectProxy>( IComponent::SComponentInitializer(pBoidEntity), true );
		pBoidEntity->SetProxy(ENTITY_PROXY_BOID_OBJECT,pBoidObjectProxy);
		pBoidObjectProxy->SetBoid(boid);

		// check if character.
		if (IsCharacterFile(m_model))
		{
			if(bHasCgfFile)
				pBoidEntity->LoadGeometry(CBoidObject::eSlot_Cgf, m_modelCgf);

			pBoidEntity->LoadCharacter( CBoidObject::eSlot_Chr,m_model );
			boid->m_object = pBoidEntity->GetCharacter(0);
			if (!boid->m_object)
			{
				gEnv->pEntitySystem->RemoveEntity(boid->m_entity,true);
				boid->m_entity = 0;
				//delete boid;
				//it = m_boids.erase(it);
				continue;
			}

		}
		else
		{
			pBoidEntity->LoadGeometry( 0,m_model );
		}

		bAnyCreated = true;

		//		boid->m_object->GetModel()->AddRef();

		AABB aabb;
		if (boid->m_object)
		{
			boid->m_object->SetFlags( CS_FLAG_DRAW_MODEL|CS_FLAG_UPDATE );
			boid->PlayAnimation( m_boidDefaultAnimName,true );
			aabb = boid->m_object->GetAABB();
		}
		else
		{
			pBoidEntity->GetLocalBounds(aabb);
		}

		float fBBoxRadius = ((aabb.max-aabb.min).GetLength()/2.0f);
		m_bc.fBoidRadius = max( fBBoxRadius, 0.001f );
		m_bc.fBoidThickness = m_bc.fBoidRadius;

		if (!m_bc.vEntitySlotOffset.IsZero())
		{
			pBoidEntity->SetSlotLocalTM(0,Matrix34::CreateTranslationMat(m_bc.vEntitySlotOffset*fBBoxRadius));
		}

		boid->Physicalize(m_bc);

		IEntityRenderProxy *pRenderProxy = (IEntityRenderProxy*)pBoidEntity->GetProxy(ENTITY_PROXY_RENDER);
		if (pRenderProxy != NULL && m_bc.fBoidRadius > 0)
		{
			float r = m_bc.fBoidRadius;
			AABB box;
			box.min = Vec3(-r,-r,-r);
			box.max = Vec3(r,r,r);
			pRenderProxy->SetLocalBounds( box,true );
		}
		IScriptTable *pScriptTable = pBoidEntity->GetScriptTable();
		if (pScriptTable)
		{
			pScriptTable->SetValue( "flock_entity",m_pEntity->GetScriptTable() );
		}
	}

	m_bEntityCreated = true;
	return bAnyCreated;
}
Exemple #9
0
void CFlock::Update( CCamera *pCamera )
{
	FUNCTION_PROFILER( GetISystem(),PROFILE_ENTITY );

	if (!IsFlockActive())
		return;

	if (!m_e_flocks)
	{
		if (m_bEntityCreated)
			DeleteEntities( true );
		return;
	}

	if(GetISystem()->IsSerializingFile() == 1) //quickloading
		return;

	if (!m_bEntityCreated)
	{
		if (!CreateEntities())
			return;
	}

	float dt = gEnv->pTimer->GetFrameTime();
	// Make sure delta time is limited.
	if (dt > 1.0f)
		dt = 0.01f;
	if (dt > 0.1f)
		dt = 0.1f;

	m_bc.fSmoothFactor = 1.f - gEnv->pTimer->GetProfileFrameBlending();
	/*
	for (Boids::iterator it = m_boids.begin(); it != m_boids.end(); ++it)
	{
		CBoidObject *boid = *it;
		boid->Think();
	}
	*/
	//m_bc.playerPos = m_flockMgr->GetPlayerPos();

	m_bc.playerPos = GetISystem()->GetViewCamera().GetMatrix().GetTranslation(); // Player position is position of camera.
	m_bc.flockPos = m_origin;
	m_bc.waterLevel = m_bc.engine->GetWaterLevel( &m_origin );

	m_bounds.min = Vec3(FLT_MAX,FLT_MAX,FLT_MAX);
	m_bounds.max = Vec3(-FLT_MAX,-FLT_MAX,-FLT_MAX);

	int numBoids = m_boids.size();
	if (m_percentEnabled < 100)
	{
		numBoids = (m_percentEnabled*numBoids)/100;
	}

	if (!m_pEntity->GetRotation().IsIdentity())
	{
		// Entity matrix must not have rotation.
		//Quat q;
		//q.SetIdentity();
		//m_pEntity->SetRotation(q);
	}

	//////////////////////////////////////////////////////////////////////////
	// Update flock random center.
	//////////////////////////////////////////////////////////////////////////
	m_fCenterFloatingTime += gEnv->pTimer->GetFrameTime();
	float tc = m_fCenterFloatingTime*0.2f;
	m_bc.randomFlockCenter = m_bc.flockPos + 
		//m_bc.fSpawnRadius*Vec3(sinf(0.9f*m_fCenterFloatingTime),cosf(1.1f*sin(0.9f*m_fCenterFloatingTime)),0.3f*sinf(1.2f*m_fCenterFloatingTime) );
		m_bc.fSpawnRadius*Vec3(sinf(tc*0.913f)*cosf(tc*1.12f),sinf(tc*0.931f)*cosf(tc*0.971f),0.4f*sinf(tc*1.045f)*cosf(tc*0.962f) );
	//gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere( m_bc.randomFlockCenter,0.1f,ColorB(255,0,0,255) );

	//////////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////
	IEntityRenderProxy *pRenderProxy = (IEntityRenderProxy*)m_pEntity->GetProxy(ENTITY_PROXY_RENDER);
	if (pRenderProxy)
	{
		if (pRenderProxy->GetRenderNode()->GetViewDistRatio() != m_nViewDistRatio)
			UpdateBoidsViewDistRatio();
	}
	//////////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////
	// Update scare factors.
	if (m_bc.scareThreatLevel > 0)
	{
		m_bc.scareThreatLevel *= 0.95f;
		m_bc.scareRatio *= 0.95f;
		if (m_bc.scareRatio < 0.01f)
		{
			m_bc.scareRatio = 0;
			m_bc.scareThreatLevel = 0;
		}
		if (m_e_flocks == 2)
		{
			int c = (int)(255*m_bc.scareRatio);
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere( m_bc.scarePoint,m_bc.scareRadius,ColorB(c,0,0,c),false );
		}
	}

	//////////////////////////////////////////////////////////////////////////

	UpdateBoidCollisions();

	Vec3 entityPos = m_pEntity->GetWorldPos();
	Matrix34 boidTM;
	int num = 0;
	for (Boids::iterator it = m_boids.begin(); it != m_boids.end(); ++it,num++)
	{
		if (num > numBoids)
			break;

		CBoidObject* boid = *it;

		m_bc.terrainZ = m_bc.engine->GetTerrainElevation(boid->m_pos.x,boid->m_pos.y);
		boid->Update(dt,m_bc);

		if (!boid->m_physicsControlled && !boid->m_dead)
		{
			IEntity *pBoidEntity = gEnv->pEntitySystem->GetEntity(boid->m_entity);
			if (pBoidEntity)
			{
				Quat q(IDENTITY);
				boid->CalcOrientation(q);
				const Vec3 scaleVector(boid->m_scale,boid->m_scale,boid->m_scale);
				pBoidEntity->SetPosRotScale( boid->m_pos, q, scaleVector, ENTITY_XFORM_NO_SEND_TO_ENTITY_SYSTEM );
			}
		}

	}

	m_updateFrameID = gEnv->pRenderer->GetFrameID(false);	
	//gEnv->pLog->Log( "Birds Update" );
}