Jump to content
sizraide

AI not spawning inside buildings

Recommended Posts

Hello,

 

I created a script to spawn an AI in every building near the location with a marker on that unit. 

 

The problem is that the AI is not spawning and I don't see any markers on the map.

 

Here is my script:

_marker = _this select 0;
_markerSize = ((getMarkerSize _marker) select 0);
_markerPos = getMarkerPos _marker;

_aafUnits = 
[
    "AAF_Soldier",
    "AAF_Soldier_GL",
    "AAF_Soldier_AR",
    "AAF_Soldier_AT",
    "AAF_Soldier_Medic",
    "AAF_Sniper"
];

_nearbyBuildings = nearestObjects [_markerPos, ["House"], _markerSize];
_housesSelected = [];

{
	_object = typeOf _x;
	_hasKeyword = false;

	if (isClass (configFile >> "CfgVehicles" >> _object)) then
	{
		{ if (_object find _x > -1) then { _hasKeyword = true; }; } forEach ["House", "Building", "Shop", "Shed"];
		if (_hasKeyword) then { _housesSelected pushBack _x; };
	};
} forEach _nearbyBuildings;

_amount = floor (count _housesSelected / 2);
_housesChosen = [];

for "_i" from 1 to _amount do
{
	_house = selectRandom _housesSelected;
	_housesChosen pushBack _house;
	_housesSelected = _housesSelected - [_house];
};

hint str _housesChosen;

{
	_unit = (createGroup INDEPENDENT) createUnit [str (selectRandom [_aafUnits]), getPos _x, [], 0, "none"];
	_unit setPos (selectRandom (_x buildingPos - 1));
	_unit setDir (random 360);

	_marker = createMarkerLocal [format ["BuildingMarker%1", _forEachIndex], _unit];
	_marker setMarkerShapeLocal "ICON";
	_marker setMarkerTypeLocal "mil_dot";
} forEach _housesChosen;

 

Share this post


Link to post
Share on other sites
11 hours ago, sizraide said:

"AAF_Soldier", "AAF_Soldier_GL", "AAF_Soldier_AR", "AAF_Soldier_AT", "AAF_Soldier_Medic", "AAF_Sniper"

You sure about those classnames? BIS have a tendency to end their official classes with "_F"

 

You can get the classes by:

1. Place the units in the editor

2. Select them all and right click one of them

3. Click Log > Classes to clipboard

4. Open your favorite text editor or the debug console and paste the contents there.

 

If that's not it then start printing debug message with either systemChat, hint or diag_log to find where it breaks.

  • Like 1

Share this post


Link to post
Share on other sites
1 hour ago, mrcurry said:

You sure about those classnames? BIS have a tendency to end their official classes with "_F"

 

You can get the classes by:

1. Place the units in the editor

2. Select them all and right click one of them

3. Click Log > Classes to clipboard

4. Open your favorite text editor or the debug console and paste the contents there.

 

If that's not it then start printing debug message with either systemChat, hint or diag_log to find where it brakes.

Yes, that was stupid of me to not check the classes. I fixed it since but it still doesn't work.

 

Here is my script.

Spoiler

_marker = _this select 0;
_markerSize = ((getMarkerSize _marker) select 0);
_markerPos = getMarkerPos _marker;

_aafUnits = 
[
    "I_Soldier_A_F",
    "I_Soldier_AR_F",
    "I_Soldier_exp_F",
    "I_Soldier_GL_F",
    "I_Soldier_M_F",
    "I_Soldier_F",
	"I_Soldier_LAT2_F"
];

_nearbyObjects = nearestObjects [_markerPos, ["House"], _markerSize];
_housesArray = [];

{
	_object = typeOf _x;
	_hasKeyword = false;

	if (isClass (configFile >> "CfgVehicles" >> _object)) then
	{
		{ if (_object find _x > -1) then { _hasKeyword = true; }; } forEach ["House", "Building", "Shop", "Shed"];
		if (_hasKeyword) then { _housesArray pushBack _x; };
	};
} forEach _nearbyObjects;

_amount = (count _housesArray) / 2;

for "_i" from 1 to _amount do
{
	_house = selectRandom _housesArray;
	_housePos = (selectRandom (_house buildingPos -1)); // Get random position inside building

	_group = createGroup [resistance, true];
	_classUnit = str (selectRandom [_aafUnits]);

  	// _unit = _group createUnit [_classUnit, _housePos, [], 0, "NONE"];
  
  	// Spawn marker on every unit created
	_marker = createMarker ["Marker_Unit_" + str _i, getPos _unit];
	_marker setMarkerType "hd_dot";
	_marker setMarkerAlpha 1;
	_marker setMarkerColor "ColorRed";

	_housesArray = _housesArray - [_house]; 
};

 

 

Share this post


Link to post
Share on other sites
str (selectRandom [_aafUnits])

You are string-ing a string and array-ing an array.

selectRandom _aafUnits

You also used the local var "_marker" twice. With a few tweaks, your original works fine (your newer version does not avoid re-using houses/house positions):

