void execute(CItem *pItem)
	{
		_this->m_attacking = false;
		_this->m_slideKick = false;
		_this->m_netAttacking = false;

		_this->m_delayTimer = 0.0f;
		pItem->SetBusy(false);
		pItem->ForcePendingActions();
		MeleeDebugLog ("CMelee<%p> StopAttackingAction is being executed!", _this);

		CActor* pActor(NULL);
		if(!gEnv->bMultiplayer)
		{
			if (IEntity* owner = pItem->GetOwner())
				if (IAIObject* aiObject = owner->GetAI())
					if (IAIActor* aiActor = aiObject->CastToIAIActor())
						aiActor->SetSignal(0, "OnMeleePerformed");
		}
		else if( g_pGameCVars->pl_melee.mp_melee_system_camera_lock_and_turn && s_meleeSnapTargetId && (pActor = pItem->GetOwnerActor()) && pActor->IsClient() )
		{
			CActor* pOwnerActor = pItem->GetOwnerActor();
			pOwnerActor->GetActorParams().viewLimits.ClearViewLimit(SViewLimitParams::eVLS_Item);

			s_meleeSnapTargetId = 0;
			CHANGED_NETWORK_STATE(pOwnerActor, CPlayer::ASPECT_SNAP_TARGET);
		}

		if(_this->m_pMeleeAction)
		{
			SAFE_RELEASE(_this->m_pMeleeAction);
		}
	}
//---------------------------------------------------------------------
void CMelee::RequestAlignmentToNearestTarget()
{
	CActor* pOwner = m_pWeapon->GetOwnerActor();
	if(pOwner && pOwner->IsClient())
	{
		if (!s_meleeSnapTargetId)
		{
			// If we don't already have an auto-aim target, try and find one.
			if (s_meleeSnapTargetId = GetNearestTarget())
			{
				IActor* pTargetActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(s_meleeSnapTargetId);
				s_bMeleeSnapTargetCrouched = pTargetActor && static_cast<CPlayer*>(pTargetActor)->GetStance() == STANCE_CROUCH;

				CHANGED_NETWORK_STATE(pOwner, CPlayer::ASPECT_SNAP_TARGET);
			}
		}

		if(!s_meleeSnapTargetId || m_netAttacking)
			return;

		if(pOwner && pOwner->IsClient() && m_pMeleeAction && g_pGameCVars->pl_melee.mp_melee_system_camera_lock_and_turn)
		{
			pOwner->GetActorParams().viewLimits.SetViewLimit(pOwner->GetViewRotation().GetColumn1(), 0.01f, 0.01f, 0.01f, 0.01f, SViewLimitParams::eVLS_Item);
		}

		g_pGame->GetAutoAimManager().SetCloseCombatSnapTarget(s_meleeSnapTargetId, 
			g_pGameCVars->pl_melee.melee_snap_end_position_range, 
			g_pGameCVars->pl_melee.melee_snap_move_speed_multiplier);
	}
}
Beispiel #3
0
	void execute(CItem *_this)
	{
		CActor *pOwner = pHMGWeapon->GetOwnerActor();

		if (pOwner)
		{
			SActorParams &params = pOwner->GetActorParams();

			params.viewLimits.SetViewLimit(Vec3Constants<float>::fVec3_OneY, 0.0f, 0.01f, 0.f, 0.f, SViewLimitParams::eVLS_Item);
		}
	}
