Jump to content
Sign in to follow this  
ashton324

Scripting help.. Ammo crate respawn?

Recommended Posts

Hey guys,

I'm basically looking for some help in making a crate respawn as soon as it is moved. So basically when someone moves a crate another one instantly respawns in the same location but the previous crate also stays. Hope you get what i mean.

I have tried using the vehicle respawn script but have not really come up with much that helps.

Ive searched Armaholic and these forums but not really come up with much that helps.

Any ideas guys?

Thanks in advance

Ashton.

Share this post


Link to post
Share on other sites

Call like so

null = [this] execVM "crateRespawn.sqf";

In crateRespawn.sqf

private["_crate","_type","_pos","_newCrate"];

_crate = _this select 0;
_type = typeOf _crate;
_pos = getPos _crate;
waitUntil {_crate distance _pos > 1};
_newCrate = _type createVehicle _pos;
[_newCrate] execVM "crateRespawn.sqf";

That should work for what you want, if I understand correctly.

Share this post


Link to post
Share on other sites

Seems to work perfect dude, i dont know if this is just me but the crate seems to spawn not in the same location it originally spawned at. Its not a problem :)

Thanks dude!

Share this post


Link to post
Share on other sites
_crate setPos [_pos select 0, _pos select 1, _pos select 2];

Share this post


Link to post
Share on other sites

What if you want the crate to be deleted when no player is near? I copied Horner's script and added a little to it but cant work out how to add the code that will delete the crate if no player within 500m.

My aim is to have a heli pilot whose role is to transport or resupply troops with sling loaded crates but without having 50 crates spawned during a mission (e.g. - Invade and Annex).

init of crate:

 null = [this] execVM "crateRespawn.sqf"; ["AmmoboxInit",[this,true]] call BIS_fnc_arsenal;

crateRespawn.sqf

 private ["_crate","_type","_pos","_newCrate"];

_crate = _this select 0;
_type = typeOf _crate;
_pos = getPos _crate;

waituntil {
       sleep 1;
       (!Alive _crate) || (_crate distance _pos > 1000);
         };


_newCrate = _type createVehicle _pos;

[_newCrate] execVM "crateRespawn.sqf", ["AmmoboxInit",[_newCrate,true]] call BIS_fnc_arsenal;

};

I don't think this would work in MP aswell. Im still learning

Edit: Sorry about the Arma 3 question in a Arma 2 thread

Edited by Trobo

Share this post


Link to post
Share on other sites

I haven't tried out A3 yet, so I can't comment as to how BIS_fnc_Arsenal works or might impact anything. I know it's an A3 command and won't work in A2. You're running it on the crates. I know if you deleteVehicle on an object still being accessed by a running script, you can get a CTD (crash to desktop). :butbut: So maybe someone else can chime in as to whether Arsenal will still be running when the crate deletes.

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

I don't think this would work in MP aswell. Im still learning

CreateVehicle is a global command. When the vehicle is created by anyone it gets created for everyone.

But what you don't want is everybody running the createVehicle code since that would create many crates. Everyone who runs the code on their machine would be creating a crate. Being an editor object, everyone runs the crate's init. Dunno how BIS_fnc_Arsenal responds to that either... but you should certainly limit crateRespawn to being run by server only. Start the crateRespawn.sqf with:

if (!isServer) exitWith {};

Whereas everyone will run the crate's init, now only the server will run the crateRespawn code.

What if you want the crate to be deleted when no player is near?

My suggestion below is a looping function running separate from the crateRespawn script. Each loop would check to see if a player is in range. If not, delete the object.

Try this, and add the arsenal function after you get it working - I tested with crate distance 30 and range 250 because I had to see the objects to know whether it worked, but I don't know how it will perform with crate distance 1000 and range 500:

crate Init:

null = [this] execVM "crateRespawn.sqf";

crateRespawn.sqf:

private ["_crate","_type","_pos","_newCrate"];

if (!isServer) exitWith {};

