mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 22:56:30 -10:00
Most places in the code that use `vm_vector_2_matrix` do so on already-normalized vectors. Changing these to `vm_vector_2_matrix_norm` avoids redundant normalization.
139 lines
3.8 KiB
C++
139 lines
3.8 KiB
C++
/*
|
|
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
|
*
|
|
* All source code herein is the property of Volition, Inc. You may not sell
|
|
* or otherwise commercially exploit the source or things you created based on the
|
|
* source.
|
|
*
|
|
*/
|
|
|
|
|
|
|
|
#include "object/object.h"
|
|
#include "weapon/flak.h"
|
|
#include "weapon/muzzleflash.h"
|
|
|
|
// --------------------------------------------------------------------------------------------------------------------------------------
|
|
// FLAK FUNCTIONS
|
|
//
|
|
|
|
/**
|
|
* Initialize flak stuff for the level
|
|
*/
|
|
void flak_level_init()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Close down flak stuff
|
|
*/
|
|
void flak_level_close()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Given a just fired flak shell, pick a detonating distance for it
|
|
*/
|
|
void flak_pick_range(object *objp, const vec3d * /*firing_pos*/, const vec3d *predicted_target_pos, float weapon_subsys_strength)
|
|
{
|
|
float final_range;
|
|
float det_range;
|
|
vec3d temp;
|
|
|
|
// make sure this flak object is valid
|
|
Assert(objp->type == OBJ_WEAPON);
|
|
Assert(objp->instance >= 0);
|
|
Assert(Weapons[objp->instance].weapon_info_index >= 0);
|
|
Assert(Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags[Weapon::Info_Flags::Flak]);
|
|
|
|
weapon_info* wip = &Weapon_info[Weapons[objp->instance].weapon_info_index];
|
|
|
|
// get the range to the target
|
|
vm_vec_sub(&temp, &objp->pos, predicted_target_pos);
|
|
final_range = vm_vec_mag(&temp);
|
|
|
|
//Is it larger than det_range?
|
|
det_range = wip->det_range;
|
|
if(det_range != 0.0f && final_range > det_range)
|
|
{
|
|
flak_set_range(objp, det_range);
|
|
return;
|
|
}
|
|
|
|
// add in some randomness
|
|
float random_range = ((wip->flak_detonation_accuracy + (wip->flak_detonation_accuracy * 0.65f * (1.0f - weapon_subsys_strength))) * frand_range(-1.0f, 1.0f));
|
|
final_range += random_range;
|
|
|
|
// make sure we're firing at least 10 meters away, or the weapons' arm distance if one was defined.
|
|
if (wip->arm_dist > 0.0f) {
|
|
if(final_range < wip->arm_dist){
|
|
final_range = wip->arm_dist;
|
|
}
|
|
} else {
|
|
if (final_range < 10.0f) {
|
|
final_range = 10.0f;
|
|
}
|
|
}
|
|
|
|
// set the range
|
|
flak_set_range(objp, final_range);
|
|
}
|
|
|
|
/**
|
|
* Add some jitter to a flak gun's aiming direction, take into account range to target so that we're never _too_ far off
|
|
* assumes dir is normalized
|
|
*/
|
|
void flak_jitter_aim(vec3d *dir, float dist_to_target, float weapon_subsys_strength, const weapon_info *wip)
|
|
{
|
|
vec3d rand_twist_pre, rand_twist_post;
|
|
matrix temp;
|
|
vec3d final_aim;
|
|
float error_val;
|
|
|
|
// get the matrix needed to rotate the base direction to the actual direction
|
|
vm_vector_2_matrix_norm(&temp, dir, nullptr, nullptr);
|
|
|
|
// error value
|
|
error_val = wip->flak_targeting_accuracy + (wip->flak_targeting_accuracy * 0.65f * (1.0f - weapon_subsys_strength));
|
|
|
|
// scale the rvec by some random value and make it the "pre-twist" value
|
|
float rand_dist = frand_range(0.0f, error_val);
|
|
// no jitter - so do nothing
|
|
if(rand_dist <= 0.0f){
|
|
return;
|
|
}
|
|
vm_vec_copy_scale(&rand_twist_pre, &temp.vec.rvec, rand_dist);
|
|
|
|
// now rotate the twist vector around the x axis (the base aim axis) at a random angle
|
|
vm_rot_point_around_line(&rand_twist_post, &rand_twist_pre, fl_radians(359.0f * frand_range(0.0f, 1.0f)), &vmd_zero_vector, dir);
|
|
|
|
// add the resulting vector to the base aim vector and normalize
|
|
final_aim = *dir;
|
|
vm_vec_scale(&final_aim, dist_to_target);
|
|
vm_vec_add(dir, &final_aim, &rand_twist_post);
|
|
vm_vec_normalize(dir);
|
|
}
|
|
|
|
/**
|
|
* Given a just fired flak shell, pick a detonating distance for it
|
|
*/
|
|
void flak_set_range(object *objp, float range)
|
|
{
|
|
Assert(objp->type == OBJ_WEAPON);
|
|
Assert(objp->instance >= 0);
|
|
|
|
// setup the flak info
|
|
Weapons[objp->instance].det_range = range;
|
|
}
|
|
|
|
/**
|
|
* Get the current range for the flak object
|
|
*/
|
|
float flak_get_range(object *objp)
|
|
{
|
|
Assert(objp->type == OBJ_WEAPON);
|
|
Assert(objp->instance >= 0);
|
|
|
|
return Weapons[objp->instance].det_range;
|
|
}
|