You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
2.5 KiB
95 lines
2.5 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#ifndef SHOT_MANIPULATOR_H |
|
#define SHOT_MANIPULATOR_H |
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
|
|
#include "mathlib/vector.h" |
|
|
|
|
|
extern ConVar ai_shot_bias_min; |
|
extern ConVar ai_shot_bias_max; |
|
|
|
|
|
//--------------------------------------------------------- |
|
// Caches off a shot direction and allows you to perform |
|
// various operations on it without having to recalculate |
|
// vecRight and vecUp each time. |
|
//--------------------------------------------------------- |
|
class CShotManipulator |
|
{ |
|
public: |
|
CShotManipulator( const Vector &vecForward ) |
|
{ |
|
SetShootDir( vecForward ); |
|
}; |
|
|
|
void SetShootDir( const Vector &vecForward ) |
|
{ |
|
m_vecShotDirection = vecForward; |
|
VectorVectors( m_vecShotDirection, m_vecRight, m_vecUp ); |
|
} |
|
|
|
const Vector &ApplySpread( const Vector &vecSpread, float bias = 1.0 ); |
|
|
|
const Vector &GetShotDirection() { return m_vecShotDirection; } |
|
const Vector &GetResult() { return m_vecResult; } |
|
const Vector &GetRightVector() { return m_vecRight; } |
|
const Vector &GetUpVector() { return m_vecUp;} |
|
|
|
private: |
|
Vector m_vecShotDirection; |
|
Vector m_vecRight; |
|
Vector m_vecUp; |
|
Vector m_vecResult; |
|
}; |
|
|
|
//--------------------------------------------------------- |
|
// Take a vector (direction) and another vector (spread) |
|
// and modify the direction to point somewhere within the |
|
// spread. This used to live inside FireBullets. |
|
//--------------------------------------------------------- |
|
inline const Vector &CShotManipulator::ApplySpread( const Vector &vecSpread, float bias ) |
|
{ |
|
// get circular gaussian spread |
|
float x, y, z; |
|
|
|
if ( bias > 1.0 ) |
|
bias = 1.0; |
|
else if ( bias < 0.0 ) |
|
bias = 0.0; |
|
|
|
float shotBiasMin = ai_shot_bias_min.GetFloat(); |
|
float shotBiasMax = ai_shot_bias_max.GetFloat(); |
|
|
|
// 1.0 gaussian, 0.0 is flat, -1.0 is inverse gaussian |
|
float shotBias = ( ( shotBiasMax - shotBiasMin ) * bias ) + shotBiasMin; |
|
|
|
float flatness = ( fabsf(shotBias) * 0.5 ); |
|
|
|
do |
|
{ |
|
x = random->RandomFloat(-1,1) * flatness + random->RandomFloat(-1,1) * (1 - flatness); |
|
y = random->RandomFloat(-1,1) * flatness + random->RandomFloat(-1,1) * (1 - flatness); |
|
if ( shotBias < 0 ) |
|
{ |
|
x = ( x >= 0 ) ? 1.0 - x : -1.0 - x; |
|
y = ( y >= 0 ) ? 1.0 - y : -1.0 - y; |
|
} |
|
z = x*x+y*y; |
|
} while (z > 1); |
|
|
|
m_vecResult = m_vecShotDirection + x * vecSpread.x * m_vecRight + y * vecSpread.y * m_vecUp; |
|
|
|
return m_vecResult; |
|
} |
|
|
|
|
|
#endif // SHOT_MANIPULATOR_H
|
|
|