//------------------------------------------------------------------------
void CVehicleDamageBehaviorCameraShake::ShakeClient(float angle, float shift, float duration, float frequency)
{
	IActorSystem *pActorSystem = gEnv->pGame->GetIGameFramework()->GetIActorSystem();
	assert(pActorSystem);
	EntityId clientId = g_pGame->GetIGameFramework()->GetClientActorId();

	for (TVehicleSeatId seatId = InvalidVehicleSeatId + 1;
			seatId != m_pVehicle->GetLastSeatId(); seatId++)
	{
		if (IVehicleSeat *pSeat = m_pVehicle->GetSeatById(seatId))
		{
			EntityId passengerId = pSeat->GetPassenger();

			if (passengerId == clientId)
			{
				CActor *pActor = static_cast<CActor *>(pActorSystem->GetActor(passengerId));

				if(pActor)
				{
					pActor->CameraShake(angle, shift, duration, frequency, Vec3(0.0f, 0.0f, 0.0f), 5, "VehicleDamageBehaviorCameraShake");
				}
			}
		}
	}
}
//------------------------------------------------------------------------
void CVehicleActionDeployRope::OnVehicleEvent(EVehicleEvent event, const SVehicleEventParams& params)
{
	if (event == eVE_PassengerExit && params.iParam == m_seatId)
	{
		IActorSystem* pActorSystem = gEnv->pGame->GetIGameFramework()->GetIActorSystem();
		assert(pActorSystem);

		IActor* pActor = pActorSystem->GetActor(params.entityId);
		if (!pActor)
		{
			assert(pActor);
			return;
		}

		m_actorId = pActor->GetEntityId();

		DeployRope();
		AttachOnRope(pActor->GetEntity());
	} 
	else if (event == eVE_Destroyed)
	{
		if (m_ropeUpperId)
		{
			gEnv->pEntitySystem->RemoveEntity(m_ropeUpperId);
			m_ropeUpperId = 0;
		}

		if (m_ropeLowerId)
		{
			gEnv->pEntitySystem->RemoveEntity(m_ropeLowerId);
			m_ropeLowerId = 0;
		}
	}
}
//------------------------------------------------------------------------
void CVehicleActionDeployRope::Update(const float deltaTime)
{
	if (!m_ropeUpperId && !m_ropeLowerId && !m_actorId)
		return;

	IActorSystem* pActorSystem = gEnv->pGame->GetIGameFramework()->GetIActorSystem();
	assert(pActorSystem);

	IActor* pActor = pActorSystem->GetActor(m_actorId);
	if (!pActor)
		return;

	Vec3 worldPos = pActor->GetEntity()->GetWorldTM().GetTranslation();

	if (IRopeRenderNode* pRopeUpper = GetRopeRenderNode(m_ropeUpperId))
	{
		Vec3 points[2];
		points[0] = m_pRopeHelper->GetWorldTM().GetTranslation();
		points[1] = worldPos;

		pRopeUpper->SetPoints(points, 2);

		float lenghtLeft = max(0.0f, g_ropeLenght - (points[0].z - points[1].z));

		if (IRopeRenderNode* pRopeLower = GetRopeRenderNode(m_ropeLowerId))
		{
			Vec3 points[2];
			points[0] = worldPos;
			points[1] = Vec3(worldPos.x, worldPos.y, worldPos.z - lenghtLeft);

			pRopeLower->SetPoints(points, 2);
		}
	}
}
Ejemplo n.º 4
0
EEntityType GetEntityType(EntityId id)
{
	int type = eET_Unknown;

	IEntitySystem *pEntitySystem = gEnv->pEntitySystem;
	if (pEntitySystem)
	{
		IEntity *pEntity = pEntitySystem->GetEntity(id);
		if (pEntity)
		{
			type = eET_Valid;

			IEntityClass *pClass = pEntity->GetClass();
			if (pClass)
			{
				const char* className = pClass->GetName();

				// Check AI
				if (pEntity->GetAI())
				{
					type |= eET_AI;
				}
				
				// Check actor
				IActorSystem *pActorSystem = gEnv->pGame->GetIGameFramework()->GetIActorSystem();
				if (pActorSystem)
				{
					IActor *pActor = pActorSystem->GetActor(id);
					if (pActor)
					{
						type |= eET_Actor;
					}
				}

				// Check vehicle
				IVehicleSystem *pVehicleSystem = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem();
				if (pVehicleSystem)
				{
					if (pVehicleSystem->IsVehicleClass(className))
					{
						type |= eET_Vehicle;
					}
				}

				// Check item
				IItemSystem *pItemSystem = gEnv->pGame->GetIGameFramework()->GetIItemSystem();
				if (pItemSystem)
				{
					if (pItemSystem->IsItemClass(className))
					{
						type |= eET_Item;
					}
				}
			}
		}
	}

	return (EEntityType)type;
}
void CAnimatedCharacter::RefreshAnimTarget()
{
	if (m_pMannequinAGState)
	{
		IActorSystem* pActorSystem = CCryAction::GetCryAction()->GetIActorSystem();
		assert(pActorSystem != NULL);
		IActor* pActor = pActorSystem->GetActor(GetEntity()->GetId());
		IMovementController* pMovementController = pActor->GetMovementController();

		m_pAnimTarget = pMovementController->GetExactPositioningTarget();
	}
}
Ejemplo n.º 6
0
//------------------------------------------------------------------------
void CVehicleSeatActionMovement::StopUsing()
{
	IActorSystem* pActorSystem = CCryAction::GetCryAction()->GetIActorSystem();
	CRY_ASSERT(pActorSystem);

	IVehicleMovement* pMovement = m_pVehicle->GetMovement();
	if (!pMovement)
		return;

	CRY_ASSERT(m_pSeat);

	// default to continuing for a bit
	m_delayedStop = 0.8f;

	IActor* pActor = pActorSystem->GetActor(m_pSeat->GetPassenger());

	if (pActor && pActor->IsPlayer())
	{
		// if stopped already don't go anywhere
		IPhysicalEntity*   pPhys = m_pVehicle->GetEntity()->GetPhysics();
		pe_status_dynamics status;
		if (pPhys && pPhys->GetStatus(&status))
		{
			if (status.v.GetLengthSquared() < 25.0f)
				m_delayedStop = 0.0f;
		}

		if (m_actionForward > 0.0f)
			m_delayedStop = 1.5f;

		if (pMovement->GetMovementType() == IVehicleMovement::eVMT_Air)
			m_delayedStop *= 2.0f;

		m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_AlwaysUpdate);

		// prevent full pedal being kept pressed, but give it a bit
		pMovement->OnAction(eVAI_MoveForward, eAAM_OnPress, 0.1f);
	}
	else
	{
		if (pMovement->GetMovementType() == IVehicleMovement::eVMT_Air)
		{
			m_delayedStop = 0.0f;
			m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_AlwaysUpdate);
		}
		else
		{
			pMovement->StopDriving();
		}
	}
}
//---------------------------------------
TAudioSignalID CAreaAnnouncer::BuildAnnouncement(const EntityId clientId)
{
	const int k_areaCount = m_areaList.size();
	if (k_areaCount > 0)
	{
		IActorSystem* pActorSystem = gEnv->pGame->GetIGameFramework()->GetIActorSystem();

		if (CActor* pClientActor = static_cast<CActor*>(pActorSystem->GetActor(clientId)))
		{
			int actorCount[k_maxAnnouncementAreas];
			memset(&actorCount, 0, sizeof(actorCount));

			CActorManager * pActorManager = CActorManager::GetActorManager();

			pActorManager->PrepareForIteration();

			const int kNumActors		= pActorManager->GetNumActors();
			const int kPlayerTeamId = g_pGame->GetGameRules()->GetTeam(clientId);

			for (int i = 0; i < kNumActors; i++)
			{
				SActorData actorData;
				pActorManager->GetNthActorData(i, actorData);

				if(actorData.teamId != kPlayerTeamId && actorData.health > 0 && actorData.spectatorMode == CActor::eASM_None)
				{
					for (int areaIndex = 0; areaIndex < k_areaCount; areaIndex++)
					{
						IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_areaList[areaIndex].m_areaProxyId);
						if(pEntity)
						{
							IEntityAreaProxy *pArea = (IEntityAreaProxy*)pEntity->GetProxy(ENTITY_PROXY_AREA);
							if(pArea && pArea->CalcPointWithin(INVALID_ENTITYID, actorData.position, true))
							{
								actorCount[areaIndex]++;
								break;
							}
						}
					}
				}
			}

			return GenerateAnnouncement(&actorCount[0], k_areaCount, clientId);
		}
	}

	return INVALID_AUDIOSIGNAL_ID;
}
Ejemplo n.º 8
0
//------------------------------------------------------------------------
void CVehicleClient::OnEnterVehicleSeat(IVehicleSeat* pSeat)
{
	m_bMovementFlagRight=m_bMovementFlagLeft=m_bMovementFlagForward=m_bMovementFlagBack=false;
	m_fLeftRight = m_fForwardBackward = 0.f;

	IVehicle* pVehicle = pSeat->GetVehicle();
	assert(pVehicle);

	IActorSystem* pActorSystem = gEnv->pGame->GetIGameFramework()->GetIActorSystem();
	assert(pActorSystem);

	IActor* pActor = pActorSystem->GetActor(pSeat->GetPassenger());
	if (pActor)
	{
		bool isThirdPerson = pActor->IsThirdPerson() || m_tp;

		TVehicleViewId viewId = InvalidVehicleViewId;
		TVehicleViewId firstViewId = InvalidVehicleViewId;

		while (viewId = pSeat->GetNextView(viewId))
		{
			if (viewId == firstViewId)
				break;

			if (firstViewId == InvalidVehicleViewId)
				firstViewId = viewId;

			if (IVehicleView* pView = pSeat->GetView(viewId))
			{
				if (pView->IsThirdPerson() == isThirdPerson)
					break;
			}
		}

		if (viewId != InvalidVehicleViewId)
			pSeat->SetView(viewId);

		if(IActor *pPassengerActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pSeat->GetPassenger()))
		{
			if(pPassengerActor->IsPlayer())
			{
				EnableActionMaps(pSeat, true);
			}
		}
	}
}
Ejemplo n.º 9
0
//-------------------------------------------------------------------------
void CGameRulesStandardState::CleanUpAbortedIntro()
{
	CGameRules::TPlayers players; 
	m_pGameRules->GetPlayers(players);
	IActorSystem* pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem();
	CGameRules::TPlayers::const_iterator iter = players.begin();
	CGameRules::TPlayers::const_iterator end = players.end();
	while(iter != end)
	{
		CPlayer* pPlayer = static_cast<CPlayer*>( pActorSystem->GetActor( *iter ) );
		if(pPlayer)
		{
			pPlayer->OnIntroSequenceFinished(); 
		}
		++iter; 
	}
}
Ejemplo n.º 10
0
//------------------------------------------------------------------------
void CVehicleClient::OnEnterVehicleSeat(IVehicleSeat* pSeat)
{
	m_bMovementFlagRight=m_bMovementFlagLeft=m_bMovementFlagForward=m_bMovementFlagBack=false;
  m_fLeftRight = m_fForwardBackward = 0.f;

	IVehicle* pVehicle = pSeat->GetVehicle();
	assert(pVehicle);

	IActorSystem* pActorSystem = gEnv->pGame->GetIGameFramework()->GetIActorSystem();
	assert(pActorSystem);

	IActor* pActor = pActorSystem->GetActor(pSeat->GetPassenger());
	bool isThirdPerson = pActor->IsThirdPerson() || m_tp;

	TVehicleViewId viewId = InvalidVehicleViewId;
	TVehicleViewId firstViewId = InvalidVehicleViewId;

	while (viewId = pSeat->GetNextView(viewId))
	{
		if (viewId == firstViewId)
			break;

		if (firstViewId == InvalidVehicleViewId)
			firstViewId = viewId;

		if (IVehicleView* pView = pSeat->GetView(viewId))
		{
			if (pView->IsThirdPerson() == isThirdPerson)
				break;
		}
	}

	if (viewId != InvalidVehicleViewId)
		pSeat->SetView(viewId);

	IActionMapManager* pMapManager = gEnv->pGame->GetIGameFramework()->GetIActionMapManager();
	assert(pMapManager);

	pMapManager->EnableActionMap("landvehicle", false);
	pMapManager->EnableActionMap("seavehicle", false);
	pMapManager->EnableActionMap("helicopter", false);
	pMapManager->EnableActionMap("vtol", false);

    pMapManager->EnableFilter ( "vehicle_no_seat_change_and_exit", true );
}
//------------------------------------------------------------------------
bool CVehicleActionDeployRope::DeployRope()
{
	IActorSystem* pActorSystem = gEnv->pGame->GetIGameFramework()->GetIActorSystem();
	assert(pActorSystem);

	IActor* pActor = pActorSystem->GetActor(m_actorId);
	if (!pActor)
		return false;

	Vec3 upperPos = m_pRopeHelper->GetWorldTM().GetTranslation();
	Vec3 lowerPos(upperPos.x, upperPos.y, upperPos.z - g_ropeLenght);

	m_ropeUpperId = CreateRope(m_pVehicle->GetEntity()->GetPhysics(), upperPos, upperPos);
	m_ropeLowerId = CreateRope(pActor->GetEntity()->GetPhysics(), upperPos, lowerPos);
	
	m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_AlwaysUpdate);

	return true;
}
void CLocalPlayerComponent::Revive()
{
	if(gEnv->bMultiplayer)
	{
		// Reset NotYetSpawned filter.
		IActionFilter* pNYSFilter = g_pGameActions->FilterNotYetSpawned();
		if(pNYSFilter && pNYSFilter->Enabled())
		{
			pNYSFilter->Enable(false);
		}

		// For Modes where we can swap teams per round, refresh everyone else's cloak colour on revive.
		CGameRules *pGameRules = g_pGame->GetGameRules();
		if( pGameRules->GetGameMode()==eGM_Gladiator )
		{
			IActorSystem* pActorSys = g_pGame->GetIGameFramework()->GetIActorSystem();
			CActorManager* pActorManager = CActorManager::GetActorManager();
			pActorManager->PrepareForIteration();
			const int kNumActors = pActorManager->GetNumActors();
			for(int i=0; i<kNumActors; i++)
			{
				SActorData actorData;
				pActorManager->GetNthActorData(i, actorData);		
				if(CActor* pActor = static_cast<CActor*>(pActorSys->GetActor(actorData.entityId)))
				{
					if(pActor->IsCloaked())
					{
						pActor->SetCloakLayer(false);
						pActor->SetCloakLayer(true);
					}
				}
			}
		}
	}

	m_bIsInFreeFallDeath = false;
	m_playedMidHealthSound = false;
}
Ejemplo n.º 13
0
//------------------------------------------------------------------------
void CVehicleSeatActionMovement::StartUsing(EntityId passengerId)
{
	IActorSystem* pActorSystem = CCryAction::GetCryAction()->GetIActorSystem();
	CRY_ASSERT(pActorSystem);

	IActor* pActor = pActorSystem->GetActor(passengerId);
	CRY_ASSERT(pActor);

	IVehicleMovement* pMovement = m_pVehicle->GetMovement();
	CRY_ASSERT(pMovement);

	if (!pMovement)
		return;

	if (m_delayedStop >= 0.0f)
	{
		m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_NoUpdate);
		m_delayedStop = 0.0f;

		pMovement->StopDriving();
	}

	pMovement->StartDriving(passengerId);
}
//------------------------------------------------------------------------
void CVehicleViewFirstPerson::HideEntitySlots(IEntity* pEnt, bool hide)
{
	IActorSystem* pActorSystem = CCryAction::GetCryAction()->GetIActorSystem();
	CRY_ASSERT(pActorSystem);

  if (hide)
  {
    for (int i=0; i<pEnt->GetSlotCount(); ++i)
    { 
      if (pEnt->IsSlotValid(i) && pEnt->GetSlotFlags(i) & ENTITY_SLOT_RENDER)
      {	
        if (pEnt->GetId() == m_pVehicle->GetEntity()->GetId())
        {
          // set character to always update
          if (ICharacterInstance* pCharInstance = pEnt->GetCharacter(i))
          {
            pCharInstance->SetFlags(pCharInstance->GetFlags() | CS_FLAG_UPDATE_ALWAYS);

            if (ISkeletonPose* pSkeletonPose = pCharInstance->GetISkeletonPose())
              pSkeletonPose->SetForceSkeletonUpdate(10);
          }
        }

				pEnt->SetSlotFlags(i, pEnt->GetSlotFlags(i) & ~ENTITY_SLOT_RENDER);

				if (IActor* pActor = pActorSystem->GetActor(pEnt->GetId()))
				{
					pActor->HideAllAttachments(true);
				}

        // store slot; we must not reveal previously hidden slots later      
        m_slotFlags.insert( std::pair<EntityId,int>(pEnt->GetId(), i) );				
      }
    }
    
		// hide all children
    for (int i=0; i<pEnt->GetChildCount(); ++i)
      HideEntitySlots(pEnt->GetChild(i), hide);  
  }
  else 
  {
    // unhide all stored slots
    for (TSlots::iterator it=m_slotFlags.begin(); it!=m_slotFlags.end(); ++it)
    {
      IEntity* pEntity = gEnv->pEntitySystem->GetEntity(it->first);

      if (pEntity && pEntity->IsSlotValid(it->second))
      {
				pEntity->SetSlotFlags(it->second, pEntity->GetSlotFlags(it->second)|(ENTITY_SLOT_RENDER));

				if (IActor* pActor = pActorSystem->GetActor(pEnt->GetId()))
				{
					pActor->HideAllAttachments(false);
				}

        if (pEntity->GetId() == m_pVehicle->GetEntity()->GetId())
        {
          // reset character flags
          if (ICharacterInstance* pCharInstance = pEntity->GetCharacter(it->second))
          {
            pCharInstance->SetFlags(pCharInstance->GetFlags() & ~CS_FLAG_UPDATE_ALWAYS);

            if (ISkeletonPose* pSkeletonPose = pCharInstance->GetISkeletonPose())
              pSkeletonPose->SetForceSkeletonUpdate(0);
          }
        }
      }
    }

    m_slotFlags.clear();
  }
}
//////////////////////////////////////////////////////////////////////////
//this respawns the active AI at their spawn locations
void CCheckpointSystem::RespawnAI(XmlNodeRef data)
{
	if(!data)
		return;

	XmlNodeRef actorData = data->findChild(ACTOR_FLAGS_SECTION);
	if(!actorData)
	{
		CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "Failed reading actor data from checkpoint, actors won't be respawned");
		return;
	}

	IActorSystem *pActorSystem = CCryAction::GetCryAction()->GetIActorSystem();

	//first run through all actors and hide/deactivate them
	IActorIteratorPtr it = pActorSystem->CreateActorIterator();
	while (IActor *pActor = it->Next())
	{
		IEntity *pEntity = pActor->GetEntity();
		//deactivate all actors
		pEntity->Hide(true);
		pEntity->Activate(false);
	}

	//load actorflags for active actors
	XmlNodeRef activatedActors = actorData->findChild(ACTIVATED_ACTORS_SECTION);
	if(activatedActors)
	{
		int actorFlags = activatedActors->getNumAttributes();
		const char *key;
		const char *value;
		for(int i = 0; i < actorFlags; ++i)
		{
			activatedActors->getAttributeByIndex(i, &key, &value);
			//format is "idXXX"
			CRY_ASSERT(strlen(key)>2);
			EntityId id = (EntityId)(atoi(&key[2]));
			bool foundEntity = RepairEntityId(id, value);
			if(foundEntity)
			{
				IActor* pActor = pActorSystem->GetActor(id);
				if(pActor)
				{
					pActor->GetEntity()->Hide(false);
					pActor->GetEntity()->Activate(true);
				}
				else
					CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "Failed finding actor %i from checkpoint.", (int)id);
			}
			else
				CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "Failed finding actor %s from checkpoint, actor is not setup correctly.", value);
		}
	}
	else
		CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "Deactivated actors section was missing in checkpoint.");

	it = pActorSystem->CreateActorIterator();
	//iterate all actors and respawn if active
	while (IActor *pActor = it->Next())
	{
		IEntity *pEntity = pActor->GetEntity();
		if(pEntity->GetId() == LOCAL_PLAYER_ENTITY_ID) //don't respawn player
			continue;

		//we don't respawn deactivated actors
		if(!pEntity->IsHidden() && pEntity->IsActive())
		{
			pActor->SetHealth(0);
			pActor->Respawn();
		}
		else //but we still reset their position
		{
			pActor->ResetToSpawnLocation();
		}
	}
}
//------------------------------------------------------------------------
void CVehicleMovementVTOL::Update(const float deltaTime)
{
	FUNCTION_PROFILER( GetISystem(), PROFILE_GAME );

	CVehicleMovementHelicopter::Update(deltaTime);
	CryAutoCriticalSection lk(m_lock);

	if (m_pWingsAnimation)
	{
		m_pWingsAnimation->SetTime(m_wingsAnimTime);
	}

	IActorSystem* pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem();
	assert(pActorSystem);

	IActor* pActor = pActorSystem->GetActor(m_actorId);
	if (pActor && pActor->IsClient())
	{
		float turbulence = m_turbulence;

		if (m_pAltitudeLimitVar)
		{
			float altitudeLimit = m_pAltitudeLimitVar->GetFVal();
			float currentHeight = m_pEntity->GetWorldPos().z;

			if (!iszero(altitudeLimit))
			{
				float altitudeLowerOffset;

				if (m_pAltitudeLimitLowerOffsetVar)
				{
					float r = 1.0f - min(1.0f, max(0.0f, m_pAltitudeLimitLowerOffsetVar->GetFVal()));
					altitudeLowerOffset = r * altitudeLimit;

					if (currentHeight >= altitudeLowerOffset)
					{
						if (currentHeight > altitudeLowerOffset)
						{
							float zone = altitudeLimit - altitudeLowerOffset;
							turbulence += (currentHeight - altitudeLowerOffset) / (zone);
						}
					}
				}
			}
		}

		if (turbulence > 0.0f)
		{
			static_cast<CActor*>(pActor)->CameraShake(0.50f * turbulence, 0.0f, 0.05f, 0.04f, Vec3(0.0f, 0.0f, 0.0f), 10, "VTOL_Update_Turbulence");
		}

		float enginePowerRatio = m_enginePower / m_enginePowerMax;

		if (enginePowerRatio > 0.0f)
		{
			float rpmScaleDesired = 0.2f;
			rpmScaleDesired += abs(m_forwardAction) * 0.8f;
			rpmScaleDesired += abs(m_strafeAction) * 0.4f;
			rpmScaleDesired += abs(m_turnAction) * 0.25f;
			rpmScaleDesired = min(1.0f, rpmScaleDesired);
			Interpolate(m_rpmScale, rpmScaleDesired, 1.0f, deltaTime);
		}

		float turnParamGoal = min(1.0f, abs(m_turnAction)) * 0.6f;
		turnParamGoal *= (min(1.0f, max(0.0f, m_speedRatio)) + 1.0f) * 0.50f;
		turnParamGoal += turnParamGoal * m_boost * 0.25f;
		Interpolate(m_soundParamTurn, turnParamGoal, 0.5f, deltaTime);
		SetSoundParam(eSID_Run, "turn", m_soundParamTurn);

		float damage = GetSoundDamage();
		if (damage > 0.1f)
		{ 
			//if (ISound* pSound = GetOrPlaySound(eSID_Damage, 5.f, m_enginePos))
				//SetSoundParam(pSound, "damage", damage);        
		}
	}
}
Ejemplo n.º 17
0
//------------------------------------------------------------------------
void CGameRulesMPDamageHandling::SvOnExplosion(const ExplosionInfo &explosionInfo, const CGameRules::TExplosionAffectedEntities& affectedEntities)
{
	// SinglePlayer.lua 1721

	IActorSystem* pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem();
	float totalDamage = 0.f;

	// calculate damage for each entity
	CGameRules::TExplosionAffectedEntities::const_iterator it = affectedEntities.begin();
	for (; it != affectedEntities.end(); ++it)
	{
		bool success = false;
		IEntity* entity = it->first;
		float obstruction = 1.0f - it->second;

		bool incone=true;
		if (explosionInfo.angle > 0 && explosionInfo.angle < 2*3.1415f)
		{
			Vec3 explosionEntityPos = entity->GetWorldPos();
			Vec3 entitypos = explosionEntityPos;
			float ha = explosionInfo.angle * 0.5f;
			Vec3 edir = entitypos - explosionInfo.pos;
			edir.normalize();
			float dot = 1;

			if (edir != Vec3(ZERO))
			{
				dot = edir.dot(explosionInfo.dir);
			}

			float angle = abs(acos_tpl(dot));
			if (angle > ha)
			{
				incone = false;
			}
		}

		if (incone && gEnv->bServer)
		{
			float damage = explosionInfo.damage;
			damage = floor_tpl(0.5f + CalcExplosionDamage(entity, explosionInfo, obstruction));	

			bool dead = false;

			HitInfo explHit;

			Vec3 dir = entity->GetWorldPos() - explosionInfo.pos;

			explHit.pos = explosionInfo.pos;
			explHit.radius = explosionInfo.radius;
			explHit.partId = -1;

			dir.Normalize();

			explHit.targetId = entity->GetId();
			explHit.weaponId = explosionInfo.weaponId;
			explHit.shooterId = explosionInfo.shooterId;
			explHit.projectileId = explosionInfo.projectileId;
			explHit.projectileClassId = explosionInfo.projectileClassId;

			uint16 weaponClass = ~uint16(0);
			const IEntity* pWeaponEntity = gEnv->pEntitySystem->GetEntity(explosionInfo.weaponId);
			if (pWeaponEntity)
			{
				g_pGame->GetIGameFramework()->GetNetworkSafeClassId(weaponClass, pWeaponEntity->GetClass()->GetName());
			}
			explHit.weaponClassId = weaponClass;

			explHit.material = 0;
			explHit.damage = damage;
			explHit.type = explosionInfo.type;
			explHit.hitViaProxy = explosionInfo.explosionViaProxy;

			explHit.dir = dir;
			explHit.normal = -dir; //set normal to reverse of  direction to avoid backface cull of damage

			if (explHit.damage > 0.0f || explosionInfo.damage == 0.f)
			{
				CActor* pActor = static_cast<CActor*>(pActorSystem->GetActor(entity->GetId()));

				if (pActor)
				{
					const float damageMultiplier = pActor->GetBodyExplosionDamageMultiplier(explHit);
					explHit.damage *= damageMultiplier; 

					// Protect players who are currently shielded
					if(pActor->IsPlayer() && static_cast<CPlayer*>(pActor)->ShouldFilterOutExplosion(explHit))
					{
						explHit.damage = 0.0f;
					}
				}
				else
				{
					CInteractiveObjectEx* pInteractiveObject = static_cast<CInteractiveObjectEx*>(g_pGame->GetIGameFramework()->QueryGameObjectExtension(entity->GetId(), "InteractiveObjectEx"));
					if(pInteractiveObject)
					{
						pInteractiveObject->OnExploded(explHit.pos);
					}
				}
			
				if(!explosionInfo.explosionViaProxy) 
				{
					if(pActor)
					{
						if(!pActor->IsFriendlyEntity(explHit.shooterId))
						{
							totalDamage += damage;
						}
					}
					else
					{
						IVehicle* pVehicle = g_pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(entity->GetId());

						if(pVehicle)
						{
							IActor* pDriver = pVehicle->GetDriver();
							int seatNum = 0;
							int numSeats = pVehicle->GetSeatCount();

							while(!pDriver && seatNum < numSeats)
							{
								IVehicleSeat* pSeat = pVehicle->GetSeatById(seatNum++);

								EntityId passengerId = pSeat ? pSeat->GetPassenger(true) : 0;
								pDriver = pActorSystem->GetActor(passengerId);
							}

							if(pDriver)
							{
								CActor* pDriverActor = static_cast<CActor*>(pDriver);
								if(!pDriverActor->IsFriendlyEntity(explHit.shooterId))
								{
									totalDamage += damage;
								}
							}
						}
					}
				}
				
				m_pGameRules->ServerHit(explHit);
			}
		}
	}

	if (totalDamage > 0.f)
	{
		IGameRulesPlayerStatsModule*  pPlayStatsMod = m_pGameRules->GetPlayerStatsModule();

		if(pPlayStatsMod)
		{
			pPlayStatsMod->ProcessSuccessfulExplosion(explosionInfo.shooterId, totalDamage, explosionInfo.projectileClassId);
		}
	}
}
Ejemplo n.º 18
0
//------------------------------------------------------------------------
// returns true if entity is killed, false if it is not
bool CGameRulesMPDamageHandling::SvOnHit( const HitInfo &hitInfo )
{
	const HitTypeInfo * pHitTypeInfo = m_pGameRules->GetHitTypeInfo(hitInfo.type);

#if !defined(_RELEASE)
	if(!pHitTypeInfo)
		CryFatalError("By ::SvOnHit() all hit info should have a hit type that is valid and registered in the GameRules. This isn't true of type %d!", hitInfo.type);
#endif

	SDamageHandling damageHandling(&hitInfo, 1.0f);

	float damage = hitInfo.damage;

	IActorSystem* pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem();
	CActor *pTargetActor = static_cast<CActor*>(pActorSystem->GetActor(hitInfo.targetId));
	CActor *pShooterActor = static_cast<CActor*>(pActorSystem->GetActor(hitInfo.shooterId));
	CPlayer* pShooterPlayer = (pShooterActor && pShooterActor->IsPlayer()) ? static_cast<CPlayer*>(pShooterActor) : NULL ;

	bool isPlayer = pTargetActor != NULL && pTargetActor->IsPlayer();

#ifndef _RELEASE
	//--- Fix to allow the damage handling to work for these entity classes in the same way as for Players
	static IEntityClass* sDamEntClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("DamageTestEnt");
	isPlayer |= pTargetActor != NULL && pTargetActor->GetEntity()->GetClass() == sDamEntClass;
#endif

	CPlayer* pPlayer = isPlayer ? static_cast<CPlayer*>(pTargetActor) : NULL;
	const bool isMelee = ((pHitTypeInfo->m_flags & CGameRules::EHitTypeFlag::IsMeleeAttack) != 0);
	const bool checkHeadshots = ((pHitTypeInfo->m_flags & CGameRules::EHitTypeFlag::IgnoreHeadshots) == 0);

	bool bIsHeadShot = false;
	if(pPlayer && hitInfo.partId >= 0 && checkHeadshots)
	{
		bIsHeadShot = pPlayer->IsHeadShot(hitInfo);

		if (!bIsHeadShot && g_pGameCVars->g_mpHeadshotsOnly)
		{
			damage = 0.f;
		}
	}

	//If the player has died more than kTimeToAllowKillsAfterDeath seconds ago, we disallow any damage they apply, unless the hit type is flagged as allowing it.
	static const float kTimeToAllowKillsAfterDeath = 0.05f;
	if(pTargetActor && pShooterPlayer && !hitInfo.hitViaProxy
		&& ((pHitTypeInfo->m_flags & CGameRules::EHitTypeFlag::AllowPostDeathDamage) == 0) && pShooterActor->IsDead()
		&& (gEnv->pTimer->GetFrameStartTime().GetSeconds() - pShooterPlayer->GetDeathTime()) > kTimeToAllowKillsAfterDeath)
	{
		damage = 0.0f;
	}

	IGameRulesStateModule *stateModule = m_pGameRules->GetStateModule();
	IGameRulesRoundsModule* pRoundsModule = m_pGameRules->GetRoundsModule();

	if ( (stateModule != NULL && (stateModule->GetGameState() == IGameRulesStateModule::EGRS_PostGame)) || 
		   (pRoundsModule!= NULL && !pRoundsModule->IsInProgress() ))
	{
		// No damage allowed once the game has ended, except in cases where it would cause graphical glitches
		if (hitInfo.type != CGameRules::EHitType::PunishFall)
		{
			damage = 0.0f;
		}
	}

	IEntity *pTarget = gEnv->pEntitySystem->GetEntity(hitInfo.targetId);

#if defined(SERVER_CHECKS)

	if(damage != 0.0f)
	{
		int nNewCheckCounter = m_checkCounter + 1;
		
		if (CItem *pItem = static_cast<CItem *>(g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(hitInfo.weaponId)))
		{
			if(CWeapon * pWeapon = static_cast<CWeapon*>(pItem->GetIWeapon()))
			{
				int nFireModeFromShotId = GetFireModeFromShotId(hitInfo.shotId);

				static const int kCheckFreq = 7;

				if(pShooterActor &&	nNewCheckCounter == kCheckFreq)
				{
					float fDamageAtXMeters = 0.0f;

					float fDistance2D, fDistanceMax, fNetLagSeconds;
					CServerCheatMonitor::GetHitValidationInfo(*pShooterActor, hitInfo, fDistance2D, fDistanceMax, fNetLagSeconds);

					bool bDoDamageValidation = false;

					if(isMelee)
					{
						if(CMelee * pMelee = pWeapon->GetMelee())
						{
							//This check can't be used for everything because the default firemode returns '0.f' for range and only CMelee extends it
							//	the horizontal player speed is x 2.0f as the players could have potentially immediately turned and run away from each other
							float fMeleeRangeError = fDistance2D - (pMelee->GetRange() + (CServerCheatMonitor::kMaxHorizontalPlayerSpeed * fNetLagSeconds * 2.0f));
							if(fMeleeRangeError > 0.1f)
							{
								g_pGame->GetAntiCheatManager()->FlagActivity(eCT_MeleeRange, pShooterActor->GetChannelId(), fMeleeRangeError);
							}

							fDamageAtXMeters = pMelee->GetDamageAmountAtXMeters(fDistance2D);

							bDoDamageValidation = true;
						}
					}
					else
					{
						//////////////////////////////////////////////////////////////////////
						// Verify that the hit is from a valid shot

						DoShotValidation(hitInfo, pHitTypeInfo, pShooterActor);

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


						CFireMode * pFireMode = static_cast<CFireMode*>(pWeapon->GetFireMode(nFireModeFromShotId));

						if(pFireMode)
						{
							const SFireModeParams * pParams = pFireMode->GetShared();

							char projectileClassName[128];
							g_pGame->GetIGameFramework()->GetNetworkSafeClassName(projectileClassName, sizeof(projectileClassName), hitInfo.projectileClassId);
							IEntityClass * pProjectileClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(projectileClassName);

							if((pProjectileClass && (pProjectileClass == pParams->fireparams.ammo_type_class ||	pProjectileClass == pParams->plantparams.ammo_type_class)))
							{
								float fBulletSpeed = 100.f;
								const SAmmoParams * pAmmoParams = g_pGame->GetWeaponSystem()->GetAmmoParams(pFireMode->GetAmmoType());
								if(pAmmoParams)
								{
									fBulletSpeed = pAmmoParams->speed;
								}

								//Might have been closer when the shot was fired
								const float fMaxTimeSinceShot	= ((fDistanceMax / fBulletSpeed) * 2.0f) + fNetLagSeconds; //Should be less than this. Laaaaarge fudge factor
								float fDistance_Conservative	= fDistance2D - (fMaxTimeSinceShot * CServerCheatMonitor::kMaxHorizontalPlayerSpeed);

								fDamageAtXMeters = pFireMode->GetDamageAmountAtXMeters(fDistance_Conservative); 
							}
						}
						else if(pHitTypeInfo->m_flags & CGameRules::EHitTypeFlag::ValidationRequired)
						{
							CryStackStringT<char, 256> invalidFireModeMessage;
							invalidFireModeMessage.Format("Invalid fire mode, weapon: '%s', firemode: %d", pWeapon->GetEntity()->GetName(), nFireModeFromShotId);
							g_pGame->GetAntiCheatManager()->FlagActivity(eCT_ValidHitInfo, pShooterActor->GetChannelId(), invalidFireModeMessage.c_str());
						}
					}

					float fDamageFromWeapon = hitInfo.damage;			

					if(fDamageFromWeapon > fDamageAtXMeters && fDamageAtXMeters > 0.0f)
					{
						//Log the ratio of actual damage to expected damage, e.g. 1.2 x expected
						CryStackStringT<char, 256> excessiveDamageMessage;
						excessiveDamageMessage.Format("Weapon '%s', firemode %d", pWeapon->GetEntity()->GetName(), nFireModeFromShotId);
						g_pGame->GetAntiCheatManager()->FlagActivity(eCT_WeaponDamage, pShooterActor->GetChannelId(), fDamageFromWeapon / fDamageAtXMeters, excessiveDamageMessage.c_str());
					}


					if(pTargetActor)
					{
						CServerCheatMonitor::ValidateTargetActorPositionAgainstHit(*pTargetActor, hitInfo, fNetLagSeconds);
					}
					
					nNewCheckCounter = 0;
				}
				else
				{
					nNewCheckCounter = kCheckFreq - 1;
				}
			}
		}
		m_checkCounter = nNewCheckCounter;
	}

	// Update the shotcounter for tracking headshots and traversal times
	if(pShooterPlayer && (pHitTypeInfo->m_flags & CGameRules::EHitTypeFlag::ValidationRequired))
	{
		char netName[128];
		g_pGame->GetIGameFramework()->GetNetworkSafeClassName(netName, sizeof(netName), hitInfo.projectileClassId);
		IEntityClass * pProjectileClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(netName);
		if (pProjectileClass)
		{
			CShotCounter* pShotCounter = pShooterPlayer->GetShotCounter();
			pShotCounter->RecordHit(hitInfo, bIsHeadShot);
		}
	}
	
#endif // SERVER_CHECKS

	IEntityClass* pTargetClass = pTarget ? pTarget->GetClass() : NULL;

	// Check for friendly fire
	if( bool bCheckFriendlyFire = ((hitInfo.targetId!=hitInfo.shooterId) && (hitInfo.type!=CGameRules::EHitType::EventDamage)) )
	{
		if(IVehicle* pTargetVehicle = g_pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(hitInfo.targetId))
		{
			if(IActor* pDriverTargetVehicle = pTargetVehicle->GetDriver())
			{
				// Vehicle driver shot own vehicle (same as shooting yourself), don't do friendly fire.
				bCheckFriendlyFire = pDriverTargetVehicle->GetEntityId()!=hitInfo.shooterId;
			}
		}
		if(bCheckFriendlyFire)
		{
			if (m_pGameRules->GetTeamCount() > 1)
			{
				int shooterTeamId = m_pGameRules->GetTeam(hitInfo.shooterId);
				int targetTeamId = m_pGameRules->GetTeam(hitInfo.targetId);

				if (shooterTeamId && (shooterTeamId == targetTeamId))
				{
					damage = GetFriendlyFireDamage(damage, hitInfo, pTargetActor);
				}
			}
		}
	}

	if (damage <= 0.f)
	{
		// If the hit isn't doing anything bail, this means any hit that gets past here has damage associated with it and thus wants to
		// display a hit indicator
		return false;
	}

	if (pPlayer)
	{
		if(hitInfo.partId >= 0 && !isMelee)
		{
			damageHandling.damageMultiplier *= pPlayer->GetBodyDamageMultiplier(hitInfo);
		}

		if (isMelee)
		{
			damageHandling.damageMultiplier *= g_pGameCVars->pl_melee.damage_multiplier_mp;
		}
	}

	damage *= damageHandling.damageMultiplier;

	HitInfo hitInfoWithDamage = hitInfo;
	hitInfoWithDamage.damage = damage;

	if(pPlayer)
	{
		SActorStats* pStats = pPlayer->GetActorStats();
		float actorHealth = pPlayer->GetHealth();

		if(pStats)
		{
#ifndef _RELEASE
			if (g_pGameCVars->g_LogDamage)
			{
				char weaponClassName[64], projectileClassName[64];

				CryLog ("[DAMAGE] %s '%s' took %.3f '%s' damage (%.3f x %.3f) weapon=%s projectile=%s",
						pPlayer->GetEntity()->GetClass()->GetName(), pPlayer->GetEntity()->GetName(),
						damage, m_pGameRules->GetHitType(hitInfo.type),
						hitInfo.damage, damageHandling.damageMultiplier,
						g_pGame->GetIGameFramework()->GetNetworkSafeClassName(weaponClassName, sizeof(weaponClassName), hitInfo.weaponClassId) ? weaponClassName : "none",
						g_pGame->GetIGameFramework()->GetNetworkSafeClassName(projectileClassName, sizeof(projectileClassName), hitInfo.projectileClassId) ? projectileClassName : "none");
			}
#endif

			if(pStats->bStealthKilling && actorHealth <= damage)
			{
				if(pPlayer->GetStealthKill().GetTargetId() != hitInfoWithDamage.shooterId)
				{
					pPlayer->StoreDelayedKillingHitInfo(hitInfoWithDamage);
				}
				
				hitInfoWithDamage.damage = 0;
			}
			else if (pStats->bStealthKilled && hitInfoWithDamage.type != CGameRules::EHitType::StealthKill)
			{
				hitInfoWithDamage.damage = 0;
			}
		}
	}
		
	bool bKilled = SvOnHitScaled(hitInfoWithDamage);

	return bKilled;
}
Ejemplo n.º 19
0
//
//-----------------------------------------------------------------------------------------------------------
// (MATT) Moved here from Scriptbind_AI when that was moved to the AI system {2008/02/15:15:23:16}
int CScriptBind_Action::RegisterWithAI(IFunctionHandler *pH)
{
	if (gEnv->bMultiplayer && !gEnv->bServer)
		return pH->EndFunction();

	int type;
	ScriptHandle hdl;

	if (!pH->GetParams(hdl, type))
		return pH->EndFunction();

	EntityId entityID = (EntityId)hdl.n;
	IEntity *pEntity = gEnv->pEntitySystem->GetEntity(entityID);

	if(!pEntity)
	{
		GameWarning("RegisterWithAI: Tried to set register with AI nonExisting entity with id [%d]. ", entityID);
		return pH->EndFunction();
	}

	// Apparently we can't assume that there is just one IGameObject to an entity, because we choose between (at least) Actor and Vehicle objects.
	// (MATT) Do we really need to check on the actor system here? {2008/02/15:18:38:34}
	IGameFramework *pGameFramework = gEnv->pGame->GetIGameFramework();
	IVehicleSystem*	pVSystem = pGameFramework->GetIVehicleSystem();
	IActorSystem*	pASystem = pGameFramework->GetIActorSystem();
	if(!pASystem)
	{
		GameWarning("RegisterWithAI: no ActorSystem for %s.", pEntity->GetName());
		return pH->EndFunction();
	}

	AIObjectParams params(type, 0, entityID);
	bool autoDisable(true);

	// For most types, we need to parse the tables
	// For others we leave them blank
	switch (type)
	{
	case AIOBJECT_ACTOR:
	case AIOBJECT_2D_FLY:
	case AIOBJECT_BOAT:
	case AIOBJECT_CAR:
	case AIOBJECT_HELICOPTER:
	
	case AIOBJECT_INFECTED:
	case AIOBJECT_ALIENTICK:
	
	case AIOBJECT_HELICOPTERCRYSIS2:
		if(gEnv->pAISystem && ! gEnv->pAISystem->ParseTables(3, true, pH, params, autoDisable))
			return pH->EndFunction();
	default:;
	}

	// Most types check these, so just get them in advance
	IActor*	pActor = pASystem->GetActor( pEntity->GetId() );

	IVehicle*	pVehicle = NULL;
	if( pVSystem )
		pVehicle = pVSystem->GetVehicle( pEntity->GetId() );

	// Set this if we've found something to create a proxy from
	IGameObject* pGameObject = NULL;

	switch(type)
	{
	case AIOBJECT_ACTOR:
	case AIOBJECT_2D_FLY:
	
	case AIOBJECT_INFECTED:
	case AIOBJECT_ALIENTICK:
	
		{
			// (MATT) The pActor/pVehicle test below - is it basically trying to distiguish between the two cases above? If so, separate them! {2008/02/15:19:38:08}
			if(!pActor)
			{
				GameWarning("RegisterWithAI: no Actor for %s.", pEntity->GetName());
				return pH->EndFunction(); 
			}
			pGameObject = pActor->GetGameObject();
		}
		break;
	case AIOBJECT_BOAT:
	case AIOBJECT_CAR:
		{
			if(!pVehicle)
			{
				GameWarning("RegisterWithAI: no Vehicle for %s (Id %i).", pEntity->GetName(), pEntity->GetId());
				return pH->EndFunction(); 
			}
			pGameObject = pVehicle->GetGameObject();
		}
		break;

	case AIOBJECT_HELICOPTER:
	case AIOBJECT_HELICOPTERCRYSIS2:
		{
			if(!pVehicle)
			{
				GameWarning("RegisterWithAI: no Vehicle for %s (Id %i).", pEntity->GetName(), pEntity->GetId());
				return pH->EndFunction(); 
			}
			pGameObject = pVehicle->GetGameObject();
			params.m_moveAbility.b3DMove = true;
		}
		break;
	case AIOBJECT_PLAYER:
		{
			if(IsDemoPlayback())
				return pH->EndFunction();

			SmartScriptTable pTable;

			if (pH->GetParamCount() > 2)
				pH->GetParam(3,pTable);
			else
				return pH->EndFunction();

			pGameObject = pActor->GetGameObject();

			pTable->GetValue("groupid",params.m_sParamStruct.m_nGroup);       

			const char* faction = 0;
			if (pTable->GetValue("esFaction", faction) && gEnv->pAISystem)
			{
				params.m_sParamStruct.factionID = gEnv->pAISystem->GetFactionMap().GetFactionID(faction);
				if (faction && *faction && (params.m_sParamStruct.factionID == IFactionMap::InvalidFactionID))
				{
					GameWarning("Unknown faction '%s' being set...", faction);
				}
			}
			else
			{
				// Márcio: backwards compatibility
				int species = -1;
				if (!pTable->GetValue("eiSpecies", species))
					pTable->GetValue("species", species);

				if (species > -1)
					params.m_sParamStruct.factionID = species;
			}

			pTable->GetValue("commrange",params.m_sParamStruct.m_fCommRange); //Luciano - added to use GROUPONLY signals

			SmartScriptTable pPerceptionTable;
			if(pTable->GetValue("Perception",pPerceptionTable))
			{
				pPerceptionTable->GetValue( "sightrange", params.m_sParamStruct.m_PerceptionParams.sightRange);
			}
		}
		break;
	case AIOBJECT_SNDSUPRESSOR:
		{
			// (MATT) This doesn't need a proxy? {2008/02/15:19:45:58}
			SmartScriptTable pTable;
			// Properties table
			if (pH->GetParamCount() > 2)
				pH->GetParam(3,pTable);
			else
				return pH->EndFunction();
			if (!pTable->GetValue("radius",params.m_moveAbility.pathRadius))
				params.m_moveAbility.pathRadius = 10.f;
			break;
		}
	case AIOBJECT_WAYPOINT:
		break;
		/*
		// this block is commented out since params.m_sParamStruct is currently ignored in pEntity->RegisterInAISystem()
		// instead of setting the group id here, it will be set from the script right after registering
		default:
		// try to get groupid settings for anchors
		params.m_sParamStruct.m_nGroup = -1;
		params.m_sParamStruct.m_nSpecies = -1;
		{
		SmartScriptTable pTable;
		if ( pH->GetParamCount() > 2 )
		pH->GetParam( 3, pTable );
		if ( *pTable )
		pTable->GetValue( "groupid", params.m_sParamStruct.m_nGroup );
		}
		break;
		*/
	}

	// Remove any existing AI object
	pEntity->RegisterInAISystem(AIObjectParams(0));
 
	// Register in AI to get a new AI object, deregistering the old one in the process
	pEntity->RegisterInAISystem(params);

	// (MATT) ? {2008/02/15:19:46:29}
	// AI object was not created (possibly AI System is disabled)
	if (IAIObject* aiObject = pEntity->GetAI())
	{
		if(type==AIOBJECT_SNDSUPRESSOR)
			aiObject->SetRadius(params.m_moveAbility.pathRadius);
		else if(type>=AIANCHOR_FIRST)	// if anchor - set radius
		{
			SmartScriptTable pTable;
			// Properties table
			if (pH->GetParamCount() > 2)
				pH->GetParam(3,pTable);
			else
				return pH->EndFunction();
			float radius(0.f);
			pTable->GetValue("radius",radius);
			int groupId = -1;
			pTable->GetValue("groupid", groupId);
			aiObject->SetGroupId(groupId);
			aiObject->SetRadius(radius);
		}

		if (IAIActorProxy* proxy = aiObject->GetProxy())
			proxy->UpdateMeAlways(!autoDisable);
	}

	return pH->EndFunction();
}
Ejemplo n.º 20
0
//------------------------------------------------------------------------
void CDebugGun::Update( SEntityUpdateContext& ctx, int update)
{ 
  if (!IsSelected())
    return;
  
  static float drawColor[4] = {1,1,1,1};
  static const int dx = 5; 
  static const int dy = 15;
  static const float font = 1.2f;
  static const float fontLarge = 1.4f;

  IRenderer* pRenderer = gEnv->pRenderer;
  IRenderAuxGeom* pAuxGeom = pRenderer->GetIRenderAuxGeom();
  pAuxGeom->SetRenderFlags(e_Def3DPublicRenderflags);

  pRenderer->Draw2dLabel(pRenderer->GetWidth()/5.f, pRenderer->GetHeight()-35, fontLarge, drawColor, false, "Firemode: %s (%.1f)", m_fireModes[m_fireMode].first.c_str(), m_fireModes[m_fireMode].second);      

  ray_hit rayhit;
  int hits = 0;
  
  unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any;
  if (m_fireModes[m_fireMode].first == "pierceability")
  { 
    flags = (unsigned int)m_fireModes[m_fireMode].second & rwi_pierceability_mask;
  }
  
  // use cam, no need for firing pos/dir
  CCamera& cam = GetISystem()->GetViewCamera();

  if (hits = gEnv->pPhysicalWorld->RayWorldIntersection(cam.GetPosition()+cam.GetViewdir(), cam.GetViewdir()*HIT_RANGE, ent_all, flags, &rayhit, 1))
  {
    IMaterialManager* pMatMan = gEnv->p3DEngine->GetMaterialManager();
    IActorSystem* pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem();
    IVehicleSystem* pVehicleSystem = g_pGame->GetIGameFramework()->GetIVehicleSystem();
    
    int x = (int)(pRenderer->GetWidth() *0.5f) + dx;
    int y = (int)(pRenderer->GetHeight()*0.5f) + dx - dy;

    // draw normal
    ColorB colNormal(200,0,0,128);
    Vec3 end = rayhit.pt + 0.75f*rayhit.n;
    pAuxGeom->DrawLine(rayhit.pt, colNormal, end, colNormal);
    pAuxGeom->DrawCone(end, rayhit.n, 0.1f, 0.2f, colNormal);

    IEntity * pEntity = (IEntity*)rayhit.pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY);
    if(pEntity)
    {  
      pRenderer->Draw2dLabel(x, y+=dy, fontLarge, drawColor, false, pEntity->GetName());      
    }
    
    // material
    const char* matName = pMatMan->GetSurfaceType(rayhit.surface_idx)->GetName();

    if (matName[0])      
      pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%s (%i)", matName, rayhit.surface_idx);

    pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.1f m", rayhit.dist);

    if (pEntity)
    {
      IScriptTable* pScriptTable = pEntity->GetScriptTable();

      // physics 
      if (IPhysicalEntity* pPhysEnt = pEntity->GetPhysics())
      {
        pe_status_dynamics status;
        if (pPhysEnt->GetStatus(&status))
        {        
          if (status.mass > 0.f)
            pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.1f kg", status.mass);

          pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "pe_type: %i", pPhysEnt->GetType());                

          if (status.submergedFraction > 0.f)
            pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.2f submerged", status.submergedFraction);

          if (status.v.len2() > 0.0001f)
            pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.2f m/s", status.v.len());
        }   
      }  

      if (pScriptTable)
      {
        HSCRIPTFUNCTION func = 0;
        if (pScriptTable->GetValue("GetFrozenAmount", func) && func)
        {
          float frozen = 0.f;
          Script::CallReturn(gEnv->pScriptSystem, func, pScriptTable, frozen);
					gEnv->pScriptSystem->ReleaseFunc(func);
          
          if (frozen > 0.f)
            pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "Frozen: %.2f", frozen); 
        }
      }
     
      // class-specific stuff
      if (IActor* pActor = pActorSystem->GetActor(pEntity->GetId()))
      {
        pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%i health", pActor->GetHealth());
      }
      else if (IVehicle* pVehicle = pVehicleSystem->GetVehicle(pEntity->GetId()))
      {
        const SVehicleStatus& status = pVehicle->GetStatus();
        
        pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.0f%% health", 100.f*status.health);
        pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%i passengers", status.passengerCount);
        
        if (pVehicle->GetMovement() && pVehicle->GetMovement()->IsPowered())
        {
          pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "Running");
        }
      }
      else
      {
        if (pScriptTable)
        {
          HSCRIPTFUNCTION func = 0;
          if (pScriptTable->GetValue("GetHealth", func) && func)
          {
            float health = 0.f;
            if (Script::CallReturn(gEnv->pScriptSystem, func, pScriptTable, health))
            {
              pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.0f health", health);
            }
						gEnv->pScriptSystem->ReleaseFunc(func);
          }
        }
      }
    }    
  }  
}