Page 1 of 11 12345 ... LastLast
Results 1 to 10 of 101

Thread: JTD Building Search script

  1. #1

    JTD Building Search script

    JTD Building Search script (Updated to version .01g)

    This is a WIP script that will send members of an AI squad into an enterable building, and sequentially search through the building positions. It was developed in an effort to take advantage of all the enterable buildings that have been introduced into ArmA, and cultivate more of a CQB atmosphere.

    First - credits:
    OFPEC - one of the best resources available IMHO
    Rommel for CBA function searchNearby
    Tophe for random house patrol
    --- http://forums.bistudio.com/showthread.php?t=76423

    Seriously, this script began by borrowing heavily from Rommel's CBA function, and was directly inspired by Tophe's house patrol. Any direct benefit people may get from this is really a product of those guys' work.

    Second - methodology:
    The script (which can be called as a function) receives at least one parameter - the group - with options for 3 other parameters - search distance, nearest building or a random one, and an initial position for the search for buildings. The script will create an array of buildings, select one, then create a waypoint for the group to a spot near that building. Upon reaching the waypoint, the leader of the group will remain outside, while members of the group enter the building, in combat mode. If there are more building positions than searchers, all available units other than the leader will enter the building.

    The searchers will basically trail through the building - not bound/overwatch. When the last building position is reached, the searchers will rejoin the leader.

    Third - a vid of a slightly older version of the script (the searching starts about a minute into it):


    Finally - a download:
    http://www.mediafire.com/file/e6wuq2...ackage_0124.7z
    (ArmaHolic)
    http://www.armaholic.com/page.php?id=13130


    And the script itself (somewhat heavy on comments):
    PHP Code:
    /* JTD Building Search Script
    by Trexian

    Purpose: have an AI squad search a building.

    Implementation: executed from trigger or script (can be as a function)
    ooooooooooooooooooooooooooooooooooooooooooooooooooo
    Usage:
    Requires 1 parameter, with an option for 4 more: group(, searchRadius , "NEAREST" or "RANDOM", initial position, include leader, occupy building)
    group = group that will be searching the building (required)
    searchRadius = number that is radius around the leader to use to generate the array of buildings (default is 50) (optional)
    NEAREST/RANDOM = string that tells the script which building, either the nearest to the position or a random one (default is random) (optional)
    initial position = position array or object  around which to search (default is leader's position at script execution) (optional)
    include leader = boolean, where 'true' includes the leader in the search (default is false, but if group has 2 or less, default is true) (optional)
    occupy building = boolean, where 'true' means that the group will stay in the building positions (default is false)

    ooooooooooooooooooooooooooooooooooooooooooooooooooo
    Credits:
    OFPEC
    Rommel for CBA function searchNearby
    Tophe for random house patrol

    Testers/Feedback:
    MadRussian
    GvsE
    Kremator
    Manzilla
    ooooooooooooooooooooooooooooooooooooooooooooooooooo
    Version:
    01a
    POC (addWaypointHousePosition doesn't work)

    01b
    used CBA searchNearby by Rommel for commandMove instead of waypoints

    01c
    Improved methodology

    01d - release version
    Improved the rejoining of the searchers
    Added ability to specify initial position of building search

    01e
    Added optional parameter to include leader in search, also an option to occupy the building
    More robust error-checking
    Can pass object instead of intialposition
    Shuffles searcher array

    01f - release version
    Added server check
    Added global JTD_lockedSearchGroups
    Added time check to make sure script ends at some point

    01g - release version
    Added JTD_bldgsrchPath as variable for Manzilla
    Array functionality wrapper

    ooooooooooooooooooooooooooooooooooooooooooooooooooo
    TTD:

    ooooooooooooooooooooooooooooooooooooooooooooooooooo
    */

    if !(isServerexitWith {diag_log text "Not server, exiting building search.";};

    //diag_log text "JTD bldg search activated";

    private ["_grpFM""_FunctionsManager""_group""_leader""_ldrPos""_behaviour""_srchRad""_whichOne""_initialPos""_andOne""_occupy""_bldgArray""_tempArray""_bldgLoc""_bldgSelect""_searchersT""_searchers""_searcherCount""_s""_checkTime""_wpArray""_currWP""_wpCnt""_d""_t""_b""_bldg""_bldgPos""_bldgCnt""_nameMarker""_marker""_bldgBB""_wpRad""_wp""_p""_totTime""_activeBP""_loop""_cycle""_unitSelect""_units"];

    if (
    isNil "JTD_bldgsrchPath"then {JTD_bldgsrchPath "";};

    // check for functions
    if (isNil "bis_fnc_init"then
    {
        
    createCenter sideLogic;
        
    _grpFM createGroup sideLogic;
        
    _FunctionsManager _grpFM createUnit ["FunctionsManager", [111], [], 0"NONE"];
        
    waitUntil {!isNil "bis_fnc_init"};
    };

    if (
    isNil "JTD_arrayShuffleFunc"then
    {
        
    JTD_arrayShuffleFunc compile preprocessFileLineNumbers (JTD_bldgsrchPath +"JTD_arrayShuffle.sqf");
    };

    if (
    isNil "JTD_lockedSearchGroups"then {JTD_lockedSearchGroups = [];};

    _group _this select 0;
    JTD_lockedSearchGroups JTD_lockedSearchGroups + [_group];
    if ((
    typeName _group) == "OBJECT"then {_group group (_this select 0)};

    //diag_log text format ["group searching: %1", _group];
    _leader leader _group;
    //diag_log text format ["group leader: %1", _leader];
    _ldrPos getPos _leader;
    _behaviour behaviour _leader;
    if ((
    count _this) >= 2then {
        
    _srchRad _this select 1;}
        else {
        
    _srchRad 50;};
    if ((
    count _this) >= 3then {
        
    _whichOne _this select 2;
        } else {
        
    _whichOne "RANDOM";};
    if ((
    count _this) >=4then {
        
    _initialPos _this select 3;
        } else {
        
    _initialPos _ldrPos;};
    if ((
    count _this) >=5then {
        
    _andOne _this select 4;
        } else {
        
    _andOne false;};
    if ((
    count _this) >=6then {
        
    _occupy _this select 5;
        } else {
        
    _occupy false;};

    _bldgArray = [];
    _tempArray = [];
    _bldgLoc = [];
    _bldgSelect = [];
    _searchersT = [];
    _searchers = [];
    _searcherCount 0;
    _s 0;

    // error catching
    if (isNil "_leader"exitWith
    {
        
    diag_log text "No valid leader selected!";
        
    false
    };
    if (
    isNil "_srchRad"then {_srchRad 50};
    if (
    _srchRad 1then {_srchRad 1};
    if (
    isNil "_whichOne"then {_whichOne "RANDOM"};
    if ((
    _whichOne != "NEAREST") || (_whichOne != "RANDOM")) then {_whichOne "RANDOM"};
    if (
    isNil "_initialPos"then {_initialPos _ldrPos};
    if ((
    typeName _initialPos) == "OBJECT"then {_initialPos getPos (this select 3)};
    if ((
    typeName _initialPos) != "ARRAY"then {_initialPos _ldrPos};
    if (
    isNil "_andOne"then
    {
        if ((
    count (units _group)) < 3then
        
    {
            
    _andOne true;
        }
        else
        {
            
    _andOne false;
        };
    };
    if ((
    typeName _andOne) != "BOOL"then {_andOne false};
    if (
    isNil "_occupy"then {_occupy false};
    if ((
    typeName _occupy) != "BOOL"then {_occupy false};

    // gets time that script starts
    _checkTime daytime;

    // remove group's waypoints
    _wpArray waypoints _group;
    //_currWP = currentWaypoint _group;
    _wpCnt count _wpArray;

    if (
    _wpCnt 1then
    {
        for [{
    _d 0}, {_d <= _wpCnt}, {_d _d 1}] do
            {
                
    deleteWaypoint [_group_d];
            };
    };

    // building check
    _tempArray nearestObjects [_initialPos, ["HOUSE"], _srchRad];
    _t count _tempArray;  // count number of buildings in array

    //for each building, find building position
    //this should serially select each building in the array, then remove it if position 0 (1) is 0,0,0

    _t _t 1;

    for [{
    _b 0},{_b <= _t},{_b _b+1}] do
    {
        
    _bldg _tempArray select _b;
        
    _bldgPos _bldg buildingPos 0;

        if (((
    _bldgPos select 0) != 0) && ((_bldgPos select 1) != 0)) then
         
    {
         
    _bldgArray _bldgArray + [_bldg];
         };
    };

    _bldgCnt count _bldgArray;
    if (
    _bldgCnt == 0exitWith 
    {
        
    diag_log text "No buildings to search!";
        
    false
    };

    // select building - either the nearest or the randomest
    if (_whichOne == "NEAREST"then
    {
        
    _bldgSelect _bldgArray select 0;        // need to do a real distance check?
        //_bldgSelect = nearestBuilding (getPos _leader);
    }
    else
    {
        
    _bldgSelect _bldgArray call BIS_fnc_selectRandom;
    };

    _bldgLoc getPos _bldgSelect;

    if (
    JTD_searchDebugthen
    {
        
    _nameMarker format ["srch_%1"str _bldgSelect];
        
    _marker createMarkerLocal [_nameMarker, [_bldgLoc select 0_bldgLoc select 1]];
        
    _marker setMarkerShapeLocal "ICON";
        
    _marker setMarkerTypeLocal "dot";
        
    _marker setMarkerColor "ColorRed";
    };

    // set new waypoint for near the building for the group
    _bldgBB boundingBox _bldgSelect;        // [[minX, minY, minZ], [maxX, maxY, maxZ]] 
    _wpRad = ((abs((_bldgBB select 0select 0) + abs((_bldgBB select 1select 0)) max (abs((_bldgBB select 0select 1) + abs((_bldgBB select 1select 1))) + 10;    // gets the longest side of the building + 10
    _wp _group addWaypoint [_bldgLoc_wpRad];
    _wp setWaypointPosition [_bldgLoc1];
    _wp setWaypointType "MOVE";
    _group setCurrentWaypoint _wp;

    //_group lockwp true;
    waituntil {unitready _leader};

    _group setbehaviour "combat";

    // find building position max
    _p 0;        // will end up being the total number of building positions
    while {str(_bldgSelect buildingPos _p) != "[0,0,0]"} do {_p _p 1;};

    // check if more units than positions (or equal), if so, select which ones to search
    // gets the lesser of available units or positions

    _totTime _p .009;        // roughly 30 seconds per position
    scopeName "bldgSearchMainScope";
    // loop through each unit to identify the searchers
    if (_andOnethen
    {
        
    _searcherCount = (count (units _group)) min _p;
        
    _s 0;
    }
    else
    {
        
    _searcherCount = ((count (units _group)) - 1min _p;
        
    _s 1;
    };
    //diag_log text format ["searchers = %1  (%2, %3)", _searcherCount, ((count (units _group)) - 1), _p];
        
    while {_s <= _searcherCount} do
        {
            if !(
    isNull ((units _groupselect _s)) then
            
    {
                
    // start at #2 (which is select 1) and add searchers up to number of house positions
                
    _searchersT _searchersT + [(units _groupselect _s];
            };
            
    _s _s 1;
        };

    // shuffle
    //diag_log text format ["searcher temp array = %1", _searchersT];
    _searchers = [_searchersTcall JTD_arrayShuffleFunc;
    //diag_log text format ["searcher array = %1", _searchers];
    // loop to string out the units

    _activeBP 0;        // building position iterator
    while {_activeBP _p} do
    {
        
    _s 0;            // searcher iterator
        
    _loop 0;
        
    // searcher assignment loop
        
    _cycle _activeBP;    // cycle through searchers based on house position number
        
    while {_loop <= _activeBP} do
        {
            
    _bldgPos _bldgSelect buildingPos _cycle;
            
    _unitSelect _searchers select _s;
            
    //diag_log text format ["unit select %1 bpos %2 %3", _unitSelect, _bldgPos, _cycle];
             
    if (unitready _unitSelectthen
            
    {
                
    _unitSelect commandmove _bldgPos;
                
    //_unitSelect domove _bldgPos;
                
    _unitSelect spawn 
                
    {
                    
    sleep 5;
                    
    waituntil {unitready _this};        // try without this, too?
                
    };
            };
            
    _s _s 1;
            if (
    _s >= (count _searchers)) then {_loop _activeBP};    // break out of loop if out of searchers
            
    _cycle _cycle 1;
            
    _loop _loop 1;
            
            
    // time check
            
    if (daytime > (_checkTime _totTime)) then
            
    {
                
    breakTo "bldgSearchMainScope";
                if (
    JTD_searchDebugthen
                
    {
                    
    diag_log text "Building search taking too long, exiting";
                };
            };
            if (! 
    alive (leader group (_searchers select _s))) then
            
    {
                
    breakTo "bldgSearchMainScope";
                
    _occupy false;
                if (
    JTD_searchDebugthen
                
    {
                    
    diag_log text "No leader of search group";
                };
            };
        };
        
    _activeBP _activeBP 1;
    };

    //diag_log text "Out of bldgSearch loop";

    _group setbehaviour _behaviour;

    // check if occupy is specified
    if !(_occupythen
    {

        
    // need some sort of wait to make sure they are ready
        //waituntil {sleep 3; {unitready _x} count _units == count (units _group) - 1};
        
    _ldrPos getPos _leader;
        {
            
    //diag_log text format ["srcher loop  %1", _x];
            
    _x doMove _ldrPos;
            
    waitUntil {moveToCompleted _x};
            
    _x doFollow _leader;

        } foreach 
    _searchers;
    };
    // waituntil ??

    //_group lockwp false;
    JTD_lockedSearchGroups JTD_lockedSearchGroups - [_group];
    //diag_log text "bldg srch ended";
    true 
    Edit:
    The arrayShuffle script that is also necessary now:
    PHP Code:
    // JTD_arrayShuffle

    private ["_array""_count""_arrayT""_arrayN""_c""_r"];

    _array _this select 0;
    _count count _array;
    _arrayN = [];
    _arrayT = [];
    _c 0;
    _r 0;

    while {
    _c < (count _array)} do
    {
        while {
    _r in _arrayT} do
        {
    _r floor (random (count _array));
        };
        
    _arrayT _arrayT + [_r];
        
    _arrayN set [_c_array select _r];
        
    _c _c 1;
    };

    _arrayN 
    Block search script:
    PHP Code:
    // JTD block search

    private ["_groupSelect""_posSelect""_radSrch""_houseArray""_c""_searchFunc""_nameMarker""_marker"];

    diag_log "Block search started";

    if (
    isNil "JTD_bldgSearchFunc"then
    {
        
    JTD_bldgSearchFunc compile preprocessFileLineNumbers "JTD_buildingSearch.sqf";
    };

    // needs group, position and radius
    _groupSelect _this select 0;
    if ((
    typeName (_groupSelect)) == "OBJECT"then {_groupSelect group (_this select 0)};
    _posStart _this select 1;
    _radSrch _this select 2;
    _houseArray = [];
    _c 0;
    diag_log text format ["groupSelect: %1"_groupSelect];


    while {
    alive (leader _groupSelect)} do
    {
        
    // building check
        
    _houseArray nearestObjects [_posStart, ["HOUSE"], _radSrch];

        {
            
    _posSelect getPos _x;
                
    diag_log text format ["selected position: %1"_posSelect];
            
    _searchFunc = [_groupSelect10"NEAREST"_posSelecttruefalseexecVM "JTD_buildingSearch.sqf";
            if (
    JTD_searchDebugthen
            
    {
                
    _c _c 1;
                
    _nameMarker format ["srch_%1"str _c];
                
    _marker createMarkerLocal [_nameMarker, [_posStart select 0_posStart select 1]];
                
    _marker setMarkerShapeLocal "ICON";
                
    _marker setMarkerTypeLocal "dot";
                
    _marker setMarkerSizeLocal [1010];
                
    _marker setMarkerColor "ColorGreenAlpha";
            };        
            
    waituntil {scriptDone _searchFunc};
        } forEach 
    _houseArray;
        
    sleep (random 60) + 60;
    }; 
    This is very much a Work In Progress, but the 7z contains a test mission and the current version of the script. With the test mission, the player has a couple minutes to move around. An array of his positions is created. The 6 opfor groups will randomly select one of those positions and search a nearby building. The mission is rather slow (there is also a playable civilian, if you want to watch), but you can get an idea of how it works.

    The parameters used in the mission are:
    _searchFunc = [_grpSelect, 20, "NEAREST", _posSelect] call JTD_bldgSearchFunc;

    Edit: there are several now!

    Oh, and the mission will spam your rpt with information. That's why it is a test mission.

    Feedback is greatly appreciated.

    ============================
    JTD:
    -- DMarkwick
    -- ReconPathFinder
    -- TRexian
    Last edited by TRexian; Jan 24 2011 at 14:38.

  2. #2
    If there is enemies inside, would they engage them?

  3. #3
    Master Gunnery Sergeant TRexian's Avatar
    Join Date
    Jun 7 2007
    Posts
    1,226
    Author of the Thread
    That depends on certain AI settings, but from my own experience, they sure shoot me!

    Now, having said that, I usually run the betas, and some betas have the AI more aggressive than others. With one of the recent patches, I could (as blufor) walk around and through a group of opfor for several seconds before getting shot. With the most recent one, though (the one from yesterday), I was shot almost immediately.

    This script will put the group into combat mode. However, it is also dependent on the ROE/weapons free status, which this script does not change. Also, if they are engaged from outside the building during the search, they will react according to the BI FSMs for contact.

    I have not explored all the permutations of what happens during significant contact during the search. With the test mission, I am eventually tracked down, and can take out a couple of the searchers, but am relatively soon afterward killed.

    But, I am not a particularly good player.

  4. #4
    Downloaded, and its fucking awesome!

  5. #5
    Master Gunnery Sergeant TRexian's Avatar
    Join Date
    Jun 7 2007
    Posts
    1,226
    Author of the Thread
    haha

    Thanks, but don't worry - that feeling will wear off.

    When you get to the point where you have ideas on how to improve it, let us know.

  6. #6

  7. #7
    Warrant Officer Demonized's Avatar
    Join Date
    Nov 16 2010
    Location
    Back from afk 2013
    Posts
    2,614
    This looks very promising

    Downloading for sure
    My scripts:
    Spoiler:

    what to do when posting any kind of code dammit!!

    Any new mission editor or scripter in Arma2 should have read Mr Murrays Editing Guide Deluxe at least once, it still applies for A2 even though it was made for Armed Assault.

  8. #8
    great! Will this be initialised by default in any misison or does it have to be activated by the creator of the mission?

  9. #9
    Master Gunnery Sergeant TRexian's Avatar
    Join Date
    Jun 7 2007
    Posts
    1,226
    Author of the Thread
    Thanks Foxhound!

    It must be initiated by the mission creator. In fact, I'd say it is probably for somewhat advanced mission makers, although I tried to make it as easy as possible.

    The main problem is, what to do with groups after the search? Any existing waypoints are deleted, so new ones have to be re-generated.

    I suspect that one thing I will need to develop is a 'wrapper' of some sort that allows mission makers to easily craft after-search behavior. Perhaps the easiest way is to have a waypoint that runs the script, after which the group returns to the waypoint system.

    Or, as DMarkwick has tried, I believe it can integrate rather well with DAC3 behavior.

  10. #10
    Warrant Officer Demonized's Avatar
    Join Date
    Nov 16 2010
    Location
    Back from afk 2013
    Posts
    2,614
    I suspect it will work very well with ups and upsmon aswell since those create their own wps in runtime, when current wp/wps are completed.

Page 1 of 11 12345 ... LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •