Jump to content
Sign in to follow this  
pcc

Preventing ACM shutdown when group dies

Recommended Posts

I commented out the unit count check in modules.pbo but the ACM still stops. 

//Shut down if the group does not contain at least one other unit.
	//if ((count _syncObjs) == 0) exitWith {debugLog "Log: [ACM] Shutting down. No units were synchronized to the ACM."};

Is there a way to force ACM to keep running even after groups wipe out?

Spoiler

scriptName "ambient_combat\data\scripts\init.sqf";
/*
	File: init.sqf
	Author: Joris-Jan van 't Land

	Description:
	Initialize the Ambient Combat Manager (ACM).

	Parameter(s):
	_this: the Logic object representing the ACM.
*/

if (isServer) then 
{
	_this setVariable ["initDone", false];
	
	sleep 0.5; //Allow scripted ACM's to add units.
	
	//Register the ACM with this squad.
	private ["_syncObjs"];
	_syncObjs = synchronizedObjects _this;
	
	//Remove all synchronized Logics from the list.
	private ["_syncObjsTmp"];
	_syncObjsTmp = +_syncObjs;
	{
		if (("Logic" countType [_x]) == 1) then {_syncObjs = _syncObjs - [_x]};
	} forEach _syncObjsTmp;
	
	//Shut down if the group does not contain at least one other unit.
	//if ((count _syncObjs) == 0) exitWith {debugLog "Log: [ACM] Shutting down. No units were synchronized to the ACM."};

	//Only the first unit's group is checked. We only allow one group synchronized with the ACM.
	private ["_grp"];
	_grp = group (_syncObjs select 0);
	_this setVariable ["grp", _grp];
	
	//Check to make sure no other ACM is active for this squad.
	private ["_cnt"];
	_cnt = {!isNil {_x getVariable "acm"}} count (units _grp);
	
	if (_cnt == 0) then 
	{
		private ["_fsm"];
		_fsm = _this execFSM "ca\modules\ambient_combat\data\fsms\ambientcombat.fsm";
		
		//TODO:
		//diag_debugFSM _fsm;
		
		//Register ACM with all units in the group.
		{
			_x setVariable ["acm", _this];
		} 
		forEach (units _grp);
	} 
	else 
	{
		debugLog "Log: [ACM] Shutting down. Another ACM was detected for this group."
	};
};

true

 

 

Share this post


Link to post
Share on other sites

The shut down is part of the FSM.  It's very likely designed to shut down because ACM uses the group of the unit it's synchronized to.  Empty groups get deleted.  The FSM would error on a null group.

 

To avoid errors,  after respawn have the server create another ACM and synch it to the player.

See "Scripted ACM" under Advanced Topics:

https://community.bistudio.com/wiki/Ambient_Combat_Manager

 

Where it states:
"This needs to be done within 0.5 seconds from the start of the mission, because after that synchronizations are processed and set in stone."

 

Part of that is not correct.  It should read:
"This needs to be done within 0.5 seconds from the creation of the ACM, because after that its synchronizations are processed and set in stone."

 

In the Init you can see the 0.5 second sleep before it processes the synchronized objects.

 

You can test in editor by placing only a player unit, and a radio trigger calling up a scripted ACM.  After calling my trigger, a chopper appeared around five minutes later.  The scripted synchronization worked fine.

 

In a server script after respawn:

Spoiler

// Server side script

// Create a new ACM and synch it to the respawned player unit.
_grpLogic = CreateGroup SideLogic;
_newACM = _grpLogic createUnit ["AmbientCombatManager",[1000,10,0],[],0,"NONE"];
_newACM synchronizeObjectsAdd [_unit];

_niv = [] spawn 
{
	// Wait for initialization to complete
	waitUntil {!isNil {_newACM getVariable "initDone"}};
	waitUntil {_newACM getVariable "initDone"};
	waitUntil {!(isnil "BIS_fnc_init")};

	// Set the custom params
	[1, _newACM] call BIS_ACM_setIntensityFunc;
	[_newACM, 400, 700] call BIS_ACM_setSpawnDistanceFunc;
	[0, 0.7, _newACM] call BIS_ACM_setSkillFunc;
	[0.2, 0.7, _newACM] call BIS_ACM_setAmmoFunc;
};

 

 

  • Like 1

Share this post


Link to post
Share on other sites

Can it work with killed event handler?  I placed the following in my unit.

this addEventHandler ["killed", {null = [] execVM "ReACM.sqf"}];
Spoiler

waitUntil {alive player};

