Jump to content
Sign in to follow this  
P4R4S

Needed CleanUp Item script - triggered by player

Recommended Posts

Hello,

 

well ... not sure how well visited this forum still is... propably not much but I want to try anyways.

 

I've allready tried ask some people I know and thought could help and in the Arma3 Steam forum but well... so far no sucesss.

 

I'd like to use a script for missions and eventually a server.

 

The hole idea here you would know if you've ever played the MIKE FORCE mission from the content creator DLC  SOG Prairie Fire.

(the screenshots bellow are from it and portrait the hole deal).

It should be the same scheme. Items on the ground of a specific area or radius around a set area should be deleted.

In the Mike Force Mission the trigger and I think also focus or starting point is a trash can (could basically be any object) the player can interact with to call up the script/ command in the scroll menu "Clean up" to clear the close area from littered item players have droped/ thrown away. I've tried to recreate this by using the public set script from this mission but it didn't work.

Main problem - I have allmost no idea of scripting and just cannot comprehend it. I get the feeling like it is connected to other scripts. For some reason it's not even working in the very same mission when opened and played in the editor. The option just would not pop up. It only works when the mission is started in multiplayer (by hosting a server).

 

By now I think I've learned how the deal with finished scripts is. Basically you have the acctual script in a .sqf file and a init.sqf file that pretty much tells the game to initialize the script(s) named inside of it. Those two have to be put inside the mission folder. Here Im not sure if it is allready a difference if its a sp or a mp mission or if it is the same deal, just another folder.

For this very script I get the idea that in the script there has to be set a variable you have to give an object ingame as well, in order to let the game/ script know where the player can call this script and where this area is set.

 

I've might be able to change variables and the size of the area and set the variable to the very object I want to be the well... Initialization point, but Im just not able to write the script. That's a language I not speak, I've tried and so far I've failed. So I ask someone able to do that, to help out creating it and if needed give instructions or just ask for his knowledge.

 

I hope someone is whilling to do that for me and that it isn't to hard / complicated. I mean I believe I get the logic and it actually sounds simple. At least if it stays that simple and doesn't get more added to it. But well... could be absolutly wrong.

In the end pretty much every kind of script and command would be to much for me allready so I don't judge but leave it to the people able to ... maybe I'll be able to get it done myself without any help one day eventually.

 

https://imgur.com/a/ptn1JpF

Share this post


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

It should be the same scheme. Items on the ground of a specific area or radius around a set area should be deleted.

In the Mike Force Mission the trigger and I think also focus or starting point is a trash can

 

There probably are scripts out there that do this but what the heck, it's a fun little thing to write up.

Now I haven't played Mike Force in a while so just clarify for me a few things (There's also a chance here of changing the behavior to fit your vision) :

  1. Do you want it to require manual input or would you prefer automatic cleanup?
  2. Do you care about the dropped gear or should it just be completely removed from the game?
  3. If user input is required, should it be locked behind admin access or available for all players?

 

Remember to Quote me or mention @mrcurry in your response so I get the notification, otherwise I might take a while to respond 🙂

  • Like 1

Share this post


Link to post
Share on other sites

Thanks for your interest Im happy to answer and explain my intention:

 

The Clean Up should be initialized by the players input - pretty much everyone should be able to do it. Just the question if it is relevant if it is a singleplayer mission or a multiplayer or if this makes no difference at all (same deal?).
Just like with the Boxes that contain an Arsenal you can initialize to gear up, it should be possible to interact with an object (I like the idea that it is a Trashcan - quite appropriate). If you get close to it, point at the very object (trashcan for example) use the scroll menu and you will get the option 'Clean up'. Click/ enable it and all the items on the floor of lets say 100m (if needed I think I could change that on my own) around this object get removed. Items like magacines, weapons and just all the equiptment. No vehicles and no objects inside of containers in this very area tho. Just items on the ground.

 

The hole deal about this is players spawn in, get their equiptment from the arsenal and very often they just throw away what they don't need or they test out stuff or whatever. Result is in more or less short time the hole place around the arsenal is littered with 'trash' - as more people doing it as worse it gets in less time. This Problem I want to solve because it is just useless ressources and at some point this makes itself noticeable in the performance.

 

Without such a feature I find myself quite often in situations that I take an empty bag and just pick all the items up to than delete the bag in the arsenal to get rid of it. I like it clean 😛

