Jump to content
Sign in to follow this  
BadHabitz

Needed: Respawning a container

Recommended Posts

I'm going to implement a feature on a MP map, but I'm trying to wrap my head around a way to respawn a container/ammo box after it's been destroyed. The container will have a filler script, or just an items list in the INIT. So the container will be moved (or not) and once destroyed it should respawn at the original location. So I guess for intents and purposes I need a way to treat a container to respawn the same way a vehicle should.

I've seen some info in old A2 threads, but I didn't want to rehash old threads, and I wasn't sure if any of that has changed for A3.

Thanks in advance...

Edited by BadHabitz

Share this post


Link to post
Share on other sites

Add a marker where you want the crate to respawn, place your filler script in its own script file rather than in the crates init box.

In the init put

handle = this execVM "myFillerScript.sqf";

myFillerScript.sqf

//stuff to put in the box
_crate = _this;
_crate addMagazineCargoGlobal ["NLAW_F",2];
_crate addMPEventHandler ["MPKilled",{_crate = (typeOf (_this select 0)) createVehicle (getMarkerPos "myCrateMarker"); _crate execVM "myFillerScript.sqf"}];

On initial spawn the init line will run the script filling your crate with what ever and will also add an event of MPKilled to the crate.

On the crate becoming dead :/ it will create another of exactly the same type placed at the marker and will run myFillerScript.sqf filling the crate and add an event to it. add infinitum.

Share this post


Link to post
Share on other sites

So I can use 'myfillerscript' on the initial map startup, or do I need a 'initialfillerscript' in addition? I'm thinking 'myfillerscript' will handle it all. Also, 'mycratemarker', do I type that in? I'm guessing I need to substitute that for something, but I'm not sure what.

Otherwise, I'll assume that when I do this as is it is written, it will spawn a container with two NLAW_F, and the crate will respawn when it's destroyed.

Share this post


Link to post
Share on other sites
So I can use 'myfillerscript' on the initial map startup
Yes, just execVM the script from the crates init box as written in my previous post and it will fill your crate and add the event, the event then reruns the script on the newly crated crate.
Also, 'mycratemarker', do I type that in? I'm guessing I need to substitute that for something, but I'm not sure what.
Create a marker in the editor and name it myCrateMarker at the position you want the crate to be placed when its respawned.
I'll assume that when I do this as is it is written, it will spawn a container with two NLAW_F, and the crate will respawn when it's destroyed.
Thats correct

Share this post


Link to post
Share on other sites

Perfect. Thanks. I have some people that want =BTC= Logistics incorporated into Invade & Annex. Delivering vehicles by helicopter is sexy, but I also wanted the ability to fly in crates for ammo resupply. The problem then is that mission can be played into perpetuity. I can drop some crates, but once they're used they're gone. I don't want to include 100 ammo crates. Your script gives the option to fly ammo into a battle area, and when it's no longer needed it can be destroyed and respawned so it can be used somewhere else. Thanks. I will include your input into the sqf.

One problem with my grand plan. Seems that ammo crates are made from a substance that is impervious to damage. I need to find a way to despawn the crate. I loaded the area of an ammo crate with about 20 M6 mines and dropped an explosive charge. The result was something that would make NASA proud, but it survived the explosion and the impact of returning from the upper atmosphere.

Edited by BadHabitz

Share this post


Link to post
Share on other sites

disregard

Edited by BadHabitz
double post

Share this post


Link to post
Share on other sites
I hold this post in high regard!

I saw kylania posted on my thread and I thought I could put all my troubles behind me... but alas...

Thanks for the chuckle though. :cool:

Share this post


Link to post
Share on other sites

Oh, sorry, I did the same. Saw Larrow had posted and blanked out since you probably had your answer. :) Off to read the actual post!

Share this post


Link to post
Share on other sites

This is deserted check, could be useful for your case

Will delete your ammo box if none is within 200m of it for 10 minutes

_vehicle = your ammo box
_timeToDelete = 0;
while{true} do {
_deserted = true;
{								
	if (_x distance _vehicle < 200) then { // 200m
		_deserted = false;					
	}; 
} forEach allPlayableUnits;
if(_deserted && _timeToDelete==0) then {
	_timeToDelete = time + 60*10; // delete after 10 mins if none is within 200 m
} else {
	_timeToDelete = 0;
};
if(_timeToDelete<time) exitWith {
	deleteVehicle _vehicle;
};
sleep 10;
};

Share this post


Link to post
Share on other sites

