Jump to content

Recommended Posts

Hello,

 

I am looking for a solution to an issue which troubles me greatly - AI going prone on contact. I guess all of us have experienced it before and know that once the AI changes combat mode, it instantly goes to the ground which is not always realistic, nor is it good for the players.

 

I have searched for a solution for some time now and most of the solutions suggested forcing AI to one specific stance, either by Zeus or by setUnitPos. Unfortunately, none of the solutions considered allowing the AI to either STAND or KNEEL, which is what I'm hoping for. Maybe there is a way to add an eventhandler of some sort which could override the PRONE stance with KNEEL, if possible. Otherwise, maybe it could just disable prone itself, leaving kneel and stand for the AI to choose normally.

 

I did find a semi-solution to this, which is using trigger areas and modules, which force the stance change of the AI within a trigger to whatever I set, however that's a) fixed to one stance, and b) always in zones that have been predefined by me, not dynamic in any way.

 

I lack enough experience to write something like this on my own, but I do feel like forbidding AIs PRONE stance only is possible - I just don't know exactly how to do it.

 

Will be grateful for any help!

Adam

  • Like 1

Share this post


Link to post
Share on other sites

I do this and it works ok, might be a better way though:
 

_unit addEventHandler ["AnimStateChanged",
{
	params ["_unit", "_anim"];
	if (canStand _unit && (behaviour _unit in ["AWARE","COMBAT"])) then {
	_unit setUnitPos "MIDDLE";
	};
}];

 

  • Like 3
  • Thanks 1

Share this post


Link to post
Share on other sites

I think it should be better to disable prone only inside buildings.

 

NOT Tested !

//________________	Thanks to Killzone Kid for his tutorials	________________
//	http://killzonekid.com/category/tutorials/

KK_fnc_inHouse = {
    private ["_house"];
    _house = "";
	lineIntersectsSurfaces [
		getPosWorld _this, 
		getPosWorld _this vectorAdd [0, 0, 50], 
		_this, objNull, true, 1, "GEOM", "NONE"
	] select 0 params ["","","","_house"];
	if (_house isKindOf "House") exitWith {true};
	false
};
//	onEachFrame {hintSilent str (player call KK_fnc_inHouse)};


GF_Force_UnitPos = {
	
	while {true} do {
		
	if (
	(alive _this) 
	&& (!(underwater _this) or ((getPosASLW _this select 2) > -1.5))
	) then {	
					
		//________________	_inHouse	________________
			
		_inHouse = _this call KK_fnc_inHouse;
			
		if (_inHouse) then {
		
		if (canStand _this && (behaviour _this in ["AWARE","COMBAT"])) then {
		_this setUnitPos "MIDDLE";
		};
		
		sleep 3;
		}else{

		
		//________________	COMBAT	________________
		//	you can also add different cases ex:
          
		if((!(_inHouse)) && (behaviour _this == "COMBAT")) then {
			//	code 
			sleep 3;
			};
		
		};
			
		}else{
		_this setUnitPos "UP";
		sleep 10;	
		};
	};
};

//________________	spawn	_____________

[] spawn {
	while {true} do {
    _time = diag_tickTime + 15;	//	% sec
    _i = 0;
    waitUntil {
        _i = _i + 1;		
        diag_tickTime >= _time
    };
	   //	hint format ["Code executed %1 times per second", _i];	
	{	
		if (
		((alive _x))
		&& (!(_x getVariable ["Var_GF_Force_UnitPos",false]))		
		&& (!isPlayer _x)
		
		/*
		//________________	You can filter the side here	________________	
		&& {((side group _x) == west || 
			(side group _x) == east || 
			(side group _x) == independent || 
			(side group _x) == civilian || 
			(side group _x) == sideUnknown)}
		
		//	&& (side _x == playerSide)	// only for the Player side
		*/
				
		) then {
		//________________	You can filter here	________________

		_x spawn GF_Force_UnitPos;
		};								
		_x setVariable ["Var_GF_Force_UnitPos",true];

		{waitUntil {!alive _x};
		_x setVariable ["Var_GF_Force_UnitPos",false];
		};
	}forEach allUnits;
	};
};

 

  • Like 2
  • Thanks 2

Share this post


Link to post
Share on other sites

George your solution is better and more elaborate but I think triggering it via the animchanged EH rather than having it in a loop would be better for optimization.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
16 minutes ago, Mr H. said:

triggering it via the animchanged EH rather than having it in a loop would be better for optimization.

 

It's always better using the EH ,

but generally if you want to apply this to the spawned units then , so else it needs the script to loop.

If not then , sure the wise choice is to use off course the EH.

Share this post


Link to post
Share on other sites

Wow, thanks for so many responses guys! I took a look at all of them and I indeed needed something that would work for spawned units as well, so I could not just assign a scirpt to a specific group.

The solution from @.kju works flawlessly - I made a small local mod out of it and works like a charm!

 

