Jump to content
🛡️FORUMS ARE IN READ-ONLY MODE Read more... ×
M1ke_SK

Trigger activation on distance of player

Recommended Posts

When I create marker on map it will spawn enemy on random position on marker when player approach marker. I added configurate distance in script.

 

Problem is, that my trigger condition is not working. Enemy is created no matter what distance I am from marker.

 

 

enemy.sqf

/*


AUTHOR: MikeSK 701st [S.O.G.]
NAME: enemy.sqf
VERSION: 0.5


DESCRIPTION:
Spawn enemy on marker when player approach.


USAGE:
Add this line to mission init:
//_handle = [markerName, classNameArray, numberOfUnits, group, showMarker, spawnDistance, respawn, timeInMinute];
Example:
//["marker1", ["O_Soldier_F","O_G_Soldier_F"], 5, east, 1, 200, false, 15] execVM "enemy.sqf";


CONFIG:
markerName: STRING - name of marker
classNameArray: ARRAY - an array of classnames of the units to spawn
numberOfUnits: SCALAR - amount of units to spawn
group: SIDE - a group will be created for the side you specify (east, west, ...)
showMarker: SCALAR - set if marker is shown on map (0 - no, 1 - yes)
spawnDistance: SCALAR - define meters from marker when units will spawn
respawn: BOOLEAN - enable / disable inifinite respawn of units
timeInMinute: SCALAR - time in minutes that units will respawn again


*/


private ["_marker", "_classArray", "_amount", "_group", "_showMarker", "_distance"];


_marker = _this select 0;
_classArray = _this select 1;
_amount = _this select 2;
_group = _this select 3;
_showMarker = _this select 4;
_distance = _this select 5;
_respawn = _this select 6;
_respawnTime = _this select 7;


_markerPos = getMarkerPos _marker;
_marker setMarkerAlpha _showMarker; 
_markerSize = getMarkerSize _marker;
_markerSizeX = _markerSize select 0;
_markerSizeY = _markerSize select 1;
_markerSize = (_markerSizeX + _markerSizeY)/2;
_markerAgl = markerDir _marker;
_markerRange = (_markerSize)/2;


_actCond="{vehicle _x in thisList && isPlayer _x} count playableUnits > 0";


_tr = createTrigger ["EmptyDetector", _markerPos];
_tr setTriggerArea [(_distance+_markerSizeX),(_distance+_markerSizeY),_markerAgl,false]; 
_tr setTriggerActivation ["ANY","PRESENT",true];
_tr setTriggerTimeout [1, 1, 1, true];
_tr setTriggerStatements [_actCond,"",""];


_trigger = [_tr, 0, "EXIT", [objNull]] call BIS_fnc_param;


_createUnits =
{


private ["_trigger", "_classArray", "_amount", "_group", "_respawnTime", "_pos", "_patrol", "_obj", "_classname"];


_trigger = _this select 0;
_classArray = _this select 1;
_amount = _this select 2;
_group = _this select 3;
_respawnTime = _this select 4;


_pos = [_trigger] call BIS_fnc_randomPosTrigger;
for "_i" from 1 to _amount do
{
_classname = _classArray select (floor random (count _classArray));
if (_classname isKindOf "man") then
{
_obj = _group createUnit [_classname, _pos, [], 0, "FORM"];
}else
{
_pos = [_trigger] call BIS_fnc_randomPosTrigger;
[_pos, random 360, _classname, _group] call BIS_fnc_spawnVehicle;
};
};
_patrol = [_trigger, _group] spawn
{
_trigger = _this select 0;
_group = _this select 1;
while {{alive _x} count units _group > 0} do
{
_group move ([_trigger] call BIS_fnc_randomPosTrigger);
waitUntil {(moveToCompleted leader _group) || (moveToFailed leader _group)};
};
};
waitUntil {{alive _x} count units _group == 0};
terminate _patrol;
sleep (_respawnTime * 60);
};