I think that could work. If it just sits unattended at it's spawn point it will despawn, but then respawn again right in the same spot.

I was thinking of adding a scroll wheel option to despawn it, but I don't want someone to do that by accident.

Share this post


Link to post
Share on other sites
I loaded the area of an ammo crate with about 20 M6 mines and dropped an explosive charge. The result was something that would make NASA proud, but it survived the explosion and the impact of returning from the upper atmosphere.
lol

Sorry chap didnt see your added post, looks like you got your answer though :D

Share this post


Link to post
Share on other sites
I think that could work. If it just sits unattended at it's spawn point it will despawn, but then respawn again right in the same spot.

I was thinking of adding a scroll wheel option to despawn it, but I don't want someone to do that by accident.

Well then, add distance from spawn check, will now only work if it moved 100m from its initial position.

_box = your ammo box
_originalPos = getPosATL _box; 
_timeToDelete = 0;
while{true} do {
if(_box distance _originalPos > 100) then {	
	_deserted = true;
	{	
		if(_deserted) then {							
			if (_x distance _box < 200) then { // 200m
				_deserted = false;					
			}; 
		};
	} forEach allPlayableUnits;
	if(_deserted && _timeToDelete==0) then {
		_timeToDelete = time + 60*10; // delete after 10 mins if none is within 200 m
	} else {
		_timeToDelete = 0;
	};
	if(_timeToDelete<time) exitWith {
		deleteVehicle _box;
		// respawn logic here
	};
};
sleep 10;
};

Share this post


Link to post
Share on other sites

To prevent accidents you can always have the action script only activate a counter, and only if you click the de-spawn action 3 times in a row within 7 seconds then the crate will despawn. Write it in the briefing, so only people who read the briefing will be able to do something as potentially annoying as de-spawning crates.

Share this post


Link to post
Share on other sites
To prevent accidents...

Thanks for the suggestion, but I think what's been provided will be enough. I plan to put 5 of these crates on the airstrip. One can be delivered, and once the objective is taken and everyone moves on to the next target the crate will neatly despawn. If they need a crate at the next target there will be others available. I'll just have to keep an eye on how things work, to adjust time and distance.

Share this post


Link to post
Share on other sites

Having trouble. Not sure if I got this right or if I need it in two sqf's.

Boxes are not despawning all of the time, and if they do it's only ammocrate1. Despawned crates don't respawn.

I did change the time for testing purposes.

// Respawning ammo crate script - August 22nd, 2013

_crate = _this;
clearMagazineCargoGlobal _crate;
clearWeaponCargoGlobal _crate;
clearBackpackCargoGlobal _crate;
clearItemCargoGlobal _crate;
_crate addMagazineCargoGlobal ["20Rnd_762x51_Mag", 150];
_crate addMagazineCargoGlobal ["HandGrenade", 200];
_crate addMagazineCargoGlobal ["7Rnd_408_Mag", 100];
_crate addMagazineCargoGlobal ["200Rnd_65x39_cased_Box", 30];
_crate addMagazineCargoGlobal ["30Rnd_65x39_caseless_mag", 200];
_crate addMagazineCargoGlobal ["16Rnd_9x21_Mag", 30];
_crate addMagazineCargoGlobal ["SatchelCharge_Remote_Mag", 10];
_crate addMagazineCargoGlobal ["NLAW_F", 50];
_crate addMagazineCargoGlobal ["SmokeShell", 50];
_crate addMagazineCargoGlobal ["SmokeShellGreen", 50];
_crate addMagazineCargoGlobal ["SmokeShellRed", 50];
_crate addItemCargoGlobal ["Medikit", 50];
_crate addItemCargoGlobal ["acc_pointer_IR", 10];
_crate addMPEventHandler ["MPKilled",{_crate = (typeOf (_this select 0)) createVehicle (getMarkerPos "ammocrate1, ammocrate2, ammocrate3, ammocrate4, ammocrate5"); _crate execVM "ammocratefiller.sqf"}];

_box = ammocrate1, ammocrate2, ammocrate3, ammocrate4, ammocrate5; 
_originalPos = getPosATL _box;  
_timeToDelete = 0; 
while{true} do { 
   if(_box distance _originalPos > 100) then {     
       _deserted = true; 
       {     
           if(_deserted) then {                             
               if (_x distance _box < 100) then { // 200m 
                   _deserted = false;                     
               };  
           }; 
       } forEach allPlayableUnits; 
       if(_deserted && _timeToDelete==0) then { 
           _timeToDelete = time + 60*1; // delete after 10 mins if none is within 200 m 
       } else { 
           _timeToDelete = 0; 
       }; 
       if(_timeToDelete<time) exitWith { 
           deleteVehicle _box; 
           // respawn logic here 
       }; 
   }; 
   sleep 10; 
};