_crate = _this select 0;
_type = typeOf _crate;
_pos = getPos _crate;

waituntil {
sleep 1;
(!Alive _crate) || (_crate distance _pos > 1000);
};

//stops crates from constantly spawning and deleting after update deletes.
if (isNull _crate) exitWith {};

_newCrate = _type createVehicle _pos;

[_newCrate] execVM "crateRespawn.sqf";

[_newCrate,500] spawn removeObjectUpdate;

compile the "removeObjectUpdate" function in Init.sqf:

waitUntil {!isNil ("BIS_fnc_init")};		// need a functions module on the map

removeObjectUpdate = Compile PreprocessFileLineNumbers ("removeObjectUpdate.sqf");

removeObjectUpdate.sqf:

functions module needed

Private ["_object","_range","_units","_players","_remove","_result"];

_object = _this select 0;			// newCrate
_range = _this select 1;			// 500 (meters)
_units = allUnits;				// creates an array of all units on the map
_players = [_units] call BIS_fnc_listPlayers; 	// filters all units down to an array of players
_remove = [];					// array used for checking result from "player distance crate"

while {(!isNull _object)} do {

{
	// Adds "false" if the player is near, "true" if player is far
	if ((_x distance _object) > _range) then
	{
		_remove = _remove + ["true"];
	}
	else
	{
		_remove = _remove + ["false"];
	};
} forEach _players;

// See if "false" is in the array (returns -1 if not found)
_result = _remove find "false";

// If "false" is found, a player is near. don't delete the object.
// If "false" not found, _result is -1. delete the object.
if (_result < 0) then 
{
	deleteVehicle _object;
	_object = objNull;		// terminates the loop
};

_remove = [];		// empty the array for the next loop

sleep 1;
};

Edited by OpusFmSPol

Share this post


Link to post
Share on other sites

Wow, thanks for taking the time to try that out. I didn't think it be that much more to add. Much appreciated. I took away the 'BIS_fnc_arsenal' and added what you said to craterespawn.sqf, init.sqf and made the removeobjectupdate.sqf. For Arma 3 it didn't work. In case others ever wonder, you did this on Arma 2 and it works?

FYI - When I tested it no error messages popped up. No functions module in arma 3, I read its automatic. I only tried 1000m from crate and 500m from player a few times, I will try the distances you tried tomorrow. Wish I could discuss what may have went wrong on my end but this scripting is just way over my head (The stare at computer screen for 2 hours with no progress made). Maybe I should look into a new angle such as limit number of crates on map to 3 or something before next one will respawn. And the 'if (!isServer) exitWith {};' helped make the script work in MP, thanks

Share this post


Link to post
Share on other sites

Yeah, it works for Arma 2. Since functions are automatic in A3, I suppose the line "waitUntil {!isNil ("BIS_fnc_init")};" in the Init.sqf might be unnecessary.

I used 30 meters for the crate to respawn, and 250 meters for the crate to delete. I used attachTo to place the crate in a truck and then drove away, watching behind to see what happened. The new crate respawned at 30 meters, and when I reached 250 it deleted.

Share this post


Link to post
Share on other sites

Removed the line "waitUntil {!isNil ("BIS_fnc_init")};" from init.sqf and reversed distances, no idea why I had it other way around, and it worked (A3). Sling loaded crate with heli, took off and saw crate spawn at 30m and delete at 250.

The starting crate wont delete if no player within 250m, but a new one will spawn if it is destroyed or moves 30m+ from start distance which is not a big deal. Problem I am having is if new crate has spawned and no player is near it will delete, leaving no crates at pickup point and ending the resupply role.

Share this post


Link to post
Share on other sites

Following the while-do that deletes the crate, you can add code that will recreate _object as another crate when a player comes in range, and have it run the respawn script.

Share this post


Link to post
Share on other sites

I hope OpusFmSPol does not mind if I used his previously postet scripts and edited them a bit.

