Jump to content
Sign in to follow this  
yoannis1995

Clear house script

Recommended Posts

I'm trying to make a script that allows you to order an AI to clear a building. But i'm having some troubles...

I use the command cursorTarget to get the ID of the building. But with that command, how can i check if it is a building with pre-defined positions and how can i list the positions of the building in an array ?

Share this post


Link to post
Share on other sites

You need to have a look at the buildingpos command http://community.bistudio.com/wiki/buildingPos

if (((your_building buildingpos 0) select 0) != 0) then {the building has more than one buildingpos ie is enterable}

_buldingpositions = your_building buildingpos; //_buildingpositions is an array with all the pre-definted positions in that building

Share this post


Link to post
Share on other sites

Thanks :) but it doesn't seem to work if i do:

_building = cursorTarget;
_buildingpositions = _building buildingpos;

Because it seems that the "CursorTarget" doesn't return only the ID of the object but also the class of the object when I try to make an "hint" with it.

So how can I just get the ID of the building ?

Edited by yoannis1995

Share this post


Link to post
Share on other sites

what does the hints shows?

try this:

_building = cursorTarget select _x;

_buildingpositions = _building buildingpos;

where _x its the number where you desired value it's(starting for 0)

example(never tried so i dont know what will it show up ,so it's just for example)

[villa_7,78890,56,24,0]

if you want the classname would be select 0... if you want the second number select 1...

Share this post


Link to post
Share on other sites

shouldn't it be

_building = cursorTarget;

_buildingpositions = _building buildingpos _x;

if _x was 0 it should return the X,Y,Z of that position.

if it returns [0,0,0] there is no position.

Edited by F2k Sel

Share this post


Link to post
Share on other sites

So now the "_buidingpositions" is an array and I can use it to make a unit go to each positions of the building with the command "forEach" ?!

I just tried that:

_building = cursorTarget; 
if (((_building buildingpos 0) select 0) != 0) then
{ hint format['ID: %1',_building]; 
_buildingpositions = _building buildingpos _x;
{s1 doMove buildingPos _x; 
waitUntil {moveToCompleted s1;}} forEach _buildingpositions;
} else {hint"The selected object is not available.";};

but it doesn't really work... :/

Edited by yoannis1995

Share this post


Link to post
Share on other sites

Take a look at this link http://forums.bistudio.com/showthread.php?102796-Get-number-of-building-positions&highlight=count+buildingpos I've only looked at the post from Twirly

.

With a little addition I made it search using cursortarget to obtain the building. It's only an example but does work.

 _cnt = 0;
  _posarray = [];

     while {true} do {

_build = cursortarget;


   //as long as building position _cnt not equal to "[0,0,0]" keep looping
  while {format ["%1", _build buildingpos _cnt] != "[0,0,0]" } do {

       _pos = _build buildingpos _cnt;        //select building position _cnt
       _posarray = _posarray + [_pos];        //add the position to the list

       _cnt = _cnt + 1;        //increment counter
       sleep 0.01;
   };  
   sleep 0.01;
 {

   s1 doMove   _x; 

waitUntil {moveToCompleted s1};
sleep 0.1;

} forEach _posarray;

   sleep 0.01;
};

Hint "search compelete";

Share this post


Link to post
Share on other sites

Thanks :) it works :)

but there's still one problem left, the loop never ends so the guy just walk from the 1st position to the last and then back again to the 1st....

So is there any possibility to know what's the last building's position ?! Or another way to stop that ?

Share this post


Link to post
Share on other sites

