mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Seeker system and network enabled laser simulation.
This commit is contained in:
parent
4188893839
commit
8386c0e22a
@ -1,3 +1,4 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
NO_DEDICATED;
|
|
||||||
|
|
||||||
|
["laser_laserOn", {_this call DFUNC(handleLaserOn)}] call EFUNC(common,addEventHandler);
|
||||||
|
["laser_laserOff", {_this call DFUNC(handleLaserOff)}] call EFUNC(common,addEventHandler);
|
||||||
|
@ -12,9 +12,18 @@ PREP(findStrongestRay);
|
|||||||
PREP(translateToModelSpace);
|
PREP(translateToModelSpace);
|
||||||
PREP(translateToWeaponSpace);
|
PREP(translateToWeaponSpace);
|
||||||
|
|
||||||
|
PREP(seekerFindLaserSpot);
|
||||||
|
PREP(laserOn);
|
||||||
|
PREP(laserOff);
|
||||||
|
PREP(handleLaserOn);
|
||||||
|
PREP(handleLaserOff);
|
||||||
|
|
||||||
|
|
||||||
PREP(laser_init);
|
PREP(laser_init);
|
||||||
|
|
||||||
PREP(laserTargetPFH);
|
PREP(laserTargetPFH);
|
||||||
|
|
||||||
ACE_LASERS = [];
|
ACE_LASERS = [];
|
||||||
ACE_DEFAULT_LASER_CODE = 1001;
|
ACE_DEFAULT_LASER_CODE = 1001;
|
||||||
|
|
||||||
|
GVAR(laserEmitters) = HASH_CREATE;
|
8
addons/laser/functions/fnc_handleLaserOff.sqf
Normal file
8
addons/laser/functions/fnc_handleLaserOff.sqf
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
//fnc_handleLaserOff.sqf
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
private ["_uuid"];
|
||||||
|
_uuid = _this select 0;
|
||||||
|
if(HASH_HASKEY(GVAR(laserEmitters), _uuid)) then {
|
||||||
|
HASH_REM(GVAR(laserEmitters), _uuid);
|
||||||
|
};
|
7
addons/laser/functions/fnc_handleLaserOn.sqf
Normal file
7
addons/laser/functions/fnc_handleLaserOn.sqf
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
//fnc_handleLaserOn.sqf
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
private ["_uuid", "_args"];
|
||||||
|
_uuid = _this select 0;
|
||||||
|
_args = _this select 1;
|
||||||
|
HASH_SET(GVAR(laserEmitters), _uuid, _args);
|
16
addons/laser/functions/fnc_laserOff.sqf
Normal file
16
addons/laser/functions/fnc_laserOff.sqf
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Author: Nou
|
||||||
|
* Turn a laser designator off.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: UUID (from laserOn) <string>
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* None
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
private ["_uuid"];
|
||||||
|
_uuid = _this select 0;
|
||||||
|
["laser_laserOff", [_uuid]] call EFUNC(common,globalEvent);
|
23
addons/laser/functions/fnc_laserOn.sqf
Normal file
23
addons/laser/functions/fnc_laserOn.sqf
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Author: Nou
|
||||||
|
* Turn a laser designator on.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Emitter <object>
|
||||||
|
* 1: Owner <object>
|
||||||
|
* 2: Method, can be code, which emitter and owner are passed to, an array with a position memory point and weapon name, or an array with a position memory point, a vector begining memory point, and vector ending memory point.
|
||||||
|
* 3: Wavelength (1550nm is common eye safe) <number>
|
||||||
|
* 4: Laser code <number>
|
||||||
|
* 5: Beam divergence (in mils off beam center).
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* String, UUID for sending to laserOff function.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
private ["_uuid", "_args"];
|
||||||
|
_uuid = format["%1%2%3", floor diag_tickTime, floor random 1000, floor random 10000];
|
||||||
|
_args = [_uuid, _this];
|
||||||
|
["laser_laserOn", _args] call EFUNC(common,globalEvent);
|
||||||
|
_uuid;
|
@ -32,7 +32,5 @@ if (_d != 0) then {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Inverse of step 1 */
|
/* Inverse of step 1 */
|
||||||
_q1 set[0, (_q2 select 0) + (_p1 select 0)];
|
_q1 = _q2 vectorAdd _p1;
|
||||||
_q1 set[1, (_q2 select 1) + (_p1 select 1)];
|
|
||||||
_q1 set[2, (_q2 select 2) + (_p1 select 2)];
|
|
||||||
_q1;
|
_q1;
|
@ -5,19 +5,12 @@ _p = _this select 0;
|
|||||||
_p1 = _this select 1;
|
_p1 = _this select 1;
|
||||||
_p2 = _this select 2;
|
_p2 = _this select 2;
|
||||||
|
|
||||||
_q1 = [];
|
|
||||||
_q2 = [];
|
_q2 = [];
|
||||||
_u = [];
|
|
||||||
|
|
||||||
/* Step 1 */
|
/* Step 1 */
|
||||||
_q1 set[0, (_p select 0) - (_p1 select 0)];
|
_q1 = _p vectorDiff _p1;
|
||||||
_q1 set[1, (_p select 1) - (_p1 select 1)];
|
_u = _p2 vectorDiff _p1;
|
||||||
_q1 set[2, (_p select 2) - (_p1 select 2)];
|
_u = vectorNormalized _u;
|
||||||
|
|
||||||
_u set[0, (_p2 select 0) - (_p1 select 0)];
|
|
||||||
_u set[1, (_p2 select 1) - (_p1 select 1)];
|
|
||||||
_u set[2, (_p2 select 2) - (_p1 select 2)];
|
|
||||||
_u = _u call BIS_fnc_unitVector;
|
|
||||||
_d = sqrt((_u select 1)*(_u select 1) + (_u select 2)*(_u select 2));
|
_d = sqrt((_u select 1)*(_u select 1) + (_u select 2)*(_u select 2));
|
||||||
|
|
||||||
/* Step 2 */
|
/* Step 2 */
|
||||||
|
139
addons/laser/functions/fnc_seekerFindLaserSpot.sqf
Normal file
139
addons/laser/functions/fnc_seekerFindLaserSpot.sqf
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Author: Nou
|
||||||
|
* Turn a laser designator on.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Position of seeker (ASL) <position>
|
||||||
|
* 1: Seeker wavelength sensitivity range, [1550,1550] is common eye safe. <array>
|
||||||
|
* 2: Seeker laser code. <number>
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* Array, [Strongest compatible laser spot ASL pos, owner object] Nil array values if nothing found.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
private ["_pos", "_seekerWavelengths", "_seekerCode", "_spots", "_buckets", "_excludes", "_bucketIndex", "_finalPos", "_owner", "_obj", "_x", "_method",
|
||||||
|
"_emitterWavelength", "_laserCode", "_divergence", "_laser", "_laserPos", "_laserDir", "_res", "_bucketPos", "_bucketList", "_c", "_forEachIndex", "_index",
|
||||||
|
"_testPos", "_finalBuckets", "_largest", "_largestIndex", "_finalBucket", "_owners", "_avgX", "_avgY", "_avgZ", "_count", "_maxOwner", "_maxOwnerIndex", "_finalOwner"];
|
||||||
|
|
||||||
|
_pos = _this select 0;
|
||||||
|
_seekerWavelengths = _this select 1;
|
||||||
|
_seekerCode = _this select 2;
|
||||||
|
|
||||||
|
_spots = [];
|
||||||
|
_buckets = [];
|
||||||
|
_excludes = [];
|
||||||
|
_bucketIndex = 0;
|
||||||
|
_finalPos = nil;
|
||||||
|
_finalOwner = nil;
|
||||||
|
|
||||||
|
{
|
||||||
|
_obj = _x select 0;
|
||||||
|
_owner = _x select 1;
|
||||||
|
_method = _x select 2;
|
||||||
|
_emitterWavelength = _x select 3;
|
||||||
|
_laserCode = _x select 4;
|
||||||
|
_divergence = _x select 5;
|
||||||
|
if(alive _obj && {_emitterWavelength >= (_seekerWavelengths select 0)} && {_emitterWavelength <= (_seekerWavelengths select 1)} && {_laserCode == _seekerCode}) then {
|
||||||
|
_laser = [];
|
||||||
|
if(IS_CODE(_method)) then {
|
||||||
|
_laser = _x call _method;
|
||||||
|
} else {
|
||||||
|
if(IS_ARRAY(_method)) then {
|
||||||
|
if(count _method == 2) then {
|
||||||
|
_laser = [ATLtoASL (_obj modelToWorldVisual (_method select 0)), _obj weaponDirection (_method select 1)];
|
||||||
|
} else {
|
||||||
|
if(count _method == 3) then {
|
||||||
|
_laser = [ATLtoASL (_obj modelToWorldVisual (_method select 0)), (ATLtoASL (_obj modelToWorldVisual (_method select 1))) vectorFromTo (ATLtoASL (_obj modelToWorldVisual (_method select 2)))];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
_laserPos = _laser select 0;
|
||||||
|
_laserDir = _laser select 1;
|
||||||
|
_res = [_laserPos, _laserDir, _divergence] call FUNC(shootCone);
|
||||||
|
{
|
||||||
|
_spots pushBack [_x select 0, _owner];
|
||||||
|
} forEach (_res select 2);
|
||||||
|
};
|
||||||
|
} forEach (GVAR(laserEmitters) select 1);
|
||||||
|
|
||||||
|
if((count _spots) > 0) then {
|
||||||
|
_bucketPos = nil;
|
||||||
|
_bucketList = nil;
|
||||||
|
_c = 0;
|
||||||
|
while { count(_spots) != count(_excludes) && _c < (count _spots) } do {
|
||||||
|
scopeName "mainSearch";
|
||||||
|
{
|
||||||
|
if(!(_forEachIndex in _excludes)) then {
|
||||||
|
_index = _buckets pushBack [_x, [_x]];
|
||||||
|
_excludes pushBack _forEachIndex;
|
||||||
|
_bucketPos = _x select 0;
|
||||||
|
_bucketList = (_buckets select _index) select 1;
|
||||||
|
breakTo "mainSearch";
|
||||||
|
};
|
||||||
|
} forEach _spots;
|
||||||
|
{
|
||||||
|
if(!(_forEachIndex in _excludes)) then {
|
||||||
|
_testPos = (_x select 0);
|
||||||
|
if(_testPos vectorDistanceSqr _bucketPos <= 100) then {
|
||||||
|
_bucketList pushBack _x;
|
||||||
|
_excludes pushBack _forEachIndex;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} forEach _spots;
|
||||||
|
_c = _c + 1;
|
||||||
|
};
|
||||||
|
_finalBuckets = [];
|
||||||
|
_largest = -1;
|
||||||
|
_largestIndex = 0;
|
||||||
|
{
|
||||||
|
_index = _finalBuckets pushBack [];
|
||||||
|
_bucketList = _finalBuckets select _index;
|
||||||
|
{
|
||||||
|
_testPos = (_x select 0);
|
||||||
|
if(!terrainIntersectASL [_pos, _testPos] && {!lineIntersects [_pos, _testPos]}) then {
|
||||||
|
_bucketList pushBack _x;
|
||||||
|
};
|
||||||
|
} forEach (_x select 1);
|
||||||
|
if((count _bucketList) > _largest) then {
|
||||||
|
_largest = (count _bucketList);
|
||||||
|
_largestIndex = _index;
|
||||||
|
};
|
||||||
|
} forEach _buckets;
|
||||||
|
|
||||||
|
_finalBucket = _finalBuckets select _largestIndex;
|
||||||
|
_owners = HASH_CREATE;
|
||||||
|
|
||||||
|
if(count _finalBucket > 0) then {
|
||||||
|
_avgX = 0;
|
||||||
|
_avgY = 0;
|
||||||
|
_avgZ = 0;
|
||||||
|
{
|
||||||
|
player sideChat format["x: %1", _x];
|
||||||
|
_avgX = _avgX + ((_x select 0) select 0);
|
||||||
|
_avgY = _avgY + ((_x select 0) select 1);
|
||||||
|
_avgZ = _avgZ + ((_x select 0) select 2);
|
||||||
|
_owner = _x select 1;
|
||||||
|
if(HASH_HASKEY(_owners, _owner)) then {
|
||||||
|
_count = HASH_GET(_owners, _owner);
|
||||||
|
HASH_SET(_owners, _owner, _count+1);
|
||||||
|
} else {
|
||||||
|
HASH_SET(_owners, _owner, 1);
|
||||||
|
};
|
||||||
|
} forEach _finalBucket;
|
||||||
|
_count = count _finalBucket;
|
||||||
|
_finalPos = [_avgX/_count, _avgY/_count, _avgZ/_count];
|
||||||
|
_maxOwner = -1;
|
||||||
|
_maxOwnerIndex = 0;
|
||||||
|
{
|
||||||
|
if((_owners select 1) select _forEachIndex > _maxOwner) then {
|
||||||
|
_maxOwner = (_owners select 1) select _forEachIndex;
|
||||||
|
_maxOwnerIndex = _forEachIndex;
|
||||||
|
};
|
||||||
|
} forEach (_owners select 0);
|
||||||
|
_finalOwner = (_owners select 0) select _maxOwnerIndex;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
[_finalPos, _owner];
|
@ -1,8 +1,13 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
// #define DEBUG_MODE_FULL
|
||||||
|
private ["_divergence","_pos","_vec","_longestReturn","_shortestReturn","_resultPositions","_p1","_p2","_p","_v","_cp","_vecRotateMap","_result",
|
||||||
|
"_resultPos","_distance","_count","_pos2","_radOffset","_offset","_offsetPos","_offsetVector"];
|
||||||
_divergence = 0.3;
|
_divergence = 0.3;
|
||||||
_pos = _this select 0;
|
_pos = _this select 0;
|
||||||
_vec = _this select 1;
|
_vec = _this select 1;
|
||||||
|
if(count _this > 2) then {
|
||||||
|
_divergence = _this select 2;
|
||||||
|
};
|
||||||
_longestReturn = -1000000000;
|
_longestReturn = -1000000000;
|
||||||
_shortestReturn = 1000000000;
|
_shortestReturn = 1000000000;
|
||||||
_resultPositions = [];
|
_resultPositions = [];
|
||||||
@ -10,7 +15,7 @@ _p1 = [0,0,0];
|
|||||||
_p2 = +_vec;
|
_p2 = +_vec;
|
||||||
_p = (_vec call CBA_fnc_vect2polar);
|
_p = (_vec call CBA_fnc_vect2polar);
|
||||||
_v = [(_p select 0), (_p select 1), (_p select 2)+90] call CBA_fnc_polar2vect;
|
_v = [(_p select 0), (_p select 1), (_p select 2)+90] call CBA_fnc_polar2vect;
|
||||||
_cp = [_vec, _v] call BIS_fnc_crossProduct;
|
_cp = _vec vectorCrossProduct _v;
|
||||||
|
|
||||||
_vecRotateMap = [_cp, _p1, _p2] call FUNC(rotateVectLineGetMap);
|
_vecRotateMap = [_cp, _p1, _p2] call FUNC(rotateVectLineGetMap);
|
||||||
|
|
||||||
@ -24,28 +29,21 @@ if(!isNil "_resultPos") then {
|
|||||||
if(_distance > _longestReturn) then {
|
if(_distance > _longestReturn) then {
|
||||||
_longestReturn = _distance;
|
_longestReturn = _distance;
|
||||||
};
|
};
|
||||||
_resultPositions set[(count _resultPositions), _result];
|
_resultPositions pushBack _result;
|
||||||
#ifdef DEBUG_MODE_FULL
|
#ifdef DEBUG_MODE_FULL
|
||||||
DRAW_LINES set[(count DRAW_LINES), [_pos, _resultPos, [0, 1, 0, 1]]];
|
// DRAW_LINES set[(count DRAW_LINES), [_pos, _resultPos, [0, 1, 0, 1]]];
|
||||||
|
drawLine3D [ASLtoATL _pos, ASLtoATL _resultPos, [1,0,0,1]];
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
_count = 8;
|
_count = 8;
|
||||||
|
|
||||||
_pos2 = [
|
_pos2 = _pos vectorAdd (_vec vectorMultiply 1000);
|
||||||
(_pos select 0)+((_vec select 0)*1000),
|
|
||||||
(_pos select 1)+((_vec select 1)*1000),
|
|
||||||
(_pos select 2)+((_vec select 2)*1000)
|
|
||||||
];
|
|
||||||
{
|
{
|
||||||
for "_i" from 0 to ceil(_count*_x) do {
|
for "_i" from 0 to ceil(_count*_x) do {
|
||||||
_radOffset = random 360;
|
_radOffset = random 360;
|
||||||
_offset = [_vecRotateMap, (((360/_count)*_i)+_radOffset) mod 360] call FUNC(rotateVectLine);
|
_offset = [_vecRotateMap, (((360/_count)*_i)+_radOffset) mod 360] call FUNC(rotateVectLine);
|
||||||
_offsetPos = [
|
_offsetPos = _pos2 vectorAdd (_offset vectorMultiply (_divergence*_x));
|
||||||
(_pos2 select 0)+((_offset select 0)*(_divergence*_x)),
|
_offsetVector = _pos vectorFromTo _offsetPos;
|
||||||
(_pos2 select 1)+((_offset select 1)*(_divergence*_x)),
|
|
||||||
(_pos2 select 2)+((_offset select 2)*(_divergence*_x))
|
|
||||||
];
|
|
||||||
_offsetVector = [_pos, _offsetPos] call BIS_fnc_vectorFromXtoY;
|
|
||||||
_result = [_pos, _offsetVector] call FUNC(shootRay);
|
_result = [_pos, _offsetVector] call FUNC(shootRay);
|
||||||
_resultPos = _result select 0;
|
_resultPos = _result select 0;
|
||||||
if(!isNil "_resultPos") then {
|
if(!isNil "_resultPos") then {
|
||||||
@ -56,9 +54,10 @@ _pos2 = [
|
|||||||
if(_distance > _longestReturn) then {
|
if(_distance > _longestReturn) then {
|
||||||
_longestReturn = _distance;
|
_longestReturn = _distance;
|
||||||
};
|
};
|
||||||
_resultPositions set[(count _resultPositions), _result];
|
_resultPositions pushBack _result;
|
||||||
#ifdef DEBUG_MODE_FULL
|
#ifdef DEBUG_MODE_FULL
|
||||||
DRAW_LINES set[(count DRAW_LINES), [_pos, _resultPos, [0, 1, 0, 1]]];
|
// DRAW_LINES set[(count DRAW_LINES), [_pos, _resultPos, [0, 1, 0, 1]]];
|
||||||
|
drawLine3D [ASLtoATL _pos, ASLtoATL _resultPos, [1,0,0,1]];
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -11,13 +11,8 @@ _lastPos = +_pos;
|
|||||||
{
|
{
|
||||||
scopeName "mainSearch";
|
scopeName "mainSearch";
|
||||||
for "_i" from 1 to 10 do {
|
for "_i" from 1 to 10 do {
|
||||||
_nextPos = [
|
_nextPos = _lastPos vectorAdd (_vec vectorMultiply _x);
|
||||||
(_lastPos select 0)+((_vec select 0)*_x),
|
if(terrainIntersectASL [_lastPos, _nextPos] || {lineIntersects [_lastPos, _nextPos]}) then {
|
||||||
(_lastPos select 1)+((_vec select 1)*_x),
|
|
||||||
(_lastPos select 2)+((_vec select 2)*_x)
|
|
||||||
];
|
|
||||||
|
|
||||||
if(lineIntersects [_lastPos, _nextPos] || terrainIntersectASL [_lastPos, _nextPos]) then {
|
|
||||||
_resultPos = _lastPos;
|
_resultPos = _lastPos;
|
||||||
breakTo "mainSearch";
|
breakTo "mainSearch";
|
||||||
} else {
|
} else {
|
||||||
@ -25,6 +20,5 @@ _lastPos = +_pos;
|
|||||||
_lastPos = _nextPos;
|
_lastPos = _nextPos;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
} forEach _fidelity;
|
} forEach _fidelity;
|
||||||
[_resultPos, _distance];
|
[_resultPos, _distance];
|
Loading…
Reference in New Issue
Block a user