_grpLogic = CreateGroup SideLogic;
_newACM = _grpLogic createUnit ["AmbientCombatManager",[1000,10,0],[],0,"NONE"];
_newACM synchronizeObjectsAdd [_unit];

_niv = [] spawn  
{
	waitUntil {!isNil {_newACM getVariable "initDone"}};
	waitUntil {_newACM getVariable "initDone"};
	waitUntil {!(isnil "BIS_fnc_init")};

	[2, _newACM] call BIS_ACM_setIntensityFunc;
	[["BIS_US", "USMC", "INS", "CDF", "RU", "GUE", "BIS_TK"], _newACM] call BIS_ACM_setFactionsFunc;
};

 

For some reason it doesn't work. 

Share this post


Link to post
Share on other sites

The unit might be respawning with the old ACM still registered or running.  You can see in the init script that when an ACM initializes it checks synchronized objects and registers in each unit of its detected group.  If a new ACM detects an ACM already registered in any unit of the group, the new ACM shuts down.

 

The old ACM might still be running, or it might not.  In the FSM the delay time between checks is random:

//Base the delay on the intensity (lower intensity means longer delays).
_delay = (20 + (60 * (1 - _intensity)) + (random (240 * (1 - _intensity)))) max 1;

After the random delay time the first thing it does is check to see if the team was wiped out:

({alive _x} count (units _grp)) == 0

If the team is detected as wiped out, the ACM cleans up and gets deleted.  But if it doesn't detect the team wiped out it keeps running.

 

It's a matter of the timing, what did the check find?  And it takes about thirty seconds for an empty group to be deleted.  Respawn might keep the group from getting deleted, but does the respawned unit still have ACM registered to it?

 

before creating a new ACM you would want to run some checks on the old ACM to find some things out, i.e,:
- Did any group members survive (old ACM remains running)?
- Has the ACM gone null (ACM is gone, detected team wiped)?
- Has respawn occured into the same group as before (group was not deleted)?
- Is the ACM still registered in any surviving units or in the respawned unit (a new ACM would shut down)?

 

Addressing these questions should help decide whether another ACM is needed, or whether certain actions are needed (like reregistering the old ACM in the respawned unit; or removing the old ACM registration before creating a new ACM).

  • Like 1

Share this post


Link to post
Share on other sites

After some testing, it appears like addEventHandler is in conflict with warfare module.   It works works fine on mission without warfare module.  Some how the warfare module prevents it from being executed.  Probably because the respawned unit is different I guess.  The radio trigger still works though.

Share this post


Link to post
Share on other sites

When a player respawns in a Warfare mission, all "killed" event handlers get removed.  Warfare's "killed" event handler is then added to the unit.  Check script Client\Functions\Client_PlayerRespawn.sqf.

 

The script Client\Functions\Client_Killed.sqf is Warfare's "killed" event handler script.  Adding it there might work, but adding it to the respawn script may be better.

 

  • Like 1

Share this post


Link to post
Share on other sites
52 minutes ago, opusfmspol said:

When a player respawns in a Warfare mission, all "killed" event handlers get removed.  Warfare's "killed" event handler is then added to the unit.  Check script Client\Functions\Client_PlayerRespawn.sqf.

 

The script Client\Functions\Client_Killed.sqf is Warfare's "killed" event handler script.  Adding it there might work, but adding it to the respawn script may be better.

 

Would it recreate an ACM just for the player for would it do it for all the AI respawns too?  I'd like to limit ACM respawn to just me player.  Would adding "player" stop AI from executing the script on respawn as well?

player AddEventHandler ["Respawn", {Null = [player] execVM "ReACM.sqf";}];

I've been testing it in init.sqf.  But I can't tell for certain if only I'm executing the script or is the AI too as well.

Share this post


Link to post
Share on other sites

The scripts only run for players.

 

Only AI leaders respawn, and their respawn is handled by Server\AI\Team\Team_Update.sqf and Server\AI\Team\Team_UpdateRespawn.sqf.

  • Like 1

Share this post


Link to post
Share on other sites

I tried to give east AI with dedicated mission defend base ACM, but not sure how to set that condition with if statement because there doesn't seem to be a team string name for defend base

like spec ops and etc.

_teamType = [_team] Call BIS_WF_GetTeamTemplateTypeName;
if (_teamType == Localize "STR_WF_TEAMINF" && (side _leader == east)) then
{
//acm
};

Tried using "" but doesn't work. 

Edit: Actually it works, the ACM units just took a long time to appear despite max intensity.

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
Sign in to follow this  

×