swift39 1 Posted April 1, 2018 Happy Easter Everyone, I am currently attempting to create a mission that involves a group of Protesters (Civilians) that initially use animations, then when the situation escalates they become armed and go on the offensive. Unfortunately my scripting skills are less than novice and reading the Forums am struggling with it. Using IndeedPete's example in this thread https://forums.bohemia.net/forums/topic/175237-arma-3-animations/ and trying various examples from other posts can only seem to make this work. _animation = ["c7a_bravoTOerc_idle8", "c7a_bravo_dovadeni1", "c7a_bravoTleskani_idle5", "c7a_bravo_dovadeni3"] call BIS_fnc_selectRandom; Protester switchMove _animation; Protester_1 switchMove _animation; Protester_2 switchMove _animation; Protester_3 switchMove _animation; On testing this seems to work intermittently and does not appear to "randomize" on the AI, I mean they all seem to get the same animation. I have created a unit called Protesters and set the Composition:Init to the following What I would like to have happen is to ensure the animations play and are truly random amongst the group, each one playing a different animation. Also would like to set it up that I don't have to add each civilian into the script and just being able to add them to the unit, I plan on a lot of protestors. Group and Unit seem to cause scripting errors, which I am sure I have missed something. Also would like the animations to randomize continually so each protester changes their animation at times. Any assistance is greatly appreciated and thank you in advance Greg Share this post Link to post Share on other sites
AZCoder 921 Posted April 1, 2018 { sleep 0.1; _animation = ["c7a_bravoTOerc_idle8", "c7a_bravo_dovadeni1", "c7a_bravoTleskani_idle5", "c7a_bravo_dovadeni3"] call BIS_fnc_selectRandom; _x switchMove _animation; } forEach [Protester,Protester_1,Protester_2,Protester_3]; sleep is optional, I like to add a slight delay in case more than one get the same animation Share this post Link to post Share on other sites
swift39 1 Posted April 2, 2018 Thank You AZCoder. I have this portion working, after finding that some animations well... Just don't work! { doStop _x; _x disableAI "PATH"; _x setDir 180; sleep 0.1; _animation = ["zevl2_c0start", "c7a_bravo_dovadeni1", "zevl7_c0start", "c7a_bravo_dovadeni3"] call BIS_fnc_selectRandom; _x switchMove _animation; playSound "protest1"; } forEach [ProtesterA, ProtesterA_1, ProtesterA_2, ProtesterA_3, ProtesterA_4, ProtesterA_5, ProtesterA_6, ProtesterA_7, ProtesterA_8, ProtesterA_9, ProtesterA_10, ProtesterA_11, ProtesterA_12, ProtesterA_13, ProtesterA_14, ProtesterA_15, ProtesterA_16, ProtesterA_17, ProtesterA_18, ProtesterA_19, ProtesterA_20, ProtesterA_21, ProtesterA_22, ProtesterA_23, ProtesterA_24]; Messing around with a loop function from the forums and not having much luck as of yet. I have been testing the animDone EH and the waitUntil script, nether seems to function yet ( I will post when I get some results other than script errors or breaking the script as I am sure I am doing something wrong there, also cannot get the custom sound file to play. What I would like to have happen is when a protester animation is completed it again randomly picks another one and continues the cycle until an event happens to stop it (gun shot or explosion) then the civilians will be armed (randomly?) and the scenario will continue. I am confident I have the sound structure set up correctly in the description.ext and the sound files are in .ogg format. class CfgSounds { sounds[] = {protest1, protest2}; class protest1 { // how the sound is referred to in the editor (e.g. trigger effects) name = "protest1"; // filename, volume, pitch, distance sound[] = {"\Sound\fx_protest1.ogg", 50, 1, 100}; // subtitle delay in seconds, subtitle text titles[] = {}; }; class protest2 { // how the sound is referred to in the editor (e.g. trigger effects) name = "protest2"; // filename, volume, pitch, distance sound[] = {"\Sound\fx_protest2.ogg", 50, 1, 100}; // subtitle delay in seconds, subtitle text titles[] = {}; }; }; Again any advice,. hints or tricks appreciated. Cheers Greg Share this post Link to post Share on other sites
swift39 1 Posted April 2, 2018 I have been playing with these for a few hours now, and it is beyond me why it appears to work in one test, partially works in another and wont do anything at all. I have been trying various versions of the following trying to follow the forum posts { doStop _x; _x disableAI "PATH"; _x setDir 180; sleep 0.1; _animation = ["zevl2_c0start", "c7a_bravo_dovadeni1", "zevl7_c0start", "c7a_bravo_dovadeni3"] call BIS_fnc_selectRandom; _x switchMove _animation; waitUntil{animationState _x != _animation}; playSound "protest1"; } forEach [ProtesterA, ProtesterA_1, ProtesterA_2, ProtesterA_3, ProtesterA_4, ProtesterA_5, ProtesterA_6, ProtesterA_7, ProtesterA_8, ProtesterA_9, ProtesterA_10, ProtesterA_11, ProtesterA_12, ProtesterA_13, ProtesterA_14, ProtesterA_15, ProtesterA_16, ProtesterA_17, ProtesterA_18, ProtesterA_19, ProtesterA_20, ProtesterA_21, ProtesterA_22, ProtesterA_23, ProtesterA_24]; and { doStop _x; _x disableAI "PATH"; _x setDir 180; sleep 0.1; _animation = ["zevl2_c0start", "c7a_bravo_dovadeni1", "zevl7_c0start", "c7a_bravo_dovadeni3"] call BIS_fnc_selectRandom; _x switchMove _animation; animLoop = _x addEventHandler ["AnimDone", { _x switchMove "_animation" }]; _x setVariable [ "animLoop", animLoop ]; playSound "protest1"; } forEach [ProtesterA, ProtesterA_1, ProtesterA_2, ProtesterA_3, ProtesterA_4, ProtesterA_5, ProtesterA_6, ProtesterA_7, ProtesterA_8, ProtesterA_9, ProtesterA_10, ProtesterA_11, ProtesterA_12, ProtesterA_13, ProtesterA_14, ProtesterA_15, ProtesterA_16, ProtesterA_17, ProtesterA_18, ProtesterA_19, ProtesterA_20, ProtesterA_21, ProtesterA_22, ProtesterA_23, ProtesterA_24]; Depending on what configuration dictates on how the AI react, obviously, but seems to very erronious and sometimes unwxpected results. Anyone have any ideas, examples or advise. Am I even on the right track with this? Anyway thanks in advance. Cheers Greg Share this post Link to post Share on other sites
AZCoder 921 Posted April 2, 2018 Some animations require disableAI "ANIM" to work correctly. If you haven't already, I would add that in there and let it apply to all animations. It prevents animation auto-switching. I believe animdone will still fire. Share this post Link to post Share on other sites
swift39 1 Posted April 3, 2018 Well I like to say it has been a weekend well wasted, kidding I have learned a bit about scripting. Thank you very much AZCoder. I still cannot get the AI animation to loop and change animations, nor get the sound to play, but have learned what various commands do and more importantly not do. I have started the Combat Mode for the Ai and while it is really a work in progress it appears that it may just work when I get it sorted out. Here is what I accomplished so far, please remember the Combat Mode was just started and am still sorting it through. { // AI prevented to move or change behaviour. _x disableAI "PATH"; _x disableAI "MOVE"; _x stop true; _x setBehaviour "CARELESS"; //Disable Animination and Set AI direction to South. sleep 0.1; _x disableAI "ANIM"; _x setFormDir 180; _x setDir 180; //AI animation is selected randomly and started _animation = ["UnaErcVelitelProslov4", "c7a_bravo_dovadeni1", "shaftoe_c0briefing_otazky_loop6", "c7a_bravo_dovadeni3"] call BIS_fnc_selectRandom; _x switchMove _animation; //AI animation is looped and randomly changed animLoop = _x addEventHandler ["AnimDone", { _x switchMove _animation }]; _x setVariable [ "animLoop", animLoop, true ]; //Protest Chant playSound "protest1"; // Combat Mode, Randomly selects weapons for Civilians _x addEventHandler ["FiredNear", { _x enableAI "ALL"; _x stop false; _x setBehaviour "COMBAT"; _x call BIS_fnc_ambientAnim__terminate; _arm = [ "hgun_Rook40_F", "hgun_P07_F", "arifle_AKM_F", "launch_RPG7_F"] call BIS_fnc_selectRandom; [_x, _arm, 8] call BIS_fnc_addWeapon; _x setCombatMode "RED"; }]; } forEach [ProtesterA, ProtesterA_1, ProtesterA_2, ProtesterA_3, ProtesterA_4, ProtesterA_5, ProtesterA_6, ProtesterA_7, ProtesterA_8, ProtesterA_9, ProtesterA_10, ProtesterA_11, ProtesterA_12, ProtesterA_13, ProtesterA_14, ProtesterA_15, ProtesterA_16, ProtesterA_17, ProtesterA_18, ProtesterA_19, ProtesterA_20, ProtesterA_21, ProtesterA_22, ProtesterA_23, ProtesterA_24]; Again any suggestions, hints, tips and tricks greatly appreciated. Unfortunately, my weekend is over and will have to get back to reality and time will be limited to work on this for a few days. Cheers Greg 1 Share this post Link to post Share on other sites
AZCoder 921 Posted April 3, 2018 A couple things I noted. Where did you get the animations? They appear to be Arma 2, so maybe you're using Indeed Pete's conversion? When I switched them to known Arma 3 animations, that part worked fine. As an example, and I know these are totally inappropriate: _animation = ["Acts_B_M05_briefing", "Acts_JetsOfficerSpilling", "acts_miller_knockout", "InBaseMoves_HandsBehindBack1"] call BIS_fnc_selectRandom; The other bit is that you need to grab the civilian inside the FiredNear event handler to make use of him. _x addEventHandler ["FiredNear", { _civ = _this select 0; _civ enableAI "ALL"; _civ stop false; _civ setBehaviour "COMBAT"; _civ switchMove ""; _arm = [ "hgun_Rook40_F", "hgun_P07_F", "arifle_AKM_F", "launch_RPG7_F"] call BIS_fnc_selectRandom; [_civ, _arm, 8] call BIS_fnc_addWeapon; _civ setCombatMode "RED"; }]; And I don't think BIS_fnc_ambientAnim__terminate does anything useful here, so I put in the switchMove "". 1 Share this post Link to post Share on other sites
XianGrim 73 Posted April 3, 2018 I've been doing a lot of custom sound work in the last few concepts and missions I've done personally. Try this in your description.ext class CfgSounds { class fx_protest1 { name = "fx_protest1"; sound[] = {"\Sound\fx_protest1.ogg", db+50, 1, 100}; titles[] = {}; }; class fx_protest2 { name = "fx_protest2"; sound[] = {"\Sound\fx_protest2.ogg",db+50, 1, 100}; titles[] = {}; }; }; You may need to test and tweak the "db+50" around, that may be a bit loud. And to call your sound, I like remoteExec since it'll broadcast in an MP setting (I didn't see whether your mission was SP or MP) [yourProtestorsNameHere,["fx_protest1",50,1]] remoteExec ["say3D",0]; That should get your sound working. Share this post Link to post Share on other sites
swift39 1 Posted April 4, 2018 Thank you very much of both of you... 14 hours ago, XianGrim said: That should get your sound working. The sound play flawlessly and yes the intent is to have this a MP mission so thanks for the advice on how to make the sound MP friendly. I do have to look into stopping the sound when the "FiredNear" or "Explosion" EH is triggered though. 23 hours ago, AZCoder said: They appear to be Arma 2, so maybe you're using Indeed Pete's conversion? When I switched them to known Arma 3 animations, that part worked fine. As an example, and I know these are totally inappropriate: Yes, I am using IndeedPete's Arma2 Cutscenes mod. The animations I selected work fine in this: _animation = ["UnaErcVelitelProslov4", "c7a_bravo_dovadeni1", "shaftoe_c0briefing_otazky_loop6", "c7a_bravo_dovadeni3"] call BIS_fnc_selectRandom; _x switchMove _animation; The problem I am having is I wanted to have the animations play in a loop with the "Protester" switching the animation when the current one is completed. The problem is in the loop function or is it because I am using Arma 2 animations: //AI animation is looped and randomly changed animLoop = _x addEventHandler ["AnimDone", { _x switchMove _animation }]; _x setVariable [ "animLoop", animLoop, true ]; Worked a bit more on the Combat state of the protesters. The plan is to have either a suicide bomber or Blufor soldier (firing a weapon or Explosion) trigger a "Riot" where the protester become armed and engage all units in the area (military or civilian). // Combat Mode, Randomly selects weapons for Civilians _x addEventHandler ["FiredNear", { _civ = _this select 0; _civ enableAI "ALL"; _civ stop false; _civ setBehaviour "COMBAT"; _civ switchMove ""; switch (round(random 5)) do { case 0: { _civ addMagazines ["16Rnd_9x21_Mag", 5]; _civ addWeapon "hgun_Rook40_F"; }; case 1: { }; case 2: { _civ addMagazines ["11Rnd_45ACP_Mag", 5]; _civ addWeapon "hgun_Pistol_heavy_01_F"; }; case 3: { _civ addMagazines ["30Rnd_762x39_Mag_F", 5]; _civ addWeapon "arifle_AKM_F"; }; case 4: { _civ addMagazines ["RPG7_F", 3]; _civ addWeapon "launch_RPG7_F"; }; }; _civ setCombatMode "RED"; _civilianUnit setFriend [West, 0]; _civilianUnit setFriend [East, 0]; _civilianUnit setFriend [civilian, 0]; }]; I created a "Random" switch manly because well the protesters need ammunition and that seemed a simple approach. In the current configuration, which definitly need more R&D on my part I am finding that: Protesters seem to not engage and continue with the expected civilian behavior. Weapons appear to be random but don't seem to attaching to the protester (eg. The weapon will appear for some one to be erect while the protester is prone or cowering state) I am thinking this is because they are not changing their state. I am also at this point handgun are holstered on the protester as I have not seen one yet. Civilians wont engage and seem not to be in an unfriendly state and continue to act like civilians. I am assuming that I will have to attempt to use the "joinSilent" approach. Again this is much a work in progress, but am happy with the results thus far. Thanks again and welcome any comments, advice or ideas. Cheers Greg Full Script to date: Spoiler { // AI prevented to move or change behaviour. _x disableAI "PATH"; _x disableAI "MOVE"; _x stop true; _x setBehaviour "CARELESS"; //Disable Animination and Set AI direction to South. sleep 0.1; _x disableAI "ANIM"; _x setFormDir 180; _x setDir 180; //AI animation is selected randomly and started //_animation = ["Acts_B_M05_briefing", "Acts_JetsOfficerSpilling", "acts_miller_knockout", "InBaseMoves_HandsBehindBack1"] call BIS_fnc_selectRandom; _animation = ["UnaErcVelitelProslov4", "c7a_bravo_dovadeni1", "shaftoe_c0briefing_otazky_loop6", "c7a_bravo_dovadeni3"] call BIS_fnc_selectRandom; _x switchMove _animation; //AI animation is looped and randomly changed animLoop = _x addEventHandler ["AnimDone", { _x switchMove _animation }]; _x setVariable [ "animLoop", animLoop, true ]; //Protest Chant [ProtesterA, ["fx_protest1", 30, 1]] remoteExec ["say3D", 0]; // Combat Mode, Randomly selects weapons for Civilians _x addEventHandler ["FiredNear", { _civ = _this select 0; _civ enableAI "ALL"; _civ stop false; _civ setBehaviour "COMBAT"; _civ switchMove ""; switch (round(random 5)) do { case 0: { _civ addMagazines ["16Rnd_9x21_Mag", 5]; _civ addWeapon "hgun_Rook40_F"; }; case 1: { }; case 2: { _civ addMagazines ["11Rnd_45ACP_Mag", 5]; _civ addWeapon "hgun_Pistol_heavy_01_F"; }; case 3: { _civ addMagazines ["30Rnd_762x39_Mag_F", 5]; _civ addWeapon "arifle_AKM_F"; }; case 4: { _civ addMagazines ["RPG7_F", 3]; _civ addWeapon "launch_RPG7_F"; }; }; _civ setCombatMode "RED"; _civilianUnit setFriend [West, 0]; _civilianUnit setFriend [East, 0]; _civilianUnit setFriend [civilian, 0]; }]; } forEach [ProtesterA, ProtesterA_1, ProtesterA_2, ProtesterA_3, ProtesterA_4, ProtesterA_5, ProtesterA_6, ProtesterA_7, ProtesterA_8, ProtesterA_9, ProtesterA_10, ProtesterA_11, ProtesterA_12, ProtesterA_13, ProtesterA_14, ProtesterA_15, ProtesterA_16, ProtesterA_17, ProtesterA_18, ProtesterA_19, ProtesterA_20, ProtesterA_21, ProtesterA_22, ProtesterA_23, ProtesterA_24]; Share this post Link to post Share on other sites
AZCoder 921 Posted April 4, 2018 That A2 anims should be fine, I just didn't have it running when I tested. Well I'd have to look at that when I'm more awake. Civilians won't ever attack, unless somebody knows a trick for that. If you want hostile civilians, you have to pick another faction and dress them up as civilians and set their combatMode blue and setCaptive true, maybe disableAI "autotarget" other things to keep them from treating you like the enemy too soon. Just guessing, haven't tried that. Share this post Link to post Share on other sites
swift39 1 Posted April 5, 2018 Thanks AZCoder, hopefully I can figure out a trick, lol Been playing around with this and while I would love to embarrass the kids with my happy dance, it will have to wait, but have shown a bit of promise that this can be done. The following is not working properly but shows promise in the sense a Civilian AI attacked me. // Combat Mode, Randomly selects weapons for Civilians _x addEventHandler ["FiredNear", { //Make enemy _x addRating -10000; _x setFriend [West, 0]; _x setFriend [civilian, 0]; //Change AI state _civ = _this select 0; _civ enableAI "ALL"; _civ stop false; _civ switchMove ""; //Give AI weapon randomly switch (round(random 5)) do { case 0: { _civ addMagazines ["16Rnd_9x21_Mag", 5]; _civ addWeapon "hgun_Rook40_F"; }; case 1: { }; case 2: { _civ addMagazines ["11Rnd_45ACP_Mag", 5]; _civ addWeapon "hgun_Pistol_heavy_01_F"; }; case 3: { _civ addMagazines ["30Rnd_762x39_Mag_F", 5]; _civ addWeapon "arifle_AKM_F"; }; case 4: { _civ addMagazines ["RPG7_F", 3]; _civ addWeapon "launch_RPG7_F"; }; }; //Set combat mode. _civ setBehaviour "COMBAT"; _civ setCombatMode "RED"; //_SideHQ = createCenter EAST; //_group = creatGroup EAST; //{[_civ] joinSilent _group;} forEach _civ addon _group; }]; Current issues in this section: Not all civilians are "breaking out" of the animation mode. Some civilians still reacting like civilians and not going into combat mode Only ProtesterA (the first in the forEach string) changes and reacts Weapon randomization may not be working as ProtesterA when killed dumps a mini arsenal and appears other given weapons may have multiple. I am sure there are other issues but in the end I had one Protester shoot at me. Thanks again and really open to any suggestions or ideas from anyone. Cheers Greg Full Code to date: Spoiler { // AI prevented to move or change behaviour. _x disableAI "PATH"; _x disableAI "MOVE"; _x stop true; _x setBehaviour "CARELESS"; //Disable Animination and Set AI direction to South. sleep 0.1; _x disableAI "ANIM"; _x setFormDir 180; _x setDir 180; //AI animation is selected randomly and started //_animation = ["Acts_B_M05_briefing", "Acts_JetsOfficerSpilling", "acts_miller_knockout", "InBaseMoves_HandsBehindBack1"] call BIS_fnc_selectRandom; _animation = ["UnaErcVelitelProslov4", "c7a_bravo_dovadeni1", "shaftoe_c0briefing_otazky_loop6", "c7a_bravo_dovadeni3"] call BIS_fnc_selectRandom; _x switchMove _animation; //AI animation is looped and randomly changed animLoop = _x addEventHandler ["AnimDone", { _x switchMove _animation }]; _x setVariable [ "animLoop", animLoop, true ]; //Protest Chant [ProtesterA, ["fx_protest1", 30, 1]] remoteExec ["say3D", 0]; // Combat Mode, Randomly selects weapons for Civilians _x addEventHandler ["FiredNear", { //Make enemy _x addRating -10000; _x setFriend [West, 0]; _x setFriend [civilian, 0]; //Change AI state _civ = _this select 0; _civ enableAI "ALL"; _civ stop false; _civ switchMove ""; //Give AI weapon randomly switch (round(random 5)) do { case 0: { _civ addMagazines ["16Rnd_9x21_Mag", 5]; _civ addWeapon "hgun_Rook40_F"; }; case 1: { }; case 2: { _civ addMagazines ["11Rnd_45ACP_Mag", 5]; _civ addWeapon "hgun_Pistol_heavy_01_F"; }; case 3: { _civ addMagazines ["30Rnd_762x39_Mag_F", 5]; _civ addWeapon "arifle_AKM_F"; }; case 4: { _civ addMagazines ["RPG7_F", 3]; _civ addWeapon "launch_RPG7_F"; }; }; //Set combat mode. _civ setBehaviour "COMBAT"; _civ setCombatMode "RED"; //_SideHQ = createCenter EAST; //_group = creatGroup EAST; //{[_civ] joinSilent _group;} forEach _civ addon _group; }]; } forEach [ProtesterA, ProtesterA_1, ProtesterA_2, ProtesterA_3, ProtesterA_4, ProtesterA_5, ProtesterA_6, ProtesterA_7, ProtesterA_8, ProtesterA_9, ProtesterA_10, ProtesterA_11, ProtesterA_12, ProtesterA_13, ProtesterA_14, ProtesterA_15, ProtesterA_16, ProtesterA_17, ProtesterA_18, ProtesterA_19, ProtesterA_20, ProtesterA_21, ProtesterA_22, ProtesterA_23, ProtesterA_24]; Share this post Link to post Share on other sites
XianGrim 73 Posted April 5, 2018 Awhile back I wanted to do a script for civilians having the ability to "concealed carry" and I got a lot of help from I believe F2kSel (it's been awhile). Take a look through it, you may find something that helps. Seems similar to what you're doing Spoiler { if (random 1 < 0.15) then { _x addEventHandler ["FiredNear", { params ["_unit", "_shooter", "_distance"]; if ( _distance > 25 || (isPlayer _unit) || {_unit getVariable ["hasTarget", false]} || {side _shooter == civilian} ) exitWith {}; _weapon = selectRandom ["hgun_ACPC2_F", "hgun_P07_F", "hgun_P07_F", "hgun_Rook40_F"]; _mag = selectRandom (getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines")); _unit addMagazine _mag; _unit addWeapon _weapon; [_unit] joinSilent createGroup sideEnemy; _unit allowFleeing 0; _unit setSkill ["courage", 1]; _unit reveal [_shooter, 3.75]; _unit setVariable ["hasTarget", true]; [_unit, _shooter, _weapon] spawn { params ["_unit", "_shooter", "_weapon"]; waitUntil { sleep 0.1; !alive _unit || {_shooter distance _unit > 50} }; _unit setVariable ["hasTarget", false]; _unit removeWeapon _weapon; }; }]; }; } forEach (allUnits select {side _x == civilian}); sleep 60; 0 = [] execVM "concealed_carry.sqf"; Specifically, I think if you look at adding the: [_unit] joinSilent createGroup sideEnemy; _unit allowFleeing 0; _unit setSkill ["courage", 1]; _unit reveal [_shooter, 3.75]; you might be able to get on the right track. Hope it helps! 1 Share this post Link to post Share on other sites
AZCoder 921 Posted April 5, 2018 Duh! LOL I should know this, I've had civs join a faction before. Yeah that looks really good. Share this post Link to post Share on other sites
XianGrim 73 Posted April 6, 2018 Quote The sound play flawlessly and yes the intent is to have this a MP mission so thanks for the advice on how to make the sound MP friendly. I do have to look into stopping the sound when the "FiredNear" or "Explosion" EH is triggered though. 1 If you want, for the sound to stop, you could place an invisible helipad down in the center of the protesters, call it "ProtesterVoice" or some such. Then play the sound from there with the code I mentioned but use the voice instead so it would be: [ProtesterVoice,["fx_protest1",50,1]] remoteExec ["say3D",0]; Then in your EH, you could simply delete it with deleteVehicle. Though you'd have to come up with a createVehicle solution to spawn the voice again if you wanted it to be reuseable. Just a thought! Share this post Link to post Share on other sites
swift39 1 Posted April 6, 2018 Thank you to you all... Unfortunately life got in the way last night so haven't had a lot of time to play with this. Will get back at after work today and see if I can achieve success. A couple questions though... in the forEach statement I currently have 25 "Protesters, is that to many should I cut it down and create smaller? I am just asking because it seems that when the "FiredNear" EH is triggered not all the AI respond, or is it just because the script isn't right yet. the other question is when creating a group do you have to create a unit to join the group ? Thanks again and hopefully will post some positive results tonight. Cheers Greg Share this post Link to post Share on other sites
AZCoder 921 Posted April 6, 2018 Performance will vary from pc to pc and I could see 25 EH's being a potential slowdown. Maybe you could assign the EH to just 3 or 4 of the protesters, the guys closest to the action, and when one is triggered then just apply the random reaction to the rest of the crowd. And make sure to remove the EH from all protesters once fired to avoid massive feedback loops. If you ever need to test script performance, in the debug console there's a timer icon somewhere, don't remember off the top of my head but it was easy to use. Also check out these links, KK posted a function you can directly call to test code http://killzonekid.com/arma-scripting-tutorials-code-performance/ and general code optimisation for SQF https://community.bistudio.com/wiki/Code_Optimisation Also if you create a group in script, you just join units to it. Share this post Link to post Share on other sites
swift39 1 Posted April 7, 2018 Again thanks to you all for your advice and input... I have been trying different ways of accomplishing this and I know its my knowledge of scripting, also reading forums I think I have managed to confuse myself a bit, so with that said I am going to take a break for a few hours, maybe a nap and attend my step grandsons ball game and hopefully re-approach this with a fresh look later this afternoon. So where I am at... Spoiler { // AI prevented to move or change behaviour. _x disableAI "PATH"; _x disableAI "MOVE"; _x stop true; _x setBehaviour "CARELESS"; //Disable Animation and Set AI direction to South. sleep 0.1; _x disableAI "ANIM"; _x setFormDir 180; _x setDir 180; //AI animation is selected randomly and started _animation = ["UnaErcVelitelProslov4", "c7a_bravo_dovadeni1", "shaftoe_c0briefing_otazky_loop6", "c7a_bravo_dovadeni3"] call BIS_fnc_selectRandom; _x switchMove _animation; The above spoiler works with all the Protesters facing south and performing a random animation. //AI animation is looped and randomly changed animLoop = _x addEventHandler ["AnimDone", { _x switchMove _animation }]; _x setVariable [ "animLoop", animLoop, true ]; Although I havent worked on this portion for awhile now, it will not loop or change animations. I intend to look at if "disableAI" is effecting the "AnimDone" EH or hopefully find out why this wont initiate. //Protest Chant [ProtesterA_1, ["fx_protest1", 30, 1]] remoteExec ["say3D", 0]; Works Great! and appears when the "FiredNear" EH is triggered and the AI change their state it stop automatically. //Determine which civilians are armed civGunChance = 0.5; //Odds Civilian will be armed civGuns = ["hgun_ACPC2_F","hgun_P07_F","hgun_P07_F","hgun_Rook40_F"]; if (random 1 < civGunChance) then { _gun = selectRandom civGuns; _mag = selectRandom (getArray (configFile >> "CfgWeapons" >> _gun >> "magazines")); _x addMagazine _mag; _x addItemToUniform _gun; }; Reading the post XianGrim created for his script, I liked the idea where this lead to. It makes sense from a "Realism" standpoint that the Protesters would be armed prior (Agitators) to the trigger and the randomness that you dont know how many armed civilians you are actally going to be faced with when the event actually happens. Also the handgun approach makes more sense than a RPG suddenly appearing on the AI's back. I hope and assume the script is right, although I have not seen the protester draw a handgun as of yet. _x addEventHandler ["FiredNear", { _civ = _this select 0; _civ enableAI "ALL"; _civ stop false; _civ switchMove ""; if ((handgunWeapon _civ) isEqualTo "") then { [_civ] joinSilent createGroup sideEnemy; _group allowFleeing 0; _group setSkill ["courage", 1]; _group reveal ["SoldierW", 3.75]; _group addRating -10000; _group setBehaviour "COMBAT"; _group setCombatMode "RED"; _group setFriend [west, 0]; _group setFriend [civilian, 0]; }; }]; This is where I am falling down and need to read and understand how the Event Handler process works, more importantly the procedure to make civilians become hostile and attack when triggered. I am not sure if this is the right approach, but seems to at least be a feasable approach, I think. Again thanks and comments welcome Cheers Greg Full script to date: Spoiler { // AI prevented to move or change behaviour. _x disableAI "PATH"; _x disableAI "MOVE"; _x stop true; _x setBehaviour "CARELESS"; //Disable Animation and Set AI direction to South. sleep 0.1; _x disableAI "ANIM"; _x setFormDir 180; _x setDir 180; //AI animation is selected randomly and started _animation = ["UnaErcVelitelProslov4", "c7a_bravo_dovadeni1", "shaftoe_c0briefing_otazky_loop6", "c7a_bravo_dovadeni3"] call BIS_fnc_selectRandom; _x switchMove _animation; //AI animation is looped and randomly changed animLoop = _x addEventHandler ["AnimDone", { _x switchMove _animation }]; _x setVariable [ "animLoop", animLoop, true ]; //Protest Chant [ProtesterA_1, ["fx_protest1", 30, 1]] remoteExec ["say3D", 0]; //Determine which civilians are armed civGunChance = 0.5; //Odds Civilian will be armed civGuns = ["hgun_ACPC2_F","hgun_P07_F","hgun_P07_F","hgun_Rook40_F"]; if (random 1 < civGunChance) then { _gun = selectRandom civGuns; _mag = selectRandom (getArray (configFile >> "CfgWeapons" >> _gun >> "magazines")); _x addMagazine _mag; _x addItemToUniform _gun; }; _x addEventHandler ["FiredNear", { _civ = _this select 0; _civ enableAI "ALL"; _civ stop false; _civ switchMove ""; if ((handgunWeapon _civ) isEqualTo "") then { [_civ] joinSilent createGroup sideEnemy; _group allowFleeing 0; _group setSkill ["courage", 1]; _group reveal ["SoldierW", 3.75]; _group addRating -10000; _group setBehaviour "COMBAT"; _group setCombatMode "RED"; _group setFriend [west, 0]; _group setFriend [civilian, 0]; }; }]; } forEach [ProtesterA_1, ProtesterA_2, ProtesterA_3, ProtesterA_4, ProtesterA_5, ProtesterA_6, ProtesterA_7, ProtesterA_8, ProtesterA_9, ProtesterA_10, ProtesterA_11, ProtesterA_12, ProtesterA_13, ProtesterA_14, ProtesterA_15, ProtesterA_16, ProtesterA_17, ProtesterA_18, ProtesterA_19, ProtesterA_20, ProtesterA_21, ProtesterA_22, ProtesterA_23, ProtesterA_24]; Share this post Link to post Share on other sites
swift39 1 Posted April 8, 2018 So I messed with this a bit more this evening and still no luck... My latest attempt will be to create a unit, which I am struggling a bit wrapping it around my head. _x addEventHandler ["FiredNear", { _civ = _this select 0; //Determine which civilians are armed _weapon = selectRandom ["hgun_ACPC2_F", "hgun_P07_F", "hgun_P07_F", "", "hgun_Rook40_F"]; _mag = selectRandom (getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines")); _civ addMagazine _mag; _civ addWeapon _weapon; //Release AI from Animation _civ enableAI "ALL"; _civ stop false; _civ switchMove ""; //Make Enemy and Set Combat Mode if ((handgunWeapon _civ) isEqualTo "") then { [_civ] joinSilent createGroup sideEnemy; _unit allowFleeing 0; _unit setSkill ["courage", 1]; _unit reveal ["SoldierW", 3.75]; _unit addRating -10000; _unit setBehaviour "COMBAT"; _unit setCombatMode "RED"; //_group setFriend [west, 0]; //_group setFriend [civilian, 0]; }; }]; I really don't know if I am over thinking this or putting to much emphasis on _civ, but tomorrow is another day. Comments and suggestions welcome Cheers Greg Share this post Link to post Share on other sites
AZCoder 921 Posted April 8, 2018 You have Apex? Sample mission here http://www.azcoder.com/arma3/protest.Tanoa.zip I'm using vanilla animations for test purposes only, the AI does switch around. Only 4 in the example so sometimes AI repeat them 2 or 3 times in a row. The more the better of course. I will also post the script here. I put a macro at the start, just makes it easier to call that function more than once. #define __RandomAnimation (["HubBriefing_lookAround1", "Acts_JetsOfficerSpilling", "acts_miller_knockout", "HubBriefing_pointAtTable"] call BIS_fnc_selectRandom); { _civ = _x; _civ setBehaviour "CARELESS"; //Disable Animination and Set AI direction to South. sleep 0.1; _dirToFace = [_civ,player] call BIS_fnc_dirTo; _civ disableAI "ANIM"; _civ setFormDir _dirToFace; _civ setDir _dirToFace; //AI animation is selected randomly and started _civ switchMove __RandomAnimation; //AI animation is looped and randomly changed _animLoop = _civ addEventHandler ["AnimDone", { _civ = _this select 0; _civ switchMove __RandomAnimation; }]; _civ setVariable [ "animLoop", _animLoop, true ]; // Combat Mode, Randomly selects weapons for Civilians _civ addEventHandler ["FiredNear", { _civ = _this select 0; _animLoop = _civ getVariable "animLoop"; _civ removeEventHandler ["AnimDone",_animLoop]; _civ enableAI "ALL"; _civ stop false; _civ setBehaviour "COMBAT"; _civ switchMove ""; _arm = [ "hgun_Rook40_F", "hgun_P07_F", "arifle_AKM_F", "launch_RPG7_F"] call BIS_fnc_selectRandom; [_civ, _arm, 8] call BIS_fnc_addWeapon; _civ setCombatMode "RED"; }]; } forEach [ProtesterA, ProtesterA_1, ProtesterA_2, ProtesterA_3, ProtesterA_4]; Share this post Link to post Share on other sites
swift39 1 Posted April 8, 2018 Thank you AZCoder... I was on my way to bed when it seemed we posted at the same time. The animation loop works and looks good. I have modified the script a bit and seems that I have one last hurdle to overcome, which tomorrow is a new day. the script now seems to work to this point. //Make Civilians Enemy if ((handgunWeapon _civ) isEqualTo true) then { [_civ] joinSilent createGroup sideEnemy; _civ addRating -10000; _civ allowFleeing 0; _civ setSkill ["courage", 1]; _civ reveal [player, 3.75]; _civ setBehaviour "COMBAT"; _civ setCombatMode "RED"; }; }]; I just started manipulating this, but am out of gas. The plan (now, after reading posts and gathering ideas) is to have any armed civilians become rogue and attack both Blufor and Civilians when the EH is triggered. The plan for the mission would be they players will have to eliminate the rogue mob while keeping civilian casualties to a minimum. throw in a couple suicide bombers and things could get interesting. Again thank you for the assistance and next time I am in Washington State I owe you a beer or six. The latest full version of the script #define __RandomAnimation (["UnaErcVelitelProslov4", "c7a_bravo_dovadeni1", "shaftoe_c0briefing_otazky_loop6", "c7a_bravo_dovadeni3"] call BIS_fnc_selectRandom); { _civ = _x; _civ setBehaviour "CARELESS"; // AI prevented to move or change behavior. _civ disableAI "PATH"; _civ disableAI "MOVE"; _civ stop true; //Disable Animation and Set AI direction to South. sleep 0.1; _dirToFace = [_civ, player] call BIS_fnc_dirTo; _civ disableAI "ANIM"; _civ setFormDir _dirToFace; _civ setDir _dirToFace; //AI animation is selected randomly and started _civ switchMove __RandomAnimation; //AI animation is looped and randomly changed _animLoop = _civ addEventHandler ["AnimDone", { _civ = _this select 0; _civ switchMove __RandomAnimation; }]; _civ setVariable [ "animLoop", _animLoop, true ]; //Protest Chant [ProtesterA_1, ["fx_protest1", 30, 1]] remoteExec ["say3D", 0]; // Combat Mode, Randomly selects weapons for Civilians _civ addEventHandler ["FiredNear", { _civ = _this select 0; //Stop animation _animLoop = _civ getVariable "animLoop"; _civ removeEventHandler ["AnimDone",_animLoop]; //Release AI from current state _civ enableAI "ALL"; _civ stop false; _civ switchMove ""; //Randomize and add weapons _weapon = selectRandom ["hgun_ACPC2_F", "", "hgun_P07_F", "hgun_P07_F", "", "hgun_Rook40_F"]; _mag = selectRandom (getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines")); _civ addMagazine _mag; _civ addWeapon _weapon; //Make Civilians Enemy if ((handgunWeapon _civ) isEqualTo true) then { [_civ] joinSilent createGroup sideEnemy; _civ addRating -10000; _civ allowFleeing 0; _civ setSkill ["courage", 1]; _civ reveal [player, 3.75]; _civ setBehaviour "COMBAT"; _civ setCombatMode "RED"; }; }]; } forEach [ProtesterA_1, ProtesterA_2, ProtesterA_3, ProtesterA_4, ProtesterA_5]; Cheers Greg Share this post Link to post Share on other sites
Grumpy Old Man 3546 Posted April 8, 2018 3 hours ago, swift39 said: Thank you AZCoder... I was on my way to bed when it seemed we posted at the same time. The animation loop works and looks good. I have modified the script a bit and seems that I have one last hurdle to overcome, which tomorrow is a new day. the script now seems to work to this point. //Make Civilians Enemy if ((handgunWeapon _civ) isEqualTo true) then { [_civ] joinSilent createGroup sideEnemy; _civ addRating -10000; _civ allowFleeing 0; _civ setSkill ["courage", 1]; _civ reveal [player, 3.75]; _civ setBehaviour "COMBAT"; _civ setCombatMode "RED"; }; }]; I just started manipulating this, but am out of gas. The plan (now, after reading posts and gathering ideas) is to have any armed civilians become rogue and attack both Blufor and Civilians when the EH is triggered. The plan for the mission would be they players will have to eliminate the rogue mob while keeping civilian casualties to a minimum. throw in a couple suicide bombers and things could get interesting. Again thank you for the assistance and next time I am in Washington State I owe you a beer or six. The latest full version of the script Cheers Greg Few things, sideEnemy will be hostile to everyone, even others from sideEnemy, civilian side will not get attacked by sideEnemy members. Units placed as civilians in the editor will have a different combat FSM running than east/west/independent units, they're more likely to flee and don't tend to fight very well. To handle multiple units that should do certain stuff on a randomized basis you can simply handle this with setVariable and flags. Making every predetermined unit possibly pull out a firearm and turn hostile towards blufor can be done like this: //unit init field: this setVariable ["GOM_fnc_potentialArmedProtester",true,true]; This enables you to dynamically place as many units as you want, without having to type out the typical forEach [Protester1,...,ProtesterN] humbug. Furthermore you can randomize the amount of actual armed aggressors depending on player count and other factors without having to do a single thing other than an initial setup in the appropriate .sqf file. First things first, you want those civs to give a proper fight, so simply place some opfor basic rifleman units on the map and put the above setVariable snippet into the init field of the first unit. Simply copy+paste the unit to add more, the init field will be automatically filled as well. Now we run into the problem that they're all geared, armed and will shoot everyone hostile to them on sight. The loadout can simply be changed using setUnitLoadout/getUnitLoadout. Basically two files are needed for something like this: //init.sqf in mission root: //inits the protesters sqf _init = [] execVM "scripts\GOM\GOM_fnc_armedProtesters.sqf";//this initializes all functions within the .sqf file waitUntil {scriptDone _init}; _initProtesters = [] spawn GOM_fnc_armedProtestersInit; _attack = [] spawn { sleep 30;//delay or condition for the attack to happen [10] spawn GOM_fnc_armedProtestersAttack;//starts the attack with amount of attackers as param, defaults to 5 if no number is given }; And another file named and placed in the appropriate folders "scripts\GOM\GOM_fnc_armedProtesters.sqf": //file: scripts\GOM\GOM_fnc_armedProtesters.sqf GOM_fnc_armedProtestersInit = { _potentialProtesters = allUnits select {_x getVariable ["GOM_fnc_potentialArmedProtester",false]}; //grab all usable civilian classes, needed to randomize loadout in the forEach loop _rndCivClasses = ("getNumber (_x >> 'side') isEqualTo 3 AND configName _x isKindOf 'Man' AND getNumber (_x >> 'scope') >= 2" configClasses (configFile >> "CfgVehicles")) apply {configName _x}; { //get direction of unit _dir = getDir _x; //join civilian group _oldGroup = group _x; _newGroup = createGroup civilian; [_x] joinSilent _newGroup; deleteGroup _oldGroup;//keep things tidy _x setBehaviour "SAFE"; //get and set random loadout _rndLoadout = getUnitLoadout selectRandom _rndCivClasses; _x setUnitLoadout _rndLoadout; _x switchMove "";//to skip weapon holster animation after weapon removal _x doWatch (_x getRelPos [50,_dir]);//reset watch direction after group change //dumb them down to stay put and allow random animations to be played _x disableAI "ALL"; //handle animation looping _anim = _x spawn { sleep random 5; while {alive _this AND behaviour _this == "SAFE"} do { _rndAnimation = selectRandom ["UnaErcVelitelProslov4", "c7a_bravo_dovadeni1", "shaftoe_c0briefing_otazky_loop6", "c7a_bravo_dovadeni3"]; if (alive _this) then {_this switchMove _rndAnimation;}; waitUntil {sleep 1;animationState _this != _rndAnimation OR behaviour _this != "SAFE" OR !alive _this}; if (!alive _this) exitWith {false}; } }; } forEach _potentialProtesters; //done, always return boolean true }; //improved BIS function by pedeathtrian NEW_fnc_arrayShuffle = { _this = []+_this; private _cnt = count _this; for "_i" from 1 to _cnt do { _this pushBack (_this deleteAt floor random (_cnt + 1 - _i)); }; _this }; GOM_fnc_armedProtestersAttack = { params [["_amount",5]]; _potentialProtesters = allUnits select {_x getVariable ["GOM_fnc_potentialArmedProtester",false]}; _armedProtesters = _potentialProtesters call NEW_fnc_arrayShuffle; _armedProtesters resize _amount; _potentialProtesters = _potentialProtesters - _armedProtesters; _pistols = "getnumber (_x >> 'type') isEqualTo 2 AND getnumber (_x >> 'scope') isEqualTo 2" configClasses (configfile >> 'CfgWeapons') apply {configName _x}; _potentialProtesters apply { _x enableAI "ALL"; _x setBehaviour "AWARE"; _x switchMove ""; }; _armedProtesters apply { _x setVariable ["GOM_fnc_armedProtester",true,true]; _x enableAI "ALL"; _x setBehaviour "AWARE"; _x switchMove ""; //arm them [_x,selectRandom _pistols,4] call BIS_fnc_addWeapon; [_x] joinSilent createGroup east; //help AI to detect hostiles after group switch _unit = _x; {_unit reveal [_x,4]} forEach (_unit nearEntities ["CAManBase",150]); //reveal the hostile protester to nearby AI {_x reveal [_unit,4]} forEach (_unit nearEntities ["CAManBase",150]); }; true; }; true; Simply check out this small demo mission using indeedPetes Arma 2 animations as sole mod on Malden 2035 to see how such a system could work. Cheers 3 1 Share this post Link to post Share on other sites
swift39 1 Posted April 8, 2018 Wow... Thank You that is exactly what I was looking for (in my mind), though I would of never of thought of it. The randomization of everything is nothing short of awesome. Your demo mission worked flawlessly, of course, when placed into my mission I am getting a Undefined variable in expression _x Quote _armedProtesters apply { _x setVariable ["GOM_fnc_armedProtester"...' Undefined variable in expression _x File C:..... line 88 Which has me a bit confused as I have not changed anything, but will sort it out. As this scenario is triggered by a player firing their weapon, would it be more efficient to have the addEventHandler in the init.sqf or the armedProtester,sqf? or create a trigger? Anyway, thanks you all and will post results as I sort them out. Cheers, Greg Share this post Link to post Share on other sites
swift39 1 Posted April 8, 2018 Again thanks and I think I have this working the way I envisioned it. With regards to the Undefined variable, I have no clue... Was trying some recommended fixes, got the point of where I was forgetting what was tried and changed, Restarted Arma with a fresh copy of the sqf. and it went away. Don't know what to think about that. To have the Protesters attack when fired near I put this in the init.sqf and it works //inits the protesters sqf _init = [] execVM "scripts\GOM\GOM_fnc_armedProtesters.sqf";//this initializes all functions within the .sqf file waitUntil {scriptDone _init}; _initProtesters = [] spawn GOM_fnc_armedProtestersInit; _attack = player addEventHandler ["FiredNear", {[10] spawn GOM_fnc_armedProtestersAttack; }]; changing GOM's From This _attack = [] spawn { sleep 60;//delay or condition for the attack to happen [10] spawn GOM_fnc_armedProtestersAttack;//starts the attack with amount of attackers as param, defaults to 5 if no number is given }; To This _attack = player addEventHandler ["FiredNear", {[10] spawn GOM_fnc_armedProtestersAttack; }]; It seems to work, but was wondering if there was a better or preferred method when it comes to initiating this or is this method going to create issues later. Thanks Greg Share this post Link to post Share on other sites
Grumpy Old Man 3546 Posted April 9, 2018 6 hours ago, swift39 said: Again thanks and I think I have this working the way I envisioned it. With regards to the Undefined variable, I have no clue... Was trying some recommended fixes, got the point of where I was forgetting what was tried and changed, Restarted Arma with a fresh copy of the sqf. and it went away. Don't know what to think about that. To have the Protesters attack when fired near I put this in the init.sqf and it works //inits the protesters sqf _init = [] execVM "scripts\GOM\GOM_fnc_armedProtesters.sqf";//this initializes all functions within the .sqf file waitUntil {scriptDone _init}; _initProtesters = [] spawn GOM_fnc_armedProtestersInit; _attack = player addEventHandler ["FiredNear", {[10] spawn GOM_fnc_armedProtestersAttack; }]; changing GOM's From This _attack = [] spawn { sleep 60;//delay or condition for the attack to happen [10] spawn GOM_fnc_armedProtestersAttack;//starts the attack with amount of attackers as param, defaults to 5 if no number is given }; To This _attack = player addEventHandler ["FiredNear", {[10] spawn GOM_fnc_armedProtestersAttack; }]; It seems to work, but was wondering if there was a better or preferred method when it comes to initiating this or is this method going to create issues later. Thanks Greg Your method will make the attack run everytime someone shoots next to the player, also when the player unit itself is firing. You can remove an eventhandler from inside the eventhandlers executed code pretty comfortably: _attack = player addEventHandler ["FiredNear", { [10] spawn GOM_fnc_armedProtestersAttack; player removeEventHandler ["FiredNear",_thisEventHandler]; }]; This will remove the eventhandler once the EH triggers, making the attack function run only once. Should work fine on SP. Cheers Share this post Link to post Share on other sites
swift39 1 Posted April 10, 2018 Thank You... I am away with work for a couple days so will switch it over when I get home. When you say it should work fine in SP is that a typo or do I need to script different for MP? Anyway thank you again everyone, I am enjoying the learning process and will post my results when I get home mid week. Cheers Greg Share this post Link to post Share on other sites