diff --git a/@ExileServer/addons/a3_dms/FSM/missions.fsm b/@ExileServer/addons/a3_dms/FSM/missions.fsm index 1e022dd..5195dba 100644 --- a/@ExileServer/addons/a3_dms/FSM/missions.fsm +++ b/@ExileServer/addons/a3_dms/FSM/missions.fsm @@ -1,4 +1,4 @@ -/*%FSM*/ +/*%FSM*/ /*%FSM*/ /* item0[] = {"",7,210,743.923157,366.553040,751.923157,374.553040,0.000000,""}; @@ -16,9 +16,9 @@ item11[] = {"Mission_Cleanup",2,250,697.923035,248.598328,797.923035,298.598328, item12[] = {"INITIALIZE",4,218,638.875183,-106.463760,728.875183,-56.463760,0.000000,"INITIALIZE"}; item13[] = {"PREPARE",2,250,763.528931,-107.864372,853.528931,-57.864372,0.000000,"PREPARE"}; item14[] = {"___min_loop",4,218,838.578918,171.729218,928.578918,221.729218,3.000000,"1 min loop"}; -item15[] = {"Select_Mission",2,250,839.279602,248.118042,929.279663,298.118042,0.000000,"Select Mission"}; +item15[] = {"Select_Mission",2,4346,839.279602,248.118042,929.279663,298.118042,0.000000,"Select Mission"}; item16[] = {"",7,210,880.582092,366.639160,888.582092,374.639160,0.000000,""}; -item17[] = {"___min_loop__AI",4,4314,975.237671,175.934219,1065.237793,225.934219,0.000000,"1 min loop (AI)"}; +item17[] = {"___min_loop__AI",4,218,975.237671,175.934219,1065.237793,225.934219,0.000000,"1 min loop (AI)"}; item18[] = {"Set_AI_Ownership",2,250,975.237732,250.921417,1065.237305,300.921417,0.000000,"Set AI Ownership"}; item19[] = {"",7,210,1016.540222,366.725281,1024.540283,374.725281,0.000000,""}; link0[] = {0,10}; @@ -44,231 +44,221 @@ link19[] = {16,0}; link20[] = {17,18}; link21[] = {18,19}; link22[] = {19,16}; -globals[] = {0.000000,0,0,0,0,640,480,2,454,6316128,1,432.812775,1219.813965,504.306030,-50.239235,799,563,1}; -window[] = {0,-1,-1,-1,-1,1045,285,1579,311,1,817}; +globals[] = {0.000000,0,0,0,0,640,480,2,454,6316128,1,432.812775,1219.813965,504.306030,-50.239235,799,589,1}; +window[] = {0,-1,-1,-1,-1,834,100,1394,100,1,817}; *//*%FSM*/ class FSM { - fsmName = "missions"; - class States + fsmName = "missions"; + class States + { + /*%FSM*/ + class INIT + { + name = "INIT"; + init = /*%FSM*/""/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class INITIALIZE { - /*%FSM*/ - class INIT - { - name = "INIT"; - itemno = 1; - init = /*%FSM*/""/*%FSM*/; - precondition = /*%FSM*/""/*%FSM*/; - class Links - { - /*%FSM*/ - class INITIALIZE - { - itemno = 12; - priority = 0.000000; - to="PREPARE"; - precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"!isnil ""bis_fnc_init"""/*%FSM*/; - action=/*%FSM*/""/*%FSM*/; - }; - /*%FSM*/ - }; - }; - /*%FSM*/ - /*%FSM*/ - class Waiting - { - name = "Waiting"; - itemno = 3; - init = /*%FSM*/"// Waiting for next task to proceed with."/*%FSM*/; - precondition = /*%FSM*/""/*%FSM*/; - class Links - { - /*%FSM*/ - class ___min_loop - { - itemno = 14; - priority = 3.000000; - to="Select_Mission"; - precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"((diag_tickTime - _selectMission) > 60)" \n - ""/*%FSM*/; - action=/*%FSM*/""/*%FSM*/; - }; - /*%FSM*/ - /*%FSM*/ - class ___min_loop_1 - { - itemno = 8; - priority = 2.000000; - to="Mission_Cleanup"; - precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"((diag_tickTime - _cleanupTime) > 300)"/*%FSM*/; - action=/*%FSM*/"_missionsMonitor = time;"/*%FSM*/; - }; - /*%FSM*/ - /*%FSM*/ - class __5_sec_loop_ - { - itemno = 5; - priority = 1.000000; - to="Check_Mission_Running"; - precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"((diag_tickTime - _missionsMonitor) > 15)"/*%FSM*/; - action=/*%FSM*/""/*%FSM*/; - }; - /*%FSM*/ - /*%FSM*/ - class ___min_loop__AI - { - itemno = 17; - priority = 0.000000; - to="Set_AI_Ownership"; - precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"((diag_tickTime - _aiLocality) > 60)"/*%FSM*/; - action=/*%FSM*/""/*%FSM*/; - }; - /*%FSM*/ - }; - }; - /*%FSM*/ - /*%FSM*/ - class Check_Mission_Running - { - name = "Check_Mission_Running"; - itemno = 6; - init = /*%FSM*/"//(format [""FSM CHECK :: calling DMS_fnc_MissionsMonitor""]) call DMS_fnc_DebugLog;" \n - "" \n - "_missionsMonitor = diag_tickTime;" \n - "call DMS_fnc_MissionsMonitor;"/*%FSM*/; - precondition = /*%FSM*/""/*%FSM*/; - class Links - { - /*%FSM*/ - class true - { - itemno = 2; - priority = 0.000000; - to="Waiting"; - precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"true"/*%FSM*/; - action=/*%FSM*/""/*%FSM*/; - }; - /*%FSM*/ - }; - }; - /*%FSM*/ - /*%FSM*/ - class Mission_Cleanup - { - name = "Mission_Cleanup"; - itemno = 11; - init = /*%FSM*/"//(format [""FSM CHECK :: calling DMS_fnc_CleanUpManager""]) call DMS_fnc_DebugLog;" \n - "" \n - "_cleanupTime = diag_tickTime;" \n - "call DMS_fnc_CleanUpManager;"/*%FSM*/; - precondition = /*%FSM*/""/*%FSM*/; - class Links - { - /*%FSM*/ - class true - { - itemno = 2; - priority = 0.000000; - to="Waiting"; - precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"true"/*%FSM*/; - action=/*%FSM*/""/*%FSM*/; - }; - /*%FSM*/ - }; - }; - /*%FSM*/ - /*%FSM*/ - class PREPARE - { - name = "PREPARE"; - itemno = 13; - init = /*%FSM*/"private [""_missionsMonitor"",""_cleanupTime"",""_selectMission""];" \n - "diag_log (""DMS :: Initializing FSM mission script"");" \n - "" \n - "_missionsMonitor = diag_tickTime;" \n - "_cleanupTime = diag_tickTime;" \n - "_selectMission = diag_tickTime;" \n - "_aiLocality = diag_tickTime;"/*%FSM*/; - precondition = /*%FSM*/""/*%FSM*/; - class Links - { - /*%FSM*/ - class true - { - itemno = 2; - priority = 0.000000; - to="Waiting"; - precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"true"/*%FSM*/; - action=/*%FSM*/""/*%FSM*/; - }; - /*%FSM*/ - }; - }; - /*%FSM*/ - /*%FSM*/ - class Select_Mission - { - name = "Select_Mission"; - itemno = 15; - init = /*%FSM*/"//(format [""FSM CHECK :: calling DMS_fnc_SelectMission""]) call DMS_fnc_DebugLog;" \n - "" \n - "_selectMission = diag_tickTime;" \n - "call DMS_fnc_SelectMission;"/*%FSM*/; - precondition = /*%FSM*/""/*%FSM*/; - class Links - { - /*%FSM*/ - class true - { - itemno = 2; - priority = 0.000000; - to="Waiting"; - precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"true"/*%FSM*/; - action=/*%FSM*/""/*%FSM*/; - }; - /*%FSM*/ - }; - }; - /*%FSM*/ - /*%FSM*/ - class Set_AI_Ownership - { - name = "Set_AI_Ownership"; - itemno = 18; - init = /*%FSM*/"//(format [""FSM CHECK :: calling DMS_fnc_AILocalityManager""]) call DMS_fnc_DebugLog;" \n - "" \n - "_aiLocality = diag_tickTime;" \n - "call DMS_fnc_AILocalityManager;"/*%FSM*/; - precondition = /*%FSM*/""/*%FSM*/; - class Links - { - /*%FSM*/ - class true - { - itemno = 2; - priority = 0.000000; - to="Waiting"; - precondition = /*%FSM*/""/*%FSM*/; - condition=/*%FSM*/"true"/*%FSM*/; - action=/*%FSM*/""/*%FSM*/; - }; - /*%FSM*/ - }; - }; - /*%FSM*/ + priority = 0.000000; + to="PREPARE"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"!isnil ""bis_fnc_init"""/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; }; - initState="INIT"; - finalStates[] = + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class Waiting + { + name = "Waiting"; + init = /*%FSM*/"// Waiting for next task to proceed with."/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class ___min_loop { + priority = 3.000000; + to="Select_Mission"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"((diag_tickTime - _selectMission) > 60)" \n + ""/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; }; + /*%FSM*/ + /*%FSM*/ + class ___min_loop_1 + { + priority = 2.000000; + to="Mission_Cleanup"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"((diag_tickTime - _cleanupTime) > 300)"/*%FSM*/; + action=/*%FSM*/"_missionsMonitor = time;"/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class __5_sec_loop_ + { + priority = 1.000000; + to="Check_Mission_Running"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"((diag_tickTime - _missionsMonitor) > 15)"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + /*%FSM*/ + class ___min_loop__AI + { + priority = 0.000000; + to="Set_AI_Ownership"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"((diag_tickTime - _aiLocality) > 60)"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class Check_Mission_Running + { + name = "Check_Mission_Running"; + init = /*%FSM*/"//(format [""FSM CHECK :: calling DMS_fnc_MissionsMonitor""]) call DMS_fnc_DebugLog;" \n + "" \n + "_missionsMonitor = diag_tickTime;" \n + "call DMS_fnc_MissionsMonitor;"/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class true + { + priority = 0.000000; + to="Waiting"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"true"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class Mission_Cleanup + { + name = "Mission_Cleanup"; + init = /*%FSM*/"//(format [""FSM CHECK :: calling DMS_fnc_CleanUpManager""]) call DMS_fnc_DebugLog;" \n + "" \n + "_cleanupTime = diag_tickTime;" \n + "call DMS_fnc_CleanUpManager;"/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class true + { + priority = 0.000000; + to="Waiting"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"true"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class PREPARE + { + name = "PREPARE"; + init = /*%FSM*/"private [""_missionsMonitor"",""_cleanupTime"",""_selectMission""];" \n + "diag_log (""DMS :: Initializing FSM mission script"");" \n + "" \n + "_missionsMonitor = diag_tickTime;" \n + "_cleanupTime = diag_tickTime;" \n + "_selectMission = diag_tickTime;" \n + "_aiLocality = diag_tickTime;"/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class true + { + priority = 0.000000; + to="Waiting"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"true"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class Select_Mission + { + name = "Select_Mission"; + init = /*%FSM*/"//(format [""FSM CHECK :: calling DMS_fnc_SelectMission""]) call DMS_fnc_DebugLog;" \n + "" \n + "_selectMission = diag_tickTime;" \n + "if (DMS_SpawnMissions_Scheduled) then" \n + "{" \n + " [] spawn DMS_fnc_SelectMission;" \n + "}" \n + "else" \n + "{" \n + " call DMS_fnc_SelectMission;" \n + "};"/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class true + { + priority = 0.000000; + to="Waiting"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"true"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + /*%FSM*/ + class Set_AI_Ownership + { + name = "Set_AI_Ownership"; + init = /*%FSM*/"//(format [""FSM CHECK :: calling DMS_fnc_AILocalityManager""]) call DMS_fnc_DebugLog;" \n + "" \n + "_aiLocality = diag_tickTime;" \n + "call DMS_fnc_AILocalityManager;"/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class true + { + priority = 0.000000; + to="Waiting"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"true"/*%FSM*/; + action=/*%FSM*/""/*%FSM*/; + }; + /*%FSM*/ + }; + }; + /*%FSM*/ + }; + initState="INIT"; + finalStates[] = + { + }; }; /*%FSM*/ \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/config.cpp b/@ExileServer/addons/a3_dms/config.cpp index 49aee45..d28c2e6 100644 --- a/@ExileServer/addons/a3_dms/config.cpp +++ b/@ExileServer/addons/a3_dms/config.cpp @@ -1,10 +1,10 @@ class CfgPatches { - class A3_dms + class a3_dms { units[] = {}; weapons[] = {}; - a3_DMS_version = 3.0; + a3_DMS_version = "March 31 2016 (TEST)"; requiredVersion = 1.36; requiredAddons[] = {"exile_client","exile_server_config"}; }; @@ -39,11 +39,13 @@ class CfgFunctions class DebugLog {}; class FillCrate {}; class FindSafePos {}; + class FindSafePos_InRange {}; class FindSuppressor {}; class GetAllUnits {}; + class GetEmptySeats {}; class GroupReinforcementsManager {}; //class HandleMissionEvents {}; - //class HeliParatroopers {}; + class HeliParatroopers_Monitor {}; //class HeliPatrol {}; class ImportFromM3E {}; class ImportFromM3E_Convert {}; @@ -72,11 +74,12 @@ class CfgFunctions class SpawnAISoldier {}; class SpawnAIStaticMG {}; class SpawnBanditMission {}; - class SpawnStaticMission {}; class SpawnCrate {}; + class SpawnHeliReinforcement {}; class SpawnMinefield {}; - class SpawnPersistentVehicle {}; class SpawnNonPersistentVehicle {}; + class SpawnPersistentVehicle {}; + class SpawnStaticMission {}; class TargetsKilled {}; }; }; diff --git a/@ExileServer/addons/a3_dms/config.sqf b/@ExileServer/addons/a3_dms/config.sqf index e442cc7..34e246b 100644 --- a/@ExileServer/addons/a3_dms/config.sqf +++ b/@ExileServer/addons/a3_dms/config.sqf @@ -16,18 +16,20 @@ DMS_DEBUG = false; DMS_Use_Map_Config = true; // Whether or not to use config overwrites specific to the map. /* - If you are using a map other than Altis, Bornholm, Esseker, or Tavi (Taviana) you should set this to false OR create a new file within the map_configs folder for the map so that you don't get a missing file error. + If you are using a map other than a map listed in the "map_configs" folder, you should set this to false OR create a new file within the map_configs folder for the map so that you don't get a missing file error. To share your map-specific config, please create a merge request on GitHub and/or leave a message on the DMS thread in the Exile forums. For any questions regarding map-specific configs, please leave a reply in the DMS thread on the Exile forums. */ DMS_Enable_RankChange = false; // Whether or not to use Rank Changes. /* - I am sharing this upgrade to all. If you utilize GR8 Humanity(fully compatible) or a custom version of a ranking system(simple variable changes), this will allow your players to score +/- for Bandit and Hero kills as well as a custom Survivor Faction added to DMS as well. You can still utilize the HERO / BANDIT / SURVIVOR respect and poptab settings for gameplay :) ENJOY! DONKEYPUNCH.INFO! + I am sharing this upgrade to all. If you utilize GR8 Humanity (fully compatible) or a custom version of a ranking system(simple variable changes), this will allow your players to score +/- for Bandit and Hero kills as well as a custom Survivor Faction added to DMS as well. You can still utilize the HERO / BANDIT / SURVIVOR respect and poptab settings for gameplay :) ENJOY! DONKEYPUNCH.INFO! */ DMS_Add_AIKill2DB = false; // Adds killstat for player in the database ;) +DMS_SpawnMissions_Scheduled = false; // Whether or not to spawn missions in a scheduled environment. Setting to true may help with lag when certain missions spawn. + /* Mission System Settings */ /*General settings for dynamic missions*/ DMS_DynamicMission = true; // Enable/disable dynamic mission system. @@ -266,27 +268,27 @@ DMS_Add_AIKill2DB = false; // Adds killstat for player in the database ;) DMS_Bandit_Vehicle_MoneyGain = 100; // The amount of Poptabs gained for killing a bandit vehicle crew member DMS_Bandit_Vehicle_RepGain = 25; // The amount of Respect gained for killing a bandit vehicle crew member DMS_Bandit_Vehicle_RankGain = 50; -/* DonkeyPunchDMS Custom Settings for Hero AI*/ +/* DonkeyPunchDMS Custom Settings for Hero AI*/ DMS_Hero_Soldier_MoneyGain = 100; // The amount of Poptabs gained for killing a hero soldier DMS_Hero_Soldier_RepGain = 20; // The amount of Respect gained for killing a hero soldier - DMS_Hero_Soldier_RankGain = -30; + DMS_Hero_Soldier_RankGain = -30; DMS_Hero_Static_MoneyGain = 120; // The amount of Poptabs gained for killing a hero static gunner - DMS_Hero_Static_RepGain = 30; // The amount of Respect gained for killing a hero static gunner + DMS_Hero_Static_RepGain = 30; // The amount of Respect gained for killing a hero static gunner DMS_Hero_Static_RankGain = -60; DMS_Hero_Vehicle_MoneyGain = 200; // The amount of Poptabs gained for killing a hero vehicle crew member DMS_Hero_Vehicle_RepGain = 50; // The amount of Respect gained for killing a hero vehicle crew member DMS_Hero_Vehicle_RankGain = -100; -/* DonkeyPunchDMS Custom Settings for Survivor AI*/ +/* DonkeyPunchDMS Custom Settings for Survivor AI*/ DMS_Survivor_Soldier_MoneyGain = -100; // The amount of Poptabs gained for killing a Survivor soldier DMS_Survivor_Soldier_RepGain = -100; // The amount of Respect gained for killing a Survivor soldier DMS_Survivor_Soldier_RankGain = -250; - DMS_Survivor_Static_MoneyGain = -100; // The amount of Poptabs gained for killing a Survivor static gunner + DMS_Survivor_Static_MoneyGain = -100; // The amount of Poptabs gained for killing a Survivor static gunner DMS_Survivor_Static_RepGain = -100; // The amount of Respect gained for killing a Survivor static gunner DMS_Survivor_Static_RankGain = -400; DMS_Survivor_Vehicle_MoneyGain = -500; // The amount of Poptabs gained for killing a Survivor vehicle crew member - DMS_Survivor_Vehicle_RepGain = -100; // The amount of Respect gained for killing a Survivor vehicle crew member + DMS_Survivor_Vehicle_RepGain = -100; // The amount of Respect gained for killing a Survivor vehicle crew member DMS_Survivor_Vehicle_RankGain = -600; - + DMS_AIKill_DistanceBonusMinDistance = 100; // Minimum distance from the player to the AI to apply the distance bonus. DMS_AIKill_DistanceBonusCoefficient = 0.05; // If the distance from the player to the killed unit is more than "DMS_AIKill_DistanceBonusMinDistance" meters then the player gets a respect bonus equivalent to the distance multiplied by this coefficient. For example, killing an AI from 400 meters will give 100 extra respect (when the coefficient is 0.25). Set to 0 to disable the bonus. This bonus will not be applied if there isn't a regular AI kill bonus. @@ -300,7 +302,7 @@ DMS_Add_AIKill2DB = false; // Adds killstat for player in the database ;) DMS_Bandit_Vehicle_RoadkillMoney = -10; // The amount of Poptabs gained/lost for running over a bandit vehicle crew member DMS_Bandit_Vehicle_RoadkillRep = -5; // The amount of Respect gained/lost for running over a bandit vehicle crew member DMS_Bandit_Vehicle_RoadkillRank = 50; -/* DonkeyPunchDMS Custom RoadKill Settings for Hero AI*/ +/* DonkeyPunchDMS Custom RoadKill Settings for Hero AI*/ DMS_Hero_Soldier_RoadkillMoney = 20; // The amount of Poptabs gained/lost for running over a hero soldier DMS_Hero_Soldier_RoadkillRep = 10; // The amount of Respect gained/lost for running over a hero soldier DMS_Hero_Soldier_RoadkillRank = -40; @@ -310,22 +312,22 @@ DMS_Add_AIKill2DB = false; // Adds killstat for player in the database ;) DMS_Hero_Vehicle_RoadkillMoney = 20; // The amount of Poptabs gained/lost for running over a hero vehicle crew member DMS_Hero_Vehicle_RoadkillRep = 10; // The amount of Respect gained/lost for running over a hero vehicle crew member DMS_Hero_Vehicle_RoadkillRank = -100; -/* DonkeyPunchDMS Custom Roadkill Settings for Survivor AI*/ +/* DonkeyPunchDMS Custom Roadkill Settings for Survivor AI*/ DMS_Survivor_Soldier_RoadkillMoney = -200; // The amount of Poptabs gained/lost for running over a Survivor soldier - DMS_Survivor_Soldier_RoadkillRep = -200; // The amount of Respect gained/lost for running over a Survivor soldier - DMS_Survivor_Soldier_RoadkillRank = -200; - DMS_Survivor_Static_RoadkillMoney = -200; // The amount of Poptabs gained/lost for running over a Survivor static gunner + DMS_Survivor_Soldier_RoadkillRep = -200; // The amount of Respect gained/lost for running over a Survivor soldier + DMS_Survivor_Soldier_RoadkillRank = -200; + DMS_Survivor_Static_RoadkillMoney = -200; // The amount of Poptabs gained/lost for running over a Survivor static gunner DMS_Survivor_Static_RoadkillRep = -200; // The amount of Respect gained/lost for running over a Survivor static gunner - DMS_Survivor_Static_RoadkillRank = -200; + DMS_Survivor_Static_RoadkillRank = -200; DMS_Survivor_Vehicle_RoadkillMoney = -500; // The amount of Poptabs gained/lost for running over a Survivor vehicle crew member - DMS_Survivor_Vehicle_RoadkillRep = -100; // The amount of Respect gained/lost for running over a Survivor vehicle crew member - DMS_Survivor_Vehicle_RoadkillRank = -100; + DMS_Survivor_Vehicle_RoadkillRep = -100; // The amount of Respect gained/lost for running over a Survivor vehicle crew member + DMS_Survivor_Vehicle_RoadkillRank = -100; DMS_banditSide = EAST; // The side (team) that AI Bandits will spawn on /* DonkeyPunchDMS Custom Side Factions */ DMS_heroSide = WEST; // The side (team) that AI Heros will spawn on - DMS_survivorSide = CIV; // The side (team) that AI Survivor will spawn on - + DMS_survivorSide = CIV; // The side (team) that AI Survivor will spawn on + DMS_clear_AI_body = false; // Clear AI body as soon as they die DMS_clear_AI_body_chance = 50; // Percentage chance that AI bodies will be cleared when they die DMS_ai_disable_ramming_damage = true; // Disables damage due to ramming into AI. !!!NOTE: THIS WILL NOT BE RELIABLE WITH "DMS_ai_offload_to_client"!!! @@ -357,10 +359,10 @@ DMS_Add_AIKill2DB = false; // Adds killstat for player in the database ;) DMS_ai_skill_randomDifficult = ["hardcore","hardcore","difficult","difficult","difficult"]; // 60% chance for "difficult", 40% chance for "hardcore" AI. DMS_ai_skill_randomEasy = ["moderate","moderate","easy","easy","easy"]; // 60% chance for "easy", 40% chance for "moderate" AI. DMS_ai_skill_randomIntermediate = ["difficult","difficult","moderate","moderate","moderate"]; // 60% chance for "moderate", 40% chance for "difficult" AI. - DMS_AI_WP_Radius_easy = 20; // Waypoint radius for "easy" AI - DMS_AI_WP_Radius_moderate = 30; // Waypoint radius for "moderate" AI - DMS_AI_WP_Radius_difficult = 50; // Waypoint radius for "difficult" AI - DMS_AI_WP_Radius_hardcore = 75; // Waypoint radius for "hardcore" AI + DMS_AI_WP_Radius_easy = 20; // Waypoint radius for "easy" AI. + DMS_AI_WP_Radius_moderate = 30; // Waypoint radius for "moderate" AI. + DMS_AI_WP_Radius_difficult = 50; // Waypoint radius for "difficult" AI. + DMS_AI_WP_Radius_hardcore = 75; // Waypoint radius for "hardcore" AI. DMS_AI_AimCoef_easy = 0.9; // "Custom Aim Coefficient" (weapon sway multiplier) for "easy" AI DMS_AI_AimCoef_moderate = 0.65; // "Custom Aim Coefficient" (weapon sway multiplier) for "moderate" AI DMS_AI_AimCoef_difficult = 0.4; // "Custom Aim Coefficient" (weapon sway multiplier) for "difficult" AI @@ -369,7 +371,10 @@ DMS_Add_AIKill2DB = false; // Adds killstat for player in the database ;) DMS_AI_EnableStamina_moderate = true; // Whether or not to keep the stamina system for "moderate" AI. DMS_AI_EnableStamina_difficult = false; // Whether or not to keep the stamina system for "difficult" AI. DMS_AI_EnableStamina_hardcore = false; // Whether or not to keep the stamina system for "hardcore" AI. - DMS_AI_WP_Radius_base = 5; // Waypoint radius for AI in bases + DMS_AI_WP_Radius_base = 5; // Waypoint radius for AI in bases. + DMS_AI_WP_Radius_heli = 500; // Waypoint radius for AI in helis. + + DMS_AI_destroyVehicleChance = 75; // Percent chance that an AI vehicle will be destroyed after the AI have been killed. Set to 100 for always, or 0 for never. DMS_AI_destroyStaticWeapon = true; // Whether or not to destroy static HMGs after AI death. DMS_AI_destroyStaticWeapon_chance = 95; // Percent chance that a static weapon will be destroyed (only applied if "DMS_AI_destroyStaticWeapon" is true) @@ -693,6 +698,11 @@ DMS_Add_AIKill2DB = false; // Adds killstat for player in the database ;) "launch_B_Titan_F" ]; + DMS_RHeli_Height = 500; // Altitude of the heli when flying to drop point. + DMS_RHeli_MinDistFromDrop = 500; // Minimum distance for the reinforcement heli to spawn from drop point. + DMS_RHeli_MaxDistFromDrop = 5000; // Maximum distance for the reinforcement heli to spawn from drop point. + DMS_RHeli_MinDistFromPlayers = 1000; // Minimum distance for the reinforcement heli to spawn from players. + /* AI Settings */ @@ -837,6 +847,7 @@ DMS_Add_AIKill2DB = false; // Adds killstat for player in the database ;) DMS_BoxItems = DMS_BoxSurvivalSupplies+DMS_BoxBuildingSupplies+DMS_BoxOptics; // Random "items" can spawn optics, survival supplies, or building supplies DMS_RareLoot = true; // Potential chance to spawn rare loot in any crate. + DMS_RareLootAmount = 1; // How many rare loot items to add. DMS_RareLootList = [ // List of rare loot to spawn "Exile_Item_SafeKit", "Exile_Item_CodeLock" @@ -891,6 +902,10 @@ DMS_Add_AIKill2DB = false; // Adds killstat for player in the database ;) "Exile_Chopper_Taru_Transport_Black" ]; + DMS_ReinforcementHelis = [ // List of helis that can spawn for AI paratrooper reinforcements. + //"B_Heli_Transport_01_camo_F" // Ghosthawk: You'll have to whitelist this in infistar if you want to use it. + ] + DMS_TransportHelis; + DMS_CarThievesVehicles = [ // List of vehicles that can spawn in the "car thieves" mission. By default, it's just "DMS_MilitaryVehicles" and "DMS_TransportTrucks". //"Exile_Car_Offroad_Armed_Guerilla01" ] + DMS_MilitaryVehicles + DMS_TransportTrucks; diff --git a/@ExileServer/addons/a3_dms/fn_DMS_postInit.sqf b/@ExileServer/addons/a3_dms/fn_DMS_postInit.sqf index bce84ad..f7b6db8 100644 --- a/@ExileServer/addons/a3_dms/fn_DMS_postInit.sqf +++ b/@ExileServer/addons/a3_dms/fn_DMS_postInit.sqf @@ -18,7 +18,7 @@ if (isNil "DMS_DynamicMission") exitWith { for "_i" from 0 to 99 do { - diag_log "DMS ERROR :: You have made an error in your DMS config.sqf! Cancelling DMS Launch."; + diag_log "DMS ERROR :: You have made an error in your DMS config.sqf! Please look for any script errors. Cancelling DMS Launch."; }; }; @@ -226,6 +226,10 @@ if (DMS_ShowDifficultyColorLegend) then } forEach DMS_StaticMissionsOnServerStart; +// Add heli paratroopers monitor to the thread system. +[5, DMS_fnc_HeliParatroopers_Monitor, [], true] call ExileServer_system_thread_addTask; + + diff --git a/@ExileServer/addons/a3_dms/fn_DMS_preInit.sqf b/@ExileServer/addons/a3_dms/fn_DMS_preInit.sqf index 6860258..685b346 100644 --- a/@ExileServer/addons/a3_dms/fn_DMS_preInit.sqf +++ b/@ExileServer/addons/a3_dms/fn_DMS_preInit.sqf @@ -7,7 +7,7 @@ DMS_HC_Object = objNull; DMS_CleanUpList = []; -DMS_Version = "February 19 2016"; +DMS_Version = getText (configFile >> "CfgPatches" >> "a3_dms" >> "a3_DMS_version"); //Load main config @@ -105,6 +105,9 @@ DMS_MaxSurfaceNormal = DMS_MinSurfaceNormal; DMS_AttemptsUntilThrottle = DMS_AttemptsUntilThrottle + 1; +DMS_HelisToClean = []; +DMS_HeliParatrooper_Arr = []; + // Initialize mission variables... call compileFinal preprocessFileLineNumbers "\x\addons\dms\missions\static_init.sqf"; diff --git a/@ExileServer/addons/a3_dms/missions/bandit/cardealer.sqf b/@ExileServer/addons/a3_dms/missions/bandit/cardealer.sqf index a625a4d..a0069c1 100644 --- a/@ExileServer/addons/a3_dms/missions/bandit/cardealer.sqf +++ b/@ExileServer/addons/a3_dms/missions/bandit/cardealer.sqf @@ -65,7 +65,7 @@ _crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; _rndDir = random 180; -_wreck = createVehicle ["Land_FuelStation_Build_F",[_pos,10+(random 5),_rndDir+90] call DMS_fnc_SelectOffsetPos,[], 0, "CAN_COLLIDE"]; +_wreck = createVehicle ["Land_FuelStation_Build_F",_pos getPos [10+(random 5),_rndDir+90],[], 0, "CAN_COLLIDE"]; _vehClass1 = "Exile_Car_SUV_Red"; @@ -90,12 +90,10 @@ if !(_extraParams isEqualTo []) then }; }; }; -_vehicle1 = [_vehClass1, [_pos,5+(random 3),_rndDir] call DMS_fnc_SelectOffsetPos] call DMS_fnc_SpawnNonPersistentVehicle; -//_vehicle1 setPosATL ([_pos,5+(random 3),_rndDir] call DMS_fnc_SelectOffsetPos); +_vehicle1 = [_vehClass1, _pos getPos [5+(random 3),_rndDir]] call DMS_fnc_SpawnNonPersistentVehicle; -_vehicle2 = [_vehClass2, [_pos,5+(random 3),_rndDir+180] call DMS_fnc_SelectOffsetPos] call DMS_fnc_SpawnNonPersistentVehicle; -//_vehicle2 setPosATL ([_pos,5+(random 3),_rndDir+180] call DMS_fnc_SelectOffsetPos); +_vehicle2 = [_vehClass2, _pos getPos [5+(random 3),_rndDir+180]] call DMS_fnc_SpawnNonPersistentVehicle; diff --git a/@ExileServer/addons/a3_dms/missions/static/saltflats.sqf b/@ExileServer/addons/a3_dms/missions/static/saltflats.sqf index 1c7ef8c..4029a49 100644 --- a/@ExileServer/addons/a3_dms/missions/static/saltflats.sqf +++ b/@ExileServer/addons/a3_dms/missions/static/saltflats.sqf @@ -105,7 +105,7 @@ _crate = [_crateClassname, _pos] call DMS_fnc_SpawnCrate; _veh = [ [ - [_pos,100,random 360] call DMS_fnc_SelectOffsetPos, + _pos getPos [_pos,100,random 360], _pos ], _group, diff --git a/@ExileServer/addons/a3_dms/scripts/fn_AddMissionToMonitor.sqf b/@ExileServer/addons/a3_dms/scripts/fn_AddMissionToMonitor.sqf index 5972989..920f0f6 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_AddMissionToMonitor.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_AddMissionToMonitor.sqf @@ -117,12 +117,15 @@ try throw format["_missionObjs |%1|",_missionObjs]; }; - _mines = []; - - if ((count _missionObjs)>3) then - { - _mines = _missionObjs param [3,[],[[]]]; - }; + _mines = + if ((count _missionObjs)>3) then + { + _missionObjs param [3,[],[[]]] + } + else + { + [] + }; // Don't spawn a minefield if there is one already defined in _missionObjs. if (DMS_SpawnMinefieldForEveryMission && {_mines isEqualTo []}) then diff --git a/@ExileServer/addons/a3_dms/scripts/fn_CreateMarker.sqf b/@ExileServer/addons/a3_dms/scripts/fn_CreateMarker.sqf index 0cafb0d..5f7627b 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_CreateMarker.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_CreateMarker.sqf @@ -15,7 +15,7 @@ _markerDot, _markerCircle ] - + */ @@ -87,7 +87,7 @@ if (_randomMarker) then { _dir = random 360; _dis = DMS_MarkerPosRandomRadius call DMS_fnc_SelectRandomVal; - _npos = [_pos,_dis,_dir] call DMS_fnc_SelectOffsetPos; + _npos = _pos getPos [_dis,_dir]; _circle setMarkerPos _npos; _dot setMarkerPos _npos; @@ -105,4 +105,4 @@ if (DMS_DEBUG) then }; -[_dot,_circle]; \ No newline at end of file +[_dot,_circle]; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_FillCrate.sqf b/@ExileServer/addons/a3_dms/scripts/fn_FillCrate.sqf index 2b27ec1..ff79760 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_FillCrate.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_FillCrate.sqf @@ -168,7 +168,7 @@ if ((_lootValues isEqualType []) && {!((_lootValues select 1) isEqualType {})}) // Add weapons + mags for "_i" from 1 to _wepCount do { - _weapon = _weps call BIS_fnc_selectRandom; + _weapon = selectRandom _weps; _ammo = _weapon call DMS_fnc_selectMagazine; if (_weapon isEqualType "") then { @@ -188,7 +188,7 @@ if ((_lootValues isEqualType []) && {!((_lootValues select 1) isEqualType {})}) // Add items for "_i" from 1 to _itemCount do { - _item = _items call BIS_fnc_selectRandom; + _item = selectRandom _items; if (_item isEqualType "") then { _item = [_item,1]; @@ -203,7 +203,7 @@ if ((_lootValues isEqualType []) && {!((_lootValues select 1) isEqualType {})}) // Add backpacks for "_i" from 1 to _backpackCount do { - _backpack = _backpacks call BIS_fnc_selectRandom; + _backpack = selectRandom _backpacks; if (_backpack isEqualType "") then { _backpack = [_backpack,1]; @@ -270,7 +270,7 @@ else }; -if(DMS_RareLoot && {count DMS_RareLootList>0}) then +if (DMS_RareLoot) then { _rareLootChance = if ((count _this)>2) then @@ -285,12 +285,15 @@ if(DMS_RareLoot && {count DMS_RareLootList>0}) then // (Maybe) Add rare loot if(random 100 < _rareLootChance) then { - _item = DMS_RareLootList call BIS_fnc_selectRandom; - if (_item isEqualType "") then + for "_i" from 1 to DMS_RareLootAmount do { - _item = [_item,1]; + _item = selectRandom DMS_RareLootList; + if (_item isEqualType "") then + { + _item = [_item,1]; + }; + _crate addItemCargoGlobal _item; }; - _crate addItemCargoGlobal _item; }; }; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_FindSafePos.sqf b/@ExileServer/addons/a3_dms/scripts/fn_FindSafePos.sqf index 7cab48b..31ae22c 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_FindSafePos.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_FindSafePos.sqf @@ -1,7 +1,7 @@ /* DMS_fnc_FindSafePos Created by eraser1 - + ALL PARAMETERS ARE OPTIONAL (as long as configs are properly defined). Excluding parameters will create some RPT spam, but it's not too much of an issue. @@ -109,6 +109,11 @@ while{!_isValidSpot} do }; _isValidSpot = [_pos, _waterNearLimit, _minSurfaceNormal, _spawnZoneNearLimit, _traderZoneNearLimit, _missionNearLimit, _playerNearLimit, _territoryNearLimit, _waterSpawn] call DMS_fnc_IsValidPosition; + + if (_attempts>5000) exitWith + { + diag_log format["DMS ERROR :: Number of attempts in DMS_fnc_findSafePos (%1) exceeded maximum number of attempts!",_attempts]; + }; }; _pos set [2,0]; @@ -120,4 +125,4 @@ if (DMS_DEBUG) then }; -_pos; \ No newline at end of file +_pos; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_FindSafePos_InRange.sqf b/@ExileServer/addons/a3_dms/scripts/fn_FindSafePos_InRange.sqf new file mode 100644 index 0000000..33dc92f --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_FindSafePos_InRange.sqf @@ -0,0 +1,74 @@ +/* + DMS_fnc_FindSafePos_InRange + Created by eraser1 + + Exactly the same as DMS_fnc_FindSafePos except it only searches in a specific area as opposed to the whole map (minus the constraints of minimum distance from borders). + + Usage: + [ + _centerPos, // ARRAY (position): 2D or 3D center position to search around. + _distanceMin, // SCALAR (distance): Minimum distance from the center position to search around. See note below for actual calculation of distance. + _distanceMax, // SCALAR (distance): Maximum distance from the center position to search around. NOTE: Due to the way this function works (because of efficiency) the practical maximum distance is actually distance*sqrt(2). Therefore, the distance parameter is not wholly accurate. + _posParameters // ARRAY: The parameters to determine the position you want. More detail below. + ] call DMS_fnc_FindSafePos_InRange; + + NOTE: I don't check to make sure "_distanceMax" is greater than "_distanceMin", so if you goof up, it's not on me. Also, if you set the values too close to each other, there's a good chance it's gonna result in performance issues and quite possibly no resulting position. + + "_posParameters" is simply passed to "DMS_fnc_FindSafePos". See the usage of that function for more detail: https://github.com/Defent/DMS_Exile/blob/master/%40ExileServer/addons/a3_dms/scripts/fn_FindSafePos.sqf + + Returns a position. +*/ + +private ["_centerPos", "_distance", "_posParameters", "_original_x", "_original_y", "_original_Blacklist", "_center_x", "_center_y", "_pos"]; + +if !(params +[ + ["_centerPos", 0, [[]], [2,3]], + ["_distanceMin", 0, [0]], + ["_distanceMax", 0, [0]], + ["_posParameters", 0, [[]]] +]) +exitWith +{ + diag_log format["DMS ERROR :: Calling DMS_fnc_FindSafePos_InRange with invalid parameters: %1",_this]; + [] +}; + +// Save the original values +_original_x = DMS_MinMax_X_Coords; +_original_y = DMS_MinMax_Y_Coords; +_original_Blacklist = DMS_findSafePosBlacklist; + +// Get the center values +_center_x = _centerPos select 0; +_center_y = _centerPos select 1; + +// Set the restrictions +DMS_MinMax_X_Coords = [_center_x - _distanceMax, _center_x + _distanceMax]; +DMS_MinMax_Y_Coords = [_center_y - _distanceMax, _center_y + _distanceMax]; + +DMS_findSafePosBlacklist = + if (_distanceMin>0) then + { + [ + [ + [_center_x - _distanceMin, _center_y - _distanceMin], + [_center_x + _distanceMin, _center_y + _distanceMin] + ] + ] + } + else + { + [] + }; + + +// NOW we get the position (hopefully) +_pos = _posParameters call DMS_fnc_findSafePos; + +// Reset the original values +DMS_MinMax_X_Coords = _original_x; +DMS_MinMax_Y_Coords = _original_y; +DMS_findSafePosBlacklist = _original_Blacklist; + +_pos diff --git a/@ExileServer/addons/a3_dms/scripts/fn_FindSuppressor.sqf b/@ExileServer/addons/a3_dms/scripts/fn_FindSuppressor.sqf index 1ee6a88..37d441c 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_FindSuppressor.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_FindSuppressor.sqf @@ -38,13 +38,13 @@ switch (true) do case ((_weaponName find "9 mm") > -1) : {_result = "muzzle_snds_L";}; - case ((_weaponName find ".338") > -1) : {_result = ["muzzle_snds_338_black","muzzle_snds_338_green","muzzle_snds_338_sand"] call BIS_fnc_selectRandom;}; + case ((_weaponName find ".338") > -1) : {_result = selectRandom ["muzzle_snds_338_black","muzzle_snds_338_green","muzzle_snds_338_sand"];}; - case ((_weaponName find "9.3 mm") > -1) : {_result = ["muzzle_snds_93mmg","muzzle_snds_93mmg_tan"] call BIS_fnc_selectRandom;}; + case ((_weaponName find "9.3 mm") > -1) : {_result = selectRandom ["muzzle_snds_93mmg","muzzle_snds_93mmg_tan"];}; }; // Zafir accepts no suppressors :( if ((_weapon find "Zafir")>-1) then {_result = "";}; -_result \ No newline at end of file +_result diff --git a/@ExileServer/addons/a3_dms/scripts/fn_GetAllUnits.sqf b/@ExileServer/addons/a3_dms/scripts/fn_GetAllUnits.sqf index f0ddf55..cbbfe6a 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_GetAllUnits.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_GetAllUnits.sqf @@ -39,28 +39,15 @@ _units = []; case "OBJECT": { - if (!(isNull _parameter) && {alive _parameter}) then - { - [_parameter] - } - else - { + [ + [_parameter], [] - } + ] select (alive _parameter); }; case "GROUP": { - if (!isNull _parameter) then - { - { - if (alive _x) then - { - _units pushBack _x; - }; - } forEach (units _parameter); - }; - [] + (units _parameter) select {alive _x}; }; default @@ -78,4 +65,4 @@ if (DMS_DEBUG) then }; -_units \ No newline at end of file +_units diff --git a/@ExileServer/addons/a3_dms/scripts/fn_GetEmptySeats.sqf b/@ExileServer/addons/a3_dms/scripts/fn_GetEmptySeats.sqf new file mode 100644 index 0000000..f1f00ce --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_GetEmptySeats.sqf @@ -0,0 +1,35 @@ +/* + DMS_fnc_GetEmptySeats + Created by eraser1 + + Usage: + _vehicle call DMS_fnc_GetEmptySeats; + or + [_vehicle] call DMS_fnc_GetEmptySeats; + + Returns a list of empty cargo seats in the form of [[unit,role,cargoIndex,turretPath,personTurret], ...]. + "unit" will always be objNull. + + See https://community.bistudio.com/wiki/fullCrew and https://community.bistudio.com/wiki/moveInCargo for more info. +*/ + +if !(params +[ + ["_vehicle",objNull,[objNull]] +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_GetEmptySeats with invalid parameter(s): %1",_this]; +}; + +(fullCrew [_vehicle, "", true]) select +{ + _x params + [ + "_unit", + "_role", + "_cargoIndex" + ]; + + isNull _unit +}; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_GroupReinforcementsManager.sqf b/@ExileServer/addons/a3_dms/scripts/fn_GroupReinforcementsManager.sqf index d03fe43..c7adfae 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_GroupReinforcementsManager.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_GroupReinforcementsManager.sqf @@ -92,6 +92,16 @@ ] NOTE: Every reinforcement vehicle counts as one unit given for monitor type "armed_vehicle" and "armed_vehicle_replace" + "heli_troopers": + _monitorParams = + [ + _AICount, // SCALAR: If the AI Group has fewer than "_AICount" living units, then the group will receive reinforcements. + _ejectFFVGunners, // BOOLEAN: Whether or not to eject the gunners that are FFV (firing from vehicle). + _remainAsGunship, // BOOLEAN: Whether or not the heli should remain in the area and function as a gunship or simply fly away and despawn. + _vehClass // (OPTIONAL) STRING: The classname of the vehicle to spawn. Use "random" to select a random vehicle from "DMS_ArmedVehicles". Default: "random" + ] + This reinforcement type will attempt to drop the AI off at the group leader's position. The heli will spawn in the air 500-5000 meters away from the leader's position and 1000 meters away from a player (default). + Returns whether or not reinforcement waves or units given exceeds/matches maximum wave or unit reinforcements. If true, then no more reinforcements will be spawned (so the passed info should be deleted from the available reinforcements list). */ @@ -371,7 +381,7 @@ if (!_reinforcementsDepleted && {(diag_tickTime-_lastUpdated)>_updateDelay}) the _veh = [ [ - if (_spawnLocations isEqualTo []) then {[_leaderPos,100+(random 200),random 360] call DMS_fnc_SelectOffsetPos} else {_spawnLocations call BIS_fnc_selectRandom}, + if (_spawnLocations isEqualTo []) then {_leaderPos getPos [100+(random 200),random 360]} else {selectRandom _spawnLocations}, _leaderPos ], _AIGroup, @@ -417,7 +427,7 @@ if (!_reinforcementsDepleted && {(diag_tickTime-_lastUpdated)>_updateDelay}) the _vehicle = [ [ - if (_spawnLocations isEqualTo []) then {[_leaderPos,100+(random 200),random 360] call DMS_fnc_SelectOffsetPos} else {_spawnLocations call BIS_fnc_selectRandom}, + if (_spawnLocations isEqualTo []) then {[_leaderPos,100+(random 200),random 360] call DMS_fnc_SelectOffsetPos} else {selectRandom _spawnLocations}, _leaderPos ], _AIGroup, @@ -488,6 +498,47 @@ if (!_reinforcementsDepleted && {(diag_tickTime-_lastUpdated)>_updateDelay}) the }; }; + case "heli_troopers": + { + if !(_monitorParams params + [ + ["_AICount",0,[0]], + ["_ejectFFVGunners",false,[false]], + ["_remainAsGunship",false,[false]] + ]) + exitWith + { + _reinforcementsDepleted = true; + diag_log format ["DMS ERROR :: Calling DMS_fnc_GroupReinforcementsManager with invalid _monitorParams: %1 | _monitorType: %2 | Setting _reinforcementsDepleted to true.",_monitorParams,_monitorType]; + }; + + if (_remainingUnits<_AICount) then + { + private["_heli"]; + + _heli = + [ + _AIGroup, + _class, + _difficulty, + _side, + getPosATL (leader _AIGroup), + _ejectFFVGunners, + _remainAsGunship + ] call DMS_fnc_SpawnHeliReinforcement; + + // Every vehicle counts as one unit given, so the number of units given is equivalent to number of waves given. + _reinforcementWavesGiven = _reinforcementWavesGiven + 1; + _reinforcementUnitsGiven = _reinforcementWavesGiven; + + + if (DMS_DEBUG) then + { + (format["GroupReinforcementsManager :: Group %1 received a ""%2"" vehicle (%3) as reinforcements.", _AIGroup, typeOf _heliClass, _heli]) call DMS_fnc_DebugLog; + }; + }; + }; + default { _reinforcementsDepleted = true; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_HeliParatroopers_Monitor.sqf b/@ExileServer/addons/a3_dms/scripts/fn_HeliParatroopers_Monitor.sqf new file mode 100644 index 0000000..f65eca6 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_HeliParatroopers_Monitor.sqf @@ -0,0 +1,166 @@ +/* + DMS_fnc_HeliParatroopers_Monitor + Created by eraser1 + + **********!!!!NOTE!!!!**********: THIS FUNCTION IS NOT FINAL, IT IS FOR TESTING PURPOSES ONLY! Changes are planned, and the function parameters will likely change. + In addition, this function is not behaving as expected. + + Used in Exile's thread system. + Every heli to be used as paratroopers has an index in "DMS_HeliParatrooper_Arr". + Every index has the values: + [ + _heli, // OBJECT: The heli that holds the units. + _dropPoint, // ARRAY (POSITION2D or 3D): The position (or object) to which the troopers need to be dropped near. + _ejectFFVGunners, // BOOLEAN: Whether or not to eject Fire-From-Vehicle (FFV) gunners. + _remainAsGunship // BOOLEAN: Whether or not to keep the heli flying around as a gunship. + ] + + This function also monitors "DMS_HelisToClean", which is a list that contains all helis to be deleted (after dropping paratroopers). +*/ + +{ + private _heli = _x; + + if (isNull _heli) then // Remove from list if the heli got deleted in some other way. + { + DMS_HelisToClean deleteAt _forEachIndex; + } + else + { // Then check to see if it's already destroyed somehow... + if !(alive _heli) exitWith + { + deleteVehicle _heli; + DMS_HelisToClean deleteAt _forEachIndex; + }; + + // Otherwise check if there's a player within 1km. + if !([_heli, 1000] call DMS_fnc_IsPlayerNearby) then + { + { + deleteVehicle _x; + } forEach ((crew _heli) + [_heli]); + + DMS_HelisToClean deleteAt _forEachIndex; + }; + }; +} forEach DMS_HelisToClean; + + +if (DMS_HeliParatrooper_Arr isEqualTo []) exitWith {}; + +{ + if !(_x params + [ + ["_heli", objNull, [objNull]], + ["_dropPoint", 0, [[], objNull], [2,3]], + ["_ejectFFVGunners", false, [false]], + ["_remainAsGunship", false, [false]] + ]) + exitWith + { + diag_log format["DMS ERROR :: Invalid index (%1) in DMS_HeliParatrooper_Arr: %2", _forEachIndex, DMS_HeliParatrooper_Arr deleteAt _forEachIndex]; + }; + + if (isNull _heli) exitWith + { + diag_log format["DMS ERROR :: Null _heli in DMS_HeliParatrooper_Arr (index %1). Parameters: %2", _forEachIndex, DMS_HeliParatrooper_Arr deleteAt _forEachIndex]; + }; + + if !(alive _heli) exitWith + { + if (DMS_DEBUG) then + { + format["HeliParatroopers_Monitor :: Heli died before it could reach drop point. Parameters: %1", DMS_HeliParatrooper_Arr deleteAt _forEachIndex] call DMS_fnc_DebugLog; + }; + }; + + if ((_heli distance2D _dropPoint)<200) then + { + private["_groupOwner","_AIGroup"]; + + _AIGroup = group _heli; + + // Grab and lock locality to control AI if necessary. + if !(local _AIGroup) then + { + _groupOwner = groupOwner _AIGroup; + _AIGroup setVariable ["DMS_LockLocality", true]; + _AIGroup setGroupOwner 2; + }; + + { + _x params + [ + "_unit", + "_role", + "_cargoIndex", + "_turretPath", + "_personTurret" + ]; + + if ((alive _unit) && {(_role isEqualTo "cargo") || {_ejectFFVGunners && {_personTurret}}}) then + { +/* + moveOut _unit; + private ["_parachute", "_dir"]; + _parachute = createVehicle ["Steerable_Parachute_F", (getPosATL _unit), [], 0, "CAN_COLLIDE"]; + _parachute setDir (getDir _unit); + _parachute enableSimulationGlobal true; + + _unit moveInDriver _parachute; +*/ + _unit action ["Eject", _heli]; + _unit setDestination [_dropPoint, "LEADER DIRECT", true]; + + _unit setVariable ["DMS_AISpawnPos", _dropPoint]; + }; + } forEach (fullCrew _heli); + + if (_remainAsGunship) then + { + [ + [driver _heli], + _AIGroup, + _dropPoint, + "heli", + "COMBAT" + ] call DMS_fnc_SetGroupBehavior_Separate; + + if (DMS_DEBUG) then + { + format["HeliParatroopers_Monitor :: Ordering heli (%1) to defend drop point position %2", _heli, _dropPoint] call DMS_fnc_DebugLog; + }; + } + else + { + private _pilot = driver _heli; + + [_pilot] joinSilent (createGroup (side _pilot)); + + _pilot setDestination [_dropPoint getPos [2 * worldSize, random 360], "VEHICLE PLANNED", true]; + {_pilot disableAI _x} forEach ["FSM", "AUTOCOMBAT", "CHECKVISIBLE", "TARGET", "AUTOTARGET"]; + + DMS_HelisToClean pushBack _heli; + + if (DMS_DEBUG) then + { + format["HeliParatroopers_Monitor :: Ordering heli (%1) to fly away from drop point position %2", _heli, _dropPoint] call DMS_fnc_DebugLog; + }; + }; + + DMS_HeliParatrooper_Arr deleteAt _forEachIndex; + + + // Revert and unlock locality if necessary. + if !(isNil "_groupOwner") then + { + _AIGroup setGroupOwner _groupOwner; + _AIGroup setVariable ["DMS_LockLocality", false]; + }; + } + else + { + (driver _heli) setDestination [_dropPoint, "VEHICLE PLANNED", true]; + _heli flyInHeight DMS_RHeli_Height; + }; +} forEach DMS_HeliParatrooper_Arr; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E.sqf b/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E.sqf index 8f2d6e2..76658ff 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E.sqf @@ -43,12 +43,12 @@ if ((count _pos)<3) then }; -_objs = []; + _export = call compile preprocessFileLineNumbers (format ["\x\addons\DMS\objects\%1.sqf",_file]); - +_objs = _export apply { // Create the object _obj = createVehicle [_x select 0, [0,0,0], [], 0, "CAN_COLLIDE"]; @@ -69,8 +69,8 @@ _export = call compile preprocessFileLineNumbers (format ["\x\addons\DMS\objects _obj setPos _objPos; }; - _objs pushBack _obj; -} foreach _export; + _obj; +}; -_objs \ No newline at end of file +_objs diff --git a/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_Convert.sqf b/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_Convert.sqf index cb99d67..f5e5b55 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_Convert.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_Convert.sqf @@ -44,12 +44,12 @@ if ((count _missionPos)<3) then }; -_objs = []; + _export = call compile preprocessFileLineNumbers (format ["\x\addons\DMS\objects\static\%1.sqf",_file]); - +_objs = _export apply { private ["_obj","_pos"]; _obj = createVehicle [_x select 0, [0,0,0], [], 0, "CAN_COLLIDE"]; @@ -65,10 +65,10 @@ _export = call compile preprocessFileLineNumbers (format ["\x\addons\DMS\objects _obj setPosATL _pos; _obj setVectorDirAndUp (_x select 3); }; - _objs pushBack _obj; -} foreach _export; + _obj; +}; [_objs,_missionPos] call DMS_fnc_setRelPositions; -_objs \ No newline at end of file +_objs diff --git a/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_Static.sqf b/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_Static.sqf index 8a7fb8e..902e65a 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_Static.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_Static.sqf @@ -48,15 +48,14 @@ if ((isNil "_export") || {!(_export isEqualType [])}) exitWith }; -_objs = []; - +_objs = _export apply { private ["_obj","_pos"]; _obj = createVehicle [_x select 0, [0,0,0], [], 0, "CAN_COLLIDE"]; _pos = _x select 1; _obj enableSimulationGlobal false; - + if (_x select 4) then { _obj setDir (_x select 2); @@ -68,8 +67,8 @@ _objs = []; _obj setVectorDirAndUp (_x select 3); }; - _objs pushBack _obj; -} foreach _export; + _obj; +}; -_objs \ No newline at end of file +_objs diff --git a/@ExileServer/addons/a3_dms/scripts/fn_IsNearWater.sqf b/@ExileServer/addons/a3_dms/scripts/fn_IsNearWater.sqf index 09f1f52..0e12290 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_IsNearWater.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_IsNearWater.sqf @@ -38,7 +38,7 @@ try for "_i" from 0 to 359 step 45 do { - if (surfaceIsWater ([_position,_radius,_i] call DMS_fnc_SelectOffsetPos)) then + if (surfaceIsWater (_position getPos [_radius,_i])) then { throw true; }; @@ -49,4 +49,4 @@ catch _result = true; }; -_result \ No newline at end of file +_result diff --git a/@ExileServer/addons/a3_dms/scripts/fn_IsValidPosition.sqf b/@ExileServer/addons/a3_dms/scripts/fn_IsValidPosition.sqf index d86a4f8..17c5c0d 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_IsValidPosition.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_IsValidPosition.sqf @@ -85,7 +85,7 @@ else private "_dir"; for "_dir" from 0 to 359 step 45 do { - if (((surfaceNormal ([_pos,5,_dir] call DMS_fnc_SelectOffsetPos)) select 2)<_minSurfaceNormal) then + if (((surfaceNormal (_pos getPos [5,_dir])) select 2)<_minSurfaceNormal) then { throw ("a nearby steep location"); }; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor_Dynamic.sqf b/@ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor_Dynamic.sqf index e4856aa..ba523a3 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor_Dynamic.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor_Dynamic.sqf @@ -82,8 +82,8 @@ private ["_pos", "_completionInfo", "_timeStarted", "_failTime", "_units", "_bui if (_completionInfo call DMS_fnc_MissionSuccessState) then { DMS_CleanUpList pushBack [_buildings,diag_tickTime,DMS_CompletedMissionCleanupTime]; - - if (_missionSide == "bandit") then + _missionTypes = ["bandit","hero","survivor"]; + if (_missionSide in _missionTypes) then { DMS_RunningBMissionCount = DMS_RunningBMissionCount - 1; } diff --git a/@ExileServer/addons/a3_dms/scripts/fn_OnKilled.sqf b/@ExileServer/addons/a3_dms/scripts/fn_OnKilled.sqf index 153df08..69f6dd3 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_OnKilled.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_OnKilled.sqf @@ -60,7 +60,7 @@ if (DMS_clear_AI_body && {(random 100) <= DMS_clear_AI_body_chance}) then if (DMS_ai_remove_launchers && {(_launcherVar != "") || {_launcher != ""}}) then { // Because arma is stupid sometimes - if (_launcher=="") then + if (_launcher isEqualTo "") then { _launcher = _launcherVar; @@ -103,7 +103,7 @@ _grpUnits = (units _grp) - [_unit]; // Give the AI a new leader if the killed unit was the leader if (!(_grpUnits isEqualTo []) && {(leader _grp) isEqualTo _unit}) then { - _grp selectLeader (_grpUnits call BIS_fnc_selectRandom); + _grp selectLeader (selectRandom _grpUnits); }; _av = _unit getVariable ["DMS_AssignedVeh",objNull]; @@ -114,9 +114,26 @@ if (!isNull _av) then // Destroy the vehicle and add it to cleanup if there are no active crew members of the vehicle. - if (_memCount<1) then + if (_memCount isEqualTo 0) then { - if ((DMS_AI_destroyStaticWeapon && {(random 100)= DMS_MinServerFPS && {(count allPlayers) >= DMS_MinPlayerCount}) if (DMS_DynamicMission && {_time - DMS_BMissionLastStart > DMS_BMissionDelay}) then { private "_mission"; - _mission = DMS_BanditMissionTypesArray call BIS_fnc_selectRandom; + _mission = selectRandom DMS_BanditMissionTypesArray; if (DMS_DEBUG) then { @@ -57,7 +57,7 @@ if (diag_fps >= DMS_MinServerFPS && {(count allPlayers) >= DMS_MinPlayerCount}) }; }; - _mission = _availableMissions call BIS_fnc_selectRandom; + _mission = selectRandom _availableMissions; if (DMS_DEBUG) then { diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SelectOffsetPos.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SelectOffsetPos.sqf index aa9154f..48e987f 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_SelectOffsetPos.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_SelectOffsetPos.sqf @@ -4,21 +4,23 @@ Usage: [ - _pos, - _distance, - _direction + _origin, // OBJECT, or POSITION (2D or 3D): Center from which the offset position will be calculated. + _distance, // SCALAR: Distance from the origin (meters) + _direction // SCALAR: Direction from the origin (degrees) ] call DMS_fnc_SelectOffsetPos; - Returns a new position offset from the provided position with the provided distance and direction. Position provided is at ground level in ATL + Returns a new position offset from the provided position with the provided distance and direction. Position provided is at ground level in AGL + + This function has been deprecated by the new functionality of the "getPos" command (https://community.bistudio.com/wiki/getPos). This function has been updated for efficiency and compatibility. */ -private ["_pos","_dis","_dir","_npos"]; +private ["_origin","_dis","_dir","_npos"]; if !(params [ - ["_pos","",[[]],[2,3]], + ["_origin","",[objNull,[]],[2,3]], ["_dis",0,[0]], ["_dir",0,[0]] ]) @@ -28,9 +30,12 @@ exitWith [0,0,0] }; -if ((count _pos) isEqualTo 2) then +/* +if ((count _origin) isEqualTo 2) then { - _pos set [2,0]; + _origin set [2,0]; }; +*/ -_pos vectorAdd [sin(_dir)*_dis,cos(_dir)*_dis,0] \ No newline at end of file +//_origin vectorAdd [sin(_dir)*_dis,cos(_dir)*_dis,0] <-- Old code +_origin getPos [_dis,_dir] diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SetGroupBehavior.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SetGroupBehavior.sqf index 203eaeb..4d33051 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_SetGroupBehavior.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_SetGroupBehavior.sqf @@ -64,22 +64,22 @@ _difficulty = { case "random": { - DMS_ai_skill_random call BIS_fnc_selectRandom; + selectRandom DMS_ai_skill_random; }; case "randomdifficult": { - DMS_ai_skill_randomDifficult call BIS_fnc_selectRandom; + selectRandom DMS_ai_skill_randomDifficult; }; case "randomeasy": { - DMS_ai_skill_randomEasy call BIS_fnc_selectRandom; + selectRandom DMS_ai_skill_randomEasy; }; case "randomintermediate": { - DMS_ai_skill_randomIntermediate call BIS_fnc_selectRandom; + selectRandom DMS_ai_skill_randomIntermediate; }; default @@ -100,12 +100,12 @@ for "_i" from count (waypoints _group) to 1 step -1 do // Add waypoints around the center position. for "_i" from 0 to 359 step 45 do { - _npos = [_pos,_radius,_i] call DMS_fnc_SelectOffsetPos; + _npos = _pos getPos [_radius,_i]; _wp = _group addWaypoint [_npos,5]; _wp setWaypointType "MOVE"; }; -_wp = _group addWaypoint [[_pos,_radius,0] call DMS_fnc_SelectOffsetPos,0]; +_wp = _group addWaypoint [_pos,0]; _wp setWaypointType "CYCLE"; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SetGroupBehavior_Separate.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SetGroupBehavior_Separate.sqf index ef3c64c..ec326e0 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_SetGroupBehavior_Separate.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_SetGroupBehavior_Separate.sqf @@ -40,7 +40,8 @@ _tmpGroup = createGroup (side _finalGroup); _units joinSilent _tmpGroup; -_return = [ +_return = +[ _tmpGroup, _pos, _difficulty, diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup.sqf index 85a428e..e1b564c 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup.sqf @@ -95,7 +95,7 @@ if ((!isNil "_launcherType") || {DMS_ai_use_launchers && {DMS_ai_launchers_per_g { _unit = _units select _i; - _launcher = ((missionNamespace getVariable [format ["DMS_AI_wep_launchers_%1",_launcherType],["launch_NLAW_F"]]) call BIS_fnc_selectRandom); + _launcher = (selectRandom (missionNamespace getVariable [format ["DMS_AI_wep_launchers_%1",_launcherType],["launch_NLAW_F"]])); removeBackpackGlobal _unit; _unit addBackpack "B_Carryall_mcamo"; @@ -104,7 +104,7 @@ if ((!isNil "_launcherType") || {DMS_ai_use_launchers && {DMS_ai_launchers_per_g [_unit, _launcher, DMS_AI_launcher_ammo_count,_rocket] call BIS_fnc_addWeapon; _unit setVariable ["DMS_AI_Launcher",_launcher]; - + if (DMS_DEBUG) then { (format["SpawnAIGroup :: Giving %1 a %2 launcher with %3 %4 rockets",_unit,_launcher,DMS_AI_launcher_ammo_count,_rocket]) call DMS_fnc_DebugLog; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup_MultiPos.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup_MultiPos.sqf index 0f04710..867d2f0 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup_MultiPos.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup_MultiPos.sqf @@ -1,7 +1,7 @@ /* DMS_fnc_SpawnAIGroup_MultiPos Created by eraser1 - + Spawns a group of AI with a given AI count at the provided list of location(s), with a given difficulty, class, and side. @@ -112,7 +112,7 @@ if ((!isNil "_launcherType") || {DMS_ai_use_launchers && {DMS_ai_launchers_per_g { _unit = _units select _i; - _launcher = ((missionNamespace getVariable [format ["DMS_AI_wep_launchers_%1",_launcherType],["launch_NLAW_F"]]) call BIS_fnc_selectRandom); + _launcher = (selectRandom (missionNamespace getVariable [format ["DMS_AI_wep_launchers_%1",_launcherType],["launch_NLAW_F"]])); removeBackpackGlobal _unit; _unit addBackpack "B_Carryall_mcamo"; @@ -121,7 +121,7 @@ if ((!isNil "_launcherType") || {DMS_ai_use_launchers && {DMS_ai_launchers_per_g [_unit, _launcher, DMS_AI_launcher_ammo_count,_rocket] call BIS_fnc_addWeapon; _unit setVariable ["DMS_AI_Launcher",_launcher]; - + if (DMS_DEBUG) then { (format["SpawnAIGroup_MultiPos :: Giving %1 a %2 launcher with %3 %4 rockets",_unit,_launcher,DMS_AI_launcher_ammo_count,_rocket]) call DMS_fnc_DebugLog; @@ -141,4 +141,4 @@ _group setFormation "WEDGE"; diag_log format ["DMS_SpawnAIGroup_MultiPos :: Spawned %1 AI using positions parameter: %2.",_count,_positions]; -_group \ No newline at end of file +_group diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAISoldier.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAISoldier.sqf index a5bc550..0df096a 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAISoldier.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAISoldier.sqf @@ -65,22 +65,22 @@ _difficulty = { case "random": { - DMS_ai_skill_random call BIS_fnc_selectRandom; + selectRandom DMS_ai_skill_random; }; case "randomdifficult": { - DMS_ai_skill_randomDifficult call BIS_fnc_selectRandom; + selectRandom DMS_ai_skill_randomDifficult; }; case "randomeasy": { - DMS_ai_skill_randomEasy call BIS_fnc_selectRandom; + selectRandom DMS_ai_skill_randomEasy; }; case "randomintermediate": { - DMS_ai_skill_randomIntermediate call BIS_fnc_selectRandom; + selectRandom DMS_ai_skill_randomIntermediate; }; default @@ -131,7 +131,7 @@ else { if (_class in DMS_ai_SupportedRandomClasses) then { - _class = (missionNamespace getVariable [format["DMS_%1_AI",_class], DMS_random_AI]) call BIS_fnc_selectRandom; + _class = selectRandom (missionNamespace getVariable [format["DMS_%1_AI",_class], DMS_random_AI]); }; }; @@ -165,10 +165,10 @@ if (!_useCustomGear) then // Clothes - _unit addHeadgear ((missionNamespace getVariable [format ["DMS_%1_helmets",_class],DMS_assault_helmets]) call BIS_fnc_selectRandom); - _unit forceAddUniform ((missionNamespace getVariable [format ["DMS_%1_clothes",_class],DMS_assault_clothes]) call BIS_fnc_selectRandom); - _unit addVest ((missionNamespace getVariable [format ["DMS_%1_vests",_class],DMS_assault_vests]) call BIS_fnc_selectRandom); - _unit addBackpack ((missionNamespace getVariable [format ["DMS_%1_backpacks",_class],DMS_assault_backpacks]) call BIS_fnc_selectRandom); + _unit addHeadgear (selectRandom (missionNamespace getVariable [format ["DMS_%1_helmets",_class],DMS_assault_helmets])); + _unit forceAddUniform (selectRandom (missionNamespace getVariable [format ["DMS_%1_clothes",_class],DMS_assault_clothes])); + _unit addVest (selectRandom (missionNamespace getVariable [format ["DMS_%1_vests",_class],DMS_assault_vests])); + _unit addBackpackGlobal (selectRandom (missionNamespace getVariable [format ["DMS_%1_backpacks",_class],DMS_assault_backpacks])); // Make AI effective at night _nighttime = (sunOrMoon != 1); @@ -179,24 +179,24 @@ if (!_useCustomGear) then if (!_unarmed) then { - _weapon = (missionNamespace getVariable [format ["DMS_%1_weps",_class],DMS_assault_weps]) call BIS_fnc_selectRandom; + _weapon = selectRandom (missionNamespace getVariable [format ["DMS_%1_weps",_class],DMS_assault_weps]); [_unit, _weapon, 6 + floor(random 3)] call BIS_fnc_addWeapon; _unit selectWeapon _weapon; if((random 100) <= (missionNamespace getVariable [format["DMS_%1_optic_chance",_class],0])) then { - _unit addPrimaryWeaponItem ((missionNamespace getVariable [format ["DMS_%1_optics",_class],DMS_assault_optics]) call BIS_fnc_selectRandom); + _unit addPrimaryWeaponItem (selectRandom (missionNamespace getVariable [format ["DMS_%1_optics",_class],DMS_assault_optics])); }; if (_nighttime && {(random 100) <= DMS_ai_nighttime_accessory_chance}) then { - _unit addPrimaryWeaponItem (["acc_pointer_IR","acc_flashlight"] call BIS_fnc_selectRandom); + _unit addPrimaryWeaponItem (selectRandom ["acc_pointer_IR","acc_flashlight"]); }; if((random 100) <= (missionNamespace getVariable [format["DMS_%1_bipod_chance",_class],0])) then { - _unit addPrimaryWeaponItem (DMS_ai_BipodList call BIS_fnc_selectRandom); + _unit addPrimaryWeaponItem (selectRandom DMS_ai_BipodList); }; if((random 100) <= (missionNamespace getVariable [format["DMS_%1_suppressor_chance",_class],0])) then @@ -222,7 +222,7 @@ if (!_useCustomGear) then _pistols = missionNamespace getVariable [format ["DMS_%1_pistols",_class],[]]; if !(_pistols isEqualTo []) then { - _pistol = _pistols call BIS_fnc_selectRandom; + _pistol = selectRandom _pistols; [_unit, _pistol, 2 + floor(random 2)] call BIS_fnc_addWeapon; }; @@ -275,7 +275,7 @@ else if !(_backpack isEqualTo "") then { - _unit addBackpack _backpack; + _unit addBackpackGlobal _backpack; }; if !(_launcher isEqualTo "") then @@ -374,16 +374,24 @@ _unit setCustomAimCoef (missionNamespace getVariable [format["DMS_AI_AimCoef_%1" _unit enableStamina (missionNamespace getVariable [format["DMS_AI_EnableStamina_%1",_difficulty], true]); -_unit setVariable ["DMS_AISpawnTime", time]; -_unit setVariable ["DMS_AI_Side", _side]; -_unit setVariable ["DMS_AI_Type", _type]; - if (_type=="Soldier") then { _unit setVariable ["DMS_AISpawnPos",_pos]; _unit setVariable ["DMS_LastAIDistanceCheck",time]; }; +// Just use "Soldier" type for everything else. +if (_type == "Paratroopers") then +{ + _type = "Soldier"; + _unit addBackpackGlobal "B_Parachute"; +}; + +_unit setVariable ["DMS_AISpawnTime", time]; +_unit setVariable ["DMS_AI_Side", _side]; +_unit setVariable ["DMS_AI_Type", _type]; + + if (DMS_DEBUG) then { (format ["SpawnAISoldier :: Spawned a %1 %2 %6 AI at %3 with %4 difficulty to group %5",_class,_side,_pos,_difficulty,_group,_type]) call DMS_fnc_DebugLog; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIStaticMG.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIStaticMG.sqf index 2e00631..1c9674d 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIStaticMG.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIStaticMG.sqf @@ -52,9 +52,9 @@ _guns = []; _MGClass = _MGClassInput; if (_MGClass == "random") then { - _MGClass = DMS_static_weapons call BIS_fnc_selectRandom; + _MGClass = selectRandom DMS_static_weapons; }; - + _gun = createVehicle [_MGClass, [0,0,0], [], 0, "CAN_COLLIDE"]; _gun setDir (random 360); _gun setPosATL _pos; @@ -66,7 +66,7 @@ _guns = []; _guns pushBack _gun; _unit = [_group,_pos,_class,_difficulty,_side,"Static"] call DMS_fnc_SpawnAISoldier; - + _unit moveInGunner _gun; reload _unit; _unit setVariable ["DMS_AssignedVeh",_gun]; @@ -83,4 +83,4 @@ if (DMS_DEBUG) then (format ["SpawnAIStaticMG :: Created %1 static AI with parameters: %2",count _positions,_this]) call DMS_fnc_DebugLog; }; -_guns \ No newline at end of file +_guns diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIVehicle.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIVehicle.sqf index e9583aa..d214987 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIVehicle.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIVehicle.sqf @@ -6,7 +6,7 @@ [ [ _spawnPos, // The position at which the AI vehicle will spawn - _gotoPos // (OPTIONAL) The position to which the AI vehicle will drive to. If it isn't defined, _spawnPos is used + _gotoPos // (OPTIONAL) The position to which the AI vehicle will drive to. If it isn't defined, _spawnPos is used. <--- THIS IS NOT USED. I'm not sure why I included this. ], _group, // Group to which the AI units belongs to _class, // Class: "random","assault","MG","sniper" or "unarmed" @@ -18,7 +18,7 @@ Returns the spawned vehicle. */ -private ["_OK", "_positions", "_veh", "_spawnPos", "_gotoPos", "_vehClass", "_driver", "_gunner", "_group", "_class", "_difficulty", "_side", "_crewCount"]; +private ["_OK", "_positions", "_veh", "_spawnPos", "_vehClass", "_driver", "_gunner", "_group", "_class", "_difficulty", "_side", "_crewCount"]; if !(params @@ -45,24 +45,25 @@ exitWith diag_log format ["DMS ERROR :: Calling DMS_fnc_SpawnAIVehicle with invalid _positions parameters: %1",_positions]; }; -_gotoPos = if ((count _positions)>1) then {_positions param [1,_spawnPos,[[]],[2,3]]} else {_spawnPos}; - -_vehClass = "random"; -if ((count _this)>5) then -{ - _vehClass = param [5,"random",[""]]; -}; +_vehClass = + if ((count _this)>5) then + { + param [5,"random",[""]] + } + else + { + "random" + }; if (_vehClass == "random") then { - _vehClass = DMS_ArmedVehicles call BIS_fnc_selectRandom; + _vehClass = selectRandom DMS_ArmedVehicles; }; _veh = createVehicle [_vehClass, _spawnPos, [], 0, "NONE"]; _veh setFuel 1; _veh engineOn true; -_veh setDir (random 360); _veh lock 2; _group addVehicle _veh; @@ -73,7 +74,7 @@ _driver setVariable ["DMS_AssignedVeh",_veh]; _crewCount = { - _unit = [_group,_spawnPos,_class,_difficulty,_side,"Vehicle"] call DMS_fnc_SpawnAISoldier; + private _unit = [_group,_spawnPos,_class,_difficulty,_side,"Vehicle"] call DMS_fnc_SpawnAISoldier; _unit moveInTurret [_veh, _x]; _unit setVariable ["DMS_AssignedVeh",_veh]; true @@ -82,7 +83,7 @@ _crewCount = if (DMS_DEBUG) then { - (format ["SpawnAIVehicle :: Created a %1 armed vehicle (%2) with %7 crew members at %3 going to %4 with %5 difficulty to group %6.",_side,_vehClass,_spawnPos,_gotoPos,_difficulty,_group,_crewCount+1]) call DMS_fnc_DebugLog; + (format ["SpawnAIVehicle :: Created a %1 armed vehicle (%2) with %3 crew members at %4 with %5 difficulty to group %6.",_side,_vehClass,_crewCount+1,_spawnPos,_difficulty,_group]) call DMS_fnc_DebugLog; }; _veh diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnBanditMission.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnBanditMission.sqf index 9978d7a..1857976 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_SpawnBanditMission.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnBanditMission.sqf @@ -21,7 +21,7 @@ _mission = missionNamespace getVariable format [ "DMS_Mission_%1", - _this param [0, DMS_BanditMissionTypesArray call BIS_fnc_selectRandom, [""]] + _this param [0,selectRandom DMS_BanditMissionTypesArray, [""]] ] ] param [0, "no",[{}]]; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnHeliReinforcement.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnHeliReinforcement.sqf new file mode 100644 index 0000000..7f04694 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnHeliReinforcement.sqf @@ -0,0 +1,170 @@ +/* + DMS_fnc_SpawnHeliReinforcement + Created by eraser1 + + **********!!!!NOTE!!!!**********: THIS FUNCTION IS NOT FINAL, IT IS FOR TESTING PURPOSES ONLY! Changes are planned, and the function parameters will likely change. + + This function will create a heli/aircraft within "DMS_RHeli_MinDistFromDrop" to "DMS_RHeli_MaxDistFromDrop" meters and drop units at "_dropPoint". + + Usage: + [ + _AIGroup, // GROUP: The group to which the heli will be assigned. + _class, // STRING: The class of AI to spawn in the heli. + _difficulty, // STRING: The difficulty of the AI to spawn in the heli. + _side, // STRING: The "side" that the AI are on. + _dropPoint, // OBJECT or ARRAY (Position2D or 3D): The location to drop the reinforcements at. + _ejectFFVGunners, // BOOLEAN: Whether or not to eject Fire-From-Vehicle (FFV) gunners. + _remainAsGunship, // BOOLEAN: Whether or not to keep the heli flying around as a gunship. + _heliClass, // STRING (OPTIONAL): The classname of the heli to spawn. + _spawnPos // ARRAY (OPTIONAL - Position2D or 3D): The position for the heli to spawn at. + ] call DMS_fnc_SpawnHeliReinforcement; + + Returns the index of the paratrooper info in "DMS_HeliParatrooper_Arr", -1 on error. +*/ + +private ["_heliClass", "_groupOwner", "_spawnPos", "_heli", "_pilot", "_units", "_crewCount", "_paratrooperCount", "_unit", "_cargoIndex"]; + + +if !(params +[ + ["_AIGroup", 0, [grpNull]], + ["_class", 0, [""]], + ["_difficulty", 0, [""]], + ["_side", 0, [""]], + ["_dropPoint", 0, [[],objNull], [2,3]], + ["_ejectFFVGunners", 0, [false]], + ["_remainAsGunship", 0, [false]] +]) +exitWith +{ + diag_log format["DMS ERROR :: Calling DMS_fnc_SpawnHeliReinforcement with invalid parameters: %1",_this]; + -1 +}; + +if (isNull _AIGroup) exitWith +{ + diag_log format["DMS ERROR :: Calling DMS_fnc_SpawnHeliReinforcement with null ""_AIGroup""! _this: %1 ",_this]; + -1 +}; + +_heliClass = if ((count _this)>7) then {_this param [7, "", [""]]} else {selectRandom DMS_ReinforcementHelis}; + +// Make the AI group local to add passengers. +if !(local _AIGroup) then +{ + _groupOwner = groupOwner _AIGroup; + _AIGroup setGroupOwner 2; +}; + +// Get the spawn position for the heli +_spawnPos = + if ((count _this)>8) then + { + _this param [8, "", [[]], [2,3]] + } + else + { + [ + _dropPoint, + DMS_RHeli_MinDistFromDrop, + DMS_RHeli_MaxDistFromDrop, + [ + 0, + 0, + 0, + 0, + 0, + 0, + DMS_RHeli_MinDistFromPlayers, + true, + false + ] + ] call DMS_fnc_FindSafePos_InRange + }; +_spawnPos set [2,DMS_RHeli_Height]; + + + +// Spawn the heli +_heli = createVehicle [_heliClass, _spawnPos, [], 0, "FLY"]; +_heli setFuel 1; +_heli engineOn true; +_heli lock 2; + +_AIGroup addVehicle _heli; + + +// Spawn the AI paratroopers +_units = []; +_paratrooperCount = 0; +_crewCount = +{ + _x params + [ + "_unit", + "_role", + "_cargoIndex", + "_turretPath", + "_personTurret" + ]; + + switch (_role) do + { + case "driver": + { + _unit = [_AIGroup,_spawnPos,_class,_difficulty,_side,"Vehicle"] call DMS_fnc_SpawnAISoldier; + _unit moveInDriver _heli; + _unit setVariable ["DMS_AssignedVeh",_heli]; + _pilot = _unit; + }; + + case "commander"; + case "gunner"; + case "turret": + { + if (_ejectFFVGunners && {_personTurret}) then + { + _unit = [_AIGroup,_spawnPos,_class,_difficulty,_side,"Paratroopers"] call DMS_fnc_SpawnAISoldier; + _paratrooperCount = _paratrooperCount + 1; + } + else + { + _unit = [_AIGroup,_spawnPos,_class,_difficulty,_side,"Vehicle"] call DMS_fnc_SpawnAISoldier; + _unit setVariable ["DMS_AssignedVeh",_heli]; + }; + _unit moveInTurret [_heli, _x]; + }; + + case "cargo": + { + _unit = [_AIGroup,_spawnPos,_class,_difficulty,_side,"Paratroopers"] call DMS_fnc_SpawnAISoldier; + _unit moveInCargo [_heli, _cargoIndex]; + _paratrooperCount = _paratrooperCount + 1; + }; + }; + _units pushBack _unit; + + true +} count (fullCrew [_heli, "", true]); + + +// Set the heli pilot's behavior. +_pilot setDestination [_dropPoint, "VEHICLE PLANNED", true]; +_heli flyInHeight DMS_RHeli_Height; + + +_units joinSilent _AIGroup; + +// Reset ownership if needed. +if !(isNil "_groupOwner") then +{ + _AIGroup setGroupOwner _groupOwner; +}; + +if (DMS_DEBUG) then +{ + (format ["SpawnHeliReinforcement :: Created a %1 heli (%2) with %3 crew members at %4 with %5 difficulty to group %6, going to %7. Units: %8",_side,_heliClass,_crewCount+1,_spawnPos,_difficulty,_AIGroup,_dropPoint,_units]) call DMS_fnc_DebugLog; +}; + +// Add the necessary information to the monitor. +DMS_HeliParatrooper_Arr pushBack [_heli, _dropPoint, _ejectFFVGunners, _remainAsGunship]; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnMinefield.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnMinefield.sqf index c710efc..02c1ecc 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_SpawnMinefield.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnMinefield.sqf @@ -1,7 +1,7 @@ /* DMS_fnc_SpawnMinefield Created by eraser1 - + Usage: [ _centerPos, // ARRAY: Position to spawn the minefield around @@ -66,7 +66,7 @@ if (DMS_SpawnMinesAroundMissions) then { private ["_minePos", "_mine"]; - _minePos = [_centerPos,random _radius,random 360] call DMS_fnc_SelectOffsetPos; + _minePos = _centerPos getPos [random _radius,random 360]; _mine = createMine ["ATMine", [0,0,0], [], 0]; // Fixes players shooting the mine and causing premature 'splosions @@ -92,7 +92,7 @@ if (DMS_SpawnMinesAroundMissions) then { _sign = createVehicle ["Land_Sign_Mines_F", [0,0,0], [], 0, "CAN_COLLIDE"]; _sign setDir (180+_i); - _sign setPosATL ([_centerPos, _radius+2, _randDirOffset+_i] call DMS_fnc_SelectOffsetPos); + _sign setPosATL (_centerPos getPos [_radius+2, _randDirOffset+_i]); _sign setVectorUp [0,0,1]; // _mines array is for only cleanup atm, so just add them to the list @@ -108,4 +108,4 @@ if (DMS_SpawnMinesAroundMissions) then -_mines \ No newline at end of file +_mines diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnStaticMission.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnStaticMission.sqf index 46c8083..ef6bf75 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_SpawnStaticMission.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnStaticMission.sqf @@ -17,7 +17,7 @@ private ["_missionType", "_mission", "_parameters", "_return"]; -_missionType = param [0, DMS_StaticMissionTypesArray call BIS_fnc_selectRandom, [""]]; +_missionType = param [0, selectRandom DMS_StaticMissionTypesArray, [""]]; _mission = [ diff --git a/@ExileServer/addons/a3_dms/scripts/fn_TargetsKilled.sqf b/@ExileServer/addons/a3_dms/scripts/fn_TargetsKilled.sqf index 957d036..b213acc 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_TargetsKilled.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_TargetsKilled.sqf @@ -28,9 +28,9 @@ try _lastDistanceCheckTime = _x getVariable ["DMS_LastAIDistanceCheck",time]; _pos = getPosWorld _x; - _spawnPos = _x getVariable ["DMS_AISpawnPos",_pos]; + _spawnPos = _x getVariable ["DMS_AISpawnPos",0]; - if ((DMS_MaxAIDistance>0) && {((time - _lastDistanceCheckTime)>DMS_AIDistanceCheckFrequency) && {(_pos distance2D _spawnPos)>DMS_MaxAIDistance}}) then + if ((DMS_MaxAIDistance>0) && {!(_spawnPos isEqualTo 0)} && {((time - _lastDistanceCheckTime)>DMS_AIDistanceCheckFrequency) && {(_pos distance2D _spawnPos)>DMS_MaxAIDistance}}) then { _x setDamage 1; diag_log format ["Killed a runaway unit! |%1| was more than %2m away from its spawn position %3!",_x,DMS_MaxAIDistance,_spawnPos]; diff --git a/README.md b/README.md index 70dc9b9..fd909a2 100644 --- a/README.md +++ b/README.md @@ -112,12 +112,12 @@ ___ - [shaworth](https://github.com/shaworth) and [KawaiiPotato](https://github.com/KawaiiPotato) for making the README all nice and pretty :) - [maca134](http://maca134.co.uk/portfolio/m3editor-arma-3-map-editor/) for M3Editor Stuff - [Darth Rogue from SOA](http://soldiersofanarchy.net/) for the awesome base for the first DMS static mission :D -- [William from Refugees of the Fallen](http://refugeesofthefallen.enjin.com/) for the amazing slums static mission base and ideas :) +- [William from Refugees of the Fallen](http://rtfgaming.com/) for the amazing slums static mission base and ideas :) - [DONKEYPUNCH](https://github.com/donkeypunchepoch) for everything on the [February 17th 2016 commit](https://github.com/Defent/DMS_Exile#february-17-2016-600-pm-cst-america) ;) - Everbody's feedback on [the DMS thread on exile forums](http://www.exilemod.com/topic/61-dms-defents-mission-system/?do=findComment&comment=242) #### Testers/Reporters: -- [William from Refugees of the Fallen](http://refugeesofthefallen.enjin.com/) +- [William from Refugees of the Fallen](http://rtfgaming.com/) - [JamieKG from Eternal Gamer](http://eternal-gamer.com/) - [Valthos from The Altis Project](https://www.thealtisproject.co.uk/) - [Flowrider from Optimum Gaming](http://www.optimum-multigaming.com/) @@ -151,6 +151,54 @@ ___ ___ # Changelog: +### Test Branch: +#### List Of new Config values: + + DMS_SpawnMissions_Scheduled + DMS_AI_WP_Radius_heli + DMS_AI_WP_Radius_heli + DMS_RHeli_Height + DMS_RHeli_MinDistFromDrop + DMS_RHeli_MaxDistFromDrop + DMS_RHeli_MinDistFromPlayers + DMS_RareLootAmount + DMS_ReinforcementHelis + + +#### March 31, 2016 (6:00 PM CST-America): +* You can now use "setVariable" to define individually on an AI vehicle its "DMS_DestructionChance". EG: ```_vehicle setVariable ["DMS_DestructionChance",100];``` to always destroy a vehicle when its crew is dead. +* "DMS_DestructionChance" values are defaulted to "DMS_AI_destroyStaticWeapon_chance" or "DMS_AI_destroyVehicleChance" for static or regular vehicles, respectively. +* Optimization + code cleanup for "DMS_fnc_SpawnHeliReinforcement". + +#### March 25, 2016 (6:00 PM CST-America): +* **NEW CONFIG VALUES:** + + DMS_AI_WP_Radius_heli + DMS_AI_WP_Radius_heli + DMS_RHeli_Height + DMS_RHeli_MinDistFromDrop + DMS_RHeli_MaxDistFromDrop + DMS_RHeli_MinDistFromPlayers + DMS_RareLootAmount + DMS_ReinforcementHelis +* DMS Version is set in the "config.cpp", and grabbed in pre-init. +* You can now define how much rare loot to spawn. +* Limit # of attempts in "DMS_fnc_FindSafePos" to 5000. +* New function: DMS_fnc_FindSafePos_InRange; Uses "DMS_fnc_FindSafePos" and edits some variables to return a "safe" position within a certain area. +* New function: DMS_fnc_GetEmptySeats; Returns all empty seats in a vehicle. Not used by DMS, I thought I needed it and I realized I didn't afterwards. +* New function: DMS_fnc_HeliParatroopers_Monitor; Monitors helis/aircraft spawned for paratroopers. **NOT YET COMPLETE** +* New function: DMS_fnc_SpawnHeliReinforcement; Spawns a heli/aircraft with paratroopers for reinforcement. **NOT YET COMPLETE** +* New group reinforcement type: "heli_troopers". Changes most likely to come. +* You can now choose whether or not to destroy or simply unlock a used AI vehicle (with a random percentage chance). +* Slight optimizations here and there (more to come). + +#### March 1, 2016 (12:30 AM CST-America): +* Initial Test Branch commit +* **NEW CONFIG VALUE:** DMS_SpawnMissions_Scheduled +* Several optimizations (mostly due to the new scripting commands introduced in 1.56) +* You can now spawn missions in scheduled environment. + + #### February 19, 2016 (5:45 PM CST-America): * Fixed a minor typo with a variable (part of the new Humanity support by DonkeyPunch). @@ -310,7 +358,7 @@ ___ * 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/) + * Credit for the base goes to [William from Refugees of the Fallen](http://rtfgaming.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.