Jump to content
Zenophon

Release - Infantry Occupy House Script

Recommended Posts

Zen,

Great script. I am using it in my West to East: Dynamic Battles mission. I am trying to setup a snipper - spotter team at only the tallest possible positions so they hAve the advantage. Can you add a parameter that forces the AI to be place only at the highest possible position in the defined radius? So the highest window in building or roof position if flat. Thanks for a great script.

Share this post


Link to post
Share on other sites
Zen,

Great script. I am using it in my West to East: Dynamic Battles mission. I am trying to setup a snipper - spotter team at only the tallest possible positions so they hAve the advantage. Can you add a parameter that forces the AI to be place only at the highest possible position in the defined radius? So the highest window in building or roof position if flat. Thanks for a great script.

The positions are currently chosen at random by their index. I can just compile all the positions into an array, sort them by height, and select from them in order. The highest positions will be checked first, but may or may not pass the checks. If the 'higher first' parameter isn't set to true, I'll just shuffle the array at random and the script will work as it does now. I'll probably release the new version in a day or two.

Share this post


Link to post
Share on other sites

Hi this is a great idea but im having issues

The AI always leave positions,exiting the houses etc.

Iv disable bcombat but still now luck.Any ideas?

EDIT: all this once enemy is known about

Share this post


Link to post
Share on other sites
The positions are currently chosen at random by their index. I can just compile all the positions into an array, sort them by height, and select from them in order. The highest positions will be checked first, but may or may not pass the checks. If the 'higher first' parameter isn't set to true, I'll just shuffle the array at random and the script will work as it does now. I'll probably release the new version in a day or two.

Thanks Zen! Looking forward to it.

Share this post


Link to post
Share on other sites

Summary

Greetings fellow scripters, by user request I am adding a new feature that allows the script to fill buildings from top to bottom. For example, it is able to put all 8 units on the roof of an office building in Kavala. The new optional parameter defaults to the old (random) behavior. The script has also be optimized slightly with newer SQF commands.

The new version is already hosted on Google Drive, and will be on Armaholic soon. All relevant sections of the original post have been updated.

Changelog

6/30/15

  1. Added: Parameter to fill buildings from top to bottom
  2. Improved: Optimized

Feedback

Hi this is a great idea but im having issues

The AI always leave positions,exiting the houses etc.

Iv disable bcombat but still now luck.Any ideas?

EDIT: all this once enemy is known about

This is compatible with the script:

{
   _x disableAI "MOVE";
   _x disableAI "FSM";
} forEach _units;

just replace _units with what you have for argument 2. AI mods can still enable those AI behaviors again, so I can only guarantee that code will work in vanilla.

Share this post


Link to post
Share on other sites

Thanks Zen! You work at the speed of light. I will be using this for my West to East: Dynamic Battles rooftop snipers and spotters.

Share this post


Link to post
Share on other sites

Hey man, this works great. Really improves town clearing scenarios. I love it that the AI will turn and react, and also begin moving once engaged. Works awesome as is. Here's a few suggestions you can consider if you like:

1. I tried two groups with overlapping building radius. I was hoping that this would result in potentially 2 units in the same building, and it did. But it can result in two units being in exact same position (which is bad). Is it easy to modify to check if another unit from another group has already occupied a particular position, so two units do not occupy same position? The reason this is desirable, is it makes the AI positioning less predictable, since you never know if there will be more than one in the house.

2. Would be great to have option to have units move to the assigned positions, rather than be teleported there. This could support AI doing random house searching, or groups arriving and garrisoning real time.

Works perfect as is though. I may play around with these ideas.

Thanks!

Edited by JohnnyBoy

Share this post


Link to post
Share on other sites

Just curious...how does this script compare to the [Zen_SpawnInfantryGarrison] script in your framework? Here's my understanding of the differences:

  • the framework's garrison script handles both spawning and garrisoning units within eligible buildings in a given area but just places the units without positioning them to watch out windows/doors.
  • this script requires that units already exist but does garrison them so they look out windows. This script also seems to allow control over how the garrisoning takes place (fill order, fill distribution, etc.)

Is that correct? Are there other differences (unit behavior, positioning, etc) that we should be aware of?

Thanks for sharing this script (and your excellent framework!) with the community!

- z

Share this post


Link to post
Share on other sites
Hey man, this works great. Really improves town clearing scenarios. I love it that the AI will turn and react, and also begin moving once engaged. Works awesome as is. Here's a few suggestions you can consider if you like:

1. I tried two groups with overlapping building radius. I was hoping that this would result in potentially 2 units in the same building, and it did. But it can result in two units being in exact same position (which is bad). Is it easy to modify to check if another unit from another group has already occupied a particular position, so new two units end up in same position? The reason this is desirable, is it makes the AI positioning less predictable, since you never know if there will be more than one in the house.

2. Would be great to have option to have units move to the assigned positions, rather than be teleported there. This could support AI doing random house searching, or groups arriving and garrisoning real time.

Works perfect as is though. I may play around with these ideas.

Thanks!

It could check for a unit nearby every position, but that would slow it down. You can give multiple groups as the second argument; one instance of the script will only use each position once. Something like:

_unitsRemaining = [_pos, (units group A) + (units group B), 100, false, true] call Zen_OccupyHouse;

where A and B are objects in the groups. That should fill the buildings evenly with both groups.

I can make it a parameter to order them to move there. I just can't guarantee the AI will always get to the exact position, face the right direction, etc. They will look like they're searching/clearing the house though. I could also randomize the order of the buildings, so filling the buildings one by one is a radius would be different every time.

Just curious...how does this script compare to the [Zen_SpawnInfantryGarrison] script in your framework? Here's my understanding of the differences:

  • the framework's garrison script handles both spawning and garrisoning units within eligible buildings in a given area but just places the units without positioning them to watch out windows/doors.
  • this script requires that units already exist but does garrison them so they look out windows. This script also seems to allow control over how the garrisoning takes place (fill order, fill distribution, etc.)

Is that correct? Are there other differences (unit behavior, positioning, etc) that we should be aware of?

Thanks for sharing this script (and your excellent framework!) with the community!

- z

Yes, Zen_SpawnInfantryGarrison is placing the units at random in the building (using Zen_FindBuildingPositions). The occupy house script orders them to watch a direction, forces them to kneel or stand up (using setUnitPos), and keeps them in place better (using forceSpeed). Zen_SpawnInfantryGarrison is better for giving AI group orders later (like move out of the building and patrol the town).

You could do the same multi-building, random placement of existing units using Zen_FindBuildingPositions, they just won't be at the windows. Because of the randomness of Zen_FindBuildingPositions, it can't find windows as successfully as this script. The hard-coded building points tend to be behind windows, on balconies, etc. Zen_FindBuildingPositions works better for randomness and dealing with large buildings that have few hard-coded points.

  • Like 1

Share this post


Link to post
Share on other sites
You can give multiple groups as the second argument; one instance of the script will only use each position once. .

Thanks for the quick reply Zen, that will satisfy my need.

Regarding moving to positions, its possible but obviously much more work. You could wait until UnitReady (i.e., move completed), then have a dowatch a position 10 meters away from unit in desired direction that you have already calculated. Maybe I will give it a try.

One of the other guys on this post mentioned integrating a side-step script with this. I've already built an "up/down" script for this purpose, so that once a unit is fired on, he will change his stance periodically which simulates ducking for cover nicely, and makes it harder to hit him. I've been using it for static snipers in windows and roof tops, and it works great.

Turns out it was super easy to integrate with your script by adding two lines of code in the section where you use setUnitPos:

                              
if (_isRoof) then {
  (_units select _unitIndex) setUnitPos "MIDDLE";
  (_units select _unitIndex) addeventhandler ["FiredNear",{ [_this select 0,["DOWN","MIDDLE"]] execVM "JBOY_UpDown.sqf";}];
} else {
  (_units select _unitIndex) setUnitPos "UP";
  (_units select _unitIndex) addeventhandler ["FiredNear",{ [_this select 0,["UP","MIDDLE"]] execVM "JBOY_UpDown.sqf";}];
};

Units won't start the up/down behavior until they are fired upon (using FiredNear eventhandler). Roof-top units will alternate between prone and crouched. Other positions will alternate between standing and crouching.

Here's my script:

// *****************************************************
// ** JBOY_UpDown.sqf 
// ** by JohnnyBoy
// ** AI will toggle between two stances with a random delay between.
// **  Call:  null = [dude, ["Up","Middle"]] execVM "JBOY_UpDown.sqf";
// ** Start with an eventhandler:
// this addeventhandler ["FiredNear",{ [_this select 0,["UP","MIDDLE"]] execVM "JBOY_UpDown.sqf";}];
// 
// *****************************************************
if (!isServer)  exitwith {};

//  Parameters:
_dude = _this select 0;   
_stances = _this select 1;

_dude removeAllEventHandlers "FiredNear";
while {alive _dude} do
{
if ((unitpos _dude) == (_stances select 0)) then
{
	_dude setUnitPos (_stances select 1);
} else
{
	_dude setUnitPos (_stances select 0);
};
sleep (1 + (random 7));
};

