Jump to content
mallinga

need help with dragging script

Recommended Posts

Hi,

I want to implement a dragging option for wounded and dead playable units in my mission. I found a good solution by bangabob. Problem is it doesnt work on my dedi server properly. And I am out of ideas. Here is the script:

/*
 DragBody script by BangaBob (H8erMaker) v1.2

 Description
  Drag dead bodies out of sight to avoid detection. JIP/MP/SP/Dedicated compatible

 Instructions
  Add this line into the init.sqf. This will add a drag action to all editor placed units.
	null = allUnits execVM "H8_dragBody.sqf";

 Functions
	[UNIT1,UNIT2,UNIT3] spawn H8_addDrag;
 Add living units into the script. (Useful for units spawned mid-mission).
*/

#define H8_DRAGTEXT		"Drag Body"		// AddAction text for drag body
#define H8_DROPTEXT		"Release Body"	// AddAction text for dropping body
#define H8_LOADTEXT		"Load Body"		// AddAction text for loading body into a vehicle
#define H8_UNLOADTEXT   "Unload Body"	// AddAction text for unloading body from a vehicle

 H8_fnc_Action = {
_dragCond = "vehicle _this != vehicle _target and isNull attachedTo _target and count attachedObjects _this == 0 and _target distance _this < 3";	
		{
	_x addaction [H8_DRAGTEXT,{call H8_DragAction},nil,6,false,false,"",_dragCond];	
		}forEach _this;
 };


 H8_DragAction = {
	_unit 	= 	(_this select 0);

// GLOBAL CODE
	_unitID = _unit getVariable "H8_increm";
 [[_unit, vehicle player,_unitID],"H8_fnc_attach",true] call BIS_fnc_MP; 
 _unit attachTo [player,[0,1,0]];

// CLIENT SIDE
	player playAction "grabDrag";
	player forceWalk true;

_dropID= player addAction [H8_DROPTEXT,{call H8_dropAction},_unit,6];
_hideID =player addAction [H8_LOADTEXT,{call H8_putIncar},_unit,6,false,false,"","_target distance _this < 8 and cursorTarget isKindOf ""LandVehicle"""];

	player setVariable ["H8hideVeh",_hideID];
	player setVariable ["H8dropact",_dropID];
 };


 H8_putIncar = {
 _hideID = (_this select 2);
 _dropID = player getVariable "H8dropact";
 _unit = (_this select 3);
 _vehicle = cursorTarget;

_loadedBody =_vehicle getVariable "H8loadedBody";
	if (isNil "_loadedBody") then {


// CLIENT CODE
	player playMove "amovpknlmstpsraswrfldnon";
	player forceWalk false;	
	player removeAction _hideID;
	player removeAction _dropID;

// GLOBAL CODE
	_unitID = _unit getVariable "H8_increm";
	0 = [[_unit, vehicle player,_unitID],"H8_fnc_detach",true] call BIS_fnc_MP;
		sleep 1;
			deTach _unit;
			_unit setPos [0,0,0];
			_vehicle setVariable ["H8loadedBody",_unit,true];
				[[_vehicle],"H8_carAction",true] call BIS_fnc_MP; 


					}else{
hint "Vehicle already has a body loaded";
	};
 };


 H8_carAction = {
 _vehicle = (_this select 0);
 _vehicle addAction [H8_UNLOADTEXT,{call H8_removeBody},nil,0,false,false,"","_this distance _target < 8"];
 };


 H8_carRemoveAction = {
 _vehicle = (_this select 0);
 _id = (_this select 1);
	_vehicle removeAction _id;
 };


 H8_removeBody = {
 _vehicle = (_this select 0);
 _player = (_this select 1);
 _id = (_this select 2);

 [[_vehicle,_id],"H8_carRemoveAction",true] call BIS_fnc_MP; 

 _unit = _vehicle getVariable "H8loadedBody";
 _vehicle setVariable ["H8loadedBody",Nil];
 	_pos  = _player modelToWorld [1,0,0];
    _unit setPos _pos;
	_unit switchMove "AinjPpneMstpSnonWrflDb_release";
 };


 H8_dropAction = {
 _dropID = (_this select 2);
 _hideID = player getVariable "H8hideVeh";
 _unit	=	(_this select 3);

// GLOBAL CODE
	_unitID = _unit getVariable "H8_increm";
 0 = [[_unit, vehicle player,_unitID],"H8_fnc_detach",true] call BIS_fnc_MP;
 deTach _unit;

// CLIENT SIDE	
	player removeAction _hideID;
	player removeAction _dropID;
	player playMove "amovpknlmstpsraswrfldnon";
	player forceWalk false;	
 };


 H8_fnc_attach = {
	_unit 	= 	(_this select 0);
	_player = 	(_this select 1);
	_unitID =	(_this select 2);

	_id = format ["h8EF%1",_unitID];
 0 = [_id, "onEachFrame", "H8_fnc_moveBody",[_unit,_player]] call BIS_fnc_addStackedEventHandler;
 };


 H8_fnc_detach = {
 	_unit 	= 	(_this select 0);
	_player = 	(_this select 1);
	_unitID =	(_this select 2);

	_id = format ["h8EF%1",_unitID];
 0 = [_id, "onEachFrame"] call BIS_fnc_removeStackedEventHandler;

	sleep 0.05;
 _relD = [_unit,_player] call BIS_fnc_dirTo;
 _unit switchMove "AinjPpneMstpSnonWrflDb_release";
 _unit setDir _relD;
 };


 H8_fnc_moveBody = {
	_unit 	= (_this select 0);
	_player	= (_this select 1);

// CREDIT TOO Das Attorney FOR CODE
	_pos  = _player modelToWorld [0,1,0];
    _unit setPos _pos;
	_unit setDir 180;
	_unit switchMove "AinjPpneMrunSnonWnonDb"; 		
 };


 H8_addDrag = {
 			{
		H8_increments = H8_increments + 1;	
	_x setVariable ["H8_increm",H8_increments,true];
	H8_dragUnitArray set [count H8_dragUnitArray, _x];
			}forEach _this;

	[_this,"H8_fnc_Action",TRUE] call BIS_fnc_MP;

publicVariable "H8_increments";
publicVariable "H8_dragUnitArray";
 };


