Exemplo n.º 1
0
//------------------------------------------------------------------------
bool CProjectile::NetSerialize(TSerialize ser, EEntityAspects aspect, uint8 profile, int pflags)
{
	if(aspect == eEA_Physics)
	{
		pe_type type = PE_NONE;

		switch(profile)
		{
		case ePT_Rigid:
			type = PE_RIGID;
			break;

		case ePT_Particle:
			type = PE_PARTICLE;
			break;

		case ePT_None:
			return true;

		case ePT_Static:
		{
			Vec3 pos = GetEntity()->GetWorldPos();
			Quat ori = GetEntity()->GetWorldRotation();
			ser.Value("pos", pos, 'wrld');
			ser.Value("ori", ori, 'ori1');

			if(ser.IsReading())
				GetEntity()->SetWorldTM(Matrix34::Create(Vec3(1,1,1), ori, pos));
		}

		return true;

		default:
			return false;
		}

		IEntityPhysicalProxy *pEPP = (IEntityPhysicalProxy *) GetEntity()->GetProxy(ENTITY_PROXY_PHYSICS);

		if(ser.IsWriting())
		{
			if(!pEPP || !pEPP->GetPhysicalEntity() || pEPP->GetPhysicalEntity()->GetType() != type)
			{
				gEnv->pPhysicalWorld->SerializeGarbageTypedSnapshot(ser, type, 0);
				return true;
			}
		}
		else if(!pEPP)
		{
			return false;
		}

		pEPP->SerializeTyped(ser, type, pflags);
	}

	return true;
}
Exemplo n.º 2
0
//------------------------------------------------------------------------
void CGunTurret::UpdatePhysics()
{
	int slots[] = {eIGS_Aux0,eIGS_Aux1,eIGS_ThirdPerson};
	int slots_num = 3;

	if(m_destroyed)
	{
		slots[1] = eIGS_Destroyed;
		slots_num = 2;
	}

	if(IEntity *pParent = GetEntity()->GetParent())
	{
		IPhysicalEntity *pParentPhysics = pParent->GetPhysics();
		IEntityPhysicalProxy *pPhysicsProxy = (IEntityPhysicalProxy *)GetEntity()->GetProxy(ENTITY_PROXY_PHYSICS);

		if(pParentPhysics && pPhysicsProxy)
		{
			Matrix34 localTM = GetEntity()->GetLocalTM();
			localTM.OrthonormalizeFast();
			Quat localQ = Quat(localTM);

			for(int i=0; i<slots_num; ++i)
			{
				pe_params_part params;

				params.partid = slots[i] + pPhysicsProxy->GetPartId0();

				const Matrix34 &slotTM = GetEntity()->GetSlotLocalTM(slots[i], false);

				params.pos = slotTM.GetTranslation();
				params.q = Quat(slotTM);

				params.pos = localTM * params.pos;
				params.q = localQ * params.q;
				pParentPhysics->SetParams(&params);
			}
		}
	}
	else
	{
		if(IPhysicalEntity *pPhysics = GetEntity()->GetPhysics())
		{
			for(int i=0; i<slots_num; ++i)
			{
				pe_params_part params;
				params.partid = slots[i];

				Matrix34 slotTM = GetEntity()->GetSlotLocalTM(slots[i], false);
				params.pMtx3x4 = &slotTM;

				pPhysics->SetParams(&params);
			}
		}
	}
}
Exemplo n.º 3
0
//-----------------------------------------------------------------------------
bool CNetworkedPhysicsEntity::NetSerialize( TSerialize ser, EEntityAspects aspect, uint8 profile, int flags )
{
	NET_PROFILE_SCOPE("NetworkedPhysicsEntity", ser.IsReading());

	if (aspect == eEA_Physics)
	{
		pe_type type = PE_NONE;
		
		switch (profile)
		{
			case ePhys_PhysicalizedRigid:
			{
				type = PE_RIGID;
				break;
			}
			case ePhys_PhysicalizedStatic:
			{
				type = PE_STATIC;

				// Serialise the position ourselves - physics system won't do it for static entities
				const Matrix34 &worldTM = GetEntity()->GetWorldTM();
				Vec3 worldPos = worldTM.GetTranslation();
				ser.Value("worldPos", worldPos, 'wrld');
				if (ser.IsReading())
				{
					Matrix34 newTM = worldTM;
					newTM.SetTranslation(worldPos);
					GetEntity()->SetWorldTM(newTM);
				}

				break;
			}
		}

		if (type == PE_NONE)
			return true;

		IEntityPhysicalProxy * pEPP = (IEntityPhysicalProxy *) GetEntity()->GetProxy(ENTITY_PROXY_PHYSICS);
		if (ser.IsWriting())
		{
			if (!pEPP || !pEPP->GetPhysicalEntity() || pEPP->GetPhysicalEntity()->GetType() != type)
			{
				gEnv->pPhysicalWorld->SerializeGarbageTypedSnapshot( ser, type, 0 );
				return true;
			}
		}
		else if (!pEPP)
		{
			return false;
		}

		pEPP->SerializeTyped( ser, type, flags );
	}
	return true;
}
Exemplo n.º 4
0
	virtual void ProcessEvent( EFlowEvent event,SActivationInfo *pActInfo )
	{
		switch (event)
		{
			case eFE_Activate:
			{
				if (!pActInfo->pEntity)
					return;

				if(IsPortActive(pActInfo, IN_ENABLE))
				{
					IEntityPhysicalProxy *pPhysicalProxy = (IEntityPhysicalProxy*)pActInfo->pEntity->GetProxy(ENTITY_PROXY_PHYSICS);
					if (pPhysicalProxy)
						pPhysicalProxy->EnablePhysics(true);
				}
				if(IsPortActive(pActInfo, IN_DISABLE))
				{
					IEntityPhysicalProxy *pPhysicalProxy = (IEntityPhysicalProxy*)pActInfo->pEntity->GetProxy(ENTITY_PROXY_PHYSICS);
					if (pPhysicalProxy)
						pPhysicalProxy->EnablePhysics(false);
				}
	
				if(IsPortActive(pActInfo, IN_ENABLE_AI))
				{
					if (IAIObject* aiObject = pActInfo->pEntity->GetAI())
						aiObject->Event(AIEVENT_ENABLE,0);
				}
				if(IsPortActive(pActInfo, IN_DISABLE_AI))
				{
					if (IAIObject* aiObject = pActInfo->pEntity->GetAI())
						aiObject->Event(AIEVENT_DISABLE,0);
				}
				break;
			}

		case eFE_Initialize:
			break;
		}
	}