void CVehicleMountedWeapon::ApplyViewLimit(EntityId userId, bool apply)
{
	// Ignore the application of view limits, they are handled 
	//	by vehicle code. Allow the cancelling though, since 
	//	HMG ripoff code locks the view during the rip off process

	CActor *pActor = GetActor(userId);
	if(pActor && !apply)
	{
		SActorParams &params = pActor->GetActorParams();

		params.viewLimits.ClearViewLimit(SViewLimitParams::eVLS_Item);

		pActor->SetSpeedMultipler(SActorParams::eSMR_Item, 1.0f);
	}
}
void CMelee::OnFailedHit()
{
	const SCollisionTestParams& collisionParams = m_collisionHelper.GetCollisionTestParams();

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

	CActor* pOwner = m_pWeapon->GetOwnerActor();

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

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

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

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

	if(m_pMeleeAction)
	{
		if(pOwner)
		{
			m_pMeleeAction->OnHitResult(pOwner, collided);
		}
		else
		{
			//Owner has dropped weapon (Likely from being killed) so we can stop and release the action
			m_pMeleeAction->ForceFinish();
			SAFE_RELEASE(m_pMeleeAction);
		}
	}
	
	ApplyMeleeEffects(collided);
}
void CMelee::OnSuccesfulHit( const ray_hit& hitResult )
{
	CActor* pOwner = m_pWeapon->GetOwnerActor();
	if( IsMeleeWeapon() && m_hitStatus != EHitStatus_ReceivedAnimEvent && hitResult.pCollider )
	{
		// we defer the MeleeDamage until the MeleeHitEvent is received!
		m_lastCollisionTest = m_collisionHelper.GetCollisionTestParams();
		m_lastRayHit = hitResult;

		m_lastRayHit.pCollider->AddRef();
		m_hitStatus = EHitStatus_HaveHitResult;
	}
	else
	{
		const SCollisionTestParams& collisionParams = m_collisionHelper.GetCollisionTestParams();
		
		ApplyMeleeDamageHit( collisionParams, hitResult );

		m_hitStatus = EHitStatus_Invalid;

		if(m_pMeleeAction)
		{
			if(pOwner)
			{
				m_pMeleeAction->OnHitResult(pOwner, true);
			}
			else
			{
				//Owner has dropped weapon (Likely from being killed) so we can stop and release the action
				m_pMeleeAction->ForceFinish();
				SAFE_RELEASE(m_pMeleeAction);
			}
		}
	}

	if(pOwner && pOwner->IsClient())
	{
		s_meleeSnapTargetId = 0;
		CHANGED_NETWORK_STATE(pOwner, CPlayer::ASPECT_SNAP_TARGET);

		if(g_pGameCVars->pl_melee.mp_melee_system_camera_lock_and_turn)
		{
			pOwner->GetActorParams().viewLimits.ClearViewLimit(SViewLimitParams::eVLS_Item);
		}
	}
}
//------------------------------------------------------------------------
void CMelee::Update(float frameTime, uint32 frameId)
{
	FUNCTION_PROFILER( GetISystem(), PROFILE_GAME );

	bool remote = false;
	bool doMelee = false;
	bool requireUpdate = false;

	Vec3 dirToTarget(ZERO);
	if(m_pMeleeAction && s_meleeSnapTargetId && g_pGameCVars->pl_melee.mp_melee_system_camera_lock_and_turn)
	{
		m_attackTime += frameTime;

		CActor* pOwner = m_pWeapon->GetOwnerActor();
		IEntity* pTarget = gEnv->pEntitySystem->GetEntity(s_meleeSnapTargetId);
		if(pOwner && pTarget)
		{
			Vec3 targetPos = pTarget->GetWorldPos();

			if(s_bMeleeSnapTargetCrouched)
			{
				targetPos.z -= g_pGameCVars->pl_melee.mp_melee_system_camera_lock_crouch_height_offset;
			}

			dirToTarget = targetPos - pOwner->GetEntity()->GetWorldPos();
			dirToTarget.Normalize();

			static const float smooth_time = 0.1f;
			SmoothCD(m_attackTurnAmount, m_attackTurnAmountSmoothRate, frameTime, 1.f, smooth_time);
			Quat newViewRotation;
			newViewRotation.SetSlerp(pOwner->GetViewRotation(), Quat::CreateRotationVDir(dirToTarget), m_attackTurnAmount);
			Ang3 newAngles(newViewRotation);
			newAngles.y = 0.f; //No head tilting
			newViewRotation = Quat(newAngles);
			pOwner->SetViewRotation( newViewRotation );
		}

		if(m_attackTime >= g_pGameCVars->pl_melee.mp_melee_system_camera_lock_time && pOwner && pOwner->IsClient())
		{
			pOwner->GetActorParams().viewLimits.ClearViewLimit(SViewLimitParams::eVLS_Item);
		}
	}

	if (m_attacking)
	{
		MeleeDebugLog ("CMelee<%p> Update while attacking: m_attacked=%d, delay=%f", this, m_attacked, m_delayTimer);

		requireUpdate = true;
		if (m_delayTimer>0.0f)
		{
			RequestAlignmentToNearestTarget();
			m_delayTimer-=frameTime;
			if (m_delayTimer<=0.0f)
			{
				m_delayTimer=0.0f;
			}
		}
		else if (m_netAttacking)
		{
			remote = true;
			doMelee = true;
			m_attacking = false;
			m_slideKick = false;
			m_netAttacking = false;

			m_pWeapon->SetBusy(false);
		}	
		else if (!m_attacked)
		{
			doMelee = true;
			m_attacked = true;
		}

		if ( !m_collisionHelper.IsBlocked() && doMelee)
		{
			if (CActor *pActor = m_pWeapon->GetOwnerActor())
			{
				if (IMovementController * pMC = pActor->GetMovementController())
				{
					SMovementState info;
					pMC->GetMovementState(info);

					if(!dirToTarget.IsZeroFast())
					{
						PerformMelee(info.weaponPosition, dirToTarget, remote); //We know where we will be facing at the point of impact - using our current fire direction is not accurate enough
					}
					else
					{
						PerformMelee(info.weaponPosition, info.fireDirection, remote);
					}
				}
			}
		}

		if( (m_useMeleeWeaponDelay <= 0.0f && m_useMeleeWeaponDelay > -1.0f) )
		{
			m_useMeleeWeaponDelay = -1.0f;

			// Switch to the MELEE WEAPON.
			SwitchToMeleeWeaponAndAttack();

			m_attacking = false;
		}
		m_useMeleeWeaponDelay -= frameTime;
	}

	if (requireUpdate)
		m_pWeapon->RequireUpdate(eIUS_FireMode);
}