if !(_trigger isEqualTo "EXIT") then
{
if (typeOf _trigger != "EmptyDetector") exitWith {};


_classArray = [_this, 2, ["O_Soldier_F"], [[]]] call BIS_fnc_param;
_amount = [_this, 2, 1, [0]] call BIS_fnc_param;
_group = createGroup ([_this, 3, east, [east]] call BIS_fnc_param);
_respawn = [_this, 6, false, [false]] call BIS_fnc_param;
_respawnTime = [_this, 7, 1, [0]] call BIS_fnc_param;


if (!_respawn) then
{
[_trigger, _classArray, _amount, _group, _respawnTime] call _createUnits;
};


while {_respawn} do
{
[_trigger, _classArray, _amount, _group, _respawnTime] call _createUnits;
};
};

Share this post


Link to post
Share on other sites
_actCond="{vehicle _x in thisList && isPlayer _x} count playableUnits > 0";

This line can be reduced to:

_actCond="{vehicle _x in thisList} count allPlayers > 0";
_tr setTriggerArea [(_distance+_markerSizeX),(_distance+_markerSizeY),_markerAgl,false];

Is your marker anything but a circle? If so, this line is ok. If your marker is a circle though, there's no need for an angle here.

_tr setTriggerTimeout [1, 1, 1, true];

Do you really want the execution of the (de)activation statement to be delayed by 1 second? If you omit this line, the execution will be immediately when the condition is met.

_trigger = [_tr, 0, "EXIT", [objNull]] call BIS_fnc_param;

This line doesn't make sense, because _tr (a trigger) is an object and you can't use "select" on an object. (What should this line do anyways?) This line leaves the trigger untouched.

Share this post


Link to post
Share on other sites

So if I get it right, your trigger actually serves no purpose as it is right now, because it's only got a condition, but no (de)activation statements and they are nowhere to be set except for that one line in your script:

_tr setTriggerStatements [_actCond,"",""];

The way I see it, your script is working very hard to call the _createUnits function as often and quickly as possible (last "while" loop), because _respawn never changes, hence it's always as it is when invoking "enemy.sqf". Please correct me if I got something wrong.

Share this post


Link to post
Share on other sites

_actCond  won't work as it's a local variable, also I still don't think it would work as it would need to be formated and called.

actCond =   format ["{ vehicle _x in thisList} count allplayers > 0"];
_tr setTriggerStatements [call compile actCond,"",""];

so in the end you may aswell just do it in trigger

_tr setTriggerStatements ["{ vehicle _x in thisList} count allplayers > 0","",""];

Share this post


Link to post
Share on other sites

@f2k that's not true, how he had it is fine. _actcond is a local variable representing a string which is passed to the setTriggerStatements command locally.

 