I may try out @GEORGE FLOROS GR's solution too, as in some missions I actualy may want the AI to lie down except for buildings - thanks for sharing the script man!

 

Thanks all for your help - that's a big thing!

  • Thanks 1

Share this post


Link to post
Share on other sites
16 minutes ago, Dj Rolnik said:

The solution from @.kju works flawlessly -

 

The 1st one or the second ?

would you like to upload this?

Thanks Dj Rolnik !

  • Like 1

Share this post


Link to post
Share on other sites
1 minute ago, GEORGE FLOROS GR said:

 

The 1st one or the second ?

would you like to upload this?

Thanks Dj Rolnik !

 

They're basically the same things, just one is a big discussion on the BI Forums and the other is a repost on Reddit. Sure, I can share this, no problem. Unfortunately I am not sure how to attach files to posts, so had to generate a link, sorry for that... I left out the raw folder just for ease of modification :)

 

https://www68.zippyshare.com/v/HdEQcsCw/file.html - it's a whopping 866 bytes so shows as 0 MB ^^

 

Otherwise, it's just a config.cpp containing the below code from @.kju's first link - packed into a PBO.

class CfgSurfaces {
	class Default {
		AIAvoidStance = 2;
	};
};

Thanks again!

  • Like 5

Share this post


Link to post
Share on other sites
1 minute ago, Dj Rolnik said:

Thanks again!

 

Thank you very much Dj Rolnik !  :thumb:

  • Like 1

Share this post


Link to post
Share on other sites

I was checking , what is the default action indoors and they don't seem to pnone .

Basically i remember when i was playing , some time ago ( because now i don't ! ) that the ai were doing this , but i didn't notice anything now.

Might this changed ?

 

Here is also a pic:

ZOeQeZI.png

Share this post


Link to post
Share on other sites

I have no idea if you ask me - it may well be the case that it was just fixed somewhere on the way : )

  • Haha 1

Share this post


Link to post
Share on other sites
On 10/1/2019 at 11:36 AM, GEORGE FLOROS GR said:

Can someone confirm this ?

Thanks !

Spoiler
On 10/1/2019 at 2:49 AM, GEORGE FLOROS GR said:

I was checking , what is the default action indoors and they don't seem to pnone .