void CVehicleDamageBehaviorBlowTire::DamagePlayers()
{
	// check for the nasty case when the player is shooting at the vehicle tires while prone 
	// under or behind the car, In that case the player should get killed by the vehicle, 
	// otherwise he gets stuck forever. Note that he should only get killed when the tier
	// is actually destroyed and not by collision resulting by the impulse added by just 
	// shooting at the tiers. Unfortunately using physics for doing this check is not reliable
	// enough so we have to check it explicitly
	
	IEntityPhysicalProxy *pPhysicsProxy = (IEntityPhysicalProxy*)m_pVehicle->GetEntity()->GetProxy(ENTITY_PROXY_PHYSICS);
	if (!pPhysicsProxy)
		return;

	AABB bbox;
	pPhysicsProxy->GetWorldBounds( bbox );

	IPhysicalWorld *pWorld = gEnv->pSystem->GetIPhysicalWorld();
	IPhysicalEntity **ppColliders;
	// check entities in collision with the car
	int cnt = pWorld->GetEntitiesInBox( bbox.min,bbox.max, ppColliders,ent_living);
	for (int i = 0; i < cnt; i++)
	{

		IEntity *pEntity = gEnv->pEntitySystem->GetEntityFromPhysics( ppColliders[i] );
		if (!pEntity)
			continue;
		
		// skip the vehicle itself
		if (pEntity==m_pVehicle->GetEntity())
			continue;

		IPhysicalEntity *pPhysEnt = pEntity->GetPhysics();
		if (!pPhysEnt) 
			continue;

		IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEntity->GetId());            
		if(!pActor)
			continue;

		//Jan M.: the player is killed when he entered the vehicle while prone although he is still passenger!
		if(m_pVehicle == pActor->GetLinkedVehicle())
			continue;

		//the player must be prone under the vehicle
		IAnimatedCharacter * animatedCharacter=pActor->GetAnimatedCharacter();
		if (!animatedCharacter)
			continue;

		int stance = animatedCharacter->GetCurrentStance();
		if (stance!=STANCE_PRONE)
			continue;

		pe_player_dimensions dim;
		if (!pPhysEnt->GetParams(&dim))
			continue;
		// position returned is at entity's feet, add head position from physics
		Vec3 vPos1=pEntity->GetPos();
		vPos1.z = vPos1.z + dim.heightHead;

		float fZ=bbox.GetCenter().z;
		if (vPos1.z>fZ)
			continue; // not under the vehicle

		// at this point we have a collision with the car moving down and the guy prone under the car, it is safe
		// to assume he has been squished so let's kill him.
		if (gEnv->bServer && pActor->GetHealth()>0)
		{
			// adding a server hit to make it working in MP
			IGameRules *pGameRules = gEnv->pGame->GetIGameFramework()->GetIGameRulesSystem()->GetCurrentGameRules();
			if (pGameRules)
			{
				HitInfo hit;

				EntityId shooterId=m_pVehicle->GetEntityId();
				if (m_pVehicle->GetDriver())
					shooterId=m_pVehicle->GetDriver()->GetEntityId();					

				hit.targetId = pEntity->GetId();      
				hit.shooterId = shooterId;
				hit.weaponId = m_pVehicle->GetEntityId();
				hit.damage = 1000.f;
				hit.type = 0;
				hit.pos = pActor->GetEntity()->GetWorldPos();

				pGameRules->ServerHit(hit); 
			}  
		} 
	} //i
}
Exemplo n.º 6
0
bool CMonoActor::NetSerialize( TSerialize ser, EEntityAspects aspect, uint8 profile, int pflags )
{
	if (aspect == eEA_Physics)
	{
		pe_type type = PE_NONE;
		switch (profile)
		{
		case eAP_NotPhysicalized:
			type = PE_NONE;
			break;
		case eAP_Spectator:
			type = PE_LIVING;
			break;
		case eAP_Alive:
			type = PE_LIVING;
			break;
		case eAP_Sleep:
			type = PE_ARTICULATED;
			break;
		case eAP_Frozen:
			type = PE_RIGID;
			break;
		case eAP_Ragdoll:
			type = PE_ARTICULATED;
			break;
		case eAP_Linked: 	//if actor is attached to a vehicle - don't serialize actor physics additionally
			return true;
			break;
		default:
			return false;
		}

		// TODO: remove this when craig fixes it in the network system
		if (profile==eAP_Spectator)
		{
			int x=0;	
			ser.Value("unused", x, 'skip');
		}
		else if (profile==eAP_Sleep)
		{
			int x=0;	
			ser.Value("unused1", x, 'skip');
			ser.Value("unused2", x, 'skip');
		}

		if (type == PE_NONE)
			return true;

		IEntityPhysicalProxy * pEPP = (IEntityPhysicalProxy *) GetEntity()->GetProxy(ENTITY_PROXY_PHYSICS);
		if (ser.IsWriting())
		{
			if (!pEPP || !pEPP->GetPhysicalEntity() || pEPP->GetPhysicalEntity()->GetType() != type)
			{
				gEnv->pPhysicalWorld->SerializeGarbageTypedSnapshot( ser, type, 0 );
				return true;
			}
		}
		else if (!pEPP)
		{
			return false;
		}

		// PLAYERPREDICTION
    	if(type!=PE_LIVING)
    	{
      		pEPP->SerializeTyped( ser, type, pflags );
    	}
		// ~PLAYERPREDICTION
	}

	ser.BeginGroup("ManagedActor");

	IMonoArray *pArgs = CreateMonoArray(4);
	pArgs->InsertNativePointer(&ser);
	pArgs->Insert(aspect);
	pArgs->Insert(profile);
	pArgs->Insert(pflags);

	m_pScript->GetClass()->InvokeArray(m_pScript, "InternalNetSerialize", pArgs);

	ser.EndGroup();

	return true;
}
Exemplo n.º 7
0
bool CShotgun::Shoot(bool resetAnimation, bool autoreload/* =true */, bool noSound /* =false */)
{
	IEntityClass *ammo = m_pShared->fireparams.ammo_type_class;
	int ammoCount = m_pWeapon->GetAmmoCount(ammo);

	if(m_pShared->fireparams.clip_size==0)
		ammoCount = m_pWeapon->GetInventoryAmmoCount(ammo);

	CActor *pActor = m_pWeapon->GetOwnerActor();
	bool playerIsShooter = pActor?pActor->IsPlayer():false;

	if(!CanFire(true))
	{
		if((ammoCount <= 0) && (!m_reloading))
		{
			m_pWeapon->PlayAction(m_pShared->actions.empty_clip);
			//Auto reload
			m_pWeapon->Reload();
		}

		return false;
	}
	else if(m_pWeapon->IsWeaponLowered())
	{
		m_pWeapon->PlayAction(m_pShared->actions.null_fire);
		return false;
	}

	if(m_reloading)
	{
		if(m_pWeapon->IsBusy())
			m_pWeapon->SetBusy(false);

		if(CanFire(true) && !m_break_reload)
		{
			m_break_reload = true;
			m_pWeapon->RequestCancelReload();
		}

		return false;
	}

	// Aim assistance
	m_pWeapon->AssistAiming();

	const char *action = m_pShared->actions.fire_cock.c_str();

	if(ammoCount == 1 || (m_pShared->fireparams.no_cock && m_pWeapon->IsZoomed()))
		action = m_pShared->actions.fire.c_str();

	m_pWeapon->PlayAction(action, 0, false, CItem::eIPAF_Default|CItem::eIPAF_RestartAnimation|CItem::eIPAF_CleanBlending);

	Vec3 hit = GetProbableHit(WEAPON_HIT_RANGE);
	Vec3 pos = GetFiringPos(hit);
	Vec3 fdir = ApplySpread(GetFiringDir(hit, pos), GetSpread());
	Vec3 vel = GetFiringVelocity(fdir);
	Vec3 dir;

	CheckNearMisses(hit, pos, fdir, WEAPON_HIT_RANGE, m_pShared->shotgunparams.spread);

	bool serverSpawn = m_pWeapon->IsServerSpawn(ammo);

	// SHOT HERE
	for(int i = 0; i < m_pShared->shotgunparams.pellets; i++)
	{
		CProjectile *pAmmo = m_pWeapon->SpawnAmmo(ammo, false);

		if(pAmmo)
		{
			dir = ApplySpread(fdir, m_pShared->shotgunparams.spread);
			int hitTypeId = g_pGame->GetGameRules()->GetHitTypeId(m_pShared->fireparams.hit_type.c_str());

			pAmmo->SetParams(m_pWeapon->GetOwnerId(), m_pWeapon->GetHostId(), m_pWeapon->GetEntityId(), m_pShared->shotgunparams.pelletdamage, hitTypeId, playerIsShooter?m_pShared->fireparams.damage_drop_per_meter:0.0f, m_pShared->fireparams.damage_drop_min_distance);
			pAmmo->SetDestination(m_pWeapon->GetDestination());
			pAmmo->Launch(pos, dir, vel);

			if((!m_pShared->tracerparams.geometry.empty() || !m_pShared->tracerparams.effect.empty()) && (ammoCount==GetClipSize() || (ammoCount%m_pShared->tracerparams.frequency==0)))
			{
				EmitTracer(pos,hit,false);
			}

			m_projectileId = pAmmo->GetEntity()->GetId();
		}
	}

	m_pWeapon->OnShoot(m_pWeapon->GetOwnerId(), 0, ammo, pos, dir, vel);

	if(m_pWeapon->IsServer())
	{
		const char *ammoName = ammo != NULL ? ammo->GetName() : NULL;
		g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(m_pWeapon->GetOwner(), GameplayEvent(eGE_WeaponShot, ammoName, m_pShared->shotgunparams.pellets, (void *)m_pWeapon->GetEntityId()));
	}

	MuzzleFlashEffect(true);
	RejectEffect();

	m_fired = true;
	m_next_shot += m_next_shot_dt;
	m_zoomtimeout = m_next_shot + 0.5f;
	ammoCount--;

	if(playerIsShooter)
	{
		if(pActor->InZeroG())
		{
			IEntityPhysicalProxy *pPhysicsProxy = (IEntityPhysicalProxy *)pActor->GetEntity()->GetProxy(ENTITY_PROXY_PHYSICS);
			SMovementState ms;
			pActor->GetMovementController()->GetMovementState(ms);
			CPlayer *plr = (CPlayer *)pActor;

			if(m_recoilparams.back_impulse > 0.0f)
			{
				Vec3 impulseDir = ms.aimDirection * -1.0f;
				Vec3 impulsePos = ms.pos;
				float impulse = m_recoilparams.back_impulse;
				pPhysicsProxy->AddImpulse(-1, impulsePos, impulseDir * impulse * 100.0f, true, 1.0f);
			}

			if(m_recoilparams.angular_impulse > 0.0f)
			{
				float impulse = m_recoilparams.angular_impulse;
				pActor->AddAngularImpulse(Ang3(0,impulse,0), 1.0f);
			}
		}

		if(pActor->IsClient())
			if(gEnv->pInput)
				gEnv->pInput->ForceFeedbackEvent(SFFOutputEvent(eDI_XI, eFF_Rumble_Basic, 0.15f, 0.0f, fabsf(m_recoilparams.back_impulse)*3.0f));
	}

	if(m_pShared->fireparams.clip_size != -1)
	{
		if(m_pShared->fireparams.clip_size!=0)
			m_pWeapon->SetAmmoCount(ammo, ammoCount);
		else
			m_pWeapon->SetInventoryAmmoCount(ammo, ammoCount);
	}

	if((ammoCount<1) && !m_pShared->fireparams.slider_layer.empty())
	{
		const char *slider_back_layer = m_pShared->fireparams.slider_layer.c_str();
		m_pWeapon->PlayLayer(slider_back_layer, CItem::eIPAF_Default|CItem::eIPAF_NoBlend);
	}

	if(OutOfAmmo())
	{
		m_pWeapon->OnOutOfAmmo(ammo);

		if(autoreload)
		{
			m_pWeapon->GetScheduler()->TimerAction(m_pWeapon->GetCurrentAnimationTime(eIGS_FirstPerson), CSchedulerAction<ScheduleReload>::Create(m_pWeapon), false);
		}
	}

	m_pWeapon->RequestShoot(ammo, pos, dir, vel, hit, 1.0f, 0, false);

	return true;
}
Exemplo n.º 8
0
bool CJaw::SetAspectProfile(EEntityAspects aspect, uint8 profile)
{
	if(aspect!=eEA_Physics)
		return BaseClass::SetAspectProfile(aspect, profile);

	bool ok = false;
	if(!gEnv->bMultiplayer && gEnv->pSystem->IsSerializingFile() && m_auxSlotUsedBQS)
		ok = true;

	int slot = (m_auxSlotUsed||ok)?eIGS_ThirdPersonAux:eIGS_ThirdPerson;

	if (aspect == eEA_Physics)
	{
		switch (profile)
		{
		case eIPhys_PhysicalizedStatic:
			{
				SEntityPhysicalizeParams params;
				params.type = PE_STATIC;
				params.nSlot = slot;

				GetEntity()->Physicalize(params);

				return true;
			}
			break;
		case eIPhys_PhysicalizedRigid:
			{
				SEntityPhysicalizeParams params;
				params.type = PE_RIGID;
				params.nSlot = slot;
				params.mass = m_sharedparams->params.mass;

				pe_params_buoyancy buoyancy;
				buoyancy.waterDamping = 1.5;
				buoyancy.waterResistance = 1000;
				buoyancy.waterDensity = 0;
				params.pBuoyancy = &buoyancy;

				GetEntity()->Physicalize(params);

				IPhysicalEntity *pPhysics = GetEntity()->GetPhysics();
				if (pPhysics)
				{
					pe_action_awake action;
					action.bAwake = m_owner.GetId()!=0;
					pPhysics->Action(&action);
				}
			}
			return true;
		case eIPhys_NotPhysicalized:
			{
				IEntityPhysicalProxy *pPhysicsProxy = GetPhysicalProxy();
				if (pPhysicsProxy)
				{
					SEntityPhysicalizeParams params;
					params.type = PE_NONE;
					params.nSlot = slot;
					pPhysicsProxy->Physicalize(params);
				}
			}
			return true;
		}
	}

	return false;
}
//------------------------------------------------------------------------
void CMelee::Impulse(const Vec3 &pt, const Vec3 &dir, const Vec3 &normal, IPhysicalEntity *pCollider, int partId, int ipart, int surfaceIdx, float impulseScale)
{
	if(m_noImpulse)
	{
		m_noImpulse = false;
		return;
	}

	if (pCollider && m_pShared->meleeparams.impulse > 0.001f)
	{
		bool strengthMode = false;
		CPlayer *pPlayer = (CPlayer *)m_pWeapon->GetOwnerActor();
		pe_status_dynamics dyn;

		if (!pCollider->GetStatus(&dyn))
		{
			if(strengthMode)
			{
				impulseScale *= 3.0f;
			}
		}
		else
		{
			impulseScale *= clamp((dyn.mass * 0.01f), 1.0f, 15.0f);
		}

		//[kirill] add impulse to phys proxy - to make sure it's applied to cylinder as well (not only skeleton) - so that entity gets pushed
		// if no pEntity - do it old way
		IEntity *pEntity = (IEntity *) pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY);

		if(gEnv->bMultiplayer && pEntity)
		{
			if(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEntity->GetId()) == NULL)
			{
				impulseScale *= 0.33f;
			}
		}

		if(pEntity)
		{
			bool crapDollFilter = false;
#ifdef CRAPDOLLS
			static IEntityClass *pDeadBodyClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("DeadBody");

			if (pEntity->GetClass() == pDeadBodyClass)
			{
				crapDollFilter = true;
			}

#endif //CRAPDOLLS

			if (!crapDollFilter)
			{
				IEntityPhysicalProxy *pPhysicsProxy = (IEntityPhysicalProxy *)pEntity->GetProxy(ENTITY_PROXY_PHYSICS);
				CActor *pActor = (CActor *)g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEntity->GetId());

				if (pActor)
				{
					SActorStats *pAS = pActor->GetActorStats();

					if (pAS && pAS->isRagDoll)
					{
						//marcok: talk to me before touching this
						impulseScale = 1.0f; //jan: melee impulses were scaled down, I made sure it still "barely moves"
#ifdef CRAPDOLLS
						crapDollFilter = true;
#endif //CRAPDOLLS
					}
				}

				// scale impulse up a bit for player
				if (!crapDollFilter)
				{
					pPhysicsProxy->AddImpulse(partId, pt, dir * m_pShared->meleeparams.impulse * impulseScale * m_meleeScale, true, 1.f);
				}
			}
		}
		else
		{
			pe_action_impulse ai;
			ai.partid = partId;
			ai.ipart = ipart;
			ai.point = pt;
			ai.iApplyTime = 0;
			ai.impulse = dir * (m_pShared->meleeparams.impulse * impulseScale * m_meleeScale);
			pCollider->Action(&ai);
		}

		ISurfaceTypeManager *pSurfaceTypeManager = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeManager();
		int invId = pSurfaceTypeManager->GetSurfaceTypeByName("mat_invulnerable")->GetId();
		// create a physical collision to break trees
		pe_action_register_coll_event collision;
		collision.collMass = 0.005f; // this is actually ignored
		collision.partid[1] = partId;
		// collisions involving partId<-1 are to be ignored by game's damage calculations
		// usually created articially to make stuff break.
		collision.partid[0] = -2;
		collision.idmat[1] = surfaceIdx;
		collision.idmat[0] = invId;
		collision.n = normal;
		collision.pt = pt;
		// scar bullet
		// m = 0.0125
		// v = 800
		// energy: 4000
		// in this case the mass of the active collider is a player part
		// so we must solve for v given the same energy as a scar bullet
		Vec3	v = dir;
		float speed = cry_sqrtf(4000.0f / (80.0f * 0.5f)); // 80.0f is the mass of the player
		// [marco] Check if an object. Should take lots of time to break stuff if not in nanosuit strength mode;
		// and still creates a very low impulse for stuff that might depend on receiving an impulse.
		IRenderNode *pBrush = (IRenderNode *)pCollider->GetForeignData(PHYS_FOREIGN_ID_STATIC);
		collision.vSelf = (v.normalized() * speed * m_meleeScale);
		collision.v = Vec3(0, 0, 0);
		collision.pCollider = pCollider;
		IEntity *pOwner = m_pWeapon->GetOwner();

		if (pOwner && pOwner->GetCharacter(0) && pOwner->GetCharacter(0)->GetISkeletonPose()->GetCharacterPhysics())
		{
			if (ISkeletonPose *pSkeletonPose = pOwner->GetCharacter(0)->GetISkeletonPose())
			{
				if (pSkeletonPose && pSkeletonPose->GetCharacterPhysics())
				{
					pSkeletonPose->GetCharacterPhysics()->Action(&collision);
				}
			}
		}
	}
}
Exemplo n.º 10
0
	void Update(float elapsed)
	{
		float maxTime = GetPortFloat(&m_actInfo, EIP_Duration);
		float percent = maxTime > FLT_EPSILON ? elapsed / maxTime : 1.0f;
		if(percent >= 1.0f)
		{
			m_actInfo.pGraph->SetRegularlyUpdated(m_actInfo.myID, false);
			m_triggered = false;
			return;
		}

		Vec3 N = GetPortVec3(&m_actInfo, EIP_Normal);

		float rangeMin = GetPortFloat(&m_actInfo, EIP_RangeMin);
		float rangeMax = GetPortFloat(&m_actInfo, EIP_RangeMax);
		const float range = rangeMax - rangeMin;
		Vec3 boxDim(rangeMax, rangeMax, rangeMax);
		Vec3 ptmin = m_effectCenter - boxDim;
		Vec3 ptmax = m_effectCenter + boxDim;

		float speed = GetPortFloat(&m_actInfo, EIP_Speed);
		float waveFront = elapsed * speed;

		float decay = GetPortFloat(&m_actInfo, EIP_Decay);
		if(decay > FLT_EPSILON) decay = 1.0f / decay;

		float force = GetPortFloat(&m_actInfo, EIP_Force);
		force = pow_tpl(force * (1-percent), decay);

		float amplitude = GetPortFloat(&m_actInfo, EIP_Amplitude);
		amplitude = pow_tpl(amplitude * (1-percent), decay);

		if (gEnv->bMultiplayer) // Turned off for performance and network issues
		{
			return;
		}

		IPhysicalEntity** pEntityList = NULL;
		static const int iObjTypes = ent_rigid | ent_sleeping_rigid | ent_living;// | ent_allocate_list;
		int numEntities = gEnv->pPhysicalWorld->GetEntitiesInBox(ptmin, ptmax, pEntityList, iObjTypes);
		AABB bounds;
		for(int i=0; i<numEntities; ++i)
		{
			IPhysicalEntity* pPhysicalEntity = pEntityList[i];
			IEntity* pEntity = static_cast<IEntity*>(pPhysicalEntity->GetForeignData(PHYS_FOREIGN_ID_ENTITY));

			// Has the entity already been affected?
			if(pEntity)
			{
				bool affected = stl::find(m_entitiesAffected, pEntity->GetId());
				if(!affected)
				{
					IEntityPhysicalProxy* pPhysicalProxy = static_cast<IEntityPhysicalProxy*>(pEntity->GetProxy(ENTITY_PROXY_PHYSICS));
					if(pPhysicalProxy)
					{
						pPhysicalProxy->GetWorldBounds(bounds);
						Vec3 p = bounds.GetCenter();
						Vec3 v = p - m_effectCenter;
						float distFromCenter = v.GetLength() + FLT_EPSILON;
						if(distFromCenter < rangeMax)
						{
							if(waveFront > distFromCenter) // has the wavefront passed the entity?
							{
								//pPhysicalEntity->GetStatus(&dyn);

								// normalize v, cheaper than another sqrt
								v /= distFromCenter;

								Vec3 dir = N + v * force;
								static bool usePos = false;
								float impulse = 1.0f - (max(0.0f, distFromCenter - rangeMin) / range);
								impulse = impulse * amplitude;// / dyn.mass;
								if(impulse > FLT_EPSILON)
								{
									pPhysicalProxy->AddImpulse(-1, p, dir * impulse, usePos, 1.0f);
									m_entitiesAffected.push_back(pEntity->GetId());
								}
							}
						}
					}
				}
			}
		}
	}
