Jump to content

Recommended Posts

I wrote a little script to help with base building. This is meant for people who want to build static bases on a map with absolute position (not a composition) and just get the simple createVehicle code back. This is essentially what the broken 3D editor does except this uses Zeus so you get all the objects and stuff.

 

Here's the script:

private ["_pos","_radius","_collection","_startingInt","_c","_final"];

_pos = param [0, (position player)];
_radius = param [1, 250];
_startingInt = param [2, 0];

_collection = nearestObjects [_pos, ["All"], _radius];

if (count _collection > 0) then {
	_c = _startingInt;
	_final = "";
	
	{
		private ["_obj","_class","_sim"];
		
		_obj = _x;
		_class = typeOf _obj;
		_sim = getText (configFile >> "CfgVehicles" >> _class >> "simulation");
		
		if !(_sim in ["soldier","invisible","curator"]) then {
			private ["_pos","_dir","_fuel","_damage"];
			
			_pos = position _obj;
			_dir = getDir _obj;
			_fuel = fuel _obj;
			_damage = damage _obj;
			
			_br = toString [13,10];
			_buildStr = format ["_vehicle_%1 = objNull; if (true) then { _this = createVehicle ['%2', %3, [], 0, 'CAN_COLLIDE']; _vehicle_%1 = _this; _this setDir %4; _this setPos %3; };", _c, _class, _pos, _dir];
			_final = _final + _br + _buildStr;
			
			_c = _c + 1;
		};
	} forEach _collection;
	
	copyToClipboard _final;
	hint "Copied to Clipboard";
};

There are 3 parameters:

0: ARRAY - Position at which the anchor the grabber

1: SCALAR - (Optional, defaults to 250) Radius to use when searching for objects

2: SCALAR - (Optional, defaults to 0) Starting interval number (use this if you want to add on to your base without having to rename variables from 0 to X etc.)

 

All you need to do is put this sort of thing in your init.sqf and then place the Zeus modules on the map in order to enter Zeus (the script will not grab any module objects).

player addAction ["Save Composition", { [position player, 200] execvm "zeusGrabber.sqf" }];
player addAction ["Load Composition", "myBase.sqf"];

Output will be something like this. Then to load your objects just call a script with the generated code inside it.

_vehicle_0 = objNull; if (true) then { _this = createVehicle ['Land_Communication_F', [3997.9,4011.65,0], [], 0, 'CAN_COLLIDE']; _vehicle_0 = _this; _this setDir 0; _this setPos [3997.9,4011.65,0]; };
_vehicle_1 = objNull; if (true) then { _this = createVehicle ['Land_BagBunker_Large_F', [3990.86,3984.25,0], [], 0, 'CAN_COLLIDE']; _vehicle_1 = _this; _this setDir 0; _this setPos [3990.86,3984.25,0]; };
_vehicle_2 = objNull; if (true) then { _this = createVehicle ['Land_ReservoirTank_Rust_F', [4018.19,3981.11,0], [], 0, 'CAN_COLLIDE']; _vehicle_2 = _this; _this setDir 0; _this setPos [4018.19,3981.11,0]; };
_vehicle_3 = objNull; if (true) then { _this = createVehicle ['Land_IndPipe2_Small_ground2_F', [4025.75,3983,0], [], 0, 'CAN_COLLIDE']; _vehicle_3 = _this; _this setDir 0; _this setPos [4025.75,3983,0]; };
_vehicle_4 = objNull; if (true) then { _this = createVehicle ['Land_Factory_Main_F', [4011.58,4021.95,0], [], 0, 'CAN_COLLIDE']; _vehicle_4 = _this; _this setDir 0; _this setPos [4011.58,4021.95,0]; };
_vehicle_5 = objNull; if (true) then { _this = createVehicle ['Land_BagBunker_Large_F', [3978.38,3996.92,0], [], 0, 'CAN_COLLIDE']; _vehicle_5 = _this; _this setDir 0; _this setPos [3978.38,3996.92,0]; };
_vehicle_6 = objNull; if (true) then { _this = createVehicle ['Land_BagBunker_Tower_F', [4009.92,3967.57,0], [], 0, 'CAN_COLLIDE']; _vehicle_6 = _this; _this setDir 0; _this setPos [4009.92,3967.57,0]; };
_vehicle_7 = objNull; if (true) then { _this = createVehicle ['Land_Shed_Small_F', [4036.71,3988.52,0], [], 0, 'CAN_COLLIDE']; _vehicle_7 = _this; _this setDir 0; _this setPos [4036.71,3988.52,0]; };

