Jump to content

Recommended Posts

A few months ago I had a script that would have a group of AI units fire into an area using a logic as their target, that then changed it's position for each new firer, so that every time a unit fired it would be at a different position within a given area. This used to work, but now I'm trying to use it again without success, as the AI will target and fire at the logic's original position, but no longer target it once it has changed position. The below code is part of what loops through each unit at a set interval while the script is still running.

_logic setPos [(_xPos - _areaSizeX) + (random (_areaSizeX*2)),(_yPos - _areaSizeY) + (random (_areaSizeY*2)),_zPos];

sleep 0.1;
_unit doWatch objNull;
_unit reveal [_logic,4];
_unit doWatch _logic;
_unit doTarget _logic;

Then, once other variables have been set (like weapon/muzzle to fire, number of rounds to fire), the AI fire. This part still works:

while {(_ammo > _endBurst)} do {
	_logic action ["UseWeapon",vehicle _unit,_unit,_index];
	_ammo = _unit ammo _weapon;
	sleep 0.05;
};

So, they end up firing as per normal, but they don't aim at the logic when it changes position (the logic DOES change position correctly). They continue to realign to the logic's original position. Any ideas why?

Share this post


Link to post
Share on other sites

What sort of logic?

Can we have the entire script please?

 

Alright, there's a fair bit in it. The logic is the editor object's Game Logic.

///////
//Set up the SBF mission.
///////
//Server check and variables to private.
///////
//If using a mod, amend _index checks to the mod's grenade launcher index if required.
//Use weaponIndexNumber.sqf (included in sbf.rar) to determine required index.
///////

if (!isServer) exitWith {};

private [
"_shooters","_time","_burstSize","_marker","_target","_areaSizeX","_areaSizeY","_index","_ammoResup",
"_countShooters","_logic","_xPos","_yPos","_zPos",
"_muzzles","_weapon","_ammo","_endBurst","_unit","_x","_currentMag","_countMags","_aliveCheck","_saveBurstSize"
];

///////
//Assign arguments to their variables.
///////

_shooters = _this select 0;
_time = _this select 1;
_burstSize = _this select 2;
_marker = _this select 3;
_target = _this select 4;
_areaSizeX = (_this select 5) select 0;
_areaSizeY = (_this select 5) select 1;
_index = _this select 6;
_ammoResup = _this select 7;

///////
//Adds check for dead AI, used prior to each fire loop.
//Remove any potentially dead AI from _shooters.
//Determine number of shooters.
//Create the logic to use with "useWeapon".
//Record position for the centre of the SBF.
//Add event handler to grenadiers to simulate grenade rounds (avoids random tree bursts and FF).
///////

_aliveCheck = {
	{
		if (!alive _x) then {
			_shooters = _shooters - [_x];
			_countShooters = _countShooters - 1;
		};
	} forEach _shooters;
};

{
	if (!alive _x) then {
		_shooters = _shooters - [_x];
	};
} forEach _shooters;

_countShooters = (count (_this select 0)) - 1; //Returns 1 less than actual shooters, for purpose of _i (0,1 for 2 shooters)
_logic = createGroup west createUnit ["Logic", [0,0,0], [], 0, "NONE"];

_xPos = (getMarkerPos _marker) select 0;
_yPos = (getMarkerPos _marker) select 1;
_zPos = 0;

if (_index == 5) then {
	{call compile format["%1 addEventHandler ['Fired',{nul = [_this,%1,%2] spawn MIL_fnc_SBF_GLA_FIX}]",_x,_target]} forEach _shooters;
};

///////
//Run the SBF mission.
///////
//Each shooter fires an opening shot/burst, equal to _burstSize.
//This "kicks off" the SBF.
///////

{
	_initiation = [_x,_burstSize,_marker,_target,[_areaSizeX,_areaSizeY],_index] spawn MIL_fnc_SBF_Mission_Initiation;
} forEach _shooters;

///////
//Roll into the fire mission for each firer.
///////

