ollem 4 Posted June 28, 2012 fabrizio_T, Thanks for your feedback. Unfortunately no time to look at it. Here a short comparison video: No TPWC - Dedicated Server TPWC - SP TPWC You will clearly see the diff... Share this post Link to post Share on other sites
Robalo 465 Posted June 28, 2012 Quick obs: if (unitpos _unit != "DOWN") then { _unit setunitpos "middle"}; This won't work. You can have units that went prone by themselves while unitpos will give you "Auto" for them. From Biki (and I can confirm since I've played with this command a lot): Return the unit position rules.The return value is always "Auto" unless the unit has gotten a setUnitPos command. In that case the value is the last stance the unit was ordered to. So the proper way to do it is to check unit's animation, for which I gave you a solution earlier in this thread. Share this post Link to post Share on other sites
kremator 1065 Posted June 28, 2012 Here a short comparison video: No TPWC - Dedicated Server TPWC - SP TPWC You will clearly see the diff... I get exactly the same as you Ollem on my dedi vs local. Share this post Link to post Share on other sites
fabrizio_t 58 Posted June 28, 2012 Quick obs: if (unitpos _unit != "DOWN") then { _unit setunitpos "middle"}; This won't work. You can have units that went prone by themselves while unitpos will give you "Auto" for them. From Biki (and I can confirm since I've played with this command a lot): So the proper way to do it is to check unit's animation, for which I gave you a solution earlier in this thread. Or you may prefer some creative usage of recently introduced eyepos or aimpos ;) FLEXAI_get_stance = { private ["_unit", "_h", "_ret"]; _unit = _this select 0; _ret = "UP"; _h = ((aimpos _unit) select 2) - ((getPosASL _unit) select 2); if( _h < 1.15) then { _ret = "MIDDLE";}; if( _h < .5) then { _ret = "DOWN";}; _ret }; It checks the true stance by measuring current aiming position height. Function is a draft and may be refined, but it's simple and you get the idea, right? usage: [_unit] call FLEXAI_get_stance; return values: "UP", "DOWN" or "MIDDLE"; Share this post Link to post Share on other sites
tpw 2315 Posted June 28, 2012 Ollem and Fabrizio_T, you guys are bloody great! I think I should retire and let the experts take over. Or rename it TPWCCF. I'll incorporate the changes ASAP. Robalo, thanks for the heads up. Seriously, I just love this level of input and collaboration. This community is awesome. Share this post Link to post Share on other sites
fabrizio_t 58 Posted June 28, 2012 (edited) Ollem and Fabrizio_T, you guys are bloody great! I think I should retire and let the experts take over. Or rename it TPWCCF. I'll incorporate the changes ASAP. Many people are glad to support you, as you notice. That's because you all (You, Coulum, Ollem, ...) are doing a great work. Simple as that. Keep it going. Edited June 28, 2012 by fabrizio_T Share this post Link to post Share on other sites
tpw 2315 Posted June 28, 2012 Many people are glad to support you, as you notice. That's because you all (You, Coulum, Ollem, ...) are doing a great work. Simple as that. Keep it going. I actually have thought of using eyepos previously, the only problem being that it won't work without beta 93666 or greater. Something like: if ((((eyepos _unit) select 2) - ((getPosASL _unit) select 2)) > 0.5) then { _unit setvehicleinit format ["this setunitpos 'middle';"]; processinitcommands; clearVehicleInit _unit; }; This would ensure that a unit would only crouch if he wasn't low to the ground (prone). Checking animation as per Robalo is independent of beta, but more work for a lazy bastard like me.. Share this post Link to post Share on other sites
Robalo 465 Posted June 28, 2012 (edited) Checking animation as per Robalo is independent of beta, but more work for a lazy bastard like me.. Nah, it's too easy. Probably less efficient than fabrizio's smart little function, but should cover at least until 1.61 comes. Edited June 28, 2012 by Robalo Share this post Link to post Share on other sites
tpw 2315 Posted June 28, 2012 (edited) Nah, it's too easy.Probably less efficient than fabrizio's smart little function, but should cover at least until 1.61 comes. Brilliant! I'm always reluctant to make something rely on a beta. ---------- Post added at 09:25 ---------- Previous post was at 08:50 ---------- Mega update! We are inching closer towards a legitimate release thanks to Ollem, Fabrizio_T and Robalo. Thanks again guys. Units only crouch if they're not prone (Robalo) Overhauled debug code, more efficient and should work better for dedi servers (Ollem) Use of switch instead of if for more efficient unit behaviour changes under suppression (Ollem) Modified bullet detection to check for foot units earlier on (Fabrizio_T) Overhauled visual fx (blur and gamma), gamma should be more noticeable Other cleanups 1.03 Code: /* TPWC AI SUPPRESSION Authors: TPW & -Coulum- Additional code: Fabrizio_T, Ollem Version: 1.03 Last modified: 20120629 Requires: CBA Disclaimer: Feel free to use and modify this code, on the proviso that you post back changes and improvements so that everyone can benefit from them, and acknowledge the original authors in any derivative works. */ if (isServer || isDedicated) then { //Log it diag_log format ["AI SUPPRESS STARTED: Server: %1 - Dedicated: %2", isServer, isDedicated]; //////////// //VARIABLES /////////// //Suppression mode. 1 = basic , 2 = light, 3 = full stance / skills modification tpwc_ai_sup_mode = 3; //Delay before suppression functions start. Allows time for other AI mods to set unit skills tpwc_ai_sup_sleep = 5; //Debugging. Will display red balls over any suppressed units. Set to 1 for debugging tpwc_ai_sup_debug = 1; //Bullet detection radius (m). Bullets must pass within this distance of unit to suppress them. If set much below 10m, bullets may not be detected tpwc_ai_sup_br = 10; //Bullet ignore radius (m). Bullets from a shooter closer than this will not suppress. tpwc_ai_sup_ir = 25; //Shot threshold. More shots than this will cause unit to drop/crawl tpwc_ai_sup_st = 5; //Pistol and SMG ammo to ignore. Add custom ammo (eg suppressed) or change to taste tpwc_ai_sup_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" ]; //Startup hint. 0 = no hint, 1 = hint tpwc_ai_sup_hint = 1; //Player suppression (shake and visuals). 0 = no suppression, 1 = suppression tpwc_ai_sup_playersup = 1; ////////// // SET UP ////////// //DECLARE PRIVATE VARIABLES private ["_stanceregain","_skillregain","_unit","_bc","_shots","_originalaccuracy","_originalshake","_originalcourage","_general","_ball1","_ball2","_ball3","_skillset","_asr","_tint","_blur","_x","_ppmod","_ppmodifier"]; //WAIT sleep tpwc_ai_sup_sleep; //START HINT if (tpwc_ai_sup_hint == 1) then { 0 = [] spawn { hintsilent "TPWC AI Suppress 1.03 Active"; sleep 3; hintsilent ""}; }; ////////////////// // MAIN FUNCTIONS ////////////////// //BASIC VERSION tpwc_ai_sup_basic = { { if (alive _x) then { _unit = _x; _stanceregain = _unit getvariable ["tpwc_stanceregain", -1]; if (_stanceregain == -1) then { _unit setvariable ["tpwc_stanceregain", diag_ticktime]; _unit addeventhandler ["fired",{tpwc_ai_sup_fired = _this select 0;tpwc_ai_sup_bullet = _this select 6}]; _ball = "Sign_sphere25cm_EP1" createvehicle getposatl _unit;_ball attachTo [_unit,[0,0,2]]; _unit setvariable ["tpwc_supball",_ball]; }; if ( diag_ticktime >= _stanceregain) then { _ball = _unit getvariable "tpwc_supball"; _ball hideobject true; _unit setvariable ["tpwc_supshots", 0]; _unit setunitpos "auto"; _unit setvariable ["tpwc_suppressedstance", 0]; _unit setvariable ["tpwc_stanceregain", diag_ticktime + 10]; }; if !(isnull tpwc_ai_sup_bullet) then { _bc = count ((getposatl _unit) nearobjects ["bulletbase",tpwc_ai_sup_br]); if (_bc > 0) then { if ((tpwc_ai_sup_fired distance _unit) > tpwc_ai_sup_ir) then { _unit setvariable ["tpwc_stanceregain", diag_ticktime + 10]; _shots = _unit getvariable "tpwc_supshots"; _unit setvariable ["tpwc_supshots", _shots + _bc]; _shots = _unit getvariable "tpwc_supshots"; _unit setunitpos "middle"; _unit setvariable ["tpwc_suppressedstance", 1]; if (tpwc_ai_sup_debug == 1) then { _ball = _unit getvariable "tpwc_supball";_ball hideobject false; }; if (_shots > tpwc_ai_sup_st) then { _unit setunitpos "down"; }; }; }; }; }; } foreach allunits; }; //LITE VERSION tpwc_ai_sup_lite = { { if (alive _x) then { _unit = _x; _stanceregain = _unit getvariable ["tpwc_stanceregain", -1]; if (_stanceregain == -1) then { _unit setvariable ["tpwc_stanceregain", diag_ticktime]; _unit addeventhandler ["fired",{tpwc_ai_sup_fired = _this select 0;tpwc_ai_sup_mag = _this select 5; tpwc_ai_sup_bullet = _this select 6}]; _ball = "Sign_sphere25cm_EP1" createvehicle getposatl _unit;_ball attachTo [_unit,[0,0,2]]; _unit setvariable ["tpwc_supball",_ball]; }; if ( diag_ticktime >= _stanceregain) then { _ball = _unit getvariable "tpwc_supball"; _ball hideobject true; _unit setvariable ["tpwc_supshots", 0]; _unit setunitpos "auto"; _unit setvariable ["tpwc_suppressedstance", 0]; _unit setvariable ["tpwc_stanceregain", diag_ticktime + 10]; }; if (!(isnull tpwc_ai_sup_bullet) && (vehicle _unit == _unit)) then { _bc = count ((getposatl _unit) nearobjects ["bulletbase",tpwc_ai_sup_br]); if (_bc > 0) then { if ((tpwc_ai_sup_fired distance _unit) > tpwc_ai_sup_ir) then { if !(tpwc_ai_sup_mag in tpwc_ai_sup_mags) then { _unit setvariable ["tpwc_stanceregain", diag_ticktime + 10]; _shots = _unit getvariable "tpwc_supshots"; _unit setvariable ["tpwc_supshots", _shots + _bc]; _unit setunitpos "middle"; _unit setvariable ["tpwc_suppressedstance", 1]; if (side tpwc_ai_sup_fired != side _unit) then { _shots = _unit getvariable "tpwc_supshots"; if (tpwc_ai_sup_debug == 1) then { _ball = _unit getvariable "tpwc_supball";_ball hideobject false; }; if (_shots > tpwc_ai_sup_st) then { _unit setunitpos "down"; }; }; }; }; }; }; }; } foreach allunits; }; //BULLET DETECTION LOOP (TIME CRITICAL) //Do not touch this please tpwc_ai_sup_detect = { { _unit = _x; if (!(isnull tpwc_ai_sup_bullet) && (vehicle _unit == _unit)) then { _bc = count ((getposatl _unit) nearobjects ["bulletbase",tpwc_ai_sup_br]); if (_bc > 0) then { if ((tpwc_ai_sup_fired distance _unit) > tpwc_ai_sup_ir) then { if !(tpwc_ai_sup_mag in tpwc_ai_sup_mags) then { _unit setvariable ["tpwc_skillregain", diag_ticktime + (random 4)-((_unit getvariable "tpwc_general")+(_unit getvariable "tpwc_originalcourage"))]; _unit setvariable ["tpwc_stanceregain", diag_ticktime + 10]; _unit setvariable ["tpwc_supshots",(_unit getvariable "tpwc_supshots") + _bc]; _unit setvariable ["tpwc_suppressedstance", 1]; if (side tpwc_ai_sup_fired != side _unit) then { _unit setvariable ["tpwc_suppressedstance", 2]; if (_unit getvariable "tpwc_supshots" > tpwc_ai_sup_st) then { _unit setvariable ["tpwc_suppressedstance", 3]; }; }; }; }; }; }; } foreach allunits; }; //UNIT STANCE/SKILL MODIFICATION LOOP (NON TIME CRITICAL) tpwc_ai_sup_behaviour = { tpwc_ai_sup_supvisflag = 0; while {true} do { { if (alive _x) then { _unit = _x; _skillregain = _unit getvariable ["tpwc_skillregain", -1]; _stanceregain = _unit getvariable ["tpwc_stanceregain", -1]; //SET INITIAL PARAMETERS FOR EACH UNIT if (_stanceregain == -1) then { _unit setvariable ["asr_ai_sys_aiskill_configured", false]; _unit setvariable ["tpwc_skillset", false]; _unit setvariable ["tpwc_combatmode", "unchanged"]; _unit setvariable ["tpwc_originalaccuracy", _unit skill "aimingaccuracy"]; _unit setvariable ["tpwc_originalshake", _unit skill "aimingshake"]; _unit setvariable ["tpwc_originalcourage", _unit skill "courage"]; _unit setvariable ["tpwc_general", _unit skill "general"]; _unit setvariable ["tpwc_stanceregain", diag_ticktime]; _unit setvariable ["tpwc_skillregain", diag_ticktime]; _unit addeventhandler ["fired",{tpwc_ai_sup_fired = _this select 0;tpwc_ai_sup_mag = _this select 5; tpwc_ai_sup_bullet = _this select 6}]; if ( ( assignedVehicleRole _unit) select 0 == "Turret" ) then { (vehicle _unit) addeventhandler ["fired",{tpwc_ai_sup_fired = _this select 0;tpwc_ai_sup_mag = _this select 5; tpwc_ai_sup_bullet = _this select 6}]; }; if (tpwc_ai_sup_debug == 1) then { _ball1 = "Sign_sphere25cm_EP1" createvehicle getposatl _unit; _ball1 setObjectTexture [0,"#(argb,8,8,3)color(0.2,0.9,0.2,0.5,ca)"]; _ball1 attachTo [_unit,[0,0,2]]; _unit setvariable ["tpwc_sup1ball",_ball1]; _ball1 hideobject true; _ball2 = "Sign_sphere25cm_EP1" createvehicle getposatl _unit; _ball2 setObjectTexture [0,"#(argb,8,8,3)color(0.6,0.9,0.0,0.7,ca)"]; //yellow _ball2 attachTo [_unit,[0,0,2]]; _unit setvariable ["tpwc_sup2ball",_ball2]; _ball2 hideobject true; _ball3 = "Sign_sphere25cm_EP1" createvehicle getposatl _unit; _ball3 setObjectTexture [0,"#(argb,8,8,3)color(0.8,0.5,0.5,0.5,ca)"]; //red _ball3 attachTo [_unit,[0,0,2]]; _unit setvariable ["tpwc_sup3ball",_ball3]; _ball3 hideobject true; }; }; //IF UNIT SKILLS ARE UNSUPPRESSED if (diag_ticktime >= _skillregain) then { _originalaccuracy = _unit getvariable "tpwc_originalaccuracy"; _originalshake = _unit getvariable "tpwc_originalshake"; _originalcourage = _unit getvariable "tpwc_originalcourage"; _general = _unit getvariable "tpwc_general"; if((_unit skill "aimingaccuracy") < _originalaccuracy) then { _unit setskill ["aimingaccuracy",(_unit skill "aimingaccuracy")+((_originalaccuracy-(_unit skill "aimingaccuracy"))*.325)]; }; if((_unit skill "aimingshake") < _originalshake) then { _unit setskill ["aimingshake",(_unit skill "aimingshake")+((_originalshake-(_unit skill "aimingshake"))*.325)]; }; }; //IF UNIT STANCE IS UNSUPPRESSED if ( diag_ticktime >= _stanceregain) then { _unit setvariable ["tpwc_supshots", 0]; _unit setunitpos "auto"; _originalcourage = _unit getvariable "tpwc_originalcourage"; _general = _unit getvariable "tpwc_general"; _unit setvariable ["tpwc_suppressedstance", 0]; //if ( _statusColor != 0 ) then { _statusColor = 1; };// status has been reset so set > 0 if((_unit skill "courage") < (_originalcourage - 0.1)) then { _unit setskill ["courage",(_unit skill "courage")+(_general)*(0.1)]; } else { if (_unit getvariable "tpwc_combatmode" != "unchanged") then { _unit setbehaviour str(_unit getvariable "tpwc_combatmode"); _unit setvariable ["tpwc_combatmode", "unchanged"]; }; }; }; //UNIT CHANGES FOR DIFFERENT SUPPRESSION switch ( _unit getvariable "tpwc_suppressedstance" ) do { case 1: //IF ANY BULLETS NEAR UNIT { if ((_unit call CBA_fnc_getunitanim) select 0 != "prone") then { _unit setvehicleinit format ["this setunitpos 'middle';"]; processinitcommands; clearVehicleInit _unit; }; }; case 2: //IF ENEMY BULLETS NEAR UNIT { if ((_unit call CBA_fnc_getunitanim) select 0 != "prone") then { _unit setvehicleinit format ["this setunitpos 'middle';"]; processinitcommands; clearVehicleInit _unit; }; _unit setvariable ["tpwc_combatmode", behaviour _unit]; if( !( behaviour _unit in ["COMBAT", "STEALTH"] ) ) then { _unit setbehaviour "COMBAT"; }; _originalaccuracy = _unit getvariable "tpwc_originalaccuracy"; _originalshake = _unit getvariable "tpwc_originalshake"; _originalcourage = _unit getvariable "tpwc_originalcourage"; _general = _unit getvariable "tpwc_general"; _shots = _unit getvariable "tpwc_supshots"; if (diag_ticktime < _skillregain) then { _unit setskill ["aimingaccuracy",_originalaccuracy*_originalcourage*_general-(_shots*(1-_general)*((_unit skill "aimingaccuracy")-.1)*.025)]; _unit setskill ["aimingshake",_originalshake*_originalcourage*_general-(_shots*(1-_general)*((_unit skill "aimingshake")-.1)*.025)]; _unit setskill ["courage",(_unit skill "courage")-(_shots*(1-_general)*(1-_originalcourage)*((_unit skill "courage")-.1)*.1)]; }; if ((_unit == player) and (tpwc_ai_sup_playersup == 1) and (diag_ticktime < _skillregain)) then { addCamShake [1.5 - (skill player),(random 4)-((_unit getvariable "tpwc_general")+(_unit getvariable "tpwc_originalcourage")) , 2.5] }; }; case 3: //IF UNIT IS SUPPRESSED WITH MORE THAN 5 ENEMY BULLETS { _unit setvehicleinit format ["this setunitpos 'down';"]; processinitcommands; clearVehicleInit _unit; _unit forcespeed -1; if( !( behaviour _unit in ["COMBAT", "STEALTH"] ) ) then { _unit setbehaviour "COMBAT"; }; _unit setvariable ["tpwc_combatmode", behaviour _unit]; //TODO: verify right order _originalaccuracy = _unit getvariable "tpwc_originalaccuracy"; _originalshake = _unit getvariable "tpwc_originalshake"; _originalcourage = _unit getvariable "tpwc_originalcourage"; _general = _unit getvariable "tpwc_general"; _shots = _unit getvariable "tpwc_supshots"; if (diag_ticktime < _skillregain) then { _unit setskill ["aimingaccuracy",_originalaccuracy*_originalcourage*_general-(_shots*(1-_general)*.003)]; _unit setskill ["aimingshake",_originalshake*_originalcourage*_general-(_shots*(1-_general)*.003)]; _unit setskill ["courage",(_unit skill "courage")-(_shots*(1-_general)*(1-_originalcourage)*.07)]; }; if ((isPlayer _unit) and (tpwc_ai_sup_playersup == 1) and (diag_ticktime < _skillregain)) then { [] spawn tpwc_ai_sup_visuals; addCamShake [2 - (skill _unit),(random 6)-((_unit getvariable "tpwc_general")+(_unit getvariable "tpwc_originalcourage")) , 5] }; }; }; //DISPLAY APPROPRIATE DEBUG BALLS if (tpwc_ai_sup_debug == 1) then { _ball1 = _unit getvariable "tpwc_sup1ball"; _ball2 = _unit getvariable "tpwc_sup2ball"; _ball3 = _unit getvariable "tpwc_sup3ball"; switch ( _unit getvariable "tpwc_suppressedstance" ) do { case 1: { tpwc_ballstatus = [_ball1, false, _ball2, true, _ball3, true]; }; case 2: { tpwc_ballstatus = [_ball1, true, _ball2, false, _ball3, true]; }; case 3: { tpwc_ballstatus = [_ball1, true, _ball2, true, _ball3, false]; }; default { tpwc_ballstatus = [_ball1, true, _ball2, true, _ball3, true]; }; }; tpwc_ballstatus call { (_this select 0) hideobject (_this select 1); (_this select 2) hideobject (_this select 3); (_this select 4) hideobject (_this select 5); }; if ( isDedicated ) then { [-1, {(_this select 0) hideobject (_this select 1);(_this select 2) hideobject (_this select 3);(_this select 4) hideobject (_this select 5);}, tpwc_ballstatus] call CBA_fnc_globalExecute; }; }; }; } foreach allunits; //REMOVE DEBUG BALLS FROM DEAD AI if (tpwc_ai_sup_debug == 1) then { { _unit = _x; _ball1 = _unit getvariable "tpwc_sup1ball"; if ( !(_ball1 == objNull) ) then { detach _ball1; deleteVehicle _ball1; _unit setvariable ["tpwc_sup1ball",nil]; }; _ball2 = _unit getvariable "tpwc_sup2ball"; if ( !(_ball2 == objNull) ) then { detach _ball2; deleteVehicle _ball2; _unit setvariable ["tpwc_sup2ball",nil]; }; _ball3 = _unit getvariable "tpwc_sup3ball"; if ( !(_ball3 == objNull) ) then { detach _ball3; deleteVehicle _ball3; _unit setvariable ["tpwc_sup3ball",nil]; }; } foreach allDead; }; sleep 1; } }; //BLUR PLAYER VISION WHEN SUPPRESSED tpwc_ai_sup_visuals = { if (tpwc_ai_sup_supvisflag == 0) then { tpwc_ai_sup_supvisflag = 1; _tint = ppEffectCreate ["Colorcorrections", 1552]; _tint ppEffectEnable true; _blur = ppEffectCreate ["RadialBlur", 1551]; _blur ppEffectEnable true; _ppmodifier = 0.001; { _ppmod = _ppmodifier * _x; _blur ppEffectAdjust [_ppmod,_ppmod,0.1,0.1]; _blur ppEffectCommit 0; _tint ppEffectAdjust[1, 1, (-5 * _ppmod), [0,0,0,0], [0,0,0,1], [0,0,0,1]]; _tint ppEffectCommit 0; sleep 0.1; } foreach [1,2,3,4,5]; sleep 5; { _ppmod = _ppmodifier * _x; _blur ppEffectAdjust [_ppmod,_ppmod,0.1,0.1]; _blur ppEffectCommit 0; _tint ppEffectAdjust[1, 1, (-5 * _ppmod), [0,0,0,0], [0,0,0,1], [0,0,0,1]]; _tint ppEffectCommit 0; sleep 0.1; } foreach [5,4,3,2,1]; ppEffectDestroy _blur; ppEffectDestroy _tint; tpwc_ai_sup_supvisflag = 0; }; }; //IF ASR AI HAS SET UNIT SKILLS, MAKE THESE THE "ORIGINALS" FOR EACH UNIT tpwc_ai_sup_asrskills = { sleep 3; while {true} do { { _unit = _x; _asr = _unit getVariable "asr_ai_sys_aiskill_configured"; _skillset = _unit getVariable "tpwc_skillset"; if ((_asr) && !(_skillset))then { _unit setvariable ["tpwc_originalaccuracy", _unit skill "aimingaccuracy"]; _unit setvariable ["tpwc_originalshake", _unit skill "aimingshake"]; _unit setvariable ["tpwc_originalcourage", _unit skill "courage"]; _unit setvariable ["tpwc_general",_unit skill "general"]; _unit setvariable ["tpwc_skillset", true]; }; } foreach allunits; sleep 30; }; }; ///////////////// // RUN IT ///////////////// //BASIC MODE if (tpwc_ai_sup_mode ==1) then { [tpwc_ai_sup_basic,0] call cba_fnc_addPerFrameHandler; }; //LITE MODE if (tpwc_ai_sup_mode ==2) then { [tpwc_ai_sup_lite,0] call cba_fnc_addPerFrameHandler; }; //FULL MODE if (tpwc_ai_sup_mode ==3) then { //Spawn behaviour loop [] spawn tpwc_ai_sup_behaviour; sleep 1; //Spawn ASR_AI skill set loop if running ASR_AI > 1.15.1 if (isclass (configfile >> "cfgPatches">>"asr_ai_sys_aiskill")) then { _asr_ai_va = getArray (configfile>>"cfgPatches">>"asr_ai_main">>"versionAr"); if (_asr_ai_va select 0 >= 1 && _asr_ai_va select 1 >= 15 && _asr_ai_va select 2 >= 1) then { [] spawn tpwc_ai_sup_asrskills; }; }; //Call time critical bullet detection loop [tpwc_ai_sup_detect,0] call cba_fnc_addPerFrameHandler; }; }; Edited June 28, 2012 by tpw Share this post Link to post Share on other sites
CameronMcDonald 146 Posted June 29, 2012 Not seeing a single unitpos in that entire script. I am disappoint. :p A-so, setunitpos doesn't count. Keep up the good work, gentlemans. Share this post Link to post Share on other sites
wolf5 13 Posted June 29, 2012 Really great. Can you update first post with the new script and addon version? Share this post Link to post Share on other sites
tpw 2315 Posted June 29, 2012 Really great.Can you update first post with the new script and addon version? Just a little bit more polishing and I will Share this post Link to post Share on other sites
kremator 1065 Posted June 29, 2012 (edited) Shaping up really nicely. Keep up the good work guys! Regarding the camerashake, I always use the latest beta, and I do get the ground shaking as tanks go past. However the script fails when addCameraShake is present. Anyone else using the latest betas that get the same thing ? Edited June 29, 2012 by Kremator Share this post Link to post Share on other sites
tpw 2315 Posted June 29, 2012 (edited) Shaping up really nicely. Keep up the good work guys!Regarding the camerashake, I always use the latest beta, and I do get the ground shaking as tanks go past. However the script fails when addCameraShake is present. Anyone else using the latest betas that get the same thing ? I'm on 94209 and addcamerashake is fine. Edited June 29, 2012 by tpw Share this post Link to post Share on other sites
metalcraze 290 Posted June 29, 2012 It may be some mod conflict. Although I'm on latest beta, use ASR AI and ACE and I'm fine. Share this post Link to post Share on other sites
orcinus 121 Posted June 29, 2012 So unfortunately there is some self suppression, especially in heavy fighting. but usually it is only light (green ball). I can look into trying to reduce sway from this type of suppression though. The only thing I can think of to truly fix the problem would be to make it so that more than one unit can be tpwc_ai_sup_fired - so that instead of a single unit, an array of units can be there. But I am not sure if this is possible and how you would then take away a unit from the tpwc_sup_fired array so he can once again be suppressed. Would it be possible to give the player unit a different variable (e.g., tpwc_P_sup_fired)? - then you could indeed use an array if you wanted to. Using switch early on to discriminate between player & AI might be useful to avoid slowing the script. Sorry, can't test today as I'm on mobile (& anyway I still maintain my claim to the title of shittiest coder in the thread). Share this post Link to post Share on other sites
CameronMcDonald 146 Posted June 29, 2012 I'm having no problems with the latest beta and a swag of mods, ASR AI included. Not sure what it might be, Kremator. Share this post Link to post Share on other sites
tpw 2315 Posted June 29, 2012 Would it be possible to give the player unit a different variable (e.g., tpwc_P_sup_fired)? - then you could indeed use an array if you wanted to. Using switch early on to discriminate between player & AI might be useful to avoid slowing the script. Sorry, can't test today as I'm on mobile (& anyway I still maintain my claim to the title of shittiest coder in the thread). It's not actually possible to be self-suppressed, or by anyone less than 25m away. if ((tpwc_ai_sup_fired distance _unit) > tpwc_ai_sup_ir) then Translation: only if shooter distance from unit is greater than 25m then proceed with rest of suppression calculations. ---------- Post added at 21:27 ---------- Previous post was at 21:17 ---------- OK, last code post before bed. I've done a bit more fiddling and refining, here's what's what 1 - Debug balls are now hidden on injured units (Ollem, please check that the dedi code is right for this) 2 - Only uninjured units can be suppressed (Thanks Fabrizio_T) 3 -I had to revert from _unit setvehicleinit format ["this setunitpos 'whateverpos';"]; processinitcommands; clearVehicleInit _unit; to _unit setunitpos "whateverpos" as this was causing the player unit to occasionally not be able to fire. No idea why. I was just thinking that part of the problem with dedi being less sensitive to bullets might be the bullet detection radius. When the whole thing is local, the 10m radius is sufficient to catch bullets. When running via dedi, the latency might mean that you need a bigger radius. Can someone check this out? 1.03 code: /* TPWC AI SUPPRESSION Authors: TPW & -Coulum- Additional code: Fabrizio_T, Ollem Version: 1.03 Last modified: 20120629 Requires: CBA Disclaimer: Feel free to use and modify this code, on the proviso that you post back changes and improvements so that everyone can benefit from them, and acknowledge the original authors in any derivative works. */ if (isServer || isDedicated) then { //Log it diag_log format ["TPWC AI SUPPRESS STARTED: Server: %1 - Dedicated: %2", isServer, isDedicated]; //////////// //VARIABLES /////////// //Suppression mode. 1 = basic , 2 = light, 3 = full stance / skills modification. tpwc_ai_sup_mode = 3; //Delay before suppression functions start. tpwc_ai_sup_sleep = 5; //Debugging. Will display coloured balls over any suppressed units. 0 = no debugging, 1 = debugging. tpwc_ai_sup_debug = 1; //Bullet detection radius (m). Bullets must pass within this distance of unit to suppress them. If set much below 10m, bullets may not be detected. tpwc_ai_sup_br = 10; //Bullet ignore radius (m). Bullets from a shooter closer than this will not suppress. tpwc_ai_sup_ir = 25; //Shot threshold. More shots than this will cause unit to drop/crawl. tpwc_ai_sup_st = 5; //Pistol and SMG ammo to ignore. Add custom ammo (eg suppressed) or change to taste. tpwc_ai_sup_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" ]; //Startup hint. 0 = no hint, 1 = hint. tpwc_ai_sup_hint = 1; //Player suppression (shake and visuals). 0 = no suppression, 1 = suppression . tpwc_ai_sup_playersup = 1; ////////// // SET UP ////////// //DECLARE PRIVATE VARIABLES private ["_stanceregain","_skillregain","_unit","_bc","_shots","_originalaccuracy","_originalshake","_originalcourage","_general","_ball","_ball1","_ball2","_ball3","_skillset","_asr","_tint","_blur","_x","_ppmod","_ppmodifier"]; //WAIT sleep tpwc_ai_sup_sleep; //START HINT if (tpwc_ai_sup_hint == 1) then { 0 = [] spawn { hintsilent "TPWC AI Suppress 1.03 Active"; sleep 3; hintsilent ""}; }; ////////////////// // MAIN FUNCTIONS ////////////////// //BASIC VERSION tpwc_ai_sup_basic = { { if (alive _x) then { _unit = _x; _stanceregain = _unit getvariable ["tpwc_stanceregain", -1]; if (_stanceregain == -1) then { _unit setvariable ["tpwc_stanceregain", diag_ticktime]; _unit addeventhandler ["fired",{tpwc_ai_sup_fired = _this select 0;tpwc_ai_sup_bullet = _this select 6}]; if (tpwc_ai_sup_debug == 1) then { _ball = "Sign_sphere25cm_EP1" createvehicle getposatl _unit; _ball attachTo [_unit,[0,0,2]]; _unit setvariable ["tpwc_supball",_ball]; }; }; if ( diag_ticktime >= _stanceregain) then { _ball = _unit getvariable "tpwc_supball"; _ball hideobject true; _unit setvariable ["tpwc_supshots", 0]; _unit setunitpos "auto"; _unit setvariable ["tpwc_suppressedstance", 0]; _unit setvariable ["tpwc_stanceregain", diag_ticktime + 10]; }; if !(isnull tpwc_ai_sup_bullet) then { _bc = count ((getposatl _unit) nearobjects ["bulletbase",tpwc_ai_sup_br]); if (_bc > 0) then { if ((tpwc_ai_sup_fired distance _unit) > tpwc_ai_sup_ir) then { _unit setvariable ["tpwc_stanceregain", diag_ticktime + 10]; _shots = _unit getvariable "tpwc_supshots"; _unit setvariable ["tpwc_supshots", _shots + _bc]; _shots = _unit getvariable "tpwc_supshots"; if ((_unit call CBA_fnc_getunitanim) select 0 != "prone") then { _unit setunitpos "middle"; }; _unit setvariable ["tpwc_suppressedstance", 1]; if (tpwc_ai_sup_debug == 1) then { _ball = _unit getvariable "tpwc_supball";_ball hideobject false; }; if (_shots > tpwc_ai_sup_st) then { _unit setunitpos "down"; }; }; }; }; }; } foreach allunits; }; //LITE VERSION tpwc_ai_sup_lite = { { if ((alive _x) && (vehicle _unit == _unit) && (lifeState _unit == "ALIVE")) then { _unit = _x; _stanceregain = _unit getvariable ["tpwc_stanceregain", -1]; if (_stanceregain == -1) then { _unit setvariable ["tpwc_stanceregain", diag_ticktime]; _unit addeventhandler ["fired",{tpwc_ai_sup_fired = _this select 0;tpwc_ai_sup_mag = _this select 5; tpwc_ai_sup_bullet = _this select 6}]; if (tpwc_ai_sup_debug == 1) then { _ball = "Sign_sphere25cm_EP1" createvehicle getposatl _unit; _ball attachTo [_unit,[0,0,2]]; _unit setvariable ["tpwc_supball",_ball]; }; }; if ( diag_ticktime >= _stanceregain) then { _ball = _unit getvariable "tpwc_supball"; _ball hideobject true; _unit setvariable ["tpwc_supshots", 0]; _unit setunitpos "auto"; _unit setvariable ["tpwc_suppressedstance", 0]; _unit setvariable ["tpwc_stanceregain", diag_ticktime + 10]; }; if !(isnull tpwc_ai_sup_bullet) then { _bc = count ((getposatl _unit) nearobjects ["bulletbase",tpwc_ai_sup_br]); if (_bc > 0) then { if ((tpwc_ai_sup_fired distance _unit) > tpwc_ai_sup_ir) then { if !(tpwc_ai_sup_mag in tpwc_ai_sup_mags) then { _unit setvariable ["tpwc_stanceregain", diag_ticktime + 10]; _shots = _unit getvariable "tpwc_supshots"; _unit setvariable ["tpwc_supshots", _shots + _bc]; if ((_unit call CBA_fnc_getunitanim) select 0 != "prone") then { _unit setunitpos "middle"; }; _unit setvariable ["tpwc_suppressedstance", 1]; if (side tpwc_ai_sup_fired != side _unit) then { _shots = _unit getvariable "tpwc_supshots"; if (tpwc_ai_sup_debug == 1) then { _ball = _unit getvariable "tpwc_supball";_ball hideobject false; }; if (_shots > tpwc_ai_sup_st) then { _unit setunitpos "down"; }; }; }; }; }; }; }; } foreach allunits; }; //BULLET DETECTION LOOP (TIME CRITICAL) //Do not touch this please tpwc_ai_sup_detect = { { _unit = _x; if (!(isnull tpwc_ai_sup_bullet) && (vehicle _unit == _unit) && (lifeState _unit == "ALIVE")) then { _bc = count ((getposatl _unit) nearobjects ["bulletbase",tpwc_ai_sup_br]); if (_bc > 0) then { if ((tpwc_ai_sup_fired distance _unit) > tpwc_ai_sup_ir) then { if !(tpwc_ai_sup_mag in tpwc_ai_sup_mags) then { _unit setvariable ["tpwc_skillregain", diag_ticktime + (random 4)-((_unit getvariable "tpwc_general")+(_unit getvariable "tpwc_originalcourage"))]; _unit setvariable ["tpwc_stanceregain", diag_ticktime + 10]; _unit setvariable ["tpwc_supshots",(_unit getvariable "tpwc_supshots") + _bc]; _unit setvariable ["tpwc_suppressedstance", 1]; if (side tpwc_ai_sup_fired != side _unit) then { _unit setvariable ["tpwc_suppressedstance", 2]; if (_unit getvariable "tpwc_supshots" > tpwc_ai_sup_st) then { _unit setvariable ["tpwc_suppressedstance", 3]; }; }; }; }; }; }; } foreach allunits; }; //UNIT STANCE/SKILL MODIFICATION LOOP (NON TIME CRITICAL) tpwc_ai_sup_behaviour = { tpwc_ai_sup_supvisflag = 0; while {true} do { { if (alive _x) then { _unit = _x; _skillregain = _unit getvariable ["tpwc_skillregain", -1]; _stanceregain = _unit getvariable ["tpwc_stanceregain", -1]; //SET INITIAL PARAMETERS FOR EACH UNIT if (_stanceregain == -1) then { _unit setvariable ["asr_ai_sys_aiskill_configured", false]; _unit setvariable ["tpwc_skillset", false]; _unit setvariable ["tpwc_combatmode", "unchanged"]; _unit setvariable ["tpwc_originalaccuracy", _unit skill "aimingaccuracy"]; _unit setvariable ["tpwc_originalshake", _unit skill "aimingshake"]; _unit setvariable ["tpwc_originalcourage", _unit skill "courage"]; _unit setvariable ["tpwc_general", _unit skill "general"]; _unit setvariable ["tpwc_stanceregain", diag_ticktime]; _unit setvariable ["tpwc_skillregain", diag_ticktime]; _unit addeventhandler ["fired",{tpwc_ai_sup_fired = _this select 0;tpwc_ai_sup_mag = _this select 5; tpwc_ai_sup_bullet = _this select 6}]; if ( ( assignedVehicleRole _unit) select 0 == "Turret" ) then { (vehicle _unit) addeventhandler ["fired",{tpwc_ai_sup_fired = _this select 0;tpwc_ai_sup_mag = _this select 5; tpwc_ai_sup_bullet = _this select 6}]; }; if (tpwc_ai_sup_debug == 1) then { _ball1 = "Sign_sphere25cm_EP1" createvehicle getposatl _unit; _ball1 setObjectTexture [0,"#(argb,8,8,3)color(0.2,0.9,0.2,0.5,ca)"]; _ball1 attachTo [_unit,[0,0,2]]; _unit setvariable ["tpwc_sup1ball",_ball1]; _ball1 hideobject true; _ball2 = "Sign_sphere25cm_EP1" createvehicle getposatl _unit; _ball2 setObjectTexture [0,"#(argb,8,8,3)color(0.6,0.9,0.0,0.7,ca)"]; //yellow _ball2 attachTo [_unit,[0,0,2]]; _unit setvariable ["tpwc_sup2ball",_ball2]; _ball2 hideobject true; _ball3 = "Sign_sphere25cm_EP1" createvehicle getposatl _unit; _ball3 setObjectTexture [0,"#(argb,8,8,3)color(0.8,0.5,0.5,0.5,ca)"]; //red _ball3 attachTo [_unit,[0,0,2]]; _unit setvariable ["tpwc_sup3ball",_ball3]; _ball3 hideobject true; }; }; //IF UNIT SKILLS ARE UNSUPPRESSED if (diag_ticktime >= _skillregain) then { _originalaccuracy = _unit getvariable "tpwc_originalaccuracy"; _originalshake = _unit getvariable "tpwc_originalshake"; _originalcourage = _unit getvariable "tpwc_originalcourage"; _general = _unit getvariable "tpwc_general"; if((_unit skill "aimingaccuracy") < _originalaccuracy) then { _unit setskill ["aimingaccuracy",(_unit skill "aimingaccuracy")+((_originalaccuracy-(_unit skill "aimingaccuracy"))*.325)]; }; if((_unit skill "aimingshake") < _originalshake) then { _unit setskill ["aimingshake",(_unit skill "aimingshake")+((_originalshake-(_unit skill "aimingshake"))*.325)]; }; }; //IF UNIT STANCE IS UNSUPPRESSED if ( diag_ticktime >= _stanceregain) then { _unit setvariable ["tpwc_supshots", 0]; _unit setunitpos "auto"; _originalcourage = _unit getvariable "tpwc_originalcourage"; _general = _unit getvariable "tpwc_general"; _unit setvariable ["tpwc_suppressedstance", 0]; if((_unit skill "courage") < (_originalcourage - 0.1)) then { _unit setskill ["courage",(_unit skill "courage")+(_general)*(0.1)]; } else { if (_unit getvariable "tpwc_combatmode" != "unchanged") then { _unit setbehaviour str(_unit getvariable "tpwc_combatmode"); _unit setvariable ["tpwc_combatmode", "unchanged"]; }; }; }; //UNIT CHANGES FOR DIFFERENT SUPPRESSION switch ( _unit getvariable "tpwc_suppressedstance" ) do { case 1: //IF ANY BULLETS NEAR UNIT { _unit setunitpos "middle"; }; case 2: //IF ENEMY BULLETS NEAR UNIT { if ((_unit call CBA_fnc_getunitanim) select 0 != "prone") then { _unit setunitpos "middle"; }; _unit setvariable ["tpwc_combatmode", behaviour _unit]; if( !( behaviour _unit in ["COMBAT", "STEALTH"] ) ) then { _unit setbehaviour "COMBAT"; }; _originalaccuracy = _unit getvariable "tpwc_originalaccuracy"; _originalshake = _unit getvariable "tpwc_originalshake"; _originalcourage = _unit getvariable "tpwc_originalcourage"; _general = _unit getvariable "tpwc_general"; _shots = _unit getvariable "tpwc_supshots"; if (diag_ticktime < _skillregain) then { _unit setskill ["aimingaccuracy",_originalaccuracy*_originalcourage*_general-(_shots*(1-_general)*((_unit skill "aimingaccuracy")-.1)*.025)]; _unit setskill ["aimingshake",_originalshake*_originalcourage*_general-(_shots*(1-_general)*((_unit skill "aimingshake")-.1)*.025)]; _unit setskill ["courage",(_unit skill "courage")-(_shots*(1-_general)*(1-_originalcourage)*((_unit skill "courage")-.1)*.1)]; }; if ((_unit == player) and (tpwc_ai_sup_playersup == 1) and (diag_ticktime < _skillregain)) then { addCamShake [1.5 - (skill player),(random 4)-((_unit getvariable "tpwc_general")+(_unit getvariable "tpwc_originalcourage")) , 2.5] }; }; case 3: //IF UNIT IS SUPPRESSED WITH MORE THAN 5 ENEMY BULLETS { _unit setunitpos "down"; _unit forcespeed -1; _unit setvariable ["tpwc_combatmode", behaviour _unit]; if( !( behaviour _unit in ["COMBAT", "STEALTH"] ) ) then { _unit setbehaviour "COMBAT"; }; _originalaccuracy = _unit getvariable "tpwc_originalaccuracy"; _originalshake = _unit getvariable "tpwc_originalshake"; _originalcourage = _unit getvariable "tpwc_originalcourage"; _general = _unit getvariable "tpwc_general"; _shots = _unit getvariable "tpwc_supshots"; if (diag_ticktime < _skillregain) then { _unit setskill ["aimingaccuracy",_originalaccuracy*_originalcourage*_general-(_shots*(1-_general)*.003)]; _unit setskill ["aimingshake",_originalshake*_originalcourage*_general-(_shots*(1-_general)*.003)]; _unit setskill ["courage",(_unit skill "courage")-(_shots*(1-_general)*(1-_originalcourage)*.07)]; }; if ((isPlayer _unit) and (tpwc_ai_sup_playersup == 1) and (diag_ticktime < _skillregain)) then { [] spawn tpwc_ai_sup_visuals; addCamShake [2 - (skill _unit),(random 6)-((_unit getvariable "tpwc_general")+(_unit getvariable "tpwc_originalcourage")) , 5] }; }; }; //DISPLAY APPROPRIATE DEBUG BALLS if (tpwc_ai_sup_debug == 1) then { _ball1 = _unit getvariable "tpwc_sup1ball"; _ball2 = _unit getvariable "tpwc_sup2ball"; _ball3 = _unit getvariable "tpwc_sup3ball"; switch ( _unit getvariable "tpwc_suppressedstance" ) do { case 1: { tpwc_ballstatus = [_ball1,false,_ball2,true,_ball3,true]; }; case 2: { tpwc_ballstatus = [_ball1,true,_ball2,false,_ball3,true]; }; case 3: { tpwc_ballstatus = [_ball1,true,_ball2,true,_ball3,false]; }; default { tpwc_ballstatus = [_ball1,true,_ball2,true,_ball3,true]; }; }; tpwc_ballstatus call { (_this select 0) hideobject (_this select 1); (_this select 2) hideobject (_this select 3); (_this select 4) hideobject (_this select 5); }; if ( isDedicated ) then { [-1, {(_this select 0) hideobject (_this select 1);(_this select 2) hideobject (_this select 3);(_this select 4) hideobject (_this select 5);}, tpwc_ballstatus] call CBA_fnc_globalExecute; }; }; }; } foreach allunits; if (tpwc_ai_sup_debug == 1) then { //REMOVE DEBUG BALLS FROM DEAD AI { _unit = _x; _ball1 = _unit getvariable "tpwc_sup1ball"; if ( !(_ball1 == objNull) ) then { detach _ball1; deleteVehicle _ball1; _unit setvariable ["tpwc_sup1ball",nil]; }; _ball2 = _unit getvariable "tpwc_sup2ball"; if ( !(_ball2 == objNull) ) then { detach _ball2; deleteVehicle _ball2; _unit setvariable ["tpwc_sup2ball",nil]; }; _ball3 = _unit getvariable "tpwc_sup3ball"; if ( !(_ball3 == objNull) ) then { detach _ball3; deleteVehicle _ball3; _unit setvariable ["tpwc_sup3ball",nil]; }; } foreach allDead; //HIDE DEBUG BALLS FROM INJURED UNITS if (lifestate _unit != "ALIVE") then { _ball1 = _unit getvariable "tpwc_sup1ball"; _ball2 = _unit getvariable "tpwc_sup2ball"; _ball3 = _unit getvariable "tpwc_sup3ball"; _ball1 hideobject true; _ball2 hideobject true; _ball3 hideobject true; if ( isDedicated ) then { [-1, {(_this select 0) hideobject true;(_this select 2) hideobject true;(_this select 4) hideobject true;}, tpwc_ballstatus] call CBA_fnc_globalExecute; }; }; }; sleep 1.5; } }; //BLUR PLAYER VISION WHEN SUPPRESSED tpwc_ai_sup_visuals = { if (tpwc_ai_sup_supvisflag == 0) then { tpwc_ai_sup_supvisflag = 1; _tint = ppEffectCreate ["Colorcorrections", 1552]; _tint ppEffectEnable true; _blur = ppEffectCreate ["RadialBlur", 1551]; _blur ppEffectEnable true; _ppmodifier = 0.001; { _ppmod = _ppmodifier * _x; _blur ppEffectAdjust [_ppmod,_ppmod,0.1,0.1]; _blur ppEffectCommit 0; _tint ppEffectAdjust[1, 1, (-5 * _ppmod), [0,0,0,0], [0,0,0,1], [0,0,0,1]]; _tint ppEffectCommit 0; sleep 0.1; } foreach [1,2,3,4,5]; sleep 5; { _ppmod = _ppmodifier * _x; _blur ppEffectAdjust [_ppmod,_ppmod,0.1,0.1]; _blur ppEffectCommit 0; _tint ppEffectAdjust[1, 1, (-5 * _ppmod), [0,0,0,0], [0,0,0,1], [0,0,0,1]]; _tint ppEffectCommit 0; sleep 0.1; } foreach [5,4,3,2,1]; ppEffectDestroy _blur; ppEffectDestroy _tint; tpwc_ai_sup_supvisflag = 0; }; }; //IF ASR AI HAS SET UNIT SKILLS, MAKE THESE THE "ORIGINALS" FOR EACH UNIT tpwc_ai_sup_asrskills = { sleep 3; while {true} do { { _unit = _x; _asr = _unit getVariable "asr_ai_sys_aiskill_configured"; _skillset = _unit getVariable "tpwc_skillset"; if ((_asr) && !(_skillset))then { _unit setvariable ["tpwc_originalaccuracy", _unit skill "aimingaccuracy"]; _unit setvariable ["tpwc_originalshake", _unit skill "aimingshake"]; _unit setvariable ["tpwc_originalcourage", _unit skill "courage"]; _unit setvariable ["tpwc_general",_unit skill "general"]; _unit setvariable ["tpwc_skillset", true]; }; } foreach allunits; sleep 30; }; }; ///////////////// // RUN IT ///////////////// //BASIC MODE if (tpwc_ai_sup_mode ==1) then { [tpwc_ai_sup_basic,0] call cba_fnc_addPerFrameHandler; }; //LITE MODE if (tpwc_ai_sup_mode ==2) then { [tpwc_ai_sup_lite,0] call cba_fnc_addPerFrameHandler; }; //FULL MODE if (tpwc_ai_sup_mode ==3) then { //Spawn behaviour loop [] spawn tpwc_ai_sup_behaviour; sleep 1; //Spawn ASR_AI skill set loop if running ASR_AI > 1.15.1 if (isclass (configfile >> "cfgPatches">>"asr_ai_sys_aiskill")) then { _asr_ai_va = getArray (configfile>>"cfgPatches">>"asr_ai_main">>"versionAr"); if (_asr_ai_va select 0 >= 1 && _asr_ai_va select 1 >= 15 && _asr_ai_va select 2 >= 1) then { [] spawn tpwc_ai_sup_asrskills; }; }; //Call time critical bullet detection loop [tpwc_ai_sup_detect,0] call cba_fnc_addPerFrameHandler; }; }; , Share this post Link to post Share on other sites
ollem 4 Posted June 29, 2012 (edited) 1 - Debug balls are now hidden on injured units (Ollem, please check that the dedi code is right for this) Gave it a quick try, but injured units were still showing debug balls.. not sure about unconcious.. Current code has only 2 options on Dedicated: no balls and red balls => I will look into this I was just thinking that part of the problem with dedi being less sensitive to bullets might be the bullet detection radius. When the whole thing is local, the 10m radius is sufficient to catch bullets. When running via dedi, the latency might mean that you need a bigger radius. Can someone check this out? I tested with detection radius of 20 meters and shot threshold of 3 bullets, and the results were hopeful: again still not as responsive as SP, but for sure much more natural effect compared to no TWPC-Suppress :cool: Needs some fine tuning for best settings. CVhxZRBlLl0 Also for Dedicated server I might add 'player only' option to only enable the 'fired' eventhandler for players - I usually play coop versus AI - so then there's no need for AI Eventhandlers. On Dedicated I did not notice the 'player shake' anyway, though I'm running latests beta. Edited June 29, 2012 by Ollem Share this post Link to post Share on other sites
SavageCDN 231 Posted June 29, 2012 (edited) I still maintain my claim to the title of shittiest coder in the thread). *raises hand* Many people are glad to support you, as you notice. That's because you all (You, Coulum, Ollem, ...) are doing a great work. Simple as that. Keep it going. Quoted for Truth @twp/coulum - you've probably had offers already but if MP testing is needed with a group of players I can offer a dedicated server and warm bodies Edited June 29, 2012 by SavageCDN Share this post Link to post Share on other sites
jiltedjock 10 Posted June 29, 2012 (edited) Can someone check this out? I've been having a lot of fun with this combined with the Line of Sight script and ASR AI - well done. I have only tested in Invasion 44 which tends to have shorter engagement ranges. In Single Player 1.03 copied out of your post, there seemed to be a little more of a performance hit than in the previous version - just a slightly laggier feel that I didn't get on the previous version. I reverted to the previous and it seemed to be 1 or 2 FPS quicker in similar circumstances (which, in a very intense scene, was about a 10% difference). No errors in the RPT. Level 3 suppression. Beta 94209 Also, in 1.03, I experienced a few instances of not being able to fire which I hadn't had before. This was on a 2500k overclocked to 4.7Ghz, Nvidia 580, with about 25 five to eight man groups, largely CQB in a built up area. JJ Edited June 29, 2012 by jiltedjock Share this post Link to post Share on other sites
orcinus 121 Posted June 29, 2012 Quoted for Truth +1 Also, I confirm the occasional inability to fire with 1.03; running with latest LOS pbo, asr_ai 1.15.1; using beta 94209. Not too much of an issue, hit the trigger again immediately & the weapon fires. Did try this with the 3rd 'real' Harvest Red mission and hit big trouble: after Reaper 1 called for support I headed towards the factory to take out the sniper. When I got near the large round towers (silos?) the FPS dropped to ~7 then 2 then the game froze. Had to use task manger to restart the PC. Reproducible, However, I suspect that this is a heavily scripted mission. Will test a few more offical & user missions/campaigns during the next week or two, since my 14-18 hrs/day work stint is over Gameplay is soooo much better with this combination. Wheee! Share this post Link to post Share on other sites
fabrizio_t 58 Posted June 29, 2012 (edited) Gave it a quick try, but injured units were still showing debug balls.. not sure about unconcious.. The code i suggested was aimed to handle exclusively the unconscious state. Wounded units do need to be suppresed in my opinion. However looks like we have to skip also units who can't stand anymore (because of wounded legs). So: if (!(isnull tpwc_ai_sup_bullet) && (vehicle _unit == _unit) && (lifeState _unit == "ALIVE")) then will become: if (!(isnull tpwc_ai_sup_bullet) && (vehicle _unit == _unit) && (lifeState _unit == "ALIVE") && canStand _unit ) then It may be debatable whether these legs-wounded units should skip being suppressed altogether (as per-example) or just for the stance handling part. Probably the latter solution would be better? If so then leave the above original code unchanged and edit: if !(tpwc_ai_sup_mag in tpwc_ai_sup_mags) then to: if ( !(tpwc_ai_sup_mag in tpwc_ai_sup_mags) && canStand _unit ) then Finally: there is a problem with: if (side tpwc_ai_sup_fired != side _unit) then The problem is it does not take in account other friendly sides, so you may end up being suppressed by allies. In this case it would suffice to change to: if ( ( side tpwc_ai_sup_fired ) getFriend ( side _unit) < 0.6 ) then Edited June 29, 2012 by fabrizio_T ortho Share this post Link to post Share on other sites
orcinus 121 Posted June 29, 2012 The code i suggested was aimed to handle exclusively the unconscious state.Wounded units do need to be suppresed in my opinion. However looks like we have to skip also units who can't stand anymore (because of wounded legs). So: if (!(isnull tpwc_ai_sup_bullet) && (vehicle _unit == _unit) && (lifeState _unit == "ALIVE")) then will become: if (!(isnull tpwc_ai_sup_bullet) && (vehicle _unit == _unit) && (lifeState _unit == "ALIVE") && canStand _unit ) then Using COSLX, prone injured units will occasionally lob a grenade at you (quite accurately, too if their arms aren't damaged) so keeping them pinned may not be such a bad idea. Perhaps it could be a config option? Share this post Link to post Share on other sites
fabrizio_t 58 Posted June 29, 2012 A notice: in tpwc_ai_sup_basic part of the initial IF statement is missing, compared to tpwc_ai_sup_lite. Unintentional i bet. Share this post Link to post Share on other sites