Jump to content
Hanz94

(Help) script to prevent equipping specific items

Recommended Posts

Hello, I am creating a multiplayer mission for a dedicated server and I need some kind of script that allows me to prevent players of a certain faction from equipping certain items in their inventory like vests and helmets. I have no idea about scripting so any help would be great. Thanks for your help beforehand .

Share this post


Link to post
Share on other sites

I need something similar, I got this from GTP-4 but it doesn't seem to work.

 

Spoiler

private _restrictedItems = [
    [
        west, // Side
        [ // Restricted items list
            "V_PlateCarrier2_rgr",
            "example_helmet_1"
        ]
    ],
    [
        east,
        [
            "V_PlateCarrier2_rgr",
            "example_helmet_2"
        ]
    ]
];

// Function to check and remove restricted items
private _checkAndRemoveRestrictedItems = {
    params ["_player", "_restrictedItems"];

    private _playerSide = side _player;
    private _restrictedItemsForSide = [];

    // Get the restricted items for the player's side
    {
        if (_x select 0 isEqualTo _playerSide) then {
            _restrictedItemsForSide = _x select 1;
        };
    } forEach _restrictedItems;

    // Iterate over the player's inventory
    {
        if (_x in _restrictedItemsForSide) then {
            // Remove the item and place it back in the container or on the ground
            if (isNull (attachedTo _player)) then {
                _player unassignItem _x;
                _player removeItem _x;
                private _pos = position _player;
                private _itemOnGround = createVehicle [_x, _pos, [], 0, "CAN_COLLIDE"];
            } else {
                private _container = attachedTo _player;
                _player unassignItem _x;
                _player removeItem _x;
                _container addItemCargoGlobal [_x, 1];
            };

            // Display a message to the player
            private _message = format ["You are not allowed to use the %1.", _x];
            [_message, [1, 0, 0, 1]] call BIS_fnc_dynamicText;
        };
    } forEach (assignedItems _player + uniformItems _player + vestItems _player + backpackItems _player);
};

// Event handler for opening inventory
["InventoryOpened", {
    params ["_player"];
    [_player, _restrictedItems] call _checkAndRemoveRestrictedItems;
}] call CBA_fnc_addDisplayHandler;

// Event handler for closing inventory
["InventoryClosed", {
    params ["_player"];
    [_player, _restrictedItems] call _checkAndRemoveRestrictedItems;
}] call CBA_fnc_addDisplayHandler;

 

Share this post


Link to post
Share on other sites

I guess the players doesn't have forbidden gears at start. So, in what case(s) do you need this restriction? picking on dead corpses? edited/spawned crates? arsenal?

Share this post


Link to post
Share on other sites
4 hours ago, pierremgi said:

I guess the players doesn't have forbidden gears at start. So, in what case(s) do you need this restriction? picking on dead corpses? edited/spawned crates? arsenal?

I explain, I need that if an object or list of objects are defined for that faction, they are automatically removed from the inventory and left on the ground, whether I get from the ground, a corpse, box or vehicle. For context, I'm trying to keep OPFOR players from taking BLUFOR helmets and vests.

Share this post


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

got this from GTP-4

I didn't do a thorough review however it's impressive how close the AI gets but it falls for a similar mistake an inexperienced human coder likely would, incorrect scoping of the variables.

 

The _restrictedItems and _checkAndRemoveRestrictedItems are defined outside the scope of the event handler causing the inner call to fail.

 

Suggested fix would be to make those variables global or in some other way pass them into scope.

 

Not sure about the use of attachedTo stuff. I'd have take a closer look later.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
9 minutes ago, mrcurry said:

I didn't do a thorough review however it's impressive how close the AI gets but it falls for a similar mistake an inexperienced human coder likely would, incorrect scoping of the variables.

 

The _restrictedItems and _checkAndRemoveRestrictedItems are defined outside the scope of the event handler causing the inner call to fail.

 

Suggested fix would be to make those variables global or in some other way pass them into scope.

 

Not sure about the use of attachedTo stuff. I'd have take a closer look later.