if (isServer) then {
if (isNil ("H8_dragUnitArray")) then {
	   H8_dragUnitArray = [];
	   H8_increments = 0;};

 			{
		H8_increments = H8_increments + 1;	
	_x setVariable ["H8_increm",H8_increments,true];
	H8_dragUnitArray set [count H8_dragUnitArray, _x];
			}forEach _this;

publicVariable "H8_increments";			
publicVariable "H8_dragUnitArray";
 };

if (!isServer && (player != player)) then { waitUntil {player == player}; waitUntil {time > 15};};

	if (!isDedicated) then {
 0 = H8_dragUnitArray spawn H8_fnc_Action;
		};

I execute the script in the init.sqf :

// Dragging
_dragOption = playableUnits execVM "Scripts\H8_dragBody.sqf";

on mission start it is possible to drag, but if players respawn there is no more action menu option to drag. If I execute it also in the onPlayerRespawn.sqf I get two drag options on mission start but no option on respawn. This happens on the dedicated server, if hosted localy the two drag options are there on respawn, too. What am I doing wrong?? Any help?

Share this post


Link to post
Share on other sites

Multiplayer scripting and single player scripting are totally two different animals. A lot of things can get messed up on the respawn functions.

 

A quick possible fix could be Try to enable the script to run again from a radio trigger after the respawn of the playable unit. 

 

May I ask what you are trying to accomplish. Do you want your playable units to respawn. The reason why I'm asking. I personally modify the AIS wound system that has all the drag carry and place wounded units into vehicles. Bangabob drag script will work with the AIS wounded system but I did not need it since the system had all those functions except for dragging dead bodies but I really didn't need it as long as I was able to carry wounded units or load them into vehicles.

 

I modified the AIS wounded system that the playable units will never die and only stay unconscious the mission will end when all playable units are unconscious. I called this last man standing mode. As long as you have one playable unit alive you can revive all playable units no respawn is needed.

 

I do have team switch enable and it all works with coop play. I would not use it in open JIP missions it could get a little screwy using team switch functionality with join in progress missions. 

 

My Playable units 18 man that can be in a single group or two 9 man groups or six 3 man groups all setup by radio triggers setup for the two squad leaders of the 9 man groups.  This is why I asked you do you want respawns with your playable units.  The modified AIS wounded system is still working progress. There are still some bugs I'm trying to work out for a multiplayer environment including team switch but it's pretty much playable with a few little bugs still present but not game-breakers.

 

 

 

Share this post


Link to post
Share on other sites

Thanks for the reply, my first joyce was also AIS but after a few tests,  I experienced some flaws, like dropped bodies in buildings sinkin into the concrete floor and thats a deal breaker. Also I want to keep it simple as possible for players.  Scenario is "escape" with vanilla revive system. The bangabob script is exactly what I want for the mission, just need help to get it to work on a dedicated server. 

Share this post


Link to post
Share on other sites

I did this from scratch recently, and it wasn't easy. The big problem was when a player didn't have a primary weapon equipped, and even then I came across problems with multiple muzzles (like grenade launcher attachments), especially with the 3GL and part-full mags. But on the end I got this: 

 

 

Basically, execute the code under add addAction on each player, then add the other 3 files into a folder called "dragging" in your mission folder. Rough instructions, i know, but i never got around to fully testing it in a natural MP environment. I did test it functionality over a LAN host with 1 other connected client and it worked fine, and I grabbed a bunch of code from some of my other stuff that I know works over a dedicated server. So hopefully it runs the way it's intended to. Let me know. 

  • Like 1

Share this post


Link to post
Share on other sites

Thanks alot beno, I'll have a look at it. How do you execute your script? via execVM in init.sqf? 

Share this post


Link to post
Share on other sites

Put the contents of addAction in initPlayerLocal.sqf

 

If you can't get it going though I could tidy it up into a proper release tomorrow though, complete with logical instructions even 😁

Share this post


Link to post
Share on other sites

Hey beno,

I tested your script today and it works fine, thanks alot. I'm executing it through init.sqf and onPlayerRespawn.sqf cause in initPlayerLocal.sqf it only executes once. But i need it on every respawning player.

I have however a request: can you please make the revived player automatically detach from the dragger, cause beeing up but stuck to the rescuer not beeing able to do anything ... that might be a way to annoy people (and they always find a way) :) other than that it works fine!

 

Share this post


Link to post
Share on other sites
9 hours ago, mallinga said:

can you please make the revived player automatically detach from the dragger

 

What do you mean exactly? Because if either player dies then the casualty should automatically detach.

Share this post


Link to post
Share on other sites

What i mean is right now, if you drag a wounded player  you can at the same time revive him while attached to you, so if he is revived he is still attached to you and he cant move but he can shoot his gun and you can walk around with him attached to you, he is in your "custody" until you release his body. So if you put in the code that the wounded is detached as soon as he is revived would be great. 

Share this post


Link to post
Share on other sites

Ok, use this in your init/onRespawn then:

 

player setVariable ["MIL_playerIsDragging",[false,objNull]];

_idDrag = player addAction [
	"<t color='#C6E32E'>Drag unconscious player</t>",
	{
		private _casualty = cursorObject;
		player setVariable ["MIL_playerIsDragging",[true,_casualty]];
		player setVariable ["#rev_enabled",false];
		nul = [_casualty] execVM "dragging\dragUnconscious.sqf";
	},
	nil,
	10,
	true,
	false,
	"",
	"(lifeState cursorObject == 'INCAPACITATED') && ('unconsciousrevivedefault' in (animationState cursorObject)) && (lifeState _this != 'INCAPACITATED') && !((_this getVariable ['MIL_playerIsDragging',[false,objNull]]) select 0)",
	1.5
];

_idDrop = player addAction [
	"<t color='#C6E32E'>Drop unconscious player</t>",
	{
		private _casualty = (player getVariable "MIL_playerIsDragging") select 1;
		private _drop = [_casualty] execVM "dragging\dropUnconscious.sqf";
		waitUntil {scriptDone _drop};
		player setVariable ["MIL_playerIsDragging",[false,objNull]];
		player setVariable ["#rev_enabled",true];
	},
	nil,
	10,
	true,
	false,
	"",
	"(lifeState _this != 'INCAPACITATED') && ((_this getVariable ['MIL_playerIsDragging',[false,objNull]]) select 0)",
	1.5
];

 

Added a line to change the #rev_enabled variable.

Share this post


Link to post
Share on other sites

Thanks alot beno, much appreciated! 

I'll add a comment that you are the author, if thats ok for you. 

Share this post


Link to post
Share on other sites

Yeah no worries 👍 let me know if there's any other issues

Share this post


Link to post
Share on other sites

Summary:

create folder: dragging

Place following files in dragging folder:

dragging.sqf:

// Dragging Wounded Script by beno_83au
// Place all dragging files in a folder called "dragging"
// Add this line to init.sqf + onPlayerRespawn.sqf: _dragOption = playableUnits execVM "dragging\dragging.sqf";


player setVariable ["MIL_playerIsDragging",[false,objNull]];

_idDrag = player addAction [
	"<t color='#C6E32E'>Drag unconscious player</t>",
	{
		private _casualty = cursorObject;
		player setVariable ["MIL_playerIsDragging",[true,_casualty]];
		player setVariable ["#rev_enabled",false];
		nul = [_casualty] execVM "dragging\dragUnconscious.sqf";
	},
	nil,
	10,
	true,
	false,
	"",
	"(lifeState cursorObject == 'INCAPACITATED') && ('unconsciousrevivedefault' in (animationState cursorObject)) && (lifeState _this != 'INCAPACITATED') && !((_this getVariable ['MIL_playerIsDragging',[false,objNull]]) select 0)",
	1.5
];

_idDrop = player addAction [
	"<t color='#C6E32E'>Drop unconscious player</t>",
	{
		private _casualty = (player getVariable "MIL_playerIsDragging") select 1;
		private _drop = [_casualty] execVM "dragging\dropUnconscious.sqf";
		waitUntil {scriptDone _drop};
		player setVariable ["MIL_playerIsDragging",[false,objNull]];
		player setVariable ["#rev_enabled",true];
	},
	nil,
	10,
	true,
	false,
	"",
	"(lifeState _this != 'INCAPACITATED') && ((_this getVariable ['MIL_playerIsDragging',[false,objNull]]) select 0)",
	1.5
];

dragUnconscious.sqf:

params ["_casualty"];

private _currentWeapon = currentWeapon player;
private _workAround = [false,[]];
switch true do {
	case (_currentWeapon == ""): {};
	case (_currentWeapon == primaryWeapon player): {};
	case (_currentWeapon == secondaryWeapon player): {
		if ((primaryWeapon player) == "") then {
			private _weapon = handgunWeapon player;
			_currentWeapon = _weapon;
			player selectWeapon _weapon;
			waitUntil {([animationState player,16,19] call BIS_fnc_trimString) == "wpst"};
			} else {
			_currentWeapon = primaryWeapon player;
		};
	};
	case (_currentWeapon == handgunWeapon player): {
		if ((primaryWeapon player) != "") then {
			private _primaryWeapon = primaryWeapon player;
			private _magazinesAmmoFull = (magazinesAmmoFull player) select {(_x select 3) == 1};
			private _primaryWeaponMagazine = [];
			{
				_primaryWeaponMagazine pushBack [_x select 0,_x select 1];
			} forEach _magazinesAmmoFull;
			private _primaryWeaponItems = primaryWeaponItems player;
			
			player removeWeapon _primaryWeapon;
			
			_workAroundHolder = "Weapon_Empty" createVehicle [0,0,0];
			_workAroundHolder setPos (getPos player);
			_workAroundHolder addWeaponWithAttachmentsCargoGlobal [[_primaryWeapon,_primaryWeaponItems select 0,_primaryWeaponItems select 1,_primaryWeaponItems select 2,[(_primaryWeaponMagazine select 0) select 0,1],[],_primaryWeaponItems select 3],1];
			_workAroundHolder attachTo [player,[0,-0.2,0],"rightshoulder"];
			_workAroundHolder setDir 290;
			_workAroundHolder setVectorUp [0,-1,0.9];
			_workAroundHolder setDamage 1;			
			
			_workAround = [true,[_primaryWeapon,_primaryWeaponItems,_primaryWeaponMagazine],_workAroundHolder];
		};
	};
};

nul = [_workAround,_currentWeapon] execVM "dragging\restrictions.sqf";

[_casualty,"AinjPpneMrunSnonWnonDb_grab"] remoteExec ["switchMove",0];
player playActionNow "grabDrag";

_casualty attachTo [player,[0.1,0.9,-0.02]];
[_casualty,180] remoteExec ["setDir",_casualty];

nul = [_casualty] spawn {
	params ["_casualty"];
	waitUntil {
		sleep 0.1;
		(
			!alive player ||
			!alive _casualty ||
			!((player getVariable "MIL_playerIsDragging") select 0)
		)
	};
	if (!alive player || !alive _casualty) then {
		[_casualty,"AinjPpneMstpSnonWrflDb_release"] remoteExec ["switchMove",0];
		detach _casualty;
		player playActionNow "released";
		player setVariable ["MIL_playerIsDragging",[false,objNull]];
	};
};

dropUnconscious.sqf:

params ["_casualty"];

[_casualty,"AinjPpneMstpSnonWrflDb_release"] remoteExec ["switchMove",0];
player playActionNow "released";

detach _casualty;

restrictions.sqf:

 params ["_workAround","_currentWeapon"];

private _ehIndex = player addEventHandler ["Fired",{
    params ["_unit","_weapon","","","","_magazine","_projectile"];
    if (({_weapon == _x} count ["Put","Throw"]) > 0) then {
        deleteVehicle _projectile;
        _unit addMagazine _magazine;
    };
}];

private _weaponEH = [
    format["%1_weaponEH",player],
    "onEachFrame",
    {
        params ["_currentWeapon"];
        if (currentWeapon player != _currentWeapon) then {
            player selectWeapon _currentWeapon;
        };
    },
    [_currentWeapon]
] call BIS_fnc_addStackedEventHandler;

waitUntil {!((player getVariable "MIL_playerIsDragging") select 0)};

[_weaponEH,"onEachFrame"] call BIS_fnc_removeStackedEventHandler;
player removeEventHandler ["Fired",_ehIndex];

