Esempio n. 1
0
	void Serialize(SActivationInfo* pActInfo, TSerialize ser)
	{
		ser.Value("active", m_active);
		ser.Value("ammo", m_ammo);
		ser.Value("weaponId", m_weapId);

		if (ser.IsReading())
		{
			if (m_active && m_weapId != 0)
			{
				IItemSystem* pItemSys = CCryAction::GetCryAction()->GetIItemSystem();

				IItem* pItem = pItemSys->GetItem(m_weapId);

				if (!pItem || !pItem->GetIWeapon())
				{
					GameWarning("[flow] CFlowNode_WeaponListener: Serialize no item/weapon.");
					return;
				}
				IWeapon* pWeapon = pItem->GetIWeapon();
				// set weapon listener
				pWeapon->AddEventListener(this, "CFlowNode_WeaponListener");
				// CryLog("[flow] CFlowNode_WeaponListener::Serialize() successfully created on '%s'", pItem->GetEntity()->GetName());
			}
			else
			{
				Reset();
			}
		}
	}
Esempio n. 2
0
	void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo )
	{ 
		switch (event)
		{
		case (eFE_Activate):
			{
				if (!IsPortActive(pActInfo, 0))
					return;

				IItemSystem* pItemSys = CCryAction::GetCryAction()->GetIItemSystem();

				// get actor
				IActor* pActor = CCryAction::GetCryAction()->GetClientActor();
				if (!pActor) 
					return;

				IInventory *pInventory = pActor->GetInventory();
				if (!pInventory)
					return;

				IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(GetPortString(pActInfo,1));
				IItem* pItem = pItemSys->GetItem(pInventory->GetItemByClass(pClass));
				if (!pItem || !pItem->GetIWeapon())
				{
					pItem = pActor->GetCurrentItem();
					if (!pItem || pItem->GetEntity()->GetClass() != pClass || !pItem->GetIWeapon())
					{
						GameWarning("[flow] CFlowNode_WeaponAmmo: No item/weapon %s!", GetPortString(pActInfo,1).c_str());
						return;
					}
				}
				IWeapon *pWeapon = pItem->GetIWeapon();
				const string& ammoType = GetPortString(pActInfo,2);
				IEntityClass* pAmmoClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(ammoType.c_str());
				CRY_ASSERT(pAmmoClass);
				IFireMode* pCurrentFireMode = pWeapon->GetFireMode(pWeapon->GetCurrentFireMode());
				if (pCurrentFireMode)
				{
					int clipSize = pCurrentFireMode->GetClipSize();
					int ammo = pWeapon->GetAmmoCount(pAmmoClass) + GetPortInt(pActInfo,3);
					ammo = CLAMP(ammo, 0, clipSize);
					pWeapon->SetAmmoCount(pAmmoClass, ammo);
				}

				ActivateOutput(pActInfo, 0, pWeapon->GetAmmoCount(pAmmoClass));
			}
			break;
		}
	}
Esempio n. 3
0
bool CHeavyMountedWeapon::CanUse(EntityId userId) const
{
	EntityId ownerId = m_owner.GetId();

	if (m_rippedOff)
	{
		CActor* pActor = GetActor(userId);
		if (pActor && pActor->IsSwimming())
			return false;

		if (ownerId == 0 || ownerId == userId)
			return true;
	}
	else if(IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(userId))
	{
		IItem* pItem = pActor->GetCurrentItem(false);
		if(pItem)
		{
			if(pItem->IsBusy())
			{
				return false;
			}
			if(IWeapon* pWeapon = pItem->GetIWeapon())
			{
				if(pWeapon->IsReloading())
				{
					return false;
				}
			}
		}
	}

	return BaseClass::CanUse(userId);
}
//---------------------------------------------
CWeapon* CLaser::GetWeapon() const
{
	IItem* pParentItem = m_pItemSystem->GetItem(GetParentId());
	if(pParentItem == NULL)
		return 0;
	CWeapon* pParentWeapon = static_cast<CWeapon*>(pParentItem->GetIWeapon());
	return pParentWeapon;
}
Esempio n. 5
0
bool CBitmapUi::CanDrawCrosshair() const
{
	assert( m_pGameFramework != NULL );

	if ( ! g_pGameCVars->g_show_crosshair )
	{
		return false;
	}

	IActor* pPlayer = m_pGameFramework->GetClientActor();
	if ( pPlayer == NULL )
	{
		return false;
	}

	bool isPlayerDead = pPlayer->IsDead();
	if ( isPlayerDead )
	{
		return false;
	}

	bool thirdPersonMode = pPlayer->IsThirdPerson();
	bool crosshairEnabledInThirdPerson = ( g_pGameCVars->g_show_crosshair_tp != 0 );
	if ( thirdPersonMode && ! crosshairEnabledInThirdPerson )
	{
		return false;
	}

	IItem* pItem = pPlayer->GetCurrentItem();
	if ( pItem == NULL )
	{
		return false;
	}

	IWeapon* pWeapon = pItem->GetIWeapon();
	if ( pWeapon == NULL )
	{
		return false;
	}

	bool carryingMeleeWeapon = pWeapon->CanMeleeAttack();
	if ( carryingMeleeWeapon )
	{
		return false;
	}

	bool isWeaponZoomed = pWeapon->IsZoomed();
	bool usingWeaponSightForAiming = ( ! thirdPersonMode && isWeaponZoomed );		
	if ( usingWeaponSightForAiming )
	{
		return false;
	}

	return true;
}
Esempio n. 6
0
CWeapon* CFlashLight::GetWeapon() const
{
	IItem* pParentItem = m_pItemSystem->GetItem(GetParentId());

	if (pParentItem == NULL)
	{
		return 0;
	}

	CWeapon* pParentWeapon = static_cast<CWeapon*>(pParentItem->GetIWeapon());
	return pParentWeapon;
}
Esempio n. 7
0
CWeapon* CCinematicInput::GetWeapon(const CCinematicInput::Weapon& weaponClass) const
{
	assert( (weaponClass >= 0) && (weaponClass < eWeapon_ClassCount) );

	if (m_weapons[weaponClass].m_weaponId != 0)
	{
		IItem* pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(m_weapons[weaponClass].m_weaponId);
		return (pItem != NULL) ? static_cast<CWeapon*>(pItem->GetIWeapon()) : NULL;
	}

	return NULL;
}
Esempio n. 8
0
//---------------------------------------
void CMiscAnnouncer::RemoveWeaponListener(EntityId weaponId)
{
	DbgLog("CMiscAnnouncer::RemoveWeaponListener() weapon=%s", g_pGame->GetGameRules()->GetEntityName(weaponId));

	IItem* pItem = gEnv->pGame->GetIGameFramework()->GetIItemSystem()->GetItem(weaponId);
	if(pItem)
	{
		IWeapon *pWeapon = pItem->GetIWeapon();
		if(pWeapon)
		{
			pWeapon->RemoveEventListener(this);
		}
	}
}
Esempio n. 9
0
//------------------------------------------------------------------------
CWeapon *CScriptBind_Weapon::GetWeapon(IFunctionHandler *pH)
{
	void *pThis = pH->GetThis();

	if (pThis)
	{
		IItem *pItem = m_pGameFW->GetIItemSystem()->GetItem((EntityId)(UINT_PTR)pThis);
		if (pItem)
		{
			IWeapon *pWeapon=pItem->GetIWeapon();
			if (pWeapon)
				return static_cast<CWeapon *>(pWeapon);
		}
	}

	return 0;
}
//----------------------------------------------
void CC4Detonator::SelectC4()
{
	if (CActor *pOwner = GetOwnerActor())
	{
		EntityId c4Id = pOwner->GetInventory()->GetItemByClass(CItem::sC4Class);

		if (c4Id)
		{
			//Do not reselect C4 is there's no ammo
			IItem *pItem = m_pItemSystem->GetItem(c4Id);
			CWeapon *pWep = pItem ? static_cast<CWeapon *>(pItem->GetIWeapon()) : NULL;

			if(pWep && pWep->OutOfAmmo(false))
			{
				return;
			}

			pOwner->SelectItemByName("C4", false);
		}
	}
}
Esempio n. 11
0
//------------------------------------------------------
void CWeapon::ForcePendingActions(uint8 blockedActions)
{
	CItem::ForcePendingActions(blockedActions);

	CActor* pOwner = GetOwnerActor();
	if(!pOwner || !pOwner->IsClient())
		return;

	//Force start firing, if needed and possible
	if(m_requestedFire)
	{
		if(!IsDualWield() && !IsWeaponRaised())
		{
			m_requestedFire = false;
			OnAction(GetOwnerId(),"attack1",eAAM_OnPress,0.0f);
		}
		else if(IsDualWield() && IsDualWieldMaster())
		{
			IItem *slave = GetDualWieldSlave();
			if(!IsWeaponRaised())
			{
				m_requestedFire = false;
				OnAction(GetOwnerId(),"attack1",eAAM_OnPress,0.0f);
			}
			else if(slave && slave->GetIWeapon())
			{
				CWeapon* dualwield = static_cast<CWeapon*>(slave);
				if(!dualwield->IsWeaponRaised())
				{
					m_requestedFire = false;
					OnAction(GetOwnerId(),"attack1",eAAM_OnPress,0.0f);
				}
			}
		}
	}
}
Esempio n. 12
0
	void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo )
	{ 
		switch (event)
		{
		case eFE_Initialize:
			{
				m_actInfo = *pActInfo;
				Reset();
			}
			break;

		case eFE_Activate:
			{ 
				IItemSystem* pItemSys = CCryAction::GetCryAction()->GetIItemSystem();

				// create listener
				if (IsPortActive(pActInfo, IN_DISABLE))
				{ 
					Reset();
				}
				if (IsPortActive(pActInfo, IN_ENABLE))
				{ 
					Reset();
					IItem* pItem = 0;

					EntityId weaponId = GetPortEntityId(pActInfo, IN_WEAPONID);                    
					if (weaponId != 0)
					{
						pItem = pItemSys->GetItem(weaponId);
					}
					else
					{            
						IActor* pActor = CCryAction::GetCryAction()->GetClientActor();
						if (!pActor) 
							return;

						IInventory *pInventory = pActor->GetInventory();
						if (!pInventory)
							return;

						const string& weaponClass = GetPortString(pActInfo, IN_WEAPONCLASS);
						if (!weaponClass.empty())
						{
							// get actor weapon by class
							IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(weaponClass);
							pItem = pItemSys->GetItem( pInventory->GetItemByClass(pClass) );
						}
						else
						{
							// get current actor weapon
							pItem = pItemSys->GetItem(pInventory->GetCurrentItem());
						}
					}          

					if (!pItem || !pItem->GetIWeapon())
					{
						GameWarning("[flow] CFlowNode_WeaponListener: no item/weapon.");
						return;
					}

					m_weapId = pItem->GetEntity()->GetId();
					IWeapon* pWeapon = pItem->GetIWeapon();

					// set initial ammo
					m_ammo = GetPortInt(pActInfo, IN_AMMO);
					if (m_ammo == 0)
						m_ammo = -1; // 0 input means infinite

					// set weapon listener                            
					pWeapon->AddEventListener(this, "CFlowNode_WeaponListener");

					m_active = true;

					//CryLog("WeaponListener successfully created on %s", pItem->GetEntity()->GetName());
				}           
				break;
			}
		}
	}
