This script teleports AI units into nearby buildings at appropriate window positions. Units will stand and face the window so they can fire out of it. Units are moved to random windows every time. If there are enough units, every possible window will be covered; otherwise, you won't know where they are watching. When there are multiple possible windows to face, units will face one at random. Units will not face a windows more than 5 meters away, and the windows will have a reasonable field of view.
By using this script, you no longer have to manually place units at windows and struggle with the 2d editor. This script allows you to easily simulate the AI occupying buildings and defending their position realistically. It works for just a few units to surprise players, and on a large scale to put dozens of enemies into defensive positions all across a city.
The function is carefully optimized for almost no performance impact, allowing it to dynamically examine each position for the best possible results. There is no debug, argument checking, or defensive code, to make it as simple and fast as possible, so make sure the arguments are correct.
These pictures are the results when the script was used on two random houses (click for a larger version).
Place the script somewhere in your mission folder.
1. Array, the building(s) nearest this position is used
2. Array of objects, the units that will garrison the building(s)
(opt.) 3. Scalar, radius in which to fill building(s), -1 for only nearest building, (default: -1)
(opt.) 4. Boolean, true to put units on the roof, false for only inside, (default: false)
(opt.) 5. Boolean, true to fill all buildings in radius evenly, false for one by one, (default: false)
(opt.) 6. Boolean, true to fill from the top of the building down, (default: false)
(opt.) 7. Boolean, true to order AI units to move to the position instead of teleporting, (default: false)
The complete documentation is also commented at the top of the file. You can run it from anywhere with execVM:
0 = [getPosATL X, units X] execVM "Zen_OccupyHouse.sqf";
You can also compile it into a function if you plan on using it many times:
Zen_OccupyHouse = compileFinal preprocessFileLineNumbers "Zen_OccupyHouse.sqf";
_units = [(getMarkerPos "mkHouse"), [X, Y, Z], 50, false, true] call Zen_OccupyHouse;
When using the compile and call method, the function returns the array of units that did not fit in the building.
If you liked/disliked it or have any suggestions for improvement, I would like to hear your thoughts. Either this thread, PM, or email is fine.
Contact the author:
This software is released under Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0).
JohnnyBoy (AI take cover)