Oh I forgot you need to remove the first while while {true} do { and the last {.

You also want to add

s1 domove getpos player;

so the unit returns.

When you've done that you now need to use look for the commands that will allow you send your selected units to do the search.

I can't remember the commands off hands and I'm out of time right now.

Edited by F2k Sel

Share this post


Link to post
Share on other sites

Oh yes thanks :) didn't see that ^^

Well I found the command http://community.bistudio.com/wiki/groupSelectedUnits

but the matter is how can we add a command in the commande menu ?! or should I put the call script command in a radio trigger ?!

This is my code now:

_cnt = 0; 
_posarray = []; 
_unit = _this select 0;
_caller = _this select 1;
_id = _this select 2;
_unit removeAction _id;
_GroupLeader = leader (group _unit);

_build = cursortarget; 


   //as long as building position _cnt not equal to "[0,0,0]" keep looping 
  while {format ["%1", _build buildingpos _cnt] != "[0,0,0]" } do { 

       _pos = _build buildingpos _cnt;        //select building position _cnt 
       _posarray = _posarray + [_pos];        //add the position to the list 

       _cnt = _cnt + 1;        //increment counter 
       sleep 0.01; 
   };   
   sleep 0.01; 
_unit setBehaviour "COMBAT";
_unit setCombatMode "RED";
_unit setSpeedMode "LIMITED";
 { 

      _unit doMove   _x;  

waitUntil {moveToCompleted _unit}; 
sleep 0.5; 

} forEach _posarray; 

   sleep 2; 
if (alive _unit) then {
_unit groupChat "Building clear !"; 
sleep 1;
_unit addAction ["Clear house", "clear.sqf"];
sleep 1;
_unit doMove (postition _GroupLeader);
};

And I put that in the init of the player

{_x addAction ["Clear house", "clear.sqf"]} forEach units group this;

Then to activate the script you select the unit and you go to the action menu of that unit and it works :)

But it would be goob to be able to use directly the command menu to be able to send more than one unit.

And there's another problem, I tried to put an ennemy unit inside a building and even in combat mode, the unit that clears the building get killed really easily. I don't know how to fix that ?!

Share this post


Link to post
Share on other sites

It's better:

waitUntil {sleep 1; (unitReady _unit || moveToCompleted _unit || moveToFailed _unit || !alive _unit)};

Share this post


Link to post
Share on other sites

Now using custom menu's

save as clear.sqf

_cnt = 0; 
_posarray = []; 
_unitL = _this select 0; // player
_unitS = _this select 1; // Units selected
//_id = _this select 2;
//_unit removeAction _id;
_GroupLeader = leader (group _unitL);

_build = cursortarget; 


   //as long as building position _cnt not equal to "[0,0,0]" keep looping 
  while {format ["%1", _build buildingpos _cnt] != "[0,0,0]" } do { 

       _pos = _build buildingpos _cnt;        //select building position _cnt 
       _posarray = _posarray + [_pos];        //add the position to the list 

       _cnt = _cnt + 1;        //increment counter 
       sleep 0.01; 
   };   


 // adjust Unit Skills
   sleep 0.01; 
   _unit setBehaviour "COMBAT";
   _unit setCombatMode "RED";
   _unit setSpeedMode "LIMITED";
 //////////////////////  


 { 
 _temp_x = _x;
      { _x  doMove   _temp_x; } foreach _units; // all units selected  

waitUntil {sleep 1; (unitReady (_unitS select 0) || moveToCompleted (_unitS select 0)  || moveToFailed (_unitS select 0) || !(alive (_unitS select 0)))};

sleep 0.5; 

} forEach _posarray; 

   sleep 2; 
if (alive (_unitS select 0)) then {
(_unitS select 0) groupChat "Building clear !"; 
sleep 1;
// _unit addAction ["Clear house", "clear.sqf"];
sleep 1;
{ _x doMove position _GroupLeader; } foreach _unitS ;
};  

dave as clear_menu.sqf

sleep 1;
[] call BIS_fnc_commsMenuCreate;

CUSTOM_menu = [
["Rank",false],
["Added Options",[2],"#USER:Rank_menu",-5,[["expression",""]],"1","1"]
];

// "NotEmpty" = greyed out if no unit selected.