while {_countShooters >= 0} do {

	call _aliveCheck;

	for "_i" from 0 to _countShooters do {

		_unit = (_shooters select _i);

		if (_index == 5) then {
			_muzzles = call compile format["getArray(configFile >> 'cfgWeapons' >> (primaryWeapon %1) >> 'muzzles')",_unit];
			_unit selectWeapon (_muzzles select 1);
		};

		_target setPos [(_xPos - _areaSizeX) + (random (_areaSizeX*2)),(_yPos - _areaSizeY) + (random (_areaSizeY*2)),_zPos];
		sleep 0.1;
		_unit doWatch objNull;
		_unit reveal [_target,4];
		_unit doWatch _target;
		_unit doTarget _target;

		if (alive _unit) then {
			uiSleep _time;
			} else {
			uiSleep (random 2)
		};

		if (_burstSize >= 5) then {
			_saveBurstSize = _burstSize;
			_burstSize = (_burstSize - 1) + (round(random 2));
			} else {
			_saveBurstSize = _burstSize;
		};

		_weapon = primaryWeapon _unit;
		_ammo = _unit ammo _weapon;
		_endBurst = ((_unit ammo _weapon) - _burstSize);

		if (_index == 5) then {

			if (alive _unit) then {

				_currentMag = currentMagazine _unit;
				_logic action ["UseWeapon",vehicle _unit,_unit,_index];
				if (_ammoResup) then {
					_unit addMagazine _currentMag;
					};
				} else {};

			} else {
				if ((alive _unit) && (_ammo != 0)) then {
					while {((_ammo > _endBurst) && (_ammo != 0))} do {
						_logic action ["UseWeapon",vehicle _unit,_unit,_index];
						_ammo = _unit ammo _weapon;
						sleep 0.05;
						};

					if (_ammoResup) then {
						_unit setAmmo [currentWeapon _unit,200];
						};
					} else {};
				};
				_burstSize = _saveBurstSize;
			};
		};

_shooters - array of the units doing the firing

_time - seconds between each unit firing

_burstSize - rounds to fire (if it's 5 or more it picks a random +/- 1)

_marker - marker for the centre of the area to be fired into

_target - logic's name

_areaSizeX - x-axis of area to fire into

_areaSizeY - y-axis of area to fire into

_index - muzzle index (usually either 0 for primary or 5 for grenade launchers)

_ammoResup - true/false for unlimited ammo

 

So I'd run this script for all the rifles, gunners and grenadiers. But over the past week I put this into VBS 3 and changed how I ran it, which was more realistic and simple anyway, and wanted to make the same changes here but when I went to confirm it still worked as intended, it failed (WRT the AI not firing at the logic's new positions).

 

The initiation just runs basically a copy of this script, except that it does it once and runs on all units at the same time.

Share this post


Link to post
Share on other sites

Is this a piece of networking code? Or is it just single player?

Also a point to bring up, make it easier on yourself, and not do this...

_logic = createGroup west createUnit ["Logic", [0,0,0], [], 0, "NONE"];

There should be only 1 statement per line in scripts at anyone time. Concatenating 2 or more different commands at once can, be a pain to read. Even for the writer.

What constitutes a statement?

https://community.bistudio.com/wiki/Statement

 

Somewhere something is preventing your AI being aware of the position update. Need more information, if the mission is multiplayer or not?

Tried making sure each thing returns what it is supposed to?
Print / hint / systemChat / diag_log format [ "%1",_someValue]; ?

First thing I do if something isn't working I take note of the code I place this in it.

 


{
    _initiation = [_x,_burstSize,_marker,_target,[_areaSizeX,_areaSizeY],_index] spawn MIL_fnc_SBF_Mission_Initiation;
    diag_log format ["Line Number %1 \n Variable _Shooters %2",__LINE__,_shooters];
} forEach _shooters;

Make sure they actually exist, see your problem is somewhere between.

_logic setPos [(_xPos - _areaSizeX) + (random (_areaSizeX*2)),(_yPos - _areaSizeY) + (random (_areaSizeY*2)),_zPos];

sleep 0.1;
_unit doWatch objNull;
_unit reveal [_logic,4];
_unit doWatch _logic;
_unit doTarget _logic;

And the top of the page,

I can't really help beyond some debugging methods sorry no PC, yet my new one is on the way though.

  • Like 1

Share this post


Link to post
Share on other sites

There should be only 1 statement per line in scripts at anyone time. Concatenating 2 or more different commands at once can, be a pain to read. Even for the writer.

