From 2216fb1dd26e6286ab5febc0b23a39a7a0fe5a48 Mon Sep 17 00:00:00 2001 From: Zepheris Date: Thu, 1 Mar 2018 21:22:37 -0700 Subject: [PATCH] Found that a3_occupation_exile was the cause of the server issues. --- @ExileServer/addons/a3_dms/$PBOPREFIX$ | 1 + @ExileServer/addons/a3_dms/$PREFIX$ | 1 + @ExileServer/addons/a3_dms/FSM/missions.fsm | 306 ++++ @ExileServer/addons/a3_dms/PboPrefix.txt | 1 + @ExileServer/addons/a3_dms/config.cpp | 95 ++ @ExileServer/addons/a3_dms/config.sqf | 1303 +++++++++++++++++ .../addons/a3_dms/fn_DMS_postInit.sqf | 260 ++++ @ExileServer/addons/a3_dms/fn_DMS_preInit.sqf | 146 ++ .../a3_dms/map_configs/altis_config.sqf | 37 + .../a3_dms/map_configs/bornholm_config.sqf | 25 + .../a3_dms/map_configs/chernarus_config.sqf | 11 + .../map_configs/chernarus_isles_config.sqf | 11 + .../map_configs/chernarus_summer_config.sqf | 11 + .../map_configs/chernarus_winter_config.sqf | 11 + .../map_configs/chernarusredux_config.sqf | 12 + .../a3_dms/map_configs/esseker_config.sqf | 15 + .../a3_dms/map_configs/kerama_config.sqf | 24 + .../a3_dms/map_configs/malden_config.sqf | 10 + .../a3_dms/map_configs/namalsk_config.sqf | 30 + .../addons/a3_dms/map_configs/napf_config.sqf | 11 + .../a3_dms/map_configs/panthera3_config.sqf | 26 + .../a3_dms/map_configs/tanoa_config.sqf | 22 + .../addons/a3_dms/map_configs/tavi_config.sqf | 28 + .../a3_dms/map_configs/taviana_config.sqf | 28 + .../addons/a3_dms/missions/bandit/bandits.sqf | 236 +++ .../addons/a3_dms/missions/bandit/bauhaus.sqf | 224 +++ .../a3_dms/missions/bandit/beertransport.sqf | 212 +++ .../missions/bandit/behindenemylines.sqf | 208 +++ .../a3_dms/missions/bandit/blackhawkdown.sqf | 209 +++ .../a3_dms/missions/bandit/cardealer.sqf | 248 ++++ .../a3_dms/missions/bandit/construction.sqf | 238 +++ .../missions/bandit/donthasslethehoff.sqf | 260 ++++ .../a3_dms/missions/bandit/foodtransport.sqf | 216 +++ .../a3_dms/missions/bandit/guntransport.sqf | 209 +++ .../a3_dms/missions/bandit/humanitarian.sqf | 211 +++ .../a3_dms/missions/bandit/lost_battalion.sqf | 206 +++ .../addons/a3_dms/missions/bandit/medical.sqf | 226 +++ .../a3_dms/missions/bandit/mercbase.sqf | 234 +++ .../a3_dms/missions/bandit/mercenaries.sqf | 203 +++ .../missions/bandit/nedbandit1_mission.sqf | 316 ++++ .../missions/bandit/nedbtrader_mission.sqf | 296 ++++ .../missions/bandit/nedbuilding1_mission.sqf | 258 ++++ .../a3_dms/missions/bandit/nedcar_mission.sqf | 286 ++++ .../bandit/nedcashbandits_mission.sqf | 300 ++++ .../bandit/neddrinkstransport_mission.sqf | 215 +++ .../missions/bandit/nedguns1_mission.sqf | 257 ++++ .../missions/bandit/nedhatchback_mission.sqf | 283 ++++ .../missions/bandit/nedhuey_mission.sqf | 264 ++++ .../missions/bandit/nedhunter_mission.sqf | 251 ++++ .../missions/bandit/nedifrit_mission.sqf | 251 ++++ .../missions/bandit/nedlittlebird_mission.sqf | 270 ++++ .../missions/bandit/nedmedical1_mission.sqf | 258 ++++ .../missions/bandit/nedoffroad_mission.sqf | 272 ++++ .../missions/bandit/nedresearch_mission.sqf | 258 ++++ .../missions/bandit/nedsnipercamp_mission.sqf | 279 ++++ .../missions/bandit/nedstrider_mission.sqf | 252 ++++ .../missions/bandit/nedural_mission.sqf | 260 ++++ .../a3_dms/missions/bandit/roguenavyseals.sqf | 207 +++ .../addons/a3_dms/missions/bandit/thieves.sqf | 229 +++ .../addons/a3_dms/missions/bandit/walmart.sqf | 208 +++ .../addons/a3_dms/missions/mission_init.sqf | 38 + .../a3_dms/missions/static/occupation.sqf | 495 +++++++ .../a3_dms/missions/static/saltflats.sqf | 288 ++++ .../addons/a3_dms/missions/static/slums.sqf | 253 ++++ .../missions/static/underwater_stash.sqf | 318 ++++ .../addons/a3_dms/missions/static_init.sqf | 37 + @ExileServer/addons/a3_dms/objects/base1.sqf | 22 + .../a3_dms/objects/nedbuild1_objects.sqf | 14 + .../a3_dms/objects/nedguns1_objects.sqf | 14 + .../addons/a3_dms/objects/nedmed1_objects.sqf | 14 + .../a3_dms/objects/nedresearch_objects.sqf | 7 + .../a3_dms/objects/nedsnipercamp_objects.sqf | 12 + .../a3_dms/objects/nedtrader_objects.sqf | 10 + .../a3_dms/objects/static/base1STATIC.sqf | 27 + .../a3_dms/objects/static/saltflatsbase.sqf | 693 +++++++++ .../a3_dms/objects/static/slums_objects.sqf | 146 ++ .../a3_dms/scripts/fn_AILocalityManager.sqf | 54 + .../a3_dms/scripts/fn_AddMissionToMonitor.sqf | 212 +++ .../scripts/fn_AddMissionToMonitor_Static.sqf | 215 +++ .../addons/a3_dms/scripts/fn_AddWeapon.sqf | 54 + .../scripts/fn_BroadcastMissionStatus.sqf | 146 ++ .../addons/a3_dms/scripts/fn_CalcPos.sqf | 47 + .../addons/a3_dms/scripts/fn_CleanUp.sqf | 93 ++ .../a3_dms/scripts/fn_CleanUpManager.sqf | 51 + .../addons/a3_dms/scripts/fn_CreateMarker.sqf | 133 ++ .../addons/a3_dms/scripts/fn_DebugLog.sqf | 23 + .../addons/a3_dms/scripts/fn_FillCrate.sqf | 319 ++++ .../addons/a3_dms/scripts/fn_FindSafePos.sqf | 116 ++ .../a3_dms/scripts/fn_FindSafePos_InRange.sqf | 75 + .../a3_dms/scripts/fn_FindSuppressor.sqf | 20 + .../a3_dms/scripts/fn_FreezeManager.sqf | 98 ++ .../addons/a3_dms/scripts/fn_FreezeToggle.sqf | 40 + .../addons/a3_dms/scripts/fn_GetAllUnits.sqf | 64 + .../addons/a3_dms/scripts/fn_GetCenter.sqf | 43 + .../a3_dms/scripts/fn_GetEmptySeats.sqf | 35 + .../scripts/fn_GroupReinforcementsManager.sqf | 637 ++++++++ .../scripts/fn_HeliParatroopers_Monitor.sqf | 162 ++ .../a3_dms/scripts/fn_ImportFromM3E.sqf | 75 + .../a3_dms/scripts/fn_ImportFromM3E_3DEN.sqf | 61 + .../scripts/fn_ImportFromM3E_3DEN_Convert.sqf | 66 + .../scripts/fn_ImportFromM3E_3DEN_Static.sqf | 58 + .../scripts/fn_ImportFromM3E_Convert.sqf | 76 + .../scripts/fn_ImportFromM3E_Static.sqf | 68 + .../addons/a3_dms/scripts/fn_IsNearWater.sqf | 47 + .../a3_dms/scripts/fn_IsPlayerNearby.sqf | 55 + .../a3_dms/scripts/fn_IsPosBlacklisted.sqf | 73 + .../a3_dms/scripts/fn_IsValidPosition.sqf | 146 ++ .../a3_dms/scripts/fn_MissionParams.sqf | 144 ++ .../a3_dms/scripts/fn_MissionSuccessState.sqf | 95 ++ .../a3_dms/scripts/fn_MissionsMonitor.sqf | 17 + .../scripts/fn_MissionsMonitor_Dynamic.sqf | 321 ++++ .../scripts/fn_MissionsMonitor_Static.sqf | 331 +++++ .../addons/a3_dms/scripts/fn_OnKilled.sqf | 370 +++++ .../a3_dms/scripts/fn_PlayerAwardOnAIKill.sqf | 198 +++ .../a3_dms/scripts/fn_RemoveMarkers.sqf | 62 + .../a3_dms/scripts/fn_SelectMagazine.sqf | 19 + .../a3_dms/scripts/fn_SelectMission.sqf | 122 ++ .../a3_dms/scripts/fn_SelectOffsetPos.sqf | 38 + .../a3_dms/scripts/fn_SelectRandomVal.sqf | 25 + .../a3_dms/scripts/fn_SetAILocality.sqf | 76 + .../a3_dms/scripts/fn_SetGroupBehavior.sqf | 109 ++ .../scripts/fn_SetGroupBehavior_Separate.sqf | 55 + .../a3_dms/scripts/fn_SetRelPositions.sqf | 42 + .../addons/a3_dms/scripts/fn_SpawnAIGroup.sqf | 128 ++ .../scripts/fn_SpawnAIGroup_MultiPos.sqf | 151 ++ .../a3_dms/scripts/fn_SpawnAISoldier.sqf | 518 +++++++ .../a3_dms/scripts/fn_SpawnAIStaticMG.sqf | 87 ++ .../a3_dms/scripts/fn_SpawnAIVehicle.sqf | 104 ++ .../a3_dms/scripts/fn_SpawnBanditMission.sqf | 45 + .../addons/a3_dms/scripts/fn_SpawnCrate.sqf | 63 + .../scripts/fn_SpawnHeliReinforcement.sqf | 172 +++ .../a3_dms/scripts/fn_SpawnMinefield.sqf | 110 ++ .../scripts/fn_SpawnNonPersistentVehicle.sqf | 97 ++ .../scripts/fn_SpawnPersistentVehicle.sqf | 113 ++ .../a3_dms/scripts/fn_SpawnStaticMission.sqf | 79 + .../addons/a3_dms/scripts/fn_SubArr.sqf | 54 + .../a3_dms/scripts/fn_TargetsKilled.sqf | 51 + @ExileServer/addons/a3_exile_occupation.pbo | Bin 242044 -> 242017 bytes .../addons/a3_exile_occupation/config.sqf | 100 +- .../scripts/extras/processReporter.sqf | 4 +- .../scripts/occupationVehicle.sqf | 1 - .../scripts/startOccupation.sqf | 14 +- @ExileServer/addons/exile_server_config.pbo | Bin 262005 -> 262005 bytes 143 files changed, 20842 insertions(+), 58 deletions(-) create mode 100644 @ExileServer/addons/a3_dms/$PBOPREFIX$ create mode 100644 @ExileServer/addons/a3_dms/$PREFIX$ create mode 100644 @ExileServer/addons/a3_dms/FSM/missions.fsm create mode 100644 @ExileServer/addons/a3_dms/PboPrefix.txt create mode 100644 @ExileServer/addons/a3_dms/config.cpp create mode 100644 @ExileServer/addons/a3_dms/config.sqf create mode 100644 @ExileServer/addons/a3_dms/fn_DMS_postInit.sqf create mode 100644 @ExileServer/addons/a3_dms/fn_DMS_preInit.sqf create mode 100644 @ExileServer/addons/a3_dms/map_configs/altis_config.sqf create mode 100644 @ExileServer/addons/a3_dms/map_configs/bornholm_config.sqf create mode 100644 @ExileServer/addons/a3_dms/map_configs/chernarus_config.sqf create mode 100644 @ExileServer/addons/a3_dms/map_configs/chernarus_isles_config.sqf create mode 100644 @ExileServer/addons/a3_dms/map_configs/chernarus_summer_config.sqf create mode 100644 @ExileServer/addons/a3_dms/map_configs/chernarus_winter_config.sqf create mode 100644 @ExileServer/addons/a3_dms/map_configs/chernarusredux_config.sqf create mode 100644 @ExileServer/addons/a3_dms/map_configs/esseker_config.sqf create mode 100644 @ExileServer/addons/a3_dms/map_configs/kerama_config.sqf create mode 100644 @ExileServer/addons/a3_dms/map_configs/malden_config.sqf create mode 100644 @ExileServer/addons/a3_dms/map_configs/namalsk_config.sqf create mode 100644 @ExileServer/addons/a3_dms/map_configs/napf_config.sqf create mode 100644 @ExileServer/addons/a3_dms/map_configs/panthera3_config.sqf create mode 100644 @ExileServer/addons/a3_dms/map_configs/tanoa_config.sqf create mode 100644 @ExileServer/addons/a3_dms/map_configs/tavi_config.sqf create mode 100644 @ExileServer/addons/a3_dms/map_configs/taviana_config.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/bandits.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/bauhaus.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/beertransport.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/behindenemylines.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/blackhawkdown.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/cardealer.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/construction.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/donthasslethehoff.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/foodtransport.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/guntransport.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/humanitarian.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/lost_battalion.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/medical.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/mercbase.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/mercenaries.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/nedbandit1_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/nedbtrader_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/nedbuilding1_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/nedcar_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/nedcashbandits_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/neddrinkstransport_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/nedguns1_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/nedhatchback_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/nedhuey_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/nedhunter_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/nedifrit_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/nedlittlebird_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/nedmedical1_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/nedoffroad_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/nedresearch_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/nedsnipercamp_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/nedstrider_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/nedural_mission.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/roguenavyseals.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/thieves.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/bandit/walmart.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/mission_init.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/static/occupation.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/static/saltflats.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/static/slums.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/static/underwater_stash.sqf create mode 100644 @ExileServer/addons/a3_dms/missions/static_init.sqf create mode 100644 @ExileServer/addons/a3_dms/objects/base1.sqf create mode 100644 @ExileServer/addons/a3_dms/objects/nedbuild1_objects.sqf create mode 100644 @ExileServer/addons/a3_dms/objects/nedguns1_objects.sqf create mode 100644 @ExileServer/addons/a3_dms/objects/nedmed1_objects.sqf create mode 100644 @ExileServer/addons/a3_dms/objects/nedresearch_objects.sqf create mode 100644 @ExileServer/addons/a3_dms/objects/nedsnipercamp_objects.sqf create mode 100644 @ExileServer/addons/a3_dms/objects/nedtrader_objects.sqf create mode 100644 @ExileServer/addons/a3_dms/objects/static/base1STATIC.sqf create mode 100644 @ExileServer/addons/a3_dms/objects/static/saltflatsbase.sqf create mode 100644 @ExileServer/addons/a3_dms/objects/static/slums_objects.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_AILocalityManager.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_AddMissionToMonitor.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_AddMissionToMonitor_Static.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_AddWeapon.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_BroadcastMissionStatus.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_CalcPos.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_CleanUp.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_CleanUpManager.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_CreateMarker.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_DebugLog.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_FillCrate.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_FindSafePos.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_FindSafePos_InRange.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_FindSuppressor.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_FreezeManager.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_FreezeToggle.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_GetAllUnits.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_GetCenter.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_GetEmptySeats.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_GroupReinforcementsManager.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_HeliParatroopers_Monitor.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_3DEN.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_3DEN_Convert.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_3DEN_Static.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_Convert.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_Static.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_IsNearWater.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_IsPlayerNearby.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_IsPosBlacklisted.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_IsValidPosition.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_MissionParams.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_MissionSuccessState.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor_Dynamic.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor_Static.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_OnKilled.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_PlayerAwardOnAIKill.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_RemoveMarkers.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SelectMagazine.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SelectMission.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SelectOffsetPos.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SelectRandomVal.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SetAILocality.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SetGroupBehavior.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SetGroupBehavior_Separate.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SetRelPositions.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup_MultiPos.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SpawnAISoldier.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SpawnAIStaticMG.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SpawnAIVehicle.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SpawnBanditMission.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SpawnCrate.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SpawnHeliReinforcement.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SpawnMinefield.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SpawnNonPersistentVehicle.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SpawnPersistentVehicle.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SpawnStaticMission.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_SubArr.sqf create mode 100644 @ExileServer/addons/a3_dms/scripts/fn_TargetsKilled.sqf diff --git a/@ExileServer/addons/a3_dms/$PBOPREFIX$ b/@ExileServer/addons/a3_dms/$PBOPREFIX$ new file mode 100644 index 0000000..493cf09 --- /dev/null +++ b/@ExileServer/addons/a3_dms/$PBOPREFIX$ @@ -0,0 +1 @@ +x\addons\DMS \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/$PREFIX$ b/@ExileServer/addons/a3_dms/$PREFIX$ new file mode 100644 index 0000000..493cf09 --- /dev/null +++ b/@ExileServer/addons/a3_dms/$PREFIX$ @@ -0,0 +1 @@ +x\addons\DMS \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/FSM/missions.fsm b/@ExileServer/addons/a3_dms/FSM/missions.fsm new file mode 100644 index 0000000..f4b5484 --- /dev/null +++ b/@ExileServer/addons/a3_dms/FSM/missions.fsm @@ -0,0 +1,306 @@ +/*%FSM*/ +/*%FSM*/ +/* +item0[] = {"",7,210,743.923157,366.553040,751.923157,374.553040,0.000000,""}; +item1[] = {"INIT",0,250,499.929565,-106.207787,589.929565,-56.207787,0.000000,"INIT"}; +item2[] = {"true",8,218,758.881348,3.975540,858.881348,53.975540,0.000000,"true"}; +item3[] = {"Waiting",2,250,758.881226,84.582077,858.881226,134.582092,0.000000,"Waiting"}; +item4[] = {"",7,210,518.910339,366.553040,526.910339,374.553040,0.000000,""}; +item5[] = {"__5_sec_loop_",4,218,547.923096,174.999939,647.923096,224.999939,1.000000,"15 sec loop" \n ""}; +item6[] = {"Check_Mission_Running",2,250,547.923035,248.598328,647.923035,298.598328,0.000000,"Check Mission" \n "Running" \n "Status"}; +item7[] = {"",7,210,518.897522,321.700806,526.897522,329.700806,0.000000,""}; +item8[] = {"___min_loop_1",4,218,702.828857,170.094177,792.828857,220.094177,2.000000,"5 min loop"}; +item9[] = {"",7,210,518.897522,24.975555,526.897522,32.975555,0.000000,""}; +item10[] = {"",7,210,593.923096,366.553040,601.923096,374.553040,0.000000,""}; +item11[] = {"Mission_Cleanup",2,250,697.923035,248.598328,797.923035,298.598328,0.000000,"Mission Cleanup"}; +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"}; +item16[] = {"",7,210,880.582092,366.639160,888.582092,374.639160,0.000000,""}; +item17[] = {"___min_loop__AI",4,218,954.751831,174.416748,1044.750732,224.416748,0.000000,"1 min loop (AI)"}; +item18[] = {"Set_AI_Ownership",2,250,953.993164,247.127747,1043.991455,297.127747,0.000000,"Set AI Ownership"}; +item19[] = {"",7,210,995.295715,366.725281,1003.295776,374.725281,0.000000,""}; +item20[] = {"Freeze_Loop",4,218,1067.345947,174.190506,1157.346191,224.190506,0.000000,"Freeze Loop"}; +item21[] = {"Freeze_Manager",2,250,1067.652466,248.645218,1157.652100,298.645233,0.000000,"Freeze Manager"}; +item22[] = {"",7,210,1108.954956,366.725311,1116.955078,374.725311,0.000000,""}; +link0[] = {0,10}; +link1[] = {1,12}; +link2[] = {2,3}; +link3[] = {3,5}; +link4[] = {3,8}; +link5[] = {3,14}; +link6[] = {3,17}; +link7[] = {3,20}; +link8[] = {4,7}; +link9[] = {5,6}; +link10[] = {6,10}; +link11[] = {7,9}; +link12[] = {8,11}; +link13[] = {9,2}; +link14[] = {10,4}; +link15[] = {11,0}; +link16[] = {12,13}; +link17[] = {13,2}; +link18[] = {14,15}; +link19[] = {15,16}; +link20[] = {16,0}; +link21[] = {17,18}; +link22[] = {18,19}; +link23[] = {19,16}; +link24[] = {20,21}; +link25[] = {21,22}; +link26[] = {22,19}; +globals[] = {0.000000,0,0,0,0,640,480,2,457,6316128,1,382.327179,1353.613037,520.585144,-195.419098,799,589,1}; +window[] = {0,-1,-1,-32000,-32030,859,125,1419,125,1,817}; +*//*%FSM*/ +class FSM +{ + fsmName = "missions"; + class States + { + /*%FSM*/ + class INIT + { + name = "INIT"; + init = /*%FSM*/""/*%FSM*/; + precondition = /*%FSM*/""/*%FSM*/; + class Links + { + /*%FSM*/ + class INITIALIZE + { + 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"; + 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 Freeze_Loop + { + priority = 0.000000; + to="Freeze_Manager"; + precondition = /*%FSM*/""/*%FSM*/; + condition=/*%FSM*/"((diag_tickTime - _freeze) > DMS_ai_freezeCheckingDelay)"/*%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 = 0;" \n + "_cleanupTime = 0;" \n + "_selectMission = 0;" \n + "_aiLocality = 0;" \n + "_freeze = 0;"/*%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*/ + /*%FSM*/ + class Freeze_Manager + { + name = "Freeze_Manager"; + init = /*%FSM*/"//(format [""FSM CHECK :: calling DMS_fnc_AILocalityManager""]) call DMS_fnc_DebugLog;" \n + "" \n + "_freeze = diag_tickTime;" \n + "call DMS_fnc_FreezeManager;"/*%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/PboPrefix.txt b/@ExileServer/addons/a3_dms/PboPrefix.txt new file mode 100644 index 0000000..493cf09 --- /dev/null +++ b/@ExileServer/addons/a3_dms/PboPrefix.txt @@ -0,0 +1 @@ +x\addons\DMS \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/config.cpp b/@ExileServer/addons/a3_dms/config.cpp new file mode 100644 index 0000000..cad366c --- /dev/null +++ b/@ExileServer/addons/a3_dms/config.cpp @@ -0,0 +1,95 @@ +class CfgPatches +{ + class a3_dms + { + units[] = {}; + weapons[] = {}; + a3_DMS_version = "September 7, 2017"; + requiredVersion = 1.68; + requiredAddons[] = {"exile_client","exile_server_config"}; + }; +}; +class CfgFunctions +{ + class DMS + { + class main + { + file = "\x\addons\dms"; + class DMS_preInit + { + preInit = 1; + }; + class DMS_postInit + { + postInit = 1; + }; + }; + class compiles + { + file = "\x\addons\dms\scripts"; + class AddMissionToMonitor {}; + class AddMissionToMonitor_Static {}; + class AddWeapon {}; + class AILocalityManager {}; + class BroadcastMissionStatus {}; + class CalcPos {}; + class CleanUp {}; + class CleanUpManager {}; + class CreateMarker {}; + class DebugLog {}; + class FillCrate {}; + class FindSafePos {}; + class FindSafePos_InRange {}; + class FindSuppressor {}; + class FreezeManager {}; + class FreezeToggle {}; + class GetAllUnits {}; + class GetCenter {}; + class GetEmptySeats {}; + class GroupReinforcementsManager {}; + //class HandleMissionEvents {}; + class HeliParatroopers_Monitor {}; + class ImportFromM3E {}; + class ImportFromM3E_Convert {}; + class ImportFromM3E_Static {}; + class ImportFromM3E_3DEN {}; + class ImportFromM3E_3DEN_Convert {}; + class ImportFromM3E_3DEN_Static {}; + class IsPlayerNearby {}; + class IsPosBlacklisted {}; + class IsNearWater {}; + class IsValidPosition {}; + class MissionParams {}; + class MissionsMonitor {}; + class MissionsMonitor_Dynamic {}; + class MissionsMonitor_Static {}; + class MissionSuccessState {}; + class OnKilled {}; + class PlayerAwardOnAIKill {}; + class RemoveMarkers {}; + class SelectRandomVal {}; + class SelectMagazine {}; + class SelectMission {}; + class SelectOffsetPos {}; + class SetAILocality {}; + class SetGroupBehavior {}; + class SetGroupBehavior_Separate {}; + class SetRelPositions {}; + class SpawnAIGroup {}; + class SpawnAIGroup_MultiPos {}; + class SpawnAIVehicle {}; + class SpawnAISoldier {}; + class SpawnAIStaticMG {}; + class SpawnBanditMission {}; + class SpawnCrate {}; + class SpawnHeliReinforcement {}; + class SpawnMinefield {}; + class SpawnNonPersistentVehicle {}; + class SpawnPersistentVehicle {}; + class SpawnStaticMission {}; + class SubArr {}; + class TargetsKilled {}; + }; + }; +}; diff --git a/@ExileServer/addons/a3_dms/config.sqf b/@ExileServer/addons/a3_dms/config.sqf new file mode 100644 index 0000000..3972e66 --- /dev/null +++ b/@ExileServer/addons/a3_dms/config.sqf @@ -0,0 +1,1303 @@ +/* + Main DMS Config File + + Created by eraser1 + Several revisions and additions have been made by community members. + + + A lot of these configs are influenced by WAI :P + https://github.com/nerdalertdk/WICKED-AI +*/ + +// You dawg... heard you like configs... so here's some configs for your config.... so you can configure your configuration to make it easier to configure your configuration http://i.imgur.com/9eJjEEo.jpg + + +// If you don't want the AI to have marksman DLC weapons, then simply remove the line below, or comment it by putting // at the beginning of the line +#define GIVE_AI_MARKSMAN_DLC_WEAPONS 1 + +// If you don't want crates to spawn with marksman DLC weapons, simply remove the line below or comment it out. +#define USE_MARKSMAN_DLC_WEAPONS_IN_CRATES 1 + +// Uncomment this if you want Apex weapons on AI. +#define GIVE_AI_APEX_WEAPONS 1 + +// Uncomment this if you want Apex gear on AI. Uniforms, Vests, Backpacks, Helmets,Scopes +#define GIVE_AI_APEX_GEAR 1 + +// Uncomment this if you want Apex weapons in loot crates +#define USE_APEX_WEAPONS_IN_CRATES 1 + +// Uncomment this if you want Apex vehicles to spawn for AI/missions +#define USE_APEX_VEHICLES 1 + + + + +DMS_Use_Map_Config = true; // Whether or not to use config overwrites specific to the map. +/* + 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 = true; // Whether or not to use Rank Changes. (Required 'true' if using Occupation) +/* + 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 = true; // 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. +//Note, if you have the above to true, you need to set DMS_ai_freezeOnSpawn = false; and DMS_ai_share_info = true; + +/* Mission System Settings */ + /*General settings for dynamic missions*/ + DMS_DynamicMission = true; // Enable/disable dynamic mission system. + DMS_MaxBanditMissions = 3; // Maximum number of Bandit Missions running at the same time + DMS_TimeToFirstMission = [180,420]; // [Minimum,Maximum] time between first mission spawn. | DEFAULT: 3-7 minutes. + DMS_TimeBetweenMissions = [600,900]; // [Minimum,Maximum] time between missions (if mission limit is not reached) | DEFAULT: 10-15 mins + DMS_MissionTimeout = [900,1800]; // [Minimum,Maximum] time it will take for a mission to timeout | DEFAULT: 15-30 mins + DMS_MissionTimeoutResetRange = 1500; // If a player is this close to a mission then it won't time-out. Set to 0 to disable this check. + DMS_MissionTimeoutResetFrequency = 180; // How often (in seconds) to check for nearby players and reset the mission timeout. + DMS_ResetMissionTimeoutOnKill = true; // Whether or not to reset the mission timeout when an AI is killed. + /*General settings for dynamic missions*/ + + /*General settings for static missions*/ + DMS_StaticMission = false; // Enable/disable static mission system. + DMS_MaxStaticMissions = 1; // Maximum number of Static Missions running at the same time. It's recommended you set this to the same amount of static missions that you have in total. This config will be ignored by "DMS_StaticMissionsOnServerStart". + DMS_TimeToFirstStaticMission = [30,30]; // [Minimum,Maximum] time between first static mission spawn. | DEFAULT: 3-7 minutes. + DMS_TimeBetweenStaticMissions = [900,1800]; // [Minimum,Maximum] time between static missions (if static mission limit is not reached) | DEFAULT: 15-30 mins + DMS_StaticMissionTimeOut = [1800,3600]; // [Minimum,Maximum] time it will take for a static mission to timeout | DEFAULT: 30-60 mins + DMS_StaticMissionTimeoutResetRange = 1500; // If a player is this close to a mission then it won't time-out. Set to 0 to disable this check. + DMS_SMissionTimeoutResetFrequency = 180; // How often (in seconds) to check for nearby players and reset the mission timeout for static missions. + DMS_ResetStaticMissionTimeoutOnKill = true; // Whether or not to reset the mission timeout when an AI is killed (for Static Missions). + DMS_StaticMinPlayerDistance = 1500; // If a player is this close to a mission location, then it won't spawn the mission and will wait 60 seconds before attempting to spawn it. + DMS_AllowStaticReinforcements = true; // Whether or not static missions will receive reinforcements. This will simply disable the calling of GroupReinforcementsMonitor; + DMS_SpawnFlareOnReinforcements = true; // Whether or not to spawn a flare and noise when AI reinforcements have spawned. + /*General settings for static missions*/ + + DMS_playerNearRadius = 100; // How close a player has to be to a mission in order to satisfy the "playerNear" mission requirement (can be customized per mission). + + DMS_AI_KillPercent = 100; // The percent amount of AI that need to be killed for "killPercent" mission requirement (NOT IMPLEMENTED) + + /*Mission Marker settings*/ + DMS_ShowDifficultyColorLegend = true; // Whether or not to show a "color legend" at the bottom left of the map that shows which color corresponds to which difficulty. I know it's not very pretty, meh. + DMS_ShowMarkerCircle = false; // Whether or not to show the colored "circle" around a mission marker. + DMS_MarkerText_ShowMissionPrefix = true; // Whether or not to place a prefix before the mission marker text. Enable this if your players get confused by the marker names :P + DMS_MarkerText_MissionPrefix = "Mission:"; // The text displayed before the mission name in the mission marker. + DMS_MarkerText_ShowAICount = true; // Whether or not to display the number of remaining AI in the marker name. + DMS_MarkerText_ShowAICount_Static = true; // Whether or not to display the number of remaining AI in the marker name for STATIC missions. + DMS_MarkerText_AIName = "Units"; // What the AI will be called in the map marker. For example, the marker text can show: "Car Dealer (3 Units remaining)" + DMS_MarkerPosRandomization = false; // Randomize the position of the circle marker of a mission + DMS_MarkerPosRandomRadius = [25,100]; // Minimum/Maximum distance that the circle marker position will be randomized | DEFAULT: 0 meters to 200 meters + DMS_RandomMarkerBrush = "Cross"; // See: https://community.bistudio.com/wiki/setMarkerBrush + DMS_MissionMarkerWinDot = true; // Keep the mission marker dot with a "win" message after mission is over + DMS_MissionMarkerLoseDot = true; // Keep the mission marker dot with a "lose" message after mission is over + DMS_MissionMarkerWinDot_Type = "mil_end"; // The marker type to show when a mission is completed. Refer to: https://community.bistudio.com/wiki/cfgMarkers + DMS_MissionMarkerLoseDot_Type = "KIA"; // The marker type to show when a mission fails. Refer to: https://community.bistudio.com/wiki/cfgMarkers + DMS_MissionMarkerWinDotTime = 30; // How many seconds the "win" mission dot will remain on the map + DMS_MissionMarkerLoseDotTime = 30; // How many seconds the "lose" mission dot will remain on the map + DMS_MissionMarkerWinDotColor = "ColorBlue"; // The color of the "win" marker dot + DMS_MissionMarkerLoseDotColor = "ColorRed"; // The color of the "lose" marker dot + /*Mission Marker settings*/ + + /*Mission Cleanup settings*/ + DMS_CompletedMissionCleanup = true; // Cleanup mission-spawned buildings and AI bodies after some time + DMS_CompletedMissionCleanupTime = 3600; // Minimum time until mission-spawned buildings and AI are cleaned up + DMS_CleanUp_PlayerNearLimit = 20; // Cleanup of an object is aborted if a player is this many meters close to the object + DMS_AIVehCleanUpTime = 300; // Time until a destroyed AI vehicle is cleaned up. + /*Mission Cleanup settings*/ + + /*Mission spawn location settings*/ + DMS_UsePredefinedMissionLocations = false; // Whether or not to use a list of pre-defined mission locations instead before attempting to find a random (valid) position. The positions will still be checked for validity. If none of the provided positions are valid, a random one will be generated. + DMS_PredefinedMissionLocations = [ // List of Preset/Predefined mission locations. + /* List of positions: + position1: [x_1,y_1,z_1], + position2: [x_2,y_2,z_2], + ... + positionN: [x_N,y_N,z_N] + */ + + ]; + + DMS_PredefinedMissionLocations_WEIGHTED = [ // List of Preset/Predefined mission locations WITH WEIGHTED CHANCES. This will NOT override "DMS_PredefinedMissionLocations", and everything from "DMS_PredefinedMissionLocations" will behave as though it has 1 weight per position. + /* List of arrays with position and weighted chance: + [[x_1,y_1,z_1], chance_1], + [[x_2,y_2,z_2], chance_2], + ... + [[x_N,y_N,z_N], chance_N] + */ + + ]; + DMS_ThrottleBlacklists = true; // Whether or not to "throttle" the blacklist distance parameters in DMS_fnc_FindSafePos. This will reduce the values of the minimum + //distances for some of the below parameters if several attempts have been made, but a suitable position was not yet found. This + //should help with server performance drops when spawning a mission, as DMS_fnc_findSafePos is the most resource-intensive function. + DMS_AttemptsUntilThrottle = 15; // How many attempts until the parameters are throttled. + DMS_ThrottleCoefficient = 0.9; // How much the parameters are throttled. The parameters are multiplied by the coefficient, so 0.9 means 90% of whatever the parameter was. + DMS_MinThrottledDistance = 500; // The minimum distance to which it will throttle. If the throttled value is less than this value, then this value is used instead. + DMS_PlayerNearBlacklist = 2000; // Missions won't spawn in a position this many meters close to a player + DMS_SpawnZoneNearBlacklist = 2500; // Missions won't spawn in a position this many meters close to a spawn zone + DMS_TraderZoneNearBlacklist = 2500; // Missions won't spawn in a position this many meters close to a trader zone + DMS_MissionNearBlacklist = 2500; // Missions won't spawn in a position this many meters close to another mission + DMS_WaterNearBlacklist = 500; // Missions won't spawn in a position this many meters close to water + DMS_TerritoryNearBlacklist = 100; // Missions won't spawn in a position this many meters close to a territory flag. This is a resource intensive check, don't set this value too high! + DMS_MixerNearBlacklist = 1000; // Missions won't spawn in a position this many meters close to a concrete mixer + DMS_ContaminatedZoneNearBlacklist = 1000; // Missions won't spawn in a position this many meters close to a contaminated zone + DMS_MinSurfaceNormal = 0.9; // Missions won't spawn in a position where its surfaceNormal is less than this amount. The lower the value, the steeper the location. Greater values means flatter locations. Values can range from 0-1, with 0 being sideways, and 1 being perfectly flat. For reference: SurfaceNormal of about 0.7 is when you are forced to walk up a surface. If you want to convert surfaceNormal to degrees, use the arc-cosine of the surfaceNormal. 0.9 is about 25 degrees. Google "(arccos 0.9) in degrees" + DMS_MinDistFromWestBorder = 250; // Missions won't spawn in a position this many meters close to the western map border. + DMS_MinDistFromEastBorder = 250; // Missions won't spawn in a position this many meters close to the easter map border. + DMS_MinDistFromSouthBorder = 250; // Missions won't spawn in a position this many meters close to the southern map border. + DMS_MinDistFromNorthBorder = 250; // Missions won't spawn in a position this many meters close to the northern map border. + DMS_SpawnZoneMarkerTypes = [ // If you're using custom spawn zone markers, make sure you define them here. CASE SENSITIVE!!! + "ExileSpawnZoneIcon" + ]; + DMS_TraderZoneMarkerTypes = [ // If you're using custom trader markers, make sure you define them here. CASE SENSITIVE!!! + "ExileTraderZoneIcon" + ]; + DMS_MixerMarkerTypes = [ // If you're using custom concrete mixer map markers, make sure you define them here. CASE SENSITIVE!!! + "ExileConcreteMixerZoneIcon" + ]; + DMS_ContaminatedZoneMarkerTypes = [ // If you're using custom contaminated zone markers, make sure you define them here. CASE SENSITIVE!!! + "ExileContaminatedZoneIcon" + ]; + /*Mission spawn location settings*/ + + DMS_MinWaterDepth = 20; // Minimum depth of water that an underwater mission can spawn at. + + /*Crate/Box settings*/ + DMS_HideBox = true; // "Hide" the box from being visible by players until the mission is completed. + DMS_EnableBoxMoving = true; // Whether or not to allow the box to move and/or be lifted by choppers. + DMS_SpawnBoxSmoke = true; // Spawn a smoke grenade on mission box upon misson completion during daytime + DMS_DefaultSmokeClassname = "SmokeShellPurple"; // Classname of the smoke you want to spawn. + DMS_SpawnBoxIRGrenade = true; // Spawn an IR grenade on mission box upon misson completion during nighttime + /*Crate/Box settings*/ + + /*Mine settings*/ + DMS_SpawnMinefieldForEveryMission = false; // Whether or not to spawn a minefield for every dynamic mission. + DMS_SpawnMinesAroundMissions = true; // Whether or not to spawn mines around AI missions that have them. + DMS_despawnMines_onCompletion = true; // Despawn mines spawned around missions when the mission is completed + DMS_MineInfo_easy = [5,50]; // Mine info for "easy" missions. This will spawn 5 mines within a 50m radius. + DMS_MineInfo_moderate = [10,50]; // Mine info for "moderate" missions. This will spawn 10 mines within a 50m radius. + DMS_MineInfo_difficult = [15,75]; // Mine info for "difficult" missions. This will spawn 15 mines within a 75m radius. + DMS_MineInfo_hardcore = [25,100]; // Mine info for "hardcore" missions. This will spawn 25 mines within a 100m radius. + DMS_SpawnMineWarningSigns = true; // Whether or not to spawn mine warning signs around a minefield. + DMS_BulletProofMines = true; // Whether or not you want to make the mines bulletproof. Prevents players from being able to shoot the mines and creating explosions. + /*Mine settings*/ + + DMS_MinPlayerCount = 0; // Minimum number of players until mission start + DMS_MinServerFPS = 10; // Minimum server FPS for missions to start + + /*Mission notification settings*/ + DMS_PlayerNotificationTypes = [ // Notification types. Supported values are: ["dynamicTextRequest", "standardHintRequest", "systemChatRequest", "textTilesRequest", "ExileToasts"]. Details below. + //"dynamicTextRequest", // You should use either "dynamicTextRequest" or "textTilesRequest", and I think "textTilesRequest" looks better, but this is less performance-intensive. + //"standardHintRequest", // Hints are a bit wonky... + //"textTilesRequest", // Keep in mind you can only have 1 "text tile" message up at a time, so the message will disappear if the player gets a kill or something while the message is shown. This message type is also performance-intensive, so I advise against it. + //"systemChatRequest", // Always nice to show in chat so that players can scroll up to read the info if they need to. + "ExileToasts" // Default notification type since Exile 0.98, see (http://www.exilemod.com/devblog/new-ingame-notifications/) + ]; + + /*Exile Toasts Notification Settings*/ + DMS_ExileToasts_Title_Size = 22; // Size for Client Exile Toasts mission titles. + DMS_ExileToasts_Title_Font = "puristaMedium"; // Font for Client Exile Toasts mission titles. + DMS_ExileToasts_Message_Color = "#FFFFFF"; // Exile Toasts color for "ExileToast" client notification type. + DMS_ExileToasts_Message_Size = 19; // Exile Toasts size for "ExileToast" client notification type. + DMS_ExileToasts_Message_Font = "PuristaLight"; // Exile Toasts font for "ExileToast" client notification type. + /*Exile Toasts Notification Settings*/ + + /*Dynamic Text Notification Settings*/ + DMS_dynamicText_Duration = 7; // Number of seconds that the message will last on the screen. + DMS_dynamicText_FadeTime = 1.5; // Number of seconds that the message will fade in/out (does not affect duration). + DMS_dynamicText_Title_Size = 1.2; // Size for Client Dynamic Text mission titles. + DMS_dynamicText_Title_Font = "puristaMedium"; // Font for Client Dynamic Text mission titles. + DMS_dynamicText_Message_Color = "#FFFFFF"; // Dynamic Text color for "dynamicTextRequest" client notification type. + DMS_dynamicText_Message_Size = 0.65; // Dynamic Text size for "dynamicTextRequest" client notification type. + DMS_dynamicText_Message_Font = "OrbitronMedium"; // Dynamic Text font for "dynamicTextRequest" client notification type. + /*Dynamic Text Notification Settings*/ + + /*Standard Hint Notification Settings*/ + DMS_standardHint_Title_Size = 2; // Size for Client Standard Hint mission titles. + DMS_standardHint_Title_Font = "puristaMedium"; // Font for Client Standard Hint mission titles. + DMS_standardHint_Message_Color = "#FFFFFF"; // Standard Hint color for "standardHintRequest" client notification type. + DMS_standardHint_Message_Size = 1; // Standard Hint size for "standardHintRequest" client notification type. + DMS_standardHint_Message_Font = "OrbitronMedium"; // Standard Hint font for "standardHintRequest" client notification type. + /*Standard Hint Notification Settings*/ + + /*Text Tiles Notification Settings*/ + DMS_textTiles_Duration = 7; // Number of seconds that the message will last on the screen. + DMS_textTiles_FadeTime = 1.5; // Number of seconds that the message will fade in/out (does not affect duration). + DMS_textTiles_Title_Size = 2.3; // Size for Client Text Tiles mission titles. + DMS_textTiles_Title_Font = "puristaMedium"; // Font for Client Text Tiles mission titles. + DMS_textTiles_Message_Color = "#FFFFFF"; // Text Tiles color for "textTilesRequest" client notification type. + DMS_textTiles_Message_Size = 1.25; // Text Tiles size for "textTilesRequest" client notification type. + DMS_textTiles_Message_Font = "OrbitronMedium"; // Text Tiles font for "textTilesRequest" client notification type. + /*Text Tiles Notification Settings*/ + + /*Mission notification settings*/ + + DMS_RandomBanditMissionsOnStart = 1; // Number of (random) bandit missions to spawn when the server starts, just so players don't have to wait for missions to spawn. + DMS_BanditMissionTypes = [ // List of missions with spawn chances. If they add up to 100%, they represent the percentage chance each one will spawn + ["bandits",3], + ["bauhaus",3], + ["beertransport",3], + ["behindenemylines",3], + ["blackhawkdown",3], + ["cardealer",3], + ["construction",3], + ["donthasslethehoff",3], + ["foodtransport",3], + ["guntransport",3], + ["humanitarian",3], + ["lost_battalion",3], + ["medical",3], + ["mercbase",2], + ["mercenaries",3], + ["nedbandit1_mission",3], + ["nedbuilding1_mission",3], + ["nedcar_mission",4], + ["nedcashbandits_mission",3], + ["neddrinkstransport_mission",4], + ["nedguns1_mission",3], + ["nedhatchback_mission",3], + ["nedhuey_mission",2], + ["nedhunter_mission",2], + ["nedifrit_mission",2], + ["nedlittlebird_mission",2], + ["nedmedical1_mission",3], + ["nedoffroad_mission",3], + ["nedresearch_mission",3], + ["nedsnipercamp_mission",3], + ["nedstrider_mission",2], + ["nedbtrader_mission",2], + ["nedural_mission",3], + ["roguenavyseals",3], + ["thieves",3], + ["walmart",3] + ]; + + + DMS_StaticMissionTypes = [ // List of STATIC missions with spawn chances. + //["saltflats",1] //<--Example (already imported by default on Altis in map configs) + //["slums",1] //<--Example (already imported by default on Altis in map configs) + //["occupation",1] //<--Example + //["sectorB",1] //<--Example for Taviana + ]; + + DMS_SpecialMissions = [ // List of special missions with restrictions. Each element must be defined as [mission, minPlayers, maxPlayers, timesPerRestart, _timeBetween]. + //["specops",15,60,2,900] //<-- Example for a mission named "specops.sqf" that must be placed in the "special" folder. It will only spawn when there are at least 15 players, less than 60 players, it will only spawn up to twice per restart, and at least 900 seconds must pass before another instance of the mission can spawn. + ]; + + DMS_BasesToImportOnServerStart = [ // List of static bases to import on server startup (spawned post-init). This will reduce the amount of work the server has to do when it actually spawns static missions, and players won't be surprised when a base suddenly pops up. You can also include any other M3E-exported bases to spawn here. + //"saltflatsbase", //<--Example (already imported by default on Altis) + //"slums_objects" //<--Example (already imported by default on Altis) + ]; + + DMS_BanditMissionsOnServerStart = [ + //"construction" //<-- Example + ]; + + DMS_StaticMissionsOnServerStart = [ // List of STATIC missions with spawn chances. + //"saltflats" //<--Example + //"slums" //<--Example + //"occupation" //<--Example + //"sectorB" //<--Example for Taviana + ]; + + + + DMS_findSafePosBlacklist = [ // This list defines areas where missions WILL NOT spawn. For position blacklist info refer to: http://www.exilemod.com/topic/61-dms-defents-mission-system/?do=findComment&comment=31190 + // There are examples in the altis map config (it blacklists the salt flats) and in the tavi/taviana map configs. + + //[[2350,4680],100] // This random example blacklists any position within 100 meters of coordinates "[2350,4680]" + ]; +/* Mission System Settings */ + + +/* AI Settings */ + DMS_AI_Classname = "O_Soldier_unarmed_F"; // Since some of you wanted this... + + DMS_AI_NamingType = 0; // This specifies the "naming scheme" for the AI. 0 corresponds with the default ArmA names; 1 means you want a DMS name (eg: [DMS BANDIT SOLDIER 123]); 2 means you want to generate a name from a list of first and last names (DMS_AI_FirstNames, DMS_AI_LastNames). + DMS_AI_FirstNames = [ // List of "first names" that an AI can have. Only used when DMS_AI_NamingType = 2. + "Adam", + "Benjamin", + "Charles", + "David", + "Eric" + // etc. + ]; + DMS_AI_LastNames = [ // List of "last names" that an AI can have. Only used when DMS_AI_NamingType = 2. + "Smith", + "Johnson", + "Williams", + "Jones", + "Brown" + // etc. + ]; + + DMS_Show_Kill_Poptabs_Notification = true; // Whether or not to show the poptabs gained/lost message on the player's screen when killing an AI. (It will still change the player's money, it just won't show the "Money Received" notification) + DMS_Show_Kill_Respect_Notification = true; // Whether or not to show the "Frag Message" on the player's screen when killing an AI. (It will still change the player's respect, it just won't show the "AI Killed" frag message) + DMS_Show_Kill_Rank_Notification = true; + DMS_Show_Party_Kill_Notification = true; // Whether or not to show in chat when a party member kills an AI. + + DMS_Spawn_AI_With_Money = true; // Whether or not to spawn AI with money that can be looted from the body. + DMS_AIMoney_PopulationMultiplier = 10; // This determines how much EXTRA money an AI will have on his body. For example, setting this to 5 and having a server population of 30 means the AI will have an extra 150 poptabs on the body. Set to 0 to disable. + + DMS_GiveMoneyToPlayer_OnAIKill = true; // Whether or not to give money directly to players when they kill AI (old method of giving money). + DMS_GiveRespectToPlayer_OnAIKill = true; // Whether or not to give respect to players when they kill AI. + + DMS_Bandit_Soldier_MoneyGain = 50; // The amount of Poptabs gained for killing a bandit soldier + DMS_Bandit_Soldier_RepGain = 10; // The amount of Respect gained for killing a bandit soldier + DMS_Bandit_Soldier_RankGain = 15; + DMS_Bandit_Soldier_SpawnMoney = 50; // The amount of Poptabs carried by a bandit soldier + + DMS_Bandit_Static_MoneyGain = 75; // The amount of Poptabs gained for killing a bandit static gunner + DMS_Bandit_Static_RepGain = 15; // The amount of Respect gained for killing a bandit static gunner + DMS_Bandit_Static_RankGain = 30; + DMS_Bandit_Static_SpawnMoney = 75; // The amount of Poptabs carried by a bandit static gunner + + 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; + DMS_Bandit_Vehicle_SpawnMoney = 100; // The amount of Poptabs carried by a bandit vehicle crew member + +/* 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_SpawnMoney = 100; // The amount of Poptabs carried by a hero soldier + + 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_RankGain = -60; + DMS_Hero_Static_SpawnMoney = 120; // The amount of Poptabs carried by a hero static gunner + + 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; + DMS_Hero_Vehicle_SpawnMoney = 200; // The amount of Poptabs carried by a hero vehicle crew member +/* 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_Soldier_SpawnMoney = 0; // The amount of Poptabs carried by a Survivor soldier + + 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_Static_SpawnMoney = 0; // The amount of Poptabs carried by a Survivor static gunner + + 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_RankGain = -600; + DMS_Survivor_Vehicle_SpawnMoney = 0; // The amount of Poptabs carried by a Survivor vehicle crew member + + 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. + + DMS_Diff_RepOrTabs_on_roadkill = true; // Whether or not you want to use different values for giving respect/poptabs when you run an AI over. Default values are NEGATIVE. This means player will LOSE respect or poptabs. + DMS_Bandit_Soldier_RoadkillMoney = -10; // The amount of Poptabs gained/lost for running over a bandit soldier + DMS_Bandit_Soldier_RoadkillRep = -5; // The amount of Respect gained/lost for running over a bandit soldier + DMS_Bandit_Soldier_RoadkillRank = 20; + DMS_Bandit_Static_RoadkillMoney = -10; // The amount of Poptabs gained/lost for running over a bandit static gunner + DMS_Bandit_Static_RoadkillRep = -5; // The amount of Respect gained/lost for running over a bandit static gunner + DMS_Bandit_Static_RoadkillRank = 30; + 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*/ + 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; + DMS_Hero_Static_RoadkillMoney = 20; // The amount of Poptabs gained/lost for running over a hero static gunner + DMS_Hero_Static_RoadkillRep = 10; // The amount of Respect gained/lost for running over a hero static gunner + DMS_Hero_Static_RoadkillRank = -60; + 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*/ + 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_Static_RoadkillRep = -200; // The amount of Respect gained/lost for running over a Survivor static gunner + 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_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_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"!!! + DMS_remove_roadkill = false; // Remove gear from AI bodies that are roadkilled + DMS_remove_roadkill_chance = 50; // Percentage chance that roadkilled AI bodies will be deleted + DMS_explode_onRoadkill = false; // Whether or not to spawn an explosion when an AI gets run over. It will likely take out the 2 front wheels. Should help mitigate the ineffective AI vs. striders issue ;) + DMS_RemoveNVG = false; // Remove NVGs from AI bodies + + DMS_MaxAIDistance = 500; // The maximum distance an AI unit can be from a mission before he is killed. Helps with AI running away and forcing the mission to keep running. Set to 0 if you don't want it. + DMS_AIDistanceCheckFrequency = 60; // How often to check within DMS_fnc_TargetsKilled whether or not the AI is out of the maximum radius. Lower values increase frequency and increase server load, greater values decrease frequency and may cause longer delays for "runaway" AI. + + DMS_ai_offload_to_client = false; // Offload spawned AI groups to random clients. Helps with server performance. + DMS_ai_offload_Only_DMS_AI = false; // Don't set this to false unless you know what you're doing. + DMS_ai_offload_notifyClient = false; // Notify the client when AI has been offloaded to the client. + + DMS_ai_allowFreezing = true; // Whether or not to "freeze" AI that are a certain distance away from players (and therefore inactive). + DMS_ai_freeze_Only_DMS_AI = true; // Whether or not to "freeze" AI that are not spawned by DMS. + DMS_ai_freezingDistance = 3500; // If there are no players within this distance of the leader of an AI group, then the AI group will be "frozen". + DMS_ai_unfreezingDistance = 3500; // If there are players within this distance of the leader of an AI group, then the AI group will be "un-frozen". + DMS_ai_offloadOnUnfreeze = true; // Whether or not to offload AI to clients once they have been "un-frozen". NOTE: This config will be ignored if "DMS_ai_offload_to_client" is set to false. + DMS_ai_freezeCheckingDelay = 15; // How often (in seconds) DMS will check whether to freeze/un-freeze AI. + DMS_ai_freezeOnSpawn = false; // Whether or not to freeze an AI group when initially spawned. + + DMS_ai_share_info = true; // Share info about killer + DMS_ai_share_info_distance = 25; // The distance killer's info will be shared to other AI + + DMS_ai_nighttime_accessory_chance = 75; // Percentage chance that AI will have a flashlight or laser pointer on their guns if spawned during nighttime + DMS_ai_enable_water_equipment = true; // Enable/disable overriding default weapons of an AI if it spawns on/in water + + // https://community.bistudio.com/wiki/AI_Sub-skills#general + DMS_ai_skill_static = [["aimingAccuracy",0.20],["aimingShake",0.70],["aimingSpeed",0.75],["spotDistance",0.70],["spotTime",0.50],["courage",1.00],["reloadSpeed",1.00],["commanding",1.00],["general",1.00]]; // Static AI Skills + DMS_ai_skill_easy = [["aimingAccuracy",0.30],["aimingShake",0.50],["aimingSpeed",0.50],["spotDistance",0.50],["spotTime",0.50],["courage",1.00],["reloadSpeed",1.00],["commanding",1.00],["general",0.50]]; // Easy + DMS_ai_skill_moderate = [["aimingAccuracy",0.60],["aimingShake",0.60],["aimingSpeed",0.60],["spotDistance",0.60],["spotTime",0.60],["courage",1.00],["reloadSpeed",1.00],["commanding",1.00],["general",0.60]]; // Moderate + DMS_ai_skill_difficult = [["aimingAccuracy",0.70],["aimingShake",0.70],["aimingSpeed",0.70],["spotDistance",0.70],["spotTime",0.80],["courage",1.00],["reloadSpeed",1.00],["commanding",1.00],["general",0.70]]; // Difficult + DMS_ai_skill_hardcore = [["aimingAccuracy",1.00],["aimingShake",1.00],["aimingSpeed",1.00],["spotDistance",1.00],["spotTime",1.00],["courage",1.00],["reloadSpeed",1.00],["commanding",1.00],["general",1.00]]; // Hardcore + DMS_ai_skill_random = ["hardcore","difficult","difficult","difficult","moderate","moderate","moderate","moderate","easy","easy"]; // Skill frequencies for "random" AI skills | Default: 10% hardcore, 30% difficult, 40% moderate, and 20% easy + 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_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 + DMS_AI_AimCoef_hardcore = 0.05; // "Custom Aim Coefficient" (weapon sway multiplier) for "hardcore" AI + DMS_AI_EnableStamina_easy = true; // Whether or not to keep the stamina system for "easy" AI. + DMS_AI_EnableStamina_moderate = true; // Whether or not to keep the stamina system for "moderate" AI. + DMS_AI_EnableStamina_difficult = true; // Whether or not to keep the stamina system for "difficult" AI. + DMS_AI_EnableStamina_hardcore = true; // 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_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) + + DMS_static_weapons = [ // Static weapons for AI + "O_HMG_01_high_F" + ]; + + DMS_ai_default_items = [ // Toolbelt items each AI will spawn with + "ItemWatch", + "ItemMap", + "ItemCompass", + "ItemRadio" + ]; + + DMS_ai_BipodList = [ + "bipod_01_F_blk", + "bipod_01_F_mtp", + "bipod_01_F_snd", + "bipod_02_F_blk", + "bipod_02_F_hex", + "bipod_02_F_tan", + "bipod_03_F_blk", + "bipod_03_F_oli" + ]; + + //Assault Class + DMS_assault_weps = [ // Assault Rifles + #ifdef GIVE_AI_APEX_WEAPONS + "arifle_AK12_F", + "arifle_ARX_ghex_F", + "arifle_CTAR_blk_F", + "arifle_SPAR_01_khk_F", + "arifle_SPAR_03_khk_F", + #endif + "arifle_Katiba_GL_F", + "arifle_MX_GL_Black_F", + "arifle_Mk20_GL_F", + "arifle_TRG21_GL_F", + "arifle_Katiba_F", + "arifle_MX_Black_F", + "arifle_TRG21_F", + "arifle_TRG20_F", + "arifle_Mk20_plain_F", + "arifle_Mk20_F", + "Exile_Weapon_AK107", + "Exile_Weapon_AK107_GL", + "Exile_Weapon_AK74_GL", + "Exile_Weapon_AK47", + "Exile_Weapon_AKS_Gold" + ]; + DMS_assault_pistols = [ // Pistols for Assault Class (Set to empty array if you don't want to give them any pistols) + "hgun_ACPC2_F", + "hgun_Rook40_F", + "hgun_P07_F", + "hgun_Pistol_heavy_01_F", + "hgun_Pistol_heavy_02_F", + "Exile_Weapon_Colt1911", + "Exile_Weapon_Makarov", + "Exile_Weapon_Taurus", + "Exile_Weapon_TaurusGold" + ]; + DMS_assault_optics = [ // Optics for Assault Class + #ifdef GIVE_AI_APEX_GEAR + "optic_ERCO_khk_F", + "optic_Holosight_blk_F", + #endif + "optic_Arco", + "optic_Hamr", + "optic_Aco", + "optic_Holosight", + "optic_MRCO", + "optic_DMS" + ]; + DMS_assault_optic_chance = 75; // Percentage chance that an Assault Class AI will get an optic + DMS_assault_bipod_chance = 25; // Percentage chance that an Assault Class AI will get a bipod + DMS_assault_suppressor_chance = 25; // Percentage chance that an Assault Class AI will get a suppressor + + DMS_assault_items = [ // Items for Assault Class AI (Loot stuff that goes in uniform/vest/backpack) + "Exile_Item_InstaDoc", + "Exile_Item_BBQSandwich", + "Exile_Item_Energydrink" + ]; + DMS_assault_equipment = [ // Equipment for Assault Class AI (stuff that goes in toolbelt slots) + "ItemGPS" + ]; + DMS_assault_RandItemCount = 2; // How many random items to add to the AI's inventory. + DMS_assault_RandItems = [ // The random items that will be added to the AI's inventory. + "Exile_Item_Catfood_Cooked", + "Exile_Item_Surstromming_Cooked", + "Exile_Item_PowerDrink", + "Exile_Item_EnergyDrink", + "Exile_Item_Vishpirin", + "Exile_Item_Bandage" + ]; + DMS_assault_helmets = [ // Helmets for Assault Class + #ifdef GIVE_AI_APEX_GEAR + "H_HelmetB_TI_tna_F", + "H_HelmetB_Enh_tna_F", + "H_HelmetSpecO_ghex_F", + "H_HelmetCrew_O_ghex_F", + #endif + "H_HelmetSpecB_paint1", + "H_HelmetIA_camo", + "H_HelmetLeaderO_ocamo", + "H_HelmetLeaderO_oucamo" + ]; + DMS_assault_clothes = [ // Uniforms for Assault Class + #ifdef GIVE_AI_APEX_GEAR + "U_B_T_Soldier_F", + "U_B_T_Soldier_SL_F", + "U_B_CTRG_Soldier_F", + "U_O_V_Soldier_Viper_F", + "U_I_C_Soldier_Bandit_2_F", + "U_I_C_Soldier_Camo_F", + "U_B_CTRG_Soldier_urb_1_F", + #endif + "U_O_CombatUniform_ocamo", + "U_O_PilotCoveralls", + //"U_B_Wetsuit", + "U_BG_Guerilla3_1", + "U_BG_Guerilla2_3", + "U_BG_Guerilla2_2", + "U_BG_Guerilla1_1", + "U_BG_Guerrilla_6_1", + "U_IG_Guerilla3_2", + "U_B_SpecopsUniform_sgg", + "U_I_OfficerUniform", + "U_B_CTRG_3", + "U_I_G_resistanceLeader_F" + ]; + DMS_assault_vests = [ // Vests for Assault Class + #ifdef GIVE_AI_APEX_GEAR + "V_TacChestrig_grn_F", + "V_PlateCarrier2_tna_F", + "V_PlateCarrierSpec_tna_F", + "V_PlateCarrierGL_tna_F", + "V_TacVest_gen_F", + "V_PlateCarrier1_rgr_noflag_F", + #endif + "V_PlateCarrierH_CTRG", + "V_PlateCarrierSpec_rgr", + "V_PlateCarrierGL_blk", + "V_PlateCarrierGL_mtp", + "V_PlateCarrierGL_rgr", + "V_PlateCarrierSpec_blk", + "V_PlateCarrierSpec_mtp", + "V_PlateCarrierL_CTRG", + "V_TacVest_blk_POLICE", + "V_PlateCarrierIA2_dgtl" + ]; + DMS_assault_backpacks = [ // Backpacks for Assault Class + #ifdef GIVE_AI_APEX_GEAR + "B_Bergen_tna_F", + "B_FieldPack_ghex_F", + "B_ViperLightHarness_khk_F", + #endif + "B_Bergen_rgr", + "B_Carryall_oli", + "B_Kitbag_mcamo", + "B_Carryall_cbr", + "B_FieldPack_oucamo", + "B_FieldPack_cbr", + "B_Bergen_blk" + ]; + + //Machine Gun Class + DMS_MG_weps = [ // Machine Guns + #ifdef GIVE_AI_MARKSMAN_DLC_WEAPONS + "MMG_01_hex_F", + "MMG_02_black_F", + #endif + + #ifdef GIVE_AI_APEX_WEAPONS + "LMG_03_F", + #endif + "LMG_Zafir_F", + "LMG_Mk200_F", + "arifle_MX_SW_Black_F", + "Exile_Weapon_RPK", + "Exile_Weapon_PKP" + ]; + DMS_MG_pistols = [ // Pistols for Assault Class (Set to empty array if you don't want to give them any pistols) + "hgun_ACPC2_F", + "hgun_Rook40_F", + "hgun_P07_F", + "hgun_Pistol_heavy_01_F", + "hgun_Pistol_heavy_02_F", + "Exile_Weapon_Colt1911", + "Exile_Weapon_Makarov", + "Exile_Weapon_Taurus", + "Exile_Weapon_TaurusGold" + ]; + DMS_MG_optics = [ // Optics for MG Class + #ifdef GIVE_AI_APEX_GEAR + "optic_ERCO_khk_F", + "optic_DMS_ghex_F", + "optic_Arco_blk_F", + #endif + "optic_Hamr", + "optic_Aco", + "optic_Holosight", + "optic_MRCO" + ]; + DMS_MG_optic_chance = 50; // Percentage chance that an MG Class AI will get an optic + DMS_MG_bipod_chance = 90; // Percentage chance that an MG Class AI will get a bipod + DMS_MG_suppressor_chance = 10; // Percentage chance that an MG Class AI will get a suppressor + + DMS_MG_items = [ // Items for MG Class AI (Loot stuff that goes in uniform/vest/backpack) + "Exile_Item_InstaDoc", + "Exile_Item_Catfood_Cooked", + "Exile_Item_PlasticBottleFreshWater", + "Exile_Item_CookingPot" + ]; + DMS_MG_equipment = [ // Equipment for MG Class AI (stuff that goes in toolbelt slots) + "Binocular" + ]; + DMS_MG_RandItemCount = 3; // How many random items to add to the AI's inventory. + DMS_MG_RandItems = [ // The random items that will be added to the AI's inventory. + "Exile_Item_EMRE", + "Exile_Item_Surstromming_Cooked", + "Exile_Item_PowerDrink", + "Exile_Item_PlasticBottleCoffee", + "Exile_Item_Vishpirin", + "Exile_Item_Instadoc" + ]; + DMS_MG_helmets = [ // Helmets for MG Class + #ifdef GIVE_AI_APEX_GEAR + "H_HelmetB_TI_tna_F", + "H_HelmetB_Enh_tna_F", + "H_HelmetSpecO_ghex_F", + "H_HelmetLeaderO_ghex_F", + "H_HelmetCrew_O_ghex_F", + #endif + "H_PilotHelmetHeli_I", + "H_PilotHelmetHeli_O", + "H_PilotHelmetFighter_I", + "H_PilotHelmetFighter_O", + "H_HelmetCrew_O", + "H_CrewHelmetHeli_I", + "H_HelmetSpecB_paint1", + "H_HelmetIA_camo", + "H_HelmetLeaderO_ocamo", + "H_HelmetLeaderO_oucamo" + ]; + DMS_MG_clothes = [ // Uniforms for MG Class + #ifdef GIVE_AI_APEX_GEAR + "U_B_T_Soldier_F", + "U_B_T_Soldier_SL_F", + "U_B_CTRG_Soldier_F", + "U_O_V_Soldier_Viper_F", + "U_I_C_Soldier_Bandit_2_F", + "U_I_C_Soldier_Camo_F", + "U_B_CTRG_Soldier_urb_1_F", + #endif + "U_O_CombatUniform_ocamo", + "U_O_PilotCoveralls", + //"U_B_Wetsuit", + "U_BG_Guerilla3_1", + "U_BG_Guerilla2_3", + "U_BG_Guerilla2_2", + "U_BG_Guerilla1_1", + "U_BG_Guerrilla_6_1", + "U_IG_Guerilla3_2", + "U_B_SpecopsUniform_sgg", + "U_I_OfficerUniform", + "U_B_CTRG_3", + "U_I_G_resistanceLeader_F" + ]; + DMS_MG_vests = [ // Vests for MG Class + #ifdef GIVE_AI_APEX_GEAR + "V_TacChestrig_grn_F", + "V_PlateCarrier2_tna_F", + "V_PlateCarrierSpec_tna_F", + "V_PlateCarrierGL_tna_F", + "V_TacVest_gen_F", + "V_PlateCarrier1_rgr_noflag_F", + #endif + "V_PlateCarrierH_CTRG", + "V_PlateCarrierSpec_rgr", + "V_PlateCarrierGL_blk", + "V_PlateCarrierGL_mtp", + "V_PlateCarrierGL_rgr", + "V_PlateCarrierSpec_blk", + "V_PlateCarrierSpec_mtp", + "V_PlateCarrierL_CTRG", + "V_TacVest_blk_POLICE", + "V_PlateCarrierIA2_dgtl", + "V_HarnessO_brn", + "V_HarnessO_gry" + ]; + DMS_MG_backpacks = [ // Backpacks for MG Class + #ifdef GIVE_AI_APEX_GEAR + "B_Bergen_tna_F", + "B_Carryall_ghex_F", + "B_ViperHarness_ghex_F", + "B_ViperLightHarness_ghex_F", + #endif + "B_Bergen_rgr", + "B_Carryall_oli", + "B_Kitbag_mcamo", + "B_Carryall_cbr", + "B_Bergen_blk" + ]; + + //Sniper Class + DMS_sniper_weps = [ // Sniper Rifles + "srifle_EBR_F", + "srifle_GM6_F", + "srifle_LRR_F", + "arifle_MXM_Black_F", + "srifle_DMR_01_F", + #ifdef GIVE_AI_MARKSMAN_DLC_WEAPONS + "srifle_DMR_02_F", + "srifle_DMR_03_woodland_F", + //"srifle_DMR_04_F", // Does anybody like the ASP-1? :p + "srifle_DMR_05_blk_F", + "srifle_DMR_06_olive_F", + #endif + + #ifdef GIVE_AI_APEX_WEAPONS + "srifle_DMR_07_ghex_F", + #endif + "Exile_Weapon_DMR", + "Exile_Weapon_SVD", + "Exile_Weapon_VSSVintorez" + ]; + DMS_sniper_pistols = [ // Pistols for Assault Class (Set to empty array if you don't want to give them any pistols) + #ifdef GIVE_AI_APEX_WEAPONS + "hgun_Pistol_01_F", + #endif + "hgun_ACPC2_F", + "hgun_Rook40_F", + "hgun_P07_F", + "hgun_Pistol_heavy_01_F", + "hgun_Pistol_heavy_02_F", + "Exile_Weapon_Colt1911", + "Exile_Weapon_Makarov", + "Exile_Weapon_Taurus", + "Exile_Weapon_TaurusGold" + ]; + DMS_sniper_optics = [ // Optics for Sniper Class + #ifdef GIVE_AI_APEX_GEAR + "optic_SOS_khk_F", + "optic_DMS_ghex_F", + "optic_LRPS_tna_F", + #endif + + #ifdef GIVE_AI_MARKSMAN_DLC_WEAPONS + "optic_AMS_khk", + #endif + "optic_SOS", + "optic_DMS", + "optic_LRPS" + ]; + DMS_sniper_optic_chance = 100; // Percentage chance that a Sniper Class AI will get an optic + DMS_sniper_bipod_chance = 90; // Percentage chance that a Sniper Class AI will get a bipod + DMS_sniper_suppressor_chance = 15; // Percentage chance that a Sniper Class AI will get a suppressor + + DMS_sniper_items = [ // Items for Sniper Class AI (Loot stuff that goes in uniform/vest/backpack) + "Exile_Item_InstaDoc", + "Exile_Item_Surstromming_Cooked", + "Exile_Item_PlasticBottleFreshWater", + "Exile_Item_PlasticBottleFreshWater", + "Exile_Item_Matches" + ]; + DMS_sniper_equipment = [ // Equipment for Sniper Class AI (stuff that goes in toolbelt slots) + "Rangefinder", + "ItemGPS" + ]; + DMS_sniper_RandItemCount = 3; // How many random items to add to the AI's inventory. + DMS_sniper_RandItems = [ // The random items that will be added to the AI's inventory. + "Exile_Item_EMRE", + "Exile_Item_PlasticBottleCoffee", + "Exile_Item_CanOpener", + "Exile_Item_Instadoc", + "Exile_Item_DuctTape" + ]; + DMS_sniper_helmets = [ // Helmets for Sniper Class + #ifdef GIVE_AI_APEX_GEAR + //"H_HelmetO_ViperSP_ghex_F", // Special helmet with in-built NVGs and thermal :o + "H_HelmetB_Enh_tna_F", + "H_HelmetSpecO_ghex_F", + "H_HelmetLeaderO_ghex_F", + #endif + "H_HelmetSpecB_paint1", + "H_HelmetIA_camo", + "H_HelmetLeaderO_ocamo", + "H_HelmetLeaderO_oucamo" + ]; + DMS_sniper_clothes = [ // Uniforms for Sniper Class + #ifdef GIVE_AI_APEX_GEAR + "U_B_T_Sniper_F", + "U_B_T_FullGhillie_tna_F", // Invisible to thermal? 0_o + "U_O_T_Sniper_F", + "U_O_T_FullGhillie_tna_F", + #endif + "U_O_GhillieSuit", + "U_B_FullGhillie_ard", + "U_B_FullGhillie_lsh", + "U_B_FullGhillie_sard", + "U_B_GhillieSuit", + "U_I_FullGhillie_ard", + "U_I_FullGhillie_lsh", + "U_I_FullGhillie_sard", + "U_I_GhillieSuit", + "U_O_FullGhillie_ard", + "U_O_FullGhillie_lsh", + "U_O_FullGhillie_sard" + ]; + DMS_sniper_vests = [ // Vests for Sniper Class + #ifdef GIVE_AI_APEX_GEAR + "V_PlateCarrier2_tna_F", + "V_PlateCarrierSpec_tna_F", + "V_PlateCarrierGL_tna_F", + "V_PlateCarrier2_rgr_noflag_F", + #endif + "V_PlateCarrierH_CTRG", + "V_PlateCarrierSpec_rgr", + "V_PlateCarrierGL_blk", + "V_PlateCarrierGL_mtp", + "V_PlateCarrierGL_rgr", + "V_PlateCarrierSpec_blk", + "V_PlateCarrierSpec_mtp", + "V_PlateCarrierL_CTRG", + "V_TacVest_blk_POLICE", + "V_PlateCarrierIA2_dgtl", + "V_HarnessO_brn", + "V_HarnessO_gry" + ]; + DMS_sniper_backpacks = [ // Backpacks for Sniper Class + #ifdef GIVE_AI_APEX_GEAR + "B_Bergen_tna_F", + "B_Bergen_hex_F", + "B_Carryall_ghex_F", + "B_ViperHarness_ghex_F", + "B_ViperHarness_blk_F", + "B_ViperLightHarness_ghex_F", + "B_ViperLightHarness_khk_F", + #endif + "B_Bergen_rgr", + "B_Carryall_oli", + "B_Kitbag_mcamo", + "B_Carryall_cbr", + "B_Bergen_blk" + ]; + + DMS_ai_SupportedClasses = [ // Allowed AI classes. If you want to create your own class, make sure you define everything as I've defined above, and add it here + "assault", + "MG", + "sniper" + ]; + + DMS_ai_SupportedRandomClasses = [ // Allowed "random" AI presets here if you want to create different random presets. + "random", + "random_non_assault", + "random_non_MG", + "random_non_sniper" + ]; + + DMS_random_AI = [ // Random AI preset that contains all default classes | DEFAULT: 60% Assault, 20% MG, 20% Sniper + "assault", + "assault", + "assault", + "MG", + "sniper" + ]; + + DMS_random_non_assault_AI = [ // Random AI preset that excludes the "assault" class + "MG", + "MG", + "sniper" + ]; + + DMS_random_non_MG_AI = [ // Random AI preset that excludes the "MG" class + "assault", + "assault", + "sniper" + ]; + + DMS_random_non_sniper_AI = [ // Random AI preset that excludes the "sniper" class + "assault", + "assault", + "MG" + ]; + + DMS_ai_use_launchers = true; // Enable/disable spawning an AI in a group with a launcher + DMS_ai_launchers_per_group = 2; // How many units per AI group can get a launcher. + DMS_ai_use_launchers_chance = 50; // Percentage chance to actually spawn the launcher (per-unit). With "DMS_ai_launchers_per_group" set to 2, and "DMS_ai_use_launchers_chance" set to 50, there will be an average of 1 launcher per group. + DMS_AI_launcher_ammo_count = 2; // How many rockets an AI will get with its launcher + DMS_ai_remove_launchers = true; // Remove rocket launchers on AI death + + DMS_AI_wep_launchers_AT = [ // AT Launchers + #ifdef GIVE_AI_APEX_WEAPONS + "launch_RPG7_F", + #endif + "launch_NLAW_F", + "launch_RPG32_F", + "launch_B_Titan_short_F" + ]; + DMS_AI_wep_launchers_AA = [ // AA Launchers + "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 */ + + +/* Loot Settings */ + DMS_GodmodeCrates = true; // Whether or not crates will have godmode after being filled with loot. + DMS_MinimumMagCount = 3; // Minimum number of magazines for weapons. + DMS_MaximumMagCount = 5; // Maximum number of magazines for weapons. + DMS_CrateCase_Sniper = [ // If you pass "Sniper" in _lootValues, then it will spawn these weapons/items/backpacks + [ + ["Rangefinder",1], + ["srifle_GM6_F",1], + ["srifle_LRR_F",1], + ["srifle_EBR_F",1], + ["hgun_Pistol_heavy_01_F",1], + ["hgun_PDW2000_F",1] + ], + [ + ["ItemGPS",1], + ["U_B_FullGhillie_ard",1], + ["U_I_FullGhillie_lsh",1], + ["U_O_FullGhillie_sard",1], + ["U_O_GhillieSuit",1], + ["V_PlateCarrierGL_blk",1], + ["V_HarnessO_brn",1], + ["Exile_Item_InstaDoc",3], + ["Exile_Item_Surstromming_Cooked",5], + ["Exile_Item_PlasticBottleFreshWater",5], + ["optic_DMS",1], + ["acc_pointer_IR",1], + ["muzzle_snds_B",1], + ["optic_LRPS",1], + ["optic_MRD",1], + ["muzzle_snds_acp",1], + ["optic_Holosight_smg",1], + ["muzzle_snds_L",1], + ["5Rnd_127x108_APDS_Mag",3], + ["7Rnd_408_Mag",3], + ["20Rnd_762x51_Mag",5], + ["11Rnd_45ACP_Mag",3], + ["30Rnd_9x21_Mag",3] + ], + [ + ["B_Carryall_cbr",1], + ["B_Kitbag_mcamo",1] + ] + ]; + DMS_BoxWeapons = [ // List of weapons that can spawn in a crate + #ifdef USE_MARKSMAN_DLC_WEAPONS_IN_CRATES + "srifle_DMR_02_F", + "srifle_DMR_03_woodland_F", + //"srifle_DMR_04_F", // ASP-1 Kir + "srifle_DMR_05_blk_F", + "srifle_DMR_06_olive_F", + "MMG_01_hex_F", + "MMG_02_black_F", + #endif + + #ifdef USE_APEX_WEAPONS_IN_CRATES + "arifle_AK12_F", + "arifle_ARX_ghex_F", + "arifle_CTAR_blk_F", + "arifle_SPAR_01_khk_F", + "arifle_SPAR_03_khk_F", + //"srifle_DMR_07_ghex_F", // Oh great, a 6.5mm 20 round sniper rifle... because everybody wanted a nerfed MXM :p + "LMG_03_F", + #endif + "Exile_Melee_Axe", + "Exile_Melee_SledgeHammer", + //"Exile_Melee_Shovel", // Not really interesting for players... + "arifle_Katiba_GL_F", + "arifle_MX_GL_Black_F", + "arifle_Mk20_GL_F", + "arifle_TRG21_GL_F", + "arifle_Katiba_F", + "arifle_MX_Black_F", + "arifle_TRG21_F", + "arifle_TRG20_F", + "arifle_Mk20_plain_F", + "arifle_Mk20_F", + "Exile_Weapon_AK107", + "Exile_Weapon_AK107_GL", + "Exile_Weapon_AK74_GL", + "Exile_Weapon_AK47", + "Exile_Weapon_AKS_Gold", + "LMG_Zafir_F", + "LMG_Mk200_F", + "arifle_MX_SW_Black_F", + "Exile_Weapon_RPK", + "Exile_Weapon_PK", + "Exile_Weapon_PKP", + "srifle_EBR_F", + "srifle_DMR_01_F", + "srifle_GM6_F", + "srifle_LRR_F", + "arifle_MXM_Black_F", + "Exile_Weapon_DMR", + "Exile_Weapon_SVD", + "Exile_Weapon_VSSVintorez", + "Exile_Weapon_CZ550", + "Exile_Weapon_SVDCamo" + ]; + DMS_BoxFood = [ // List of food that can spawn in a crate. + "Exile_Item_GloriousKnakworst_Cooked", + "Exile_Item_Surstromming_Cooked", + "Exile_Item_SausageGravy_Cooked", + "Exile_Item_ChristmasTinner_Cooked", + "Exile_Item_BBQSandwich_Cooked", + "Exile_Item_Catfood_Cooked", + "Exile_Item_DogFood_Cooked", + "Exile_Item_EMRE", + "Exile_Item_BeefParts", + "Exile_Item_Noodles", + "Exile_Item_SeedAstics", + "Exile_Item_Raisins", + "Exile_Item_Moobar", + "Exile_Item_InstantCoffee" + ]; + DMS_BoxDrinks = [ + "Exile_Item_PlasticBottleCoffee", + "Exile_Item_PowerDrink", + "Exile_Item_PlasticBottleFreshWater", + "Exile_Item_EnergyDrink", + "Exile_Item_MountainDupe", + "Exile_Item_ChocolateMilk" + ]; + DMS_BoxMeds = [ + "Exile_Item_InstaDoc", + "Exile_Item_Vishpirin", + "Exile_Item_Bandage" + ]; + DMS_BoxSurvivalSupplies = [ //List of survival supplies (food/drink/meds) that can spawn in a crate. "DMS_BoxFood", "DMS_BoxDrinks", and "DMS_BoxMeds" is automatically added to this list. + "Exile_Item_Matches", + "Exile_Item_CookingPot", + "Exile_Melee_Axe", + "Exile_Item_CanOpener" + ] + DMS_BoxFood + DMS_BoxDrinks + DMS_BoxMeds; + DMS_Box_BaseParts_Wood = [ // List of wooden base parts. + "Exile_Item_WoodWallKit", + "Exile_Item_WoodWallHalfKit", + "Exile_Item_WoodWindowKit", + "Exile_Item_WoodDoorKit", + "Exile_Item_WoodDoorwayKit", + "Exile_Item_WoodGateKit", + "Exile_Item_WoodFloorKit", + "Exile_Item_WoodFloorPortKit", + "Exile_Item_WoodStairsKit" + ]; + DMS_Box_BaseParts_Concrete = [ // List of concrete base parts + "Exile_Item_ConcreteWallKit", + "Exile_Item_ConcreteWindowKit", + "Exile_Item_ConcreteDoorKit", + "Exile_Item_ConcreteDoorwayKit", + "Exile_Item_ConcreteGateKit", + "Exile_Item_ConcreteFloorKit", + "Exile_Item_ConcreteFloorPortKit", + "Exile_Item_ConcreteStairsKit" + ]; + DMS_BoxBaseParts = [ // List of all base parts to spawn. Weighted towards wood base parts. + "Exile_Item_FortificationUpgrade", + "Exile_Item_FortificationUpgrade", + "Exile_Item_SandBagsKit_Long", + "Exile_Item_SandBagsKit_Long", + "Exile_Item_SandBagsKit_Corner", + "Exile_Item_SandBagsKit_Corner", + "Exile_Item_HBarrier5Kit" + ] + DMS_Box_BaseParts_Wood + DMS_Box_BaseParts_Wood + DMS_Box_BaseParts_Wood + DMS_Box_BaseParts_Concrete; + DMS_BoxCraftingMaterials = [ + "Exile_Item_Cement", + "Exile_Item_Sand", + "Exile_Item_Sand", + "Exile_Item_WaterCanisterDirtyWater", + "Exile_Item_MetalBoard", + "Exile_Item_MetalPole", + "Exile_Item_MetalPole", + "Exile_Item_JunkMetal", + "Exile_Item_JunkMetal", + "Exile_Item_JunkMetal", + "Exile_Item_WoodPlank", + "Exile_Item_WoodPlank", + "Exile_Item_WoodPlank", + "Exile_Item_WoodPlank" + ]; + DMS_BoxTools = [ + "Exile_Item_Grinder", + "Exile_Item_Handsaw", + "Exile_Item_CanOpener", + "Exile_Item_Pliers", + "Exile_Item_Screwdriver", + "Exile_Item_Foolbox" + ]; + DMS_BoxBuildingSupplies = [ // List of building supplies that can spawn in a crate ("DMS_BoxBaseParts", "DMS_BoxCraftingMaterials", and "DMS_BoxTools" are automatically added to this list. "DMS_BoxCraftingMaterials" is added twice for weight.) + "Exile_Item_DuctTape", + "Exile_Item_PortableGeneratorKit" + ] + DMS_BoxBaseParts + DMS_BoxCraftingMaterials + DMS_BoxCraftingMaterials + DMS_BoxTools; + DMS_BoxOptics = [ // List of optics that can spawn in a crate + "optic_Arco", + "optic_Hamr", + "optic_Aco", + "optic_Holosight", + "optic_MRCO", + "optic_SOS", + "optic_DMS", + "optic_LRPS", + "optic_Nightstalker" // Nightstalker scope lost thermal in Exile v0.9.4 + ]; + DMS_BoxBackpacks = [ //List of backpacks that can spawn in a crate + "B_Bergen_rgr", + "B_Carryall_oli", + "B_Kitbag_mcamo", + "B_Carryall_cbr", + "B_FieldPack_oucamo", + "B_FieldPack_cbr", + "B_Bergen_blk" + ]; + DMS_BoxItems = DMS_BoxSurvivalSupplies+DMS_BoxBuildingSupplies+DMS_BoxOptics; // Random "items" can spawn optics, survival supplies, or building supplies + + DMS_Box_BreachingCharges = [ // List of breaching charges (weighted). Not used (yet). + "BreachingChargeBigMomma", + "BreachingChargeMetal", + "BreachingChargeMetal", + "BreachingChargeWood", + "BreachingChargeWood", + "BreachingChargeWood" + ]; + + 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" + ]; + DMS_RareLootChance = 10; // Percentage Chance to spawn rare loot in any crate | Default: 10% + + // Vehicles + DMS_ArmedVehicles = [ // List of armed vehicles that can spawn + #ifdef USE_APEX_VEHICLES + "B_T_LSV_01_armed_F", + "O_T_LSV_02_armed_F", + #endif + "Exile_Car_Offroad_Armed_Guerilla01" + ]; + + DMS_MilitaryVehicles = [ // List of (unarmed) military vehicles that can spawn + #ifdef USE_APEX_VEHICLES + "B_T_LSV_01_unarmed_F", + "O_T_LSV_02_unarmed_F", + #endif + "Exile_Car_Strider", + "Exile_Car_Hunter", + "Exile_Car_Ifrit" + ]; + + DMS_TransportTrucks = [ // List of transport trucks that can spawn + "Exile_Car_Van_Guerilla01", + "Exile_Car_Zamak", + "Exile_Car_Tempest", + "Exile_Car_HEMMT", + "Exile_Car_Ural_Open_Military", + "Exile_Car_Ural_Covered_Military" + ]; + + DMS_RefuelTrucks = [ // List of refuel trucks that can spawn + "Exile_Car_Van_Fuel_Black", + "Exile_Car_Van_Fuel_White", + "Exile_Car_Van_Fuel_Red", + "Exile_Car_Van_Fuel_Guerilla01", + "Exile_Car_Van_Fuel_Guerilla02", + "Exile_Car_Van_Fuel_Guerilla03" + ]; + + DMS_CivilianVehicles = [ // List of civilian vehicles that can spawn + #ifdef USE_APEX_VEHICLES + "C_Offroad_02_unarmed_F", + "I_C_Van_01_transport_F", + #endif + "Exile_Car_SUV_Red", + "Exile_Car_Hatchback_Rusty1", + "Exile_Car_Hatchback_Rusty2", + "Exile_Car_Hatchback_Sport_Red", + "Exile_Car_SUV_Red", + "Exile_Car_Offroad_Rusty2", + "Exile_Bike_QuadBike_Fia" + ]; + + DMS_TransportHelis = [ // List of transport helis that can spawn + #ifdef USE_APEX_VEHICLES + "B_T_VTOL_01_infantry_F", + "O_T_VTOL_02_infantry_F", + #endif + "Exile_Chopper_Hummingbird_Green", + "Exile_Chopper_Orca_BlackCustom", + "Exile_Chopper_Mohawk_FIA", + "Exile_Chopper_Huron_Black", + "Exile_Chopper_Hellcat_Green", + "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; +/* Loot Settings */ + + +DMS_ConfigLoaded = true; diff --git a/@ExileServer/addons/a3_dms/fn_DMS_postInit.sqf b/@ExileServer/addons/a3_dms/fn_DMS_postInit.sqf new file mode 100644 index 0000000..7d38e86 --- /dev/null +++ b/@ExileServer/addons/a3_dms/fn_DMS_postInit.sqf @@ -0,0 +1,260 @@ +/* + DMS post-init + + Created by eraser1 and Defent +*/ + +if !(isServer) exitWith +{ + for "_i" from 0 to 99 do + { + diag_log "The DMS PBO is for the SERVER ONLY. It will NOT work for any form of client! DMS launch cancelled."; + }; +}; + + + +if (isNil "DMS_ConfigLoaded") exitWith +{ + for "_i" from 0 to 99 do + { + diag_log "DMS ERROR :: You have made an error in your DMS config.sqf! Please look for any script errors. Cancelling DMS Launch."; + }; +}; + + +// This code is NECESSARY for spawning persistent vehicles. DO NOT REMOVE THIS CODE UNLESS YOU KNOW WHAT YOU ARE DOING +if !("isKnownAccount:DMS_PersistentVehicle" call ExileServer_system_database_query_selectSingleField) then +{ + "createAccount:DMS_PersistentVehicle:DMS_PersistentVehicle" call ExileServer_system_database_query_fireAndForget; +}; + + + + + +// Some custom maps don't have the proper safePos config entries. +// DMS no longer uses these values as of October 30, 2015. +switch (toLower worldName) do +{ + case "altis": // [16000,16000] w/ radius of 16000 works well for Altis + { + DMS_MapCenterPos = [16000,16000]; + DMS_MapRadius = 16000; + }; + case "bornholm": // Thanks to thirdhero for testing this info + { + DMS_MapCenterPos = [11265,11265]; + DMS_MapRadius = 12000; + }; + case "esseker": // Thanks to Flowrider for this info + { + DMS_MapCenterPos = [6275,6350]; + DMS_MapRadius = 5000; + }; + case "taviana"; // Thanks to JamieKG for this info + case "tavi": + { + DMS_MapCenterPos = [12800,12800]; + DMS_MapRadius = 12800; + }; + default // Use "worldSize" to determine map center/radius (not always very nice). + { + private "_middle"; + _middle = worldSize/2; + DMS_MapCenterPos = [_middle,_middle]; + DMS_MapRadius = _middle; + }; +}; + +// Since we use primarily ATL +DMS_MapCenterPos set [2,0]; + + + +EAST setFriend[WEST,0]; +EAST setFriend[RESISTANCE,0]; +RESISTANCE setFriend[WEST,0]; +RESISTANCE setFriend[EAST,0]; +WEST setFriend[EAST,0]; +WEST setFriend[RESISTANCE,0]; + + + +if ((!isNil "A3XAI_isActive") && {!DMS_ai_offload_Only_DMS_AI}) then +{ + diag_log 'DMS DETECTED A3XAI. Enabling "DMS_ai_offload_Only_DMS_AI"!'; + DMS_ai_offload_Only_DMS_AI = true; +}; + +if ((isClass (configFile >> "CfgPatches" >> "Ryanzombies")) && {!DMS_ai_offload_Only_DMS_AI}) then +{ + diag_log 'DMS DETECTED RyanZombies. Enabling "DMS_ai_offload_Only_DMS_AI"!'; + DMS_ai_offload_Only_DMS_AI = true; +}; + +if !(DMS_ai_offload_to_client) then +{ + DMS_ai_offloadOnUnfreeze = false; +}; + +if !(DMS_ai_allowFreezing) then +{ + DMS_ai_freezeOnSpawn = false; +}; + + + +DMS_A3_AllMarkerColors = []; +for "_i" from 0 to ((count(configfile >> "CfgMarkerColors"))-1) do +{ + DMS_A3_AllMarkerColors pushBack (toLower (configName ((configfile >> "CfgMarkerColors") select _i))); +}; + + +if !((toLower DMS_MissionMarkerWinDotColor) in DMS_A3_AllMarkerColors) then +{ + diag_log format ["DMS ERROR :: Unsupported color for DMS_MissionMarkerWinDotColor (""%1""). Switching color to ""ColorBlue"".",DMS_MissionMarkerWinDotColor]; + DMS_MissionMarkerWinDotColor = "ColorBlue"; +}; + +if !((toLower DMS_MissionMarkerLoseDotColor) in DMS_A3_AllMarkerColors) then +{ + diag_log format ["DMS ERROR :: Unsupported color for DMS_MissionMarkerLoseDotColor (""%1""). Switching color to ""ColorRed"".",DMS_MissionMarkerLoseDotColor]; + DMS_MissionMarkerLoseDotColor = "ColorRed"; +}; + + + +// Send Client Functions using compileFinal for security. +publicVariable "DMS_CLIENT_fnc_spawnDynamicText"; +publicVariable "DMS_CLIENT_fnc_spawnTextTiles"; +publicVariable "DMS_CLIENT_fnc_hintSilent"; + +publicVariable "DMS_Version"; + + +format["DMS_Version: %1",DMS_Version] remoteExecCall ["diag_log", -2, "DMS_LogVersion_JIP_ID"]; + + + +// Add the weighted predefined locations to the list of predefined locations +{ + for "_i" from 1 to (_x select 1) do + { + DMS_PredefinedMissionLocations pushBack (_x select 0); + }; +} forEach DMS_PredefinedMissionLocations_WEIGHTED; + + + +// Set up the minimum/maximum co-ordinate values for x and y... +DMS_MinMax_X_Coords = [DMS_MinDistFromWestBorder, worldSize - DMS_MinDistFromEastBorder]; +DMS_MinMax_Y_Coords = [DMS_MinDistFromSouthBorder, worldSize - DMS_MinDistFromNorthBorder]; + + +execFSM "\x\addons\dms\FSM\missions.fsm"; + + +if (DMS_ShowDifficultyColorLegend) then +{ + private "_title"; + _title = createmarker ["DMS_MissionMarker_DifficultyColorLegend",[-500,-200]]; + _title setMarkerColor "ColorRed"; + _title setmarkertext "DMS Mission Difficulties Color Legend"; + _title setMarkerType "mil_dot"; + _title setMarkerAlpha 0.5; + { + private _difficulty = _x; + + private _color = "ColorGreen"; + private _markerType = "ExileMissionEasyIcon"; + + + switch (_difficulty) do + { + case "moderate": + { + _color = "ColorYellow"; + _markerType = "ExileMissionModerateIcon"; + }; + case "difficult": + { + _color = "ColorRed"; + _markerType = "ExileMissionDifficultIcon"; + }; + case "hardcore": + { + _color = "ColorBlack"; + _markerType = "ExileMissionHardcoreIcon"; + }; + }; + + private _num = -200 * (_forEachIndex - 0.5); + private _pos = [100,_num]; + + if (DMS_ShowMarkerCircle) then + { + private _circle = createMarker [format ["DMS_MissionMarker_DifficultyColor_%1",_color], _pos]; + _circle setMarkerColor _color; + _circle setMarkerShape "ELLIPSE"; + _circle setMarkerBrush "Solid"; + _circle setMarkerSize [100,100]; + }; + + private _dot = createMarker [format ["DMS_MissionMarker_Difficulty_%1",_difficulty],_pos]; + _dot setMarkerType _markerType; + _dot setMarkerText _difficulty; + _dot setMarkerAlpha 0.5; + } forEach ["hardcore","difficult","moderate","easy"]; +}; + + +// Add heli paratroopers monitor to the thread system. +[5, DMS_fnc_HeliParatroopers_Monitor, [], true] call ExileServer_system_thread_addTask; + + +{ + [_x] call DMS_fnc_ImportFromM3E_Static; // Spawn all of the bases that are supposed to be spawned on server startup. +} forEach DMS_BasesToImportOnServerStart; + + +{ + missionNamespace setVariable + [ + format["DMS_Mission_%1",_x], + compileFinal preprocessFileLineNumbers (format ["\x\addons\DMS\missions\bandit\%1.sqf",_x]) + ]; + + [_x] call DMS_fnc_SpawnBanditMission; +} forEach DMS_BanditMissionsOnServerStart; + + +if (DMS_StaticMission) then +{ + private _temp = DMS_StaticMinPlayerDistance; + DMS_StaticMinPlayerDistance = 0; + + { + missionNamespace setVariable + [ + format["DMS_StaticMission_%1",_x], + compileFinal preprocessFileLineNumbers (format ["\x\addons\DMS\missions\static\%1.sqf",_x]) + ]; + + [_x] call DMS_fnc_SpawnStaticMission; + } forEach DMS_StaticMissionsOnServerStart; + + DMS_StaticMinPlayerDistance = _temp; +}; + + +for "_i" from 1 to DMS_RandomBanditMissionsOnStart do +{ + [selectRandom DMS_BanditMissionTypesArray] call DMS_fnc_SpawnBanditMission; +}; + + + + +format ["DMS post-init complete. productVersion: %1 | infiSTAR version: %2", productVersion, if (!isNil "INFISTARVERSION") then {INFISTARVERSION} else {"not installed"}] call DMS_fnc_DebugLog; diff --git a/@ExileServer/addons/a3_dms/fn_DMS_preInit.sqf b/@ExileServer/addons/a3_dms/fn_DMS_preInit.sqf new file mode 100644 index 0000000..ba1bb87 --- /dev/null +++ b/@ExileServer/addons/a3_dms/fn_DMS_preInit.sqf @@ -0,0 +1,146 @@ +/* + DMS Pre-init + Created by eraser1 +*/ +#define CALLFILE(FILE) call compile preprocessFileLineNumbers FILE; + +// Enables debug logging in DMS functions. !!!NOTE:!!! You must uncomment the line above if you want DMS to even check whether or not debug mode is enabled! +// Logs will be written in the RPT, and if you have infiSTAR's "ARMA_LOG" DLL loaded, it will also produce logs in the server directory. +// If you have mARMA by maca134, DMS will also utilize mARMA logs. +// This will produce A LOT of logs, so make sure you leave it to false unless you know what you're doing. +DMS_DEBUG = false; + + + +DMS_CleanUpList = []; + +DMS_Version = getText (configFile >> "CfgPatches" >> "a3_dms" >> "a3_DMS_version"); + + +//Load main config +CALLFILE("\x\addons\dms\config.sqf"); + +// Let's be honest - you know it's gonna happen. +if (isNil "DMS_AI_NamingType") then +{ + for "_i" from 0 to 99 do + { + diag_log format["!!!!!!!!MAKE SURE YOUR DMS CONFIG IS UPDATED!!!!!"]; + }; + DMS_ConfigLoaded = nil; +}; + + +//Load map-specific configs. Should make it easier for people with multiple servers/maps. One PBO to rule them all... +if (DMS_Use_Map_Config) then +{ + private _file = preprocessFileLineNumbers (format ["\x\addons\dms\map_configs\%1_config.sqf",toLower worldName]); + if (_file isEqualTo "") then + { + 'You need to set the config value "DMS_Use_Map_Config" to false!' call DMS_fnc_DebugLog; + } + else + { + call compile _file; + }; +}; + +DMS_MagRange = DMS_MaximumMagCount - DMS_MinimumMagCount; + +/* + Original Functions from + http://maca134.co.uk/portfolio/m3editor-arma-3-map-editor/ + + Slightly modified by eraser1 +*/ + +M3E_fnc_getCenter = DMS_fnc_GetCenter; + +M3E_fnc_subArr = DMS_fnc_SubArr; + +// Because I fucked up the name on first implementation and don't want to mess anybody up who didn't realize to change every occurence of "DMS_MaxSurfaceNormal" to "DMS_MinSurfaceNormal". +DMS_MaxSurfaceNormal = DMS_MinSurfaceNormal; + + +DMS_AttemptsUntilThrottle = DMS_AttemptsUntilThrottle + 1; + +DMS_HelisToClean = []; +DMS_HeliParatrooper_Arr = []; +DMS_FrozenAIGroups = []; + + + +DMS_CLIENT_fnc_spawnDynamicText = compileFinal +(" +if (isNil 'DMS_CLIENT_DynamicText_inProgress') then +{ + DMS_CLIENT_DynamicText_inProgress = true; + _this spawn + { + [ + _this, + 0, + safeZoneY, + "+str DMS_dynamicText_Duration+", + "+str DMS_dynamicText_FadeTime+", + 0, + 24358 + ] call BIS_fnc_dynamicText; + DMS_CLIENT_DynamicText_inProgress = nil; + }; +} +else +{ + ["+str (DMS_dynamicText_Duration+DMS_dynamicText_FadeTime) +",{_this call DMS_CLIENT_fnc_spawnDynamicText},_this,false,false] call ExileClient_system_thread_addTask; +}; +"); + +DMS_CLIENT_fnc_spawnTextTiles = compileFinal +(" +if (isNil 'DMS_CLIENT_TextTiles_inProgress') then +{ + DMS_CLIENT_TextTiles_inProgress = true; + _this spawn + { + [ + parseText _this, + [ + 0, + safeZoneY, + 1, + 1 + ], + [10,10], + "+str DMS_textTiles_Duration+", + "+str DMS_textTiles_FadeTime+", + 0 + ] call BIS_fnc_textTiles; + DMS_CLIENT_TextTiles_inProgress = nil; + }; +} +else +{ + ["+str (DMS_textTiles_Duration+DMS_textTiles_FadeTime) +",{_this call DMS_CLIENT_fnc_spawnTextTiles},_this,false,false] call ExileClient_system_thread_addTask; +}; +"); + +DMS_CLIENT_fnc_hintSilent = compileFinal "hintSilent parsetext format['%1',_this];"; + + +// Initialize mission variables... +CALLFILE("\x\addons\dms\missions\static_init.sqf"); +CALLFILE("\x\addons\dms\missions\mission_init.sqf"); + + +{ + private _mission = _x select 0; + + missionNamespace setVariable + [ + format["DMS_SpecialMission_%1",_mission], + compileFinal preprocessFileLineNumbers (format ["\x\addons\DMS\missions\special\%1.sqf",_mission]) + ]; + + missionNamespace setVariable [format["DMS_SpecialMissionSpawnCount_%1",_mission], 0]; + missionNamespace setVariable [format["DMS_SpecialMissionLastSpawn_%1",_mission], 0]; +} forEach DMS_SpecialMissions; diff --git a/@ExileServer/addons/a3_dms/map_configs/altis_config.sqf b/@ExileServer/addons/a3_dms/map_configs/altis_config.sqf new file mode 100644 index 0000000..65f2347 --- /dev/null +++ b/@ExileServer/addons/a3_dms/map_configs/altis_config.sqf @@ -0,0 +1,37 @@ +/* + Custom configs for Altis. + Sample by eraser1 + + All of these configs exist in the main config. The configs below will simply override any config from the main config (although the majority of them are the same). + Explanations to all of these configs also exist in the main config. +*/ + +DMS_findSafePosBlacklist append +[ + [[23600,18200],1500] // Salt flats are blacklisted for Altis by default. +]; + +// These configs are the default values from the main config. Just included here as an example. +DMS_PlayerNearBlacklist = 2000; +DMS_SpawnZoneNearBlacklist = 2500; +DMS_TraderZoneNearBlacklist = 2500; +DMS_MissionNearBlacklist = 2500; +DMS_WaterNearBlacklist = 500; + +// Altis is pretty flat, so we can make the min surfaceNormal ... stricter? more strict? Who cares, you get the idea. +DMS_MinSurfaceNormal = 0.95; + + +// Making these configs below as strict as possible will help in reducing the number of attempts taken to find a valid position, and as a result, improve performance. + +DMS_MinDistFromWestBorder = 2000; // There's at least 2km of ocean from the west edge to the first bit of land. +DMS_MinDistFromEastBorder = 2250; // There's over 2km of ocean from the east edge to the first bit of land. +DMS_MinDistFromSouthBorder = 5000; // There's about 5km of ocean from the south edge to the first bit of land. +DMS_MinDistFromNorthBorder = 5200; // There's around 5km of ocean from the north edge to the first bit of land (including the island). + + +// Add the "saltflats" and "slums" mission to the existing mission types. +DMS_StaticMissionTypes append [["saltflats",1],["slums",1]]; + +// Add the "salt flats base" and "slums" to the "bases" to spawn on server startup. NOTE: "append" and "pushback" are NOT the same. +DMS_BasesToImportOnServerStart append ["saltflatsbase","slums_objects"]; diff --git a/@ExileServer/addons/a3_dms/map_configs/bornholm_config.sqf b/@ExileServer/addons/a3_dms/map_configs/bornholm_config.sqf new file mode 100644 index 0000000..8425c77 --- /dev/null +++ b/@ExileServer/addons/a3_dms/map_configs/bornholm_config.sqf @@ -0,0 +1,25 @@ +/* + Custom configs for Bornholm. + Sample by eraser1 + + All of these configs exist in the main config. The configs below will simply override any config from the main config (although the majority of them are the same). + Explanations to all of these configs also exist in the main config. +*/ + +// These configs are the default values from the main config. Just included here as an example. +DMS_PlayerNearBlacklist = 2000; +DMS_SpawnZoneNearBlacklist = 2500; +DMS_TraderZoneNearBlacklist = 2500; +DMS_MissionNearBlacklist = 2500; +DMS_WaterNearBlacklist = 500; + +// Bornholm seems to be fine with a greater minimum surfaceNormal. +DMS_MinSurfaceNormal = 0.95; + + +// Making these configs below as strict as possible will help in reducing the number of attempts taken to find a valid position, and as a result, improve performance. + +DMS_MinDistFromWestBorder = 1000; // About 1km of plain ocean to the west +DMS_MinDistFromEastBorder = 4000; // Just about 4km of ocean to the east +DMS_MinDistFromSouthBorder = 1000; // We get the proper landmass at about 1km from the south +DMS_MinDistFromNorthBorder = 1500; // Avoid getting missions at the northern "tip" diff --git a/@ExileServer/addons/a3_dms/map_configs/chernarus_config.sqf b/@ExileServer/addons/a3_dms/map_configs/chernarus_config.sqf new file mode 100644 index 0000000..057bbe7 --- /dev/null +++ b/@ExileServer/addons/a3_dms/map_configs/chernarus_config.sqf @@ -0,0 +1,11 @@ +/* + Custom configs for Chernarus. + Created by Hollow (slight edits by eraser1). +*/ + +// Making these configs below as strict as possible will help in reducing the number of attempts taken to find a valid position, and as a result, improve performance. + +DMS_MinDistFromWestBorder = 750; +DMS_MinDistFromEastBorder = 2500; +DMS_MinDistFromSouthBorder = 3500; +DMS_MinDistFromNorthBorder = 1000; diff --git a/@ExileServer/addons/a3_dms/map_configs/chernarus_isles_config.sqf b/@ExileServer/addons/a3_dms/map_configs/chernarus_isles_config.sqf new file mode 100644 index 0000000..50ebc84 --- /dev/null +++ b/@ExileServer/addons/a3_dms/map_configs/chernarus_isles_config.sqf @@ -0,0 +1,11 @@ +/* + Custom configs for Chernarus Isles. + Created by [FPS]kuplion. +*/ + +// Making these configs below as strict as possible will help in reducing the number of attempts taken to find a valid position, and as a result, improve performance. + +DMS_MinDistFromWestBorder = 750; +DMS_MinDistFromEastBorder = 2500; +DMS_MinDistFromSouthBorder = 2500; +DMS_MinDistFromNorthBorder = 1000; diff --git a/@ExileServer/addons/a3_dms/map_configs/chernarus_summer_config.sqf b/@ExileServer/addons/a3_dms/map_configs/chernarus_summer_config.sqf new file mode 100644 index 0000000..42a041b --- /dev/null +++ b/@ExileServer/addons/a3_dms/map_configs/chernarus_summer_config.sqf @@ -0,0 +1,11 @@ +/* + Custom configs for Chernarus Summer. + Created by [FPS]kuplion. +*/ + +// Making these configs below as strict as possible will help in reducing the number of attempts taken to find a valid position, and as a result, improve performance. + +DMS_MinDistFromWestBorder = 750; +DMS_MinDistFromEastBorder = 2500; +DMS_MinDistFromSouthBorder = 3500; +DMS_MinDistFromNorthBorder = 1000; diff --git a/@ExileServer/addons/a3_dms/map_configs/chernarus_winter_config.sqf b/@ExileServer/addons/a3_dms/map_configs/chernarus_winter_config.sqf new file mode 100644 index 0000000..8b378ff --- /dev/null +++ b/@ExileServer/addons/a3_dms/map_configs/chernarus_winter_config.sqf @@ -0,0 +1,11 @@ +/* + Custom configs for Chernarus Winter. + Created by [FPS]kuplion. +*/ + +// Making these configs below as strict as possible will help in reducing the number of attempts taken to find a valid position, and as a result, improve performance. + +DMS_MinDistFromWestBorder = 750; +DMS_MinDistFromEastBorder = 2500; +DMS_MinDistFromSouthBorder = 3500; +DMS_MinDistFromNorthBorder = 1000; diff --git a/@ExileServer/addons/a3_dms/map_configs/chernarusredux_config.sqf b/@ExileServer/addons/a3_dms/map_configs/chernarusredux_config.sqf new file mode 100644 index 0000000..70bcaee --- /dev/null +++ b/@ExileServer/addons/a3_dms/map_configs/chernarusredux_config.sqf @@ -0,0 +1,12 @@ +/* + Custom configs for Chernarus Redux. + Created by [FPS]kuplion. + Map Name edited by MGTDB. +*/ + +// Making these configs below as strict as possible will help in reducing the number of attempts taken to find a valid position, and as a result, improve performance. + +DMS_MinDistFromWestBorder = 750; +DMS_MinDistFromEastBorder = 2500; +DMS_MinDistFromSouthBorder = 3500; +DMS_MinDistFromNorthBorder = 1000; diff --git a/@ExileServer/addons/a3_dms/map_configs/esseker_config.sqf b/@ExileServer/addons/a3_dms/map_configs/esseker_config.sqf new file mode 100644 index 0000000..855640f --- /dev/null +++ b/@ExileServer/addons/a3_dms/map_configs/esseker_config.sqf @@ -0,0 +1,15 @@ +/* + Custom configs for Esseker. + Sample by eraser1 + Credit goes to "Flowrider" and "Darth Rogue" for providing tested configs. + + All of these configs exist in the main config. The configs below will simply override any config from the main config. + Explanations to all of these configs also exist in the main config. +*/ + +// Reduce the blacklist range since Esseker is a smaller map. +DMS_PlayerNearBlacklist = 750; +DMS_SpawnZoneNearBlacklist = 1250; +DMS_TraderZoneNearBlacklist = 1250; +DMS_MissionNearBlacklist = 1250; +DMS_WaterNearBlacklist = 250; diff --git a/@ExileServer/addons/a3_dms/map_configs/kerama_config.sqf b/@ExileServer/addons/a3_dms/map_configs/kerama_config.sqf new file mode 100644 index 0000000..6e142a5 --- /dev/null +++ b/@ExileServer/addons/a3_dms/map_configs/kerama_config.sqf @@ -0,0 +1,24 @@ +/* + Custom configs for Kerama. + Created by InsertCoins + + All of these configs exist in the main config. The configs below will simply override any config from the main config. +*/ + +// Kerama is a pretty small island +DMS_WaterNearBlacklist = 100; + +// Kerama is not super flat +DMS_MinSurfaceNormal = 0.75; + +DMS_SpawnZoneNearBlacklist = 500; +DMS_TraderZoneNearBlacklist = 500; + + +// Making these configs below as strict as possible will help in reducing the number of attempts taken to find a valid position, and as a result, improve performance. +// Distances set up to ignore the small islands and the military islands in the north + +DMS_MinDistFromWestBorder = 7500; // There's at least 7.5km of ocean from the west edge to the first bit of land. +DMS_MinDistFromEastBorder = 7300; // There's over 7.3km of ocean from the east edge to the first bit of land. +DMS_MinDistFromSouthBorder = 4800; // There's about 4.8km of ocean from the south edge to the first bit of land. +DMS_MinDistFromNorthBorder = 4600; // There's around 4.6km of ocean from the north edge to the first bit of land (including the island). diff --git a/@ExileServer/addons/a3_dms/map_configs/malden_config.sqf b/@ExileServer/addons/a3_dms/map_configs/malden_config.sqf new file mode 100644 index 0000000..762cc46 --- /dev/null +++ b/@ExileServer/addons/a3_dms/map_configs/malden_config.sqf @@ -0,0 +1,10 @@ +DMS_MinDistFromWestBorder = 500; +DMS_MinDistFromEastBorder = 500; +DMS_MinDistFromSouthBorder = 500; +DMS_MinDistFromNorthBorder = 500; +DMS_MinSurfaceNormal = 0.8; +DMS_PlayerNearBlacklist = 500; +DMS_SpawnZoneNearBlacklist = 1500; +DMS_TraderZoneNearBlacklist = 1500; +DMS_MissionNearBlacklist = 2500; +DMS_WaterNearBlacklist = 100; diff --git a/@ExileServer/addons/a3_dms/map_configs/namalsk_config.sqf b/@ExileServer/addons/a3_dms/map_configs/namalsk_config.sqf new file mode 100644 index 0000000..372807d --- /dev/null +++ b/@ExileServer/addons/a3_dms/map_configs/namalsk_config.sqf @@ -0,0 +1,30 @@ +/* + Custom configs for Namalsk. + Created by Vishpala, slight adjustments by eraser1 + + All of these configs exist in the main config. The configs below will simply override any config from the main config. +*/ + +DMS_findSafePosBlacklist append +[ + [[4866.21,7962.4],[5085.27,8157.23]], // Sebjan Trader + [[4890.65,6535.2],[5090.37,6714.44]], // Object A2 + [[3908.65,8405.29],[4029.93,8542.39]] // Object A1 +]; + +// Namalsk is a pretty small island +DMS_WaterNearBlacklist = 100; + +// Namalsk is pretty flat +DMS_MinSurfaceNormal = 0.85; + +DMS_SpawnZoneNearBlacklist = 500; +DMS_TraderZoneNearBlacklist = 500; + + +// Making these configs below as strict as possible will help in reducing the number of attempts taken to find a valid position, and as a result, improve performance. + +DMS_MinDistFromWestBorder = 2000; // There's at least 2km of ocean from the west edge to the first bit of land. +DMS_MinDistFromEastBorder = 3500; // There's over 3km of ocean from the east edge to the first bit of land. +DMS_MinDistFromSouthBorder = 4500; // There's about 4.8km of ocean from the south edge to the first bit of land. +DMS_MinDistFromNorthBorder = 700; // There's around 750m of ocean from the north edge to the first bit of land (including the island). diff --git a/@ExileServer/addons/a3_dms/map_configs/napf_config.sqf b/@ExileServer/addons/a3_dms/map_configs/napf_config.sqf new file mode 100644 index 0000000..3fffa88 --- /dev/null +++ b/@ExileServer/addons/a3_dms/map_configs/napf_config.sqf @@ -0,0 +1,11 @@ +/* + Custom configs for Napf. + Created by Hollow (slight edits by eraser1) +*/ + +// Making these configs below as strict as possible will help in reducing the number of attempts taken to find a valid position, and as a result, improve performance. + +DMS_MinDistFromWestBorder = 1000; +DMS_MinDistFromEastBorder = 1000; +DMS_MinDistFromSouthBorder = 1800; +DMS_MinDistFromNorthBorder = 250; diff --git a/@ExileServer/addons/a3_dms/map_configs/panthera3_config.sqf b/@ExileServer/addons/a3_dms/map_configs/panthera3_config.sqf new file mode 100644 index 0000000..b49b4ba --- /dev/null +++ b/@ExileServer/addons/a3_dms/map_configs/panthera3_config.sqf @@ -0,0 +1,26 @@ +/* + Custom configs for Panthera3 (Panthera). + Sample by eraser1 + + All of these configs exist in the main config. The configs below will simply override any config from the main config. + Explanations to all of these configs also exist in the main config. +*/ + +// Let missions spawn closer to water, since we aren't spoiled for choice with all of the steep terrain. +DMS_WaterNearBlacklist = 200; + +// Panthera is super hilly/mountain-y, so we allow a tolerance of up to a 30 degree slope. +DMS_MinSurfaceNormal = 0.85; + + +// Thanks to JamieKG from Eternal Gamer for telling me about these optimized values :) +DMS_SpawnZoneNearBlacklist = 1500; +DMS_TraderZoneNearBlacklist = 1500; + + +// Comment out the below configs if you want missions to be able to spawn on the islands surrounding the mainland. + +DMS_MinDistFromWestBorder = 1500; +DMS_MinDistFromEastBorder = 1000; +DMS_MinDistFromSouthBorder = 1500; +DMS_MinDistFromNorthBorder = 2500; diff --git a/@ExileServer/addons/a3_dms/map_configs/tanoa_config.sqf b/@ExileServer/addons/a3_dms/map_configs/tanoa_config.sqf new file mode 100644 index 0000000..20871e1 --- /dev/null +++ b/@ExileServer/addons/a3_dms/map_configs/tanoa_config.sqf @@ -0,0 +1,22 @@ +/* + Custom configs for Tanoa. + Created by eraser1 + + All of these configs exist in the main config. The configs below will simply override any config from the main config. + Explanations to all of these configs also exist in the main config. +*/ + + +DMS_MinDistFromWestBorder = 1300; +DMS_MinDistFromEastBorder = 800; +DMS_MinDistFromSouthBorder = 1500; +DMS_MinDistFromNorthBorder = 1900; + +// Plenty of slopes +DMS_MinSurfaceNormal = 0.8; + + +DMS_StaticMissionsOnServerStart append +[ + "underwater_stash" +]; diff --git a/@ExileServer/addons/a3_dms/map_configs/tavi_config.sqf b/@ExileServer/addons/a3_dms/map_configs/tavi_config.sqf new file mode 100644 index 0000000..d4c19f7 --- /dev/null +++ b/@ExileServer/addons/a3_dms/map_configs/tavi_config.sqf @@ -0,0 +1,28 @@ +/* + Custom configs for Tavi (Taviana). + Sample by eraser1 + + All of these configs exist in the main config. The configs below will simply override any config from the main config (although the majority of them are the same). + Explanations to all of these configs also exist in the main config. +*/ + +DMS_findSafePosBlacklist append +[ + [[11375,16170],[14302,18600]], + [[13300,14670],[14875,16170]] +]; + +// These configs are the default values from the main config. Just included here as an example. +DMS_PlayerNearBlacklist = 2000; +DMS_SpawnZoneNearBlacklist = 2500; +DMS_TraderZoneNearBlacklist = 2500; +DMS_MissionNearBlacklist = 2500; +DMS_WaterNearBlacklist = 500; + + +// Making these configs below as strict as possible will help in reducing the number of attempts taken to find a valid position, and as a result, improve performance. + +DMS_MinDistFromWestBorder = 500; // The western island is pretty close to the western border. +DMS_MinDistFromEastBorder = 4500; // About 4.5km of ocean from the eastern border to the edge of the main east island. Set to 6000 if you want to "cut off" most of the Taviana Zoo area. +DMS_MinDistFromSouthBorder = 100; // The western island almost touches the southern border so this one is tiny... +DMS_MinDistFromNorthBorder = 3000; // About 3km from the northern tip of the east island to the edge. diff --git a/@ExileServer/addons/a3_dms/map_configs/taviana_config.sqf b/@ExileServer/addons/a3_dms/map_configs/taviana_config.sqf new file mode 100644 index 0000000..b8a6bd3 --- /dev/null +++ b/@ExileServer/addons/a3_dms/map_configs/taviana_config.sqf @@ -0,0 +1,28 @@ +/* + Custom configs for Taviana. + Sample by eraser1 + + All of these configs exist in the main config. The configs below will simply override any config from the main config (although the majority of them are the same). + Explanations to all of these configs also exist in the main config. +*/ + +DMS_findSafePosBlacklist append +[ + [[11375,16170],[14302,18600]], + [[13300,14670],[14875,16170]] +]; + +// These configs are the default values from the main config. Just included here as an example. +DMS_PlayerNearBlacklist = 2000; +DMS_SpawnZoneNearBlacklist = 2500; +DMS_TraderZoneNearBlacklist = 2500; +DMS_MissionNearBlacklist = 2500; +DMS_WaterNearBlacklist = 500; + + +// Making these configs below as strict as possible will help in reducing the number of attempts taken to find a valid position, and as a result, improve performance. + +DMS_MinDistFromWestBorder = 500; // The western island is pretty close to the western border. +DMS_MinDistFromEastBorder = 4500; // About 4.5km of ocean from the eastern border to the edge of the main east island. Set to 6000 if you want to "cut off" most of the Taviana Zoo area. +DMS_MinDistFromSouthBorder = 100; // The western island almost touches the southern border so this one is tiny... +DMS_MinDistFromNorthBorder = 3000; // About 3km from the northern tip of the east island to the edge. diff --git a/@ExileServer/addons/a3_dms/missions/bandit/bandits.sqf b/@ExileServer/addons/a3_dms/missions/bandit/bandits.sqf new file mode 100644 index 0000000..7e1d1b4 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/bandits.sqf @@ -0,0 +1,236 @@ +/* + Bandits Mission with new difficulty selection system + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_extraParams", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [25,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _classname or [_classname] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos","_pos ERROR",[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION bandits.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "easy", + "easy", + "moderate", + "moderate", + "moderate", + "difficult", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (3 + (round (random 2))); +_crate_weapons = (2 + (round (random 3))); +_crate_items = (2 + (round (random 4))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 2))); +_crate_weapons = (4 + (round (random 5))); +_crate_items = (4 + (round (random 6))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (4 + (round (random 3))); +_crate_weapons = (6 + (round (random 7))); +_crate_items = (6 + (round (random 8))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (4 + (round (random 4))); +_crate_weapons = (8 + (round (random 9))); +_crate_items = (8 + (round (random 10))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// Create Crate +_crate = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// Check to see if a special vehicle class is defined in "_extraParams", and make sure it's valid, otherwise use the default (Offroad Armed) +_vehClass = + if (_extraParams isEqualTo []) then + { + "Exile_Car_Offroad_Armed_Guerilla01" + } + else + { + if ((typeName _extraParams)=="STRING") then + { + _extraParams + } + else + { + if (((typeName _extraParams)=="ARRAY") && {(typeName (_extraParams select 0))=="STRING"}) then + { + _extraParams select 0 + } + else + { + "Exile_Car_Offroad_Armed_Guerilla01" + }; + }; + }; + +_vehicle = [_vehClass,[_pos,3+(random 5),random 360] call DMS_fnc_SelectOffsetPos] call DMS_fnc_SpawnNonPersistentVehicle; + +// setup crate iteself with items from choice +_crate_loot_values = +[ + _crate_weapons, // Weapons + _crate_items, // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [], // No spawned buildings + [_vehicle], + [[_crate,_crate_loot_values]] +]; + +// Define Mission Start message +_msgStart = ['#FFFF00',format["A heavily armed bandit group has been spotted, take the %1 bandits out and claim their vehicle!",_difficulty]]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have successfully taken care of the bandit group!"]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The bandits have driven off, no loot today!"]; + +// Define mission name (for map markers, mission messages, and logging) +_missionName = "Armed Bandits"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/bauhaus.sqf b/@ExileServer/addons/a3_dms/missions/bandit/bauhaus.sqf new file mode 100644 index 0000000..1ff8e86 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/bauhaus.sqf @@ -0,0 +1,224 @@ +/* + Bauhaus with new version of difficulty selection + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_vehicle", "_class", "_veh", "_crate_loot_values", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons1", "_crate_weapon_list1", "_crate_items1", "_crate_item_list1", "_crate_backpacks1", "_PossibleDifficulty", "_crate1", "_crate2", "_wreck", "_crate_loot_values1", "_crate_loot_values2", "_crate_weapons2", "_crate_weapon_list2", "_crate_items2", "_crate_item_list2", "_crate_backpacks2"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// This mission doesn't use "_extraParams" in any way currently. +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION bauhaus.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "moderate", + "moderate", + "difficult", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (2 + (round (random 2))); +_crate_weapons1 = (1 + (round (random 1))); +_crate_items1 = (2 + (round (random 3))); +_crate_backpacks1 = (1 + (round (random 1))); +_crate_weapons2 = (1 + (round (random 1))); +_crate_items2 = (3 + (round (random 3))); +_crate_backpacks2 = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 2))); +_crate_weapons1 = (1 + (round (random 2))); +_crate_items1 = (5 + (round (random 5))); +_crate_backpacks1 = (2 + (round (random 1))); +_crate_weapons2 = (1 + (round (random 2))); +_crate_items2 = (5 + (round (random 5))); +_crate_backpacks2 = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (6 + (round (random 2))); +_crate_weapons1 = (2 + (round (random 2))); +_crate_items1 = (10 + (round (random 6))); +_crate_backpacks1 = (2 + (round (random 1))); +_crate_weapons2 = (1 + (round (random 2))); +_crate_items2 = (10 + (round (random 6))); +_crate_backpacks2 = (4 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (6 + (round (random 4))); +_crate_weapons1 = (3 + (round (random 2))); +_crate_items1 = (15 + (round (random 6))); +_crate_backpacks1 = (3 + (round (random 1))); +_crate_weapons2 = (2 + (round (random 2))); +_crate_items2 = (15 + (round (random 6))); +_crate_backpacks2 = (5 + (round (random 1))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// Create Crates +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; +_crate2 = ["Box_NATO_Wps_F",[(_pos select 0)+2,(_pos select 1)-1,0]] call DMS_fnc_SpawnCrate; + +_wreck = createVehicle ["Land_Wreck_Ural_F",[(_pos select 0) - 10, (_pos select 1),-0.2],[], 0, "CAN_COLLIDE"]; + +// Set crate loot values +_crate_loot_values1 = +[ + _crate_weapons1 , // Weapons + [_crate_items1,DMS_BoxBuildingSupplies], // Items + _crate_backpacks1 // Backpacks +]; +_crate_loot_values2 = +[ + _crate_weapons2, // Weapons + _crate_items2, // Items + _crate_backpacks2 // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [_wreck], + [], + [[_crate1,_crate_loot_values1],[_crate2,_crate_loot_values2]] +]; + +// Define mission start message +_msgStart = ['#FFFF00',"A Bauhaus truck has crashed and lost all its building supplies! Get there quickly!"]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have successfully claimed the crashed Bauhaus truck!"]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The crew have repaired the Bauhaus truck and escaped!"]; + +// Define mission name (for map marker and logging) +_missionName = "Bauhaus Truck"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/beertransport.sqf b/@ExileServer/addons/a3_dms/missions/bandit/beertransport.sqf new file mode 100644 index 0000000..3d684da --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/beertransport.sqf @@ -0,0 +1,212 @@ +/* + Beer Transport Mission with new difficulty selection system + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_wreck", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// This mission doesn't use "_extraParams" in any way currently. +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION beertransport.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "easy", + "moderate", + "moderate", + "moderate", + "difficult", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (3 + (round (random 2))); +_crate_weapons = (2 + (round (random 3))); +_crate_items = (8 + (round (random 3))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 2))); +_crate_weapons = (4 + (round (random 4))); +_crate_items = (10 + (round (random 3))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (4 + (round (random 3))); +_crate_weapons = (6 + (round (random 4))); +_crate_items = (12 + (round (random 3))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (4 + (round (random 4))); +_crate_weapons = (8 + (round (random 3))); +_crate_items = (14 + (round (random 3))); +_crate_backpacks = 4; + }; +}; + +// used for all +_crate_item_list = ["Exile_Item_Beer"]; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// Create Crates +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +_wreck = createVehicle ["Land_Wreck_Van_F",[(_pos select 0) - 10, (_pos select 1),-0.2],[], 0, "CAN_COLLIDE"]; + +// Set crate loot values +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + [_crate_items,_crate_item_list], // Items + selection list + _crate_backpacks // Backpacks + +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [_wreck], + [], + [[_crate1,_crate_loot_values1]] +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A transport truck carrying beer and guns is being robbed, stop the %1 robbers and steal the loot!",_difficulty]]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have successfully claimed all of the beer and guns."]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The robbers have taken off with all the beer and all the guns! What a travesty!"]; + +// Define mission name (for map marker and logging) +_missionName = "Beer N' Guns Truck"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/behindenemylines.sqf b/@ExileServer/addons/a3_dms/missions/bandit/behindenemylines.sqf new file mode 100644 index 0000000..092ab4a --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/behindenemylines.sqf @@ -0,0 +1,208 @@ +/* + Behind Enemy Llines Mission with new difficulty selection system + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty", "_wreck"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// This mission doesn't use "_extraParams" in any way currently. +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION behindenemylines.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "moderate", + "moderate", + "difficult", + "difficult", + "difficult", + "hardcore", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (3 + (round (random 2))); +_crate_weapons = (2 + (round (random 3))); +_crate_items = (2 + (round (random 4))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 2))); +_crate_weapons = (4 + (round (random 5))); +_crate_items = (4 + (round (random 6))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (5 + (round (random 3))); +_crate_weapons = (6 + (round (random 7))); +_crate_items = (6 + (round (random 8))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (6 + (round (random 4))); +_crate_weapons = (8 + (round (random 9))); +_crate_items = (8 + (round (random 10))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// Create Crates +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +_wreck = createVehicle ["Land_BagBunker_Tower_F",[(_pos select 0) - 10, (_pos select 1),-0.2],[], 0, "CAN_COLLIDE"]; + +// Set crate loot values +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + _crate_items, // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [_wreck], + [], + [[_crate1,_crate_loot_values1]] +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A team of %1 soldiers have set up a bunker inside convict land. Rid them from this place!",_difficulty]]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have successfully taken care of the enemies and their bunker!"]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The soldiers became impatient and have escaped the area!"]; + +// Define mission name (for map marker and logging) +_missionName = "Enemy Bunker"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/blackhawkdown.sqf b/@ExileServer/addons/a3_dms/missions/bandit/blackhawkdown.sqf new file mode 100644 index 0000000..16452ba --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/blackhawkdown.sqf @@ -0,0 +1,209 @@ +/* + Black Hawk Down Mission with new difficulty selection system + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_wreck", "_crate", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// This mission doesn't use "_extraParams" in any way currently. +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION blackhawkdown.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "easy", + "moderate", + "moderate", + "moderate", + "difficult", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (3 + (round (random 2))); +_crate_weapons = (2 + (round (random 3))); +_crate_items = (2 + (round (random 4))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 2))); +_crate_weapons = (4 + (round (random 5))); +_crate_items = (4 + (round (random 6))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (5 + (round (random 3))); +_crate_weapons = (6 + (round (random 7))); +_crate_items = (6 + (round (random 8))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (6 + (round (random 4))); +_crate_weapons = (8 + (round (random 9))); +_crate_items = (8 + (round (random 10))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// Create Crates +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +_wreck = createVehicle ["Land_Wreck_Heli_Attack_02_F",[(_pos select 0) - 10, (_pos select 1),-0.2],[], 0, "CAN_COLLIDE"]; + +// Set crate loot values +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + _crate_items, // Items + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [_wreck], + [], + [[_crate1,_crate_loot_values1]] +]; + +// Define Mission Start message with difficulty +_msgStart = ['#FFFF00',format["We got a Blackhawk down, Super 6-1 is down, secure the perimeter and claim what can be claimed from the %1 bandits!",_difficulty]]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have secured the blackhawk and claimed the remaining loot!"]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The blackhawk has been seized by the enemy and the loot has been destroyed!"]; + +// Define mission name (for map marker and logging) +_missionName = "Blackhawk Down"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/cardealer.sqf b/@ExileServer/addons/a3_dms/missions/bandit/cardealer.sqf new file mode 100644 index 0000000..f4b97f4 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/cardealer.sqf @@ -0,0 +1,248 @@ +/* + Car Dealer Mission with new difficulty selection system + Random SUV chosen for prizes, Mission gives % chance of 2nd vehicle + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_extraParams", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_wreck", "_crate", "_crate1", "_vehicle", "_PossibleVehicleClass", "_pinCode", "_class", "_veh", "_crate_loot_values", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can use _extraParams to define which vehicles to spawn. _vehClass1, [_vehClass1], or [_vehClass1,_vehClass2] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION cardealer.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "moderate", + "moderate", + "moderate", + "difficult", + "difficult", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (3 + (round (random 2))); +_VehicleChance = 40; //40% Spawn 2 Vehicles chance +_crate_weapons = (2 + (round (random 3))); +_crate_items = (2 + (round (random 4))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 2))); +_VehicleChance = 60; //60% Spawn 2 Vehicles chance +_crate_weapons = (3 + (round (random 5))); +_crate_items = (3 + (round (random 6))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (4 + (round (random 3))); +_VehicleChance = 75; //75% Spawn 2 Vehicles chance +_crate_weapons = (4 + (round (random 7))); +_crate_items = (4 + (round (random 8))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (4 + (round (random 4))); +_VehicleChance = 90; //90% Spawn 2 Vehicles chance +_crate_weapons = (5 + (round (random 9))); +_crate_items = (5 + (round (random 10))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// Create Crates +_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"]; + +_PossibleVehicleClass = [ + "Exile_Car_SUV_Red", + "Exile_Car_SUV_Black", + "Exile_Car_SUV_Grey", + "Exile_Car_SUV_Orange", + "Exile_Car_SUV_Red", + "Exile_Car_SUV_Black", + "Exile_Car_SUV_Grey", + "Exile_Car_SUV_Orange", + "Exile_Car_SUV_Red", + "Exile_Car_SUV_Black", + "Exile_Car_SUV_Grey", + "Exile_Car_SUV_Orange", + "Exile_Car_SUVXL_Black" + ]; +//choose the vehicle +_vehClass1 = selectRandom _PossibleVehicleClass; +_vehClass2 = selectRandom _PossibleVehicleClass; + +// vehicle 1 is always spawned +_vehicle1 = [_vehClass1, [_pos,5+(random 3),_rndDir] call DMS_fnc_SelectOffsetPos] call DMS_fnc_SpawnNonPersistentVehicle; + +// Set crate loot values +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + _crate_items, // Items + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// is %chance greater than random number add 2nd vehicle and adjust clean up script to include +if (_VehicleChance >= (random 100)) then { +_vehicle2 = [_vehClass2, [_pos,5+(random 3),_rndDir+180] call DMS_fnc_SelectOffsetPos] call DMS_fnc_SpawnNonPersistentVehicle; +_missionObjs = +[ + [_wreck], + [_vehicle1,_vehicle2], + [[_crate1,_crate_loot_values1]] +]; + } else + { +_missionObjs = +[ + [_wreck], + [_vehicle1], + [[_crate1,_crate_loot_values1]] +]; + }; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A local car dealership is being robbed by %1 bandits. Stop them!",_difficulty]]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have secured the local dealership and eliminated the bandits!"]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The bandits have escaped with the cars and left nothing but a trail of smoke behind!"]; + +// Define mission name (for map marker and logging) +_missionName = "Car Dealer Robbery"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/construction.sqf b/@ExileServer/addons/a3_dms/missions/bandit/construction.sqf new file mode 100644 index 0000000..ff93966 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/construction.sqf @@ -0,0 +1,238 @@ +/* + Construction Mission with new difficulty selection system + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_group", "_pos", "_side", "_OK", "_difficulty", "_AICount", "_type", "_launcher", "_crate", "_wreck1", "_wreck2", "_wreck3", "_vehClass", "_vehicle", "_crate_loot_values", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_crate_weapons", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [25,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _classname or [_classname] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION construction.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "moderate", + "moderate", + "difficult", + "difficult", + "hardcore", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (5 + (round (random 2))); +_crate_weapons = (1 + (round (random 1))); +_crate_items = (8 + (round (random 4))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (5 + (round (random 4))); +_crate_weapons = (1 + (round (random 2))); +_crate_items = (12 + (round (random 4))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (5 + (round (random 4))); +_crate_weapons = (2 + (round (random 2))); +_crate_items = (15 + (round (random 6))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (5 + (round (random 4))); +_crate_weapons = (3 + (round (random 3))); +_crate_items = (20 + (round (random 6))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +// used for all +_crate_item_list = ["DMS_BoxBuildingSupplies"]; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// Create Crate +_crate = ["Box_NATO_Wps_F",[(_pos select 0)+2,(_pos select 1)-1,0]] call DMS_fnc_SpawnCrate; + +_wreck1 = createVehicle ["Land_CinderBlocks_F",[(_pos select 0) - 10, (_pos select 1),-0.1],[], 0, "CAN_COLLIDE"]; +_wreck2 = createVehicle ["Land_Bricks_V1_F",[(_pos select 0) - 5, (_pos select 1),-3.3],[], 0, "CAN_COLLIDE"]; +_wreck3 = createVehicle ["Land_Bricks_V1_F",[(_pos select 0) - 13, (_pos select 1),-1],[], 0, "CAN_COLLIDE"]; + +// Check to see if a special vehicle class is defined in "_extraParams", and make sure it's valid, otherwise use the default (Offroad Armed) +_vehClass = + if (_extraParams isEqualTo []) then + { + "Exile_Car_Zamak" + } + else + { + if ((typeName _extraParams)=="STRING") then + { + _extraParams + } + else + { + if (((typeName _extraParams)=="ARRAY") && {(typeName (_extraParams select 0))=="STRING"}) then + { + _extraParams select 0 + } + else + { + "Exile_Car_Zamak" + }; + }; + }; + +_vehicle = [_vehClass,_pos] call DMS_fnc_SpawnNonPersistentVehicle; + +// Set crate loot values +_crate_loot_values = +[ + _crate_weapons, // Weapons + [_crate_items,DMS_BoxBuildingSupplies], // Items + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [_wreck1,_wreck2,_wreck3], // No spawned buildings + [_vehicle], + [[_crate,_crate_loot_values]] +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A group of %1 mercenaries have set up a construction site. Clear them out!",_difficulty]]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have successfully demolished the construction site!"]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The mercenaries have dismantled their construction site and escaped!"]; + +// Define mission name (for map marker and logging) +_missionName = "Construction Site"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/donthasslethehoff.sqf b/@ExileServer/addons/a3_dms/missions/bandit/donthasslethehoff.sqf new file mode 100644 index 0000000..2e8b53a --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/donthasslethehoff.sqf @@ -0,0 +1,260 @@ +/* + Dont Hassel the Hoff Mission with new difficulty selection system + Mission gives % chance of persistent vehicle + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_crate1", "_wreck", "_vehClass", "_vehicle", "_pinCode", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _vehClass or [_vehClass] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION donthasslethehoff.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "easy", + "moderate", + "moderate", + "difficult", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 2))); +_VehicleChance = 10; //10% SpawnPersistentVehicle chance +_crate_weapons = (2 + (round (random 3))); +_crate_items = (2 + (round (random 4))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 4))); +_VehicleChance = 20; //20% SpawnPersistentVehicle chance +_crate_weapons = (4 + (round (random 5))); +_crate_items = (4 + (round (random 6))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (5 + (round (random 3))); +_VehicleChance = 30; //30% SpawnPersistentVehicle chance +_crate_weapons = (6 + (round (random 7))); +_crate_items = (6 + (round (random 8))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (6 + (round (random 4))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance +_crate_weapons = (8 + (round (random 9))); +_crate_items = (8 + (round (random 10))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +_staticGuns = +[ + [ + [(_pos select 0)+(5+(random 5)),(_pos select 1)+(5+(random 5)),0], + [(_pos select 0) + -1*(5+(random 5)),(_pos select 1) + -1*(5+(random 5)),0] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStaticMG; + +// Create Crates +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +_wreck = createVehicle ["Land_Wreck_Heli_Attack_02_F",[(_pos select 0) - 10, (_pos select 1),-0.2],[], 0, "CAN_COLLIDE"]; + +_vehClass = + if (_extraParams isEqualTo []) then + { + "Exile_Car_SUV_Black" + } + else + { + if ((typeName _extraParams)=="STRING") then + { + _extraParams + } + else + { + if (((typeName _extraParams)=="ARRAY") && {(typeName (_extraParams select 0))=="STRING"}) then + { + _extraParams select 0 + } + else + { + "Exile_Car_SUV_Black" + }; + }; + }; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = [_vehClass,[(_pos select 0), (_pos select 1)],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts secured KITT; that will show the bandits not to Hassle the Hoff, KITTs entry code is %1...",_pinCode]]; + } else + { + _vehicle = [_vehClass,_pos] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts secured KITT; that will show the bandits not to Hassle the Hoff!"]; + }; + +// Set crate loot values +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + _crate_items, // Items + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [_wreck]+_staticGuns, + [_vehicle], + [[_crate1,_crate_loot_values1]] +]; + +// Define Mission Start message with difficulty +_msgStart = ['#FFFF00',format["KITT has been kidnapped by %1 bandits. Secure the position and reclaim KITT!",_difficulty]]; + +// Define Mission Win message in vehicle choice + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"KITT was never secured and has now been dismantled by the bandits... What a grim fate."]; + +// Define mission name (for map marker and logging) +_missionName = "KITT's Location"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/foodtransport.sqf b/@ExileServer/addons/a3_dms/missions/bandit/foodtransport.sqf new file mode 100644 index 0000000..c6cd782 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/foodtransport.sqf @@ -0,0 +1,216 @@ +/* + Food Transport Mission with new difficulty selection system + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_OK", "_pos", "_difficulty", "_AICount", "_group", "_type", "_launcher", "_crate1", "_wreck", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// This mission doesn't use "_extraParams" in any way currently. +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION foodtransport.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "easy", + "easy", + "easy", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (3 + (round (random 2))); +_crate_weapons = 0; +_crate_items = (10 + (round (random 5))); +_crate_backpacks = 0; + }; + case "moderate": + { +_AICount = (4 + (round (random 2))); +_crate_weapons = 0; +_crate_items = (12 + (round (random 7))); +_crate_backpacks = 0; + }; + case "difficult": + { +_AICount = (4 + (round (random 3))); +_crate_weapons = 0; +_crate_items = (14 + (round (random 9))); +_crate_backpacks = 0; + }; + //case "hardcore": + default + { +_AICount = (4 + (round (random 4))); +_crate_weapons = 0; +_crate_items = (16 + (round (random 11))); +_crate_backpacks = 0; + }; +}; + +//used for all +_crate_item_list = ["Exile_Item_GloriousKnakWorst_Cooked","Exile_Item_PlasticBottleFreshWater","Exile_Item_PlasticBottleFreshWater","Exile_Item_BBQSandwich_Cooked","Exile_Item_Catfood_Cooked","Exile_Item_ChristmasTinner_Cooked"]; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + + +// Create Crates +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +_wreck = createVehicle ["Land_Wreck_Van_F",[(_pos select 0) - 10, (_pos select 1),-0.2],[], 0, "CAN_COLLIDE"]; + +// Set crate loot values +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + [_crate_items,_crate_item_list], // Items + _crate_backpacks // Backpacks +]; + + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [_wreck], + [], + [[_crate1,_crate_loot_values1]] +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A food supply truck has been seized by %1 bandits. Stop them!",_difficulty]]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have successfully claimed the food supplies!"]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The bandits have taken the food supplies and escaped!"]; + +// Define mission name (for map marker and logging) +_missionName = "Food Supplies"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/guntransport.sqf b/@ExileServer/addons/a3_dms/missions/bandit/guntransport.sqf new file mode 100644 index 0000000..0602902 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/guntransport.sqf @@ -0,0 +1,209 @@ +/* + Gun Transport Mission with new difficulty selection system + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_OK", "_group", "_pos", "_difficulty", "_AICount", "_type", "_launcher", "_crate1", "_wreck", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// This mission doesn't use "_extraParams" in any way currently. +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION guntransport.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "moderate", + "moderate", + "moderate", + "difficult", + "difficult", + "difficult", + "hardcore", + "hardcore" + ]; + +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (3 + (round (random 2))); +_crate_weapons = (3 + (round (random 3))); +_crate_items = (2 + (round (random 3))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 2))); +_crate_weapons = (5 + (round (random 5))); +_crate_items = (4 + (round (random 4))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (5 + (round (random 3))); +_crate_weapons = (7 + (round (random 7))); +_crate_items = (6 + (round (random 6))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (6 + (round (random 4))); +_crate_weapons = (9 + (round (random 9))); +_crate_items = (8 + (round (random 8))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// Create Crates +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +_wreck = createVehicle ["Land_Wreck_Van_F",[(_pos select 0) - 10, (_pos select 1),-0.2],[], 0, "CAN_COLLIDE"]; + +// Set crate loot values +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + _crate_items, // Items + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [_wreck], + [], + [[_crate1,_crate_loot_values1]] +]; + +// Define Mission start message with difficulty level +_msgStart = ['#FFFF00',format["A gun transport truck has crashed. Secure the crash site from the %1 bandits!",_difficulty]]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have successfully secured the area and claimed the guns for their own!"]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The transport truck has been repaired and driven off!"]; + +// Define mission name (for map marker and logging) +_missionName = "Gun Transport"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/humanitarian.sqf b/@ExileServer/addons/a3_dms/missions/bandit/humanitarian.sqf new file mode 100644 index 0000000..000ac45 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/humanitarian.sqf @@ -0,0 +1,211 @@ +/* + humanitarian Mission with new difficulty selection system + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_OK", "_group", "_pos", "_difficulty", "_AICount", "_type", "_launcher", "_crate1", "_wreck", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// This mission doesn't use "_extraParams" in any way currently. +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION humanitarian.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "easy", + "easy", + "moderate", + "moderate", + "moderate", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 2))); +_crate_weapons = (1 + (round (random 1))); +_crate_items = (2 + (round (random 4))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 4))); +_crate_weapons = (2 + (round (random 1))); +_crate_items = (4 + (round (random 7))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (5 + (round (random 4))); +_crate_weapons = (3 + (round (random 1))); +_crate_items = (6 + (round (random 9))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (6 + (round (random 4))); +_crate_weapons = (5 + (round (random 1))); +_crate_items = (10 + (round (random 12))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +// used for all +_crate_item_list = ["Exile_Item_GloriousKnakWorst_Cooked","Exile_Item_PlasticBottleFreshWater","Exile_Item_PlasticBottleFreshWater","Exile_Item_BBQSandwich_Cooked","Exile_Item_Catfood_Cooked","Exile_Item_ChristmasTinner_Cooked"]; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// Create Crates +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +_wreck = createVehicle ["Land_Wreck_Van_F",[(_pos select 0) - 10, (_pos select 1),-0.2],[], 0, "CAN_COLLIDE"]; + +// Set crate loot values +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + [_crate_items,_crate_item_list], // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [_wreck], + [], + [[_crate1,_crate_loot_values1]] +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A truck carrying humanitarian supplies has been seized by %1 bandits. Stop them!",_difficulty]]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have successfully claimed the humanitarian supplies for themselves!"]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The bandits have taken the humanitarian supplies and escaped!"]; + +// Define mission name (for map marker and logging) +_missionName = "Humanitarian Supplies"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/lost_battalion.sqf b/@ExileServer/addons/a3_dms/missions/bandit/lost_battalion.sqf new file mode 100644 index 0000000..f66ad02 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/lost_battalion.sqf @@ -0,0 +1,206 @@ +/* + Lost Battalion Mission with new difficulty selection system + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_extraParams", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_wreck", "_crate", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// This mission doesn't use "_extraParams" in any way currently. +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION lost_battalion.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "moderate", + "moderate", + "moderate", + "difficult", + "difficult", + "difficult", + "hardcore", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 4))); +_crate_weapons = (2 + (round (random 3))); +_crate_items = (2 + (round (random 4))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (7 + (round (random 2))); +_crate_weapons = (4 + (round (random 5))); +_crate_items = (4 + (round (random 6))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (7 + (round (random 4))); +_crate_weapons = (6 + (round (random 7))); +_crate_items = (6 + (round (random 8))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (7 + (round (random 6))); +_crate_weapons = (8 + (round (random 9))); +_crate_items = (8 + (round (random 10))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// Create Crate +_crate = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// setup crate iteself with items from choice +_crate_loot_values = +[ + _crate_weapons, // Weapons + _crate_items, // Items + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [], + [], + [[_crate,_crate_loot_values]] +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A battalion of %1 soldiers have gotten lost in convict land! Eliminate them!",_difficulty]]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have successfully eliminated the lost battalion!"]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"Whittlesey escaped with his Lost Battalion!"]; + +// Define mission name (for map marker and logging) +_missionName = "Lost Battalion"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/medical.sqf b/@ExileServer/addons/a3_dms/missions/bandit/medical.sqf new file mode 100644 index 0000000..71615df --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/medical.sqf @@ -0,0 +1,226 @@ +/* + Medical Mission with new difficulty selection system + Mission gives % chance of persistent vehicle + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_OK", "_group", "_pos", "_difficulty", "_AICount", "_type", "_launcher", "_crate", "_building", "_vehicle", "_pinCode", "_crate_loot_values", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// This mission doesn't use "_extraParams" in any way currently. +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION medical.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "easy", + "easy", + "moderate", + "moderate", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (3 + (round (random 2))); +_VehicleChance = 10; //10% SpawnPersistentVehicle chance +_crate_weapons = (2 + (round (random 3))); +_crate_items = (2 + (round (random 4))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 2))); +_VehicleChance = 20; //20% SpawnPersistentVehicle chance +_crate_weapons = (4 + (round (random 5))); +_crate_items = (4 + (round (random 6))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (5 + (round (random 3))); +_VehicleChance = 30; //30% SpawnPersistentVehicle chance +_crate_weapons = (6 + (round (random 7))); +_crate_items = (6 + (round (random 8))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (6 + (round (random 4))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance +_crate_weapons = (8 + (round (random 9))); +_crate_items = (8 + (round (random 10))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +//use by all +_crate_item_list = ["Exile_Item_InstaDoc","Exile_Item_PlasticBottleFreshWater","Exile_Item_Bandage","Exile_Item_PlasticBottleFreshWater","Exile_Item_Vishpirin","Exile_Item_PlasticBottleFreshWater","Exile_Item_Bandage","Exile_Item_Vishpirin","Exile_Item_Bandage","Exile_Item_Vishpirin","Exile_Item_Bandage","Exile_Item_Vishpirin","Exile_Item_InstaDoc","Exile_Item_Bandage","Exile_Item_Vishpirin","Exile_Item_Bandage","Exile_Item_Vishpirin","Exile_Item_Bandage","Exile_Item_Vishpirin"]; + + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// Create Crate +_crate = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +_building = createVehicle ["Land_Medevac_HQ_V1_F",[(_pos select 0) - 30, (_pos select 1),-10],[], 0, "CAN_COLLIDE"]; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = ["I_Truck_02_medical_F",_pos,_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts have claimed the medical supplies for their own, vehicle entry code %1...",_pinCode]]; + } else + { + _vehicle = ["I_Truck_02_medical_F",_pos] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts have claimed the medical supplies for their own!"]; + }; + +// Set crate loot values +_crate_loot_values = +[ + _crate_weapons, // Weapons + [_crate_items,_crate_item_list], // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [_building], // Medevac + [_vehicle], + [[_crate,_crate_loot_values]] +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A group of deranged %1 doctors have set up a field hospital. Seize it for your own!",_difficulty]]; + +// Define Mission Win message defined in persistent choice + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"Hawkeye has ran off with the medical supplies! Everything is gone!"]; + +// Define mission name (for map marker and logging) +_missionName = "Deranged Doctors"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/mercbase.sqf b/@ExileServer/addons/a3_dms/missions/bandit/mercbase.sqf new file mode 100644 index 0000000..3c77f2a --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/mercbase.sqf @@ -0,0 +1,234 @@ +/* + Mercbase Mission with new difficulty selection system + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_OK", "_group", "_pos", "_difficulty", "_AICount", "_veh", "_staticGuns", "_baseObjs", "_crate", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_PossibleDifficulty"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [50,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// This mission doesn't use "_extraParams" in any way currently. +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION mercbase.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "moderate", + "difficult", + "difficult", + "difficult", + "difficult", + "difficult", + "difficult", + "hardcore", + "hardcore", + "hardcore", + "hardcore", + "hardcore", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 3))); + }; + case "moderate": + { +_AICount = (5 + (round (random 4))); + }; + case "difficult": + { +_AICount = (6 + (round (random 5))); + }; + //case "hardcore": + default + { +_AICount = (7 + (round (random 6))); + }; +}; + +_group = +[ + [_pos,[-9.48486,-12.4834,0]] call DMS_fnc_CalcPos, + _AICount, + _difficulty, + "random", + _side +] call DMS_fnc_SpawnAIGroup; + +_veh = +[ + [ + [_pos,100,random 360] call DMS_fnc_SelectOffsetPos, + _pos + ], + _group, + "assault", + _difficulty, + _side +] call DMS_fnc_SpawnAIVehicle; + +[ + _group, + [_pos,[-9.48486,-12.4834,0]] call DMS_fnc_CalcPos, + "base" +] call DMS_fnc_SetGroupBehavior; + + +_staticGuns = +[ + [ + [_pos,[-6.29138,3.9917,0]] call DMS_fnc_CalcPos + ], + _group, + "assault", + _difficulty, + "bandit", + "O_HMG_01_high_F" +] call DMS_fnc_SpawnAIStaticMG; + +(_staticGuns select 0) setDir 15; + +_baseObjs = +[ + "base1", + _pos +] call DMS_fnc_ImportFromM3E; + +// Create Crate +_crate = ["Box_NATO_AmmoOrd_F",_pos] call DMS_fnc_SpawnCrate; + +// Pink Crate ;) +_crate setObjectTextureGlobal [0,"#(rgb,8,8,3)color(1,0.08,0.57,1)"]; +_crate setObjectTextureGlobal [1,"#(rgb,8,8,3)color(1,0.08,0.57,1)"]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns+_baseObjs+[_veh], // armed AI vehicle, base objects, and static gun + [], + [[_crate,"Sniper"]] +]; + +// Define Mission Start message +_msgStart = ['#FFFF00',format ["A mercenary base has been located at %1! There are reports of a dandy crate inside of it...",mapGridPosition _pos]]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have successfully assaulted the Mercenary Base and obtained the dandy crate!"]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"Seems like the Mercenaries packed up and drove away..."]; + +// Define mission name (for map marker and logging) +_missionName = "Mercenary Base"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/mercenaries.sqf b/@ExileServer/addons/a3_dms/missions/bandit/mercenaries.sqf new file mode 100644 index 0000000..66e5a59 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/mercenaries.sqf @@ -0,0 +1,203 @@ +/* + Mercenaries Mission with new difficulty selection system + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_OK", "_group", "_pos", "_difficulty", "_AICount", "_type", "_launcher", "_crate", "_crate_loot_values", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// This mission doesn't use "_extraParams" in any way currently. +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION mercenaries.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "moderate", + "moderate", + "difficult", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 2))); +_crate_weapons = (1 + (round (random 1))); +_crate_items = (2 + (round (random 4))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (6 + (round (random 2))); +_crate_weapons = (2 + (round (random 1))); +_crate_items = (4 + (round (random 5))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (6 + (round (random 4))); +_crate_weapons = (3 + (round (random 1))); +_crate_items = (7 + (round (random 6))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (6 + (round (random 4))); +_crate_weapons = (4 + (round (random 1))); +_crate_items = (10 + (round (random 7))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// Create Crate +_crate = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// Set crate loot values +_crate_loot_values = +[ + _crate_weapons, // Weapons + _crate_items, // Items + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [], + [], + [[_crate,_crate_loot_values]] +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A group of %1 mercenaries has been spotted. Kill them and take their equipment!",_difficulty]]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have successfully eliminated the mercenaries!"]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The mercenaries have escaped and they took all their loot with them!"]; + +// Define mission name (for map marker and logging) +_missionName = "Mercenary Group"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/nedbandit1_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/nedbandit1_mission.sqf new file mode 100644 index 0000000..83afaa0 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/nedbandit1_mission.sqf @@ -0,0 +1,316 @@ +/* + nedbandit1 with new difficulty selection system + Mission gives % chance of persistent vehicle + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk + based on work by Defent and eraser1 + Vehicle loading borrowed from Occupation Crate mission by second_coming +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_extraParams", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_wreck", "_crate", "_vehicle", "_vehicleP", "_pinCode", "_class", "_veh", "_crate_loot_values", "_veh", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_PossibleDifficulty", "_PossibleColour", "_colour", "_VehicleChance", "_Vwin", "_cash", "_ned_VehicleItems", "_item", "_itemType", "_amount", "_randomAmount", "_customGearSet", "_customGearSet2"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3],[],[],[]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION nedbandit1_mission.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "moderate", + "moderate", + "moderate", + "difficult", + "difficult", + "difficult", + "hardcore", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 4))); +_VehicleChance = 20; //20% SpawnPersistentVehicle chance +_ned_VehicleItems = [["U_NikosAgedBody",1,0], ["U_NikosBody",1,1], ["H_Cap_press",1,0],["H_StrawHat_dark",1,0], ["Exile_Item_EMRE",1,1], ["Exile_Item_PlasticBottleCoffee",1,1], ["ItemGPS",1,0], ["hgun_Rook40_F",1,1], ["hgun_ACPC2_F",0,1], ["9Rnd_45ACP_Mag",1,1], ["16Rnd_9x21_Mag",1,1]]; +_cash = (250 + round (random (500))); + }; + case "moderate": + { +_AICount = (7 + (round (random 2))); +_VehicleChance = 25; //25% SpawnPersistentVehicle chance +_ned_VehicleItems = [["U_NikosAgedBody",1,1], ["U_NikosBody",1,2], ["H_Cap_press",1,1],["H_StrawHat_dark",1,1], ["Exile_Item_EMRE",1,2], ["Exile_Item_PlasticBottleCoffee",1,2], ["ItemGPS",1,1], ["hgun_Rook40_F",1,2], ["hgun_ACPC2_F",1,1], ["9Rnd_45ACP_Mag",2,2], ["16Rnd_9x21_Mag",2,2]]; +_cash = (500 + round (random (750))); + }; + case "difficult": + { +_AICount = (7 + (round (random 4))); +_VehicleChance = 33; //33% SpawnPersistentVehicle chance +_ned_VehicleItems = [["U_NikosAgedBody",1,2], ["U_NikosBody",1,3], ["H_Cap_press",1,2],["H_StrawHat_dark",1,2], ["Exile_Item_EMRE",1,3], ["Exile_Item_PlasticBottleCoffee",1,3], ["ItemGPS",1,2], ["hgun_Rook40_F",1,3], ["hgun_ACPC2_F",1,2], ["9Rnd_45ACP_Mag",3,3], ["16Rnd_9x21_Mag",3,3]]; +_cash = (750 + round (random (1000))); + }; + //case "hardcore": + default + { +_AICount = (7 + (round (random 6))); +_VehicleChance = 50; //50% SpawnPersistentVehicle chance +_ned_VehicleItems = [["U_NikosAgedBody",1,3], ["U_NikosBody",1,4], ["H_Cap_press",1,3],["H_StrawHat_dark",1,3], ["Exile_Item_EMRE",1,4], ["Exile_Item_PlasticBottleCoffee",1,4], ["ItemGPS",1,3], ["hgun_Rook40_F",1,4], ["hgun_ACPC2_F",2,2], ["9Rnd_45ACP_Mag",4,4], ["16Rnd_9x21_Mag",4,4]]; +_cash = (1000 + round (random (1500))); + }; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleColour = [ + "red", + "black", + "grey", + "orange", + "special" + ]; +//choose colour and set value +_colour = selectRandom _PossibleColour; + +switch (_colour) do +{ + case "red": + { + _vehicleP = "Exile_Car_SUV_Red"; + _missionName = "Code-Red Bandit Outlaw"; + }; + case "black": + { + _vehicleP = "Exile_Car_SUV_Black"; + _missionName = "Code-Black Bandit Outlaw"; + }; + case "grey": + { + _vehicleP = "Exile_Car_SUV_Grey"; + _missionName = "Code-Grey Bandit Outlaw"; + }; + case "orange": + { + _vehicleP = "Exile_Car_SUV_Orange"; + _missionName = "Code-Orange Bandit Outlaw"; + }; + //case "special": + default + { + _vehicleP = "Exile_Car_SUV_Armed_Black"; + _missionName = "Code-Special Bandit Outlaw"; + }; +}; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = [_vehicleP,[(_pos select 0), (_pos select 1)],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format["Convicts have successfully eliminated the %1 bandit outlaw, entry code is %2 ...",_colour,_pinCode]]; + _Vwin = "Win"; //just for logging purposes + } else + { + _vehicle = [_vehicleP,[(_pos select 0), (_pos select 1),0],[], 0, "CAN_COLLIDE"] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',format["Convicts have successfully eliminated the %1 bandit outlaw",_colour]]; + _Vwin = "Lose"; //just for logging purposes + }; + +//export to logs for testing - comment next line out for no log +diag_log format ["nedbandit1 :: Called MISSION with these parameters: >>AI Group: %1 (plus leader) >>Cash: %2 >>Vwin: %3 >>Colour: %4 >>Difficulty: %5 >>Vehicle: %6",_AICount,_cash,_Vwin,_colour,_difficulty,_vehicleP]; + +// no crate so load vehicle with basic goodies + clearMagazineCargoGlobal _vehicle; + clearWeaponCargoGlobal _vehicle; + clearItemCargoGlobal _vehicle; + { + _item = _x select 0; + _amount = _x select 1; + _randomAmount = _x select 2; + _amount = _amount + (random _randomAmount); + _itemType = _x call BIS_fnc_itemType; + + if((_itemType select 0) == "Weapon") then {_vehicle addWeaponCargoGlobal [_item, _amount];}; + if((_itemType select 0) == "Magazine") then {_vehicle addMagazineCargoGlobal [_item, _amount];}; + if((_itemType select 0) == "Item") then {_vehicle addItemCargoGlobal [_item, _amount];}; + if((_itemType select 0) == "Equipment") then {_vehicle addItemCargoGlobal [_item, _amount];}; + if((_itemType select 0) == "Backpack") then {_vehicle addBackpackCargoGlobal [_item, _amount];}; + }forEach _ned_VehicleItems; +// load tabs in +_vehicle setVariable ["ExileMoney", _cash,true]; + + +// Create customised leader AI +_customGearSet2 = [ + "Exile_Weapon_M1014", // String | EG: "LMG_Zafir_F" + [], // Array of strings | EG: ["optic_dms","bipod_03_F_blk"] + [["9Rnd_45ACP_Mag",1],["Exile_Magazine_8Rnd_74Pellets",3]], // Array of arrays | EG: [["150Rnd_762x54_Box",2],["16Rnd_9x21_Mag",3],["Exile_Item_InstaDoc",3]] + "hgun_ACPC2_F", // String | EG: "hgun_Pistol_heavy_01_snds_F" + ["muzzle_snds_acp"], // Array of strings | EG: ["optic_MRD","muzzle_snds_acp"] + ["ItemGPS"], // Array of strings | EG: ["Rangefinder","ItemGPS","NVGoggles"] + "", // String | EG: "launch_RPG32_F" + "H_StrawHat", // String | EG: "H_HelmetLeaderO_ocamo" + "U_Competitor", // String | EG: "U_O_GhillieSuit" + "V_BandollierB_blk", // String | EG: "V_PlateCarrierGL_blk" + "" // String | EG: "B_Carryall_oli" + ]; +_group2 = +[ + _pos, // Position of AI + 1, // Just 1 leader + _difficulty, // chosen in difficulty + "custom", // "custom" + _side, // "bandit" + _customGearSet2 // customise with gear above +] call DMS_fnc_SpawnAIGroup; + + +// Create customised AI group +_customGearSet = [ + "Exile_Weapon_AK47", // String | EG: "LMG_Zafir_F" + ["optic_Holosight"], // Array of strings | EG: ["optic_dms","bipod_03_F_blk"] + [["Exile_Magazine_30Rnd_762x39_AK",3],["9Rnd_45ACP_Mag",3]], // Array of arrays | EG: [["150Rnd_762x54_Box",2],["16Rnd_9x21_Mag",3],["Exile_Item_InstaDoc",3]] + "hgun_ACPC2_F", // String | EG: "hgun_Pistol_heavy_01_snds_F" + ["muzzle_snds_acp"], // Array of strings | EG: ["optic_MRD","muzzle_snds_acp"] + ["ItemGPS"], // Array of strings | EG: ["Rangefinder","ItemGPS","NVGoggles"] + "", // String | EG: "launch_RPG32_F" + "H_Cap_blk", // String | EG: "H_HelmetLeaderO_ocamo" + "U_Marshal", // String | EG: "U_O_GhillieSuit" + "V_BandollierB_blk", // String | EG: "V_PlateCarrierGL_blk" + "" // String | EG: "B_Carryall_oli" + ]; + +_group = +[ + _pos, // Position of AI + _AICount, // chosen in difficulty + _difficulty, // chosen in difficulty + "custom", // "custom" + _side, // "bandit" + _customGearSet // customise with gear above +] call DMS_fnc_SpawnAIGroup; + + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group2, // AI leader + _group // AI group +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [], + [_vehicle], //prize vehicle + [] +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A %1 class bandit outlaw has escaped, go kill this %2 outlaw!",_colour,_difficulty]]; + +// Define Mission Win message - defined in persistent vehicle toss + +// Define Mission Lose message +_msgLOSE = ['#FF0000',format["The %1 bandit outlaw has escaped",_colour]]; + +// Define mission name (for map marker and logging) - defined in colour choice + + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + [_group,_group2] + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/nedbtrader_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/nedbtrader_mission.sqf new file mode 100644 index 0000000..5f80817 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/nedbtrader_mission.sqf @@ -0,0 +1,296 @@ +/* + Hijacked Ikea Trader Mission with new difficulty selection system + Mission gives % chance of persistent vehicle + based on work by Defent and eraser1 and Ikea convoy from WAI missions + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_ned_VehicleItems", "_PossibleDifficulty", "_VehicleChance", "_cash", "_vehClass", "_ArmedVehicles", "_unArmedVehicles"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _vehClass or [_vehClass] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3],[],[],[]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION nedbtrader_mission.sqf with invalid parameters: %1",_this]; +}; + +//doing bespoke AI vehicles +_ArmedVehicles = [ // List of armed vehicles that can spawn + "Exile_Car_Offroad_Armed_Guerilla01", + "Exile_Car_Offroad_Armed_Guerilla02", + "Exile_Car_Offroad_Armed_Guerilla03", + "Exile_Car_Offroad_Armed_Guerilla04", + "Exile_Car_Offroad_Armed_Guerilla05", + "Exile_Car_Offroad_Armed_Guerilla06", + "Exile_Car_Offroad_Armed_Guerilla07", + "Exile_Car_Offroad_Armed_Guerilla08", + "Exile_Car_Offroad_Armed_Guerilla09", + "Exile_Car_Offroad_Armed_Guerilla10", + "Exile_Car_Offroad_Armed_Guerilla11", + "Exile_Car_Offroad_Armed_Guerilla12" + ]; +_unArmedVehicles = [ // List of unarmed vehicles that can spawn + "Exile_Car_Offroad_Guerilla01", + "Exile_Car_Offroad_Guerilla02", + "Exile_Car_Offroad_Guerilla03", + "Exile_Car_Offroad_Guerilla04", + "Exile_Car_Offroad_Guerilla05", + "Exile_Car_Offroad_Guerilla06", + "Exile_Car_Offroad_Guerilla07", + "Exile_Car_Offroad_Guerilla08", + "Exile_Car_Offroad_Guerilla09", + "Exile_Car_Offroad_Guerilla10", + "Exile_Car_Offroad_Guerilla11", + "Exile_Car_Offroad_Guerilla12" + ]; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "moderate", + "moderate", + "difficult", + "difficult", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 4))); +_VehicleChance = 10; //10% SpawnPersistentVehicle chance +_ned_VehicleItems = [["Exile_Item_ExtensionCord",1,0], ["Exile_Item_DuctTape",1,1], ["Exile_Item_LightBulb",1,0],["Exile_Item_MetalBoard",1,1], ["Exile_Item_MetalPole",1,1], ["Exile_Melee_SledgeHammmer",0,1], ["Exile_Item_Handsaw",1,0], ["Exile_Item_Pliers",1,1], ["Exile_Item_Grinder",0,1], ["Exile_Item_WoodDoorKit",1,1], ["Exile_Item_WoodDoorwayKit",0,1], ["Exile_Item_WoodFloorKit",1,1], ["Exile_Item_WoodGateKit",1,1], ["Exile_Item_WoodSupportKit",1,1], ["Exile_Item_WoodWallKit",1,1], ["Exile_Item_WoodWindowKit",1,1], ["Exile_Item_MetalHedgehogKit",0,1]]; +_cash = (250 + round (random (500))); //cash prize +_vehClass = selectRandom _unArmedVehicles; + }; + case "moderate": + { +_AICount = (6 + (round (random 4))); +_VehicleChance = 20; //20% SpawnPersistentVehicle chance +_ned_VehicleItems = [["Exile_Item_ExtensionCord",1,0], ["Exile_Item_DuctTape",1,1], ["Exile_Item_LightBulb",1,0],["Exile_Item_MetalBoard",1,1], ["Exile_Item_MetalPole",1,1], ["Exile_Melee_SledgeHammmer",1,1], ["Exile_Item_Handsaw",1,0], ["Exile_Item_Pliers",1,1], ["Exile_Item_Grinder",0,1], ["Exile_Item_WoodDoorKit",1,1], ["Exile_Item_WoodDoorwayKit",1,1], ["Exile_Item_WoodFloorKit",1,2], ["Exile_Item_WoodGateKit",1,1], ["Exile_Item_WoodStairsKit",1,1], ["Exile_Item_WoodSupportKit",1,1], ["Exile_Item_WoodWallKit",1,2], ["Exile_Item_WoodWindowKit",1,1], ["Exile_Item_MetalHedgehogKit",1,1]]; +_cash = (500 + round (random (750))); //cash prize +_vehClass = selectRandom _unArmedVehicles; + }; + case "difficult": + { +_AICount = (8 + (round (random 4))); +_VehicleChance = 30; //30% SpawnPersistentVehicle chance +_ned_VehicleItems = [["Exile_Item_ExtensionCord",1,0], ["Exile_Item_DuctTape",1,2], ["Exile_Item_LightBulb",1,2],["Exile_Item_MetalBoard",1,3], ["Exile_Item_MetalPole",1,1], ["Exile_Melee_SledgeHammmer",1,1], ["Exile_Item_Handsaw",1,0], ["Exile_Item_Pliers",1,1], ["Exile_Item_Grinder",1,1], ["Exile_Item_WoodDoorKit",1,2], ["Exile_Item_WoodDoorwayKit",0,1], ["Exile_Item_ConcreteFloorKit",1,1], ["Exile_Item_WoodGateKit",1,1], ["Exile_Item_WoodStairsKit",1,2], ["Exile_Item_WoodSupportKit",1,2], ["Exile_Item_WoodWallKit",1,2], ["Exile_Item_WoodWindowKit",1,2], ["Exile_Item_MetalHedgehogKit",1,1], ["Exile_Item_SafeKit",0,1]]; +_cash = (750 + round (random (1000))); //cash prize +_vehClass = selectRandom _ArmedVehicles; + }; + //case "hardcore": + default + { +_AICount = (8 + (round (random 8))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance +_ned_VehicleItems = [["Exile_Item_ExtensionCord",1,1], ["Exile_Item_DuctTape",1,3], ["Exile_Item_LightBulb",1,2],["Exile_Item_MetalBoard",1,3], ["Exile_Item_MetalPole",1,3], ["Exile_Melee_SledgeHammmer",1,1], ["Exile_Item_Handsaw",1,0], ["Exile_Item_Pliers",1,1], ["Exile_Item_Grinder",1,1], ["Exile_Item_WoodDoorKit",1,2], ["Exile_Item_ConcreteDoorwayKit",1,1], ["Exile_Item_ConcreteFloorKit",1,1], ["Exile_Item_ConcreteGateKit",1,1], ["Exile_Item_ConcreteStairsKit",1,1], ["Exile_Item_ConcreteSupportKit",1,1], ["Exile_Item_ConcreteWallKit",1,1], ["Exile_Item_WoodWindowKit",1,1], ["Exile_Item_MetalHedgehogKit",1,2], ["Exile_Item_SafeKit",1,0]]; +_cash = (1000 + round (random (1500))); //cash prize +_vehClass = selectRandom _ArmedVehicles; + }; +}; + +// Spawn AI +_group = +[ + [(_pos select 0)+(random 3),(_pos select 1)-(random 3),0], // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// add vehicle patrol and randomise a little - same for all levels (as it uses variable) +_veh = +[ + [ +[(_pos select 0) -(75-(random 25)),(_pos select 1) +(75+(random 25)),0] + ], + _group, + "assault", + _difficulty, + _side, + _vehClass +] call DMS_fnc_SpawnAIVehicle; + +// add static guns - same for all levels +_staticGuns = +[ + [ + // make statically positioned relative to centre point and randomise a little + [(_pos select 0) + 0.1, (_pos select 1) + 20, 0], + [(_pos select 0) + 0.1, (_pos select 1) - 20, 0] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStaticMG; + +// Create Buildings - use seperate file as found in the mercbase mission - same for all levels +_baseObjs = +[ + "nedtrader_objects", + _pos +] call DMS_fnc_ImportFromM3E; + +// Make buildings flat on terrain surface +{ _x setVectorUp surfaceNormal position _x; } count _baseObjs; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = ["Exile_Car_Ural_Open_Worker",[(_pos select 0) +17.2, (_pos select 1) -0],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts have killed the bandits and stolen the supplies,the truck code is %1...",_pinCode]]; + } else + { + _vehicle = ["Exile_Car_Ural_Open_Worker",[(_pos select 0) +17.2, (_pos select 1) -0,0],[], 0, "CAN_COLLIDE"] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts have killed the bandits and stolen the suplies"]; + }; + +// no crate so load vehicle with goodies + clearMagazineCargoGlobal _vehicle; + clearWeaponCargoGlobal _vehicle; + clearItemCargoGlobal _vehicle; + { + _item = _x select 0; + _amount = _x select 1; + _randomAmount = _x select 2; + _amount = _amount + (random _randomAmount); + _itemType = _x call BIS_fnc_itemType; + + if((_itemType select 0) == "Weapon") then {_vehicle addWeaponCargoGlobal [_item, _amount];}; + if((_itemType select 0) == "Magazine") then {_vehicle addMagazineCargoGlobal [_item, _amount];}; + if((_itemType select 0) == "Item") then {_vehicle addItemCargoGlobal [_item, _amount];}; + if((_itemType select 0) == "Equipment") then {_vehicle addItemCargoGlobal [_item, _amount];}; + if((_itemType select 0) == "Backpack") then {_vehicle addBackpackCargoGlobal [_item, _amount];}; + }forEach _ned_VehicleItems; + +// load tabs in vehicle +_vehicle setVariable ["ExileMoney", _cash,true]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns+_baseObjs+[_veh], // armed AI vehicle, base objects, and static guns + [_vehicle], // this is prize vehicle + [] // no crate +]; + +// Define Mission Win message +_msgStart = ['#FFFF00',format["%1 Bandits are raiding an Ikea travelling trader",_difficulty]]; + +// Define Mission Lose message - same for all levels +_msgLOSE = ['#FF0000',"The Bandits have left with all the building supplies"]; + +// Define mission name (for map marker and logging) - same for all levels +_missionName = "Hijacked Ikea Trader"; + +// Create Markers - same for all levels +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/nedbuilding1_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/nedbuilding1_mission.sqf new file mode 100644 index 0000000..f2d2541 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/nedbuilding1_mission.sqf @@ -0,0 +1,258 @@ +/* + Building Raid Mission with new difficulty selection system + Mission gives % chance of persistent vehicle + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk + based on work by Defent and eraser1 +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _vehClass or [_vehClass] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3],[],[],[]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION nedbuilding1_mission.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "moderate", + "moderate", + "moderate", + "difficult", + "difficult", + "hardcore", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 4))); +_VehicleChance = 10; //10% SpawnPersistentVehicle chance +_crate_weapons = (1 + (round (random 1))); +_crate_items = (3 + (round (random 3))); +_crate_backpacks = 1; + }; + case "moderate": + { +_AICount = (6 + (round (random 4))); +_VehicleChance = 20; //20% SpawnPersistentVehicle chance +_crate_weapons = (2 + (round (random 1))); +_crate_items = (6 + (round (random 3))); +_crate_backpacks = 2; + }; + case "difficult": + { +_AICount = (8 + (round (random 4))); +_VehicleChance = 30; //30% SpawnPersistentVehicle chance +_crate_weapons = (3 + (round (random 1))); +_crate_items = (9 + (round (random 3))); +_crate_backpacks = 3; + }; + //case "hardcore": + default + { +_AICount = (10 + (round (random 4))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance +_crate_weapons = (4 + (round (random 1))); +_crate_items = (12 + (round (random 6))); +_crate_backpacks = 4; + }; +}; + +// used by all +_crate_item_list = ["Exile_Item_WoodDoorKit","Exile_Item_WoodDoorwayKit","Exile_Item_WoodFloorKit","Exile_Item_WoodFloorPortKit","Exile_Item_WoodGateKit","Exile_Item_WoodStairsKit","Exile_Item_WoodSupportKit","Exile_Item_WoodWallHalfKit","Exile_Item_WoodWallKit","Exile_Item_WoodWindowKit","Exile_Item_WoodStairsKit","Exile_Item_WoodDoorwayKit","Exile_Item_WoodFloorKit","Exile_Item_WoodFloorKit","Exile_Item_WoodFloorPortKit","Exile_Item_WoodGateKit","Exile_Item_WoodStairsKit","Exile_Item_WoodSupportKit","Exile_Item_WoodWallHalfKit","Exile_Item_WoodWallKit","Exile_Item_WoodWindowKit"]; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// add vehicle patrol +_veh = +[ + [ +[(_pos select 0) -50,(_pos select 1)+50,0] + ], + _group, + "assault", + _difficulty, + _side +] call DMS_fnc_SpawnAIVehicle; + +// add static guns +_staticGuns = +[ + [ + // make statically positioned relative to centre point and randomise a little + [(_pos select 0) -(5-(random 2)),(_pos select 1)+(5-(random 2)),0], + [(_pos select 0) -(5+(random 2)),(_pos select 1)-(5+(random 2)),0], + [(_pos select 0) +(5+(random 2)),(_pos select 1)+(5+(random 2)),0], + [(_pos select 0) +(5-(random 2)),(_pos select 1)-(5-(random 2)),0] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStaticMG; + +// Create Buildings - use seperate file as found in the mercbase mission +_baseObjs = +[ + "nedbuild1_objects", + _pos +] call DMS_fnc_ImportFromM3E; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = ["Exile_Car_Ural_Covered_Worker",[(_pos select 0) -30, (_pos select 1) -30],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts grabbed all the building materials, entry code is %1...",_pinCode]]; + } else + { + _vehicle = ["Exile_Car_Ural_Covered_Worker",[(_pos select 0) -30, (_pos select 1) -30,0],[], 0, "CAN_COLLIDE"] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts grabbed all the building materials"]; + }; + +// Create Crate type +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// setup crate iteself with items +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + [_crate_items,_crate_item_list], // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns+_baseObjs+[_veh], // armed AI vehicle, base objects, and static guns + [_vehicle], //this is prize vehicle + [[_crate1,_crate_loot_values1]] //this is prize crate +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A DIY storage is under attack! Go kill the %1 attackers",_difficulty]]; + +// Define Mission Win in persistent choice + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The attackers stole everything!"]; + +// Define mission name (for map marker and logging) +_missionName = "Building Materials"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/nedcar_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/nedcar_mission.sqf new file mode 100644 index 0000000..46fade0 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/nedcar_mission.sqf @@ -0,0 +1,286 @@ +/* + nedCar Mission with new difficulty selection system + Mission gives % chance of persistent vehicle + based on work by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_extraParams", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_wreck", "_crate", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_rndlevel", "_PossibleVehicleClass", "_VehicleClass", "_PossibleDifficulty", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _vehClass or [_vehClass] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3],[],[],[]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION nedcar_mission.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that - removed "hardcore" from this mission +_PossibleDifficulty = [ + "easy", + "easy", + "easy", + "easy", + "easy", + "easy", + "moderate", + "moderate", + "difficult" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (3 + (round (random 2))); +_VehicleChance = 60; //60% SpawnPersistentVehicle chance +_crate_weapons = (2 + (round (random 3))); +_crate_items = (2 + (round (random 4))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 2))); +_VehicleChance = 70; //70% SpawnPersistentVehicle chance +_crate_weapons = (4 + (round (random 5))); +_crate_items = (4 + (round (random 6))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (5 + (round (random 3))); +_VehicleChance = 80; //80% SpawnPersistentVehicle chance +_crate_weapons = (6 + (round (random 7))); +_crate_items = (6 + (round (random 8))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (6 + (round (random 4))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance +_crate_weapons = (8 + (round (random 9))); +_crate_items = (8 + (round (random 10))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +/* no patrol vehicle as this is easy! +// add vehicle patrol +_veh = +[ + [ +[(_pos select 0) -75,(_pos select 1)+75,0] + ], + _group, + "assault", + "easy", + _side +] call DMS_fnc_SpawnAIVehicle; +*/ + +// add static guns +_staticGuns = +[ + [ + // make statically positioned relative to centre point and randomise a little + [(_pos select 0) -(5-(random 2)),(_pos select 1)+(5-(random 2)),0], + [(_pos select 0) +(5-(random 2)),(_pos select 1)-(5-(random 2)),0] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStaticMG; + +//create possible vehicle list + +// If hardcore give possibility of better car +if (_difficulty isEqualTo "hardcore") then { +_PossibleVehicleClass = [ + "Exile_Car_SUVXL_Black", + "Exile_Car_Hatchback_Sport_Red", + "Exile_Car_Hatchback_Sport_Blue", + "Exile_Car_Hatchback_Sport_Orange", + "Exile_Car_Hatchback_Sport_White", + "Exile_Car_Hatchback_Sport_Beige", + "Exile_Car_Hatchback_Sport_Green", + "Exile_Car_Lada_Green", + "Exile_Car_Lada_Red", + "Exile_Car_Lada_White", + "Exile_Car_Lada_Hipster", + "Exile_Car_Volha_Blue", + "Exile_Car_Volha_White", + "Exile_Car_Volha_Black" + ]; + } else + { +_PossibleVehicleClass = [ + "Exile_Car_Lada_Green", + "Exile_Car_Lada_Taxi", + "Exile_Car_Lada_Red", + "Exile_Car_Lada_White", + "Exile_Car_Lada_Hipster", + "Exile_Car_Volha_Blue", + "Exile_Car_Volha_White", + "Exile_Car_Volha_Black" + ]; + }; + +//choose the vehicle +_VehicleClass = selectRandom _PossibleVehicleClass; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = [_VehicleClass,[(_pos select 0) -30, (_pos select 1) -30],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts killed everyone and made off with the old car, entry code %1...",_pinCode]]; + } else + { + _vehicle = [_VehicleClass,[(_pos select 0) -30, (_pos select 1) -30]] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts killed everyone and made off with the old car"]; + }; + +// Create Crate type +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// setup crate iteself with items +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + _crate_items, // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns, // static guns - no patrol vehicle + [_vehicle], //this is prize vehicle + [[_crate1,_crate_loot_values1]] //this is prize crate +]; + +// Define Mission start message with difficulty level +_msgStart = ['#FFFF00',format["Bandits with an old car have broken down. Go kill the %1 bandits and steal their car",_difficulty]]; + +// Define Mission Win message set in persistent chance + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The attackers drove off and escaped attack."]; + +// Define mission name (for map marker and logging) +_missionName = "Old Car"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/nedcashbandits_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/nedcashbandits_mission.sqf new file mode 100644 index 0000000..0c8bd17 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/nedcashbandits_mission.sqf @@ -0,0 +1,300 @@ +/* + ned Cash Bandits Mission with difficulty selection system + Changeable % chance for permenant vehicle + rework of bandits mission with only cash reward originally created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_extraParams", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_items", "_crate_backpacks", "_PossibleDifficulty", "_cash", "_VehicleChance", "_PossibleVehicleClass", "_VehicleClass"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [25,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _classname or [_classname] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos","_pos ERROR",[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION bandits.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "easy", + "easy", + "moderate", + "moderate", + //"moderate", + //"difficult", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (3 + (round (random 2))); +_cash = (250 + round (random (500))); //this gives 250 to 750 cash +_VehicleChance = 20; //20% SpawnPersistentVehicle chance +_PossibleVehicleClass = [ "Exile_Car_Offroad_DarkRed", + "Exile_Car_Offroad_BlueCustom", + "Exile_Car_Lada_Green", + "Exile_Car_Lada_Taxi", + "Exile_Car_Lada_Red", + "Exile_Car_Lada_White", + "Exile_Car_Lada_Hipster", + "Exile_Car_Volha_Blue", + "Exile_Car_Volha_White", + "Exile_Car_Volha_Black", + "Exile_Car_Offroad_Guerilla01", + "Exile_Car_Offroad_Guerilla02", + "Exile_Car_Offroad_Guerilla03" + ]; //possible vehicle list +_crate_weapons = 0; //cash mission but you could add weapons e.g. = (2 + (round (random 3))); +_crate_items = 0; //cash mission but you could add items e.g. = (2 + (round (random 4))); +_crate_backpacks = 0; //cash mission but you could add backpacks e.g. = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 2))); +_cash = (500 + round (random (750))); //this gives 500 to 1250 cash +_VehicleChance = 25; //25% SpawnPersistentVehicle chance +_PossibleVehicleClass = [ "Exile_Car_Offroad_DarkRed", + "Exile_Car_Offroad_BlueCustom", + "Exile_Car_Offroad_Guerilla01", + "Exile_Car_Offroad_Guerilla02", + "Exile_Car_Offroad_Guerilla03", + "Exile_Car_Offroad_Guerilla04", + "Exile_Car_Offroad_Guerilla05", + "Exile_Car_Offroad_Guerilla06", + "Exile_Car_Offroad_Guerilla07", + "Exile_Car_Offroad_Guerilla08", + "Exile_Car_Offroad_Guerilla09", + "Exile_Car_Offroad_Guerilla10", + "Exile_Car_Offroad_Guerilla11", + "Exile_Car_Offroad_Guerilla12" + ]; //possible vehicle list +_crate_weapons = 0; //cash mission but you could add weapons e.g. = (2 + (round (random 3))); +_crate_items = 0; //cash mission but you could add items e.g. = (2 + (round (random 4))); +_crate_backpacks = 0; //cash mission but you could add backpacks e.g. = (1 + (round (random 1))); + }; + case "difficult": + { +_AICount = (4 + (round (random 3))); +_cash = (750 + round (random (1000))); //this gives 750 to 1750 cash +_VehicleChance = 33; //33% SpawnPersistentVehicle chance +_PossibleVehicleClass = [ "Exile_Car_Offroad_Guerilla01", + "Exile_Car_Offroad_Guerilla02", + "Exile_Car_Offroad_Guerilla03", + "Exile_Car_Offroad_Guerilla04", + "Exile_Car_Offroad_Guerilla05", + "Exile_Car_Offroad_Guerilla06", + "Exile_Car_Offroad_Guerilla07", + "Exile_Car_Offroad_Guerilla08", + "Exile_Car_Offroad_Guerilla09", + "Exile_Car_Offroad_Guerilla10", + "Exile_Car_Offroad_Guerilla11", + "Exile_Car_Offroad_Guerilla12", + "Exile_Car_Offroad_Armed_Guerilla01", + "Exile_Car_Offroad_Armed_Guerilla02", + "Exile_Car_Offroad_Armed_Guerilla03", + "Exile_Car_Offroad_Armed_Guerilla04", + "Exile_Car_Offroad_Armed_Guerilla05", + "Exile_Car_Offroad_Armed_Guerilla06" + ]; //possible vehicle list +_crate_weapons = 0; //cash mission but you could add weapons e.g. = (2 + (round (random 3))); +_crate_items = 0; //cash mission but you could add items e.g. = (2 + (round (random 4))); +_crate_backpacks = 0; //cash mission but you could add backpacks e.g. = (1 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (4 + (round (random 4))); +_cash = (1000 + round (random (1500))); //this gives 1000 to 2500 cash +_VehicleChance = 50; //50% SpawnPersistentVehicle chance +_PossibleVehicleClass = [ "Exile_Car_Offroad_Guerilla01", + "Exile_Car_Offroad_Guerilla02", + "Exile_Car_Offroad_Guerilla03", + "Exile_Car_Offroad_Guerilla04", + "Exile_Car_Offroad_Guerilla05", + "Exile_Car_Offroad_Guerilla06", + "Exile_Car_Offroad_Armed_Guerilla01", + "Exile_Car_Offroad_Armed_Guerilla02", + "Exile_Car_Offroad_Armed_Guerilla03", + "Exile_Car_Offroad_Armed_Guerilla04", + "Exile_Car_Offroad_Armed_Guerilla05", + "Exile_Car_Offroad_Armed_Guerilla06", + "Exile_Car_Offroad_Armed_Guerilla07", + "Exile_Car_Offroad_Armed_Guerilla08", + "Exile_Car_Offroad_Armed_Guerilla09", + "Exile_Car_Offroad_Armed_Guerilla10", + "Exile_Car_Offroad_Armed_Guerilla11", + "Exile_Car_Offroad_Armed_Guerilla12" + ]; //possible vehicle list +_crate_weapons = 0; //cash mission but you could add weapons e.g. = (2 + (round (random 3))); +_crate_items = 0; //cash mission but you could add items e.g. = (2 + (round (random 4))); +_crate_backpacks = 0; //cash mission but you could add backpacks e.g. = (1 + (round (random 1))); + }; +}; + +_group = + [ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. + ] call DMS_fnc_SpawnAIGroup; + +// Create Crate +_crate = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + + +// select randomly from _PossibleVehicleClass in settings +_VehicleClass = selectRandom _PossibleVehicleClass; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = [_VehicleClass,[(_pos select 0) -10, (_pos select 1) +10],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format["Convicts have successfully taken care of the bandits and taken their cash and vehicle, entry code is %1 ...",_pinCode]]; + } else + { + _vehicle = [_VehicleClass,[(_pos select 0) -10, (_pos select 1) +10]] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts have successfully taken care of the bandit group and taken their cash!"]; + }; + +// setup crate iteself with items from choice +_crate_loot_values = + [ + _crate_weapons, // Weapons + _crate_items, // Items + selection list + _crate_backpacks // Backpacks + ]; + +// add cash to crate +_crate setVariable ["ExileMoney", _cash,true]; + +// Define mission-spawned AI Units +_missionAIUnits = + [ + _group // We only spawned the single group for this mission + ]; + +// Define mission-spawned objects and loot values +_missionObjs = + [ + [], // No spawned buildings + [_vehicle], + [[_crate,_crate_loot_values]] + ]; + +// Define Mission Start message +_msgStart = ['#FFFF00',format["A heavily armed bandit group has been spotted, take the %1 bandits out and claim their vehicle and the cash they stole!",_difficulty]]; + +// Define Mission Win message in vehicle choice + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The bandits have driven off with the cash, no loot today!"]; + +// Define mission name (for map markers, mission messages, and logging) +_missionName = "Cash Bandits"; + +// Create Markers +_markers = + [ + _pos, + _missionName, + _difficulty + ] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = + [ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] + ] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/neddrinkstransport_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/neddrinkstransport_mission.sqf new file mode 100644 index 0000000..3ff7953 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/neddrinkstransport_mission.sqf @@ -0,0 +1,215 @@ +/* + Drink Transport Mission with new difficulty selection system + Originally Beer Transport Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_wreck", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// This mission doesn't use "_extraParams" in any way currently. +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION neddrinkstransport_mission.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "easy", + "easy", + "easy", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (3 + (round (random 2))); +_crate_weapons = 0; +_crate_items = (10 + (round (random 5))); +_crate_backpacks = 0; + }; + case "moderate": + { +_AICount = (4 + (round (random 2))); +_crate_weapons = 0; +_crate_items = (12 + (round (random 7))); +_crate_backpacks = 0; + }; + case "difficult": + { +_AICount = (4 + (round (random 3))); +_crate_weapons = 0; +_crate_items = (14 + (round (random 9))); +_crate_backpacks = 0; + }; + //case "hardcore": + default + { +_AICount = (4 + (round (random 4))); +_crate_weapons = 0; +_crate_items = (16 + (round (random 11))); +_crate_backpacks = 0; + }; +}; + +// used for all +_crate_item_list = ["Exile_Item_PlasticBottleCoffee", "Exile_Item_PowerDrink", "Exile_Item_PlasticBottleFreshWater", "Exile_Item_Beer", "Exile_Item_EnergyDrink", "Exile_Item_ChocolateMilk", "Exile_Item_MountainDupe"]; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// Create Crates +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +_wreck = createVehicle ["Land_Wreck_Van_F",[(_pos select 0) - 10, (_pos select 1),-0.2],[], 0, "CAN_COLLIDE"]; + +// Set crate loot values +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + [_crate_items,_crate_item_list], // Items + selection list + _crate_backpacks // Backpacks + +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [_wreck], + [], + [[_crate1,_crate_loot_values1]] +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A Bandits are moving a truck carrying their drink supplies, stop the %1 bandits and steal their supplies!",_difficulty]]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have successfully claimed all of the supplies."]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The robbers have taken off with all theit supplies, you missed out there!"]; + +// Define mission name (for map marker and logging) +_missionName = "Drink Supply"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/nedguns1_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/nedguns1_mission.sqf new file mode 100644 index 0000000..b34d3b9 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/nedguns1_mission.sqf @@ -0,0 +1,257 @@ +/* + Guns Guns Guns Mission with new difficulty selection system + Mission gives % chance of persistent vehicle + based on work by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _vehClass or [_vehClass] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3],[],[],[]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION newguns1_mission.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "moderate", + "moderate", + "difficult", + "difficult", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (3 + (round (random 2))); +_VehicleChance = 10; //10% SpawnPersistentVehicle chance +_crate_weapons = (2 + (round (random 3))); +_crate_items = (2 + (round (random 4))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 2))); +_VehicleChance = 20; //20% SpawnPersistentVehicle chance +_crate_weapons = (4 + (round (random 5))); +_crate_items = (4 + (round (random 6))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (5 + (round (random 3))); +_VehicleChance = 30; //30% SpawnPersistentVehicle chance +_crate_weapons = (6 + (round (random 7))); +_crate_items = (6 + (round (random 8))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (6 + (round (random 4))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance +_crate_weapons = (8 + (round (random 9))); +_crate_items = (8 + (round (random 10))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +//used by all +_crate_item_list = ["100Rnd_65x39_caseless_mag","100Rnd_65x39_caseless_mag_Tracer","10Rnd_127x54_Mag","10Rnd_338_Mag","10Rnd_762x54_Mag","10Rnd_762x51_Mag","150Rnd_762x51_Box","10Rnd_93x64_DMR_05_Mag","11Rnd_45ACP_Mag","150Rnd_762x54_Box","150Rnd_762x54_Box_Tracer","150Rnd_762x51_Box_Tracer","16Rnd_9x21_Mag","30Rnd_9x21_Green_Mag","30Rnd_9x21_Yellow_Mag","30Rnd_9x21_Red_Mag","200Rnd_65x39_cased_Box","200Rnd_65x39_cased_Box_Tracer","20Rnd_556x45_UW_mag","20Rnd_762x51_Mag","30Rnd_45ACP_Mag_SMG_01"]; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "assault", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// add vehicle patrol +_veh = +[ + [ +[(_pos select 0) -50,(_pos select 1)+50,0] + ], + _group, + "assault", + _difficulty, + _side +] call DMS_fnc_SpawnAIVehicle; + +// add static guns +_staticGuns = +[ + [ + // make statically positioned relative to centre point and randomise a little + [(_pos select 0) -(5-(random 2)),(_pos select 1)+(5-(random 2)),0], + [(_pos select 0) -(5+(random 2)),(_pos select 1)-(5+(random 2)),0], + [(_pos select 0) +(5+(random 2)),(_pos select 1)+(5+(random 2)),0], + [(_pos select 0) +(5-(random 2)),(_pos select 1)-(5-(random 2)),0] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStaticMG; + +// Create Buildings - use seperate file as found in the mercbase mission +_baseObjs = +[ + "nedguns1_objects", + _pos +] call DMS_fnc_ImportFromM3E; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = ["Exile_Car_Ural_Covered_Military",[(_pos select 0) -30, (_pos select 1) -30],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts have got their hands on the weapons, entry code for Ural is %1...",_pinCode]]; + } else + { + _vehicle = ["Exile_Car_Ural_Covered_Military",[(_pos select 0) -30, (_pos select 1) -30,0],[], 0, "CAN_COLLIDE"] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts have got their hands on the weapons"]; + }; + +// Create Crate type +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// setup crate iteself with items +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + [_crate_items,_crate_item_list], // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns+_baseObjs+[_veh], // armed AI vehicle, base objects, and static guns + [_vehicle], //this is prize vehicle + [[_crate1,_crate_loot_values1]] //this is prize crate +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["Some %1 terroists are out stealing guns, get in first!",_difficulty]]; + +// Define Mission Win message in vehicle persistent choice + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The attackers stole everything, no guns for you!"]; + +// Define mission name (for map marker and logging) +_missionName = "Guns Guns Guns"; + +// Create Markers - same for all levels +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/nedhatchback_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/nedhatchback_mission.sqf new file mode 100644 index 0000000..fc5b9ac --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/nedhatchback_mission.sqf @@ -0,0 +1,283 @@ +/* + nedHatchback Mission with new difficulty selection system + Mission gives % chance of persistent vehicle + based on work by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_extraParams", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_wreck", "_crate", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty", "_PossibleVehicleClass", "_VehicleClass", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _vehClass or [_vehClass] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3],[],[],[]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION nedhatchback_mission.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "easy", + "easy", + "moderate", + "moderate", + "moderate", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (3 + (round (random 2))); +_VehicleChance = 60; //60% SpawnPersistentVehicle chance +_crate_weapons = (2 + (round (random 3))); +_crate_items = (2 + (round (random 4))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 2))); +_VehicleChance = 70; //70% SpawnPersistentVehicle chance +_crate_weapons = (4 + (round (random 5))); +_crate_items = (4 + (round (random 6))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (5 + (round (random 3))); +_VehicleChance = 80; //80% SpawnPersistentVehicle chance +_crate_weapons = (6 + (round (random 7))); +_crate_items = (6 + (round (random 8))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (6 + (round (random 4))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance +_crate_weapons = (8 + (round (random 9))); +_crate_items = (8 + (round (random 10))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// add vehicle patrol +_veh = +[ + [ +[(_pos select 0) -75,(_pos select 1)+75,0] + ], + _group, + "assault", + "easy", + _side +] call DMS_fnc_SpawnAIVehicle; + +// add static guns +_staticGuns = +[ + [ + // make statically positioned relative to centre point and randomise a little + [(_pos select 0) -(5-(random 2)),(_pos select 1)+(5-(random 2)),0], + [(_pos select 0) +(5-(random 2)),(_pos select 1)-(5-(random 2)),0] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStaticMG; + +// If hardcore give possibility of better car +if (_difficulty isEqualTo "hardcore") then { +_PossibleVehicleClass = [ + "Exile_Car_Hatchback_Sport_Red", + "Exile_Car_Hatchback_Sport_Blue", + "Exile_Car_Hatchback_Sport_Orange", + "Exile_Car_Hatchback_Sport_White", + "Exile_Car_Hatchback_Sport_Beige", + "Exile_Car_Hatchback_Sport_Green", + "Exile_Car_Hatchback_Green", + "Exile_Car_Hatchback_BlueCustom", + "Exile_Car_Hatchback_BeigeCustom", + "Exile_Car_Hatchback_Yellow", + "Exile_Car_Hatchback_Grey", + "Exile_Car_Hatchback_Black", + "Exile_Car_Hatchback_Dark" + ]; + } else + { +_PossibleVehicleClass = [ + "Exile_Car_Hatchback_Beige", + "Exile_Car_Hatchback_Green", + "Exile_Car_Hatchback_Blue", + "Exile_Car_Hatchback_BlueCustom", + "Exile_Car_Hatchback_BeigeCustom", + "Exile_Car_Hatchback_Yellow", + "Exile_Car_Hatchback_Grey", + "Exile_Car_Hatchback_Black", + "Exile_Car_Hatchback_Dark", + "Exile_Car_Hatchback_Rusty1", + "Exile_Car_Hatchback_Rusty2", + "Exile_Car_Hatchback_Rusty3" + ]; + }; +//choose the vehicle +_VehicleClass = selectRandom _PossibleVehicleClass; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = [_VehicleClass,[(_pos select 0) -30, (_pos select 1) -30],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts killed everyone and made off with the hatchback, entry code %1...",_pinCode]]; + } else + { + _vehicle = [_VehicleClass,[(_pos select 0) -30, (_pos select 1) -30]] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts killed everyone and made off with the hatchback"]; + }; +// Create Crate type +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// setup crate iteself with items +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + _crate_items, // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns+[_veh], // armed AI vehicle and static guns + [_vehicle], //this is prize vehicle + [[_crate1,_crate_loot_values1]] //this is prize crate +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["Bandits with a hatchback have broken down. Go kill the %1 bandits and steal their car",_difficulty]]; + +// Define Mission Win message in persistent choice + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The attackers drove off and escaped attack."]; + +// Define mission name (for map marker and logging) +_missionName = "Hatchback Steal"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/nedhuey_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/nedhuey_mission.sqf new file mode 100644 index 0000000..4dd9255 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/nedhuey_mission.sqf @@ -0,0 +1,264 @@ +/* + Huey Mission with new difficulty selection system + Mission gives % chance of persistent vehicle + based on work by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_extraParams", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_wreck", "_crate", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_rndlevel", "_PossibleVehicleClass", "_PossibleDifficulty", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _vehClass or [_vehClass] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3],[],[],[]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION nedhuey_mission.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "moderate", + "difficult", + "difficult", + "hardcore", + "hardcore", + "hardcore", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 2))); +_VehicleChance = 10; //10% SpawnPersistentVehicle chance +_crate_weapons = (1 + (round (random 1))); +_crate_items = (2 + (round (random 5))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "moderate": + { +_AICount = (6 + (round (random 5))); +_VehicleChance = 20; //20% SpawnPersistentVehicle chance +_crate_weapons = (2 + (round (random 1))); +_crate_items = (4 + (round (random 5))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (8 + (round (random 4))); +_VehicleChance = 75; //75% SpawnPersistentVehicle chance +_crate_weapons = (3 + (round (random 1))); +_crate_items = (6 + (round (random 6))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (10 + (round (random 6))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance +_crate_weapons = (4 + (round (random 1))); +_crate_items = (8 + (round (random 7))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// add vehicle patrol +_veh = +[ + [ +[(_pos select 0) -75,(_pos select 1)+75,0] + ], + _group, + "assault", + _difficulty, + _side +] call DMS_fnc_SpawnAIVehicle; + +// add static guns +_staticGuns = +[ + [ + // make statically positioned relative to centre point and randomise a little + [(_pos select 0) -(5-(random 2)),(_pos select 1)+(5-(random 2)),0], + [(_pos select 0) +(5-(random 2)),(_pos select 1)-(5-(random 2)),0] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStaticMG; + +//create possible vehicle list +_PossibleVehicleClass = [ + "Exile_Chopper_Huey_Armed_Desert", + "Exile_Chopper_Huey_Armed_Green", + "Exile_Chopper_Huey_Desert", + "Exile_Chopper_Huey_Desert", + "Exile_Chopper_Huey_Desert", + "Exile_Chopper_Huey_Desert", + "Exile_Chopper_Huey_Desert", + "Exile_Chopper_Huey_Green", + "Exile_Chopper_Huey_Green", + "Exile_Chopper_Huey_Green", + "Exile_Chopper_Huey_Green", + "Exile_Chopper_Huey_Green" + ]; +//choose the vehicle +_VehicleClass = selectRandom _PossibleVehicleClass; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = [_VehicleClass,[(_pos select 0) -30, (_pos select 1) -30],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts killed everyone and made off with the huey, entry code %1...",_pinCode]]; + } else + { + _vehicle = [_VehicleClass,[(_pos select 0) -30, (_pos select 1) -30, 0]] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts killed everyone and made off with the huey."]; + }; + +// Create Crate type +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// setup crate iteself with items +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + _crate_items, // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns+[_veh], // armed AI vehicle and static guns + [_vehicle], //this is prize vehicle + [[_crate1,_crate_loot_values1]] //this is prize crate +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A huey has landed at a small %1 bandit base. Go kill them and steal the heli!",_difficulty]]; + +// Define Mission Win message defined in persistent choice + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The bandits flew off and the base escaped attack."]; + +// Define mission name (for map marker and logging) +_missionName = "Huey Steal"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/nedhunter_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/nedhunter_mission.sqf new file mode 100644 index 0000000..5dcc02c --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/nedhunter_mission.sqf @@ -0,0 +1,251 @@ +/* + Hunter Mission with new difficulty selection system + Mission gives % chance of persistent vehicle + based on work by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_extraParams", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_wreck", "_crate", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _vehClass or [_vehClass] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3],[],[],[]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION nedhunter_mission.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "moderate", + "moderate", + "difficult", + "difficult", + "difficult", + "difficult", + "hardcore", + "hardcore", + "hardcore", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 4))); +_VehicleChance = 10; //10% SpawnPersistentVehicle chance +_crate_weapons = (2 + (round (random 2))); +_crate_items = (4 + (round (random 4))); +_crate_backpacks = (1 + (round (random 2))); + }; + case "moderate": + { +_AICount = (6 + (round (random 4))); +_VehicleChance = 20; //20% SpawnPersistentVehicle chance +_crate_weapons = (3 + (round (random 3))); +_crate_items = (6 + (round (random 4))); +_crate_backpacks = (2 + (round (random 2))); + }; + case "difficult": + { +_AICount = (8 + (round (random 4))); +_VehicleChance = 75; //75% SpawnPersistentVehicle chance +_crate_weapons = (4 + (round (random 4))); +_crate_items = (6 + (round (random 6))); +_crate_backpacks = (3 + (round (random 2))); + }; + //case "hardcore": + default + { +_AICount = (10 + (round (random 4))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance +_crate_weapons = (5 + (round (random 5))); +_crate_items = (8 + (round (random 8))); +_crate_backpacks = (4 + (round (random 2))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// add vehicle patrol +_veh = +[ + [ +[(_pos select 0) -75,(_pos select 1)+75,0] + ], + _group, + "assault", + _difficulty, + _side +] call DMS_fnc_SpawnAIVehicle; + +// add static guns +_staticGuns = +[ + [ + // make statically positioned relative to centre point and randomise a little + [(_pos select 0) -(5-(random 2)),(_pos select 1)+(5-(random 2)),0], + [(_pos select 0) -(5+(random 2)),(_pos select 1)-(5+(random 2)),0], + [(_pos select 0) +(5+(random 2)),(_pos select 1)+(5+(random 2)),0], + [(_pos select 0) +(5-(random 2)),(_pos select 1)-(5-(random 2)),0] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStaticMG; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = ["Exile_Car_Hunter",[(_pos select 0) -30, (_pos select 1) -30],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts killed everyone and made off with the Hunter, entry code %1...",_pinCode]]; + } else + { + _vehicle = ["Exile_Car_Hunter",[(_pos select 0) -30, (_pos select 1) -30]] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts killed everyone and made off with the Hunter"]; + }; + +// Create Crate type +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// setup crate iteself with items +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + _crate_items, // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns+[_veh], // armed AI vehicle and static guns + [_vehicle], //this is prize vehicle + [[_crate1,_crate_loot_values1]] //this is prize crate +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A Hunter is parked at a small %1 base! Go kill them and steal it",_difficulty]]; + +// Define Mission Win message in persistent choice + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The attackers drove off and the base escaped attack."]; + +// Define mission name (for map marker and logging) +_missionName = "Hunter Steal"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/nedifrit_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/nedifrit_mission.sqf new file mode 100644 index 0000000..0185ce3 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/nedifrit_mission.sqf @@ -0,0 +1,251 @@ +/* + Ifrit Mission with new difficulty selection system + Mission gives % chance of persistent vehicle + based on work by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_extraParams", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_wreck", "_crate", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _vehClass or [_vehClass] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3],[],[],[]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION nedifrit_mission.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "moderate", + "moderate", + "difficult", + "difficult", + "difficult", + "difficult", + "hardcore", + "hardcore", + "hardcore", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 4))); +_VehicleChance = 10; //10% SpawnPersistentVehicle chance +_crate_weapons = (2 + (round (random 2))); +_crate_items = (4 + (round (random 4))); +_crate_backpacks = (1 + (round (random 2))); + }; + case "moderate": + { +_AICount = (6 + (round (random 4))); +_VehicleChance = 20; //20% SpawnPersistentVehicle chance +_crate_weapons = (3 + (round (random 3))); +_crate_items = (6 + (round (random 4))); +_crate_backpacks = (2 + (round (random 2))); + }; + case "difficult": + { +_AICount = (8 + (round (random 4))); +_VehicleChance = 75; //75% SpawnPersistentVehicle chance +_crate_weapons = (4 + (round (random 4))); +_crate_items = (6 + (round (random 6))); +_crate_backpacks = (3 + (round (random 2))); + }; + //case "hardcore": + default + { +_AICount = (10 + (round (random 4))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance +_crate_weapons = (5 + (round (random 5))); +_crate_items = (8 + (round (random 8))); +_crate_backpacks = (4 + (round (random 2))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// add vehicle patrol +_veh = +[ + [ +[(_pos select 0) -75,(_pos select 1)+75,0] + ], + _group, + "assault", + _difficulty, + _side +] call DMS_fnc_SpawnAIVehicle; + +// add static guns +_staticGuns = +[ + [ + // make statically positioned relative to centre point and randomise a little + [(_pos select 0) -(5-(random 2)),(_pos select 1)+(5-(random 2)),0], + [(_pos select 0) -(5+(random 2)),(_pos select 1)-(5+(random 2)),0], + [(_pos select 0) +(5+(random 2)),(_pos select 1)+(5+(random 2)),0], + [(_pos select 0) +(5-(random 2)),(_pos select 1)-(5-(random 2)),0] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStaticMG; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = ["Exile_Car_Ifrit",[(_pos select 0) -30, (_pos select 1) -30],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts killed everyone and made off with the Ifrit, entry code %1...",_pinCode]]; + } else + { + _vehicle = ["Exile_Car_Ifrit",[(_pos select 0) -30, (_pos select 1) -30]] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts killed everyone and made off with the Ifrit"]; + }; + +// Create Crate type +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// setup crate iteself with items +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + _crate_items, // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns+[_veh], // armed AI vehicle and static guns + [_vehicle], //this is prize vehicle + [[_crate1,_crate_loot_values1]] //this is prize crate +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["An Ifrit is parked at a small %1 base! Go kill them and steal it",_difficulty]]; + +// Define Mission Win message defined in persistent choice + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The attackers drove off in the Ifrit and the base escaped attack."]; + +// Define mission name (for map marker and logging) +_missionName = "Ifrit Steal"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/nedlittlebird_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/nedlittlebird_mission.sqf new file mode 100644 index 0000000..b17b298 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/nedlittlebird_mission.sqf @@ -0,0 +1,270 @@ +/* + Littlebird Mission with new difficulty selection system + Mission gives % chance of persistent vehicle + based on work by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_extraParams", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_wreck", "_crate", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_rndlevel", "_PossibleVehicleClass", "_PossibleDifficulty", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _vehClass or [_vehClass] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3],[],[],[]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION nedlittlebird_mission.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "moderate", + "difficult", + "difficult", + "difficult", + "hardcore", + "hardcore", + "hardcore", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 2))); +_VehicleChance = 10; //10% SpawnPersistentVehicle chance +_crate_weapons = (1 + (round (random 1))); +_crate_items = (2 + (round (random 5))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "moderate": + { +_AICount = (6 + (round (random 5))); +_VehicleChance = 20; //20% SpawnPersistentVehicle chance +_crate_weapons = (2 + (round (random 1))); +_crate_items = (4 + (round (random 5))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (8 + (round (random 4))); +_VehicleChance = 75; //75% SpawnPersistentVehicle chance +_crate_weapons = (3 + (round (random 1))); +_crate_items = (6 + (round (random 6))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (10 + (round (random 6))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance +_crate_weapons = (4 + (round (random 1))); +_crate_items = (8 + (round (random 7))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// add vehicle patrol +_veh = +[ + [ +[(_pos select 0) -75,(_pos select 1)+75,0] + ], + _group, + "assault", + _difficulty, + _side +] call DMS_fnc_SpawnAIVehicle; + +// add static guns +_staticGuns = +[ + [ + // make statically positioned relative to centre point and randomise a little + [(_pos select 0) -(5-(random 2)),(_pos select 1)+(5-(random 2)),0], + [(_pos select 0) +(5-(random 2)),(_pos select 1)-(5-(random 2)),0] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStaticMG; + +//create possible vehicle list +_PossibleVehicleClass = [ + "Exile_Chopper_Hummingbird_Civillian_Blue", + "Exile_Chopper_Hummingbird_Civillian_Red", + "Exile_Chopper_Hummingbird_Civillian_ION", + "Exile_Chopper_Hummingbird_Civillian_BlueLine", + "Exile_Chopper_Hummingbird_Civillian_Digital", + "Exile_Chopper_Hummingbird_Civillian_Elliptical", + "Exile_Chopper_Hummingbird_Civillian_Furious", + "Exile_Chopper_Hummingbird_Civillian_GrayWatcher", + "Exile_Chopper_Hummingbird_Civillian_Jeans", + "Exile_Chopper_Hummingbird_Civillian_Light", + "Exile_Chopper_Hummingbird_Civillian_Shadow", + "Exile_Chopper_Hummingbird_Civillian_Sheriff", + "Exile_Chopper_Hummingbird_Civillian_Speedy", + "Exile_Chopper_Hummingbird_Civillian_Sunset", + "Exile_Chopper_Hummingbird_Civillian_Vrana", + "Exile_Chopper_Hummingbird_Civillian_Wasp", + "Exile_Chopper_Hummingbird_Civillian_Wave" + ]; +//choose the vehicle +_VehicleClass = selectRandom _PossibleVehicleClass; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = [_VehicleClass,[(_pos select 0) -30, (_pos select 1) -30],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts killed everyone and made off with the heli, entry code %1...",_pinCode]]; + } else + { + _vehicle = [_VehicleClass,[(_pos select 0) -30, (_pos select 1) -30, 0]] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts killed everyone and made off with the heli."]; + }; + +// Create Crate type +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// setup crate iteself with items +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + _crate_items, // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns+[_veh], // armed AI vehicle and static guns + [_vehicle], //this is prize vehicle + [[_crate1,_crate_loot_values1]] //this is prize crate +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A heli has landed at a small %1 bandit base. Go kill them and steal the heli!",_difficulty]]; + +// Define Mission Win message defined in persistent choice + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The attackers flew off and the base escaped attack."]; + +// Define mission name (for map marker and logging) +_missionName = "Heli Steal"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/nedmedical1_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/nedmedical1_mission.sqf new file mode 100644 index 0000000..1160e3c --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/nedmedical1_mission.sqf @@ -0,0 +1,258 @@ +/* + Medical Mission Mission with new difficulty selection system + Mission gives % chance of persistent vehicle + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk + based on work by Defent and eraser1 +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _vehClass or [_vehClass] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3],[],[],[]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION newmedical1_mission.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "moderate", + "moderate", + "moderate", + "difficult", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 4))); +_VehicleChance = 10; //10% SpawnPersistentVehicle chance +_crate_weapons = (1 + (round (random 1))); +_crate_items = (3 + (round (random 3))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (6 + (round (random 4))); +_VehicleChance = 20; //20% SpawnPersistentVehicle chance +_crate_weapons = (2 + (round (random 1))); +_crate_items = (6 + (round (random 3))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (8 + (round (random 4))); +_VehicleChance = 30; //30% SpawnPersistentVehicle chance +_crate_weapons = (3 + (round (random 1))); +_crate_items = (9 + (round (random 3))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (10 + (round (random 4))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance +_crate_weapons = (4 + (round (random 1))); +_crate_items = (12 + (round (random 6))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +//used by all +_crate_item_list = ["Exile_Item_InstaDoc","Exile_Item_Bandage","Exile_Item_Vishpirin","Exile_Item_Bandage","Exile_Item_Vishpirin","Exile_Item_Bandage","Exile_Item_Vishpirin","Exile_Item_Bandage","Exile_Item_Vishpirin","Exile_Item_InstaDoc","Exile_Item_Bandage","Exile_Item_Vishpirin","Exile_Item_Bandage","Exile_Item_Vishpirin","Exile_Item_Bandage","Exile_Item_Vishpirin"]; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "assault", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// add vehicle patrol +_veh = +[ + [ +[(_pos select 0) -50,(_pos select 1)+50,0] + ], + _group, + "assault", + _difficulty, + _side +] call DMS_fnc_SpawnAIVehicle; + +// add static guns +_staticGuns = +[ + [ + // make statically positioned relative to centre point and randomise a little + [(_pos select 0) -(5-(random 2)),(_pos select 1)+(5-(random 2)),0], + [(_pos select 0) -(5+(random 2)),(_pos select 1)-(5+(random 2)),0], + [(_pos select 0) +(5+(random 2)),(_pos select 1)+(5+(random 2)),0], + [(_pos select 0) +(5-(random 2)),(_pos select 1)-(5-(random 2)),0] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStaticMG; + +// Create Buildings - use seperate file as found in the mercbase mission +_baseObjs = +[ + "nedmed1_objects", + _pos +] call DMS_fnc_ImportFromM3E; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = ["Exile_Car_Ural_Covered_Blue",[(_pos select 0) -30, (_pos select 1) -30],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts freed the hospital and got free meds, entry code is %1...",_pinCode]]; + } else + { + _vehicle = ["Exile_Car_Ural_Covered_Blue",[(_pos select 0) -30, (_pos select 1) -30,0],[], 0, "CAN_COLLIDE"] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts freed the hospital and got free meds"]; + }; + +// Create Crate type +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// setup crate iteself with items +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + [_crate_items,_crate_item_list], // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns+_baseObjs+[_veh], // armed AI vehicle, base objects, and static guns + [_vehicle], //this is prize vehicle + [[_crate1,_crate_loot_values1]] //this is prize crate +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A field hospital is under attack by bandits. Go kill the %1 attackers!",_difficulty]]; + +// Define Mission Win message defined in persistent choice + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The attackers killed the medics and stole everything!"]; + +// Define mission name (for map marker and logging) +_missionName = "Hospital Attack"; + +// Create Markers - same for all levels +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/nedoffroad_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/nedoffroad_mission.sqf new file mode 100644 index 0000000..3dd0ff4 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/nedoffroad_mission.sqf @@ -0,0 +1,272 @@ +/* + Offroad Mission with new difficulty selection system + Random selected vehicle, Mission gives % chance of persistent vehicle + based on work by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_extraParams", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_wreck", "_crate", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty", "_PossibleVehicleClass", "_VehicleClass", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _vehClass or [_vehClass] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3],[],[],[]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION nedoffroad_mission.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "moderate", + "moderate", + "moderate", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 2))); +_VehicleChance = 33; //33% SpawnPersistentVehicle chance +_crate_weapons = (1 + (round (random 2))); +_crate_items = (2 + (round (random 4))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 4))); +_VehicleChance = 40; //40% SpawnPersistentVehicle chance +_crate_weapons = (2 + (round (random 2))); +_crate_items = (4 + (round (random 4))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (4 + (round (random 4))); +_VehicleChance = 50; //50% SpawnPersistentVehicle chance +_crate_weapons = (3 + (round (random 2))); +_crate_items = (6 + (round (random 4))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (4 + (round (random 2))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance +_crate_weapons = (4 + (round (random 2))); +_crate_items = (8 + (round (random 4))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// add vehicle patrol +_veh = +[ + [ +[(_pos select 0) -75,(_pos select 1)+75,0] + ], + _group, + "assault", + "easy", + _side +] call DMS_fnc_SpawnAIVehicle; + +// add static guns +_staticGuns = +[ + [ + // make statically positioned relative to centre point and randomise a little + [(_pos select 0) -(5-(random 2)),(_pos select 1)+(5-(random 2)),0], + [(_pos select 0) +(5-(random 2)),(_pos select 1)-(5-(random 2)),0] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStaticMG; + +//create possible vehicle list +_PossibleVehicleClass = [ + "Exile_Car_Offroad_Red", + "Exile_Car_Offroad_Beige", + "Exile_Car_Offroad_White", + "Exile_Car_Offroad_Blue", + "Exile_Car_Offroad_DarkRed", + "Exile_Car_Offroad_BlueCustom", + "Exile_Car_Offroad_Guerilla01", + "Exile_Car_Offroad_Guerilla02", + "Exile_Car_Offroad_Guerilla03", + "Exile_Car_Offroad_Guerilla04", + "Exile_Car_Offroad_Guerilla05", + "Exile_Car_Offroad_Guerilla06", + "Exile_Car_Offroad_Guerilla07", + "Exile_Car_Offroad_Guerilla08", + "Exile_Car_Offroad_Guerilla09", + "Exile_Car_Offroad_Guerilla10", + "Exile_Car_Offroad_Guerilla11", + "Exile_Car_Offroad_Guerilla12", + "Exile_Car_Offroad_Rusty1", + "Exile_Car_Offroad_Rusty2", + "Exile_Car_Offroad_Rusty3" + ]; +//choose the vehicle +_VehicleClass = selectRandom _PossibleVehicleClass; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = [_VehicleClass,[(_pos select 0) -30, (_pos select 1) -30],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts killed everyone and made off with the offroad, entry code %1...",_pinCode]]; + } else + { + _vehicle = [_VehicleClass,[(_pos select 0) -30, (_pos select 1) -30]] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts killed everyone and made off with the offroad"]; + }; + +// Create Crate type +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// setup crate iteself with items +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + _crate_items, // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns+[_veh], // armed AI vehicle and static guns + [_vehicle], //this is prize vehicle + [[_crate1,_crate_loot_values1]] //this is prize crate +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["Bandits with an offroad have broken down. Go kill the % bandits and steal their offroad",_difficulty]]; + +// Define Mission Win message in persistent choice + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The attackers drove off and escaped attack."]; + +// Define mission name (for map marker and logging) +_missionName = "OffRoad Steal"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/nedresearch_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/nedresearch_mission.sqf new file mode 100644 index 0000000..325b6db --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/nedresearch_mission.sqf @@ -0,0 +1,258 @@ +/* + Research Mission with new difficulty selection system + Mission gives % chance of persistent vehicle + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk + based on work by Defent and eraser1 +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _vehClass or [_vehClass] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3],[],[],[]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION nedresearch_mission.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "moderate", + "moderate", + "difficult", + "difficult", + "difficult", + "hardcore", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 4))); +_VehicleChance = 10; //10% SpawnPersistentVehicle chance +_crate_weapons = (4 + (round (random 2))); +_crate_items = (3 + (round (random 3))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 6))); +_VehicleChance = 20; //20% SpawnPersistentVehicle chance +_crate_weapons = (6 + (round (random 3))); +_crate_items = (6 + (round (random 3))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (6 + (round (random 6))); +_VehicleChance = 30; //30% SpawnPersistentVehicle chance +_crate_weapons = (8 + (round (random 3))); +_crate_items = (8 + (round (random 4))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (8 + (round (random 8))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance +_crate_weapons = (10 + (round (random 6))); +_crate_items = (15 + (round (random 8))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +//used by all +_crate_weapon_list = ["arifle_SDAR_F","arifle_MX_GL_Black_F","MMG_01_hex_F","MMG_01_tan_F","MMG_02_black_F","MMG_02_camo_F","MMG_02_sand_F","hgun_PDW2000_F","SMG_01_F","hgun_Pistol_heavy_01_F","hgun_Pistol_heavy_02_F"]; +_crate_item_list = ["H_HelmetLeaderO_ocamo","H_HelmetLeaderO_ocamo","H_HelmetLeaderO_oucamo","H_HelmetLeaderO_oucamo","U_B_survival_uniform","U_B_Wetsuit","U_O_Wetsuit","U_I_Wetsuit","H_HelmetB_camo","H_HelmetSpecB","H_HelmetSpecO_blk","Exile_Item_EMRE","Exile_Item_InstantCoffee","Exile_Item_PowerDrink","Exile_Item_InstaDoc"]; + +// Create Buildings - use seperate file as found in the mercbase mission +_baseObjs = +[ + "nedresearch_objects", + _pos +] call DMS_fnc_ImportFromM3E; + +_group = +[ + [[(_pos select 0)+2,(_pos select 1)+4,0],[(_pos select 0)-10,(_pos select 1)+0,0]], // Position AI in tent + 2nd squad + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "assault", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup_MultiPos; + +// add vehicle patrol +_veh = +[ + [ + [(_pos select 0)+5,(_pos select 1)+40,0] + ], + _group, + "assault", + _difficulty, + _side +] call DMS_fnc_SpawnAIVehicle; + +// add static guns +_staticGuns = +[ + [ + // make statically positioned relative to centre point, keep static as they are on top of building + [(_pos select 0)+7,(_pos select 1)+3,(_pos select 2)+3.11146], + [(_pos select 0)+7,(_pos select 1)+4,(_pos select 2)+3.11146] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStaticMG; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = ["Exile_Car_Ural_Covered_Yellow",[(_pos select 0) -30, (_pos select 1) -0],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts have taken over the research camp, vehicle entry code is %1...",_pinCode]]; + } else + { + _vehicle = ["Exile_Car_Ural_Covered_Yellow",[(_pos select 0)-30,(_pos select 1)+0,0],[], 0, "CAN_COLLIDE"] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts have taken over the research camp"]; + }; + +// Create Crate type +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// setup crate iteself with items +_crate_loot_values1 = +[ + [_crate_weapons,_crate_weapon_list], // Weapons + [_crate_items,_crate_item_list], // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns+_baseObjs+[_veh], // armed AI vehicle, base objects, and static guns + [_vehicle], //this is prize vehicle + [[_crate1,_crate_loot_values1]] //this is prize crate +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A research camp with %1 bandits has been spotted, find out what they are up to",_difficulty]]; + +// Define Mission Win message defined in persistent choice + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The research camp has packed up and left with whatever they were making"]; + +// Define mission name (for map marker and logging) +_missionName = "Research Camp"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/nedsnipercamp_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/nedsnipercamp_mission.sqf new file mode 100644 index 0000000..d1af1d9 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/nedsnipercamp_mission.sqf @@ -0,0 +1,279 @@ +/* + Sniper Camp Mission with new difficulty selection system + Mission gives % chance of persistent vehicle + based on work by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _vehClass or [_vehClass] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3],[],[],[]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION nedsnipercamp_mission.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "moderate", + "moderate", + "difficult", + "difficult", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 4))); +_VehicleChance = 10; //10% SpawnPersistentVehicle chance +_crate_weapons = (4 + (round (random 2))); +_crate_weapon_list = ["arifle_MXM_Black_F","srifle_DMR_01_F","srifle_EBR_F","srifle_GM6_camo_F","srifle_LRR_camo_F"]; +_crate_items = (8 + (round (random 3))); +_crate_item_list = ["10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","100Rnd_65x39_caseless_mag","10Rnd_127x54_Mag","16Rnd_9x21_Mag","30Rnd_65x39_caseless_mag","30Rnd_556x45_Stanag"]; +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (6 + (round (random 4))); +_VehicleChance = 20; //20% SpawnPersistentVehicle chance +_crate_weapons = (6 + (round (random 2))); +_crate_weapon_list = ["arifle_MXM_Black_F","srifle_DMR_01_F","srifle_EBR_F","srifle_GM6_camo_F","srifle_LRR_camo_F"]; +_crate_items = (10 + (round (random 3))); +_crate_item_list = ["10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","100Rnd_65x39_caseless_mag","10Rnd_127x54_Mag","16Rnd_9x21_Mag","30Rnd_65x39_caseless_mag","30Rnd_556x45_Stanag"]; +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (8 + (round (random 4))); +_VehicleChance = 30; //30% SpawnPersistentVehicle chance +_crate_weapons = (9 + (round (random 2))); +_crate_weapon_list = ["srifle_DMR_03_khaki_F","srifle_DMR_03_tan_F","srifle_DMR_03_woodland_F","srifle_DMR_05_blk_F","srifle_DMR_05_hex_F","srifle_DMR_06_camo_F","srifle_DMR_06_olive_F","srifle_EBR_F","srifle_GM6_camo_F","srifle_LRR_camo_F"]; +_crate_items = (14 + (round (random 3))); +_crate_item_list = ["10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","100Rnd_65x39_caseless_mag","10Rnd_127x54_Mag","16Rnd_9x21_Mag","100Rnd_65x39_caseless_mag","10Rnd_127x54_Mag","16Rnd_9x21_Mag","30Rnd_65x39_caseless_mag","30Rnd_556x45_Stanag"]; +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (8 + (round (random 8))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance +_crate_weapons = (14 + (round (random 2))); +_crate_weapon_list = ["srifle_DMR_02_camo_F","srifle_DMR_02_sniper_F","srifle_DMR_03_khaki_F","srifle_DMR_03_multicam_F","srifle_DMR_03_woodland_F","srifle_DMR_04_F","srifle_DMR_04_Tan_F","srifle_DMR_05_blk_F","srifle_DMR_05_hex_F","srifle_DMR_05_tan_f","srifle_DMR_06_camo_F","srifle_DMR_06_olive_F","srifle_EBR_F","srifle_GM6_camo_F","srifle_LRR_camo_F"]; +_crate_items = (17 + (round (random 3))); +_crate_item_list = ["10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","10Rnd_93x64_DMR_05_Mag","100Rnd_65x39_caseless_mag","10Rnd_127x54_Mag","16Rnd_9x21_Mag","100Rnd_65x39_caseless_mag","10Rnd_127x54_Mag","16Rnd_9x21_Mag","30Rnd_65x39_caseless_mag","16Rnd_9x21_Mag","100Rnd_65x39_caseless_mag","10Rnd_127x54_Mag","16Rnd_9x21_Mag","30Rnd_65x39_caseless_mag","30Rnd_556x45_Stanag"]; +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +// Hardcore needs different settings for AI +if (_difficulty isEqualTo "hardcore") then { +_group = +[ + [[(_pos select 0)+3,(_pos select 1)-3,0],[(_pos select 0)+(10+(random 20)),(_pos select 1)+(10+(random 20)),0]], // Position AI in tent + 2nd squad + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "sniper", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup_MultiPos; + } else + { +_group = +[ + [(_pos select 0)+3,(_pos select 1)-3,0], // Position AI in tent + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "sniper", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + }; + +// add vehicle patrol and randomise a little - same for all levels (as it uses variable) +_veh = +[ + [ +[(_pos select 0) -(75-(random 25)),(_pos select 1) +(75+(random 25)),0] + ], + _group, + "assault", + _difficulty, + _side +] call DMS_fnc_SpawnAIVehicle; + +// add static guns - same for all levels +_staticGuns = +[ + [ + // make statically positioned relative to centre point and randomise a little + [(_pos select 0) -(5-(random 1)),(_pos select 1)+(5-(random 1)),0], + [(_pos select 0) +(5-(random 1)),(_pos select 1)-(5-(random 1)),0] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStaticMG; + +// Create Buildings - use seperate file as found in the mercbase mission - same for all levels +_baseObjs = +[ + "nedsnipercamp_objects", + _pos +] call DMS_fnc_ImportFromM3E; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = ["Exile_Car_Ural_Covered_Military",[(_pos select 0) +17.2, (_pos select 1) -0],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts have killed the snipers and stolen their rifles,the truck code is %1...",_pinCode]]; + } else + { + _vehicle = ["Exile_Car_Ural_Covered_Military",[(_pos select 0) +17.2, (_pos select 1) -0,0],[], 0, "CAN_COLLIDE"] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts have killed the snipers and stolen their rifles"]; + }; + +// Create Crate type - same for all levels +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// setup crate iteself with items - same for all levels +_crate_loot_values1 = +[ + [_crate_weapons,_crate_weapon_list], // Weapons + [_crate_items,_crate_item_list], // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns+_baseObjs+[_veh], // armed AI vehicle, base objects, and static guns + [_vehicle], //this is prize vehicle + [[_crate1,_crate_loot_values1]] //this is prize crate +]; + +// Define Mission start message with difficulty level - choice due to "an" being required for "an easy" and "a" for rest +if (_difficulty isEqualTo "easy") then { +_msgStart = ['#FFFF00',format["Snipers have set up an %1 training camp, go steal their rifles",_difficulty]]; + } else + { +_msgStart = ['#FFFF00',format["Snipers have set up a %1 training camp, go steal their rifles",_difficulty]]; + }; + +// Define Mission Win message - defined in choices + +// Define Mission Lose message - same for all levels +_msgLOSE = ['#FF0000',"The Snipers have packed up and left, no rifles for you!"]; + +// Define mission name (for map marker and logging) - same for all levels +_missionName = "Sniper Camp"; + +// Create Markers - same for all levels +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/nedstrider_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/nedstrider_mission.sqf new file mode 100644 index 0000000..cf005c0 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/nedstrider_mission.sqf @@ -0,0 +1,252 @@ +/* + Strider Mission with new difficulty selection system + Mission gives % chance of persistent vehicle + based on work by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_extraParams", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_wreck", "_crate", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_rndlevel", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _vehClass or [_vehClass] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3],[],[],[]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION nedstrider_mission.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "moderate", + "moderate", + "difficult", + "difficult", + "difficult", + "difficult", + "hardcore", + "hardcore", + "hardcore", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 4))); +_VehicleChance = 10; //10% SpawnPersistentVehicle chance +_crate_weapons = (2 + (round (random 2))); +_crate_items = (4 + (round (random 4))); +_crate_backpacks = (1 + (round (random 2))); + }; + case "moderate": + { +_AICount = (6 + (round (random 4))); +_VehicleChance = 20; //20% SpawnPersistentVehicle chance +_crate_weapons = (3 + (round (random 3))); +_crate_items = (6 + (round (random 4))); +_crate_backpacks = (2 + (round (random 2))); + + }; + case "difficult": + { +_AICount = (8 + (round (random 4))); +_VehicleChance = 75; //75% SpawnPersistentVehicle chance +_crate_weapons = (4 + (round (random 4))); +_crate_items = (6 + (round (random 6))); +_crate_backpacks = (3 + (round (random 2))); + }; + //case "hardcore": + default + { +_AICount = (10 + (round (random 4))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance +_crate_weapons = (5 + (round (random 5))); +_crate_items = (8 + (round (random 8))); +_crate_backpacks = (4 + (round (random 2))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// add vehicle patrol +_veh = +[ + [ +[(_pos select 0) -75,(_pos select 1)+75,0] + ], + _group, + "assault", + _difficulty, + _side +] call DMS_fnc_SpawnAIVehicle; + +// add static guns +_staticGuns = +[ + [ + // make statically positioned relative to centre point and randomise a little + [(_pos select 0) -(5-(random 2)),(_pos select 1)+(5-(random 2)),0], + [(_pos select 0) -(5+(random 2)),(_pos select 1)-(5+(random 2)),0], + [(_pos select 0) +(5+(random 2)),(_pos select 1)+(5+(random 2)),0], + [(_pos select 0) +(5-(random 2)),(_pos select 1)-(5-(random 2)),0] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStaticMG; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = ["Exile_Car_Strider",[(_pos select 0) -30, (_pos select 1) -30],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts killed everyone and made off with the Strider, entry code %1...",_pinCode]]; + } else + { + _vehicle = ["Exile_Car_Strider",[(_pos select 0) -30, (_pos select 1) -30]] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts killed everyone and made off with the Strider"]; + }; + +// Create Crate type +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// setup crate iteself with items +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + _crate_items, // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns+[_veh], // armed AI vehicle and static guns + [_vehicle], //this is prize vehicle + [[_crate1,_crate_loot_values1]] //this is prize crate +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A Strider is parked at a small %1 base. Go kill them and steal it!",_difficulty]]; + +// Define Mission Win message defined in difficulty choice + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The attackers drove off with the Strider and the base escaped attack."]; + +// Define mission name (for map marker and logging) +_missionName = "Strider Steal"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/nedural_mission.sqf b/@ExileServer/addons/a3_dms/missions/bandit/nedural_mission.sqf new file mode 100644 index 0000000..9ca89b7 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/nedural_mission.sqf @@ -0,0 +1,260 @@ +/* + Ural Mission with new difficulty selection system + Mission gives % chance of persistent vehicle + based on work by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_extraParams", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_wreck", "_crate", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty", "_PossibleVehicleClass", "_VehicleClass", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _vehClass or [_vehClass] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3],[],[],[]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION nedural_mission.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "moderate", + "moderate", + "moderate", + "difficult", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 2))); +_VehicleChance = 10; //10% SpawnPersistentVehicle chance +_crate_weapons = (1 + (round (random 1))); +_crate_items = (2 + (round (random 4))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 4))); +_VehicleChance = 20; //20% SpawnPersistentVehicle chance +_crate_weapons = (2 + (round (random 2))); +_crate_items = (4 + (round (random 4))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (4 + (round (random 4))); +_VehicleChance = 75; //75% SpawnPersistentVehicle chance +_crate_weapons = (3 + (round (random 3))); +_crate_items = (4 + (round (random 6))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (6 + (round (random 4))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance +_crate_weapons = (4 + (round (random 4))); +_crate_items = (6 + (round (random 6))); +_crate_backpacks = (4 + (round (random 2))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// add vehicle patrol +_veh = +[ + [ +[(_pos select 0) -75,(_pos select 1)+75,0] + ], + _group, + "assault", + _difficulty, + _side +] call DMS_fnc_SpawnAIVehicle; + +// add static guns +_staticGuns = +[ + [ + // make statically positioned relative to centre point and randomise a little + [(_pos select 0) -(5-(random 2)),(_pos select 1)+(5-(random 2)),0], + [(_pos select 0) +(5-(random 2)),(_pos select 1)-(5-(random 2)),0] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStaticMG; + +//create possible vehicle list +_PossibleVehicleClass = [ + "Exile_Car_Ural_Open_Blue", + "Exile_Car_Ural_Open_Yellow", + "Exile_Car_Ural_Open_Worker", + "Exile_Car_Ural_Open_Military", + "Exile_Car_Ural_Covered_Blue", + "Exile_Car_Ural_Covered_Yellow", + "Exile_Car_Ural_Covered_Worker", + "Exile_Car_Ural_Covered_Military" + ]; +//choose the vehicle +_VehicleClass = selectRandom _PossibleVehicleClass; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = [_VehicleClass,[(_pos select 0) -30, (_pos select 1) -30],_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts killed everyone and made off with the Ural, entry code %1...",_pinCode]]; + } else + { + _vehicle = [_VehicleClass,[(_pos select 0) -30, (_pos select 1) -30]] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts killed everyone and made off with the Ural"]; + }; + +// Create Crate type +_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// setup crate iteself with items +_crate_loot_values1 = +[ + _crate_weapons, // Weapons + _crate_items, // Items + selection list + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns+[_veh], // armed AI vehicle and static guns + [_vehicle], //this is prize vehicle + [[_crate1,_crate_loot_values1]] //this is prize crate +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["Bandits with a Ural have stopped for lunch. Go kill the %1 bandits and steal the truck",_difficulty]]; + +// Define Mission Win message in persistent vehicle choice + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The attackers finished eating and drove off."]; + +// Define mission name (for map marker and logging) +_missionName = "Ural Picnic"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/roguenavyseals.sqf b/@ExileServer/addons/a3_dms/missions/bandit/roguenavyseals.sqf new file mode 100644 index 0000000..6f3bc20 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/roguenavyseals.sqf @@ -0,0 +1,207 @@ +/* + Rogue Navy Seals Mission with new difficulty selection system + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_pos", "_OK", "_difficulty", "_extraParams", "_AICount", "_group", "_type", "_launcher", "_staticGuns", "_wreck", "_crate", "_crate1", "_vehicle", "_pinCode", "_class", "_veh", "_crate_loot_values", "_crate_loot_values1", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_baseObjs", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// This mission doesn't use "_extraParams" in any way currently. +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION roguenavyseals.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "easy", + "easy", + "moderate", + "moderate", + "moderate", + "difficult", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (3 + (round (random 2))); +_crate_weapons = (2 + (round (random 4))); +_crate_items = (2 + (round (random 4))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (4 + (round (random 2))); +_crate_weapons = (5 + (round (random 4))); +_crate_items = (5 + (round (random 4))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (4 + (round (random 3))); +_crate_weapons = (7 + (round (random 4))); +_crate_items = (7 + (round (random 4))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (5 + (round (random 4))); +_crate_weapons = (9 + (round (random 4))); +_crate_items = (9 + (round (random 4))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// Create Crate +_crate = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; + +// Set crate loot values +_crate_loot_values = +[ + _crate_weapons, // Weapons + _crate_items, // Items + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [], + [], + [[_crate,_crate_loot_values]] +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A squad of %1 Navy Seals is performing gorilla warfare in convict land. Deal with them!",_difficulty]]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have successfully taken care of the Navy Seals. You must be the top of your class!"]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The Navy Seals have escaped and are now planning their next raid!"]; + +// Define mission name (for map marker and logging) +_missionName = "Rogue Navy Seals"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/thieves.sqf b/@ExileServer/addons/a3_dms/missions/bandit/thieves.sqf new file mode 100644 index 0000000..efcf701 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/thieves.sqf @@ -0,0 +1,229 @@ +/* + Thieves Mission with new difficulty selection system + Mission gives % chance of persistent vehicle + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_OK", "_group", "_pos", "_difficulty", "_AICount", "_extraParams", "_type", "_launcher", "_class", "_pinCode", "_vehicle", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_PossibleDifficulty", "_VehicleChance"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [15,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// You can define "_extraParams" to specify the vehicle classname to spawn, either as _classname or [_classname] +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION thieves.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "easy", + "easy", + "easy", + "easy", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (3 + (round (random 2))); +_VehicleChance = 10; //10% SpawnPersistentVehicle chance + }; + case "moderate": + { +_AICount = (4 + (round (random 2))); +_VehicleChance = 20; //20% SpawnPersistentVehicle chance + }; + case "difficult": + { +_AICount = (4 + (round (random 3))); +_VehicleChance = 50; //50% SpawnPersistentVehicle chance + }; + //case "hardcore": + default + { +_AICount = (4 + (round (random 4))); +_VehicleChance = 90; //90% SpawnPersistentVehicle chance + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +_class = + if (_extraParams isEqualTo []) then + { + DMS_CarThievesVehicles call BIS_fnc_SelectRandom + } + else + { + if (_extraParams isEqualType "") then + { + _extraParams + } + else + { + if ((_extraParams isEqualType []) && {(_extraParams select 0) isEqualType ""}) then + { + _extraParams select 0 + } + else + { + DMS_CarThievesVehicles call BIS_fnc_SelectRandom + }; + }; + }; + +// is %chance greater than random number +if (_VehicleChance >= (random 100)) then { + _pinCode = (1000 +(round (random 8999))); + _vehicle = [_class,_pos,_pinCode] call DMS_fnc_SpawnPersistentVehicle; + _msgWIN = ['#0080ff',format ["Convicts have eliminated the thieves! Looks like the thieves managed to figure out that the code was %1...",_pinCode]]; + + } else + { + _vehicle = [_class,_pos] call DMS_fnc_SpawnNonPersistentVehicle; + _msgWIN = ['#0080ff',"Convicts have eliminated the thieves! Looks like the thieves managed to steal the vehicle"]; + }; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects +_missionObjs = +[ + [], // No spawned buildings + [_vehicle], + [] +]; + +// Define Mission Start message +_msgStart = ['#FFFF00',format ["A band of thieves are attempting to break into a %1. Eliminate them and you might get the car for yourself!",getText (configFile >> "CfgVehicles" >> _class >> "displayName")]]; + +// Define Mission Win message in persistent choice + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The thieves cracked the code and drove off!"]; + +// Define mission name (for map markers, mission messages, and logging) +_missionName = "Car Thieves"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group, + true + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/bandit/walmart.sqf b/@ExileServer/addons/a3_dms/missions/bandit/walmart.sqf new file mode 100644 index 0000000..846d37c --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/bandit/walmart.sqf @@ -0,0 +1,208 @@ +/* + Walmart Mission with new difficulty selection system + Created by Defent and eraser1 + easy/mod/difficult/hardcore - reworked by [CiC]red_ned http://cic-gaming.co.uk +*/ + +private ["_num", "_side", "_OK", "_group", "_pos", "_difficulty", "_AICount", "_type", "_launcher", "_crate", "_wreck1", "_wreck2", "_wreck3", "_wreck4", "_wreck5", "_crate_loot_values", "_missionAIUnits", "_missionObjs", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_markers", "_time", "_added", "_cleanup", "_crate_weapons", "_crate_weapon_list", "_crate_items", "_crate_item_list", "_crate_backpacks", "_PossibleDifficulty"]; + +// For logging purposes +_num = DMS_MissionCount; + +// Set mission side +_side = "bandit"; + +// This part is unnecessary, but exists just as an example to format the parameters for "DMS_fnc_MissionParams" if you want to explicitly define the calling parameters for DMS_fnc_FindSafePos. +// It also allows anybody to modify the default calling parameters easily. +if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then +{ + _this = + [ + [10,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists], + [ + [] + ], + _this + ]; +}; + +// Check calling parameters for manually defined mission position. +// This mission doesn't use "_extraParams" in any way currently. +_OK = (_this call DMS_fnc_MissionParams) params +[ + ["_pos",[],[[]],[3]], + ["_extraParams",[]] +]; + +if !(_OK) exitWith +{ + diag_log format ["DMS ERROR :: Called MISSION walmart.sqf with invalid parameters: %1",_this]; +}; + +//create possible difficulty add more of one difficulty to weight it towards that +_PossibleDifficulty = [ + "easy", + "easy", + "easy", + "easy", + "moderate", + "moderate", + "moderate", + "difficult", + "difficult", + "hardcore" + ]; +//choose difficulty and set value +_difficulty = selectRandom _PossibleDifficulty; + +switch (_difficulty) do +{ + case "easy": + { +_AICount = (4 + (round (random 2))); +_crate_weapons = (1 + (round (random 1))); +_crate_items = (2 + (round (random 4))); +_crate_backpacks = (1 + (round (random 1))); + }; + case "moderate": + { +_AICount = (6 + (round (random 2))); +_crate_weapons = (2 + (round (random 1))); +_crate_items = (5 + (round (random 5))); +_crate_backpacks = (2 + (round (random 1))); + }; + case "difficult": + { +_AICount = (6 + (round (random 4))); +_crate_weapons = (3 + (round (random 1))); +_crate_items = (8 + (round (random 5))); +_crate_backpacks = (3 + (round (random 1))); + }; + //case "hardcore": + default + { +_AICount = (6 + (round (random 4))); +_crate_weapons = (4 + (round (random 1))); +_crate_items = (12 + (round (random 5))); +_crate_backpacks = (4 + (round (random 1))); + }; +}; + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + _difficulty, // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +// Create Crate +_crate = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; +_wreck1 = createVehicle ["Land_i_Shop_01_V1_F",[(_pos select 0) - 10, (_pos select 1),-0.1],[], 0, "CAN_COLLIDE"]; +_wreck2 = createVehicle ["Land_Sacks_goods_F",[(_pos select 0) - 2, (_pos select 1),-0.8],[], 0, "CAN_COLLIDE"]; +_wreck3 = createVehicle ["Land_StallWater_F",[(_pos select 0) - 5, (_pos select 1),-0.8],[], 0, "CAN_COLLIDE"]; +_wreck4 = createVehicle ["Land_WoodenCart_F",[(_pos select 0) - 16, (_pos select 1),-0.5],[], 0, "CAN_COLLIDE"]; +_wreck5 = createVehicle ["Land_CratesWooden_F",[(_pos select 0) - 16, (_pos select 1),-0.3],[], 0, "CAN_COLLIDE"]; + +// Set crate loot values +_crate_loot_values = +[ + _crate_weapons, // Weapons + _crate_items, // Items + _crate_backpacks // Backpacks +]; + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [_wreck1,_wreck2,_wreck3,_wreck4,_wreck5], + [], + [[_crate,_crate_loot_values]] +]; + +// define start messages with difficulty choice +_msgStart = ['#FFFF00',format["A local Walmart shop is being raided. Stop the %1 raiders and take the loot!",_difficulty]]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have done a good deed and stopped the raiders!"]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The raiders have looted everything from Walmart and escaped!"]; + +// Define mission name (for map marker and logging) +_missionName = "Walmart Riot"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + _cleanup call DMS_fnc_CleanUp; + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/missions/mission_init.sqf b/@ExileServer/addons/a3_dms/missions/mission_init.sqf new file mode 100644 index 0000000..71b5cfb --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/mission_init.sqf @@ -0,0 +1,38 @@ +/* + mission_init.sqf + Created by eraser1 + + Initializes dynamic mission variables for DMS +*/ + +diag_log "DMS :: Initializing Dynamic Mission Variables"; + +// Initialize Variables +DMS_Mission_Arr = []; +DMS_MissionCount = 0; +DMS_RunningBMissionCount = 0; +DMS_BMissionLastStart = diag_tickTime; +DMS_BMissionDelay = DMS_TimeToFirstMission call DMS_fnc_SelectRandomVal; + + +if (DMS_DEBUG) then +{ + diag_log format ["DMS_DEBUG mission_init :: Random time between missions is initially set to %1s | DMS_BMissionLastStart: %2",DMS_BMissionDelay,DMS_BMissionLastStart]; +}; + +// Set mission frequencies from config +DMS_BanditMissionTypesArray = []; +{ + private _missionName = _x select 0; + + for "_i" from 1 to (_x select 1) do + { + DMS_BanditMissionTypesArray pushBack _missionName; + }; + + missionNamespace setVariable + [ + format["DMS_Mission_%1",_missionName], + compileFinal preprocessFileLineNumbers (format ["\x\addons\DMS\missions\bandit\%1.sqf",_missionName]) + ]; +} forEach DMS_BanditMissionTypes; diff --git a/@ExileServer/addons/a3_dms/missions/static/occupation.sqf b/@ExileServer/addons/a3_dms/missions/static/occupation.sqf new file mode 100644 index 0000000..5d1074c --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/static/occupation.sqf @@ -0,0 +1,495 @@ +/* + "Occupation" static mission for Altis, Chernarus, Namalsk and Taviana + Created by second_coming + Multi-map positions help from Diamond +*/ + +private["_wp","_wp2","_wp3","_pos","_missionName","_msgStart","_msgWIN","_msgLOSE"]; + +// For logging purposes +private _num = DMS_MissionCount; + + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +switch (toLower worldName) do +{ + case "taviana": + { + _pos = [14000,12220,0]; + _missionName = "Solibor Occupation"; + _msgStart = ['#FFFF00',"Solibor is under martial law! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the town of Solibor and secured the cache!"]; + _msgLOSE = ['#FF0000',"The troops have left Solibor, taking the cache with them..."]; + }; + + case "namalsk": + { + _pos = [3926,7523,0]; + _missionName = "Norinsk Occupation"; + _msgStart = ['#FFFF00',"Norinsk is under martial law! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the town of Norinsk and secured the cache!"]; + _msgLOSE = ['#FF0000',"The troops have left Norinsk, taking the cache with them..."]; + }; + + case "napf": + { + _chance = floor(random 2); + switch (_chance) do + { + case 0: + { + _pos = [8846,16066,0]; + _missionName = "Lenzburg Occupation"; + _msgStart = ['#FFFF00',"Lenzburg is under martial law! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the town of Lenzburg and secured the cache!"]; + _msgLOSE = ['#FF0000',"The troops have left Lenzburg, taking the cache with them..."]; + }; + case 1: + { + _pos = [2426,7712,0]; + _missionName = "Worb Occupation"; + _msgStart = ['#FFFF00',"Worb is under martial law! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the town of Worb and secured the cache!"]; + _msgLOSE = ['#FF0000',"The troops have left Worb, taking the cache with them..."]; + }; + }; + }; + + case "chernarus": + { + _chance = floor(random 4); + switch (_chance) do + { + case 0: + { + _pos = [3810,8887,0]; + _missionName = "Vybor Occupation"; + _msgStart = ['#FFFF00',"Vybor is under martial law! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the town of Vybor and secured the cache!"]; + _msgLOSE = ['#FF0000',"The troops have left Vybor, taking the cache with them..."]; + }; + case 1: + { + _pos = [12024,9083,0]; + _missionName = "Berenzio Occupation"; + _msgStart = ['#FFFF00',"Berenzio is under martial law! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the town of Berenzio and secured the cache!"]; + _msgLOSE = ['#FF0000',"The troops have left Berenzio, taking the cache with them..."]; + }; + case 2: + { + _pos = [6773,2365,0]; + _missionName = "Chernogorsk Occupation"; + _msgStart = ['#FFFF00',"Chernogorsk is under martial law! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the town of Chernogorsk and secured the cache!"]; + _msgLOSE = ['#FF0000',"The troops have left Chernogorsk, taking the cache with them..."]; + }; + case 3: + { + _pos = [6079.98,7789,0]; + _missionName = "Stary Sobar Occupation"; + _msgStart = ['#FFFF00',"Stary Sobar is under martial law! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the town of Stary Sobar and secured the cache!"]; + _msgLOSE = ['#FF0000',"The troops have left Stary Sobar, taking the cache with them..."]; + }; + }; + }; + + case "altis": + { + _chance = floor(random 5); + switch (_chance) do + { + case 0: + { + _pos = [12571,14337,0]; + _missionName = "Neochori Occupation"; + _msgStart = ['#FFFF00',"Neochori is under martial law! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the town of Neochori and secured the cache!"]; + _msgLOSE = ['#FF0000',"The troops have left Neochori, taking the cache with them..."]; + }; + case 1: + { + _pos = [3679,13048,0]; + _missionName = "Kavala Occupation"; + _msgStart = ['#FFFF00',"Kavala is under martial law! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the town of Kavala and secured the cache!"]; + _msgLOSE = ['#FF0000',"The troops have left Kavala, taking the cache with them..."]; + }; + case 2: + { + _pos = [16812,12610,0]; + _missionName = "Pyrgos Occupation"; + _msgStart = ['#FFFF00',"Pyrgos is under martial law! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the town of Pyrgos and secured the cache!"]; + _msgLOSE = ['#FF0000',"The troops have left Pyrgos, taking the cache with them..."]; + }; + case 3: + { + _pos = [20885,16947,0]; + _missionName = "Paros Occupation"; + _msgStart = ['#FFFF00',"Paros is under martial law! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the town of Paros and secured the cache!"]; + _msgLOSE = ['#FF0000',"The troops have left Paros, taking the cache with them..."]; + }; + case 4: + { + _pos = [25764,21344,0]; + _missionName = "Sofia Occupation"; + _msgStart = ['#FFFF00',"Sofia is under martial law! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the town of Sofia and secured the cache!"]; + _msgLOSE = ['#FF0000',"The troops have left Sofia, taking the cache with them..."]; + }; + }; + }; + + case "esseker": + { + _chance = floor(random 4); + switch (_chance) do + { + case 0: + { + _pos = [1120,10279,0]; + _missionName = "Camp Spencer Occupation"; + _msgStart = ['#FFFF00',"Camp Spencer is under bandit control! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted Camp Spencer and secured the cache!"]; + _msgLOSE = ['#FF0000',"The Bandits have left Camp Spencer, taking the cache with them..."]; + }; + case 1: + { + _pos = [11932,7920,0]; + _missionName = "Novi Grad Occupation"; + _msgStart = ['#FFFF00',"Novi Grad is under bandit control! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the town of Novi Grad and secured the cache!"]; + _msgLOSE = ['#FF0000',"The Bandits have left Novi Grad, taking the cache with them..."]; + }; + case 2: + { + _pos = [8771,5438,0]; + _missionName = "Old Essker Raid"; + _msgStart = ['#FFFF00',"Old Essker is Being occupied by bandits! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the Old Essker Ruins and secured the cache!"]; + _msgLOSE = ['#FF0000',"The bandits have left the Old Essker Ruins, taking the cache with them..."]; + }; + case 3: + { + _pos = [4493,3597,0]; + _missionName = "Petlov Grad Park Occupation"; + _msgStart = ['#FFFF00',"Petlov Grad Park is under bandits Occupation! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the Park and secured the cache!"]; + _msgLOSE = ['#FF0000',"The bandits have left Petlov Grad Park, taking the cache with them..."]; + }; + }; + }; + + case "tanoa": + { + _chance = floor(random 7); + switch (_chance) do + { + case 0: + { + _pos = [11621,2648,0]; + _missionName = "Lijnhaven Occupation"; + _msgStart = ['#FFFF00',"Lijnhaven is under martial law! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the town of Lijnhaven and secured the cache!"]; + _msgLOSE = ['#FF0000',"The troops have left Lijnhaven, taking the cache with them..."]; + }; + case 1: + { + _pos = [5850,10216,0]; + _missionName = "Georgetown Occupation"; + _msgStart = ['#FFFF00',"Georgetown is under martial law! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the town of Georgetown and secured the cache!"]; + _msgLOSE = ['#FF0000',"The troops have left Georgetown, taking the cache with them..."]; + }; + case 2: + { + _pos = [8414,10331,0]; + _missionName = "Suger Company Raid"; + _msgStart = ['#FFFF00',"Tanoa Suger Company is Being Raided by bandits! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the Suger Company and secured the cache!"]; + _msgLOSE = ['#FF0000',"The troops have left the Suger Company, taking the cache with them..."]; + }; + case 3: + { + _pos = [13446,12303,0]; + _missionName = "Blue Pearl Industrial Raid"; + _msgStart = ['#FFFF00',"Blue Pearl Industrial is Being Raided by bandits! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the Blue Pearl Industrial Complex and secured the cache!"]; + _msgLOSE = ['#FF0000',"The troops have left the Blue Pearl Complex, taking the cache with them..."]; + }; + case 4: + { + _pos = [1812,13278,0]; + _missionName = "Forbidden Village Occupation"; + _msgStart = ['#FFFF00',"Forbidden Village is under Bandit Occupation! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted the Forbidden Village and secured the cache!"]; + _msgLOSE = ['#FF0000',"The Bandits have left the Forbidden Village, taking the cache with them..."]; + }; + case 5: + { + _pos = [10032,11796,0]; + _missionName = "Comms ALPHA Occupation"; + _msgStart = ['#FFFF00',"Comms ALPHA is under Bandit Occupation! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted Comms ALPHA and secured the cache!"]; + _msgLOSE = ['#FF0000',"The Bandits have left Comms ALPHA, taking the cache with them..."]; + }; + case 6: + { + _pos = [11157,11501,0]; + _missionName = "Comms BRAVO Occupation"; + _msgStart = ['#FFFF00',"Comms BRAVO is under Bandit Occupation! There are reports they have a large weapon cache..."]; + _msgWIN = ['#0080FF',"Convicts have successfully assaulted Comms BRAVO and secured the cache!"]; + _msgLOSE = ['#FF0000',"The Bandits have left Comms BRAVO, taking the cache with them..."]; + }; + }; + }; + default + { + diag_log format["DMS ERROR :: Attempting to run occupation with unsupported map: %1",worldName]; + }; +}; + +if (isNil "_pos") exitWith {}; + +if ([_pos,DMS_StaticMinPlayerDistance] call DMS_fnc_IsPlayerNearby) exitWith {"delay"}; + +diag_log text "[DMS]: Town Occupation Mission Started"; + + +// Set general mission difficulty +_difficulty = "hardcore"; + + +// Create AI +_AICount = 27; +_group1Count = ceil(_AICount/3); +_group2Count = ceil(_AICount/3); +_group3Count = ceil(_AICount/3); + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Get AI to defend the position +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +_group = [_pos, _group1Count, _difficulty, "random", _side] call DMS_fnc_SpawnAIGroup; +[ _group,_pos,_difficulty,"COMBAT" ] call DMS_fnc_SetGroupBehavior; + +_buildings = _pos nearObjects ["building", 200]; +{ + _buildingPositions = [_x, 10] call BIS_fnc_buildingPositions; + if(count _buildingPositions > 0) then + { + _y = _x; + // Find Highest Point + _highest = [0,0,0]; + { + if(_x select 2 > _highest select 2) then + { + _highest = _x; + }; + + } foreach _buildingPositions; + _spawnPosition = _highest; + + _i = _buildingPositions find _spawnPosition; + _wp = _group addWaypoint [_spawnPosition,0] ; + _wp setWaypointFormation "Column"; + _wp setWaypointBehaviour "AWARE"; + _wp setWaypointCombatMode "RED"; + _wp setWaypointCompletionRadius 1; + _wp waypointAttachObject _y; + _wp setwaypointHousePosition _i; + _wp setWaypointType "MOVE"; + + }; + +} foreach _buildings; +if(count _buildings > 0 ) then +{ + _wp setWaypointType "CYCLE"; +}; + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +_group2 = [ _pos, _group2Count, _difficulty, "random", _side] call DMS_fnc_SpawnAIGroup; +[ _group2,_pos,_difficulty,"COMBAT" ] call DMS_fnc_SetGroupBehavior; + +_buildings = _pos nearObjects ["building", 100]; +{ + _buildingPositions = [_x, 10] call BIS_fnc_buildingPositions; + if(count _buildingPositions > 0) then + { + _y = _x; + // Find Highest Point + _highest = [0,0,0]; + { + if(_x select 2 > _highest select 2) then + { + _highest = _x; + }; + + } foreach _buildingPositions; + _spawnPosition = _highest; + + _i = _buildingPositions find _spawnPosition; + _wp2 = _group2 addWaypoint [_spawnPosition,0] ; + _wp2 setWaypointFormation "Column"; + _wp2 setWaypointBehaviour "AWARE"; + _wp2 setWaypointCombatMode "RED"; + _wp2 setWaypointCompletionRadius 1; + _wp2 waypointAttachObject _y; + _wp2 setwaypointHousePosition _i; + _wp2 setWaypointType "MOVE"; + }; + +} foreach _buildings; +if(count _buildings > 0 ) then +{ + _wp2 setWaypointType "CYCLE"; +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +_group3 = [_pos, _group3Count, _difficulty, "random", _side] call DMS_fnc_SpawnAIGroup; +[ _group3,_pos,_difficulty,"COMBAT" ] call DMS_fnc_SetGroupBehavior; + +_buildings = _pos nearObjects ["building", 100]; +{ + _buildingPositions = [_x, 10] call BIS_fnc_buildingPositions; + if(count _buildingPositions > 0) then + { + _y = _x; + // Find Highest Point + _highest = [0,0,0]; + { + if(_x select 2 > _highest select 2) then + { + _highest = _x; + }; + + } foreach _buildingPositions; + _spawnPosition = _highest; + + _i = _buildingPositions find _spawnPosition; + _wp3 = _group2 addWaypoint [_spawnPosition,0] ; + _wp3 setWaypointFormation "Column"; + _wp3 setWaypointBehaviour "AWARE"; + _wp3 setWaypointCombatMode "RED"; + _wp3 setWaypointCompletionRadius 1; + _wp3 waypointAttachObject _y; + _wp3 setwaypointHousePosition _i; + _wp3 setWaypointType "MOVE"; + + }; + +} foreach _buildings; +if(count _buildings > 0 ) then +{ + _wp3 setWaypointType "CYCLE"; +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// Get the AI to shut the fuck up :) +enableSentences false; +enableRadio false; + +// Create Crate +_crate = ["I_CargoNet_01_ammo_F",_pos] call DMS_fnc_SpawnCrate; + + +// Define mission-spawned AI Units +_missionAIUnits = +[ + [_group,_group2,_group3] +]; + +// Define the group reinforcements +_groupReinforcementsInfo = []; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [_missionAIUnits], // armed AI vehicle and static gun(s). Note, we don't add the base itself because we don't want to delete it and respawn it if the mission respawns. + [], + [[_crate,[30 + (random 20),100 + (random 40),15 + (random 5)]]] // weapons,items,backpacks +]; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +(_markers select 1) setMarkerSize [500,500]; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + [_group,_group2,_group3] + ], + [ + "playerNear", + [_pos,100] + ] + ], + _groupReinforcementsInfo, + [ + _time, + DMS_StaticMissionTimeOut call DMS_fnc_SelectRandomVal + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [[],[]] +] call DMS_fnc_AddMissionToMonitor_Static; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_fnc_AddMissionToMonitor_Static! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; diff --git a/@ExileServer/addons/a3_dms/missions/static/saltflats.sqf b/@ExileServer/addons/a3_dms/missions/static/saltflats.sqf new file mode 100644 index 0000000..82794f8 --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/static/saltflats.sqf @@ -0,0 +1,288 @@ +/* + "saltflats" static mission for Altis. + Created by eraser1 + Credits to "Darth Rogue" for creating the base. +*/ + +// For logging purposes +_num = DMS_MissionCount; + + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +_pos = [23300,18800,0]; + +if ([_pos,DMS_StaticMinPlayerDistance] call DMS_fnc_IsPlayerNearby) exitWith {"delay"}; + + +// Set general mission difficulty +_difficulty = "hardcore"; + + +// Define spawn locations for AI Soldiers. These will be used for the initial spawning of AI as well as reinforcements. +// The center spawn location is added 3 times so at least 3 AI will spawn initially at the center location, and so that future reinforcements are more likely to spawn at the center. +_AISoldierSpawnLocations = +[ + _pos, + _pos, + _pos, + [23500,18750,0.5], + [23498,18715,0.5], + [23461,18478.2,0], + [23443,18495.3,0], + [23424,18479.4,0], + [23405.9,18497,0], + [23387.1,18479.7,0], + [23378.3,18497.6,0], + [23359.2,18480,0], + [23334.9,18479.2,0], + [23295.1,18515.4,3.12796], + [23242.7,18793.5,0.5], + [23387.2,18638.5,0.5], + [23294.6,18640.8,0.2], + [23309.1,18683.1,0.6], + [23308.5,18683,4], + [23360.5,18686.3,4], + [23362.9,18679,0.6], + [23403.1,18685.1,0.6], + [23420.9,18839.6,4.35], + [23420.8,18843.4,12.35], + [23421,18838.6,0.36], + [23422.2,18823.8,0.4], + [23502.1,18862.3,15.37], + [23494.2,18478.6,15.37], + [23206.6,18493.8,15.37], + [23239.4,18561.1,0] +]; + +// Create AI +_AICount = 20 + (round (random 5)); + + +_group = +[ + _AISoldierSpawnLocations, + _AICount, + _difficulty, + "random", + _side +] call DMS_fnc_SpawnAIGroup_MultiPos; + + +_staticGuns = +[ + [ + //[23424.4,18844.1,15.33], // Top of the construction building. I added this and I thought it may be too much. Your choice if you want to uncomment ;) + _pos vectorAdd [5,0,0], // 5 meters East of center pos + _pos vectorAdd [-5,0,0], // 5 meters West of center pos + _pos vectorAdd [0,5,0], // 5 meters North of center pos + _pos vectorAdd [0,-5,0], // 5 meters South of center pos + [23216.3,18863.6,20.5], // Top of NorthWest Tower + [23506.6,18867.6,20.5], // Top of NorthEast Tower + [23497.9,18483.8,20.5], // Top of SouthEast Tower + [23211.1,18489.3,20.5], // Top of SouthWest Tower + [23509.7,18788.1,22.52] // Top of the concrete water tower thing. + ], + _group, + "assault", + _difficulty, + "bandit", + "random" +] call DMS_fnc_SpawnAIStaticMG; + + + +// Create Crate +_crateClassname = "I_CargoNet_01_ammo_F"; +deleteVehicle (nearestObject [_pos, _crateClassname]); // Make sure to remove any previous crate. + +_crate = [_crateClassname, _pos] call DMS_fnc_SpawnCrate; + + + +// Spawn the vehicle AFTER the base so that it spawns the vehicle in a (relatively) clear position. +_veh = +[ + [ + _pos getPos [100,random 360], + _pos + ], + _group, + "assault", + _difficulty, + _side +] call DMS_fnc_SpawnAIVehicle; + + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define the group reinforcements +_groupReinforcementsInfo = +[ + [ + _group, // pass the group + [ + [ + 5, // Only 5 "waves" (5 vehicles can spawn as reinforcement) + 0 + ], + [ + -1, // No need to limit the number of units since we're limiting "waves" + 0 + ] + ], + [ + 300, // At least a 5 minute delay between reinforcements. + diag_tickTime + ], + [ + [23239.7,18865.8,0], + [23397,18862.8,0], + [23485.5,18861.3,0], + [23486,18683.9,0], + [23493.1,18515.5,0], + [23873.8,19413.2,0], + [23211.9,18572.5,0], + [23212.9,18751.7,0], + [23211.5,18809.1,0] + ], + "random", + _difficulty, + _side, + "armed_vehicle", + [ + 7, // Reinforcements will only trigger if there's fewer than 7 members left in the group + "random" // Select a random armed vehicle from "DMS_ArmedVehicles" + ] + ], + [ + _group, // pass the group (again) + [ + [ + -1, // Let's limit number of units instead... + 0 + ], + [ + 100, // Maximum 100 units can be given as reinforcements. + 0 + ] + ], + [ + 240, // About a 4 minute delay between reinforcements. + diag_tickTime + ], + _AISoldierSpawnLocations, + "random", + _difficulty, + _side, + "reinforce", + [ + 10, // Reinforcements will only trigger if there's fewer than 10 members left in the group + 7 // 7 reinforcement units per wave. + ] + ] +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns+[_veh], // armed AI vehicle and static gun(s). Note, we don't add the base itself because we don't want to delete it and respawn it if the mission respawns. + [], + [[_crate,[75,250,25]]] +]; + +// Define Mission Start message +_msgStart = ['#FFFF00', "A heavily guarded base has been located on the salt flats! There are reports they have a large weapon cache..."]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have successfully assaulted the base on the salt flats and secured the cache!"]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"Seems like the guards got bored and left the base, taking the cache with them..."]; + +// Define mission name (for map marker and logging) +_missionName = "Mercenary Base"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +(_markers select 1) setMarkerSize [750,750]; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,100] + ] + ], + _groupReinforcementsInfo, + [ + _time, + DMS_StaticMissionTimeOut call DMS_fnc_SelectRandomVal + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor_Static; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_fnc_AddMissionToMonitor_Static! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + + + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; diff --git a/@ExileServer/addons/a3_dms/missions/static/slums.sqf b/@ExileServer/addons/a3_dms/missions/static/slums.sqf new file mode 100644 index 0000000..293703e --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/static/slums.sqf @@ -0,0 +1,253 @@ +/* + "slums" static mission for Altis. + Created by eraser1 + Credits to "William" for creating the base. +*/ + +// For logging purposes +_num = DMS_MissionCount; + + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +_pos = [15981.6,16253.2,0]; + +if ([_pos,DMS_StaticMinPlayerDistance] call DMS_fnc_IsPlayerNearby) exitWith {"delay"}; + + +// Set general mission difficulty +_difficulty = "hardcore"; + + +// Define spawn locations for AI Soldiers. These will be used for the initial spawning of AI as well as reinforcements. +// The center spawn location is added 3 times so at least 3 AI will spawn initially at the center location, and so that future reinforcements are more likely to spawn at the center. +_AISoldierSpawnLocations = +[ + [16082.4,16192,0.79], + [16072.2,16191.5,0], + [16076.5,16189.9,0], + [15941,16289.9,0.33], + [16021.3,16241.4,0.31], + [16040.2,16254.3,0.17], + [16046,16253.5,0.09], + [16065.6,16250.7,0], + [16080.2,16248.5,0], + [16098.5,16242.6,0], + [16069.4,16206.7,3.6], + [16058,16207.3,4] +]; + +// Create AI +_AICount = 20 + (round (random 5)); + + +_group = +[ + _AISoldierSpawnLocations+[_pos,_pos,_pos], // Pass the regular spawn locations as well as the center pos 3x + _AICount, + _difficulty, + "random", + _side +] call DMS_fnc_SpawnAIGroup_MultiPos; + + +_staticGuns = +[ + [ + [15914.6,16284.2,0], + [15919.9,16271.2,0], + [16087.8,16229.4,1.4], + [16088.7,16192.4,0.15], + [16100.4,16225.1,0], + [16019.2,16216.5,2.93] + ], + _group, + "assault", + _difficulty, + "bandit", + "random" +] call DMS_fnc_SpawnAIStaticMG; + + + +// Define the classnames and locations where the crates can spawn (at least 2, since we're spawning 2 crates) +_crateClasses_and_Positions = +[ + [[16018,16210,0.61],"I_CargoNet_01_ammo_F"], + [[15916,16262,0],"I_CargoNet_01_ammo_F"], + [[15975,16223.5,0.2],"I_CargoNet_01_ammo_F"], + [[16014,16242.5,4.5],"I_CargoNet_01_ammo_F"], + [[16026,16226.5,0.72],"I_CargoNet_01_ammo_F"] +]; + +{ + deleteVehicle (nearestObject _x); // Make sure to remove any previous crates. +} forEach _crateClasses_and_Positions; + +// Shuffle the list +_crateClasses_and_Positions = _crateClasses_and_Positions call ExileClient_util_array_shuffle; + + +// Create Crates +_crate0 = [_crateClasses_and_Positions select 0 select 1, _crateClasses_and_Positions select 0 select 0] call DMS_fnc_SpawnCrate; +_crate1 = [_crateClasses_and_Positions select 1 select 1, _crateClasses_and_Positions select 1 select 0] call DMS_fnc_SpawnCrate; + +// Disable smoke on the crates so that the players have to search for them >:D +{ + _x setVariable ["DMS_AllowSmoke", false]; +} forEach [_crate0,_crate1]; + +/* +// Don't think an armed AI vehicle fit the idea behind the mission. You're welcome to uncomment this if you want. +_veh = +[ + [ + [_pos,100,random 360] call DMS_fnc_SelectOffsetPos, + _pos + ], + _group, + "assault", + _difficulty, + _side +] call DMS_fnc_SpawnAIVehicle; +*/ + + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define the group reinforcements +_groupReinforcementsInfo = +[ + [ + _group, // pass the group + [ + [ + -1, // Let's limit number of units instead... + 0 + ], + [ + 100, // Maximum 100 units can be given as reinforcements. + 0 + ] + ], + [ + 240, // About a 4 minute delay between reinforcements. + diag_tickTime + ], + _AISoldierSpawnLocations, + "random", + _difficulty, + _side, + "reinforce", + [ + 10, // Reinforcements will only trigger if there's fewer than 10 members left in the group + 7 // 7 reinforcement units per wave. + ] + ] +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns, // static gun(s). Note, we don't add the base itself because it already spawns on server start. + [], + [[_crate0,[50,100,2]],[_crate1,[3,150,15]]] +]; + +// Define Mission Start message +_msgStart = ['#FFFF00', "A large group of mercenaries are trying to hide in some slums! They were seen stockpiling multiple crates..."]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have successfully rooted out the mercenaries and claimed the caches for themselves!"]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"The mercenaries got spooked and left..."]; + +// Define mission name (for map marker and logging) +_missionName = "Slums Base"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +_circle = _markers select 1; +_circle setMarkerDir 20; +_circle setMarkerSize [150,50]; + + +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,100] + ] + ], + _groupReinforcementsInfo, + [ + _time, + DMS_StaticMissionTimeOut call DMS_fnc_SelectRandomVal + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + _difficulty, + [] +] call DMS_fnc_AddMissionToMonitor_Static; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_fnc_AddMissionToMonitor_Static! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + + + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]) call DMS_fnc_DebugLog; +}; diff --git a/@ExileServer/addons/a3_dms/missions/static/underwater_stash.sqf b/@ExileServer/addons/a3_dms/missions/static/underwater_stash.sqf new file mode 100644 index 0000000..2ed6c0c --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/static/underwater_stash.sqf @@ -0,0 +1,318 @@ +/* + "Underwater Stash" mission for Tanoa + Created by eraser1 +*/ + +// For logging purposes +_num = DMS_MissionCount; + + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + +_pos = [5884,2997,10]; + +// This mission should spawn on server start. Otherwise, if somebody is dumb enough to wait for it to spawn, then they're gonna get killed lol. +//if ([_pos,DMS_StaticMinPlayerDistance] call DMS_fnc_IsPlayerNearby) exitWith {"delay"}; + + +DMS_CrateCase_DiverGear = +[ + [ + "arifle_SDAR_F", + "arifle_SDAR_F", + "arifle_SDAR_F", + "arifle_SDAR_F", + "arifle_SDAR_F" + ], + [ + "20Rnd_556x45_UW_mag", + "20Rnd_556x45_UW_mag", + "20Rnd_556x45_UW_mag", + "20Rnd_556x45_UW_mag", + "20Rnd_556x45_UW_mag", + "20Rnd_556x45_UW_mag", + "20Rnd_556x45_UW_mag", + "20Rnd_556x45_UW_mag", + "20Rnd_556x45_UW_mag", + "20Rnd_556x45_UW_mag", + "U_O_Wetsuit", + "U_O_Wetsuit", + "U_O_Wetsuit", + "U_O_Wetsuit", + "U_O_Wetsuit", + "V_RebreatherIA", + "V_RebreatherIA", + "V_RebreatherIA", + "V_RebreatherIA", + "V_RebreatherIA" + ], + [ + "B_Carryall_oli", + "B_Bergen_tna_F", + "B_ViperHarness_oli_F" + ] +]; + +// I only made some of the variables in this file "private" because I couldn't bother making all of them private :p +private _crate = ["Box_IND_AmmoVeh_F",[5630,3100,0]] call DMS_fnc_SpawnCrate; +_crate setVariable ["DMS_AllowSmoke", false]; + + +[_crate, "DiverGear"] call DMS_fnc_FillCrate; + + + +private _sub1 = ["Exile_Boat_SDV_CSAT",[0,0,0]] call DMS_fnc_SpawnNonPersistentVehicle; +_sub1 setPosASL [5884,2997,-66]; +_sub1 setVariable ["DMS_AllowSmoke", false]; + +private _sub2 = ["Exile_Boat_SDV_CSAT",[0,0,0]] call DMS_fnc_SpawnNonPersistentVehicle; +_sub2 setPosASL [5893.5,3037,-55]; +_sub2 setVariable ["DMS_AllowSmoke", false]; + + + +private _diverGearSet = +[ + "arifle_SDAR_F", + [], + [["20Rnd_556x45_UW_mag",6]], + "", + [], + ["Rangefinder","ItemGPS","NVGoggles"], + "", + "", + "U_O_Wetsuit", + "V_RebreatherIA", + "B_Bergen_mcamo" +]; + + +private _temp = DMS_ai_use_launchers; +DMS_ai_use_launchers = false; + +private _diverGroup = +[ + [ + [5850.8,3048.1,-37.8057], + [5863.21,3036.56,-38.2891], + [5871.43,3054.4,-39.343], + [5915.36,3021.77,-58.8748], + [5905.08,2987.15,-65.313], + [5877.29,2984.19,-60.6961], + [5887.88,2986.54,-60.7556], + [5909.77,3037.79,-52.0807], + [5878.36,3045.98,-48.1157], + [5845.63,3028.38,-49.0821], + [5851.09,3009.14,-52.1915], + [5856.83,3016.01,-49.785], + [5869.44,3017.86,-49.7803], + [5879.65,3022.51,-47.769], + [5892.57,3030.16,-48.894], + [5900.21,3031.82,-50.4109], + [5882.36,3003.04,-55.3779], + [5858.68,2977.79,-63.6817], + [5899.83,3044.99,-51.4147], + [5875.81,3007.73,-55.331], + [5899.77,2994.57,-61.1307] + ], + 21, + "hardcore", + "custom", + _side, + _diverGearSet +] call DMS_fnc_SpawnAIGroup_MultiPos; + +DMS_ai_use_launchers = _temp; + + +{ + _x disableAI "PATH"; +} forEach (units _diverGroup); + + + + + +private _landGroup = +[ + [5633,3108,0], + 5, + "hardcore", + "sniper", + "bandit" +] call DMS_fnc_SpawnAIGroup; + + + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _diverGroup, // We only spawned the single group for this mission + _landGroup +]; + +// Define the group reinforcements +_groupReinforcementsInfo = +[ + // Removed reinforcements for this because while I was testing the mission the AI took too long to get back to the objective, and that's annoying + /* + [ + _diverGroup, // pass the group + [ + [ + -1, // Let's limit number of units instead... + 0 + ], + [ + 10, // Maximum 10 units can be given as reinforcements. + 0 + ] + ], + [ + 180, // About a 3 minute delay between reinforcements. + diag_tickTime + ], + [ + [5810,2874,1], + [5933,2912,2], + [5862,3132,0.5] + ], + "custom", + "hardcore", + _side, + "reinforce", + [ + 5, // Reinforcements will only trigger if there's fewer than 5 members left in the group + 3 // 3 reinforcement units per wave. + ], + _diverGearSet + ] + */ +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + [], + [_sub1, _sub2], + [ + [ + _sub1, + [ + 1, + [2,DMS_Box_BaseParts_Concrete], + 1 + ] + ], + [ + _sub2, + [ + [2,DMS_sniper_weps], // Spawn a random 5 weapons that AI snipers can spawn with. + [5,DMS_BoxSurvivalSupplies], + 1 + ] + ] + ] +]; + +// Define Mission Start message +_msgStart = ['#FFFF00', "The CSAT are storing money and supplies in an underwater stash! Eliminate them and take the supplies!"]; + +// Define Mission Win message +_msgWIN = ['#0080ff',"Convicts have successfully eliminated the CSAT and obtained the underwater stash!"]; + +// Define Mission Lose message +_msgLOSE = ['#FF0000',"Seems like CSAT forces moved their stash away..."]; + +// Define mission name (for map marker and logging) +_missionName = "Underwater Stash"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + "hardcore" +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _diverGroup // Only need to kill the diver group. + ], + [ + "playerNear", + [_sub1,40] + ] + ], + _groupReinforcementsInfo, + [ + _time, + DMS_StaticMissionTimeOut call DMS_fnc_SelectRandomVal + ], + _missionAIUnits, + _missionObjs, + [_missionName,_msgWIN,_msgLOSE], + _markers, + _side, + "hardcore", + [], + [ + [ + [ + _sub1, + {_this setVariable ["ExileMoney",25000,true]} // The submarine will have 25,000 poptabs after the mission completes. The capacity is actually 5000, but I just overload it. + ] + ], + [], + {}, + {} + ] +] call DMS_fnc_AddMissionToMonitor_Static; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_fnc_AddMissionToMonitor_Static! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + + +// Notify players +[_missionName,_msgStart] call DMS_fnc_BroadcastMissionStatus; + + + +if (DMS_DEBUG) then +{ + (format ["MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,26,"hardcore",_time]) call DMS_fnc_DebugLog; +}; diff --git a/@ExileServer/addons/a3_dms/missions/static_init.sqf b/@ExileServer/addons/a3_dms/missions/static_init.sqf new file mode 100644 index 0000000..de35bbf --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/static_init.sqf @@ -0,0 +1,37 @@ +/* + static_init.sqf + Created by eraser1 + + Initializes static mission variables for DMS +*/ + +diag_log "DMS :: Initializing Static Mission Variables"; + +// Initialize Variables +DMS_StaticMission_Arr = []; +DMS_RunningStaticMissions = []; +DMS_StaticMissionLastStart = diag_tickTime; +DMS_StaticMissionDelay = DMS_TimeToFirstStaticMission call DMS_fnc_SelectRandomVal; + + +if (DMS_DEBUG) then +{ + diag_log format ["DMS_DEBUG static_init :: Random time between missions is initially set to %1s | DMS_BMissionLastStart: %2",DMS_StaticMissionDelay,DMS_StaticMissionLastStart]; +}; + +// Set mission frequencies from config +DMS_StaticMissionTypesArray = []; +{ + private _missionName = _x select 0; + + for "_i" from 1 to (_x select 1) do + { + DMS_StaticMissionTypesArray pushBack _missionName; + }; + + missionNamespace setVariable + [ + format["DMS_StaticMission_%1",_missionName], + compileFinal preprocessFileLineNumbers (format ["\x\addons\DMS\missions\static\%1.sqf",_missionName]) + ]; +} forEach DMS_StaticMissionTypes; diff --git a/@ExileServer/addons/a3_dms/objects/base1.sqf b/@ExileServer/addons/a3_dms/objects/base1.sqf new file mode 100644 index 0000000..bedb128 --- /dev/null +++ b/@ExileServer/addons/a3_dms/objects/base1.sqf @@ -0,0 +1,22 @@ +[ + ["Land_HBarrierTower_F",[-9.12122,9.17334,0],180.049], + ["Land_HBarrierTower_F",[5.15552,-9.92236,0],270.462], + ["Land_HBarrierTower_F",[-9.02209,-29.1157,0],0], + ["Land_HBarrierTower_F",[-23.2937,-10.021,0],90.6414], + ["Land_HBarrierWall_corridor_F",[-24.0222,-15.5698,0],0], + ["Land_CncWall4_F",[-15.0026,-27.3579,0],0], + ["Land_CncWall4_F",[-19.0652,-25.082,0],53.1818], + ["Land_CncWall4_F",[-21.0901,-20.4282,0],82.6364], + ["Land_CncWall4_F",[-2.98938,-27.3594,0],0], + ["Land_CncWall4_F",[1.07483,-25.02,0],302.318], + ["Land_CncWall4_F",[2.92139,-20.2295,0],280.636], + ["Land_HBarrierWall_corridor_F",[5.90735,-15.3979,0],0], + ["Land_CncWall4_F",[3.50403,-3.87158,0],262.221], + ["Land_CncWall4_F",[2.09851,1.11768,0],249.539], + ["Land_CncWall4_F",[-1.08093,5.08643,0],215.994], + ["Land_CncWall1_F",[-3.72351,6.81592,0],201.682], + ["Land_HBarrier_1_F",[-4.89832,7.65137,0],290.455], + ["Land_HBarrier_1_F",[-4.89832,7.65137,1.3],290.455], + ["Land_HBarrier_Big_F",[-15.7292,4.59131,0],309.682], + ["Land_HBarrier_Big_F",[-20.431,-2.63086,0],298.636] +] \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/objects/nedbuild1_objects.sqf b/@ExileServer/addons/a3_dms/objects/nedbuild1_objects.sqf new file mode 100644 index 0000000..0a52a80 --- /dev/null +++ b/@ExileServer/addons/a3_dms/objects/nedbuild1_objects.sqf @@ -0,0 +1,14 @@ +[ + ["Land_Cargo_House_V4_F",[0,15,0],0], + ["Land_Cargo_House_V4_F",[6.2,15,0],0], + ["Land_Cargo_House_V4_F",[-6.2,15,0],0], + ["Land_Cargo_House_V4_F",[15,0,0],90], + ["Land_Cargo_House_V4_F",[15,6.2,0],90], + ["Land_Cargo_House_V4_F",[15,-6.2,0],90], + ["Land_Cargo_House_V4_F",[0,-15,0],180], + ["Land_Cargo_House_V4_F",[-6.2,-15,0],180], + ["Land_Cargo_House_V4_F",[6.2,-15,0],180], + ["Land_Cargo_House_V4_F",[-15,0,0],270], + ["Land_Cargo_House_V4_F",[-15,-6.2,0],270], + ["Land_Cargo_House_V4_F",[-15,6.2,0],270] +] \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/objects/nedguns1_objects.sqf b/@ExileServer/addons/a3_dms/objects/nedguns1_objects.sqf new file mode 100644 index 0000000..4b84d63 --- /dev/null +++ b/@ExileServer/addons/a3_dms/objects/nedguns1_objects.sqf @@ -0,0 +1,14 @@ +[ + ["Land_Cargo_House_V3_F",[0,15,0],0], + ["Land_Cargo_House_V3_F",[6.2,15,0],0], + ["Land_Cargo_House_V3_F",[-6.2,15,0],0], + ["Land_Cargo_House_V3_F",[15,0,0],90], + ["Land_Cargo_House_V3_F",[15,6.2,0],90], + ["Land_Cargo_House_V3_F",[15,-6.2,0],90], + ["Land_Cargo_House_V3_F",[0,-15,0],180], + ["Land_Cargo_House_V3_F",[-6.2,-15,0],180], + ["Land_Cargo_House_V3_F",[6.2,-15,0],180], + ["Land_Cargo_House_V3_F",[-15,0,0],270], + ["Land_Cargo_House_V3_F",[-15,-6.2,0],270], + ["Land_Cargo_House_V3_F",[-15,6.2,0],270] +] \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/objects/nedmed1_objects.sqf b/@ExileServer/addons/a3_dms/objects/nedmed1_objects.sqf new file mode 100644 index 0000000..ce80ba4 --- /dev/null +++ b/@ExileServer/addons/a3_dms/objects/nedmed1_objects.sqf @@ -0,0 +1,14 @@ +[ + ["Land_Medevac_house_V1_F",[0,15,0],0], + ["Land_Medevac_house_V1_F",[6.2,15,0],0], + ["Land_Medevac_house_V1_F",[-6.2,15,0],0], + ["Land_Medevac_house_V1_F",[15,0,0],90], + ["Land_Medevac_house_V1_F",[15,6.2,0],90], + ["Land_Medevac_house_V1_F",[15,-6.2,0],90], + ["Land_Medevac_house_V1_F",[0,-15,0],180], + ["Land_Medevac_house_V1_F",[-6.2,-15,0],180], + ["Land_Medevac_house_V1_F",[6.2,-15,0],180], + ["Land_Medevac_house_V1_F",[-15,0,0],270], + ["Land_Medevac_house_V1_F",[-15,-6.2,0],270], + ["Land_Medevac_house_V1_F",[-15,6.2,0],270] +] \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/objects/nedresearch_objects.sqf b/@ExileServer/addons/a3_dms/objects/nedresearch_objects.sqf new file mode 100644 index 0000000..5d6da9c --- /dev/null +++ b/@ExileServer/addons/a3_dms/objects/nedresearch_objects.sqf @@ -0,0 +1,7 @@ +[ + ["Land_Research_HQ_F",[10,0,0],0], + ["Land_CncBarrierMedium4_F",[1,7,0],0], + ["Land_CncBarrierMedium4_F",[1,-7,0],0], + ["Land_CncBarrierMedium4_F",[-3,-4,0],90], + ["Land_CncBarrierMedium4_F",[-3,3.5,0],90] +] \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/objects/nedsnipercamp_objects.sqf b/@ExileServer/addons/a3_dms/objects/nedsnipercamp_objects.sqf new file mode 100644 index 0000000..76e66a9 --- /dev/null +++ b/@ExileServer/addons/a3_dms/objects/nedsnipercamp_objects.sqf @@ -0,0 +1,12 @@ +[ + ["Land_PartyTent_01_F",[0,0,0],0], + ["Land_TentA_F",[0,-10,0],0], + ["Land_TentA_F",[-2.7,-10,0],0], + ["Land_TentA_F",[2.7,-10,0],0], + ["Land_TentA_F",[0,10,0],180], + ["Land_TentA_F",[2.7,10,0],180], + ["Land_TentA_F",[-2.7,10,0],180], + ["MapBoard_stratis_F",[-2,0,0],0], + ["MapBoard_altis_F",[2,0,0],0], + ["Land_RattanChair_01_F",[-4,-3,0],0] +] \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/objects/nedtrader_objects.sqf b/@ExileServer/addons/a3_dms/objects/nedtrader_objects.sqf new file mode 100644 index 0000000..a1097c3 --- /dev/null +++ b/@ExileServer/addons/a3_dms/objects/nedtrader_objects.sqf @@ -0,0 +1,10 @@ +[ + ["Land_Wreck_Ural_F",[0,+10,0],180], + ["Land_Wreck_Ural_F",[0,+20,0],180], + ["Land_Sacks_heap_F",[-5,19015,0],0], + ["Land_Sacks_heap_F",[-6.7,+15,0],0], + ["Land_Sacks_heap_F",[-6.7,+13.7,0],0], + ["Land_Sacks_heap_F",[-5,+13.7,0],0], + ["Land_CratesWooden_F",[-5,+10,0],0], + ["Land_CratesWooden_F",[-8,+10,0],0] +] \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/objects/static/base1STATIC.sqf b/@ExileServer/addons/a3_dms/objects/static/base1STATIC.sqf new file mode 100644 index 0000000..ee72396 --- /dev/null +++ b/@ExileServer/addons/a3_dms/objects/static/base1STATIC.sqf @@ -0,0 +1,27 @@ +// This file is effectively the exact same as "base1.sqf" in the folder above it. +//Using relative position is preferable; this file is just an example on how to format a file with static objects. + +private ["_objs"]; +_objs = [ + ["Land_HBarrierTower_F",[1688.42,5601.6,0],180.049,[[-0.000857441,-1,0],[-0,0,1]],false], + ["Land_HBarrierTower_F",[1702.61,5582.49,0],270.462,[[-0.999968,0.00806372,0],[0,0,1]],false], + ["Land_HBarrierTower_F",[1688.42,5563.38,0],0,[[0,1,0],[0,0,1]],false], + ["Land_HBarrierTower_F",[1674.23,5582.49,0],90.6414,[[0.999937,-0.0111948,0],[0,-0,1]],false], + ["Land_HBarrierWall_corridor_F",[1673.47,5576.89,0],0,[[0,1,0],[0,0,1]],false], + ["Land_CncWall4_F",[1682.45,5565.37,0],0,[[0,1,0],[0,0,1]],false], + ["Land_CncWall4_F",[1678.62,5567.57,0],53.1818,[[0.800541,0.599277,0],[0,0,1]],false], + ["Land_CncWall4_F",[1676.66,5572.1,0],82.6364,[[0.991753,0.128166,0],[0,0,1]],false], + ["Land_CncWall4_F",[1694.47,5565.37,0],0,[[0,1,0],[0,0,1]],false], + ["Land_CncWall4_F",[1698.32,5567.56,0],302.318,[[-0.845092,0.534621,0],[0,0,1]],false], + ["Land_CncWall4_F",[1700.14,5572.25,0],280.636,[[-0.982818,0.184575,0],[0,0,1]],false], + ["Land_HBarrierWall_corridor_F",[1703.4,5577.06,0],0,[[0,1,0],[0,0,1]],false], + ["Land_CncWall4_F",[1700.73,5588.52,0],262.221,[[-0.990797,-0.135353,0],[-0,0,1]],false], + ["Land_CncWall4_F",[1699.35,5593.46,0],249.539,[[-0.936912,-0.349566,0],[-0,0,1]],false], + ["Land_CncWall4_F",[1696.28,5597.31,0],215.994,[[-0.587697,-0.809081,0],[-0,0,1]],false], + ["Land_CncWall1_F",[1693.6,5599.05,0],201.682,[[-0.369452,-0.92925,0],[-0,0,1]],false], + ["Land_HBarrier_1_F",[1692.58,5600.12,0],290.455,[[-0.93695,0.349464,0],[0,0,1]],false], + ["Land_HBarrier_Big_F",[1681.72,5597.13,0],309.682,[[-0.769601,0.638525,0],[0,0,1]],false], + ["Land_HBarrier_Big_F",[1677,5589.9,0],298.636,[[-0.877679,0.479249,0],[0,0,1]],false] +]; + +_objs; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/objects/static/saltflatsbase.sqf b/@ExileServer/addons/a3_dms/objects/static/saltflatsbase.sqf new file mode 100644 index 0000000..17dab4d --- /dev/null +++ b/@ExileServer/addons/a3_dms/objects/static/saltflatsbase.sqf @@ -0,0 +1,693 @@ +// Credits to Darth Rogue from "http://soldiersofanarchy.net/" +// DMS author(s) did not create the export below. They were created/adapted specifically for DMS by the author above. + +[ + ["Flag_CSAT_F",[23302,18802,0],0,[[0,1,0],[0,0,1]],true], + ["Land_HBarrierTower_F",[23216.7,18479.3,0],2.27275,[[0.0396563,0.999213,0],[0,0,1]],false], + ["Land_HBarrierTower_F",[23236.4,18478.8,2.38419e-007],1.81822,[[0.0317284,0.999497,0],[0,0,1]],false], + ["Land_BarGate_F",[23226.6,18480.6,-0.0227547],1.36359,[[0.0237968,0.999717,0],[0,0,1]],false], + ["Land_CncBarrier_stripes_F",[23229.1,18469.9,0],1.36366,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CncBarrierMedium4_F",[23233.4,18470.8,0],92.7273,[[0.998867,-0.0475825,0],[0,-0,1]],false], + ["Land_CncBarrierMedium4_F",[23233.1,18463.4,0],92.7273,[[0.998867,-0.0475825,0],[0,-0,1]],false], + ["Land_CncBarrierMedium4_F",[23219.2,18463.6,0],92.7273,[[0.998867,-0.0475825,0],[0,-0,1]],false], + ["Land_CncBarrierMedium4_F",[23219.6,18471,0],92.7273,[[0.998867,-0.0475825,0],[0,-0,1]],false], + ["Land_CncBarrier_stripes_F",[23223.1,18458.2,0],1.36366,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CncBarrierMedium4_F",[23218.9,18456.2,0],92.7273,[[0.998867,-0.0475825,0],[0,-0,1]],false], + ["Land_CncBarrierMedium4_F",[23232.8,18456.1,0],92.7273,[[0.998867,-0.0475825,0],[0,-0,1]],false], + ["Land_Sign_WarningMilitaryArea_F",[23217.1,18452.7,0],0.909076,[[0.0158659,0.999874,0],[0,0,1]],false], + ["Land_Sign_WarningMilitaryArea_F",[23234.3,18452.4,0],0.909097,[[0.0158659,0.999874,0],[0,0,1]],false], + ["Land_Airport_Tower_F",[23292,18639.7,0],93.1818,[[0.998458,-0.0555044,0],[0,-0,1]],false], + ["Land_Radar_F",[23489.9,18659.8,0],149.091,[[0.513676,-0.857984,0],[0,-0,1]],false], + ["Land_PowerGenerator_F",[23295.6,18643.1,0],271.364,[[-0.999717,0.0238043,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23294.4,18634.9,0],94.0909,[[0.997452,-0.0713387,0],[0,-0,1]],false], + ["Land_Pavement_wide_corner_F",[23292.4,18612.5,0],94.5454,[[0.996855,-0.0792492,0],[0,-0,1]],false], + ["Land_spp_Panel_F",[23502.9,18594.5,0],2.72727,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Transformer_F",[23455.5,18575.2,0],4.09089,[[0.0713387,0.997452,0],[0,0,1]],false], + ["Land_TBox_F",[23365.4,18874.5,0],0,[[0,1,0],[0,0,1]],false], + ["Land_TTowerBig_2_F",[23359.7,18873.6,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Cargo_Tower_V1_No1_F",[23209.8,18488.6,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],true], + ["Land_Cargo_Tower_V1_No3_F",[23498.3,18482.3,0],1.36358,[[0.0237968,0.999717,0],[0,0,1]],true], + ["Land_Cargo_Tower_V1_No2_F",[23506.8,18865.9,0],1.36361,[[0.0237974,0.999717,0],[0,0,1]],true], + ["Land_Cargo_Tower_V1_No4_F",[23216.6,18861.9,0],0.454538,[[0.00793294,0.999969,0],[0,0,1]],true], + ["Land_i_Barracks_V2_F",[23321.8,18682.9,0],0,[[0,1,0],[0,0,1]],true], + ["Land_dp_smallFactory_F",[23489.9,18620.4,0],90.9091,[[0.999874,-0.0158665,0],[0,-0,1]],false], + ["Land_spp_Panel_F",[23494.8,18594.9,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23486.7,18595.3,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23478.6,18595.6,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23470.5,18596,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23462.4,18596.4,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23462.1,18590.7,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23470.2,18590.3,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23478.3,18589.9,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23486.4,18589.5,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23494.6,18589.1,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23502.7,18588.7,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23502.4,18583,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23494.3,18583.4,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23478,18584.2,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23469.9,18584.5,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23461.8,18584.9,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23461.5,18579.2,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23469.7,18578.8,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23494,18577.6,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23502.1,18577.2,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23501.8,18571.5,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23493.7,18571.9,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Panel_F",[23461.3,18573.4,-2.38419e-007],2.72726,[[0.0475818,0.998867,0],[0,0,1]],false], + ["Land_spp_Transformer_F",[23456,18585.4,0],3.63634,[[0.0634237,0.997987,0],[0,0,1]],false], + ["Land_spp_Transformer_F",[23456.5,18595.7,0],4.09088,[[0.0713387,0.997452,0],[0,0,1]],false], + ["Land_PowerGenerator_F",[23368.7,18874.7,0],180.455,[[-0.00794149,-0.999968,0],[-0,0,1]],false], + ["StorageBladder_01_fuel_sand_F",[23375.1,18872,0],0,[[0,1,0],[0,0,1]],false], + ["Land_MilOffices_V1_F",[23328,18631.5,2.38419e-007],1.81821,[[0.0317284,0.999497,0],[0,0,1]],true], + ["Land_MilOffices_V1_F",[23384.1,18629.7,2.38419e-007],1.81821,[[0.0317284,0.999497,0],[0,0,1]],true], + ["Land_MilOffices_V1_F",[23382.5,18578.9,2.38419e-007],1.81821,[[0.0317284,0.999497,0],[0,0,1]],true], + ["Land_Pavement_wide_F",[23294.1,18630.9,0],94.0909,[[0.997452,-0.0713387,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23293.8,18627,0],94.0909,[[0.997452,-0.0713387,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23293.5,18623,0],94.0909,[[0.997452,-0.0713387,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23293.3,18619.1,0],94.0909,[[0.997452,-0.0713387,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23293,18615.2,0],94.0909,[[0.997452,-0.0713387,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23295.3,18612.6,0],4.09096,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23298.3,18612.4,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23301.3,18612.2,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23304.3,18612,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23307.2,18611.8,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23310.2,18611.6,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23313.2,18611.4,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23316.2,18611.1,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23319.2,18610.9,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23322.2,18610.7,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23325.1,18610.5,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23328.1,18610.3,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23331.1,18610.1,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23334.1,18609.9,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23337.1,18609.7,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23340.1,18609.4,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23343,18609.2,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23346,18609,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23349,18608.8,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23352,18608.6,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23355,18608.4,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23357.9,18608.2,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23360.9,18607.9,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23363.9,18607.7,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23366.9,18607.5,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23369.9,18607.3,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23372.9,18607.1,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23375.8,18606.9,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23378.8,18606.7,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23381.8,18606.5,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23384.8,18606.2,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23387.8,18606,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23390.8,18605.8,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23394.5,18605.5,0],4.09097,[[0.0713403,0.997452,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23329.5,18623.5,0],92.2728,[[0.999213,-0.0396575,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23329.4,18620.5,0],92.2728,[[0.999213,-0.0396575,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23329.3,18617.5,0],92.2728,[[0.999213,-0.0396575,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23329.2,18614.5,0],92.2728,[[0.999213,-0.0396575,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23329.1,18611.5,0],92.2728,[[0.999213,-0.0396575,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23342.1,18621.7,0],92.2728,[[0.999213,-0.0396575,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23342,18618.2,0],92.2728,[[0.999213,-0.0396575,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23341.8,18614.8,0],92.2728,[[0.999213,-0.0396575,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23341.7,18611.3,0],92.2728,[[0.999213,-0.0396575,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23385.9,18621.5,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23385.8,18618,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23385.7,18614.5,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23385.6,18611,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23385.5,18607.5,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23398.1,18620,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23398,18616.5,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23397.8,18613,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23397.7,18609.5,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_Pavement_wide_F",[23372.9,18593,0],271.818,[[-0.999497,0.0317249,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23373,18596.5,0],271.818,[[-0.999497,0.0317249,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23373.2,18600,0],271.818,[[-0.999497,0.0317249,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23373.3,18603.5,0],271.818,[[-0.999497,0.0317249,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23316.8,18594.7,0],271.818,[[-0.999497,0.0317249,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23316.9,18598.2,0],271.818,[[-0.999497,0.0317249,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23317,18601.7,0],271.818,[[-0.999497,0.0317249,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23317.1,18605.2,0],271.818,[[-0.999497,0.0317249,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23317.2,18608.7,0],271.818,[[-0.999497,0.0317249,0],[0,0,1]],false], + ["Land_Pavement_wide_corner_F",[23397.3,18605,0],5.45456,[[0.0950563,0.995472,0],[0,0,1]],false], + ["Land_Pavement_wide_F",[23397.6,18607.1,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_i_Barracks_V2_F",[23321.7,18723,0],0,[[0,1,0],[0,0,1]],true], + ["Land_i_Barracks_V2_F",[23407.8,18723.1,0],0,[[0,1,0],[0,0,1]],true], + ["Land_i_Barracks_V2_F",[23364.3,18683,0],0,[[0,1,0],[0,0,1]],true], + ["Land_i_Barracks_V2_F",[23408.7,18682.4,0],0,[[0,1,0],[0,0,1]],true], + ["Land_i_Barracks_V2_F",[23364.8,18723.1,0],0,[[0,1,0],[0,0,1]],true], + ["Land_Cargo_House_V3_F",[23465.8,18480.2,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_House_V3_F",[23456.5,18480.4,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_House_V3_F",[23447.3,18480.6,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_House_V3_F",[23438,18480.8,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_House_V3_F",[23428.8,18481,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_House_V3_F",[23419.6,18481.3,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_House_V3_F",[23410.3,18481.5,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_House_V3_F",[23401.1,18481.7,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_House_V3_F",[23391.9,18481.9,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_House_V3_F",[23382.6,18482.2,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_House_V3_F",[23373.4,18482.4,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_House_V3_F",[23364.2,18482.6,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_House_V3_F",[23354.9,18482.8,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_House_V3_F",[23345.7,18483,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_House_V3_F",[23346,18496.6,0],1.81845,[[0.0317326,0.999496,0],[0,0,1]],true], + ["Land_Cargo_House_V3_F",[23355.3,18496.3,0],1.81845,[[0.0317326,0.999496,0],[0,0,1]],true], + ["Land_Cargo_House_V3_F",[23364.5,18496,0],1.81845,[[0.0317326,0.999496,0],[0,0,1]],true], + ["Land_Cargo_House_V3_F",[23373.7,18495.7,0],1.81845,[[0.0317326,0.999496,0],[0,0,1]],true], + ["Land_Cargo_House_V3_F",[23383,18495.4,0],1.81845,[[0.0317326,0.999496,0],[0,0,1]],true], + ["Land_Cargo_House_V3_F",[23392.2,18495.1,0],1.81845,[[0.0317326,0.999496,0],[0,0,1]],true], + ["Land_Cargo_House_V3_F",[23401.4,18494.8,0],1.81845,[[0.0317326,0.999496,0],[0,0,1]],true], + ["Land_Cargo_House_V3_F",[23410.7,18494.5,0],1.81845,[[0.0317326,0.999496,0],[0,0,1]],true], + ["Land_Cargo_House_V3_F",[23419.9,18494.2,0],1.81845,[[0.0317326,0.999496,0],[0,0,1]],true], + ["Land_Cargo_House_V3_F",[23429.1,18493.9,0],1.81845,[[0.0317326,0.999496,0],[0,0,1]],true], + ["Land_Cargo_House_V3_F",[23438.4,18493.6,0],1.81845,[[0.0317326,0.999496,0],[0,0,1]],true], + ["Land_Cargo_House_V3_F",[23447.6,18493.3,0],1.81845,[[0.0317326,0.999496,0],[0,0,1]],true], + ["Land_Cargo_House_V3_F",[23456.8,18493.1,0],1.81845,[[0.0317326,0.999496,0],[0,0,1]],true], + ["Land_Cargo_House_V3_F",[23466.1,18492.8,0],1.81845,[[0.0317326,0.999496,0],[0,0,1]],true], + ["Land_HBarrier_5_F",[23466.1,18498,0],1.81814,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23471.7,18497.8,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23477.2,18497.7,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23486.1,18493.9,0],270.909,[[-0.999874,0.0158647,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23488.2,18497.3,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23493.7,18497.1,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23499.2,18497,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23504.7,18496.8,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23505.5,18496.7,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23485.9,18481.7,0],270.909,[[-0.999874,0.0158647,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23485.8,18476.1,0],270.909,[[-0.999874,0.0158647,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23479,18494,0],92.2727,[[0.999213,-0.0396559,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23478.4,18482,0],92.2727,[[0.999213,-0.0396559,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23478.2,18476.4,0],92.2727,[[0.999213,-0.0396559,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23460.6,18498.2,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23455.1,18498.4,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23449.6,18498.5,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23444.1,18498.7,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23438.6,18498.9,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23433.1,18499.1,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23427.6,18499.2,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23422.1,18499.4,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23416.6,18499.6,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23411.1,18499.7,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23405.6,18499.9,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23400.1,18500.1,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23394.6,18500.3,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23389.1,18500.4,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23383.6,18500.6,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23378.1,18500.8,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23372.6,18501,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23367.1,18501.1,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23361.6,18501.3,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23356.1,18501.5,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23350.6,18501.7,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23345.1,18501.8,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23341.5,18499.9,0],271.364,[[-0.999717,0.0238043,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23341.1,18486.3,0],271.364,[[-0.999717,0.0238043,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23340.9,18480.7,0],271.364,[[-0.999717,0.0238043,0],[0,0,1]],false], + ["Land_Cargo_Patrol_V3_F",[23335.9,18481.8,0],0.909076,[[0.0158659,0.999874,0],[0,0,1]],true], + ["Land_HBarrier_5_F",[23329.1,18481,0],271.364,[[-0.999717,0.0238043,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23329.1,18487.1,0],271.364,[[-0.999717,0.0238043,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23337.8,18488.4,0],2.27271,[[0.0396558,0.999213,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23205.4,18499.8,0],0.909088,[[0.0158659,0.999874,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23209.9,18499.7,0],0.909088,[[0.0158659,0.999874,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23214.5,18499.6,0],0.909088,[[0.0158659,0.999874,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23219.7,18489.4,0],92.2727,[[0.999213,-0.0396559,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23219.5,18483.8,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23219.9,18495,0],92.2727,[[0.999213,-0.0396559,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23234.2,18483.4,0],92.2727,[[0.999213,-0.0396559,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23234.4,18489,0],92.2727,[[0.999213,-0.0396559,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23234.6,18494.6,0],92.2727,[[0.999213,-0.0396559,0],[0,-0,1]],false], + ["Land_ReservoirTank_Airport_F",[23307.7,18482.8,0],269.545,[[-0.999968,-0.00794067,0],[-0,0,1]],false], + ["Land_Tank_rust_F",[23330.2,18853.7,0],90.909,[[0.999874,-0.0158643,0],[0,-0,1]],false], + ["Land_ReservoirTower_F",[23509.8,18788.4,-0.021095],273.182,[[-0.998458,0.0555082,0],[0,0,1]],false], + ["Land_i_Shed_Ind_F",[23280.7,18855.3,0],271.364,[[-0.999717,0.0238043,0],[0,0,1]],true], + ["Land_u_Shed_Ind_F",[23340.7,18854.7,0.0847158],270.455,[[-0.999968,0.00794117,0],[0,0,1]],true], + ["Land_FieldToilet_F",[23515.4,18849.1,0],90.4545,[[0.999969,-0.0079325,0],[0,-0,1]],true], + ["Land_Pallets_F",[23350.4,18870.7,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Pipes_large_F",[23347.3,18876.8,0],0,[[0,1,0],[0,0,1]],false], + ["Land_EngineCrane_01_F",[23337.7,18864.1,0],345,[[-0.258819,0.965926,0],[0,0,1]],false], + ["Land_Portable_generator_F",[23509.4,18838.8,0],268.182,[[-0.999497,-0.0317244,0],[-0,0,1]],false], + ["Land_PortableLight_double_F",[23508.7,18840.6,0],336.238,[[-0.402944,0.915225,0],[0,0,1]],false], + ["Land_WeldingTrolley_01_F",[23341.2,18863,0.0988188],39.0909,[[0.630553,0.776146,0],[0,0,1]],false], + ["Land_MobileScafolding_01_F",[23346.6,18855.6,0],61.8182,[[0.881454,0.472271,0],[0,0,1]],false], + ["Land_BagBunker_Small_F",[23513.5,18839.8,0],1.81815,[[0.0317273,0.999497,0],[0,0,1]],false], + ["Land_BagFence_Long_F",[23515,18845.1,0],0,[[0,1,0],[0,0,1]],false], + ["Land_BagFence_Long_F",[23512.3,18845.1,0],0,[[0,1,0],[0,0,1]],false], + ["Land_BagFence_Long_F",[23510.6,18843.8,0],92.2727,[[0.999213,-0.0396559,0],[0,-0,1]],false], + ["Land_BagFence_Long_F",[23510.3,18838.7,0],92.2727,[[0.999213,-0.0396559,0],[0,-0,1]],false], + ["Land_BagFence_Long_F",[23514.7,18837.3,0],0.909101,[[0.0158659,0.999874,0],[0,0,1]],false], + ["Land_BagFence_Long_F",[23511.5,18837.4,0],0.909088,[[0.0158659,0.999874,0],[0,0,1]],false], + ["Land_Sign_WarningMilitaryArea_F",[23519.6,18835.1,-0.347955],270.909,[[-0.999874,0.0158647,0],[0,0,1]],false], + ["Land_Sign_WarningMilitaryArea_F",[23519.4,18828.7,-0.368505],270.909,[[-0.999874,0.0158647,0],[0,0,1]],false], + ["Land_LampAirport_F",[23515.4,18835.9,0],180.909,[[-0.0158645,-0.999874,0],[-0,0,1]],false], + ["Land_LampAirport_F",[23204.2,18869,4.76837e-007],7.67708e-005,[[1.5979e-006,1,0],[0,0,1]],false], + ["Land_LampHalogen_F",[23239.9,18480.9,0],333.636,[[-0.444072,0.895991,0],[0,0,1]],false], + ["Land_LampHalogen_F",[23215.6,18482.8,0],213.636,[[-0.553915,-0.832573,0],[-0,0,1]],false], + ["Land_i_Shed_Ind_F",[23307.6,18855,0.089165],271.364,[[-0.999717,0.0238043,0],[0,0,1]],true], + ["Land_Sign_WarningMilitaryArea_F",[23207.9,18882.8,-0.368505],177.389,[[0.0455562,-0.998962,0],[0,-0,1]],false], + ["Land_HBarrierTower_F",[23201.2,18872.7,0],90.0001,[[1,-1.59343e-006,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23214.6,18873.6,0],1.81819,[[0.0317278,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23220.1,18873.4,0],1.81818,[[0.0317278,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23225.5,18873.3,0],1.36366,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23227.8,18867.6,0],271.364,[[-0.999717,0.0238043,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23227.7,18862.3,0],271.364,[[-0.999717,0.0238043,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23227.6,18856.6,0],271.364,[[-0.999717,0.0238043,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23207.1,18854.1,0],359.545,[[-0.00794099,0.999968,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23212.6,18854.1,0],359.545,[[-0.00794099,0.999968,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23218.2,18854.2,0],359.545,[[-0.00794099,0.999968,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23221.6,18854.2,0],359.545,[[-0.00794099,0.999968,0],[0,0,1]],false], + ["Land_FieldToilet_F",[23205.3,18850.9,0],270.455,[[-0.999968,0.00794117,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23513.9,18852.9,0],0.909108,[[0.0158664,0.999874,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23508.3,18853,0],0.909119,[[0.0158664,0.999874,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23502.6,18853.1,0],0.909119,[[0.0158664,0.999874,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23496.2,18871.4,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23496,18865.8,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23495.8,18860.2,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23495.7,18855.7,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_Wreck_Hunter_F",[23338,18860.7,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],false], + ["Land_CncBarrier_stripes_F",[23228.8,18448,0],343.182,[[-0.289332,0.957229,0],[0,0,1]],false], + ["Land_Wreck_HMMWV_F",[23229.5,18446.4,0],214.091,[[-0.560509,-0.828148,0],[-0,0,1]],false], + ["Land_Cargo_House_V2_ruins_F",[23280.9,18484.3,0],206.984,[[-0.477745,-0.861692,0.171015],[-0.0955405,0.244475,0.964937]],false], + ["Land_Cargo_House_V2_ruins_F",[23270.9,18483.3,0.0219307],142.642,[[0.60362,-0.796888,0.0247735],[-0.134224,-0.0709437,0.988408]],false], + ["Land_Cargo_House_V3_F",[23298.9,18484.2,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_House_V3_F",[23291.1,18484.6,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_House_V3_F",[23261.8,18485.6,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_House_V3_F",[23251.9,18485.9,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],true], + ["Land_Cargo_HQ_V3_F",[23294.1,18515.2,0],1.36364,[[0.0237979,0.999717,0],[0,0,1]],true], + ["Land_HBarrier_5_F",[23236.8,18498.2,0],181.818,[[-0.0317247,-0.999497,0],[-0,0,1]],false], + ["Land_HBarrier_5_F",[23242.4,18498,0],181.818,[[-0.0317247,-0.999497,0],[-0,0,1]],false], + ["Land_HBarrier_5_F",[23248,18497.8,0],181.818,[[-0.0317247,-0.999497,0],[-0,0,1]],false], + ["Land_HBarrier_5_F",[23253.6,18497.6,0],181.818,[[-0.0317247,-0.999497,0],[-0,0,1]],false], + ["Land_HBarrier_5_F",[23259.2,18497.5,0],181.818,[[-0.0317247,-0.999497,0],[-0,0,1]],false], + ["Land_HBarrier_5_F",[23264.8,18497.3,0],181.818,[[-0.0317247,-0.999497,0],[-0,0,1]],false], + ["Land_HBarrier_5_F",[23270.4,18497.1,0],181.818,[[-0.0317247,-0.999497,0],[-0,0,1]],false], + ["Land_HBarrier_5_F",[23272.5,18500.6,0],91.3638,[[0.999717,-0.0238007,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23272.7,18506.2,0],91.3638,[[0.999717,-0.0238007,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23272.9,18514.1,0],91.3638,[[0.999717,-0.0238007,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23272.9,18517.4,0],91.3638,[[0.999717,-0.0238007,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23273.1,18523,0],91.3638,[[0.999717,-0.0238007,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23273.2,18528.6,0],91.3638,[[0.999717,-0.0238007,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23273.3,18534.2,0],91.3638,[[0.999717,-0.0238007,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23273.4,18539.9,0],91.3638,[[0.999717,-0.0238007,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23273.6,18545.4,0],91.3638,[[0.999717,-0.0238007,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23273.7,18551,0],91.3638,[[0.999717,-0.0238007,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23273.9,18556.6,0],91.3638,[[0.999717,-0.0238007,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23205.8,18560.1,0],0.909221,[[0.015868,0.999874,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23210.4,18560,0],0.90921,[[0.015868,0.999874,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23216,18559.9,0],0.90921,[[0.015868,0.999874,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23219.8,18559.8,0],0.90921,[[0.015868,0.999874,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23244,18559.4,0],0.90921,[[0.015868,0.999874,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23249.6,18559.3,0],0.90921,[[0.015868,0.999874,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23255.3,18559.2,0],0.90921,[[0.015868,0.999874,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23260.9,18559.2,0],0.90921,[[0.015868,0.999874,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23266.5,18559.1,0],0.90921,[[0.015868,0.999874,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23271.3,18559,0],0.90921,[[0.015868,0.999874,0],[0,0,1]],false], + ["Land_Crash_barrier_F",[23270.8,18503.6,0],271.364,[[-0.999717,0.0238043,0],[0,0,1]],false], + ["Land_Crash_barrier_F",[23271.2,18516.3,0],271.364,[[-0.999717,0.0238043,0],[0,0,1]],false], + ["Land_Crash_barrier_F",[23271.5,18528.5,0],271.364,[[-0.999717,0.0238043,0],[0,0,1]],false], + ["Land_Crash_barrier_F",[23271.9,18540.5,0],271.364,[[-0.999717,0.0238043,0],[0,0,1]],false], + ["Land_Crash_barrier_F",[23272.2,18551.1,0],271.364,[[-0.999717,0.0238043,0],[0,0,1]],false], + ["Land_Crash_barrier_F",[23265.6,18557.4,0],180.909,[[-0.0158645,-0.999874,0],[-0,0,1]],false], + ["Land_Crash_barrier_F",[23252.3,18557.8,0],180.909,[[-0.0158645,-0.999874,0],[-0,0,1]],false], + ["Land_Crash_barrier_F",[23240.3,18558,0],180.909,[[-0.0158645,-0.999874,0],[-0,0,1]],false], + ["Land_Crash_barrier_F",[23218.9,18558.2,0],0.909119,[[0.0158664,0.999874,0],[0,0,1]],false], + ["Land_Crash_barrier_F",[23208.5,18558.5,0],0.909076,[[0.0158659,0.999874,0],[0,0,1]],false], + ["Land_BagBunker_Tower_F",[23237.6,18561.7,0],271.364,[[-0.999717,0.0238043,0],[0,0,1]],false], + ["Land_BarGate_F",[23227.4,18559.3,0],1.81822,[[0.0317284,0.999497,0],[0,0,1]],true], + ["Land_Wreck_Skodovka_F",[23266.5,18504,0],258.182,[[-0.978803,-0.204803,0],[-0,0,1]],false], + ["Land_Wreck_Offroad2_F",[23267.3,18515.6,0],44.5455,[[0.701476,0.712694,0],[0,0,1]],false], + ["Land_Wreck_Car3_F",[23269.8,18530.7,0],236.364,[[-0.832574,-0.553914,0],[-0,0,1]],false], + ["Land_Wreck_Slammer_F",[23228.7,18511.6,0],50.4545,[[0.771119,0.636691,0],[0,0,1]],false], + ["Land_Wreck_Truck_F",[23268.1,18537.2,0],275.455,[[-0.995471,0.0950639,0],[0,0,1]],false], + ["Land_Wreck_HMMWV_F",[23218.7,18526.6,0],338.636,[[-0.364292,0.931285,0],[0,0,1]],false], + ["Land_Wreck_Car2_F",[23230.6,18471.2,0],323.636,[[-0.592913,0.805266,0],[0,0,1]],false], + ["Land_Wreck_Hunter_F",[23232.3,18548.5,0],300,[[-0.866025,0.5,0],[0,0,1]],false], + ["Land_Wreck_Ural_F",[23251.3,18547.4,0],35.9091,[[0.586501,0.809949,0],[0,0,1]],false], + ["Land_CncBarrier_F",[23222.5,18561.8,0],274.091,[[-0.997452,0.0713414,0],[0,0,1]],false], + ["Land_CncBarrier_F",[23222.7,18564.4,0],274.091,[[-0.997452,0.0713414,0],[0,0,1]],false], + ["Land_CncBarrier_F",[23222.9,18567,0],274.091,[[-0.997452,0.0713414,0],[0,0,1]],false], + ["Land_CncBarrier_F",[23223.1,18569.6,0],274.091,[[-0.997452,0.0713414,0],[0,0,1]],false], + ["Land_CncBarrier_F",[23223.2,18572.2,0],274.091,[[-0.997452,0.0713414,0],[0,0,1]],false], + ["Land_CncBarrier_F",[23233.3,18565.9,0],274.091,[[-0.997452,0.0713414,0],[0,0,1]],false], + ["Land_CncBarrier_F",[23233.5,18568.5,0],274.091,[[-0.997452,0.0713414,0],[0,0,1]],false], + ["Land_CncBarrier_F",[23233.7,18571.1,0],274.091,[[-0.997452,0.0713414,0],[0,0,1]],false], + ["Land_Crane_F",[23430.7,18856.1,0],2.27269,[[0.0396558,0.999213,0],[0,0,1]],false], + ["Land_Cargo40_grey_F",[23452.6,18871.9,0],3.18186,[[0.0555053,0.998458,0],[0,0,1]],false], + ["Land_Cargo40_light_green_F",[23439.8,18872.5,0],2.72729,[[0.0475823,0.998867,0],[0,0,1]],false], + ["Land_Cargo40_red_F",[23464.8,18871.6,0],0.909076,[[0.0158659,0.999874,0],[0,0,1]],false], + ["Land_Cargo40_sand_F",[23445.4,18872.4,2.71519],0,[[0,1,0],[0,0,1]],false], + ["Land_Cargo40_yellow_F",[23459.6,18871.5,2.67402],6.36364,[[0.110838,0.993838,0],[0,0,1]],false], + ["Land_Cargo40_cyan_F",[23442.7,18856.3,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Cargo40_brick_red_F",[23455,18856.3,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Cargo40_brick_red_F",[23455,18856.3,2.62761],0,[[0,1,0],[0,0,1]],false], + ["Land_Cargo40_cyan_F",[23439,18855.5,18.2696],311.364,[[-0.750526,0.660841,0],[0,0,1]],false], + ["Land_Cargo40_blue_F",[23442.8,18843.9,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Cargo40_light_green_F",[23455.1,18843.9,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Cargo40_blue_F",[23442.9,18843.9,2.58522],0,[[0,1,0],[0,0,1]],false], + ["Land_Cargo40_light_green_F",[23455.2,18843.9,2.55033],0,[[0,1,0],[0,0,1]],false], + ["Land_Cargo40_white_F",[23467.4,18856.3,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Cargo40_yellow_F",[23467.4,18843.9,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Cargo40_sand_F",[23467.4,18856.3,2.57376],0,[[0,1,0],[0,0,1]],false], + ["Land_Cargo40_light_blue_F",[23467.4,18843.9,2.60446],0,[[0,1,0],[0,0,1]],false], + ["Land_Cargo20_military_green_F",[23473.2,18866.4,0],38.1818,[[0.618159,0.786053,0],[0,0,1]],false], + ["Land_Cargo20_vr_F",[23357.9,18757.4,0],54.5454,[[0.814576,0.580058,0],[0,0,1]],false], + ["CargoNet_01_barrels_F",[23362.1,18751.3,0],0,[[0,1,0],[0,0,1]],false], + ["CargoNet_01_box_F",[23367.5,18760.9,3.09637],0,[[0,1,0],[0,0,1]],false], + ["Land_Medevac_house_V1_F",[23351.8,18767,0],273.182,[[-0.998458,0.0555082,0],[0,0,1]],true], + ["Land_Medevac_HQ_V1_F",[23369,18762.4,0],270.455,[[-0.999968,0.00794117,0],[0,0,1]],true], + ["Land_Medevac_house_V1_F",[23356.7,18780.1,0],317.273,[[-0.678506,0.734595,0],[0,0,1]],true], + ["Land_Medevac_house_V1_F",[23380.4,18778.9,0],47.7272,[[0.739951,0.672661,0],[0,0,1]],true], + ["Land_Dome_Big_F",[23370.3,18766.1,0],0,[[0,1,0],[0,0,1]],true], + ["Land_Medevac_house_V1_F",[23382.6,18753.9,0],133.182,[[0.729184,-0.684318,0],[0,-0,1]],true], + ["Land_HelipadCivil_F",[23267,18716.7,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Cargo_HQ_V1_F",[23212.6,18713.1,0],180.454,[[-0.00792385,-0.999969,0],[-0,0,1]],true], + ["Land_Cargo_House_V1_F",[23206.9,18693.4,0],180,[[-8.74228e-008,-1,0],[-0,0,1]],true], + ["Land_Cargo_House_V1_F",[23214.1,18693.4,0],180,[[-8.74228e-008,-1,0],[-0,0,1]],true], + ["Land_Cargo_House_V1_F",[23221.3,18693.4,0],180,[[-8.74228e-008,-1,0],[-0,0,1]],true], + ["Land_Cargo_House_V1_F",[23228.6,18693.4,0],180,[[-8.74228e-008,-1,0],[-0,0,1]],true], + ["Land_Cargo_House_V1_F",[23207.1,18732.8,0],0.000134468,[[2.13053e-006,1,0],[0,0,1]],true], + ["Land_Cargo_House_V1_F",[23214.4,18732.8,0],0.00012207,[[2.13053e-006,1,0],[0,0,1]],true], + ["Land_Cargo_House_V1_F",[23221.6,18732.8,0],0.00012207,[[2.13053e-006,1,0],[0,0,1]],true], + ["Land_Cargo_House_V1_F",[23228.9,18732.8,0],0.00012207,[[2.13053e-006,1,0],[0,0,1]],true], + ["Land_HBarrierBig_F",[23208,18687.6,0],0.909108,[[0.0158664,0.999874,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23216.7,18687.7,0],0.909119,[[0.0158664,0.999874,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23225.3,18687.8,0],0.909119,[[0.0158664,0.999874,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23233.3,18687.9,0],0.909119,[[0.0158664,0.999874,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23236.7,18693.1,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_HBarrierBig_F",[23236.7,18701.6,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_HBarrierBig_F",[23236.7,18710,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_HBarrierBig_F",[23236.3,18724.8,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_HBarrierBig_F",[23236.2,18733.3,0],91.8182,[[0.999497,-0.0317285,0],[0,-0,1]],false], + ["Land_HBarrierBig_F",[23208,18738.6,0],180.909,[[-0.0158645,-0.999874,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23216.6,18738.7,0],180.909,[[-0.0158645,-0.999874,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23224.9,18738.6,0],180.909,[[-0.0158645,-0.999874,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23232.9,18738.7,0],180.909,[[-0.0158645,-0.999874,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23241.3,18721.5,0],181.818,[[-0.0317247,-0.999497,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23241.9,18713.2,0],181.818,[[-0.0317247,-0.999497,0],[-0,0,1]],false], + ["Land_LampStadium_F",[23204.1,18721.4,0],180.455,[[-0.00794149,-0.999968,0],[-0,0,1]],false], + ["Land_LampHalogen_F",[23235.4,18689.1,0],64.5454,[[0.902926,0.429796,0],[0,0,1]],false], + ["Land_LampHalogen_F",[23235,18737.1,0],302.727,[[-0.841256,0.540637,0],[0,0,1]],false], + ["Land_LampShabby_F",[23350.4,18718.1,0],222.727,[[-0.678506,-0.734595,0],[-0,0,1]],false], + ["Land_LampShabby_F",[23394.2,18687,2.38419e-007],313.182,[[-0.729183,0.684318,0],[0,0,1]],false], + ["Land_LampShabby_F",[23307.4,18687.4,0],315,[[-0.707107,0.707107,0],[0,0,1]],false], + ["Land_LampSolar_F",[23336,18623.8,0],271.818,[[-0.999497,0.0317249,0],[0,0,1]],false], + ["Land_LampSolar_F",[23313.8,18593.9,0],91.8183,[[0.999496,-0.03173,0],[0,-0,1]],false], + ["Land_LampSolar_F",[23392.5,18622.2,0],274.091,[[-0.997452,0.0713414,0],[0,0,1]],false], + ["Land_LampSolar_F",[23369.8,18592.1,0],92.2727,[[0.999213,-0.0396559,0],[0,-0,1]],false], + ["MetalBarrel_burning_F",[23493.9,18491.1,0],0,[[0,1,0],[0,0,1]],false], + ["Land_BarrelWater_F",[23485,18491.3,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Box_AmmoOld_F",[23489,18482.3,0],315.455,[[-0.701469,0.7127,0],[0,0,1]],false], + ["Land_TentDome_F",[23498.4,18494.8,0],271.818,[[-0.999497,0.0317249,0],[0,0,1]],false], + ["Land_TablePlastic_01_F",[23490.3,18490,0],40.9091,[[0.654861,0.75575,0],[0,0,1]],false], + ["Land_Sunshade_01_F",[23490.4,18490,0],0,[[0,1,0],[0,0,1]],false], + ["Land_FieldToilet_F",[23204.5,18727.2,0],270.455,[[-0.999968,0.00794117,0],[0,0,1]],false], + ["Land_FieldToilet_F",[23507,18502.1,0],90.455,[[0.999968,-0.00794156,0],[0,-0,1]],false], + ["Land_MilOffices_V1_F",[23239.8,18784.4,2.38419e-007],359.545,[[-0.00794099,0.999968,0],[0,0,1]],true], + ["Land_i_Shed_Ind_F",[23494.7,18711.4,0.0891647],0.454926,[[0.00793986,0.999968,0],[0,0,1]],true], + ["Land_WIP_F",[23413,18828.9,0],181.364,[[-0.0238044,-0.999717,0],[-0,0,1]],false], + ["Land_i_Shed_Ind_F",[23495.6,18747.6,0.0891647],0.454926,[[0.00793986,0.999968,0],[0,0,1]],true], + ["Land_Wreck_CarDismantled_F",[23483.3,18765.2,0],77.7273,[[0.977147,0.212565,0],[0,0,1]],false], + ["Land_Wreck_Skodovka_F",[23505.9,18738.8,0],92.2727,[[0.999213,-0.0396559,0],[0,-0,1]],false], + ["Land_Wreck_UAZ_F",[23503.6,18733.1,0],86.8182,[[0.998458,0.0555042,0],[0,0,1]],false], + ["Land_Wreck_Heli_Attack_02_F",[23489,18730.5,0],52.7273,[[0.795762,0.605609,0],[0,0,1]],false], + ["Land_Wreck_BMP2_F",[23481.9,18704.6,0],69.0909,[[0.934148,0.356887,0],[0,0,1]],false], + ["Land_Wreck_Offroad_F",[23504.5,18725.1,0],132.727,[[0.734595,-0.678506,0],[0,-0,1]],false], + ["Land_Wreck_Car3_F",[23509.5,18764.5,0],29.0909,[[0.486197,0.873849,0],[0,0,1]],false], + ["Land_Wreck_Truck_F",[23495.9,18703.4,0],96.3636,[[0.993839,-0.110837,0],[0,-0,1]],false], + ["Land_Wreck_Ural_F",[23481.7,18740,0],146.364,[[0.553915,-0.832573,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23511.8,18770.4,0],0,[[0,1,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23506.2,18770.4,0],0,[[0,1,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23500.6,18770.4,0],0,[[0,1,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23495,18770.4,0],0,[[0,1,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23489.4,18770.4,0],0,[[0,1,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23483.8,18770.4,0],0,[[0,1,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23478.2,18770.4,0],0,[[0,1,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23476.1,18766.8,0],90.4545,[[0.999969,-0.0079325,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23476.1,18761.2,0],90.4545,[[0.999969,-0.0079325,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23476,18744.4,0],90.4545,[[0.999969,-0.0079325,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23475.9,18738.8,0],90.4545,[[0.999969,-0.0079325,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23475.9,18733.2,0],90.4545,[[0.999969,-0.0079325,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23475.8,18727.6,0],90.4545,[[0.999969,-0.0079325,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23475.7,18710.8,0],90.4545,[[0.999969,-0.0079325,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23475.6,18705.2,0],90.4545,[[0.999969,-0.0079325,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23475.6,18699.5,0],90.4545,[[0.999969,-0.0079325,0],[0,-0,1]],false], + ["Land_HBarrier_5_F",[23479.2,18697.5,0],1.36363,[[0.0237974,0.999717,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23484.8,18697.4,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23490.4,18697.2,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23496,18697.1,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23501.6,18697,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23507.2,18696.8,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23510.1,18696.8,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23277,18536.2,0],1.50775,[[0.0263122,0.999654,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23282.6,18536.1,0],1.50775,[[0.0263122,0.999654,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23288.2,18535.9,0],1.50775,[[0.0263122,0.999654,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23289.4,18535.8,0],1.50775,[[0.0263122,0.999654,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23299.4,18535.6,0],1.50775,[[0.0263122,0.999654,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23305,18535.5,0],1.50775,[[0.0263122,0.999654,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23310.6,18535.3,0],1.50775,[[0.0263122,0.999654,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23312.6,18531.7,0],272.417,[[-0.99911,0.0421723,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23312.3,18526.1,0],272.417,[[-0.99911,0.0421723,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23312.1,18520.5,0],272.417,[[-0.99911,0.0421723,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23311.8,18514.9,0],272.417,[[-0.99911,0.0421723,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23311.6,18509.3,0],272.417,[[-0.99911,0.0421723,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23335.7,18502,0],181.053,[[-0.0183775,-0.999831,0],[-0,0,1]],false], + ["Land_HBarrier_5_F",[23330.1,18502.1,0],181.053,[[-0.0183775,-0.999831,0],[-0,0,1]],false], + ["Land_HBarrier_5_F",[23324.4,18502.2,0],181.053,[[-0.0183775,-0.999831,0],[-0,0,1]],false], + ["Land_HBarrier_5_F",[23318.8,18502.3,0],181.053,[[-0.0183775,-0.999831,0],[-0,0,1]],false], + ["Land_HBarrier_5_F",[23313.2,18502.4,0],181.053,[[-0.0183775,-0.999831,0],[-0,0,1]],false], + ["Land_HBarrier_5_F",[23311.4,18505.6,0],272.417,[[-0.99911,0.0421723,0],[0,0,1]],false], + ["Land_HBarrierWall_corridor_F",[23294.5,18537.9,0],91.3636,[[0.999717,-0.023797,0],[0,-0,1]],false], + ["Land_Cargo_Patrol_V3_F",[23289.3,18540.3,0],92.2727,[[0.999213,-0.0396559,0],[0,-0,1]],true], + ["Land_CinderBlocks_F",[23204.8,18602.8,0],1.36364,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23204.8,18603.8,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23204.9,18604.9,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23204.9,18605.9,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23204.9,18606.9,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23204.9,18608,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23205,18609,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23205,18610,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23205,18611.1,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23205,18612.1,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23205.1,18613.1,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23205.1,18614.2,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23205.1,18615.2,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23205.1,18616.2,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23206.4,18616.2,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23206.3,18615.2,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23206.3,18614.1,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23206.3,18613.1,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23206.3,18612.1,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23206.2,18611,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23206.2,18610,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23206.2,18609,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23206.2,18607.9,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23206.1,18606.9,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23206.1,18605.9,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23206.1,18604.8,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23206.1,18603.8,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_CinderBlocks_F",[23206,18602.8,0],1.36365,[[0.0237979,0.999717,0],[0,0,1]],false], + ["Land_ConcretePipe_F",[23207.7,18593.4,0],351.364,[[-0.150156,0.988662,0],[0,0,1]],false], + ["Land_ConcretePipe_F",[23206.1,18581.6,-2.38419e-007],76.3636,[[0.971811,0.23576,0],[0,0,1]],false], + ["Land_ConcretePipe_F",[23213.6,18595.7,-2.38419e-007],24.5454,[[0.415414,0.909632,0],[0,0,1]],false], + ["Land_ConcretePipe_F",[23213.1,18608.8,-2.38419e-007],62.7272,[[0.888835,0.458228,0],[0,0,1]],false], + ["Land_ConcretePipe_F",[23217.9,18626,-2.38419e-007],359.091,[[-0.015864,0.999874,0],[0,0,1]],false], + ["Land_ConcretePipe_F",[23221,18607,-2.38419e-007],21.3636,[[0.364285,0.931288,0],[0,0,1]],false], + ["Land_ConcretePipe_F",[23212.8,18634.1,-2.38419e-007],67.7273,[[0.92539,0.379015,0],[0,0,1]],false], + ["Land_Coil_F",[23211.6,18621.5,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Coil_F",[23216.5,18586.2,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Coil_F",[23222.7,18596.2,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Pipes_large_F",[23207.5,18588.2,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Pipes_large_F",[23207.5,18587,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Pipes_large_F",[23207.5,18585.9,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Timbers_F",[23205.7,18636.4,0],0,[[0,1,0],[0,0,1]],false], + ["Land_LampSolar_F",[23289,18509.3,0],21.3636,[[0.364285,0.931288,0],[0,0,1]],false], + ["Land_LampShabby_F",[23232.9,18558.8,0],265.455,[[-0.996855,-0.079242,0],[-0,0,1]],false], + ["Land_Cargo40_yellow_F",[23507.1,18536.8,0],91.3637,[[0.999717,-0.023799,0],[0,-0,1]],false], + ["Land_Cargo40_red_F",[23506.8,18524.5,0],91.3637,[[0.999717,-0.023799,0],[0,-0,1]],false], + ["Land_Cargo40_light_blue_F",[23507.1,18524.8,2.5908],87.2728,[[0.998867,0.0475806,0],[0,0,1]],false], + ["Land_Cargo40_military_green_F",[23507.2,18537.4,2.59217],91.8181,[[0.999497,-0.0317269,0],[0,-0,1]],false], + ["Land_Cargo20_blue_F",[23507.9,18512.2,0.0176594],136.269,[[0.691269,-0.722598,0],[0,-0,1]],false], + ["Land_Cargo40_sand_F",[23507.3,18510.5,2.57103],55.9091,[[0.828149,0.560508,0],[0.0417925,-0.0617483,0.997216]],false], + ["Land_Wreck_Hunter_F",[23506.6,18516.3,-0.492616],290.909,[[-0.910493,0.347848,0.223618],[0.208892,-0.0798058,0.974677]],false], + ["Land_Wreck_Offroad2_F",[23418.7,18533.1,0],217.273,[[-0.605614,-0.795759,0],[-0,0,1]],false], + ["Land_Wreck_HMMWV_F",[23342.3,18534.6,0],130,[[0.766044,-0.642788,0],[0,-0,1]],false], + ["Land_Wreck_Ural_F",[23337.9,18580,0.188128],133.636,[[0.742209,-0.650054,-0.16296],[-0.0469336,-0.292984,0.954965]],false], + ["Land_Barracks_ruins_F",[23325.3,18586.9,0],182.727,[[-0.0475774,-0.998868,0],[-0,0,1]],false], + ["Land_Wreck_BRDM2_F",[23375.1,18514,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Wreck_HMMWV_F",[23271.6,18583.8,0],130,[[0.766044,-0.642788,0],[0,-0,1]],false], + ["Land_Wreck_Truck_F",[23249.7,18634.9,0],289.091,[[-0.945,0.32707,0],[0,0,1]],false], + ["Land_Wreck_Offroad2_F",[23270.2,18627.9,0],44.5455,[[0.701476,0.712694,0],[0,0,1]],false], + ["Land_Wreck_Skodovka_F",[23263.8,18665.4,0],155.455,[[0.415408,-0.909635,0],[0,-0,1]],false], + ["Land_Cargo20_grey_F",[23496.8,18505.3,-0.11775],309.545,[[-0.0132614,0.0109493,0.999852],[0.771011,-0.63659,0.0171974]],false], + ["Land_UWreck_MV22_F",[23478.6,18573.4,0],230,[[-0.766045,-0.642788,0],[-0,0,1]],false], + ["Land_spp_Mirror_ruins_F",[23486.1,18582.5,-0.592143],175.909,[[0.23313,-0.906378,0.352321],[0.367186,0.417531,0.831169]],false], + ["Land_spp_Mirror_ruins_F",[23485.8,18578.2,0],224.091,[[-0.6958,-0.718235,0],[-0,0,1]],false], + ["Land_spp_Mirror_ruins_F",[23485.6,18573.8,-0.765256],222.273,[[-0.573014,-0.630331,0.523773],[0.352323,0.387565,0.851858]],false], + ["Land_spp_Mirror_ruins_F",[23474.5,18576.5,-0.947617],151.818,[[0.253162,-0.911687,-0.323629],[0.620622,-0.103566,0.77724]],false], + ["Land_spp_Mirror_ruins_F",[23468.8,18573.5,0],183.182,[[-0.0555083,-0.998458,0],[-0,0,1]],false], + ["Land_spp_Mirror_ruins_F",[23478.5,18579.2,-0.483662],183.182,[[0.211824,-0.851539,0.479596],[0.427774,0.522011,0.737912]],false], + ["Land_HBarrierBig_F",[23202.4,18699.4,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.4,18708.1,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.4,18716.9,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.3,18725.6,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.3,18734.3,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.3,18743.1,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.3,18751.8,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.3,18760.5,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.2,18769.2,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.2,18778,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.2,18786.7,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.2,18795.4,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.2,18804.2,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.1,18812.9,2.38419e-007],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.1,18821.6,4.76837e-007],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.1,18830.3,4.76837e-007],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.1,18839.1,4.76837e-007],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.1,18847.8,4.76837e-007],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202,18856.5,4.76837e-007],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202,18865.3,4.76837e-007],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23210.8,18881.6,4.76837e-007],181.627,[[-0.0283974,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23202.2,18878.2,4.76837e-007],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23209.2,18873.8,0],1.81818,[[0.0317278,0.999497,0],[0,0,1]],false], + ["Land_HBarrier_5_F",[23204,18874,0],1.81818,[[0.0317278,0.999497,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23219.3,18881.3,4.76837e-007],181.627,[[-0.0283981,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23227.8,18881.1,4.76837e-007],181.627,[[-0.0283984,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23236.3,18880.8,4.76837e-007],181.627,[[-0.0283988,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23244.9,18880.6,4.76837e-007],181.627,[[-0.0283991,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23253.4,18880.4,4.76837e-007],181.627,[[-0.0283993,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23261.9,18880.1,4.76837e-007],181.627,[[-0.0283998,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23270.4,18879.9,4.76837e-007],181.627,[[-0.0284005,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23279,18879.6,4.76837e-007],181.627,[[-0.0284007,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23287.5,18879.4,4.76837e-007],181.627,[[-0.028401,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23296,18879.1,4.76837e-007],181.627,[[-0.0284015,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23304.5,18878.9,4.76837e-007],181.628,[[-0.0284017,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23313.1,18878.7,4.76837e-007],181.628,[[-0.0284022,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23321.6,18878.4,4.76837e-007],181.628,[[-0.0284029,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23330.1,18878.2,4.76837e-007],181.628,[[-0.0284031,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23338.6,18877.9,4.76837e-007],181.628,[[-0.0284034,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23347.2,18877.7,4.76837e-007],181.628,[[-0.0284038,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23355.7,18877.4,4.76837e-007],181.628,[[-0.0284041,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23364.2,18877.2,4.76837e-007],181.628,[[-0.0284046,-0.999597,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23372.7,18877,4.76837e-007],181.628,[[-0.0284053,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23381.3,18876.7,4.76837e-007],181.628,[[-0.0284055,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23389.8,18876.5,4.76837e-007],181.628,[[-0.0284057,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23398.3,18876.2,4.76837e-007],181.628,[[-0.0284062,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23406.8,18876,4.76837e-007],181.628,[[-0.0284065,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23415.4,18875.8,4.76837e-007],181.628,[[-0.0284069,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23423.9,18875.5,4.76837e-007],181.628,[[-0.0284072,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23432.4,18875.3,4.76837e-007],181.628,[[-0.0284074,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23440.9,18875,4.76837e-007],181.628,[[-0.0284079,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23449.5,18874.8,4.76837e-007],181.628,[[-0.0284081,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23458.2,18874.6,4.76837e-007],181.628,[[-0.0284086,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23466.5,18874.3,4.76837e-007],181.628,[[-0.0284093,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23475,18874.1,4.76837e-007],181.628,[[-0.0284096,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23483.6,18873.8,4.76837e-007],181.628,[[-0.0284098,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23492.1,18873.6,4.76837e-007],181.628,[[-0.0284103,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23500.6,18873.3,4.76837e-007],181.628,[[-0.0284105,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23509.1,18873.1,4.76837e-007],181.628,[[-0.028411,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23515.2,18873.3,4.76837e-007],181.628,[[-0.0284117,-0.999596,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23518.7,18868.2,4.76837e-007],271.389,[[-0.999706,0.0242353,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23518.5,18859.6,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23518.2,18851.1,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23518,18842.6,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23518.1,18837.9,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23517.6,18825.5,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23517.4,18817,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23517.2,18808.5,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23517,18799.9,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23516.8,18791.4,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23516.6,18782.9,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23516.4,18774.3,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23516.2,18765.8,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23516,18757.3,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23515.8,18748.8,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23515.6,18740.2,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23515.3,18731.7,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23515.1,18723.2,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23514.9,18714.7,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23514.7,18706.1,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23514.5,18697.6,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23514.3,18689.1,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23514.1,18680.5,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23513.9,18672,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23513.7,18663.5,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23513.5,18655,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23513.3,18646.4,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23513.1,18637.9,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23512.9,18629.4,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23512.7,18620.9,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23512.5,18612.3,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23512.2,18603.8,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23512,18595.3,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23511.8,18586.7,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23511.6,18578.2,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23511.4,18569.7,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23511.2,18561.2,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23512.9,18828.6,4.76837e-007],358.756,[[-0.0217138,0.999764,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23507.7,18831.5,4.76837e-007],274.181,[[-0.997338,0.0729128,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23511,18552.6,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23510.8,18544.1,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23510.6,18535.6,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23510.4,18527.1,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23511.2,18518.5,4.76837e-007],256.229,[[-0.971256,-0.238039,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[23510.1,18511.1,4.76837e-007],317.266,[[-0.67859,0.734517,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23509.7,18502.3,4.76837e-007],278.57,[[-0.988836,0.14901,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23509.4,18477.2,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23509.4,18485.5,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23509.3,18493.8,4.76837e-007],271.389,[[-0.999706,0.0242357,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23506.3,18471.9,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23497.8,18472.2,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23489.3,18472.4,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23480.7,18472.6,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23472.2,18472.9,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23463.7,18473.1,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23455.1,18473.3,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23446.6,18473.6,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23438.1,18473.8,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23429.6,18474,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23421,18474.3,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23412.5,18474.5,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23404,18474.7,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23395.5,18474.9,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23386.9,18475.2,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23378.4,18475.4,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23369.9,18475.6,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23361.4,18475.9,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23352.8,18476.1,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23344.3,18476.3,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23335.8,18476.6,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23327.3,18476.8,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23318.7,18477,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23310.2,18477.2,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23301.7,18477.5,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23293.2,18477.7,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23284.6,18477.9,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23243.7,18478.9,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23252.1,18478.8,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23260.5,18478.6,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23269,18478.6,4.76837e-007],1.54828,[[0.0270193,0.999635,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.4,18690.9,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.4,18682.4,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.4,18673.8,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.5,18665.3,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.5,18656.8,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.5,18648.2,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.5,18639.7,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.5,18631.2,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.6,18622.7,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.6,18614.1,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.6,18605.6,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.6,18597.1,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.6,18588.5,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.7,18580,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.7,18571.5,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.7,18562.9,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.7,18554.4,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.7,18545.9,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.8,18537.4,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.8,18528.8,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.8,18520.3,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.8,18511.8,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.8,18503.2,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.9,18494.7,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23202.9,18486.2,0],89.8719,[[0.999997,0.00223477,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23206.1,18481.3,0],2.90385,[[0.0506604,0.998716,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[23209.4,18481.2,0],180.43,[[-0.00751282,-0.999972,0],[-0,0,1]],false] +]; diff --git a/@ExileServer/addons/a3_dms/objects/static/slums_objects.sqf b/@ExileServer/addons/a3_dms/objects/static/slums_objects.sqf new file mode 100644 index 0000000..af72237 --- /dev/null +++ b/@ExileServer/addons/a3_dms/objects/static/slums_objects.sqf @@ -0,0 +1,146 @@ +[ + ["Land_City2_8m_F",[15977,16201.3,0],17.7273,[[0.304487,0.952517,0],[0,0,1]],false], + ["Land_City2_8m_F",[15913.4,16222.7,0],35.9091,[[0.586501,0.809948,0],[0,0,1]],false], + ["Land_cargo_house_slum_F",[16010.7,16228.3,-0.0505352],95.9091,[[0.994686,-0.102951,0],[0,-0,1]],false], + ["Land_Slum_House03_F",[16096.6,16240.1,0.22751],331.818,[[-0.472271,0.881453,0],[0,0,1]],false], + ["Land_Cargo_HQ_V2_F",[16020.8,16213.9,-0.139826],106.364,[[0.959493,-0.281733,0],[0,-0,1]],false], + ["Land_HBarrierBig_F",[16083.6,16185.3,-0.072401],15.9092,[[0.274113,0.961698,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16075.6,16187.4,-0.072401],15.9091,[[0.274113,0.961698,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16067.3,16189.4,-0.22118],15.9091,[[0.274113,0.961698,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16059.1,16191.3,-0.0723972],11.8183,[[0.204808,0.978802,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16051.1,16193.1,-0.0723953],12.2728,[[0.212566,0.977147,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16043,16194.7,-0.110312],15.9091,[[0.274113,0.961698,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16034.9,16196.6,-0.11031],15.9091,[[0.274113,0.961698,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16026.4,16198.3,-0.016922],10.4546,[[0.181457,0.983399,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16018.3,16199.9,-0.110308],15.9091,[[0.274113,0.961698,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16010.3,16201.8,-0.110306],15.9091,[[0.274113,0.961698,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16002.2,16204.1,-0.110304],18.1819,[[0.312035,0.950071,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15994.1,16206.3,-0.110304],15.9091,[[0.274113,0.961698,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15985.8,16208.4,-0.110304],15.9091,[[0.274113,0.961698,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15977.8,16210.6,-0.110304],15.9091,[[0.274113,0.961698,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15969.8,16212.5,-0.110302],15.9091,[[0.274113,0.961698,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15961.7,16214.8,-0.110302],18.6364,[[0.319562,0.947565,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15953.9,16216.5,-0.110302],15.9091,[[0.274113,0.961698,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15946.5,16219.5,-0.110302],31.8182,[[0.527226,0.849725,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16091.4,16184.8,-0.0723991],353.182,[[-0.118717,0.992928,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16099.1,16184.5,-0.0723991],15.9092,[[0.274113,0.961698,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16105.3,16185.3,-0.760269],335,[[-0.422617,0.906309,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15939.4,16223.8,-0.110302],31.8182,[[0.527226,0.849725,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15932.7,16227.8,-0.110302],31.8182,[[0.527226,0.849725,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15926.1,16232.1,-0.110302],35.9091,[[0.586501,0.809948,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15919.7,16236.2,-0.110302],31.8182,[[0.527226,0.849725,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15914.2,16242,-0.110302],50,[[0.766045,0.642787,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15908.7,16247.6,-0.110302],38.1819,[[0.61816,0.786052,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15903.8,16253,-0.110302],60.4546,[[0.869965,0.493113,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15946.4,16295.5,-0.339949],205.909,[[-0.436945,-0.899488,0],[-0,0,1]],false], + ["Land_HBarrierBig_F",[15952,16292,-0.339949],45.4546,[[0.712695,0.701474,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15958,16286.1,-0.339947],45.4546,[[0.712695,0.701474,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15963.9,16280.1,-0.339947],47.2728,[[0.734592,0.678509,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15969.9,16274,-0.339947],45.4546,[[0.712695,0.701474,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15976.5,16268.7,-0.339947],33.6364,[[0.55392,0.83257,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15983.8,16264.3,-0.339947],32.7273,[[0.540641,0.841253,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15991.4,16261.8,-0.339947],12.7273,[[0.220311,0.97543,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15999.8,16260.4,-0.339947],10.4546,[[0.181456,0.983399,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16008.1,16259,-0.339947],10.9091,[[0.189252,0.981929,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16016.6,16258.2,-0.339947],2.27275,[[0.0396569,0.999213,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16025,16257.7,-0.339947],6.36368,[[0.110839,0.993838,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16033.5,16257.2,-0.339947],6.36367,[[0.110839,0.993838,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16041.9,16256.7,-0.339945],6.36367,[[0.110839,0.993838,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16050.3,16256.2,-0.339945],6.36367,[[0.110839,0.993838,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16058.8,16255.6,-0.339945],6.36367,[[0.110839,0.993838,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16067.3,16254.8,-0.339945],10,[[0.173649,0.984808,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16075.9,16253.8,-0.339945],10,[[0.173649,0.984808,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16084.3,16252.3,-0.339945],13.1819,[[0.228043,0.973651,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16092.3,16250.7,-0.339945],15.4546,[[0.266475,0.963842,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16100.5,16248.9,-0.339945],12.7273,[[0.220311,0.97543,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16104.6,16249.6,-0.456839],352.273,[[-0.134457,0.990919,0],[0,0,1]],false], + ["Land_i_House_Small_02_V3_dam_F",[16083.3,16196.9,0.116032],101.364,[[0.980397,-0.197033,0],[0,-0,1]],false], + ["Land_u_Addon_01_V1_F",[16090,16189.1,0.226271],280,[[-0.984807,0.17365,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16071.3,16198.6,-0.22118],280.455,[[-0.983399,0.181457,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16068.7,16192.4,-0.22118],308.182,[[-0.786052,0.61816,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[16085.3,16243,-0.232141],90.4547,[[0.999969,-0.00793513,0],[0,-0,1]],false], + ["Land_HBarrierBig_F",[16085.6,16248.9,-0.262724],102.273,[[0.977147,-0.212567,0],[0,-0,1]],false], + ["Land_Mil_WiredFence_Gate_F",[16103.1,16214.4,0.41972],102.273,[[0.977147,-0.212566,0],[0,-0,1]],false], + ["Land_Mil_WiredFence_F",[16102.3,16205.6,0],260.909,[[-0.987439,-0.158001,0],[-0,0,1]],false], + ["Land_Mil_WiredFence_F",[16103.5,16197.9,0],260.909,[[-0.987439,-0.158001,0],[-0,0,1]],false], + ["Land_Mil_WiredFence_F",[16104.7,16190.2,0],260.909,[[-0.987439,-0.158001,0],[-0,0,1]],false], + ["Land_Mil_WiredFence_F",[16103.8,16223.2,0],270.909,[[-0.999874,0.0158666,0],[0,0,1]],false], + ["Land_Mil_WiredFence_F",[16103.6,16230.9,0],266.364,[[-0.997987,-0.0634225,0],[-0,0,1]],false], + ["Land_Mil_WiredFence_F",[16103.1,16238.6,0],266.364,[[-0.997987,-0.063423,0],[-0,0,1]],false], + ["Land_Mil_WiredFence_F",[16102.8,16246.4,0],270.909,[[-0.999874,0.0158666,0],[0,0,1]],false], + ["Land_Mound01_8m_F",[16105.5,16190.2,0.221277],82.2727,[[0.990919,0.134458,0],[0,0,1]],false], + ["Land_Mound01_8m_F",[16104.9,16196.5,0.221277],82.2727,[[0.990919,0.134458,0],[0,0,1]],false], + ["Land_Mound01_8m_F",[16103.4,16204.7,0.0821114],77.7273,[[0.977147,0.212565,0],[0,0,1]],false], + ["Land_Mound01_8m_F",[16104.3,16200,0.0821114],77.7273,[[0.977147,0.212565,0],[0,0,1]],false], + ["Land_Mound01_8m_F",[16104.8,16224.2,0.0821114],89.091,[[0.999874,0.0158653,0],[0,0,1]],false], + ["Land_Mound01_8m_F",[16103.9,16230.9,0.0821114],262.727,[[-0.991955,-0.126592,0],[-0,0,1]],false], + ["Land_Mound01_8m_F",[16104.1,16237,0.0821114],84.091,[[0.994687,0.102949,0],[0,0,1]],false], + ["Land_Mound01_8m_F",[16104,16243.2,0.0821114],90.0001,[[1,-1.11659e-006,0],[0,-0,1]],false], + ["Land_CampingChair_V2_F",[16107.9,16222.1,0],17.2727,[[0.29692,0.954902,0],[0,0,1]],false], + ["Land_CampingChair_V2_F",[16106.6,16222.4,0],312.727,[[-0.734592,0.67851,0],[0,0,1]],false], + ["Land_CampingTable_F",[16107,16221.3,0],24.5454,[[0.415415,0.909632,0],[0,0,1]],false], + ["Land_CampingChair_V2_F",[16107,16220.2,0],162.727,[[0.29692,-0.954902,0],[0,-0,1]],false], + ["Land_Device_disassembled_F",[16023.2,16208.4,0.869701],288.182,[[-0.950071,0.312034,0],[0,0,1]],false], + ["Land_Device_assembled_F",[16022.3,16214.2,0.626175],286.364,[[-0.959493,0.281732,0],[0,0,1]],false], + ["Land_PaperBox_closed_F",[16025.6,16219,0],0,[[0,1,0],[0,0,1]],false], + ["Land_PaperBox_open_empty_F",[16024,16219.9,0],44.5454,[[0.701475,0.712694,0],[0,0,1]],false], + ["Land_Wreck_Car2_F",[16066.5,16215.5,0],13.6364,[[0.235759,0.971812,0],[0,0,1]],false], + ["Land_Wreck_HMMWV_F",[16085.1,16225.9,0.12949],0,[[0,1,0],[0,0,1]],false], + ["Land_Wreck_Skodovka_F",[16099.8,16221.8,0],288.636,[[-0.947566,0.319561,0],[0,0,1]],false], + ["Land_Wreck_Truck_F",[16100.2,16206.7,0],180,[[-1.27952e-006,-1,0],[-0,0,1]],false], + ["Land_cargo_addon02_V2_F",[16106.3,16221.8,0],274.091,[[-0.997452,0.07134,0],[0,0,1]],false], + ["Land_BarGate_F",[16102.8,16214.2,0.45191],280,[[-0.984808,0.173648,0],[0,0,1]],false], + ["Land_Coil_F",[16098.8,16196.6,0],0,[[0,1,0],[0,0,1]],false], + ["Land_cargo_house_slum_F",[16041,16250.6,-0.0505352],83.1819,[[0.992928,0.118718,0],[0,0,1]],false], + ["Land_cargo_house_slum_F",[16044.3,16250.6,-0.0505352],122.273,[[0.845515,-0.533951,0],[0,-0,1]],false], + ["Land_Slum_House01_F",[16064.7,16250.8,0],94.091,[[0.997452,-0.0713399,0],[0,-0,1]],false], + ["Land_cargo_addon01_V1_F",[16047.8,16251.7,-0.0761833],300.909,[[-0.857983,0.513678,0],[0,0,1]],false], + ["Land_cargo_addon01_V1_F",[16046.7,16250,-0.160095],301.818,[[-0.849725,0.527226,0],[0,0,1]],false], + ["Land_Slum_House03_F",[16078.2,16247.5,0.22751],6.81812,[[0.118718,0.992928,0],[0,0,1]],false], + ["Land_i_Shop_01_V2_dam_F",[16033.3,16241,0],10.4545,[[0.181455,0.983399,0],[0,0,1]],false], + ["Land_BellTower_02_V2_F",[16038.3,16224.5,0],9.99998,[[0.173648,0.984808,0],[0,0,1]],false], + ["Land_Chapel_Small_V2_F",[16027.5,16226.2,0.5917],189.091,[[-0.158002,-0.987439,0],[-0,0,1]],false], + ["Land_Maroula_F",[16062,16222.3,0.0514984],314.545,[[-0.712694,0.701475,0],[0,0,1]],false], + ["Land_Cargo20_military_green_F",[16055.4,16223.8,0.0202141],312.727,[[-0.734591,0.67851,0],[0,0,1]],false], + ["Land_Cargo20_vr_F",[16061.2,16228.7,0],1.81817,[[0.0317278,0.999497,0],[0,0,1]],false], + ["Land_Cargo40_red_F",[16081.2,16207.7,-0.220516],303.182,[[-0.836937,0.547299,0],[0,0,1]],false], + ["Land_Coil_F",[16116.7,16211.6,0],333.636,[[-0.444066,0.895994,0],[0,0,1]],false], + ["Land_SlideCastle_F",[15985.6,16257.1,0.0155277],84.0909,[[0.994686,0.102951,0],[0,0,1]],false], + ["Land_TreeBin_F",[15993.3,16254.2,0],0,[[0,1,0],[0,0,1]],false], + ["Land_GarbageBin_01_F",[15988,16256.4,0],350,[[-0.173648,0.984808,0],[0,0,1]],false], + ["Land_GarbageBin_01_F",[15984.3,16256,0],349.545,[[-0.181455,0.983399,0],[0,0,1]],false], + ["Land_dp_transformer_F",[16006.4,16206.3,0],14.5454,[[0.251148,0.967949,0],[0,0,1]],false], + ["Land_dp_transformer_F",[16007.2,16209.2,-0.0845985],194.091,[[-0.24346,-0.969911,0],[-0,0,1]],false], + ["Land_TTowerSmall_1_F",[16020.8,16210.7,5.30356],0,[[0,1,0],[0,0,1]],false], + ["Land_TBox_F",[16003.8,16209.6,0],104.545,[[0.967949,-0.251148,0],[0,-0,1]],false], + ["Land_TBox_F",[16008.6,16215.6,0],285,[[-0.965926,0.258819,0],[0,0,1]],false], + ["Land_dp_transformer_F",[16007.9,16211.9,-0.208273],14.5454,[[0.251148,0.967949,0],[0,0,1]],false], + ["Land_LuggageHeap_04_F",[16086.6,16234.4,0.938828],175.455,[[0.07925,-0.996855,0],[0,-0,1]],false], + ["Land_RowBoat_V3_F",[16003.1,16238.7,0],319.091,[[-0.65486,0.75575,0],[0,0,1]],false], + ["Land_Scrap_MRAP_01_F",[15968.2,16249.1,0],152.273,[[0.465263,-0.885172,0],[0,-0,1]],false], + ["Land_ScrapHeap_1_F",[15973,16250.8,0],43.1818,[[0.684316,0.729186,0],[0,0,1]],false], + ["WaterPump_01_sand_F",[15965.7,16237.1,0],0,[[0,1,0],[0,0,1]],false], + ["Land_CrabCages_F",[15962,16246.7,0],0,[[0,1,0],[0,0,1]],false], + ["Land_Cargo40_military_green_F",[15954,16257.1,0],27.2727,[[0.458227,0.888835,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15904.3,16258.6,-0.1103],131.364,[[0.75053,-0.660837,0],[0,-0,1]],false], + ["Land_HBarrierBig_F",[15907.4,16265.1,-0.1103],107.273,[[0.954902,-0.296921,0],[0,-0,1]],false], + ["Land_HBarrierBig_F",[15941.2,16297.5,-0.1103],14.091,[[0.243462,0.96991,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15935.1,16296.8,-0.1103],156.364,[[0.40093,-0.916109,0],[0,-0,1]],false], + ["CraterLong",[15927.8,16298.4,0],0,[[0,1,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15907.9,16272.9,-0.1103],88.6364,[[0.999717,0.0237968,0],[0,0,1]],false], + ["Land_HBarrierBig_F",[15908,16280.5,-0.1103],99.091,[[0.987439,-0.158002,0],[0,-0,1]],false], + ["Land_HBarrierBig_F",[15911.9,16285.7,-0.1103],145,[[0.573576,-0.819153,0],[0,-0,1]],false], + ["Land_HBarrierBig_F",[15918.3,16288.1,-0.1103],174.091,[[0.10295,-0.994687,0],[0,-0,1]],false], + ["Land_HBarrierBig_F",[15929.7,16289.5,-0.1103],132.273,[[0.739951,-0.67266,0],[0,-0,1]],false], + ["Land_Wreck_Slammer_F",[15917.2,16255.9,0],64.0909,[[0.899488,0.436945,0],[0,0,1]],false], + ["Land_Wreck_Offroad_F",[15915.4,16266.2,0],266.364,[[-0.997987,-0.0634235,0],[-0,0,1]],false], + ["Land_Wreck_Car3_F",[15915.2,16272.9,0],262.727,[[-0.991955,-0.126592,0],[-0,0,1]],false], + ["Land_Wreck_Car2_F",[15914.7,16276,0],272.273,[[-0.999213,0.0396567,0],[0,0,1]],false], + ["Land_Wreck_CarDismantled_F",[15924.1,16269.8,0],83.6364,[[0.993838,0.110838,0],[0,0,1]],false], + ["Land_Wreck_Skodovka_F",[15914.7,16279.9,0],313.636,[[-0.723734,0.690079,0],[0,0,1]],false], + ["Land_Wreck_HMMWV_F",[15924,16279.1,0],65,[[0.906308,0.422618,0],[0,0,1]],false], + ["Land_Wreck_Van_F",[15930.9,16270.4,0],131.364,[[0.750531,-0.660835,0],[0,-0,1]],false], + ["Land_Wreck_Truck_dropside_F",[15924.3,16263.1,0],86.3636,[[0.997987,0.0634243,0],[0,0,1]],false], + ["Land_Wreck_Ural_F",[15925.4,16257.7,0],171.364,[[0.150163,-0.988661,0],[0,-0,1]],false], + ["Land_Wreck_UAZ_F",[15975.4,16226.9,0.148146],41.3637,[[0.660836,0.75053,0],[0,0,1]],false] +]; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/scripts/fn_AILocalityManager.sqf b/@ExileServer/addons/a3_dms/scripts/fn_AILocalityManager.sqf new file mode 100644 index 0000000..b2e8586 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_AILocalityManager.sqf @@ -0,0 +1,54 @@ +/* + DMS_fnc_AILocalityManager + Created by Defent and eraser1 + + https://github.com/Defent/DMS_Exile/wiki/DMS_fnc_AILocalityManager + + Offloads AI groups to a nearby client in order to improve server performance. +*/ + +if (!DMS_ai_offload_to_client) exitWith {}; + +{ + if (((count (units _x))>1) && {!(_x getVariable ["DMS_LockLocality",false])} && {!(DMS_ai_offload_Only_DMS_AI && {!(_x getVariable ["DMS_SpawnedGroup",false])})}) then + { + private _leader = leader _x; + private _group = _x; + if !(isPlayer _leader) then + { + // Ignore Exile flyovers. + if (((side _group) isEqualTo independent) && {(count (units _group)) isEqualTo 1}) exitWith {}; + + if (DMS_DEBUG) then + { + (format ["AILocalityManager :: Finding owner for group: %1",_group]) call DMS_fnc_DebugLog; + }; + + private _groupOwner = groupOwner _group; + private _ownerObj = objNull; + private _isLocal = local _group; + + if !(_isLocal) then // Only check for the group owner in players if it doesn't belong to the server. + { + { + if (_groupOwner isEqualTo (owner _x)) exitWith + { + _ownerObj = _x; + }; + } forEach allPlayers; + }; + + // If the owner doesn't exist or is too far away... Attempt to set a new player owner, and if none are found... and if the group doesn't belong to the server... + if (((isNull _ownerObj) || {(_ownerObj distance2D _leader)>3500}) && {!([_group,_leader] call DMS_fnc_SetAILocality)} && {!_isLocal}) then + { + // Reset locality to the server + _group setGroupOwner 2; + + if (DMS_DEBUG) then + { + (format ["AILocalityManager :: Current owner of group %1 is too far away and no other viable owner found; resetting ownership to the server.",_group]) call DMS_fnc_DebugLog; + }; + }; + }; + }; +} forEach allGroups; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_AddMissionToMonitor.sqf b/@ExileServer/addons/a3_dms/scripts/fn_AddMissionToMonitor.sqf new file mode 100644 index 0000000..c31c5f0 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_AddMissionToMonitor.sqf @@ -0,0 +1,212 @@ +/* + DMS_fnc_AddMissionToMonitor + Created by eraser1 + + https://github.com/Defent/DMS_Exile/wiki/DMS_fnc_AddMissionToMonitor + + Parses and adds mission information to "DMS_Mission_Arr" for Mission Monitoring. + + Usage: + [ + _position, + [ + [ + _completionType1, + _completionArgs1 + ], + [ + _completionType2, + _completionArgs3 + ], + ... + [ + _completionTypeN, + _completionArgsN + ], + ], + [ + _timeStarted, + _timeUntilFail + ], + [ + _AIUnitOrGroup1, + _AIUnitOrGroup2, + ..., + _AIUnitOrGroupN + ], + [ + [_cleanupObj1,_cleanupObj2,...,_cleanupObjX], + [_vehicle1,_vehicle2,...,_vehicleX], + [ + [_crate1,_crate_loot_values1], + [_crate2,_crate_loot_values2] + ] + ], + [_missionName,_msgWIN,_msgLose], + _markers, + _side, + _difficulty, + _missionEvents, + [ + _onSuccessScripts, // (OPTIONAL) Array of code or string to be executed on mission completion (in addition to regular code). Each element should be an array in the form [_params, _code]. + _onFailScripts, // (OPTIONAL) Array of code or string to be executed on mission failure (in addition to regular code). Each element should be an array in the form [_params, _code]. + _onMonitorStart, // (OPTIONAL) Code to run when the monitor starts to check the mission status. The passed parameter (_this) is the mission data array itself. + _onMonitorEnd // (OPTIONAL) Code to run when the monitor is done with checking the mission status. The passed parameter (_this) is the mission data array itself. + ] + ] call DMS_fnc_AddMissionToMonitor; + + Returns whether or not info was added successfully + +*/ + +private _added = false; + +if !(params +[ + "_pos", + "_completionInfo", + "_timeOutInfo", + "_units", + "_missionObjs", + "_messages", + "_markers", + "_side", + "_difficulty", + "_missionEvents" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_AddMissionToMonitor with invalid parameters: %1",_this]; + false; +}; + +private _onEndingScripts = if ((count _this)>10) then {_this select 10} else {[[],[],{},{}]}; + + +try +{ + if ((count _pos) isEqualTo 2) then + { + _pos set [2,0]; + }; + + if (_completionInfo isEqualTo []) then + { + throw "_completionInfo is empty!"; + }; + + _timeOutInfo params + [ + ["_timeStarted",diag_tickTime,[0]], + ["_timeUntilFail",DMS_MissionTimeOut call DMS_fnc_SelectRandomVal,[0]] + ]; + + if !(_missionObjs params + [ + ["_buildings","",[[]]], + ["_vehs","",[[]]], + ["_crate_info_array","",[[]]] + ]) + then + { + throw format["_missionObjs |%1|",_missionObjs]; + }; + + private _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 + { + _mines = [_pos, _difficulty, _side] call DMS_fnc_SpawnMinefield; + }; + + + + if !(_messages params + [ + ["_missionName","",[""]], + ["_msgWIN",[],[[]],[2]], + ["_msgLose",[],[[]],[2]] + ]) + then + { + throw format["_messages |%1|",_messages]; + }; + _msgWIN pushBack "win"; + _msgLose pushBack "lose"; + + + if !(_onEndingScripts params + [ + ["_onSuccessScripts", [], [[]]], + ["_onFailScripts", [], [[]]], + ["_onMonitorStart", {}, [{}]], + ["_onMonitorEnd", {}, [{}]] + ]) + then + { + throw format["_onEndingScripts |%1|",_onEndingScripts]; + }; + + private _unitCount = count (_units call DMS_fnc_GetAllUnits); + + private _arr = + [ + _pos, + _completionInfo, + [ + _timeStarted, + _timeUntilFail + ], + _units, + [ + _buildings, + _vehs, + _crate_info_array, + _mines + ], + [ + _missionName, + _msgWIN, + _msgLose + ], + _markers, + _side, + _difficulty, + _missionEvents, + [ + _onSuccessScripts, + _onFailScripts, + _onMonitorStart, + _onMonitorEnd + ], + _unitCount + ]; + DMS_Mission_Arr pushBack _arr; + _added = true; + + if (DMS_MarkerText_ShowAICount) then + { + private _markerDot = _markers select 0; + _markerDot setMarkerText (format ["%1 (%2 %3 remaining)",markerText _markerDot,_unitCount,DMS_MarkerText_AIName]); + }; + + if (DMS_DEBUG) then + { + (format ["AddMissionToMonitor :: Added |%1| to DMS_Mission_Arr!",_arr]) call DMS_fnc_DebugLog; + }; +} +catch +{ + diag_log format ["DMS ERROR :: Calling DMS_AddMissionToMonitor with invalid parameter: %1",_exception]; +}; + +_added diff --git a/@ExileServer/addons/a3_dms/scripts/fn_AddMissionToMonitor_Static.sqf b/@ExileServer/addons/a3_dms/scripts/fn_AddMissionToMonitor_Static.sqf new file mode 100644 index 0000000..254fe0b --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_AddMissionToMonitor_Static.sqf @@ -0,0 +1,215 @@ +/* + DMS_fnc_AddMissionToMonitor_Static + Created by eraser1 + + https://github.com/Defent/DMS_Exile/wiki/DMS_fnc_AddMissionToMonitor_Static + + Parses and adds mission information to "DMS_StaticMission_Arr" for Mission Monitoring. + + Usage: + [ + _position, + [ + [ + _completionType1, + _completionArgs1 + ], + [ + _completionType2, + _completionArgs3 + ], + ... + [ + _completionTypeN, + _completionArgsN + ], + ], + [ + _groupReinforcementsInfo1, + _groupReinforcementsInfo2, + ..., + _groupReinforcementsInfoN + ], + [ + _timeStarted, + _timeUntilFail + ], + [ + _AIUnitOrGroup1, + _AIUnitOrGroup2, + ..., + _AIUnitOrGroupN + ], + [ + [_cleanupObj1,_cleanupObj2,...,_cleanupObjX], + [_vehicle1,_vehicle2,...,_vehicleX], + [ + [_crate1,_crate_loot_values1], + [_crate2,_crate_loot_values2] + ] + ], + [ + _missionName, + _msgWIN, + _msgLose + ], + _markers, + _side, + _difficulty, + _missionEvents, + [ + _onSuccessScripts, // (OPTIONAL) Array of code or string to be executed on mission completion (in addition to regular code). Each element should be an array in the form [_params, _code]. + _onFailScripts, // (OPTIONAL) Array of code or string to be executed on mission failure (in addition to regular code). Each element should be an array in the form [_params, _code]. + _onMonitorStart, // (OPTIONAL) Code to run when the monitor starts to check the mission status. The passed parameter (_this) is the mission data array itself. + _onMonitorEnd // (OPTIONAL) Code to run when the monitor is done with checking the mission status. The passed parameter (_this) is the mission data array itself. + ] + ] call DMS_fnc_AddMissionToMonitor_Static; + + Returns whether or not info was added successfully + +*/ + +private _added = false; + +if !(params +[ + "_pos", + "_completionInfo", + "_groupReinforcementsInfo", + "_timeOutInfo", + "_units", + "_missionObjs", + "_messages", + "_markers", + "_side", + "_difficulty", + "_missionEvents" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_AddMissionToMonitor_Static with invalid parameters: %1",_this]; + false; +}; + +private _onEndingScripts = if ((count _this)>11) then {_this select 11} else {[[],[],{},{}]}; + + +try +{ + if ((count _pos) isEqualTo 2) then + { + _pos set [2,0]; + }; + + if (_completionInfo isEqualTo []) then + { + throw "_completionInfo is empty!"; + }; + + _timeOutInfo params + [ + ["_timeStarted",diag_tickTime,[0]], + ["_timeUntilFail",DMS_MissionTimeOut call DMS_fnc_SelectRandomVal,[0]] + ]; + + if !(_missionObjs params + [ + ["_buildings","",[[]]], + ["_vehs","",[[]]], + ["_crate_info_array","",[[]]] + ]) + then + { + throw format["_missionObjs |%1|",_missionObjs]; + }; + + private _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 + { + _mines = [_pos, _difficulty, _side] call DMS_fnc_SpawnMinefield; + }; + + + if !(_messages params + [ + ["_missionName","",[""]], + ["_msgWIN",[],[[]],[2]], + ["_msgLose",[],[[]],[2]] + ]) + then + { + throw format["_messages |%1|",_messages]; + }; + _msgWIN pushBack "win"; + _msgLose pushBack "lose"; + + + if !(_onEndingScripts params + [ + ["_onSuccessScripts", [], [[]]], + ["_onFailScripts", [], [[]]], + ["_onMonitorStart", {}, [{}]], + ["_onMonitorEnd", {}, [{}]] + ]) + then + { + throw format["_onEndingScripts |%1|",_onEndingScripts]; + }; + + private _unitCount = count (_units call DMS_fnc_GetAllUnits); + + private _arr = + [ + _pos, + _completionInfo, + _groupReinforcementsInfo, + [ + _timeStarted, + _timeUntilFail + ], + _units, + [ + _buildings, + _vehs, + _crate_info_array, + _mines + ], + [ + _missionName, + _msgWIN, + _msgLose + ], + _markers, + _side, + _difficulty, + _missionEvents, + [ + _onSuccessScripts, + _onFailScripts, + _onMonitorStart, + _onMonitorEnd + ], + _unitCount + ]; + DMS_StaticMission_Arr pushBack _arr; + _added = true; + + if (DMS_MarkerText_ShowAICount_Static) then + { + private _markerDot = _markers select 0; + _markerDot setMarkerText (format ["%1 (%2 %3 remaining)",markerText _markerDot,_unitCount,DMS_MarkerText_AIName]); + }; + + if (DMS_DEBUG) then + { + (format ["AddMissionToMonitor_Static :: Added |%1| to DMS_StaticMission_Arr!",_arr]) call DMS_fnc_DebugLog; + }; +} +catch +{ + diag_log format ["DMS ERROR :: Calling DMS_AddMissionToMonitor_Static with invalid parameter: %1",_exception]; +}; + +_added diff --git a/@ExileServer/addons/a3_dms/scripts/fn_AddWeapon.sqf b/@ExileServer/addons/a3_dms/scripts/fn_AddWeapon.sqf new file mode 100644 index 0000000..9da4aa7 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_AddWeapon.sqf @@ -0,0 +1,54 @@ +/* + DMS_fnc_AddWeapon + created by eraser1 - based off of BIS_fnc_AddWeapon + + https://github.com/Defent/DMS_Exile/wiki/DMS_fnc_AddWeapon + + Description: + Add a weapon to a unit with the right magazines. Magazine class is obtained from the weapon's config. + + Usage: + [ + _unit, // The unit that is to receive the weapon (and magazines). + _weapon, // The classname of the weapon to be added. + _magazineCount, // Number of magazines to be added. + _magClassname // (Optional) The classname of the magazine to be added. + ] call DMS_fnc_AddWeapon; + + Nothing is returned +*/ + +if (params +[ + "_unit", + "_weapon", + "_magazineCount" +]) +then +{ + //Add magazines + if (_magazineCount > 0) then + { + private _magazine = + if ((count _this) > 3) then + { + _this select 3 + } + else + { + _weapon call DMS_fnc_selectMagazine + }; + + for "_i" from 1 to _magazineCount do + { + _unit addMagazine _magazine; + }; + }; + + //Add weapon + _unit addWeapon _weapon; +} +else +{ + diag_log format["DMS ERROR :: Calling DMS_fnc_AddWeapon with invalid parameters: %1",_this]; +}; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_BroadcastMissionStatus.sqf b/@ExileServer/addons/a3_dms/scripts/fn_BroadcastMissionStatus.sqf new file mode 100644 index 0000000..7540687 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_BroadcastMissionStatus.sqf @@ -0,0 +1,146 @@ +/* + DMS_fnc_BroadcastMissionStatus + Created by eraser1 + + https://github.com/Defent/DMS_Exile/wiki/DMS_fnc_BroadcastMissionStatus + + Usage: + [ + _messageTitle, // The title of the message + [ + _titleColor, // The color of the message (in hex colors) + _message, // The actual message. Usually a string. + _status // (OPTIONAL) The mission status. eg "win" or "lose". Currently only used on Exile Toasts. + ] + ] call DMS_fnc_BroadcastMissionStatus; + + Returns nothing +*/ + +if !(params +[ + "_messageTitle", + "_messageInfo" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_BroadcastMissionStatus with invalid parameters: %1",_this]; +}; + +_messageInfo params +[ + "_titleColor", + "_message" +]; + +if (DMS_DEBUG) then +{ + (format["BroadcastMissionStatus :: Notification types: |%1| for broadcasting mission status: %2",DMS_PlayerNotificationTypes,_message]) call DMS_fnc_DebugLog; +}; + +if !(_message isEqualType "") then +{ + _message = str _message; +}; + +private _status = + if ((count _messageInfo)>2) then + { + _messageInfo select 2 + } + else + { + "start" + }; + +{ + switch (toLower _x) do + { + case "systemchatrequest": + { + format["%1: %2",toUpper _messageTitle,_message] remoteExecCall ["systemChat",-2]; + }; + + case "exiletoasts": + { + private _toast_type = + switch (_status) do + { + case "win": {"SuccessEmpty"}; + case "lose": {"ErrorEmpty"}; + default {"InfoEmpty"}; // case "start": + }; + + [ + "toastRequest", + [ + _toast_type, + [ + format + [ + "%4
%8", + _titleColor, + DMS_ExileToasts_Title_Size, + DMS_ExileToasts_Title_Font, + _messageTitle, + DMS_ExileToasts_Message_Color, + DMS_ExileToasts_Message_Size, + DMS_ExileToasts_Message_Font, + _message + ] + ] + ] + ] call ExileServer_system_network_send_broadcast; + }; + + case "standardhintrequest": + { + format + [ + "%4
%8", + _titleColor, + DMS_standardHint_Title_Size, + DMS_standardHint_Title_Font, + _messageTitle, + DMS_standardHint_Message_Color, + DMS_standardHint_Message_Size, + DMS_standardHint_Message_Font, + _message + ] remoteExecCall ["DMS_CLIENT_fnc_hintSilent",-2]; + }; + + case "dynamictextrequest": + { + (format + [ + "%4
%8", + _titleColor, + DMS_dynamicText_Title_Size, + DMS_dynamicText_Title_Font, + _messageTitle, + DMS_dynamicText_Message_Color, + DMS_dynamicText_Message_Size, + DMS_dynamicText_Message_Font, + _message + ]) remoteExecCall ["DMS_CLIENT_fnc_spawnDynamicText", -2]; + }; + + case "texttilesrequest": + { + (format + [ + "%4
%8", + _titleColor, + DMS_textTiles_Title_Size, + DMS_textTiles_Title_Font, + _messageTitle, + DMS_textTiles_Message_Color, + DMS_textTiles_Message_Size, + DMS_textTiles_Message_Font, + _message + ]) remoteExecCall ["DMS_CLIENT_fnc_spawnTextTiles", -2]; + }; + + default { diag_log format ["DMS ERROR :: Unsupported Notification Type in DMS_PlayerNotificationTypes: %1 | Calling parameters: %2",_x,_this]; }; + }; +} forEach DMS_PlayerNotificationTypes; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_CalcPos.sqf b/@ExileServer/addons/a3_dms/scripts/fn_CalcPos.sqf new file mode 100644 index 0000000..4926758 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_CalcPos.sqf @@ -0,0 +1,47 @@ +/* + DMS_fnc_CalcPos + Created by eraser1 + + https://github.com/Defent/DMS_Exile/wiki/DMS_fnc_CalcPos + + Usage: + [ + _positionOrObject, // Object or Position: The center + _relativePosition // Array: The offset + ] call DMS_fnc_CalcPos; + + Returns the absolute position from the provided relative position from the provided center position or object. +*/ + +if !(params +[ + "_pos", + "_relPos" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_CalcPos with invalid parameters: %1",_this]; +}; + + +// Get the position if an object was supplied instead of position +if (_pos isEqualType objNull) then +{ + _pos = getPosATL _pos; +}; + +// Set the center pos to 0 if it isn't defined +if ((count _pos)<3) then +{ + _pos set [2,0]; +}; + + +// Set the z-pos offset to 0 if it isn't defined +if ((count _relPos)<3) then +{ + _relPos set [2,0]; +}; + +// Script command "vectorAdd" is much faster than adding each element manually. +_pos vectorAdd _relPos diff --git a/@ExileServer/addons/a3_dms/scripts/fn_CleanUp.sqf b/@ExileServer/addons/a3_dms/scripts/fn_CleanUp.sqf new file mode 100644 index 0000000..af0b6d3 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_CleanUp.sqf @@ -0,0 +1,93 @@ +/* + DMS_fnc_CleanUp + Created by eraser1 + + Usage: + [ + _objectOrGroup1, + _objectOrGroup2, + ... + _objectOrGroupN + ] call DMS_fnc_CleanUp; + + Alternative Usage: + _objectOrGroup call DMS_fnc_CleanUp; +*/ + +if (DMS_DEBUG) then +{ + (format ["CleanUp :: CLEANING UP: %1",_this]) call DMS_fnc_DebugLog; +}; + +if !(_this isEqualType []) then +{ + _this = [_this]; +}; + + +private _skippedObjects = []; +{ + private _parameter = _x; + + switch (typeName _parameter) do + { + case "ARRAY": + { + if (DMS_DEBUG) then + { + (format ["CleanUp :: Doing recursive call for ARRAY: %1",_parameter]) call DMS_fnc_DebugLog; + }; + _parameter call DMS_fnc_CleanUp; + }; + + case "OBJECT": + { + if (isNull _parameter) exitWith {}; + + if !([_parameter,DMS_CleanUp_PlayerNearLimit] call DMS_fnc_IsPlayerNearby) then + { + _parameter call ExileServer_system_garbageCollector_deleteObject; + } + else + { + _skippedObjects pushBack _parameter; + if (DMS_DEBUG) then + { + (format ["CleanUp :: Skipping cleanup for |%1|, player within %2 meters!",_parameter,DMS_CleanUp_PlayerNearLimit]) call DMS_fnc_DebugLog; + }; + }; + }; + + case "GROUP": + { + if (isNull _parameter) exitWith {}; + + // Group cleanup should only be called when it has to be deleted regardless of player presence, so no need to check for nearby players + // If you want to check player presence before deleting a group, then do {(units _group) call DMS_fnc_CleanUp} instead of {_group call DMS_fnc_CleanUp} + { + _x call ExileServer_system_garbageCollector_deleteObject; + } forEach (units _parameter); + + if (local _parameter) then + { + deleteGroup _parameter; + } + else + { + [groupOwner _parameter, "DeleteGroupPlz", [_parameter]] call ExileServer_system_network_send_to; + }; + }; + + default + { + diag_log format ["DMS ERROR :: Calling DMS_fnc_CleanUp with an invalid parameter: %1 | Type: %2", _parameter, typeName _parameter]; + [] + }; + }; +} forEach _this; + + +if !(_skippedObjects isEqualTo []) then +{ + DMS_CleanUpList pushBack [_skippedObjects,diag_tickTime,30]; +}; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_CleanUpManager.sqf b/@ExileServer/addons/a3_dms/scripts/fn_CleanUpManager.sqf new file mode 100644 index 0000000..9c2578f --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_CleanUpManager.sqf @@ -0,0 +1,51 @@ +/* + DMS_fnc_CleanUpManager + Created by eraser1 + + Objects to be cleaned up together have an entry in "DMS_CleanUpList" + The list is formatted as: + [ + [ + _objectToClean1, + _objectToClean2, + ... + _objectToCleanN + ], + _timeAddedToList, + _timeUntilClean + ] + + A single object can also be used for (_this select 0) +*/ + +{ + if (DMS_DEBUG) then + { + (format ["CleanUpManager :: Checking Cleaning Status for: %1",_x]) call DMS_fnc_DebugLog; + }; + + + if !(_x params + [ + "_objs", + "_timeAddedToList", + "_timeUntilClean" + ]) + then + { + diag_log format ["DMS ERROR :: Invalid parameters for DMS_fnc_CleanUpManager: %1 replaced with %2",_x,[_objs,_timeAddedToList,_timeUntilClean]]; + }; + + if ((diag_tickTime-_timeAddedToList)>=_timeUntilClean) then + { + _objs call DMS_fnc_CleanUp; + DMS_CleanUpList deleteAt _forEachIndex; + } + else + { + if (DMS_DEBUG) then + { + (format ["CleanUpManager :: %1 is not yet ready to clean!",_x]) call DMS_fnc_DebugLog; + }; + }; +} forEach DMS_CleanUpList; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_CreateMarker.sqf b/@ExileServer/addons/a3_dms/scripts/fn_CreateMarker.sqf new file mode 100644 index 0000000..7db1370 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_CreateMarker.sqf @@ -0,0 +1,133 @@ +/* + DMS_fnc_CreateMarker + Created by Defent and eraser1 + + Usage: + [ + _pos, // Array: Position of the markers + _text, // String: The text on the map marker that will appear on the map + _difficulty, // (OPTIONAL) String: "hardcore","difficult","moderate", "easy", OR custom color + _randomMarker // (OPTIONAL) Boolean: Whether or not to place the map marker on a random offset from mission, defined by DMS_MarkerPosRandomRadius + ] call DMS_fnc_CreateMarker; + + Returns markers in format: + [ + _markerDot, + _markerCircle + ] + +*/ + +params +[ + ["_pos","ERROR",[[]],[2,3]], + ["_text","ERROR",[""]], + ["_difficulty","moderate",[""]] +]; + +if ((_pos isEqualTo "ERROR") || ("_text" isEqualTo "ERROR")) exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_CreateMarker with invalid parameters: %1",_this]; + + []; +}; + + +private _randomMarker = + if ((count _this)>3) then + { + _this select 3; + } + else + { + DMS_MarkerPosRandomization; + }; + +private _num = DMS_MissionCount; + + +private _markerType = "mil_dot"; + +private _color = + switch (toLower _difficulty) do + { + case "easy": + { + _markerType = "ExileMissionEasyIcon"; + "ColorGreen" + }; + case "moderate": + { + _markerType = "ExileMissionModerateIcon"; + "ColorYellow" + }; + case "difficult": + { + _markerType = "ExileMissionDifficultIcon"; + "ColorRed" + }; + case "hardcore": + { + _markerType = "ExileMissionHardcoreIcon"; + "ColorBlack" + }; + + default + { + _difficulty + }; + }; + +/* +// Don't think this is really needed, ArmA gives you an error anyways. +if !((toLower _color) in DMS_A3_AllMarkerColors) then +{ + diag_log format ["DMS ERROR :: Color ""%1"" is not a valid marker color! Switching to ""ColorRed""",_color]; + _color = "ColorRed"; +}; +*/ + +private _circle = createMarker [format ["DMS_MissionMarkerCircle%1_%2",_num,round(time)], _pos]; + +if (DMS_ShowMarkerCircle) then +{ + _circle setMarkerColor _color; + _circle setMarkerShape "ELLIPSE"; + _circle setMarkerBrush "Solid"; + _circle setMarkerSize [150,150]; +}; + +private _dot = createMarker [format ["DMS_MissionMarkerDot%1_%2",_num,round(time)], _pos]; +_dot setMarkerType _markerType; +_dot setMarkerText _text; + +missionNamespace setVariable [format ["%1_pos",_dot], _pos]; +missionNamespace setVariable [format ["%1_text",_dot], _text]; + +if (DMS_MarkerText_ShowMissionPrefix) then +{ + _dot setMarkerText (format ["%1 %2",DMS_MarkerText_MissionPrefix,_text]); +}; + +if (_randomMarker) then +{ + private _dis = DMS_MarkerPosRandomRadius call DMS_fnc_SelectRandomVal; + private _npos = _pos getPos [_dis,random 360]; + + _circle setMarkerPos _npos; + _dot setMarkerPos _npos; + _circle setMarkerBrush DMS_RandomMarkerBrush; + + if (DMS_DEBUG) then + { + (format ["CreateMarker :: Moving markers %1 from %2 to %3 (%4m away)",[_dot,_circle],_pos,_npos,_dis]) call DMS_fnc_DebugLog; + }; +}; + +if (DMS_DEBUG) then +{ + (format ["CreateMarker :: Created markers |%1| at %2 with text |%3| colored %4",[_dot,_circle],_pos,_text,_color]) call DMS_fnc_DebugLog; +}; + + +[_dot,_circle]; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_DebugLog.sqf b/@ExileServer/addons/a3_dms/scripts/fn_DebugLog.sqf new file mode 100644 index 0000000..3a16641 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_DebugLog.sqf @@ -0,0 +1,23 @@ +/* + DMS_fnc_DebugLog + Created by eraser1 + + Usage: + _anyValue call DMS_fnc_DebugLog; + + This function will write the passed parameter as well as server updtime and FPS to RPT. + If you have infiSTAR's DLLs, then it will also utilize the "ARMA_LOG" dll to write debug info. +*/ + +_this = format ['%1 |::|::| (DMS_Version: "%4" | time: %2 | diag_tickTime: %5 | %3 FPS)',_this,time,diag_fps,DMS_Version,diag_tickTime]; +diag_log format ["DMS_DEBUG :: %1",_this]; + +if (!isNil "FNC_A3_CUSTOMLOG") then // infiSTAR logging +{ + ['DMS_DEBUG',_this] call FNC_A3_CUSTOMLOG; +}; + +if (!isNil "MAR_fnc_log") then // mARMA logging +{ + [_this,"info"] call MAR_fnc_log; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/scripts/fn_FillCrate.sqf b/@ExileServer/addons/a3_dms/scripts/fn_FillCrate.sqf new file mode 100644 index 0000000..a46889c --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_FillCrate.sqf @@ -0,0 +1,319 @@ +/* + DMS_fnc_FillCrate + + Inspired by WAI: https://github.com/nerdalertdk/WICKED-AI + created by eraser1 + + Usage: + [ + _crate, // OBJECT: The crate object + _lootValues, // ARRAY, STRING, or NUMBER: String or number refers to a crate case in config.cfg; array determines random crate weapons/items/backpacks + _rareLootChance // (OPTIONAL) NUMBER: Manually define the percentage chance of spawning some rare items. + ] call DMS_fnc_FillCrate; + + If the "_lootValues" parameter is a number or a string, the function will look for a value defined as "DMS_CrateCase_*", where the "*" is replaced by the "_lootValues" parameter. EG: DMS_CrateCase_Sniper. + + Otherwise, the "_lootValues" parameter must be defined as: + [ + _weapons, + _items, + _backpacks + ] + + Each loot argument can be an explicitly defined array of weapons with a number to spawn, or simply a number and weapons defined in the config.sqf are used. + For example, if you want to configure the list from which weapons, items, and backpacks are selected, it should be of the form: + [ + [ + _number_of_weapons, + [ + "wepClassname1", + "wepClassname2", + ... + "wepClassnameN" + ] + ], + [ + _number_of_items, + [ + "itemClassname1", + "itemClassname2", + ... + "itemClassnameN" + ] + ], + [ + _number_of_backpacks, + [ + "backpackClassname1", + "backpackClassname2", + ... + "backpackClassnameN" + ] + ] + ] + + For example, _weapons could simply be a number, in which case the given number of weapons are selected from "DMS_boxWeapons", + or an array as [_wepCount,_weps], where _wepCount is the number of weapons, and _weps is an array of weapons from which the guns are randomly selected. + + OR: + [ + _customLootFunctionParams, + _customLootFunction + ] + In this case, "_customLootFunctionParams" is passed to "_customLootFunction", and the custom loot function must return the loot in the form: + [ + [ + weapon1, + weapon2, + [weapon_that_appears_twice,2], + ... + weaponN + ], + [ + item1, + item2, + [item_that_appears_5_times,5], + ... + itemN + ], + [ + backpack1, + backpack2, + [backpack_that_appears_3_times,3], + ... + backpackN + ] + ] +*/ + +if (!(params +[ + "_crate", + "_lootValues" +]) +|| +{isNull _crate}) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_FillCrate with invalid parameters: %1",_this]; +}; + +_crate hideObjectGlobal false; + +if !(_crate getVariable ["DMS_CrateGodMode",DMS_GodmodeCrates]) then +{ + _crate allowDamage true; +}; +if (_crate getVariable ["DMS_CrateEnableRope",DMS_EnableBoxMoving]) then +{ + _crate enableRopeAttach true; +}; + +_crate enableSimulationGlobal true; + + +if ((_lootValues isEqualType []) && {!((_lootValues select 1) isEqualType {})}) then +{ + // Weapons + private _wepValues = _lootValues select 0; + private _wepCount = 0; + private _weps = + if (_wepValues isEqualType []) then + { + _wepCount = _wepValues select 0; + _wepValues select 1 + } + else + { + _wepCount = _wepValues; + DMS_boxWeapons + }; + + + // Items + private _itemValues = _lootValues select 1; + private _itemCount = 0; + private _items = + if (_itemValues isEqualType []) then + { + _itemCount = _itemValues select 0; + _itemValues select 1 + } + else + { + _itemCount = _itemValues; + DMS_boxItems + }; + + + // Backpacks + private _backpackValues = _lootValues select 2; + private _backpackCount = 0; + private _backpacks = + if (_backpackValues isEqualType []) then + { + _backpackCount = _backpackValues select 0; + _backpackValues select 1 + } + else + { + _backpackCount = _backpackValues; + DMS_boxBackpacks + }; + + if (DMS_DEBUG) then + { + (format["FillCrate :: Filling %4 with %1 guns, %2 items and %3 backpacks",_wepCount,_itemCount,_backpackCount,_crate]) call DMS_fnc_DebugLog; + }; + + + if (count _weps>0) then + { + // Add weapons + mags + for "_i" from 1 to _wepCount do + { + private _weapon = selectRandom _weps; + private _ammo = _weapon call DMS_fnc_selectMagazine; + if (_weapon isEqualType "") then + { + _weapon = [_weapon,1]; + }; + _crate addWeaponCargoGlobal _weapon; + if !(_ammo in ["Exile_Magazine_Swing","Exile_Magazine_Boing","Exile_Magazine_Swoosh"]) then + { + _crate addItemCargoGlobal [_ammo, (DMS_MinimumMagCount + floor(random DMS_MagRange))]; + }; + }; + }; + + + if (count _items>0) then + { + // Add items + for "_i" from 1 to _itemCount do + { + private _item = selectRandom _items; + if (_item isEqualType "") then + { + _item = [_item,1]; + }; + _crate addItemCargoGlobal _item; + }; + }; + + + if (count _backpacks>0) then + { + // Add backpacks + for "_i" from 1 to _backpackCount do + { + private _backpack = selectRandom _backpacks; + if (_backpack isEqualType "") then + { + _backpack = [_backpack,1]; + }; + _crate addBackpackCargoGlobal _backpack; + }; + }; +} +else +{ + private _crateValues = + if (_lootValues isEqualType []) then + { + (_lootValues select 0) call (_lootValues select 1) + } + else + { + missionNamespace getVariable (format ["DMS_CrateCase_%1",_lootValues]) + }; + + if !((_crateValues params + [ + "_weps", + "_items", + "_backpacks" + ])) + exitWith + { + diag_log format ["DMS ERROR :: Invalid ""_crateValues"" (%1) generated from _lootValues: %2",_crateValues,_lootValues]; + }; + + // Weapons + { + if (_x isEqualType "") then + { + _x = [_x,1]; + }; + _crate addWeaponCargoGlobal _x; + } forEach _weps; + + // Items/Mags + { + if (_x isEqualType "") then + { + _x = [_x,1]; + }; + _crate addItemCargoGlobal _x; + } forEach _items; + + // Backpacks + { + if (_x isEqualType "") then + { + _x = [_x,1]; + }; + _crate addBackpackCargoGlobal _x; + } forEach _backpacks; + + if (DMS_DEBUG) then + { + (format["FillCrate :: Filled crate %1 (at %5) with weapons |%2|, items |%3|, and backpacks |%4|",_crate, _weps, _items, _backpacks, getPosATL _crate]) call DMS_fnc_DebugLog; + }; +}; + + +if (DMS_RareLoot) then +{ + private _rareLootChance = + if ((count _this)>2) then + { + _this param [2,DMS_RareLootChance,[0]] + } + else + { + DMS_RareLootChance + }; + + // (Maybe) Add rare loot + if(random 100 < _rareLootChance) then + { + for "_i" from 1 to DMS_RareLootAmount do + { + _item = selectRandom DMS_RareLootList; + if (_item isEqualType "") then + { + _item = [_item,1]; + }; + _crate addItemCargoGlobal _item; + }; + }; +}; + +// You can choose if you want to enable/disable smoke individually using setVariable. +if (_crate getVariable ["DMS_AllowSmoke", true]) then +{ + if (DMS_SpawnBoxSmoke && {sunOrMoon isEqualTo 1}) then + { + private _marker = (_crate getVariable ["DMS_CrateSmokeClassname", DMS_DefaultSmokeClassname]) createVehicle getPosATL _crate; + _marker setPosATL (getPosATL _crate); + _marker attachTo [_crate,[0,0,0]]; + }; + + if (DMS_SpawnBoxIRGrenade && {sunOrMoon != 1}) then + { + private _marker = "B_IRStrobe" createVehicle getPosATL _crate; + _marker setPosATL (getPosATL _crate); + _marker attachTo [_crate, [0,0,0.5]]; + }; +}; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_FindSafePos.sqf b/@ExileServer/addons/a3_dms/scripts/fn_FindSafePos.sqf new file mode 100644 index 0000000..89f54bf --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_FindSafePos.sqf @@ -0,0 +1,116 @@ +/* + 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. + + Usage: + [ + _nearestObjectMinDistance, // NUMBER (distance): Minimum distance from the nearest object. + _waterNearLimit, // NUMBER (distance): Minimum distance from water. + _minSurfaceNormal, // NUMBER (between 0-1): Maximum "surfaceNormal"; Basically determines how steep a position is. Check the comment for config value "DMS_MinSurfaceNormal" in config.sqf for more info + _spawnZoneNearLimit, // NUMBER (distance): Minimum distance from a spawn point. + _traderZoneNearLimit, // NUMBER (distance): Minimum distance from a trader zone. + _missionNearLimit, // NUMBER (distance): Minimum distance from another mission. + _playerNearLimit, // NUMBER (distance): Minimum distance from a player. + _territoryNearLimit, // NUMBER (distance): Minimum distance from a territory. + _throttleParams // BOOLEAN: Whether or not some of the distance values should be throttled on repeated attempts. + ] call DMS_fnc_findSafePos; +*/ +#define MAX_ATTEMPTS 5000 + +params +[ + ["_nearestObjectMinDistance", 5, [0] ], + ["_waterNearLimit", DMS_WaterNearBlacklist, [0] ], + ["_minSurfaceNormal", DMS_MinSurfaceNormal, [0] ], + ["_spawnZoneNearLimit", DMS_SpawnZoneNearBlacklist, [0] ], + ["_traderZoneNearLimit", DMS_TraderZoneNearBlacklist,[0] ], + ["_missionNearLimit", DMS_MissionNearBlacklist, [0] ], + ["_playerNearLimit", DMS_PlayerNearBlacklist, [0] ], + ["_territoryNearLimit", DMS_TerritoryNearBlacklist, [0] ], + ["_throttleParams", DMS_ThrottleBlacklists, [true]] +]; + +/* +if (!isNil "DMS_DebugMarkers") then +{ + {deleteMarker _x} forEach DMS_DebugMarkers; +}; +DMS_DebugMarkers = []; +*/ + +private _isValidSpot = false; + +private _presetLocs = []; +private _presetLocsLength = 0; + +if (DMS_UsePredefinedMissionLocations) then +{ + // Shuffle the array so that the positions are selected in random order + _presetLocs = DMS_PredefinedMissionLocations call ExileClient_util_array_shuffle; + _presetLocsLength = count _presetLocs; +}; + + +private _pos = []; + +for "_attempts" from 1 to MAX_ATTEMPTS do +{ + _pos = + if (DMS_UsePredefinedMissionLocations && {_attempts<=_presetLocsLength}) then + { + _presetLocs select (_attempts - 1) + } + else + { + [DMS_MinMax_X_Coords call DMS_fnc_SelectRandomVal,DMS_MinMax_Y_Coords call DMS_fnc_SelectRandomVal] isFlatEmpty [_nearestObjectMinDistance, -1, -1, 1, -1, false, objNull] + }; + + /* + _dot = createMarker [format ["DMS_DebugMarker_attempt%1", _attempts], _pos]; + _dot setMarkerColor "ColorWEST"; + _dot setMarkerType "mil_dot"; + _dot setMarkerText format["Attempt #%1",_attempts]; + DMS_DebugMarkers pushBack _dot; + */ + + + // It will only throttle the missionNear blacklist and playerNear limits because those are the most likely to throw an exception. + // The throttling works by decreasing the parameters by 10% every 15 attempts, until it reaches 100 meters (by default). + if (_throttleParams && {(_attempts>=DMS_AttemptsUntilThrottle) && {(_attempts%DMS_AttemptsUntilThrottle)==0}}) then + { + _missionNearLimit = (DMS_ThrottleCoefficient * _missionNearLimit) max DMS_MinThrottledDistance; + _playerNearLimit = (DMS_ThrottleCoefficient * _playerNearLimit) max DMS_MinThrottledDistance; + + // SurfaceNormal is a bit more tricky than distances, so it's throttled differently. To convert from degrees to surfaceNormal, you take the cosine of the degrees from horizontal. Take the arc-cosine to convert surfaceNormal to degrees: arccos(0.8) in degrees ~= 37 + _minSurfaceNormal = (_minSurfaceNormal - 0.005) max 0.75; + + if (DMS_DEBUG) then + { + (format ["FindSafePos :: Throttling _missionNearLimit to %1 and _playerNearLimit to %2 and _minSurfaceNormal to %4 after %3 failed attempts to find a safe position!",_missionNearLimit,_playerNearLimit,_attempts,_minSurfaceNormal]) call DMS_fnc_DebugLog; + }; + }; + + _isValidSpot = [_pos, _waterNearLimit, _minSurfaceNormal, _spawnZoneNearLimit, _traderZoneNearLimit, _missionNearLimit, _playerNearLimit, _territoryNearLimit, DMS_MixerNearBlacklist, DMS_ContaminatedZoneNearBlacklist] call DMS_fnc_IsValidPosition; + + if (_isValidSpot) exitWith + { + if (DMS_DEBUG) then + { + (format["FindSafePos :: Found mission position %1 in %2 attempts. _this: %3",_pos,_attempts,_this]) call DMS_fnc_DebugLog; + }; + }; +}; + +if !(_isValidSpot) exitWith +{ + diag_log format["DMS ERROR :: Number of attempts in DMS_fnc_findSafePos (%1) reached maximum number of attempts!",MAX_ATTEMPTS]; +}; + +_pos set [2,0]; + + +_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..9f6f95c --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_FindSafePos_InRange.sqf @@ -0,0 +1,75 @@ +/* + 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. +*/ + +if !(params +[ + "_centerPos", + "_distanceMin", + "_distanceMax", + "_posParameters" +]) +exitWith +{ + diag_log format["DMS ERROR :: Calling DMS_fnc_FindSafePos_InRange with invalid parameters: %1",_this]; + [] +}; + +// Save the original values +private _original_x = DMS_MinMax_X_Coords; +private _original_y = DMS_MinMax_Y_Coords; +private _original_Blacklist = DMS_findSafePosBlacklist; + +// Get the center values +private _center_x = _centerPos select 0; +private _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 + { + [] + }; + +private _usePresetOriginal = DMS_UsePredefinedMissionLocations; +DMS_UsePredefinedMissionLocations = false; + +// NOW we get the position (hopefully) +private _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; +DMS_UsePredefinedMissionLocations = _usePresetOriginal; + +_pos diff --git a/@ExileServer/addons/a3_dms/scripts/fn_FindSuppressor.sqf b/@ExileServer/addons/a3_dms/scripts/fn_FindSuppressor.sqf new file mode 100644 index 0000000..644b1e9 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_FindSuppressor.sqf @@ -0,0 +1,20 @@ +/* + DMS_fnc_FindSuppressor + Originally from WAI + Modified by eraser1 & Defent + + Usage: + _weaponClassName call DMS_fnc_FindSuppressor; + +*/ + +private _compatibleMuzzles = getArray (configfile >> "CfgWeapons" >> _this >> "WeaponSlotsInfo" >> "MuzzleSlot" >> "compatibleItems"); + +if (_compatibleMuzzles isEqualTo []) then +{ + "" // Return an empty string if there are no compatible muzzles/suppressors +} +else +{ + selectRandom _compatibleMuzzles // Choose a random muzzle/suppressor (this is actually faster than selecting the first one) +}; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_FreezeManager.sqf b/@ExileServer/addons/a3_dms/scripts/fn_FreezeManager.sqf new file mode 100644 index 0000000..e4f2bbe --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_FreezeManager.sqf @@ -0,0 +1,98 @@ +/* + DMS_fnc_FreezeManager + Created by eraser1 + + Determines which AI groups (if any) to "freeze" in order to improve server performance, and will "un-freeze" frozen AI when a player is nearby. + This function will also offload AI after "un-freezing" if configured to do so. + + NOTE: If you want this function to ignore a specific group, then you can set the variable "DMS_AllowFreezing" on the group to false. + eg: _group setVariable ["DMS_AllowFreezing",false] +*/ + +{ + private _leader = leader _x; + private _units = units _x; + + + if (_x getVariable ["DMS_isGroupFrozen",false]) then + { + if ([_leader,DMS_ai_unfreezingDistance] call DMS_fnc_IsPlayerNearby) then + { + { + _x enableSimulationGlobal true; + (vehicle _x) enableSimulationGlobal true; + } forEach _units; + + _x setVariable ["DMS_isGroupFrozen",false]; + + + if (DMS_ai_offloadOnUnfreeze) then + { + [_x, _leader] call DMS_fnc_SetAILocality; + }; + + + if (DMS_DEBUG) then + { + format["FreezeManager :: Un-froze AI Group: %1",_x] call DMS_fnc_DebugLog; + }; + }; + } + else + { + if (DMS_ai_allowFreezing) then + { + private _canFreeze = false; + + try + { + if !(_x getVariable ["DMS_AllowFreezing",true]) throw "not allowed to be frozen"; + + if ((side _x) isEqualTo independent) then + { + { + if (isPlayer _x) throw "player group"; + } forEach _units; + + + if ((count _units) isEqualTo 1) throw "Exile flyover (probably)"; + }; + + if (DMS_ai_freeze_Only_DMS_AI && {!(_x getVariable ["DMS_SpawnedGroup",false])}) throw "not a DMS-spawned group"; + + _canFreeze = true; + } + catch + { + // Mark the group to speed up future checks + _x setVariable ["DMS_AllowFreezing",false]; + + if (DMS_DEBUG) then + { + format["FreezeManager :: Cannot freeze group ""%1"": %2", _x, _exception] call DMS_fnc_DebugLog; + }; + }; + + + + if (_canFreeze) then + { + if !([_leader,DMS_ai_freezingDistance] call DMS_fnc_IsPlayerNearby) then + { + { + _x enableSimulationGlobal false; + (vehicle _x) enableSimulationGlobal false; + } forEach _units; + + _x setVariable ["DMS_isGroupFrozen",true]; + + + if (DMS_DEBUG) then + { + format["FreezeManager :: Froze AI Group: %1",_x] call DMS_fnc_DebugLog; + }; + }; + }; + }; + }; +} forEach allGroups; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_FreezeToggle.sqf b/@ExileServer/addons/a3_dms/scripts/fn_FreezeToggle.sqf new file mode 100644 index 0000000..5cc6377 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_FreezeToggle.sqf @@ -0,0 +1,40 @@ +/* + DMS_fnc_FreezeToggle + created by eraser1 + + Usage: + [ + _group, // GROUP: The AI Group to be frozen + _freeze // BOOL: "true" if you want to freeze, false if you want to un-freeze + ] call DMS_fnc_FreezeToggle; + + Freezes/un-freezes a specified group. +*/ + +if !(params +[ + "_group", + "_freeze" +]) exitWith +{ + diag_log format["DMS ERROR :: Calling DMS_fnc_FreezeToggle with invalid parameters: %1",_this]; +}; + +if (_freeze) then +{ + { + _x enableSimulationGlobal false; + (vehicle _x) enableSimulationGlobal false; + } forEach (units _group); + + _group setVariable ["DMS_isGroupFrozen",true]; +} +else +{ + { + _x enableSimulationGlobal true; + (vehicle _x) enableSimulationGlobal true; + } forEach (units _group); + + _group setVariable ["DMS_isGroupFrozen",false]; +}; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_GetAllUnits.sqf b/@ExileServer/addons/a3_dms/scripts/fn_GetAllUnits.sqf new file mode 100644 index 0000000..61b648a --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_GetAllUnits.sqf @@ -0,0 +1,64 @@ +/* + DMS_fnc_GetAllUnits + Created by eraser1 + + + Usage: + [ + _unitOrGroupOrArray1, + _unitOrGroupOrArray2, + ... + _unitOrGroupOrArrayN + ] call DMS_fnc_GetAllUnits; + + Returns all living units from a given array of groups or objects. +*/ + +if !(_this isEqualType []) then +{ + _this = [_this]; +}; + +private _units = []; + +{ + private _parameter = _x; + + _units append + ( + switch (typeName _parameter) do + { + case "ARRAY": + { + _parameter call DMS_fnc_GetAllUnits + }; + + case "OBJECT": + { + [ + [], + [_parameter] + ] select (alive _parameter); + }; + + case "GROUP": + { + (units _parameter) select {alive _x}; + }; + + default + { + diag_log format ["DMS ERROR :: Calling DMS_fnc_GetAllUnits with an invalid parameter: %1 | Type: %2", _parameter, typeName _parameter]; + [] + }; + } + ); +} forEach _this; + +if (DMS_DEBUG) then +{ + (format ["GetAllUnits :: Input (%1) produced units: %2",_this,_units]) call DMS_fnc_DebugLog; +}; + + +_units diff --git a/@ExileServer/addons/a3_dms/scripts/fn_GetCenter.sqf b/@ExileServer/addons/a3_dms/scripts/fn_GetCenter.sqf new file mode 100644 index 0000000..727cabf --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_GetCenter.sqf @@ -0,0 +1,43 @@ +/* + DMS_fnc_GetCenter + Originally created by Maca134 for the M3Editor + Adapted by eraser1 + + Usage: + [ + [ + _object1, + _object2, + ... + _objectN + ] + ] call DMS_fnc_GetCenter; + + Calculates and returns the approximate center co-ordinates (in PositionATL) for a list of objects. +*/ + +private _objects = _this param [0, [], [[]]]; +private _ax = []; +private _ay = []; +private _az = []; + +{ + private _position = getPosASL _x; + _ax pushBack (_position select 0); + _ay pushBack (_position select 1); + _az pushBack (_position select 2); +} foreach _objects; + +private _xs = 0; +private _xc = {_xs = _xs + _x; true} count _ax; +private _xz = _xs / _xc; + +private _ys = 0; +private _yc = {_ys = _ys + _x; true} count _ay; +private _yz = _ys / _yc; + +private _zs = 0; +private _zc = {_zs = _zs + _x; true} count _az; +private _zz = _zs / _zc; + +ASLToATL [_xz, _yz, _zz] 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 new file mode 100644 index 0000000..9c1f9a1 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_GroupReinforcementsManager.sqf @@ -0,0 +1,637 @@ +/* + DMS_fnc_GroupReinforcementsManager + Created by eraser1 + + Usage: + [ + _AIGroup, // GROUP: The AI group to monitor. + [ + [ + _maxReinforcementWaves, // SCALAR: The maximum number of reinforcement waves that this group can receive. Set to -1 for unlimited reinforcement waves. + _reinforcementWavesGiven // SCALAR: The number of reinforcement waves given to this group. + ], + [ + _maxReinforcementUnits, // SCALAR: The maximum number of reinforcement units that this group can receive. Set to -1 for unlimited reinforcement units. + _reinforcementUnitsGiven // SCALAR: The number of reinforcement units given to this group. + ] + ], + [ + _updateDelay, // SCALAR: Delay in seconds until the AI group is reinforced. + _lastUpdated // SCALAR: The time (diag_tickTime) when the group was last reinforced. + ], + _spawnLocations, // ARRAY: Array of positions (ATL) where reinforcement AI can spawn. Passing an empty array will cause the group leader's position to be used. For "armed_vehicle" _monitorType, a random position between 100 and 300 meters from the leader is used. + _class, // STRING: The "class" of AI to spawn as reinforcements. Supported values: "random","assault","MG","sniper" or "unarmed" + _difficulty, // STRING: The difficulty of the AI to be spawned. Supported values: "random","static","hardcore","difficult","moderate", or "easy" + _side, // STRING: The "side" that the AI are on. Currently only "bandit" is supported. + _monitorType, // STRING: How the AI group should be managed. Supported types: "playernear", "maintain", "reinforce", "increasing_resistance", "armed_vehicle" + _monitorParams, // ARRAY: Parameters specific to the _monitorType. See below. + _customGearSet // (OPTIONAL) ARRAY: The custom gear set of the AI. Refer to documentation of fn_SpawnAISoldier.sqf for more info: https://github.com/Defent/DMS_Exile/blob/master/%40ExileServer/addons/a3_dms/scripts/fn_SpawnAISoldier.sqf + ] call DMS_fnc_GroupReinforcementsManager; + + About "_monitorType" types: + + "playernear": + _monitorParams = + [ + _posOrObj, // ARRAY (position): The position at which the players have to be near. + _radius, // SCALAR: The distance (in meters) that a player has to be near in order for reinforcements to spawn + _reinforcementCount, // SCALAR: The (maximum) number of units to spawn as reinforcements. + _maxAICount // (OPTIONAL) SCALAR: Maximum number of AI Units after reinforcements. Set to 0 for no limit. Default value is 0. + ] + + "maintain": + _monitorParams = + [ + _AICount // SCALAR: If the AI Group has fewer than "_AICount" living units, then new members will be added to the group until it has "_AICount" living units again. + ] + + "reinforce": + _monitorParams = + [ + _AICount, // SCALAR: If the AI Group has fewer than "_AICount" living units, then the group will receive reinforcements. + _reinforcementCount, // SCALAR: The (maximum) number of units to spawn as reinforcements. + _maxAICount // (OPTIONAL) SCALAR: Maximum number of AI Units after reinforcements. Set to 0 for no limit. Default value is equivalent to _AICount. + ] + + "increasing_resistance": + _monitorParams = + [ + _AICount, // SCALAR: If the AI Group has fewer than "_AICount" living units, then the group will receive reinforcements. + _reinforcementCount, // SCALAR: The (maximum) number of units to spawn as reinforcements. + _increment_AICount, // SCALAR: After reinforcements, "_AICount" is increased by this amount, so subsequent reinforcements will be spawned for even greater amounts of AI (increasing the number of total AI, until "_maxAICount" is reached). + _maxAICount // (OPTIONAL) SCALAR: Maximum number of AI Units after reinforcements. Default value is equivalent to _AICount. Set to 0 for no limit. + ] + + "increasing_difficulty": + _monitorParams = + [ + _AICount, // SCALAR: If the AI Group has fewer than "_AICount" living units, then the group will receive reinforcements. + _reinforcementCount, // SCALAR: The (maximum) number of units to spawn as reinforcements. + _maxAICount // (OPTIONAL) SCALAR: Maximum number of AI Units after reinforcements. Default value is equivalent to _AICount. Set to 0 for no limit. + ] + + "static_gunner": + _monitorParams = + [ + _staticGun, // OBJECT: If this object (static gun) loses its gunner and/or is deleted, then a new static gun and/or gunner will spawn to replace the previous one. + _gunPos, // ARRAY (positionATL): The position of the static gun. + _staticGunClass // (OPTIONAL) STRING: The classname of the static gun to spawn as reinforcement. + ] + + "armed_vehicle": + _monitorParams = + [ + _AICount, // SCALAR: If the AI Group has fewer than "_AICount" living units, then the group will receive reinforcements. + _vehClass // (OPTIONAL) STRING: The classname of the vehicle to spawn. Use "random" to select a random vehicle from "DMS_ArmedVehicles". Default: "random" + ] + + "armed_vehicle_replace": + _monitorParams = + [ + _vehicle, // OBJECT: When this vehicle is null or dead, then this group will receive reinforcements. The spawned vehicle will then be the new _vehicle. + _vehClass // (OPTIONAL) STRING: The classname of the vehicle to spawn. Use "random" to select a random vehicle from "DMS_ArmedVehicles". Default: "random" + ] + 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 Fire-From-Vehicle (FFV) gunners. + _maxJumpers, // SCALAR: Maximum number of AI to eject from the aircraft. Set to a really high # to ignore (like 999). + _remainAsGunship, // BOOLEAN: Whether or not to keep the heli flying around as a gunship. + _dropPoint, // OBJECT or ARRAY (OPTIONAL - Position2D or 3D): The location to drop the reinforcements at. The drop point will default to the group leader. + _heliClass, // STRING (OPTIONAL): The classname of the heli to spawn. + _spawnPos // ARRAY (OPTIONAL - Position2D or 3D): The position for the heli to spawn at. + ] + 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). +*/ + +// Check ALL the variables +if !(params +[ + "_AIGroup", + "_reinforcementInfo", + "_updateInfo", + "_spawnLocations", + "_class", + "_difficulty", + "_side", + "_monitorType", + "_monitorParams" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_GroupReinforcementsManager with invalid parameters: %1",_this]; + true +}; + + +if !(_reinforcementInfo params +[ + "_wavesInfo", + "_unitsInfo" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_GroupReinforcementsManager with invalid _reinforcementInfo: %1",_reinforcementInfo]; + true +}; + + +if !(_wavesInfo params +[ + "_maxReinforcementWaves", + "_reinforcementWavesGiven" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_GroupReinforcementsManager with invalid _wavesInfo: %1",_wavesInfo]; + true +}; + + +if !(_unitsInfo params +[ + "_maxReinforcementUnits", + "_reinforcementUnitsGiven" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_GroupReinforcementsManager with invalid _unitsInfo: %1",_unitsInfo]; + true +}; + + +if !(_updateInfo params +[ + "_updateDelay", + "_lastUpdated" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_GroupReinforcementsManager with invalid _updateInfo: %1",_updateInfo]; + true +}; + +private _customGearSet = + if ((count _this) > 9) then + { + _this select 9 + } + else + { + [] + }; + + + +_fnc_isDepleted = +{ + switch (true) do + { + // Both "_maxReinforcementWaves" and "_maxReinforcementUnits" are limited, so we check both. + case ((_maxReinforcementWaves>0) && {_maxReinforcementUnits>0}): {((_reinforcementWavesGiven>=_maxReinforcementWaves) || {_reinforcementUnitsGiven>=_maxReinforcementUnits})}; + + // Only "_maxReinforcementWaves" is limited. + case (_maxReinforcementWaves>0): {(_reinforcementWavesGiven>=_maxReinforcementWaves)}; + + // Only "_maxReinforcementUnits" is limited. + case (_maxReinforcementUnits>0): {(_reinforcementUnitsGiven>=_maxReinforcementUnits)}; + + // Neither are limited, so reinforcements will never be depleted. + default {false}; + }; +}; + +private _reinforcementsDepleted = call _fnc_isDepleted; + +if (!_reinforcementsDepleted && {(diag_tickTime-_lastUpdated)>_updateDelay}) then +{ + private "_unitsToSpawn"; + + private _remainingUnits = + if (isNull _AIGroup) then + { + // The group (presumably) lost all units and got deleted, so we create a new group using the given side and continue with that. + _AIGroup = createGroup (missionNamespace getVariable [format ["DMS_%1Side",_side],EAST]); + + _this set [0, _AIGroup]; + + + if (DMS_DEBUG) then + { + (format ["GroupReinforcementsManager :: Group provided was null! Created new group for ""%1"" side: %2",_side, _AIGroup]) call DMS_fnc_DebugLog; + }; + + 0 + } + else + { + {alive _x} count (units _AIGroup); + }; + + + if (DMS_DEBUG) then + { + (format ["GroupReinforcementsManager :: Checking reinforcements for group %1 with %2 surviving units. _this: %3",_AIGroup, _remainingUnits, _this]) call DMS_fnc_DebugLog; + }; + + switch (toLower _monitorType) do + { + case "playernear": + { + if !(_monitorParams params + [ + "_posOrObj", + "_radius", + "_reinforcementCount" + ]) + 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 ([_posOrObj,_radius] call DMS_fnc_IsPlayerNearby) then + { + private _maxAICount = if ((count _monitorParams)>3) then {_monitorParams param [3, 0, [0]]} else {0}; + + _unitsToSpawn = _reinforcementCount min ((_maxAICount-_remainingUnits) max 0); + }; + }; + + case "maintain": + { + if !(_monitorParams params + [ + "_AICount" + ]) + 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 + { + _unitsToSpawn = _AICount - _remainingUnits; + }; + }; + + case "reinforce": + { + if !(_monitorParams params + [ + "_AICount", + "_reinforcementCount" + ]) + 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 _maxAICount = if ((count _monitorParams)>2) then {_monitorParams param [2, 0, [0]]} else {_AICount}; + + _unitsToSpawn = _reinforcementCount min ((_maxAICount-_remainingUnits) max 0); + }; + }; + + case "increasing_resistance": + { + if !(_monitorParams params + [ + "_AICount", + "_reinforcementCount", + "_increment_AICount" + ]) + 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 _maxAICount = if ((count _monitorParams)>3) then {_monitorParams param [3, 0, [0]]} else {_AICount}; + + _unitsToSpawn = _reinforcementCount min ((_maxAICount-_remainingUnits) max 0); + + _monitorParams set [0, _AICount + _increment_AICount]; + }; + }; + + case "increasing_difficulty": + { + if !(_monitorParams params + [ + "_AICount", + "_reinforcementCount" + ]) + 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 + { + _difficulty = + switch (toLower _difficulty) do + { + case "easy": {"moderate"}; + case "moderate": {"difficult"}; + case "difficult"; + case "hardcore": {"hardcore"}; + }; + + private _maxAICount = if ((count _monitorParams)>3) then {_monitorParams param [3, 0, [0]]} else {_AICount}; + + _unitsToSpawn = _reinforcementCount min ((_maxAICount-_remainingUnits) max 0); + }; + }; + + case "armed_vehicle": + { + if !(_monitorParams params + [ + "_AICount" + ]) + 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 _vehClass = if ((count _monitorParams)>1) then {_monitorParams param [1, "", [""]]} else {"random"}; + + private _leaderPos = getPosATL (leader _AIGroup); + + private _veh = + [ + [ + if (_spawnLocations isEqualTo []) then {_leaderPos getPos [100+(random 200),random 360]} else {selectRandom _spawnLocations}, + _leaderPos + ], + _AIGroup, + _class, + _difficulty, + _side, + _vehClass + ] call DMS_fnc_SpawnAIVehicle; + + // 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, _vehClass, _veh]) call DMS_fnc_DebugLog; + }; + }; + }; + + case "armed_vehicle_replace": + { + if !(_monitorParams params + [ + "_vehicle" + ]) + 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 ((isNull _vehicle) || {!alive _vehicle} || {(count (crew _vehicle)) isEqualTo 0}) then + { + deleteVehicle _vehicle; + + private _vehClass = if ((count _monitorParams)>1) then {_monitorParams param [1, "", [""]]} else {"random"}; + + private _leaderPos = getPosATL (leader _AIGroup); + + _vehicle = + [ + [ + if (_spawnLocations isEqualTo []) then {[_leaderPos,100+(random 200),random 360] call DMS_fnc_SelectOffsetPos} else {selectRandom _spawnLocations}, + _leaderPos + ], + _AIGroup, + _class, + _difficulty, + _side, + _vehClass + ] call DMS_fnc_SpawnAIVehicle; + + // 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; + + _monitorParams set [0, _vehicle]; + + if (DMS_DEBUG) then + { + (format["GroupReinforcementsManager :: Group %1 received a ""%2"" vehicle (%3) as reinforcements.",_AIGroup, _vehClass, _vehicle]) call DMS_fnc_DebugLog; + }; + }; + }; + + case "static_gunner": + { + if !(_monitorParams params + [ + "_staticGun", + "_gunPos" + ]) + 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 ((isNull _staticGun) || {!alive _staticGun} || {(count (crew _staticGun)) isEqualTo 0}) then + { + deleteVehicle _staticGun; + + private _staticGunClass = if ((count _monitorParams)>1) then {_monitorParams param [1, "", [""]]} else {"random"}; + + private _leaderPos = getPosATL (leader _AIGroup); + + _staticGun = + [ + [ + _gunPos + ], + _AIGroup, + _class, + _difficulty, + _side, + _staticGunClass + ] call DMS_fnc_SpawnAIStaticMG; + + // 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; + + _monitorParams set [0, _staticGun]; + + if (DMS_DEBUG) then + { + (format["GroupReinforcementsManager :: Group %1 received a ""%2"" static gun (%3) as reinforcement at %4.",_AIGroup, _staticGunClass, _staticGun, _gunPos]) call DMS_fnc_DebugLog; + }; + }; + }; + + case "heli_troopers": + { + if !(_monitorParams params + [ + "_AICount", + "_ejectFFVGunners", + "_maxJumpers", + "_remainAsGunship" + ]) + 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 _dropPoint = if ((count _monitorParams)>4) then {_monitorParams param [4, getPosATL (leader _AIGroup), [objNull,[]], [2,3]]} else {getPosATL (leader _AIGroup)}; + private _heliClass = if ((count _monitorParams)>5) then {_monitorParams param [5, "", [""]]} else {selectRandom DMS_ReinforcementHelis}; + + private _params = + [ + _AIGroup, + _class, + _difficulty, + _side, + _dropPoint, + _ejectFFVGunners, + _maxJumpers, + _remainAsGunship, + _heliClass + ]; + + if ((count _monitorParams)>6) then + { + _params pushBack (_monitorParams select 6); + }; + + private _heli = _params 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; + diag_log format ["DMS ERROR :: Calling DMS_fnc_GroupReinforcementsManager with unsupported _monitorType: %1 | Setting _reinforcementsDepleted to true.",_monitorType]; + }; + }; + + if ((!isNil "_unitsToSpawn") && {_unitsToSpawn>0}) then + { + private _spawnPos = []; + + if (_maxReinforcementUnits>0) then + { + _maxAvailableReinforcements = (_maxReinforcementUnits-_reinforcementUnitsGiven) max 0; + if (_maxAvailableReinforcements<_unitsToSpawn) then + { + if (DMS_DEBUG) then + { + (format["GroupReinforcementsManager :: Group %1 requested %2 units for backup, but only %3 are available. Providing %3 units and setting _reinforcementsDepleted to true.",_AIGroup, _unitsToSpawn, _maxAvailableReinforcements]) call DMS_fnc_DebugLog; + }; + _unitsToSpawn = _maxAvailableReinforcements; + _reinforcementsDepleted = true; + }; + }; + + private _units = []; + + if (_spawnLocations isEqualTo []) then + { + // No spawn locations were provided, so we just use the leader of the group as the spawn location. + _spawnPos = getPosATL (leader _AIGroup); + + for "_i" from 0 to (_unitsToSpawn-1) do + { + _units pushBack ([_AIGroup,_spawnPos,_class,_difficulty,_side,"Soldier",_customGearSet] call DMS_fnc_SpawnAISoldier); + }; + } + else + { + // Shuffle the list. + private _spawningLocations = _spawnLocations call ExileClient_util_array_shuffle; + _spawnPos = _spawningLocations select 0; // Define it for spawning flares + _spawningLocations_count = count _spawningLocations; + + // Add extra spawning locations if there are not enough. + for "_i" from 0 to (_unitsToSpawn-_spawningLocations_count-1) do + { + _spawningLocations pushBack (selectRandom _spawningLocations); + }; + + // Now to spawn the AI... + for "_i" from 0 to (_unitsToSpawn-1) do + { + _units pushBack ([_AIGroup,_spawningLocations select _i,_class,_difficulty,_side,"Soldier",_customGearSet] call DMS_fnc_SpawnAISoldier); + }; + }; + + _units joinSilent _AIGroup; // Otherwise they don't like each other... + + // Update the given reinforcements count. + _reinforcementWavesGiven = _reinforcementWavesGiven + 1; + _reinforcementUnitsGiven = _reinforcementUnitsGiven + _unitsToSpawn; + + if (DMS_SpawnFlareOnReinforcements) then + { + playSound3D ["a3\missions_f_beta\data\sounds\Showcase_Night\flaregun_4.wss", objNull, false, (ATLToASL _spawnPos) vectorAdd [0,0,250],2]; + ("F_20mm_Red" createVehicle (_spawnPos vectorAdd [0,0,250])) setVelocity [0,0,-1]; + }; + + if (DMS_DEBUG) then + { + (format["GroupReinforcementsManager :: Group %1 received %2 units as backup (wave #%3, %4 units given total). Reinforcements Depleted: %5",_AIGroup, _unitsToSpawn, _reinforcementWavesGiven, _reinforcementUnitsGiven, _reinforcementsDepleted]) call DMS_fnc_DebugLog; + }; + }; + + if (!_reinforcementsDepleted) then + { + _reinforcementsDepleted = call _fnc_isDepleted; + }; + + // Update values + _this set [1, [[_maxReinforcementWaves,_reinforcementWavesGiven],[_maxReinforcementUnits,_reinforcementUnitsGiven]]]; + _this set [2, [_updateDelay,diag_tickTime]]; +}; + + + +_reinforcementsDepleted 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..adc5b38 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_HeliParatroopers_Monitor.sqf @@ -0,0 +1,162 @@ +/* + DMS_fnc_HeliParatroopers_Monitor + Created by eraser1 + + 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. + _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 !(_x params + [ + "_heli", + "_dropPoint", + "_remainAsGunship" + ]) + 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 = []; + + private _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; + }; + + { + private _unit = _x; + + if ((alive _unit) && {_unit getVariable ["DMS_Paratrooper", false]}) then + { + /* + moveOut _unit; + private _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 (crew _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; + private _pilotGrp = createGroup (side _pilot); + private _newPos = _dropPoint getPos [2 * worldSize, random 360]; + + [_pilot] joinSilent _pilotGrp; + + _pilot setDestination [_newPos, "VEHICLE PLANNED", true]; + + for "_i" from count (waypoints _pilotGrp) to 1 step -1 do + { + deleteWaypoint ((waypoints _pilotGrp) select _i); + }; + + private _wp = _pilotGrp addWaypoint [_newPos,5]; + _wp setWaypointType "MOVE"; + //{_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 !(_groupOwner isEqualTo []) 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 new file mode 100644 index 0000000..8e91278 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E.sqf @@ -0,0 +1,75 @@ +/* + DMS_fnc_ImportFromM3E + Created by eraser1 + + Check out M3 Editor: http://maca134.co.uk/portfolio/m3editor-arma-3-map-editor/ + + Usage: + [ + _file, // String: The filename (or filepath under the objects folder) that contains the exported M3E objects + _pos // Object or Array: Center position + ] call DMS_fnc_ImportFromM3E; + + It takes RELATIVE POSITION as argument. In order to get relative positions, check this link: http://maca134.co.uk/portfolio/m3editor-arma-3-map-editor/ + + Returns all created objects. +*/ + +if !(params +[ + ["_file","",[""]], + ["_pos","",[[],objNull],[2,3]] +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_ImportFromM3E with invalid parameters: %1",_this]; + [] +}; + + +// Get the position if an object was supplied instead of position +if (_pos isEqualType objNull) then +{ + _pos = getPosATL _pos; +}; + +// Set the center pos to 0 if it isn't defined +if ((count _pos)<3) then +{ + _pos set [2,0]; +}; + +private _export = call compile preprocessFileLineNumbers (format ["\x\addons\DMS\objects\%1.sqf",_file]); + +if ((isNil "_export") || {!(_export isEqualType [])}) exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_ImportFromM3E with invalid file/filepath: %1 | _export: %2",_file,_export]; + [] +}; + +private _objs = _export apply +{ + // Create the object + private _obj = createVehicle [_x select 0, [0,0,0], [], 0, "CAN_COLLIDE"]; + _obj enableSimulationGlobal false; + + // Calculate the object's position using provided relative position + private _objPos = [_pos,_x select 1] call DMS_fnc_CalcPos; + + if (((count _x)>4) && {!(_x select 4)}) then + { + // Supports bank/pitch + _obj setPosATL _objPos; + _obj setVectorDirAndUp (_x select 3); + } + else + { + _obj setDir (_x select 2); + _obj setPos _objPos; + }; + + _obj; +}; + + +_objs diff --git a/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_3DEN.sqf b/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_3DEN.sqf new file mode 100644 index 0000000..88d0a06 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_3DEN.sqf @@ -0,0 +1,61 @@ +/* + DMS_fnc_ImportFromM3E_3DEN + Created by eraser1 + + Check out M3 Editor - 3DEN: https://github.com/maca134/m3e_3den/releases + + Usage: + [ + _file, // String: The filename (or filepath under the objects folder) that contains the exported M3E objects + _center // Object or Array (PositionATL): Center position + ] call DMS_fnc_ImportFromM3E_3DEN; + + This function is should be used with the "Export Objects (Relative)" command. + + Returns all created objects. +*/ + +if !(params +[ + ["_file","",[""]], + ["_center","",[[],objNull],[2,3]] +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_ImportFromM3E with invalid parameters: %1",_this]; + [] +}; + + +// Get the position if an object was supplied instead of position +if (_center isEqualType objNull) then +{ + _center = getPosATL _center; +}; + +// Set the center pos to 0 if it isn't defined +if ((count _center)<3) then +{ + _center set [2,0]; +}; + +private _export = call compile preprocessFileLineNumbers (format ["\x\addons\DMS\objects\%1.sqf",_file]); + +if ((isNil "_export") || {!(_export isEqualType [])}) exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_ImportFromM3E with invalid file/filepath: %1 | _export: %2",_file,_export]; + [] +}; + +private _objs = _export apply +{ + private _object = (_x select 0) createVehicle [0,0,0]; + _object setDir (_x select 2); + _object setPosATL (_center vectorAdd (_x select 1)); + _object enableSimulationGlobal ((_x select 3) select 0); + _object allowDamage ((_x select 3) select 1); + _object; +}; + + +_objs diff --git a/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_3DEN_Convert.sqf b/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_3DEN_Convert.sqf new file mode 100644 index 0000000..a4ffcb6 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_3DEN_Convert.sqf @@ -0,0 +1,66 @@ +/* + DMS_fnc_ImportFromM3E_3DEN_Convert + Created by eraser1 + + Check out M3 Editor - 3DEN: https://github.com/maca134/m3e_3den/releases + + Usage: + [ + _file, // String: The filename (or filepath under the objects folder) that contains the exported M3E objects + _missionPos // Object or Array: Center position + ] call DMS_fnc_ImportFromM3E_3DEN_Convert; + + This function will take a file exported from M3Editor, convert it into relative position, then place the objects from the converted relative positions. + Use this function if you don't know how to get the relative position, and you only have the exported static positions. + + This function will return all created objects. +*/ + +if !(params +[ + ["_file","",[""]], + ["_missionPos","",[[],objNull],[2,3]] +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_ImportFromM3E_Convert with invalid parameters: %1",_this]; + [] +}; + + +// Get the position if an object was supplied instead of position +if (_missionPos isEqualType objNull) then +{ + _missionPos = getPosATL _missionPos; +}; + +// Set the center pos to 0 if it isn't defined +if ((count _missionPos)<3) then +{ + _missionPos set [2,0]; +}; + + +private _export = call compile preprocessFileLineNumbers (format ["\x\addons\DMS\objects\static\%1.sqf",_file]); + +if ((isNil "_export") || {!(_export isEqualType [])}) exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_ImportFromM3E_Convert with invalid file/filepath: %1 | _export: %2",_file,_export]; + [] +}; + +private _objs = _export apply +{ + private _object = (_x select 0) createVehicle [0,0,0]; + _object setPosASL ((_x select 1) vectorAdd [0,0,5000]); + _object setVectorDirAndUp (_x select 2); + _object enableSimulationGlobal ((_x select 3) select 0); + _object allowDamage ((_x select 3) select 1); + + _object; +}; + +[_objs,_missionPos] call DMS_fnc_SetRelPositions; + + +_objs diff --git a/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_3DEN_Static.sqf b/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_3DEN_Static.sqf new file mode 100644 index 0000000..f39d7fc --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_3DEN_Static.sqf @@ -0,0 +1,58 @@ +/* + DMS_fnc_ImportFromM3E_3DEN_Static + Created by eraser1 + + Check out M3 Editor - 3DEN: https://github.com/maca134/m3e_3den/releases + + Usage: + [ + _file // String: The filename (or filepath under the objects folder) that contains the exported M3E objects + ] call DMS_fnc_ImportFromM3E_3DEN_Static; + + _file call DMS_fnc_ImportFromM3E_3DEN_Static; // This also works + + This function will simply create the objects from a file that was exported from M3Editor, and return a list of those objects. +*/ + +if !(params +[ + ["_file","",[""]] +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_ImportFromM3E_Static with invalid parameters: %1",_this]; + [] +}; + +// The next few lines checks to see if the static base has been spawned previously, in order to avoid spawning duplicate objects. +private _varname = format ["DMS_StaticBaseSpawned_%1",_file]; + +if (missionNamespace getVariable [_varname,false]) exitWith +{ + diag_log format ["DMS ERROR :: Attempting to spawn static base with file ""%1"" after it has already been spawned!",_file]; +}; + +missionNamespace setVariable [_varname,true]; + + +private _export = call compile preprocessFileLineNumbers (format ["\x\addons\DMS\objects\static\%1.sqf",_file]); + +if ((isNil "_export") || {!(_export isEqualType [])}) exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_ImportFromM3E_Static with invalid file/filepath: %1 | _export: %2",_file,_export]; + [] +}; + +private _objs = _export apply +{ + private _object = (_x select 0) createVehicle [0,0,0]; + _object setPosASL (_x select 1); + _object setVectorDirAndUp (_x select 2); + _object enableSimulationGlobal ((_x select 3) select 0); + _object allowDamage ((_x select 3) select 1); + + _object; +}; + + +_objs diff --git a/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_Convert.sqf b/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_Convert.sqf new file mode 100644 index 0000000..492abe9 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_Convert.sqf @@ -0,0 +1,76 @@ +/* + DMS_fnc_ImportFromM3E_Convert + Created by eraser1 + + Check out M3 Editor: http://maca134.co.uk/portfolio/m3editor-arma-3-map-editor/ + + Usage: + [ + _file, // String: The filename (or filepath under the objects folder) that contains the exported M3E objects + _missionPos // Object or Array: Center position + ] call DMS_fnc_ImportFromM3E_Convert; + + This function will take a file exported from M3Editor, convert it into relative position, then place the objects from the converted relative positions. + Use this function if you don't know how to get the relative position, and you only have the exported static positions. + + This function will return all created objects. +*/ + +if !(params +[ + ["_file","",[""]], + ["_missionPos","",[[],objNull],[2,3]] +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_ImportFromM3E_Convert with invalid parameters: %1",_this]; + [] +}; + + +// Get the position if an object was supplied instead of position +if (_missionPos isEqualType objNull) then +{ + _missionPos = getPosATL _missionPos; +}; + +// Set the center pos to 0 if it isn't defined +if ((count _missionPos)<3) then +{ + _missionPos set [2,0]; +}; + + +private _export = call compile preprocessFileLineNumbers (format ["\x\addons\DMS\objects\static\%1.sqf",_file]); + +if ((isNil "_export") || {!(_export isEqualType [])}) exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_ImportFromM3E_Convert with invalid file/filepath: %1 | _export: %2",_file,_export]; + [] +}; + +private _objs = _export apply +{ + private _obj = createVehicle [_x select 0, [0,0,0], [], 0, "CAN_COLLIDE"]; + _obj enableSimulationGlobal false; + + private _pos = (_x select 1) vectorAdd [0,0,5000]; + + if (_x select 4) then + { + _obj setDir (_x select 2); + _obj setPosATL _pos; + } + else + { + _obj setPosATL _pos; + _obj setVectorDirAndUp (_x select 3); + }; + + _obj; +}; + +[_objs,_missionPos] call DMS_fnc_SetRelPositions; + + +_objs diff --git a/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_Static.sqf b/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_Static.sqf new file mode 100644 index 0000000..f2798bc --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_ImportFromM3E_Static.sqf @@ -0,0 +1,68 @@ +/* + DMS_fnc_ImportFromM3E_Static + Created by eraser1 + + Check out M3 Editor: http://maca134.co.uk/portfolio/m3editor-arma-3-map-editor/ + + Usage: + [ + _file // String: The filename (or filepath under the objects folder) that contains the exported M3E objects + ] call DMS_fnc_ImportFromM3E_Static; + + _file call DMS_fnc_ImportFromM3E_Static; // This also works + + This function will simply create the objects from a file that was exported from M3Editor, and return a list of those objects. +*/ + +if !(params +[ + ["_file","",[""]] +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_ImportFromM3E_Static with invalid parameters: %1",_this]; + [] +}; + +// The next few lines checks to see if the static base has been spawned previously, in order to avoid spawning duplicate objects. +private _varname = format ["DMS_StaticBaseSpawned_%1",_file]; + +if (missionNamespace getVariable [_varname,false]) exitWith +{ + diag_log format ["DMS ERROR :: Attempting to spawn static base with file ""%1"" after it has already been spawned!",_file]; +}; + +missionNamespace setVariable [_varname,true]; + + +private _export = call compile preprocessFileLineNumbers (format ["\x\addons\DMS\objects\static\%1.sqf",_file]); + +if ((isNil "_export") || {!(_export isEqualType [])}) exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_ImportFromM3E_Static with invalid file/filepath: %1 | _export: %2",_file,_export]; + [] +}; + +private _objs = _export apply +{ + private _obj = createVehicle [_x select 0, [0,0,0], [], 0, "CAN_COLLIDE"]; + _obj enableSimulationGlobal false; + + private _pos = _x select 1; + + if (_x select 4) then + { + _obj setDir (_x select 2); + _obj setPosATL _pos; + } + else + { + _obj setPosATL _pos; + _obj setVectorDirAndUp (_x select 3); + }; + + _obj; +}; + + +_objs diff --git a/@ExileServer/addons/a3_dms/scripts/fn_IsNearWater.sqf b/@ExileServer/addons/a3_dms/scripts/fn_IsNearWater.sqf new file mode 100644 index 0000000..2ba6e8c --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_IsNearWater.sqf @@ -0,0 +1,47 @@ +/* + DMS_fnc_IsNearWater + Original function by WAI + Improved by eraser1 + + Usage: + [ + _position, + _radius + ] call DMS_fnc_IsNearWater + +*/ + +if !(params +[ + "_position", + "_radius" +]) +exitWith +{ + diag_log format["DMS ERROR :: Calling DMS_fnc_IsNearWater with invalid parameters: %1",_this]; + false +}; + +private _result = false; + +try +{ + if (surfaceIsWater _position) then + { + throw true; + }; + + for "_i" from 0 to 359 step 45 do + { + if (surfaceIsWater (_position getPos [_radius,_i])) then + { + throw true; + }; + }; +} +catch +{ + _result = true; +}; + +_result diff --git a/@ExileServer/addons/a3_dms/scripts/fn_IsPlayerNearby.sqf b/@ExileServer/addons/a3_dms/scripts/fn_IsPlayerNearby.sqf new file mode 100644 index 0000000..078801e --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_IsPlayerNearby.sqf @@ -0,0 +1,55 @@ +/* + DMS_fnc_IsPlayerNearby + Created by eraser1 + + Usage: + [ + _positionOrObject, + _distance + ] call DMS_fnc_IsPlayerNearby; + + Returns whether or not a player is within "_distance" meters of "_positionOrObject". +*/ + +if !(params +[ + "_pos", + "_dis" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_IsPlayerNearby with invalid parameters: %1",_this]; + false; +}; + +if (_dis isEqualTo 0) exitWith {false}; + +private _isNear = false; + +try +{ + { + { + if (isPlayer _x) then + { + throw _x; + }; + } forEach (crew _x); + } forEach (_pos nearEntities [["Exile_Unit_Player","LandVehicle", "Air", "Ship"], _dis]); + + if (DMS_DEBUG) then + { + (format ["IsPlayerNearby :: No players within %1 meters of %2!",_dis,_pos]) call DMS_fnc_DebugLog; + }; +} +catch +{ + _isNear = true; + if (DMS_DEBUG) then + { + (format ["IsPlayerNearby :: %1 is within %2 meters of %3!",_exception,_dis,_pos]) call DMS_fnc_DebugLog; + }; +}; + + +_isNear; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_IsPosBlacklisted.sqf b/@ExileServer/addons/a3_dms/scripts/fn_IsPosBlacklisted.sqf new file mode 100644 index 0000000..fcef326 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_IsPosBlacklisted.sqf @@ -0,0 +1,73 @@ +/* + DMS_fnc_IsPosBlacklisted + Created by eraser1 + + Usage: + [ + _pos, + [ + _blacklist1, + _blacklist2, + ... + _blacklistN + ] + ] call DMS_fnc_IsPosBlacklisted; + + A blacklist can be in the form: + [[x1,y1],[x2,y2]] + where x1 is LESS than x2, and y1 is LESS than y2. This method is SLOWER. + + or, + [[x,y],radius] + where any position within "radius" meters of position "x,y" is blacklisted. This method is FASTER. + + Returns true if the given position is blacklisted. +*/ + + +if !(params +[ + "_pos", + "_blacklists" +]) exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_IsPosBlacklisted with invalid parameters: %1",_this]; +}; + + +try +{ + { + _x params + [ + "_blacklist_pos", + "_blacklist_parameter" + ]; + + if (_blacklist_parameter isEqualType 0) then + { + if ((_pos distance2D _blacklist_pos) <= _blacklist_parameter) throw _x; + } + else + { + if + ( + ((_pos select 0) >= (_blacklist_pos select 0)) && // if x is greater than x1 and + {(_pos select 0) <= (_blacklist_parameter select 0)} && // if x is less than x2 and + {(_pos select 1) >= (_blacklist_pos select 1)} && // if y is greater than y1 and + {(_pos select 1) <= (_blacklist_parameter select 1)} // if y is less than y2 + ) throw _x; // blacklisted + }; + } forEach _blacklists; + + false +} +catch +{ + if (DMS_DEBUG) then + { + format["Position |%1| is blacklisted by blacklist parameter |%2|. All provided blacklists: %3",_pos,_exception,_blacklists] call DMS_fnc_DebugLog; + }; + + true +}; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_IsValidPosition.sqf b/@ExileServer/addons/a3_dms/scripts/fn_IsValidPosition.sqf new file mode 100644 index 0000000..ddbcf5c --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_IsValidPosition.sqf @@ -0,0 +1,146 @@ +/* + DMS_fnc_IsValidPosition + Created by eraser1 + + Usage: + [ + _pos, // ARRAY (position): The position to check. + _waterNearLimit, // NUMBER (distance): Minimum distance from water. + _minSurfaceNormal, // NUMBER (between 0-1): Maximum "surfaceNormal"; Basically determines how steep a position is. Check the comment for config value "DMS_MinSurfaceNormal" in config.sqf for more info + _spawnZoneNearLimit, // NUMBER (distance): Minimum distance from a spawn point. + _traderZoneNearLimit, // NUMBER (distance): Minimum distance from a trader zone. + _missionNearLimit, // NUMBER (distance): Minimum distance from another mission. + _playerNearLimit, // NUMBER (distance): Minimum distance from a player. + _territoryNearLimit, // NUMBER (distance): Minimum distance from a territory. + _mixerNearLimit, // NUMBER (distance): Minimum distance from a concrete mixer. + _contaminatedZoneNearLimit // NUMBER (distance): Minimum distance from a contaminated zone. + ] call DMS_fnc_IsValidPosition; + + All parameters except "_pos" are optional. + + Returns whether or not the provided position matches the parameters. +*/ + +if !(params +[ + "_pos", + "_waterNearLimit", + "_minSurfaceNormal", + "_spawnZoneNearLimit", + "_traderZoneNearLimit", + "_missionNearLimit", + "_playerNearLimit", + "_territoryNearLimit", + "_mixerNearLimit", + "_contaminatedZoneNearLimit" +]) +then +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_isValidPosition with invalid parameters: %1",_this]; + false +} +else +{ + private _isValidPos = false; + + try + { + if ((count _pos)<2) then + { + throw ("(UNDEFINED POSITION)"); + }; + + if ((count _pos) isEqualTo 2) then + { + _pos set [2, 0]; + }; + + + if ([_pos, DMS_findSafePosBlacklist] call DMS_fnc_IsPosBlacklisted) throw "a blacklisted position"; + + + // Check for nearby water + if ((_waterNearLimit>0) && {[_pos,_waterNearLimit] call DMS_fnc_isNearWater}) throw "water"; + + // Terrain steepness check + // 0 surfacenormal means completely vertical, 1 surfaceNormal means completely flat and horizontal. + // Take the arccos of the surfaceNormal to determine how many degrees it is from the horizontal. In SQF: {acos ((surfaceNormal _pos) select 2)}. Don't forget to define _pos. + if ((_minSurfaceNormal>0) && {_minSurfaceNormal<=1}) then + { + if (((surfaceNormal _pos) select 2)<_minSurfaceNormal) throw "a steep location"; + + // Check the surrounding area (within 5 meters) + private "_dir"; + for "_dir" from 0 to 359 step 45 do + { + if (((surfaceNormal (_pos getPos [5,_dir])) select 2)<_minSurfaceNormal) throw "a nearby steep location"; + }; + }; + + + { + if (((getMarkerPos _x) distance2D _pos)<=_missionNearLimit) throw "an A3XAI mission"; + } forEach (missionNamespace getVariable ["A3XAI_mapMarkerArray",[]]); + + { + private _markerType = markertype _x; + + // Check for nearby spawn points + if ((_markerType in DMS_SpawnZoneMarkerTypes) && {((getMarkerPos _x) distance2D _pos)<=_spawnZoneNearLimit}) throw "a spawn zone"; + + // Check for nearby trader zones + if ((_markerType in DMS_TraderZoneMarkerTypes) && {((getMarkerPos _x) distance2D _pos)<=_traderZoneNearLimit}) throw "a trader zone"; + + // Check for nearby concrete mixers + if ((_markerType in DMS_MixerMarkerTypes) && {((getMarkerPos _x) distance2D _pos)<=_mixerNearLimit}) throw "a concrete mixer"; + + // Check for nearby contaminated zones + if ((_markerType in DMS_ContaminatedZoneMarkerTypes) && {((getMarkerPos _x) distance2D _pos)<=_contaminatedZoneNearLimit}) throw "a contaminated zone"; + + // Check for nearby missions + if (_missionNearLimit>0) then + { + _missionPos = missionNamespace getVariable [format ["%1_pos",_x], []]; + if (!(_missionPos isEqualTo []) && {(_missionPos distance2D _pos)<=_missionNearLimit}) throw "a DMS mission"; + + if + ( + ( + ((_x find "ZCP_CM_dot_") >= 0) // Look in the marker string for the ZCP marker prefix + || + {(_x find "VEMFr_DynaLocInva_ID") >= 0} // Look in the marker string for the VEMF marker prefix + ) + && + {((getMarkerPos _x) distance2D _pos)<=_missionNearLimit} // Then check if the marker is close to the position + ) throw "a VEMF or ZCP mission"; + }; + } forEach allMapMarkers; + + + // Check for nearby players + if ((_playerNearLimit>0) && {[_pos,_playerNearLimit] call DMS_fnc_IsPlayerNearby}) throw "a player"; + + // Check for nearby territories. This is done last because it is likely to be the most resource intensive. + if ((_territoryNearLimit>0) && {[_pos,_territoryNearLimit] call ExileClient_util_world_isTerritoryInRange}) throw "a territory"; + + + // No exceptions found + _isValidPos = true; + } + catch + { + /* + _dot = createMarker [format ["DMS_DebugMarker_attempt%1", _pos], _pos]; + _dot setMarkerColor "ColorWEST"; + _dot setMarkerType "mil_dot"; + _dot setMarkerText (format["close to: %1",_exception]); + DMS_DebugMarkers pushBack _dot; + */ + if (DMS_DEBUG) then + { + (format ["IsValidPosition :: Position %1 is too close to %2!",_pos,_exception]) call DMS_fnc_DebugLog; + }; + }; + + _isValidPos +}; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_MissionParams.sqf b/@ExileServer/addons/a3_dms/scripts/fn_MissionParams.sqf new file mode 100644 index 0000000..4bd97c1 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_MissionParams.sqf @@ -0,0 +1,144 @@ +/* + DMS_fnc_MissionParams + Created by eraser1 + + Takes input of any argument and converts it into a standard format for DMS missions. + + It will use provided mission position requirements (if they exist) and simply return a position that matches the requirements. + + If arguments provided do not have the mission position information, index 0 of the returned array will be an empty array. + Any other passed values (other than empty array "[]") will be added to the end of the returned array. + + Usage: + [ + _findSafePosParams, // ARRAY: If a new mission position has to be generated, these values are passed to "DMS_fnc_FindSafePos" if the provided _missionPosition is improperly defined, or if it doesn't have to spawn at the provided position and that position is invalid. + [ + _missionPosition, // ARRAY (position ATL): Defines where the mission will spawn + _forceSpawn // (OPTIONAL) BOOL: Whether or not to force the mission to spawn at that location. Setting "_forceSpawn" to true means that the "DMS_fnc_IsValidPosition" check will be skipped, and the provided _missionPosition will be used regardless. + ], + [ + _extraParam_1, // (OPTIONAL) ANY: Extra parameter(s) that may be used by the mission. + _extraParam_2, // (OPTIONAL) ANY: Extra parameter(s) that may be used by the mission. + ... + _extraParam_N // (OPTIONAL) ANY: Extra parameter(s) that may be used by the mission. + ] + ] call DMS_fnc_MissionParams; + + or + + _extraParams call DMS_fnc_MissionParams; // This will simply cause the function to use the default values for "DMS_fnc_FindSafePos" to generate a mission position. The "_extraParam" will be added to the back. + + NOTE: If you pass an array with more than 1 element as an argument, the array must be in the form of the first example or the example below, or else you may get unexpected results. + If you want to pass some _extraParams as an array but spawn the mission at a random (valid) position, then call it as: + [ + _findSafePosParams, + [ + [], + ], + _extraParams_ARRAY + ] call DMS_fnc_MissionParams; + + + + Returns an array in the form + [ + _missionPos, + _extraParams + ] +*/ + +private _missionPosition = []; + +private _extraParams = []; + +if (isNil "_this") then +{ + if (DMS_DEBUG) then + { + (format ["MissionParams :: Calling with nil parameter; Setting _missionPosition to generated position with default values."]) call DMS_fnc_DebugLog; + }; + + // Simply use generated position with default values. + _missionPosition = + [ + 25,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists + ] call DMS_fnc_FindSafePos; +} +else +{ + if ((_this isEqualType []) && {(count _this)>1}) then + { + if (params + [ + ["_findSafePosParams",[25,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists],[[]]], + ["_posInfo",[],[[]],[1,2]] + ]) + then + { + _missionPosition = _posInfo select 0; + private _forceSpawn = if ((count _posInfo)>1) then {_posInfo select 1} else {false}; + + if (!(_missionPosition isEqualType []) || {(count _missionPosition)<2}) then + { + // Empty array means that you want to generate a mission position. + if !(_missionPosition isEqualTo []) then + { + diag_log format ["DMS ERROR :: Calling MissionParams with invalid _missionPosition: %1 | Generating new one with _findSafePosParams: %2",_missionPosition,_findSafePosParams]; + }; + + // Passed _missionPosition parameter is invalid, so we just find a position the regular way. + _missionPosition = _findSafePosParams call DMS_fnc_FindSafePos; + } + else + { + // Make sure z-pos is defined. + if ((count _missionPosition) isEqualTo 2) then + { + _missionPosition set [2,0]; + }; + + if (!_forceSpawn && {!([_missionPosition,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist] call DMS_fnc_IsValidPosition)}) then + { + if (DMS_DEBUG) then + { + (format ["MissionParams :: Finding new position as provided non-mandatory _missionPosition (%1) is invalid. Finding new position.",_missionPosition]) call DMS_fnc_DebugLog; + }; + // Passed _missionPosition parameter is not mandatory and doesn't meet requirements, so we just find a new position. + _missionPosition = _findSafePosParams call DMS_fnc_FindSafePos; + }; + }; + + // Assign "_extraParams" if they exist. + _extraParams = if ((count _this)>2) then {_this select 2} else {[]}; + } + else + { + diag_log format ["DMS ERROR :: Calling MissionParams with invalid _findSafePosParams or _posInfo: %1 | Generating _missionPosition with _findSafePosParams params: %2. Setting _this as _extraParams: %3",_posInfo,_findSafePosParams,_this]; + + _missionPosition = _findSafePosParams call DMS_fnc_FindSafePos; + _extraParams = _this; + }; + } + else + { + _missionPosition = + [ + 5,DMS_WaterNearBlacklist,DMS_MinSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists + ] call DMS_fnc_FindSafePos; + + _extraParams = _this; + }; +}; + +private _parsedParams = +[ + _missionPosition, + _extraParams +]; + +if (DMS_DEBUG) then +{ + (format ["MissionParams :: Returning _parsedParams: %1 | Calling params: %2",_parsedParams,_this]) call DMS_fnc_DebugLog; +}; + +_parsedParams diff --git a/@ExileServer/addons/a3_dms/scripts/fn_MissionSuccessState.sqf b/@ExileServer/addons/a3_dms/scripts/fn_MissionSuccessState.sqf new file mode 100644 index 0000000..f7bd720 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_MissionSuccessState.sqf @@ -0,0 +1,95 @@ +/* + DMS_fnc_MissionSuccessState + Created by eraser1 + + Usage: + [ + [_completionType1,_completionArgs1,_isAbsoluteCondition], + [_completionType2,_completionArgs2,_isAbsoluteCondition], + ... + [_completionTypeN,_completionArgsN,_isAbsoluteCondition] + ] call DMS_fnc_MissionSuccessState; +*/ + +if !(_this isEqualType []) exitWith +{ + diag_log format ["DMS ERROR :: DMS_fnc_MissionSuccessState called with invalid parameter: %1",_this]; +}; + +private _success = true; +private _exit = false; + +{ + if (_exit) exitWith {}; + + try + { + if !(_x params + [ + "_completionType", + "_completionArgs" + ]) + then + { + diag_log format ["DMS ERROR :: DMS_fnc_MissionSuccessState has invalid parameters in: %1",_x]; + throw "ERROR"; + }; + + + private _absoluteWinCondition = if ((count _x)>2) then {_x select 2} else {false}; + + if (!_success && {!_absoluteWinCondition}) then + { + throw format ["Skipping completion check for condition |%1|; Condition is not absolute and a previous condition has already been failed.",_x]; + }; + + + if (DMS_DEBUG) then + { + (format ["MissionSuccessState :: Checking completion type ""%1"" with argument |%2|. Absolute: %3",_completionType,_completionArgs,_absoluteWinCondition]) call DMS_fnc_DebugLog; + }; + + switch (toLower _completionType) do + { + case "kill": + { + _success = _completionArgs call DMS_fnc_TargetsKilled; + }; + /* + case "killpercent": + { + _success = _completionArgs call DMS_fnc_TargetsKilledPercent;//<---TODO + }; + */ + case "playernear": + { + _success = _completionArgs call DMS_fnc_IsPlayerNearby; + }; + case "external": // This is a special completion type. It is intended to be a flag for people who want to control mission completion using _onMonitorStart and _onMonitorEnd through array manipulation. You probably don't want to use this unless you know what you're doing. + { + _success = _completionArgs; + }; + default + { + diag_log format ["DMS ERROR :: Invalid completion type (%1) with args: %2",_completionType,_completionArgs]; + throw "ERROR"; + }; + }; + + + if (_success && {_absoluteWinCondition}) then + { + _exit = true; + throw format ["Mission completed because of absolute win condition: %1",_x]; + }; + } + catch + { + if (DMS_DEBUG) then + { + (format ["MissionSuccessState :: %1",_exception]) call DMS_fnc_DebugLog; + }; + }; +} forEach _this; + +_success; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor.sqf b/@ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor.sqf new file mode 100644 index 0000000..ede4b48 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor.sqf @@ -0,0 +1,17 @@ +/* + DMS_fnc_MissionsMonitor + + Created by eraser1 + + Calls the respective functions for Dynamic and Static mission monitoring based on DMS configuration. +*/ + +if (DMS_DynamicMission) then +{ + call DMS_fnc_MissionsMonitor_Dynamic; +}; + +if (DMS_StaticMission) then +{ + call DMS_fnc_MissionsMonitor_Static; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor_Dynamic.sqf b/@ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor_Dynamic.sqf new file mode 100644 index 0000000..ab54d0f --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor_Dynamic.sqf @@ -0,0 +1,321 @@ +/* + DMS_fnc_MissionsMonitor_Dynamic + + Created by eraser1 + + Each mission has its own index in "DMS_Mission_Arr". + Every index is a subarray with the values: + [ + _pos, + _completionInfo, //<--- More info in "DMS_fnc_MissionSuccessState" + [_timeStarted,_failTime], + [_AIUnit1,_AIUnit2,...,_AIUnitX], + [ + [_cleanupObj1,_cleanupObj2,...,_cleanupObjX], + [_vehicle1,_vehicle2,...,_vehicleX], + [ + [_crate1,_crate_loot_values1], + [_crate2,_crate_loot_values2] + ] + ], + [_missionName,_msgWIN,_msgLose], + _markers, + _missionSide, + _missionDifficulty, + _missionEvents, + [ + _onSuccessScripts, + _onFailScripts, + _onMonitorStart, + _onMonitorEnd + ], + _prevAICount + ] + + A semi-full breakdown can be found in fn_AddMissionToMonitor.sqf +*/ + +{ + if !(_x params + [ + "_pos", + "_completionInfo", + "_timing", + "_units", + "_missionObjs", + "_msgInfo", + "_markers", + "_missionSide", + "_missionDifficulty", + "_missionEvents", + "_missionScripts", + "_prevAICount", + "_isSpecial" + ]) + then + { + DMS_Mission_Arr deleteAt _forEachIndex; + diag_log format ["DMS ERROR :: Invalid Index (%1) in DMS_Mission_Arr: %2",_forEachIndex,_x]; + }; + + + if !(_timing params + [ + "_timeStarted", + "_failTime" + ]) + exitWith + { + DMS_Mission_Arr deleteAt _forEachIndex; + diag_log format ["DMS ERROR :: Invalid _timing (%1) in DMS_Mission_Arr: %2",_timing,_x]; + }; + + + if !(_missionObjs params + [ + "_buildings", + "_vehs", + "_crate_info_array", + "_mines" + ]) + exitWith + { + DMS_Mission_Arr deleteAt _forEachIndex; + diag_log format ["DMS ERROR :: Invalid _missionObjs (%1) in DMS_Mission_Arr: %2",_missionObjs,_x]; + }; + + + if !(_msgInfo params + [ + "_missionName", + "_msgWIN", + "_msgLose" + ]) + exitWith + { + DMS_Mission_Arr deleteAt _forEachIndex; + diag_log format ["DMS ERROR :: Invalid _msgInfo (%1) in DMS_Mission_Arr: %2",_msgInfo,_x]; + }; + + + if !(_missionScripts params + [ + "_onSuccessScripts", + "_onFailScripts", + "_onMonitorStart", + "_onMonitorEnd" + ]) + exitWith + { + DMS_Mission_Arr deleteAt _forEachIndex; + diag_log format ["DMS ERROR :: Invalid _missionScripts (%1) in DMS_Mission_Arr: %2",_missionScripts,_x]; + }; + + try + { + /* + if (DMS_DEBUG) then + { + (format ["MissionsMonitor_Dynamic :: Checking Mission Status (index %1): ""%2"" at %3",_forEachIndex,_missionName,_pos]) call DMS_fnc_DebugLog; + }; + */ + + if !(_onMonitorStart isEqualTo {}) then + { + if (DMS_DEBUG) then + { + (format ["MissionsMonitor_Dynamic :: Calling _onMonitorStart (index %1): ""%2"" at %3. Code: %4",_forEachIndex,_missionName,_pos,_onMonitorStart]) call DMS_fnc_DebugLog; + }; + _x call _onMonitorStart; + }; + + + if (_completionInfo call DMS_fnc_MissionSuccessState) then + { + DMS_CleanUpList pushBack [_buildings,diag_tickTime,DMS_CompletedMissionCleanupTime]; + + if (_missionSide == "bandit") then + { + DMS_RunningBMissionCount = DMS_RunningBMissionCount - 1; + }; + + { + _x allowDamage true; + _x enableRopeAttach true; + _x enableSimulationGlobal true; + + if (_x getVariable ["ExileIsPersistent", false]) then + { + _x lock 0; + _x setVariable ["ExileIsLocked",0]; + + _x setVariable ["ExileLastLockToggleAt", time]; + _x setVariable ["ExileAccessDenied", false]; + _x setVariable ["ExileAccessDeniedExpiresAt", 0]; + + // NOW we save the vehicle in the database, since we know we're not deleting this vehicle. + _x call ExileServer_object_vehicle_database_insert; + _x call ExileServer_object_vehicle_database_update; + } + else + { + _x lock 1; + }; + + _x call ExileServer_system_simulationMonitor_addVehicle; + } forEach _vehs; + + { + _x call DMS_fnc_FillCrate; + } forEach _crate_info_array; + + if (DMS_despawnMines_onCompletion) then + { + { + deleteVehicle _x; + } forEach _mines; + }; + + { + _params = _x select 0; + _code = _x select 1; + if (_code isEqualType "") then + { + _code = compile _code; + }; + _params call _code; + } forEach _onSuccessScripts; + + [_missionName,_msgWIN] call DMS_fnc_BroadcastMissionStatus; + [_markers,"win"] call DMS_fnc_RemoveMarkers; + + DMS_Mission_Arr deleteAt _forEachIndex; + + throw format ["Mission (%1) Success at %2 with message %3.",_missionName,_pos,_msgWIN]; + }; + + + private _timeElapsed = diag_tickTime - _timeStarted; + + if (DMS_ResetMissionTimeoutOnKill) then + { + private _AICount = count (_units call DMS_fnc_GetAllUnits); + + if (_AICount != _prevAICount) then + { + _x set [2,[diag_tickTime,_failTime]]; + _x set [11, _AICount]; + _timeElapsed = 0; + + if (DMS_DEBUG) then + { + format["MissionsMonitor_Dynamic :: Mission Timeout Extended to %1 more seconds; AI count changed from %2 to %3. Position: %4, MissionIndex: %5",_failTime, _prevAICount, _AICount,_pos,_forEachIndex] call DMS_fnc_DebugLog; + }; + }; + }; + + switch (true) do + { + case (_timeElapsed > DMS_MissionTimeoutResetFrequency): + { + if ([_pos,DMS_MissionTimeoutResetRange] call DMS_fnc_IsPlayerNearby) then + { + _x set [2,[diag_tickTime,_failTime]]; + + if (DMS_DEBUG) then + { + format["MissionsMonitor_Dynamic :: Mission Timeout Extended to %1 more seconds; player found within %2 meters. Position: %3, MissionIndex: %4",_failTime,DMS_MissionTimeoutResetRange,_pos,_forEachIndex] call DMS_fnc_DebugLog; + }; + }; + }; + + case (_timeElapsed > _failTime): + { + // Check to see if the timeout should be extended before ending the mission. + if ([_pos,DMS_MissionTimeoutResetRange] call DMS_fnc_IsPlayerNearby) then + { + _x set [2,[diag_tickTime,_failTime]]; + + throw format["Mission Timeout Extended to %1 more seconds; player found within %2 meters. Position: %3, MissionIndex: %4",_failTime,DMS_MissionTimeoutResetRange,_pos,_forEachIndex] call DMS_fnc_DebugLog; + }; + + //Nobody is nearby so just cleanup objects from here + private _cleanupList = ((_units call DMS_fnc_GetAllUnits)+_buildings+_vehs+_mines); + + { + _cleanupList pushBack (_x select 0); + } forEach _crate_info_array; + + private _prev = DMS_CleanUp_PlayerNearLimit; + DMS_CleanUp_PlayerNearLimit = 0; // Temporarily set the limit to 0 since we want to delete all the stuff regardless of player presence. + + _cleanupList call DMS_fnc_CleanUp; + + DMS_CleanUp_PlayerNearLimit = _prev; + + + if (_missionSide == "bandit") then + { + DMS_RunningBMissionCount = DMS_RunningBMissionCount - 1; + }; + + { + _params = _x select 0; + _code = _x select 1; + if (_code isEqualType "") then + { + _code = compile _code; + }; + _params call _code; + } forEach _onFailScripts; + + [_missionName,_msgLose] call DMS_fnc_BroadcastMissionStatus; + [_markers,"lose"] call DMS_fnc_RemoveMarkers; + + DMS_Mission_Arr deleteAt _forEachIndex; + + throw format ["Mission (%1) Fail at %2 with message %3.",_missionName,_pos,_msgLose]; + }; + }; + + + if (DMS_MarkerText_ShowAICount) then + { + private _dot = _markers select 0; + private _text = missionNamespace getVariable [format ["%1_text",_dot],_missionName]; + + if (DMS_MarkerText_ShowMissionPrefix) then + { + _text = format ["%1 %2",DMS_MarkerText_MissionPrefix,_text]; + }; + + _dot setMarkerText (format ["%1 (%2 %3 remaining)",_text,count (_units call DMS_fnc_GetAllUnits),DMS_MarkerText_AIName]); + }; + + + if !(_onMonitorEnd isEqualTo {}) then + { + if (DMS_DEBUG) then + { + (format ["MissionsMonitor_Dynamic :: Calling _onMonitorEnd (index %1): ""%2"" at %3. Code: %4",_forEachIndex,_missionName,_pos,_onMonitorEnd]) call DMS_fnc_DebugLog; + }; + _x call _onMonitorEnd; + }; + } + catch + { + if !(_onMonitorEnd isEqualTo {}) then + { + if (DMS_DEBUG) then + { + (format ["MissionsMonitor_Dynamic :: Calling _onMonitorEnd (index %1): ""%2"" at %3. Code: %4",_forEachIndex,_missionName,_pos,_onMonitorEnd]) call DMS_fnc_DebugLog; + }; + _x call _onMonitorEnd; + }; + + if (DMS_DEBUG) then + { + (format ["MissionsMonitor_Dynamic :: %1",_exception]) call DMS_fnc_DebugLog; + }; + }; +} forEach DMS_Mission_Arr; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor_Static.sqf b/@ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor_Static.sqf new file mode 100644 index 0000000..69979eb --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor_Static.sqf @@ -0,0 +1,331 @@ +/* + DMS_fnc_MissionsMonitor_Static + + Created by eraser1 + Mostly identical to "DMS_fnc_MissionsMonitor_Dynamic" + + + Each mission has its own index in "DMS_StaticMission_Arr". + Every index is a subarray with the values: + [ + _missionPos, + _completionInfo, //<--- More info in "DMS_fnc_MissionSuccessState" + _groupReinforcementsInfo, //<--- More info in "DMS_fnc_GroupReinforcementsManager" + [_timeStarted,_failTime], + [_AIGroup1,_AIGroup2,...,_AIGroupX], + [ + [_cleanupObj1,_cleanupObj2,...,_cleanupObjX], + [_vehicle1,_vehicle2,...,_vehicleX], + [ + [_crate1,_crate_loot_values1], + [_crate2,_crate_loot_values2], + ... + [_crateX,_crate_loot_valuesX] + ], + [_mine1,_mine2,...,_mineX] + ], + [_missionName,_msgWIN,_msgLose], + _markers, + _missionSide, + _missionDifficulty, + _missionEvents, + [ + _onSuccessScripts, + _onFailScripts, + _onMonitorStart, + _onMonitorEnd + ], + _prevAICount + ] + + A semi-full breakdown can be found in fn_AddStaticMissionToMonitor.sqf +*/ + +{ + if !(_x params + [ + "_missionPos", + "_completionInfo", + "_groupReinforcementsInfo", + "_timing", + "_inputAIUnits", + "_missionObjs", + "_msgInfo", + "_markers", + "_missionSide", + "_missionDifficulty", + "_missionEvents", + "_missionScripts", + "_prevAICount" + ]) + then + { + DMS_StaticMission_Arr deleteAt _forEachIndex; + diag_log format ["DMS ERROR :: Invalid Index (%1) in DMS_StaticMission_Arr: %2",_forEachIndex,_x]; + }; + + + if !(_timing params + [ + "_timeStarted", + "_failTime" + ]) + exitWith + { + DMS_StaticMission_Arr deleteAt _forEachIndex; + diag_log format ["DMS ERROR :: Invalid _timing (%1) in DMS_StaticMission_Arr: %2",_timing,_x]; + }; + + + if !(_missionObjs params + [ + "_buildings", + "_vehs", + "_crate_info_array", + "_mines" + ]) + exitWith + { + DMS_StaticMission_Arr deleteAt _forEachIndex; + diag_log format ["DMS ERROR :: Invalid _missionObjs (%1) in DMS_StaticMission_Arr: %2",_missionObjs,_x]; + }; + + + if !(_msgInfo params + [ + "_missionName", + "_msgWIN", + "_msgLose" + ]) + exitWith + { + DMS_StaticMission_Arr deleteAt _forEachIndex; + diag_log format ["DMS ERROR :: Invalid _msgInfo (%1) in DMS_StaticMission_Arr: %2",_msgInfo,_x]; + }; + + + if !(_missionScripts params + [ + "_onSuccessScripts", + "_onFailScripts", + "_onMonitorStart", + "_onMonitorEnd" + ]) + exitWith + { + DMS_StaticMission_Arr deleteAt _forEachIndex; + diag_log format ["DMS ERROR :: Invalid _missionScripts (%1) in DMS_StaticMission_Arr: %2",_missionScripts,_x]; + }; + + try + { + /* + if (DMS_DEBUG) then + { + (format ["MissionsMonitor_Static :: Checking Mission Status (index %1): ""%2"" at %3",_forEachIndex,_missionName,_missionPos]) call DMS_fnc_DebugLog; + }; + */ + + if !(_onMonitorStart isEqualTo {}) then + { + if (DMS_DEBUG) then + { + (format ["MissionsMonitor_Static :: Calling _onMonitorStart (index %1): ""%2"". Code: %3",_forEachIndex,_missionName,_onMonitorStart]) call DMS_fnc_DebugLog; + }; + _x call _onMonitorStart; + }; + + + if (_completionInfo call DMS_fnc_MissionSuccessState) then + { + DMS_CleanUpList pushBack [_buildings,diag_tickTime,DMS_CompletedMissionCleanupTime]; + + { + _x allowDamage true; + _x enableRopeAttach true; + _x enableSimulationGlobal true; + + if (_x getVariable ["ExileIsPersistent", false]) then + { + _x lock 0; + _x setVariable ["ExileIsLocked",0]; + + _x setVariable ["ExileLastLockToggleAt", time]; + _x setVariable ["ExileAccessDenied", false]; + _x setVariable ["ExileAccessDeniedExpiresAt", 0]; + + // NOW we save the vehicle in the database, since we know we're not deleting this vehicle. + _x call ExileServer_object_vehicle_database_insert; + _x call ExileServer_object_vehicle_database_update; + } + else + { + _x lock 1; + }; + + _x call ExileServer_system_simulationMonitor_addVehicle; + } forEach _vehs; + + { + _x call DMS_fnc_FillCrate; + } forEach _crate_info_array; + + if (DMS_despawnMines_onCompletion) then + { + { + deleteVehicle _x; + } forEach _mines; + }; + + { + _params = _x select 0; + _code = _x select 1; + if (_code isEqualType "") then + { + _code = compile _code; + }; + _params call _code; + } forEach _onSuccessScripts; + + [_missionName,_msgWIN] call DMS_fnc_BroadcastMissionStatus; + [_markers,"win"] call DMS_fnc_RemoveMarkers; + + DMS_StaticMission_Arr deleteAt _forEachIndex; + DMS_RunningStaticMissions deleteAt _forEachIndex; + + throw format ["Mission (%1) Success at %2 with message %3.",_missionName,_missionPos,_msgWIN]; + }; + + + private _timeElapsed = diag_tickTime - _timeStarted; + + if (DMS_ResetStaticMissionTimeoutOnKill) then + { + private _AICount = count (_inputAIUnits call DMS_fnc_GetAllUnits); + + if (_AICount != _prevAICount) then + { + _x set [3,[diag_tickTime,_failTime]]; + _x set [12, _AICount]; + _timeElapsed = 0; + + if (DMS_DEBUG) then + { + format["MissionsMonitor_Static :: Static Mission Timeout Extended to %1 more seconds; AI count changed from %2 to %3. Position: %4, MissionIndex: %5",_failTime, _prevAICount, _AICount,_pos,_forEachIndex] call DMS_fnc_DebugLog; + }; + }; + }; + + switch (true) do + { + case (_timeElapsed > DMS_SMissionTimeoutResetFrequency): + { + if ([_missionPos,DMS_StaticMissionTimeoutResetRange] call DMS_fnc_IsPlayerNearby) then + { + _x set [3,[diag_tickTime,_failTime]]; + + if (DMS_DEBUG) then + { + format["MissionsMonitor_Static :: Static Mission Timeout Extended to %1 more seconds; player found within %2 meters. Position: %3, MissionIndex: %4",_failTime,DMS_StaticMissionTimeoutResetRange,_pos,_forEachIndex] call DMS_fnc_DebugLog; + }; + }; + }; + + case (_timeElapsed > _failTime): + { + // Check to see if the timeout should be extended before ending the mission. + if ((DMS_StaticMissionTimeoutResetRange>0) && {[_missionPos,DMS_StaticMissionTimeoutResetRange] call DMS_fnc_IsPlayerNearby}) then + { + _x set [3,[diag_tickTime,_failTime]]; + + throw format ["Mission Timeout Extended at %1 with timeout after %2 seconds. Position: %3",diag_tickTime,_failTime,_missionPos]; + }; + + //Nobody is nearby so just cleanup objects from here + _cleanupList = ((_inputAIUnits call DMS_fnc_GetAllUnits)+_buildings+_vehs+_mines); + + { + _cleanupList pushBack (_x select 0); + } forEach _crate_info_array; + + private _prev = DMS_CleanUp_PlayerNearLimit; + DMS_CleanUp_PlayerNearLimit = 0; // Temporarily set the limit to 0 since we want to delete all the stuff regardless of player presence. + + _cleanupList call DMS_fnc_CleanUp; + + DMS_CleanUp_PlayerNearLimit = _prev; + + + { + _params = _x select 0; + _code = _x select 1; + if (_code isEqualType "") then + { + _code = compile _code; + }; + _params call _code; + } forEach _onFailScripts; + + [_missionName,_msgLose] call DMS_fnc_BroadcastMissionStatus; + [_markers,"lose"] call DMS_fnc_RemoveMarkers; + + DMS_StaticMission_Arr deleteAt _forEachIndex; + DMS_RunningStaticMissions deleteAt _forEachIndex; + + throw format ["Mission (%1) Fail at %2 with message %3.",_missionName,_missionPos,_msgLose]; + }; + }; + + + if (DMS_MarkerText_ShowAICount_Static) then + { + private _dot = _markers select 0; + private _text = missionNamespace getVariable [format ["%1_text",_dot],_missionName]; + + if (DMS_MarkerText_ShowMissionPrefix) then + { + _text = format ["%1 %2",DMS_MarkerText_MissionPrefix,_text]; + }; + + _dot setMarkerText (format ["%1 (%2 %3 remaining)",_text,count (_inputAIUnits call DMS_fnc_GetAllUnits),DMS_MarkerText_AIName]); + }; + + + if (DMS_AllowStaticReinforcements) then + { + { + if (_x call DMS_fnc_GroupReinforcementsManager) then + { + _groupReinforcementsInfo deleteAt _forEachIndex; + }; + } forEach _groupReinforcementsInfo; + }; + + + if !(_onMonitorEnd isEqualTo {}) then + { + if (DMS_DEBUG) then + { + (format ["MissionsMonitor_Static :: Calling _onMonitorEnd (index %1): ""%2"". Code: %3",_forEachIndex,_missionName,_onMonitorEnd]) call DMS_fnc_DebugLog; + }; + _x call _onMonitorEnd; + }; + } + catch + { + if !(_onMonitorEnd isEqualTo {}) then + { + if (DMS_DEBUG) then + { + (format ["MissionsMonitor_Static :: Calling _onMonitorEnd (index %1): ""%2"". Code: %3",_forEachIndex,_missionName,_onMonitorEnd]) call DMS_fnc_DebugLog; + }; + _x call _onMonitorEnd; + }; + + + if (DMS_DEBUG) then + { + (format ["MissionsMonitor_Static :: %1",_exception]) call DMS_fnc_DebugLog; + }; + }; +} forEach DMS_StaticMission_Arr; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_OnKilled.sqf b/@ExileServer/addons/a3_dms/scripts/fn_OnKilled.sqf new file mode 100644 index 0000000..699ec70 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_OnKilled.sqf @@ -0,0 +1,370 @@ +/* + DMS_fnc_OnKilled + Created by eraser1 and Defent + Influenced by WAI + + Usage: + [ + _killedUnit, + _killer + ] call DMS_fnc_OnKilled; + ***Designed for use with the ArmA "MPKilled" EH. This function should not be explicitly called otherwise.*** +*/ +if (DMS_DEBUG) then +{ + (format ["OnKilled :: Logging AI death with parameters: %1",_this]) call DMS_fnc_DebugLog; +}; + +params +[ + "_unit", + "_killer" +]; +private _side = _unit getVariable ["DMS_AI_Side", "bandit"]; +private _type = _unit getVariable ["DMS_AI_Type", "soldier"]; +private _launcher = secondaryWeapon _unit; +private _launcherVar = _unit getVariable ["DMS_AI_Launcher",""]; +private _playerObj = objNull; + +_unit call ([missionNamespace getVariable [_unit getVariable ["DMS_AI_CustomOnKilledFnc",""],{}]] param [0,{},[{}]]); + +// Some of the previously used functions work with non-local argument. Some don't. BIS is annoying +private _removeAll = +{ + {_this removeWeaponGlobal _x;} forEach (weapons _this); + {_this unlinkItem _x;} forEach (assignedItems _this); + {_this removeItem _x;} forEach (items _this); + + removeAllItemsWithMagazines _this; + removeHeadgear _this; + removeUniform _this; + removeVest _this; + removeBackpackGlobal _this; +}; + +moveOut _unit; + +_unit removeAllEventHandlers "HandleDamage"; +_unit enableSimulationGlobal true; + +// Remove gear according to configs +if ((_unit getVariable ["DMS_clear_AI_body",DMS_clear_AI_body]) && {(random 100) <= (_unit getVariable ["DMS_clear_AI_body_chance",DMS_clear_AI_body_chance])}) then +{ + _unit call _removeAll; +}; + +if ((_unit getVariable ["DMS_ai_remove_launchers",DMS_ai_remove_launchers]) && {(_launcherVar != "") || {_launcher != ""}}) then +{ + // Because arma is stupid sometimes + if (_launcher isEqualTo "") then + { + _launcher = _launcherVar; + + diag_log "sneaky launchers..."; + + _unit spawn + { + uiSleep 0.5; + + { + _holder = _x; + { + if (_x isKindOf ["LauncherCore", configFile >> "CfgWeapons"]) exitWith + { + deleteVehicle _holder; + diag_log "gotcha"; + }; + } forEach (weaponCargo _holder); + } forEach (nearestObjects [_this, ["GroundWeaponHolder","WeaponHolderSimulated"], 5]); + }; + }; + + _unit removeWeaponGlobal _launcher; + + { + if (_x isKindOf ["CA_LauncherMagazine", configFile >> "CfgMagazines"]) then + { + _unit removeMagazineGlobal _x; + }; + } forEach (magazines _unit); +}; + +if (_unit getVariable ["DMS_RemoveNVG",DMS_RemoveNVG]) then +{ + _unit unlinkItem "NVGoggles"; +}; + +private _grp = group _unit; +private _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 (selectRandom _grpUnits); +}; + +private _av = _unit getVariable ["DMS_AssignedVeh",objNull]; +if (!isNull _av) then +{ + _av enableSimulationGlobal true; + + // Determine whether or not the vehicle has any active crew remaining. + private _memCount = {[(alive _x),false] select (_unit isEqualTo _x);} count (crew _av); + + + // Destroy the vehicle and add it to cleanup if there are no active crew members of the vehicle. + if (_memCount isEqualTo 0) then + { + /* + This is some pretty funky code because this is about the fastest way to do the task. + An "if-statement" inside another "if-statement" is almost as fast, but it isn't as slick ;) + */ + if + ( + call + ([ + { (random 100)<(_av getVariable ["DMS_DestructionChance",DMS_AI_destroyVehicleChance]) }, + { DMS_AI_destroyStaticWeapon && {(random 100)<(_av getVariable ["DMS_DestructionChance",DMS_AI_destroyStaticWeapon_chance])} } + ] select (_av isKindOf "StaticWeapon")) + ) then + { + _av setDamage [1, false]; + _av setVariable ["ExileDiedAt",time]; + + [if (_av isKindOf "Air") then {30} else {5}, {_this enableSimulationGlobal false}, _av, false, false] call ExileServer_system_thread_addTask; + + + if (DMS_DEBUG) then + { + (format["OnKilled :: Destroying used AI vehicle %1, and disabling simulation.",typeOf _av]) call DMS_fnc_DebugLog; + }; + } + else + { + if (local _av) then + { + _av lock 1; + } + else + { + [_av, 1] remoteExecCall ["lock", _av]; + }; + + _av call ExileServer_system_simulationMonitor_addVehicle; + + _av setVariable ["ExileMoney",0,true]; + _av setVariable ["ExileIsPersistent", false]; + _av addMPEventHandler ["MPKilled", { if (isServer) then {_this call ExileServer_object_vehicle_event_onMPKilled;};}]; + _av addEventHandler ["GetIn", {_this call ExileServer_object_vehicle_event_onGetIn}]; + + if (!isNil "AVS_Version") then + { + _av call AVS_fnc_sanitizeVehicle; + }; + + if (DMS_DEBUG) then + { + (format["OnKilled :: Unlocking used AI vehicle (%1).",typeOf _av]) call DMS_fnc_DebugLog; + }; + }; + } + else + { + // Only check for this stuff for ground vehicles that have guns... + if ((_av isKindOf "LandVehicle") && {(count (weapons _av))>0}) then + { + private _gunner = gunner _av; + private _driver = driver _av; + + + // The fact that I have to do this in the FUCKING ONKILLED EVENTHANDLER is a testament to why ArmA will make me die prematurely + private _gunnerIsAlive = alive _gunner; + private _driverIsAlive = alive _driver; + + if (_unit isEqualTo _gunner) then + { + _gunnerIsAlive = false; + }; + if (_unit isEqualTo _driver) then + { + _driverIsAlive = false; + }; + + // If the gunner is dead but the driver is alive, then the driver becomes the gunner. + // Helps with troll AI vehicles driving around aimlessly after the gunner is shot off. More realistic imo + if (!_gunnerIsAlive && {_driverIsAlive}) then + { + [_driver,_av,_killer] spawn + { + params + [ + "_driver", + "_av", + "_killer" + ]; + + private _grp = group _driver; + private _owner = groupOwner _grp; + + _grp setVariable ["DMS_LockLocality",true]; + + // The AI has to be local in order for these commands to work, so I reset locality, just because it's really difficult to deal with otherwise + if !(_owner in [2,0]) then + { + diag_log format ["DMS Seat Switcher :: Temporarily setting owner of %1 to server from %2. Success: %3",_grp,_owner,_grp setGroupOwner 2]; + }; + + uiSleep 5+(random 3); // 5 to 8 seconds delay after gunner death + + if !(alive _driver) exitWith {}; + + unassignVehicle _driver; + moveOut _driver; + + _driver disableCollisionWith _av; + + _av setVehicleAmmoDef 1; + + waitUntil + { + unassignVehicle _driver; + doGetOut _driver; + moveOut _driver; + (vehicle _driver)==_driver + }; + + _driver assignAsGunner _av; + [_driver] orderGetIn true; + + uiSleep 1.5; + if !(alive _driver) exitWith {}; + + _driver moveInGunner _av; + + _driver enableCollisionWith _av; + + if (DMS_DEBUG) then + { + (format["OnKilled :: Switched driver of AI Vehicle (%1) to gunner.",typeOf _av]) call DMS_fnc_DebugLog; + }; + + if !(_owner in [2,0]) then + { + private _start = time; + + // Controlling AI... yes. I have to do this + waitUntil + { + _driver assignAsGunner _av; + [_driver] orderGetIn true; + + _driver moveInGunner _av; + + (((gunner _av) isEqualTo _driver) || {(time-_start)>30}) + }; + + uiSleep 3; + + _start = time; + + waitUntil + { + _driver assignAsGunner _av; + [_driver] orderGetIn true; + + _driver moveInGunner _av; + + (((gunner _av) isEqualTo _driver) || {(time-_start)>30}) + }; + + _driver doTarget _killer; + _driver doSuppressiveFire _killer; + + uiSleep 15; + + diag_log format ["DMS Seat Switcher :: Resetting ownership of %1 to %2. Success: %3",_grp,_owner,_grp setGroupOwner _owner]; + }; + + _grp setVariable ["DMS_LockLocality",false]; + }; + }; + }; + }; +}; + +private _roadKilled = false; + +if (isPlayer _killer) then +{ + private _veh = vehicle _killer; + + _playerObj = _killer; + + + // Fix for players killing AI from mounted vehicle guns + if (!(_killer isKindOf "Exile_Unit_Player") && {!isNull (gunner _killer)}) then + { + _playerObj = gunner _killer; + }; + + + if (!(_veh isEqualTo _killer) && {(driver _veh) isEqualTo _killer} && {(_killer distance _unit)<10}) then + { + _playerObj = driver _veh; + + _roadKilled = true; + + if (_unit getVariable ["DMS_explode_onRoadkill",DMS_explode_onRoadkill]) then + { + private _boom = createVehicle ["SLAMDirectionalMine_Wire_Ammo", [0,0,100], [], 0, "CAN_COLLIDE"]; + _boom setPosATL (getPosATL _playerObj); + _boom setDamage 1; + if (DMS_DEBUG) then + { + (format ["OnKilled :: %1 roadkilled an AI! Creating mine at the roadkilled AI's position!",name _killer]) call DMS_fnc_DebugLog; + }; + }; + + + // Remove gear from roadkills if configured to do so + if ((_unit getVariable ["DMS_remove_roadkill",DMS_remove_roadkill]) && {(random 100) <= (_unit getVariable ["DMS_remove_roadkill_chance",DMS_remove_roadkill_chance])}) then + { + _unit call _removeAll; + }; + }; + + _unit setVariable ["DMS_KillerID",owner _playerObj]; + + + // Reveal the killer to the AI units + if (_unit getVariable ["DMS_ai_share_info",DMS_ai_share_info]) then + { + private _revealAmount = 3; + + private _muzzle = currentMuzzle _playerObj; + + if (_muzzle isEqualType "") then + { + private _silencer = _playerObj weaponAccessories _muzzle select 0; + if (!isNil "_silencer" && {_silencer != ""}) then + { + _revealAmount = 1.5; + }; + }; + + private _shareInfoDistance = _unit getVariable ["DMS_ai_share_info_distance",DMS_ai_share_info_distance]; + { + if ((_x distance2D _unit) <= _shareInfoDistance) then + { + _x reveal [_killer, _revealAmount]; + }; + } forEach _grpUnits; + }; +}; + + +[_playerObj, _unit, _side, _type, _roadKilled] call DMS_fnc_PlayerAwardOnAIKill; + + +// Let Exile handle the AI Body cleanup. +_unit setVariable ["ExileDiedAt",time]; +_unit setVariable ["DMS_KillerObj",[_playerObj,_killer] select (isNull _playerObj)]; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_PlayerAwardOnAIKill.sqf b/@ExileServer/addons/a3_dms/scripts/fn_PlayerAwardOnAIKill.sqf new file mode 100644 index 0000000..a8276ea --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_PlayerAwardOnAIKill.sqf @@ -0,0 +1,198 @@ +/* + DMS_fnc_PlayerAwardOnAIKill + Created by eraser1 + + Gives (or removes) a player's respect/poptabs for killing an AI. + + Usage: + [ + _playerObj, + _unit, + _AISide, + _AIType, + _roadKilled + ] call DMS_fnc_PlayerAwardOnAIKill; + + Returns nothing +*/ + +if !(params +[ + "_playerObj", + "_unit", + "_AISide", + "_AIType", + "_roadKilled" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_PlayerAwardOnAIKill with invalid parameters: %1",_this]; +}; + + +private _playerUID = getPlayerUID _playerObj; + +if ((!isNull _playerObj) && {(_playerUID != "") && {_playerObj isKindOf "Exile_Unit_Player"}}) then +{ + // Check for individually defined AI money/respect/rank. + private _moneyChange = _unit getVariable ["DMS_AI_Money",0]; + private _repChange = _unit getVariable ["DMS_AI_Respect",0]; + //private _unitRank = _unit getVariable ["DMS_AI_Rank",0]; + + + if (_roadKilled && {_unit getVariable ["DMS_Diff_RepOrTabs_on_roadkill",DMS_Diff_RepOrTabs_on_roadkill]}) then + { + _moneyChange = missionNamespace getVariable [format ["DMS_%1_%2_RoadkillMoney",_AISide,_AIType],0]; + _repChange = missionNamespace getVariable [format ["DMS_%1_%2_RoadkillRep",_AISide,_AIType],0]; + //_rankChange = missionNamespace getVariable [format ["DMS_%1_%2_RoadkillRank",_AISide,_AIType],0]; + }; + + + private _playerMoney = _playerObj getVariable ["ExileMoney", 0]; + private _playerRespect = _playerObj getVariable ["ExileScore", 0]; + //private _playerRank = _playerObj getVariable ["ExileHumanity", 0]; + private _unitName = name _unit; + private _distance = []; + + /* + if (DMS_DEBUG) then + { + format ["PlayerAwardOnAIKill :: Attempting to give %1 (%2) %3 poptabs and %4 respect and %5 rank. Player currently has %6 tabs and %7 respect and &8 rank.", name _playerObj, _playerUID, _moneyChange, _repChange, _rankChange,_playerMoney, _playerRespect,_playerRank] call DMS_fnc_DebugLog; + }; + */ + + + if (DMS_GiveMoneyToPlayer_OnAIKill && {_moneyChange!=0}) then + { + // Set client's money + _playerMoney = (_playerMoney + _moneyChange) max 0; //Also make sure that they don't get negative poptabs + _playerObj setVariable ["ExileMoney",_playerMoney,true]; + + if (DMS_Show_Kill_Poptabs_Notification) then + { + // Create and send message to player + private _msgParams = + if (_moneyChange > 0) then + { + ["SuccessTitleOnly",[format ["Gained %1 poptabs for killing %2 AI!",abs _moneyChange,_AIType]]]; + } + else + { + ["ErrorTitleOnly",[format ["Lost %1 poptabs for killing %2 AI!",abs _moneyChange,_AIType]]]; + }; + + // Send notification + [_playerObj, "toastRequest", _msgParams] call ExileServer_system_network_send_to; + + // Update money in database + format["setPlayerMoney:%1:%2", _playerMoney, _playerObj getVariable ["ExileDatabaseID", 0]] call ExileServer_system_database_query_fireAndForget; + }; + }; + + + if (DMS_GiveRespectToPlayer_OnAIKill && {_repChange!=0}) then + { + private _attributes = [[format ["KILLED %1",toUpper(_unitName)],_repChange]]; + + if (DMS_AIKill_DistanceBonusCoefficient>0) then + { + _distance = floor (_unit distance _playerObj); + + if (_distance>DMS_AIKill_DistanceBonusMinDistance) then + { + private _distanceBonus = floor (_distance * DMS_AIKill_DistanceBonusCoefficient); + _attributes pushBack [format ["%1m RANGE BONUS",_distance], _distanceBonus]; + + _repChange = _repChange + _distanceBonus; + }; + }; + + // Set client's respect + _playerRespect = _playerRespect + _repChange; + _playerObj setVariable ["ExileScore",_playerRespect]; + + if (DMS_Show_Kill_Respect_Notification) then + { + // Send frag message + [_playerObj, "showFragRequest", [_attributes]] call ExileServer_system_network_send_to; + }; + + // Update respect in database + format["setAccountScore:%1:%2", _playerRespect, _playerUID] call ExileServer_system_database_query_fireAndForget; + + // Send updated respect value to client + ExileClientPlayerScore = _playerRespect; + (owner _playerObj) publicVariableClient "ExileClientPlayerScore"; + ExileClientPlayerScore = nil; + }; + + + if (DMS_Show_Party_Kill_Notification) then + { + private _group = group _playerObj; + private _members = units _group; + + if ((count _members)>1) then + { + private _msg = format + [ + "%1 killed %2 from %3 meters away and received %4 poptabs, and %5 respect.", + name _playerObj, + _unitName, + if (_distance isEqualTo []) then {floor(_unit distance _playerObj)} else {_distance}, + _moneyChange, + _repChange + ]; + + /* + if (DMS_Enable_RankChange) then + { + _msg = _msg + format[" (+%1 rank)", _rankChange]; + }; + */ + + { + _msg remoteExecCall ["systemChat", _x]; + } forEach _members; + }; + }; + + + //DONKEYPUNCH CUSTOM KILL STAT ADD FOR AI KILL + if (DMS_Add_AIKill2DB) then + { + _newKillerFrags = _killer getVariable ["ExileKills", 0]; + _newKillerFrags = _newKillerFrags + 1; + _killer setVariable ["ExileKills", _newKillerFrags]; + format["addAccountKill:%1", getPlayerUID _killer] call ExileServer_system_database_query_fireAndForget; + ExileClientPlayerKills = _newKillerFrags; + (owner _playerObj) publicVariableClient "ExileClientPlayerKills"; + ExileClientPlayerKills = nil; + }; + + /* + //DONKEYPUNCH CUSTOM KILL RANK CHANGE FOR AI KILL + if (DMS_Enable_RankChange && {_rankChange!=0}) then + { + _playerRank = (_playerRank+_rankChange); + _killer setVariable ["ExileHumanity",_playerRank]; + format["modifyAccountHumanity:%1:%2",_rankChange,getPlayerUID _killer] call ExileServer_system_database_query_fireAndForget; + ExileClientPlayerHumanity = _playerRank; + (owner _playerObj) publicVariableClient "ExileClientPlayerHumanity"; + ExileClientPlayerHumanity = nil; + }; + */ + + + if (DMS_DEBUG) then + { + format ["PlayerAwardOnAIKill :: %1 (%2) awarded %3 poptabs and %4 respect for killing %5. Player's money is now %6, and respect is now %7. Roadkill: %8", name _playerObj, _playerUID, _moneyChange, _repChange, _unit, _playerMoney, _playerRespect, _roadKilled] call DMS_fnc_DebugLog; + }; +} +else +{ + if (DMS_DEBUG) then + { + format ["PlayerAwardOnAIKill :: No reward for non-player _playerObj: %1",_playerObj] call DMS_fnc_DebugLog; + }; +}; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_RemoveMarkers.sqf b/@ExileServer/addons/a3_dms/scripts/fn_RemoveMarkers.sqf new file mode 100644 index 0000000..7dd1639 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_RemoveMarkers.sqf @@ -0,0 +1,62 @@ +/* + DMS_fnc_RemoveMarkers + Created by eraser1 + + Usage: + [ + [ + _markerDot, + _markerCircle + ], + _status + ] call DMS_fnc_RemoveMarkers; +*/ + +private _markerDot = _this select 0 select 0; +private _markerCircle = _this select 0 select 1; +private _status = _this select 1; +private _text = missionNamespace getVariable [format ["%1_text",_markerDot],markerText _markerDot]; + + +if (DMS_DEBUG) then +{ + (format ["RemoveMarkers :: Calling DMS_RemoveMarkers with parameters %1.",_this]) call DMS_fnc_DebugLog; +}; + + +deleteMarker _markerCircle; +missionNamespace setVariable [format ["%1_pos",_markerDot], nil]; +missionNamespace setVariable [format ["%1_text",_markerDot], nil]; + +if (_status == "win") then +{ + if (!DMS_MissionMarkerWinDot) exitWith + { + deleteMarker _markerDot; + }; + _markerDot setMarkerText ("COMPLETED: "+_text); + _markerDot setMarkerColor DMS_MissionMarkerWinDotColor; + _markerDot setMarkerType DMS_MissionMarkerWinDot_Type; + //_markerDot spawn {sleep DMS_MissionMarkerWinDotTime;deleteMarker _this;}; + [DMS_MissionMarkerWinDotTime, {deleteMarker (_this select 0);}, [_markerDot], false] call ExileServer_system_thread_addTask; + if (DMS_DEBUG) then + { + (format ["RemoveMarkers :: %1 Marker will be removed in %2 seconds!",_markerDot,DMS_MissionMarkerWinDotTime]) call DMS_fnc_DebugLog; + }; +} +else +{ + if (!DMS_MissionMarkerLoseDot) exitWith + { + deleteMarker _markerDot; + }; + _markerDot setMarkerText ("FAILED: "+_text); + _markerDot setMarkerColor DMS_MissionMarkerLoseDotColor; + _markerDot setMarkerType DMS_MissionMarkerLoseDot_Type; + //_markerDot spawn {sleep DMS_MissionMarkerLoseDotTime;deleteMarker _this;}; + [DMS_MissionMarkerLoseDotTime, {deleteMarker (_this select 0);}, [_markerDot], false] call ExileServer_system_thread_addTask; + if (DMS_DEBUG) then + { + (format ["RemoveMarkers :: %1 Marker will be removed in %2 seconds!",_markerDot,DMS_MissionMarkerLoseDotTime]) call DMS_fnc_DebugLog; + }; +}; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SelectMagazine.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SelectMagazine.sqf new file mode 100644 index 0000000..aaaf5df --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SelectMagazine.sqf @@ -0,0 +1,19 @@ +/* + DMS_fnc_selectMagazine + Created by eraser1 + + Usage: + _weaponClassName call DMS_fnc_selectMagazine; + + Apply magazine type filters if needed +*/ + +private _result = ""; +private _magArray = getArray (configFile >> "CfgWeapons" >> _this >> "magazines"); + +if (count _magArray > 0) then +{ + _result = _magArray select 0; +}; + +_result diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SelectMission.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SelectMission.sqf new file mode 100644 index 0000000..63fbcbd --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SelectMission.sqf @@ -0,0 +1,122 @@ +/* + DMS_fnc_selectMission + Influenced by WAI + Created by eraser1 + + Selects/Spawns missions. Takes no arguments, returns nothing. +*/ + +private _time = diag_tickTime; +private _playerCount = count allPlayers; + +if (DMS_RunningBMissionCount >= DMS_MaxBanditMissions) then +{ + DMS_BMissionLastStart = _time; +}; + +if ((count DMS_RunningStaticMissions) >= DMS_MaxStaticMissions) then +{ + DMS_StaticMissionLastStart = _time; +}; + + + +if (diag_fps >= DMS_MinServerFPS && {_playerCount >= DMS_MinPlayerCount}) then +{ + if (DMS_DynamicMission && {_time - DMS_BMissionLastStart > DMS_BMissionDelay}) then + { + private _mission = selectRandom DMS_BanditMissionTypesArray; + + if (DMS_DEBUG) then + { + (format ["SelectMission :: Selected bandit mission: %1",_mission]) call DMS_fnc_DebugLog; + }; + + [_mission] call DMS_fnc_SpawnBanditMission; + + if (DMS_DEBUG) then + { + (format ["SelectMission :: Spawning of bandit mission ""%1"" complete!",_mission]) call DMS_fnc_DebugLog; + }; + }; + + + if (DMS_StaticMission && {_time - DMS_StaticMissionLastStart > DMS_StaticMissionDelay}) then + { + private _availableMissions = (DMS_StaticMissionTypesArray - DMS_RunningStaticMissions); + + if (_availableMissions isEqualTo []) exitWith + { + DMS_StaticMissionLastStart = _time; + if (DMS_DEBUG) then + { + (format ["SelectMission :: No available missions! Running missions: %1", DMS_RunningStaticMissions]) call DMS_fnc_DebugLog; + }; + }; + + private _mission = selectRandom _availableMissions; + + if (DMS_DEBUG) then + { + (format ["SelectMission :: Selected static mission: %1", _mission]) call DMS_fnc_DebugLog; + }; + + [_mission] call DMS_fnc_SpawnStaticMission; + + if (DMS_DEBUG) then + { + (format ["SelectMission :: Spawning of static mission ""%1"" complete!", _mission]) call DMS_fnc_DebugLog; + }; + }; + + + { + _x params + [ + "_mission", + "_minPlayers", + "_maxPlayers", + "_maxTimesPerRestart", + "_timeBetween" + ]; + + private _timesSpawned = missionNamespace getVariable format["DMS_SpecialMissionSpawnCount_%1",_mission]; + + if + ( + (_playerCount > _minPlayers) && + {_playerCount < _maxPlayers} && + {_maxTimesPerRestart > _timesSpawned} && + {(_time - (missionNamespace getVariable format["DMS_SpecialMissionLastSpawn_%1",_mission])) > _timeBetween} + ) then + { + private _missionCode = + [ + missionNamespace getVariable format + [ + "DMS_SpecialMission_%1", + _mission + ] + ] param [0, "no",[{}]]; + + + if (_missionCode isEqualTo "no") then + { + diag_log format ["DMS ERROR :: Attempting to spawn a special mission that isn't precompiled! Parameters: %1", DMS_SpecialMissions deleteAt _forEachIndex]; + } + else + { + missionNamespace setVariable [format["DMS_SpecialMissionSpawnCount_%1",_mission], _timesSpawned+1]; + + call _missionCode; + + missionNamespace setVariable [format["DMS_SpecialMissionLastSpawn_%1",_mission], _time]; + + if (DMS_DEBUG) then + { + (format ["SelectMission :: Spawned special mission %1. DMS_SpawnedSpecialMissions: %2", _mission, DMS_SpawnedSpecialMissions]) call DMS_fnc_DebugLog; + }; + }; + }; + } forEach DMS_SpecialMissions; +}; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SelectOffsetPos.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SelectOffsetPos.sqf new file mode 100644 index 0000000..16f35d3 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SelectOffsetPos.sqf @@ -0,0 +1,38 @@ +/* + DMS_fnc_SelectOffsetPos + Created by eraser1 + + Usage: + [ + _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 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 retained for compatibility. + +*/ + +if !(params +[ + "_origin", + "_dis", + "_dir" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_SelectOffsetPos with invalid parameters: %1",_this]; + [0,0,0] +}; + +/* +if ((count _origin) isEqualTo 2) then +{ + _origin set [2,0]; +}; +*/ + +//_origin vectorAdd [sin(_dir)*_dis,cos(_dir)*_dis,0] <-- Old code +_origin getPos [_dis,_dir] diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SelectRandomVal.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SelectRandomVal.sqf new file mode 100644 index 0000000..5948c37 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SelectRandomVal.sqf @@ -0,0 +1,25 @@ +/* + DMS_fnc_SelectRandomVal + Created by eraser1 + + Usage: + [ + _min, + _max + ] call DMS_fnc_SelectRandomVal; + + Returns a random value between _min and _max. + +*/ + +if !(params +[ + "_min", + "_max" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_SelectRandomVal with invalid parameters: %1",_this]; +}; + +_min + random(_max - _min) diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SetAILocality.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SetAILocality.sqf new file mode 100644 index 0000000..845408e --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SetAILocality.sqf @@ -0,0 +1,76 @@ +/* + DMS_fnc_SetAILocality + Created by Defent and eraser1 + + Usage: + [ + _groupOrUnit, + _posOrObject // Does not have to be defined if element 1 is a unit + ] call DMS_fnc_SetAILocality; + + Makes a random player within 3 KM of the AI unit or group the owner. + Offloading AI will improve server performance, but the unit will no longer be local, which will limit the server's control over it. + Could however have negative effects if target player has a potato PC. + + Returns true if a viable owner was found, false otherwise. +*/ + +private _AI = param [0,objNull,[objNull,grpNull]]; + +if (isNull _AI) exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_SetAILocality with null parameter; _this: %1",_this]; +}; + +private _AIType = typeName _AI; + +private _pos = if (_AIType isEqualTo "OBJECT") then {_AI} else {param [1,"",[objNull,[]],[2,3]]}; + +if (_pos isEqualTo "") exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_SetAILocality with invalid position; this: %1",_this]; +}; + + +private _client = objNull; + +{ + if ((alive _x) && {(_x distance2D _pos)<=3000}) exitWith + { + _client = _x; + }; +} forEach allPlayers; + + +if (!isNull _client) then +{ + private _swapped = if (_AIType isEqualTo "OBJECT") then {_AI setOwner (owner _client)} else {_AI setGroupOwner (owner _client)}; + + if (!_swapped) then + { + ExileServerOwnershipSwapQueue pushBack [_AI,_client]; + }; + + if (DMS_ai_offload_notifyClient) then + { + private _msg = format ["DMS :: AI %1 |%2| has been offloaded to you.",_AIType,_AI]; + _msg remoteExecCall ["systemChat", _client]; + _msg remoteExecCall ["diag_log", _client]; + }; + + if (DMS_DEBUG) then + { + (format ["SetAILocality :: Ownership swap of %1 (%4) to %2 (%3) is initialized. Initial swap attempt successful: %5",_AI, name _client, getPlayerUID _client, _AIType, _swapped]) call DMS_fnc_DebugLog; + }; + + true +} +else +{ + if (DMS_DEBUG) then + { + (format ["SetAILocality :: No viable client found for the ownership of %1! _pos: %2.",_AI,_pos]) call DMS_fnc_DebugLog; + }; + + false +}; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SetGroupBehavior.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SetGroupBehavior.sqf new file mode 100644 index 0000000..50c26be --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SetGroupBehavior.sqf @@ -0,0 +1,109 @@ +/* + DMS_fnc_SetGroupBehavior + Created by eraser1 + + Usage: + [ + _group, // GROUP or OBJECT: Group or unit whose behavior is to be changed. + _pos, // ARRAY (positionATL): Location for the AI to guard + _difficulty, // STRING: Difficulty of the AI + _behavior // (OPTIONAL) STRING: AI Behavior. Refer to: https://community.bistudio.com/wiki/setBehaviour + ] call DMS_fnc_SetGroupBehavior; + + Returns true if the call was completed +*/ + +if !(params +[ + "_group", + "_pos", + "_difficulty" +]) +then +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_SetGroupBehavior with invalid params: %1",_this]; +}; + +private _exit = false; + +try +{ + if (isNull _group) throw "_group is null!"; + + if (_group isEqualType objNull) then + { + if !(alive _group) throw "_group is a dead object!"; + + _group = group _group; + }; +} +catch +{ + _exit = true; + if (DMS_DEBUG) then + { + format["SetGroupBehavior :: Exiting function because %1", _exception] call DMS_fnc_DebugLog; + }; +}; + +if (_exit) exitWith {false}; + + +private _behavior = if ((count _this)>3) then {_this select 3;} else {"COMBAT"}; + + +_group setCombatMode "RED"; +_group setBehaviour _behavior; + + +_difficulty = + switch (toLower _difficulty) do + { + case "random": + { + selectRandom DMS_ai_skill_random; + }; + + case "randomdifficult": + { + selectRandom DMS_ai_skill_randomDifficult; + }; + + case "randomeasy": + { + selectRandom DMS_ai_skill_randomEasy; + }; + + case "randomintermediate": + { + selectRandom DMS_ai_skill_randomIntermediate; + }; + + default + { + _difficulty; + }; + }; + +private _radius = missionNamespace getVariable [format["DMS_AI_WP_Radius_%1",_difficulty],40]; + + +// Remove all previous waypoints +for "_i" from count (waypoints _group) to 1 step -1 do +{ + deleteWaypoint ((waypoints _group) select _i); +}; + +// Add waypoints around the center position. +for "_i" from 0 to 359 step 45 do +{ + private _npos = _pos getPos [_radius,_i]; + private _wp = _group addWaypoint [_npos,5]; + _wp setWaypointType "MOVE"; +}; + +_wp = _group addWaypoint [_pos,0]; +_wp setWaypointType "CYCLE"; + + +true diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SetGroupBehavior_Separate.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SetGroupBehavior_Separate.sqf new file mode 100644 index 0000000..485a9ad --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SetGroupBehavior_Separate.sqf @@ -0,0 +1,55 @@ +/* + DMS_fnc_SetGroupBehavior_Separate + created by eraser1 + + Takes in an array of unit(s), moves them to a temporary group, sets their behavior, then moves them back to the original group. + Use this function if you want to change the behavior of certain units in a group without adjusting the behavior of the whole group. + + Usage: + [ + [ // ARRAY of OBJECTs: Units whose behavior will be changed + _unit1, + _unit2, + ... + _unitN + ], + _finalGroup, // GROUP: The final group that the units will be moved to. + _pos, // ARRAY (positionATL): Location for the AI to guard + _difficulty, // STRING: Difficulty of the AI + _behavior // (OPTIONAL) STRING: AI Behavior. Refer to: https://community.bistudio.com/wiki/setBehaviour + ] call DMS_fnc_SetGroupBehavior_Separate; + + Returns true if behavior was successfully changed, false otherwise. +*/ + +if !(params +[ + "_units", + "_finalGroup", + "_pos", + "_difficulty" +]) +then +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_SetGroupBehavior_Separate with invalid params: %1",_this]; +}; + +private _behavior = if ((count _this)>3) then {_this select 3;} else {"COMBAT"}; + +private _tmpGroup = createGroup (side _finalGroup); + +_units joinSilent _tmpGroup; + +private _return = +[ + _tmpGroup, + _pos, + _difficulty, + _behavior +] call DMS_fnc_SetGroupBehavior; + +_units joinSilent _finalGroup; +deleteGroup _tmpGroup; + + +_return diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SetRelPositions.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SetRelPositions.sqf new file mode 100644 index 0000000..9868d1c --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SetRelPositions.sqf @@ -0,0 +1,42 @@ +/* + DMS_fnc_SetRelPositions + Created by eraser1 + + Usage: + [ + [ + _object1, + _object2, + ... + _objectN + ], + _newCenterPos + ] call DMS_fnc_SetRelPositions; + + This function will move a list of objects to a new location by calculating their center position, then their relative position from the center, and then place them in their corresponding relative positions in the new location. +*/ + +if !(params +[ + "_objects", + "_newCPos" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_setRelPositions with invalid parameters: %1",_this]; +}; + + +private _center = [_objects] call DMS_fnc_GetCenter; + +{ + private _relpos = (getPosATL _x) vectorDiff _center; + private _objPos = [_newCPos,_relpos] call DMS_fnc_CalcPos; + + _x setPosATL _objPos; + + if (DMS_DEBUG) then + { + format ["Setting %1 at %2; %3 is the relpos from original center %4, reapplied to new center %5",typeOf _x,_objPos,_relpos,_center,_newCPos] call DMS_fnc_DebugLog; + }; +} foreach _objects; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup.sqf new file mode 100644 index 0000000..24e4418 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup.sqf @@ -0,0 +1,128 @@ +/* + DMS_fnc_SpawnAIGroup + Created by eraser1 + Based off of WAI + + Usage: + [ + _pos, // ARRAY (positionATL): Position of AI + _count, // SCALAR: Number of AI + _difficulty, // STRING: AI Difficulty: "random","hardcore","difficult","moderate", or "easy" + _class, // STRING: AI Class: "random","assault","MG", or "sniper" OR [_class,_launcherType] + _side, // STRING: Only "bandit" is supported by default + _customGearSet // (OPTIONAL) ARRAY: Manually defined AI gear. Refer to functional documentation of fn_SpawnAISoldier.sqf for more info: https://github.com/Defent/DMS_Exile/blob/master/%40ExileServer/addons/a3_dms/scripts/fn_SpawnAISoldier.sqf + ] call DMS_fnc_SpawnAIGroup; + + Returns AI Group +*/ + +if !(params +[ + "_pos", + "_count", + "_difficulty", + "_class", + "_side" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_SpawnAIGroup with invalid parameters: %1",_this]; + grpNull +}; + +if (DMS_DEBUG) then +{ + (format["SpawnAIGroup :: Spawning %1 %2 %3 AI at %4 with %5 difficulty.",_count,_class,_side,_pos,_difficulty]) call DMS_fnc_DebugLog; +}; + + +private _launcherType = ""; + +// if soldier have AT/AA weapons +if (_class isEqualType []) then +{ + _launcherType = _class select 1; + _class = _class select 0; +}; + + +private _customGearSet = []; + +if (_class == "custom") then +{ + if ((count _this)>5) then + { + _customGearSet = _this select 5; + } + else + { + diag_log format["DMS ERROR :: Calling DMS_fnc_SpawnAIGroup with custom class without defining _customGearSet! Setting _class to ""random"" _this: %1",_this]; + _class = "random"; + }; +}; + + +_group = createGroup (missionNamespace getVariable [format ["DMS_%1Side",_side],EAST]); + +_group setVariable ["DMS_LockLocality",true]; // Lock locality until all units are spawned +_group setVariable ["DMS_SpawnedGroup",true]; +_group setVariable ["DMS_Group_Side", _side]; + +for "_i" from 1 to _count do +{ + _unit = [_group,_pos,_class,_difficulty,_side,"Soldier",_customGearSet] call DMS_fnc_SpawnAISoldier; +}; + +// An AI will definitely spawn with a launcher if you define type +if (DMS_ai_use_launchers || {!(_launcherType isEqualTo "")}) then +{ + if (_launcherType isEqualTo "") then + { + _launcherType = "AT"; + }; + + private _units = units _group; + private _launchers = missionNamespace getVariable [format ["DMS_AI_wep_launchers_%1",_launcherType],DMS_AI_wep_launchers_AT]; + + for "_i" from 0 to ((DMS_ai_launchers_per_group min _count)-1) do + { + if ((random 100) 0): Number of AI + _difficulty, // STRING: AI Difficulty: "random","hardcore","difficult","moderate", or "easy" + _class, // STRING: AI Class: "random","assault","MG","sniper" or "unarmed" OR [_class,_launcherType] + _side // STRING: Only "bandit" is supported atm + _customGearSet // (OPTIONAL) ARRAY: Manually defined AI gear. Refer to functional documentation of fn_SpawnAISoldier.sqf for more info: https://github.com/Defent/DMS_Exile/blob/master/%40ExileServer/addons/a3_dms/scripts/fn_SpawnAISoldier.sqf + ] call DMS_fnc_SpawnAIGroup_MultiPos; + + Returns AI Group +*/ + +if !(params +[ + "_positions", + "_count", + "_difficulty", + "_class", + "_side" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_SpawnAIGroup_MultiPos with invalid parameters: %1",_this]; + grpNull +}; + +private _positionsCount = count _positions; + +if (_positionsCount<1) exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_SpawnAIGroup_MultiPos with an empty list of positions! _this: %1",_this]; + grpNull +}; + +if (_count < 1) exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_SpawnAIGroup_MultiPos with less than 1 _count! _this: %1",_this]; + grpNull +}; + + +if (DMS_DEBUG) then +{ + (format["SpawnAIGroup_MultiPos :: Spawning %1 %2 %3 AI at positions %4 with %5 difficulty.",_count,_class,_side,_positions,_difficulty]) call DMS_fnc_DebugLog; +}; + + +private _launcherType = ""; + +// if soldier have AT/AA weapons +if (_class isEqualType []) then +{ + _launcherType = _class select 1; + _class = _class select 0; +}; + + +_customGearSet = []; + +if (_class == "custom") then +{ + if ((count _this)>5) then + { + _customGearSet = _this select 5; + } + else + { + diag_log format["DMS ERROR :: Calling DMS_fnc_SpawnAIGroup with custom class without defining _customGearSet! Setting _class to ""random"" _this: %1",_this]; + _class = "random"; + }; +}; + + + +private _group = createGroup (missionNamespace getVariable [format ["DMS_%1Side",_side],EAST]); + +_group setVariable ["DMS_LockLocality",true]; // Lock locality until all units are spawned +_group setVariable ["DMS_SpawnedGroup",true]; +_group setVariable ["DMS_Group_Side", _side]; + +for "_i" from 1 to _count do +{ + private _unit = [_group,_positions select (_i % _positionsCount),_class,_difficulty,_side,"Soldier",_customGearSet] call DMS_fnc_SpawnAISoldier; +}; + +// An AI will definitely spawn with a launcher if you define type +if (DMS_ai_use_launchers || {!(_launcherType isEqualTo "")}) then +{ + if (_launcherType isEqualTo "") then + { + _launcherType = "AT"; + }; + + private _units = units _group; + private _launchers = missionNamespace getVariable [format ["DMS_AI_wep_launchers_%1",_launcherType],DMS_AI_wep_launchers_AT]; + + for "_i" from 0 to ((DMS_ai_launchers_per_group min _count)-1) do + { + if ((random 100)6}) then + { + _customGearSet = _this select 6; + }; +}; + +_difficulty = + switch (toLower _difficulty) do + { + case "random": + { + selectRandom DMS_ai_skill_random; + }; + + case "randomdifficult": + { + selectRandom DMS_ai_skill_randomDifficult; + }; + + case "randomeasy": + { + selectRandom DMS_ai_skill_randomEasy; + }; + + case "randomintermediate": + { + selectRandom DMS_ai_skill_randomIntermediate; + }; + + default + { + _difficulty; + }; + }; + + +//Create unit +private _unit = _group createUnit [DMS_AI_Classname, _pos, [], 0,"FORM"]; +_unit allowFleeing 0; + +// Remove existing gear +{_unit removeWeaponGlobal _x;} forEach (weapons _unit); +{_unit unlinkItem _x;} forEach (assignedItems _unit); +{_unit removeItem _x;} forEach (items _unit); +removeAllItemsWithMagazines _unit; +removeHeadgear _unit; +removeUniform _unit; +removeVest _unit; +removeBackpackGlobal _unit; + + +if (_class in DMS_ai_SupportedRandomClasses) then +{ + _class = selectRandom (missionNamespace getVariable [format["DMS_%1_AI",_class], DMS_random_AI]); +}; + +// Set random DMS unit names if you don't want Arma assigned (real names) +switch (DMS_AI_NamingType) do +{ + case 1: + { + _unit setName format["[DMS %1 %2 %3]",toUpper _side,_class,floor(random 1000)]; + }; + + case 2: + { + _unit setName format["%1 %2", selectRandom DMS_AI_FirstNames, selectRandom DMS_AI_LastNames]; + }; + + default {}; // Default ArmA names otherwise... +}; + + +if (_customGearSet isEqualTo []) then +{ + // Make sure the "_class" is supported. This check is moved here to maintain backwards compatibility. + if !(_class in DMS_ai_SupportedClasses) exitWith + { + diag_log format ["DMS ERROR :: DMS_SpawnAISoldier called with unsupported _class: %1 | _this: %2",_class,_this]; + }; + + + // Add Clothes first to make sure the unit can store everything... + _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])); + + + // Equipment (Stuff that goes in the toolbelt slots) + { + if (_x in ["Binocular","Rangefinder","Laserdesignator","Laserdesignator_02","Laserdesignator_03"]) then + { + _unit addWeapon _x; + } + else + { + _unit linkItem _x; + }; + } forEach (missionNamespace getVariable [format ["DMS_%1_equipment",_class],[]]); + + + + // Random items that can be added to the unit's inventory, such as food, meds, etc. + private _randItemCount = missionNamespace getVariable [format ["DMS_%1_RandItemCount",_class],0]; + if (_randItemCount>0) then + { + private _randItems = missionNamespace getVariable [format ["DMS_%1_RandItems",_class],["Exile_Item_PlasticBottleFreshWater"]]; + for "_i" from 1 to _randItemCount do + { + _unit addItem (selectRandom _randItems); + }; + }; + + + // Items (Loot stuff that goes in uniform/vest/backpack) + {_unit addItem _x;} forEach (missionNamespace getVariable [format ["DMS_%1_items",_class],[]]); + + // Make AI effective at night + private _nighttime = (sunOrMoon != 1); + if (_nighttime) then + { + _unit linkItem "NVGoggles"; + }; + + + private _weapon = selectRandom (missionNamespace getVariable [format ["DMS_%1_weps",_class],DMS_assault_weps]); + [_unit, _weapon, 6 + floor(random 3)] call DMS_fnc_AddWeapon; + _unit selectWeapon _weapon; + + +#ifdef USE_EXTRA_CHECKING + // "Guaranteed" method of finding/adding weapon attachments. + if ((random 100) <= (missionNamespace getVariable [format["DMS_%1_optic_chance",_class],0])) then + { + private _optic = selectRandom + ( + (missionNamespace getVariable [format ["DMS_%1_optics",_class],DMS_assault_optics]) arrayIntersect + (getArray (configfile >> "CfgWeapons" >> _weapon >> "WeaponSlotsInfo" >> "CowsSlot")) + ); + + if !(isNil "_optic") then + { + _unit addPrimaryWeaponItem _optic; + }; + }; + + if (_nighttime && {(random 100) <= DMS_ai_nighttime_accessory_chance}) then + { + private _accessory = selectRandom (getArray (configfile >> "CfgWeapons" >> _weapon >> "WeaponSlotsInfo" >> "PointerSlot")); + + if !(isNil "_accessory") then + { + _unit addPrimaryWeaponItem _accessory; + }; + }; + + if ((random 100) <= (missionNamespace getVariable [format["DMS_%1_bipod_chance",_class],0])) then + { + private _bipod = selectRandom + ( + DMS_AI_BipodList arrayIntersect + (getArray (configfile >> "CfgWeapons" >> _weapon >> "WeaponSlotsInfo" >> "UnderBarrelSlot")) + ); + + if !(isNil "_bipod") then + { + _unit addPrimaryWeaponItem _bipod; + }; + }; + +#else + // "Regular" method of finding/adding weapon attachments. + if ((random 100) <= (missionNamespace getVariable [format["DMS_%1_optic_chance",_class],0])) then + { + _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 (selectRandom ["acc_pointer_IR","acc_flashlight"]); + }; + + if ((random 100) <= (missionNamespace getVariable [format["DMS_%1_bipod_chance",_class],0])) then + { + _unit addPrimaryWeaponItem (selectRandom DMS_AI_BipodList); + }; + +#endif + + + if ((random 100) <= (missionNamespace getVariable [format["DMS_%1_suppressor_chance",_class],0])) then + { + private _suppressor = _weapon call DMS_fnc_FindSuppressor; + if (_suppressor != "") then + { + _unit addPrimaryWeaponItem _suppressor; + }; + }; + + /* + // In case spawn position is water + if (DMS_ai_enable_water_equipment && {surfaceIsWater _pos}) then + { + removeHeadgear _unit; + removeAllWeapons _unit; + _unit forceAddUniform "U_O_Wetsuit"; + _unit addVest "V_RebreatherIA"; + _unit addGoggles "G_Diving"; + [_unit, "arifle_SDAR_F", 4 + floor(random 3), "20Rnd_556x45_UW_mag"] call DMS_fnc_AddWeapon; + }; + */ + + private _pistols = missionNamespace getVariable [format ["DMS_%1_pistols",_class],[]]; + if !(_pistols isEqualTo []) then + { + private _pistol = selectRandom _pistols; + [_unit, _pistol, 2 + floor(random 2)] call DMS_fnc_AddWeapon; + }; + + // Infinite Ammo. This will NOT work if AI unit is offloaded to client. + // Removed because there isn't much need for this. + // _unit addeventhandler ["Fired", {(vehicle (_this select 0)) setvehicleammo 1;}]; +} +else +{ + if !(_customGearSet params + [ + ["_weapon","",[""]], + ["_weaponAttachments",[],[[]]], + ["_magazines",[],[[]]], + ["_pistol","",[""]], + ["_pistolAttachments",[],[[]]], + ["_assignedItems",[],[[]]], + ["_launcher","",[""]], + ["_helmet","",[""]], + ["_uniform","",[""]], + ["_vest","",[""]], + ["_backpack","",[""]] + ]) + then + { + diag_log format ["DMS ERROR :: Calling DMS_SpawnAISoldier with invalid _customGearSet: %1 | _this: %2",_customGearSet,_this]; + }; + + if (DMS_DEBUG) then + { + (format ["SpawnAISoldier :: Equipping unit %1 with _customGearSet: %2",_unit,_customGearSet]) call DMS_fnc_DebugLog; + }; + + // Clothes + if !(_helmet isEqualTo "") then + { + _unit addHeadgear _helmet; + }; + + if !(_uniform isEqualTo "") then + { + _unit forceAddUniform _uniform; + }; + + if !(_vest isEqualTo "") then + { + _unit addVest _vest; + }; + + if !(_backpack isEqualTo "") then + { + _unit addBackpackGlobal _backpack; + }; + + if !(_launcher isEqualTo "") then + { + _unit addWeapon _launcher; + }; + + + // Add pistol and attachments + if !(_pistol isEqualTo "") then + { + _unit addWeapon _pistol; + + { + _unit addHandgunItem _x; + } forEach _pistolAttachments; + }; + + + // Add gun and attachments + if !(_weapon isEqualTo "") then + { + _unit addWeapon _weapon; + + { + _unit addPrimaryWeaponItem _x; + } forEach _weaponAttachments; + + _unit selectWeapon _weapon; + }; + + + // Add magazines and items about half a second after spawning so that backpack inventory can be used reliably. Thanks to second_coming for reporting this issue. + [ + 0.5, + { + params + [ + "_unit", + "_magazines", + "_assignedItems" + ]; + + { + if (_x isEqualType "") then + { + _x = [_x,1]; + }; + _unit addMagazines _x; + } forEach _magazines; + + { + if (_x in ["Binocular","Rangefinder","Laserdesignator","Laserdesignator_02","Laserdesignator_03"]) then + { + _unit addWeapon _x; + } + else + { + _unit linkItem _x; + }; + } forEach _assignedItems; + }, + [_unit,_magazines,_assignedItems], + false, + false + ] call ExileServer_system_thread_addTask; +}; + +// Give default items +{ + // "Why doesn't linkItem work with any of these? Because fuck you, that's why" - BIS + if (_x in ["Binocular","Rangefinder","Laserdesignator","Laserdesignator_02","Laserdesignator_03"]) then + { + _unit addWeapon _x; + } + else + { + _unit linkItem _x; + }; +} forEach DMS_ai_default_items; + + + + +// Soldier killed event handler +_unit addMPEventHandler ["MPKilled",'if (isServer) then {_this call DMS_fnc_OnKilled;};']; + + + +// Remove ramming damage from players. +// Will not work if unit is not local (offloaded) +if (DMS_ai_disable_ramming_damage) then +{ + _unit addEventHandler ["HandleDamage", + { + _dmg = _this select 2; + _source = _this select 3; + _projectile = _this select 4; + + if ((_projectile isEqualTo "") && {isPlayer _source}) then + { + _dmg = 0; + }; + + _dmg + }]; +}; + + +// Tweak difficulty stuff. +{ + _unit setSkill _x; +} forEach (missionNamespace getVariable [format["DMS_ai_skill_%1",_difficulty],[]]); + +if (_difficulty == "hardcore") then +{ + // Make him a little bit harder ;) + { + _unit disableAI _x; + } forEach ["SUPPRESSION", "AIMINGERROR"]; +}; + +if (_difficulty == "easy") then +{ + // Disable visibility raycasts for "easy" AI. + _unit disableAI "CHECKVISIBLE"; +}; + +_unit setCustomAimCoef (missionNamespace getVariable [format["DMS_AI_AimCoef_%1",_difficulty], 0.7]); +_unit enableStamina (missionNamespace getVariable [format["DMS_AI_EnableStamina_%1",_difficulty], true]); + + + +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"; +}; + + +// Set info variables +_unit setVariable ["DMS_AISpawnTime", time]; +_unit setVariable ["DMS_AI_Side", _side]; +_unit setVariable ["DMS_AI_Type", _type]; + +// Set money/respect variables +_unit setVariable +[ + "DMS_AI_Money", + missionNamespace getVariable [format ["DMS_%1_%2_MoneyGain",_side,_type],0] +]; +_unit setVariable +[ + "DMS_AI_Respect", + missionNamespace getVariable [format ["DMS_%1_%2_RepGain",_side,_type],0] +]; + + +private _AIMoney = + if (DMS_Spawn_AI_With_Money) then + { + private _base_money_amount = missionNamespace getVariable [format["DMS_%1_%2_SpawnMoney",_side,_type], 0]; + private _population_bonus = DMS_AIMoney_PopulationMultiplier * (if (isNil '_playerCount') then {count allPlayers} else {_playerCount}); + _base_money_amount + _population_bonus + } + else + { + 0 + }; + +_unit setVariable +[ + "ExileMoney", + _AIMoney, + true +]; + + +if (DMS_DEBUG) then +{ + (format ["SpawnAISoldier :: Spawned a %1 %2 %6 AI at %3 with %4 difficulty carrying %7 poptabs to group %5",_class,_side,_pos,_difficulty,_group,_type,_AIMoney]) call DMS_fnc_DebugLog; +}; + + +[_unit] joinSilent _group; + + +_unit diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIStaticMG.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIStaticMG.sqf new file mode 100644 index 0000000..4f369e2 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIStaticMG.sqf @@ -0,0 +1,87 @@ +/* + DMS_fnc_SpawnAIStaticMG + Created by eraser1 + Influenced by WAI + + Usage: + [ + [ // Array of static gun positions + _pos1, + _pos2, + ... + _pos3 + ], + _group, // GROUP: Group to which the AI unit(s) belongs to + _class, // STRING: "random","assault","MG","sniper" or "unarmed" + _difficulty, // STRING: "random","static","hardcore","difficult","moderate", or "easy" + _side, // STRING: "bandit","hero", etc. + _MGClass // (OPTIONAL) STRING: classname of the MG. Use "random" to select a random one from DMS_static_weapons + ] call DMS_fnc_SpawnAIStaticMG; + + Returns an array of static gun objects. +*/ + +if !(params +[ + "_positions", + "_group", + "_class", + "_difficulty", + "_side" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_SpawnAIStaticMG with invalid parameters: %1",_this]; +}; + +private _MGClassInput = + if ((count _this)>5) then + { + _this select 5 + } + else + { + "random" + }; + + +private _guns = _positions apply +{ + private _MGClass = _MGClassInput; + if (_MGClass == "random") then + { + _MGClass = selectRandom DMS_static_weapons; + }; + + private _gun = createVehicle [_MGClass, [0,0,0], [], 0, "CAN_COLLIDE"]; + _gun setDir (random 360); + _gun setPosATL _x; + _gun lock 2; + + _group addVehicle _gun; + + private _unit = [_group,_x,_class,_difficulty,_side,"Static"] call DMS_fnc_SpawnAISoldier; + + _unit moveInGunner _gun; + reload _unit; + _unit setVariable ["DMS_AssignedVeh",_gun]; + + if (_group getVariable ["DMS_isGroupFrozen",false]) then + { + _unit enableSimulationGlobal false; + }; + + if (DMS_DEBUG) then + { + (format ["SpawnAIStaticMG :: Created unit %1 at %2 as static gunner in %3",_unit,_x,_gun]) call DMS_fnc_DebugLog; + }; + _gun +}; + + +if (DMS_DEBUG) then +{ + (format ["SpawnAIStaticMG :: Created %1 static AI with parameters: %2",count _positions,_this]) call DMS_fnc_DebugLog; +}; + +_guns diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIVehicle.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIVehicle.sqf new file mode 100644 index 0000000..0bee2dc --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIVehicle.sqf @@ -0,0 +1,104 @@ +/* + DMS_fnc_SpawnAIVehicle + Created by eraser1 + + Usage: + [ + [ + _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. <--- 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" + _difficulty, // Difficulty: "random","static","hardcore","difficult","moderate", or "easy" + _side, // "bandit","hero", etc. + _vehClass // (OPTIONAL) String: classname of the Vehicle. Use "random" to select a random one from DMS_ArmedVehicles + ] call DMS_fnc_SpawnAIVehicle; + + Returns the spawned vehicle. +*/ + +if !(params +[ + "_positions", + "_group", + "_class", + "_difficulty", + "_side" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_SpawnAIVehicle with invalid parameters: %1",_this]; +}; + + +_spawnPos = _positions select 0; + +private _vehClass = + if ((count _this)>5) then + { + param [5,"random",[""]] + } + else + { + "random" + }; + +if (_vehClass == "random") then +{ + _vehClass = selectRandom DMS_ArmedVehicles; +}; + + +private _veh = createVehicle [_vehClass, _spawnPos, [], 0, "NONE"]; + +clearWeaponCargoGlobal _veh; +clearItemCargoGlobal _veh; +clearBackpackCargoGlobal _veh; + +if (getNumber (configFile >> "CfgSettings" >> "VehicleSpawn" >> "nightVision") isEqualTo 0) then +{ + _veh disableNVGEquipment true; +}; +if (getNumber (configFile >> "CfgSettings" >> "VehicleSpawn" >> "thermalVision") isEqualTo 0) then +{ + _veh disableTIEquipment true; +}; + + +_veh engineOn true; +_veh lock 2; + +_group addVehicle _veh; + +private _toFreeze = _group getVariable ["DMS_isGroupFrozen",false]; + +private _driver = [_group,_spawnPos,_class,_difficulty,_side,"Vehicle"] call DMS_fnc_SpawnAISoldier; +_driver moveInDriver _veh; +_driver setVariable ["DMS_AssignedVeh",_veh]; + +if (_toFreeze) then +{ + _driver enableSimulationGlobal false; +}; + +private _crewCount = +{ + private _unit = [_group,_spawnPos,_class,_difficulty,_side,"Vehicle"] call DMS_fnc_SpawnAISoldier; + _unit moveInTurret [_veh, _x]; + _unit setVariable ["DMS_AssignedVeh",_veh]; + if (_toFreeze) then + { + _unit enableSimulationGlobal false; + }; + true +} count (allTurrets [_veh, true]); + + +if (DMS_DEBUG) then +{ + (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 new file mode 100644 index 0000000..e5870f6 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnBanditMission.sqf @@ -0,0 +1,45 @@ +/* + DMS_fnc_SpawnBanditMission + Created by eraser1 + + Usage: + [ + _missionType, + _parameters + ] call DMS_fnc_SpawnBanditMission; + + Simply spawns a mission with the given mission type and passes parameters to it. Returns nothing +*/ + +private _missionName = _this param [0,selectRandom DMS_BanditMissionTypesArray, [""]]; +private _missionCode = +[ + missionNamespace getVariable format + [ + "DMS_Mission_%1", + _missionName + ] +] param [0, "no",[{}]]; + +if (_missionCode isEqualTo "no") then +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_SpawnBanditMission for a mission that isn't in DMS_BanditMissionTypesArray! Parameters: %1",_this]; +} +else +{ + private _parameters = if ((count _this)>1) then {_this select 1} else {[]}; + + DMS_MissionCount = DMS_MissionCount + 1; + DMS_RunningBMissionCount = DMS_RunningBMissionCount + 1; + DMS_BMissionDelay = DMS_TimeBetweenMissions call DMS_fnc_SelectRandomVal; + + _parameters call _missionCode; + + DMS_BMissionLastStart = diag_tickTime; + + + if (DMS_DEBUG) then + { + (format ["SpawnBanditMission :: Spawned mission %1 with parameters (%2) | DMS_BMissionDelay set to %3 seconds", _missionName, _parameters, DMS_BMissionDelay]) call DMS_fnc_DebugLog; + }; +}; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnCrate.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnCrate.sqf new file mode 100644 index 0000000..c80d331 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnCrate.sqf @@ -0,0 +1,63 @@ +/* + DMS_fnc_SpawnCrate + Created by eraser1 + + Usage: + [ + _crateClassName, // STRING: The classname of the crate you want to spawn. + _pos, // ARRAY (position): Where to spawn the crate. + _spawnATL // (OPTIONAL) BOOLEAN: Whether or not to spawn the crate ATL (Above Terrain Level) or ASL (Above Sea Level). Default: true (ATL) + ] call DMS_fnc_SpawnCrate; + Returns crate object + +*/ + +if !(params +[ + "_crateClassName", + "_pos" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_SpawnCrate with invalid parameters: %1",_this]; + objNull +}; + +if !(isClass (configFile >> "CfgVehicles" >> _crateClassName)) exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_SpawnCrate with non-existent vehicle className: %1",_crateClassName]; + objNull +}; + +private _spawnATL = if ((count _this)>2) then {_this select 2} else {true}; + +private _crate = createVehicle [_crateClassName,_pos,[], 0, "CAN_COLLIDE"]; + +_crate setDir (random 360); + +if (_spawnATL) then +{ + _crate setPosATL _pos; +} +else +{ + _crate setPosASL _pos; +}; + +_crate allowDamage false; +_crate enableSimulationGlobal false; +_crate enableRopeAttach false; + +clearWeaponCargoGlobal _crate; +clearItemCargoGlobal _crate; +clearMagazineCargoGlobal _crate; +clearBackpackCargoGlobal _crate; + +_crate setVariable ["ExileMoney",0,true]; + +if (DMS_HideBox) then +{ + _crate hideObjectGlobal true; +}; + +_crate; 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..712b6fb --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnHeliReinforcement.sqf @@ -0,0 +1,172 @@ +/* + DMS_fnc_SpawnHeliReinforcement + Created by eraser1 + + 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. + _maxJumpers, // SCALAR: Maximum number of AI to eject from the aircraft. Set to a really high # to ignore (like 999). + _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. +*/ + +if !(params +[ + "_AIGroup", + "_class", + "_difficulty", + "_side", + "_dropPoint", + "_ejectFFVGunners", + "_maxJumpers", + "_remainAsGunship" +]) +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 +}; + +private _heliClass = if ((count _this)>8) then {_this param [8, "", [""]]} 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 +private _spawnPos = + if ((count _this)>9) then + { + _this param [9, [0,0,0], [[]], [2,3]] + } + else + { + [ + _dropPoint, + DMS_RHeli_MinDistFromDrop, + DMS_RHeli_MaxDistFromDrop, + [ + 0, + 0, + 0, + 0, + 0, + 0, + DMS_RHeli_MinDistFromPlayers, + 0, + false + ] + ] call DMS_fnc_FindSafePos_InRange + }; +_spawnPos set [2,DMS_RHeli_Height]; + + + +// Spawn the heli +private _heli = createVehicle [_heliClass, _spawnPos, [], 0, "FLY"]; +_heli setFuel 1; +_heli engineOn true; +_heli lock 2; + +_AIGroup addVehicle _heli; + + +// Spawn the AI paratroopers +private _paratrooperCount = 0; +private _units = (fullCrew [_heli, "", true]) apply +{ + _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]; + _unit setDestination [_dropPoint, "VEHICLE PLANNED", true]; + }; + + case "commander"; + case "gunner"; + case "turret": + { + if (_ejectFFVGunners && {_personTurret} && {_paratrooperCount < _maxJumpers}) then + { + _unit = [_AIGroup,_spawnPos,_class,_difficulty,_side,"Paratroopers"] call DMS_fnc_SpawnAISoldier; + + _unit setVariable ["DMS_Paratrooper", true]; + _paratrooperCount = _paratrooperCount + 1; + } + else + { + _unit = [_AIGroup,_spawnPos,_class,_difficulty,_side,"Vehicle"] call DMS_fnc_SpawnAISoldier; + _unit setVariable ["DMS_AssignedVeh",_heli]; + }; + + _unit moveInTurret [_heli, _turretPath]; + }; + + case "cargo": + { + if (_paratrooperCount < _maxJumpers) then + { + _unit = [_AIGroup,_spawnPos,_class,_difficulty,_side,"Paratroopers"] call DMS_fnc_SpawnAISoldier; + _unit moveInCargo [_heli, _cargoIndex]; + + _unit setVariable ["DMS_Paratrooper", true]; + _paratrooperCount = _paratrooperCount + 1; + }; + }; + }; + + _unit +}; + + +// Set the heli pilot's behavior. +_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,count _units,_spawnPos,_difficulty,_AIGroup,_dropPoint,_units]) call DMS_fnc_DebugLog; +}; + +// Add the necessary information to the monitor. +DMS_HeliParatrooper_Arr pushBack [_heli, _dropPoint, _remainAsGunship]; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnMinefield.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnMinefield.sqf new file mode 100644 index 0000000..44156a1 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnMinefield.sqf @@ -0,0 +1,110 @@ +/* + DMS_fnc_SpawnMinefield + Created by eraser1 + + Usage: + [ + _centerPos, // ARRAY: Position to spawn the minefield around + _difficulty, // STRING or ARRAY: The "difficulty" level of the minefield. Determines the number of mines and the radius it spawns at. String refers to a difficulty set in config, array is defined as [_mineCount,_radius]; + _side, // STRING: The "side" for which the mines should spawn. The spawned mines will be revealed to the AI so they don't run into it. + _spawnWarningSign, // (OPTIONAL) BOOL: Whether or not to spawn the warning signs around the minefield (at maximum radius + 2 meters) + _mineClassname // (OPTIONAL) STRING: The classname of the mine to spawn. + ] call DMS_fnc_SpawnMinefield; +*/ + +private _mines = []; + +if (DMS_SpawnMinesAroundMissions) then +{ + if !(params + [ + "_centerPos", + "_difficulty", + "_side" + ]) + exitWith + { + diag_log format ["DMS ERROR :: Calling DMS_fnc_SpawnMinefield with invalid parameters: %1",_this]; + }; + + _spawnWarningSign = DMS_SpawnMineWarningSigns; + _mineClassname = "ATMine"; + if ((count _this)>3) then + { + _spawnWarningSign = param [3,DMS_SpawnMineWarningSigns,[true]]; + + if ((count _this)>4) then + { + _mineClassname = param [4,"ATMine",[true]]; + }; + }; + + + if !(getText (configfile >> "CfgVehicles" >> _mineClassname >> "vehicleClass") isEqualTo "Mines") exitWith + { + diag_log format ["DMS ERROR :: Calling DMS_fnc_SpawnMinefield with invalid _mineClassname: %1 | _this: %2",_mineClassname, _this]; + }; + + + private _minesInfo = + if (_difficulty isEqualType "") then + { + missionNamespace getVariable [format ["DMS_MineInfo_%1", _difficulty], [10,50]]; + } + else + { + _difficulty + }; + + private _AISide = missionNamespace getVariable [format ["DMS_%1Side", _side], EAST]; + + + private _mineCount = _minesInfo select 0; + private _radius = _minesInfo select 1; + + + for "_i" from 1 to _mineCount do + { + private _minePos = _centerPos getPos [random _radius,random 360]; + private _mine = createMine ["ATMine", [0,0,0], [], 0]; + + // Fixes players shooting the mine and causing premature 'splosions + if (DMS_BulletProofMines) then + { + _mine allowDamage false; + }; + + //In case you're using directional mines such as tripwires/SLAMs + _mine setDir (random 360); + _mine setPosATL _minePos; + + _AISide revealMine _mine; + + + _mines pushBack _mine; + }; + + if (_spawnWarningSign) then + { + private _randDirOffset = random 45; + for "_i" from 0 to 359 step 90 do + { + private _sign = createVehicle ["Land_Sign_Mines_F", [0,0,0], [], 0, "CAN_COLLIDE"]; + _sign setDir (180+_i); + _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 + _mines pushBack _sign; + }; + }; + + if (DMS_DEBUG) then + { + (format ["SpawnMinefield :: Spawned %1 mines around %2 with _minesInfo: %3 | Warning signs spawned: %5 | _mines: %4",_mineCount,_centerPos,_minesInfo,_mines,_spawnWarningSign]) call DMS_fnc_DebugLog; + }; +}; + + + +_mines diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnNonPersistentVehicle.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnNonPersistentVehicle.sqf new file mode 100644 index 0000000..bb8359f --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnNonPersistentVehicle.sqf @@ -0,0 +1,97 @@ +/* + DMS_fnc_SpawnNonPersistentVehicle + + Spawns a vehicle, but it isn't saved to database by this function. + This function takes into consideration Exile config settings for enabling/disabling Night Vision and Thermal Equipment on a vehicle. + It will also apply all regular Exile EventHandlers, as well as an additional "RopeAttach" EventHandler that will enable simulation on a vehicle that is about to be lifted to prevent issues. (Only for helis) + + The vehicle is LOCKED, has godmode, disabled simulation, and is not able to be slingloaded on spawn. + + NOTE: This function only takes ATL, and will not necessarily spawn directly on the given pos. It will attempt to find a clear position for the given vehicle, and then spawn it at the "clear" position. + If you want the vehicle to be placed precisely at the position provided, you will have to do a setPosXXX at that position on the vehicle after spawning. + + Created by Zupa + Edited by eraser1 + + Usage: + [ + _vehicleClass, // STRING: Classname of the vehicle + _pos // ARRAY: Position to spawn it at (roughly) + ] call DMS_fnc_SpawnNonPersistentVehicle; + + Returns the vehicle object of the created vehicle. + + EXAMPLE: + _exampleVeh = ['Exile_Chopper_Hummingbird_Green',_pos] call DMS_fnc_SpawnNonPersistentVehicle; + +*/ + +if !(params +[ + "_vehicleClass", + "_position" +]) +exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_SpawnNonPersistentVehicle with invalid parameters: %1",_this]; + objNull +}; + +if !(isClass (configFile >> "CfgVehicles" >> _vehicleClass)) exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_SpawnNonPersistentVehicle with non-existent vehicle className: %1",_vehicleClass]; + objNull +}; + +private _vehObj = createVehicle [_vehicleClass, _position, [], 0, "NONE"]; + +clearWeaponCargoGlobal _vehObj; +clearItemCargoGlobal _vehObj; +clearBackpackCargoGlobal _vehObj; + +if (_vehicleClass isKindOf "I_UGV_01_F") then +{ + createVehicleCrew _vehObj; +}; +if (getNumber (configFile >> "CfgSettings" >> "VehicleSpawn" >> "nightVision") isEqualTo 0) then +{ + _vehObj disableNVGEquipment true; +}; +if (getNumber (configFile >> "CfgSettings" >> "VehicleSpawn" >> "thermalVision") isEqualTo 0) then +{ + _vehObj disableTIEquipment true; +}; + +_vehObj setFuel (0.75+(random 0.25)); +_vehObj setDir (random 360); + +if ((getTerrainHeightASL _position)>0) then +{ + _vehObj setVectorUp (surfaceNormal _position); +}; + +_vehObj setVariable ["ExileMoney",0,true]; +_vehObj setVariable ["ExileIsPersistent", false]; +_vehObj setVariable ["ExileIsSimulationMonitored", false]; +_vehObj addMPEventHandler ["MPKilled", { if (isServer) then {_this call ExileServer_object_vehicle_event_onMPKilled;};}]; +_vehObj addEventHandler ["GetIn", {_this call ExileServer_object_vehicle_event_onGetIn}]; + + +if (!isNil "AVS_Version") then +{ + _vehObj call AVS_fnc_sanitizeVehicle; +}; + +_vehObj lock 2; +_vehObj allowDamage false; +_vehObj enableRopeAttach false; +_vehObj enableSimulationGlobal false; + + +if (DMS_DEBUG) then +{ + (format ["SpawnNonPersistentVehicle :: Created %1 at %2 with calling parameters: %3",_vehObj,_position,_this]) call DMS_fnc_DebugLog; +}; + + +_vehObj diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnPersistentVehicle.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnPersistentVehicle.sqf new file mode 100644 index 0000000..3b581eb --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnPersistentVehicle.sqf @@ -0,0 +1,113 @@ +/* + DMS_fnc_SpawnPersistentVehicle + Created by eraser1 + + Usage: + [ + _vehicleClass, // STRING: Vehicle classname to spawn. + _pos, // ARRAY (positionATL or position2d): Where the vehicle will be spawned (strict) + _pinCode // STRING or NUMBER: String has to be 4 digits. Number has to be between 0-9999, and will be automatically formatted. + _spawnATL // (OPTIONAL) BOOLEAN: Whether or not to spawn the vehicle ATL (Above Terrain Level) or ASL (Above Sea Level). Default: true (ATL) + ] call DMS_fnc_SpawnPersistentVehicle; + + Returns the created vehicle object. +*/ + +private _vehObj = objNull; + +try +{ + if !(params + [ + "_vehicleClass", + "_pos", + "_pinCode" + ]) + then + { + throw (format ["invalid parameters: %1",_this]); + }; + + if !(isClass (configFile >> "CfgVehicles" >> _vehicleClass)) then + { + throw (format ["non-existent vehicle className: %1",_vehicleClass]); + }; + + + if ((count _pos) isEqualTo 2) then + { + _pos set [2,0]; + }; + + + if (_pinCode isEqualType 0) then + { + if (_pinCode<0 || {_pinCode>9999}) then + { + throw (format ["invalid SCALAR _pinCode value (must be between 0 and 9999): %1",_pinCode]); + }; + + switch (true) do + { + case (_pinCode<10): + { + _pinCode = format ["000%1",_pinCode]; + }; + + case (_pinCode<100): + { + _pinCode = format ["00%1",_pinCode]; + }; + + case (_pinCode<1000): + { + _pinCode = format ["0%1",_pinCode]; + }; + + default + { + _pinCode = str _pinCode; + }; + }; + }; + + if ((count _pinCode)!=4) then + { + throw (format ["invalid STRING _pinCode value (must be 4 digits): %1",_pinCode]); + }; + + private _spawnATL = if ((count _this)>3) then {_this select 3} else {true}; + + // Create and set the vehicle + _vehObj = [_vehicleClass,_pos] call DMS_fnc_SpawnNonPersistentVehicle; + + if (_spawnATL) then + { + _vehObj setPosATL _pos; + } + else + { + _vehObj setPosASL _pos; + }; + + // Save vehicle on exit. + _vehObj addEventHandler ["GetOut", { _this call ExileServer_object_vehicle_event_onGetOut}]; + + // Set up vars + _vehObj setVariable ["ExileIsPersistent", true]; + _vehObj setVariable ["ExileAccessCode", _pinCode]; + _vehObj setVariable ["ExileOwnerUID", "DMS_PersistentVehicle"]; // Don't change this unless you know what you're doing. + + // Deny access until specified to do so. + _vehObj setVariable ["ExileIsLocked",-1]; + _vehObj setVariable ["ExileLastLockToggleAt", time]; + _vehObj setVariable ["ExileAccessDenied", true]; + _vehObj setVariable ["ExileAccessDeniedExpiresAt", 999999]; +} +catch +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_SpawnPersistentVehicle with %1!",_exception]; +}; + + +_vehObj diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnStaticMission.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnStaticMission.sqf new file mode 100644 index 0000000..722f855 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnStaticMission.sqf @@ -0,0 +1,79 @@ +/* + DMS_fnc_SpawnStaticMission + Created by eraser1 + + Usage: + [ + _missionType, + _parameters + ] call DMS_fnc_SpawnStaticMission; + + Simply spawns a mission with the given mission type and passes parameters to it. Returns nothing + + If the mission returns the string "delay", then DMS will attempt to spawn the mission again in 60 seconds. +*/ + +private _missionType = param [0, selectRandom DMS_StaticMissionTypesArray, [""]]; + +private _mission = +[ + missionNamespace getVariable format + [ + "DMS_StaticMission_%1", + _missionType + ] +] param [0, "no", [{}]]; + +try +{ + if (_mission isEqualTo "no") then + { + throw format ["for a mission that isn't in DMS_StaticMissionTypesArray! Parameters: %1",_this]; + }; + + if (_missionType in DMS_RunningStaticMissions) then + { + throw format ["with a mission that's already running! Parameters: %1",_this]; + }; + + + private _parameters = if ((count _this)>1) then {_this select 1} else {[]}; + + DMS_MissionCount = DMS_MissionCount + 1; + + private _return = _parameters call _mission; + + if ((!isNil "_return") && {_return isEqualTo "delay"}) then + { + DMS_MissionCount = DMS_MissionCount - 1; + + if (DMS_SpawnMissions_Scheduled) then + { + [60, DMS_fnc_SpawnStaticMission, [_missionType], false] call ExileServer_system_thread_addTask; + } + else + { + [60, {[_this, DMS_fnc_SpawnStaticMission] execFSM "exile_server\fsm\call.fsm";}, [_missionType], false] call ExileServer_system_thread_addTask; + }; + + if (DMS_DEBUG) then + { + (format ["SpawnStaticMission :: Mission ""%1"" requested delay",_missionType]) call DMS_fnc_DebugLog; + }; + } + else + { + DMS_StaticMissionDelay = DMS_TimeBetweenStaticMissions call DMS_fnc_SelectRandomVal; + DMS_StaticMissionLastStart = diag_tickTime; + DMS_RunningStaticMissions pushBack _missionType; + + if (DMS_DEBUG) then + { + (format ["SpawnStaticMission :: Spawned mission %1 with parameters (%2) | DMS_StaticMissionDelay set to %3 seconds", _missionType, _parameters, DMS_StaticMissionDelay]) call DMS_fnc_DebugLog; + }; + }; +} +catch +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_SpawnStaticMission %1", _exception]; +}; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SubArr.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SubArr.sqf new file mode 100644 index 0000000..921c280 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SubArr.sqf @@ -0,0 +1,54 @@ +/* + DMS_fnc_SubArr + Originally created by Maca134 for the M3Editor + Adapted by eraser1 + + Usage: + [ + [ + _num1, + _num2, + _num3 + ], + [ + _num4, + _num5, + _num6 + ] + ] call DMS_fnc_SubArr; + + Subtracts the values of two arrays from each other and returns a new array with those values. +*/ + +if !(params +[ + "_a1", + "_a2" +]) +exitWith +{ + diag_log format["DMS ERROR :: Calling DMS_fnc_SubArr with invalid parameters: %1",_this]; +}; + +private _a1_len = count _a1; +private _a2_len = count _a2; + +if (_a1_len == 0 || {_a2_len == 0}) exitWith +{ + diag_log format["DMS ERROR :: Calling DMS_fnc_SubArr with an empty array! _this: %1", _this]; + [] +}; + +if (_a1_len != _a2_len2) exitWith +{ + diag_log format["DMS ERROR :: Calling DMS_fnc_SubArr with arrays that have unequal lengths! _this: %1", _this]; + [] +}; + + +private _a3 = []; +{ + _a3 pushBack (_x - (_a2 select _forEachIndex)); +} forEach _a1; + +_a3 diff --git a/@ExileServer/addons/a3_dms/scripts/fn_TargetsKilled.sqf b/@ExileServer/addons/a3_dms/scripts/fn_TargetsKilled.sqf new file mode 100644 index 0000000..ae904e9 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_TargetsKilled.sqf @@ -0,0 +1,51 @@ +/* + DMS_fnc_TargetsKilled + Created by eraser1 + + Usage: + [ + _unit, + _group, + _object + ] call DMS_fnc_TargetsKilled; + + Will accept non-array argument of group, unit, or object. +*/ + +if (_this isEqualTo []) exitWith +{ + diag_log "DMS ERROR :: Calling DMS_TargetsKilled with empty array!"; +}; + +private _killed = false; + +try +{ + { + private _lastDistanceCheckTime = _x getVariable ["DMS_LastAIDistanceCheck",time]; + private _pos = getPosWorld _x; + private _spawnPos = _x getVariable ["DMS_AISpawnPos",0]; + + 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]; + } + else + { + _x setVariable ["DMS_LastAIDistanceCheck",time]; + throw _x; + }; + } forEach (_this call DMS_fnc_GetAllUnits); // DMS_fnc_GetAllUnits will return living AI unit objects only, so we only need to check for runaway units + + _killed = true; +} +catch +{ + if (DMS_DEBUG) then + { + (format ["TargetsKilled :: %1 is still alive! All of %2 are not yet killed!",_exception,_this]) call DMS_fnc_DebugLog; + }; +}; + +_killed; diff --git a/@ExileServer/addons/a3_exile_occupation.pbo b/@ExileServer/addons/a3_exile_occupation.pbo index e31d4792a96597ab7d4eebe399bf7aa4417c084c..ef4b375278af187cc1e0f2f530bc8e5d575b1951 100644 GIT binary patch delta 1406 zcmYjPZA@EL81A{}-b-&kptGMqfdV5Sbfsl7GGX#zB*l%;ZlZ1|q#|^KvcdotncKwa zrY>87ckYGLz%3z3vO6ecMR)l)aLBxS4R zfwyCoigbR$J7AW zi+YuEP-v#f;L}yZ<5-HOlI;$pR|+p>uH|0Jq`~V_5FQZdQ`HMwX_~LBa#r$lwlvN$ zK^fOe6keF#6h{ zDwqZb{Y7xe=Rze=9ZZFD52_*AA7eZvaMk}e+6{toflEO2{S_;y#_y0a0Q9vOwX zT9asLe2Hh<1EF5=&8D{*D5|u;M8GWWZ=O}760tgXA4VP+Y%7Ed9a++8vZFy-4V@LJ z6qZ9<;8>>*&~YdH@&ymyhd51rps#grTW^l@u1N3-4)gRff2(FitxFK(CB zy85=hK*$#kwXM_ZcI*r8?W^ezJ++R6{4Qgn51rW4HI1Z8SB7)wYKJ3XE%rD|A-g9H zM#EuI+r3jGBtAfa3~^xK8xwNFu1G!nJ6i`oMeMlmK)R0F>EIjDZa zo;c@^-92l>8)yEo!Tex8d67XDUfAYvIGP}O*$Retq#s8zt`ozJGueq`Lz6Di@!Gg- z-Uvl=f;fKlBq#OoD2z-m(H;h89%HemTtlM2p-l14?7@7l%w4V#Kv!uONB*iz!o`IG zp!?0SMTABWuPH3n94-e><69?kSrp4GTG|FuGmML@c1#4^TV!qPvgR!i!<@l(U-s5 K{PnG-cmD_O6}f-_ delta 1431 zcmY*WZA@EL80MUNdv7mLptO`y%2r?%#L^EIQlXm+%m}zOD>BVMfdVTG7%g9$iQ52~ zVJ-$Kykv(s6Bt3GKb+zv=?_0(x{bhO%g`V5*KjdQaQk5twOeN9z2|NQ&!2Oj=Y5{% zeb0M;zLW6iPD1zugRgXt^_#5^+&wjmC?=*k6l`g0wfAoJjb1U!&yLq_u8l2Z zQ2p)g@&yRlIq9y+!Z3~WP>IqhbW=!fEa5~LK^iN=oOo>Y)X;oB-B zRZXcBl`dAM$+`&{f#;ODr#LDt;Ie5@yqs@@-Y4*?0_Qms4Z6uGQ(UI)h&2NxDWiL( zpDiDGycx%nVFb(N7V*7`G6bb1DdI1caU62N zg$6zBDN%vo>y!-t!LYApOOdHs;CDJbf^^7K6H0~ks@t&m@?U&k&#{2VVu7xg%n+=$ zK(sm!J{-!DzV&eE;79P;kWox|Wr$-Wp?LnaSqvv%Fo4Ey5Zmk5)NtHqf;Ud*h^JaN zF)%?leB7>sKhD^|-_F5ehYJ1~PTPvvvOu5*P_PIFI(%?-*v)$z`0bx+?=_LLo7|t0I>4jxbtS_s5H8-@K(qh0rwW1$|fx z-Vy-@SM3lTHA7%ES+s^Orn}>7kov1Zg5voDxaGXdJP5j@VOxZq1(A$D+tS79SWV)#tF5 zWK81h$jUi9ZztXv%txY2H~~faui#!B;g+$knN*cwJ9$5!`GQ=tG5h(_%3_PPu$ZLg xGZk^RhQ_wi=DxP$fjXkKGoHwKNq1U*xm+_hfB%!Y#hJD5#dkbks``sY{slkY$pHWW diff --git a/@ExileServer/addons/a3_exile_occupation/config.sqf b/@ExileServer/addons/a3_exile_occupation/config.sqf index 97f4d58..4138ef5 100644 --- a/@ExileServer/addons/a3_exile_occupation/config.sqf +++ b/@ExileServer/addons/a3_exile_occupation/config.sqf @@ -22,7 +22,7 @@ SC_useMapOverrides = true; // set to true to enable o SC_maxAIcount = 200; // the maximum amount of AI, if the AI count is above this then additional AI won't spawn SC_mapMarkers = false; // Place map markers at the occupied areas (occupyPlaces and occupyMilitary only) true/false -SC_minFPS = 20; // any lower than minFPS on the server and additional AI won't spawn +SC_minFPS = 5; // any lower than minFPS on the server and additional AI won't spawn SC_scaleAI = 10; // any more than _scaleAI players on the server and _maxAIcount is reduced for each extra player SC_minDistanceToSpawnZones = 750; // Minimum distance in metres to the nearest spawn zone @@ -37,14 +37,14 @@ SC_useWaypoints = true; // When spawning AI create waypoint ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// SC_processReporter = true; // log the a list of active server processes every 60 seconds (useful for debugging server problems) -SC_fastNights = false; // true if you want night time to go faster than daytime +SC_fastNights = false; // true if you want night time to go faster than daytime SC_occupyPlaces = true; // true if you want villages,towns,cities patrolled by bandits SC_occupyTraders = true; // true if you want to create trader camps at positions specified in SC_occupyTraderDetails SC_occupyStatic = false; // true if you want to add AI in specific locations -SC_occupyTransport = false; // true if you want pubic transport (travels between traders) +SC_occupyTransport = true; // true if you want pubic transport (travels between traders) SC_occupyLootCrates = true; // true if you want to have random loot crates with guards SC_occupyRandomSpawn = false; // (WORK IN PROGRESS) true if you want random spawning AI that hunt for nearby players -SC_occupyMilitary = true; // true if you want military buildings patrolled +SC_occupyMilitary = true; // true if you want military buildings patrolled SC_occupyVehicle = true; // true if you want to have roaming AI land vehicles SC_occupySky = true; // true if you want to have roaming AI helis SC_occupySea = false; // true if you want to have roaming AI boats @@ -63,18 +63,18 @@ SC_fastNightsMultiplierDay = 4; // the time multiplier to // Random Spawn Setup (Work in progress) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -SC_randomSpawnMinPlayers = 1; // Minimum number of players to be online before random spawning AI can spawn -SC_randomSpawnMaxGroups = 20; // Maximum amount of random AI groups allowed at any time -SC_randomSpawnMinGroupSize = 1; // Minimum amount of random AI groups allowed per group +SC_randomSpawnMinPlayers = 0; // Minimum number of players to be online before random spawning AI can spawn +SC_randomSpawnMaxGroups = 5; // Maximum amount of random AI groups allowed at any time +SC_randomSpawnMinGroupSize = 2; // Minimum amount of random AI groups allowed per group SC_randomSpawnMaxGroupSize = 5; // Maximum amount of random AI groups allowed per group -SC_randomSpawnChance = 30; // Percentage chance of spawning if suitable player found +SC_randomSpawnChance = 12; // Percentage chance of spawning if suitable player found SC_randomSpawnIgnoreCount = true; // true if you want spawn random AI groups regardless of overall AI count (they still count towards the total though) -SC_randomSpawnFrequency = 600; // time in seconds between the possibility of random AI hunting the same player (1800 for 30 minutes) +SC_randomSpawnFrequency = 3600; // time in seconds between the possibility of random AI hunting the same player (1800 for 30 minutes) SC_randomSpawnNearBases = true; // true if you want to allow random spawns in range of territories -SC_randomSpawnNearSpawns = true; // true if you want to allow random spawns in range of spawn zones -SC_randomSpawnTargetBambis = true; // true if you want to allow random spawns to target bambis +SC_randomSpawnNearSpawns = false; // true if you want to allow random spawns in range of spawn zones +SC_randomSpawnTargetBambis = false; // true if you want to allow random spawns to target bambis SC_randomSpawnAnnounce = true; // true if you want a warning toast issued to all players when AI spawns -SC_randomSpawnNameTarget = true; // true if you want to name the targeted player +SC_randomSpawnNameTarget = true; // true if you want to name the targeted player ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Occupy Places Setup @@ -97,7 +97,7 @@ SC_occupyTraderDetails = [ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// SC_staticIgnoreNearbyPlayers = false;// Spawn even if players are nearby -SC_staticIgnoreAICount = true;// Ignore the AI count for Static AI Spawns +SC_staticIgnoreAICount = false;// Ignore the AI count for Static AI Spawns SC_staticBandits = [ //[[pos],ai count,radius,search buildings] ]; @@ -109,7 +109,7 @@ SC_staticSurvivors = [ //[[pos],ai count,radius,search buildings] // Public Transport Setup ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -SC_colourTransport = false; // true if you want the public transport coloured +SC_colourTransport = true; // true if you want the public transport coloured SC_secureTransport = true; // true if you want the public transport and pilot to be indestructible SC_occupyTransportClass = ["Exile_Chopper_Orca_BlackCustom"]; // to always use the same vehicle, specify one option only @@ -144,7 +144,7 @@ SC_occupyLootCratesLocations = [ ]; SC_SpawnLootCrateGuards = true; // true if you want to enable AI guards SC_numberofLootCrates = 6; // if SC_occupyLootCrates = true spawn this many loot crates (overrided below for Namalsk) -SC_LootCrateGuards = 5; // number of AI to spawn at each crate +SC_LootCrateGuards = 2; // number of AI to spawn at each crate SC_LootCrateGuardsRandomize = true; // Use a random number of guards up to a maximum = SC_LootCrateGuards (so between 1 and SC_LootCrateGuards) SC_occupyLootCratesMarkers = true; // true if you want to have markers on the loot crate spawns @@ -154,17 +154,17 @@ SC_ropeAttach = true; // Allow lootcrates to be a // ["Exile_Item_Matches",1,2] this example would add between 1 and 3 Exile_Item_Matches to the crate (1 + 0 to 2 more) // to add a fixed amount make the second number 0 SC_LootCrateItems = [ - ["Exile_Melee_Axe",0,1], - ["Exile_Item_GloriousKnakworst",0,2], - ["Exile_Item_PlasticBottleFreshWater",0,2], - ["Exile_Item_Beer",0,1], + ["Exile_Melee_Axe",1,0], + ["Exile_Item_GloriousKnakworst",1,2], + ["Exile_Item_PlasticBottleFreshWater",1,2], + ["Exile_Item_Beer",5,1], ["Exile_Item_BaseCameraKit",0,2], - ["Exile_Item_InstaDoc",0,1], - ["Exile_Item_Matches",0,1], - ["Exile_Item_CookingPot",0,1], - ["Exile_Item_MetalPole",0,1], - ["Exile_Item_LightBulb",0,1], - ["Exile_Item_FuelCanisterEmpty",0,1], + ["Exile_Item_InstaDoc",1,1], + ["Exile_Item_Matches",1,0], + ["Exile_Item_CookingPot",1,0], + ["Exile_Item_MetalPole",1,0], + ["Exile_Item_LightBulb",1,0], + ["Exile_Item_FuelCanisterEmpty",1,0], ["Exile_Item_WoodPlank",0,8], ["Exile_Item_woodFloorKit",0,2], ["Exile_Item_WoodWindowKit",0,1], @@ -172,12 +172,13 @@ SC_LootCrateItems = [ ["Exile_Item_WoodFloorPortKit",0,2], ["Exile_Item_Laptop",0,1], ["Exile_Item_CodeLock",0,1], - ["Exile_Item_Cement",0,10], - ["Exile_Item_Sand",0,10], - ["Exile_Item_MetalWire",0,5], + ["Exile_Item_Cement",2,10], + ["Exile_Item_Sand",2,10], + ["Exile_Item_MetalWire",1,5], ["Exile_Item_WaterCanisterEmpty",0,2], ["Exile_Item_Shovel",0,1], ["Exile_Item_MetalScrews",0,5], + //Added by Z ["Exile_Item_WorkBenchKit",0,1], ["Exile_Item_WoodWindowKit",0,2], @@ -241,7 +242,7 @@ SC_LootCrateItems = [ ["Exile_Item_Grinder",0,1], ["Exile_Item_Handsaw",0,1], ["Exile_Item_Pliers",0,1], - ["Exile_Melee_SledgeHammmer",0,1] + ["Exile_Melee_SledgeHammmer",0,1] ]; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -318,9 +319,9 @@ SC_maximumCrewAmount = 5; // Maximum amount of AI allowed in a vehi // Roaming Land Vehicle Setup ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -SC_maxNumberofVehicles = 15; // How many roaming vehicles to spawn -SC_occupyLandVehicleIgnoreCount = true; // true if you want spawn vehicles regardless of overall AI count -SC_occupyVehiclesLocked = false; // true if AI vehicles to stay locked until all the linked AI are dead +SC_maxNumberofVehicles = 10; // How many roaming vehicles to spawn +SC_occupyLandVehicleIgnoreCount = false; // true if you want spawn vehicles regardless of overall AI count +SC_occupyVehiclesLocked = true; // true if AI vehicles to stay locked until all the linked AI are dead SC_occupyVehicleSurvivors = false; // true if you want a chance to spawn survivor AI as well as bandits (SC_occupyVehicle must be true to use this option) SC_occupyVehicleUseFixedPos = false; // True if you want to specify the patrol positions and radius of the area to patrol / false for random @@ -335,8 +336,10 @@ SC_occupyVehicleFixedPositions = [ ]; // Array of arrays of ground vehicles which can be used by AI patrols (the number next to next vehicle is the maximum amount of that class allowed, 0 for no limit) -SC_VehicleClassToUse = [["Exile_Car_Hatchback_Rusty1",1],["Exile_Car_Hatchback_Rusty2",1]]; - /*["Exile_Car_Hatchback_Rusty3",1], +SC_VehicleClassToUse = [ + ["Exile_Car_Hatchback_Rusty1",1], + ["Exile_Car_Hatchback_Rusty2",1], + ["Exile_Car_Hatchback_Rusty3",1], ["Exile_Car_Hatchback_Sport_Red",1], ["Exile_Car_SUV_Red",1], ["Exile_Car_Offroad_Rusty1",1], @@ -491,11 +494,13 @@ SC_VehicleClassToUse = [["Exile_Car_Hatchback_Rusty1",1],["Exile_Car_Hatchb ["Exile_Car_Van_Fuel_Red",1], ["Exile_Car_Van_Fuel_White",1], ["Exile_Car_MB4WD",1], - ["Exile_Car_MB4WDOpen",1]*/ - //]; -SC_VehicleClassToUseRare = [["Exile_Car_Hatchback_Rusty2",1],["Exile_Car_Hatchback_Rusty3",1]]; - //["Exile_Car_Hatchback_Rusty1",1], - /*["Exile_Car_Hatchback_Sport_Red",1], + ["Exile_Car_MB4WDOpen",1] + ]; +SC_VehicleClassToUseRare = [ + ["Exile_Car_Hatchback_Rusty2",1], + ["Exile_Car_Hatchback_Rusty3",1], + ["Exile_Car_Hatchback_Rusty1",1], + ["Exile_Car_Hatchback_Sport_Red",1], ["Exile_Car_SUV_Red",1], ["Exile_Car_Offroad_Rusty1",1], ["Exile_Car_Offroad_Rusty2",1], @@ -649,8 +654,8 @@ SC_VehicleClassToUseRare = [["Exile_Car_Hatchback_Rusty2",1],["Exile_Car_Hatc ["Exile_Car_Van_Fuel_Red",1], ["Exile_Car_Van_Fuel_White",1], ["Exile_Car_MB4WD",1], - ["Exile_Car_MB4WDOpen",1]*/ - //]; + ["Exile_Car_MB4WDOpen",1] + ]; // Array of arrays of ground vehicles which can be used by Survivor AI patrols (the number next to next vehicle is the maximum amount of that class allowed, 0 for no limit) SC_SurvivorVehicleClassToUse = [ @@ -673,12 +678,12 @@ SC_SurvivorVehicleClassToUseRare = [ // Settings for roaming airborne AI (non armed helis will just fly around) SC_maxNumberofHelis = 2; -SC_occupySkyVehicleIgnoreCount = true; // true if you want spawn vehicles regardless of overall AI count +SC_occupySkyVehicleIgnoreCount = false; // true if you want spawn vehicles regardless of overall AI count // Array of aircraft which can be used by AI patrols (the number next to next vehicle is the maximum amount of that class allowed, 0 for no limit) SC_HeliClassToUse = [ ["Exile_Chopper_Huey_Armed_Green",0] ]; -SC_occupyHeliUseFixedPos = false; // True if you want to specify the patrol positions and radius of the area to patrol / false for random +SC_occupyHeliUseFixedPos = true; // True if you want to specify the patrol positions and radius of the area to patrol / false for random // if you set SC_maxNumberofHelis higher than the number of static positions, the remainder will be random // they will also ignore any blacklisted areas @@ -694,7 +699,7 @@ SC_occupyHeliFixedPositions = [ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Settings for roaming seaborne AI (non armed boats will just sail around) -SC_maxNumberofBoats = 0; +SC_maxNumberofBoats = 1; SC_occupySeaVehicleIgnoreCount = false; // true if you want spawn vehicles regardless of overall AI count // Array of boats which can be used by AI patrols (the number next to next vehicle is the maximum amount of that class allowed, 0 for no limit) @@ -830,7 +835,7 @@ if (worldName == 'Tanoa' AND SC_useMapOverrides) then if (worldName == 'Malden' AND SC_useMapOverrides) then { - SC_maxAIcount = 150; + SC_maxAIcount = 70; SC_useApexClasses = false; }; @@ -888,7 +893,7 @@ if(SC_useApexClasses) then "U_B_CTRG_Soldier_urb_3_F" ]; - /*SC_VehicleClassToUse = [ +/* SC_VehicleClassToUse = [ ["B_GEN_Offroad_01_gen_F",0], ["C_Offroad_02_unarmed_F",0], ["I_C_Offroad_02_unarmed_F",0] @@ -898,7 +903,8 @@ if(SC_useApexClasses) then ["B_LSV_01_unarmed_black_F",1], ["O_T_LSV_02_unarmed_black_F",1], ["O_T_Truck_03_device_ghex_F",1] - ];*/ + ]; +*/ }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/@ExileServer/addons/a3_exile_occupation/scripts/extras/processReporter.sqf b/@ExileServer/addons/a3_exile_occupation/scripts/extras/processReporter.sqf index 734a767..ea29e1c 100644 --- a/@ExileServer/addons/a3_exile_occupation/scripts/extras/processReporter.sqf +++ b/@ExileServer/addons/a3_exile_occupation/scripts/extras/processReporter.sqf @@ -1,9 +1,7 @@ -_aiActive = { !isPlayer _x } count allunits; - _logDetail = "======================================================================================================="; [_logDetail,'A3_EXILE_PROCESSREPORTER'] call SC_fnc_log; - _logDetail = format['[processReporter] Started @ %4 : [FPS: %1|PLAYERS: %2|AI: %5:THREADS: %3]',diag_fps,count allplayers,count diag_activeSQFScripts,time,_aiActive]; + _logDetail = format['[processReporter] Started @ %4 : [FPS: %1|PLAYERS: %2|THREADS: %3]',diag_fps,count allplayers,count diag_activeSQFScripts,time]; [_logDetail,'A3_EXILE_PROCESSREPORTER'] call SC_fnc_log; _logDetail = "======================================================================================================="; [_logDetail,'A3_EXILE_PROCESSREPORTER'] call SC_fnc_log; diff --git a/@ExileServer/addons/a3_exile_occupation/scripts/occupationVehicle.sqf b/@ExileServer/addons/a3_exile_occupation/scripts/occupationVehicle.sqf index 409e873..49d9d99 100644 --- a/@ExileServer/addons/a3_exile_occupation/scripts/occupationVehicle.sqf +++ b/@ExileServer/addons/a3_exile_occupation/scripts/occupationVehicle.sqf @@ -104,7 +104,6 @@ if(_vehiclesToSpawn > 0) then _group setVariable ["DMS_Group_Side", _side]; _VehicleClass = SC_VehicleClassToUse call BIS_fnc_selectRandom; - _VehicleClassToUse = _VehicleClass select 0; vehicleOkToSpawn = false; diff --git a/@ExileServer/addons/a3_exile_occupation/scripts/startOccupation.sqf b/@ExileServer/addons/a3_exile_occupation/scripts/startOccupation.sqf index 7e59ddc..4db5f4c 100644 --- a/@ExileServer/addons/a3_exile_occupation/scripts/startOccupation.sqf +++ b/@ExileServer/addons/a3_exile_occupation/scripts/startOccupation.sqf @@ -67,13 +67,6 @@ if(SC_occupyMilitary) then [SC_refreshTime, fnc_occupationMilitary, [], true] call ExileServer_system_thread_addTask; }; -if(SC_occupyVehicle) then -{ - uiSleep 15; // delay the start - fnc_occupationVehicle = compile preprocessFileLineNumbers "\x\addons\a3_exile_occupation\scripts\occupationVehicle.sqf"; - [SC_refreshTime, fnc_occupationVehicle, [], true] call ExileServer_system_thread_addTask; -}; - if(SC_occupyRandomSpawn) then { uiSleep 15; // delay the start @@ -93,6 +86,13 @@ if(SC_occupyHeliCrashes) then call compile preprocessFileLineNumbers "\x\addons\a3_exile_occupation\scripts\occupationHeliCrashes.sqf"; }; +if(SC_occupyVehicle) then +{ + uiSleep 15; // delay the start + fnc_occupationVehicle = compile preprocessFileLineNumbers "\x\addons\a3_exile_occupation\scripts\occupationVehicle.sqf"; + [SC_refreshTime, fnc_occupationVehicle, [], true] call ExileServer_system_thread_addTask; +}; + if(SC_occupyStatic) then { uiSleep 15; // delay the start diff --git a/@ExileServer/addons/exile_server_config.pbo b/@ExileServer/addons/exile_server_config.pbo index c08b422c91f79e350fd076e7868de03354af36bd..b9522f48c95cb9bd6fb3a5191bbf027aa57f54a9 100644 GIT binary patch delta 53 zcmV-50LuUM{txy350FR)Q(~A}`~CxwQ51n=g<}DQV*<5f1OEOL=Oh8dgq-d~Jja`O LJ-AKNY?QXXxFZ@M delta 53 zcmV-50LuUM{txy350FR)s!f<$`~CxwQ51n=g<}DQV*<5f1OEOLNXjmpT#hguqf5tl L%m_~w_Bl~+v49u}