DMS_Exile/@ExileServer/addons/a3_dms/scripts/fn_IsValidPosition.sqf
eraser1 70fae7bc44 Merry Xmas :D
* **NEW CONFIG VALUES:**

DMS_SpawnFlareOnReinforcements
DMS_MissionMarkerWinDot_Type
DMS_MissionMarkerLoseDot_Type
DMS_EnableBoxMoving
DMS_BasesToImportOnServerStart
DMS_AI_Classname
DMS_AI_AimCoef_easy
DMS_AI_AimCoef_moderate
DMS_AI_AimCoef_difficult
DMS_AI_AimCoef_hardcore
DMS_AI_EnableStamina_easy
DMS_AI_EnableStamina_moderate
DMS_AI_EnableStamina_difficult
DMS_AI_EnableStamina_hardcore
DMS_AI_destroyStaticWeapon
DMS_AI_destroyStaticWeapon_chance
DMS_ai_SupportedRandomClasses
DMS_random_non_assault_AI
DMS_random_non_MG_AI
DMS_random_non_sniper_AI
* Please check out the new config values in config.sqf to see what they
do :)
* Fixed issue with "thieves" mission (and DMS-spawned persistent
vehicles in general). Big thank you to [JamieKG from Eternal
Gamer](http://eternal-gamer.com/) and Torndeco.
* **New static mission: "slums"**
* Credit for the base goes to [William from Refugees of the
Fallen](http://refugeesofthefallen.enjin.com/)
* Spawns 2 crates at 2 different locations from a list of 5 locations.
* No AI vehicles, only infantry (introduces Close Quarters Combat)
* Added to Altis by default.
* Static bases can now be imported on server startup instead of mission
spawns. Enabled by default for saltflats and slums.
* Increased "DMS_MissionTimeoutResetRange" from 1000 to 1500.
* Removed the Navid from config (MG AI and box weapons).
* Edited panthera3_config to reduce SpawnZoneNear and TraderZoneNear
blacklists.
* Edited "blackhawkdown" and "donthasslethehoff" missions to use a
slightly different heli wreck classname.
* Increased marker circle diameter for saltflats mission to 750 meters.
* Moved "DMS_Version" variable assignment to pre-init.
* Moved Map Center and Map Radius assignments to post-init.
* Added support for 2 new optional parameters: _onMonitorStart and
_onMonitorEnd, run before and after the Mission Monitor checks the
mission, but AFTER "Mission Success State" is checked.
* Mines should now be deleted when a mission fails.
* Script optimizations for almost all functions using new command(s)
introduced in ArmA v1.54, as well as improved technique(s).
* "ExileServer_system_garbageCollector_deleteObject" is now used to
actually delete items by DMS_fnc_CleanUp.
* AI and vehicle cleanup should now be completely handled by Exile.
* Added support for mARMA logging.
* **You can now disable the movement/lifting of loot crates after the
mission is complete using "DMS_EnableBoxMoving".**
* Added some debug code to DMS_fnc_FindSafePos and
DMS_fnc_IsValidPosition (commented out by default)
* New group reinforcement type "increasing_difficulty".
* DMS_fnc_IsNearWater now checks for invalid parameter(s).
* DMS_fnc_PlayerAwardOnAIKill now checks for roadkill values AFTER
unit-defined respect/tabs.
* You can now define different marker types for mission
completion/failure using "DMS_MissionMarkerWinDot_Type" and
"DMS_MissionMarkerLoseDot_Type" respectively.
* "DMS_fnc_SetGroupBehavior" can now take a unit as parameter as well.
It will also now return true if behavior was changed, false otherwise.
* "DMS_fnc_SpawnAIGroup" and "DMS_fnc_SpawnAIGroup_MultiPos" now
supports the definition of custom gear sets.
* Improved function documentation for "DMS_fnc_SpawnAIGroup",
"DMS_fnc_SpawnAIGroup_MultiPos", and "DMS_fnc_SpawnAISoldier".
* "DMS_fnc_SpawnAISoldier" now supports multiple different random AI
class presets. This means that you can define a certain "random" class
preset, but have it select from a specially defined list that excludes
classes that you don't want.
* Added default values to certain "missionNameSpace getVariable"s in
DMS_fnc_SpawnAISoldier to prevent script errors in the event of invalid
definitions.
* Slight logic tweak/fix to DMS_fnc_TargetsKilled (it shouldn't throw
errors when there aren't any).
2015-12-24 13:45:20 -06:00

182 lines
5.3 KiB
Plaintext

/*
DMS_fnc_IsValidPosition
Created by eraser1
Usage:
[
_pos, // ARRAY (position): The position to check.
_waterNearLimit, // NUMBER (distance): Minimum distance from water.
_minSurfaceNormal, // NUMBER (between 0-1): Maximum "surfaceNormal"; Basically determines how steep a position is. Check the comment for config value "DMS_MinSurfaceNormal" in config.sqf for more info
_spawnZoneNearLimit, // NUMBER (distance): Minimum distance from a spawn point.
_traderZoneNearLimit, // NUMBER (distance): Minimum distance from a trader zone.
_missionNearLimit, // NUMBER (distance): Minimum distance from another mission.
_playerNearLimit, // NUMBER (distance): Minimum distance from a player.
_waterSpawn // BOOLEAN: Whether or not the mission is supposed to spawn on water.
] call DMS_fnc_IsValidPosition;
All parameters except "_pos" are optional.
Returns whether or not the provided position matches the parameters.
*/
private ["_pos", "_nearestObjectMinDistance", "_waterNearLimit", "_minSurfaceNormal", "_spawnZoneNearLimit", "_traderZoneNearLimit", "_missionNearLimit", "_playerNearLimit", "_territoryNearLimit", "_waterSpawn", "_isValidPos"];
_isValidPos = false;
if !(params
[
["_pos", [], [[]], [0,2,3]],
["_waterNearLimit", DMS_WaterNearBlacklist, [0] ],
["_minSurfaceNormal", DMS_MinSurfaceNormal, [0] ],
["_spawnZoneNearLimit", DMS_SpawnZoneNearBlacklist, [0] ],
["_traderZoneNearLimit", DMS_TraderZoneNearBlacklist,[0] ],
["_missionNearLimit", DMS_MissionNearBlacklist, [0] ],
["_playerNearLimit", DMS_PlayerNearBlacklist, [0] ],
["_territoryNearLimit", DMS_TerritoryNearBlacklist, [0] ],
["_waterSpawn", false, [false] ]
])
then
{
diag_log format ["DMS ERROR :: Calling DMS_fnc_isValidPosition with invalid parameters: %1",_this];
}
else
{
try
{
if ((count _pos)<2) then
{
throw ("(ERROR UNDEFINED POSITION)");
};
if ((count _pos) isEqualTo 2) then
{
_pos set [2, 0];
};
if (!(DMS_findSafePosBlacklist isEqualTo []) && {([_pos, DMS_findSafePosBlacklist] call BIS_fnc_isPosBlacklisted)}) then
{
throw ("a blacklisted position");
};
// Only do these checks if the mission is supposed to be on land.
if (!_waterSpawn) then
{
// Check for nearby water
if ((_waterNearLimit>0) && {[_pos,_waterNearLimit] call DMS_fnc_isNearWater}) then
{
throw ("water");
};
// Terrain steepness check
// 0 surfacenormal means completely vertical, 1 surfaceNormal means completely flat and horizontal.
// Take the arccos of the surfaceNormal to determine how many degrees it is from the horizontal. In SQF: {acos ((surfaceNormal _pos) select 2)}. Don't forget to define _pos.
if ((_minSurfaceNormal>0) && {_minSurfaceNormal<=1}) then
{
if (((surfaceNormal _pos) select 2)<_minSurfaceNormal) then
{
throw ("a steep location");
};
// Check the surrounding area (within 5 meters)
private "_dir";
for "_dir" from 0 to 359 step 45 do
{
if (((surfaceNormal ([_pos,5,_dir] call DMS_fnc_SelectOffsetPos)) select 2)<_minSurfaceNormal) then
{
throw ("a nearby steep location");
};
};
};
}
else
{
// Check to see if the position is actually water.
if !(surfaceIsWater _pos) then
{
throw ("land");
};
// Check the depth of the water.
if ((getTerrainHeightASL _pos)<-DMS_MinWaterDepth) then
{
throw ("shallow water");
};
};
{
if (((getMarkerPos _x) distance2D _pos)<=_missionNearLimit) then
{
throw ("an A3XAI mission");
};
} forEach (missionNamespace getVariable ["A3XAI_mapMarkerArray",[]]);
{
// Check for nearby spawn points
if ((_spawnZoneNearLimit>0) && {((markertype _x) == "ExileSpawnZone") && {((getMarkerPos _x) distance2D _pos)<=_spawnZoneNearLimit}}) then
{
throw ("a spawn zone");
};
// Check for nearby trader zones
if ((_traderZoneNearLimit>0) && {((markertype _x) == "ExileTraderZone") && {((getMarkerPos _x) distance2D _pos)<=_traderZoneNearLimit}}) then
{
throw ("a trader zone");
};
// Check for nearby missions
if (_missionNearLimit>0) then
{
_missionPos = missionNamespace getVariable [format ["%1_pos",_x], []];
if (!(_missionPos isEqualTo []) && {(_missionPos distance2D _pos)<=_missionNearLimit}) then
{
throw ("a mission");
};
if (((_x find "VEMFr_DynaLocInva_ID")>0) && {((getMarkerPos _x) distance2D _pos)<=_missionNearLimit}) then
{
throw ("a VEMF mission");
};
};
} forEach allMapMarkers;
// Check for nearby players
// This is done last because it is likely to be the most resource intensive.
if ((_playerNearLimit>0) && {[_pos,_playerNearLimit] call DMS_fnc_IsPlayerNearby}) then
{
throw ("a player");
};
if ((_territoryNearLimit>0) && {[_pos,_territoryNearLimit] call ExileClient_util_world_isTerritoryInRange}) then
{
throw ("a territory");
};
// No exceptions found
_isValidPos = true;
}
catch
{
/*
_dot = createMarker [format ["DMS_DebugMarker_attempt%1", _pos], _pos];
_dot setMarkerColor "ColorWEST";
_dot setMarkerType "mil_dot";
_dot setMarkerText (format["close to: %1",_exception]);
DMS_DebugMarkers pushBack _dot;
*/
if (DMS_DEBUG) then
{
(format ["IsValidPosition :: Position %1 is too close to %2!",_pos,_exception]) call DMS_fnc_DebugLog;
};
};
};
_isValidPos;