But Im sick of that. Actually Im sick of players that cannot just delete the stuff they don't need in the arsenal or just load their safed loadout but instead throw away half empty mags.

I also think it would be better than a script that is automaticaly searching the area every now and than and clear items on its own. So it should be just initialized if needed and the players decide.
I mean in general there is a feature that clears items and stuff if there is no player around but in the arsenal/ spawn area this somehow does not work, maybe because there is allways players around I don't know. But actually I like this idea in general. Seen it in other variants on other servers or missions but I really love the MIKE FORCE way to deal with this problem.

Share this post


Link to post
Share on other sites

In case you don't know the mike feature mission or can't remember I've added a link to check out the screenshots I made that might help to get an idea.

 

Actually I realized I messed up adding all the pictures so I did a new one.

 

https://imgur.com/a/auMzLoV

Share this post


Link to post
Share on other sites

It will remove weapons that are dropped you can set the number of weapons that are allowed to be in the mission. 

Share this post


Link to post
Share on other sites
On 5/1/2024 at 8:55 PM, P4R4S said:

Thanks for your interest Im happy to answer and explain my intention:

 

Alright I've got something that should* suit your needs. Since it might be useful for others I've added some options for automatic cleanup and admin control, explore them if you wish.

 

Setup:

Save the script into a sqf-file or copy the cleanup_script.sqf from the example mission into your scenario folder.

Then open the editor and:

  1. Add a trigger covering the area, give it a unique variable name.
  2. Add an appropriate 'collector' object to act as the interaction point (or as data holder if using automatic mode).
  3. Copy one of the execution examples (see the script header) to the init of your 'collector' and change the parameters to your needs.
  4. If you need multiple areas repeat the above steps as many times as you want.

 

Though I haven't fully tested in an MP environment I've done this enough to say that SP/MP compatibility shouldn't** be a problem if you set it up as described.

 

See the full description below for more details:

Spoiler

Parameter(s):

        0 - _collector  - Interaction object [OBJECT]

        1 - _trigger    - Trigger covering the area to by cleared [TRIGGER]

        2 - _mode       - Mode, see below. Default: -1 [NUMBER]

   

    Description:

        Script takes a collector object (to handle input and hold logic) and a trigger (to define an area)

        and provides a 'dropped gear cleanup service' either on user input action or automatically,

        depending on the mode set in the third parameter (index 2).

       

        The _mode parameter is a numerical parameter.

        It's value controls the behaviour like so:

            -3  -> Activated with user action on _collector, limited to host and logged in admins

            -2  -> Activated with user action on _collector, limited to host and any admins

            -1  -> Activated with user action on _collector, any user (Default)

            0   -> Automatic activation as soon as all players leave the trigger area

            X   -> Automatic activation on interval X in seconds, for negative values the absolut value is used.

 

        Multiplayer notes:      

            The script is built to be called from the _collector object's init.

            With that MP compatability is guarantueed.

 

            If you must execute it elsewhere use global and JIP-client execution.

 

    Execution example (default):

        [this, myTrigger] execVM "cleanup_script.sqf"

    Execution example (full):

        [this, myTrigger, -1] execVM "cleanup_script.sqf"

 

The full source code is here:

Spoiler

/*
	File: cleanup_script.sqf
	Description: Allows players to cleanup dropped gear (object type: GroundWeaponHolder)
	Author: mrCurry - https://forums.bohemia.net/profile/759255-mrcurry/
	Date: 2024-05-02

	Parameter(s):
		0 - _collector	- Interaction object [OBJECT]
		1 - _trigger 	- Trigger covering the area to by cleared [TRIGGER]
		2 - _mode 		- Mode, see below. Default: -1 [NUMBER]
	
	Description:
		Script takes a collector object (to handle input and hold logic) and a trigger (to define an area) 
		and provides a 'dropped gear cleanup service' either on user input action or automatically, 
		depending on the mode set in the third parameter (index 2).
		
		The _mode parameter is a numerical parameter. 
		It's value controls the behaviour like so:
			-3 	-> Activated with user action on _collector, limited to host and logged in admins
			-2 	-> Activated with user action on _collector, limited to host and any admins
			-1	-> Activated with user action on _collector, any user (Default)
			0	-> Automatic activation as soon as all players leave the trigger area
			X 	-> Automatic activation on interval X in seconds, for negative values the absolut value is used.

		Multiplayer notes:		
			The script is built to be called from the _collector object's init.
			With that MP compatability is guarantueed.

			If you must execute it elsewhere use global and JIP-client execution.

	Execution example (default):
		[this, myTrigger] execVM "cleanup_script.sqf"
	Execution example (full):
		[this, myTrigger, -1] execVM "cleanup_script.sqf"
*/	

