From 80cae641270886dad6639d6ea8465a611c592f03 Mon Sep 17 00:00:00 2001 From: IT07 Date: Sun, 10 Apr 2016 17:25:24 +0200 Subject: [PATCH] v0.741 --- exile_vemf_reloaded/config.cpp | 55 +- exile_vemf_reloaded/config_override.cpp | 31 ++ .../functions/fn_checkSide.sqf | 49 ++ exile_vemf_reloaded/functions/fn_findPos.sqf | 301 +++++------ .../functions/fn_getSetting.sqf | 46 +- exile_vemf_reloaded/functions/fn_launch.sqf | 50 +- exile_vemf_reloaded/functions/fn_loadInv.sqf | 341 ++++++------ exile_vemf_reloaded/functions/fn_log.sqf | 47 +- .../functions/fn_missionTimer.sqf | 6 +- .../functions/fn_spawnInvasionAI.sqf | 211 ++++++++ .../functions/fn_spawnVEMFrAI.sqf | 104 ++++ .../missions/DynamicLocationInvasion.sqf | 487 ++++++++++-------- 12 files changed, 1133 insertions(+), 595 deletions(-) create mode 100644 exile_vemf_reloaded/config_override.cpp create mode 100644 exile_vemf_reloaded/functions/fn_checkSide.sqf create mode 100644 exile_vemf_reloaded/functions/fn_spawnInvasionAI.sqf create mode 100644 exile_vemf_reloaded/functions/fn_spawnVEMFrAI.sqf diff --git a/exile_vemf_reloaded/config.cpp b/exile_vemf_reloaded/config.cpp index 677f6c2..13ec565 100644 --- a/exile_vemf_reloaded/config.cpp +++ b/exile_vemf_reloaded/config.cpp @@ -16,8 +16,9 @@ class CfgVemfReloaded { - /////// Debugging/learning mode /////// - debugMode = 2; // 0 = no debugging | 1 = ERRORS only | 2 = INFO only | 3 = ERRORS & INFO + /////// Debugging/learning/logging /////// + debugMode = 3; // 0 = no debugging | 1 = ERRORS only | 2 = INFO only | 3 = ERRORS & INFO + overridesToRPT = 1; // Enable/disable logging of override settings to .RPT /////////////////////////////////////// // Global settings @@ -33,7 +34,7 @@ class CfgVemfReloaded minServerFPS = 20; // Enable/disable minimum server FPS for VEMF to keep spawning missions missionDistance = 2000; // Enable/disable minimum distance between missions missionList[] = {"DynamicLocationInvasion"}; // Each entry should represent an .sqf file in the missions folder - noMissionPos[] = {{{2998.62,18175.4,0.00143886},500},{{14601.3,16799.3,0.00143814},800},{{23334.8,24189.5,0.00132132},600}}; // Format: {{position},radius} | Default: Exile safezones + noMissionPos[] = {{{2998.62,18175.4,0.00143886},500},{{14601.3,16799.3,0.00143814},800},{{23334.8,24189.5,0.00132132},600}}; // Format: {{position},radius} | Default: Exile Altis safezones nonPopulated = 1; // Enable/disable allowance of missions at locations WITHOUT (enterable) buildings punishRoadKills = 1; // Enable/disable respect deduction if player roadkills AI removeAllAssignedItems = 0; // Enable/disable removal of Map, Compass, Watch and Radio from all AI @@ -70,10 +71,10 @@ class CfgVemfReloaded }; }; - class DynamicLocationInvasion // DynamicLocationInvasion (mission) settings - { + class DynamicLocationInvasion + { // DynamicLocationInvasion (mission) settings allowCrateLift = 0; // Allow/disallow the loot crate to be lifted with helicopter - aiLaunchers = 1; // Allow/disallow AI to HAVE rocket launchers + aiLaunchers = 1; // Allow/disallow AI to have rocket launchers allowTWS = 0; // Enable/disable the usage of TWS scopes by AI announce = 1; // Enable/disable mission notificatons cal50s = 3; // Max amount of .50 caliber machineguns at mission | Needs to be lower than total unit count per mission @@ -83,43 +84,43 @@ class CfgVemfReloaded groupCount[] = {2,4}; // In format: {minimum, maximum}; VEMF will pick a random number between min and max. If you want the same amount always, use same numbers for minimum and maximum. groupUnits[] = {4,6}; // How much units in each group. Works the same like groupCount hasLauncherChance = 25; // In percentage. How big the chance that each AI gets a launcher - marker = 1; // Enable/disable mission markers + heliPatrol[] = {1, {"B_Heli_Light_01_armed_F","B_Heli_Attack_01_F","B_Heli_Transport_03_F","B_Heli_Transport_01_F","B_Heli_Transport_01_camo_F"}}; // Enable/disable heli patrol at mission location and set the types of heli(s) + marker = 1; // Enable/disable mission markers markCrateOnMap = 1; // Enable/disable loot crate marker on map called "Loot" markCrateVisual = 1; // Enable/disable loot crate VISUAL marker (smoke and/or chem) - maxDistance = 15000; // Maximum distance from random player for mission location selection /* maxDistance NOTE: make sure to keep this number very high. 15000 is for Altis */ maxDistancePrefered = 7000; // Prefered maximum mission distance from player maxInvasions = 7; // Max amount of active uncompleted invasions allowed at the same time mines = 0; // Enable/disable mines at mission | 1 = anti-Armor mines | 2 = anti-Personell mines | 3 = both anti-Armor and anti-Personell mines minesAmount = 20; // Ignore if placeMines = 0; minesCleanup = 1; // Enable/disable the removal of mines once mission has been completed | 2 = explode mines + nonPopulated = -1; // Allow/disallow this mission type being placed at locations without buildings | using -1 will ignore this setting and use the global settting parachuteCrate[] = {0, 250}; // default: {disabled, 250 meters} | use 1 as first number to enable crate parachute spawn randomModes = 1; // Enable/disable randomization of AI types (linked to aiMode setting) - skipDistance = 800; // No missions at locations which have players within this range (in meters) - smokeTypes[] = {"SmokeShell","SmokeShellBlue","SmokeShellGreen","SmokeShellOrange","SmokeShellRed","SmokeShellYellow"}; - streetLights = 0; // Enable/disable street lights at mission location - streetLightsRestore = 1; // Enable/disable restoration of street lights after mission completion - streetLightsRange = 500; // Affects streetlights within this distance from mission's center + skipDistance = 800; // No missions at locations which have players within this range (in meters) + smokeTypes[] = {"SmokeShell","SmokeShellBlue","SmokeShellGreen","SmokeShellOrange","SmokeShellRed","SmokeShellYellow"}; + streetLights = 0; // Enable/disable street lights at mission location + streetLightsRestore = 1; // Enable/disable restoration of street lights after mission completion + streetLightsRange = 500; // Affects streetlights within this distance from mission's center }; - class aiCleanUp // Contains settings for removal of items from each AI that gets eliminated - { + class aiCleanUp + { // Contains settings for removal of items from each AI that gets eliminated aiDeathRemovalEffect = 0; // Enable/disable the "death effect" from Virtual Arsenal. Flashes AI and deletes it after being eliminated removeHeadGear = 0; // Enable/disable removal of headgear after AI has been eliminated, obviously removeLaunchers = 0; // Enable/disable removal of rocket launchers from AI after they are eliminated }; class aiStatic - { + { // Simply spawns units at desired positions amount[] = {10,20,12,11,40,21,19}; // How much AI units on each seperate position. Example: 1st location, 10. 2nd location, 20. 3rd location, 12. And so on.... enabled = 0; // Enable/disable static AI spawning positions[] = {}; // Add positions here. Each position must have {} around it and must be seperated with a comma if multiple positions present. Last position in list should NOT have a comma behind it! random = 1; // Enable/disable randomization of AI units amount }; - // Global AI skill settings. They affect each VEMF unit for any default VEMF mission class aiSkill // Minimum: 0 | Maximum: 1 - { + { // Global AI skill settings. They affect each VEMF unit for any default VEMF mission difficulty = "Veteran"; // Options: "Easy" "Normal" "Veteran" "Hardcore" | Default: Veteran class Easy // AI looks stupid with this setting xD { @@ -163,9 +164,8 @@ class CfgVemfReloaded vests[] = {"V_TacVest_blk_POLICE","V_PlateCarrierSpec_blk","V_PlateCarrierGL_blk","V_TacVestCamo_khk","V_TacVest_blk","V_BandollierB_blk","V_Rangemaster_belt"}; }; - // Loot crate configuration class crateLoot - { + { // Loot crate configuration primarySlotsMax = 10; // Maximum primary weapons in each loot crate primarySlotsMin = 4; // Minimum primary weapons in each loot crate primaryWeaponLoot[] = @@ -276,8 +276,7 @@ class CfgVemfReloaded // End of loot crate configuration }; class aiGear - { - // Configuration of what AI have + { // Configuration of what AI have aiHeadGear[] = { "H_HelmetB","H_HelmetB_camo","H_HelmetB_paint","H_HelmetB_light","H_Booniehat_khk","H_Booniehat_oli","H_Booniehat_indp", @@ -346,8 +345,13 @@ class CfgVemfReloaded "hgun_ACPC2_F","hgun_Rook40_F","hgun_P07_F","hgun_Pistol_heavy_01_F","hgun_Pistol_heavy_02_F" }; }; + class CfgSettingsOverride + { + #include "config_override.cpp" + }; }; + class CfgPatches { class exile_vemf_reloaded @@ -356,8 +360,8 @@ class CfgPatches requiredAddons[] = {"exile_server"}; fileName = "exile_vemf_reloaded.pbo"; requiredVersion = 1.56; // VEMF does not work on older versions due to use of the latest scripting commands - version = 0740.30; // Do NOT change - author[]= {"IT07"}; + version = 0.741; // Do NOT change + author = "IT07"; }; }; @@ -383,11 +387,14 @@ class CfgFunctions class giveAmmo {}; class giveWeaponItems {}; class spawnAI {}; + class spawnInvasionAI {}; class spawnStaticAI {}; + class spawnVEMFrAI {}; class loadLoot {}; class placeMines {}; class waitForPlayers {}; class waitForMissionDone {}; + class checkSide {}; class checkLoot {}; class missionTimer {}; class launch { postInit = 1; }; diff --git a/exile_vemf_reloaded/config_override.cpp b/exile_vemf_reloaded/config_override.cpp new file mode 100644 index 0000000..351c966 --- /dev/null +++ b/exile_vemf_reloaded/config_override.cpp @@ -0,0 +1,31 @@ +/* + File: config_override.cpp + Description: put all of the settings you always change in here and simply put the file back whenever you update VEMFr. Then you don't have to redo all your changes to the config.cpp everytime + Description 2: the only thing you will have to do now is simply check the CHANGELOG.md on GitHub everytime there is an update to check if there are any deprecated settings + Description 3: instead of changing the config.cpp settings everytime, just add your changes here. Saves a lot of time. Yes you are welcome you lucky bastard + Note: it is extremely difficult for a coder to explain with text how to do this so I have put a few examples in this file instead + Note 2: the already present lines below line 10 are just examples so feel free to delete them +*/ + +// Put all the settings you want to override below this line +/* +debugMode = 2; // Overrides CfgVemfReloaded >> debugMode +maxGlobalMissions = 5; // Overrides CfgVemfReloaded >> maxGlobalMissions +minServerFPS = 5; // Overrides CfgVemfReloaded >> minServerFPS +class crateLoot +{ + primarySlotsMax = 3; // Overrides CfgVemfReloaded >> crateLoot >> primarySlotsMax + primarySlotsMin = 1; // Overrides CfgVemfReloaded >> crateLoot >> primarySlotsMin +}; +class locationBlackLists +{ // NOTE: If the map you use is not listed below, simply add it by yourself or put the locations you want to blacklist into the locations array of the Other class + class Altis + { + locations[] = {}; // Overrides CfgVemfReloaded >> locationBlackLists >> Altis >> locations + }; +}; +class aiGear +{ + aiPistols[] = {"hgun_ACPC2_F","hgun_Rook40_F"}; // Overrides CfgVemfReloaded >> aiGear >> aiPistols +}; +*/ diff --git a/exile_vemf_reloaded/functions/fn_checkSide.sqf b/exile_vemf_reloaded/functions/fn_checkSide.sqf new file mode 100644 index 0000000..eff7490 --- /dev/null +++ b/exile_vemf_reloaded/functions/fn_checkSide.sqf @@ -0,0 +1,49 @@ +/* + Author: IT07 + + Description: checks the side of given unit and returns it + + Params: + _this: STRING - unit classname + + Returns: SIDE - unit's side +*/ + +private ["_return","_cfg","_faction"]; +if (_this isEqualType "") then +{ + _cfg = configFile >> "CfgVehicles" >> _this >> "faction"; + if not isNull _cfg then + { + _faction = getText _cfg; + switch _faction do + { + case "BLU_G_F": + { + _return = WEST; + }; + case "CIV_F": + { + _return = civilian; + }; + case "IND_F": + { + _return = independent; + }; + case "IND_G_F": + { + _return = resistance; + }; + case "OPF_F": + { + _return = EAST; + }; + default + { + ["fn_checkSide", 0, format["Fatal error; Unknown faction '%1'", _faction]] spawn VEMFr_fnc_log; + }; + }; + }; +}; + +_return diff --git a/exile_vemf_reloaded/functions/fn_findPos.sqf b/exile_vemf_reloaded/functions/fn_findPos.sqf index c8b8bff..d99c893 100644 --- a/exile_vemf_reloaded/functions/fn_findPos.sqf +++ b/exile_vemf_reloaded/functions/fn_findPos.sqf @@ -7,14 +7,15 @@ Params: _this select 0: STRING - Mode to use. Options: "loc" or "pos" _this select 1: BOOLEAN - True if _pos needs to be a road - _this select 2: OBJECT - Center for nearestLocations check - _this select 3: SCALAR - Max distance in meters from center to search for _pos - _this select 4: SCALAR - Distance in meters. Locations closer than that will be excluded - _this select 5: SCALAR - Max prefered distance in meters from center. If not achievable, further dest will be selected - _this select 6: SCALAR - Distance in meters to check from _cntr for players + _this select 2: POSITION - Center for nearestLocations check + _this select 3: SCALAR - Distance in meters. Locations closer than that will be excluded + _this select 4: SCALAR - Max prefered distance in meters from center. If not achievable, further dest will be selected + _this select 5: SCALAR - Distance in meters to check from _cntr for players + _this select 6: STRING (optional) - Exact config name of mission override settings to load Returns: - ARRAY - [name of town, town position] + if mode = loc then: ARRAY - format [name of town/location, town position] + if mode = pos then POSITION */ private ["_settings","_locPos","_loc","_locName","_ret","_continue","_settings","_blackList","_usedLocs","_checkRange","_tooCloseRange","_maxPrefered","_skipDistance","_nonPopulated","_mode","_pos","_hasPlayers","_blackPos","_checkBlackPos"]; @@ -25,6 +26,20 @@ _settings = [["nonPopulated","noMissionPos","missionDistance"]] call VEMFr_fnc_g _nonPopulated = _settings param [0, 1, [0]]; _blackPos = _settings param [1, [], [[]]]; _missionDistance = _settings param [2, 3000, [0]]; +_range = worldSize; +// Settings override system +_missionConfigName = param [6, "", [""]]; +if not(_missionConfigName isEqualTo "") then +{ + _nonPopulatedOverride = ([[_missionConfigName],["nonPopulated"]] call VEMFr_fnc_getSetting) select 0; + if not isNil"_nonPopulatedOverride" then + { + if not(_nonPopulatedOverride isEqualTo -1) then + { + _nonPopulated = _nonPopulatedOverride; + }; + }; +}; _checkBlackPos = false; if (count _blackPos > 0) then { @@ -36,178 +51,174 @@ if not(_mode isEqualTo "") then _onRoad = param [1, false, [false]]; _roadRange = 5000; _cntr = param [2, [], [[]]]; - if (count _cntr > 0) then + if (_cntr isEqualTypeArray [0,0,0]) then { - _rad = param [3, -1, [0]]; - if (_rad > -1) then + _tooCloseRange = param [3, -1, [0]]; + if (_tooCloseRange > -1) then { - _tooCloseRange = param [4, -1, [0]]; - if (_tooCloseRange > -1) then + _maxPrefered = param [4, -1, [0]]; + if (_maxPrefered > -1) then { - _maxPrefered = param [5, -1, [0]]; - if (_maxPrefered > -1) then + _skipDistance = param [5, -1, [0]]; + if (_skipDistance > -1) then { - _skipDistance = param [6, -1, [0]]; - if (_skipDistance > -1) then + if (_mode isEqualTo "loc") then { - if (_mode isEqualTo "loc") then + // Get a list of locations close to _cntr (position of player) + _locs = nearestLocations [_cntr, ["CityCenter","Strategic","StrongpointArea","NameVillage","NameCity","NameCityCapital",if(_nonPopulated isEqualTo 1)then{"nameLocal","Area","BorderCrossing","Hill","fakeTown","Name","RockArea","ViewPoint"}], _range]; + if (count _locs > 0) then { - // Get a list of locations close to _cntr (position of player) - _locs = nearestLocations [_cntr, ["Area","BorderCrossing","CityCenter","Hill","fakeTown","Name","RockArea","Strategic","StrongpointArea","ViewPoint","NameVillage","NameCity","NameCityCapital",if(_nonPopulated isEqualTo 1)then{"nameLocal"}], _rad]; - if (count _locs > 0) then - { - _usedLocs = uiNamespace getVariable "VEMFrUsedLocs"; - _remLocs = []; - _blackListMapClasses = "true" configClasses (configFile >> "CfgVemfReloaded" >> "locationBlackLists"); - _listedMaps = []; // Define - { // Make a list of locationBlackLists's children - _listedMaps pushBack (configName _x); - } forEach _blackListMapClasses; - private ["_blackList"]; - if (worldName in _listedMaps) then { _blackList = ([["locationBlackLists", worldName],["locations"]] call VEMFr_fnc_getSetting) select 0 }; - if not(worldName in _listedMaps) then { _blackList = ([["locationBlackLists","Other"],["locations"]] call VEMFr_fnc_getSetting) select 0 }; + _usedLocs = uiNamespace getVariable "VEMFrUsedLocs"; + _remLocs = []; + _blackListMapClasses = "true" configClasses (configFile >> "CfgVemfReloaded" >> "locationBlackLists"); + _listedMaps = []; // Define + { // Make a list of locationBlackLists's children + _listedMaps pushBack (configName _x); + } forEach _blackListMapClasses; + private ["_blackList"]; + if (worldName in _listedMaps) then { _blackList = ([["locationBlackLists", worldName],["locations"]] call VEMFr_fnc_getSetting) select 0 }; + if not(worldName in _listedMaps) then { _blackList = ([["locationBlackLists","Other"],["locations"]] call VEMFr_fnc_getSetting) select 0 }; - { // Check _locs for invalid locations (too close, hasPlayers or inBlacklist) - _hasPlayers = [locationPosition _x, _skipDistance] call VEMFr_fnc_checkPlayerPresence; - if _hasPlayers then + { // Check _locs for invalid locations (too close, hasPlayers or inBlacklist) + _hasPlayers = [locationPosition _x, _skipDistance] call VEMFr_fnc_checkPlayerPresence; + if _hasPlayers then + { + _remLocs pushBack _x; + }; + if not _hasPlayers then + { + if _checkBlackPos then + { + private ["_locPos","_loc"]; + _locPos = locationPosition _x; + _loc = _x; + { + if (count _x isEqualTo 2) then + { + _pos = _x param [0, [0,0,0], [[]]]; + if not(_pos isEqualTo [0,0,0]) then + { + _range = _x param [1, 600, [0]]; + if ((_pos distance _locPos) < _range) then + { + _remLocs pushBack _loc; + }; + }; + }; + if not(count _x isEqualTo 2) then + { + ["fn_findPos", 0, format["found invalid entry in mission blacklist: %1", _x]] spawn VEMFr_fnc_log; + }; + } forEach _blackPos; + }; + if ((text _x) in _blackList) then { _remLocs pushBack _x; }; - if not _hasPlayers then + if not((text _x) in _blackList) then { - if _checkBlackPos then - { - private ["_locPos","_loc"]; - _locPos = locationPosition _x; - _loc = _x; - { - if (count _x isEqualTo 2) then - { - _pos = _x param [0, [0,0,0], [[]]]; - if not(_pos isEqualTo [0,0,0]) then - { - _range = _x param [1, 600, [0]]; - if ((_pos distance _locPos) < _range) then - { - _remLocs pushBack _loc; - }; - }; - }; - if not(count _x isEqualTo 2) then - { - ["fn_findPos", 0, format["found invalid entry in mission blacklist: %1", _x]] spawn VEMFr_fnc_log; - }; - } forEach _blackPos; - }; - if ((text _x) in _blackList) then + if (_cntr distance (locationPosition _x) < _tooCloseRange) then { _remLocs pushBack _x; }; - if not((text _x) in _blackList) then + if (_cntr distance (locationPosition _x) > _tooCloseRange) then { - if (_cntr distance (locationPosition _x) < _tooCloseRange) then + if (([text _x, locationPosition _x]) in _usedLocs) then { _remLocs pushBack _x; }; - if (_cntr distance (locationPosition _x) > _tooCloseRange) then - { - if (([text _x, locationPosition _x]) in _usedLocs) then - { - _remLocs pushBack _x; - }; - }; }; - if (count _usedLocs > 0) then + }; + if (count _usedLocs > 0) then + { + private ["_loc"]; + _loc = _x; { - private ["_loc"]; - _loc = _x; + if (((locationPosition _loc) distance (_x select 1)) < _missionDistance) then { - if (((locationPosition _loc) distance (_x select 1)) < _missionDistance) then - { - _remLocs pushBack _loc; - }; - } forEach _usedLocs; - }; - }; - } forEach _locs; - - { // Remove all invalid locations from _locs - _index = _locs find _x; - _locs deleteAt _index; - } forEach _remLocs; - - // Check what kind of distances we have - _far = []; // Further than _maxPrefered - _pref = []; // Closer then _maxPrefered - { - _dist = _cntr distance (locationPosition _x); - if (_dist > _maxPrefered) then - { - _far pushBack _x; - }; - if (_dist < _maxPrefered) then - { - _pref pushBack _x; - }; - } forEach _locs; - - // Check if there are any prefered locations. If yes, randomly select one - if (count _pref > 0) then - { - _loc = selectRandom _pref; - }; - - // Check if _far has any locations and if _pref is empty - if (count _far > 0) then - { - if (count _pref isEqualTo 0) then - { - _loc = selectRandom _far; + _remLocs pushBack _loc; + }; + } forEach _usedLocs; }; }; + } forEach _locs; - // Validate _locs just to prevent the .RPT from getting spammed - if (count _locs > 0) then + { // Remove all invalid locations from _locs + _index = _locs find _x; + _locs deleteAt _index; + } forEach _remLocs; + + // Check what kind of distances we have + _far = []; // Further than _maxPrefered + _pref = []; // Closer then _maxPrefered + { + _dist = _cntr distance (locationPosition _x); + if (_dist > _maxPrefered) then { - // Return Name and POS - _ret = [text _loc, locationPosition _loc]; - (uiNamespace getVariable "VEMFrUsedLocs") pushBack _ret; + _far pushBack _x; + }; + if (_dist < _maxPrefered) then + { + _pref pushBack _x; + }; + } forEach _locs; + + // Check if there are any prefered locations. If yes, randomly select one + if (count _pref > 0) then + { + _loc = selectRandom _pref; + }; + + // Check if _far has any locations and if _pref is empty + if (count _far > 0) then + { + if (count _pref isEqualTo 0) then + { + _loc = selectRandom _far; }; }; - }; - if (_mode isEqualTo "pos") then - { - _valid = false; - for "_p" from 1 to 10 do + + // Validate _locs just to prevent the .RPT from getting spammed + if (count _locs > 0) then { - if (_ret isEqualType true) then + // Return Name and POS + _ret = [text _loc, locationPosition _loc]; + (uiNamespace getVariable "VEMFrUsedLocs") pushBack _ret; + }; + }; + }; + if (_mode isEqualTo "pos") then + { + _valid = false; + for "_p" from 1 to 10 do + { + if (_ret isEqualType true) then + { + if not _ret then { - if not _ret then + _pos = [_cntr, _tooCloseRange, -1, 2, 0, 50, 0] call BIS_fnc_findSafePos; + if _onRoad then { - _pos = [_cntr, _tooCloseRange, _rad, 2, 0, 500, 0] call BIS_fnc_findSafePos; - if _onRoad then + _roads = _pos nearRoads _roadRange; + if (count _roads > 0) then { - _roads = _pos nearRoads _roadRange; - if (count _roads > 0) then - { - private ["_closest","_dist"]; - _closest = ["", _roadRange]; - { // Find the closest road - _dist = _x distance _pos; - if (_dist < (_closest select 1)) then - { - _closest = [_x, _dist]; - }; - } forEach _roads; - _pos = position (_closest select 0); - }; - }; - _hasPlayers = [_pos, _skipDistance] call VEMFr_fnc_checkPlayerPresence; - if not(_hasPlayers) then - { - _ret = _pos; + private ["_closest","_dist"]; + _closest = ["", _roadRange]; + { // Find the closest road + _dist = _x distance _pos; + if (_dist < (_closest select 1)) then + { + _closest = [_x, _dist]; + }; + } forEach _roads; + _pos = position (_closest select 0); }; }; + _hasPlayers = [_pos, _skipDistance] call VEMFr_fnc_checkPlayerPresence; + if not(_hasPlayers) then + { + _ret = _pos; + }; }; }; }; diff --git a/exile_vemf_reloaded/functions/fn_getSetting.sqf b/exile_vemf_reloaded/functions/fn_getSetting.sqf index 73f2e7a..deedcde 100644 --- a/exile_vemf_reloaded/functions/fn_getSetting.sqf +++ b/exile_vemf_reloaded/functions/fn_getSetting.sqf @@ -17,7 +17,7 @@ ARRAY - Result */ -private["_cfg","_v","_r","_path","_check"]; +private["_cfg","_v","_r","_path","_check","_build"]; _r = []; _check = { @@ -43,7 +43,13 @@ _check = if (_this isEqualType "") then { - _cfg = configFile >> "CfgVemfReloaded" >> _this; + if (isNull (configFile >> "CfgVemfReloaded" >> "CfgSettingsOverride" >> _this)) then + { + _cfg = configFile >> "CfgVemfReloaded" >> _this; + } else + { + _cfg = configFile >> "CfgVemfReloaded" >> "CfgSettingsOverride" >> _this; + }; call _check; if not(isNil"_v") then { @@ -53,15 +59,29 @@ if (_this isEqualType "") then if (_this isEqualType []) then { - if (count _this isEqualTo 2) then + if (_this isEqualTypeArray [[],[]]) then { - _cfg = configFile >> "CfgVemfReloaded"; - _path = _cfg; + _path = _this select 0; + //["fn_getSetting", 1, format["_path = %1", _path]] spawn VEMFr_fnc_log; + _build = { + { + _cfg = _cfg >> _x; + } forEach _path; + }; { - _path = _path >> _x; // Build the config path - } forEach (_this select 0); - { - _cfg = _path >> _x; + _cfg = configFile >> "CfgVemfReloaded" >> "CfgSettingsOverride"; + call _build; + _cfg = _cfg >> _x; + //["fn_getSetting", 1, format["_cfg after first build = %1", _cfg]] spawn VEMFr_fnc_log; + if (isNull _cfg) then + { + //["fn_getSetting", 1, format["_cfg isNull. Resetting _cfg...."]] spawn VEMFr_fnc_log; + _cfg = configFile >> "CfgVemfReloaded"; + call _build; + _cfg = _cfg >> _x; + //["fn_getSetting", 1, format["_cfg after second build = %1", _cfg]] spawn VEMFr_fnc_log; + }; + //["fn_getSetting", 1, format["_cfg after appending _x = %1", _cfg]] spawn VEMFr_fnc_log; call _check; if not isNil"_v" then { @@ -69,10 +89,14 @@ if (_this isEqualType []) then }; } forEach (_this select 1); }; - if (count _this isEqualTo 1) then + if (_this isEqualTypeArray [[]]) then { { - _cfg = configFile >> "CfgVemfReloaded" >> _x; + _cfg = configFile >> "CfgVemfReloaded" >> "CfgSettingsOverride" >> _x; + if (isNull _cfg) then + { + _cfg = configFile >> "CfgVemfReloaded" >> _x; + }; call _check; _r pushBack _v; } forEach (_this select 0); diff --git a/exile_vemf_reloaded/functions/fn_launch.sqf b/exile_vemf_reloaded/functions/fn_launch.sqf index 24055f2..5bc62a1 100644 --- a/exile_vemf_reloaded/functions/fn_launch.sqf +++ b/exile_vemf_reloaded/functions/fn_launch.sqf @@ -5,11 +5,59 @@ launches VEMFr (You don't say?) */ -["Launcher", 2, format["/// STARTING v%1 \\\", getNumber (configFile >> "CfgPatches" >> "Exile_VEMF_Reloaded" >> "version")]] spawn VEMFr_fnc_log; +["Launcher", 2, format["/// STARTING v%1 \\\", getNumber (configFile >> "CfgPatches" >> "exile_vemf_reloaded" >> "version")]] spawn VEMFr_fnc_log; uiNamespace setVariable ["VEMFrUsedLocs", []]; uiNamespace setVariable ["VEMFrHcLoad", []]; + [] spawn VEMFr_fnc_checkLoot; // Check loot tables if enabled [] spawn VEMFr_fnc_missionTimer; // Launch mission timer [] spawn VEMFr_fnc_spawnStaticAI; // Launch Static AI spawner west setFriend [independent, 0]; independent setFriend [west, 0]; + +[] spawn +{ + uiSleep 4; + _overridesToRPT = "overridesToRPT" call VEMFr_fnc_getSetting; + if (_overridesToRPT isEqualTo 1) then + { + _root = configProperties [configFile >> "CfgVemfReloaded" >> "CfgSettingsOverride", "true", false]; + if (count _root > 0) then + { + { + if (isClass _x) then + { + _classLv1Name = configName _x; + _levelOne = configProperties [configFile >> "CfgVemfReloaded" >> "CfgSettingsOverride" >> _classLv1Name, "true", false]; + if (count _levelOne > 0) then + { + { + if (isClass _x) then + { + _classLv2Name = configName _x; + _levelTwo = configProperties [configFile >> "CfgVemfReloaded" >> "CfgSettingsOverride" >> _classLv1Name >> _classLv2Name, "true", false]; + if (count _levelTwo > 0) then + { + { + if not(isClass _x) then + { + ["overridesToRPT", 1, format["Overriding 'CfgVemfReloaded >> %1 >> %2 >> %3'", _classLv1Name, _classLv2Name, configName _x]] spawn VEMFr_fnc_log; + }; + } forEach _levelTwo; + }; + }; + if not(isClass _x) then + { + ["overridesToRPT", 1, format["Overriding 'CfgVemfReloaded >> %1 >> %2", _classLv1Name, configName _x]] spawn VEMFr_fnc_log; + }; + } forEach _levelOne; + }; + }; + if not(isClass _x) then + { + ["overridesToRPT", 1, format["Overriding 'CfgVemfReloaded >> %1'", configName _x]] spawn VEMFr_fnc_log; + }; + } forEach _root; + }; + }; +}; diff --git a/exile_vemf_reloaded/functions/fn_loadInv.sqf b/exile_vemf_reloaded/functions/fn_loadInv.sqf index 6d08f4b..a970a73 100644 --- a/exile_vemf_reloaded/functions/fn_loadInv.sqf +++ b/exile_vemf_reloaded/functions/fn_loadInv.sqf @@ -7,14 +7,14 @@ Param: _this: ARRAY _this select 0: ARRAY - units to load inventory for - _this select 1: STRING - what type of mission the loadout should be for + _this select 1: STRING - must be in missionList _this select 2: SCALAR - inventory mode Returns: BOOLEAN - true if nothing failed */ -private ["_ok","_params","_units","_mode","_settings","_aiLaunchers","_aiGear","_uniforms","_headGear","_vests","_backpacks","_launchers","_rifles","_pistols","_aiMode","_givenAmmo"]; +private ["_ok","_params","_units","_missionName","_settings","_aiLaunchers","_aiGear","_uniforms","_headGear","_vests","_backpacks","_launchers","_rifles","_pistols","_aiMode","_givenAmmo"]; _ok = false; _params = _this; if (_this isEqualType []) then @@ -22,196 +22,203 @@ if (_this isEqualType []) then _units = param [0, [], [[]]]; if (count _units > 0) then { - _mode = param [1, "", [""]]; - if not(_mode isEqualTo "") then + _missionName = param [1, "", [""]]; + if (_missionName in ("missionList" call VEMFr_fnc_getSetting)) then { _aiMode = param [2, 0, [0]]; - if (_aiMode isEqualTo 0) then + switch _aiMode do { - // Define settings - _aiGear = [["aiGear"],["aiUniforms","aiHeadGear","aiVests","aiBackpacks","aiLaunchers","aiRifles","aiPistols"]] call VEMFr_fnc_getSetting; - _uniforms = _aiGear select 0; - _headGear = _aiGear select 1; - _vests = _aiGear select 2; - _backpacks = _aiGear select 3; - _rifles = _aiGear select 5; - _pistols = _aiGear select 6; - _aiLaunchers = ([["DynamicLocationInvasion"],["aiLaunchers"]] call VEMFr_fnc_getSetting) select 0; - if (_aiLaunchers isEqualTo 1) then + case 0: { - _launchers = _aiGear select 4; - }; - { - private ["_unit","_gear","_ammo"]; - _unit = _x; - // Strip it - removeAllWeapons _unit; - removeAllItems _unit; - if ("removeAllAssignedItems" call VEMFr_fnc_getSetting isEqualTo 1) then + // Define settings + _aiGear = [["aiGear"],["aiUniforms","aiHeadGear","aiVests","aiBackpacks","aiLaunchers","aiRifles","aiPistols"]] call VEMFr_fnc_getSetting; + _uniforms = _aiGear select 0; + _headGear = _aiGear select 1; + _vests = _aiGear select 2; + _backpacks = _aiGear select 3; + _rifles = _aiGear select 5; + _pistols = _aiGear select 6; + _aiLaunchers = ([[_missionName],["aiLaunchers"]] call VEMFr_fnc_getSetting) select 0; + if (_aiLaunchers isEqualTo 1) then { - removeAllAssignedItems _unit; + _launchers = _aiGear select 4; }; - removeUniform _unit; - removeVest _unit; - removeBackpack _unit; - removeGoggles _unit; - removeHeadGear _unit; - - _gear = selectRandom _uniforms; - _unit forceAddUniform _gear; // Give the poor naked guy some clothing :) - - _gear = selectRandom _headGear; - _unit addHeadGear _gear; - - _gear = selectRandom _vests; - _unit addVest _gear; - - if ((floor random 2) isEqualTo 0) then { - _gear = selectRandom _backpacks; - _unit addBackpack _gear; - if (_aiLaunchers isEqualTo 1) then + private ["_unit","_gear","_ammo"]; + _unit = _x; + // Strip it + removeAllWeapons _unit; + removeAllItems _unit; + if ("removeAllAssignedItems" call VEMFr_fnc_getSetting isEqualTo 1) then { - if ((floor random 4) isEqualTo 0) then + removeAllAssignedItems _unit; + }; + removeUniform _unit; + removeVest _unit; + removeBackpack _unit; + removeGoggles _unit; + removeHeadGear _unit; + + _gear = selectRandom _uniforms; + _unit forceAddUniform _gear; // Give the poor naked guy some clothing :) + + _gear = selectRandom _headGear; + _unit addHeadGear _gear; + + _gear = selectRandom _vests; + _unit addVest _gear; + + if ((floor random 2) isEqualTo 0) then + { + _gear = selectRandom _backpacks; + _unit addBackpack _gear; + if (_aiLaunchers isEqualTo 1) then { - private ["_ammo"]; - _gear = selectRandom _launchers; - _unit addWeapon _gear; - _ammo = getArray (configFile >> "cfgWeapons" >> _gear >> "magazines"); - if (count _ammo > 2) then + if ((floor random 4) isEqualTo 0) then { - _ammo resize 2; - }; - for "_i" from 0 to (2 + (round random 1)) do - { - _unit addMagazine (selectRandom _ammo); + private ["_ammo"]; + _gear = selectRandom _launchers; + _unit addWeapon _gear; + _ammo = getArray (configFile >> "cfgWeapons" >> _gear >> "magazines"); + if (count _ammo > 2) then + { + _ammo resize 2; + }; + for "_i" from 0 to (2 + (round random 1)) do + { + _unit addMagazine (selectRandom _ammo); + }; }; }; }; - }; - // Add Weapons & Ammo - _gear = selectRandom _rifles; - _unit addWeapon _gear; - _unit selectWeapon _gear; + // Add Weapons & Ammo + _gear = selectRandom _rifles; + _unit addWeapon _gear; + _unit selectWeapon _gear; - _gear = selectRandom _pistols; - _unit addWeapon _gear; + _gear = selectRandom _pistols; + _unit addWeapon _gear; - // Give this guy some ammo - _givenAmmo = [_unit] call VEMFr_fnc_giveAmmo; - if not _givenAmmo then - { - ["fn_loadInv", 0, format["FAILED to give ammo to AI: %1", _unit]] spawn VEMFr_fnc_log; - }; - // Give this guy some weaponItems - _giveAttachments = [_unit] call VEMFr_fnc_giveWeaponItems; - if not _giveAttachments then - { - ["fn_loadInv", 0, format["FAILED to giveWeaponItems to %1", _unit]] spawn VEMFr_fnc_log; - }; + // Give this guy some ammo + _givenAmmo = [_unit] call VEMFr_fnc_giveAmmo; + if not _givenAmmo then + { + ["fn_loadInv", 0, format["FAILED to give ammo to AI: %1", _unit]] spawn VEMFr_fnc_log; + }; + // Give this guy some weaponItems + _giveAttachments = [_unit] call VEMFr_fnc_giveWeaponItems; + if not _giveAttachments then + { + ["fn_loadInv", 0, format["FAILED to giveWeaponItems to %1", _unit]] spawn VEMFr_fnc_log; + }; - } forEach _units; - _ok = true; - }; - - if (_aiMode isEqualTo 1) then - { - private ["_policeGear","_headGear","_vests"]; - _policeGear = [["policeConfig"],["headGear","vests","uniforms","rifles","pistols","backpacks"]] call VEMFr_fnc_getSetting; - _headGear = _policeGear select 0; - _vests = _policeGear select 1; - _uniforms = _policeGear select 2; - _rifles = _policeGear select 3; - _pistols = _policeGear select 4; - _backpacks = _policeGear select 5; + } forEach _units; + _ok = true; + }; + case 1: { - _unit = _x; - // Strip it - removeAllWeapons _unit; - removeAllItems _unit; - if ("removeAllAssignedItems" call VEMFr_fnc_getSetting isEqualTo 1) then + private ["_policeGear","_headGear","_vests"]; + _policeGear = [["policeConfig"],["headGear","vests","uniforms","rifles","pistols","backpacks"]] call VEMFr_fnc_getSetting; + _headGear = _policeGear select 0; + _vests = _policeGear select 1; + _uniforms = _policeGear select 2; + _rifles = _policeGear select 3; + _pistols = _policeGear select 4; + _backpacks = _policeGear select 5; { - removeAllAssignedItems _unit; - }; - removeUniform _unit; - removeVest _unit; - removeBackpack _unit; - removeGoggles _unit; - removeHeadGear _unit; + _unit = _x; + // Strip it + removeAllWeapons _unit; + removeAllItems _unit; + if ("removeAllAssignedItems" call VEMFr_fnc_getSetting isEqualTo 1) then + { + removeAllAssignedItems _unit; + }; + removeUniform _unit; + removeVest _unit; + removeBackpack _unit; + removeGoggles _unit; + removeHeadGear _unit; - _hat = selectRandom _headGear; - _unit addHeadGear _hat; - _vest = selectRandom _vests; - _unit addVest _vest; - _uniform = selectRandom _uniforms; - _unit forceAddUniform _uniform; - _rifle = selectRandom _rifles; + _hat = selectRandom _headGear; + _unit addHeadGear _hat; + _vest = selectRandom _vests; + _unit addVest _vest; + _uniform = selectRandom _uniforms; + _unit forceAddUniform _uniform; + _rifle = selectRandom _rifles; + _unit addWeapon _rifle; + _unit selectWeapon _rifle; + _pistol = selectRandom _pistols; + _unit addWeapon _pistol; + _backpack = selectRandom _backpacks; + _unit addBackPack _backpack; + + // Give this guy some ammo + _givenAmmo = [_unit] call VEMFr_fnc_giveAmmo; + if not _givenAmmo then + { + ["fn_loadInv", 0, format["FAILED to give ammo to AI: %1", _unit]] spawn VEMFr_fnc_log; + }; + // Give this guy some weaponItems + _giveAttachments = [_unit] call VEMFr_fnc_giveWeaponItems; + if not _giveAttachments then + { + ["fn_loadInv", 0, format["FAILED to giveWeaponItems to %1", _unit]] spawn VEMFr_fnc_log; + }; + } forEach _units; + _ok = true; + }; + case 2: + { + private ["_policeGear","_headGear","_vests"]; + _policeGear = [["policeConfig"],["rifles","pistols"]] call VEMFr_fnc_getSetting; + _rifles = _policeGear select 0; + _pistols = _policeGear select 1; + { + _unit = _x; + // Strip it + removeAllWeapons _unit; + removeAllItems _unit; + if ("removeAllAssignedItems" call VEMFr_fnc_getSetting isEqualTo 1) then + { + removeAllAssignedItems _unit; + }; + removeUniform _unit; + removeVest _unit; + removeBackpack _unit; + removeGoggles _unit; + removeHeadGear _unit; + _unit addHeadGear "H_HelmetB_light_black"; + _unit addGoggles "G_Balaclava_blk"; + _unit addVest "V_PlateCarrier2_blk"; + _unit forceAddUniform "Exile_Uniform_ExileCustoms"; + _rifle = selectRandom _rifles; _unit addWeapon _rifle; _unit selectWeapon _rifle; - _pistol = selectRandom _pistols; + _pistol = selectRandom _pistols; _unit addWeapon _pistol; - _backpack = selectRandom _backpacks; - _unit addBackPack _backpack; - // Give this guy some ammo - _givenAmmo = [_unit] call VEMFr_fnc_giveAmmo; - if not _givenAmmo then - { - ["fn_loadInv", 0, format["FAILED to give ammo to AI: %1", _unit]] spawn VEMFr_fnc_log; - }; - // Give this guy some weaponItems - _giveAttachments = [_unit] call VEMFr_fnc_giveWeaponItems; - if not _giveAttachments then - { - ["fn_loadInv", 0, format["FAILED to giveWeaponItems to %1", _unit]] spawn VEMFr_fnc_log; - }; - } forEach _units; - }; - - if (_aiMode isEqualTo 2) then - { - private ["_policeGear","_headGear","_vests"]; - _policeGear = [["policeConfig"],["rifles","pistols"]] call VEMFr_fnc_getSetting; - _rifles = _policeGear select 0; - _pistols = _policeGear select 1; + // Give this guy some ammo + _givenAmmo = [_unit] call VEMFr_fnc_giveAmmo; + if not _givenAmmo then + { + ["fn_loadInv", 0, format["FAILED to give ammo to AI: %1", _unit]] spawn VEMFr_fnc_log; + }; + // Give this guy some weaponItems + _giveAttachments = [_unit] call VEMFr_fnc_giveWeaponItems; + if not _giveAttachments then + { + ["fn_loadInv", 0, format["FAILED to giveWeaponItems to %1", _unit]] spawn VEMFr_fnc_log; + }; + } forEach _units; + _ok = true; + }; + default { - _unit = _x; - // Strip it - removeAllWeapons _unit; - removeAllItems _unit; - if ("removeAllAssignedItems" call VEMFr_fnc_getSetting isEqualTo 1) then - { - removeAllAssignedItems _unit; - }; - removeUniform _unit; - removeVest _unit; - removeBackpack _unit; - removeGoggles _unit; - removeHeadGear _unit; - _unit addHeadGear "H_HelmetB_light_black"; - _unit addGoggles "G_Balaclava_blk"; - _unit addVest "V_PlateCarrier2_blk"; - _unit forceAddUniform "Exile_Uniform_ExileCustoms"; - _rifle = selectRandom _rifles; - _unit addWeapon _rifle; - _unit selectWeapon _rifle; - _pistol = selectRandom _pistols; - _unit addWeapon _pistol; - - // Give this guy some ammo - _givenAmmo = [_unit] call VEMFr_fnc_giveAmmo; - if not _givenAmmo then - { - ["fn_loadInv", 0, format["FAILED to give ammo to AI: %1", _unit]] spawn VEMFr_fnc_log; - }; - // Give this guy some weaponItems - _giveAttachments = [_unit] call VEMFr_fnc_giveWeaponItems; - if not _giveAttachments then - { - ["fn_loadInv", 0, format["FAILED to giveWeaponItems to %1", _unit]] spawn VEMFr_fnc_log; - }; - } forEach _units; + ["fn_loadInv", 0, format["Incorrect _aiMode of %1 given!", _aiMode]] spawn VEMFr_fnc_log; + }; }; }; }; diff --git a/exile_vemf_reloaded/functions/fn_log.sqf b/exile_vemf_reloaded/functions/fn_log.sqf index 0b9745e..656eb2d 100644 --- a/exile_vemf_reloaded/functions/fn_log.sqf +++ b/exile_vemf_reloaded/functions/fn_log.sqf @@ -16,22 +16,35 @@ private ["_param","_prefix","_mode","_logThis","_logModesAllowed","_loggingEnabled"]; _loggingEnabled = "debugMode" call VEMFr_fnc_getSetting; -if (_loggingEnabled > 0) then +if not(_loggingEnabled isEqualTo 0) then { - if (_loggingEnabled < 4) then - { - _type = param [1, 3, [0]]; - _line = param [2, "", [""]]; - if (_type < _loggingEnabled) then - { - if not(_line isEqualTo "") then - { - diag_log text format["IT07: [exile_vemf_reloaded] %1", _line]; - }; - }; - if (_type isEqualTo 2) then // Always allow log type 2 no matter which debugMode is set - { - diag_log text format["IT07: [exile_vemf_reloaded] %1", _line]; - }; - }; + _prefix = param [0, "", [""]]; + _type = param [1, 3, [0]]; + _line = param [2, "", [""]]; + _doLog = + { + diag_log text format["IT07: [exile_vemf_reloaded] %1 -- %2", _prefix, _line]; + }; + + switch _type do + { + case 0: + { + if (_loggingEnabled isEqualTo 1 OR _loggingEnabled isEqualTo 3) then + { + call _doLog; + }; + }; + case 1: + { + if (_loggingEnabled isEqualTo 2 OR _loggingEnabled isEqualTo 3) then + { + call _doLog; + }; + }; + case 2: + { + call _doLog; + }; + }; }; diff --git a/exile_vemf_reloaded/functions/fn_missionTimer.sqf b/exile_vemf_reloaded/functions/fn_missionTimer.sqf index d31b32e..803b534 100644 --- a/exile_vemf_reloaded/functions/fn_missionTimer.sqf +++ b/exile_vemf_reloaded/functions/fn_missionTimer.sqf @@ -32,7 +32,7 @@ if (_minFPS > -1) then waitUntil { uiSleep 5; (if (([_minPlayers] call VEMFr_fnc_playerCount) AND (diag_fps > _minFPS)) then { true } else { false }) }; ["missionTimer", 1, format["Minimal player count of %1 reached! Starting timer...", _minPlayers]] spawn VEMFr_fnc_log; - VEMFr_missionCount = 0; + VEMFrMissionCount = 0; private ["_ignoreLimit"]; _ignoreLimit = false; if (_maxGlobalMissions isEqualTo 0) then @@ -55,11 +55,11 @@ if (_minFPS > -1) then }; if not _ignoreLimit then { - if (VEMFr_missionCount <= _maxGlobalMissions) then + if (VEMFrMissionCount <= _maxGlobalMissions) then { _missVar = selectRandom _missionList; [] execVM format["exile_vemf_reloaded\missions\%1.sqf", _missVar]; - VEMFr_missionCount = VEMFr_missionCount +1; + VEMFrMissionCount = VEMFrMissionCount +1; _lastMission = serverTime; }; }; diff --git a/exile_vemf_reloaded/functions/fn_spawnInvasionAI.sqf b/exile_vemf_reloaded/functions/fn_spawnInvasionAI.sqf new file mode 100644 index 0000000..11de1b1 --- /dev/null +++ b/exile_vemf_reloaded/functions/fn_spawnInvasionAI.sqf @@ -0,0 +1,211 @@ +/* + Author: original by Vampire, completely rewritten by IT07 + + Description: + spawns AI using given _pos and unit/group count. + + Params: + _this select 0: POSITION - where to spawn the units around + _this select 1: SCALAR - how many groups to spawn + _this select 2: SCALAR - how many units to put in each group + _this select 3: SCALAR - AI mode + _this select 4: STRING - exact config name of mission + + Returns: + ARRAY format [UNITS,[groups],50cals] +*/ + +private // Make sure that the vars in this function do not interfere with vars in the calling script +[ + "_pos","_grpCount","_unitsPerGrp","_sldrClass","_groups","_settings","_hc","_skills","_newPos","_return","_waypoints","_wp","_cyc","_units","_missionName", + "_accuracy","_aimShake","_aimSpeed","_stamina","_spotDist","_spotTime","_courage","_reloadSpd","_commanding","_general","_loadInv","_noHouses","_cal50sVehs","_mode" +]; + +_spawned = [[],[]]; +_pos = param [0, [], [[]]]; +if (count _pos isEqualTo 3) then +{ + _grpCount = param [1, 1, [0]]; + if (_grpCount > 0) then + { + _unitsPerGrp = param [2, 1, [0]]; + if (_unitsPerGrp > 0) then + { + _mode = param [3, -1, [0]]; + _missionName = param [4, "", [""]]; + if (_missionName in ("missionList" call VEMFr_fnc_getSetting)) then + { + _sldrClass = "unitClass" call VEMFr_fnc_getSetting; + _groups = []; + _hc = "headLessClientSupport" call VEMFr_fnc_getSetting; + _aiDifficulty = [["aiSkill"],["difficulty"]] call VEMFr_fnc_getSetting param [0, "Veteran", [""]]; + _skills = [["aiSkill", _aiDifficulty],["accuracy","aimingShake","aimingSpeed","endurance","spotDistance","spotTime","courage","reloadSpeed","commanding","general"]] call VEMFr_fnc_getSetting; + _accuracy = _skills select 0; + _aimShake = _skills select 1; + _aimSpeed = _skills select 2; + _stamina = _skills select 3; + _spotDist = _skills select 4; + _spotTime = _skills select 5; + _courage = _skills select 6; + _reloadSpd = _skills select 7; + _commanding = _skills select 8; + _general = _skills select 9; + + _houses = nearestTerrainObjects [_pos, ["House"], 200]; // Find some houses to spawn in + _notTheseHouses = "housesBlackList" call VEMFr_fnc_getSetting; + _goodHouses = []; + { // Filter the houses that are too small for one group + if not(typeOf _x in _notTheseHouses) then + { + if ([_x, _unitsPerGrp] call BIS_fnc_isBuildingEnterable) then + { + _goodHouses pushBack _x; + }; + }; + } forEach _houses; + _goodHouses = _goodHouses call BIS_fnc_arrayShuffle; + _noHouses = false; + if (count _goodHouses < _grpCount) then + { + _noHouses = true; + }; + + _cal50s = [["DynamicLocationInvasion"],["cal50s"]] call VEMFr_fnc_getSetting param [0, 3, [0]]; + if (_cal50s > 0) then + { + _cal50sVehs = []; + }; + _units = []; // Define units array. the for loops below will fill it with units + for "_g" from 1 to _grpCount do // Spawn Groups near Position + { + if not _noHouses then + { + if (count _goodHouses < 1) then + { + _noHouses = true + }; + }; + private ["_unitSide","_grp","_unit","_groupSide"]; + _groupSide = ("unitClass" call VEMFr_fnc_getSetting) call VEMFr_fnc_checkSide; + if not isNil"_groupSide" then + { + _grp = createGroup _groupSide; + (_spawned select 1) pushBack _grp; + }; + if not isNil"_grp" then + { + if not _noHouses then + { + _grp enableAttack false; + }; + _grp setBehaviour "AWARE"; + _grp setCombatMode "RED"; + _grp allowFleeing 0; + private ["_house","_housePositions"]; + if not _noHouses then + { + _house = selectRandom _goodHouses; + _houseID = _goodHouses find _house; + _goodHouses deleteAt _houseID; + _housePositions = [_house] call BIS_fnc_buildingPositions; + }; + + _placed50 = false; + for "_u" from 1 to _unitsPerGrp do + { + private ["_spawnPos","_hmg"]; + if not _noHouses then + { + _spawnPos = selectRandom _housePositions; + if not _placed50 then + { + _placed50 = true; + if (_cal50s > 0) then + { + _hmg = createVehicle ["B_HMG_01_high_F", _spawnPos, [], 0, "CAN_COLLIDE"]; + _hmg setVehicleLock "LOCKEDPLAYER"; + (_spawned select 2) pushBack _hmg; + }; + }; + }; + if _noHouses then + { + _spawnPos = [_pos,20,250,1,0,200,0] call BIS_fnc_findSafePos; // Find Nearby Position + }; + + _unit = _grp createUnit [_sldrClass, _spawnPos, [], 0, "CAN_COLLIDE"]; // Create Unit There + if not _noHouses then + { + doStop _unit; + if (_cal50s > 0) then + { + if not isNil"_hmg" then + { + if not isNull _hmg then + { + _unit moveInGunner _hmg; + _hmg = nil; + _cal50s = _cal50s - 1; + }; + }; + }; + + _houseIndex = _housePositions find _spawnPos; + _housePositions deleteAt _houseIndex; + }; + + _unit addMPEventHandler ["mpkilled","if (isDedicated) then { [_this select 0, _this select 1] spawn VEMFr_fnc_aiKilled }"]; + (_spawned select 0) pushBack _unit; + // Set skills + _unit setSkill ["aimingAccuracy", _accuracy]; + _unit setSkill ["aimingShake", _aimShake]; + _unit setSkill ["aimingSpeed", _aimSpeed]; + _unit setSkill ["endurance", _stamina]; + _unit setSkill ["spotDistance", _spotDist]; + _unit setSkill ["spotTime", _spotTime]; + _unit setSkill ["courage", _courage]; + _unit setSkill ["reloadSpeed", _reloadSpd]; + _unit setSkill ["commanding", _commanding]; + _unit setSkill ["general", _general]; + _unit setRank "Private"; // Set rank + }; + _grp selectLeader _unit; // Leader Assignment + _groups pushBack _grp; // Push it into the _groups array + }; + }; + + _invLoaded = [_spawned select 0, _missionName, _mode] call VEMFr_fnc_loadInv; // Load the AI's inventory + if isNil"_invLoaded" then + { + ["fn_spawnAI", 0, "failed to load AI's inventory..."] spawn VEMFr_fnc_log; + }; + + if (count _groups isEqualTo _grpCount) then + { + if _noHouses then + { + _waypoints = + [ + [(_pos select 0), (_pos select 1)+50, 0], + [(_pos select 0)+50, (_pos select 1), 0], + [(_pos select 0), (_pos select 1)-50, 0], + [(_pos select 0)-50, (_pos select 1), 0] + ]; + { // Make them Patrol + for "_z" from 1 to (count _waypoints) do + { + _wp = _x addWaypoint [(_waypoints select (_z-1)), 10]; + _wp setWaypointType "SAD"; + _wp setWaypointCompletionRadius 20; + }; + _cyc = _x addWaypoint [_pos,10]; + _cyc setWaypointType "CYCLE"; + _cyc setWaypointCompletionRadius 20; + } forEach _groups; + }; + }; + }; + }; + }; +}; +_spawned diff --git a/exile_vemf_reloaded/functions/fn_spawnVEMFrAI.sqf b/exile_vemf_reloaded/functions/fn_spawnVEMFrAI.sqf new file mode 100644 index 0000000..b3c071b --- /dev/null +++ b/exile_vemf_reloaded/functions/fn_spawnVEMFrAI.sqf @@ -0,0 +1,104 @@ +/* + Author: original by Vampire, completely rewritten by IT07 + + Description: + spawns VEMFr AI using given _pos and unit/group count. Handles their inventory and transfers them to a client + + Params: + _this select 0: POSITION - where to spawn the units around + _this select 1: SCALAR - how many groups to spawn + _this select 2: SCALAR - how many units to put in each group + _this select 3: SCALAR - AI mode + _this select 4: STRING - exact config name of mission + + Returns: + ARRAY with group(s) +*/ + +private // Make sure that the vars in this function do not interfere with vars in the calling script +[ + "_spawned","_allUnits","_pos","_grpCount","_unitsPerGrp","_sldrClass","_settings","_hc","_skills","_newPos","_return","_units","_missionName", + "_accuracy","_aimShake","_aimSpeed","_stamina","_spotDist","_spotTime","_courage","_reloadSpd","_commanding","_general","_loadInv","_mode" +]; + +_spawned = []; +_allUnits = []; +_pos = param [0, [], [[]]]; +if (count _pos isEqualTo 3) then +{ + _grpCount = param [1, 1, [0]]; + if (_grpCount > 0) then + { + _unitsPerGrp = param [2, 1, [0]]; + if (_unitsPerGrp > 0) then + { + _mode = param [3, -1, [0]]; + _missionName = param [4, "", [""]]; + if (_missionName in ("missionList" call VEMFr_fnc_getSetting)) then + { + _sldrClass = "unitClass" call VEMFr_fnc_getSetting; + _hc = "headLessClientSupport" call VEMFr_fnc_getSetting; + _aiDifficulty = [["aiSkill"],["difficulty"]] call VEMFr_fnc_getSetting param [0, "Veteran", [""]]; + _skills = [["aiSkill", _aiDifficulty],["accuracy","aimingShake","aimingSpeed","endurance","spotDistance","spotTime","courage","reloadSpeed","commanding","general"]] call VEMFr_fnc_getSetting; + _accuracy = _skills select 0; + _aimShake = _skills select 1; + _aimSpeed = _skills select 2; + _stamina = _skills select 3; + _spotDist = _skills select 4; + _spotTime = _skills select 5; + _courage = _skills select 6; + _reloadSpd = _skills select 7; + _commanding = _skills select 8; + _general = _skills select 9; + + _units = []; // Define units array. the for loops below will fill it with units + for "_g" from 1 to _grpCount do // Spawn Groups near Position + { + private ["_unitSide","_grp","_unit","_groupSide"]; + _groupSide = ("unitClass" call VEMFr_fnc_getSetting) call VEMFr_fnc_checkSide; + if not isNil"_groupSide" then + { + private["_unit"]; + _grp = createGroup _groupSide; + if not isNil"_grp" then + { + _grp setBehaviour "AWARE"; + _grp setCombatMode "RED"; + _grp allowFleeing 0; + for "_u" from 1 to _unitsPerGrp do + { + _unit = _grp createUnit [_sldrClass, _pos, [], 10, "FORM"]; // Create Unit There + _allUnits pushBack _unit; + _unit addMPEventHandler ["mpkilled","if (isDedicated) then { [_this select 0, _this select 1] spawn VEMFr_fnc_aiKilled }"]; + + // Set skills + _unit setSkill ["aimingAccuracy", _accuracy]; + _unit setSkill ["aimingShake", _aimShake]; + _unit setSkill ["aimingSpeed", _aimSpeed]; + _unit setSkill ["endurance", _stamina]; + _unit setSkill ["spotDistance", _spotDist]; + _unit setSkill ["spotTime", _spotTime]; + _unit setSkill ["courage", _courage]; + _unit setSkill ["reloadSpeed", _reloadSpd]; + _unit setSkill ["commanding", _commanding]; + _unit setSkill ["general", _general]; + _unit setRank "Private"; // Set rank + }; + }; + _grp selectLeader _unit; // Leader Assignment + _grp enableAttack true; + _spawned pushBack _grp; + }; + }; + + _invLoaded = [_allUnits, _missionName, _mode] call VEMFr_fnc_loadInv; // Load the AI's inventory + if not _invLoaded then + { + _spawned = false; + ["fn_spawnVEMFrAI", 0, "failed to load AI's inventory..."] spawn VEMFr_fnc_log; + }; + }; + }; + }; +}; +_spawned diff --git a/exile_vemf_reloaded/missions/DynamicLocationInvasion.sqf b/exile_vemf_reloaded/missions/DynamicLocationInvasion.sqf index 6befda8..11922bf 100644 --- a/exile_vemf_reloaded/missions/DynamicLocationInvasion.sqf +++ b/exile_vemf_reloaded/missions/DynamicLocationInvasion.sqf @@ -1,41 +1,42 @@ /* DynamicLocationInvasion by Vampire, rewritten by IT07 */ -private ["_settings","_grpCount","_groupUnits","_skipDistance","_loc","_hasPlayers","_spawned","_grpArr","_unitArr","_done","_boxes","_box","_chute","_colors","_lightType","_light","_smoke"]; -// Define _settings -_settings = [["DynamicLocationInvasion"],["maxInvasions","groupCount","groupUnits","maxDistance","maxDistancePrefered","skipDistance","marker","parachuteCrate","markCrateVisual","markCrateOnMap","announce","streetLights","streetLightsRestore","streetLightsRange","allowCrateLift"]] call VEMFr_fnc_getSetting; -_maxInvasions = _settings select 0; -if isNil"VEMFr_invasCount" then +if isNil"VEMFrInvasionCount" then { - VEMFr_invasCount = 0; + VEMFrInvasionCount = 0; }; -VEMFr_invasCount = VEMFr_invasCount + 1; -if (VEMFr_invasCount <= _maxInvasions) then -{ - _grpCount = _settings select 1; - _groupUnits = _settings select 2; - _range = _settings select 3; - _maxPref = _settings select 4; - _skipDistance = _settings select 5; - _useMissionMarker = _settings select 6; - _useChute = (_settings select 7) select 0; - _crateAltitude = (_settings select 7) select 1; - _markCrateVisual = _settings select 8; - _markCrateOnMap = _settings select 9; - _announce = _settings select 10; - _streetLights = _settings select 11; - _streetLightsRestore = _settings select 12; - _streetLightsRange = _settings select 13; - _allowCrateLift = _settings select 14; - _loc = ["loc", false, position (selectRandom allPlayers), _range, _skipDistance, _maxPref, _skipDistance] call VEMFr_fnc_findPos; - if (_loc isEqualType []) then +if (VEMFrInvasionCount < (([["DynamicLocationInvasion"],["maxInvasions"]] call VEMFr_fnc_getSetting) select 0)) then +{ + VEMFrInvasionCount = VEMFrInvasionCount + 1; + private ["_settings","_grpCount","_groupUnits","_skipDistance","_loc","_hasPlayers","_spawned","_grpArr","_unitArr","_done","_boxes","_box","_chute","_colors","_lightType","_light","_smoke"]; + // Define _settings + _settings = [["DynamicLocationInvasion"],["groupCount","groupUnits","maxDistance","maxDistancePrefered","skipDistance","marker","parachuteCrate","markCrateVisual","markCrateOnMap","announce","streetLights","streetLightsRestore","streetLightsRange","allowCrateLift"]] call VEMFr_fnc_getSetting; + _grpCount = _settings select 0; + _groupUnits = _settings select 1; + _range = _settings select 2; + _maxPref = _settings select 3; + _skipDistance = _settings select 4; + _useMissionMarker = _settings select 5; + _useChute = (_settings select 6) select 0; + _crateAltitude = (_settings select 6) select 1; + _markCrateVisual = _settings select 7; + _markCrateOnMap = _settings select 8; + _announce = _settings select 9; + _streetLights = _settings select 10; + _streetLightsRestore = _settings select 11; + _streetLightsRange = _settings select 12; + _allowCrateLift = _settings select 13; + + _loc = ["loc", false, position (selectRandom allPlayers), _skipDistance, _maxPref, _skipDistance, "DynamicLocationInvasion"] call VEMFr_fnc_findPos; + if (_loc isEqualTypeArray ["",[]]) then { _locName = _loc select 0; + _locPos = _loc select 1; if (_locName isEqualTo "") then { _locName = "Area"; }; ["DynamicLocationInvasion", 1, format["Invading %1...", _locName]] spawn VEMFr_fnc_log; - VEMFr_invasCount = VEMFr_invasCount + 1; + VEMFrInvasionCount = VEMFrInvasionCount + 1; // Send message to all players private ["_mode"]; _mode = "aiMode" call VEMFr_fnc_getSetting; @@ -48,21 +49,21 @@ if (VEMFr_invasCount <= _maxInvasions) then { if (_mode isEqualTo 0) then { - [[format["Plundering groups have invaded %1 @ %2", _locName, mapGridPosition (_loc select 1)], "NEW INVASION"], ""] spawn VEMFr_fnc_broadCast; + [[format["Plundering groups have invaded %1 @ %2", _locName, mapGridPosition _locPos], "NEW INVASION"], ""] spawn VEMFr_fnc_broadCast; }; if (_mode isEqualTo 1) then { - [[format["%1 Police forces are now controlling %2 @ %3", worldName, _locName, mapGridPosition (_loc select 1)], "NEW MISSION"], ""] spawn VEMFr_fnc_broadCast; + [[format["%1 Police forces are now controlling %2 @ %3", worldName, _locName, mapGridPosition _locPos], "NEW MISSION"], ""] spawn VEMFr_fnc_broadCast; }; if (_mode isEqualTo 2) then { - [[format["%1 S.W.A.T. teams are now raiding %2 @ %3", worldName, _locName, mapGridPosition (_loc select 1)], "NEW RAID"], ""] spawn VEMFr_fnc_broadCast; + [[format["%1 S.W.A.T. teams are now raiding %2 @ %3", worldName, _locName, mapGridPosition _locPos], "NEW RAID"], ""] spawn VEMFr_fnc_broadCast; }; }; private["_marker"]; if (_useMissionMarker isEqualTo 1) then { // Create/place the marker if enabled - _marker = createMarker [format["VEMFr_DynaLocInva_ID%1", random 9000], (_loc select 1)]; + _marker = createMarker [format["VEMFr_DynaLocInva_ID%1", random 9000], _locPos]; _marker setMarkerShape "ICON"; _marker setMarkerType "o_unknown"; switch true do @@ -86,7 +87,7 @@ if (VEMFr_invasCount <= _maxInvasions) then if (_streetLights isEqualTo 0) then { private ["_all"]; - _all = nearestObjects [_loc select 1, ["Lamps_Base_F","PowerLines_base_F","Land_PowerPoleWooden_L_F"], _streetLightsRange]; + _all = nearestObjects [_locPos, ["Lamps_Base_F","PowerLines_base_F","Land_PowerPoleWooden_L_F"], _streetLightsRange]; { if (damage _x < 0.95) then { @@ -97,239 +98,273 @@ if (VEMFr_invasCount <= _maxInvasions) then }; // Usage: POSITION, Radius - _playerNear = [_loc select 1, 800] call VEMFr_fnc_waitForPlayers; + _playerNear = [_locPos, 800] call VEMFr_fnc_waitForPlayers; if _playerNear then { // Player is Near, so Spawn the Units - _spawned = [_loc select 1, ((_grpCount select 0) + round random ((_grpCount select 1) - (_grpCount select 0))), ((_groupUnits select 0) + round random ((_groupUnits select 1) - (_groupUnits select 0))), _mode] call VEMFr_fnc_spawnAI; - if (count (_spawned select 0) > 0) then + _spawned = [_locPos, ((_grpCount select 0) + round random ((_grpCount select 1) - (_grpCount select 0))), ((_groupUnits select 0) + round random ((_groupUnits select 1) - (_groupUnits select 0))), _mode, "DynamicLocationInvasion"] call VEMFr_fnc_spawnInvasionAI; + if (_spawned isEqualType []) then { - private ["_cal50s"]; - if (count (_spawned select 1) > 0) then + if (_spawned isEqualTypeArray [[],[]]) then { - _cal50s = _spawned select 1; - }; - // Place mines if enabled - private ["_minesPlaced","_mines"]; - _mines = [["DynamicLocationInvasion"],["mines"]] call VEMFr_fnc_getSetting param [0, 0, [0]]; - if (_mines > 0) then - { - _minesPlaced = [_loc select 1, 5, 100] call VEMFr_fnc_placeMines param [0, [], [[]]]; - if (count _minesPlaced > 0) then + private ["_units","_cal50s"]; + _units = _spawned select 0; + _groups = _spawned select 1; { - ["DynamicLocationInvasion", 1, format["Successfully placed mines at %1", _locName]] spawn VEMFr_fnc_log; - }; - if (count _minesPlaced isEqualto 0) then - { - ["DynamicLocationInvasion", 0, format["Failed to place mines at %1", _locName]] spawn VEMFr_fnc_log; - _minesPlaced = nil; - }; - }; + [_x] spawn VEMFr_fnc_signAI; + } forEach _groups; + _cal50s = _spawned select 2; - // Wait for Mission Completion - _done = [_loc select 0, _loc select 1, _spawned select 0, _skipDistance] call VEMFr_fnc_waitForMissionDone; - _usedLocs = uiNamespace getVariable "VEMFrUsedLocs"; - _index = _usedLocs find [_loc select 0, _loc select 1]; - if (_index > -1) then - { - _usedLocs deleteAt _index; - }; - if _done then - { - // Broadcast - if (_announce isEqualTo 1) then - { - if (_mode isEqualTo 0) then - { - [[format["%1 @ %2 has been cleared of %3 bad guys", _locName, mapGridPosition (_loc select 1), worldName], "COMPLETED"], ""] spawn VEMFr_fnc_broadCast; - }; - if (_mode isEqualTo 1) then - { - [[format["%1 @ %2 has been cleared of %3 Police forces", _locName, mapGridPosition (_loc select 1), worldName], "CLEARED"], ""] spawn VEMFr_fnc_broadCast; - }; - if (_mode isEqualTo 2) then - { - [[format["S.W.A.T. raid on %1 @ %2 has been eliminated", _locName, mapGridPosition (_loc select 1)], "DEFEATED"], ""] spawn VEMFr_fnc_broadCast; - }; - }; - // Deal with the 50s - if not isNil"_cal50s" then - { - private["_cal50sDelete"]; - _cal50sDelete = ([["DynamicLocationInvasion"],["cal50sDelete"]] call VEMFr_fnc_getSetting) select 0; - if (_cal50sDelete > 0) then + private ["_heliUnits"]; + _heliPatrolSettings = ([["DynamicLocationInvasion"],["heliPatrol"]] call VEMFr_fnc_getSetting) select 0; + if (_heliPatrolSettings select 0 isEqualTo 1) then + { // If heliPatrol setting is enabled + ["DynamicLocationInvasion", 1, format["Adding a heli patrol to the invasion of %1 at %2", _locName, mapGridPosition _locPos]] spawn VEMFr_fnc_log; + _heli = createVehicle [selectRandom (_heliPatrolSettings select 1), _locPos, [], 50, "FLY"]; + _heli engineOn true; // Just to make sure + _spawnHeliGroup = [_locPos, 1, (((count allTurrets _heli) + (_heli emptyPositions "cargo") + (_heli emptyPositions "commander")) + 1), _mode, "DynamicLocationInvasion"] call VEMFr_fnc_spawnVEMFrAI; + if (_spawnHeliGroup isEqualType []) then { + _heliGroup = _spawnHeliGroup select 0; + _heliUnits = units _heliGroup; { - if (_cal50sDelete isEqualTo 1) then - { - deleteVehicle _x; - }; - if (_cal50sDelete isEqualTo 2) then - { - _x setDamage 1; - }; - } forEach _cal50s; + _x moveInAny _heli; + removeBackpack _x; + _x addBackpack "B_Parachute"; + _units pushBack _x; + } forEach _heliUnits; + + _loiterWaypoint = _heliGroup addWaypoint [_locPos, 50, 1]; + _loiterWaypoint setWaypointType "LOITER"; + _loiterWaypoint setWaypointSpeed "LIMITED"; + _loiterWaypoint setWaypointCombatMode "RED"; + _loiterWaypoint setWaypointBehaviour "AWARE"; + _loiterWaypoint setWaypointLoiterType "CIRCLE_L"; + _loiterWaypoint setWaypointLoiterRadius 25; + _heliGroup setCurrentWaypoint _loiterWaypoint; + + [_heliGroup] spawn VEMFr_fnc_signAI; }; }; - // Choose a box - _boxes = [["DynamicLocationInvasion"],["crateTypes"]] call VEMFr_fnc_getSetting; - _box = (_boxes select 0) call BIS_fnc_selectRandom; - _pos = [_loc select 1, 0, 100, 0, 0, 300, 0] call bis_fnc_findSafePos; - private ["_crate"]; - if (_useChute isEqualTo 1) then - { - _chute = createVehicle ["I_Parachute_02_F", _pos, [], 0, "FLY"]; - _chute setPos [getPos _chute select 0, getPos _chute select 1, _crateAltitude]; - _chute enableSimulationGlobal true; - if not isNull _chute then + // Place mines if enabled + private ["_minesPlaced","_mines"]; + _mines = [["DynamicLocationInvasion"],["mines"]] call VEMFr_fnc_getSetting param [0, 0, [0]]; + if (_mines > 0) then + { + _minesPlaced = [_locPos, 5, 100] call VEMFr_fnc_placeMines param [0, [], [[]]]; + if (count _minesPlaced > 0) then { - _crate = createVehicle [_box, getPos _chute, [], 0, "NONE"]; + ["DynamicLocationInvasion", 1, format["Successfully placed mines at %1", _locName]] spawn VEMFr_fnc_log; + }; + if (count _minesPlaced isEqualto 0) then + { + ["DynamicLocationInvasion", 0, format["Failed to place mines at %1", _locName]] spawn VEMFr_fnc_log; + _minesPlaced = nil; + }; + }; + + // Wait for Mission Completion + _done = [_loc select 0, _locPos, _units, _skipDistance] call VEMFr_fnc_waitForMissionDone; + _usedLocs = uiNamespace getVariable "VEMFrUsedLocs"; + _index = _usedLocs find [_loc select 0, _locPos]; + if (_index > -1) then + { + _usedLocs deleteAt _index; + }; + if _done then + { + // Broadcast + if (_announce isEqualTo 1) then + { + if (_mode isEqualTo 0) then + { + [[format["%1 @ %2 has been cleared of %3 bad guys", _locName, mapGridPosition (_locPos), worldName], "COMPLETED"], ""] spawn VEMFr_fnc_broadCast; + }; + if (_mode isEqualTo 1) then + { + [[format["%1 @ %2 has been cleared of %3 Police forces", _locName, mapGridPosition (_locPos), worldName], "CLEARED"], ""] spawn VEMFr_fnc_broadCast; + }; + if (_mode isEqualTo 2) then + { + [[format["S.W.A.T. raid on %1 @ %2 has been eliminated", _locName, mapGridPosition (_locPos)], "DEFEATED"], ""] spawn VEMFr_fnc_broadCast; + }; + }; + // Deal with the 50s + if not isNil"_cal50s" then + { + private["_cal50sDelete"]; + _cal50sDelete = ([["DynamicLocationInvasion"],["cal50sDelete"]] call VEMFr_fnc_getSetting) select 0; + if (_cal50sDelete > 0) then + { + { + if (_cal50sDelete isEqualTo 1) then + { + deleteVehicle _x; + }; + if (_cal50sDelete isEqualTo 2) then + { + _x setDamage 1; + }; + } forEach _cal50s; + }; + }; + // Choose a box + _boxes = [["DynamicLocationInvasion"],["crateTypes"]] call VEMFr_fnc_getSetting; + _box = (_boxes select 0) call BIS_fnc_selectRandom; + _pos = [_locPos, 0, 100, 0, 0, 300, 0] call bis_fnc_findSafePos; + private ["_crate"]; + if (_useChute isEqualTo 1) then + { + _chute = createVehicle ["I_Parachute_02_F", _pos, [], 0, "FLY"]; + _chute setPos [getPos _chute select 0, getPos _chute select 1, _crateAltitude]; + _chute enableSimulationGlobal true; + + if not isNull _chute then + { + _crate = createVehicle [_box, getPos _chute, [], 0, "NONE"]; + _crate allowDamage false; + _crate enableSimulationGlobal true; + _crate attachTo [_chute, [0,0,0]]; + if (_allowCrateLift isEqualTo 0) then + { + _crate enableRopeAttach false; + }; + ["DynamicLocationInvasion", 1, format ["Crate parachuted at: %1 / Grid: %2", (getPosATL _crate), mapGridPosition (getPosATL _crate)]] spawn VEMFr_fnc_log; + _lootLoaded = [_crate] call VEMFr_fnc_loadLoot; + if _lootLoaded then { ["DynamicLocationInvasion", 1, "Loot loaded successfully into parachuting crate"] spawn VEMFr_fnc_log }; + }; + }; + if (_useChute isEqualTo 0) then + { + _crate = createVehicle [_box, _pos, [], 0, "NONE"]; _crate allowDamage false; - _crate enableSimulationGlobal true; - _crate attachTo [_chute, [0,0,0]]; if (_allowCrateLift isEqualTo 0) then { _crate enableRopeAttach false; }; - ["DynamicLocationInvasion", 1, format ["Crate parachuted at: %1 / Grid: %2", (getPosATL _crate), mapGridPosition (getPosATL _crate)]] spawn VEMFr_fnc_log; _lootLoaded = [_crate] call VEMFr_fnc_loadLoot; - if _lootLoaded then { ["DynamicLocationInvasion", 1, "Loot loaded successfully into parachuting crate"] spawn VEMFr_fnc_log }; + if _lootLoaded then { ["DynamicLocationInvasion", 1, "Loot loaded successfully into crate"] spawn VEMFr_fnc_log }; }; - }; - if (_useChute isEqualTo 0) then - { - _crate = createVehicle [_box, _pos, [], 0, "NONE"]; - _crate allowDamage false; - if (_allowCrateLift isEqualTo 0) then + if (_markCrateVisual isEqualTo 1) then { - _crate enableRopeAttach false; - }; - _lootLoaded = [_crate] call VEMFr_fnc_loadLoot; - if _lootLoaded then { ["DynamicLocationInvasion", 1, "Loot loaded successfully into crate"] spawn VEMFr_fnc_log }; - }; - if (_markCrateVisual isEqualTo 1) then - { - uiSleep 0.5; - // If night, attach a chemlight - if (dayTime < 5 OR dayTime > 19) then - { - _colors = [["DynamicLocationInvasion"],["flairTypes"]] call VEMFr_fnc_getSetting param [0, [], [[]]]; + uiSleep 0.5; + // If night, attach a chemlight + if (dayTime < 5 OR dayTime > 19) then + { + _colors = [["DynamicLocationInvasion"],["flairTypes"]] call VEMFr_fnc_getSetting param [0, [], [[]]]; + if (count _colors > 0) then + { + _lightType = selectRandom _colors; + _light = _lightType createVehicle (position _crate); + _light attachTo [_crate,[0,0,0]]; + }; + }; + // Attach smoke + _colors = [["DynamicLocationInvasion"],["smokeTypes"]] call VEMFr_fnc_getSetting param [0, [], [[]]]; if (count _colors > 0) then { - _lightType = selectRandom _colors; - _light = _lightType createVehicle (position _crate); - _light attachTo [_crate,[0,0,0]]; + _rndmColor = selectRandom _colors; + _smoke = createVehicle [_rndmColor, getPos _crate, [], 0, "CAN_COLLIDE"]; + _smoke attachTo [_crate,[0,0,0]]; }; }; - // Attach smoke - _colors = [["DynamicLocationInvasion"],["smokeTypes"]] call VEMFr_fnc_getSetting param [0, [], [[]]]; - if (count _colors > 0) then + if (_useChute isEqualTo 1) then { - _rndmColor = selectRandom _colors; - _smoke = createVehicle [_rndmColor, getPos _crate, [], 0, "CAN_COLLIDE"]; - _smoke attachTo [_crate,[0,0,0]]; + waitUntil { uiSleep 1; (((getPos _crate) select 2) < 7) }; + detach _crate; }; - }; - if (_useChute isEqualTo 1) then - { - waitUntil { uiSleep 1; (((getPos _crate) select 2) < 7) }; - detach _crate; - }; - if not isNil"_marker" then - { - deleteMarker _marker - }; - VEMFr_invasCount = VEMFr_invasCount - 1; - VEMFr_missionCount = VEMFr_missionCount - 1; - - // Put a marker on the crate if enabled - if not isNil "_crate" then - { - if not isNull _crate then + if not isNil"_marker" then { - if not ([getPos _crate, 2] call VEMFr_fnc_checkPlayerPresence) then + deleteMarker _marker + }; + VEMFrInvasionCount = VEMFrInvasionCount - 1; + VEMFrMissionCount = VEMFrMissionCount - 1; + + // Put a marker on the crate if enabled + if not isNil "_crate" then + { + if not isNull _crate then { - _addMarker = [["DynamicLocationInvasion"],["markCrateOnMap"]] call VEMFr_fnc_getSetting param [0, 1, [0]]; - if (_addMarker isEqualTo 1) then + if not ([getPos _crate, 2] call VEMFr_fnc_checkPlayerPresence) then { - private ["_crateMarker"]; - _crateMarker = createMarker [format["VEMF_lootCrate_ID%1", random 9000], position _crate]; - _crateMarker setMarkerShape "ICON"; - _crateMarker setMarkerType "mil_box"; - _crateMarker setMarkerColor "colorBlack"; - _crateMarker setMarkerText " Loot"; - [_crate, _crateMarker] spawn + _addMarker = [["DynamicLocationInvasion"],["markCrateOnMap"]] call VEMFr_fnc_getSetting param [0, 1, [0]]; + if (_addMarker isEqualTo 1) then { - _crate = _this select 0; - _crateMarker = _this select 1; - waitUntil { uiSleep 4; [getPos _crate, 3] call VEMFr_fnc_checkPlayerPresence }; - deleteMarker _crateMarker; + private ["_crateMarker"]; + _crateMarker = createMarker [format["VEMF_lootCrate_ID%1", random 9000], position _crate]; + _crateMarker setMarkerShape "ICON"; + _crateMarker setMarkerType "mil_box"; + _crateMarker setMarkerColor "colorBlack"; + _crateMarker setMarkerText " Loot"; + [_crate, _crateMarker] spawn + { + _crate = _this select 0; + _crateMarker = _this select 1; + waitUntil { uiSleep 4; [getPos _crate, 3] call VEMFr_fnc_checkPlayerPresence }; + deleteMarker _crateMarker; + }; }; }; }; }; - }; - if isNil "_crate" then - { - ["DynamicLocationInvasion", 0, "ERROR! _crate not found"] spawn VEMFr_fnc_log; - }; - - // Explode or remove the mines - if not isNil"_minesPlaced" then - { - private ["_cleanMines"]; - _cleanMines = [["DynamicLocationInvasion"],["minesCleanup"]] call VEMFr_fnc_getSetting param [0, 1, [0]]; - if (_cleanMines isEqualTo 2) then + if isNil "_crate" then { - { - if not isNull _x then - { - _x setDamage 1; - uiSleep (2 + round random 2); - }; - } forEach _minesPlaced; - ["DynamicLocationInvasion", 1, format["Successfully exploded all %1 mines at %2", count _minesPlaced, _locName]] spawn VEMFr_fnc_log; - _minesPlaced = nil; + ["DynamicLocationInvasion", 0, "ERROR! _crate not found"] spawn VEMFr_fnc_log; }; - if (_cleanMines isEqualTo 1) then - { - { - if not isNull _x then - { - deleteVehicle _x; - }; - } forEach _minesPlaced; - ["DynamicLocationInvasion", 1, format["Successfully deleted all %1 mines at %2", count _minesPlaced, _locName]] spawn VEMFr_fnc_log; - _minesPlaced = nil; - }; - }; - // If enabled, fix all the lights - if (_streetLightsRestore isEqualTo 1) then - { - private ["_all"]; - _all = nearestObjects [_loc select 1, ["Lamps_Base_F","PowerLines_base_F","Land_PowerPoleWooden_L_F"], _streetLightsRange]; + // Explode or remove the mines + if not isNil"_minesPlaced" then { - if (damage _x > 0.94) then + private ["_cleanMines"]; + _cleanMines = [["DynamicLocationInvasion"],["minesCleanup"]] call VEMFr_fnc_getSetting param [0, 1, [0]]; + if (_cleanMines isEqualTo 2) then { - _x setDamage 0; - uiSleep 0.2; + { + if not isNull _x then + { + _x setDamage 1; + uiSleep (2 + round random 2); + }; + } forEach _minesPlaced; + ["DynamicLocationInvasion", 1, format["Successfully exploded all %1 mines at %2", count _minesPlaced, _locName]] spawn VEMFr_fnc_log; + _minesPlaced = nil; }; - } forEach _all; + if (_cleanMines isEqualTo 1) then + { + { + if not isNull _x then + { + deleteVehicle _x; + }; + } forEach _minesPlaced; + ["DynamicLocationInvasion", 1, format["Successfully deleted all %1 mines at %2", count _minesPlaced, _locName]] spawn VEMFr_fnc_log; + _minesPlaced = nil; + }; + }; + + // If enabled, fix all the lights + if (_streetLightsRestore isEqualTo 1) then + { + private ["_all"]; + _all = nearestObjects [_locPos, ["Lamps_Base_F","PowerLines_base_F","Land_PowerPoleWooden_L_F"], _streetLightsRange]; + { + if (damage _x > 0.94) then + { + _x setDamage 0; + uiSleep 0.2; + }; + } forEach _all; + }; }; }; }; - if isNil"_spawned" then + if not(_spawned isEqualType []) exitWith { - ["DynamicLocationInvasion", 0, format["Failed to spawn AI in %1", _locName]] spawn VEMFr_fnc_log; - if not isNil"_marker" then - { - deleteMarker _marker - }; - VEMFr_invasCount = VEMFr_invasCount - 1; - VEMFr_missionCount = VEMFr_missionCount - 1; + VEMFrInvasionCount = VEMFrInvasionCount - 1; + VEMFrMissionCount = VEMFrMissionCount - 1; + [[format["Failed to spawn AI in %1 @ %2", _locName, mapGridPosition (_locPos)], "ERROR!"], ""] spawn VEMFr_fnc_broadCast; }; }; if not _playerNear then @@ -345,18 +380,16 @@ if (VEMFr_invasCount <= _maxInvasions) then { _usedLocs deleteAt _index; }; - VEMFr_invasCount = VEMFr_invasCount - 1; - VEMFr_missionCount = VEMFr_missionCount - 1; + VEMFrInvasionCount = VEMFrInvasionCount - 1; + VEMFrMissionCount = VEMFrMissionCount - 1; }; }; if not(_loc isEqualType []) then { - VEMFr_invasCount = VEMFr_invasCount - 1; - VEMFr_missionCount = VEMFr_missionCount - 1; + VEMFrInvasionCount = VEMFrInvasionCount - 1; + VEMFrMissionCount = VEMFrMissionCount - 1; }; -}; -if (VEMFr_invasCount >= _maxInvasions) then +} else { - VEMFr_invasCount = VEMFr_invasCount - 1; - VEMFr_missionCount = VEMFr_missionCount - 1; + VEMFrMissionCount = VEMFrMissionCount - 1; };