예제 #1
0
//------------------------------------------------------------------------
void CCannonBall::ProcessHit(CGameRules& gameRules, const EventPhysCollision& collision, IEntity& target, float damage, int hitMatId, const Vec3& hitDir)
{
	if(damage > 0.f)
	{
		EntityId targetId = target.GetId();
		bool alreadyHit = CheckForPreviousHit(targetId, damage);

		if(!alreadyHit)
		{
			HitInfo hitInfo(m_ownerId ? m_ownerId : m_hostId, targetId, m_weaponId,
				damage, 0.0f, hitMatId, collision.partid[1],
				m_hitTypeId, collision.pt, hitDir, collision.n);

			hitInfo.remote = IsRemote();
			hitInfo.projectileId = GetEntityId();
			hitInfo.bulletType = m_pAmmoParams->bulletType;
			hitInfo.knocksDown = CheckAnyProjectileFlags(ePFlag_knocksTarget) && ( damage > m_minDamageForKnockDown );
			hitInfo.knocksDownLeg = m_chanceToKnockDownLeg>0 && damage>m_minDamageForKnockDownLeg && m_chanceToKnockDownLeg>(int)Random(100);
			hitInfo.penetrationCount = m_penetrationCount;
			hitInfo.hitViaProxy = CheckAnyProjectileFlags(ePFlag_firedViaProxy);
			hitInfo.aimed = CheckAnyProjectileFlags(ePFlag_aimedShot);

			IPhysicalEntity* pPhysicalEntity = collision.pEntity[1];
			if (pPhysicalEntity && pPhysicalEntity->GetType() == PE_ROPE)
			{
				hitInfo.partId = GetRopeBoneId(collision, target, pPhysicalEntity);
			}

			gameRules.ClientHit(hitInfo);

			ReportHit(targetId);
		}
	}
}
bool CMFXParticleEffect::AttachToTarget( const SMFXParticleEntry& particleParams, const SMFXRunTimeEffectParams& params, IParticleEffect* pParticleEffect, const Vec3& dir, float scale )
{
	bool shouldTryToAttach = particleParams.attachToTarget && (params.trg != 0);
	if (!shouldTryToAttach)
	{
		return false;
	}

	IEntity* pTargetEntity = gEnv->pEntitySystem->GetEntity(params.trg);
	if (pTargetEntity)
	{
		//Try to figure out if it's a character using physics type
		IPhysicalEntity* pTargetPhysics = pTargetEntity->GetPhysics();
		int physicsType = pTargetPhysics ? pTargetPhysics->GetType() : PE_NONE;

		bool isCharacter = (physicsType == PE_LIVING) || (physicsType == PE_ARTICULATED);

		if (isCharacter)
		{
			return AttachToCharacter(*pTargetEntity, particleParams, params, dir, scale);
		}
		//else
		//{
			//return AttachToEntity(*pTargetEntity, particleParams, params, pParticleEffect, dir, scale);
		//}
	}

	return false;
}
EntityId CAICorpseManager::SpawnAICorpseFromEntity( IEntity& sourceEntity, const SCorpseParameters& corpseParams )
{
	assert(gEnv->IsEditor() == false);
	assert(gEnv->bMultiplayer == false);

	if(g_pGameCVars->g_aiCorpses_Enable == 0)
		return 0;

	if(m_corpsesArray.size() == m_maxCorpses)
	{
		RemoveSomeCorpses();

		assert((uint32)m_corpsesArray.size() < m_maxCorpses);
	}

	MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Other, EMemStatContextFlags::MSF_None, "AICorpseManager::SpawnCorpse");

	EntityId corpseId = 0;
	IPhysicalEntity* pSourcePhysics = sourceEntity.GetPhysics();
	if ((pSourcePhysics != NULL) && (pSourcePhysics->GetType() == PE_ARTICULATED))
	{
		ICharacterInstance *pSourceCharacterInstance = sourceEntity.GetCharacter(0);

		if (pSourceCharacterInstance != NULL)
		{
			IEntityClass *pCorpseClass =  gEnv->pEntitySystem->GetClassRegistry()->FindClass("AICorpse");
			assert(pCorpseClass);

			stack_string corpseName;
			corpseName.Format("%s_Corpse", sourceEntity.GetName());
			SEntitySpawnParams params;
			params.pClass = pCorpseClass;
			params.sName = corpseName.c_str();

#if !AI_CORPSES_ENABLE_SERIALIZE
			params.nFlags |= ENTITY_FLAG_NO_SAVE;
#endif

			params.vPosition = sourceEntity.GetWorldPos();
			params.qRotation = sourceEntity.GetWorldRotation();

			IEntity *pCorpseEntity = gEnv->pEntitySystem->SpawnEntity(params, true);
			if(pCorpseEntity != NULL)
			{
				corpseId = pCorpseEntity->GetId();
				
				CorpseInfo* pCorpseInfo = FindCorpseInfo( corpseId );
				assert(pCorpseInfo != NULL);

				CAICorpse* pCorpse = pCorpseInfo->GetCorpse();
				assert(pCorpse != NULL);
				pCorpse->SetupFromSource( sourceEntity, *pSourceCharacterInstance, (uint32)corpseParams.priority);
			}
		}
	}

	return corpseId;
}
void CReplayActor::OnRagdollized()
{
	if(!m_ragdollImpulse.impulse.IsZero())
	{
		IPhysicalEntity* pPhys = GetEntity()->GetPhysics();
		CRY_ASSERT(pPhys && pPhys->GetType()==PE_ARTICULATED);
		pPhys->Action(&m_ragdollImpulse);
	}
	m_ragdollImpulse.impulse.zero();
}
void CReplayActor::ApplyRagdollImpulse( pe_action_impulse& impulse )
{
	IPhysicalEntity* pPhys = GetEntity()->GetPhysics();
	if(!pPhys || pPhys->GetType()!=PE_ARTICULATED)
	{
		m_ragdollImpulse = impulse;
	}
	else
	{
		pPhys->Action(&impulse);
	}
}
예제 #6
0
	void ResetVelocity(SActivationInfo* pActInfo)
	{
		IEntity* pGraphEntity = pActInfo->pEntity;
		if (pGraphEntity)
		{
			IPhysicalEntity* pPhysicalEntity = pGraphEntity->GetPhysics();
			if (pPhysicalEntity && pPhysicalEntity->GetType() != PE_STATIC)
			{
				pe_action_set_velocity setVel;
				setVel.v.zero();
				setVel.w.zero();
				pPhysicalEntity->Action(&setVel);
			}
		}
	}