Esempio n. 13
0
void CHUDCrosshair::Update(float fDeltaTime)
{
	if(m_bBroken)
		return;

	IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor();
	IItemSystem *pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem();
	
	if(!pClientActor || !pItemSystem)
		return;

	IInventory *pInventory = pClientActor->GetInventory();
	if(!pInventory)
		return;

  IItem *pItem = pItemSystem->GetItem(pInventory->GetCurrentItem());      
  IWeapon *pWeapon = NULL;
	IWeapon *pSlaveWeapon = NULL;
	const float fAlternateIronSight = 0.03f;
  
  if(pItem)
	{
		pWeapon = pItem->GetIWeapon();        

		if(pItem->IsDualWieldMaster())
		{
			if(IItem *pSlave=pItem->GetDualWieldSlave())
				pSlaveWeapon = pSlave->GetIWeapon();
		}
  }
  else if(IVehicle *pVehicle=pClientActor->GetLinkedVehicle())
  {
    pItem = pItemSystem->GetItem(pVehicle->GetCurrentWeaponId(pClientActor->GetEntityId()));
    if(pItem)
      pWeapon = pItem->GetIWeapon();
  }

	if(pWeapon)
	{
		float fMinSpread = 0.0f;
		float fMaxSpread = 0.0f;

		m_spread = 0.0f;

		if(IFireMode *pFireMode=pWeapon->GetFireMode(pWeapon->GetCurrentFireMode()))
		{
			fMinSpread = pFireMode->GetMinSpread();
			fMaxSpread = pFireMode->GetMaxSpread();

			m_spread = pFireMode->GetSpread();
		}

		if(pSlaveWeapon)
		{
			if(IFireMode *pSlaveFireMode=pSlaveWeapon->GetFireMode(pSlaveWeapon->GetCurrentFireMode()))
			{
				fMinSpread += pSlaveFireMode->GetMinSpread();
				fMaxSpread += pSlaveFireMode->GetMaxSpread();

				m_spread += pSlaveFireMode->GetSpread();
			}
		}

		CPlayer *pPlayer = static_cast<CPlayer*>(pClientActor);
		if(pPlayer && pPlayer->GetNanoSuit() && pPlayer->GetNanoSuit()->GetMode() == NANOMODE_STRENGTH)
			m_spread *=0.5;

		if(g_pGameCVars->hud_iAlternateCrosshairSpread)
		{
			if(m_spread < fMinSpread)
				m_spread = min(m_spread,g_pGameCVars->hud_fAlternateCrosshairSpreadCrouch) / g_pGameCVars->hud_fAlternateCrosshairSpreadCrouch;
			else
				m_spread = min(m_spread,g_pGameCVars->hud_fAlternateCrosshairSpreadNeutral) / g_pGameCVars->hud_fAlternateCrosshairSpreadNeutral;
		}
		else
		{
			m_spread = min((m_spread-fMinSpread),15.0f) / 15.0f;

			IZoomMode *pZoomMode = pWeapon->GetZoomMode(pWeapon->GetCurrentZoomMode());
			if(pZoomMode && !pZoomMode->IsToggle() && (pZoomMode->IsZoomed() || pZoomMode->IsZooming()))
			{
				m_spread -= fAlternateIronSight;
			}
			else
			{
				m_spread = min(m_spread,1.0f);
				m_spread = max(m_spread,0.0f);
			}
		}
	}

	if(m_animCrossHair.GetVisible() && !g_pHUD->InSpectatorMode())
	{
		//also disables the damage indicator
		if(/*g_pGameCVars->hud_crosshair>0 && m_iCrosshair > 0 &&*/ (g_pGameCVars->g_difficultyLevel<4 || gEnv->bMultiplayer))
		{
			m_animCrossHair.GetFlashPlayer()->Advance(fDeltaTime);
			m_animCrossHair.GetFlashPlayer()->Render();
		}

		if(m_animInterActiveIcons.GetVisible()) //if the crosshair is invisible, the use icon should be too
		{
			if(!m_bHideUseIconTemp)	//hides the icon, when something is already grabbed/being used
			{
				m_animInterActiveIcons.GetFlashPlayer()->Advance(fDeltaTime);
				m_animInterActiveIcons.GetFlashPlayer()->Render();
			}
		}
	}

	if(m_animFriendCross.GetVisible())
	{
		m_animFriendCross.GetFlashPlayer()->Advance(fDeltaTime);
		m_animFriendCross.GetFlashPlayer()->Render();
	}

	if(!g_pGameCVars->hud_iAlternateCrosshairSpread)
	{
		m_spread = max(m_spread,-fAlternateIronSight);
		m_spread = min(m_spread,1.0f);
	}

	if (m_smoothSpread != m_spread)
	{
		Interpolate(m_smoothSpread, m_spread, 20.0f, fDeltaTime);
		m_animCrossHair.Invoke("setRecoil", m_smoothSpread);
	}

	UpdateCrosshair();
}
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;
}
Esempio n. 15
0
//-----------------------------------------------------------------------
bool CSpectacularKill::StartOnTarget(CActor* pTargetActor)
{
	FUNCTION_PROFILER(gEnv->pSystem, PROFILE_GAME);

	CRY_ASSERT(pTargetActor);
	CRY_ASSERT_MESSAGE(!IsBusy(), "spectacular kill should not be initiated while a spectacular kill is already in progress");

	SSpectacularKillAnimation anim;
	if (!IsBusy() && pTargetActor && GetValidAnim(pTargetActor, anim) && CanExecuteOnTarget(pTargetActor, anim))
	{
		// Disable AI
		if (!pTargetActor->IsPlayer() && pTargetActor->GetEntity()->GetAI())
			pTargetActor->GetEntity()->GetAI()->Event(AIEVENT_DISABLE, 0);

		if (!m_pOwner->IsPlayer() && m_pOwner->GetEntity()->GetAI())
			m_pOwner->GetEntity()->GetAI()->Event(AIEVENT_DISABLE, 0);

		// make sure they aren't firing when the anim starts
		{
			IItem* pItem = pTargetActor->GetCurrentItem();
			IWeapon* pWeapon = pItem ? pItem->GetIWeapon() : NULL;
			if (pWeapon)
				pWeapon->StopFire();
		}
		{
			IItem* pItem = m_pOwner->GetCurrentItem();
			IWeapon* pWeapon = pItem ? pItem->GetIWeapon() : NULL;
			if (pWeapon)
				pWeapon->StopFire();
		}

		SActorStats* pStats = m_pOwner->GetActorStats();
		if(pStats)
		{
			pStats->spectacularKillPartner = pTargetActor->GetEntityId();
		}

		SActorStats* pTargetStats = pTargetActor->GetActorStats();
		if(pTargetStats)
		{
			pTargetStats->spectacularKillPartner = m_pOwner->GetEntityId();
		}

		const float slideTime = 0.2f;

		const char* pKillerAnim = anim.killerAnimation.c_str();
		const char* pVictimAnim = anim.victimAnimation.c_str();

		SCharacterParams killerParams(m_pOwner->GetAnimatedCharacter(), pKillerAnim, /*allowHPhysics*/false, slideTime);
		SCharacterParams targetParams(pTargetActor->GetAnimatedCharacter(), pVictimAnim, /*allowHPhysics*/false, slideTime);
		SCooperativeAnimParams animParams(/*forceStart*/true, /*looping*/ false, /*alignment*/ /*eAF_FirstActorNoRot*/eAF_FirstActor);
		animParams.bIgnoreCharacterDeath = true;
		animParams.bPreventFallingThroughTerrain = false;
		animParams.bNoCollisionsBetweenFirstActorAndRest = true;

		ICooperativeAnimationManager* pCooperativeAnimationManager = gEnv->pGame->GetIGameFramework()->GetICooperativeAnimationManager();
		bool bStarted = pCooperativeAnimationManager->StartNewCooperativeAnimation(killerParams, targetParams, animParams);
		if (bStarted)
		{
			m_targetId = pTargetActor->GetEntityId();
			m_isBusy = true;

			// Register the killing
			s_lastKillInfo.killerAnim = pKillerAnim;
			s_lastKillInfo.timeStamp = gEnv->pTimer->GetFrameStartTime().GetSeconds();

#ifndef _RELEASE
			// Clean persistant debug information
			IPersistantDebug* pPersistantDebug = BeginPersistantDebug();

			// Send telemetry event
			CStatsRecordingMgr* pRecordingMgr = g_pGame->GetStatsRecorder();
			IStatsTracker* pTracker = pRecordingMgr ? pRecordingMgr->GetStatsTracker(m_pOwner) : NULL;
			if (pTracker)
			{
				EGameStatisticEvent eventType = eGSE_SpectacularKill;

				if(pRecordingMgr->ShouldRecordEvent(eventType, m_pOwner))
				{
					pTracker->Event(eventType, (anim.killerAnimation + " -> " + anim.victimAnimation).c_str()); 
				}
			}
#endif

			return true;
		}
	}

	return false;
}
Esempio n. 16
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;
}
//////////////////////////////////////////////////////////////////////////
// IsMountedWeaponUsableWithTarget
// A piece of game-code moved from CryAction when scriptbind_AI moved to the AI system
//////////////////////////////////////////////////////////////////////////
int CScriptBind_Game::IsMountedWeaponUsableWithTarget(IFunctionHandler *pH)
{
	int paramCount = pH->GetParamCount();
	if(paramCount<2)
	{
		GameWarning("%s: too few parameters.", __FUNCTION__);
		return pH->EndFunction();
	}

	GET_ENTITY(1);

	if(!pEntity)
	{
		GameWarning("%s: wrong entity id in parameter 1.", __FUNCTION__);
		return pH->EndFunction();
	}

	IAIObject* pAI = pEntity->GetAI();
	if (!pAI)
	{
		GameWarning("%s: Entity '%s' does not have AI.",__FUNCTION__,  pEntity->GetName());
		return pH->EndFunction();
	}

	EntityId itemEntityId;
	ScriptHandle hdl2;

	if(!pH->GetParam(2,hdl2))
	{
		GameWarning("%s: wrong parameter 2 format.", __FUNCTION__);
		return pH->EndFunction();
	}

	itemEntityId = (EntityId)hdl2.n;

	if (!itemEntityId)
	{
		GameWarning("%s: wrong entity id in parameter 2.", __FUNCTION__);
		return pH->EndFunction();
	}
	
	IGameFramework *pGameFramework = gEnv->pGame->GetIGameFramework();
	IItem* pItem = pGameFramework->GetIItemSystem()->GetItem(itemEntityId);
	if (!pItem)
	{
		//gEnv->pAISystem->Warning("<CScriptBind> ", "entity in parameter 2 is not an item/weapon");
		GameWarning("%s: entity in parameter 2 is not an item/weapon.", __FUNCTION__);
		return pH->EndFunction();
	}

	float minDist = 7;
	bool bSkipTargetCheck = false;
	Vec3 targetPos(ZERO);

	if(paramCount > 2)
	{
		for(int i=3;i <= paramCount ; i++)
		{
			if(pH->GetParamType(i) == svtBool)
				pH->GetParam(i,bSkipTargetCheck);
			else if(pH->GetParamType(i) == svtNumber)
				pH->GetParam(i,minDist);
			else if(pH->GetParamType(i) == svtObject)
				pH->GetParam(i,targetPos);
		}
	}

	IAIActor* pAIActor = CastToIAIActorSafe(pAI);
	if (!pAIActor)
	{
		GameWarning("%s: entity '%s' in parameter 1 is not an AI actor.", __FUNCTION__, pEntity->GetName());
		return pH->EndFunction();
	}


	IEntity* pItemEntity = pItem->GetEntity();
	if(!pItemEntity)
		return pH->EndFunction();


	if(!pItem->GetOwnerId())
	{
		// weapon is not used, check if it is on a vehicle
		IEntity* pParentEntity = pItemEntity->GetParent();
		if(pParentEntity)
		{
			IAIObject* pParentAI = pParentEntity->GetAI();
			if(pParentAI && pParentAI->GetAIType()==AIOBJECT_VEHICLE)
			{
				// (MATT) Feature was cut and code was tricky, hence ignore weapons in vehicles  {2008/02/15:11:08:51}
				return pH->EndFunction();
			}
		}
	}
	else if( pItem->GetOwnerId()!= pEntity->GetId()) // item is used by someone else?
		return pH->EndFunction(false);

	// check target
	if(bSkipTargetCheck)
		return pH->EndFunction(true);

	IAIObject* pTarget = pAIActor->GetAttentionTarget();
	if(targetPos.IsZero())
	{
		if(!pTarget)
			return pH->EndFunction();
		targetPos = pTarget->GetPos();
	}

	Vec3 targetDir(targetPos - pItemEntity->GetWorldPos());
	Vec3 targetDirXY(targetDir.x, targetDir.y, 0);

	float length2D = targetDirXY.GetLength();
	if(length2D < minDist || length2D<=0)
		return pH->EndFunction();

	targetDirXY /= length2D;//normalize

	IWeapon* pWeapon = pItem->GetIWeapon(); 
	bool vehicleGun = pWeapon && pWeapon->GetHostId();

	if (!vehicleGun)
	{
		Vec3 mountedAngleLimits(pItem->GetMountedAngleLimits());

		float yawRange = DEG2RAD(mountedAngleLimits.z);
		if(yawRange > 0 && yawRange < gf_PI)
		{
			float deltaYaw = pItem->GetMountedDir().Dot(targetDirXY);
			if(deltaYaw < cosf(yawRange))
				return pH->EndFunction(false);
		}

		float minPitch = DEG2RAD(mountedAngleLimits.x);
		float maxPitch = DEG2RAD(mountedAngleLimits.y);

		//maxPitch = (maxPitch - minPitch)/2;
		//minPitch = -maxPitch;

		float pitch = atanf(targetDir.z / length2D);

		if ( pitch < minPitch || pitch > maxPitch )
			return pH->EndFunction(false);
	}

	if(pTarget)
	{
		IEntity* pTargetEntity = pTarget->GetEntity();
		if(pTargetEntity)
		{
			// check target distance and where he's going
			IPhysicalEntity *phys = pTargetEntity->GetPhysics();
			if(phys)
			{
				pe_status_dynamics	dyn;
				phys->GetStatus(&dyn);
				Vec3 velocity ( dyn.v);
				velocity.z = 0;

				float speed = velocity.GetLength2D();
				if(speed>0)
				{
					//velocity /= speed;
					if(length2D< minDist * 0.75f && velocity.Dot(targetDirXY)<=0)
						return pH->EndFunction(false);
				}
			}
		}
	}
	return pH->EndFunction(true);

}
Esempio n. 18
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;
		}

	}
}
Esempio n. 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;
}
Esempio n. 20
0
//
// Extract the various modifiers out into their own function.
//
// Aim is to make the code easier to understand and modify, as 
// well as to ease the addition of new modifiers.
//
void CPlayerView::ViewFirstPerson(SViewParams &viewParams)
{
		//headbob
		Ang3 angOffset(0,0,0);
		Vec3 weaponOffset(0,0,0);
		Ang3 weaponAngleOffset(0,0,0);

		// jump/land spring effect. Adjust the eye and weapon pos as required.
		FirstPersonJump(viewParams,weaponOffset,weaponAngleOffset);

		//float standSpeed(GetStanceMaxSpeed(STANCE_STAND));

		Vec3 vSpeed(0,0,0);
		if (m_in.standSpeed>0.001f)
			vSpeed = (m_in.stats_velocity / m_in.standSpeed);

		float vSpeedLen(vSpeed.len());
		if (vSpeedLen>1.5f)
			vSpeed = vSpeed / vSpeedLen * 1.5f;

		float speedMul(0);
		if (m_in.standSpeed>0.001f)
			speedMul=(m_in.stats_flatSpeed / m_in.standSpeed * 1.1f);

		speedMul = min(1.5f,speedMul);

		bool crawling(m_in.stance==STANCE_PRONE /*&& m_in.stats_flatSpeed>0.1f*/ && m_in.stats_onGround>0.1f);
		bool weaponZoomed = false;
		bool weaponZomming = false;

		//Not crawling while in zoom mode
		IActor *owner = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.entityId);
		if(owner && owner->IsPlayer())
		{
			IItem *pItem = owner->GetCurrentItem();
			if(pItem)
			{
				CWeapon *pWeapon = static_cast<CWeapon*>(pItem->GetIWeapon());
				if(pWeapon)
				{
					weaponZoomed = pWeapon->IsZoomed();
					weaponZomming = pWeapon->IsZooming();
					if(weaponZoomed||weaponZomming||pWeapon->IsModifying())
						crawling = false;
				}
			}
		}
	
		// On the ground.
		if (m_in.stats_inAir < 0.1f /*&& m_in.stats_inWater < 0.1f*/)
		{
			//--- Bobbing.
			// bobCycle is a speed varying time step running (looping) from 0 to 1 
			// this feeds into a sin eqn creating a double horizontal figure of 8.
			// ( a lissajous figure with the vertical freq twice the horz freq ).

			// To tweak the total speed of the curve:

			// To tweak the effect speed has on the curve:
			float kSpeedToBobFactor=1.15f;//0.9f
			// To tweak the width of the bob:
			float kBobWidth=0.1f;
			// To tweak the height of the bob:
			float kBobHeight=0.05f;
			// To tweak the scale of strafing lag: (may need to manually adjust the strafing angle offsets as well.)
			const float kStrafeHorzScale=0.05f;

			kBobWidth = 0.15f;
			kBobHeight = 0.06f;

			m_io.stats_bobCycle += m_in.frameTime * kSpeedToBobFactor * speedMul;// * (m_in.bSprinting?1.25f:1.0f);

			//if player is standing set the bob to rest. (bobCycle reaches 1.0f within 1 second)
			if (speedMul < 0.1f)
				m_io.stats_bobCycle = min(m_io.stats_bobCycle + m_in.frameTime * 1.0f,1.0f);

			// bobCycle loops between 0 and 1
			if (m_io.stats_bobCycle>1.0f)
				m_io.stats_bobCycle = m_io.stats_bobCycle - 1.0f;

			if (crawling)
				kBobWidth *= 2.0f * speedMul;
			else if (m_in.bSprinting)
				kBobWidth *= 1.25f * speedMul;

			//set the bob offset
			Vec3 bobDir(cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f)*kBobWidth*speedMul,0,cry_sinf(m_io.stats_bobCycle*gf_PI*4.0f)*kBobHeight*speedMul);
						
			//not the bob offset for the weapon
			bobDir *= 0.25f;
			//if player is strafing shift a bit the weapon on left/right
			if (speedMul > 0.01f)
			{
				// right vector dot speed vector
				float dot(m_io.viewQuatFinal.GetColumn0() * vSpeed);

				bobDir.x -= dot * kStrafeHorzScale;	// the faster we move right, the more the gun lags to the left and vice versa

				//tweak the right strafe for weapon laser
				if (dot>0.0f)
					weaponAngleOffset.z += dot * 1.5f;	// kStrafeHorzScale
				else
					weaponAngleOffset.z -= dot * 2.0f;	// kStrafeHorzScale

				weaponAngleOffset.y += dot * 5.0f;		// kStrafeHorzScale
			}
			//CryLogAlways("bobDir.z: %f", bobDir.z);
			if (bobDir.z < 0.0f)
			{
				bobDir.x *= 1.0f;
				bobDir.y *= 1.0f;
				bobDir.z *= 0.35f;
				speedMul *= 0.65f;
			}
			else
				bobDir.z *= 1.85f;

			//CryLogAlways("bobDir.z: %f after", bobDir.z);
			weaponOffset += m_io.viewQuatFinal * bobDir;
			weaponOffset -= m_io.baseQuat.GetColumn2() * 0.035f * speedMul;

			weaponAngleOffset.y += cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f) * speedMul * -1.5f;
			if (crawling)
				weaponAngleOffset.y *= 3.0f;

			weaponAngleOffset.x += speedMul * 1.5f;
			if (crawling)
				weaponAngleOffset.z += cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f) * speedMul * 3.0f;

			//FIXME: viewAngles must include all the view offsets, otherwise aiming wont be precise.
			angOffset.x += cry_sinf(m_io.stats_bobCycle*gf_PI*4.0f)*0.7f*speedMul;

			if (crawling)
			{
				angOffset.x *= 2.5f;
				angOffset.y += cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f)*1.25f*speedMul;
				angOffset.z -= cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f)*2.5f*speedMul;

			}
			else if (m_in.bSprinting)
			{
				angOffset.x *= 2.5f;
				angOffset.y += cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f)*1.0f*speedMul;
				angOffset.z -= cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f)*2.25f*speedMul;
			}
			else if(m_in.stance==STANCE_CROUCH && !weaponZoomed && !weaponZomming)
			{
				weaponOffset.z   += 0.035f;
				weaponOffset.y   -= m_io.viewQuatFinal.GetColumn1().y * 0.03f;
			}
			else if(m_in.stance==STANCE_CROUCH && weaponZomming)
			{
				weaponOffset.z	-= 0.07f;
				weaponOffset.y	+=  m_io.viewQuatFinal.GetColumn1().y * 0.06f;
			}
			else
			{
				//angOffset.x *= 2.25f;
				//angOffset.y += cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f)*0.5f*speedMul;
				//angOffset.z -= cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f)*1.125f*speedMul;
			}
		}
		else
		{
			m_io.stats_bobCycle = 0;

			//while flying offset a bit the weapon model by the player speed	
			if (m_in.stats_velocity.len2()>0.001f)
			{				
				float dotFwd(m_io.viewQuatFinal.GetColumn1() * vSpeed);
				float dotSide(m_io.viewQuatFinal.GetColumn0() * vSpeed);
				float dotUp(m_io.viewQuatFinal.GetColumn2() * vSpeed);

				weaponOffset += m_io.viewQuatFinal * Vec3(dotSide * -0.05f,dotFwd * -0.035f,dotUp * -0.05f);

				weaponAngleOffset.x += dotUp * 2.0f;
				weaponAngleOffset.y += dotSide * 5.0f;
				weaponAngleOffset.z -= dotSide * 2.0f;
			}
		}

		//add some inertia to weapon due view direction change.
		float deltaDotSide(m_io.vFPWeaponLastDirVec * m_io.viewQuatFinal.GetColumn0());
		float deltaDotUp(m_io.vFPWeaponLastDirVec * m_io.viewQuatFinal.GetColumn2());

		weaponOffset += m_io.viewQuatFinal * Vec3(deltaDotSide * 0.1f + m_in.stats_leanAmount * 0.05f,0,deltaDotUp * 0.1f - fabs(m_in.stats_leanAmount) * 0.05f) * m_in.params_weaponInertiaMultiplier;

		weaponAngleOffset.x -= deltaDotUp * 5.0f * m_in.params_weaponInertiaMultiplier;
		weaponAngleOffset.z += deltaDotSide * 5.0f * m_in.params_weaponInertiaMultiplier;
		weaponAngleOffset.y += deltaDotSide * 5.0f * m_in.params_weaponInertiaMultiplier;

		if(m_in.stats_leanAmount<0.0f)
			weaponAngleOffset.y += m_in.stats_leanAmount * 5.0f;

		//the weapon model tries to stay parallel to the terrain when the player is freefalling/parachuting

		if (m_in.stats_inWater > 0.0f)
			weaponOffset -= m_io.viewQuat.GetColumn2() * 0.15f;

		if (m_in.stats_inWater>0.1f && !m_in.stats_headUnderWater)
		{
			Ang3 offset(m_io.viewQuatFinal);
			offset.z = 0;
			if (offset.x<0.0f)
				offset.x = 0;

			weaponAngleOffset -= offset*(180.0f/gf_PI)*0.75f;
		}
		else if (m_io.stats_inFreefall)
		{
			Ang3 offset(m_io.viewQuatFinal);
			offset.z = 0;

			weaponAngleOffset -= offset*(180.0f/gf_PI)*0.5f;
		}
		//same thing with crawling
		else if (crawling)
		{
			//FIXME:to optimize, looks like a bit too expensive
			Vec3 forward(m_io.viewQuatFinal.GetColumn1());
			Vec3 up(m_io.baseQuat.GetColumn2());
			Vec3 right(-(up % forward));

			Matrix33 mat;
			mat.SetFromVectors(right,up%right,up);
			mat.OrthonormalizeFast();

			Ang3 offset(m_io.viewQuatFinal.GetInverted() * Quat(mat));

			weaponAngleOffset += offset*(180.0f/gf_PI)*0.5f;

			float lookDown(m_io.viewQuatFinal.GetColumn1() * m_io.baseQuat.GetColumn2());
			weaponOffset += m_io.baseQuat * Vec3(0,-0.5f*max(-lookDown,0.0f),-0.05f);

			float scale = 0.5f;;
			if(weaponAngleOffset.x>0.0f)
			{
				scale = min(0.5f,weaponAngleOffset.x/15.0f);
				weaponAngleOffset.x *= scale;
			}
			else
			{
				scale = min(0.5f,-weaponAngleOffset.x/20.0f);
				weaponAngleOffset *= (1.0f-scale);
				weaponOffset *= scale;
			}
			//if(vSpeedLen>0.1f)
				//weaponAngleOffset += Ang3(-8.0f,0,-12.5f);
			
		}
		else if (m_in.bSprinting && vSpeedLen>0.5f)
		{
			weaponAngleOffset += Ang3(-20.0f,0,10.0f);
			weaponOffset += m_io.viewQuatFinal * Vec3(0.0f, -.01f, .1f);
		}
		else if (m_in.bLookingAtFriendlyAI && !weaponZomming && !weaponZoomed)
		{
			weaponAngleOffset += Ang3(-15.0f,0,8.0f);
			weaponOffset += m_io.viewQuatFinal * Vec3(0.0f, -.01f, .05f);
		}

		//apply some multipliers
		weaponOffset *= m_in.params_weaponBobbingMultiplier;
		angOffset *= m_io.bobMul * 0.25f;
		if (m_io.bobMul*m_io.bobMul!=1.0f)
		{
			weaponOffset *= m_io.bobMul;
			weaponAngleOffset *= m_io.bobMul;
		}

		float bobSpeedMult(1.0f);
		if(m_in.stats_inWater>0.1)
			bobSpeedMult = 0.75f;
