Files

122 lines
3.9 KiB
C++

#include "gamelib/effects/weapontracemanager.h"
idWeaponTraceManager::idWeaponTraceManager()
: weaponTraces{}
, currentDeferred(0) {
Init();
}
void idWeaponTraceManager::Init() {
weaponTraces[0].Clear();
weaponTraces[1].Clear();
currentDeferred = 0;
}
void idWeaponTraceManager::Update() {
currentDeferred ^= 1;
weaponTraces[currentDeferred].Clear();
}
void idWeaponTraceManager::AddTrace(const idVec3& start,
const idVec3& end, const idSpawnId attacker,
const idDeclDamage* const damage) {
idStaticList<weaponTrace_t, 6>& traces = weaponTraces[currentDeferred];
if (traces.Num() >= traces.Max()) {
return;
}
weaponTrace_t* const trace = traces.Alloc();
trace->start = start;
trace->end = end;
trace->impactPoint = end;
trace->dir.Zero();
trace->attacker = attacker;
trace->projectile.Invalidate();
trace->damageDecl = damage;
trace->radius = 0.0f;
trace->weaponTraceType = weaponTrace_t::WEAPON_TRACE_BULLET;
}
void idWeaponTraceManager::AddExplosion(const idVec3& origin,
const float radius, const idSpawnId attacker,
const idDeclDamage* const damage) {
idStaticList<weaponTrace_t, 6>& traces = weaponTraces[currentDeferred];
if (traces.Num() >= traces.Max()) {
return;
}
weaponTrace_t* const trace = traces.Alloc();
trace->start = origin;
trace->end = origin;
trace->impactPoint = origin;
trace->dir.Zero();
trace->attacker = attacker;
trace->projectile.Invalidate();
trace->damageDecl = damage;
trace->radius = radius;
trace->weaponTraceType = weaponTrace_t::WEAPON_TRACE_EXPLOSION;
}
void idWeaponTraceManager::AddProjectile(const idVec3& origin,
const float radius, const idSpawnId attacker,
const idSpawnId projectile, const idDeclDamage* const damage) {
idStaticList<weaponTrace_t, 6>& traces = weaponTraces[currentDeferred];
if (traces.Num() >= traces.Max()) {
return;
}
weaponTrace_t* const trace = traces.Alloc();
trace->start = origin;
trace->end = origin;
trace->impactPoint = origin;
trace->dir.Zero();
trace->attacker = attacker;
trace->projectile = projectile;
trace->damageDecl = damage;
trace->radius = radius;
trace->weaponTraceType = weaponTrace_t::WEAPON_TRACE_PROJECTILE;
}
int idWeaponTraceManager::GetCollisions(const idBounds& bounds,
idList<weaponTrace_t, 5>& outTraces) {
outTraces.Clear();
const idStaticList<weaponTrace_t, 6>& traces =
weaponTraces[currentDeferred ^ 1];
for (int index = 0; index < traces.Num(); ++index) {
const weaponTrace_t& source = traces[index];
weaponTrace_t result = source;
switch (source.weaponTraceType) {
case weaponTrace_t::WEAPON_TRACE_BULLET: {
result.dir = source.end - source.start;
float scale = 0.0f;
if (!bounds.RayIntersection(source.start, result.dir, scale) ||
scale < 0.0f || scale >= 1.0f) {
continue;
}
result.dir.NormalizeFast();
result.radius = 0.0f;
break;
}
case weaponTrace_t::WEAPON_TRACE_EXPLOSION:
if (!bounds.SphereIntersection(source.start, source.radius)) {
continue;
}
result.end = (bounds[0] + bounds[1]) * 0.5f;
result.impactPoint = result.end;
result.dir = result.end - result.start;
result.dir.NormalizeFast();
break;
case weaponTrace_t::WEAPON_TRACE_PROJECTILE:
if (!bounds.SphereIntersection(source.start, source.radius)) {
continue;
}
result.end = result.start;
result.impactPoint = result.start;
result.dir.Zero();
break;
default:
continue;
}
outTraces.Append(result);
}
return outTraces.Num();
}