예제 #1
0
void MM_ClipVelocity2D
	(
	float *in,
	float *normal,
	float *out,
	float overbounce
	)

{
	float backoff;
	float dir_z;
	float normal2[ 3 ];

	if( normal[ 2 ] >= 0.70f )
	{
		if( in[ 0 ] == 0.0f && in[ 1 ] == 0.0f )
		{
			VectorClear( out );
			return;
		}

		normal2[ 0 ] = in[ 0 ] + DotProduct2D( in, normal );
		normal2[ 1 ] = in[ 1 ] + DotProduct2D( in, normal );
		normal2[ 2 ] = normal[ 2 ] * DotProduct2D( in, in );

		VectorNormalize( normal2 );

		dir_z = -normal2[ 2 ];

		out[ 0 ] = in[ 0 ];
		out[ 1 ] = in[ 1 ];
		out[ 2 ] = DotProduct2D( in, normal2 ) / -normal2[ 2 ];
	}
	else
	{
		backoff = DotProduct2D( in, normal );

		if( backoff < 0 )
			backoff *= overbounce;
		else
			backoff /= overbounce;

		out[ 0 ] = in[ 0 ] - normal[ 0 ] * backoff;
		out[ 1 ] = in[ 1 ] - normal[ 1 ] * backoff;
		out[ 2 ] = -( backoff * normal[ 2 ] );
	}
}
예제 #2
0
int CWeaponCrowbar::WeaponMeleeAttack1Condition( float flDot, float flDist )
{
	// Attempt to lead the target (needed because citizens can't hit manhacks with the crowbar!)
	CAI_BaseNPC *pNPC	= GetOwner()->MyNPCPointer();
	CBaseEntity *pEnemy = pNPC->GetEnemy();
	if (!pEnemy)
		return COND_NONE;

	Vector vecVelocity;
	vecVelocity = pEnemy->GetSmoothedVelocity( );

	// Project where the enemy will be in a little while
	float dt = sk_crowbar_lead_time.GetFloat();
	dt += random->RandomFloat( -0.3f, 0.2f );
	if ( dt < 0.0f )
		dt = 0.0f;

	Vector vecExtrapolatedPos;
	VectorMA( pEnemy->WorldSpaceCenter(), dt, vecVelocity, vecExtrapolatedPos );

	Vector vecDelta;
	VectorSubtract( vecExtrapolatedPos, pNPC->WorldSpaceCenter(), vecDelta );

	if ( fabs( vecDelta.z ) > 70 )
	{
		return COND_TOO_FAR_TO_ATTACK;
	}

	Vector vecForward = pNPC->BodyDirection2D( );
	vecDelta.z = 0.0f;
	float flExtrapolatedDist = Vector2DNormalize( vecDelta.AsVector2D() );
	if ((flDist > 64) && (flExtrapolatedDist > 64))
	{
		return COND_TOO_FAR_TO_ATTACK;
	}

	float flExtrapolatedDot = DotProduct2D( vecDelta.AsVector2D(), vecForward.AsVector2D() );
	if ((flDot < 0.7) && (flExtrapolatedDot < 0.7))
	{
		return COND_NOT_FACING_ATTACK;
	}

	return COND_CAN_MELEE_ATTACK1;
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : flDot - 
//			flDist - 
// Output : int
//-----------------------------------------------------------------------------
int CNPC_Bug_Warrior::MeleeAttack1Conditions( float flDot, float flDist )
{
	if ( ( gpGlobals->curtime - m_flLastAttackTime ) < 1.0f )
		return 0;

#if 0

	float		flPrDist, flPrDot;
	Vector		vecPrPos;
	Vector2D	vec2DPrDir;

	//Get our likely position in one second
	UTIL_GetPredictedPosition( GetEnemy(), 0.5f, &vecPrPos );

	flPrDist = ( vecPrPos - GetAbsOrigin() ).Length();

	vec2DPrDir	= ( vecPrPos - GetAbsOrigin() ).AsVector2D();

	Vector vecBodyDir;
	
	BodyDirection2D( &vecBodyDir );

	Vector2D	vec2DBodyDir = vecBodyDir.AsVector2D();
	
	flPrDot	= DotProduct2D (vec2DPrDir, vec2DBodyDir );

	if ( flPrDist > BUG_WARRIOR_MELEE1_RANGE )
		return COND_TOO_FAR_TO_ATTACK;

	if ( flPrDot < 0.5f )
		return COND_NOT_FACING_ATTACK;

#else

	if ( flDist > BUG_WARRIOR_MELEE1_RANGE )
		return COND_TOO_FAR_TO_ATTACK;

	if ( flDot < 0.5f )
		return COND_NOT_FACING_ATTACK;

#endif

	return COND_CAN_MELEE_ATTACK1;
}
예제 #4
0
//-----------------------------------------------------------------------------
// Animation event handlers
//-----------------------------------------------------------------------------
void CWeaponCrowbar::HandleAnimEventMeleeHit( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
{
	// Trace up or down based on where the enemy is...
	// But only if we're basically facing that direction
	Vector vecDirection;
	AngleVectors( GetAbsAngles(), &vecDirection );

	CBaseEntity *pEnemy = pOperator->MyNPCPointer() ? pOperator->MyNPCPointer()->GetEnemy() : NULL;
	if ( pEnemy )
	{
		Vector vecDelta;
		VectorSubtract( pEnemy->WorldSpaceCenter(), pOperator->Weapon_ShootPosition(), vecDelta );
		VectorNormalize( vecDelta );
		
		Vector2D vecDelta2D = vecDelta.AsVector2D();
		Vector2DNormalize( vecDelta2D );
		if ( DotProduct2D( vecDelta2D, vecDirection.AsVector2D() ) > 0.8f )
		{
			vecDirection = vecDelta;
		}
	}

	Vector vecEnd;
	VectorMA( pOperator->Weapon_ShootPosition(), 50, vecDirection, vecEnd );
	CBaseEntity *pHurt = pOperator->CheckTraceHullAttack( pOperator->Weapon_ShootPosition(), vecEnd, 
		Vector(-16,-16,-16), Vector(36,36,36), sk_npc_dmg_crowbar.GetInt(), DMG_CLUB, 0.75 );
	
	// did I hit someone?
	if ( pHurt )
	{
		// play sound
		WeaponSound( MELEE_HIT );

		// Fake a trace impact, so the effects work out like a player's crowbaw
		trace_t traceHit;
		UTIL_TraceLine( pOperator->Weapon_ShootPosition(), pHurt->GetAbsOrigin(), MASK_SHOT_HULL, pOperator, COLLISION_GROUP_NONE, &traceHit );
		ImpactEffect( traceHit );
	}
	else
	{
		WeaponSound( MELEE_MISS );
	}
}
예제 #5
0
int CWeaponStunStick::WeaponMeleeAttack1Condition( float flDot, float flDist )
{
	// Attempt to lead the target (needed because citizens can't hit manhacks with the crowbar!)
	CAI_BaseNPC *pNPC	= GetOwner()->MyNPCPointer();
	CBaseEntity *pEnemy = pNPC->GetEnemy();
	if (!pEnemy)
		return COND_NONE;

	Vector vecVelocity;
	AngularImpulse angVelocity;
	pEnemy->GetVelocity( &vecVelocity, &angVelocity );

	// Project where the enemy will be in a little while, add some randomness so he doesn't always hit
	float dt = sk_crowbar_lead_time.GetFloat();
	dt += random->RandomFloat( -0.3f, 0.2f );
	if ( dt < 0.0f )
		dt = 0.0f;

	Vector vecExtrapolatedPos;
	VectorMA( pEnemy->WorldSpaceCenter(), dt, vecVelocity, vecExtrapolatedPos );

	Vector vecDelta;
	VectorSubtract( vecExtrapolatedPos, pNPC->WorldSpaceCenter(), vecDelta );

	if ( fabs( vecDelta.z ) > 70 )
	{
		return COND_TOO_FAR_TO_ATTACK;
	}

	Vector vecForward = pNPC->BodyDirection2D( );
	vecDelta.z = 0.0f;
	float flExtrapolatedDot = DotProduct2D( vecDelta.AsVector2D(), vecForward.AsVector2D() );
	if ((flDot < 0.7) && (flExtrapolatedDot < 0.7))
	{
		return COND_NOT_FACING_ATTACK;
	}

	float flExtrapolatedDist = Vector2DNormalize( vecDelta.AsVector2D() );

	if( pEnemy->IsPlayer() )
	{
		//Vector vecDir = pEnemy->GetSmoothedVelocity();
		//float flSpeed = VectorNormalize( vecDir );

		// If player will be in front of me in one-half second, clock his arse.
		Vector vecProjectEnemy = pEnemy->GetAbsOrigin() + (pEnemy->GetAbsVelocity() * 0.35);
		Vector vecProjectMe = GetAbsOrigin();

		if( (vecProjectMe - vecProjectEnemy).Length2D() <= 48.0f )
		{
			return COND_CAN_MELEE_ATTACK1;
		}
	}
/*
	if( metropolice_move_and_melee.GetBool() )
	{
		if( pNPC->IsMoving() )
		{
			flTargetDist *= 1.5f;
		}
	}
*/
	float flTargetDist = 48.0f;
	if ((flDist > flTargetDist) && (flExtrapolatedDist > flTargetDist))
	{
		return COND_TOO_FAR_TO_ATTACK;
	}

	return COND_CAN_MELEE_ATTACK1;
}
예제 #6
0
void CWeaponStunStick::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
{
	switch( pEvent->event )
	{
		case EVENT_WEAPON_MELEE_HIT:
		{
			// Trace up or down based on where the enemy is...
			// But only if we're basically facing that direction
			Vector vecDirection;
			AngleVectors( GetAbsAngles(), &vecDirection );

			CBaseEntity *pEnemy = pOperator->MyNPCPointer() ? pOperator->MyNPCPointer()->GetEnemy() : NULL;
			if ( pEnemy )
			{
				Vector vecDelta;
				VectorSubtract( pEnemy->WorldSpaceCenter(), pOperator->Weapon_ShootPosition(), vecDelta );
				VectorNormalize( vecDelta );
				
				Vector2D vecDelta2D = vecDelta.AsVector2D();
				Vector2DNormalize( vecDelta2D );
				if ( DotProduct2D( vecDelta2D, vecDirection.AsVector2D() ) > 0.8f )
				{
					vecDirection = vecDelta;
				}
			}

			Vector vecEnd;
			VectorMA( pOperator->Weapon_ShootPosition(), 32, vecDirection, vecEnd );
			// Stretch the swing box down to catch low level physics objects
			CBaseEntity *pHurt = pOperator->CheckTraceHullAttack( pOperator->Weapon_ShootPosition(), vecEnd, 
				Vector(-16,-16,-40), Vector(16,16,16), GetDamageForActivity( GetActivity() ), DMG_CLUB, 0.5f, false );
			
			// did I hit someone?
			if ( pHurt )
			{
				// play sound
				WeaponSound( MELEE_HIT );

				CBasePlayer *pPlayer = ToBasePlayer( pHurt );

				CNPC_MetroPolice *pCop = dynamic_cast<CNPC_MetroPolice *>(pOperator);
				bool bFlashed = false;

				if ( pCop != NULL && pPlayer != NULL )
				{
					// See if we need to knock out this target
					if ( pCop->ShouldKnockOutTarget( pHurt ) )
					{
						float yawKick = random->RandomFloat( -48, -24 );

						//Kick the player angles
						pPlayer->ViewPunch( QAngle( -16, yawKick, 2 ) );

						color32 white = {255,255,255,255};
						UTIL_ScreenFade( pPlayer, white, 0.2f, 1.0f, FFADE_OUT|FFADE_PURGE|FFADE_STAYOUT );
						bFlashed = true;
						
						pCop->KnockOutTarget( pHurt );

						break;
					}
					else
					{
						// Notify that we've stunned a target
						pCop->StunnedTarget( pHurt );
					}
				}
				
				// Punch angles
				if ( pPlayer != NULL && !(pPlayer->GetFlags() & FL_GODMODE) )
				{
					float yawKick = random->RandomFloat( -48, -24 );

					//Kick the player angles
					pPlayer->ViewPunch( QAngle( -16, yawKick, 2 ) );

					Vector	dir = pHurt->GetAbsOrigin() - GetAbsOrigin();

					// If the player's on my head, don't knock him up
					if ( pPlayer->GetGroundEntity() == pOperator )
					{
						dir = vecDirection;
						dir.z = 0;
					}

					VectorNormalize(dir);

					dir *= 500.0f;

					//If not on ground, then don't make them fly!
					if ( !(pPlayer->GetFlags() & FL_ONGROUND ) )
						 dir.z = 0.0f;

					//Push the target back
					pHurt->ApplyAbsVelocityImpulse( dir );

					if ( !bFlashed )
					{
						color32 red = {128,0,0,128};
						UTIL_ScreenFade( pPlayer, red, 0.5f, 0.1f, FFADE_IN );
					}
					
					// Force the player to drop anyting they were holding
					pPlayer->ForceDropOfCarriedPhysObjects();
				}
				
				// do effect?
			}
			else
			{
				WeaponSound( MELEE_MISS );
			}
		}
		break;
		default:
			BaseClass::Operator_HandleAnimEvent( pEvent, pOperator );
			break;
	}
}
void CHL2MP_Player::KickAttack(void)
{
	if (!IsDead())
	{
		CBaseViewModel *vm = GetViewModel(1);

		if (vm)
		{
			int	idealSequence = vm->SelectWeightedSequence(ACT_VM_PRIMARYATTACK);

			if (idealSequence >= 0)
			{
				vm->SendViewModelMatchingSequence(idealSequence);
				m_flNextKickAttack = gpGlobals->curtime + vm->SequenceDuration(idealSequence) - 0.5f;
			}
			QAngle	recoil = QAngle(random->RandomFloat(1.0f, 2.0f), random->RandomFloat(-1.0f, 1.0f), 0);
			this->ViewPunch(recoil);

			// Trace up or down based on where the enemy is...
			// But only if we're basically facing that direction
			Vector vecDirection;
			int kick_maxrange = 120;
			AngleVectors(QAngle(clamp(EyeAngles().x, 20, kick_maxrange), EyeAngles().y, EyeAngles().z), &vecDirection);

			CBaseEntity *pEnemy = MyNPCPointer() ? MyNPCPointer()->GetEnemy() : NULL;
			if (pEnemy)
			{
				Vector vecDelta;
				VectorSubtract(pEnemy->WorldSpaceCenter(), Weapon_ShootPosition(), vecDelta);
				VectorNormalize(vecDelta);

				Vector2D vecDelta2D = vecDelta.AsVector2D();
				Vector2DNormalize(vecDelta2D);
				if (DotProduct2D(vecDelta2D, vecDirection.AsVector2D()) > 0.8f)
				{
					vecDirection = vecDelta;
				}
			}

			Vector vecEnd;
			VectorMA(Weapon_ShootPosition(), 50, vecDirection, vecEnd);
			trace_t tr;
			UTIL_TraceHull(Weapon_ShootPosition(), vecEnd, Vector(-16, -16, -16), Vector(16, 16, 16), MASK_SHOT_HULL, this, COLLISION_GROUP_NONE, &tr);

			// did I hit someone?
			float KickDamageMult = 50 + (1 * ((fabs(GetAbsVelocity().x) + fabs(GetAbsVelocity().y) + fabs(GetAbsVelocity().z)) / 48));
			float KickThrowForceMult = 20 + (1 * ((fabs(GetAbsVelocity().x) + fabs(GetAbsVelocity().y) + fabs(GetAbsVelocity().z)) / 48));

			DevMsg("Kicking at %.2f of damage!\n", KickDamageMult);
			DevMsg("Kicking at %.2f of force!\n", KickThrowForceMult);

			if (tr.m_pEnt)
			{
				if (!(tr.m_pEnt))
				{
					//	return;
				}
				else
				{
					CBasePropDoor *pDoor = dynamic_cast<CBasePropDoor*>((CBaseEntity*)tr.m_pEnt);
					if (pDoor)
					{
						if (pDoor->HasSpawnFlags(SF_BREAKABLE_BY_PLAYER))
						{
							AngularImpulse angVelocity(random->RandomFloat(0, 45), 18, random->RandomFloat(-45, 45));
							pDoor->PlayBreakOpenSound();
							pDoor->BreakDoor(Weapon_ShootPosition(), angVelocity);
							return;
						}
						pDoor->PlayBreakFailSound();
						pDoor->KickFail();
						return;
					}

					CBaseEntity *Victim = this->CheckTraceHullAttack(Weapon_ShootPosition(), vecEnd, Vector(-16, -16, -16), Vector(16, 16, 16), KickDamageMult, DMG_CRUSH, KickThrowForceMult, true);
					if (Victim)
					{
						EmitSound("HL2Player.kick_body");
						return;
					}
				}
			}
			UTIL_TraceLine(Weapon_ShootPosition(), vecEnd, MASK_SHOT_HULL, this, COLLISION_GROUP_NONE, &tr);//IF we hit anything else
			if (tr.DidHit())
			{
				EmitSound("HL2Player.kick_wall");
			}
			else
			{
				EmitSound("HL2Player.kick_fire");
			}

		}
	}
}
예제 #8
0
void CHostageImprov::__MAKE_VHOOK(OnUpdate)(float deltaT)
{
	if (!IsAlive() || cv_hostage_stop.value > 0.0f)
		return;

	if (m_blinkTimer.IsElapsed())
	{
		if (m_scaredTimer.IsElapsed() && m_animateState.GetPerformance() != HostageAnimateState::Afraid)
		{
			m_blinkTimer.Start(RANDOM_FLOAT(3, 10));
			m_blinkCounter = RANDOM_LONG(2, 4);
		}
		else
		{
			m_blinkTimer.Start(RANDOM_FLOAT(0.5f, 2.0f));
			m_blinkCounter = RANDOM_LONG(1, 2);

		}
	}

	if (m_blinkCounter)
	{
		m_hostage->pev->body = 1;
		--m_blinkCounter;
	}
	else
	{
		m_hostage->pev->body = 0;
	}

	UpdateGrenadeReactions();
	UpdateDelayedChatter();
	UpdateVision();

	m_behavior.Update();

	m_actualVel.x = m_hostage->pev->origin.x - m_lastPosition.x;
	m_actualVel.y = m_hostage->pev->origin.y - m_lastPosition.y;

	const float runSpeed = 289.0f;
	const float walkSpeed = 9.0f;
	const float fallVelocity = -1000.0f;
	const float safeTime = 0.4f;

	if (IsOnGround())
	{
		if (IsCrouching())
		{
			if (m_actualVel.LengthSquared() > 9.0f)
			{
				if (m_animateState.GetPerformance() != HostageAnimateState::CrouchWalk)
				{
					m_animateState.Reset();
					m_animateState.SetPerformance(HostageAnimateState::CrouchWalk);

					ClearLookAt();
					if (m_scaredTimer.IsElapsed() && m_animateState.GetPerformance() != HostageAnimateState::Afraid)
						m_animateState.AddSequence(this, ACT_CROUCH_WALK, 99.9, 2.0);
					else
						m_animateState.AddSequence(this, ACT_CROUCH_WALK_SCARED, 99.9, 2.0);
				}
			}
			else if (m_animateState.GetPerformance() != HostageAnimateState::Crouch)
			{
				m_animateState.Reset();
				m_animateState.SetPerformance(HostageAnimateState::Crouch);

				if (m_scaredTimer.IsElapsed())
					m_animateState.AddSequence(this, ACT_CROUCH_IDLE, 99.9);
				else
					m_animateState.AddSequence(this, ACT_CROUCH_IDLE_SCARED);
			}
		}
		else
		{
			UTIL_MakeVectors(m_hostage->pev->angles);

			float dot = DotProduct2D(gpGlobals->v_forward, m_actualVel);

			if (dot < -3.0f)
			{
				if (m_animateState.GetPerformance() != HostageAnimateState::Walk)
				{
					m_animateState.Reset();
					m_animateState.SetPerformance(HostageAnimateState::Walk);
					ClearLookAt();

					float speed;
					if (m_actualVel.LengthSquared() > runSpeed)
						speed = 2.0f;
					else
						speed = 1.0f;

					m_animateState.AddSequence(this, ACT_WALK_BACK, 99.9, speed);
				}
			}
			else
			{
				if (m_actualVel.LengthSquared() > runSpeed)
				{
					if (m_animateState.GetPerformance() != HostageAnimateState::Run)
					{
						m_animateState.Reset();
						m_animateState.SetPerformance(HostageAnimateState::Run);
						ClearLookAt();

						if (m_scaredTimer.IsElapsed() && m_animateState.GetPerformance() != HostageAnimateState::Afraid && !m_behavior.IsState(&m_escapeState))
							m_animateState.AddSequence(this, ACT_RUN, 99.9, 2.0);
						else
							m_animateState.AddSequence(this, ACT_RUN_SCARED, 99.9, 2.0);
					}
				}
				else if (m_actualVel.LengthSquared() > walkSpeed)
				{
					if (m_animateState.GetPerformance() != HostageAnimateState::Walk)
					{
						m_animateState.Reset();
						m_animateState.SetPerformance(HostageAnimateState::Walk);
						ClearLookAt();

						if (m_behavior.IsState(&m_escapeState))
						{
							m_animateState.AddSequence(this, ACT_WALK_SNEAKY, 99.9, 1.5);
						}
						else if (m_scaredTimer.IsElapsed() && m_animateState.GetPerformance() != HostageAnimateState::Afraid)
						{
							m_animateState.AddSequence(this, ACT_WALK, 99.9, 1.5);
						}
						else
							m_animateState.AddSequence(this, ACT_WALK_SCARED, 99.9, 1.5);
					}
				}
				else
				{
					if (m_animateState.GetPerformance() == HostageAnimateState::Walk || m_animateState.GetPerformance() == HostageAnimateState::Run)
						m_animateState.Reset();

					UpdateStationaryAnimation();
				}
			}
		}
	}
	else if (m_hostage->pev->velocity.z < fallVelocity && m_animateState.GetPerformance() != HostageAnimateState::Fall)
	{
		m_animateState.Reset();
		m_animateState.SetPerformance(HostageAnimateState::Fall);
		m_animateState.AddSequence(this, ACT_FALL, 99.9);
	}

	if (!m_collisionTimer.HasStarted() || m_collisionTimer.IsGreaterThen(safeTime))
		SetKnownGoodPosition(m_lastPosition);

	m_lastPosition = m_hostage->pev->origin;
	m_animateState.OnUpdate(this);
}
예제 #9
0
// for backwards compatability
vec_t Vector2D::Dot(const Vector2D& vOther) const
{
	return DotProduct2D(*this, vOther);
}