Jump to content
avibird 1

Can't see this error in the script. it may be just a typo but can't see it help and thank you.

Recommended Posts

I have been using this script for many years actually since ARMA2 upgrade to ARMA3 it works fine but the last few years it gives me a script error when test playing in the editor. Its actually an awesome script that gives the AI unlimited Ammo including AT/AA rounds but it will not let you spam rockets like some other scripts that give you a machine AT/AA launcher lol.  

 

Here is the error massage that I get in the debug screen in the editor.

 

'...nt - _foundMags) do

{

_unit addMagazine  |#|_magazineType;

};

};

sleep 1;

file c:\Users\Avibird.AVIBIRD-pc\Documents\Arma

};'

Error undefined variable in expression: _magazinetype

3\mpmissions\!Raven_Platoon_Biological_weapon_Raid.Tanoa\unlimitedAmmo.sqf…,

line 34

 

 

 

UnlimitedAmmo.sqf

line 34 is the third line from the bottom.

_unit = _this select 0;
_ammoCount = _this select 1;
_primeWpn = "";
_prevWpn = "";
_magazineType = "";
_foundMags = 0;
//hint format["%1 is added",_unit];              //used to check if units are spawned into the mission
//diag_log format["%1 is added",_unit];          //used to check if units are spawned into the mission

while {alive _unit} do {
    waitUntil {sleep 0.5; currentWeapon _unit != ""};
    _primeWpn = currentWeapon _unit;
    
    if (_primeWpn != _prevWpn) then
    {
        _prevWpn = _primeWpn;
        _magazineType = getArray(configFile >> "cfgWeapons" >> _primeWpn >> "magazines") select 0;
    };
    
    _foundMags = 0;
    {
        if (_x == _magazineType) then
        {
            _foundMags = _foundMags + 1;
        };
    } forEach (magazines _unit);

    if (_foundMags < _ammoCount) then
    {
        for "_i" from 1 to (_ammoCount - _foundMags) do
        {
            _unit addMagazine _magazineType;
        };
    };

    sleep 1;
};

Share this post


Link to post
Share on other sites

I hate trying to read code from my phone, but private maybe?

 

private _magazineType = "";

  • Like 1

Share this post


Link to post
Share on other sites

@Harzach I have the unlmitedAmmo.SQF  in my main mission folder and I have this code lines in my mission init.sqf

 

 

//Unlimited Ammo**********
grantUnlimitedAmmo = compile preprocessFileLineNumbers "unlimitedAmmo.sqf";

[] spawn {
 if (!isNil "UNLAMMO_ARR") exitWith {};
 UNLAMMO_ARR = []; // empty global array for check, and to notify not to start a second loop on player connect if already running.
 if !(isServer) exitWith {};  // exit if not server.
 while {true} do {
  {
   if (!(_x in UNLAMMO_ARR) AND alive _x) then {
    [[_x, 1], "grantUnlimitedAmmo", _x] call BIS_fnc_MP;
    UNLAMMO_ARR = UNLAMMO_ARR + [_x];
   };
  } foreach allUnits;
  {
   if !(alive _x OR isNull _x) then {UNLAMMO_ARR = UNLAMMO_ARR - [_x]};
  } foreach UNLAMMO_ARR;
  sleep 1;
 };
};

 

This has been driving me nuts for a while the script works fine but can't paly in the editor because of the constant error pop ups. By the way thank you for the help and marry X mass

Share this post


Link to post
Share on other sites

You should probably move that stuff to initServer.sqf. The less you have in init.sqf the better. Also, BIS_fnc_MP is deprecated, use remoteExec/remoteExecCall.

if (!isNil "UNLAMMO_ARR") exitWith {};
 UNLAMMO_ARR = []; // empty global array for check, and to notify not to start a second loop on player connect if already running.

This doesn't work. A global variable is global to all scripts locally, not on all connected machines. The script will run for every new client as the variable doesn't yet exist for them. Which means the loop can have many iterations running on each client.

 

