Jump to content

[Fix] Glitch into base via relog


Shawn

Recommended Posts

If a player was to hover over a base with, say a mozzie, and relog, they would be inside the base. This is very game breaking, and so the fix is as follows:

1. Open up server_onPlayerDisconnect.sqf and find:

if (!isNull _playerObj) then {
 
	_playerPos = getPosATL _playerObj;
	_characterID =	_playerObj getVariable ["CharacterID","0"];
	_timeout = _playerObj getVariable["combattimeout",0];

Add below:

_newPos = [_playerPos, 80, 100, 10, 0, 20, 0] call BIS_fnc_findSafePos;

2. Add _newPos to the Private array at the top of the file, so it looks like:

private ["_invehicle","_isplayernearby","_playerObj","_myGroup","_id","_playerUID","_playerName","_characterID","_timeout","_message","_magazines","_playerPos","_newPos"];

3. Finally, find:

if (vehicle _playerObj != _playerObj) then {
		_playerObj action ["eject", vehicle _playerObj];
		_invehicle = true;

And add below:

		_playerObj setVariable["USEC_injured", true]; 
		_playerObj setVariable["NORRN_unconscious",true, true];
		_playerObj setVariable["unconsciousTime",180,true];
		_playerObj setpos _newPos;

If you do not want the player to be bleeding and unconscious, only add:

		_playerObj setPos _newPos ;  

And that's about it!

 

Link to comment
Share on other sites

 

 


scriptName "Functions\misc\fn_findSafePos.sqf";
/*
	File: findSafePos.sqf
	Author: Joris-Jan van 't Land

	Description:
	Function to retrieve and dynamic position in the world according to several parameters.

	Parameter(s):
	_this select 0: center position (Array)
						Note: passing [] (empty Array), the world's safePositionAnchor entry will be used.
	_this select 1: minimum distance from the center position (Number)
	_this select 2: maximum distance from the center position (Number)
						Note: passing -1, the world's safePositionRadius entry will be used.
	_this select 3: minimum distance from the nearest object (Number)
	_this select 4: water mode (Number)
						0: cannot be in water
						1: can either be in water or not
						2: must be in water
	_this select 5: maximum terrain gradient (average altitude difference in meters - Number)
	_this select 6: shore mode (Number):
						0: does not have to be at a shore
						1: must be at a shore
	_this select 7: (optional) blacklist (Array of Arrays):
						(_this select 7) select X: Top-left and bottom-right coordinates of blacklisted area (Array)
	_this select 8: (optional) default positions (Array of Arrays):
						(_this select 8) select 0: default position on land (Array)
						(_this select 8) select 1: default position on water (Array)
	
	Returns:
	Coordinate array with a position solution.
	
	TODO:
	* Maybe allow passing several combinations of position, min and max dist ... so that you can 
	avoid several things?
	* Interpretation of minDist / maxDist is wrong. It's not true distance that is used. Too bad?
*/

scopeName "main";

private ["_pos", "_minDist", "_maxDist", "_objDist", "_waterMode", "_maxGradient", "_shoreMode", "_defaultPos", "_blacklist"];
_pos = _this select 0;
_minDist = _this select 1;
_maxDist = _this select 2;
_objDist = _this select 3;
_waterMode = _this select 4;
_maxGradient = _this select 5;
_shoreMode = _this select 6;

if (_shoreMode == 0) then {_shoreMode = false} else {_shoreMode = true};

_blacklist = [];
if ((count _this) > 7) then 
{
	_blacklist = _this select 7;
};

_defaultPos = [];
if ((count _this) > 8) then 
{
	_defaultPos = _this select 8;
};

//See if default world values should be used.
if ((count _pos) == 0) then 
{
	_pos = getArray(configFile >> "CfgWorlds" >> worldName >> "safePositionAnchor");
};
if ((count _pos) == 0) exitWith {debugLog "Log: [findSafePos] No center position was passed!"; []}; //TODO: instead return defaults below.

if (_maxDist == -1) then 
{
	_maxDist = getNumber(configFile >> "CfgWorlds" >> worldName >> "safePositionRadius");
};

//TODO: Validate parameters.

private ["_newPos", "_posX", "_posY"];
_newPos = [];
_posX = _pos select 0;
_posY = _pos select 1;


//Limit the amount of attempts at finding a good location.
private ["_attempts"];
_attempts = 0;
while {_attempts < 1000} do
{
	private ["_newX", "_newY", "_testPos"];
	_newX = _posX + (_maxDist - (random (_maxDist * 2)));
	_newY = _posY + (_maxDist - (random (_maxDist * 2)));
	_testPos = [_newX, _newY];

	//Blacklist check.
	//TODO: Do not use function when the blacklist is empty?
	if (!([_testPos, _blacklist] call BIS_fnc_isPosBlacklisted)) then
	{
			if ((_pos distance _testPos) >= _minDist) then
			{
				if (!((count (_testPos isFlatEmpty [_objDist, 0, _maxGradient, _objDist max 5, _waterMode, _shoreMode, objNull])) == 0)) then 
				{
					_newPos = _testPos;
					breakTo "main";
				};
			};
	};

	_attempts = _attempts + 1;
};

//No position was found, use defaults.
if ((count _newPos) == 0) then
{
	if (_waterMode == 0) then
	{
		if ((count _defaultPos) > 0) then 
		{
			_newPos = _defaultPos select 0;
		} 
		else 
		{
			//Use world Armory default position:
			_newPos = getArray(configFile >> "CfgWorlds" >> worldName >> "Armory" >> "positionStart");
		};
	}
	else
	{
		if ((count _defaultPos) > 1) then 
		{
			_newPos = _defaultPos select 1;
		} 
		else 
		{
			//Use world Armory default water position:
			_newPos = getArray(configFile >> "CfgWorlds" >> worldName >> "Armory" >> "positionStartWater");
		};
	};
};

if ((count _newPos) == 0) then 
{
	//Still nothing was found, use world center positions.
	_newPos = getArray(configFile >> "CfgWorlds" >> worldName >> "centerPosition");
};

_newPos

Ok, so here is the fn_findSafePos.sqf code ^^. Can we add this in our mission file and edit it so it loops with a higher max distance until a safepos is found rather than setting _pos to debug?

Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
  • Advertisement
  • Discord

×
×
  • Create New...