Пример #1
0
IMPLEMENT_RMI(CGameRules, ClEnteredGame)
{
	if(!gEnv->bServer && m_pGameFramework->GetClientActor())
	{
		CActor* pActor = GetActorByChannelId(m_pGameFramework->GetClientActor()->GetChannelId());
		if(pActor)
		{
			int status[2];
			status[0] = GetTeam(pActor->GetEntityId());
			status[1] = pActor->GetSpectatorMode();
			m_pGameplayRecorder->Event(pActor->GetEntity(), GameplayEvent(eGE_Connected, 0, 0, (void*)status));
		}
	}
	return true;
}
Пример #2
0
//------------------------------------------------------------------------
int CScriptBind_Actor::Fall(IFunctionHandler *pH, Vec3 hitPos)
{
	CActor *pActor = GetActor(pH);
	if (!pActor)
		return pH->EndFunction();

	// [Mikko] 11.10.2007 - Moved the check here, since it was causing too much trouble in CActor.Fall().
	// The point of this filtering is to mostly mask out self-induced collision damage on friendly NPCs
	// which are playing special animations.
	if(!g_pGameCVars->g_enableFriendlyFallAndPlay)
	{
		if (IAnimatedCharacter* pAC = pActor->GetAnimatedCharacter())
		{
			if ((pAC->GetPhysicalColliderMode() == eColliderMode_NonPushable) ||
				(pAC->GetPhysicalColliderMode() == eColliderMode_PushesPlayersOnly))
			{
				// Only mask for player friendly NPCs.
				if (pActor->GetEntity() && pActor->GetEntity()->GetAI())
				{
					IAIObject* pAI = pActor->GetEntity()->GetAI();
					IAIObject* playerAI = 0;
					if (IActor* pPlayerActor = m_pGameFW->GetClientActor())
						playerAI = pPlayerActor->GetEntity()->GetAI();

					if (playerAI 
						&& gEnv->pAISystem->GetFactionMap().GetReaction(playerAI->GetFactionID(), pAI->GetFactionID()) > IFactionMap::eRT_Hostile)
						return pH->EndFunction();
				}
			}
		}
	}

	pActor->Fall(hitPos);

	return pH->EndFunction();
}
Пример #3
0
void CFists::RaiseWeapon(bool raise, bool faster /*= false*/)
{
	//Only when colliding something while running
	if(raise && (GetCurrentAnimState()==eFAS_RUNNING || GetCurrentAnimState()==eFAS_JUMPING) && !IsWeaponRaised())
	{
		if((m_fm && m_fm->IsFiring())||(m_melee && m_melee->IsFiring()))
			return;

		PlayAction(g_pItemStrings->raise);

		SetDefaultIdleAnimation( eIGS_FirstPerson,g_pItemStrings->idle_relaxed);
		SetWeaponRaised(true);

		//Also give the player some impulse into the opposite direction
		CActor *pPlayer = GetOwnerActor();
		Vec3		pos;
		if(pPlayer)
		{
			IPhysicalEntity* playerPhysics = pPlayer->GetEntity()->GetPhysics();
			if(playerPhysics)
			{
				IMovementController *pMC = pPlayer->GetMovementController();
				if(pMC)
				{
					SMovementState state;
					pMC->GetMovementState(state);
					
					pe_action_impulse impulse;
					impulse.iApplyTime = 1;
					impulse.impulse = -state.eyeDirection*600.0f;
					playerPhysics->Action(&impulse);

					pos = state.eyePosition + state.eyeDirection*0.5f;
				}
				
			}
		}

		GetScheduler()->TimerAction(GetCurrentAnimationTime(eIGS_FirstPerson), CSchedulerAction<EndRaiseWeaponAction>::Create(EndRaiseWeaponAction(this)), true);

		//Sound and FX feedback
		CollisionFeeback(pos,m_currentAnimState);
	}
	else if(!raise)
		SetWeaponRaised(false);

}
void CMelee::OnFailedHit()
{
	const SCollisionTestParams& collisionParams = m_collisionHelper.GetCollisionTestParams();

	bool collided = PerformCylinderTest(collisionParams.m_pos, collisionParams.m_dir, collisionParams.m_remote);

	CActor* pOwner = m_pWeapon->GetOwnerActor();

	if(pOwner && pOwner->IsClient())
	{
		if(!collided && s_meleeSnapTargetId)
		{
			Vec3 ownerpos = pOwner->GetEntity()->GetWorldPos();
			IEntity* pTarget = gEnv->pEntitySystem->GetEntity(s_meleeSnapTargetId);

			if(pTarget && ownerpos.GetSquaredDistance(pTarget->GetWorldPos()) < cry_sqr(GetRange() * m_pMeleeParams->meleeparams.target_range_mult))
			{
				collided = m_collisionHelper.PerformMeleeOnAutoTarget(s_meleeSnapTargetId);
			}
		}

		s_meleeSnapTargetId = 0;
		CHANGED_NETWORK_STATE(pOwner, CPlayer::ASPECT_SNAP_TARGET);

		if(g_pGameCVars->pl_melee.mp_melee_system_camera_lock_and_turn)
		{
			pOwner->GetActorParams().viewLimits.ClearViewLimit(SViewLimitParams::eVLS_Item);
		}
	}

	if(m_pMeleeAction)
	{
		if(pOwner)
		{
			m_pMeleeAction->OnHitResult(pOwner, collided);
		}
		else
		{
			//Owner has dropped weapon (Likely from being killed) so we can stop and release the action
			m_pMeleeAction->ForceFinish();
			SAFE_RELEASE(m_pMeleeAction);
		}
	}
	
	ApplyMeleeEffects(collided);
}
Пример #5
0
//------------------------------------------------------------------------
int CScriptBind_Actor::AttachVulnerabilityEffect(IFunctionHandler *pH, int characterSlot, int partid, Vec3 hitPos, float radius, const char* effect, const char* attachmentIdentifier)
{
  CActor *pActor = GetActor(pH);  
	if (!pActor)
		return pH->EndFunction();

  IEntity* pEntity = pActor->GetEntity();
  ICharacterInstance* pChar = pEntity->GetCharacter(characterSlot);

  if (!pChar || !effect)  
    return pH->EndFunction();

  //fallback: use nearest attachment
  float minDiff = radius*radius;  
  IAttachment* pClosestAtt = 0;
  
  IAttachmentManager* pMan = pChar->GetIAttachmentManager();
  for (int i=0; i<pMan->GetAttachmentCount(); ++i)
  {
    IAttachment* pAtt = pMan->GetInterfaceByIndex(i);
    
    float diff = (hitPos - pAtt->GetAttWorldAbsolute().t).len2();        
    if (diff < minDiff)
    {
      // only use specified attachments 
      if (attachmentIdentifier[0] && !strstr(pAtt->GetName(), attachmentIdentifier))
        continue;

      minDiff = diff; 
      pClosestAtt = pAtt;      
    }   
    //CryLog("diff: %.2f, att: %s", diff, attName.c_str());
  }

  if (!pClosestAtt)
    return pH->EndFunction();

  //CryLog("AttachVulnerabilityEffect: closest att %s, attaching effect %s", pClosestAtt->GetName(), effect);
  
  CEffectAttachment *pEffectAttachment = new CEffectAttachment(effect, Vec3(ZERO), Vec3(0,1,0), 1.f);

  pClosestAtt->AddBinding(pEffectAttachment);
  pClosestAtt->HideAttachment(0);
  
  return pH->EndFunction(pClosestAtt->GetName());    
}
Пример #6
0
void CAutoAimManager::RegisterCharacterTargetInfo(const CActor& targetActor, const SAutoaimTargetRegisterParams& registerParams)
{
	SAutoaimTarget aimTarget;
	aimTarget.entityId = targetActor.GetEntityId();
	aimTarget.pActorWeak = targetActor.GetWeakPtr();
	aimTarget.fallbackOffset = registerParams.fallbackOffset;
	aimTarget.primaryBoneId = registerParams.primaryBoneId;
	aimTarget.physicsBoneId = registerParams.physicsBoneId;
	aimTarget.secondaryBoneId = registerParams.secondaryBoneId;
	aimTarget.innerRadius = registerParams.innerRadius;
	aimTarget.outerRadius = registerParams.outerRadius;
	aimTarget.snapRadius = registerParams.snapRadius;
	aimTarget.snapRadiusTagged = registerParams.snapRadiusTagged;

	if (!gEnv->bMultiplayer)
	{
		IEntity* pTargetEntity = targetActor.GetEntity();

		aimTarget.aiFaction = IFactionMap::InvalidFactionID;

		//Instance properties, other stuff could be added here easily (grab enemy, sliding hit, etc)
		SmartScriptTable props;
		SmartScriptTable propsPlayerInteractions;
		IScriptTable* pScriptTable = pTargetEntity->GetScriptTable();
		if (pScriptTable && pScriptTable->GetValue("Properties", props))
		{
			if (props->GetValue("PlayerInteractions", propsPlayerInteractions))
			{
				int stealhKill = 0;
				if (propsPlayerInteractions->GetValue("bStealthKill", stealhKill) && (stealhKill != 0))
				{
					aimTarget.SetFlag(eAATF_StealthKillable);
				}
				int canBeGrabbed = 0;
				if (propsPlayerInteractions->GetValue("bCanBeGrabbed", canBeGrabbed) && (canBeGrabbed != 0))
				{
					aimTarget.SetFlag(eAATF_CanBeGrabbed);
				}
			}
		}
	}

	m_autoaimTargets.push_back(aimTarget);
}
Пример #7
0
//------------------------------------------------------------------------
void CWeapon::OnShoot(EntityId shooterId, EntityId ammoId, IEntityClass *pAmmoType, const Vec3 &pos, const Vec3 &dir, const Vec3 &vel)
{
	BROADCAST_WEAPON_EVENT(OnShoot, (this, shooterId, ammoId, pAmmoType, pos, dir, vel));

	//FIXME:quick temporary solution
	CActor *pActor = static_cast<CActor *>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(shooterId));

	if(pActor)
		pActor->HandleEvent(SGameObjectEvent(eCGE_OnShoot,eGOEF_ToExtensions));

	IActor *pClientActor=m_pGameFramework->GetClientActor();

	if(pActor && pActor->GetActorClass() == CPlayer::GetActorClassType() && IsServer())
	{
		if(pActor == pClientActor)
		{
			if(IAIObject *pAIObject=pActor->GetEntity()->GetAI())
				gEnv->pAISystem->SendSignal(SIGNALFILTER_LEADER, 1, "OnEnableFire",	pAIObject, 0);
		}
	}

	if(pClientActor && m_fm && strcmp(m_fm->GetType(), "Thrown"))
	{
		// inform the HUDRadar about the sound event
		Vec3 vPlayerPos=pClientActor->GetEntity()->GetWorldPos();
		float fDist2=(vPlayerPos-pos).len2();

		if(fDist2<250.0f*250.0f)
		{
			//if (pClientActor->GetEntityId() != shooterId)
			//	pHUD->ShowSoundOnRadar(pos);

			if(gEnv->bMultiplayer)
			{
				CGameRules *pGameRules = g_pGame->GetGameRules();

			}

			if((!IsSilencerAttached()) && fDist2<sqr(SAFE_GAMEAUDIO_BATTLESTATUS_FUNC_RET(GetBattleRange())))
				SAFE_GAMEAUDIO_BATTLESTATUS_FUNC(TickBattleStatus(1.0f));
		}
	}
}
Пример #8
0
//------------------------------------------------------------------------
int CScriptBind_Actor::IsFlying(IFunctionHandler *pH)
{
	CActor *pActor = GetActor(pH);
	if (!pActor)
		return pH->EndFunction();

	if (pActor)
	{
		pe_status_living livStat;
		IPhysicalEntity *pPhysEnt = pActor->GetEntity()->GetPhysics();

		if (!pPhysEnt)
			return pH->EndFunction();

		if(pPhysEnt->GetStatus(&livStat))
			return pH->EndFunction(livStat.bFlying!=0);
	}

	return pH->EndFunction();
}
Пример #9
0
//------------------------------------------------------------------------
int CScriptBind_Actor::ResetVulnerabilityEffects(IFunctionHandler *pH, int characterSlot)
{
  CActor *pActor = GetActor(pH);  
	if (!pActor)
		return pH->EndFunction();

  IEntity* pEntity = pActor->GetEntity();

  ICharacterInstance* pChar = pEntity->GetCharacter(characterSlot);

  if (pChar)  
  {
    IAttachmentManager* pMan = pChar->GetIAttachmentManager();
    for (int i=0; i<pMan->GetAttachmentCount(); ++i)
    {
      IAttachment* pAtt = pMan->GetInterfaceByIndex(i);
      if (strstr(pAtt->GetName(), "vulnerable"))
        pAtt->ClearBinding();
    }
  }
  return pH->EndFunction();
}
Пример #10
0
//------------------------------------------------------------------------
void SSleepEffect::Activate(EntityId targetId, EntityId ownerId, EntityId weaponId, const char *effect, const char *defaultEffect)
{
	CActor *pActor = (CActor *)gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(targetId);
	
	if (pActor)
	{
		IAISystem *pAISystem=gEnv->pAISystem;
		if (pAISystem)
		{
			if(IEntity* pEntity=pActor->GetEntity())
			{
				if(IAIObject* pAIObj=pEntity->GetAI())
				{
					IAISignalExtraData *pEData = pAISystem->CreateSignalExtraData();	// no leak - this will be deleted inside SendAnonymousSignal
					// try to retrieve the shooter position
					if (IEntity* pOwnerEntity = gEnv->pEntitySystem->GetEntity(ownerId))
						pEData->point = pOwnerEntity->GetWorldPos();
					else
						pEData->point = pEntity->GetWorldPos();
					IAIActor* pAIActor = pAIObj->CastToIAIActor();
					if(pAIActor)
						pAIActor->SetSignal(1,"TRANQUILIZED",0,pEData);
				}
			}
		}

		pActor->CreateScriptEvent("sleep", 0);
		pActor->GetGameObject()->SetPhysicalizationProfile(eAP_Sleep);

		// no dropping weapons for AI
		if(pActor->IsPlayer())
			pActor->DropItem(pActor->GetCurrentItemId(), 1.0f, false);

		pActor->SetSleepTimer(12.5f);
	}
}
Пример #11
0
// returns true if firing is allowed
bool CPlant::GetPlantingParameters(Vec3& pos, Vec3& dir, Vec3& vel) const
{
	CActor *pActor = m_pWeapon->GetOwnerActor();
	IMovementController *pMC = pActor?pActor->GetMovementController():0;
	SMovementState info;
	if (pMC)
		pMC->GetMovementState(info);

	if (m_pWeapon->GetStats().fp)
		pos = m_pWeapon->GetSlotHelperPos( eIGS_FirstPerson, m_plantparams.helper.c_str(), true);
	else if (pMC)
		pos = info.eyePosition+info.eyeDirection*0.25f;
	else
		pos = pActor->GetEntity()->GetWorldPos();

	if (pMC)
		dir = info.eyeDirection;
	else
		dir = pActor->GetEntity()->GetWorldRotation().GetColumn1();

	if (IPhysicalEntity *pPE=pActor->GetEntity()->GetPhysics())
	{
		pe_status_dynamics sv;
		if (pPE->GetStatus(&sv))
		{
			if (sv.v.len2()>0.01f)
			{
				float dot=sv.v.GetNormalized().Dot(dir);
				if (dot<0.0f)
					dot=0.0f;
				vel=sv.v*dot;
			}
		}
	}

	// if the ammo should be placed (claymore/mine) rather than thrown forward (c4), check if we can do so...
	if(m_plantparams.place_on_ground)
	{
		ray_hit hit;
		static const int objTypes = ent_static | ent_terrain;
		static const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any;
		static IPhysicalEntity* pSkipEnts[10];
		int nskip = CSingle::GetSkipEntities(m_pWeapon, pSkipEnts, 10);
		int res = gEnv->pPhysicalWorld->RayWorldIntersection(pos, 2.0f * dir, objTypes, flags, &hit, 1, pSkipEnts, nskip);
		if(!res)
			return false;
		else
		{
			// check surface normal - must be close to up
			if(hit.n.z < 0.8f)
				return false;

 			// special case to stop stacking of claymores/mines (they are static so are hit by the ray)
 			if(hit.pCollider && hit.pCollider->GetiForeignData() == PHYS_FOREIGN_ID_ENTITY)
			{
				IEntity * pEntity = (IEntity*)hit.pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY);
				if(pEntity)
				{
					if(!m_pClaymoreClass)
						m_pClaymoreClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("claymoreexplosive");
					if(!m_pAVMineClass)
						m_pAVMineClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("avexplosive");

					if(pEntity->GetClass() == m_pClaymoreClass || pEntity->GetClass() == m_pAVMineClass)
						return false;
				}
 			}

			// second check to see if there is another object in the way
			float hitDist = hit.dist;
			int res = gEnv->pPhysicalWorld->RayWorldIntersection(pos, 2.0f * dir, ent_all, flags, &hit, 1, pSkipEnts, nskip);
			if(res && hit.dist < hitDist-0.1f)
			{
				return false;
			}

			pos = hit.pt;
		}
	}

	return true;
}
Пример #12
0
//------------------------------------------------------------------------
void CMelee::Hit(const Vec3 &pt, const Vec3 &dir, const Vec3 &normal, IPhysicalEntity *pCollider, int partId, int ipart, int surfaceIdx, float damageScale, bool remote)
{
	// generate the damage
	IEntity *pTarget = gEnv->pEntitySystem->GetEntityFromPhysics(pCollider);
	// Report punch to AI system.
	// The AI notification must come before the game rules are
	// called so that the death handler in AIsystem understands that the hit
	// came from the player.
	bool ok = true;

	if(pTarget)
	{
		CActor *pActor = m_pWeapon->GetOwnerActor();

		if(!gEnv->bMultiplayer && pActor && pActor->IsPlayer())
		{
			if (IActor *pAITarget = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTarget->GetId()))
			{
				if (IAIObject *pAITargetObject = pTarget->GetAI())
				{
					if (pAITargetObject->IsFriendly(pActor->GetEntity()->GetAI(), false))
					{
						ok = false;
						m_noImpulse = true;
					}
				}
			}
		}

		if(ok)
		{
			CGameRules *pGameRules = g_pGame->GetGameRules();
			HitInfo info(m_pWeapon->GetOwnerId(), pTarget->GetId(), m_pWeapon->GetEntityId(),
						 m_pShared->meleeparams.damage * damageScale * m_meleeScale, 0.0f, pGameRules->GetHitMaterialIdFromSurfaceId(surfaceIdx), partId,
						 pGameRules->GetHitTypeId(m_pShared->meleeparams.hit_type.c_str()), pt, dir, normal);
			info.remote = remote;
			pGameRules->ClientHit(info);
		}
	}

	// play effects
	if(ok)
	{
		if(IMaterialEffects *pMaterialEffects = gEnv->pGame->GetIGameFramework()->GetIMaterialEffects())
		{
			TMFXEffectId effectId = pMaterialEffects->GetEffectId("melee", surfaceIdx);

			if (effectId != InvalidEffectId)
			{
				SMFXRunTimeEffectParams params;
				params.pos = pt;
				params.normal = -dir;
				params.playflags = MFX_PLAY_ALL | MFX_DISABLE_DELAY;
				params.soundSemantic = eSoundSemantic_Player_Foley;
				pMaterialEffects->ExecuteEffect(effectId, params);
			}
		}
	}

	ApplyCameraShake(true);
	m_pWeapon->PlayAction(m_pShared->meleeactions.hit.c_str());
}
Пример #13
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;
}
void CAIAwarenessToPlayerHelper::RecalculateAwareness()
{
	int highestAlertnessInGameRightNow = 0;

	float distanceToTheClosestHostileAgentSq = FLT_MAX;
	Vec3 playerPosition(ZERO);

	const IFactionMap& factionMap = gEnv->pAISystem->GetFactionMap();
	uint8 playerFactionID = factionMap.GetFactionID("Players");

	IAIObject* playerAiObject = NULL;
	CActor* playerActor = static_cast<CActor*>(gEnv->pGame->GetIGameFramework()->GetClientActor());

	if (playerActor)
	{
		if (IEntity* playerEntity = playerActor->GetEntity())
		{
			playerPosition = playerEntity->GetWorldPos();
			playerAiObject = playerEntity->GetAI();
		}
	}

	IF_UNLIKELY ((playerActor == NULL) || (playerAiObject == NULL))
		return;

	const bool playerIsCloaked = playerActor ? playerActor->IsCloaked() : true;

	const bool applyProximityToHostileAgentIncrement = m_actualAwareness < kAIAwarenessToPlayerAware && !playerPosition.IsZero();

	// Go through actors
	IActorIteratorPtr actorIt = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->CreateActorIterator();
	if (actorIt)
	{
		while (IActor* actor = actorIt->Next())
		{
			const IAIObject* ai = actor->GetEntity()->GetAI();
			const IAIActor* aiActor = ai ? ai->CastToIAIActor() : NULL;
			if (aiActor && aiActor->IsActive())
			{
				const int alertness = GetAlertnessAffectedByVisibility(*aiActor, *playerAiObject, playerIsCloaked);

				highestAlertnessInGameRightNow = std::max(alertness, highestAlertnessInGameRightNow);

				if (applyProximityToHostileAgentIncrement && 
					factionMap.GetReaction(playerFactionID, ai->GetFactionID()) == IFactionMap::Hostile)
				{
					float distanceSq = playerPosition.GetSquaredDistance(ai->GetPos());
					if (distanceToTheClosestHostileAgentSq > distanceSq)
					{
						distanceToTheClosestHostileAgentSq = distanceSq;
					}
				}
			}
		}
	}

	// Go through non Actors
	{
		SAwarenessEntitiesVector::iterator it = m_awarenessEntities.begin();
		SAwarenessEntitiesVector::iterator end = m_awarenessEntities.end();

		for (; it != end; ++it)
		{
			const IAwarenessEntity* pAwarenessEntity = *it;
			const int awareness = pAwarenessEntity->GetAwarenessToActor( playerAiObject, playerActor );
			highestAlertnessInGameRightNow = std::max(awareness, highestAlertnessInGameRightNow);
		}
	}


	///
	assert(highestAlertnessInGameRightNow >= 0 && highestAlertnessInGameRightNow <= 2);

	switch (highestAlertnessInGameRightNow)
	{
	default: 
		{
			const float thresholdDistanceSq = square(g_pGameCVars->ai_ProximityToHostileAlertnessIncrementThresholdDistance);
			if (applyProximityToHostileAgentIncrement && distanceToTheClosestHostileAgentSq < thresholdDistanceSq)
			{
				m_actualAwareness = kAIAwarenessToPlayerAware * (1 - (distanceToTheClosestHostileAgentSq / thresholdDistanceSq));
			}
			else
			{
				m_actualAwareness = 0.0f;
			}
		}
		break;
	case 1:  m_actualAwareness = kAIAwarenessToPlayerAware;  break;
	case 2:  m_actualAwareness = kAIAwarenessToPlayerAlerted; break;
	}
}
Пример #15
0
void CHandGrenades::UpdateStowedWeapons()
{
	CActor *pOwnerActor = GetOwnerActor();
	if (!pOwnerActor)
		return;

	ICharacterInstance *pOwnerCharacter = pOwnerActor->GetEntity()->GetCharacter(0);
	if (!pOwnerCharacter)
		return;

	IStatObj *pTPObj = GetEntity()->GetStatObj(eIGS_ThirdPerson);
	if (!pTPObj)
		return;


	int ammoCount = m_fm ? pOwnerActor->GetInventory()->GetAmmoCount(m_fm->GetAmmoType()) : 0;
	if (IsSelected() && (ammoCount > 0))
	{
		ammoCount--;
	}
	if (!pOwnerActor->IsThirdPerson())
	{
		ammoCount = 0;
	}

	int numGrenDiff = ammoCount - m_numStowedCopies;
	if(numGrenDiff != 0)
	{
		if (m_stowSlot < 0)
		{
			m_stowSlot = PickStowSlot(pOwnerCharacter->GetIAttachmentManager(), m_sharedparams->params.bone_attachment_01.c_str(), m_sharedparams->params.bone_attachment_02.c_str());
		}

		if (m_stowSlot >= 0)
		{
			bool attach = numGrenDiff > 0;
			int tot = abs(numGrenDiff);

			IAttachmentManager *pAttachmentManager = pOwnerCharacter->GetIAttachmentManager();
			IAttachment *pAttachment = NULL;

			for (int i=0; i<tot; i++)
			{
				//--- Generate the secondary slot from the first by adding one to the attachment name, is all we need at present...
				const char *attach1 = (m_stowSlot == 0) ? m_sharedparams->params.bone_attachment_01.c_str() : m_sharedparams->params.bone_attachment_02.c_str();
				int lenAttachName = strlen(attach1);
				stack_string attach2(attach1, lenAttachName-1);
				attach2 += (attach1[lenAttachName-1]+1);

				if (attach)
				{
					pAttachment = pAttachmentManager->GetInterfaceByName(attach1);
					if(pAttachment && pAttachment->GetIAttachmentObject())
					{
						pAttachment = pAttachmentManager->GetInterfaceByName(attach2);
					}

					if (pAttachment && !pAttachment->GetIAttachmentObject())
					{
						CCGFAttachment *pCGFAttachment = new CCGFAttachment();
						pCGFAttachment->pObj = pTPObj;
						pAttachment->AddBinding(pCGFAttachment);
						pAttachment->HideAttachment(0);
						pAttachment->HideInShadow(0);

						m_numStowedCopies++;
					}
				}
				else
				{
					pAttachment = pAttachmentManager->GetInterfaceByName(attach2);
					if(!pAttachment || !pAttachment->GetIAttachmentObject())
					{
						pAttachment = pAttachmentManager->GetInterfaceByName(attach1);
					}

					if (pAttachment && pAttachment->GetIAttachmentObject())
					{
						pAttachment->ClearBinding();
						m_numStowedCopies--;					
					}
				}
			}
		}
	}
}
Пример #16
0
void CGameStateRecorder::OnGameplayEvent(IEntity *pEntity, const GameplayEvent &event)
{
	EntityId id;
	if(!pEntity || !(id = pEntity->GetId()))
	{
		GameWarning("TimeDemo:GameState::OnGamePlayEvent: Entity not found");
		return;
	}
	CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id));
	if(!pActor)
	{
		GameWarning("TimeDemo:GameState::OnGamePlayEvent: Entity %s has no actor", pEntity->GetName());
		return;
	}

	GameplayEvent  event2 = event;
	event2.extra = 0;// event2 is the forwarded event, extra either will be not used by the listener or re-set as a string
	uint8 eType = event.event;

	bool bPlayer = (pActor->IsPlayer() && m_mode);
	if(bPlayer || m_mode==GPM_AllActors)
	{
		//items
		switch(eType)
		{
			case eGE_ItemPickedUp:
				{
					CheckInventory(pActor,0);//,*m_pRecordGameEventFtor);
				}
				break;

			case eGE_ItemDropped:
				{
					TItemName itemName = GetItemName(EntityId(event.extra));
					if(!itemName ) //if(itemIdx < 0)
						break;
					event2.description = itemName;
					SendGamePlayEvent(pEntity,event2);
					IEntity* pItemEntity = gEnv->pEntitySystem->FindEntityByName(itemName);
					if(!pItemEntity)
						break;
					IItem* pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pItemEntity->GetId());
					if(!pItem)
						break;

					IEntityClass* pItemClass = pItem->GetEntity()->GetClass();
					if(pItemClass && !strcmpi(pItemClass->GetName(),"SOCOM"))
					{
						IItem* pCurrentItem = pActor->GetCurrentItem();
						if(pCurrentItem)
						{
							IEntityClass* pCurrentItemClass = pCurrentItem->GetEntity()->GetClass();
							if(pCurrentItemClass && !strcmpi(pCurrentItemClass->GetName(),"SOCOM"))
							{
								GameplayEvent event3;
								event3.event = eGE_ItemSelected;
								TItemName itemName = GetItemName(pCurrentItem->GetEntity()->GetId());
								if(!itemName)
									break;
								event3.value = 0;
								event3.description = (const char*)itemName;
								SendGamePlayEvent(pEntity,event3);
							}
						}
					}
				}
				break;

			case eGE_WeaponFireModeChanged:
				{
					TItemName itemIdx = GetItemName(EntityId(event.extra));
					if(!itemIdx)//if(itemIdx < 0)
						break;
					event2.description = (const char*)itemIdx;
					SendGamePlayEvent(pEntity,event2);
				}
				break;

			case eGE_ItemSelected:
				{
					EntityId itemId = EntityId(event.extra);
					TItemName itemIdx = GetItemName(itemId);
					if(itemId && !itemIdx)
						break;
					event2.value = 0;
					event2.description = (const char*)itemIdx;
					SendGamePlayEvent(pEntity,event2);
				}
				break;

			case eGE_AttachedAccessory:
				{
					if(!IsGrenade(event.description)) // NOT OffHandGrenade
						SendGamePlayEvent(pEntity,event2);
				}
				break;

			case eGE_AmmoCount:
				{
					const char* itemIdx = event.description;
					if(!itemIdx)
						break;

					TGameStates::iterator itGS;
					/*if(pActor->IsPlayer())
						itGS = m_itSingleActorGameState;
					else */if(pActor->GetEntity())
						itGS = m_GameStates.find(pActor->GetEntity()->GetId());
					else
						break;

					if(itGS == m_GameStates.end())
						break;

					SActorGameState& gstate = itGS->second;

					IEntity* pItemEntity = gEnv->pEntitySystem->FindEntityByName(itemIdx);
					if(!pItemEntity)
						break;
					IItem* pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pItemEntity->GetId());
					if(!pItem)
						break;

					CWeapon* pWeapon = (CWeapon*)(pItem->GetIWeapon());
					if(pWeapon && pWeapon->GetEntity())
					{
						TItemContainer::iterator it = gstate.Items.find(itemIdx);
						if(it==gstate.Items.end())
							break;
						SItemProperties& recItem = it->second;
						
						SWeaponAmmo weaponAmmo = pWeapon->GetFirstAmmo();
						bool bGrenade = false;
						if(!weaponAmmo.pAmmoClass)
						{
							// special case for grenades
							if(IsAmmoGrenade((const char*)(event.extra)))
							{
								weaponAmmo.pAmmoClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass((const char*)event.extra);
								weaponAmmo.count = (int)event.value;
								bGrenade = true;
							}
						}
						
						for(; weaponAmmo.pAmmoClass ; weaponAmmo = pWeapon->GetNextAmmo())
						{
							int ammoCount = weaponAmmo.count;
							const char* ammoClass;
							if(weaponAmmo.pAmmoClass && (ammoClass = weaponAmmo.pAmmoClass->GetName()))
							{
								TAmmoContainer& recAmmo = bGrenade? gstate.AmmoMags : recItem.Ammo;
								if(recAmmo.find(ammoClass) == recAmmo.end())
									recAmmo.insert(std::make_pair(ammoClass,0));
								if(ammoCount != recAmmo[ammoClass])
								{
									event2.event = eGE_AmmoCount;
									event2.value = (float)ammoCount;
									if(event2.value < 0)
										event2.value = 0;
									event2.extra = (void*)ammoClass;
									event2.description = (const char*)itemIdx;
									SendGamePlayEvent(pEntity,event2);
								}
							}
						}
					}

				}
				break;

			case eGE_EntityGrabbed:
				{
					EntityId entityId = EntityId(event.extra);
					IEntity * pGrabbedEntity = gEnv->pEntitySystem->GetEntity(entityId);
					if(pGrabbedEntity)
					{
						event2.description = pGrabbedEntity->GetName();
						SendGamePlayEvent(pEntity,event2);
					}
				}
				break;

			case eGE_WeaponReload:
			case eGE_ZoomedIn:
			case eGE_ZoomedOut:			
			case eGE_HealthChanged:
			case eGE_ItemExchanged:
				SendGamePlayEvent(pEntity,event2);
				break;

			default:
				break;
		}

	}
}
Пример #17
0
//------------------------------------------------------------------------
int CScriptBind_Actor::SetNanoSuitMode(IFunctionHandler *pH, int mode)
{
	CActor *pActor = GetActor(pH);
	if (!pActor)
		return pH->EndFunction();
	if(mode<0 || mode>=NANOMODE_LAST)
		return pH->EndFunction();
	if(pActor->GetActorClass() != CPlayer::GetActorClassType())
		return pH->EndFunction();

	if(CNanoSuit *pSuit = ((CPlayer*)pActor)->GetNanoSuit())
		pSuit->SetMode((ENanoMode)mode);
	else
		GameWarning("Lua tried to set NanoMode on not activated/existing Nanosuit of Player %s!", pActor->GetEntity()->GetName());

	return pH->EndFunction();
}
Пример #18
0
void CFlashLight::EnableLight(bool enable)
{
	CWeapon* pWeapon = GetWeapon();

	if (!pWeapon || !m_sharedparams->pFlashLightParams || (m_lightEnabled && enable) || (!m_lightEnabled && !enable))
	{
		return;
	}

	CActor* pOwner = pWeapon->GetOwnerActor();
	bool ownerIsFP = pWeapon->IsOwnerFP();
	int slot = ownerIsFP ? eIGS_FirstPerson : eIGS_ThirdPerson;

	if (enable)
	{
		const char* attachHelper = "light_term";
		const Vec3 direction = Vec3(-1.0f, 0.0f, 0.0f);

		IRenderNode* pCasterException = NULL;

		if (pOwner)
		{
			IComponentRender* pRenderProxy = static_cast<IComponentRender*>(pOwner->GetEntity()->GetComponent<IComponentRender>().get());

			if (pRenderProxy)
			{
				pCasterException = pRenderProxy->GetRenderNode();
			}
		}

		EntityEffects::SLightAttachParams lightParams;

		lightParams.pCasterException = pCasterException;
		lightParams.color = m_sharedparams->pFlashLightParams->color * m_sharedparams->pFlashLightParams->diffuseMult;
		lightParams.direction = direction;
		lightParams.radius = m_sharedparams->pFlashLightParams->distance;
		lightParams.specularMultiplier = m_sharedparams->pFlashLightParams->specularMult;
		lightParams.projectFov = m_sharedparams->pFlashLightParams->fov;
		lightParams.hdrDynamic = m_sharedparams->pFlashLightParams->HDRDynamic;
		lightParams.projectTexture = m_sharedparams->pFlashLightParams->lightCookie.c_str();
		lightParams.style = m_sharedparams->pFlashLightParams->style;
		lightParams.animSpeed = m_sharedparams->pFlashLightParams->animSpeed;
		lightParams.castShadows = g_pGameCVars->i_flashlight_has_shadows != 0;
		lightParams.firstSafeSlot = eIGS_Last;

		m_lightId = pWeapon->AttachLight(slot, attachHelper, lightParams);

		EnableFogVolume(pWeapon, slot, true);
	}
	else
	{
		if (m_lightId)
		{
			pWeapon->DetachEffect(m_lightId);
		}

		m_lightId = 0;
		EnableFogVolume(pWeapon, slot, false);
	}

	m_lightEnabled = enable;
}
Пример #19
0
void CPlayerView::ViewSpectatorTarget(SViewParams &viewParams)
{
	CActor* pTarget = (CActor*)g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.stats_spectatorTarget);
	if(!pTarget)
		return;

	IVehicle* pVehicle = pTarget->GetLinkedVehicle();

	static float defaultOffset = 0.3f;
	static float viewHeight = 1.8f;

	Matrix34 worldTM = pTarget->GetEntity()->GetWorldTM();
	Vec3 worldPos = worldTM.GetTranslation();
	if(!pVehicle)
	{
		const SStanceInfo* stanceInfo = pTarget->GetStanceInfo(pTarget->GetStance());
		if(stanceInfo)
		{
			Interpolate(viewHeight, stanceInfo->viewOffset.z, 5.0f, viewParams.frameTime);
			worldPos.z += viewHeight + defaultOffset;
		}
		else
		{
			worldPos.z += 1.8f;
		}
	}
	else
	{
		// use vehicle pos/ori
		worldTM = pVehicle->GetEntity()->GetWorldTM();
		worldPos = pVehicle->GetEntity()->GetWorldPos();
		worldPos.z += 1.5f;
	}
	
	Ang3 worldAngles = Ang3::GetAnglesXYZ(Matrix33(worldTM));
	float distance = 3;

	// if freelook allowed, get orientation and distance from player entity
	if(g_pGameCVars->g_spectate_FixedOrientation == 0)
	{
		CPlayer* pThisPlayer = static_cast<CPlayer*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.entityId));
		if(!pThisPlayer)
			return;
		Matrix34 ownOrientation = pThisPlayer->GetEntity()->GetWorldTM();

		worldAngles += Ang3::GetAnglesXYZ(Matrix33(ownOrientation));
		distance = pThisPlayer->GetSpectatorZoom();
	}

	if(pVehicle)
	{
		distance *= 4.0f;

		// air vehicles need bigger distance
		if(pVehicle->GetMovement() && pVehicle->GetMovement()->GetMovementType() == IVehicleMovement::eVMT_Air)
			distance *= 2.0f;
	}

	Vec3 goal;
	goal.x = distance * cos(worldAngles.z + gf_PI*1.5f) + worldPos.x;
	goal.y = distance * sin(worldAngles.z - gf_PI/2.0f) + worldPos.y;

	AABB targetBounds;
	pTarget->GetEntity()->GetLocalBounds(targetBounds);
	goal.z = targetBounds.max.z;
	float offset = defaultOffset;
	if(pVehicle)
	{
		if(pVehicle->GetMovement() && pVehicle->GetMovement()->GetMovementType() == IVehicleMovement::eVMT_Air)
			offset = 3.0f;
		else
			offset = 1.0f;
	}
	goal.z += pTarget->GetEntity()->GetWorldPos().z + offset;

	// store / interpolate the offset, not the world pos (reduces percieved jitter in vehicles)
	static Vec3 viewOffset(goal-worldPos);
	static Vec3 camPos(goal);
	static Vec3 entPos(worldPos);
	static EntityId lastSpectatorTarget(m_in.stats_spectatorTarget);

	// do a ray cast to check for camera intersection
	static ray_hit hit;	
	IPhysicalEntity* pSkipEntities[10];
	int nSkip = 0;
	if(pVehicle)
	{
		// vehicle drivers don't seem to have current items, so need to add the vehicle itself here
		nSkip = pVehicle->GetSkipEntities(pSkipEntities, 10);
	}
	else
	{
		IItem* pItem = pTarget->GetCurrentItem();
		if (pItem)
		{
			CWeapon* pWeapon = (CWeapon*)pItem->GetIWeapon();
			if (pWeapon)
				nSkip = CSingle::GetSkipEntities(pWeapon, pSkipEntities, 10);
		}
	}

	static float minDist = 0.4f;	// how close we're allowed to get to the target
	static float wallSafeDistance = 0.3f; // how far to keep camera from walls

	Vec3 dir = goal - worldPos;
	primitives::sphere sphere;
	sphere.center = worldPos;
	sphere.r = wallSafeDistance;

	geom_contact *pContact = 0;          
	float hitDist = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, dir, ent_static|ent_terrain|ent_rigid|ent_sleeping_rigid,
		&pContact, 0, (geom_colltype_player<<rwi_colltype_bit) | rwi_stop_at_pierceable, 0, 0, 0, pSkipEntities, nSkip);

	// even when we have contact, keep the camera the same height above the target
	float minHeightDiff = dir.z;

	if(hitDist > 0 && pContact)
	{
		goal = worldPos + (hitDist * dir.GetNormalizedSafe());
		
		if(goal.z - worldPos.z < minHeightDiff)
		{
			// can't move the camera far enough away from the player in this direction. Try moving it directly up a bit
			int numHits = 0;
			sphere.center = goal;

			// (move back just slightly to avoid colliding with the wall we've already found...)
			sphere.center -= dir.GetNormalizedSafe() * 0.05f;

			float newHitDist = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, Vec3(0,0,minHeightDiff), ent_static|ent_terrain|ent_rigid|ent_sleeping_rigid,
				&pContact, 0, (geom_colltype_player<<rwi_colltype_bit) | rwi_stop_at_pierceable, 0, 0, 0, pSkipEntities, nSkip);

			float raiseDist = minHeightDiff - (goal.z - worldPos.z) - wallSafeDistance;
			if(newHitDist != 0)
			{
				raiseDist = MIN(minHeightDiff, newHitDist);
			}
			
			raiseDist = MAX(0.0f, raiseDist);
			
			goal.z += raiseDist;
			worldPos.z += raiseDist*0.8f;
		}
	}

	int thisFrameId = gEnv->pRenderer->GetFrameID();
	static int frameNo(thisFrameId);
	if(thisFrameId - frameNo > 5)
	{
		// reset positions
		viewOffset = goal - worldPos;
		entPos = worldPos;
		camPos = goal;
	}
	if(lastSpectatorTarget != m_in.stats_spectatorTarget)
	{
		viewOffset = goal - worldPos;
		entPos = worldPos;
		camPos = goal;
		lastSpectatorTarget = m_in.stats_spectatorTarget;
	}
	frameNo = thisFrameId;

	static float interpSpeed = 5.0f;
	static float interpSpeed2 = 5.0f;
	static float interpSpeed3 = 8.0f;

	if(pVehicle)
	{
		Interpolate(viewOffset, goal-worldPos, interpSpeed, viewParams.frameTime);
		entPos = worldPos;
		viewParams.position = worldPos + viewOffset;
		camPos = viewParams.position;
	}
	else
	{
		Vec3 camPosChange = goal - camPos;
		Vec3 entPosChange = worldPos - entPos;

		if(camPosChange.GetLengthSquared() > 100.0f)
			camPos = goal;
		if(entPosChange.GetLengthSquared() > 100.0f)
			entPos = worldPos;

		Interpolate(camPos, goal, interpSpeed2, viewParams.frameTime);
		Interpolate(entPos, worldPos, interpSpeed3, viewParams.frameTime);
		viewParams.position = camPos;
	}

	Matrix33 rotation = Matrix33::CreateRotationVDir((entPos - viewParams.position).GetNormalizedSafe());
	viewParams.rotation = GetQuatFromMat33(rotation);	
	m_io.bUsePivot = true;
	m_io.stats_bobCycle = 0.0;
}
Пример #20
0
void CPlayerView::ViewDeathCamTarget(SViewParams &viewParams)
{
	CActor* pTarget = (CActor*)g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.stats_spectatorTarget);
	if(!pTarget)
		return;

	Matrix34 targetWorldTM = pTarget->GetEntity()->GetWorldTM();

	Vec3 camPos = viewParams.position;
	static float offset = 1.5f;
	camPos.z += offset;

	float heightOffset = 1.5f;
	const SStanceInfo* pSI = pTarget->GetStanceInfo(pTarget->GetStance());
	if(pSI)
	{
		heightOffset = pSI->viewOffset.z;
	}

	Vec3 targetPos = targetWorldTM.GetTranslation();
	targetPos.z += heightOffset;

	int thisFrameId = gEnv->pRenderer->GetFrameID();
	static int frameNo(thisFrameId);
	static Vec3 oldCamPos(camPos);
	static Vec3 oldTargetPos(targetPos);
	static EntityId lastSpectatorTarget(m_in.stats_spectatorTarget);
	static float oldFOVScale(1.0f);

	// if more than a few frames have passed since our last update, invalidate the positions
	if(thisFrameId - frameNo > 5)
	{
		oldCamPos = viewParams.position;	// interpolate from current camera pos
		oldTargetPos = targetPos;
		oldFOVScale = 1.0f;
	}
	// if target changed, reset positions
	if(lastSpectatorTarget != m_in.stats_spectatorTarget)
	{
		oldCamPos = camPos;
		oldTargetPos = targetPos;
		lastSpectatorTarget = m_in.stats_spectatorTarget;
		oldFOVScale = 1.0f;
	}
	frameNo = thisFrameId;

	// slight zoom after 2s
	float timeNow = gEnv->pTimer->GetCurrTime();
	float distSq = (targetPos - camPos).GetLengthSquared();
	float scale = 1.0f;
	if(timeNow - m_in.deathTime > 1.0f && distSq > 2500.0f)
	{
		// 1.0f at 50m, 0.3f at 100m+
		scale = 1.0f - (distSq - 2500.0f)/25000.0f;
		scale = CLAMP(scale, 0.3f, 1.0f);
	}

	Interpolate(oldCamPos, camPos, 5.0f, viewParams.frameTime);
	Interpolate(oldTargetPos, targetPos, 5.0f, viewParams.frameTime);
	Interpolate(oldFOVScale, scale, 0.5f, viewParams.frameTime);
	
	viewParams.position = oldCamPos;
	Vec3 dir = (oldTargetPos - oldCamPos).GetNormalizedSafe();
	Matrix33 rotation = Matrix33::CreateRotationVDir(dir);	
	dir.z = 0.0f;

	// quick ray check to make sure there's not a wall in the way...
	IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.entityId);
	if (pActor)
	{
		static ray_hit hit;	
		IPhysicalEntity* pSkipEntities[10];
		int nSkip = 0;
		IItem* pItem = pActor->GetCurrentItem();
		if (pItem)
		{
			CWeapon* pWeapon = (CWeapon*)pItem->GetIWeapon();
			if (pWeapon)
				nSkip = CSingle::GetSkipEntities(pWeapon, pSkipEntities, 10);
		}

		if (gEnv->pPhysicalWorld->RayWorldIntersection(viewParams.position, -dir, ent_static|ent_terrain|ent_rigid,
			rwi_ignore_noncolliding | rwi_stop_at_pierceable, &hit, 1, pSkipEntities, nSkip))
		{
			dir.zero();
		}
	}

	viewParams.position -= dir;

	viewParams.fov = m_in.defaultFov*oldFOVScale*(gf_PI/180.0f);;
	viewParams.rotation = GetQuatFromMat33(rotation);	
	m_io.bUsePivot = true;
	m_io.stats_bobCycle = 0.0;
}
void CPlayerView::ViewSpectatorTarget(SViewParams &viewParams)
{
	CActor *pTarget = (CActor *)g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.stats_spectatorTarget);

	if(!pTarget)
	{
		return;
	}

	Matrix34 worldTM = pTarget->GetEntity()->GetWorldTM();
	Vec3 worldPos = worldTM.GetTranslation();
	worldPos.z += 1.5f;
	Ang3 worldAngles = Ang3::GetAnglesXYZ(Matrix33(worldTM));
	float rot = worldAngles.z;// + m_rot;
	float distance = 3;//(m_defaultDistance != 0) ? m_defaultDistance : m_distance;

	if(IVehicle *pVehicle = pTarget->GetLinkedVehicle())
	{
		AABB vehicleBox;
		pVehicle->GetEntity()->GetLocalBounds(vehicleBox);
		distance = 2.0f * vehicleBox.GetRadius();
	}

	Vec3 goal;
	float zoom = 1.0f;
	goal.x = distance * zoom * cosf(rot + gf_PI * 1.5f) + worldPos.x;
	goal.y = distance * zoom * sinf(rot - gf_PI / 2.0f) + worldPos.y;
	AABB targetBounds;
	pTarget->GetEntity()->GetLocalBounds(targetBounds);
	goal.z = targetBounds.max.z;
	static float defaultOffset = 0.75f;
	float offset = defaultOffset;

	if(pTarget->GetLinkedVehicle())
	{
		offset = 2.0f;
	}

	goal.z += pTarget->GetEntity()->GetWorldPos().z + offset;
	// store / interpolate the offset, not the world pos (reduces percieved jitter in vehicles)
	static Vec3 viewOffset(goal - worldPos);
	static Vec3 position(goal);
	static Vec3 entPos(worldPos);
	static EntityId lastSpectatorTarget(m_in.stats_spectatorTarget);
	// do a ray cast to check for camera intersection
	static ray_hit hit;
	IPhysicalEntity *pSkipEntities[10];
	int nSkip = 0;
	IItem *pItem = pTarget->GetCurrentItem();

	if (pItem)
	{
		CWeapon *pWeapon = (CWeapon *)pItem->GetIWeapon();

		if (pWeapon)
		{
			nSkip = CSingle::GetSkipEntities(pWeapon, pSkipEntities, 10);
		}
	}
	else if(IVehicle *pVehicle = pTarget->GetLinkedVehicle())
	{
		// vehicle drivers don't seem to have current items, so need to add the vehicle itself here
		nSkip = pVehicle->GetSkipEntities(pSkipEntities, 10);
	}

	const float wallSafeDistance = 0.2f; // how far to keep camera from walls
	Vec3 dir = goal - worldPos;
	primitives::sphere sphere;
	sphere.center = worldPos;
	sphere.r = wallSafeDistance;
	geom_contact *pContact = 0;
	float hitDist = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, dir, ent_static | ent_terrain | ent_rigid | ent_sleeping_rigid,
					&pContact, 0, geom_colltype_player, 0, 0, 0, pSkipEntities, nSkip);
	// even when we have contact, keep the camera the same height above the target
	float minHeightDiff = dir.z;

	if(hitDist > 0 && pContact)
	{
		goal = worldPos + (hitDist * dir.GetNormalizedSafe());

		if(goal.z - worldPos.z < minHeightDiff)
		{
			// can't move the camera far enough away from the player in this direction. Try moving it directly up a bit
			sphere.center = goal;
			// (move back just slightly to avoid colliding with the wall we've already found...)
			sphere.center -= dir.GetNormalizedSafe() * 0.05f;
			float newHitDist = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, Vec3(0, 0, minHeightDiff), ent_static | ent_terrain | ent_rigid | ent_sleeping_rigid,
							   &pContact, 0, geom_colltype_player, 0, 0, 0, pSkipEntities, nSkip);
			float raiseDist = minHeightDiff - (goal.z - worldPos.z) - wallSafeDistance;

			if(newHitDist != 0)
			{
				raiseDist = MIN(minHeightDiff, newHitDist);
			}

			raiseDist = MAX(0.0f, raiseDist);
			goal.z += raiseDist;
			worldPos.z += raiseDist * 0.8f;
		}
	}

	int thisFrameId = gEnv->pRenderer->GetFrameID();
	static int frameNo(thisFrameId);

	if(thisFrameId - frameNo > 5)
	{
		// reset positions
		viewOffset = goal - worldPos;
		entPos = worldPos;
		position = goal;
	}

	if(lastSpectatorTarget != m_in.stats_spectatorTarget)
	{
		viewOffset = goal - worldPos;
		entPos = worldPos;
		position = goal;
		lastSpectatorTarget = m_in.stats_spectatorTarget;
	}

	frameNo = thisFrameId;

	if(pTarget->GetLinkedVehicle())
	{
		Interpolate(viewOffset, goal - worldPos, 5.0f, viewParams.frameTime);
		entPos = worldPos;
		viewParams.position = worldPos + viewOffset;
		position = viewParams.position;
	}
	else
	{
		Vec3 camPosChange = goal - position;
		Vec3 entPosChange = worldPos - entPos;

		if(camPosChange.GetLengthSquared() > 100.0f)
		{
			position = goal;
		}

		if(entPosChange.GetLengthSquared() > 100.0f)
		{
			entPos = worldPos;
		}

		Interpolate(position, goal, 5.0f, viewParams.frameTime);
		Interpolate(entPos, worldPos, 5.0f, viewParams.frameTime);
		viewParams.position = position;
	}

	Matrix33 rotation = Matrix33::CreateRotationVDir((entPos - viewParams.position).GetNormalizedSafe());
	viewParams.rotation = Quat(rotation);
	m_io.bUsePivot = true;
	m_io.stats_bobCycle = 0.0;
}
Пример #22
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;
}
Пример #23
0
//------------------------------------------------------------------------
void CWeapon::OnShoot(EntityId shooterId, EntityId ammoId, IEntityClass* pAmmoType, const Vec3 &pos, const Vec3 &dir, const Vec3&vel)
{
	BROADCAST_WEAPON_EVENT(OnShoot, (this, shooterId, ammoId, pAmmoType, pos, dir, vel));

	//FIXME:quick temporary solution
	CActor *pActor = static_cast<CActor*> (g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(shooterId));
	if (pActor)
		pActor->HandleEvent(SGameObjectEvent(eCGE_OnShoot,eGOEF_ToExtensions));

	IActor *pClientActor=m_pGameFramework->GetClientActor();

	if (pActor && pActor->GetActorClass() == CPlayer::GetActorClassType() && IsServer())
	{
		if (pActor == pClientActor)
		{
			if (IAIObject *pAIObject=pActor->GetEntity()->GetAI())
				gEnv->pAISystem->SendSignal(SIGNALFILTER_LEADER, 1, "OnEnableFire",	pAIObject, 0);
		}

		CPlayer *pPlayer=static_cast<CPlayer *>(pActor);
		CNanoSuit *pSuit=pPlayer->GetNanoSuit();

		if(m_fm && strcmp(m_fm->GetType(), "Repair"))
		{
			if(pSuit)
			{
				if (pSuit->GetMode() == NANOMODE_STRENGTH && !IsMounted())
					pSuit->SetSuitEnergy(pSuit->GetSuitEnergy()-g_pGameCVars->g_suitRecoilEnergyCost);
				else if(pSuit->GetMode() == NANOMODE_CLOAK)
					pSuit->SetSuitEnergy(0.0f);
			}
		}

		if (gEnv->bServer && pSuit && pSuit->IsInvulnerable())
			pSuit->SetInvulnerability(false);
	}
	
	if (pClientActor && m_fm && strcmp(m_fm->GetType(), "Thrown"))	
	{
		// inform the HUDRadar about the sound event
		Vec3 vPlayerPos=pClientActor->GetEntity()->GetWorldPos();
		float fDist2=(vPlayerPos-pos).len2();
		if (fDist2<250.0f*250.0f)
		{			
			//if (pClientActor->GetEntityId() != shooterId) 
				//	pHUD->ShowSoundOnRadar(pos);
				
			if(gEnv->bMultiplayer)
			{
				CGameRules *pGameRules = g_pGame->GetGameRules();
				if(pGameRules->GetTeamCount() < 2 || (pGameRules->GetTeam(shooterId) != pGameRules->GetTeam(pClientActor->GetEntityId())))
				{
					//Small workaround for patch2...
					IFireMode* pFM = GetFireMode(GetCurrentFireMode());
					bool grenade = pFM?(pFM->GetAmmoType()==CItem::sScarGrenadeClass):false;
					//~...

					if (!IsSilencerAttached() || grenade)
					{
						SAFE_HUD_FUNC(GetRadar()->AddEntityTemporarily(shooterId, 5.0f));
					}
					else if(fDist2<5.0f*5.0f)
					{
						//Silencer attached
						SAFE_HUD_FUNC(GetRadar()->AddEntityTemporarily(shooterId, 5.0f));
					}
				}
			}

			if ((!IsSilencerAttached()) && fDist2<sqr(SAFE_HUD_FUNC_RET(GetBattleRange())))
				SAFE_HUD_FUNC(TickBattleStatus(1.0f));
		}
	}
}
Пример #24
0
//------------------------------------------------------------------------
int CScriptBind_Actor::GetCloseColliderParts(IFunctionHandler *pH, int characterSlot, Vec3 hitPos, float radius)
{
  // find nearest physic. parts to explosion center
  // for now we just return the closest part (using the AABB)  
  
  CActor *pActor = GetActor(pH);  
	if (!pActor)
		return pH->EndFunction();

  IEntity* pEntity = pActor->GetEntity();

  ICharacterInstance* pChar = pEntity->GetCharacter(characterSlot);

  if (pChar && pChar->GetISkeletonPose()->GetCharacterPhysics())  
  { 
    IPhysicalEntity* pPhysics = pChar->GetISkeletonPose()->GetCharacterPhysics();
    
    pe_status_nparts nparts;
    int numParts = pPhysics->GetStatus(&nparts);    

    float minLenSq = radius*radius + 0.1f;
    int minLenPart = -1;
    
    pe_status_pos status;

    for (int i=0; i<numParts; ++i)
    {
      status.ipart = i;
      if (pPhysics->GetStatus(&status))
      { 
        AABB box(status.pos+status.BBox[0], status.pos+status.BBox[1]);
             
        // if hitpos inside AABB, return
        if (box.IsContainPoint(hitPos))
        {
          minLenPart = i;          
          break;
        }

        // else find closest distance 
        float lenSq = Distance::Point_AABBSq(hitPos, box);
        if (lenSq < minLenSq)
        {
          minLenSq = lenSq;
          minLenPart = i;          
        }
      }      
    }

    // get material from selected part
    static ISurfaceTypeManager* pSurfaceMan = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeManager();

    if (minLenPart != -1)
    {
	     pe_params_part params;
      params.ipart = minLenPart;
      if (pPhysics->GetParams(&params))
      { 
        phys_geometry* pGeom = params.pPhysGeomProxy ? params.pPhysGeomProxy : params.pPhysGeom;
        if (pGeom->surface_idx > 0 &&  pGeom->surface_idx < params.nMats)
				{
					if (ISurfaceType *pSurfaceType=pSurfaceMan->GetSurfaceType(pGeom->pMatMapping[pGeom->surface_idx]))
						return pH->EndFunction(params.partid, pSurfaceType->GetName(), pSurfaceType->GetType());
				}
      }

      return pH->EndFunction(params.partid);
    }    
  }
  return pH->EndFunction();
}
Пример #25
0
//------------------------------------------------------------------------
void CItem::UpdateMounted(float frameTime)
{
	IRenderAuxGeom* pAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom();

	if (!m_ownerId || !m_stats.mounted)
		return;

	CActor *pActor = GetOwnerActor();
	if (!pActor)
		return;

	CheckViewChange();

  if (true)
  {  
	  if (IsClient())
	  {
		  ICharacterInstance *pCharacter = GetEntity()->GetCharacter(eIGS_FirstPerson);

		  if (pCharacter && !m_idleAnimation[eIGS_FirstPerson].empty() && pCharacter->GetISkeletonAnim()->GetNumAnimsInFIFO(0)<1)
			  PlayAction(m_idleAnimation[eIGS_FirstPerson], 0, true);
	  }

		// need to explicitly update characters at this point
		// cause the entity system update occered earlier, with the last position
		for (int i=0; i<eIGS_Last; i++)
		{
			if (GetEntity()->GetSlotFlags(i)&ENTITY_SLOT_RENDER)
			{
				ICharacterInstance *pCharacter = GetEntity()->GetCharacter(i);
				if (pCharacter)
				{
					Matrix34 mloc = GetEntity()->GetSlotLocalTM(i,false);
					Matrix34 m34 = GetEntity()->GetWorldTM()*mloc;
					QuatT renderLocation = QuatT(m34);
					pCharacter->GetISkeletonPose()->SetForceSkeletonUpdate(9);
					pCharacter->SkeletonPreProcess(renderLocation, renderLocation, GetISystem()->GetViewCamera(),0x55 );
					pCharacter->SetPostProcessParameter(renderLocation, renderLocation, 0, 0.0f, 0x55 );		
				}
			}
		}

	//	f32 fColor[4] = {1,1,0,1};
	//	f32 g_YLine=60.0f;
	//	gEnv->pRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false, "Mounted Gun Code" ); 

		//adjust the orientation of the gun based on the aim-direction


		SMovementState info;
		IMovementController* pMC = pActor->GetMovementController();		
		pMC->GetMovementState(info);
		Vec3 dir = info.aimDirection.GetNormalized();
		Matrix34 tm = Matrix33::CreateRotationVDir(dir);
		Vec3 vGunXAxis=tm.GetColumn0();

		if (pActor->GetLinkedVehicle()==0)
		{
			if (pMC)
			{						
				if(!pActor->IsPlayer())
				{
					// prevent snapping direction
					Vec3 currentDir = GetEntity()->GetWorldRotation().GetColumn1();
					float dot = currentDir.Dot(dir);
					dot = CLAMP(dot,-1,1);
					float reqAngle = cry_acosf(dot);
					const float maxRotSpeed = 2.0f;
					float maxAngle = frameTime * maxRotSpeed;
					if(fabs(reqAngle) > maxAngle)
					{
						Vec3 axis = currentDir.Cross(dir);
						if(axis.GetLengthSquared()>0.001f) // current dir and new dir are enough different
							dir = currentDir.GetRotated(axis.GetNormalized(),sgn(reqAngle)*maxAngle);
					}
				}				
				//adjust the orientation of the gun based on the aim-direction
				tm = Matrix33::CreateRotationVDir(dir);
				Vec3 vWPos=GetEntity()->GetWorldPos();
				tm.SetTranslation(vWPos);
				GetEntity()->SetWorldTM(tm);  //set the new orientation of the mounted gun

				vGunXAxis=tm.GetColumn0();
				Vec3 vInitialAimDirection = m_stats.mount_dir;
				Matrix33 vInitialPlayerOrientation = Matrix33::CreateRotationVDir(vInitialAimDirection);
				assert( vInitialAimDirection.IsUnit() );

	  		Vec3 newp;

				if (pActor->IsThirdPerson())
				{
					//third person
					f32 dist = m_mountparams.body_distance*1.3f;
					Vec3 oldp = pActor->GetEntity()->GetWorldPos();
					newp = GetEntity()->GetWorldPos()-vInitialAimDirection*dist; //mounted gun
					newp.z = oldp.z;
				}
				else
				{
					//first person
					f32 fMoveBack = (1.0f+(dir.z*dir.z*dir.z*dir.z*4.0f))*0.75f;
					f32	dist = m_mountparams.eye_distance*fMoveBack;
					Vec3 oldp = pActor->GetEntity()->GetWorldPos();
					newp = GetEntity()->GetWorldPos()-dir*dist; //mounted gun
					//newp.z -= 0.75f;
					newp.z = oldp.z;
				}


				Matrix34 actortm(pActor->GetEntity()->GetWorldTM());

				//if (pActor->IsThirdPerson())
				actortm=vInitialPlayerOrientation;

				actortm.SetTranslation(newp);
				pActor->GetEntity()->SetWorldTM(actortm, ENTITY_XFORM_USER);
				pActor->GetAnimationGraphState()->SetInput("Action","gunnerMounted");
				
				//f32 g_YLine=80.0f;
				//gEnv->pRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false, "Mounted Gun Active for FP and AI" ); 

				if (ICharacterInstance *pCharacter = pActor->GetEntity()->GetCharacter(0))
				{
					ISkeletonAnim *pSkeletonAnim = pCharacter->GetISkeletonAnim();
					assert(pSkeletonAnim);

					uint32 numAnimsLayer = pSkeletonAnim->GetNumAnimsInFIFO(0);
					for(uint32 i=0; i<numAnimsLayer; i++)
					{
						CAnimation &animation = pSkeletonAnim->GetAnimFromFIFO(0, i);
						if (animation.m_AnimParams.m_nFlags & CA_MANUAL_UPDATE)
						{
							f32 aimrad = Ang3::CreateRadZ(Vec2(vInitialAimDirection),Vec2(dir));
							animation.m_fAnimTime = clamp_tpl(aimrad/gf_PI,-1.0f,+1.0f)*0.5f+0.5f;
							//if (pActor->IsThirdPerson()==0)
								//animation.m_fAnimTime=0.6f; //Ivo & Benito: high advanced future code. don't ask what it is 
							                                //Benito - Not needed any more ;)

							//f32 g_YLine=100.0f;
							//gEnv->pRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false, "AnimTime: %f    MyAimAngle: %f deg:%   distance:%f", animation.m_fAnimTime, aimrad, RAD2DEG(aimrad),m_mountparams.body_distance ); 
						}
					}

				}

				m_stats.mount_last_aimdir = dir;
				
			}
		}
    
    if (ICharacterInstance* pCharInstance = pActor->GetEntity()->GetCharacter(0))
		{
      if (ISkeletonAnim* pSkeletonAnim = pCharInstance->GetISkeletonAnim())
      {   
        OldBlendSpace ap;				
        if (GetAimBlending(ap))
        {
					pSkeletonAnim->SetBlendSpaceOverride(eMotionParamID_TurnSpeed, 0.5f + 0.5f * ap.m_turn, true);
        }        
      }        
    } 

    UpdateIKMounted(pActor, vGunXAxis*0.1f);
   
		RequireUpdate(eIUS_General);
  }
}
Пример #26
0
void CHUD::UpdateMissionObjectiveIcon(EntityId objective, int friendly, FlashOnScreenIcon iconType, bool forceNoOffset, Vec3 rotationTarget)
{
	IEntity *pObjectiveEntity = GetISystem()->GetIEntitySystem()->GetEntity(objective);
	if(!pObjectiveEntity) return;

	AABB box;
	pObjectiveEntity->GetWorldBounds(box);
	Vec3 vWorldPos = Vec3(0,0,0);

	SEntitySlotInfo info;
	int slotCount = pObjectiveEntity->GetSlotCount();
	for(int i=0; i<slotCount; ++i)
	{
		if (pObjectiveEntity->GetSlotInfo(i, info))
		{
			if (info.pCharacter)
			{
				int16 id = info.pCharacter->GetISkeletonPose()->GetJointIDByName("objectiveicon");
				if (id >= 0)
				{
					//vPos = pCharacter->GetISkeleton()->GetHelperPos(helper);
					vWorldPos = info.pCharacter->GetISkeletonPose()->GetAbsJointByID(id).t;
					if (!vWorldPos.IsZero())
					{
						vWorldPos = pObjectiveEntity->GetSlotWorldTM(i).TransformPoint(vWorldPos);
						break;
					}
				}
			}
		}
	}
	if(vWorldPos == Vec3(0,0,0))
		vWorldPos = pObjectiveEntity->GetWorldPos();

	if(!forceNoOffset)
		vWorldPos.z += 2.0f;

	Vec3 vEntityScreenSpace;
	m_pRenderer->ProjectToScreen(	vWorldPos.x, vWorldPos.y,	vWorldPos.z, &vEntityScreenSpace.x, &vEntityScreenSpace.y, &vEntityScreenSpace.z);
	Vec3 vEntityTargetSpace;
	bool useTarget = false;
	if(!rotationTarget.IsZero())
	{
		m_pRenderer->ProjectToScreen(	rotationTarget.x, rotationTarget.y,	rotationTarget.z, &vEntityTargetSpace.x, &vEntityTargetSpace.y, &vEntityTargetSpace.z);
		useTarget = true;
	}

	CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetClientActor());
	bool bBack = false;
	if (IMovementController *pMV = pActor->GetMovementController())
	{
		SMovementState state;
		pMV->GetMovementState(state);
		Vec3 vLook = state.eyeDirection;
		Vec3 vDir = vWorldPos - pActor->GetEntity()->GetWorldPos();
		float fDot = vLook.Dot(vDir);
		if(fDot<0.0f)
			bBack = true;
	}

	bool bLeft(false), bRight(false), bTop(false), bBottom(false);

	if(vEntityScreenSpace.z > 1.0f && bBack)
	{
		Vec2 vCenter(50.0f, 50.0f);
		Vec2 vTarget(-vEntityScreenSpace.x, -vEntityScreenSpace.y);
		Vec2 vScreenDir = vTarget - vCenter;
		vScreenDir = vCenter + (100.0f * vScreenDir.NormalizeSafe());
		vEntityScreenSpace.y = vScreenDir.y;
		vEntityScreenSpace.x = vScreenDir.x;
		useTarget = false;
	}
	if(vEntityScreenSpace.x < 2.0f)
	{
		bLeft = true;
		vEntityScreenSpace.x = 2.0f;
		useTarget = false;
	}
	if(vEntityScreenSpace.x > 98.0f)
	{
		bRight = true;
		vEntityScreenSpace.x = 98.0f;
		useTarget = false;
	}
	if(vEntityScreenSpace.y < 2.01f)
	{
		bTop = true;
		vEntityScreenSpace.y = 2.0f;
		useTarget = false;
	}
	if(vEntityScreenSpace.y > 97.99f)
	{
		bBottom = true;
		vEntityScreenSpace.y = 98.0f;
		useTarget = false;
	}

	float fScaleX = 0.0f;
	float fScaleY = 0.0f;
	float fHalfUselessSize = 0.0f;
	GetProjectionScale(&m_animMissionObjective,&fScaleX,&fScaleY,&fHalfUselessSize);

	if(bLeft && bTop)
	{
		iconType = eOS_TopLeft;
	}
	else if(bLeft && bBottom)
	{
		iconType = eOS_BottomLeft;
	}
	else if(bRight && bTop)
	{
		iconType = eOS_TopRight;
	}
	else if(bRight && bBottom)
	{
		iconType = eOS_BottomRight;
	}
	else if(bLeft)
	{
		iconType = eOS_Left;
	}
	else if(bRight)
	{
		iconType = eOS_Right;
	}
	else if(bTop)
	{
		iconType = eOS_Top;
	}
	else if(bBottom)
	{
		iconType = eOS_Bottom;
	}

	float rotation = 0.0f;
	if(useTarget)
	{
		float diffX = (vEntityScreenSpace.x*fScaleX+fHalfUselessSize+16.0f) - (vEntityTargetSpace.x*fScaleX+fHalfUselessSize+16.0f);
		float diffY = (vEntityScreenSpace.y*fScaleY) - (vEntityTargetSpace.y*fScaleY);
		Vec2 dir(diffX, diffY);
		dir.NormalizeSafe();

		float fAngle;
		if(dir.y < 0)
		{
			fAngle = RAD2DEG(acos_tpl(dir.x));
		}
		else
		{
			fAngle = RAD2DEG(gf_PI2-acos_tpl(dir.x));
		}
		rotation = fAngle - 90.0f;
	}

	int		iMinDist = g_pGameCVars->hud_onScreenNearDistance;
	int		iMaxDist = g_pGameCVars->hud_onScreenFarDistance;
	float	fMinSize = g_pGameCVars->hud_onScreenNearSize;
	float	fMaxSize = g_pGameCVars->hud_onScreenFarSize;

	CActor *pPlayerActor = static_cast<CActor *>(gEnv->pGame->GetIGameFramework()->GetClientActor());

	float	fDist = (vWorldPos-pPlayerActor->GetEntity()->GetWorldPos()).len();
	float fSize = 1.0;
	if(fDist<=iMinDist)
	{
		fSize = fMinSize;
	}
	else if(fDist>=iMaxDist)
	{
		fSize = fMaxSize;
	}
	else if(iMaxDist>iMinDist)
	{
		float fA = ((float)iMaxDist - fDist);
		float fB = (float)(iMaxDist - iMinDist);
		float fC = (fMinSize - fMaxSize);
		fSize = ((fA / fB) * fC) + fMaxSize;
	}

	float centerX = 50.0;
	float centerY = 50.0;

	m_missionObjectiveNumEntries += FillUpMOArray(&m_missionObjectiveValues, objective, vEntityScreenSpace.x*fScaleX+fHalfUselessSize+16.0f, vEntityScreenSpace.y*fScaleY, iconType, friendly, (int)fDist, fSize*fSize, -rotation);
	bool nearCenter = (pow(centerX-vEntityScreenSpace.x+1.5f,2.0f)+pow(centerY-vEntityScreenSpace.y+2.5f,2.0f))<16.0f;
	if(nearCenter && (gEnv->bMultiplayer || m_pHUDScopes->IsBinocularsShown()))
	{
		m_objectiveNearCenter = objective;
	}
}
Пример #27
0
float CGameStateRecorder::RenderInfo(float y, bool bRecording)
{
	float retY = 0;

	IRenderer *pRenderer = gEnv->pRenderer;

	if (bRecording)
	{
		float fColor[4] = {1,0,0,1};
		pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," Recording game state");
		retY +=15;
	}
	else 
	{
		const float xp = 300;
		const float xr = 400;
		const float xri = 600;

		float fColor[4] = {0,1,0,1};
		float fColorWarning[4] = {1,1,0,1};

		const char* actorName = m_demo_actorInfo->GetString();
		CActor *pActor = GetActorOfName(actorName);
		if(pActor)
		{
			pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," Game state - Actor: %s --------------------------------------------------",pActor->GetEntity()? pActor->GetEntity()->GetName(): "(no entity)");
			retY +=15;

			if(m_itSingleActorGameState != m_GameStates.end() && pActor->GetEntity() && m_itSingleActorGameState->first == pActor->GetEntity()->GetId())
			{
				ICVar *pVar = gEnv->pConsole->GetCVar( "demo_force_game_state" );
				if(pVar)
				{
					int demo_forceGameState = pVar->GetIVal();
					if(demo_forceGameState)
					{
						pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false,demo_forceGameState==1 ? 
							" Override mode = (health, suit energy)" : " Override mode = (all)");
						retY +=15;
					}
				}

				pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColor,false,"Current");
				pRenderer->Draw2dLabel( xr,y+retY, 1.3f, fColor,false,"Recorded");
				retY +=15;

				SActorGameState& gstate = m_itSingleActorGameState->second;
				float recordedHealth = (float)gstate.health;
				float health = (float)pActor->GetHealth();
				bool bError = CHECK_MISMATCH(health, recordedHealth,10);

				pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," Health:");
				pRenderer->Draw2dLabel( xp,y+retY, 1.3f, bError? fColorWarning : fColor, false,"%d",(int)health);
				pRenderer->Draw2dLabel( xr,y+retY, 1.3f, bError? fColorWarning : fColor, false,"%d",(int)recordedHealth);
				retY +=15;
				
				// items
				pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," Inventory ---------------------------------------------------------------------------------------");
				retY +=15;
				pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColor,false,"Current");
				pRenderer->Draw2dLabel( xri,y+retY, 1.3f, fColor,false,"Recorded");
				retY +=15;

				CInventory *pInventory = (CInventory*)(pActor->GetInventory());
				if(pInventory)
				{
					int nInvItems = pInventory->GetCount();
						
					TItemContainer& Items = gstate.Items;
					int nRecItems = Items.size();
					int maxItems = max(nRecItems,nInvItems);

					int i=0;
					EntityId curSelectedId = pActor->GetCurrentItemId();
					TItemName curSelClass = GetItemName(curSelectedId);
					bool bSelectedError = !equal_strings(gstate.itemSelected,curSelClass);

					for(; i< nInvItems; i++)
					{
						IItem *pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pInventory->GetItem(i));
						if(pItem)	
						{
							TItemName szItemName = GetItemName(pItem->GetEntityId());

							TItemContainer::iterator it = Items.find(szItemName);
							bError = it==Items.end();
							pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," %2d)",i+1);

							EntityId curId = pItem->GetEntityId();
							TItemName curClass = GetItemName(curId);
							if(equal_strings(curClass,curSelClass) )
								pRenderer->Draw2dLabel( xp-16,y+retY, 1.3f,bSelectedError ? fColorWarning:fColor, false, "[]");

							if(equal_strings(szItemName, gstate.itemSelected))
								pRenderer->Draw2dLabel( xri-16,y+retY, 1.3f,bSelectedError ? fColorWarning:fColor, false, "[]");

							char itemName[32];
							const char* originalItemName = pItem->GetEntity() ? pItem->GetEntity()->GetName():"(null)";
							int length = strlen(originalItemName);
							length = min(length,31);
							strncpy(itemName,originalItemName,length);
							itemName[length]=0;
							pRenderer->Draw2dLabel( 1,y+retY, 1.3f, bError? fColorWarning : fColor, false,"     %s",itemName);

							if(bError)
								pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColorWarning, false, "Missing");
							else
							{
								SItemProperties& recItem = it->second;
								CWeapon *pWeapon = (CWeapon*)(pItem->GetIWeapon());

								IEntityClass* pItemClass = pItem->GetEntity()->GetClass();
								if(pItemClass && !strcmpi(pItemClass->GetName(),"binoculars"))
									pWeapon = NULL; // no fire mode or ammo recorded for binocular (which is a weapon)

								if(pWeapon)
								{
									int idx = 0;
									// ammo
									float xa = 0;
									for(SWeaponAmmo weaponAmmo = pWeapon->GetFirstAmmo(); weaponAmmo.pAmmoClass ; weaponAmmo = pWeapon->GetNextAmmo())
									{
										int ammoCount = weaponAmmo.count;
										const char* ammoClass;
										if(weaponAmmo.pAmmoClass && (ammoClass = weaponAmmo.pAmmoClass->GetName()))
										{
											TAmmoContainer::iterator it = recItem.Ammo.find(ammoClass);
											if(it!=recItem.Ammo.end())
											{
												int recAmmoCount = recItem.Ammo[ammoClass];
												bool bError2 = ammoCount!=recAmmoCount;
												pRenderer->Draw2dLabel( xp+xa,y+retY, 1.3f, bError2? fColorWarning : fColor, false,"Am%d:%d",idx,ammoCount);
												pRenderer->Draw2dLabel( xri+xa,y+retY, 1.3f, bError2? fColorWarning : fColor, false,"Am%d:%d",idx,recAmmoCount);
												xa += 50;
												++idx;
												if(idx%5 ==0)
												{
													xa=0;
													retY+=15;
												}
											}
										}
									}

									// current fire mode
									int curFireModeIdx = pWeapon->GetCurrentFireMode();
									int recFireModeIdx = recItem.fireMode;
									bool bError3 = curFireModeIdx!= recFireModeIdx;
									pRenderer->Draw2dLabel( xp+xa,y+retY, 1.3f, bError3? fColorWarning : fColor, false,"FMode:%d",curFireModeIdx);
									pRenderer->Draw2dLabel( xri+xa,y+retY, 1.3f, bError3? fColorWarning : fColor, false,"FMode:%d",recFireModeIdx);
								}
								else
								{
									pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColor, false, "Ok");
								}
							}

						}
						retY +=15;
					}

					/// Accessories

					int nInvAccessories = pInventory->GetAccessoryCount();

					TAccessoryContainer& Accessories = gstate.Accessories;
					int nRecAccessories = Accessories.size();
					if(nRecAccessories)
					{
						pRenderer->Draw2dLabel( 1,y+retY, 1.3f, bError? fColorWarning : fColor, false," Accessories");
						retY +=15;
					}

					for(int j=0 ; j< nInvAccessories; j++,i++)
					{
						const char* accessory = pInventory->GetAccessory(j);
						if(accessory && strlen(accessory))	
						{

							IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(accessory);
							if(pClass)
							{
								TItemName szItemName = pClass->GetName();
								TAccessoryContainer::iterator it = Accessories.find(szItemName);
								bError = it==Accessories.end();
								pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," %2d)",i+1);

								char itemName[32];
								int length = strlen(accessory);
								length = min(length,31);
								strncpy(itemName,accessory,length);
								itemName[length]=0;
								pRenderer->Draw2dLabel( 1,y+retY, 1.3f, bError? fColorWarning : fColor, false,"     %s",itemName);

								if(bError)
									pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColorWarning, false, "Missing");
								else
									pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColor, false, "Ok");

								retY +=15;
							}
						}

					}
					/// Ammo Mags
					TAmmoContainer& Ammo = gstate.AmmoMags;
					int nRecAmmo = Ammo.size();
					int nInvAmmo = pInventory->GetAmmoPackCount();
					if(nInvAmmo)
					{
						pRenderer->Draw2dLabel( 1,y+retY, 1.3f, bError? fColorWarning : fColor, false," Ammo Packs");
						retY +=15;
					}

					pInventory->AmmoIteratorFirst();
					for(int j=0 ; !pInventory->AmmoIteratorEnd(); j++, pInventory->AmmoIteratorNext())
					{
						TAmmoContainer& Mags = gstate.AmmoMags;
						const IEntityClass* pAmmoClass = pInventory->AmmoIteratorGetClass();
						if(pAmmoClass)
						{
							int invAmmoCount = pInventory->AmmoIteratorGetCount();
							const char* ammoClassName = pAmmoClass->GetName();
							bool bNotFound = Mags.find(ammoClassName) == Mags.end();
							int recAmmoCount = bNotFound ? 0 :Mags[ammoClassName];
							bool bError =  bNotFound || invAmmoCount!= recAmmoCount;

							pRenderer->Draw2dLabel( 1,y+retY, 1.3f, bError? fColorWarning : fColor, false,"  %s:",ammoClassName);
							pRenderer->Draw2dLabel( xp,y+retY, 1.3f, bError? fColorWarning : fColor, false,"%d",invAmmoCount);
							if(bNotFound)
								pRenderer->Draw2dLabel( xr,y+retY, 1.3f, fColorWarning, false,"NotRecd");
							else
								pRenderer->Draw2dLabel( xr,y+retY, 1.3f, bError? fColorWarning : fColor, false,"%d",recAmmoCount);
							retY +=15;

						}
					}
				}
			}
			else // m_itSingleActorGameState != m_GameStates.end()
			{
				pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false, "<<Not Recorded>>");
				retY +=15;
			}
		}
		else // pActor
		{
			pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false, "<<Actor %s not in the map>>",actorName ? actorName:"(no name)");
			retY +=15;		
		}

	}
	return retY;
}
Пример #28
0
void CAnimatedGrabHandler::UpdatePosVelRot(float frameTime)
{
	IEntity *pGrab = gEnv->pEntitySystem->GetEntity(m_grabStats.grabId);
	
	if ( !pGrab) return;

	IEntity *pEnt = m_pActor->GetEntity();

	if (m_grabStats.grabDelay<0.001f)
	{
		Vec3 grabWPos (GetGrabBoneWorldTM ().t);

		// NOTE Aug 3, 2007: <pvl> the second part of this test means don't enable
		// the correction if animation/ik wasn't used for grabbing in the first place
		if (m_grabStats.readIkInaccuracyCorrection && m_grabStats.grabAnimGraphSignal[0])
		{
			// NOTE Aug 2, 2007: <pvl> executed the first time this function is called
			// for a particular grabbing action
			m_grabStats.ikInaccuracyCorrection = grabWPos - (pGrab->GetWorldTM().GetTranslation() + m_grabStats.entityGrabSpot);
			m_grabStats.readIkInaccuracyCorrection = false;

			// FIXME Sep 13, 2007: <pvl> only putting it here because it's called just
			// once, at the instant when the object is grabbed - rename readIkInaccuracyCorrection
			// to make this clearer, or put this somewhere else
			DisableGrabbedAnimatedCharacter (true);
		}
		else
		{
			// NOTE Aug 2, 2007: <pvl> phase it out gradually
			m_grabStats.ikInaccuracyCorrection *= 0.9f;
			if (m_grabStats.ikInaccuracyCorrection.len2 () < 0.01f)
				m_grabStats.ikInaccuracyCorrection = Vec3 (0.0f, 0.0f, 0.0f);
		}
		// NOTE Sep 13, 2007: <pvl> this should prevent us from calling SetWPos()
		// later so that the IK "release" phase can take over
		m_grabStats.IKActive = false;

		Matrix34 tm(pGrab->GetWorldTM());
		tm.SetTranslation(grabWPos - (m_grabStats.ikInaccuracyCorrection + pGrab->GetRotation() * m_grabStats.entityGrabSpot));
		pGrab->SetWorldTM(tm,ENTITY_XFORM_USER);
	}

	//update IK
	for (int i=0;i<m_grabStats.limbNum;++i)
	{
		SIKLimb *pLimb = m_pActor->GetIKLimb(m_grabStats.limbId[i]);

		// NOTE Dez 14, 2006: <pvl> this class is always supposed to have
		// m_grabStats.usingAnimation == true
		if (m_grabStats.usingAnimation && m_grabStats.releaseIKTime>0.001f && m_grabStats.IKActive)
		{
			// NOTE Dez 15, 2006: <pvl> use IK to constantly offset the
			// animation so that the difference between where the animation
			// expects the object to be and where the object really is is taken
			// into account.
			Vec3 animPos = pEnt->GetSlotWorldTM(0) * pLimb->lAnimPos;
			Vec3 assumedGrabPos = pEnt->GetSlotWorldTM(0) * m_grabStats.grabbedObjOfs;
			Vec3 actualGrabPos = pGrab->GetWorldPos() + m_grabStats.entityGrabSpot;
			Vec3 adjustment = actualGrabPos - assumedGrabPos;
			pLimb->SetWPos(pEnt,animPos + adjustment,ZERO,0.5f,2.0f,1000);
			//gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(pGrab->GetWorldPos() + m_grabStats.entityGrabSpot, 0.5f, ColorB(0,255,0,100));
		}
		
		//if there are multiple limbs, only the first one sets the rotation of the object.
		if (m_grabStats.useIKRotation && i == 0 && m_grabStats.grabDelay<0.001f)
		{
			// NOTE Aug 8, 2007: <pvl> the idea here is to store current world
			// rotations of both the object being grabbed and the end bone of
			// a grabbing limb.  Then track how the end bone rotates with respect
			// to the stored original rotation and rotate the grabbed object
			// the same way.  That way, the grabbed object rotates the same as
			// the limb and appears to be "stabbed" by it.
			QuatT endBoneWorldRot = GetGrabBoneWorldTM ();
			endBoneWorldRot.q.Normalize();	// may not be necessary - just to be safe

			if ( ! m_grabStats.origRotationsValid)
			{
				m_grabStats.origRotation = pGrab->GetRotation();
				m_grabStats.origRotation.Normalize();			// may not be necessary - just to be safe
				m_grabStats.origEndBoneWorldRot = endBoneWorldRot;
				m_grabStats.origRotationsValid = true;
			}

			Quat grabQuat( (endBoneWorldRot*m_grabStats.origEndBoneWorldRot.GetInverted()).q * m_grabStats.origRotation);
			grabQuat.Normalize();

			// NOTE Dez 14, 2006: <pvl> this code sets up and look vectors for the grabbed
			// entity in case it's an Actor (the player, mostly) so that the player always
			// looks roughly at the grabber.  The grabber is supposed to be the Hunter here
			// so this code is somewhat Hunter-specific.
			// UPDATE Aug 7, 2007: <pvl> do the above for the player only
			// UPDATE Sep 13, 2007: <pvl> don't do it for anybody ATM, it doesn't seem useful
			CActor *pGrabbedActor = (CActor *)g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_grabStats.grabId);
			if (false && pGrabbedActor && pGrabbedActor->IsClient() && pGrabbedActor->GetActorStats())
			{
				Vec3 upVec(Quat(endBoneWorldRot.q * m_grabStats.additionalRotation).GetColumn2());
				upVec.z = fabs_tpl(upVec.z) * 2.0f;
				upVec.NormalizeSafe(Vec3(0,0,1));

				SActorStats *pAS = pGrabbedActor->GetActorStats();
				if (pAS)
				{
					pAS->forceUpVector = upVec;
					pAS->forceLookVector = (pEnt->GetSlotWorldTM(0) * m_pActor->GetLocalEyePos(0)) - pGrabbedActor->GetEntity()->GetWorldPos();
					float lookLen(pAS->forceLookVector.len());
					pAS->forceLookVector *= (1.0f/lookLen)*0.33f;
					//pAS->forceLookVector = -Quat(boneRot * m_grabStats.additionalRotation).GetColumn1();//boneRot.GetColumn2();
				}
			}
			else
			{
				pGrab->SetRotation(grabQuat,ENTITY_XFORM_USER);
			}
		}
	}

	if (m_grabStats.grabDelay<0.001f)
	{
		// NOTE Sep 16, 2007: <pvl> now that grabbed entity rotation coming from
		// a grabbing bone (if any) is computed, bone-space offset can be applied
		Matrix34 tm(pGrab->GetWorldTM());
		tm.AddTranslation(GetGrabBoneWorldTM().q * m_grabStats.boneGrabOffset);
		pGrab->SetWorldTM(tm,ENTITY_XFORM_USER);

		/*
		{
			// debug draw for the grab bone
			QuatT grabBoneWorldTM = GetGrabBoneWorldTM();
			Vec3 start = grabBoneWorldTM.t;
			Vec3 end = start + grabBoneWorldTM.q * Vec3 (1,0,0) * 3;
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine (start, ColorB (255,0,0), end, ColorB (0,0,255), 6.0f);
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere (start, 0.5f, ColorB (255,128,0));
		}
		*/
		/*
		{
			// draw complete coord systems for both the end bone and the grabbed thing
			QuatT grabBoneWorldTM = GetGrabBoneWorldTM();
			Vec3 start = grabBoneWorldTM.t;
			Vec3 end = start + grabBoneWorldTM.q * Vec3 (1,0,0) * 3;
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine (start, ColorB (128,0,0), end, ColorB (128,0,0), 6.0f);
			end = start + grabBoneWorldTM.q * Vec3 (0,1,0) * 3;
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine (start, ColorB (0,128,0), end, ColorB (0,128,0), 6.0f);
			end = start + grabBoneWorldTM.q * Vec3 (0,0,1) * 3;
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine (start, ColorB (0,0,128), end, ColorB (0,0,128), 6.0f);
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere (start, 0.2f, ColorB (255,255,255));

			start = pGrab->GetWorldTM().GetTranslation();
			end = start + pGrab->GetRotation() * Vec3 (1,0,0) * 3;
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine (start, ColorB (128,0,0), end, ColorB (128,0,0), 6.0f);
			end = start + pGrab->GetRotation() * Vec3 (0,1,0) * 3;
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine (start, ColorB (0,128,0), end, ColorB (0,128,0), 6.0f);
			end = start + pGrab->GetRotation() * Vec3 (0,0,1) * 3;
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine (start, ColorB (0,0,128), end, ColorB (0,0,128), 6.0f);
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere (start, 0.2f, ColorB (64,64,64));
		}
		*/
	}