Share this post


Link to post
Share on other sites

Are you defining allPlayableUnits?

Also, you cannot define "_box" in that way.

Also, notice you still only have a placeholder comment "// respawn logic here", so of coures it does not respawn.

Are you using -showScriptErrors? If not, then you should. I bet it'd point out quite a few errors in your script, maybe more than those I've noticed.

Share this post


Link to post
Share on other sites
Are you defining allPlayableUnits?

Also, you cannot define "_box" in that way.

Also, notice you still only have a placeholder comment "// respawn logic here", so of coures it does not respawn.

Are you using -showScriptErrors? If not, then you should. I bet it'd point out quite a few errors in your script, maybe more than those I've noticed.

Yeah, I'm sorry. I'm trying to figure out scripting, but by the time I figure it out we'll be playing Arma 7. That's why I ask for help on the forums.

Share this post


Link to post
Share on other sites

Hopefully this is correct, ive been trying to get this sorted while packing to go away this weekend.

Same as before, name your ammoboxes e.g ammobox1, place a marker with the same name where you want them to spawn e.g "ammobox1".

In the init line of the ammobox place

_handle = this execVM "ammocratefiller.sqf";

ammocratefiller.sqf

_crate = _this;
_crate setPosATL getMarkerPos (vehicleVarName _crate);

clearMagazineCargoGlobal _crate;
clearWeaponCargoGlobal _crate;
clearBackpackCargoGlobal _crate;
clearItemCargoGlobal _crate;
_crate addMagazineCargoGlobal ["20Rnd_762x51_Mag", 150];
_crate addMagazineCargoGlobal ["HandGrenade", 200];
_crate addMagazineCargoGlobal ["7Rnd_408_Mag", 100];
_crate addMagazineCargoGlobal ["200Rnd_65x39_cased_Box", 30];
_crate addMagazineCargoGlobal ["30Rnd_65x39_caseless_mag", 200];
_crate addMagazineCargoGlobal ["16Rnd_9x21_Mag", 30];
_crate addMagazineCargoGlobal ["SatchelCharge_Remote_Mag", 10];
_crate addMagazineCargoGlobal ["NLAW_F", 50];
_crate addMagazineCargoGlobal ["SmokeShell", 50];
_crate addMagazineCargoGlobal ["SmokeShellGreen", 50];
_crate addMagazineCargoGlobal ["SmokeShellRed", 50];
_crate addItemCargoGlobal ["Medikit", 50];
_crate addItemCargoGlobal ["acc_pointer_IR", 10];
_crate addMPEventHandler ["MPKilled",{
_varName = vehicleVarName (_this select 0);
_crateType = (typeOf (_this select 0));
deleteVehicle (_this select 0);
_crate = _crateType createVehicle (getMarkerPos _varName);
_crate setVehicleVarName _varName;
_crate call compile format["%1 = _this; publicVariable ""%1"";",(vehicleVarName _crate)];
_crate execVM "ammocratefiller.sqf";
}];

_spawningPos = getPosATL _crate;
_desertedTimeOut = 600; //10 mins
_deletionTime = 0;
_deserted = false;
_moved = false;
while{alive _crate} do {
//default distance allowed to move from spawn marker
//before being monitored for desertion
if(_crate distance _spawningPos > 2) then {
	_moved = true;
};
while {alive _crate && _moved} do {
	if ({
			//distance players need to be within to stop it despawning
			_x distance (getPosATL _crate) < 200
		}count (playableUnits + switchableUnits) == 0) then {
			_deserted = true;
			if (_deletionTime == 0) then {
				_deletionTime = time + _desertedTimeOut;
			};
	}else{
		_deserted = false;
		if ( _deletionTime != 0 ) then {
			_deletionTime = 0;
		};
	};
	if (_deserted && (time >= _deletionTime)) then {
		_crate setPosATL _spawningPos;
		_moved = false;
	};
	sleep 0.5;
};
sleep 0.5;
};

As coded above the ammobox will spawn and set its position at the marker with the same name.

On being destroyed the old box will delete itself and a new one will spawn at the marker.

If the box is moved more than 2 meters from its marker it will then start monitoring for any players within 200 meters, if there are no players within 200 meters of it for 10 minutes then it will despawn and reappear at its default marker location.

