Hey guys,
with ur help in this Topic I managed to write a script which can predict a targets Position in the moment when ur current magazines ammo is reaching it.
I ll post an example Mission within the next days.
And here it is:
/*
Author: Sarogahtyp
File: pre_tar_pos.sqf
Description:
Calculates the postion of a moving target at the time the bullet of shooters current magazine is arriving at target.
Works with most self propelled weapons, too. Works with vehicles. Tested without MODs only - vanilla style.
Version 0.0 Pre-Alpha
Known issues:
Not working with RPG but will be fixed soon.
Parameter(s):
0: target - the object the shooter wants to shoot at - default is the nearest target to shooters crosshair
1: shooter - the one who wants to shoot at target - default is the player
Returns:
position - position of the target when the current bullet will reach it
*/
params [["_target", cursorTarget], ["_shooter", player],
["_speed_coef_muzzle", 1], ["_flight_dist", 0], "_weapon", "_magazine", "_init_speed_gun", "_init_speed_mag",
"_ammo_class", "_air_friction", "_items", "_init_time", "_max_speed", "_thrust", "_thrust_time", "_rel_speed",
["_air_fric_fact", -0.002], ["_burned_out", false], ["_prop_started", false], ["_burn_time", 0], ["_last_dist", 0],
["_last_time", 0], ["_time_diff", 0], "_distance", "_dist_step", "_last_speed", "_last_accel", "_new_dist", "_term",
"_new_time", "_new_speed", "_new_accel"];
_shooter = vehicle _shooter;
_weapon = currentWeapon _shooter;
_magazine = currentMagazine _shooter;
_init_speed_gun = getNumber(configfile >> "CfgWeapons" >> _weapon >> "initSpeed");
_init_speed_mag = getNumber(configfile >> "CfgMagazines" >> _magazine >> "initSpeed");
_ammo_class = getText(configFile >> "CfgMagazines" >> _magazine >> "ammo");
_air_friction = getNumber(configFile >> "CfgAmmo" >> _ammo_class >> "airFriction");
_items = _shooter weaponAccessories _weapon;
_init_time = getNumber(configFile >> "CfgAmmo" >> _ammo_class >> "initTime");
_max_speed = getNumber(configFile >> "CfgAmmo" >> _ammo_class >> "maxSpeed");
_thrust = getNumber(configFile >> "CfgAmmo" >> _ammo_class >> "thrust");
_thrust_time = getNumber(configFile >> "CfgAmmo" >> _ammo_class >> "thrustTime");;
_rel_speed = ((velocity _target) vectorDiff (velocity _shooter));
if((_init_speed_gun) < 0) then
{
_init_speed_gun = -1 * init_speed_gun * _init_speed_mag;
};
if((_init_speed_gun) == 0) then
{
_init_speed_gun = _init_speed_mag;
};
{
if((_x find "muzzle") > -1) then
{
_temp_coef = getNumber(configfile >> "CfgWeapons" >> _x >> "ItemInfo" >> "MagazineCoef" >> "initSpeed");
_speed_coef_muzzle = if (_temp_coef !=0) then {_temp_coef}else{1};
};
} forEach _items;
_init_speed_gun = _init_speed_gun * _speed_coef_muzzle;
if((vectorMagnitude _rel_speed) > 0) exitWith
{
_distance = _target distance _shooter;
if(_air_friction > 0) then {_air_friction = _air_friction * _air_fric_fact;};
_dist_step = _distance / (10 * diag_fps);
_last_speed = _init_speed_gun;
_last_accel = _air_friction * _init_speed_gun ^ 2;
while {_last_dist < _distance} do
{
_new_dist = _last_dist + _dist_step;
//calculate time from last position to actual position (_time_diff)
if (_last_accel < 0) then // standard case - bullet is decelerated by airflow
{
_term = _last_speed / _last_accel;
_time_diff = -1 * sqrt (_term ^ 2 + 2 * _dist_step / _last_accel) - _term;
}
else
{
if(_last_accel == 0) then //maybe no value for air friction stored in config then we have just t=s/v
{
_time_diff = _dist_step / _last_speed;
}
else // positive acceleration should happen if a propulsion is burning only
{
_term = _last_speed / _last_accel;
_time_diff = sqrt (_term ^ 2 + 2 * _dist_step / _last_accel) - _term;
};
};
_new_time = _time_diff + _last_time;
_new_speed = _last_speed + _last_accel * _time_diff;
if(_new_speed <= 0) exitWith {0};
_new_accel = _air_friction * _new_speed ^ 2; //calc air frictions influence to acceleration
//check if bullet is a rocket and if propulsion should accelerate
if((_max_speed > 30) and (!_burned_out) and (_last_time > _init_time)) then
{
if(!_prop_started) then
{
_prop_started = true;
_burn_time = diag_tickTime + _thrust_time;
}
else
{
if(diag_tickTime > _burn_time) then
{
_burned_out = true;
};
};
_new_accel = _new_accel + _thrust;
};
_last_dist = _new_dist;
_last_time = _new_time;
_last_speed = _new_speed;
_last_accel = _new_accel;
};
((_target modelToWorld [0,0,1.2]) vectorAdd (_rel_speed vectorMultiply _last_time))
};
(_target modelToWorld [0,0,1.2])
Now I d like to optimize that script some more.
My first question:
Is the way I use params a good one?
I just put every local variable in it to ensure it is private.
The Problem I see is that someone could pass more than the 2 thought Parameters to the script. That would destroy the calculations. How can I avoid this?
Beside that question tell me ur thoughts about the script please and also if u think ist worth a release if its more optimized.
EDIT: this script is thought to be executed once each frame
EDIT: moving this to first post ...