From ffd41d0025d4b651588098f4aa4f004ff1499903 Mon Sep 17 00:00:00 2001 From: Chris Cardozo Date: Thu, 6 Aug 2020 01:02:58 -0400 Subject: [PATCH] Build 214 - improvements in finding mission positions --- .../Functions/GMS_fnc_findSafePosn.sqf | 145 ++++++++++++++---- .../GMS_fnc_monitorInitializedMissions.sqf | 7 +- .../custom_server/Configs/blck_configs.sqf | 16 +- .../Configs/blck_configs_mil.sqf | 6 +- 4 files changed, 130 insertions(+), 44 deletions(-) diff --git a/@GMS/addons/custom_server/Compiles/Functions/GMS_fnc_findSafePosn.sqf b/@GMS/addons/custom_server/Compiles/Functions/GMS_fnc_findSafePosn.sqf index 5af818f..a7e28d3 100644 --- a/@GMS/addons/custom_server/Compiles/Functions/GMS_fnc_findSafePosn.sqf +++ b/@GMS/addons/custom_server/Compiles/Functions/GMS_fnc_findSafePosn.sqf @@ -8,6 +8,13 @@ All the code and information provided here is provided under an Attribution Non-Commercial ShareAlike 4.0 Commons License. http://creativecommons.org/licenses/by-nc-sa/4.0/ + + Notes: cosine acute angle = hypotenuse / opposite. We always know the opposite = 1/2 mapsize so if we pick a random angle, we can calculate distance to edge of map. + Thus, we can have a random direction, calculate distance to the map edge as cos(direction - east/south/west/north angle) * 1/2 mapsize. Then, we can use 1/2 the lenght of the hypotenuse as the search range. + In this way we can reduce the radius of the search by about 1/2 and ensure a wider range of terrain is selected. + + However, if we use this approach, we risk having some missions spawn outside the map so much check for that. + It may be quicker just to pick a random angle and use 1/2 map size to search a position obtained by getPos[(1/2 mapSize),random(359)]; to pick that random seed location for the search. */ #include "\q\addons\custom_server\Configs\blck_defines.hpp"; @@ -51,54 +58,134 @@ _fn_buildBlacklistedLocationsList = { _blacklistedLocs }; +_fnc_nearWater = { + private _result = false; + private _coords = _this select 0; + private _radius = _this select 1; + + for "_i" from 0 to 359 step 45 do { + //_checkposition = [(_coords select 0) + (sin(_i)*_radius), (_coords select 1) + (cos(_i)*_radius)]; + //_checkposition2 = [(_coords select 0) + (sin(_i)*_radius/2), (_coords select 1) + (cos(_i)*_radius/2)]; + //_checkPosition = _coords getPos[_radius, _i]; + if (surfaceIsWater (_coords getPos[_radius, _i])) exitWith { + _result = true; + }; + }; + _result +}; + private _minDistToBases = blck_minDistanceToBases; private _minDistToPlayers = blck_minDistanceToPlayer; private _minDistToTowns = blck_minDistanceFromTowns; private _mindistToMissions = blck_MinDistanceFromMission; private _minToRecentMissionLocation = 200; +private _keyDistances = [_minDistToBases,_minDistToPlayers,_minDistToTowns,_minToRecentMissionLocation]; private _coords = []; -private _blacklistedLocations = [_minDistToBases,_minDistToPlayers,_minDistToTowns,_mindistToMissions,_minToRecentMissionLocation] call _fn_buildBlacklistedLocationsList; +//private _blacklistedLocations = [_minDistToBases,_minDistToPlayers,_minDistToTowns,_mindistToMissions,_minToRecentMissionLocation] call _fn_buildBlacklistedLocationsList; private _count = 25; -private "_isFlatCoords"; -private _slope = 0.10; - -_coords = [blck_mapCenter,0,blck_mapRange,10,0,_slope,0,_blacklistedLocations] call BIS_fnc_findSafePos; -if !(_coords isEqualTo []) then +private _flatCoords = []; +private _slope = 0.15; +private _searchDist = blck_mapRange / 2; +private _timeIn = diag_tickTime; +private _validspot = false; +while { !_validspot} do { - _isFlatCoords = _coords isFlatEmpty [10,0,_slope,30,0,false]; -}; + private _angle = random(359); + private _searchCenter = blck_mapCenter getPos[_searchDist, random(359)]; + _coords = [_searchCenter,0,_searchDist,10,0,_slope,0] call BIS_fnc_findSafePos; -while { (_isFlatCoords isEqualTo [] || _coords isEqualTo []) && _count > 0} do -{ - - _coords = [blck_mapCenter,0,blck_mapRange,10,0,_slope,0,_blacklistedLocations] call BIS_fnc_findSafePos; - /* Check whether the location is flat enough: returns [] if not. */ - // position isFlatEmpty [minDistance, mode, maxGradient, maxGradientRadius, overLandOrWater, shoreLine, ignoreObject] - - if !(_coords isEqualTo []) then + if (_coords isEqualTo []) then { - _isFlatCoords = _coords isFlatEmpty [10,0,_slope,30,0,false]; - }; - - if (_coords isEqualTo [] || !(_isFlatCoords isEqualTo [])) then - { - { - //private _range = (_x select 1) * 0.7; - _x set[1,(_x select 1) * 0.75]; - } forEach _blackListedLocations; _count = _count - 1; _slope = _slope + 0.02; - uiSleep 0.1; + uiSleep 0.1; // to give the server a chance to handle other jobs for a moment + } else { + + //uiSleep 1; + _validspot = true; + + if (count _coords > 2) then { + _validspot = false; + }; + if(_validspot) then { + if ([_coords,500] call _fnc_nearWater) then { + _validspot = false; + }; + }; + if(_validspot) then { + _isflat = _coords isFlatEmpty [20,0,0.5,100,0,false]; + if (_isflat isequalto []) then { + _validspot = false; + }; + }; + if(_validspot) then { + { + if (_coords distance _x < blck_MinDistanceFromMission) exitwith { + _validspot = false; + }; + } foreach (blck_ActiveMissionCoords); + }; + + // Check for near Bases + if(_validspot) then { + if (blck_modType isEqualTo "Epoch") then { + { + if (_coords distance _x < blck_minDistanceToBases) exitwith { + _validspot = false; + }; + } foreach (missionnamespace getvariable ["Epoch_PlotPoles",[]]); + } + else { + if (blck_modType isEqualTo "Exile") then { + { + if (_coords distance _x < blck_minDistanceToBases) exitwith { + _validspot = false; + }; + } foreach (nearestObjects [blck_mapCenter, ["Exile_Construction_Flag_Static"], blck_mapRange + 25000]); + }; + }; + }; + + // Check for near Players + if(_validspot) then { + { + if (_coords distance _x < blck_minDistanceToPlayer) exitwith { + _validspot = false; + }; + } foreach allplayers; + }; + + // Check for near locations + if (_validspot) then { + { + if (_coords distance (_x select 0) < (_x select 1)) exitWith { + _validspot = false; + }; + } forEach blck_locationBlackList; + }; + + // Check for DMS missions + if (blck_minDistanceFromDMS > 0 && _validspot) then + { + { + if (_coords distance _x < blck_minDistanceFromDMS) exitWith { + _validspot = false; + }; + } forEach ([] call blck_fnc_getAllDMSMarkers); + }; + }; + //diag_log format["_fnc_findSafePosn: _coords = %1 | _flatCoords = %2 | _searchCenter = %3 | _angle %4 | _count = %5 | _validSpot = %6",_coords,_flatCoords,_searchCenter,_angle,_count,_validspot]; }; -if (_coords isEqualTo [] || _isFlatCoords isEqualTo []) then +if (_coords isEqualTo []) then { diag_log format["[blckeagls] Could not find a safe position for a mission, consider reducing values for minimum distances between missions and players, bases, other missions or towns"]; } else { - _isFlatCoords set[2, 0]; + _coords set[2, 0]; + diag_log format["_fnc_findSafePosn: _exit with _coords = %1 | time spent = %2",_coords,diag_tickTime - _timeIn]; }; -_isFlatCoords +_coords diff --git a/@GMS/addons/custom_server/Compiles/Missions/GMS_fnc_monitorInitializedMissions.sqf b/@GMS/addons/custom_server/Compiles/Missions/GMS_fnc_monitorInitializedMissions.sqf index a6a5aeb..db67a66 100644 --- a/@GMS/addons/custom_server/Compiles/Missions/GMS_fnc_monitorInitializedMissions.sqf +++ b/@GMS/addons/custom_server/Compiles/Missions/GMS_fnc_monitorInitializedMissions.sqf @@ -268,8 +268,9 @@ _missionParameters params[ }; }; uiSleep delayTime; - - if (_spawnCratesTiming isEqualTo "atMissionSpawnGround") then + if (blck_debugLevel >= 3) then {diag_log format["monitorInitializedMissions: _spawnCrateTiming = %1 _loadCratesTiming = %2 | _markerMissionName = %3",_spawnCratesTiming,_loadCratesTiming, _markerMissionName]}; + if (blck_debugLevel >= 3) then {diag_log format["monitorInitializedMissions: _missionLootBoxes = %1",_missionLootBoxes]}; + if (_spawnCratesTiming in ["atMissionSpawnGround","atMissionStartAir"]) then { if (_missionLootBoxes isEqualTo []) then { @@ -306,7 +307,6 @@ _missionParameters params[ // Everything spawned withouth serous errors so lets keep the mission active for future monitoring blck_activeMissionsList pushBack _el; - if (blck_debugOn) then {[format["Spawned Mission %1 | description %2 | difficulty %3 at %4",_markerName, _markerMissionName, _difficulty, diag_tickTime]] call blck_fnc_log;} } catch @@ -478,7 +478,6 @@ _missionParameters params[ _waitTime = diag_tickTime + _tMin + random(_tMax - _tMin); _missionCategoryDescriptors set [noActive,_noActive - 1]; _missionCategoryDescriptors set [waitTime,_waitTime]; - if (blck_debugOn) then {[format["Ended Mission %1 | description %2 | difficulty %3 at %4",_markerName, _markerMissionName, _difficulty, diag_tickTime]] call blck_fnc_log;} }; case 2: { // Abort, crate moved. _endMsg = "Crate Removed from Mission Site Before Mission Completion: Mission Aborted"; diff --git a/@GMS/addons/custom_server/Configs/blck_configs.sqf b/@GMS/addons/custom_server/Configs/blck_configs.sqf index 491377a..e431e94 100644 --- a/@GMS/addons/custom_server/Configs/blck_configs.sqf +++ b/@GMS/addons/custom_server/Configs/blck_configs.sqf @@ -17,8 +17,8 @@ changing any of these variables may break the mission systemChat */ blck_locationBlackList = []; // Do not touch ... - blck_debugON = true; // Do not touch ... - blck_debugLevel = 3; // Do not touch ... + blck_debugON = false; // Do not touch ... + blck_debugLevel = 0; // Do not touch ... #ifdef blck_milServer if (true) exitWith { @@ -100,8 +100,8 @@ blck_showCountAliveAI = true; //Minimum distance between missions - blck_MinDistanceFromMission = 800; - blck_minDistanceToBases = 1000; + blck_MinDistanceFromMission = 2000; + blck_minDistanceToBases = 800; blck_minDistanceToPlayer = 800; blck_minDistanceFromTowns = 400; blck_minDistanceFromDMS = 800; // minimum distance for a blackeagls mission from any nearby DMS missions. set to -1 to disable this check. @@ -122,7 +122,7 @@ /////////////////////////////// blck_killPercentage = 0.999999; // The mission will complete if this fraction of the total AI spawned has been killed. // This facilitates mission completion when one or two AI are spawned into objects. - blck_spawnCratesTiming = "atMissionSpawnGround"; // Choices: "atMissionSpawnGround","atMissionEndGround","atMissionEndAir". + blck_spawnCratesTiming = "atMissionSpawnGround"; // Choices: "atMissionSpawnGround","atMissionStartAir","atMissionEndGround","atMissionEndAir". // Crates spawned in the air will be spawned at mission center or the position(s) defined in the mission file and dropped under a parachute. // This sets the default value but can be overridden by defining _spawnCrateTiming in the file defining a particular mission. blck_loadCratesTiming = "atMissionSpawn"; // valid choices are "atMissionCompletion" and "atMissionSpawn"; @@ -145,10 +145,10 @@ blck_VK_Gear = true; // When set to true, AI that have been killed by a player in a vehicle in the list of forbidden vehicles or using a forbiden gun will be stripped of gear and the vehicle will be given blck_RunGearDamage of damage blck_VK_RunoverDamage = true; // when the AI was run over blck_RunGearDamage of damage will be applied to the killer's vehicle. blck_VK_GunnerDamage = false; // when the AI was killed by a gunner on a vehicle that is is in the list of forbidden vehicles, blck_RunGearDamage of damage will be applied to the killer's vehicle each time an AI is killed with a vehicle's gun. - blck_forbidenVehicles = ["B_MRAP_01_hmg_F","O_MRAP_02_hmg_F","I_MRAP_03_hmg_F","B_MRAP_01_hmg_F","O_MRAP_02_hmg_F"]; // Add any vehicles for which you wish to forbid vehicle kills + blck_forbidenVehicles = []; // Examples include ["B_MRAP_01_hmg_F","O_MRAP_02_hmg_F","I_MRAP_03_hmg_F","B_MRAP_01_hmg_F","O_MRAP_02_hmg_F"]; // Add any vehicles for which you wish to forbid vehicle kills // For a listing of the guns mounted on various land vehicles see the following link: https://community.bistudio.com/wiki/Arma_3_CfgWeapons_Vehicle_Weapons // HMG_M2 is mounted on the armed offroad that is spawned by Epoch - blck_forbidenVehicleGuns = ["LMG_RCWS","LMG_M200","HMG_127","HMG_127_APC","HMG_M2","HMG_NSVT","GMG_40mm","GMG_UGV_40mm","autocannon_40mm_CTWS","autocannon_30mm_CTWS","autocannon_35mm","LMG_coax","autocannon_30mm","HMG_127_LSV_01"]; // Add any vehicles for which you wish to forbid vehicle kills, o + blck_forbidenVehicleGuns = []; // examples include["LMG_RCWS","LMG_M200","HMG_127","HMG_127_APC","HMG_M2","HMG_NSVT","GMG_40mm","GMG_UGV_40mm","autocannon_40mm_CTWS","autocannon_30mm_CTWS","autocannon_35mm","LMG_coax","autocannon_30mm","HMG_127_LSV_01"]; // Add any vehicles for which you wish to forbid vehicle kills, o /////////////////////////////// @@ -242,7 +242,7 @@ // Change this value to reduce the number of spawned missions at any one time. - blck_maxSpawnedMissions = 9; + blck_maxSpawnedMissions = 15; // Reduce to 1 sec for immediate spawns, or longer if you wish to space the missions out blck_TMin_Orange = 480; diff --git a/@GMS/addons/custom_server/Configs/blck_configs_mil.sqf b/@GMS/addons/custom_server/Configs/blck_configs_mil.sqf index b4a0b17..476ff73 100644 --- a/@GMS/addons/custom_server/Configs/blck_configs_mil.sqf +++ b/@GMS/addons/custom_server/Configs/blck_configs_mil.sqf @@ -76,8 +76,8 @@ blck_showCountAliveAI = true; //Minimum distance between missions - blck_MinDistanceFromMission = 800; - blck_minDistanceToBases = 500; + blck_MinDistanceFromMission = 2000; + blck_minDistanceToBases = 800; blck_minDistanceToPlayer = 500; blck_minDistanceFromTowns = 300; blck_minDistanceFromDMS = 500; // minimum distance for a blackeagls mission from any nearby DMS missions. set to -1 to disable this check. @@ -89,7 +89,7 @@ // global loot crate options // Options to spawn a smoking wreck near the crate. When the first parameter is true, a wreck or junk pile will be spawned. // It's position can be either "center" or "random". smoking wreck will be spawned at a random location between 15 and 50 m from the mission. - blck_SmokeAtMissions = [false,"random"]; // set to [false,"anything here"] to disable this function altogether. + blck_SmokeAtMissions = [true,"random"]; // set to [false,"anything here"] to disable this function altogether. blck_useSignalEnd = true; // When true a smoke grenade/chemlight will appear at the loot crate for 2 min after mission completion. ///////////////////////////////