private _marker = _this select 0; 
private _markerSize = ((getMarkerSize _marker) select 0);
private _markerPos = getMarkerPos _marker;

private _aafUnits = 
[
	"I_Soldier_A_F",
	"I_Soldier_AR_F",
	"I_Soldier_exp_F",
	"I_Soldier_GL_F",
	"I_Soldier_M_F",
	"I_Soldier_F",
	"I_Soldier_LAT2_F"
];

private _nearbyBuildings = nearestObjects [_markerPos, ["House"], _markerSize];
private _housesSelected = [];

{
	private _object = typeOf _x;
	private _hasKeyword = false;

	if (isClass (configFile >> "CfgVehicles" >> _object)) then
	{
		{ if (_object find _x > -1) then { _hasKeyword = true; }; } forEach ["House", "Building", "Shop", "Shed"];
		if (_hasKeyword) then { _housesSelected pushBack _x; };
	};
} forEach _nearbyBuildings;

private _amount = floor (count _housesSelected / 2);
private _housesChosen = [];

for "_i" from 1 to _amount do
{
	private _house = selectRandom _housesSelected;
	_housesChosen pushBack _house;
	_housesSelected = _housesSelected - [_house];
};

{ 
	private _grp = createGroup independent;
	private _type = selectRandom _aafUnits;
	private _unit = _grp createUnit [_type, [0,0,100], [], 0, "NONE"]; 
	_unit setPos (selectRandom (_x buildingPos - 1)); 
	_unit setDir (random 360); 

	private _name = format ["BuildingMarker%1", _forEachIndex];
	private _mkr = createMarkerLocal [_name, _unit]; 
	_mkr setMarkerShapeLocal "ICON"; 
	_mkr setMarkerTypeLocal "mil_dot"; 
	_mkr setMarkerColor "ColorRed";
} forEach _housesChosen;

There is likely room for streamlining/optimization, but this tests fine.

  • Like 1

Share this post


Link to post
Share on other sites
5 minutes ago, Harzach said:

str (selectRandom [_aafUnits])

You are string-ing a string and array-ing an array.


selectRandom _aafUnits

You also used the local var "_marker" twice. With a few tweaks, your original works fine (your newer version does not avoid re-using houses/house positions):


private _marker = _this select 0; 
private _markerSize = ((getMarkerSize _marker) select 0);
private _markerPos = getMarkerPos _marker;

private _aafUnits = 
[
	"I_Soldier_A_F",
	"I_Soldier_AR_F",
	"I_Soldier_exp_F",
	"I_Soldier_GL_F",
	"I_Soldier_M_F",
	"I_Soldier_F",
	"I_Soldier_LAT2_F"
];

private _nearbyBuildings = nearestObjects [_markerPos, ["House"], _markerSize];
private _housesSelected = [];

{
	private _object = typeOf _x;
	private _hasKeyword = false;

	if (isClass (configFile >> "CfgVehicles" >> _object)) then
	{
		{ if (_object find _x > -1) then { _hasKeyword = true; }; } forEach ["House", "Building", "Shop", "Shed"];
		if (_hasKeyword) then { _housesSelected pushBack _x; };
	};
} forEach _nearbyBuildings;

private _amount = floor (count _housesSelected / 2);
private _housesChosen = [];

for "_i" from 1 to _amount do
{
	private _house = selectRandom _housesSelected;
	_housesChosen pushBack _house;
	_housesSelected = _housesSelected - [_house];
};

{ 
	private _grp = createGroup independent;
	private _type = selectRandom _aafUnits;
	private _unit = _grp createUnit [_type, [0,0,100], [], 0, "NONE"]; 
	_unit setPos (selectRandom (_x buildingPos - 1)); 
	_unit setDir (random 360); 

	private _name = format ["BuildingMarker%1", _forEachIndex];
	private _mkr = createMarkerLocal [_name, _unit]; 
	_mkr setMarkerShapeLocal "ICON"; 
	_mkr setMarkerTypeLocal "mil_dot"; 
	_mkr setMarkerColor "ColorRed";
} forEach _housesChosen;

There is likely room for streamlining/optimization, but this tests fine.

It works great, I appreciate it.

 

Could you give me some sources to optimize code? Or some advice?

Share this post


Link to post
Share on other sites

Optimizing is a matter of fluency, having a command of the language - commands/functions/etc. and how they work (or don't work) together. This comes with experience. Familiarize yourself with the Biki (see links in sig). Every command, function, event handler, etc. is there, with at least the most basic documentation of locality, syntax, and even relevance.

 

If you are having problems with code, follow @mrcurry's advice and add some debugging. Break your code into chunks and make sure each step is executing correctly.

 

And trust me when I say that my command of the language is rudimentary at best. There are many very smart people here who are happy to help, so ask questions!

Share this post


Link to post
Share on other sites
1 hour ago, sizraide said:

Could you give me some sources to optimize code? Or some advice?

 

1 hour ago, Harzach said:

Optimizing is a matter of fluency,

 

1. First make it work 

2. Then make it pretty (easy to understand)

3. Then make it fast 

4. Then ignore 2 and 3 unless forced at gunpoint.

  • Haha 2

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

×