Jump to content
  • 0

Freeze Units, while Player is not near


Guest

Question

Hi,

 

i want to prevent AI from using waypoints 'n stuff, due to Performance reasons. So i came up with this:

 

private ["_unitGroup","_cache","_counter","_i","_unit"]

_unitGroup = _this select 0;
_cache = _this select 1;

fnc_freeze {
	
	if (_cache) then {
		diag_log format ["Freezing %1 Units",(count _unitGroup)];
		_i = 0;
		{
			_unit = _unitGroup select _i;
			_unit disableAI "TARGET";
			_unit disableAI "AUTOTARGET";
			_unit disableAI "MOVE";
			_unit disableAI "ANIM";
			_unit disableAI "FSM";
			_i = _i + 1;
		} foreach _unitGroup;
	} else {
		diag_log format ["UnFreezing %1 Units",(count _unitGroup)];
		_i = 0;
		{
			_unit = _unitGroup select _i;
			_unit enableAI "TARGET";
			_unit enableAI "AUTOTARGET";
			_unit enableAI "MOVE";
			_unit enableAI "ANIM";
			_unit enableAI "FSM";
			_i = _i + 1;
		} foreach _unitGroup;
	};
};


while {true} do {
	_counter = _unitGroup nearEntities ["CAManBase",1250];
	if (_counter != 0) then {[] spawn fnc_freeze;};
	sleep 15;
};

Apparently there's something wrong with the counter. I can't see, what?

Link to comment
Share on other sites

22 answers to this question

Recommended Posts

  • 0

Hi,

 

i want to prevent AI from using waypoints 'n stuff, due to Performance reasons. So i came up with this:

spoiler'd

private ["_unitGroup","_cache","_counter","_i","_unit"]

_unitGroup = _this select 0;
_cache = _this select 1;

fnc_freeze {
	
	if (_cache) then {
		diag_log format ["Freezing %1 Units",(count _unitGroup)];
		_i = 0;
		{
			_unit = _unitGroup select _i;
			_unit disableAI "TARGET";
			_unit disableAI "AUTOTARGET";
			_unit disableAI "MOVE";
			_unit disableAI "ANIM";
			_unit disableAI "FSM";
			_i = _i + 1;
		} foreach _unitGroup;
	} else {
		diag_log format ["UnFreezing %1 Units",(count _unitGroup)];
		_i = 0;
		{
			_unit = _unitGroup select _i;
			_unit enableAI "TARGET";
			_unit enableAI "AUTOTARGET";
			_unit enableAI "MOVE";
			_unit enableAI "ANIM";
			_unit enableAI "FSM";
			_i = _i + 1;
		} foreach _unitGroup;
	};
};


while {true} do {
	_counter = _unitGroup nearEntities ["CAManBase",1250];
	if (_counter != 0) then {[] spawn fnc_freeze;};
	sleep 15;
};

Apparently there's something wrong with the counter. I can't see, what?

y u no read documentation? :P

your _counter is being created via BIS function nearEntities; it is of array type as per returnValue section in documentation => https://community.bistudio.com/wiki/nearEntities

if no matching objects found it will be an empty array. it will look like this =>  [];

if matching objects are found, then it will be an array of 1 or more. it will look like this (I think) => [R Alpha 1-3:1 REMOTE,1];

 

In either case your check in the next line is not going to work.

in the next line, you are using "if the value is not zero" how can an array (a list) be or not be a zero, I think what you mean is is "if the size of the array is '1 or more', then do blah". which we can write as: var >=1

 

Therefore you need something like this:

private ["_matchingObjectsArray","_sizeOfMatchingObjectsArrayNumber"];

while {true} do {
	_matchingObjectsArray = _unitGroup nearEntities ["CAManBase",1250];
	_sizeOfMatchingObjectsArrayNumber = (count matchingObjectsArray);
	if (_sizeOfMatchingObjectsArrayNumber >= 1) then {[] spawn fnc_freeze;};
	sleep 15;
};