// ## DEFINES ##
// The ACTION_TITLE can be changed if so desired, Structured Text supported
#define ACTION_TITLE "Cleanup gear"
#define INFINITY 1e39

// ## Parameter handling ##
params [
	[ "_collector", objNull, [objNull] ],
	[ "_area_trigger", objNull ],
	[ "_mode", -1, [0] ]
];

if( isNull _collector ) exitWith {
	["Undefined object passed as parameter _collector. Check your input."] call BIS_fnc_error;
};

if( isNull _area_trigger ) exitWith {
	["Undefined object passed as parameter _area_trigger. Check your input."] call BIS_fnc_error;
};

// Set partner objects
_collector setVariable ["CUS_partner", _area_trigger];
_area_trigger setVariable ["CUS_partner", _collector];

// Check if collector object is compatible with setVariable
if( isNil { _collector getVariable "CUS_partner" } ) exitWith {
	["CUS collector '%1' (%2) cannot is not a compatible object.", typeOf _collector, _collector] call BIS_fnc_error;
};

// Compute search radius
triggerArea _area_trigger params ["_a", "_b", "", "", "_c"];
private _radius = if ( _c < 0 ) then {
	// Radius is not finite since trigger height is infinite
	INFINITY 
} else { 
	// Radius = Sqrt of 2 largest dimensions
	private _dim = [_a, _b, _c];
	_dim sort false;
	sqrt (_dim#0 * _dim#0 + _dim#1 * _dim#1 );
};
_collector setVariable ["CUS_search_radius", _radius];

// Params OK

//////////////////////////////////////
// Cleanup function - Params: [_collector, _trigger]
private _fnc_cleanup = {
	systemChat "Starting cleanup...";
	params [["_collector", objNull], ["_trigger", objNull]];
	if(isNull _collector) then { _collector = _trigger getVariable ["CUS_partner", objNull] };
	if(isNull _trigger) then { _trigger = _collector getVariable ["CUS_partner", objNull] };

	// Find all objects in search area
	private _radius = _collector getVariable "CUS_search_radius";
	private _objects = if( _radius < 750 ) then {
		_trigger nearObjects ["GroundWeaponHolder", _radius];
	} else {
		"GroundWeaponHolder" allObjects 0
	};

	// Delete those contained in the trigger
	{
		if( _x inArea _trigger ) then {
			deleteVehicle _x;
		};
	} forEach _objects;
	systemChat "Cleanup complete.";
};
//////////////////////////////////////

// Store function reference
_collector setVariable ["CUS_fnc_cleanup", _fnc_cleanup];
_area_trigger setVariable ["CUS_fnc_cleanup", _fnc_cleanup];

private _trigger_activation = [];
switch _mode do {
	case -3; // Manual, for host and logged admins
	case -2; // Manual, for host, voted admins and logged admins
	case -1: { // Manual, for everyone
		private _title = ACTION_TITLE;
		private _condition = "isPlayer _this";
		if( _mode < -1 ) then {
			_title = format ["%1 (Admin)", _title];
			_condition = format ["%1 && ( isServer or (call BIS_fnc_admin + %2 >= 0) )", _condition, _mode + 1];
		};

		_collector addAction [
			_title, 
			{ 
				params ["_trgt"];
				[ _trgt ] call ( _trgt getVariable "CUS_fnc_cleanup" );
			},
			nil, 666, true, true, "", _condition
		];

		_area_trigger setTriggerActivation ["NONE", "PRESENT", false];
		_area_trigger setTriggerStatements ["false", "", ""];
		_area_trigger enableSimulation false;
	};
	case 0: { // Auto - Proximity
		private _trigger_params = if( isServer ) then {
			_area_trigger setTriggerActivation ["ANYPLAYER", "PRESENT", true];
			_area_trigger setTriggerStatements [
				"this",
				"",
				"[nil, thisTrigger] call (thisTrigger getVariable 'CUS_fnc_cleanup')"
			];
		} else {
			_area_trigger setTriggerActivation ["NONE", "PRESENT", false];
			_area_trigger setTriggerStatements ["false", "", ""];
			_area_trigger enableSimulation false;
		};
	};
	default { // Auto - Timed
		private _trigger_params = if( isServer ) then {
			private _t = abs _mode;
			_area_trigger setTriggerActivation ["NONE", "PRESENT", true];
			_area_trigger setTriggerStatements [
				"thisTrigger getVariable ['CUS_timeout', true]",
				"[nil, thisTrigger] call (thisTrigger getVariable 'CUS_fnc_cleanup'); thisTrigger setVariable ['CUS_timeout', false];",
				"thisTrigger setVariable ['CUS_timeout', true];"
			];
			_area_trigger setTriggerTimeout [_t,_t,_t, false];
		} else {
			_area_trigger setTriggerActivation ["NONE", "PRESENT", false];
			_area_trigger setTriggerStatements ["false", "", ""];
			_area_trigger enableSimulation false;
		};
	};
};

 

 

And an example mission can be found here:

Dropbox link

 

* - I am human and I make mistakes.

** - See *.

  • Thanks 1

Share this post


Link to post
Share on other sites

Thanks alot my friend I will try it out and let you know. I'll try on a test mission I've allready set up in order to test scripts and mechanics.

Share this post


Link to post
Share on other sites

ehm... I tried to get your example mission but I get an errormessage telling that something went wrong.

 

I wanted to have a look how exactly it is made with the variables. I mean I get the idea but the implementation - or right way to implement it - Im not to sure about.
Especially since I have never worked with the triggers in the editor. I mean... Im propably missing something here, but don't I have to know how exactly to name the variable since the script needs to know in order to work? I mean... I think I can't just name it whatever I want can I ? Or do I have to change something in the script - put in the variables I give away to the trigger at least? At least I understand that I need the trigger area (done) and give it a name. I guess I than have to insert the variabel for the object 'the collector' in the trigger:execution (I've just placed a Trashcan and named it CleanUp)

 

By now I've put the script in and also put the execution in an init file. Here Im not quite certain if I understand the use of the "full" execution. Am I right that you have created a scipt with several options how to get triggered and by who? So In case I want to only allow it to a host/admin or want to set it to automatic mode - so instead of  [this, myTrigger, -1] execVM "cleanup_script.sqf" I put in one of those parameters

20 hours ago, mrcurry said:

        The _mode parameter is a numerical parameter.

        It's value controls the behaviour like so:

            -3  -> Activated with user action on _collector, limited to host and logged in admins

            -2  -> Activated with user action on _collector, limited to host and any admins

            -1  -> Activated with user action on _collector, any user (Default)

            0   -> Automatic activation as soon as all players leave the trigger area

            X   -> Automatic activation on interval X in seconds, for negative values the absolut value is used. 

 

Share this post


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

ehm... I tried to get your example mission but I get an errormessage telling that something went wrong

 

My bad, broken link - updated to a working one in the previous post and added some comments to the mission.

Take a look in there and it should make more sense.
 

On editor variable names Larrow recently explained this perfectly in another thread:

On 5/2/2024 at 3:24 AM, Larrow said:

When you name some object in the editor by filling out its variable name property two things happen when the mission loads...

  1. The vehicle is given a vehicleVarName of the STRING we gave in the property

  2. A global variable of the same name is made referencing said object

 

For us the important bit is the 2nd part.

The object in our case is the area trigger, give it a variable name, e.g. trigger1, which you can then use to access that particular trigger from anywhere in the mission.

In the execution example you replace myTrigger with the name you have selected e.g. trigger1:

// Replace myTrigger
[this, myTrigger, -1] execVM "cleanup_script.sqf";
// with your name, here I also changed the mode.
[this, trigger1, -1] execVM "cleanup_script.sqf";

 

It's good practice (for your own sanity) to use verbose names such as 'cleanupTrigger1' but not required.

For full rules and recommendations see this link, variable names given in the editor are considered global variables.

Share this post


Link to post
Share on other sites

oh now I see... the init goes in the object and not in an extra init file ... yeh... that makes sense... sorry. The other script I use to repack mags got an own file to initialize the script. I got told that to be the standard procedure.
Nice it's working in my test mission now as well. I guess the main problem was indeed that I have put the init in an extra init file within the mission file, instead for just puting it in the objects init, but somehow there also was another weird problem. The object that I used first didn't respond and instead of a yellow mark it had a grey mark (no idea why because it had the very same characteristics as shown in your test mission). In the end I just deleted it and set a new one and this one had no problems.

Thanks again. That's perfect 🙂

  • Like 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
Sign in to follow this  

×