//		m_io.viewQuatForWeapon *= Quat::CreateRotationXYZ(Ang3(rx,ry,rz));
		
		Interpolate(m_io.vFPWeaponOffset,weaponOffset,3.95f*bobSpeedMult,m_in.frameTime);
		Interpolate(m_io.vFPWeaponAngleOffset,weaponAngleOffset,10.0f*bobSpeedMult,m_in.frameTime);
		Interpolate(m_io.vFPWeaponLastDirVec,m_io.viewQuatFinal.GetColumn1(),5.0f*bobSpeedMult,m_in.frameTime);

		Interpolate(m_io.angleOffset,angOffset,10.0f,m_in.frameTime,0.002f);
		if(weaponZomming)
		{
			m_io.vFPWeaponLastDirVec = m_io.viewQuatFinal.GetColumn1();
			m_io.vFPWeaponOffset.Set(0.0f,0.0f,0.0f);
			m_io.vFPWeaponAngleOffset.Set(0.0f,0.0f,0.0f);
			m_io.bobOffset.Set(0.0f,0.0f,0.0f);
		}

		if (m_in.bSprinting)
		{
			float headBobScale = (m_in.stats_flatSpeed / m_in.standSpeed);
			headBobScale = min(1.0f, headBobScale);

			m_io.bobOffset = m_io.vFPWeaponOffset * 2.5f * g_pGameCVars->cl_headBob * headBobScale;
			float bobLenSq = m_io.bobOffset.GetLengthSquared();
			float bobLenLimit = g_pGameCVars->cl_headBobLimit;
			if (bobLenSq > bobLenLimit*bobLenLimit)
			{
				float bobLen = sqrt_tpl(bobLenSq);
				m_io.bobOffset *= bobLenLimit/bobLen;
			}
			viewParams.position += m_io.bobOffset;
		}
}
Esempio n. 21
0
void CPlayerView::ViewThirdPerson(SViewParams &viewParams)
{
	if (m_in.thirdPersonYaw>0.001f)
	{
		viewParams.rotation *= Quat::CreateRotationXYZ(Ang3(0,0,m_in.thirdPersonYaw * gf_PI/180.0f));
		m_io.viewQuatFinal = viewParams.rotation;
	}

	if (g_pGameCVars->goc_enable)
	{
		Vec3 target(g_pGameCVars->goc_targetx, g_pGameCVars->goc_targety, g_pGameCVars->goc_targetz);
		static Vec3 current(target);

		Interpolate(current, target, 5.0f, m_in.frameTime);

		// make sure we don't clip through stuff that much
		Vec3 offsetX(0,0,0);
		Vec3 offsetY(0,0,0);
		Vec3 offsetZ(0,0,0);
		offsetX = m_io.viewQuatFinal.GetColumn0() * current.x;
		offsetY = m_io.viewQuatFinal.GetColumn1() * current.y;
		offsetZ = m_io.viewQuatFinal.GetColumn2() * current.z;

		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);
			}

			float oldLen = offsetY.len();

			Vec3 start = m_io.baseQuat * m_io.eyeOffsetView + viewParams.position+offsetX+offsetZ;
			if (gEnv->pPhysicalWorld->RayWorldIntersection(start, offsetY, ent_static|ent_terrain|ent_rigid,
				rwi_ignore_noncolliding | rwi_stop_at_pierceable, &hit, 1, pSkipEntities, nSkip))
			{
				offsetY = hit.pt - start;
				if (offsetY.len()> 0.25f)
				{
					offsetY -= offsetY.GetNormalized()*0.25f;
				}
				current.y = current.y * (hit.dist/oldLen);
			}
		}
		
		//viewParams.position += m_io.viewQuatFinal.GetColumn0() * current.x;		// right 
		//viewParams.position += m_io.viewQuatFinal.GetColumn1() * current.y;	// back
		//viewParams.position += m_io.viewQuatFinal.GetColumn2() * current.z;	// up
		viewParams.position += offsetX + offsetY + offsetZ;
	}
	else
	{
	if (m_io.bUsePivot)			
		viewParams.position += m_io.viewQuatFinal.GetColumn1() * m_in.params_viewDistance + m_io.viewQuatFinal.GetColumn2() * (0.25f + m_in.params_viewHeightOffset);
	else
		{
		viewParams.position += m_io.viewQuatFinal.GetColumn1() * -m_in.thirdPersonDistance + m_io.viewQuatFinal.GetColumn2() * (0.25f + m_in.params_viewHeightOffset);
}
	}
}
Esempio n. 22
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;
}
Esempio n. 23
0
void CGameStateRecorder::OnRecordedGameplayEvent(IEntity *pEntity, const GameplayEvent &event, int currentFrame, bool bRecording)
{
	EntityId id;
	m_currentFrame = currentFrame;

	int demo_forceGameState = 0;
	if(!bRecording)
	{
		ICVar *pVar = gEnv->pConsole->GetCVar( "demo_force_game_state" );
		if(pVar)
			demo_forceGameState = pVar->GetIVal();
	}
	
	if(!pEntity || !(id = pEntity->GetId()))
		return;

	if(m_IgnoredEvents.size())
		if(event.event == m_IgnoredEvents[0])
		{
			m_IgnoredEvents.erase(m_IgnoredEvents.begin());
			return;
		}

		TGameStates::iterator itActor = m_GameStates.find(id);
	if(itActor == m_GameStates.end())
	{
		m_GameStates.insert(std::make_pair(id,SActorGameState()));
		itActor = m_GameStates.find(id);
	}
	if(itActor == m_GameStates.end())
	{
		GameWarning("TimeDemo:GameState: actor %s not found in records",pEntity->GetName());
		return;
	}

	SActorGameState& gstate = itActor->second;

	switch(event.event)
	{
		case eGE_HealthChanged: 
			{
				gstate.health = event.value;

				if(!m_bRecording)
				{
					CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id));
					if(pActor)
					{
						if(m_bLogWarning)
						{
							if(CHECK_MISMATCH(pActor->GetHealth(), gstate.health,10))
							{
								if(!gstate.bHealthDifferent)
								{
									GameWarning("TimeDemo:GameState: Frame %d - Actor %s - HEALTH mismatch (%d, %d)",m_currentFrame,pEntity->GetName(), static_cast<int>(pActor->GetHealth()), static_cast<int>(gstate.health));
									gstate.bHealthDifferent = true;
								}
							}
							else
								gstate.bHealthDifferent = false;
						}

						if( demo_forceGameState)
							pActor->SetHealth(gstate.health);
					}
				}
			}
			break;

		case eGE_WeaponFireModeChanged:
			{
				TItemName sel = (event.description);
				if(sel)
				{
					TItemContainer& Items = gstate.Items;
					TItemContainer::iterator iti = Items.find(sel);
					uint8 recFireModeIdx = uint8(event.value);
					if(iti != Items.end())
						iti->second.fireMode = recFireModeIdx;

					CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id));
					if(pActor && pActor->GetInventory())
					{
						IItem* pItem = pActor->GetInventory()->GetItemByName(sel);
						CWeapon* pWeapon;
						if(pItem && (pWeapon = (CWeapon*)(pItem->GetIWeapon())))
						{

						int fireModeIdx = pWeapon->GetCurrentFireMode();
						if(m_bLogWarning)
							{
									CheckDifference(recFireModeIdx,fireModeIdx,"TimeDemo:GameState: Frame %d - Actor %s - FIRE MODE mismatch for weapon %s (rec:%d, cur:%d)",pEntity,pItem->GetEntity() ? pItem->GetEntity()->GetName() : "(null)");
							}

							if(demo_forceGameState==2 && fireModeIdx!= recFireModeIdx)
								pWeapon->SetCurrentFireMode(recFireModeIdx);
						}
					}
				}
			}
			break;

		case eGE_WeaponReload:
			{
				const char* ammoType = event.description;
				TAmmoContainer& ammoMags = gstate.AmmoMags;
				TAmmoContainer::iterator it = ammoMags.find(ammoType);
				if(it!=ammoMags.end())
				{
					it->second -= (uint16)event.value;
				
					CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id));
					if(pActor)
					{
						CInventory* pInventory = (CInventory*)(pActor->GetInventory());
						if(pInventory)
						{
							{
								IEntityClass* pAmmoClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(ammoType);
								if(pAmmoClass)
								{
									if(m_bLogWarning)
										CheckDifference(it->second,pInventory->GetAmmoCount(pAmmoClass),"TimeDemo:GameState: Frame %d - Actor %s - WEAPON RELOAD, ammo count mismatch for ammo class %s (rec:%d, cur:%d)",pEntity,ammoType);
		
									if(demo_forceGameState == 2)
										pInventory->SetAmmoCount(pAmmoClass,it->second);
								}
							}
						}
					}
				}
			}
			break;

		case eGE_ItemSelected:
			{
				TItemName itemName = event.description;
				gstate.itemSelected = itemName;
				if(itemName)
				{
					if( !bRecording && (event.value > 0 || demo_forceGameState==2)) // EVENT.VALUE > 0 means initialization
					{
						CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id));
						if(pActor && pActor->GetInventory())
						{
							IItem* pItem = pActor->GetInventory()->GetItemByName(itemName);
							if(pItem)
								pActor->SelectItem(pItem->GetEntityId(),false);
						}
					}
				}

				if(m_bLogWarning)
				{	
					CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id));
					if(pActor)
					{
						IItem* pItem = pActor->GetCurrentItem();
						const char* curItemName= pItem && pItem->GetEntity() ? pItem->GetEntity()->GetName(): NULL;
						CheckDifferenceString(itemName,curItemName,"TimeDemo:GameState: Frame %d - Actor %s - SELECTED ITEM mismatch (rec:%s, cur:%s)",pEntity);
					}
				}
				break;
			}
			break;

		case eGE_ItemExchanged:
			{
				// prevent unwanted record/play mismatch error with current item during item exchanging
				// two unneeded game events are sent (selecting fists)
				m_IgnoredEvents.push_back(eGE_ItemSelected);
				m_IgnoredEvents.push_back(eGE_ItemSelected);
			}
			break;

		case eGE_ItemPickedUp:
			{
				TItemName sel = (TItemName)event.description;
//				gstate.itemSelected = sel;
				TItemContainer& Items = gstate.Items;
				TItemContainer::iterator it = Items.find(sel);
				if(it == Items.end())
				{
					Items.insert(std::make_pair(sel,SItemProperties()));
					it = Items.find(sel);
				}

				if(it != Items.end())
				{
					it->second.count++;

					CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id));
					if(pActor && !m_bRecording)
					{
						CInventory* pInventory = (CInventory*)(pActor->GetInventory());
						if(pInventory)
						{
							// just check if the item is the inventory
							if(m_bLogWarning && !pInventory->GetItemByName(sel))
								GameWarning("TimeDemo:GameState: Frame %d - Actor %s - Recorded PICKED UP ITEM class '%s' not found in current inventory",m_currentFrame,pEntity->GetName(),sel);

							if(demo_forceGameState == 2)
							{
								IEntity* pItemEntity = gEnv->pEntitySystem->FindEntityByName(sel);
								if(pItemEntity)
									pInventory->AddItem(pItemEntity->GetId());
								else
									GameWarning("TimeDemo:GameState: Frame %d - Actor %s - PICKED UP ITEM entity %s not found in level",m_currentFrame,pEntity->GetName(),sel);
							}
						}
					}
				}
				else if(m_bLogWarning)
				{
					if(!sel)
						sel = "(null)";
					GameWarning("TimeDemo:GameState: Frame %d - Actor %s - PICKED UP ITEM %s not found in recorded inventory",m_currentFrame,pEntity->GetName(),sel);
				}

			}
			break;

		case eGE_AmmoPickedUp:
			{
				uint16 ammoCount = (uint16)(event.value);
				TItemName sel = (TItemName)event.description;
				TAmmoContainer& Ammo = gstate.AmmoMags;

				TAmmoContainer::iterator it = Ammo.find(sel);
				if(it == Ammo.end())
					Ammo.insert(std::make_pair(sel,ammoCount));
				else
					it->second = ammoCount;

				if( !m_bRecording)
				{
					CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id));
					if(pActor)
					{
						CInventory* pInventory = (CInventory*)(pActor->GetInventory());
						if(pInventory)
						{
							IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(sel);
							if(m_bLogWarning)
								CheckDifference(ammoCount,pInventory->GetAmmoCount(pClass),"TimeDemo:GameState: Frame %d - Actor %s - AMMO PICKEDUP: count mismatch for ammo class %s (rec:%d, cur:%d)", pEntity,sel);

							if(demo_forceGameState == 2)
								pInventory->SetAmmoCount(pClass,ammoCount);
						}
					}
				}
			}
			break;

		case eGE_AccessoryPickedUp:
			{
				TItemName sel = (TItemName)event.description;
				//				gstate.itemSelected = sel;
				TAccessoryContainer& Accessories = gstate.Accessories;
				TAccessoryContainer::iterator it = Accessories.find(sel);
				if(it == Accessories.end())
				{
					Accessories.insert(std::make_pair(sel,1));
				}
				else
					it->second++;

				CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id));
				if(pActor)
				{
					CInventory* pInventory = (CInventory*)(pActor->GetInventory());
					if(pInventory)
					{
						IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(sel);
						
						if(m_bLogWarning && !pInventory->HasAccessory(pClass))
							GameWarning("TimeDemo:GameState: Frame %d - Actor %s - ACCESSORY PICKEDUP %s not found in current inventory", m_currentFrame, pEntity->GetName(),sel ? sel:"(null)");

						if(demo_forceGameState == 2 && pClass)					
							pInventory->AddAccessory(pClass);// doesn't actually add it if it's there already

					}
				}
			}
			break;

		case eGE_ItemDropped:
			{
				TItemName sel = (TItemName)event.description;
				//gstate.itemSelected = sel;
				TItemContainer& Items = gstate.Items;
				TItemContainer::iterator it = Items.find(sel);
				if(it != Items.end())
				{
					it->second.count--;
					if(it->second.count<=0)
						Items.erase(it);

					if(demo_forceGameState == 2)
					{
						CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id));
						if(pActor)
						{
							CInventory* pInventory = (CInventory*)(pActor->GetInventory());
							if(pInventory)
							{
								IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(sel);
								if(pClass)
								{
									EntityId itemId = pInventory->GetItemByClass(pClass);
									if(itemId)
										pInventory->RemoveItem(itemId);
								}
							}
						}
					}
				}
				else
					GameWarning("TimeDemo:GameState: Frame %d - Actor %s - ITEM DROPPED, wrong item selected (%s)",m_currentFrame,pEntity->GetName(),sel);
			}
			break;

		case eGE_AmmoCount: 
			{
				TItemContainer& Items = gstate.Items;
				TItemName itemClassDesc = event.description;
				TItemContainer::iterator it = Items.find(itemClassDesc);
				if(it != Items.end())
				{
					SItemProperties& item = it->second;
					const char* ammoClassDesc = (const char*)(event.extra);
					if(ammoClassDesc)
					{
						string szAmmoClassDesc(ammoClassDesc);
						bool bAmmoMag = IsAmmoGrenade(ammoClassDesc);
						TAmmoContainer& itemAmmo = bAmmoMag ? gstate.AmmoMags : item.Ammo;

						if(itemAmmo.find(szAmmoClassDesc)==itemAmmo.end())
							itemAmmo.insert(std::make_pair(szAmmoClassDesc,int(event.value)));
						else
							itemAmmo[szAmmoClassDesc] = (uint16)event.value;

						if(!bRecording && (m_bLogWarning || demo_forceGameState==2))
						{
							CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id));
							if(pActor)
							{
								CInventory* pInventory = (CInventory*)(pActor->GetInventory());
								if(pInventory)
								{
									IItem* pItem = pInventory->GetItemByName(itemClassDesc);

									if(pItem)
									{
										CWeapon* pWeapon = (CWeapon*)(pItem->GetIWeapon());
										if(pWeapon)
										{
											IEntityClass* pAmmoClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(ammoClassDesc);
											if(pAmmoClass)
											{
												if(m_bLogWarning)
												{
													int curAmmoCount = (bAmmoMag ? pInventory->GetAmmoCount(pAmmoClass) : 
														pWeapon->GetAmmoCount(pAmmoClass));
													CheckDifference( int(event.value),curAmmoCount,"TimeDemo:GameState: Frame %d - Actor %s - AMMO COUNT mismatch for ammo class %s (rec:%d, cur:%d)",pEntity,ammoClassDesc);
												}

												if(demo_forceGameState==2)
													pWeapon->SetAmmoCount(pAmmoClass,int(event.value));

											}
										}
									}
								}
							}
						}
					}
					else
						GameWarning("TimeDemo:GameState: Frame %d - Actor %s - AMMO COUNT null ammoClass descriptor",m_currentFrame,pEntity->GetName());
				}
				else
					GameWarning("TimeDemo:GameState: Frame %d - Actor %s - AMMO COUNT wrong item selected (%s)",m_currentFrame,pEntity->GetName(),itemClassDesc);
			}
			break;

		case eGE_AttachedAccessory: 
			{
				// always force attachment of accessory to the current weapon
				// kind of a workaround, the HUD weapon modifier menu is spawned during timedemo playback 
				// but it doesn't use recorded input events
				if(!bRecording)
				{
					CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id));
					if(pActor)
					{
						CInventory* pInventory = (CInventory*)(pActor->GetInventory());
						if(pInventory)
						{
							const char* sel = event.description;
							IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(sel);
							if(!sel)
								sel = "(null)";
							if(!pInventory->HasAccessory(pClass))
							{
								if(m_bLogWarning)
									GameWarning("TimeDemo:GameState: Frame %d - Actor %s - ATTACHED ACCESSORY %s not found in current inventory", m_currentFrame,pEntity->GetName(),sel);
							}
							else
							{
								CItem* pCurrentItem = (CItem*)(pActor->GetCurrentItem());
								if(pCurrentItem)
									pCurrentItem->SwitchAccessory(sel);
							}
						}
					}
				}
			}
			break;

		case eGE_EntityGrabbed:
			{
				if(demo_forceGameState==2)
				{
					TItemName itemName = event.description;
					if(itemName)
					{
						IEntity * pGrabbedEntity = gEnv->pEntitySystem->FindEntityByName(itemName);
						if(pGrabbedEntity)
						{
							CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id));
							if(pActor)
							{
								IItem* pItem = GetItemOfName(pActor,itemName);
								if(!pItem)
								{
									// it's a pickable entity, won't end up in the inventory
									//(otherwise it would be managed by eGE_ItemPickedUp)
									COffHand* pOffHand = static_cast<COffHand*>(pActor->GetWeaponByClass(CItem::sOffHandClass));
									if(pOffHand && !pOffHand->GetPreHeldEntityId())
										pOffHand->ForcePickUp(pGrabbedEntity->GetId());
								}
							}
						}
					}	
				}
			}
			break;

		default:
			break;
	}
}
Esempio n. 24
0
	virtual void ProcessEvent( EFlowEvent event,SActivationInfo *pActInfo )
	{
		IVehicleSystem * pVehicleSystem = NULL;
		IVehicle * pVehicle = NULL;

		switch(event)
		{
		case eFE_Initialize:
			{
				pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, false);
				break;
			}

		case eFE_Activate:
			{
				if (!pActInfo->pEntity)
					return;

				pVehicleSystem = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem();
				pVehicle = pVehicleSystem->GetVehicle(pActInfo->pEntity->GetId());

				if (!pVehicleSystem || !pVehicle)
					return;

				string givenString = GetPortString(pActInfo, IN_PARTS);
				currentParam = givenString.substr(0,givenString.find_first_of(":"));
				currentSetting = givenString.substr(givenString.find_first_of(":")+1,(givenString.length()-givenString.find_first_of(":")));

				column1 = 10.f;
				column2 = 100.f;

				if (IsPortActive(pActInfo,IN_SHOW))
					pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, true);

				break;
			}

		case eFE_Update:
			{
				IRenderer * pRenderer = gEnv->pRenderer;

				pVehicleSystem = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem();
				pVehicle = pVehicleSystem->GetVehicle(pActInfo->pEntity->GetId());

				if(!pVehicleSystem || !pActInfo->pEntity || !pVehicle)
					return;

				pRenderer->Draw2dLabel(column1,10,GetPortFloat(pActInfo,IN_SIZE)+2.f,Col_Cyan,false,pActInfo->pEntity->GetName());

				if(currentParam=="Seats")
				{
					loops = 0;

					for(uint32 i=0;i<pVehicle->GetSeatCount();i++)
					{
						IVehicleSeat * currentSeat;

						if(currentSetting=="All")
						{
							currentSeat = pVehicle->GetSeatById(i+1);
						}
						else
						{
							currentSeat = pVehicle->GetSeatById(pVehicle->GetSeatId(currentSetting));
							i = pVehicle->GetSeatCount()-1;
						}

						loops += 1;

						// column 1
						string pMessage = ("%s:", currentSeat->GetSeatName());

						if (column2<pMessage.size()*8*GetPortFloat(pActInfo, IN_SIZE))
							column2=pMessage.size()*8*GetPortFloat(pActInfo, IN_SIZE);

						pRenderer->Draw2dLabel(column1,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),Col_Cyan,false,pMessage);

						// column 2
						if(currentSeat->GetPassenger(true))
						{
							pMessage = ("- %s", gEnv->pEntitySystem->GetEntity(currentSeat->GetPassenger(true))->GetName());
							pRenderer->Draw2dLabel(column2,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),Col_Cyan,false,pMessage);
						}
					}
				}

				else if(currentParam=="Wheels")
				{
					pRenderer->Draw2dLabel(column1,50.f,GetPortFloat(pActInfo,IN_SIZE)+1.f,Col_Red,false,"!");
				}

				else if(currentParam=="Weapons")
				{
					loops = 0;

					for(int i=0;i<pVehicle->GetWeaponCount();i++)
					{
						IItemSystem * pItemSystem = gEnv->pGame->GetIGameFramework()->GetIItemSystem();
						IWeapon * currentWeapon;
						EntityId currentEntityId;
						IItem * pItem;

						if(currentSetting=="All")
						{
							currentEntityId = pVehicle->GetWeaponId(i+1);
						}
						else
						{
							currentEntityId = gEnv->pEntitySystem->FindEntityByName(currentSetting)->GetId();
							i = pVehicle->GetWeaponCount()-1;
						}

						if(!pItemSystem->GetItem(currentEntityId))
							return;

						pItem = pItemSystem->GetItem(currentEntityId);
						currentWeapon = pItem->GetIWeapon();

						loops += 1;

						// column 1
						string pMessageName = string().Format("%s", gEnv->pEntitySystem->GetEntity(currentEntityId)->GetName());
						pRenderer->Draw2dLabel(column1,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),Col_Cyan,false,pMessageName);

						if (column2<pMessageName.size()*8*GetPortFloat(pActInfo, IN_SIZE))
							column2=pMessageName.size()*8*GetPortFloat(pActInfo, IN_SIZE);

						// column 2
						string pMessageValue = string().Format("seat: %s firemode: %i", pVehicle->GetWeaponParentSeat(currentEntityId)->GetSeatName(), currentWeapon->GetCurrentFireMode()).c_str();
						pRenderer->Draw2dLabel(column2,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),Col_Cyan,false,pMessageValue);
					}
				}

				else if(currentParam=="Components")
				{
					loops = 0;

					for(int i=0;i<pVehicle->GetComponentCount();i++)
					{
						IVehicleComponent * currentComponent;

						if(currentSetting=="All")
						{
							currentComponent = pVehicle->GetComponent(i);
						}
						else
						{
							currentComponent = pVehicle->GetComponent(currentSetting);
							i = pVehicle->GetComponentCount()-1;
						}

						loops += 1;

						ColorF labelColor;
						labelColor = ColorF(currentComponent->GetDamageRatio(),(1.f-currentComponent->GetDamageRatio()),0.f);

						// column 1
						string pMessageName = string().Format("%s", currentComponent->GetComponentName()).c_str();
						pRenderer->Draw2dLabel(column1,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),labelColor,false,pMessageName);

						if (column2<pMessageName.size()*8*GetPortFloat(pActInfo, IN_SIZE))
							column2=pMessageName.size()*8*GetPortFloat(pActInfo, IN_SIZE);

						// column 2
						string pMessageValue = string().Format("%5.2f (%3.2f)", currentComponent->GetDamageRatio()*currentComponent->GetMaxDamage(), currentComponent->GetDamageRatio()).c_str();
						pRenderer->Draw2dLabel(column2,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),labelColor,false,pMessageValue);
					}
				}

				else
				{
					pRenderer->Draw2dLabel(column1,50.f,GetPortFloat(pActInfo,IN_SIZE)+1.f,Col_Red,false,"no component selected!");
				}
				break;
			}
		}
	};