I haven't gone over all of this, but it looks like the problem is basically that you're not using the trigger (as Here's Johnny said).

 

@mikesk: I haven't tested this or anything, but I think this is closer to what you're trying to do:

//this function needs to be referenced by a public variable so it can be called later when the script is activated.
//it'd be better to declare this elsewhere (maybe init.sqf) so it's not redefined for every trigger.
mikesk_fnc_createUnits =
{
private ["_trigger", "_classArray", "_amount", "_group", "_respawnTime", "_pos", "_patrol", "_obj", "_classname"];
params ["_triggerName", "_classArray", "_amount", "_group", "_respawnTime"];
_trigger = missionNamespace getVariable _triggerName;
_pos = [_trigger] call BIS_fnc_randomPosTrigger;
for "_i" from 1 to _amount do
{
_classname = _classArray select (floor random (count _classArray));
if (_classname isKindOf "man") then
{
_obj = _group createUnit [_classname, _pos, [], 0, "FORM"];
}else
{
_pos = [_trigger] call BIS_fnc_randomPosTrigger;
[_pos, random 360, _classname, _group] call BIS_fnc_spawnVehicle;
};
};
_patrol = [_trigger, _group] spawn
{
_trigger = _this select 0;
_group = _this select 1;
while {{alive _x} count units _group > 0} do
{
_group move ([_trigger] call BIS_fnc_randomPosTrigger);
waitUntil {(moveToCompleted leader _group) || (moveToFailed leader _group)};
};
};
waitUntil {{alive _x} count units _group == 0};
terminate _patrol;
sleep (_respawnTime * 60);
};
 
 
private ["_marker", "_classArray", "_amount", "_group", "_showMarker", "_distance"];
params ["_marker", "_classArray", "_amount", "_group", "_showMarker", "_distance", "_respawn", "_respawnTime"];
 
_markerPos = getMarkerPos _marker;
_marker setMarkerAlpha _showMarker; 
_markerSize = getMarkerSize _marker;
_markerSize params ["_markerSizeX", "_markerSizeY"];
_markerSize = (_markerSizeX + _markerSizeY)/2;
_markerAgl = markerDir _marker;
_markerRange = (_markerSize)/2;
 
 
_actCond="{vehicle _x in thisList && isPlayer _x} count playableUnits > 0";
 
 
_tr = createTrigger ["EmptyDetector", _markerPos];
 
//because you need to refer to the trigger in another script (the activation script), set it as a public variable (mikesk_triggers_markername).
_triggerName = format["mikesk_triggers_%1", _markerName];
missionNamespace setVariable[_triggerName, _tr];
 
//create the statement string. will end up something like:
// ["mikesk_triggers_markername", ["b_soldier_f"], 10, EAST, 5] spawn mikesk_fnc_createUnits
// (note: no private variables)
_actStatement = format["[%1, %2, %3, %4, %5, %6] spawn mikesk_fnc_createUnits", _triggerName, _classArray, _amount, _group, _respawnTime];
_tr setTriggerArea [(_distance+_markerSizeX),(_distance+_markerSizeY),_markerAgl,false]; 
_tr setTriggerActivation ["ANY","PRESENT",true];
_tr setTriggerTimeout [1, 1, 1, true];
_tr setTriggerStatements [_actCond,_actStatement, ""];
 
//I'm not clear what this part is.
/*
_trigger = [_tr, 0, "EXIT", [objNull]] call BIS_fnc_param;
 
if !(_trigger isEqualTo "EXIT") then
{
if (typeOf _trigger != "EmptyDetector") exitWith {};
 
 
_classArray = [_this, 2, ["O_Soldier_F"], [[]]] call BIS_fnc_param;
_amount = [_this, 2, 1, [0]] call BIS_fnc_param;
_group = createGroup ([_this, 3, east, [east]] call BIS_fnc_param);
_respawn = [_this, 6, false, [false]] call BIS_fnc_param;
_respawnTime = [_this, 7, 1, [0]] call BIS_fnc_param;
 
 
if (!_respawn) then
{
[_trigger, _classArray, _amount, _group, _respawnTime] call _createUnits;
};
 
 
while {_respawn} do
{
[_trigger, _classArray, _amount, _group, _respawnTime] call _createUnits;
};
};
*/

Share this post


Link to post
Share on other sites
//create the statement string. will end up something like:
// ["mikesk_triggers_markername", ["b_soldier_f"], 10, EAST, 5] spawn mikesk_fnc_createUnits
// (note: no private variables)
_actStatement = format["[%1, %2, %3, %4, %5, %6] spawn mikesk_fnc_createUnits", _triggerName, _classArray, _amount, _group, _respawnTime];

 

Stringifying a group does not return its side (e.g. "EAST") but rather something like "B Alpha 1-1". You can get the side with side _group though.

But this format won't work as you can't stringify a group and pass it to a function like that. The best solution I found so far is to find the group in allGroups and format the respective index into a string where the group is selected from allGroups, like so:

_actStatement = format["[%1, %2, %3, allGroups select %4, %5] spawn mikesk_fnc_createUnits", _triggerName, _classArray, _amount, allGroups find _group, _respawnTime];

Share this post


Link to post
Share on other sites

Yes I realized my mistake as soon as I'd gone to bed and thought about it, I guess I shouldn't post at 3am sorry.

Share this post


Link to post
Share on other sites
The best solution I found so far is to find the group in allGroups and format the respective index into a string where the group is selected from allGroups

 

Having said that I don't know what happens when allGroups changes. Assumingly, the index of the previously created group changes, hence this is probably not the best solution for code that is not executed immediately. Probably, rather setVariable the group to the trigger (if it's only one group per trigger) and getVariable it onAct again.

Share this post


Link to post
Share on other sites

heere's johnny: oh ok, I was assuming _group was a side (it says EAST or WEST in the description).

Share this post


Link to post
Share on other sites

×