Could you give an example of what you mean? Like I said, I'm not good at scripting and it's hard for me to interpret the problem.

Share this post


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

That script also requires CBA3.

I know, it still doesn't work using CBA3

Share this post


Link to post
Share on other sites
22 hours ago, Hanz94 said:

Could you give an example of what you mean? Like I said, I'm not good at scripting and it's hard for me to interpret the problem.

Yeah, turns out I was wrong... a deeper review shows that the AI got the general structure correct but the contents are pretty much nonsense.

We don't need to worry about being supplanted just yet... 😓

 

So here's a solution with plenty of comments and no CBA requirement.

It only checks vests and headgear, the vest content is maintained when pushed back into the container.

If you only need BLUFOR and OPFOR you can remove the entries for the other sides if you wish.

The code goes in an sqf-file called initPlayerLocal  inside your scenario folder.

Spoiler

// initPlayerLocal.sqf

// Define restricted items
HANZ_restrictedItems = createHashMapFromArray [
	[
		BLUFOR, 
		[
			/*
				You can extend this list by adding more strings just remember to end all lines except the last with a comma-character , 
			*/
			"V_DeckCrew_blue_F",
			"V_HarnessOGL_brn",
			"Classname_Restricted_item_for_blufor_n"
		]
	],
	[
		OPFOR, 
		[
			/*
				You can extend this list by adding more strings just remember to end all lines except the last with a comma-character , 
			*/
			"Classname_Restricted_item_for_opfor_1",
			"Classname_Restricted_item_for_opfor_2",
			"Classname_Restricted_item_for_opfor_n"
		]
	],
	[
		INDEPENDENT, 
		[
			/*
				You can extend this list by adding more strings just remember to end all lines except the last with a comma-character , 
			*/
			"Classname_Restricted_item_for_indep_1",
			"Classname_Restricted_item_for_indep_2",
			"Classname_Restricted_item_for_indep_n"
		]
	],
	[
		CIVILIAN, 
		[
			/*
				You can extend this list by adding more strings just remember to end all lines except the last with a comma-character , 
			*/
			"Classname_Restricted_item_for_civ_1",
			"Classname_Restricted_item_for_civ_2",
			"Classname_Restricted_item_for_civ_n"
		]
	]
];

// Convert each item array into a hashmap for quicker access in the check function
{
	// Create the new map
	private _sideMap = createHashMap;
	// _x is the side, redirect the hashmap to point to the _sideMap
	HANZ_restrictedItems set [_x, _sideMap];
	
	// Iterato over _y which is the reference to the "restricted items"-list for current side
	// here _x is the reference to each item in the list which we use as the key to, the value 0 is arbitrary since we're treating the hashmap as Set-like datastorage.
	{ _sideMap set [toLower _x, 0]; } forEach _y;
} forEach HANZ_restrictedItems;

