This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
nekohook/modules/source2013/sdk/game/shared/shot_manipulator.h
2020-08-04 13:13:01 -04:00

88 lines
2.7 KiB
C++

//========= 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