good luck! once you got it working, please take a moment to come back and document for the next guy...

Link to comment
Share on other sites

  • 0

Thanks a lot. Meanwhile i've noticed, that the whole Function is pretty much useless. It's meant to un-freeze the Units from the Group, but i only just noticed, that it does not know which Unit Group to un-freeze. Any Ideas?

 

I thought about maybe getting all Groups and check, via getVar, if the Units are freezed or not. Should be possible, since a Group is concidered to be a Object, but i don't know on how to get all groups..

 

//EDIT: If i get all Groups, then again i don't want to un-freeze all groups, just that one group the player is near to..

Link to comment
Share on other sites

  • 0

Thanks a lot. Meanwhile i've noticed, that the whole Function is pretty much useless. It's meant to un-freeze the Units from the Group, but i only just noticed, that it does not know which Unit Group to un-freeze. Any Ideas?

 

I thought about maybe getting all Groups and check, via getVar, if the Units are freezed or not. Should be possible, since a Group is concidered to be a Object, but i don't know on how to get all groups..

 

//EDIT: If i get all Groups, then again i don't want to un-freeze all groups, just that one group the player is near to..

Let's see..

So you have (say) 10 Groups; at run time you don't know what group(s) are in what state so you can't pre-determine their fate. Your code, at runtime will decide (let's say) group 1,2 and 8 to be frozen.

 

15 seconds later... during the next iteration, you want to check whether to unfreeze or not. You will have to do another vicinity check.

If there are 0 (EpochMan or EpochWoman(?)) around unit to be (re-)frozen (and/or just left in frozen state).

If there are more than 0 EpochMan/Woman around, unit to be unfrozen.

 

Is the above correct? if so, I would do something like this

  • at the AIGroup creation code, you mark them as 'aigroup' (using SetVariable) so you can get a list any time you want.
  • then you traverse the list using forEach and for each item, do the following:

    1. get all EpochMan/Woman near this group and save to '_nearByArray'

       

    2. _sizeOfNearByMatchingObjects = (count _nearByArray);

       

    3. if (_sizeOfNearByMatchingObjects == 0) && (!(_x _inFrozenState)) then {[_x] Freeze; };          <== _x (in a forEach loop, means the current object I am working on) read more on BIKI if you want to see a working example // not in frozen state thus we freeze this particular unit now

       

    4. if (_sizeOfNearByMatchingObjects >= 1) && (_x _inFrozenState) then {[_x] unfreeze; };         <== shouldn't be frozen as there are EpochMan/Woman nearby

       

I was experimenting with this last night and briefly tonight, it appears, one need to add uiSleep/sleep 0.05 to ensure the commands properly get processed, otherwise, say 3rd/4th command (disable move) may not work.

about the intentional brief delay, you can see a tested example code

 

also I read somewhere (I think it was on BIKI) that if you disable A CERTAIN ai feature, and then re-enable it, it might not 'activate' as you would expect.

in other words, you disable it but you may not be able to re-enable it in a reasonable amount of time [or ever until the restart].

so proceed with caution if you are to push this code to a busy server. take your time in testing, possibly with artificially generated CPU load on your test server to simulate high pop stress & behavior otherwise it might perform excellent in your tests and can totally tank in your production server.

 

 

 

one other thing, you probably don't want spawn there. use call instead so script goes there does the work and comes back and carries one from within a SINGLE thread.

spawn not that good as it may not actually spawn anytime soon. it may stay behind and with too many threads your FPS will sink and so on,.in case of unexpected behaviour, at least with call damage will be contained.

Link to comment
Share on other sites

  • 0

I thought about something more easy.. Since this is being ran multiple times anyway, i'll pass the UnitCroup from the file that creates the Group. That way, the file is called individually for each Group, which actually happens anyway.. So meanwhile it looks like this (ignore the unnecessary privatizing):

 

private ["_unitGroup","_cache","_matchingObjectsArray","_numberOfMatchingObjectsNumber"];

_unitGroup = _this select 0;
_cache = _this select 1;
[_unitGroup] spawn fnc_freeze;

fnc_freeze = {
	private ["_unitGroup"];
	_unitGroup = _this select 0;
	
	diag_log("Freezing Units");
	
	{
		_this disableAI "TARGET";
		_this disableAI "AUTOTARGET";
		_this disableAI "MOVE";
		_this disableAI "ANIM";
		_this disableAI "FSM";
	} foreach units _unitGroup;
};

fnc_unfreeze = {
	private ["_unitGroup"];
	_unitGroup = _this select 0;
	
	diag_log("Un Freezing Units");
	
	{
		_this enableAI "TARGET";
		_this enableAI "AUTOTARGET";
		_this enableAI "MOVE";
		_this enableAI "ANIM";
		_this enableAI "FSM";
	} foreach units _unitGroup;
};

while {true} do {
	_matchingObjectsArray = _unitGroup nearEntities ["CAManBase",1250];
	_numberOfMatchingObjectsNumber = (count _matchingObjectsArray);
	if (_numberOfMatchingObjectsNumber >= 1) then {[_unitGroup] spawn fnc_unfreeze;};
	sleep 15;
};

Now in the Logs i see this:

 

2:06:58 Error in expression <he = _this select 1;
[_unitGroup] spawn fnc_freeze;

fnc_freeze = {
private ["_u>
2:06:58 Error position: <fnc_freeze;

fnc_freeze = {
private ["_u>
2:06:58 Error Undefined variable in expression: fnc_freeze
2:06:58 File z\addons\dayz_server\WAI\compile\cache_units.sqf, line 5
2:06:59 "WAI: Spawned a group of 4 AI (Hero) at [12414.9,8504.16,0]"
2:06:59 Error in expression <do {
_matchingObjectsArray = _unitGroup nearEntities ["CAManBase",1250];
_number>
2:06:59 Error position: <nearEntities ["CAManBase",1250];
_number>
2:06:59 Error nearentities: Type Group, expected Array,Object
2:06:59 File z\addons\dayz_server\WAI\compile\cache_units.sqf, line 38
2:06:59 "Freezing Units"
2:06:59 Error in expression <;

diag_log("Freezing Units");

{
_this disableAI "TARGET";
_this disableAI "AUT>
2:06:59 Error position: <disableAI "TARGET";
_this disableAI "AUT>
2:06:59 Error disableai: Type Array, expected Object
2:06:59 File z\addons\dayz_server\WAI\compile\cache_units.sqf, line 14

Now you can't get nearEntities of a Group, ok i can solve that, by simply selecting a Unit of that Group, but i don't get what's wrong with the forEach Loop.

Link to comment
Share on other sites

  • 0

I thought about something more easy.. Since this is being ran multiple times anyway, i'll pass the UnitCroup from the file that creates the Group. That way, the file is called individually for each Group, which actually happens anyway.. So meanwhile it looks like this (ignore the unnecessary privatizing):

 

spoiler'd!

private ["_unitGroup","_cache","_matchingObjectsArray","_numberOfMatchingObjectsNumber"];

_unitGroup = _this select 0;
_cache = _this select 1;
[_unitGroup] spawn fnc_freeze;

fnc_freeze = {
	private ["_unitGroup"];
	_unitGroup = _this select 0;
	
	diag_log("Freezing Units");
	
	{
		_this disableAI "TARGET";
		_this disableAI "AUTOTARGET";
		_this disableAI "MOVE";
		_this disableAI "ANIM";
		_this disableAI "FSM";
	} foreach units _unitGroup;
};

fnc_unfreeze = {
	private ["_unitGroup"];
	_unitGroup = _this select 0;
	
	diag_log("Un Freezing Units");
	
	{
		_this enableAI "TARGET";
		_this enableAI "AUTOTARGET";
		_this enableAI "MOVE";
		_this enableAI "ANIM";
		_this enableAI "FSM";
	} foreach units _unitGroup;
};

while {true} do {
	_matchingObjectsArray = _unitGroup nearEntities ["CAManBase",1250];
	_numberOfMatchingObjectsNumber = (count _matchingObjectsArray);
	if (_numberOfMatchingObjectsNumber >= 1) then {[_unitGroup] spawn fnc_unfreeze;};
	sleep 15;
};

Now in the Logs i see this:

 

2:06:58 Error in expression <he = _this select 1;
[_unitGroup] spawn fnc_freeze;

fnc_freeze = {
private ["_u>
2:06:58 Error position: <fnc_freeze;

fnc_freeze = {
private ["_u>
2:06:58 Error Undefined variable in expression: fnc_freeze
2:06:58 File z\addons\dayz_server\WAI\compile\cache_units.sqf, line 5
2:06:59 "WAI: Spawned a group of 4 AI (Hero) at [12414.9,8504.16,0]"
2:06:59 Error in expression <do {
_matchingObjectsArray = _unitGroup nearEntities ["CAManBase",1250];
_number>
2:06:59 Error position: <nearEntities ["CAManBase",1250];
_number>
2:06:59 Error nearentities: Type Group, expected Array,Object
2:06:59 File z\addons\dayz_server\WAI\compile\cache_units.sqf, line 38
2:06:59 "Freezing Units"
2:06:59 Error in expression <;

diag_log("Freezing Units");

{
_this disableAI "TARGET";
_this disableAI "AUT>
2:06:59 Error position: <disableAI "TARGET";
_this disableAI "AUT>
2:06:59 Error disableai: Type Array, expected Object
2:06:59 File z\addons\dayz_server\WAI\compile\cache_units.sqf, line 14

spoiler'd!

Now you can't get nearEntities of a Group, ok i can solve that, by simply selecting a Unit of that Group, but i don't get what's wrong with the forEach Loop.

simpler is better, I like it.

I don't like 15 threads running (I'd prefer ONE thread running) but your script, your way. (also at this small scale it won't matter much, it's just about the habit for me).

 

anyway, on to business...

 

first of all, ignoring the blank lines, counting actual code, on line 4 you're calling a freeze  function which poor arma has no clue about => 2:06:58 Error Undefined variable in expression: fnc_freeze

move the function to the space AFTER local var declarations and BEFORE actual "main code". so when main code runs, its local vars and everything in order. sweet.

 

item #2 in list is, the foreach you have does have issues indeed. basically once you do the checks and stuff in the end you are issuing a command to an object [a unit].

that unit is not _this as your cade thinks it is.

it is actually _x the magic variable which you can read about here => https://community.bistudio.com/wiki/forEach

 

it might be better to just copy & paste a working example then keep changing...

 

 

 

 

as it happens I was writing one last night. below is the foreach code I have, you might want to adapt it to your use.

in there you will also see getVariable and setVariable [on the object] which you will eventually need to start using.

{
	if ((alive _x) && (_x getVariable "isclickNGoTaxi") && ((_x	getVariable ["vehiclePayNowMenuStatus",0]) == 0)) then {
		_myGUSUIDNumber = (_x		getVariable "GUSUIDNumber");
		_null = [_x,	_myGUSUIDNumber] spawn mgmTfA_fnc_client_doProcessclickNGoTaxiAddActionWork;
		_x 	setVariable ["vehiclePayNowMenuStatus", 1, false];
		_getInEvent 	= _x addEventHandler ["GetIn",   {_this spawn mgmTfA_fnc_client_clickNGoTaxiDisplayInstructions}];
		_discoveredNewclickNGoTaxiVehiclesArray pushBack _x;
	};
} forEach _nearestclickNGoTaxiSameClassVehiclesArray;

I assume with the above information, your current problem will be resolved. to make your life easier, one thing you might want to get familiar with is reading the arma error messages, initially it looks cryptic but in time you start understanding Arma's errors better.

 

it is basically clearly saying two things above:

1. Undefined variable fnc_freeze [so go & define it]

2. nearentities Type is Group but I was expecting Array or Object? [so use _x which will point to the CURRENT object, in the array which might have more than one such objects]

 

one other thing that might help is using more feedback from the engine. I did google for hours when I just started writing my first from-scratch script about 1.5 months ago.

long story cut short, I should have done this from day 1 to minimize pain:

diag_log format ["[mgmTfA] [mgmTfA_fnc_client_doProcessclickNGoTaxiAddActionWork.sqf]  [D3] 		DEVDEBUG		I have been SPAWN'd.	This is what I have received:	(%1).", (str _this)];//dbg

Stick that line above to top of any function/sqf and you will 'see' what that particular (complaining) function/sqf 'sees'.

sometimes just the above simple line clearly shows what is wrong. (such as: soldier=any, telling you that soldier variable has not been passed properly)

 

one other tip I have for you to reduce troubleshooting time is batch file, which I updated after 45 days (wish I did it on day0 as it reduces rebuild and relaunch to a single click).

 

anyway hope the above helps.

Link to comment
Share on other sites

  • 0

Thanks a lot, for all this help and research. The while loop wanted a check, whetever the found CAManBase is a player or not, but i managed that. The distance wants tweaking and for whatever reason only 2 out of 3 Groups were frozen, but at least that worked and so did the re-activation.

This saves me a lot of resources, because AI won't be doing silly things anymore, like occupiing memory for just running around hehe.

I got a FPS Increase of 10 Frames which is amazing. Thought it would be like 2 or 3 Frames only. I'll look into it further on why i didn't froze ths last group and the script want's to be cleaned up, but first it's bed time :D

So yeah thanks a lot for all that research and help and all those affords.

Link to comment
Share on other sites

  • 0

How about...

_globalGroups = allGroups;

{
	_groupLeader = leader _x;
	if !(isplayer _groupLeader) then {
		_groupLeaderArray set [(count _groupLeaderArray), [_x, _groupLeader];
	}; // create array of AI groups with their leader.
} count _globalGroups;

// Now you have an array of AI groups and their leaders.

{
	_playerNearby = false;
	_groupLeader = _x select 1;
	_AIState = _x getvariable ["Frozen",false];
	_nearbyPlayers = _groupLeader nearEntities ["CAManBase",1250]; 
	}
	        if (isplayer _x) exitwith {_playerNearby = true};
	} count _nearbyPlayers; // Check if near units are players.
	
	if (_playerNearby) then{
		if !(_AIState) then {[_x select 0] call fnc_freeze};  // No player close so freeze or unfreeze
        }else{
        	if (_AIState) then {[_x select 0] call fnc_unFreeze};  // Player close so unfreeze
        };
} count _groupLeaderArray;

A few notes

  • The fnc_freeze / fnc_unfreeze functions need to be added.
  • You will need to add setvariable ["Frozen",true or false]; depending on the freeze or unfreeze in the fnc_freeze / fnc_unFreeze functions.
  • Wrap it up in a loop (while (true) do {} ;) with a uisleep to set how often it would run and spawn it on server start (server_monitor.sqf or init.sqf should work).
  • I would also add a bit of randomness in to their location when unfreezing or it will look like they were frozen having never moved from their last spotted location.
  • Whilst the AI are presumed to be local to the server, if you are running something like a headless client you would need to setup Public Variables to kick off the freeze / unfreeze scripts off on the AI Owner client machine.

What the code 'should' do (not tested so probably has a few typos / bugs).

  • Collect a list of groups on the server.
  • Get the leader of each group
  • Check to see if the leader is a player and add the group and leader details to an array if not a player.
  • Check each leader to see if any players are within range.
  • Players in range then check if frozen and if not then unfreeze.
  • Players not in range the check frozen and if not then freeze.
Link to comment
Share on other sites

  • 0

Thank you very much for all that help and suggestions. The "un-cleaned" version atm looks like so:

 

private ["_unitGroup","_cache","_matchingObjectsArray","_numberOfMatchingObjectsNumber","_playerCount"];

_unitGroup = _this select 0;
[_unitGroup] spawn fnc_freeze;

fnc_freeze = {
	private ["_unitGroup"];
	_unitGroup = _this select 0;
	
	diag_log("Freezing Units");
	
	{
		_x disableAI "TARGET";
		_x disableAI "AUTOTARGET";
		_x disableAI "MOVE";
		_x disableAI "ANIM";
		_x disableAI "FSM";
	} foreach units _unitGroup;
};

fnc_unfreeze = {
	private ["_unitGroup"];
	_unitGroup = _this select 0;
	
	diag_log("Un Freezing Units");
	
	{
		_x enableAI "TARGET";
		_x enableAI "AUTOTARGET";
		_x enableAI "MOVE";
		_x enableAI "ANIM";
		_x enableAI "FSM";
	} foreach units _unitGroup;
};

while {true} do {
	_matchingObjectsArray = ((units _unitGroup) select 0) nearEntities ["CAManBase",1250];
	_numberOfMatchingObjectsNumber = (count _matchingObjectsArray);
	if (_numberOfMatchingObjectsNumber >= 1) then {
		{
			if (isPlayer _x) then {
				[_unitGroup] spawn fnc_unfreeze;
			};
		} foreach _matchingObjectsArray;
	};
	sleep 15;
};


What i will want to do is remove the unnecessary privatize, of _unitGroup, also add a check for the speed of the Player and the vehicle he's using.. (Is he just in a car driving by?) -- Ofc like MGM said, i will want to move the Functions call under the functions itself. The distance i'll set to 800, that's enough distance for a Mission i guess. And yeah maybe add a call to freeze the Units again, when player left..

Link to comment
Share on other sites

  • 0

Thank you very much for all that help and suggestions. The "un-cleaned" version atm looks like so:

 

spoiler'd

private ["_unitGroup","_cache","_matchingObjectsArray","_numberOfMatchingObjectsNumber","_playerCount"];

_unitGroup = _this select 0;
[_unitGroup] spawn fnc_freeze;

fnc_freeze = {
	private ["_unitGroup"];
	_unitGroup = _this select 0;
	
	diag_log("Freezing Units");
	
	{
		_x disableAI "TARGET";
		_x disableAI "AUTOTARGET";
		_x disableAI "MOVE";
		_x disableAI "ANIM";
		_x disableAI "FSM";
	} foreach units _unitGroup;
};

fnc_unfreeze = {
	private ["_unitGroup"];
	_unitGroup = _this select 0;
	
	diag_log("Un Freezing Units");
	
	{
		_x enableAI "TARGET";
		_x enableAI "AUTOTARGET";
		_x enableAI "MOVE";
		_x enableAI "ANIM";
		_x enableAI "FSM";
	} foreach units _unitGroup;
};

while {true} do {
	_matchingObjectsArray = ((units _unitGroup) select 0) nearEntities ["CAManBase",1250];
	_numberOfMatchingObjectsNumber = (count _matchingObjectsArray);
	if (_numberOfMatchingObjectsNumber >= 1) then {
		{
			if (isPlayer _x) then {
				[_unitGroup] spawn fnc_unfreeze;
			};
		} foreach _matchingObjectsArray;
	};
	sleep 15;
};

spoiler'd

What i will want to do is remove the unnecessary privatize, of _unitGroup, also add a check for the speed of the Player and the vehicle he's using.. (Is he just in a car driving by?) -- Ofc like MGM said, i will want to move the Functions call under the functions itself. The distance i'll set to 800, that's enough distance for a Mission i guess. And yeah maybe add a call to freeze the Units again, when player left..

it's not a major optimization really, leave the private alone! :)

what you might want to do is add uiSleep (say 0.05)  between these:

_x disableAI "TARGET";

_x disableAI "AUTOTARGET";

otherwise in some cases it may not work.

 

depends on system load, better to be safe than sorry...

Link to comment
Share on other sites

  • 0

Thanks. At the Moment i'm scared about the following: This script is meant to reduce server last, but would getting a variable every 15 seconds when a player is not near actually defeat that purpose? How much resources would that take to get the var over an over again and how can i do it better?

This is how it looks:

/**
Please take my Special Thanks, 
- RimBlock ( http://epochmod.com/forum/index.php?/user/12612-rimblock/ ) 
- MGM ( http://epochmod.com/forum/index.php?/user/16852-mgm/ )
**/
private ["_unitGroup","_state","_stateFroze","_timeFroze","_matchingObjectsArray","_numberOfMatchingObjectsNumber","_playerCount"];

_unitGroup = _this select 0;

fnc_freeze = {
	private ["_unitGroup"];
	_unitGroup = _this select 0;
	
	diag_log("Freezing Units");
	
	{
		_x disableAI "TARGET";
		sleep 0.5;
		_x disableAI "AUTOTARGET";
		sleep 0.5;
		_x disableAI "MOVE";
		sleep 0.5;
		_x disableAI "ANIM";
		sleep 0.5;
		_x disableAI "FSM";
		sleep 0.5;
	} foreach units _unitGroup;
	
	_unitGroup setVariable["FrozenState",[time,true],true];
};

fnc_unfreeze = {
	private ["_unitGroup"];
	_unitGroup = _this select 0;
	
	diag_log("Un Freezing Units");
	
	{
		_x enableAI "TARGET";
		sleep 0.5;
		_x enableAI "AUTOTARGET";
		sleep 0.5;
		_x enableAI "MOVE";
		sleep 0.5;
		_x enableAI "ANIM";
		sleep 0.5;
		_x enableAI "FSM";
		sleep 0.5;
	} foreach units _unitGroup;
	
	_unitGroup setVariable["FrozenState",[time,false],true];
};

[_unitGroup] spawn fnc_freeze;

while {true} do {
	_matchingObjectsArray = ((units _unitGroup) select 0) nearEntities ["CAManBase",800];
	_numberOfMatchingObjectsNumber = (count _matchingObjectsArray);
	if (_numberOfMatchingObjectsNumber >= 1) then {
		
		_state = _unitGroup getVariable["FrozenState",[]];
		_stateFroze = _state select 1;
		//If frozen = true then 
		if (_stateFroze) then {
		
			{
				//  is a Player?  &&  player != vehicle player - not in a vehicle
				if (isPlayer _x && (_x != vehicle _x)) then {
					[_unitGroup] spawn fnc_unfreeze;
				};
			} foreach _matchingObjectsArray;
			
		};
		
	} else {
	
		_state = _unitGroup getVariable["FrozenState",[]];
		_timeFroze = _state select 0;
		_stateFroze = _state select 1;
		
		//If frozen = true && last time frozen is bigger then 30 secs
		if (!_stateFroze && ((time - _timeFroze) > 30)) then {
			[_unitGroup] spawn fnc_freeze;
		};
	};
	sleep 15;
};

Link to comment
Share on other sites

  • 0

Thanks. At the Moment i'm scared about the following: This script is meant to reduce server last, but would getting a variable every 15 seconds when a player is not near actually defeat that purpose? How much resources would that take to get the var over an over again and how can i do it better?

This is how it looks:

/**
Please take my Special Thanks, 
- RimBlock ( http://epochmod.com/forum/index.php?/user/12612-rimblock/ ) 
- MGM ( http://epochmod.com/forum/index.php?/user/16852-mgm/ )
**/
private ["_unitGroup","_state","_stateFroze","_timeFroze","_matchingObjectsArray","_numberOfMatchingObjectsNumber","_playerCount"];

_unitGroup = _this select 0;

fnc_freeze = {
	private ["_unitGroup"];
	_unitGroup = _this select 0;
	
	diag_log("Freezing Units");
	
	{
		_x disableAI "TARGET";
		sleep 0.5;
		_x disableAI "AUTOTARGET";
		sleep 0.5;
		_x disableAI "MOVE";
		sleep 0.5;
		_x disableAI "ANIM";
		sleep 0.5;
		_x disableAI "FSM";
		sleep 0.5;
	} foreach units _unitGroup;
	
	_unitGroup setVariable["FrozenState",[time,true],true];
};

fnc_unfreeze = {
	private ["_unitGroup"];
	_unitGroup = _this select 0;
	
	diag_log("Un Freezing Units");
	
	{
		_x enableAI "TARGET";
		sleep 0.5;
		_x enableAI "AUTOTARGET";
		sleep 0.5;
		_x enableAI "MOVE";
		sleep 0.5;
		_x enableAI "ANIM";
		sleep 0.5;
		_x enableAI "FSM";
		sleep 0.5;
	} foreach units _unitGroup;
	
	_unitGroup setVariable["FrozenState",[time,false],true];
};

[_unitGroup] spawn fnc_freeze;

while {true} do {
	_matchingObjectsArray = ((units _unitGroup) select 0) nearEntities ["CAManBase",800];
	_numberOfMatchingObjectsNumber = (count _matchingObjectsArray);
	if (_numberOfMatchingObjectsNumber >= 1) then {
		
		_state = _unitGroup getVariable["FrozenState",[]];
		_stateFroze = _state select 1;
		//If frozen = true then 
		if (_stateFroze) then {
		
			{
				//  is a Player?  &&  player != vehicle player - not in a vehicle
				if (isPlayer _x && (_x != vehicle _x)) then {
					[_unitGroup] spawn fnc_unfreeze;
				};
			} foreach _matchingObjectsArray;
			
		};
		
	} else {
	
		_state = _unitGroup getVariable["FrozenState",[]];
		_timeFroze = _state select 0;
		_stateFroze = _state select 1;
		
		//If frozen = true && last time frozen is bigger then 30 secs
		if (!_stateFroze && ((time - _timeFroze) > 30)) then {
			[_unitGroup] spawn fnc_freeze;
		};
	};
	sleep 15;
};

getVariable is nothing it's reading local memory, don't worry about it at this size.

much more costly is obtaining and processing all matching objects.

 

not relevant to this case but for future reference:

publicVariableServer does cost network traffic [sends data to the server computer]

publicVariableClient does cost network traffic [sends data to a specific client computer]

publicVariable does cost much more network traffic [sends data to all connected client computers]

 

now on to the most important part of this whole script:

why is RimBlock's name above mine in credits. :P

just joking, RB always does serious coding. a real IT professional there... keep him at the top. I would add a * next to him ;)

Link to comment
Share on other sites

  • 0

hey man I just noticed, you're using 0.5. that's too much, isn't it? try 0.05 there...

 

Gosh, thanks xD Didn't had a coffee then :P You don't mind this being released, once i'm finished or do you?

I'll just add some community support (config variables for for range and time) and then finish the testing in about an hour.

 

//EDIT: This script works Server Side, but the re-activation is triggered by Player.

Link to comment
Share on other sites

  • 0

Gosh, thanks xD Didn't had a coffee then :P You don't mind this being released, once i'm finished or do you?

I'll just add some community support (config variables for for range and time) and then finish the testing in about an hour.

Sounds great! What about LICENSE? I would love to see this becoming GNU GPL free software :wub:

Link to comment
Share on other sites

  • 0

Did anyone have a chance to look into mgms last post? Caching vehicles would be very usful id imagine

 

Yes i did. Unfortionately it is no good, as it kills the vehicle actions. You can get in, but not start the engine and after you got in you was locked inside your vehicle.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
  • Discord

×
×
  • Create New...