// Function that enforces the restriction
HANZ_fnc_enforceItemRestrictions = {
	// Get the parameters of event
	params [ "_unit", "_container" ];

	// Get the side of the group the unit belongs to, covers most cases where the player might appear civilian or belong to another side via "join".
	private _side = side group _unit;
	// Retrieve the side's item set
	private _restrictedSet =  HANZ_restrictedItems get _side;

	// If set is defined
	if( !isNil "_restrictedSet" ) then {
		// Check if the containers is a corpse and if so get the supplies of that corpse, if non exists create one
		if( _container isKindOf "Man" ) then {
			private _corpse = _container;
			private _nearSupplies = _corpse nearSupplies 3 select { getCorpse _x == _corpse };
			if(count _nearSupplies > 0) then {
				_container = _nearSupplies # 0;
			} else {
				_container = createVehicle ["WeaponHolderSimulated", getPosATL _corpse, [], 1, "NONE"];
			}
		};

		// Check unit's headgear
		private _headgear = headgear _unit;
		if( toLower _headgear in _restrictedSet ) then {
			if( isNull _container ) then {
				// Container is undefined, we create a ground weapon holder to put the contents into
				_container = createVehicle ["GroundWeaponHolder", getPosATL _unit, [], 1, "NONE"];					
			};

			// Add helmet to the container
			_container addItemCargoGlobal [_headgear, 1];

			// Remove helmet from unit
			removeHeadgear _unit;

			systemChat "Headgear dropped due to side restrictions.";
		};

		private _vest = vest _unit;
		if( toLower _vest in _restrictedSet ) then {
			if( isNull _container ) then {
				// Container is undefined, same as above
				_container = createVehicle ["WeaponHolderSimulated", getPosATL _unit, [], 1, "NONE"];
			};

			// Add the vest to the container
			_container addItemCargoGlobal [_vest, 1];

			// The new vestContainer is the last added in everyContainer _container
			private _subContainers = everyContainer _container;
			private _newVestContainer = _subContainers # ( count _subContainers - 1 ) # 1;

			// Iterate over all weapons and items of the vest and push them into the the new vest container so they aren't lost
			private _vestContainer = vestContainer _unit;
			private _vestContents = getWeaponCargo _vestContainer + getItemCargo _vestContainer;
			for "_i" from 0 to (count _vestContents - 2) step 2 do {
				private _names = _vestContents # _i;
				private _counts = _vestContents # (_i + 1);
				{
					_newVestContainer addItemCargoGlobal [_x, _counts # _forEachIndex];
				} forEach _names;
			};

			// Do the same for magazines but make sure the bullets are counted
			{
				_x params ["_magazine", "_numBullets"];
				_newVestContainer addMagazineAmmoCargo [_magazine, 1, _numBullets];
			} forEach magazinesAmmoCargo _vestContainer;

			// Remove the vest from the unit
			removeVest _unit;

			systemChat "Vest dropped due to side restrictions.";
		};		
	};
};

// Add Take eventhandler
player addEventHandler [
	"Take",
	HANZ_fnc_enforceItemRestrictions
];

 

 

Edited by mrcurry
Added support for corpse containers
  • Like 1
  • Thanks 1
  • Haha 1

Share this post


Link to post
Share on other sites

Thank you very much for that, I will test it immediately!

Share this post


Link to post
Share on other sites
2 hours ago, mrcurry said:

 

Yeah, turns out I was wrong... a deeper review shows that the AI got the general structure correct but the contents are pretty much nonsense.

We don't need to worry about being supplanted just yet... 😓

 

So here's a solution with plenty of comments and no CBA requirement.

It only checks vests and headgear, the vest content is maintained when pushed back into the container.

If you only need BLUFOR and OPFOR you can remove the entries for the other sides if you wish.

The code goes in an sqf-file called initPlayerLocal  inside your scenario folder.

  Reveal hidden contents


// initPlayerLocal.sqf

// Define restricted items
HANZ_restrictedItems = createHashMapFromArray [
	[
		BLUFOR, 
		[
			/*
				You can extend this list by adding more strings just remember to end all lines except the last with a comma-character , 
			*/
			"V_DeckCrew_blue_F",
			"Classname_Restricted_item_for_blufor_2",
			"Classname_Restricted_item_for_blufor_n"
		]
	],
	[
		OPFOR, 
		[
			/*
				You can extend this list by adding more strings just remember to end all lines except the last with a comma-character , 
			*/
			"Classname_Restricted_item_for_opfor_1",
			"Classname_Restricted_item_for_opfor_2",
			"Classname_Restricted_item_for_opfor_n"
		]
	],
	[
		INDEPENDENT, 
		[
			/*
				You can extend this list by adding more strings just remember to end all lines except the last with a comma-character , 
			*/
			"Classname_Restricted_item_for_indep_1",
			"Classname_Restricted_item_for_indep_2",
			"Classname_Restricted_item_for_indep_n"
		]
	],
	[
		CIVILIAN, 
		[
			/*
				You can extend this list by adding more strings just remember to end all lines except the last with a comma-character , 
			*/
			"Classname_Restricted_item_for_civ_1",
			"Classname_Restricted_item_for_civ_2",
			"Classname_Restricted_item_for_civ_n"
		]
	]
];

// Convert each item array into a hashmap for quicker access in the check function
{
	// Create the new map
	private _sideMap = createHashMap;
	// _x is the side, redirect the hashmap to point to the _sideMap
	HANZ_restrictedItems set [_x, _sideMap];
	
	// Iterato over _y which is the reference to the "restricted items"-list for current side
	// here _x is the reference to each item in the list which we use as the key to, the value 0 is arbitrary since we're treating the hashmap as Set-like datastorage.
	{ _sideMap set [toLower _x, 0]; } forEach _y;
} forEach HANZ_restrictedItems;

// Function that enforces the restriction
HANZ_fnc_enforceItemRestrictions = {
	// Get the parameters of event
	params [ "_unit", "_container" ];

	// Get the side of the group the unit belongs to, covers most cases where the player might appear civilian or belong to another side via "join".
	private _side = side group _unit;
	// Retrieve the side's item set
	private _restrictedSet =  HANZ_restrictedItems get _side;

	// If set is defined
	if( !isNil "_restrictedSet" ) then {
		// Check unit's headgear
		private _headgear = headgear _unit;
		if( toLower _headgear in _restrictedSet ) then {
			if( isNull _container ) then {
				// Container is undefined, we create a ground weapon holder to put the contents into
				_container = createVehicle ["GroundWeaponHolder", getPosATL _unit, [], 1, "NONE"];					
			};

			// Add helmet to the container
			_container addItemCargoGlobal [_headgear, 1];

			// Remove helmet from unit
			removeHeadgear _unit;

			systemChat "Headgear dropped due to side restrictions.";
		};

		private _vest = vest _unit;
		if( toLower _vest in _restrictedSet ) then {
			if( isNull _container ) then {
				// Container is undefined, same as above
				_container = createVehicle ["GroundWeaponHolder", getPosATL _unit, [], 1, "NONE"];					
			};

			// Add the vest to the container
			_container addItemCargoGlobal [_vest, 1];

			// The new vestContainer is the last added in everyContainer _container
			private _subContainers = everyContainer _container;
			private _newVestContainer = _subContainers # ( count _subContainers - 1 ) # 1;

			// Iterate over all weapons and items of the vest and push them into the the new vest container so they aren't lost
			private _vestContainer = vestContainer _unit;
			private _vestContents = getWeaponCargo _vestContainer + getItemCargo _vestContainer;
			for "_i" from 0 to (count _vestContents - 2) step 2 do {
				private _names = _vestContents # _i;
				private _counts = _vestContents # (_i + 1);
				{
					_newVestContainer addItemCargoGlobal [_x, _counts # _forEachIndex];
				} forEach _names;
			};

			// Do the same for magazines but make sure the bullets are counted
			{
				_x params ["_magazine", "_numBullets"];
				_newVestContainer addMagazineAmmoCargo [_magazine, 1, _numBullets];
			} forEach magazinesAmmoCargo _vestContainer;

			// Remove the vest from the unit
			removeVest _unit;

			systemChat "Vest dropped due to side restrictions.";
		};		
	};
};

// Add Take eventhandler
player addEventHandler [
	"Take",
	HANZ_fnc_enforceItemRestrictions
];

// Add Inventory closed eventhandler
// This should only be needed if your players could receive incorrect equipment via scripted sources
player addEventHandler [ 
	"InventoryClosed", 
	HANZ_fnc_enforceItemRestrictions
];

 


 

Well that turned out to work pretty well, thanks so much for the help. I only got a problem when trying to take the items from corpses. The object was removed instead of being left on the ground and there seems to be something wrong with line 104. Any suggestions?

Share this post


Link to post
Share on other sites
13 hours ago, Hanz94 said:

Well that turned out to work pretty well, thanks so much for the help. I only got a problem when trying to take the items from corpses. The object was removed instead of being left on the ground and there seems to be something wrong with line 104. Any suggestions?

I forgot corpse weapon containers are a bit of a special case. I've updated the code to account for this and this also gets rid of the error. See my previous post.

  • 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

×