militarypolice 10 Posted July 20, 2021 Hello! I have 2 questions. One is a request of the sorts and another is help with a function. 1. I would like to create a script that will keep a popup target up until 2 hits are achieved. I know it would require "Hit" event handlers. But I do not know how to work with Event Handlers yet. I've done it once before, but was a long while ago. Any direction on that, would be great. I'm sure I can figure it out, I just need some help with a foundation! 2. I'm using BIS_animateMoveSmooth to create a smooth movement of popup targets. In single player it works just fine and is smooth. But, in multiplayer it does not work at all, well the animation doesn't play. I click the button to move a target closer and it's like it plays the animation on the server, but not to the clients. Once it seems like the animation is done on the server it then teleports the target to the right place for everyone, including the person who selected the button. I wonder if I need to execute it via a remoteexec? Below is the block of code I am using: call{this addAction ["Move 0m", "[l3t, [l330m, l30m]] spawn BIS_animateMoveSmooth;"]; this addAction ["Move 35m", "[l3t, [l330m, l320m]] spawn BIS_animateMoveSmooth;"]; this addAction ["Move 30m", "[l3t, [l30m, l330m]] spawn BIS_animateMoveSmooth;"];} Name of the target is "l3t" and it then moves to a rail that is named "l330m" or "l320m" etc. Any help on this would be greatly appreciated as well! Share this post Link to post Share on other sites
militarypolice 10 Posted July 21, 2021 Any help would be greatly appreciated! I found some scripts throughout Google, but I assume something has changed in the backend as those scripts do not work anymore... I am kinda desperate as I've been reading and reading and testing and testing and am just failing lol... I've been looking for something that can accomplish multiple hits on a popup target for a very long time! A tutorial on how to create Hit MPEventHandlers or something would help too! I'm totally not trying to have someone do this for me. I would much rather learn, I just need to be pointed in the right direction! Thanks! Share this post Link to post Share on other sites
sarogahtyp 1109 Posted July 21, 2021 No need to use MP event handler. The Hit event handler executed where popups are local (most likely on server) should be enough. The problem is to suppress the engine animation for popping up again, but I m on it... Share this post Link to post Share on other sites
sarogahtyp 1109 Posted July 21, 2021 (edited) This is tested in init field of popup in SP only and working. Its a long thing and maybe there is a shorter solution. Should work in MP as well but not testet it there: if !(local this) exitWith {}; this addEventHandler ["Hit", { private _hit_num = 10; private _down_time = 5; params ["_unit"]; private _phase = _unit animationPhase "Terc"; if ( _phase isNotEqualTo 0 ) exitWith { }; private ["_dummy"]; private _hit_already = _unit getVariable ["saro_hit_num", 0]; if ( _hit_already < _hit_num - 1) exitWith { _unit setVariable ["saro_hit_num", (_hit_already + 1) ]; _dummy = _unit spawn { sleep diag_deltaTime; _this animateSource ["Terc", 0]; }; }; _dummy = [_unit, _down_time] spawn { params [ "_unit", "_down_time" ]; private ["_phase"]; private _down_start = 0; sleep diag_deltaTime; waitUntil { _phase = _unit animationPhase "Terc"; if ( _phase isEqualTo 1 && _down_start isEqualTo 0 ) then { _down_start = diag_tickTime }; _unit animateSource ["Terc", 1]; _down_start > 0 and (diag_tickTime - _down_start) > _down_time }; _unit animateSource ["Terc", 0]; _unit setVariable ["saro_hit_num", 0]; }; }]; you are able to adjust needed number of hits with variable _hit_num and the time the target is down with _down_time Edited July 21, 2021 by sarogahtyp minor changes 2 Share this post Link to post Share on other sites
militarypolice 10 Posted July 21, 2021 11 hours ago, sarogahtyp said: This is tested in init field of popup in SP only and working. Its a long thing and maybe there is a shorter solution. Should work in MP as well but not testet it there: if !(local this) exitWith {}; this addEventHandler ["Hit", { private _hit_num = 10; private _down_time = 5; params ["_unit"]; private _phase = _unit animationPhase "Terc"; if ( _phase isNotEqualTo 0 ) exitWith { }; private ["_dummy"]; private _hit_already = _unit getVariable ["saro_hit_num", 0]; if ( _hit_already < _hit_num - 1) exitWith { _unit setVariable ["saro_hit_num", (_hit_already + 1) ]; _dummy = _unit spawn { sleep diag_deltaTime; _this animateSource ["Terc", 0]; }; }; _dummy = [_unit, _down_time] spawn { params [ "_unit", "_down_time" ]; private ["_phase"]; private _down_start = 0; sleep diag_deltaTime; waitUntil { _phase = _unit animationPhase "Terc"; if ( _phase isEqualTo 1 && _down_start isEqualTo 0 ) then { _down_start = diag_tickTime }; _unit animateSource ["Terc", 1]; _down_start > 0 and (diag_tickTime - _down_start) > _down_time }; _unit animateSource ["Terc", 0]; _unit setVariable ["saro_hit_num", 0]; }; }]; you are able to adjust needed number of hits with variable _hit_num and the time the target is down with _down_time So this did work! Thank you very much for your time and interest!! But, I'm seeing that if I want to create a shooting drill program, for targets to popup, it loses the hit event handler when they popup again. So I have a program to select random targets and pop them up. The init.sqf file has nopop = true; within it. I removed: _dummy = [_unit, _down_time] spawn { params [ "_unit", "_down_time" ]; private ["_phase"]; private _down_start = 0; sleep diag_deltaTime; waitUntil { _phase = _unit animationPhase "Terc"; if ( _phase isEqualTo 1 && _down_start isEqualTo 0 ) then { _down_start = diag_tickTime }; _unit animateSource ["Terc", 1]; _down_start > 0 and (diag_tickTime - _down_start) > _down_time }; _unit animateSource ["Terc", 0]; _unit setVariable ["saro_hit_num", 0]; }; }]; from your script as it seemed to be popping up the target regardless of having nopop=true; within the init.sqf. The script I created for the shooting drill is this: sleep 1; _target = selectRandom [t1,t2,t3,t4,t5,t6,t7]; _target animate["terc", 0]; _target = selectRandom [t1,t2,t3,t4,t5,t6,t7]; _target animate["terc", 0]; sleep 4; execVM "alldown.sqf"; (alldown.sqf just pops all targets down) That just runs when someone selects it from a computer via addaction. Add and take away when you want more then one target to popup. So, before running the program, multiple hits work and the targets do not go down unless the 2 hits are achieved. But once I run the program, it goes back to one hit. Any ideas? Share this post Link to post Share on other sites
militarypolice 10 Posted July 21, 2021 Okay, so I did some playing around! I removed: _unit animateSource ["Terc", 0]; from the script and now the program works and when they pop back up and it takes 2 shots to put the target back down!! So, the only thing now, is to make something where the it can be executed via spawn or execVM with a oneliner as I will likely have hundreds of popup targets that will use this in my Training Map! That will make administration easy and will cut down on the SQM size! Share this post Link to post Share on other sites
militarypolice 10 Posted July 21, 2021 Okay! I've gotten it figured out! I tried spawn, execVM and call and compile file routes. I do admit, I'm not 100% understanding of the variables. I'm a PowerSheller and understand variables and scoping very well. But, when it comes to arma, I guess I second guess myself.. But, what I've done, is created a foreach loop in the init file with your script: _types = ["TargetP_Inf4_F","Land_TargetEpopup"]; for [{_i=0},{_i < (count _types)},{_i=_i+1}] do { _targets = getMarkerPos "target" nearObjects [_types select _i, 500]; if (count _targets < 1) exitWith { systemChat "No Enemy were found."; //exit if no targets have been found }; {if (isServer) then { _x addEventHandler ["Hit", { private _hit_num = 2; private _down_time = 0.1; params ["_unit"]; private _phase = _unit animationPhase "Terc"; if ( _phase isNotEqualTo 0 ) exitWith { }; private ["_dummy"]; private _hit_already = _unit getVariable ["saro_hit_num", 0]; if ( _hit_already < _hit_num - 1) exitWith { _unit setVariable ["saro_hit_num", (_hit_already + 1) ]; _dummy = _unit spawn { sleep diag_deltaTime; _this animateSource ["Terc", 0]; }; }; _dummy = [_unit, _down_time] spawn { params [ "_unit", "_down_time" ]; private ["_phase"]; private _down_start = 0; sleep diag_deltaTime; waitUntil { _phase = _unit animationPhase "Terc"; if ( _phase isEqualTo 1 && _down_start isEqualTo 0 ) then { _down_start = diag_tickTime }; _unit animateSource ["Terc", 1]; _down_start > 0 and (diag_tickTime - _down_start) > _down_time }; _unit setVariable ["saro_hit_num", 0]; }; }];};} forEach _targets; }; this way, I can control which targets are need to be hit multiple times and which ones do not. This route also doesnt touch the SQM file size either! Let me know if you approve of this method? or if there is a better method? Share this post Link to post Share on other sites
militarypolice 10 Posted July 22, 2021 Okay, so everything works in SP and Hosted Multiplayer. But it doesn't work with Dedicated Servers. Do you know how I could fix that? This is how I am getting it to all of the Pop-up targets that need it: _types = ["TargetP_Inf4_F"]; for [{_i=0},{_i < (count _types)},{_i=_i+1}] do { _targets = getMarkerPos "target" nearObjects [_types select _i, 15000]; if (count _targets < 1) exitWith { systemChat "No Targets were found."; //exit if no targets have been found }; {if !(local _x) exitWith {}; _x addEventHandler ["Hit", { private _hit_num = 2; private _down_time = 0.1; params ["_unit"]; private _phase = _unit animationPhase "Terc"; if ( _phase isNotEqualTo 0 ) exitWith { }; private ["_dummy"]; private _hit_already = _unit getVariable ["saro_hit_num", 0]; if ( _hit_already < _hit_num - 1) exitWith { _unit setVariable ["saro_hit_num", (_hit_already + 1) ]; _dummy = _unit spawn { sleep diag_deltaTime; _this animateSource ["Terc", 0]; }; }; _dummy = [_unit, _down_time] spawn { params [ "_unit", "_down_time" ]; private ["_phase"]; private _down_start = 0; sleep diag_deltaTime; waitUntil { _phase = _unit animationPhase "Terc"; if ( _phase isEqualTo 1 && _down_start isEqualTo 0 ) then { _down_start = diag_tickTime }; _unit animateSource ["Terc", 1]; _down_start > 0 and (diag_tickTime - _down_start) > _down_time }; _unit setVariable ["saro_hit_num", 0]; }; }];} forEach _targets; }; This is placed in the init.sqf file. Any ideas? Share this post Link to post Share on other sites
sarogahtyp 1109 Posted July 22, 2021 (edited) I did not fully understand what you want to do exactly but I guess you need to enable/disable the EH behaviour related on actions taken by clients. The important thing is to execute the event handler where the popups are local. This should be on server. If you need other behaviour then the event handler provides then you have to remove the EH from those targets. Therefore you should apply the EH everytime you need the behaviour and remove it after that. If a client decides on which popups the EH should get applied then you have to remoteExec the EH on the server. This can be done by first creating a sqf file with the EH. You could name it apply_EH.sqf apply_EH.sqf params ["_popup"]; //apply EH private _eh_index = _popup addEventHandler ["Hit", { private _hit_num = 10; private _down_time = 5; params ["_unit"]; private _phase = _unit animationPhase "Terc"; if ( _phase isNotEqualTo 0 ) exitWith { }; private ["_dummy"]; private _hit_already = _unit getVariable ["saro_hit_num", 0]; if ( _hit_already < _hit_num - 1) exitWith { _unit setVariable ["saro_hit_num", (_hit_already + 1) ]; _dummy = _unit spawn { sleep diag_deltaTime; _this animateSource ["Terc", 0]; }; }; _dummy = [_unit, _down_time] spawn { params [ "_unit", "_down_time" ]; private ["_phase"]; private _down_start = 0; sleep diag_deltaTime; waitUntil { _phase = _unit animationPhase "Terc"; if ( _phase isEqualTo 1 && _down_start isEqualTo 0 ) then { _down_start = diag_tickTime }; _unit animateSource ["Terc", 1]; _down_start > 0 and (diag_tickTime - _down_start) > _down_time }; _unit animateSource ["Terc", 0]; _unit setVariable ["saro_hit_num", 0]; }; }]; //store the EH index on popup to be able to remove the EH later _popup setVariable ["saro_eh_index", _eh_index]; for one specific popup (I call it _one_popup here) chosen by a client to get the EH behaviour on it you can do now: [_one_popup, "apply_EH.sqf"] remoteExec ["execVM", 2]; next thing you need a sqf file to remove that behaviour. remove_EH.sqf params [_popup]; //get the prior stored Index of the EH private _eh_index = _popup getVariable "saro_eh_index"; // no index found, just leave if (isNil "_eh_index") exitWith {}; //remove the EH _popup removeEventHandler ["Hit", _eh_index]; //destroy the index variable on popup _popup setVariable ["saro_eh_index", nil]; After that on the time a client decides to not need the EH behaviour anymore you can just do [_one_popup, "remove_EH.sqf"] remoteExec ["execVM", 2]; not tested but should work... Edited July 22, 2021 by sarogahtyp finished post Share this post Link to post Share on other sites
militarypolice 10 Posted July 22, 2021 Okay, the code for the hits works! But it still doesnt work in Dedicated Servers. I tried with just "2" and I tried with "[0, -2] select isDedicated,true". With "[0, -2] select isDedicated,true" the target would start to pop down and then half way through come back up for the second hit and once the second hit it would stay down. Also, it was very hit or miss, like it wouldnt do it for all targets. Just randomly some. But with just "2" it would not work at all. This is the code I am using to put the remoteexec on every target needed (This is ran in the init.sqf file): _types = ["TargetP_Inf4_F"]; for [{_i=0},{_i < (count _types)},{_i=_i+1}] do { _targets = getMarkerPos "target" nearObjects [_types select _i, 30000]; if (count _targets < 1) exitWith { systemChat "No Enemy were found."; //exit if no targets have been found }; {[_x, "scripts\apply_EH.sqf"] remoteExec ["execVM", [0, -2] select isDedicated,true];} forEach _targets; }; I think we are getting closer! Share this post Link to post Share on other sites
sarogahtyp 1109 Posted July 22, 2021 Try the object _x instead of 2 Share this post Link to post Share on other sites
militarypolice 10 Posted July 22, 2021 I will try that! Quick question, so the Event handler doesn't stick if the "Enable Damage Button" in specials properties is checked. I was running through a program in single player and over time, the popup target was destroyed because of how many rounds was being used. I have a bunch of people who will be using these popup targets. To combat this, what we've done, is to just have Simulation on and have Damage off for popup targets. Is there a way to get the script to run while damage is off? I will try the _x option right now and let you know!! Also, seriously, thank you for your help! this is awesome! Share this post Link to post Share on other sites
militarypolice 10 Posted July 22, 2021 So, I tried it with _x: _types = ["TargetP_Inf4_F"]; for [{_i=0},{_i < (count _types)},{_i=_i+1}] do { _targets = getMarkerPos "target" nearObjects [_types select _i, 30000]; if (count _targets < 1) exitWith { systemChat "No Enemy were found."; //exit if no targets have been found }; {[_x, "scripts\apply_EH.sqf"] remoteExec ["execVM", _x];} forEach _targets; }; and it did not work and went back to as if it was "2". Share this post Link to post Share on other sites
sarogahtyp 1109 Posted July 23, 2021 do you have any remote execution restrictions in your description.ext as described here? https://community.bistudio.com/wiki/Arma_3:_CfgRemoteExec Share this post Link to post Share on other sites
militarypolice 10 Posted July 23, 2021 I did not. But I just added the first block of code on that page. Ill test it in a second and let you know! Share this post Link to post Share on other sites
militarypolice 10 Posted July 23, 2021 If you'd like to take a look at the mission file: http://www.575th.com/public/(U)_S3_Missions_PopUp_Target_Test.VR.rar Also, in the remoteexec call, using [0,-2] works the best. It goes half way down, but then comes back up waiting for the second shot. But in single player, it doesnt go down until after the 2nd shot. Do you think this is a MP issue? Share this post Link to post Share on other sites
sarogahtyp 1109 Posted July 24, 2021 12 hours ago, militarypolice said: If you'd like to take a look at the mission file: http://www.575th.com/public/(U)_S3_Missions_PopUp_Target_Test.VR.rar the file is damaged, I cant open it ... Share this post Link to post Share on other sites
wogz187 1086 Posted July 26, 2021 @sarogahtyp My favorite line from the script above, _down_start > 0 and (diag_tickTime - _down_start) > _down_time now that's how you return bool like a pro! Thanks, man! 2 1 Share this post Link to post Share on other sites
Smart Games 76 Posted July 26, 2021 I helped him and I think we already fixed the problem. At least it looks like he has no more questions. Share this post Link to post Share on other sites
militarypolice 10 Posted July 27, 2021 Sorry about that! Its been a long week... But, thank you all for your help! For now this is fine and working! I've learned a lot and will try to implement things I've learned and continue to learn in the future! Share this post Link to post Share on other sites
Smart Games 76 Posted July 27, 2021 If anyone is interested, here is the main part of the solution: [] call JF_fnc_Options; player addEventHandler ["Fired", { params ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_gunner"]; private _cTarget = cursorTarget; private _types = missionNamespace getVariable "types"; if ((typeOf _cTarget) in _types) then { deleteVehicle _projectile; private _hit_already = _cTarget getVariable "saro_hit_num"; private _phase = _cTarget animationSourcePhase "terc"; if ( _hit_already < (HIT_NUM - 1)) then { _cTarget setVariable ["saro_hit_num", (_hit_already + 1), true]; } else { _cTarget animateSource ["terc", 1.5]; _cTarget setVariable ["saro_hit_num", 0, true]; }; hint parseText format ["<t color='#FFFFFF'>The Target <t color='#23D9C1'> %1 <t color='#FFFFFF'> has been hit <t color='#23D9C1'> %2 <t color='#FFFFFF'> times. </t>", _cTarget, _hit_already+1]; }; } ]; And here's the mission folder: https://ufile.io/4dt0g2ke Share this post Link to post Share on other sites