Rank_menu = [
["Bottom_title",false],
["1 Clear House",[],"",-5,[["expression","nul=[player,(groupSelectedUnits player),'PRIVATE',0] execVM 'clear.sqf'"]],"1","NotEmpty"]
];

 BIS_MENU_GroupCommunication = [
[localize "", false],["Clear House",[2],"#USER:Rank_menu",-5,[["expression",""]],"1","1"]
];

if (true) exitWith {hint "I'm out of here"};// remove hint (testing only).

start it by placing null=[] execvm "clear_menu.sqf" in an init

I'm not sure how well the waituntil movetocompleted part will work as it's only really checking one unit.

Edited by F2k Sel

Share this post


Link to post
Share on other sites

Thanks guy, works well :)

I'm now reading some more about "BIS_fnc_commsMenuCreate" fonctions and stuff to improve the script.

But there's still on main problem left.... the IA sucks at clearing building :p they get killed really easily after comming in a building even if they're 3 and there's only 1 ofpor inside....

Share this post


Link to post
Share on other sites

I haven't really tested that although it may be worth looking at the enemy skill levels and reducing it. You could make your AI slightly tougher when inside so they can take more hits.

setskill

http://www.ofpec.com/COMREF/index.php?action=details&id=739&game=All

Tougher units

http://forums.bistudio.com/showthread.php?134872-How-to-increase-a-unit-vehicle-s-health-to-200-or-more&highlight=eventhandler+damage

Share this post


Link to post
Share on other sites

Thanks, quite helpful :) Is there any possibility to list the OPFOR inside the building ? Then we could add them at the known target of the selected units before making then going into the building, which could help no ?!

Share this post


Link to post
Share on other sites

You could make an array of nearestobjects or use a trigger with thislist containing the array. There's also bounding box that you could use to get the size of the building but whatever method you use you may always catch the odd one outside.

Share this post


Link to post
Share on other sites

Yes thanks, i'm gonna try :)

I tried to make the IA a bit better but now the script doesn't work anymore, the units don't move.

What's the problem in that:

_cnt = 0; 
_posarray = []; 
_unitL = _this select 0; // player
_unitS = _this select 1; // Units selected
//_id = _this select 2;
//_unit removeAction _id;
_GroupLeader = leader (group _unitL);

_build = cursortarget; 


   //as long as building position _cnt not equal to "[0,0,0]" keep looping 
  while {format ["%1", _build buildingpos _cnt] != "[0,0,0]" } do { 

       _pos = _build buildingpos _cnt;        //select building position _cnt 
       _posarray = _posarray + [_pos];        //add the position to the list 

       _cnt = _cnt + 1;        //increment counter 
       sleep 0.01; 
   };   

{ 
{ // adjust Unit Skills
   sleep 0.01; 
   _x setBehaviour "AWARE";
   _x setCombatMode "YELLOW";
   _x setSpeedMode "LIMITED";
_x setSkill ["aimingAccuracy",1];
_x setSkill ["aimingShake",1];
_x setSkill ["endurance",1];
_x setSkill ["aimingSpeed",1];
_x setSkill ["spotDistance",1];
_x setSkill ["spotTime",1];
_x setSkill ["courage",1];
_x setSkill ["reloadSpeed",1];
_x setSkill ["commanding",1];
_x setSkill ["general",1];
 //////////////////////   
 _temp_x = _x;
  _x  doMove   _temp_x;  // all units selected  

// this needs work as it's only checking one unit 
waitUntil {sleep 1; (unitReady (_x select 0) || moveToCompleted (_x select 0)  || moveToFailed (_x select 0))};
} foreach _units;
sleep 0.5; 

} forEach _posarray; 

   sleep 2; 
if (alive _units) then {
_unit groupChat "Building clear !"; 
sleep 1;
// _unit addAction ["Clear house", "clear.sqf"];
sleep 1;
_units doMove position _GroupLeader;
};  

Share this post


Link to post
Share on other sites

You messed up the foreach and the waitunti _x in there won't work.

It's working again now but I've found another problem. They often skip the room with the enemy in, I assume it's because that position is occupied.