Share this post


Link to post
Share on other sites

execVM isn't going to be good for big bases.......... 

 

why you ask? Because it pulls it off the slow hard drive, and since that file can be quite large it will probably freeze the game when spawning it in. Much faster to preprocess it and have it loaded in the RAM as its magnitudes faster (and it can move more data at once)

 

execVM may look friendly and all but if its going to be used for something large or more than once it should be put in RAM instead.

Share this post


Link to post
Share on other sites

execVM isn't going to be good for big bases.......... 

 

why you ask? Because it pulls it off the slow hard drive, and since that file can be quite large it will probably freeze the game when spawning it in. Much faster to preprocess it and have it loaded in the RAM as its magnitudes faster (and it can move more data at once)

 

execVM may look friendly and all but if its going to be used for something large or more than once it should be put in RAM instead.

Ah okay good to know. After testing this script on Altis it's totally useless. It grabs objects that are placed in the Altis map, things like bushes and lamp posts etc. Needs more work :/

Share this post


Link to post
Share on other sites
nearestObjects [_pos, ["All"], _radius];

The red part is the issue. You could use a variety of other parent classes for searching (basically what the current object exactly is), some of them could be

 

Building

LandVehicle

Man

Car

Tank

Air

 

more can be found inside the config viewer under the parent classes section of the selected config.

Share this post


Link to post
Share on other sites
nearestObjects [_pos, ["All"], _radius];

The red part is the issue. You could use a variety of other parent classes for searching (basically what the current object exactly is), some of them could be

 

Building

LandVehicle

Man

Car

Tank

Air

 

more can be found inside the config viewer under the parent classes section of the selected config.

 

Ah okay thank you :D

Share this post


Link to post
Share on other sites

It grabs objects that are placed in the Altis map, things like bushes and lamp posts etc.

If your using Zeus to place the objects just use curatorEditableObjects to get all the objects they have placed?

 

