Ejemplo n.º 1
0
bool CPlayerStateGround::CheckForVaultTrigger(CPlayer & player, float frameTime)
{
	const int enableVaultFromStandingCVar = g_pGameCVars->pl_ledgeClamber.enableVaultFromStanding;
	const bool doCheck = (enableVaultFromStandingCVar == 3) || ((enableVaultFromStandingCVar > 0) && player.m_jumpButtonIsPressed);

	if (doCheck)
	{
		SLedgeTransitionData ledgeTransition(LedgeId::invalid_id);
		const float zPos = player.GetEntity()->GetWorldPos().z;
		const bool ignoreMovement = (enableVaultFromStandingCVar == 2);

		if (CPlayerStateLedge::TryLedgeGrab(player, zPos, zPos, true, &ledgeTransition, ignoreMovement) && ledgeTransition.m_ledgeTransition != SLedgeTransitionData::eOLT_None)
		{
			CRY_ASSERT( LedgeId(ledgeTransition.m_nearestGrabbableLedgeId).IsValid() );
			const SLedgeInfo ledgeInfo = g_pGame->GetLedgeManager()->GetLedgeById( LedgeId(ledgeTransition.m_nearestGrabbableLedgeId) );
			
			CRY_ASSERT( ledgeInfo.IsValid() );

			if (ledgeInfo.AreAnyFlagsSet(kLedgeFlag_useVault|kLedgeFlag_useHighVault))
			{
#ifdef STATE_DEBUG

				if (g_pGameCVars->pl_ledgeClamber.debugDraw)
				{
					const char * transitionName = s_ledgeTransitionNames[ledgeTransition.m_ledgeTransition];

					IEntity* pEntity = gEnv->pEntitySystem->GetEntity(ledgeInfo.GetEntityId());
					CryWatch ("[LEDGEGRAB] $5%s nearest ledge: %s%s%s%s, transition=%s", player.GetEntity()->GetEntityTextDescription(), pEntity ? pEntity->GetEntityTextDescription() : "none", ledgeInfo.AreFlagsSet(kLedgeFlag_isThin) ? " THIN" : "", ledgeInfo.AreFlagsSet(kLedgeFlag_isWindow) ? " WINDOW" : "", ledgeInfo.AreFlagsSet(kLedgeFlag_endCrouched) ? " ENDCROUCHED" : "", transitionName);
				}

#endif

				if (player.m_jumpButtonIsPressed || enableVaultFromStandingCVar == 3)
				{
					ledgeTransition.m_comingFromOnGround=true;
					ledgeTransition.m_comingFromSprint=player.IsSprinting();

					SStateEventLedge ledgeEvent(ledgeTransition);
					player.StateMachineHandleEventMovement(ledgeEvent);
					return true;
				}
				else
				{
#ifdef STATE_DEBUG
					if (g_pGameCVars->pl_ledgeClamber.debugDraw)
					{
						const char * message = NULL;
						switch (ledgeTransition.m_ledgeTransition)
						{
							case SLedgeTransitionData::eOLT_VaultOnto:
							message = "CLIMB";
							break;

							case SLedgeTransitionData::eOLT_VaultOver:
							message = "VAULT";
							break;

							default:
							CRY_ASSERT_TRACE(0, ("Unexpected ledge transition #%d when trying to display HUD prompt for vault-from-standing!", ledgeTransition.m_ledgeTransition));
							break;
						}

						if (message)
						{
							const float textColor[4] = {1.f, 1.f, 1.f, 1.0f};
							const float bracketColor[4] = {0.7f, 0.7f, 0.7f, 1.0f};
							const float iconSize = 4.f;
							const float textSize = 2.f;
							const float iconColor[4] = {0.3f, 1.f, 0.3f, 1.0f};
							const char * iconText = "A";

							gEnv->pRenderer->Draw2dLabel((gEnv->pRenderer->GetWidth() * 0.5f), (gEnv->pRenderer->GetHeight() * 0.65f), iconSize, bracketColor, true, "( )");
							gEnv->pRenderer->Draw2dLabel((gEnv->pRenderer->GetWidth() * 0.5f), (gEnv->pRenderer->GetHeight() * 0.65f), iconSize, iconColor, true, "%s", iconText);
							gEnv->pRenderer->Draw2dLabel((gEnv->pRenderer->GetWidth() * 0.5f), (gEnv->pRenderer->GetHeight() * 0.72f), textSize, textColor, true, "%s", message);
						}
					}
#endif
				}
			}
		}
	}

	return false;
}
Ejemplo n.º 2
0
LedgeId CLedgeManager::FindNearestLedge( const Vec3 &referencePosition, const Vec3 &testDirection, float maxDistance /*= 2.0f*/, float angleRange /*= DEG2RAD(35.0f)*/, float extendedAngleRange /*= DEG2RAD(50.0f)*/ ) const
{
	if (m_editorManager.IsInEditorMode())
	{
		return m_editorManager.FindNearestLedge( referencePosition, testDirection, maxDistance, angleRange, extendedAngleRange );
	}
	else
	{
		LedgeId bestLedgeId;

		float closestDistanceSq = maxDistance* maxDistance;
		const float fCosMaxAngleTable[2] = { cosf(angleRange), cosf(extendedAngleRange) };
		const float side[2] = { 1.0f, -1.0f };

		SLedgeInfo ledgeInfo;

		const uint32 ledgeObjectCount = m_levelLedges.m_ledgeCount;
		for(uint32 objectIdx = 0; objectIdx < ledgeObjectCount; ++objectIdx)
		{
			const SLedgeObject& ledgeObject = m_levelLedges.m_pLedgeObjects[objectIdx];
			const uint32 startMarkerIdx = ledgeObject.m_markersStartIdx;
			const uint32 endMarkerIdx = ledgeObject.m_markersStartIdx + ledgeObject.m_markersCount;
			CRY_ASSERT ( endMarkerIdx <= m_levelLedges.m_markerCount );
			
			const uint32 sideCount = 1 + ((ledgeObject.m_ledgeFlags[LedgeSide_In] & kLedgeFlag_isDoubleSided) != 0);
			const bool enabled = (ledgeObject.m_ledgeFlags[LedgeSide_In] & kLedgeFlag_enabled) != 0;

			CRY_ASSERT(sideCount <= 2);

			uint32 currentSide = 0;
			do 
			{
				for (uint32 markerIdx = startMarkerIdx; markerIdx < (endMarkerIdx - 1); ++markerIdx)
				{
					ELedgeFlagBitfield flags = kLedgeFlag_none;

					if (m_levelLedges.m_pMarkers[markerIdx].m_endOrCorner)
					{
						flags |= kledgeRunTimeOnlyFlag_p0IsEndOrCorner;
					}
					if (m_levelLedges.m_pMarkers[markerIdx+1].m_endOrCorner)
					{
						flags |= kledgeRunTimeOnlyFlag_p1IsEndOrCorner;
					}

					ledgeInfo = SLedgeInfo( ledgeObject.m_entityId, m_levelLedges.m_pMarkers[markerIdx].m_worldPosition, m_levelLedges.m_pMarkers[markerIdx+1].m_worldPosition,
						m_levelLedges.m_pMarkers[markerIdx].m_facingDirection * side[currentSide], flags, ledgeObject.m_ledgeCornerEndAdjustAmount );

					// Explanation: (Please do not delete this comment)
					//	The item can be skipped if the angle is too big.
					//	Since only the cosine of angles are compared,
					//	bigger angles result in smaller values (hence the less_than comparison)
					const uint32 thresholdIdx = ((ledgeObject.m_ledgeFlags[currentSide] & (kLedgeFlag_useVault|kLedgeFlag_useHighVault)) != 0);
					CRY_ASSERT( thresholdIdx < 2 );

					const float fCosMaxAngle = fCosMaxAngleTable[thresholdIdx];

					const Vec3 vPosToLedge = _FindVectorToClosestPointOnLedge( referencePosition, ledgeInfo );

					float distanceSq;
					if( IsBestLedge( vPosToLedge, testDirection, ledgeInfo, closestDistanceSq, fCosMaxAngle, enabled, distanceSq ) == false )
						continue;
					
					bestLedgeId = LedgeId( objectIdx, (markerIdx - startMarkerIdx), currentSide );
					closestDistanceSq = distanceSq;
				}

				currentSide++;

			} while ( currentSide < sideCount );
		}

		return bestLedgeId;
	}
}