Jump to content

Recommended Posts

Hello, im newbie at scripting on Arma 3. I write a short script for searchlight. But for unknow for me reasons its crashes.

 

_searchlights = [searchlightTower1, searchlightTower2, searchlightTower3, searchlightTower4];   
_searchlightmans = [searchlightman1, searchlightman2, searchlightman3, searchlightman4];

{
    _searchlightman = _x;
    _searchlightman spawn {
	params ["_searchlightman", "_searchlights"];
        while {alive _searchlightman && alive _searchlights} do {  
        	if (!alive _searchlightman || !alive _searchlights) then {
			_searchlights select _forEachIndex setDamage 1;
			break;
		};
        };
            
    };

} forEach _searchlightmans;


What am i doing wrong? Can u help me pls.

Share this post


Link to post
Share on other sites

Hi, and welcome to the forum.
So there is a lot of things wrong with this code. Let's get through the code.

1)you're passing only _searchlightman variable to new scope (when you use spawn it creates new scope and all variables needs to be passed or redeclared)
2)_searchlights therefore aren't defined
3)while {alive _searchlightman && alive _searchlights} you're passing whole array of lights there, that should be only one object
4)If you'll use && code will never be run, because while condition exits when condition returns false, you need to change that for ||
5)if (!alive _searchlightman || !alive _searchlights) again you're passing whole array of lights there
6)There is no good reason to check the code if searchlight is dead, so you can simplify it to only check searchlight status in a while loop and searchlightman status in if condition
7)_forEachIndex is not defined here, it only exists in forEach loop
8)there is no sleep at the end of the loop which can cause whole game to freeze. While loop is iterated multiple times per frame if there is no sleep inside. Here is good explanation.

If I'd followed same logic you wrote it, fixed code should look like this. 
 

Spoiler

_searchlights = [searchlightTower1, searchlightTower2];    
_searchlightmans = [searchlightman1, searchlightman2]; 
 
{ 
    _searchlightman = _x; 
    _searchLight = _searchlights select _forEachIndex; [_searchlightman,_searchLight] spawn { 
 params ["_searchlightman", "_searchLight"]; 
        while {alive _searchLight} do {   
         if (!alive _searchlightman) then { 
   _searchLight setDamage 1; 
   break; 
  }; 
sleep 1;
        }; 
             
    }; 
 
} forEach _searchlightmans;

 

However I don't really recomment this. If you'll create too many searchlightman units, you might see it on game performance because scheduler will be cluttered with these codes. I suggest to use killed eventhandler for this. It's much easier to use for this situation and also code is called only when searchlightman dies. That means you can have as many units as you want and scheduler is not cluttered.
This code should be run only on the server in case it's for multiplayer mission. Either put the code below in initServer.sqf or add condition if(isServer) then {//paste the code here};

Spoiler

_searchlights = [searchlightTower1, searchlightTower2];    
_searchlightmans = [searchlightman1, searchlightman2]; 

{
    _searchlightman = _x; 
    _searchLight = _searchlights select _forEachIndex;
	_searchlightman setVariable ["linkedLight",_searchLight];
	_searchlightman addEventHandler ["Killed", {
	params ["_unit"];
	private _light = _unit getVariable ["linkedLight",objNull];
	_light setDamage 1;
}];
} forEach _searchlightmans;

 

 

  • Like 1
  • Thanks 2

Share this post


Link to post
Share on other sites
4 minutes ago, soldierXXXX said:

Hi, and welcome to the forum.
So there is a lot of things wrong with this code. Let's get through the code.

1)you're passing only _searchlightman variable to new scope (when you use spawn it creates new scope and all variables needs to be passed or redeclared)
2)_searchlights therefore aren't defined
3)while {alive _searchlightman && alive _searchlights} you're passing whole array of lights there, that should be only one object
4)If you'll use && code will never be run, because while condition exits when condition returns false, you need to change that for ||
5)if (!alive _searchlightman || !alive _searchlights) again you're passing whole array of lights there
6)There is no good reason to check the code if searchlight is dead, so you can simplify it to only check searchlight status in a while loop and searchlightman status in if condition
7)_forEachIndex is not defined here, it only exists in forEach loop
8)there is no sleep at the end of the loop which can cause whole game to freeze. While loop is iterated multiple times per frame if there is no sleep inside. Here is good explanation.

If I'd followed same logic you wrote it, fixed code should look like this. 
 

  Reveal hidden contents


_searchlights = [searchlightTower1, searchlightTower2];    
_searchlightmans = [searchlightman1, searchlightman2]; 
 
{ 
    _searchlightman = _x; 
    _searchLight = _searchlights select _forEachIndex; [_searchlightman,_searchLight] spawn { 
 params ["_searchlightman", "_searchLight"]; 
        while {alive _searchLight} do {   
         if (!alive _searchlightman) then { 
   _searchLight setDamage 1; 
   break; 
  }; 
sleep 1;
        }; 
             
    }; 
 
} forEach _searchlightmans;

 

However I don't really recomment this. If you'll create too many searchlightman units, you might see it on game performance because scheduler will be cluttered with these codes. I suggest to use killed eventhandler for this. It's much easier to use for this situation and also code is called only when searchlightman dies. That means you can have as many units as you want and scheduler is not cluttered.
This code should be run only on the server in case it's for multiplayer mission. Either put the code below in initServer.sqf or add condition if(isServer) then {//paste the code here};

  Reveal hidden contents


_searchlights = [searchlightTower1, searchlightTower2];    
_searchlightmans = [searchlightman1, searchlightman2]; 

{
    _searchlightman = _x; 
    _searchLight = _searchlights select _forEachIndex;
	_searchlightman setVariable ["linkedLight",_searchLight];
	_searchlightman addEventHandler ["Killed", {
	params ["_unit"];
	private _light = _unit getVariable ["linkedLight",objNull];
	_light setDamage 1;
}];
} forEach _searchlightmans;

 

 


thanks, i get it😊. still hard, but tnx.

Share this post


Link to post
Share on other sites

if each searchlight has a man (_searchlightman) operating it, and if you want to destroy the searchlight when this operator is killed:

 

{_x addEventHandler ["killed", {vehicle (_this #0) setDamage 1}] } forEach [searchlightman1, searchlightman2];

 

you can even code the reverse behavior, i.e. kill the operator when light is bent (little bit more tricky, depending on your mod). Example, for a CUP searchlight:

you can write in init field of such searchlight (turret, not gunner):
 

this addEventHandler ["handleDamage", {params ["_sl", "_selection", "_damage"]; if (_damage > 0.5 && "light" in _selection) then { gunner _sl setDamage 1; _damage = 1};_damage}];

Should work also with other mods/DLCs...

  • Like 2

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×