OFPEC Forum
Editors Depot - Mission Editing and Scripting => Arma2 - Editing/Scripting General => Topic started by: Bingoz on 25 Feb 2011, 20:48:41
-
I am trying to understand the best way of passing EH data to scripts.
A question first, what is the better way of detecting if shots are fired at a specific unit?
I was trying something like this.
wepFired = this AddEventHandler ["Fired", {this exec "Fired.sqf"}];
Fired.sqf ( Fictional at the moment )
UnitDat = _this;
_Unit = UnitDat select 0;
_Weap = UnitDat select 1;
_WAmo = UnitDat select 3;
// ----------------------------------------------------------------- Get Position of Shooter ---------
_UnitPos = Position _Unit;
_UnitPosx = _UnitPos select 0;
_UnitPosy = _UnitPos select 1;
// ----------------------------------------------------------------- Get Shooters Target, Shooters Range, and Skill -------------
_UnitTar = GetTarget _Unit;
_UnitRng = ( _Unit GetDistance _UnitTar );
_UnitSkl = GetSkill _Unit;
// ----------------------------------------------------------------- Determine if under fire ------------------------------
if (_UnitTar == Gn1) then { isUndFir = True } Else { isUndFir = False};
Hint str _WAmo;
I am trying to gain the following data,
The shooters Target
The shooters rang from its target
The shooters Skill
The shooters weapon
At the moment I am using a “wepFired = this AddEventGandler ["Fired}; {this exec "Fired.sqf"}];” in the shooters Init box right now, but I would like to have it in a trigger, so that any enemy that are in the trigger zone will be assigned that event handler so when they fire this data is gained.
I will also be placing a pause in there so that not every shot is registered after the first.
-
Hi!
A much, much easier way of doing this would be to simply use the FiredNear (http://community.bistudio.com/wiki/ArmA_2:_Event_Handlers#FiredNear) eventhandler on the target instead. That way no-one but the one you need would have to have an eventhandler attached, and...yeah. Note that it runs whenever the unit fires as well, so be sure to exit the script if _unit == _unit :)
An example script would be something like:
g1 addeventhandler ["FiredNear", {_this execvm "underfire.sqf"}];
_unit = _this select 0;
_firer = _this select 1;
if (_unit == _firer) exitWith {};
_dist = _this select 2;
_weapon = _this select 3;
The eventhandler gives you everything you need by itself. :) Good luck!
Wolfrug out.
-
_unit = _this select 0;
_firer = _this select 1;
if (_unit == _firer) exitWith {};
Roger that, I was trying something like that, and I am noticing that Even thought I am using a ExitWith {}; that the code that follows is still ran, any way of killing the script at that point?
-
exitWith shouldn't be used to exit scripts. Take the other way and use a normal if.
-
exitWith shouldn't be used to exit scripts
Out of curiosity, why?
Has always worked for me... :dunno:
-
In this case I added that exitWith because apparently this eventhandler is run even when the unit itself is doing the shooting: this basically just checks if the unit == the firer and if so -> quit.
The only reason exitWith wouldn't work here is because you're running the code inside a scope, rather than in the main scope. Let me explain:
// this is your main scope
_stuff = _this select 0;
for "_i" from 0 to 5 do
{
//this is a secondary scope
if (_i == 4) exitWith {};
};
//the above exitwith only exited out of the secondary scope and back to the main one, NOT the whole script, thus the below code still runs
hint str (_stuff);
// exit from main scope
if (true) exitwith {hint "Weee!"};
// this code is never run
hint "Booo!";
Get it? So make sure you're not messing up with the scopes, and the exitwith should work just fine. :)
Wolfrug out.
-
@h-
When you use exitWith not inside a loops, the behaviour is undefined - sometimes it may exit the script, sometimes some other scope, but this is not intended and designed behaviour of this command, and it is not guaranteed to work reliably.
It exits the loop only, not the script.
Written by Suma
-
okay all of this is correct, as in fact ExitWith in any scope other than the main scope is useless if you are trying to kill the script all to gather.
So the real question would be, HOW can one Exit a script no matter what scope it is in, or alternatively is there a way to us something like a GOTO,?
Example of the old Gotos I am use to.
If a = A then Goto "Spaming!"
end if
"Spaming!"
Runs code here, bypassing code after the if, IF a = a, Else it runs the code following the if.
-
If a != A then
... code after the if
end if
"Spaming!"
Runs code here, bypassing code after the if, IF a = a, Else it runs the code following the if.
-
Written by Suma
Well, despite that I have never ever experienced any problems exiting scripts using exitWith..
EDIT:
Oh, and recently discovered another "sqs-esque" way of exiting sqf scripts; using breakTo with a non-existent scope (as in not set with scopeName), like breakTo "blah". Terminates the whole script, not just the scope it's "run" in.
private["_i"];
_i = 0;
while {true} do {
player sideChat "runs";
sleep 1;
_i = _i + 1;
if (_i>= 3) then {breakTo "blah"};
};
hintC "exited";The hintC won't show.
Discovered this in ArmA (by accident), seems to work at least in Arma2 1.08/OA 1.57..
-
private["_i"];
_i = 0;
while {true} do {
player sideChat "runs";
sleep 1;
_i = _i + 1;
if (_i>= 3) then {breakTo "blah"};
};
hintC "exited";
Yes your on the same path I am, I was just looking at the Breakto. I will give it a try and let ya know if it worked as needed.
Thanks guys I truly appreciate your efforts of answering this questions.
-
Thanks for everyone, this thread explains many of the mysterious problems with exiting scripts in ArmA 2.
I'm gonna fix up all those errors in my scripts.
But I have a little confusion with what Suma said.
When you use exitWith not inside a loops, the behaviour is undefined - sometimes it may exit the script, sometimes some other scope, but this is not intended and designed behaviour of this command, and it is not guaranteed to work reliably.
Does this mean that exitWith is not reliable to exit scripts? Does it mean it only works SOMETIMES?
Sorry, I'm too dumb to understand the experts' conversation. :(
Regards,
Haroon1992
-
Fundamentally it means that the behaviour is undefined - as in, it could change at any time, be affected by an update to the lexer/parser, or anything like that. In the most straightforward way possible: BIS didn't 'intend' it to function like that... so it could change easily, and without notice, in the future :)
That doesn't mean it doesn't work now it just means that it's not guaranteed to remain that way. And, there could be circumstances under which it doesn't work already.
-
Fundamentally it means that the behaviour is undefined
???
From http://www.arma2.com/comref/comref.html
if exitWith code
Operand types:
if: If Type
code: Code
Compatibility:
Version 2 required.
Type of returned value:
Any
Description:
if result of condition is true, evaluates code, and __current block__ with result of code
Example:
if (_x>5) exitWith {echo "_x is too big";_x} , result is [when _x is greater then 5, outputs message and terminates code in current level with value of _xI emphasized "current block". This command terminates the current block.
for example:
_searchedValue = ({
if (_k == _x select 0) exitwith { _x select 1 };
_defaultValue;
} foreach [[key1, value1], [key2, value2], ... ])
-
Interesting - I was merely referencing Suma's comment about it being undefined when used outside of a loop... but then your reference would seem to counter that, anyway. I wonder what the 'official' line is, these days (in truth, I'd probably suggest the ComRef is the more accurate reference). :dunno:
-
Interesting - I was merely referencing Suma's comment about it being undefined when used outside of a loop... but then your reference would seem to counter that, anyway.
Oh, sorry :confused:
but nevertheless:
_var = _k call {
if (_this == 1) exitwith { "a" };
if (_this == 2) exitwith { "b" };
if (_this == 3) exitwith { "c" };
"d" // default value
}