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"
|
||||
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(translateToWeaponSpace);
|
||||
|
||||
PREP(seekerFindLaserSpot);
|
||||
PREP(laserOn);
|
||||
PREP(laserOff);
|
||||
PREP(handleLaserOn);
|
||||
PREP(handleLaserOff);
|
||||
|
||||
|
||||
PREP(laser_init);
|
||||
|
||||
PREP(laserTargetPFH);
|
||||
|
||||
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 */
|
||||
_q1 set[0, (_q2 select 0) + (_p1 select 0)];
|
||||
_q1 set[1, (_q2 select 1) + (_p1 select 1)];
|
||||
_q1 set[2, (_q2 select 2) + (_p1 select 2)];
|
||||
_q1 = _q2 vectorAdd _p1;
|
||||
_q1;
|
@ -5,19 +5,12 @@ _p = _this select 0;
|
||||
_p1 = _this select 1;
|
||||
_p2 = _this select 2;
|
||||
|
||||
_q1 = [];
|
||||
_q2 = [];
|
||||
_u = [];
|
||||
|
||||
/* Step 1 */
|
||||
_q1 set[0, (_p select 0) - (_p1 select 0)];
|
||||
_q1 set[1, (_p select 1) - (_p1 select 1)];
|
||||
_q1 set[2, (_p select 2) - (_p1 select 2)];
|
||||
|
||||
_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;
|
||||
_q1 = _p vectorDiff _p1;
|
||||
_u = _p2 vectorDiff _p1;
|
||||
_u = vectorNormalized _u;
|
||||
_d = sqrt((_u select 1)*(_u select 1) + (_u select 2)*(_u select 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"
|
||||
|
||||
// #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;
|
||||
_pos = _this select 0;
|
||||
_vec = _this select 1;
|
||||
if(count _this > 2) then {
|
||||
_divergence = _this select 2;
|
||||
};
|
||||
_longestReturn = -1000000000;
|
||||
_shortestReturn = 1000000000;
|
||||
_resultPositions = [];
|
||||
@ -10,7 +15,7 @@ _p1 = [0,0,0];
|
||||
_p2 = +_vec;
|
||||
_p = (_vec call CBA_fnc_vect2polar);
|
||||
_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);
|
||||
|
||||
@ -24,28 +29,21 @@ if(!isNil "_resultPos") then {
|
||||
if(_distance > _longestReturn) then {
|
||||
_longestReturn = _distance;
|
||||
};
|
||||
_resultPositions set[(count _resultPositions), _result];
|
||||
_resultPositions pushBack _result;
|
||||
#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
|
||||
};
|
||||
_count = 8;
|
||||
|
||||
_pos2 = [
|
||||
(_pos select 0)+((_vec select 0)*1000),
|
||||
(_pos select 1)+((_vec select 1)*1000),
|
||||
(_pos select 2)+((_vec select 2)*1000)
|
||||
];
|
||||
_pos2 = _pos vectorAdd (_vec vectorMultiply 1000);
|
||||
{
|
||||
for "_i" from 0 to ceil(_count*_x) do {
|
||||
_radOffset = random 360;
|
||||
_offset = [_vecRotateMap, (((360/_count)*_i)+_radOffset) mod 360] call FUNC(rotateVectLine);
|
||||
_offsetPos = [
|
||||
(_pos2 select 0)+((_offset select 0)*(_divergence*_x)),
|
||||
(_pos2 select 1)+((_offset select 1)*(_divergence*_x)),
|
||||
(_pos2 select 2)+((_offset select 2)*(_divergence*_x))
|
||||
];
|
||||
_offsetVector = [_pos, _offsetPos] call BIS_fnc_vectorFromXtoY;
|
||||
_offsetPos = _pos2 vectorAdd (_offset vectorMultiply (_divergence*_x));
|
||||
_offsetVector = _pos vectorFromTo _offsetPos;
|
||||
_result = [_pos, _offsetVector] call FUNC(shootRay);
|
||||
_resultPos = _result select 0;
|
||||
if(!isNil "_resultPos") then {
|
||||
@ -56,9 +54,10 @@ _pos2 = [
|
||||
if(_distance > _longestReturn) then {
|
||||
_longestReturn = _distance;
|
||||
};
|
||||
_resultPositions set[(count _resultPositions), _result];
|
||||
_resultPositions pushBack _result;
|
||||
#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
|
||||
};
|
||||
};
|
||||
|
@ -11,13 +11,8 @@ _lastPos = +_pos;
|
||||
{
|
||||
scopeName "mainSearch";
|
||||
for "_i" from 1 to 10 do {
|
||||
_nextPos = [
|
||||
(_lastPos select 0)+((_vec select 0)*_x),
|
||||
(_lastPos select 1)+((_vec select 1)*_x),
|
||||
(_lastPos select 2)+((_vec select 2)*_x)
|
||||
];
|
||||
|
||||
if(lineIntersects [_lastPos, _nextPos] || terrainIntersectASL [_lastPos, _nextPos]) then {
|
||||
_nextPos = _lastPos vectorAdd (_vec vectorMultiply _x);
|
||||
if(terrainIntersectASL [_lastPos, _nextPos] || {lineIntersects [_lastPos, _nextPos]}) then {
|
||||
_resultPos = _lastPos;
|
||||
breakTo "mainSearch";
|
||||
} else {
|
||||
@ -25,6 +20,5 @@ _lastPos = +_pos;
|
||||
_lastPos = _nextPos;
|
||||
};
|
||||
};
|
||||
|
||||
} forEach _fidelity;
|
||||
[_resultPos, _distance];
|
Loading…
Reference in New Issue
Block a user