Exemplo n.º 11
0
//---------------------------------------------------------------------------
IEntity* CFireModePlugin_AutoAim::CalculateBestProjectileAutoAimTarget(const Vec3& attackerPos, const Vec3& attackerDir, const bool bCurrentlyZoomed, const EntityId ownerId) const
{

#if ALLOW_PROJECTILEHELPER_DEBUGGING
	static const ColorB red(127,0,0);
	static const ColorB green(0,127,0);
	static const ColorB brightGreen(0,255,0);
	static const float s_sphereDebugRad = 0.15f;
#endif


	IEntity* pBestTarget = NULL;
	float    fBestScore  = 0.0f;

	const TAutoaimTargets& players = g_pGame->GetAutoAimManager().GetAutoAimTargets();

	// Cache commonly required constants for scoring
	const ConeParams& aimConeSettings = GetAimConeSettings(bCurrentlyZoomed);

	const float minAutoAimDistSqrd   = cry_sqr(aimConeSettings.m_minDistance);
	const float maxAutoAimDistSqrd   = cry_sqr(aimConeSettings.m_maxDistance);
	const float  coneSizeRads		 = aimConeSettings.m_outerConeRads;
	IEntitySystem* pEntitySystem	 = gEnv->pEntitySystem;
	CPlayerVisTable* pVisTable		 = g_pGame->GetPlayerVisTable();

	const float distanceConstant	 = __fres(max(aimConeSettings.m_maxDistance, FLT_EPSILON));
	const float	coneAngleConstant	 = __fres(max(coneSizeRads*0.5f, FLT_EPSILON));

	// For each potential target we do a dist + cone check
	TAutoaimTargets::const_iterator endIter = players.end();
	for(TAutoaimTargets::const_iterator iter = players.begin(); iter != endIter; ++iter)
	{
		// If entity exists and we are allowed to target them
		EntityId targetEntityId = iter->entityId;
		IEntity* pEntity = pEntitySystem->GetEntity(targetEntityId);
		if(pEntity && AllowedToTargetPlayer(ownerId,targetEntityId))
		{
			// If further than allowed dist, discard
			Vec3 targetTestPos;

			// Test against primary Auto aim position
			const SAutoaimTarget* pAutoAimInfo = g_pGame->GetAutoAimManager().GetTargetInfo(targetEntityId);
			if(pAutoAimInfo)
			{
				targetTestPos = pAutoAimInfo->primaryAimPosition; 
			}
			else
			{
				// Then  ABBB centre as backup
				IEntityPhysicalProxy* pPhysProxy = static_cast<IEntityPhysicalProxy*>(pEntity->GetProxy(ENTITY_PROXY_PHYSICS));
				if(pPhysProxy)
				{
					AABB aabb;
					pPhysProxy->GetWorldBounds(aabb);
					targetTestPos = aabb.GetCenter();
				}
				else
				{
					targetTestPos = pEntity->GetWorldPos();
				}
			}

			Vec3 toTarget = targetTestPos - attackerPos;
			float distSqrd = toTarget.GetLengthSquared();
			if( distSqrd >= minAutoAimDistSqrd &&
				distSqrd <= maxAutoAimDistSqrd )
			{

				// If not within cone.. discard
				float theta = 0.0f;
				if(TargetPositionWithinFrontalCone(attackerPos,targetTestPos, attackerDir,coneSizeRads, theta))
				{
					// If cant see them .. next
					if(!pVisTable->CanLocalPlayerSee(targetEntityId, 5))
					{

#if ALLOW_PROJECTILEHELPER_DEBUGGING
						m_lastTargetRejectionReason.append("VISION BLOCKED"); 	
#endif // #if ALLOW_PROJECTILEHELPER_DEBUGGING

						continue;
					}

					// For each candidate, generate their Auto Aim score.

					// 1) [0.0f,1.0f] score comprised of DISTANCE based score (closer is better)
					float targetDistScore    =  1.0f - ( sqrtf(distSqrd) *  distanceConstant );

					// Lets try squaring this to make candidates with only small gaps between them reflect distance scoring better and reduce the importance of distance at super long ranges
					targetDistScore *= targetDistScore;

					// 2) +  [0.0f,1.0f]  cone based score (central is better)
					const float targetConeScore		 =  1.0f - ( theta * coneAngleConstant );

					// Factor in designer controlled multipliers
					const float finalScore = (targetDistScore * g_pGameCVars->pl_pickAndThrow.chargedThrowAutoAimDistanceHeuristicWeighting) +  // TODO - move these weightings into params
						(targetConeScore * g_pGameCVars->pl_pickAndThrow.chargedThrowAutoAimAngleHeuristicWeighting);

					if(finalScore > fBestScore)
					{
						fBestScore  = finalScore;
						pBestTarget = pEntity;
					}

					// Debug rendering!
#if ALLOW_PROJECTILEHELPER_DEBUGGING
					if(g_pGameCVars->pl_debug_projectileAimHelper)
					{
						CryWatch("Entity [%s - %d] DistScore [%.2f] , ConeScore[%.2f], totalScore [%.3f]", pEntity->GetName(), pEntity->GetId(), targetDistScore, targetConeScore, finalScore);
						
						// Draw a green sphere to indicate valid
						gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(targetTestPos, s_sphereDebugRad,green);
					}
#endif //#if ALLOW_PROJECTILEHELPER_DEBUGGING

				}
#if ALLOW_PROJECTILEHELPER_DEBUGGING
				else
				{
					m_lastTargetRejectionReason.Format("OUTSIDE CONE [%.3f]",RAD2DEG(theta));

					if(g_pGameCVars->pl_debug_projectileAimHelper)
					{
						// Draw a red sphere to indicate not valid
						gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(targetTestPos, s_sphereDebugRad, red);
					}
				}
#endif //#if ALLOW_PROJECTILEHELPER_DEBUGGING
			}
#if ALLOW_PROJECTILEHELPER_DEBUGGING
			else
			{
				if(distSqrd >= minAutoAimDistSqrd)
				{
					m_lastTargetRejectionReason.Format("TOO CLOSE [%.3f]", cry_sqrtf_fast(distSqrd)); 
				}
				else
				{
					m_lastTargetRejectionReason.Format("TOO FAR [%.3f]",cry_sqrtf_fast(distSqrd));  
				}
			}
#endif //#if ALLOW_PROJECTILEHELPER_DEBUGGING
		}
	}

	// Draw a Really bright sphere on BEST target
#if ALLOW_PROJECTILEHELPER_DEBUGGING
	if(pBestTarget && g_pGameCVars->pl_debug_projectileAimHelper)
	{
		// If further than allowed dist, discard
		Vec3 targetTestPos = pBestTarget->GetPos();

		// We use aabb centre to reduce error
		IEntityPhysicalProxy* pPhysProxy = static_cast<IEntityPhysicalProxy*>(pBestTarget->GetProxy(ENTITY_PROXY_PHYSICS));
		if(pPhysProxy)
		{
			AABB aabb;
			pPhysProxy->GetWorldBounds(aabb);
			targetTestPos = aabb.GetCenter();
		}

		// Draw a bright green sphere to indicate target chosen
		gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(targetTestPos, s_sphereDebugRad*1.05f, brightGreen);
	}
#endif //#if ALLOW_PROJECTILEHELPER_DEBUGGING

	return pBestTarget;
}
Exemplo n.º 12
0
void CAICorpseManager::Update( const float frameTime )
{
	const uint32 maxCorpsesToUpdateThisFrame = 4;

	const float cullPhysicsDistanceSqr = g_pGameCVars->g_aiCorpses_CullPhysicsDistance * g_pGameCVars->g_aiCorpses_CullPhysicsDistance;
	const float forceDeleteDistanceSqr = g_pGameCVars->g_aiCorpses_ForceDeleteDistance * g_pGameCVars->g_aiCorpses_ForceDeleteDistance;

	if (m_lastUpdatedCorpseIdx >= (uint32)m_corpsesArray.size())
		m_lastUpdatedCorpseIdx = 0;

	const CCamera& viewCamera = gEnv->pSystem->GetViewCamera();

	CryFixedArray<EntityId, maxCorpsesToUpdateThisFrame> corpsesToDelete;
	const uint32 corpsesEndIdx = min(m_lastUpdatedCorpseIdx + maxCorpsesToUpdateThisFrame, (uint32)m_corpsesArray.size());

	for(uint32 i = m_lastUpdatedCorpseIdx; i < corpsesEndIdx; ++i)
	{
		CorpseInfo& corpseInfo = m_corpsesArray[i];

		IEntity* pCorpseEntity = corpseInfo.GetCorpseEntity();
		if(pCorpseEntity != NULL)
		{
			AABB corpseBbox;
			pCorpseEntity->GetWorldBounds(corpseBbox);
			corpseBbox.Expand(Vec3(0.1f, 0.1f, 0.1f));

			const Vec3 corpsePosition = corpseBbox.GetCenter();
			const float distanceSqr = (corpsePosition - viewCamera.GetPosition()).len2();

			const bool attemptDeleteFarAway = (distanceSqr > forceDeleteDistanceSqr);
			const bool cullPhysics = (distanceSqr > cullPhysicsDistanceSqr);
			const bool isVisible = viewCamera.IsAABBVisible_F(corpseBbox);
			
			corpseInfo.flags.SetFlags( CorpseInfo::eFlag_FarAway, attemptDeleteFarAway );
			
			if(attemptDeleteFarAway && !isVisible)
			{
				corpsesToDelete.push_back(corpseInfo.corpseId);
			}
			else if(cullPhysics != corpseInfo.flags.AreAllFlagsActive( CorpseInfo::eFlag_PhysicsDisabled ))
			{
				IEntityPhysicalProxy* pCorpsePhysicsProxy = static_cast<IEntityPhysicalProxy*>(pCorpseEntity->GetProxy( ENTITY_PROXY_PHYSICS ));
				if (pCorpsePhysicsProxy != NULL)
				{
					//Simulate entity event to enable/disable physics
					SEntityEvent visibilityEvent;
					visibilityEvent.event = cullPhysics ? ENTITY_EVENT_HIDE : ENTITY_EVENT_UNHIDE;
					pCorpsePhysicsProxy->ProcessEvent( visibilityEvent );
					
					if(cullPhysics == false)
					{
						IPhysicalEntity* pCorpsePhysics = pCorpseEntity->GetPhysics();
						if(pCorpsePhysics != NULL)
						{
							pe_action_awake awakeAction;
							awakeAction.bAwake = 0;
							pCorpsePhysics->Action( &awakeAction );
						}
					}
				}

				corpseInfo.flags.SetFlags( CorpseInfo::eFlag_PhysicsDisabled, cullPhysics );
			}
		}
		else
		{
			//This should not happen, but in case remove the entity from the list
			GameWarning("AICorpseManager - Detected corpse with no entity, removing from list");
			corpsesToDelete.push_back(corpseInfo.corpseId);
		}
	}

	m_lastUpdatedCorpseIdx = corpsesEndIdx;

	for(uint32 i = 0; i < (uint32)corpsesToDelete.size(); ++i)
	{
		RemoveCorpse(corpsesToDelete[i]);
	}

	DebugDraw();
}