And Merry Christmas to you!

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Thank you for the feedback and help. do I just replace the UNLAMMO_ARR with this UNLAMMO_ARR = []; in the script. If I move it from from the mission init to a initServer.sqf. do I need to do anything else to call the script during the mission. Even though I've been playing operation flashpoint and arma for decades I still really have no clue about scripting. I'm able to read some code and splice some lines together but that is the extent of my knowledge lol. It's a work in progress. Merry Christmas

Share this post


Link to post
Share on other sites
_magazineType = getArray(configFile >> "cfgWeapons" >> _primeWpn >> "magazines") select 0;

When getArray returns an empty array, there is no _magazineType to select.

  • Thanks 1

Share this post


Link to post
Share on other sites

So do I need to add that to my unlimitedammo.sqf and take out the other codelines? I understand according harzach there is more efficient way of running the script but it works fine I've been using it for years just want to get this error message removed.

Share this post


Link to post
Share on other sites

The "grantUnlimitedAmmo" function gets used by all, client and server, so compiling it should be done in the init.sqf:

Spoiler

//Unlimited Ammo**********
grantUnlimitedAmmo = compile preprocessFileLineNumbers "unlimitedAmmo.sqf";

 

 

The spawn is a server update loop, it has the server update the array UNLAMMO_ARR and has living units not already running the "grantUnlimitedAmmo" function run that function where they are local.  As  @Harzach points out, it should be moved to the InitServer.sqf, and you need to change the BIS_fnc_MP call to RemoteExec.

 

As I see it, UNLAMMO_ARR is a server-only variable.  Unless clients also need of an UNLAMMO_ARR array, this:

Spoiler

	if (!isNil "UNLAMMO_ARR") exitWith {};
	UNLAMMO_ARR = []; // empty global array for check, and to notify not to start a second loop on player connect if already running.
	if !(isServer) exitWith {};  // exit if not server.

 

can be changed to this in initServer.sqf:

Spoiler

	if (isNil "UNLAMMO_ARR") then {UNLAMMO_ARR = []};

 

 

And this is not good:

Spoiler

		{
			if !(alive _x OR isNull _x) then {UNLAMMO_ARR = UNLAMMO_ARR - [_x]};
		} foreach UNLAMMO_ARR;

 

Inside the forEach, you're deleting from the array being cycled by the forEach.  It messes up the cycle.

And when more than one unit is null, they all get removed at one go ( UNLAMMO_ARR - [objNull] ).

 

Cycle a copy of the array instead of the array itself, and remove the null units first:

Spoiler

		UNLAMMO_ARR = UNLAMMO_ARR - [objNull];
		_arrayTemp = +(UNLAMMO_ARR);
		{
			if !(alive _x) then {UNLAMMO_ARR = UNLAMMO_ARR - [_x]};
		} foreach _arrayTemp;

 

 

The grantUnlimitedAmmo function is an update getting run on each local unit, by server and clients. Being a cycled update with suspension, use remoteExec and not remoteExecCall.

 

The problem the function has (as I see it) is that:

-1): _primeWpn can return an emty string. That means _magazineType will return an empty array.

-2) _magazineType can return an empty array, wherein there is no "Select 0" to select from.  This results in _magazineType being undefined.

And the code is not conditioned to handle that.

 

The sequence should be, I think:

Spoiler

/* ------------------
// _magazineArray = [];		// predefine before loop
// _magazineType = "";		// predefine before loop
		// Inside loop:
// _primeWpn = currentWeapon _unit;	// read wiki notes and discussion on this command
// _magazineType = "";
// if (_primeWpn != "") then {_magazineArray = getArray ...;};
// if (count _magazineArray > 0) then {_magazineType = _magazineArray select 0};
// if (_magazineType != "") then { /* do other stuff */ };
-------------------- */

 

 

Hope this is helpful.

  • Like 1
  • Thanks 1

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

×