Basically i remember when i was playing , some time ago ( because now i don't ! ) that the ai were doing this , but i didn't notice anything now.

Might this changed ?

 

Here is also a pic:

ZOeQeZI.png

@.kju

Share this post


Link to post
Share on other sites

Maybe it's a bit late for an answer @Dj Rolnikbut here's a script that works well, for those who might be interested in the future :

[yourUnitName] spawn {
	params ["_unit"];
	while {alive _unit} do {
		if (behaviour _unit =="COMBAT") then {
			waitUntil {speed _unit < 1};
			_unit setUnitpos "MIDDLE";
			waitUntil {speed _unit > 2};
			_unit setUnitpos "UP";
		} else {
			_unit setUnitpos "AUTO";
			sleep 2;
		};
	};
};

 

If in COMBAT mode, the unit will take a knee when not moving, and stand up when on the move.

  • Like 4

Share this post


Link to post
Share on other sites
On 1/9/2019 at 8:23 PM, Dj Rolnik said:

 

They're basically the same things, just one is a big discussion on the BI Forums and the other is a repost on Reddit. Sure, I can share this, no problem. Unfortunately I am not sure how to attach files to posts, so had to generate a link, sorry for that... I left out the raw folder just for ease of modification 🙂

 

https://www68.zippyshare.com/v/HdEQcsCw/file.html - it's a whopping 866 bytes so shows as 0 MB ^^

 

Otherwise, it's just a config.cpp containing the below code from @.kju's first link - packed into a PBO.


class CfgSurfaces {
	class Default {
		AIAvoidStance = 2;
	};
};

Thanks again!

 

Dear @Dj Rolnik could you please re upload the PBO, I cannot get it anymore 😞

Share this post


Link to post
Share on other sites
4 hours ago, Tova said:

Maybe it's a bit late for an answer @Dj Rolnikbut here's a script that works well, for those who might be interested in the future :


[yourUnitName] spawn {
	params ["_unit"];
	while {true} do {
		if (behaviour _unit =="COMBAT") then {
			waitUntil {speed _unit < 1};
			_unit setUnitpos "MIDDLE";
			waitUntil {speed _unit > 2};
			_unit setUnitpos "UP";
		} else {
			_unit setUnitpos "AUTO";
			sleep 2;
		};
	};
};

 

If in COMBAT mode, the unit will take a knee when not moving, and stand up when on the move.

Hi @Tova

is there anyway to make this work on all OpFor units only, so i don't have to name them all.

The units is not spawned in to game only placed in editor for a SP game

or is it enough just to replace [yourUnitName] with _this ?? and put it inside units INIT field ??

Share this post


Link to post
Share on other sites

Hello @Play3r !

 

16 hours ago, Play3r said:

is it enough just to replace [yourUnitName] with _this ?? and put it inside units INIT field ?? 

 

Yes that would work ! However you'll have to put [this] if it's in the init field and not _this (note the little "_" and the [ ])

 

I've also made you a code that will call the script on all the opfor units :

 

TOV_noProne= {
	params ["_unit"];
	while {alive _unit} do {
		if (behaviour _unit =="COMBAT") then {
			waitUntil {speed _unit < 1};
			_unit setUnitpos "MIDDLE";
			waitUntil {speed _unit > 2};
			_unit setUnitpos "UP";
		} else {
			_unit setUnitpos "AUTO";
			sleep 2;
		};
	};
};



{
	if (side _x==east) then {
		[_x] spawn TOV_noProne;
	};
} forEach allUnits;

Just put it in a trigger set to true 🙂

 

NOTE : I updated the script so it stops when the unit dies.

Also I'm not sure how running the script on many units will affect performance. You'll have to try 🙂 But please let me know !

 

Have fun !

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

@LSValmont Hey man, sorry it's been a while since I visited the forums and thus did not see your message.

 

Here goes the link:
https://drive.google.com/open?id=1bRUPluH_0kEf68G40W7twRZ20DNWWEEr

 

I packed it into an archive if you wish to load it via a local mod. Optionally, you can subscribe to the Workshop version which I uploaded for ease of use, right here:
https://steamcommunity.com/sharedfiles/filedetails/?id=2011658088

 

Cheers!

  • Thanks 1

Share this post


Link to post
Share on other sites
On 3/26/2020 at 5:17 PM, Dj Rolnik said:

@LSValmont Hey man, sorry it's been a while since I visited the forums and thus did not see your message.

 

Here goes the link:
https://drive.google.com/open?id=1bRUPluH_0kEf68G40W7twRZ20DNWWEEr

 

I packed it into an archive if you wish to load it via a local mod. Optionally, you can subscribe to the Workshop version which I uploaded for ease of use, right here:
https://steamcommunity.com/sharedfiles/filedetails/?id=2011658088

 

Cheers!

 

Thank you so much @Dj Rolnik!

 

Got it both ways!

Share this post


Link to post
Share on other sites
On 1/9/2019 at 4:07 PM, GEORGE FLOROS GR said:

I think it should be better to disable prone only inside buildings.

 

NOT Tested !


//________________	Thanks to Killzone Kid for his tutorials	________________
//	http://killzonekid.com/category/tutorials/

KK_fnc_inHouse = {
    private ["_house"];
    _house = "";
	lineIntersectsSurfaces [
		getPosWorld _this, 
		getPosWorld _this vectorAdd [0, 0, 50], 
		_this, objNull, true, 1, "GEOM", "NONE"
	] select 0 params ["","","","_house"];
	if (_house isKindOf "House") exitWith {true};
	false
};
//	onEachFrame {hintSilent str (player call KK_fnc_inHouse)};


GF_Force_UnitPos = {
	
	while {true} do {
		
	if (
	(alive _this) 
	&& (!(underwater _this) or ((getPosASLW _this select 2) > -1.5))
	) then {	
					
		//________________	_inHouse	________________
			
		_inHouse = _this call KK_fnc_inHouse;
			
		if (_inHouse) then {
		
		if (canStand _this && (behaviour _this in ["AWARE","COMBAT"])) then {
		_this setUnitPos "MIDDLE";
		};
		
		sleep 3;
		}else{

		
		//________________	COMBAT	________________
		//	you can also add different cases ex:
          
		if((!(_inHouse)) && (behaviour _this == "COMBAT")) then {
			//	code 
			sleep 3;
			};
		
		};
			
		}else{
		_this setUnitPos "UP";
		sleep 10;	
		};
	};
};

//________________	spawn	_____________

[] spawn {
	while {true} do {
    _time = diag_tickTime + 15;	//	% sec
    _i = 0;
    waitUntil {
        _i = _i + 1;		
        diag_tickTime >= _time
    };
	   //	hint format ["Code executed %1 times per second", _i];	
	{	
		if (
		((alive _x))
		&& (!(_x getVariable ["Var_GF_Force_UnitPos",false]))		
		&& (!isPlayer _x)
		
		/*
		//________________	You can filter the side here	________________	
		&& {((side group _x) == west || 
			(side group _x) == east || 
			(side group _x) == independent || 
			(side group _x) == civilian || 
			(side group _x) == sideUnknown)}
		
		//	&& (side _x == playerSide)	// only for the Player side
		*/
				
		) then {
		//________________	You can filter here	________________

		_x spawn GF_Force_UnitPos;
		};								
		_x setVariable ["Var_GF_Force_UnitPos",true];

		{waitUntil {!alive _x};
		_x setVariable ["Var_GF_Force_UnitPos",false];
		};
	}forEach allUnits;
	};
};

 

Definitely late to the party but the inHouse function above is brilliant! Thank you for sharing KillZone's solution. This works flawlessly for 99% of cases.

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

×