_cnt = 0; 
_posarray = []; 
_unitL = _this select 0; // player
_unitS = _this select 1; // Units selected
//_id = _this select 2;
//_unit removeAction _id;
_GroupLeader = leader (group _unitL);

_build = cursortarget; 


   //as long as building position _cnt not equal to "[0,0,0]" keep looping 
  while {format ["%1", _build buildingpos _cnt] != "[0,0,0]" } do { 

       _pos = _build buildingpos _cnt;        //select building position _cnt 
       _posarray = _posarray + [_pos];        //add the position to the list 

       _cnt = _cnt + 1;        //increment counter 
       sleep 0.01; 
   };   

{ 
 _temp_x = _x;
{ // adjust Unit Skills
   sleep 0.01; 
   _x setBehaviour "AWARE";
   _x setCombatMode "YELLOW";
   _x setSpeedMode "LIMITED";
   _x setSkill ["aimingAccuracy",1];
   _x setSkill ["aimingShake",0];
   _x setSkill ["endurance",1];
   _x setSkill ["aimingSpeed",1];
   _x setSkill ["spotDistance",1];
   _x setSkill ["spotTime",1];
   _x setSkill ["courage",1];
   _x setSkill ["reloadSpeed",1];
   _x setSkill ["commanding",1];
   _x setSkill ["general",1];
 //////////////////////   

  _x  doMove   _temp_x;  // all units selected  
} foreach _units;
// this needs work as it's only checking one unit 
waitUntil {sleep 1; (unitReady (_unitS select 0) || moveToCompleted (_unitS select 0)  || moveToFailed (_unitS select 0))};

sleep 0.5; 

} forEach _posarray; 

   sleep 2; 


if ({alive _x} count _unitS != 0) then {
(_unitS select 0)  groupChat "Building clear !"; 
};


{
// _unit addAction ["Clear house", "clear.sqf"];
sleep 1;
_x doMove position _GroupLeader;
}  foreach _unitS;  

Share this post


Link to post
Share on other sites
It's working again now but I've found another problem. They often skip the room with the enemy in, I assume it's because that position is occupied.

Would there be a way to check whether a unit has skipped a position (if _currentslotinPositionarray - _lastslotinPosition array >1 then..)?; and somehow (knowsAbout?) 'tell' the unit there's an enemy at that position?

There would still perhaps be an issue that the unit won't/can't enter the room because the only position is occupied.

Share this post


Link to post
Share on other sites

The AI reports that he can't get there so it may be possible to change the position to a simple move.

You could use reveal command to alert the AI.

Also I think it may be useful for the AI to do other things such as turn 360 randomly so it looks like it's searching.

Share this post


Link to post
Share on other sites

Ah, I didn't know you got a report. Reveal - of course, I forgot the name! (every time I've searched the BiKi today I've had error 504, Gateway timeout).

Turning randomly might be a bit hazardous if there are enemies wandering around inside the building.

Hmm - is there a command to make a unit move it's head (i.e., look) from side to side without changing direction? (I'm also interested in that as I want to make some members of an AI-led team "scan horizon").

Share this post


Link to post
Share on other sites

you can use setformdir, they will turn but if they see an enemy they will engage and stop turning, it all needs test but I'm so short of time right now.

Isn't there a house clear script already done, I'm sure I've seen one but never tested it.

Share this post


Link to post
Share on other sites

Thanks, F2k Sel! - no worries, I'll check it out. And I want them to stop turning & engage the enemy so it's great that the engine will take over :)

I think you're right, indeed there may be more than one. I'll see what I have bookmarked.

Share this post


Link to post
Share on other sites

@yoannio1995: have a look at JTD's Building search script

@F2KSel: setFormdir doesn't look like the answer to my question, I want an AI group to carry on to its waypoint but with some of the squad dong the equivalent of the "Scan horizon" for human-led teams - that is, turning their heads from one side to the other to look for enemies. Damn, I think it's another of those engine commands/functions that are not public domain :(

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  

×