Jump to content
BlackbirdSD

Dying near a rock then spawning into it problem

Recommended Posts

In multiplayer it has happened many times that we have died near a rock then respawned inside the rock and there is no way out.  This happens on various maps.  Any idea how to fix this?

Thanks

Share this post


Link to post
Share on other sites

Known also from SP unit spawn scripts etc. I suppose, it is because rock formations are one of the largest objects, so if you determine safe spawn position (not colliding with any object) you have to apply quite large radius to be sure, it will find also a rock object (its center point namely, which can be pretty distant even, when standing just at the rock). Such big radius however will very often include some objects, so the obstacle will be nearly always reported, which makes finding safe spot almost impossible. 

 

Perhaps this applies also to the algorithm looking for good respawn position, be it some scripted solution or native Arma's code. It could be workarounded assuming, one can customize respawn position via script (within respawn event handler perhaps?). The trick would be to check for any obstacles in small radius, and then also check for rock formations obstacles specifically in quite large radius when looking for a good spot, probably using nearestTerrainObjects with "ROCK", "ROCKS" and, as I read, "HIDE" types of map objects. Another way could be perhaps not searching by object's center (meaning  - position itself), but rather it's bounding box edges, but that sounds like lots of excessive complex calculations and it is possible, not all objects have proper bounding boxes.

Share this post


Link to post
Share on other sites
27 minutes ago, Rydygier said:

Known also from SP unit spawn scripts etc. I suppose, it is because rock formations are one of the largest objects, so if you determine safe spawn position (not colliding with any object) you have to apply quite large radius to be sure, it will find also a rock object (its center point namely, which can be pretty distant even, when standing just at the rock). Such big radius however will very often include some objects, so the obstacle will be nearly always reported, which makes finding safe spot almost impossible. 

 

Perhaps this applies also to the algorithm looking for good respawn position, be it some scripted solution or native Arma's code. It could be workarounded assuming, one can customize respawn position via script (within respawn event handler perhaps?). The trick would be to check for any obstacles in small radius, and then also check for rock formations obstacles specifically in quite large radius when looking for a good spot, probably using nearestTerrainObjects with "ROCK", "ROCKS" and, as I read, "HIDE" types of map objects. Another way could be perhaps not searching by object's center (meaning  - position itself), but rather it's bounding box edges, but that sounds like lots of excessive complex calculations and it is possible, not all objects have proper bounding boxes.

I guess I should have also let you know that I have it set to respawn on location of death.

Share this post


Link to post
Share on other sites

So, I'm not MP scripting expert, hence this code may need some corrections, but one way to do, what I described, would be something like:

 

Spoiler

player addEventHandler ["Respawn", 
	{
	params ["_unit","_corpse"];
	
	_isGood = false;
	_pos = getPosATL _corpse;
	_safePos = _pos findEmptyPosition [0.5,5,(typeOf _unit)];

	if ((count _safePos) > 1) then
		{
		_isGood = ((nearestTerrainObjects [_safePos,["ROCK","ROCKS","HIDE"],35]) findIf {(((0 boundingBoxReal _x) select 2) > 10)}) < 0;
		};

	_ct = 0;	
	while {not (_isGood)} do
		{
		_ct = _ct + 10;
		for "_i" from 36 to 360 step 36 do
			{
			_safePos = (_pos getPos [_ct,_i]) findEmptyPosition [0.5,(_ct/2),(typeOf _unit)];

			if ((count _safePos) > 1) then
				{
				_isGood = ((nearestTerrainObjects [_safePos,["ROCK","ROCKS","HIDE"],35]) findIf {(((0 boundingBoxReal _x) select 2) > 10)}) < 0;
				};
				
			if (_isGood) exitWith {};
			};
			
		if ((_ct > 100) and {not (_isGood)}) exitWith
			{
			_safePos = _pos
			};
		};
		
	_safePos set [2,0.01];	

	_unit setPos _safePos;
	}];

 

 

 

This probably (? not sure...) should be put into init.sqf to be executed on every machine with player...

 

If this works, still sometimes player lands inside a rock, then possibly some radiuses may need to be higher.

Share this post


Link to post
Share on other sites
17 hours ago, BlackbirdSD said:

In multiplayer it has happened many times that we have died near a rock then respawned inside the rock and there is no way out.  This happens on various maps.  Any idea how to fix this?

Thanks

 

Truly, I can't reproduce that, but perhaps you have some respawn markers on such places.

Anyway, this solution works (in init.sqf):

 

addMissionEventHandler ["entityRespawned",{
  params ["_entity", "_corpse"];
  private _pos = (getPos _entity vectorAdd [0,0,100]);
  _entity setVehiclePosition [_pos,[],0,"CAN_COLLIDE"];
  deleteVehicle _corpse;
}];

 

Share this post


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

 

Truly, I can't reproduce that, but perhaps you have some respawn markers on such places.

Anyway, this solution works (in init.sqf):

 


addMissionEventHandler ["entityRespawned",{
  params ["_entity", "_corpse"];
  private _pos = (getPos _entity vectorAdd [0,0,100]);
  _entity setVehiclePosition [_pos,[],0,"CAN_COLLIDE"];
  deleteVehicle _corpse;
}];

 

That worked, thank you, How can I hide this command into the custom menu (9) or radio so its not so easy to hit when using the action key?  I wonder why I can clip into the rocks so easily, I dont have any respawn markers setup just respawn on position of death.

Thanks

Share this post


Link to post
Share on other sites

This code is for the respawn sequence only. You don't have to add it in a menu. For your other post, see the answer at the right page.

Share this post


Link to post
Share on other sites
18 minutes ago, pierremgi said:

This code is for the respawn sequence only. You don't have to add it in a menu. For your other post, see the answer at the right page.

Thats better.  Thank you very much

Share this post


Link to post
Share on other sites
On 8/9/2020 at 6:15 PM, pierremgi said:

 

Truly, I can't reproduce that, but perhaps you have some respawn markers on such places.

Anyway, this solution works (in init.sqf):

 


addMissionEventHandler ["entityRespawned",{
  params ["_entity", "_corpse"];
  private _pos = (getPos _entity vectorAdd [0,0,100]);
  _entity setVehiclePosition [_pos,[],0,"CAN_COLLIDE"];
  deleteVehicle _corpse;
}];

 

pierremgi:

I liked your suggestion for when I respawn inside a rock to use this

 

Suggestion 1:

addMissionEventHandler ["entityRespawned",{ params ["_entity", "_corpse"]; private _pos = (getPos _entity vectorAdd [0,0,100]); _entity setVehiclePosition [_pos,[],0,"CAN_COLLIDE"]; deleteVehicle _corpse; }];

 

But dying inside a building and respawning on the roof, sucks.  So I like your other suggestion

 

Suggestion 2:

player addAction ["unstick", { params ["_plyr"]; _pos = (getPos _plyr vectorAdd [0,0,100]); _plyr setVehiclePosition [_pos,[],0,"CAN_COLLIDE"] }];

 

 

I liked the idea of the players body getting removed on respawn with the "DeleteVehicle _corpse".  How do I make this work with suggestion 2?

 

Thank you 

Share this post


Link to post
Share on other sites

Focus on rocks proximity (above player):

addMissionEventHandler ["entityRespawned",{
  params ["_entity", "_corpse"];
  private _rocks = nearestTerrainObjects [getpos _entity, ["rock"],30];
  private _ceils = (lineIntersectsSurfaces [getPosASL _entity vectorAdd [0,0,50],getposASL _entity,objNull,_entity,false,-1,"VIEW","FIRE"]);
  if (!(_rocks isEqualTo []) && {!(_ceils isEqualTo [])} && {_ceils #0#2 in _rocks}) then {
      _entity setposASL ((_ceils #0#0) vectorAdd [0,0,0.2]);
  };
  deleteVehicle _corpse;
}];

 

Share this post


Link to post
Share on other sites
27 minutes ago, pierremgi said:

Focus on rocks proximity (above player):


addMissionEventHandler ["entityRespawned",{
  params ["_entity", "_corpse"];
  private _rocks = nearestTerrainObjects [getpos _entity, ["rock"],30];
  private _ceils = (lineIntersectsSurfaces [getPosASL _entity vectorAdd [0,0,50],getposASL _entity,objNull,_entity,false,-1,"VIEW","FIRE"]);
  if (!(_rocks isEqualTo []) && {!(_ceils isEqualTo [])} && {_ceils #0#2 in _rocks}) then {
      _entity setposASL ((_ceils #0#0) vectorAdd [0,0,0.2]);
  };
  deleteVehicle _corpse;
}];

 

But there are very large rocks i have respawned into, much taller than a small building.  I just tried this and respawned inside a very low rock.  I think suggestion 2 with unstick will work most reliably for me but how do I add the delete corpse to it?

Share this post


Link to post
Share on other sites

Not sure to understand the problem. When you respawn, you can fire an EH which run a code; like I wrote. The corpse deletion is inside. What else?

Share this post


Link to post
Share on other sites
On 8/18/2020 at 2:22 PM, pierremgi said:

Not sure to understand the problem. When you respawn, you can fire an EH which run a code; like I wrote. The corpse deletion is inside. What else?

Thanks for you patience.  What do you mean "You can fire an EH" you mean I can select when to run the script?  

Thanks

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

×