What constitutes a statement?

 

I know what you mean and I usually do that. Can't tell you why I did it like that though, maybe I was just being lazy.

 

The intention was for this to be for MP (as is the VBS 3 version of it now) and back when it was working it did function correctly in an MP environment when I tested it (I ran everything local to the server I believe... but I may be lying), but at the moment I'm only running it in SP again. Everything seems to work correctly, including units targeting the correct logic..... If I've changed anything since I had it working a while ago I certainly don't remember doing it, and I've been back through and taken out as much as I can concerning AI behaviour (like any disableAI I was running on them). Might be worth rebuilding from scratch if I can't get a handle on the aiming. If only it were as simple as having the same code across both games.

 

I can't really help beyond some debugging methods sorry no PC, yet my new one is on the way though.

 

 

Congrats on the new PC btw. I built a new one less than 6 months ago.

Share this post


Link to post
Share on other sites

yeah VBS 3.0 is very different from ArmA 3, a lot of commands in VBS 3,0 are not present in arma 3.
My Machine is massive lets say that. It involves having a Corsair 900D Supertower case and
A thermltake F6 Commander fancontroller and Noctua NF-A14 x 3 IP 67 fans and NF-F12 x 3 IP 67 connected to the F6 fan controller. Each 2000RPM each with stablising rubber standoffs.

  • Like 1

Share this post


Link to post
Share on other sites

So, playing around with it a bit I can setDir and setFormDir (for units and vehicle gunners respectively) and that's cool, but this is what I started with back when I began making this, and just as it did then it leaves me with the problem of elevating for the correct range.

 

As a thought, I guess velocity could be added to a projectile's y-axis once it leaves the barrel, to simulate it's flight path from an elevated barrel. But if the maths isn't simple (converting distance to velocity, and hoping that accounts for difference in elevation between firing point and the target) then I'll have nothing lol. Maths was once a strong point.... 15 years ago.

Share this post


Link to post
Share on other sites

By using [_unit] join grpnull; it sort of clears the AI memory and will usually forget previous target.

 

sleep 0.1;

[_unit] join grpnull;
_unit doWatch objNull;
_unit reveal [_logic,4];
_unit doWatch _logic;
_unit doTarget _logic;

 

down side is it will take  the unit out of the current group  and remove any waypoints  assigned to it.

  • Like 1

Share this post


Link to post
Share on other sites

down side is it will take  the unit out of the current group  and remove any waypoints  assigned to it.

I'll be giving this a go. The good thing is, i take them out of their group (after "saving" it) before running this. Thanks for the tip.

Share this post


Link to post
Share on other sites

By using [_unit] join grpnull; it sort of clears the AI memory and will usually forget previous target.

 

sleep 0.1;

[_unit] join grpnull;

_unit doWatch objNull;

_unit reveal [_logic,4];

_unit doWatch _logic;

_unit doTarget _logic;

 

down side is it will take  the unit out of the current group  and remove any waypoints  assigned to it.

 

Worked. Thanks guys :)

Share this post


Link to post
Share on other sites

There's something dodgy about your _aliveCheck function.

 

should be something like:

 

 

_aliveCheck = {

       private ['_countShooters'];

      _shooters = _this;

     

    /* rest of function */

 

    _countShooters;      // return value

};

 

 

// in the script

_countShooters = _shooters call _aliveCheck;

  • Like 1

Share this post


Link to post
Share on other sites

Thanks, there's probably a lot that I do that's dodgy to some degree. Except for some very basic software design that I did back nearly 20 years ago at the beginning of high school I've never done any course/lessons or anything like that to help with scripting. Everything I do in ArmA/VBS is all self-taught (backed up by some excellent help here and from a few guides). So most of what I do could probably be improved on in some way, like you've mentioned. I'll make the change :)

Share this post


Link to post
Share on other sites

Software engineering? There is numerous places you can read about on the net, excluding wikipedia.

Share this post


Link to post
Share on other sites

Lol, I can't remember the last time I looked on wikipedia for anything. When a need arises though, that's when I'll go and learn something new, kind of like a learn-as-you-go deal. A few months ago I had to relearn some trigonometry to change a marker's properties.

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

×