//------------------------------------------------------------------------
void CThrow::Update(float frameTime, uint32 frameId)
{
	CSingle::Update(frameTime, frameId);

	if (m_firing)
	{
		if (!m_pulling && !m_throwing && !m_thrown)
		{
			if(m_hold_timer > 0.0f)
			{
				m_hold_timer -= frameTime;

				if (m_hold_timer < 0.0f)
				{
					m_hold_timer = 0.0f;
				}
			}
		}
		else if (m_throwing && m_throw_time <= 0.0f)
		{
			CActor *pOwner = m_pWeapon->GetOwnerActor();
			m_pWeapon->HideItem(true);

			if (m_throwableId)
			{
				IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_throwableId);

				if (pEntity)
				{
					if (m_throwableAction)
					{
						m_throwableAction->execute(m_pWeapon);
					}

					IPhysicalEntity *pPE = pEntity->GetPhysics();

					if (pPE && (pPE->GetType() == PE_RIGID || pPE->GetType() == PE_PARTICLE))
					{
						ThrowObject(pEntity, pPE);
					}
					else if (pPE && (pPE->GetType() == PE_LIVING || pPE->GetType() == PE_ARTICULATED))
					{
						ThrowLivingEntity(pEntity, pPE);
					}
				}
			}
			else if (!m_netfiring)
			{
				ThrowGrenade();
			}

			m_throwing = false;
		}
		else if (m_thrown && m_throw_time <= 0.0f)
		{
			m_pWeapon->SetBusy(false);
			m_pWeapon->HideItem(false);
			int ammoCount = m_pWeapon->GetAmmoCount(m_pShared->fireparams.ammo_type_class);

			if (ammoCount > 0)
			{
				m_pWeapon->PlayAction(m_pShared->throwactions.next);
			}
			else if (m_pShared->throwparams.auto_select_last)
			{
				static_cast<CPlayer *>(m_pWeapon->GetOwnerActor())->SelectLastItem(true);
			}

			m_firing = false;
			m_throwing = false;
			m_thrown = false;
		}

		m_throw_time -= frameTime;

		if (m_throw_time < 0.0f)
		{
			m_throw_time = 0.0f;
		}

		m_pWeapon->RequireUpdate(eIUS_FireMode);
	}
}
//--------------------------------------
void CThrow::DoDrop()
{
	m_pWeapon->HideItem(true);

	if (m_throwableId)
	{
		IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_throwableId);

		if (pEntity)
		{
			IPhysicalEntity *pPE = pEntity->GetPhysics();

			if (pPE && (pPE->GetType() == PE_RIGID || pPE->GetType() == PE_PARTICLE))
			{
				Vec3 hit = GetProbableHit(WEAPON_HIT_RANGE);
				Vec3 pos = GetFiringPos(hit);
				CActor *pActor = m_pWeapon->GetOwnerActor();
				IMovementController *pMC = pActor ? pActor->GetMovementController() : 0;

				if (pMC)
				{
					SMovementState info;
					pMC->GetMovementState(info);
					float speed = 2.5f;
					CPlayer *pPlayer = static_cast<CPlayer *>(m_pWeapon->GetOwnerActor());

					if(info.aimDirection.z < -0.1f)
					{
						if(pPlayer)
						{
							if(SPlayerStats *pStats = static_cast<SPlayerStats *>(pPlayer->GetActorStats()))
							{
								if(pStats->grabbedHeavyEntity)
								{
									speed = 4.0f;
								}
							}
						}
					}

					if(CheckForIntersections(pPE, info.eyeDirection))
					{
						Matrix34 newTM = pEntity->GetWorldTM();
						newTM.SetTranslation(newTM.GetTranslation() - (info.eyeDirection * 0.4f));
						pEntity->SetWorldTM(newTM, ENTITY_XFORM_POS);
						pe_action_set_velocity asv;
						asv.v = (-info.eyeDirection * speed);
						pPE->Action(&asv);
					}
					else
					{
						pe_action_set_velocity asv;
						asv.v = (info.eyeDirection * speed);
						pPE->Action(&asv);
					}

					SEntityEvent entityEvent;
					entityEvent.event = ENTITY_EVENT_PICKUP;
					entityEvent.nParam[0] = 0;

					if (pPlayer)
					{
						entityEvent.nParam[1] = pPlayer->GetEntityId();
					}

					entityEvent.fParam[0] = speed;
					pEntity->SendEvent( entityEvent );
				}
			}
		}

		if (m_throwableAction)
		{
			m_throwableAction->execute(m_pWeapon);
		}
	}
}
예제 #9
0
파일: Tornado.cpp 프로젝트: Xydrel/Infected
void CTornado::UpdateFlow()
{
	IVehicleSystem* pVehicleSystem = g_pGame->GetIGameFramework()->GetIVehicleSystem();
	assert(pVehicleSystem);

	float frameTime(gEnv->pTimer->GetFrameTime());

	IPhysicalWorld *ppWorld = gEnv->pPhysicalWorld;

	Vec3 pos(GetEntity()->GetWorldPos());

	//first, check the entities in range
	m_nextEntitiesCheck -= frameTime;
	if (m_nextEntitiesCheck<0.0f)
	{
		m_nextEntitiesCheck = 1.0f;
		
		Vec3 radiusVec(m_radius,m_radius,0);
		
		IPhysicalEntity **ppList = NULL;

		int	numEnts = ppWorld->GetEntitiesInBox(pos-radiusVec,pos+radiusVec+Vec3(0,0,m_cloudHeight*0.5f),ppList,ent_sleeping_rigid|ent_rigid|ent_living);

		m_spinningEnts.clear();
		for (int i=0;i<numEnts;++i)
		{
			// add check for spectating players...
			EntityId id = ppWorld->GetPhysicalEntityId(ppList[i]);
			CActor* pActor = static_cast<CActor*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id));
			if(!pActor || !pActor->GetSpectatorMode())
			{
				m_spinningEnts.push_back(id);
			}
		}
		//OutputDistance();
	}

	//mess entities around
	for (size_t i=0;i<m_spinningEnts.size();++i)
	{
		IPhysicalEntity *ppEnt = ppWorld->GetPhysicalEntityById(m_spinningEnts[i]);
		if (ppEnt)
		{
			pe_status_pos spos;
			pe_status_dynamics sdyn;

			if (!ppEnt->GetStatus(&spos) || !ppEnt->GetStatus(&sdyn))
				continue;
		
			//gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(spos.pos,2.0f,ColorB(255,0,255,255));
						
			Vec3 delta(pos - spos.pos);
			delta.z = 0.0f;

			float dLen(delta.len());
			float forceMult(max(0.0f,(m_radius-dLen)/m_radius));

			if (dLen>0.001f)
				delta /= dLen;
			else
				delta.zero();

			Vec3 upVector(0,0,1);

			float spinImpulse(m_spinImpulse);
			float attractionImpulse(m_attractionImpulse);
			float upImpulse(m_upImpulse);

			if (ppEnt->GetType() == PE_LIVING)
			{
				upImpulse *= 0.75f;
				attractionImpulse *= 0.35f;
				spinImpulse *= 1.5f;
			}

			
			if (IVehicle* pVehicle = pVehicleSystem->GetVehicle(m_spinningEnts[i]))
			{
				IVehicleMovement* pMovement = pVehicle->GetMovement();

				if (pMovement && pMovement->GetMovementType() == IVehicleMovement::eVMT_Air)
				{
					SVehicleMovementEventParams params;
					params.fValue = forceMult;
					pMovement->OnEvent(IVehicleMovement::eVME_Turbulence, params);
				}
			}

			Vec3 spinForce( (delta % upVector) * spinImpulse );
			Vec3 attractionForce(delta * attractionImpulse);
			Vec3 upForce(0,0,upImpulse);

			pe_action_impulse aimpulse;

			aimpulse.impulse = (spinForce + attractionForce + upForce) * (forceMult * sdyn.mass * frameTime);
			aimpulse.angImpulse = (upVector + (delta % upVector)) * (gf_PI * 0.33f * forceMult * sdyn.mass * frameTime);

			aimpulse.iApplyTime = 0;
			ppEnt->Action(&aimpulse);

			//gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(spos.pos,ColorB(255,0,255,255),spos.pos+aimpulse.impulse.GetNormalizedSafe(ZERO),ColorB(255,0,255,255));
		}
	}
}
예제 #10
0
//--------------------------------------------------------------------------------------------------
// Name: HandleImpact
// Desc: Passes an impact on to the simulation
//--------------------------------------------------------------------------------------------------
int CBreakableGlassSystem::HandleImpact(const EventPhys* pPhysEvent)
{
	if (CCryAction* pCryAction = CCryAction::GetCryAction())
	{
		if (CBreakableGlassSystem* pGlassSystem = static_cast<CBreakableGlassSystem*>(pCryAction->GetIBreakableGlassSystem()))
		{
			pGlassSystem->AssertUnusedIfDisabled();

			if (pGlassSystem->m_enabled)
			{
				if (const EventPhysCollision* pCollEvent = static_cast<const EventPhysCollision*>(pPhysEvent))
				{
					// Glass fragments always get destroyed on their first collision
					const uint physFrag = (pCollEvent->iForeignData[0] == PHYS_FOREIGN_ID_BREAKABLE_GLASS_FRAGMENT) ? 0 : 1;
					IPhysicalEntity* pPhysEnt = pCollEvent->pEntity[physFrag];

					if (pPhysEnt && pCollEvent->iForeignData[physFrag] == PHYS_FOREIGN_ID_BREAKABLE_GLASS_FRAGMENT)
					{
						// Fragments only collide with non-glass geometry
						const int nonFragType = pCollEvent->iForeignData[1-physFrag];

						if (nonFragType != PHYS_FOREIGN_ID_BREAKABLE_GLASS
							&& nonFragType != PHYS_FOREIGN_ID_BREAKABLE_GLASS_FRAGMENT
							&& nonFragType != PHYS_FOREIGN_ID_ENTITY) // Only break on floors, walls, etc.
						{
							// Verify parent glass node, then allow it to handle impact
							if (SGlassPhysFragment* pPhysFrag = (SGlassPhysFragment*)pCollEvent->pForeignData[physFrag])
							{
								if (IBreakableGlassRenderNode* pRenderNode = (IBreakableGlassRenderNode*)pPhysFrag->m_pRenderNode)
								{
									pRenderNode->DestroyPhysFragment(pPhysFrag);
								}
							}	
						}	
					}
					else if (pCollEvent->iForeignData[PHYSEVENT_COLLIDEE] == PHYS_FOREIGN_ID_BREAKABLE_GLASS)
					{
						// Get breakable glass data
						PodArray<IBreakableGlassRenderNode*>& glassPlanes = pGlassSystem->m_glassPlanes;
						const int numPlanes = glassPlanes.Count();

						// Duplicate event so we can freely manipulate it
						EventPhysCollision dupeEvent = *pCollEvent;
						const EventPhysCollision* pDupeEvent = (const EventPhysCollision*)&dupeEvent;

						// Some actors can force breaks for gameplay reasons
						IPhysicalEntity* pCollider = dupeEvent.pEntity[PHYSEVENT_COLLIDER];

						if (pCollider && pCollider->GetType() == PE_LIVING)
						{
							IEntity* pColliderEntity = (IEntity*)pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY);
							IActor* pActor = pColliderEntity ? gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pColliderEntity->GetId()) : NULL;

							if (pActor && pActor->MustBreakGlass())
							{
								pGlassSystem->ModifyEventToForceBreak(&dupeEvent);
							}		
						}

						// Verify glass node and pass impact through
						IBreakableGlassRenderNode* pRenderNode = (IBreakableGlassRenderNode*)pCollEvent->pForeignData[PHYSEVENT_COLLIDEE];
						const int targetId = pRenderNode ? pRenderNode->GetId() : numPlanes;

						if (targetId < numPlanes && pRenderNode == glassPlanes[targetId])
						{
							pGlassSystem->PassImpactToNode(pRenderNode, pDupeEvent);
						}
					}
				}
			}
		}
	}

	return 1; // Pass event to other handlers even if we processed it
}//------------------------------------------------------------------------------------------------- 
예제 #11
0
//------------------------------------------------------------------------
bool CGameRules::OnInitiate(SHostMigrationInfo& hostMigrationInfo, uint32& state)
{
	if (!g_pGame->GetIGameFramework()->ShouldMigrateNub(hostMigrationInfo.m_session))
	{
		return true;
	}

	CryLog("[Host Migration]: CGameRules::OnInitiate() Saving character for host migration started");

	m_hostMigrationClientHasRejoined = false;

	IEntityScriptProxy* pScriptProxy = static_cast<IEntityScriptProxy*>(GetEntity()->GetProxy(ENTITY_PROXY_SCRIPT));
	if (pScriptProxy)
	{
		if (string(pScriptProxy->GetState())  == "InGame")
		{
			m_hostMigrationTimeSinceGameStarted = (m_cachedServerTime - m_gameStartedTime);
		}
	}

	HostMigrationStopAddingPlayers();

	if (gEnv->IsClient())
	{
		if (!m_pHostMigrationParams)
		{
			m_pHostMigrationParams = new SHostMigrationClientRequestParams();
			m_pHostMigrationClientParams = new SHostMigrationClientControlledParams();
		}

		IActor *pPlayer = g_pGame->GetIGameFramework()->GetClientActor();
		if (pPlayer)
		{
			m_pHostMigrationClientParams->m_viewQuat = pPlayer->GetViewRotation();
			m_pHostMigrationClientParams->m_position = pPlayer->GetEntity()->GetPos();

			pe_status_living livStat;
			IPhysicalEntity *pPhysicalEntity = pPlayer->GetEntity()->GetPhysics();
			if (pPhysicalEntity != NULL && (pPhysicalEntity->GetType() == PE_LIVING) && (pPhysicalEntity->GetStatus(&livStat) > 0))
			{
				m_pHostMigrationClientParams->m_velocity = livStat.velUnconstrained;
				m_pHostMigrationClientParams->m_hasValidVelocity = true;
				CryLog("    velocity={%f,%f,%f}", m_pHostMigrationClientParams->m_velocity.x, m_pHostMigrationClientParams->m_velocity.y, m_pHostMigrationClientParams->m_velocity.z);
			}

			IInventory *pInventory = pPlayer->GetInventory();

			m_pHostMigrationClientParams->m_numExpectedItems = 0;

			int numAmmoTypes = 0;
			m_pHostMigrationClientParams->m_pAmmoParams = new SHostMigrationClientControlledParams::SAmmoParams[numAmmoTypes];
			m_pHostMigrationClientParams->m_numAmmoParams = numAmmoTypes;

			/*CryLog("  player has %i different ammo types", numAmmoTypes);
			for (int i = 0; i < numAmmoTypes; ++ i)
			{
				IEntityClass *pAmmoType = pInventory->GetAmmoType(i);
				int ammoCount = pInventory->GetAmmoCount(pAmmoType);

				m_pHostMigrationClientParams->m_pAmmoParams[i].m_pAmmoClass = pAmmoType;
				m_pHostMigrationClientParams->m_pAmmoParams[i].m_count = ammoCount;

				CryLog("    %s : %i", pAmmoType->GetName(), ammoCount);
			}*

			EntityId holseredItemId = pInventory->GetHolsteredItem();
			if (holseredItemId)
			{
				IEntity *pHolsteredEntity = gEnv->pEntitySystem->GetEntity(holseredItemId);
				if (pHolsteredEntity)
				{
					m_pHostMigrationClientParams->m_pHolsteredItemClass = pHolsteredEntity->GetClass();
				}
			}*/

			IMovementController *pMovementController = pPlayer->GetMovementController();
			if(pMovementController)
			{
				SMovementState movementState;
				pMovementController->GetMovementState(movementState);

				m_pHostMigrationClientParams->m_aimDirection = movementState.aimDirection;
			}

			/*CItem *pItem = static_cast<CItem*>(pPlayer->GetCurrentItem());
			if (pItem)
			{
				m_pHostMigrationClientParams->m_pSelectedItemClass = pItem->GetEntity()->GetClass();
				CryLog("  currently using item '%s", pItem->GetEntity()->GetName());
			}*/
		}
		else
		{
			CRY_ASSERT_MESSAGE(false, "Failed to find client actor when initiating a host migration");
			gEnv->pNetwork->TerminateHostMigration(hostMigrationInfo.m_session);
			return false;
		}
	}

	g_pGame->SetHostMigrationState(CGame::eHMS_WaitingForPlayers);

	CCCPOINT(HostMigration_OnInitiate);
	return true;
}
예제 #12
0
//-----------------------------------------------
//This function is only executed on the server
void CC4Projectile::Stick(EventPhysCollision *pCollision)
{
	assert(pCollision);
	int trgId = 1;
	IPhysicalEntity *pTarget = pCollision->pEntity[trgId];

	if(pTarget == GetEntity()->GetPhysics())
	{
		trgId = 0;
		pTarget = pCollision->pEntity[trgId];
	}

	//Do not stick to breakable glass
	if(ISurfaceType *pSurfaceType = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceType(pCollision->idmat[trgId]))
	{
		if(pSurfaceType->GetBreakability()==1)
		{
			m_notStick = true;
			return;
		}
	}

	IEntity *pTargetEntity = pTarget ? gEnv->pEntitySystem->GetEntityFromPhysics(pTarget) : 0;

	if(pTarget && (!pTargetEntity || (pTargetEntity->GetId() != m_ownerId)))
	{
		//Special cases
		if(pTargetEntity)
		{
			//Stick to actors using a character attachment
			CActor *pActor = static_cast<CActor *>(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTargetEntity->GetId()));

			//Not in MP
			if(pActor && gEnv->bMultiplayer)
			{
				m_notStick = true;
				return;
			}

			if(pActor && pActor->GetHealth()>0)
			{
				if(pActor->GetActorSpecies()!=eGCT_HUMAN)
				{
					m_notStick = true;
					return;
				}

				if(StickToCharacter(true,pTargetEntity))
				{
					GetGameObject()->SetAspectProfile(eEA_Physics, ePT_None);
					m_stuck = true;
				}

				m_notStick = true;
				return;
			}

			//Do not stick to small objects...
			if(!pActor)
			{
				pe_params_part pPart;
				pPart.ipart = 0;

				if(pTarget->GetParams(&pPart) && pPart.pPhysGeom && pPart.pPhysGeom->V<0.15f)
				{
					m_notStick = true;
					return;
				}
			}

		}
		else if(pTarget->GetType()==PE_LIVING)
		{
			m_notStick = true;
			return;
		}

		if(!pTargetEntity)
			StickToStaticObject(pCollision,pTarget);
		else
		{
			//Do not attach to items
			if(g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pTargetEntity->GetId()))
			{
				m_notStick = true;
				return;
			}

			Matrix34 mat = pTargetEntity->GetWorldTM();
			mat.Invert();
			Vec3 pos = mat.TransformPoint(pCollision->pt);
			mat.SetIdentity();
			mat.SetRotation33(Matrix33::CreateOrientation(-pCollision->n,GetEntity()->GetWorldTM().TransformVector(Vec3(0,0,1)),gf_PI));
			mat.SetTranslation(pos);

			//Dephysicalize and stick
			GetGameObject()->SetAspectProfile(eEA_Physics, ePT_None);

			StickToEntity(pTargetEntity,mat);

			if(gEnv->bMultiplayer)
			{
				Quat rot(Matrix33::CreateOrientation(-pCollision->n,GetEntity()->GetWorldTM().TransformVector(Vec3(0,0,1)),gf_PI*0.5f));
				GetGameObject()->InvokeRMI(CC4Projectile::ClStickToEntity(),ProjectileStickToEntity(pTargetEntity->GetId(),pos,rot),eRMI_ToAllClients);
			}
		}

		m_stuck = true;
	}
}
예제 #13
0
	virtual void ProcessEvent( EFlowEvent event,SActivationInfo* pActInfo )
	{
		switch (event)
		{
		case eFE_Activate:
		{
			m_lastTime = gEnv->pTimer->GetFrameStartTime();
			m_bActive  = !GetPortBool(pActInfo, 1);
			pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, m_bActive );

			if (!m_bActive)
			{
				ResetVelocity(pActInfo);
			}
		}

		break;
		case eFE_Initialize:
		{
			if (pActInfo->pEntity)
				m_localRot = pActInfo->pEntity->GetRotation();
			else
				m_localRot.SetIdentity();
			m_worldRot.SetIdentity();
			m_lastTime = gEnv->pTimer->GetFrameStartTime();
			m_bActive  = !GetPortBool(pActInfo, 1);
			pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, m_bActive );
			break;
		}

		case eFE_Update:
		{
			if (m_bActive && pActInfo->pEntity)
			{
				CTimeValue time           = gEnv->pTimer->GetFrameStartTime();
				float      timeDifference = (time - m_lastTime).GetSeconds();
				m_lastTime = time;

				IEntity*   pEntity   = pActInfo->pEntity;
				const bool bUseWorld = GetPortInt(pActInfo, 2) == 0 ? true : false;
				Vec3       speed     = GetPortVec3(pActInfo, 0);
				speed *= timeDifference;
				Quat deltaRot (Ang3(DEG2RAD(speed)));
				Quat finalRot;
				if (bUseWorld == false)
				{
					finalRot  = pEntity->GetRotation();
					finalRot *= deltaRot;
				}
				else
				{
					m_worldRot *= deltaRot;
					finalRot    = m_worldRot;
					finalRot   *= m_localRot;
				}
				finalRot.NormalizeSafe();

				IPhysicalEntity* piPhysEnt = pEntity->GetPhysics();
				if (piPhysEnt && piPhysEnt->GetType() != PE_STATIC)
				{
					if (timeDifference > 0.0001f)
					{
						pe_action_set_velocity asv;
						asv.w                    = Quat::log(deltaRot) * (2.f / timeDifference);
						asv.bRotationAroundPivot = 1;
						pEntity->GetPhysics()->Action(&asv);
					}
				}
				else
				{
					pEntity->SetRotation(finalRot);
				}
				Ang3 currentAng = Ang3(finalRot);
				ActivateOutput(pActInfo, 1, Vec3(currentAng));
				currentAng = RAD2DEG(currentAng);
				ActivateOutput(pActInfo, 0, Vec3(currentAng));
			}
			break;
		}
		}
	}
	virtual void ProcessEvent( EFlowEvent event,SActivationInfo *pActInfo )
	{
		switch (event)
		{
			case eFE_Activate:
			{
				// update destination only if dynamic update is enabled. otherwise destination is read on Start/Reset only
				if (m_bActive && IsPortActive(pActInfo, IN_DEST) && GetPortBool(pActInfo, IN_DYN_DEST) == true)
				{
					ReadDestinationPosFromInput( pActInfo );
					if (m_valueType==VT_TIME)
						CalcSpeedFromTimeInput( pActInfo );
				}
				if (m_bActive && IsPortActive(pActInfo, IN_VALUE))
				{
					ReadSpeedFromInput( pActInfo ); 
				}
				if (IsPortActive(pActInfo, IN_START))
				{
					Start( pActInfo );
				}
				if (IsPortActive(pActInfo, IN_STOP))
				{
					pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, false );
					if (m_bActive)
					{
						ActivateOutput(pActInfo, OUT_DONE, true);
						m_bActive = false;
					}
					ActivateOutput(pActInfo, OUT_STOP, true);
				}

				// we dont support dynamic change of those inputs
				assert( !IsPortActive(pActInfo, IN_COORDSYS) );
				assert( !IsPortActive(pActInfo, IN_VALUETYPE) );

				break;
			}

			case eFE_Initialize:
			{
				m_bActive = false;
				m_position = ZERO;
				m_coorSys = (ECoordSys)GetPortInt( pActInfo, IN_COORDSYS );
				m_valueType = (EValueType)GetPortInt(pActInfo, IN_VALUETYPE);
				IEntity *pEnt = pActInfo->pEntity;
				if(pEnt)
					m_position = pEnt->GetWorldPos();
				ActivateOutput(pActInfo, OUT_CURRENT, m_position);  // i dont see a sense for this, but lets keep it for now
				pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, false );
				break;
			}

			case eFE_Update:
			{
				IEntity *pEnt = pActInfo->pEntity;
			  if (!pEnt)
				{
					pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, false );
					break;
				}

				// Use physics velocity updates, unless the entity is parented in another entity space and not rigid.
				IPhysicalEntity* pPhysEnt = pEnt->GetPhysics();
				if( pPhysEnt && (pEnt->GetParent()!=NULL || pPhysEnt->GetType() == PE_STATIC) )
				{
					pPhysEnt = NULL;
				}

				if (m_stopping)
				{
					m_stopping = false;
					pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, false );

					if( pPhysEnt == NULL )
					{
						SetPos(pActInfo, m_destination);
					}

					m_bActive = false;
					break;
				}
				
				if (!m_bActive) break;
				float time = gEnv->pTimer->GetFrameStartTime().GetSeconds();
				float timeDifference = time - m_lastFrameTime; 
				m_lastFrameTime = time;

					// note - if there's no physics then this will be the same, but if the platform is moved through physics, then
					//        we have to get back the actual movement - this maybe framerate dependent.
				m_position = pActInfo->pEntity->GetPos();

				// let's compute the movement vector now
				Vec3 oldPosition = m_position;

				if(m_bForceFinishAsTooNear || m_position.IsEquivalent(m_destination, 0.01f))
				{
					m_position = m_destination;
					oldPosition = m_destination;
					ActivateOutput(pActInfo, OUT_DONE, true);
					ActivateOutput(pActInfo, OUT_FINISH, true);
					SetPos(pActInfo, m_position); // for finishing we have to make a manual setpos even if there is physics involved, to make sure the entity will be where it should.
					if (pPhysEnt)
					{
						pe_action_set_velocity setVel;
						setVel.v = ZERO;
						pPhysEnt->Action( &setVel );

						m_stopping = true;
					}
					else
					{
						pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, false );
						m_bActive = false;
					}
				}
				else
				{
					Vec3 direction = m_destination - m_position;
					float distance = direction.GetLength();
					Vec3 directionAndSpeed = direction.normalized();

					// ease-area calcs
					float distanceForEaseOutCalc = distance + m_easeOutDistance * EASE_MARGIN_FACTOR;
					if (distanceForEaseOutCalc < m_easeOutDistance)	// takes care of m_easeOutDistance being 0
					{
						directionAndSpeed *= distanceForEaseOutCalc / m_easeOutDistance;
					}
					else  // init code makes sure both eases dont overlap, when the movement is time defined. when it is speed defined, only ease out is applied if they overlap. 
					{
						if (m_easeInDistance>0.f)
						{
							Vec3 vectorFromStart = m_position - m_startPos;
							float distanceFromStart = vectorFromStart.GetLength();
							float distanceForEaseInCalc = distanceFromStart + m_easeInDistance * EASE_MARGIN_FACTOR;
							if (distanceForEaseInCalc < m_easeInDistance)
							{
								directionAndSpeed *= distanceForEaseInCalc / m_easeInDistance;
							}
						}
					}

					directionAndSpeed *= (m_topSpeed * timeDifference);

					if(direction.GetLength() < directionAndSpeed.GetLength())
					{
						m_position = m_destination;
						m_bForceFinishAsTooNear = true;
					}
					else
						m_position += directionAndSpeed;
				}
				ActivateOutput(pActInfo, OUT_CURRENT, m_position);
				if (pPhysEnt == NULL)
				{
					SetPos(pActInfo, m_position);
				}
				else
				{
					pe_action_set_velocity setVel;
					float rTimeStep = timeDifference>0.000001f ? 1.f / timeDifference : 0.0f;
					setVel.v = (m_position - oldPosition) * rTimeStep;  
					pPhysEnt->Action( &setVel );
				}
				break;
			}
		};
	};