This Version does spawn a new crate at the position of the first one if this one is moved more than XXm away from its original position or got destroyed somehow.

The script then monitors the moved crate (not the one at the static respawn) and deletes that crate if it is abandoned (no player in a radius of XXm) or destroyed.

I think this is what the OP was looking for.

Open the

object init:

if(isServer)then{[this,50,200] execVM "objectRespawn.sqf"}

This will respawn a new crate if the old one was moved more than 50m away from its original position and delete all moved crates that have no players within 200m around them.

Default are 500 and 250 and You can also just pass the Object to the script using:

[this] execVM "objectRespawn.sqf"

compile the "removeObjectUpdate" function in Init.sqf:

/* ONLY FOR ARMA2
waitUntil {!isNil ("BIS_fnc_init")};		// need a functions module on the map
*/

removeObjectUpdate = Compile PreprocessFileLineNumbers "removeObjectUpdate.sqf";

objectRespawn.sqf:

private ["_object","_respawnDist","_abandonDist","_type","_pos","_dir","_objMoved","_newObj"];

if (!isServer) exitWith {};

_object = _this select 0;	// Object to monitor
_type = typeOf _object;
_pos = getPos _object;
_dir = getDir _object;

// Respawn distance if object is moved - Default 500m
if(count _this > 1)then[{_respawnDist = _this select 1},{_respawnDist = 500}];

// Distance if object is abandoned (no player around) - Default 250m
if(count _this > 2)then[{_abandonDist = _this select 2},{_abandonDist = 250}];


waitUntil { sleep 5;
_objMoved = (_object distance _pos > _respawnDist);
(!alive _object || _objMoved)
};

if(!alive _object)then[{deleteVehicle _object},{[_object, _abandonDist] spawn removeObjectUpdate}];

//Spawn a new crate at the start position
_newObj = _type createVehicle _pos;
_newObj setDir _dir;
_newObj setPos _pos;	//Because ArmA
//_newObj setVectorUp (surfaceNormal _pos);
[_newObj,_respawnDist,_abandonDist] execVM "objectRespawn.sqf";

removeObjectUpdate.sqf:

private ["_object","_abandonDist","_playerNear"];

if (!isServer) exitWith {};

_object = _this select 0;	// Object
if(count _this > 1)then[{_abandonDist = _this select 1},{_abandonDist = 250}]; 

waitUntil { sleep 10; _playerNear = false;

	//For local testing (editor or localhost) use "allUnits"
	//For Multiplayer (dedicated server) use "playableUnits"
{if((_x distance _object) < _abandonDist)exitWith{_playerNear = true}} count allUnits;	//Use exitWith to stop counting at the first unit detected to be within the distance, also count is faster than forEach!

	/*
	Additional approach of using "count" to return true at the first unit found to be near:
	_playerNear = {if((_x distance _object) < _abandonDist)exitWith{true}} count allUnits;	//returns true or a number
	if(typeName _playerNear == "SCALAR")then{_playerNear = false}; //If return from count is not true make it false
	*/

(!alive _object || !_playerNear)
};

deleteVehicle _object;

A respawn timer could also be implemented if needed.

Just leave a note and I can add this to the Script.

Greez KiloSwiss

Edited by KiloSwiss
Script testet in A3 and it works

Share this post


Link to post
Share on other sites
I hope OpusFmSPol does not mind if I used his previously postet scripts and edited them a bit.

Not a problem at all, it was a suggestion and I like learning new and better methods. i.e., I just recently started learning the potential of {_x} count _value and have yet to fully grasp it. And I have yet to start embracing the "faster" methods as well, still working hard to obtain "functional" first. I appreciate the showing how it can be used.

Constructive critique and some good ol' simplified Show-Me-How is always welcome here!

Share this post


Link to post
Share on other sites

Hi. This working great but is not usable as boxes are respawned under transporting.

There must be somehow if(vehicle player == player) implemented. Can someone plese help?

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  

×