Here's a short video showing it work:

Feel free to integrate it with your script if you like it. You can take the code and use it any way you want (put inside your script, etc.).

Once again thanks for this great script. I'm going to have to take an in-depth look at your framework also.

Edited by JohnnyBoy
  • Like 1

Share this post


Link to post
Share on other sites

Thanks for the quick reply Zen, that will satisfy my need.

Regarding moving to positions, its possible but obviously much more work. You could wait until UnitReady (i.e., move completed), then have a dowatch a position 10 meters away from unit in desired direction that you have already calculated. Maybe I will give it a try.

One of the other guys on this post mentioned integrating a side-step script with this. I've already built an "up/down" script for this purpose, so that once a unit is fired on, he will change his stance periodically which simulates ducking for cover nicely, and makes it harder to hit him. I've been using it for static snipers in windows and roof tops, and it works great.

Turns out it was super easy to integrate with your script by adding two lines of code in the section where you use setUnitPos:

                              
if (_isRoof) then {
  (_units select _unitIndex) setUnitPos "MIDDLE";
  (_units select _unitIndex) addeventhandler ["FiredNear",{ [_this select 0,["DOWN","MIDDLE"]] execVM "JBOY_UpDown.sqf";}];
} else {
  (_units select _unitIndex) setUnitPos "UP";
  (_units select _unitIndex) addeventhandler ["FiredNear",{ [_this select 0,["UP","MIDDLE"]] execVM "JBOY_UpDown.sqf";}];
};

Units won't start the up/down behavior until they are fired upon (using FiredNear eventhandler). Roof-top units will alternate between prone and crouched. Other positions will alternate between standing and crouching.

Here's my script:

// *****************************************************
// ** JBOY_UpDown.sqf 
// ** by JohnnyBoy
// ** AI will toggle between two stances with a random delay between.
// **  Call:  null = [dude, ["Up","Middle"]] execVM "JBOY_UpDown.sqf";
// ** Start with an eventhandler:
// this addeventhandler ["FiredNear",{ [_this select 0,["UP","MIDDLE"]] execVM "JBOY_UpDown.sqf";}];
// 
// *****************************************************
if (!isServer)  exitwith {};

//  Parameters:
_dude = _this select 0;   
_stances = _this select 1;

_dude removeAllEventHandlers "FiredNear";
while {alive _dude} do
{
if ((unitpos _dude) == (_stances select 0)) then
{
	_dude setUnitPos (_stances select 1);
} else
{
	_dude setUnitPos (_stances select 0);
};
sleep (1 + (random 7));
};

Here's a short video showing it work:

Feel free to integrate it with your script if you like it. You can take the code and use it any way you want (put inside your script, etc.).

Once again thanks for this great script. I'm going to have to take an in-depth look at your framework also.

Thanks, this is a great addition. I'll include your code and credit you for the next release (which is in probably 1 or 2 days). As the script is just a single SQF file, I'll have to put your code into the eventhandler directly.

Share this post


Link to post
Share on other sites

Sweet. I'm glad I could make a small contribution. I look forward to the next release.

Share this post


Link to post
Share on other sites

Summary

Greetings fellow scripters. Due to some user feedback and contributions, I am able to add some new features. Thanks to JohnnyBoy, the AI will now take cover when fired upon; all credit goes to him for this feature. I've also added a parameter to make the AI move to their positions. Unfortunately, this does not always work perfectly due to AI pathfinding. Also, when filling multiple buildings, the order they are filled is now random. Finally, I've made a few more slight optimizations to the code.

The new version is already hosted on Google Drive, and will be on Armaholic soon. All relevant sections of the original post have been updated.

Changelog

7/6/15

  1. Added: AI now take cover when fired upon (credit to JohnnyBoy)
  2. Added: Parameter to order the AI to move to their position
  3. Improved: The order of buildings filled is now random
  4. Improved: A few minor optimizations

  • Like 1

Share this post


Link to post
Share on other sites

Zeno, looks good will have to give this a try. I know when I was trying to implement this in alpha in my own personal missions we could never get the AI to stay in place. We tried all the disable commands and everything else (FSM/tweaking allowable actions/etc..)but at some point if you were successful it would just turn them completely stupid. So it looks like this finally works Im eager to give it a shot. Thanks.

Share this post


