SD_BOB 10 Posted February 1, 2014 Hi guys, i'm looking for the best way to detect if an IR Grenade has been thrown in a certain area. I want to drop an IR Grenade on a position, which once complete will trigger an objective. Ideally, well definatly... :) I would very much like the solution to work in a dedicated environment as the mission is a coop. I have had a good search for a solution, the couple i found that looked as though could be adapted don't appear to work. Any help would be greatly appreciated. Share this post Link to post Share on other sites
champ-1 40 Posted February 1, 2014 http://community.bistudio.com/wiki/Arma_3:_Event_Handlers#Fired I guess you can get the projectile type and position via Event Handlers. Share this post Link to post Share on other sites
SD_BOB 10 Posted February 2, 2014 (edited) I'm aware of the possibility of using an event handler, as i said i had a good search and tried a couple of methods posted for other similar problems. These included the use of event handlers... But alas i could not get them to work, so here i am posting. This is one method i looked at, but no luck (and yes i did modify it for the IR classname). http://www.armaholic.com/forums.php?m=posts&q=21295 Also the possibility of using this as a trigger condition. ({(typeOf _x) isKindOf "Throw"}count (nearestObjects [thistrigger,[],10]) > 0); But i haven't had any luck with either of them. Edited February 2, 2014 by Shadow.D. ^BOB^ Share this post Link to post Share on other sites
champ-1 40 Posted February 2, 2014 player addEventHandler ["fired",{ _unit = _this select 0; _weapon = _this select 1; _muzzle = _this select 2; _mode = _this select 3; _ammo = _this select 4; _magazine = _this select 5; _projectile = _this select 6; _pos = getPos _projectile; player globalChat format["%1 @ %2", _projectile, _pos]; }]; This actually gives projectile name and coordinates, so it works. Also if no one gives you ready answer, you can take a look at this script and find out how to get projectile postion over time. /* General init for the tracer function */ hyp_var_tracer_tracedUnits = []; addMissionEventHandler ["Draw3D", { { private["_unit"]; _unit = _x; { private["_positions","_color","_muzzleVelocity"]; _positions = _unit getVariable [format["hyp_var_tracer_projectile_%1", _x], []]; _color = _unit getVariable ["hyp_var_tracer_color", [1,0,0,1]]; _muzzleVelocity = _positions select 0 select 1; for "_i" from 0 to (count _positions) - 2 do { //Variant of Dslyecxi's awesome color tracking modification if (_unit getVariable ["hyp_var_tracer_trackVel", false]) then { private["_velocity"]; _velocity = (_positions select _i) select 1; _color = switch true do { case (_velocity / _muzzleVelocity >= .75) : {[1,0,0,1]}; case (_velocity / _muzzleVelocity >= .50) : {[.5,.5,0,1]}; case (_velocity / _muzzleVelocity >= .25) : {[0,1,0,1]}; case (_velocity / _muzzleVelocity >= .10) : {[0,0,1,1]}; case (_velocity / _muzzleVelocity >= 0.0) : {[1,1,1,1]}; default {_color}; }; }; drawLine3D [_positions select _i select 0, _positions select (_i + 1) select 0, _color]; }; } forEach ( _unit getVariable["hyp_var_tracer_activeIndexes", []] ); } forEach hyp_var_tracer_tracedUnits; }]; //Adding of the option to manually clear lines. If you don't want the addaction, simply remove these 4 lines (player) addAction["Clear Lines", { { [_x] call hyp_fnc_traceFireClear; } forEach hyp_var_tracer_tracedUnits; }]; //Clears the lines of all drawn projectiles /* Syntax: [_unit, _color, _lifetime, _interval, _maxDistance, _maxDuration, _trackVel] call hyp_fnc_traceFire; Params: _unit: Either a vehicle or unit. (Default player) _color: Color array for the lines. (Default [1,0,0,1]) _lifetime: Duration after firing to keep the line drawn. (Default -1, for indefinite duration) _interval: Number of frames to wait between recording locations (Default 0 for record on every frame) _maxDistance: Maximum Distance from origin point to record positions (Default -1, for no max) _maxDuration: Maximum Duration from time of firing to record posiitons (Default -1, for no max) _trackVel: If true, _color is overriden by the a color indicative of velocity at that moment. Thanks to Dslyecxi for this parameter! (Default false) Return Value: Scalar: The ID of the "fired" EventHandler that was added. */ hyp_fnc_traceFire = { private["_this","_unit","_color","_lifetime","_interval","_maxDistance","_maxDuration","_eventHandle"]; _unit = [_this, 0, player, [objNull]] call BIS_fnc_param; _color = [_this, 1, [1,0,0,1], [[]], [4]] call BIS_fnc_param; _lifetime = [_this, 2, -1, [0]] call BIS_fnc_param; _interval = [_this, 3, 0, [0]] call BIS_fnc_param; _maxDistance = [_this, 4, -1, [0]] call BIS_fnc_param; _maxDuration = [_this, 5, -1, [0]] call BIS_fnc_param; _trackVel = [_this, 6, false, [false]] call BIS_fnc_param; _unit setVariable ["hyp_var_tracer_color", _color]; _unit setVariable ["hyp_var_tracer_lifetime", _lifetime]; _unit setVariable ["hyp_var_tracer_interval", _interval]; _unit setVariable ["hyp_var_tracer_trackVel", _trackVel]; _unit setVariable ["hyp_var_tracer_maxDistance", _maxDistance]; _unit setVariable ["hyp_var_tracer_maxDuration", _maxDuration]; _unit setVariable ["hyp_var_tracer_currentIndex", 0]; _unit setVariable ["hyp_var_tracer_activeIndexes", []]; _unit setVariable ["hyp_var_tracer_initialized", true]; _eventHandle = _unit addEventHandler ["fired", { [_this, (position(_this select 6)),(velocity (_this select 6)) distance [0,0,0]] spawn hyp_fnc_traceFireEvent; }]; _unit setVariable ["hyp_var_tracer_eventHandle", _eventHandle]; hyp_var_tracer_tracedUnits set [count hyp_var_tracer_tracedUnits, _unit]; }; hyp_fnc_traceFireEvent = { private["_this","_params","_initialPos","_unit","_projectile","_color","_lifetime","_interval","_maxDistance", "_maxDuration","_startTime","_skippedFrames","_positions","_projIndex","_activeIndexes","_initialVel"]; _params = _this select 0; _initialPos = _this select 1; _initialVel = _this select 2; _unit = _params select 0; _projectile = _params select 6; _color = _unit getVariable "hyp_var_tracer_color"; _lifetime = _unit getVariable "hyp_var_tracer_lifetime"; _interval = _unit getVariable "hyp_var_tracer_interval"; _maxDistance = _unit getVariable "hyp_var_tracer_maxDistance"; _maxDuration = _unit getVariable "hyp_var_tracer_maxDuration"; _startTime = diag_tickTime; _skippedFrames = _interval; //Number of frames since last full operation. Starts at interval value to record first position _positions = [[_initialPos,_initialVel]]; _projIndex = -1; _activeIndexes = []; _projIndex = _unit getVariable "hyp_var_tracer_currentIndex"; //Get the index to assign to the bullet _unit setVariable ["hyp_var_tracer_currentIndex", _projIndex + 1]; //Increment index for next bullet //Initialize final array into which all positions for the current projectile will be stored... _unit setVariable [format["hyp_var_tracer_projectile_%1", _projIndex], _positions]; //...Then update the activeIndexes to indicate that the projectile is active _activeIndexes = _unit getVariable "hyp_var_tracer_activeIndexes"; _activeIndexes set [count _activeIndexes, _projIndex]; _unit setVariable ["hyp_var_tracer_activeIndexes", _activeIndexes]; _activeIndexes = nil; //Completely nil this variable just as a safety measure, as the data it holds may be outdated now //Loop to run as long as the projectile's line is being updated waitUntil { //First, handle skipping frames on an interval if (_interval != 0 && _skippedFrames < _interval) exitWith {_skippedFrames = _skippedFrames + 1; false}; //Check and handle if frame should be skipped if (_interval != 0) then {_skippedFrames = 0;}; //Reset skipped frame counter on recording a frame //Next, check if the bullet still exists if (!alive _projectile) exitWith {true}; //Finally, handle the duration and distance checks if (_maxDuration != -1 && ((diag_tickTime - _startTime) >= _maxDuration)) exitWith {true}; //Break loop if duration for tracking has been exceeded if (_maxDistance != -1 && ((_initialPos distance _projectile) >= _maxDistance)) exitWith {true}; //Break loop if distance for tracking has been exceeded //Now, checks have all been run, so let's do the actual bullet tracking stuff _positions set [count _positions, [position _projectile, (velocity _projectile) distance [0,0,0]]]; _unit setVariable [format["hyp_var_tracer_projectile_%1", _projIndex], _positions]; }; //Now, if a lifetime is specified, wait until it has elapsed, then delete all data for that projectile if (_lifetime != -1) then { waitUntil {(diag_tickTime - _startTime) >= _lifetime}; //Remove the current projectile's index from the activeIndexes... _activeIndexes = _unit getVariable "hyp_var_tracer_activeIndexes"; _activeIndexes = _activeIndexes - [_projIndex]; _unit setVariable ["hyp_var_tracer_activeIndexes", _activeIndexes]; //... Then delete the data for the projectile itself _unit setVariable [format["hyp_var_tracer_projectile_%1", _projIndex], nil]; //Delete the projectile's data }; }; //Clears all lines created by a given unit manually hyp_fnc_traceFireClear = { private["_this","_unit"]; _unit = _this select 0; { _unit setVariable [format["hyp_var_tracer_projectile_%1", _x], nil]; } forEach (_unit getVariable ["hyp_var_tracer_activeIndexes", []]); _unit setVariable ["hyp_var_tracer_activeIndexes", []]; }; //Completely removes this script from a unit hyp_fnc_traceFireRemove = { private["_this","_unit"]; _unit = _this select 0; _unit removeEventHandler ["fired", (_unit getVariable ["hyp_var_tracer_eventHandle", 0])]; { _unit setVariable [format["hyp_var_tracer_projectile_%1", _x], nil]; } forEach (_unit getVariable ["hyp_var_tracer_activeIndexes", []]); _unit setVariable ["hyp_var_tracer_color", nil]; _unit setVariable ["hyp_var_tracer_lifetime", nil]; _unit setVariable ["hyp_var_tracer_interval", nil]; _unit setVariable ["hyp_var_tracer_maxDistance", nil]; _unit setVariable ["hyp_var_tracer_maxDuration", nil]; _unit setVariable ["hyp_var_tracer_currentIndex", nil]; _unit setVariable ["hyp_var_tracer_activeIndexes", []]; _unit setVariable ["hyp_var_tracer_eventHandle", nil]; }; Although not sure how useful its gonna be for you since IR nades don't travel very far. Share this post Link to post Share on other sites
SD_BOB 10 Posted February 2, 2014 Thankyou for the input thus far DudeGuyManBro, its appreciated. I will keep trying... Share this post Link to post Share on other sites
brians200 51 Posted February 2, 2014 (edited) This is an adaption of the code I use in my IED script for detecting grenades being thrown at them. I didn't have time to test my changes, so let me know if you get an error. ProjectileDetection.sqf _range = 35; _origin = [5000,5000,0]; //some location you care about _fired = []; while {true} do //some condition to keep detecting { _list = _origin nearObjects ["IRStrobeBase",_range]; //IRStrobeBase= superclass of ir grenades if (count _list >=1) then { _ammo = _list select 0; if (!(_ammo in _fired)) then { [_ammo, typeof _ammo, getpos _ammo, _origin ] spawn STROBE_WATCHER; _fired = _fired + [_ammo]; }; }; sleep 0.1; //remove dead projectiles _fired = _fired - [objNull]; }; StrobeWatcher.sqf _item = _this select 0; _class = _this select 1; _position = _this select 2; _origin = _this select 3; _updateInterval = .1; _radius = 49; //squared while {(alive _item)} do { _position = getpos _item; if(_origin distancesqr _position < _radius) then { //IR STROBE IS IN THE AREA YOU CARE ABOUT }; sleep _updateInterval; }; //IR STROBE turned off here. Edited February 2, 2014 by brians200 Share this post Link to post Share on other sites
SD_BOB 10 Posted February 10, 2014 Apologies for the late reply brians, i've only just had a chance to sit back down to some editing. I will test this and report back... Share this post Link to post Share on other sites
Noble Gas 10 Posted February 11, 2014 Well? Does it work? Share this post Link to post Share on other sites
brians200 51 Posted February 12, 2014 The methodology works, as that is what I do to detect explosives in my IED script. Whether I had a typo or not, is another story. Share this post Link to post Share on other sites