//------------------------------------------------------------------------
bool CGameRules::OnInitiate(SHostMigrationInfo &hostMigrationInfo, uint32 &state)
{
	if (!g_pGame->GetIGameFramework()->ShouldMigrateNub(hostMigrationInfo.m_session))
	{
		return true;
	}

	CryLog("[Host Migration]: CGameRules::OnInitiate() Saving character for host migration started");
	m_hostMigrationClientHasRejoined = false;
	IEntityScriptProxy *pScriptProxy = static_cast<IEntityScriptProxy *>(GetEntity()->GetProxy(ENTITY_PROXY_SCRIPT));

	if (pScriptProxy)
	{
		if (string(pScriptProxy->GetState())  == "InGame")
		{
			m_hostMigrationTimeSinceGameStarted = (m_cachedServerTime - m_gameStartedTime);
		}
	}

	HostMigrationStopAddingPlayers();

	if (gEnv->IsClient())
	{
		if (!m_pHostMigrationParams)
		{
			m_pHostMigrationParams = new SHostMigrationClientRequestParams();
			m_pHostMigrationClientParams = new SHostMigrationClientControlledParams();
		}

		CPlayer *pPlayer = static_cast<CPlayer *>(g_pGame->GetIGameFramework()->GetClientActor());

		if (pPlayer)
		{
			m_pHostMigrationClientParams->m_viewQuat = pPlayer->GetViewRotation();
			m_pHostMigrationClientParams->m_position = pPlayer->GetEntity()->GetPos();
			pe_status_living livStat;
			IPhysicalEntity *pPhysicalEntity = pPlayer->GetEntity()->GetPhysics();

			if (pPhysicalEntity != NULL && (pPhysicalEntity->GetType() == PE_LIVING) && (pPhysicalEntity->GetStatus(&livStat) > 0))
			{
				m_pHostMigrationClientParams->m_velocity = livStat.velUnconstrained;
				m_pHostMigrationClientParams->m_hasValidVelocity = true;
				CryLog("    velocity={%f,%f,%f}", m_pHostMigrationClientParams->m_velocity.x, m_pHostMigrationClientParams->m_velocity.y, m_pHostMigrationClientParams->m_velocity.z);
			}

			IMovementController *pMovementController = pPlayer->GetMovementController();
			SMovementState movementState;
			pMovementController->GetMovementState(movementState);
			m_pHostMigrationClientParams->m_aimDirection = movementState.aimDirection;
		}
		else
		{
			CRY_ASSERT_MESSAGE(false, "Failed to find client actor when initiating a host migration");
			gEnv->pNetwork->TerminateHostMigration(hostMigrationInfo.m_session);
			return false;
		}
	}

	g_pGame->SetHostMigrationState(CGame::eHMS_WaitingForPlayers);
	CCCPOINT(HostMigration_OnInitiate);
	return true;
}