Jump to content
slothstronaut

Dynamically adding items to container

Recommended Posts

Hey guys,

 

I have a problem. I'm building a script that loads a bunch of predefined items into a crate when it's accessed by the correct player. The logic is:

 

- InventoryOpened event triggers

- Check if you can open the container

- If yes, load the container

- If no, show message, stop you from loading the container

 

When loading the container, the following steps happen:

 

- Clear the current contents (clearItemCargoGlobal, clearWeaponCargoGlobal etc)

- Load each item in (addItemCargoGlobal, addWeaponCargoGlobal etc)

 

This all works correctly, however, when the Inventory window actually shows, none of the added items are added until you change the gear type filter (All, Items, Magazines, Weapons at the top of the left inventory panel). As soon as you change the filter all of the correct items show up.

 

Does anyone know why this is happening / what I can do to stop this from happening?

 

Cheers for any help you can give me :)

 

Share this post


Link to post
Share on other sites

Do you have a code sample? It's not easy guessing what could go wrong with those informations.

 

By the way, you shouldn't need the "can open" check, not with the EH you're using.

Share this post


Link to post
Share on other sites

To give some context, the reason I do the "can open" step, is because I want only one person accessing the box at one time, so on open it sets an inUse variable to true, which blocks any other player accessing it at the same time. Regardless, I don't think it's actually contributing to my problem.
 

So, code sample:

Event Handler:

_this addEventHandler ["InventoryOpened", { 
	if (_this call crj_fnc_openContainer) then { 
		true; 
	} 
	else { 
		_this execVM "crj_evt_inventoryOpened.sqf" }; 
	}
];

crj_evt_intentoryOpened.sqf

private _unit = _this select 0;
private _container = _this select 1;
private _name = "TEST";

private _isContainerLocker = _container getVariable "crjContainerLocker";
if (isNil "_isContainerLocker") then {
	true;
}
else {
	private _inUse = _container getVariable "inUse";

	if (isNil "_inUse") then
	{
		_inUse = false;
	};

	if (_inUse) then
	{
		closeDialog 106; true;
	}
	else
	{
		_container setVariable ["inUse", true, true];

		_params = [_container, _unit, _name];
		[_params, "crj_fnc_loadContainer", false] call BIS_fnc_MP;
	}
};

crj_fnc_loadContainer.sqf (edited for brevity)

private _unit = _this select 1;
private _container = _this select 0;
private _name = _this _select 2;

_params = [_container, _unit, _name];
[_params, "crj_fnc_loadContainer", false] call BIS_fnc_MP;

crj_fnc_loadContainer.sqf (edited for brevity)

crj_fnc_loadContainer = {
	params ["_container", "_unit", "_name"];

	_params = [_container];
	_params call crj_fnc_clearContainer;

	// Load contents in...
};

crj_fnc_clearContainer = {
	params ["_container"];
	clearItemCargoGlobal _container;
	clearMagazineCargoGlobal _container;
	clearWeaponCargoGlobal _container;
	clearBackpackCargoGlobal _container;
};

So, crj_evt_inventoryOpened.sqf is called when you open an appropriate container, crj_fnc_loadContainer.sqf is then actioned, which calls crj_fnc_loadContainer.sqf (which in turn calls crj_fnc_clearContainer).

Hopefully that adds some clarity to what I'm trying to do.

Cheers!

Share this post


Link to post
Share on other sites

Its just a slight timing issue, you need to wait until the inventory display is open before filling the container.

waitUntil{ !isNull ( findDisplay 602 ) };
  • Like 1

Share this post


Link to post
Share on other sites

Why do you say that KK?

Even if you do it all in the EH without creating a scheduler thread(spawn/execVM) you still end up with the same problem of items look missing until you refresh the list. e.g

player addEventHandler [ "InventoryOpened", {
    params[ "_unit", "_container" ];
    
    if ( _container getVariable [ "crjContainerLocker", false ] ) then {
        if !( _container getVariable [ "inUse", false ] ) then {
            _container setVariable [ "inUse", true, true ];
            
            _container addMagazineCargoGlobal [ "Chemlight_green", 2 ];
            
            player addEventHandler [ "InventoryClosed", {
                params[ "_unit", "_container" ];
                
                _container setVariable[ "inUse", false, true ];
                player removeEventHandler[ "InventoryClosed", _thisEventHandler ];
            }];
        }else{
            _h = [] spawn {
                waitUntil{ !isNull findDisplay 602 };
                findDisplay 602 closeDisplay 2;
            };
        };
    };
}];
The two chemlights will not show until you refresh the list.

 

As the inventory is mostly handled engines side I'm presuming it is a timing issue between initial first scan of the cargo and when it starts up events to monitor changes in cargo.

If you waituntil the display is initialised there is no such problem.

player addEventHandler [ "InventoryOpened", {
    params[ "_unit", "_container" ];
    
    if ( _container getVariable [ "crjContainerLocker", false ] ) then {
        if !( _container getVariable [ "inUse", false ] ) then {
            _container setVariable [ "inUse", true, true ];
            
            _h = _container spawn {
                params[ "_container" ];
                
                waitUntil{ !isNull findDisplay 602 };
                
                _container addMagazineCargoGlobal [ "Chemlight_green", 2 ];
                
                player addEventHandler [ "InventoryClosed", {
                    params[ "_unit", "_container" ];
                    
                    _container setVariable[ "inUse", false, true ];
                    player removeEventHandler[ "InventoryClosed", _thisEventHandler ];
                }];
            };
        }else{
            _h = [] spawn {
                waitUntil{ !isNull findDisplay 602 };
                findDisplay 602 closeDisplay 2;
            };
        };
    };
}];

Share this post


Link to post
Share on other sites

Why do you say that KK?

 

You are right, EH must be triggering after the content lists are already compiled. Then maybe one can do this:

 

player addEventHandler ["InventoryOpened", 
{
	_container = _this select 1;
	_currentUser = _container getVariable ["CurrentUser", objNull];
	if (isNull _currentUser) then
	{
		_container setVariable ["CurrentUser", player, true];
		_container spawn {player action ["Gear", _this]};
		
		clearWeaponCargoGlobal _container;
		clearMagazineCargoGlobal _container;
		clearItemCargoGlobal _container;
		_container addMagazineCargoGlobal ["Chemlight_green", 20];

		true
	}
	else
	{
		_currentUser != player
	};
}];

player addEventHandler ["InventoryClosed", 
{
	_container setVariable ["CurrentUser", objNull, true];
]};

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

×