Link to post
Share on other sites
Zeno, looks good will have to give this a try. I know when I was trying to implement this in alpha in my own personal missions we could never get the AI to stay in place. We tried all the disable commands and everything else (FSM/tweaking allowable actions/etc..)but at some point if you were successful it would just turn them completely stupid. So it looks like this finally works Im eager to give it a shot. Thanks.

After someone reported that the AI can move when in combat (danger.fsm I'm guessing), I added 'forceSpeed 0' on the unit. disableAI 'Move' is also an option, but forceSpeed seems a little less severe. disableAI 'FSM' will make them stupid, so it's a last resort.

Share this post


Link to post
Share on other sites

Love this script, great update, thank you guys!

Share this post


Link to post
Share on other sites

Man I keep getting 'undefined variable' errors and the squad does not go indoors :(

Share this post


Link to post
Share on other sites
Man I keep getting 'undefined variable' errors and the squad does not go indoors :(

Can you post or PM me the arguments used and the full text of the error? The script does not check its arguments for the correct type or format, so giving the wrong thing will result in errors.

Share this post


Link to post
Share on other sites

In the AI groupleader's init field

null = [this , units group this] execVM "Zen_OccupyHouse.sqf";

Error message(s) from rpt:

 9:52:38 Error in expression <"];
_array = _this select 0;

if (count _array > 1) then {
for "_i" from 0 to (c>
9:52:38   Error position: <_array > 1) then {
for "_i" from 0 to (c>
9:52:38   Error Undefined variable in expression: _array
9:52:38 File C:\Users\Greg\Documents\Arma 3\missions\House%20Script.pja305\Zen_OccupyHouse.sqf, line 85
9:52:38 Error in expression <us = _this select 2;
_putOnRoof = _this select 3;
_fillEvenly = _this select 4;
>
9:52:38   Error position: <select 3;
_fillEvenly = _this select 4;
>
9:52:38   Error Zero divisor
9:52:38 File C:\Users\Greg\Documents\Arma 3\missions\House%20Script.pja305\Zen_OccupyHouse.sqf, line 33

Share this post


Link to post
Share on other sites
In the AI groupleader's init field

null = [this , units group this] execVM "Zen_OccupyHouse.sqf";

Error message(s) from rpt:

 9:52:38 Error in expression <"];
_array = _this select 0;

if (count _array > 1) then {
for "_i" from 0 to (c>
9:52:38   Error position: <_array > 1) then {
for "_i" from 0 to (c>
9:52:38   Error Undefined variable in expression: _array
9:52:38 File C:\Users\Greg\Documents\Arma 3\missions\House%20Script.pja305\Zen_OccupyHouse.sqf, line 85
9:52:38 Error in expression <us = _this select 2;
_putOnRoof = _this select 3;
_fillEvenly = _this select 4;
>
9:52:38   Error position: <select 3;
_fillEvenly = _this select 4;
>
9:52:38   Error Zero divisor
9:52:38 File C:\Users\Greg\Documents\Arma 3\missions\House%20Script.pja305\Zen_OccupyHouse.sqf, line 33

The error in line 33 is caused by you only passing 2 parameters, but trying to fill 5 (_this select 0 through 4) inside the script. You might wanna use BIS_fnc_param to fix this.

The error in line 85 is caused by the same reason, which is that _buildingRadius is not given in your execVM line.

Share this post


Link to post
Share on other sites
In the AI groupleader's init field

null = [this , units group this] execVM "Zen_OccupyHouse.sqf";

Error message(s) from rpt:

 9:52:38 Error in expression <"];
_array = _this select 0;

if (count _array > 1) then {
for "_i" from 0 to (c>
9:52:38   Error position: <_array > 1) then {
for "_i" from 0 to (c>
9:52:38   Error Undefined variable in expression: _array
9:52:38 File C:\Users\Greg\Documents\Arma 3\missions\House%20Script.pja305\Zen_OccupyHouse.sqf, line 85
9:52:38 Error in expression <us = _this select 2;
_putOnRoof = _this select 3;
_fillEvenly = _this select 4;
>
9:52:38   Error position: <select 3;
_fillEvenly = _this select 4;
>
9:52:38   Error Zero divisor
9:52:38 File C:\Users\Greg\Documents\Arma 3\missions\House%20Script.pja305\Zen_OccupyHouse.sqf, line 33

The first 5 parameters are required; only the last two are not. So you'd need something like:

null = [this, units group this, -1, false, false] execVM "Zen_OccupyHouse.sqf";

They are intentionally required so that the user makes a decision about the argument and is aware of what it does, rather than accepting whatever default value I put there. The last two are only optional because I don't want to break people's code after nearly 1 year if they get the new version just for the optimizations.

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

×