/*
	{
		// debug draw for the grabbed object
		Vec3 start = pGrab->GetWorldTM().GetTranslation();
		Vec3 end = start + pGrab->GetRotation() * Vec3 (0,0,1) * 3;
		gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine (start, ColorB (255,0,0), end, ColorB (0,0,255), 6.0f);
		gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere (start, 0.2f, ColorB (255,128,0));
	}
*/
}
Пример #29
0
//------------------------------------------------------------------------
void CGameRules::ProcessServerHit(const HitInfo &hitInfo)
{
	bool ok=true;
	// check if shooter is alive
	CActor *pShooter = GetActorByEntityId(hitInfo.shooterId);
	CActor *pTarget = GetActorByEntityId(hitInfo.targetId);

	if (hitInfo.shooterId)
	{
		if (pShooter && pShooter->GetHealth()<=0)
			ok=false;
	}

	if (hitInfo.targetId)
	{
		if (pTarget && pTarget->GetSpectatorMode())
			ok=false;
	}

	if (ok)
	{
		float fTargetHealthBeforeHit = 0.0f;
		if(pTarget)
		{
			fTargetHealthBeforeHit = pTarget->GetHealth();
		}

		CreateScriptHitInfo(m_scriptHitInfo, hitInfo);
		CallScript(m_serverStateScript, "OnHit", m_scriptHitInfo);

		if(pTarget && !pTarget->IsDead())
		{
			const float fCausedDamage = fTargetHealthBeforeHit - pTarget->GetHealth();
			ProcessLocalHit(hitInfo, fCausedDamage);
		}

		// call hit listeners if any
		if (m_hitListeners.empty() == false)
		{
			for (size_t i = 0; i < m_hitListeners.size(); )
			{
				size_t count = m_hitListeners.size();
				m_hitListeners[i]->OnHit(hitInfo);
				if (count == m_hitListeners.size())
					i++;
				else
					continue;
			}
		}

		if (pShooter && hitInfo.shooterId!=hitInfo.targetId && hitInfo.weaponId!=hitInfo.shooterId && hitInfo.weaponId!=hitInfo.targetId && hitInfo.damage>=0)
		{
			EntityId params[2];
			params[0] = hitInfo.weaponId;
			params[1] = hitInfo.targetId;
			m_pGameplayRecorder->Event(pShooter->GetEntity(), GameplayEvent(eGE_WeaponHit, 0, 0, (void *)params));
		}

		if (pShooter)
			m_pGameplayRecorder->Event(pShooter->GetEntity(), GameplayEvent(eGE_Hit, 0, 0, (void *)hitInfo.weaponId));

		if (pShooter)
			m_pGameplayRecorder->Event(pShooter->GetEntity(), GameplayEvent(eGE_Damage, 0, hitInfo.damage, (void *)hitInfo.weaponId));
	}
}
Пример #30
0
//------------------------------------------------------------------------
void CMelee::Hit(const Vec3 &pt, const Vec3 &dir, const Vec3 &normal, IPhysicalEntity *pCollider, int partId, int ipart, int surfaceIdx, float damageScale, bool remote)
{
	// generate the damage
	IEntity *pTarget = gEnv->pEntitySystem->GetEntityFromPhysics(pCollider);

	// Report punch to AI system.
	// The AI notification must come before the game rules are 
	// called so that the death handler in AIsystem understands that the hit
	// came from the player.
	CActor *pActor = m_pWeapon->GetOwnerActor();
	if (pActor && pActor->GetActorClass() == CPlayer::GetActorClassType())
	{
		CPlayer *pPlayer = (CPlayer *)pActor;
		if (pPlayer && pPlayer->GetNanoSuit())
		{
			if (pPlayer->GetEntity() && pPlayer->GetEntity()->GetAI())
			{
				SAIEVENT AIevent;
				AIevent.targetId = pTarget ? pTarget->GetId() : 0;
				// pPlayer->GetNanoSuit()->GetMode() == NANOMODE_STRENGTH
				pPlayer->GetEntity()->GetAI()->Event(AIEVENT_PLAYER_STUNT_PUNCH, &AIevent);
			}
		}
	}

	bool ok = true;
	if(pTarget)
	{
		if(!gEnv->bMultiplayer && pActor && pActor->IsPlayer())
		{
			IActor* pAITarget = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTarget->GetId());
			if(pAITarget && pTarget->GetAI() && !pTarget->GetAI()->IsHostile(pActor->GetEntity()->GetAI(),false))
			{
				ok = false;
				m_noImpulse = true;
			}
		}

		if(ok)
		{
			CGameRules *pGameRules = g_pGame->GetGameRules();

			HitInfo info(m_pWeapon->GetOwnerId(), pTarget->GetId(), m_pWeapon->GetEntityId(),
				m_meleeparams.damage*damageScale*m_meleeScale, 0.0f, pGameRules->GetHitMaterialIdFromSurfaceId(surfaceIdx), partId,
				pGameRules->GetHitTypeId(m_meleeparams.hit_type.c_str()), pt, dir, normal);

			info.remote = remote;

			if (m_pWeapon->GetForcedHitMaterial() != -1)
				info.material=pGameRules->GetHitMaterialIdFromSurfaceId(m_pWeapon->GetForcedHitMaterial());

			pGameRules->ClientHit(info);
		}
	}

	// play effects
	if(ok)
	{
		IMaterialEffects* pMaterialEffects = gEnv->pGame->GetIGameFramework()->GetIMaterialEffects();

		TMFXEffectId effectId = pMaterialEffects->GetEffectId("melee", surfaceIdx);
		if (effectId != InvalidEffectId)
		{
			SMFXRunTimeEffectParams params;
			params.pos = pt;
			params.playflags = MFX_PLAY_ALL | MFX_DISABLE_DELAY;
			params.soundSemantic = eSoundSemantic_Player_Foley;
			pMaterialEffects->ExecuteEffect(effectId, params);
		}
	}

	ApplyCameraShake(true);

	m_pWeapon->PlayAction(m_meleeactions.hit.c_str());
}