my test mission, just incase ive messed anything up in the script above by deleting all my debugging info.

Im outta here away for along UK bank holiday weekend :yay:!!! laters

Share this post


Link to post
Share on other sites
Im outta here away for along UK bank holiday weekend :yay:!!! laters
You're the man. Take as much time off as you want. You deserve it. Thanks!

Just tested it and it works! Tweaked the time/distance for my purposes, but it's fantastic!

Share this post


Link to post
Share on other sites

UPDATE: I just put this script through some dedicated server testing since ive got home and ive discovered a problem, plus ive also added some tweaks. Posting in code tags so i can highlight the changes.

init.sqf

[color="#FF0000"]//array of crates to start script on
crates = [ammocrate1, ammocrate2, ammocrate3, ammocrate4, ammocrate5];

if (isServer) then {
fnc_fillScript = compile preprocessFileLineNumbers "ammocratefiller.sqf";
{
	_handle = _x spawn fnc_fillscript;
}forEach crates;
};[/color]

As this is something that should only be monitored from the server remove all the execVM's from the crates init boxes and use the above init.sqf instead to start the scripts for each crate. Ive also compiled the ammocratefiller.sqf into a function called fnc_fillScript to stop the script having to reload and compile the script every time its called. This solves a little problem i found that multiple crates were sometimes being produced on the crate being destroyed.

ammocratefiller.sqf

_crate = _this;
_crate setPosATL getMarkerPos (vehicleVarName _crate);

clearMagazineCargoGlobal _crate;
clearWeaponCargoGlobal _crate;
clearBackpackCargoGlobal _crate;
clearItemCargoGlobal _crate;
_crate addMagazineCargoGlobal ["20Rnd_762x51_Mag", 150];
_crate addMagazineCargoGlobal ["HandGrenade", 200];
_crate addMagazineCargoGlobal ["7Rnd_408_Mag", 100];
_crate addMagazineCargoGlobal ["200Rnd_65x39_cased_Box", 30];
_crate addMagazineCargoGlobal ["30Rnd_65x39_caseless_mag", 200];
_crate addMagazineCargoGlobal ["16Rnd_9x21_Mag", 30];
_crate addMagazineCargoGlobal ["SatchelCharge_Remote_Mag", 10];
_crate addMagazineCargoGlobal ["NLAW_F", 50];
_crate addMagazineCargoGlobal ["SmokeShell", 50];
_crate addMagazineCargoGlobal ["SmokeShellGreen", 50];
_crate addMagazineCargoGlobal ["SmokeShellRed", 50];
_crate addItemCargoGlobal ["Medikit", 50];
_crate addItemCargoGlobal ["acc_pointer_IR", 10];
_crate [color="#FF0000"]addEventHandler ["Killed"[/color],{
_varName = vehicleVarName (_this select 0);
_crateType = (typeOf (_this select 0));
deleteVehicle (_this select 0);
_crate = _crateType createVehicle (getMarkerPos _varName);
_crate setVehicleVarName _varName;
_crate call compile format["%1 = _this; publicVariable ""%1"";",(vehicleVarName _crate)];
_crate [color="#FF0000"]spawn fnc_fillscript;[/color]
}];

_spawningPos = getPosATL _crate;
_desertedTimeOut = 10;
_deletionTime = 0;
_deserted = false;
_moved = false;
while{alive _crate} do {
if(_crate distance _spawningPos > 10) then {
	_moved = true;
};
while {alive _crate && _moved} do {
	if ({
			_x distance (getPosATL _crate) < 30
		}count (playableUnits + switchableUnits) == 0) then {
			_deserted = true;
			if (_deletionTime == 0) then {
				_deletionTime = time + _desertedTimeOut;
			};
	}else{
		_deserted = false;
		if ( _deletionTime != 0 ) then {
			_deletionTime = 0;
		};
	};
	if (_deserted && (time >= _deletionTime)) then {
		[color="#FF0000"]_crate setVectorUp [0,0,1];[/color]
		_crate setPosATL _spawningPos;
		[color="#FF0000"]_crate setDamage 0;[/color]
		_moved = false;
	};
	sleep 0.5;
};
sleep 0.5;
};

Here i have changed the event handler to a normal one rather than MP as again it only needs to be monitored via the server, this also fixes some spawning issues i noticed on testing in a dedicated enviroment.

I have also added some code for when the ammocrate is moved back to its starting location to remove any damage it may have received and to make sure it is stood upright.

Updated test mission.

Share this post


Link to post
Share on other sites

Thanks!

Edited by BadHabitz

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  

×