metalcraze 290 Posted July 3, 2012 May i ask why you think that 0.1 is rather low?My experimental data is saying that an unit that is given "aimingAccuracy" = 0.1 is usually hitting a target at 200m and from standing stance with a single M4 burst. In average it needs 3 -5 bullets. When you ideally face such a lowly skilled threat remember you have in average 0.3-0.5 seconds to react before being killed. Good luck ;) Well from my experience with TPWCAS it looks to me like suppressed AI units are barely able to hit anything. And I mean - my fireteam can be 4 people and they can have a squad of 9 and if they are suppressed I can just sit there and take my time to place aimed shots at them because they start missing hard (I also play with AI skill at 0.9 in game settings - just in case). I think increasing a lower limit will be a good idea for more testing. Share this post Link to post Share on other sites
Gunter Severloh 4037 Posted July 3, 2012 Something I like to report, might be fixed, not sure if its a bug or what, just letting you guys know, and this was using the 2.00 version I noticed enemy AI as I was blufor when being shot at, sometimes would stand there and aim at the ball above them, at least I think thats what they were doing, just happen to notice this but haven't tested or played enough, figured I'd say something. Share this post Link to post Share on other sites
tpw 2315 Posted July 3, 2012 Well from my experience with TPWCAS it looks to me like suppressed AI units are barely able to hit anything. And I mean - my fireteam can be 4 people and they can have a squad of 9 and if they are suppressed I can just sit there and take my time to place aimed shots at them because they start missing hard (I also play with AI skill at 0.9 in game settings - just in case).I think increasing a lower limit will be a good idea for more testing. I've included the lower limit as a user configurable variable for the 2.02 release, which will be up reasonably soon. ---------- Post added at 22:29 ---------- Previous post was at 22:25 ---------- Something I like to report, might be fixed, not sure if its a bug or what, just letting you guys know, and this was using the 2.00 versionI noticed enemy AI as I was blufor when being shot at, sometimes would stand there and aim at the ball above them, at least I think thats what they were doing, just happen to notice this but haven't tested or played enough, figured I'd say something. Yeah I thought I saw it occasionally too. Ideally I'd use something other than attached balls. I thought about using worldtoscreen to print each units suppression status onto the screen, but quickly put it in the too bloody hard basket. Ideally, once most of us are fully happy with the suppression, the debug won't be needed so much. Share this post Link to post Share on other sites
fabrizio_t 58 Posted July 3, 2012 (edited) I've included the lower limit as a user configurable variable for the 2.02 release. Best way around, so people may test and share some feedback. Here is the updated bdetect.sqf, should cope well with 2.02. Many additions and some rollback. bDetect v0.64 /* Basic bullet detection framework Version: 0.64 Date: 03/07/2012 Author: Fabrizio_T Additional code: TPW File Name: bdetect.sqf CHANGELOG: ------------- Version: 0.64 ------------- * Incorporated suggestions from tpw: http://forums.bistudio.com/showthread.php?136304-TPWC-AI-suppression-system&p=2182742&viewfull=1#post2182742 * Minor optimization / fixes * Introduced variable "bdetect_callback_mode": (String, Default "spawn") Allowed values: "call" or "spawn". It controls synchronous vs.asynchronous bdetect_callback() execution. ------------- Version: 0.63 ------------- * Temporarily reverted from "diag_tickTime" to "time" for issues to be looked in ------------- Version: 0.62 ------------- * Fixed bullet position handling ------------- Version: 0.61 ------------- * Fixed problem with units eventually detecting own shots ------------ Version: 0.6 ------------ * Incorporated v0.51 changes/fixes by tpw. * Function bdetect_fnc_callback() slightly changed. See bottom of this file for example. * Function bdetect_fnc_init() waits for 5 seconds to pass by after mission start, before activating the framework. * Introduced function bdetect_fnc_eh_fired_add(): suitable to force -immediate- assignment of a fired EH to any unit. Syntax: [unit] call bdetect_fnc_eh_fired_add(); * Fixed function bdetect_fnc_benchmark(): internally using code spawning, not to block code execution after function call. * Tweaked internals so that "diag_tickTime" is used instead of "time" (Thanks Ollem). * Introduced function bdetect_fnc_eh_loop(): iteratively checks ( each "bdetect_eh_assign_cycle_wait" seconds ) for newly spawned units to assign them a 'Fired' event Handler. * Renamed "bdetect_bullet_min_distance" to "bdetect_bullet_max_proximity" * Introduced variable "bdetect_init_done": (Boolean). It evaulates true when framework is loaded. Usage: "waitUntil { bdetect_init_done};" * Introduced variable "bdetect_eh_assign_cycle_wait": (seconds, Default 10). Wait duration foreach cyclic execution of bdetect_fnc_eh_loop() * Introduced variable "bdetect_bullet_min_distance": (meters, Default 25). Bullets not having travelled this distance are ignored * Introduced variable "bdetect_bullet_initial_min_speed": (meters / second, Default 360). Bullets initially slower than this are ignored (good for subsonic bullets skipping). * Introduced variable "bdetect_debug_chat": (Boolean, Default false) Show debug messages also in globalChat. * Changed Variable "bdetect_debug_min_level" to "bdetect_debug_levels". (Array). Default [0,1,2,3,4,5,6,7,8,9]. 0-9 are reserved levels. * Much more ------------ Version: 0.5 ------------ * Framework is named "bdetect" and contained into a single file: bdetect.sqf * Renamed variable "bdetect_debug" to "bdetect_debug_enable" * Introduced variables "bdetect_name" and "bdetect_version": name and version of the framework; * Introduced function bdetect_fnc_init() to handle the framework bootstrap. * Introduced variable "bdetect_callback" (string). It defines the name of a custom callback function to be called on a unit when it detects a close bullet (Default: "bdetect_fnc_callback"). * Functions and variable names polishing. All vars named bdetect_<varname>. All functions named bdetect_fnc_<funcname>. * Added some missing private vars. ------------ Version: 0.4 ------------ * Introduced variables "bdetect_enable" (boolean), "bdetect_debug_levels" (Number), "bdetect_skip_mags" (array). * Variable "bdetect_enable" act as a toggle to enable / disable framework. * Variable "bdetect_debug_levels" allows for selective display / logging of debug messages based on level. * Introduced function bdetect_fnc_benchmark() to display performance stats. * Added "bdetect_skip_mags", which is a blacklist of bullet types which should not trigger detection ------------ Version: 0.3 ------------ * Introduced variables "bdetect_bullet_delay" (seconds) , "bdetect_bullet_max_height" (meters). * Variable "bdetect_bullet_delay" (seconds) changes dinamycally between "bdetect_bullet_min_delay" (lower bound) and 1 (upper bound), depending on actual FPS vs "bdetect_fps_min". * Variable "bdetect_bullet_max_height" (meters) is the maximum height for bullets, over ground. Bullets higher than this value (Default: 10) and with up vector > 0 are skipped from detection, since they are too high and diverge from ground. * Some Code optimization. ------------ Version: 0.2 ------------ * Position of bullet as SetPosASL. * Introduced variables "bdetect_fps_min" (fps), "bdetect_bullet_max_distance" (meters), "bdetect_bullet_max_lifespan" (seconds). * Introduced function bdetect_fnc_diag_min_fps(): in case FPS go under "bdetect_fps_min" value (Default: 25) bdetect_bullet_delay is gradually raised. * Function bdetect_fnc_bullet_remove() edited and renamed to bdetect_fnc_bullet_tag_remove(), since actual removal is done elsewhere. * Bullets are removed from bdetect_fired_bullets if distance is over "bdetect_bullet_max_distance" meters or lifespan is over "bdetect_bullet_max_lifespan" seconds. ------------ Version: 0.1 ------------ * First draft */ //BEGINNING OF FRAMEWORK CODE // ----------------------------- // Constants // ----------------------------- bdetect_name = "bDetect - Bullet Detection Framework"; bdetect_short_name = "bDetect"; bdetect_version = "0.64"; bdetect_init_done= false; // ----------------------------- // Functions // ----------------------------- bdetect_fnc_init = { private [ "_msg", "_x" ]; sleep 5; // You may override these variables if(isNil "bdetect_enable") then { bdetect_enable = true; }; // (Boolean, Default true) Toggle to Enable / Disable bdetect altogether. if(isNil "bdetect_debug_enable") then { bdetect_debug_enable = false; }; // (Boolean, Default false) Toggle to Enable / Disable debug messages. if(isNil "bdetect_debug_chat") then { bdetect_debug_chat = false; }; // (Boolean, Default false) Show debug messages also in globalChat. if(isNil "bdetect_debug_levels") then { bdetect_debug_levels = [0,1,2,3,4,5,6,7,8,9]; }; // (Array, Default [0,1,2,3,4,5,6,7,8,9]) Filter debug messages by included levels. if(isNil "bdetect_callback") then { bdetect_callback = "bdetect_fnc_callback"; }; // (String, Default "bdetect_fnc_callback") Name for your own callback function if(isNil "bdetect_callback_mode") then { bdetect_callback_mode = "spawn"; }; // (String, Default "spawn") Allowed values: "call" or "spawn" if(isNil "bdetect_fps_min") then { bdetect_fps_min = 25; }; // (Number, Default 25) The minimum FPS you wish to keep if(isNil "bdetect_fps_calc_each_x_frames") then { bdetect_fps_calc_each_x_frames = 16; }; // (Number, Default 16) FPS check is done each "bdetect_fps_min" frames. 1 means each frame. if(isNil "bdetect_eh_assign_cycle_wait") then { bdetect_eh_assign_cycle_wait = 10; }; // (Seconds, Default 10). Wait duration foreach cyclic execution of bdetect_fnc_eh_loop() if(isNil "bdetect_bullet_min_delay") then { bdetect_bullet_min_delay = 0.1; }; // (Seconds, Default 0.1) Minimum time between 2 consecutive shots fired by an unit for the last bullet to be tracked. Very low values may cause lag. if(isNil "bdetect_bullet_max_delay") then { bdetect_bullet_max_delay = 2; }; // (Seconds, Default 2) if(isNil "bdetect_bullet_initial_min_speed") then { bdetect_bullet_initial_min_speed = 360; }; // (Meters/Second, Default 360) Bullets slower than this are ignored. if(isNil "bdetect_bullet_max_proximity") then { bdetect_bullet_max_proximity = 10; }; // (Meters, Default 10) Maximum proximity to unit for triggering detection if(isNil "bdetect_bullet_min_distance") then { bdetect_bullet_min_distance = 25; }; // (Meters, Default 25) Bullets having travelled less than this distance are ignored if(isNil "bdetect_bullet_max_distance") then { bdetect_bullet_max_distance = 400; }; // (Meters, Default 400) Bullets past this distance are ignored if(isNil "bdetect_bullet_max_lifespan") then { bdetect_bullet_max_lifespan = 0.5; }; // (Seconds, Default 0.5) Bullets living more than this are ignored if(isNil "bdetect_bullet_max_height") then { bdetect_bullet_max_height = 6; }; // (Meters, Default 6) Bullets higher than this -and- diverging from ground are ignored if(isNil "bdetect_skip_mags") then { // (Array) Skip these bullet types altogether bdetect_skip_mags = [ "30rnd_9x19_MP5", "30rnd_9x19_MP5SD", "15Rnd_9x19_M9", "15Rnd_9x19_M9SD", "7Rnd_45ACP_1911", "7Rnd_45ACP_1911", "8Rnd_9x18_Makarov", "8Rnd_9x18_MakarovSD", "64Rnd_9x19_Bizon", "64Rnd_9x19_SD_Bizon", "13Rnd_9mm_SLP", "17Rnd_9x19_glock17", "6Rnd_45ACP", "30Rnd_9x19_UZI", "30Rnd_9x19_UZI_SD" ]; }; // Do not edit the variables below. if(isNil "bdetect_fired_bullets") then { bdetect_fired_bullets = []; }; if(isNil "bdetect_fps") then { bdetect_fps = bdetect_fps_min; }; if(isNil "bdetect_bullet_delay") then { bdetect_bullet_delay = bdetect_bullet_min_delay; }; if(isNil "bdetect_frame_tstamp") then { bdetect_frame_tstamp = 0; }; if(isNil "bdetect_frame_min_duration") then { bdetect_frame_min_duration = (bdetect_bullet_max_proximity * 2 * .66 / 900) max .01; }; // bullet speed converted to kmh bdetect_bullet_initial_min_speed = bdetect_bullet_initial_min_speed * 3.6; // compile callback name into function bdetect_callback_compiled = call compile format["%1", bdetect_callback]; _msg = format["Starting %1 v%2.", bdetect_name, bdetect_version]; [ _msg, 0 ] call bdetect_fnc_debug; bdetect_spawned_loop_handler = [] spawn bdetect_fnc_eh_loop; [bdetect_fnc_detect,0] call cba_fnc_addPerFrameHandler; bdetect_init_done= true; hint format["%1 v%2 started.", bdetect_name, bdetect_version]; }; // Keep searching units for newly spawned ones and assign fired EH to them bdetect_fnc_eh_loop = { private [ "_x", "_msg"]; while { true } do { { [_x] call bdetect_fnc_eh_fired_add; } foreach allUnits; sleep bdetect_eh_assign_cycle_wait; }; }; // Assign fired EH to a single unit bdetect_fnc_eh_fired_add = { private ["_unit", "_msg"]; _unit = _this select 0; if( isNil { _unit getVariable "bdetect_fired_eh" } ) then { _unit setVariable ["bdetect_fired_eh", true]; _unit addEventHandler ["Fired", bdetect_fnc_fired]; if ( ( assignedVehicleRole _unit) select 0 == "Turret" && isNil { (vehicle _x) getVariable "bdetect_fired_eh" } ) then { (vehicle _x) setVariable ["bdetect_fired_eh", true]; (vehicle _x) addeventhandler ["Fired", bdetect_fnc_fired]; }; _msg = format["[%1] was assigned 'Fired' EH", _unit]; [ _msg, 3 ] call bdetect_fnc_debug; } else { _msg = format["[%1] already had an assigned 'Fired' EH", _unit]; [ _msg, 3 ] call bdetect_fnc_debug; }; }; // Fired EH bdetect_fnc_fired = { private ["_unit", "_muzzle", "_magazine", "_bullet", "_speed", "_msg", "_time", "_dt"]; if( bdetect_enable ) then { _unit = _this select 0; _muzzle = _this select 2; _magazine = _this select 5; _bullet = _this select 6; _speed = speed _bullet; _time = time; //diag_tickTime _dt = _time - ( _unit getVariable ["bdetect_fired_time", 0] ); if( _dt > bdetect_bullet_delay && !( _magazine in bdetect_skip_mags ) && _speed > bdetect_bullet_initial_min_speed ) then { _unit setVariable ["bdetect_fired_time", _time]; // Append info to bullets array [ _bullet, _unit, _time ] call bdetect_fnc_bullet_add; _msg = format["[%1] Fired bullet: speed=%2, type=%3, Delay=%4", _unit, _speed, typeOf _bullet, _dt ]; [ _msg, 2 ] call bdetect_fnc_debug; } else { _msg = format["[%1] Skipped bullet: speed=%2, type=%3, Delay=%4 [%5 - %6]", _unit, _speed, typeOf _bullet, _dt, _time , ( _unit getVariable ["bdetect_fired_time", 0] )]; [ _msg, 2 ] call bdetect_fnc_debug; }; }; }; // Time-critical detection function, to be executed per-frame bdetect_fnc_detect = { private ["_n", "_tot", "_bullet", "_data", "_side", "_pos", "_time", "_shooter", "_blacklist", "_update_blacklist", "_dist", "_units", "_x", "_data", "_func", "_t", "_k", "_bpos", "_nul"]; _t = time; //diag_tickTime if( bdetect_enable && (_t - bdetect_frame_tstamp) >= bdetect_frame_min_duration) then { _msg = format["Frame duration=%1, min duration:%2", (_t - bdetect_frame_tstamp), bdetect_frame_min_duration ]; [ _msg, 4 ] call bdetect_fnc_debug; _tot = count bdetect_fired_bullets; bdetect_frame_tstamp = _t; if ( _tot > 0 ) then { if( diag_frameno % bdetect_fps_calc_each_x_frames == 0) then { call bdetect_fnc_diag_min_fps; }; for "_n" from 0 to _tot - 1 step 2 do { _bullet = bdetect_fired_bullets select _n; _data = bdetect_fired_bullets select (_n + 1); _shooter = _data select 0; _pos = _data select 1; _time = _data select 2; _blacklist = _data select 3; _update_blacklist = false; if( !( isnull _bullet ) ) then { _bpos = getPosATL _bullet; _dist = _bpos distance _pos; //_msg = format["Following bullet %1. Time: %2. Distance: %3 Speed: %4. Position: %5", _bullet, _t - _time, _dist, (speed _bullet / 3.6), getPosASL _bullet]; //[ _msg, 2 ] call bdetect_fnc_debug; }; if( isNull _bullet || !(alive _bullet) || _t - _time > bdetect_bullet_max_lifespan || _dist > bdetect_bullet_max_distance || speed _bullet < bdetect_bullet_initial_min_speed // funny rebounds handling || ( ( _bpos select 2) > bdetect_bullet_max_height && ( ( vectordir _bullet ) select 2 ) > 0 ) ) then { [_bullet] call bdetect_fnc_bullet_tag_remove; } else { if( _dist > bdetect_bullet_min_distance ) then { _units = _bpos nearEntities [ ["MAN"] , bdetect_bullet_max_proximity]; { if( alive _x && !(_x in _blacklist) && _x != _shooter ) then { if( vehicle _x == _x && lifestate _x == "ALIVE") then { _blacklist = _blacklist + [_x]; _update_blacklist = true; if(bdetect_callback_mode == "spawn") then { _nul = [_x, _bullet, _x distance _bpos, _data] spawn bdetect_callback_compiled; } else { [_x, _bullet, _x distance _bpos, _data] call bdetect_callback_compiled; }; _msg = format["[%1] close to bullet %2 fired by %3, proximity=%4m, data=%5", _x, _bullet, _shooter, _x distance _bpos, _data]; [ _msg, 9 ] call bdetect_fnc_debug; }; } else { _msg = format["[%1] Blacklisted, bullet %2 ignored", _x, _bullet]; [ _msg, 5 ] call bdetect_fnc_debug; }; } foreach _units; if(_update_blacklist) then { // Update blacklist bdetect_fired_bullets set[ _n + 1, [_shooter, _pos, _time, _blacklist] ]; }; //_msg = format["bdetect_fired_bullets = %1", bdetect_fired_bullets]; //[ _msg, 2 ] call bdetect_fnc_debug; }; }; }; // remove dead / expired bullets bdetect_fired_bullets = bdetect_fired_bullets - [-1]; //_msg = format["%1 bullets in array", count ( bdetect_fired_bullets ) / 2]; //[ _msg, 2 ] call bdetect_fnc_debug; }; }; }; bdetect_fnc_diag_min_fps = { private ["_fps", "_msg"]; _fps = diag_fps; _msg = format["FPS=%1, Min.FPS=%2, Prev. FPS=%3, bdetect_bullet_delay=%4)", _fps, bdetect_fps_min, bdetect_fps, bdetect_bullet_delay ]; [ _msg, 1 ] call bdetect_fnc_debug; if( _fps < bdetect_fps_min * 1.15) then { if( bdetect_bullet_delay + .15 < bdetect_bullet_max_delay && _fps < bdetect_fps_min ) then { bdetect_bullet_delay = bdetect_bullet_delay + .15; _msg = format["FPS down to %1. Augmenting bdetect_bullet_delay to %2", _fps, bdetect_bullet_delay]; [ _msg, 1 ] call bdetect_fnc_debug; }; } else { if( ( bdetect_bullet_delay - .15 ) >= bdetect_bullet_min_delay ) then { bdetect_bullet_delay = bdetect_bullet_delay - .15; _msg = format["FPS up to %1. Reducing bdetect_bullet_delay to %2", _fps, bdetect_bullet_delay]; [ _msg, 1 ] call bdetect_fnc_debug; }; }; bdetect_fps = _fps; }; // Function to add a bullet to bdetect_fired_bullets bdetect_fnc_bullet_add = { private ["_bullet", "_shooter", "_pos", "_time", "_msg", "_n"]; _bullet = _this select 0; // bullet object _shooter = _this select 1; // shooter _pos = getPosATL _bullet; // bullet start position _time = _this select 2; // bullet shoot time _n = count bdetect_fired_bullets; bdetect_fired_bullets set [ _n, _bullet ]; bdetect_fired_bullets set [ _n + 1, [ _shooter, _pos, _time, [] ] ]; _msg = format["bullet %1 added", _bullet, _n / 2]; [ _msg, 2] call bdetect_fnc_debug; }; // Function to remove a bullet from bdetect_fired_bullets bdetect_fnc_bullet_tag_remove = { private ["_bullet", "_n", "_msg" ]; _bullet = _this select 0; _n = bdetect_fired_bullets find _bullet; if( _n != -1 ) then { bdetect_fired_bullets set[ _n, -1 ]; bdetect_fired_bullets set[ _n + 1, -1 ]; _msg = format["null/expired bullet removed"]; [ _msg, 2 ] call bdetect_fnc_debug; }; }; // Callback function to be executed from within bdetect_fnc_detect bdetect_fnc_callback = { private [ "_unit", "_bullet", "_proximity", "_data", "_shooter", "_pos", "_time", "_msg" ]; _unit = _this select 0; // unit being under fire _bullet = _this select 1; // bullet object _proximity = _this select 2; // distance between _bullet and _unit _data = _this select 3; // Array containing more data _shooter = _data select 0; // shooter _pos = _data select 1; // starting position of bullet _time = _data select 2; // starting time of bullet _msg = format["[%1] close to bullet %2 fired by %3, proximity=%4m, data=%5", _unit, _bullet, _shooter, _proximity, _data]; [ _msg, 9 ] call bdetect_fnc_debug; }; // function to display and log stuff (into .rpt file) level zero is intended only for builtin messages bdetect_fnc_debug = { private [ "_msg", "_level"]; /* DEBUG LEVELS: From 0-9 are reserved. 0 = unclassified messages 1 = FPS related messages 2 = "bdetect_fired_bullets" related messages 3 = EH related messages 4 = Frame related messages 5 = Unit blacklist messages ... 9 = Unit detection related messages */ _level = _this select 1; if( bdetect_debug_enable && _level in bdetect_debug_levels) then { _msg = _this select 0; diag_log format["%1 [%2 v%3] Frame:%4 L%5: %6", time, bdetect_short_name, bdetect_version, diag_frameno, _level, _msg ]; if( bdetect_debug_chat ) then { player globalchat format["%1 - %2", time, _msg ]; }; }; }; bdetect_fnc_benchmark = { private ["_cnt"]; if(isNil "bdetect_stats_max_bullets") then { bdetect_stats_max_bullets = 0;}; if(isNil "bdetect_stats_min_fps") then { bdetect_stats_min_fps = 999;}; if(isNil "bdetect_fired_bullets") then { bdetect_fired_bullets = [];}; _nul = [] spawn { sleep 5; while { true } do { _cnt = count ( bdetect_fired_bullets ) / 2; if( _cnt > bdetect_stats_max_bullets ) then { bdetect_stats_max_bullets = _cnt; }; if( diag_fps < bdetect_stats_min_fps ) then { bdetect_stats_min_fps = diag_fps }; hintsilent format["TIME: %1\nFPS: %2 (min: %3)\nBULLETS: %4 (max: %5)\nS.DELAY: %6 (Min FPS: %7)", time, diag_fps, bdetect_stats_min_fps, _cnt, bdetect_stats_max_bullets, bdetect_bullet_delay, bdetect_fps_min]; sleep .1; }; }; }; // END OF FRAMEWORK CODE // ----------------------------------------------------------- // Example for running the script // ----------------------------------------------------------- // The following commented code is not part of the framework, // just an advice on how to run it from within another file // ----------------------------------------------------------- /* // load framework call compile preprocessFileLineNumbers "bdetect.sqf"; // First declare any optional variables whose value should be other than Default (see the defined variables in bdetect.sqf, function bdetect_fnc_init() bdetect_debug_enable = true; bdetect_debug_levels = [9]; bdetect_debug_chat = true; // Then name your own unit callback function (the one that should be triggered when a bullet is close to a unit) bdetect_callback = "my_suppression_function"; // Define your own callback function, named as above my_suppression_function = { private [ "_unit", "_bullet", "_proximity", "_data", "_shooter", "_pos", "_time", "_msg" ]; _unit = _this select 0; _bullet = _this select 1; _proximity = _this select 2; _data = _this select 3; _shooter = _data select 0; // enemy shooter _pos = _data select 1; // starting position of bullet _time = _data select 2; // starting time of bullet _msg = format["my_suppression_function - [%1] close to bullet %2 fired by %3, proximity=%4m, data=%5", _unit, _bullet, _shooter, _proximity, _data]; [ _msg, 9 ] call bdetect_fnc_debug; }; // Then initialize framework call bdetect_fnc_init; // Wait stuff to be loaded waitUntil { bdetect_init_done}; // finally, activate display of stats if you wish call bdetect_fnc_benchmark; // All done, now put your other stuff here ... */ Now time for some job related issues. See you later. Edited July 3, 2012 by fabrizio_T Share this post Link to post Share on other sites
twisted 127 Posted July 3, 2012 just want to say 1st thanks very much - now fire has an effect! awesome. and i get the guys aiming up with tpw and ace and asr. only there with tpw 2.01. worth it though... Share this post Link to post Share on other sites
tpw 2315 Posted July 3, 2012 Best way around, so people may test and share some feedback.Here is the updated bdetect.sqf, should cope well with 2.02. Many additions and some rollback. bDetect v0.64 /* Basic bullet detection framework Version: 0.64 Date: 03/07/2012 Author: Fabrizio_T Additional code: TPW File Name: bdetect.sqf CHANGELOG: ------------- Version: 0.64 ------------- * Incorporated suggestions from tpw: http://forums.bistudio.com/showthread.php?136304-TPWC-AI-suppression-system&p=2182742&viewfull=1#post2182742 * Minor optimization / fixes * Introduced variable "bdetect_callback_mode": (String, Default "spawn") Allowed values: "call" or "spawn". It controls synchronous vs.asynchronous bdetect_callback() execution. ------------- Version: 0.63 ------------- * Temporarily reverted from "diag_tickTime" to "time" for issues to be looked in ------------- Version: 0.62 ------------- * Fixed bullet position handling ------------- Version: 0.61 ------------- * Fixed problem with units eventually detecting own shots ------------ Version: 0.6 ------------ * Incorporated v0.51 changes/fixes by tpw. * Function bdetect_fnc_callback() slightly changed. See bottom of this file for example. * Function bdetect_fnc_init() waits for 5 seconds to pass by after mission start, before activating the framework. * Introduced function bdetect_fnc_eh_fired_add(): suitable to force -immediate- assignment of a fired EH to any unit. Syntax: [unit] call bdetect_fnc_eh_fired_add(); * Fixed function bdetect_fnc_benchmark(): internally using code spawning, not to block code execution after function call. * Tweaked internals so that "diag_tickTime" is used instead of "time" (Thanks Ollem). * Introduced function bdetect_fnc_eh_loop(): iteratively checks ( each "bdetect_eh_assign_cycle_wait" seconds ) for newly spawned units to assign them a 'Fired' event Handler. * Renamed "bdetect_bullet_min_distance" to "bdetect_bullet_max_proximity" * Introduced variable "bdetect_init_done": (Boolean). It evaulates true when framework is loaded. Usage: "waitUntil { bdetect_init_done};" * Introduced variable "bdetect_eh_assign_cycle_wait": (seconds, Default 10). Wait duration foreach cyclic execution of bdetect_fnc_eh_loop() * Introduced variable "bdetect_bullet_min_distance": (meters, Default 25). Bullets not having travelled this distance are ignored * Introduced variable "bdetect_bullet_initial_min_speed": (meters / second, Default 360). Bullets initially slower than this are ignored (good for subsonic bullets skipping). * Introduced variable "bdetect_debug_chat": (Boolean, Default false) Show debug messages also in globalChat. * Changed Variable "bdetect_debug_min_level" to "bdetect_debug_levels". (Array). Default [0,1,2,3,4,5,6,7,8,9]. 0-9 are reserved levels. * Much more ------------ Version: 0.5 ------------ * Framework is named "bdetect" and contained into a single file: bdetect.sqf * Renamed variable "bdetect_debug" to "bdetect_debug_enable" * Introduced variables "bdetect_name" and "bdetect_version": name and version of the framework; * Introduced function bdetect_fnc_init() to handle the framework bootstrap. * Introduced variable "bdetect_callback" (string). It defines the name of a custom callback function to be called on a unit when it detects a close bullet (Default: "bdetect_fnc_callback"). * Functions and variable names polishing. All vars named bdetect_<varname>. All functions named bdetect_fnc_<funcname>. * Added some missing private vars. ------------ Version: 0.4 ------------ * Introduced variables "bdetect_enable" (boolean), "bdetect_debug_levels" (Number), "bdetect_skip_mags" (array). * Variable "bdetect_enable" act as a toggle to enable / disable framework. * Variable "bdetect_debug_levels" allows for selective display / logging of debug messages based on level. * Introduced function bdetect_fnc_benchmark() to display performance stats. * Added "bdetect_skip_mags", which is a blacklist of bullet types which should not trigger detection ------------ Version: 0.3 ------------ * Introduced variables "bdetect_bullet_delay" (seconds) , "bdetect_bullet_max_height" (meters). * Variable "bdetect_bullet_delay" (seconds) changes dinamycally between "bdetect_bullet_min_delay" (lower bound) and 1 (upper bound), depending on actual FPS vs "bdetect_fps_min". * Variable "bdetect_bullet_max_height" (meters) is the maximum height for bullets, over ground. Bullets higher than this value (Default: 10) and with up vector > 0 are skipped from detection, since they are too high and diverge from ground. * Some Code optimization. ------------ Version: 0.2 ------------ * Position of bullet as SetPosASL. * Introduced variables "bdetect_fps_min" (fps), "bdetect_bullet_max_distance" (meters), "bdetect_bullet_max_lifespan" (seconds). * Introduced function bdetect_fnc_diag_min_fps(): in case FPS go under "bdetect_fps_min" value (Default: 25) bdetect_bullet_delay is gradually raised. * Function bdetect_fnc_bullet_remove() edited and renamed to bdetect_fnc_bullet_tag_remove(), since actual removal is done elsewhere. * Bullets are removed from bdetect_fired_bullets if distance is over "bdetect_bullet_max_distance" meters or lifespan is over "bdetect_bullet_max_lifespan" seconds. ------------ Version: 0.1 ------------ * First draft */ //BEGINNING OF FRAMEWORK CODE // ----------------------------- // Constants // ----------------------------- bdetect_name = "bDetect - Bullet Detection Framework"; bdetect_short_name = "bDetect"; bdetect_version = "0.64"; bdetect_init_done= false; // ----------------------------- // Functions // ----------------------------- bdetect_fnc_init = { private [ "_msg", "_x" ]; sleep 5; // You may override these variables if(isNil "bdetect_enable") then { bdetect_enable = true; }; // (Boolean, Default true) Toggle to Enable / Disable bdetect altogether. if(isNil "bdetect_debug_enable") then { bdetect_debug_enable = false; }; // (Boolean, Default false) Toggle to Enable / Disable debug messages. if(isNil "bdetect_debug_chat") then { bdetect_debug_chat = false; }; // (Boolean, Default false) Show debug messages also in globalChat. if(isNil "bdetect_debug_levels") then { bdetect_debug_levels = [0,1,2,3,4,5,6,7,8,9]; }; // (Array, Default [0,1,2,3,4,5,6,7,8,9]) Filter debug messages by included levels. if(isNil "bdetect_callback") then { bdetect_callback = "bdetect_fnc_callback"; }; // (String, Default "bdetect_fnc_callback") Name for your own callback function if(isNil "bdetect_callback_mode") then { bdetect_callback_mode = "spawn"; }; // (String, Default "spawn") Allowed values: "call" or "spawn" if(isNil "bdetect_fps_min") then { bdetect_fps_min = 25; }; // (Number, Default 25) The minimum FPS you wish to keep if(isNil "bdetect_fps_calc_each_x_frames") then { bdetect_fps_calc_each_x_frames = 16; }; // (Number, Default 16) FPS check is done each "bdetect_fps_min" frames. 1 means each frame. if(isNil "bdetect_eh_assign_cycle_wait") then { bdetect_eh_assign_cycle_wait = 10; }; // (Seconds, Default 10). Wait duration foreach cyclic execution of bdetect_fnc_eh_loop() if(isNil "bdetect_bullet_min_delay") then { bdetect_bullet_min_delay = 0.1; }; // (Seconds, Default 0.1) Minimum time between 2 consecutive shots fired by an unit for the last bullet to be tracked. Very low values may cause lag. if(isNil "bdetect_bullet_max_delay") then { bdetect_bullet_max_delay = 2; }; // (Seconds, Default 2) if(isNil "bdetect_bullet_initial_min_speed") then { bdetect_bullet_initial_min_speed = 360; }; // (Meters/Second, Default 360) Bullets slower than this are ignored. if(isNil "bdetect_bullet_max_proximity") then { bdetect_bullet_max_proximity = 10; }; // (Meters, Default 10) Maximum proximity to unit for triggering detection if(isNil "bdetect_bullet_min_distance") then { bdetect_bullet_min_distance = 25; }; // (Meters, Default 25) Bullets having travelled less than this distance are ignored if(isNil "bdetect_bullet_max_distance") then { bdetect_bullet_max_distance = 400; }; // (Meters, Default 400) Bullets past this distance are ignored if(isNil "bdetect_bullet_max_lifespan") then { bdetect_bullet_max_lifespan = 0.5; }; // (Seconds, Default 0.5) Bullets living more than this are ignored if(isNil "bdetect_bullet_max_height") then { bdetect_bullet_max_height = 6; }; // (Meters, Default 6) Bullets higher than this -and- diverging from ground are ignored if(isNil "bdetect_skip_mags") then { // (Array) Skip these bullet types altogether bdetect_skip_mags = [ "30rnd_9x19_MP5", "30rnd_9x19_MP5SD", "15Rnd_9x19_M9", "15Rnd_9x19_M9SD", "7Rnd_45ACP_1911", "7Rnd_45ACP_1911", "8Rnd_9x18_Makarov", "8Rnd_9x18_MakarovSD", "64Rnd_9x19_Bizon", "64Rnd_9x19_SD_Bizon", "13Rnd_9mm_SLP", "17Rnd_9x19_glock17", "6Rnd_45ACP", "30Rnd_9x19_UZI", "30Rnd_9x19_UZI_SD" ]; }; // Do not edit the variables below. if(isNil "bdetect_fired_bullets") then { bdetect_fired_bullets = []; }; if(isNil "bdetect_fps") then { bdetect_fps = bdetect_fps_min; }; if(isNil "bdetect_bullet_delay") then { bdetect_bullet_delay = bdetect_bullet_min_delay; }; if(isNil "bdetect_frame_tstamp") then { bdetect_frame_tstamp = 0; }; if(isNil "bdetect_frame_min_duration") then { bdetect_frame_min_duration = (bdetect_bullet_max_proximity * 2 * .66 / 900) max .01; }; // bullet speed converted to kmh bdetect_bullet_initial_min_speed = bdetect_bullet_initial_min_speed * 3.6; // compile callback name into function bdetect_callback_compiled = call compile format["%1", bdetect_callback]; _msg = format["Starting %1 v%2.", bdetect_name, bdetect_version]; [ _msg, 0 ] call bdetect_fnc_debug; bdetect_spawned_loop_handler = [] spawn bdetect_fnc_eh_loop; [bdetect_fnc_detect,0] call cba_fnc_addPerFrameHandler; bdetect_init_done= true; hint format["%1 v%2 started.", bdetect_name, bdetect_version]; }; // Keep searching units for newly spawned ones and assign fired EH to them bdetect_fnc_eh_loop = { private [ "_x", "_msg"]; while { true } do { { [_x] call bdetect_fnc_eh_fired_add; } foreach allUnits; sleep bdetect_eh_assign_cycle_wait; }; }; // Assign fired EH to a single unit bdetect_fnc_eh_fired_add = { private ["_unit", "_msg"]; _unit = _this select 0; if( isNil { _unit getVariable "bdetect_fired_eh" } ) then { _unit setVariable ["bdetect_fired_eh", true]; _unit addEventHandler ["Fired", bdetect_fnc_fired]; if ( ( assignedVehicleRole _unit) select 0 == "Turret" && isNil { (vehicle _x) getVariable "bdetect_fired_eh" } ) then { (vehicle _x) setVariable ["bdetect_fired_eh", true]; (vehicle _x) addeventhandler ["Fired", bdetect_fnc_fired]; }; _msg = format["[%1] was assigned 'Fired' EH", _unit]; [ _msg, 3 ] call bdetect_fnc_debug; } else { _msg = format["[%1] already had an assigned 'Fired' EH", _unit]; [ _msg, 3 ] call bdetect_fnc_debug; }; }; // Fired EH bdetect_fnc_fired = { private ["_unit", "_muzzle", "_magazine", "_bullet", "_speed", "_msg", "_time", "_dt"]; if( bdetect_enable ) then { _unit = _this select 0; _muzzle = _this select 2; _magazine = _this select 5; _bullet = _this select 6; _speed = speed _bullet; _time = time; //diag_tickTime _dt = _time - ( _unit getVariable ["bdetect_fired_time", 0] ); if( _dt > bdetect_bullet_delay && !( _magazine in bdetect_skip_mags ) && _speed > bdetect_bullet_initial_min_speed ) then { _unit setVariable ["bdetect_fired_time", _time]; // Append info to bullets array [ _bullet, _unit, _time ] call bdetect_fnc_bullet_add; _msg = format["[%1] Fired bullet: speed=%2, type=%3, Delay=%4", _unit, _speed, typeOf _bullet, _dt ]; [ _msg, 2 ] call bdetect_fnc_debug; } else { _msg = format["[%1] Skipped bullet: speed=%2, type=%3, Delay=%4 [%5 - %6]", _unit, _speed, typeOf _bullet, _dt, _time , ( _unit getVariable ["bdetect_fired_time", 0] )]; [ _msg, 2 ] call bdetect_fnc_debug; }; }; }; // Time-critical detection function, to be executed per-frame bdetect_fnc_detect = { private ["_n", "_tot", "_bullet", "_data", "_side", "_pos", "_time", "_shooter", "_blacklist", "_update_blacklist", "_dist", "_units", "_x", "_data", "_func", "_t", "_k", "_bpos", "_nul"]; _t = time; //diag_tickTime if( bdetect_enable && (_t - bdetect_frame_tstamp) >= bdetect_frame_min_duration) then { _msg = format["Frame duration=%1, min duration:%2", (_t - bdetect_frame_tstamp), bdetect_frame_min_duration ]; [ _msg, 4 ] call bdetect_fnc_debug; _tot = count bdetect_fired_bullets; bdetect_frame_tstamp = _t; if ( _tot > 0 ) then { if( diag_frameno % bdetect_fps_calc_each_x_frames == 0) then { call bdetect_fnc_diag_min_fps; }; for "_n" from 0 to _tot - 1 step 2 do { _bullet = bdetect_fired_bullets select _n; _data = bdetect_fired_bullets select (_n + 1); _shooter = _data select 0; _pos = _data select 1; _time = _data select 2; _blacklist = _data select 3; _update_blacklist = false; if( !( isnull _bullet ) ) then { _bpos = getPosATL _bullet; _dist = _bpos distance _pos; //_msg = format["Following bullet %1. Time: %2. Distance: %3 Speed: %4. Position: %5", _bullet, _t - _time, _dist, (speed _bullet / 3.6), getPosASL _bullet]; //[ _msg, 2 ] call bdetect_fnc_debug; }; if( isNull _bullet || !(alive _bullet) || _t - _time > bdetect_bullet_max_lifespan || _dist > bdetect_bullet_max_distance || speed _bullet < bdetect_bullet_initial_min_speed // funny rebounds handling || ( ( _bpos select 2) > bdetect_bullet_max_height && ( ( vectordir _bullet ) select 2 ) > 0 ) ) then { [_bullet] call bdetect_fnc_bullet_tag_remove; } else { if( _dist > bdetect_bullet_min_distance ) then { _units = _bpos nearEntities [ ["MAN"] , bdetect_bullet_max_proximity]; { if( alive _x && !(_x in _blacklist) && _x != _shooter ) then { if( vehicle _x == _x && lifestate _x == "ALIVE") then { _blacklist = _blacklist + [_x]; _update_blacklist = true; if(bdetect_callback_mode == "spawn") then { _nul = [_x, _bullet, _x distance _bpos, _data] spawn bdetect_callback_compiled; } else { [_x, _bullet, _x distance _bpos, _data] call bdetect_callback_compiled; }; _msg = format["[%1] close to bullet %2 fired by %3, proximity=%4m, data=%5", _x, _bullet, _shooter, _x distance _bpos, _data]; [ _msg, 9 ] call bdetect_fnc_debug; }; } else { _msg = format["[%1] Blacklisted, bullet %2 ignored", _x, _bullet]; [ _msg, 5 ] call bdetect_fnc_debug; }; } foreach _units; if(_update_blacklist) then { // Update blacklist bdetect_fired_bullets set[ _n + 1, [_shooter, _pos, _time, _blacklist] ]; }; //_msg = format["bdetect_fired_bullets = %1", bdetect_fired_bullets]; //[ _msg, 2 ] call bdetect_fnc_debug; }; }; }; // remove dead / expired bullets bdetect_fired_bullets = bdetect_fired_bullets - [-1]; //_msg = format["%1 bullets in array", count ( bdetect_fired_bullets ) / 2]; //[ _msg, 2 ] call bdetect_fnc_debug; }; }; }; bdetect_fnc_diag_min_fps = { private ["_fps", "_msg"]; _fps = diag_fps; _msg = format["FPS=%1, Min.FPS=%2, Prev. FPS=%3, bdetect_bullet_delay=%4)", _fps, bdetect_fps_min, bdetect_fps, bdetect_bullet_delay ]; [ _msg, 1 ] call bdetect_fnc_debug; if( _fps < bdetect_fps_min * 1.15) then { if( bdetect_bullet_delay + .15 < bdetect_bullet_max_delay && _fps < bdetect_fps_min ) then { bdetect_bullet_delay = bdetect_bullet_delay + .15; _msg = format["FPS down to %1. Augmenting bdetect_bullet_delay to %2", _fps, bdetect_bullet_delay]; [ _msg, 1 ] call bdetect_fnc_debug; }; } else { if( ( bdetect_bullet_delay - .15 ) >= bdetect_bullet_min_delay ) then { bdetect_bullet_delay = bdetect_bullet_delay - .15; _msg = format["FPS up to %1. Reducing bdetect_bullet_delay to %2", _fps, bdetect_bullet_delay]; [ _msg, 1 ] call bdetect_fnc_debug; }; }; bdetect_fps = _fps; }; // Function to add a bullet to bdetect_fired_bullets bdetect_fnc_bullet_add = { private ["_bullet", "_shooter", "_pos", "_time", "_msg", "_n"]; _bullet = _this select 0; // bullet object _shooter = _this select 1; // shooter _pos = getPosATL _bullet; // bullet start position _time = _this select 2; // bullet shoot time _n = count bdetect_fired_bullets; bdetect_fired_bullets set [ _n, _bullet ]; bdetect_fired_bullets set [ _n + 1, [ _shooter, _pos, _time, [] ] ]; _msg = format["bullet %1 added", _bullet, _n / 2]; [ _msg, 2] call bdetect_fnc_debug; }; // Function to remove a bullet from bdetect_fired_bullets bdetect_fnc_bullet_tag_remove = { private ["_bullet", "_n", "_msg" ]; _bullet = _this select 0; _n = bdetect_fired_bullets find _bullet; if( _n != -1 ) then { bdetect_fired_bullets set[ _n, -1 ]; bdetect_fired_bullets set[ _n + 1, -1 ]; _msg = format["null/expired bullet removed"]; [ _msg, 2 ] call bdetect_fnc_debug; }; }; // Callback function to be executed from within bdetect_fnc_detect bdetect_fnc_callback = { private [ "_unit", "_bullet", "_proximity", "_data", "_shooter", "_pos", "_time", "_msg" ]; _unit = _this select 0; // unit being under fire _bullet = _this select 1; // bullet object _proximity = _this select 2; // distance between _bullet and _unit _data = _this select 3; // Array containing more data _shooter = _data select 0; // shooter _pos = _data select 1; // starting position of bullet _time = _data select 2; // starting time of bullet _msg = format["[%1] close to bullet %2 fired by %3, proximity=%4m, data=%5", _unit, _bullet, _shooter, _proximity, _data]; [ _msg, 9 ] call bdetect_fnc_debug; }; // function to display and log stuff (into .rpt file) level zero is intended only for builtin messages bdetect_fnc_debug = { private [ "_msg", "_level"]; /* DEBUG LEVELS: From 0-9 are reserved. 0 = unclassified messages 1 = FPS related messages 2 = "bdetect_fired_bullets" related messages 3 = EH related messages 4 = Frame related messages 5 = Unit blacklist messages ... 9 = Unit detection related messages */ _level = _this select 1; if( bdetect_debug_enable && _level in bdetect_debug_levels) then { _msg = _this select 0; diag_log format["%1 [%2 v%3] Frame:%4 L%5: %6", time, bdetect_short_name, bdetect_version, diag_frameno, _level, _msg ]; if( bdetect_debug_chat ) then { player globalchat format["%1 - %2", time, _msg ]; }; }; }; bdetect_fnc_benchmark = { private ["_cnt"]; if(isNil "bdetect_stats_max_bullets") then { bdetect_stats_max_bullets = 0;}; if(isNil "bdetect_stats_min_fps") then { bdetect_stats_min_fps = 999;}; if(isNil "bdetect_fired_bullets") then { bdetect_fired_bullets = [];}; _nul = [] spawn { sleep 5; while { true } do { _cnt = count ( bdetect_fired_bullets ) / 2; if( _cnt > bdetect_stats_max_bullets ) then { bdetect_stats_max_bullets = _cnt; }; if( diag_fps < bdetect_stats_min_fps ) then { bdetect_stats_min_fps = diag_fps }; hintsilent format["TIME: %1\nFPS: %2 (min: %3)\nBULLETS: %4 (max: %5)\nS.DELAY: %6 (Min FPS: %7)", time, diag_fps, bdetect_stats_min_fps, _cnt, bdetect_stats_max_bullets, bdetect_bullet_delay, bdetect_fps_min]; sleep .1; }; }; }; // END OF FRAMEWORK CODE // ----------------------------------------------------------- // Example for running the script // ----------------------------------------------------------- // The following commented code is not part of the framework, // just an advice on how to run it from within another file // ----------------------------------------------------------- /* // load framework call compile preprocessFileLineNumbers "bdetect.sqf"; // First declare any optional variables whose value should be other than Default (see the defined variables in bdetect.sqf, function bdetect_fnc_init() bdetect_debug_enable = true; bdetect_debug_levels = [9]; bdetect_debug_chat = true; // Then name your own unit callback function (the one that should be triggered when a bullet is close to a unit) bdetect_callback = "my_suppression_function"; // Define your own callback function, named as above my_suppression_function = { private [ "_unit", "_bullet", "_proximity", "_data", "_shooter", "_pos", "_time", "_msg" ]; _unit = _this select 0; _bullet = _this select 1; _proximity = _this select 2; _data = _this select 3; _shooter = _data select 0; // enemy shooter _pos = _data select 1; // starting position of bullet _time = _data select 2; // starting time of bullet _msg = format["my_suppression_function - [%1] close to bullet %2 fired by %3, proximity=%4m, data=%5", _unit, _bullet, _shooter, _proximity, _data]; [ _msg, 9 ] call bdetect_fnc_debug; }; // Then initialize framework call bdetect_fnc_init; // Wait stuff to be loaded waitUntil { bdetect_init_done}; // finally, activate display of stats if you wish call bdetect_fnc_benchmark; // All done, now put your other stuff here ... */ Now time for some job related issues. See you later. Awesome, incorporating it now Changed line 334 to _blacklist set [_blacklist,_x]; This will gain an extra 0.0000000000000000000001 fps Share this post Link to post Share on other sites
fabrizio_t 58 Posted July 3, 2012 (edited) Awesome, incorporating it nowChanged line 334 to _blacklist set [_blacklist,_x]; This will gain an extra 0.0000000000000000000001 fps I don't think it would work. Maybe _blacklist set [ count _blacklist, _x]; However should be very marginal (blacklisting is maybe 10% of detections, detections are about 1% of whole checking). There's plenty of room for optimization, so far i'm concerned about reliability and features. Squeezing off some more fps should be possibile once the framework is considered mature enough. By the way however v0.64 is a bit faster than v0.63, due to more aggressive FPS balancing. On my system it runs about 2-3 FPS faster in low FPS situations. Edited July 3, 2012 by fabrizio_T Share this post Link to post Share on other sites
KeyCat 131 Posted July 3, 2012 (edited) Last night I had some time to play around with this addon and I love it! Great job and as previously said this part is really missing from BIS AI routines... However after bumping up the "bdetect_bullet_max_distance" and "bdetect_bullet_max_lifespan" for sniping purposes it feels quite wierd that the AI instantly knows your position and turns around in a split second and starts to return fire. I mean one singel shot from ~1000 m distance by a sniper in a ghillie suit is not easy to detect especially if you are engaged from the back. Would be nice if the reveal part could be optional set in the user config as well, I cut and paste what I edited in the script version... ... //AI REVEAL SHOOTER tpwcas_reveal = 1; ... ... if (_shooterside getFriend ( side _unit) < 0.6 ) then { _ebc = _ebc + 1; _unit setvariable ["tpwcas_ebc", _ebc]; if (tpwcas_reveal == 1) then { _unit reveal [_shooter, 3]; }; }; ... This along with Robalos ASR-AI is must have for me, once again thanks for making and sharing! /KC Edited July 3, 2012 by KeyCat Share this post Link to post Share on other sites
SavageCDN 231 Posted July 3, 2012 i get the guys aiming up with tpw and ace and asr. only there with tpw 2.01. worth it though... +1 ASR_AI with ACE and TPWC_Suppression 2.00beta / LOS 1.0 script versions Not all units are affected. Share this post Link to post Share on other sites
tpw 2315 Posted July 3, 2012 Ok I've had a gutful of coding, here's the latest version before I hit the sack TPWCAS 2.02b: http://filesonly.com/download.php?file=166TPWC_AI_SUPPRESS_202.zip Uses bDetect 0.64 User configurable minimum skill values User configurable reveal value ( 0 = unit knows nothing about shooter, 4 = everything about shooter is revealed to unit). Knock yourselves out, and tell me about how flawed it is in 8 hours time :) Share this post Link to post Share on other sites
tadanobu 1 Posted July 3, 2012 Hello there I'm new here and I've been following this thread from the beginning. Since I have no scripting skills whatsoever I haven't had any reason to post. But I've noticed something that may be a bug. I've been using a side-counting trigger for awhile to keep track of the unit numbers in missions. Activation: Anybody Repeatedly Condition: time % 2 > 1; On Act: hint format ["West: %1\nEast: %2\nCiv: %3", west countSide thislist, east countSide thislist, civilian countSide thislist]; Now what I find is that if I set tpwcas_debug=1, then once bdetect is called the civilian count immediately jumps to a figure just over 3 times the total of east/west unit numbers on the map, even though I have not placed any civilian units on the map to begin with. Then once shooting starts the civ count increases continuously even after one side is annihilated. When it reaches somewhere around 3000+ the game starts to freeze very briefly every couple of seconds. If I set debug to 0 this does not occur, but then of course I'm unable to observe the coloured discs. I've run the game with various combinations of mods including asr and have removed all in turn to see if I could pinpoint any incompatibility, but it really does seem that it stems from tpwc and bdetect. Of course I might be misinterpreting something else, but using just the pbo (instead of the script and turning off debug) I cannot run the mod for more than 10 minutes, whereas before tpwc and bdetect were combined I was able to have battles that lasted 30+ minutes with no problems. Of course tpwc with bdetect may not be designed to run in debugging mode for extended times, so that might be the problem. Hope this is of help. Share this post Link to post Share on other sites
tpw 2315 Posted July 3, 2012 (edited) I don't think it would work.Maybe _blacklist set [ count _blacklist, _x]; However should be very marginal (blacklisting is maybe 10% of detections, detections are about 1% of whole checking). There's plenty of room for optimization, so far i'm concerned about reliability and features. Squeezing off some more fps should be possibile once the framework is considered mature enough. By the way however v0.64 is a bit faster than v0.63, due to more aggressive FPS balancing. On my system it runs about 2-3 FPS faster in low FPS situations. _blacklist set [ count _blacklist, _x]; = what I actually meant to write. Brain is fading badly, time for bed! ---------- Post added at 23:57 ---------- Previous post was at 23:52 ---------- Hello thereI'm new here and I've been following this thread from the beginning. Since I have no scripting skills whatsoever I haven't had any reason to post. But I've noticed something that may be a bug. I've been using a side-counting trigger for awhile to keep track of the unit numbers in missions. Activation: Anybody Repeatedly Condition: time % 2 > 1; On Act: hint format ["West: %1\nEast: %2\nCiv: %3", west countSide thislist, east countSide thislist, civilian countSide thislist]; Now what I find is that if I set tpwcas_debug=1, then once bdetect is called the civilian count immediately jumps to a figure just over 3 times the total of east/west unit numbers on the map, even though I have not placed any civilian units on the map to begin with. Then once shooting starts the civ count increases continuously even after one side is annihilated. When it reaches somewhere around 3000+ the game starts to freeze very briefly every couple of seconds. If I set debug to 0 this does not occur, but then of course I'm unable to observe the coloured discs. I've run the game with various combinations of mods including asr and have removed all in turn to see if I could pinpoint any incompatibility, but it really does seem that it stems from tpwc and bdetect. Of course I might be misinterpreting something else, but using just the pbo (instead of the script and turning off debug) I cannot run the mod for more than 10 minutes, whereas before tpwc and bdetect were combined I was able to have battles that lasted 30+ minutes with no problems. Of course tpwc with bdetect may not be designed to run in debugging mode for extended times, so that might be the problem. Hope this is of help. Very interesting. I wonder if the balls are counted as civilians? Because there are actually 3 balls for every unit on the map. This bastard debugging code is more trouble than it's worth!!! I will look into it tomorrow, and thanks tadanobu OH, AND WELCOME TO THE FORUM! Edited July 3, 2012 by tpw Share this post Link to post Share on other sites
SavageCDN 231 Posted July 3, 2012 Ok I've had a gutful of coding, here's the latest version before I hit the sackTPWCAS 2.02b: http://filesonly.com/download.php?file=166TPWC_AI_SUPPRESS_202.zip Uses bDetect 0.64 User configurable minimum skill values User configurable reveal value ( 0 = unit knows nothing about shooter, 4 = everything about shooter is revealed to unit). Knock yourselves out, and tell me about how flawed it is in 8 hours time :) Thanks again for your hard work :p Share this post Link to post Share on other sites
kiberkiller 10 Posted July 3, 2012 Ok I've had a gutful of coding, here's the latest version before I hit the sackTPWCAS 2.02b: http://filesonly.com/download.php?file=166TPWC_AI_SUPPRESS_202.zip Uses bDetect 0.64 User configurable minimum skill values User configurable reveal value ( 0 = unit knows nothing about shooter, 4 = everything about shooter is revealed to unit). Knock yourselves out, and tell me about how flawed it is in 8 hours time :) I still love you but I've got 2 questions: 1) Can you stop using that file service? Because it forces me to wait 30 seconds and it has a capcha (Mediafire is much better alternative). 2) How exactly does tpwcas_reveal work? If tpwcas_reveal = 4 then a supressed AI will instantly know where you are? What's the purpose of this, besides extra challenge? Can you explain all the levels between 0 and 4 in more detail? I guess that was a bit more than 2 questions. Share this post Link to post Share on other sites
fabrizio_t 58 Posted July 3, 2012 (edited) 2) How exactly does tpwcas_reveal work? If tpwcas_reveal = 4 then a supressed AI will instantly know where you are? reveal=4 means unit gains exact knowledge of type and position of the revealed one. reveal=1.5 means reveal basically just its side. The rest is inbetween. The purpose is helping AI units in identifying targets. Vanilla AI is not that clever regarding that. Since a unidentified target won't be attacked, this can be a major problem, especially if it's close and in line of sight. I think these settings are being refined / finetuned by Coulum, so expect them to eventually change. Please see here for some comments: http://community.bistudio.com/wiki/knowsAbout Edited July 3, 2012 by fabrizio_T Share this post Link to post Share on other sites
kiberkiller 10 Posted July 3, 2012 Ahaaaa! So that solves the issue of AI with downs syndrome, when they will aim directly onto an enemy but will never fire. That's great. Share this post Link to post Share on other sites
mr_centipede 31 Posted July 3, 2012 I got performance drop with the latest version after a few minutes of a firefight... a few seconds pause kind of stutter... tried to defrag, still no go. Also removed the debugging option in userconfig, still no go Share this post Link to post Share on other sites
ollem 4 Posted July 3, 2012 Ok I've had a gutful of coding, here's the latest version before I hit the sackTPWCAS 2.02b: The pace at which you and F release new version makes it very hard for me too keep up with testing :-) Minor bug at line 290: tpwcas_filter = should be tpwcas_fnc_filter = Share this post Link to post Share on other sites
tadanobu 1 Posted July 3, 2012 (edited) Playing around with the script some more I found in bdetect there is an area of commented code at the bottom: // END OF FRAMEWORK CODE // ----------------------------------------------------------- // Example for running the script // ----------------------------------------------------------- // The following commented code is not part of the framework, // just an advice on how to run it from within another file // ----------------------------------------------------------- /* // load framework call compile preprocessFileLineNumbers "bdetect.sqf"; // First declare any optional variables whose value should be other than Default (see the defined variables in bdetect.sqf, function bdetect_fnc_init() bdetect_debug_enable = true; bdetect_debug_levels = [9]; bdetect_debug_chat = true; etc I've now commented each line of this area in the script version and part of the problem that I mentioned in earlier post has been solved. Although I still get the initial civ count as 3 x total of east/west units on map, the civ counter no longer increments as it did. Again hope this helps. Edited July 3, 2012 by tadanobu Mistake Share this post Link to post Share on other sites
fabrizio_t 58 Posted July 3, 2012 Playing around with the script some more I found in bdetect there is an area of commented code at the bottom:// END OF FRAMEWORK CODE // ----------------------------------------------------------- // Example for running the script // ----------------------------------------------------------- // The following commented code is not part of the framework, // just an advice on how to run it from within another file // ----------------------------------------------------------- /* // load framework call compile preprocessFileLineNumbers "bdetect.sqf"; // First declare any optional variables whose value should be other than Default (see the defined variables in bdetect.sqf, function bdetect_fnc_init() bdetect_debug_enable = true; bdetect_debug_levels = [9]; bdetect_debug_chat = true; etc I've now commented each line of this area in the script version and part of the problem that I mentioned in earlier post has been solved. Although I still get the initial civ count as 3 x total of east/west units on map, the civ counter no longer increments as it did. Again hope this helps. Those lines should remain commented (they already are), they are just an example for implementation. bDetect is already started at the bottom of tpwc_ai_suppress202.sqf as you can see: //CALL BDETECT call compile preprocessFileLineNumbers "bdetect064.sqf"; bdetect_skip_mags = tpwcas_mags; bdetect_debug_enable = false; bdetect_callback = "tpwcas_fnc_localbullets"; call bdetect_fnc_init; waitUntil { bdetect_init_done}; To solve the problem i think you'll have to wait for tpw intervention. Share this post Link to post Share on other sites
tadanobu 1 Posted July 3, 2012 Lol shows what I know about scripting. Dont think what I did made any difference. My apologies for presuming that the mistake lay there. Played some more and noticed that the problem arises after a unit dies. The civ count drops by 3 with the first fatality, then starts to increase incrementally from that point on. Damn hope I haven't posted prematurely this time and that this info is at least helpful. Share this post Link to post Share on other sites
fabrizio_t 58 Posted July 3, 2012 I confirm the issue portraied by tadanobu and (maybe) Mr_Centipede exists. Too many balls around. I think tpw will solve easily. Also i noticed that red suppression balls still appear upon corpses. Share this post Link to post Share on other sites
UGLY58 10 Posted July 3, 2012 (edited) I have been following the development of this with great interest, but being away from home have been unable to test for myself. A couple of ideas that I wanted to pass on when considering Real Life effects 1. Incoming bullet cracks only get really scary when you realize they are close, you don`t realize they are close until you see them hit the ground near you, you or friends. I think the 25 m radius is probably about right. One thing you may want to add is casualties to massively up the affect of suppression. So I guess what I am saying is light suppression slows you but you still end up crawling about, returning fire etc. Effective suppression is when you start taking casualties, the effects of this are completely different to taking a few rounds overhead and hitting your belt buckles. People cease returning fire, focus on the casualties and need to be well led to recover from the immediate effects. More experienced troops are affected less by this than green ones. - So possibly add an extra suppression affect for nearby casualties. 2. If you are in vehicles you generally are only aware of rounds when they hit the vehicle, Sound proofing in military vehicles is not good and there is so much background noise that you generally are unaware of rounds passing near, they have to be real close or hit. The bigger and the louder the vehicle the less the effect of suppression. Just try suppressing an MBT crew with an MG...you will just make them angry. Equally guys sitting in an APC will not be suppressed so easily as those in a light vehicle. Vehicle casualties are again key here. - Less suppression on armored vehicles, but casualties key. 3. Aircraft do not even know they are being suppressed until you hit them, again aircraft noise over powers the effects of bullet cracks. Seeing tracer coming up at you is difficult, even at night. You do get suppressed when you hear them hit, normally meaning that you move, shift attack heading etc. Seeing your wing man explode, well that's a different matter. - suppression of aircraft through casualties in the group. Fear in combat comes from the senses: Sight, Sound, Smell, Touch - If you remove any one or more of these, the sense of what you are perceiving is markedly reduced. If all four are present the effects can be debilitating. Some individuals are less affected than others both during and after the combat. These effects in combat be over come with training and experience. Key is the management of the effects after the event. Edited July 3, 2012 by UGLY58 Share this post Link to post Share on other sites
oldbear 390 Posted July 3, 2012 New on front page at Armed Assault.info Link to mirror : TPWC AI Suppress (TPWCAS) (v2.00) : http://www.armedassault.info/index.php?game=1&cat=addons&id=1960 Share this post Link to post Share on other sites
SaOk 112 Posted July 3, 2012 I included the script version to my SP mission Zub. You can find the mission here if interested. You only need to have CBA addon installed and the scripts are automatically enabled: http://forums.bistudio.com/showthread.php?132726-SP-MP-Dynamic-Whole-Map-Missions-by-SaOk Share this post Link to post Share on other sites