if (_workAround select 0) then {
    waitUntil {animationState player != "acinpknlmstpsnonwpstdnon_amovpknlmstpsraswpstdnon"};
    _workAround params ["","_weaponData","_workAroundHolder"];
    _weaponData params ["_primaryWeapon","_primaryWeaponItems","_primaryWeaponMagazine"];
    deleteVehicle _workAroundHolder;
    player addWeapon _primaryWeapon;
    
    {
        player addWeaponItem [_primaryWeapon,_x,true];
    } forEach _primaryWeaponItems;
    
    private _grabbedMags = (magazinesAmmoFull player) select {(_x select 2) && ((_x select 3) == 1)};
    
    if (count (getArray (configFile >> "CfgWeapons" >> _primaryWeapon >> "muzzles")) == 1) then {
        if (count _grabbedMags > 0) then {
            player addMagazine [(_grabbedMags select 0) select 0,(_grabbedMags select 0) select 1];
        };
        if (count _primaryWeaponMagazine > 0) then {
            player setAmmo [_primaryWeapon,(_primaryWeaponMagazine select 0) select 1];
            } else {
            player setAmmo [_primaryWeapon,0];
        };
        
        } else {
        
        if (count _primaryWeaponMagazine == 1) then {
            private _check = _primaryWeaponMagazine;
            {
                if (((_check select 0) select 0) != (_x select 0)) then {
                    _primaryWeaponMagazine = [_primaryWeaponMagazine,[["",0]],_forEachIndex] call BIS_fnc_arrayInsert;
                };
            } forEach _grabbedMags;
        };
        if (count _grabbedMags > 0) then {
            {
                player addMagazine [_x select 0,_x select 1];
                player removePrimaryWeaponItem (_x select 0);
            } forEach _grabbedMags;
        };
        if (count _primaryWeaponMagazine > 0) then {
            private _ehIndex = player addEventHandler ["Reloaded",{player setVariable ["MIL_Workaround_Reloaded",true]}];
            player setVariable ["MIL_Workaround_Reloaded",false];
            {
                private _mag = _x select 0;
                private _rounds = _x select 1;
                private _index = _forEachIndex;
                private _muzzle = [_primaryWeapon,(getArray (configFile >> "CfgWeapons" >> _primaryWeapon >> "muzzles")) select 1] select (_index > 0);

                if (_rounds > 0) then {
                    player addMagazine [_mag,_rounds];
                };
                {
                    private _exit = false;
                    if (((_x select 0) == _mag) && ((_x select 1) == _rounds)) then {
                        _id = parseNumber ((((magazinesDetail player) select _forEachIndex) splitstring "[:/]") select 4);
                        _cr = parseNumber ((((magazinesDetail player) select _forEachIndex) splitstring "[:/]") select 5);
                        player action ["loadMagazine",player,objNull,_cr,_id,primaryWeapon player,_muzzle];
                        waitUntil {player getVariable "MIL_Workaround_Reloaded"};
                        player setVariable ["MIL_Workaround_Reloaded",false];
                        _exit = true;
                    };
                    if (_exit) exitWith {};
                } forEach (magazinesAmmo player);
                
            } forEach _primaryWeaponMagazine;
            player removeEventHandler ["Reloaded",_ehIndex];
        };
    };
}; 

 Then add this line to init.sqf + onPlayerRespawn.sqf:

_dragOption = playableUnits execVM "dragging\dragging.sqf";

 

Share this post


Link to post
Share on other sites

Hey beno, 

After playing a whole mission, we came across following issues (which I tried to solve without luck):

 

- The action menu is activating from far away (50meters) so players could start dragging from up to 50 meters away. The injured is then teleported to the player. I see there is a 1.5 m radius set in the code but changing this doesnt have any effect. 

 

- if dragger is incapacitated, the two bodies are still attached to each other, so the two bodies can be dragged at the same time, and this is stackable: if the dragger of the two is incapacitated the three bodies can be dragged and so on. 

 

 

  • Thanks 1

Share this post


Link to post
Share on other sites

Ok, remember kids, it's a bad idea to maintain two copies of things, then make changes on the second copy and not move those changes into the main copy....... I knew I'd already accounted for distance and deaths somewhere 🙄

I updated the other post with (what should be) the correct code: https://forums.bohemia.net/forums/topic/229717-pistols-playactionnow-grabdrag/?do=findComment&amp;comment=3411854

Sorry!

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

×