Esempio n. 25
0
//--------------------------------------------------------------------
bool CWeapon::OnActionAttack(EntityId actorId, const ActionId& actionId, int activationMode, float value)
{
	if(!m_modifying)
	{
		COffHand * offHandWeapon = NULL;
		bool isOffHandSelected = false;
		GetOffHandInfo(this,isOffHandSelected,&offHandWeapon);

		if(IsTwoHand())
		{
			if(offHandWeapon && 
				(offHandWeapon->GetOffHandState()&(eOHS_HOLDING_GRENADE|eOHS_SWITCHING_GRENADE|eOHS_PICKING_ITEM)))
				return false;
		}

		if (activationMode == eAAM_OnPress)
		{

			if(PreActionAttack(true))
				return true;

			bool isDualWield = false;
			CWeapon *dualWield = NULL;
			GetDualWieldInfo(this,isDualWield,&dualWield);

			// EXPANSION: Dino has rewritten dual wield control!
			/*if (isDualWield)
			{
				m_fire_alternation = !m_fire_alternation;
				m_requestedFire = true;

				if (!m_fire_alternation && dualWield->OutOfAmmo(false) && dualWield->CanReload())
				{
					dualWield->Reload();
					return true;
				}
				else if(m_fire_alternation && OutOfAmmo(false) && CanReload())
				{
					Reload();
					return true;
				}

				if (m_fire_alternation || (!dualWield->CanFire() || !dualWield->IsSelected()))
				{
					if(!IsWeaponRaised() && CanFire())
						StartFire();
					else if(!dualWield->IsWeaponRaised() && dualWield->IsSelected())
						dualWield->StartFire();
				}
				else if (dualWield->CanFire())
				{
					if(!dualWield->IsWeaponRaised() && dualWield->CanFire())
						dualWield->StartFire();
					else if(!IsWeaponRaised())
						StartFire();
				}
			}*/
			// /EXPANSION
		
			if (isDualWield)
			{
				if (offHandWeapon && !(offHandWeapon->GetOffHandState() & (eOHS_INIT_STATE)))
					return false;

				m_fire_alternation = false;
								
				if (!dualWield->IsWeaponRaised())// && dualWield->CanFire())
				{
					dualWield->StartFire();
				}
			/*	else if(dualWield->OutOfAmmo(false) && !dualWield->IsReloading())
				{
					dualWield->Reload();
				}*/

				dualWield->m_requestedFire = true;
			}
			else
			{
				if(!m_weaponRaised)
				{
					StartFire();
				}

				m_requestedFire = true;
			}
		}
		else if (activationMode == eAAM_OnRelease)
		{
			PreActionAttack(false);

			// EXP 1: Don't stop both slave and master simultaneously!!!
				//Stop slave
			if(IsDualWieldMaster())
			{
				//FireSlave(actorId,false);
				CWeapon *dualWield = NULL;
				IItem *slave = GetDualWieldSlave();

				if (slave && slave->GetIWeapon())
					dualWield = static_cast<CWeapon *>(slave);

				if(dualWield)
				{
					dualWield->StopFire();
					dualWield->m_requestedFire=false;
				}

			}
			else if (m_fm)
			{
				m_fm->StopFire();
				m_requestedFire = false;
			}
			// StopFire();
			// /EXP 1
		}
	}

	return true;
}
Esempio n. 26
0
void CItem::AttachAccessory(const ItemString &name, bool attach, bool noanim, bool force, bool initialSetup)
{
	if(!force && IsBusy())
		return;

	bool anim = !noanim && m_stats.fp;
	SAccessoryParams *params = GetAccessoryParams(name);

	if(!params)
		return;

	if(attach)
	{
		if(!IsAccessoryHelperFree(params->attach_helper))
			return;

		if(CItem *pAccessory = AddAccessory(name))
		{
			pAccessory->Physicalize(false, false);
			pAccessory->SetViewMode(m_stats.viewmode);

			if(!initialSetup)
				pAccessory->m_bonusAccessoryAmmo.clear();

			SetCharacterAttachment(eIGS_FirstPerson, params->attach_helper, pAccessory->GetEntity(), eIGS_FirstPerson, 0);
			SetBusy(true);

			AttachAction action(pAccessory, params);

			if(anim)
			{
				PlayAction(params->attach_action, 0, false, eIPAF_Default|eIPAF_NoBlend);
				m_scheduler.TimerAction(GetCurrentAnimationTime(eIGS_FirstPerson), CSchedulerAction<AttachAction>::Create(action), false);
			}
			else
				action.execute(this);

		}
	}
	else
	{
		if(CItem *pAccessory = GetAccessory(name))
		{
			DetachAction action(pAccessory, params);

			if(anim)
			{
				StopLayer(params->attach_layer, eIPAF_Default|eIPAF_NoBlend);
				PlayAction(params->detach_action, 0, false, eIPAF_Default|eIPAF_NoBlend);
				m_scheduler.TimerAction(GetCurrentAnimationTime(eIGS_FirstPerson), CSchedulerAction<DetachAction>::Create(action), false);
				SetBusy(true);
			}
			else
			{
				SetBusy(true);
				action.execute(this);
			}
		}
	}

	//Skip all this for the offhand
	if(GetEntity()->GetClass()!=CItem::sOffHandClass)
		FixAccessories(params, attach);

	//Attach silencer to 2nd SOCOM
	/////////////////////////////////////////////////////////////
	bool isDualWield = IsDualWieldMaster();
	CItem *dualWield = 0;

	if(isDualWield)
	{
		IItem *slave = GetDualWieldSlave();

		if(slave && slave->GetIWeapon())
			dualWield = static_cast<CItem *>(slave);
		else
			isDualWield = false;
	}

	if(isDualWield)
		dualWield->AttachAccessory(name,attach,noanim);

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

	//Luciano - send game event
	g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(GetOwner(), GameplayEvent(eGE_AttachedAccessory, name, (float)attach, (void *)GetEntityId()));

}
Esempio n. 27
0
void CPlayerStateJump::Landed(CPlayer& player, const bool isHeavyWeapon, float fallSpeed)
{
#ifdef STATE_DEBUG
	bool remoteControlled = false;
	IVehicle* pVehicle = player.GetLinkedVehicle();
	if(pVehicle)
	{
		IVehicleSeat* pVehicleSeat = pVehicle->GetSeatForPassenger(player.GetEntityId());
		if(pVehicleSeat && pVehicleSeat->IsRemoteControlled())
		{
			remoteControlled = true;
		}
	}
	CRY_ASSERT_MESSAGE( player.GetLinkedEntity()==NULL || remoteControlled, "Cannot 'land' when you're linked to another entity!" );
#endif

	const SPlayerStats& stats = player.m_stats;

	Vec3 playerPosition = player.GetEntity()->GetWorldPos();
	IPhysicalEntity *phys = player.GetEntity()->GetPhysics();
	IMaterialEffects *mfx = gEnv->pGame->GetIGameFramework()->GetIMaterialEffects();

	const SActorPhysics& actorPhysics = player.GetActorPhysics();
	int matID = actorPhysics.groundMaterialIdx != -1 ? actorPhysics.groundMaterialIdx : mfx->GetDefaultSurfaceIndex();

	const float fHeightofEntity = playerPosition.z;
	const float worldWaterLevel = player.m_playerStateSwim_WaterTestProxy.GetWaterLevel();
	
	TMFXEffectId effectId = mfx->GetEffectId("bodyfall", matID);
	if (effectId != InvalidEffectId)
	{
		SMFXRunTimeEffectParams params;
		Vec3 direction = Vec3(0,0,0);
		if (IMovementController *pMV = player.GetMovementController())
		{
			SMovementState state;
			pMV->GetMovementState(state);
			direction = state.aimDirection;
		}
		params.pos = playerPosition + direction;
		//params.soundSemantic = eSoundSemantic_Player_Foley;

		float landFallParamVal = (float)__fsel( -(fallSpeed - 7.5f), 0.25f, 0.75f);
		params.AddAudioRtpc("landfall", landFallParamVal);

		const float speedParamVal = min(fabsf((actorPhysics.velocity.z * 0.1f)), 1.0f);
		params.AddAudioRtpc("speed", speedParamVal);

		mfx->ExecuteEffect(effectId, params);
	}

	bool heavyLanded = false;

	IItem* pCurrentItem = player.GetCurrentItem();
	CWeapon* pCurrentWeapon = pCurrentItem ? static_cast<CWeapon*>(pCurrentItem->GetIWeapon()) : NULL;

	if (fallSpeed > 0.0f && player.IsPlayer())
	{
		if(!gEnv->bMultiplayer)
		{
			const float verticalSpeed = fabs(fallSpeed);
			const float speedForHeavyLand = g_pGameCVars->pl_health.fallSpeed_HeavyLand;
			if ((verticalSpeed >= speedForHeavyLand) && (player.GetPickAndThrowEntity() == 0) && !player.IsDead())
			{
				if ( !isHeavyWeapon )
				{
					if (pCurrentWeapon)
					{
						pCurrentWeapon->FumbleGrenade();
						pCurrentWeapon->CancelCharge();
					}

					player.StartInteractiveActionByName("HeavyLand", false);
				}
				heavyLanded = true;
			}
		}
	}

	if(player.m_isClient)
	{
		if (fallSpeed > 0.0f)
		{
			const float fallIntensityMultiplier = stats.wasHit ? g_pGameCVars->pl_fall_intensity_hit_multiplier : g_pGameCVars->pl_fall_intensity_multiplier;
			const float fallIntensityMax = g_pGameCVars->pl_fall_intensity_max;
			const float fallTimeMultiplier = g_pGameCVars->pl_fall_time_multiplier;
			const float fallTimeMax = g_pGameCVars->pl_fall_time_max;
			const float zoomMultiplayer = (pCurrentWeapon && pCurrentWeapon->IsZoomed()) ? 0.2f : 1.0f;
			const float direction = ((cry_rand()%2)==0) ? -1.0f : 1.0f;
			const float intensity = clamp_tpl(fallIntensityMultiplier*fallSpeed*zoomMultiplayer, 0.0f, fallIntensityMax);
			const float shakeTime = clamp_tpl(fallTimeMultiplier*fallSpeed*zoomMultiplayer, 0.0f, fallTimeMax);
			const Vec3 rotation = Vec3(-0.5f, 0.15f*direction, 0.05f*direction);

			if (CScreenEffects* pGameScreenEffects = g_pGame->GetScreenEffects())
			{
				pGameScreenEffects->CamShake(rotation*intensity, Vec3(0, 0, 0), shakeTime, shakeTime, 0.05f, CScreenEffects::eCS_GID_Player);
			}

			IForceFeedbackSystem* pForceFeedback = g_pGame->GetIGameFramework()->GetIForceFeedbackSystem();
			assert(pForceFeedback);

			ForceFeedbackFxId fxId = pForceFeedback->GetEffectIdByName("landFF");
			pForceFeedback->PlayForceFeedbackEffect(fxId, SForceFeedbackRuntimeParams(intensity, 0.0f));

			if(fallSpeed > 7.0f)
			{
				player.PlaySound(CPlayer::ESound_Fall_Drop);
			}

			CPlayer::EPlayerSounds playerSound = heavyLanded ? CPlayer::ESound_Gear_HeavyLand : CPlayer::ESound_Gear_Land;
			player.PlaySound(playerSound, true);
		}
		CCCPOINT(PlayerMovement_LocalPlayerLanded);
	}
	
	if( gEnv->pAISystem )
	{
		// Notify AI
		//If silent feet active, ignore here
		const float noiseSupression = 0.0f;
		const float fAISoundRadius = (g_pGameCVars->ai_perception.landed_baseRadius + (g_pGameCVars->ai_perception.landed_speedMultiplier * fallSpeed)) * (1.0f - noiseSupression);
		SAIStimulus stim(AISTIM_SOUND, AISOUND_MOVEMENT_LOUD, player.GetEntityId(), 0,
			player.GetEntity()->GetWorldPos() + player.GetEyeOffset(), ZERO, fAISoundRadius);
		gEnv->pAISystem->RegisterStimulus(stim);
	}

	// Record 'Land' telemetry stats.

	CStatsRecordingMgr::TryTrackEvent(&player, eGSE_Land, fallSpeed);

	if (fallSpeed > 0.0f)
	{
		player.CreateScriptEvent( heavyLanded ? "heavylanded" : "landed",stats.fallSpeed);
	}
}
Esempio n. 28
0
//----------------------------------------------------------------------------
void CHomingMissile::UpdateCruiseMissile(float frameTime)
{

	IRenderer* pRenderer = gEnv->pRenderer;
	IRenderAuxGeom* pGeom = pRenderer->GetIRenderAuxGeom();
	float color[4] = {1,1,1,1};
	const static float step = 15.f;  
	float y = 20.f;    

	bool bDebug = g_pGameCVars->i_debug_projectiles > 0;

	if (m_targetId)
	{
		IEntity* pTarget = gEnv->pEntitySystem->GetEntity(m_targetId);
		if (pTarget)
		{
			AABB box;
			pTarget->GetWorldBounds(box);
			SetDestination( box.GetCenter() );

			//if (bDebug)
				//pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "Target Entity: %s", pTarget->GetName());
		}    
	}
	else 
	{
		// update destination pos from weapon
		static IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem();
		IItem* pItem = pItemSystem->GetItem(m_weaponId);
		if (pItem && pItem->GetIWeapon())
		{
			const Vec3& dest = pItem->GetIWeapon()->GetDestination();
			SetDestination( dest );

			//if (bDebug)
				//pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "Weapon Destination: (%.1f %.1f %.1f)", dest.x, dest.y, dest.z);
		}
	}

	pe_status_dynamics status;
	if (!GetEntity()->GetPhysics()->GetStatus(&status))
		return;

	float currentSpeed = status.v.len();
	Vec3 currentPos = GetEntity()->GetWorldPos();
	Vec3 goalDir(ZERO);

	if (!m_destination.IsZero())
	{

		if((currentPos-m_destination).len2()<(m_detonationRadius*m_detonationRadius))
		{
			Explode(true, true, m_destination, -status.v.normalized(), status.v, m_targetId);
			return;
		}

		if (bDebug)
			pGeom->DrawCone(m_destination, Vec3(0,0,-1), 2.5f, 7.f, ColorB(255,0,0,255));

		float heightDiff = (m_cruiseAltitude-m_alignAltitude) - currentPos.z;

		if (!m_isCruising && heightDiff * sgn(status.v.z) > 0.f)
		{
			// if heading towards align altitude (but not yet reached) accelerate to max speed    
			if (bDebug)
				pRenderer->Draw2dLabel(5.0f,  y+=step,   1.5f, color, false, "[HomingMissile] accelerating (%.1f / %.1f)", currentSpeed, m_maxSpeed);    
		}
		else if (!m_isCruising && heightDiff * sgnnz(status.v.z) < 0.f && (status.v.z<0 || status.v.z>0.25f))
		{
			// align to cruise
			if (currentSpeed != 0)
			{
				goalDir = status.v;
				goalDir.z = 0;
				goalDir.normalize();
			}    

			if (bDebug)
				pRenderer->Draw2dLabel(5.0f,  y+=step, 1.5f, color, false, "[HomingMissile] aligning"); 
		}
		else
		{
			if (bDebug)
				pRenderer->Draw2dLabel(5.0f,  y+=step, 1.5f, color, false, "[HomingMissile] cruising..."); 

			// cruise
			m_isCruising = true;

			if (!m_destination.IsZero())
			{
				float groundDistSq = m_destination.GetSquaredDistance2D(currentPos);
				float distSq = m_destination.GetSquaredDistance(currentPos);
				float descendDistSq = sqr(m_descendDistance);

				if (m_isDescending || groundDistSq <= descendDistSq)
				{
					if (bDebug)
						pRenderer->Draw2dLabel(5.0f,  y+=step, 1.5f, color, false, "[HomingMissile] descending!"); 

					if (distSq != 0)
						goalDir = (m_destination - currentPos).normalized();
					else 
						goalDir.zero();

					m_isDescending = true;
				}              
				else
				{
					Vec3 airPos = m_destination;
					airPos.z = currentPos.z;          
					goalDir = airPos - currentPos;
					if (goalDir.len2() != 0)
						goalDir.Normalize();
				}    
			}
		}
	}  

	float desiredSpeed = currentSpeed;
	if (currentSpeed < m_maxSpeed-0.1f)
	{
		desiredSpeed = min(m_maxSpeed, desiredSpeed + m_accel*frameTime);
	}

	Vec3 currentDir = status.v.GetNormalizedSafe(FORWARD_DIRECTION);
	Vec3 dir = currentDir;

	if (!goalDir.IsZero())
	{ 
		float cosine = max(min(currentDir.Dot(goalDir), 0.999f), -0.999f);
		float goalAngle = RAD2DEG(acos_tpl(cosine));
		float maxAngle = m_turnSpeed * frameTime;

		if (bDebug)
		{ 
			pGeom->DrawCone( currentPos, goalDir, 0.4f, 12.f, ColorB(255,0,0,255) );
			pRenderer->Draw2dLabel(5.0f,  y+=step, 1.5f, color, false, "[HomingMissile] goalAngle: %.2f", goalAngle); 

		}

		if (goalAngle > maxAngle+0.05f)    
			dir = (Vec3::CreateSlerp(currentDir, goalDir, maxAngle/goalAngle)).normalize();
		else //if (goalAngle < 0.005f)
			dir = goalDir;
	}

	pe_action_set_velocity action;
	action.v = dir * desiredSpeed;
	GetEntity()->GetPhysics()->Action(&action);

	if (bDebug)
	{
		pGeom->DrawCone( currentPos, dir, 0.4f, 12.f, ColorB(128,128,0,255) );  
		pRenderer->Draw2dLabel(5.0f,  y+=step, 1.5f, color, false, "[HomingMissile] currentSpeed: %.1f (max: %.1f)", currentSpeed, m_maxSpeed); 
	}
}