player addAction [ "copy objects", {
	
	if ( count ( curatorEditableObjects ( getAssignedCuratorLogic player ))  isEqualTo 0 ) exitWith {
		hint "There are no objects placed for output";
	};
	
	
	KNG_fnc_outputObjects = {
		_collection = curatorEditableObjects ( getAssignedCuratorLogic player );
		_radius = _this;
		_c = 0;
		_br = toString [13];
		_final = "_objs = [];" + _br;
		
		{
			_obj = _x;
					
			if ( _radius isEqualTo -1 || player distance _obj < _radius ) then {
	
				_class = typeOf _obj;
				_sim = getText (configFile >> "CfgVehicles" >> _class >> "simulation");
				
				if !(_sim in ["soldier","invisible","curator"]) then {
					
					_pos = position _obj;
					_dir = getDir _obj;
					_fuel = fuel _obj;
					_damage = damage _obj;
					
					_final = _final + format ["_obj = createVehicle ['%1', [0, 0, 1000], [], 0, 'CAN_COLLIDE'];%4_obj enableSimulationGlobal false;%4_obj setDir %3;%4_obj setPos %2;%4_objs pushback _obj;%4_obj enableSimulationGlobal true;%4",_class, _pos, _dir, _br];
					_c = _c + 1;
				};
			};
		} forEach _collection;
		
		if ( _c > 0 ) then {
			copyToClipboard ( _final + "_objs" ) ;
			hint format [ "Copied %1 objects to the Clipboard", _c ];
		}else{
			hint "No objects within radius";
		};
	};
	
	
	hint "Enter a\nradius from your current position\nor\n-1 for all placed objects";
	disableSerialization;
	
	createDialog "RscDisplayCommonMessage";
	waitUntil { !isNil { uiNamespace getVariable [ "RscDisplayCommonMessage_display", nil ] } };
	_display = uiNamespace getVariable "RscDisplayCommonMessage_display";
	
	ctrlSetText [ 235100, "Enter Radius" ];

	_ctrlGroup = _display displayCtrl 2351;
	
	_edit = _display ctrlCreate ["RscEdit", 1234, _ctrlGroup];
	_edit ctrlSetPosition [ 0.08 * safeZoneW, 0.03 * safeZoneH ];
	_edit ctrlCommit 0;
	_edit ctrlSetText "-1";
	ctrlSetFocus _edit;
	
	_buttonOK = _display displayCtrl 235106;
	_buttonOK ctrlAddEventHandler [ "ButtonDown",{
		
		_replyNum = parseNumber ctrlText 1234;
		if ( _replyNum > 0 || _replyNum isEqualTo -1 ) then {
			closeDialog 1;
			_replyNum call KNG_fnc_outputObjects;
		}else{
			hint "Enter a valid number\ngreater than 0\nor -1 for all placed objects";
			ctrlSetText [ 1234, "-1" ];
			_clearHint = [] spawn {
				sleep 10;
				hint "";
			};
		};
	}];
	
	_buttonCANCEL = _display displayCtrl 235107;
	_buttonCANCEL ctrlAddEventHandler [ "ButtonDown",{
		closeDialog 2;
	}];


}];


Share this post


Link to post
Share on other sites

Just a question, why dont you just use the BIS function? Especially if you only want to save placed objects. I am unsure if it saves placed units, but tbh I doubt it.

Grabber function: https://community.bistudio.com/wiki/BIS_fnc_ObjectsGrabberand the placement function: https://community.bistudio.com/wiki/BIS_fnc_ObjectsMapper

Here is my scripts I use for mp or whatever. You can modify it to capture around the player but I prefer markers like in this code below:

Object Grabber:

//===================================================================================================================
// This script is called to "grab" any zeus placed objects around the marker position. It is stored to the clipboard.
// How to use: Execute this in an execution box or through addAction command 
//             null = ["anchorMrk",size] execVM "compositionGrabber.sqf";
//             "anchorMrk" = is the name of the marker which serves as the reference point from which the objects 
//                            are copied. 
//              size = is the maximum raduis from the reference point that any object is copied 
//===================================================================================================================

hint "Grabbing compilations";
_markerName       = _this select 0;
_size             = _this select 1;
0 = [getMarkerPos _markerName, _size] call BIS_fnc_objectsGrabber;

Object Mapper:

//===================================================================================================================
// This script is called to "map" any zeus saved objects around the marker position. It mapped compositions will be
// called from file with the format example below. The composition route should be clearly specified to the composition.sqf
// How to use: Execute this in an execution box or through addAction command 
//             null = ["anchorMrk","compPath"] execVM "compositionMapper.sqf";
//             "anchorMrk" = is the name of the marker which serves as the reference point from which the objects 
//                            are copied. 
//              "compPath" = is the composition directory path to the composition.sqf. Ex. "compositions\cityGravia_Comp1.sqf"
//===================================================================================================================
_anchorMrk  = _this select 0;
_compPath   = _this select 1;

hint "Placing compilations";
0 = [getMarkerPos _anchorMrk, 0, call (compile (preprocessFileLineNumbers _compPath))] call BIS_fnc_ObjectsMapper;

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

×