Merry Xmas :D

* **NEW CONFIG VALUES:**

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

View File

@ -8,6 +8,7 @@
// Enables debug logging in DMS functions.
// 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;
@ -28,7 +29,7 @@ DMS_Use_Map_Config = true; // Whether or not to use config overwrites specific t
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 = 1000; // If a player is this close to a mission then it won't time-out. Set to 0 to disable this check.
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.
/*General settings for dynamic missions*/
/*General settings for static missions*/
@ -40,6 +41,7 @@ DMS_Use_Map_Config = true; // Whether or not to use config overwrites specific t
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_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).
@ -58,6 +60,8 @@ DMS_Use_Map_Config = true; // Whether or not to use config overwrites specific t
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
@ -115,6 +119,7 @@ DMS_Use_Map_Config = true; // Whether or not to use config overwrites specific t
/*Crate/Box settings*/
DMS_HideBox = false; // "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_SpawnBoxIRGrenade = true; // Spawn an IR grenade on mission box upon misson completion during nighttime
/*Crate/Box settings*/
@ -173,13 +178,13 @@ DMS_Use_Map_Config = true; // Whether or not to use config overwrites specific t
/*Mission notification settings*/
DMS_BanditMissionTypes = [ // List of missions with spawn chances. If they add up to 100%, they represent the percentage chance each one will spawn
["blackhawkdown",7],
["donthasslethehoff",6],
["donthasslethehoff",5],
["bandits",5],
["bauhaus",5],
["cardealer",5],
["humanitarian",5],
["foodtransport",5],
["blackhawkdown",4],
["construction",4],
["walmart",4],
["mercenaries",4],
@ -197,15 +202,20 @@ DMS_Use_Map_Config = true; // Whether or not to use config overwrites specific t
];
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.
];
DMS_findSafePosBlacklist = [ // For BIS_fnc_findSafePos position blacklist info refer to: https://community.bistudio.com/wiki/BIS_fnc_findSafePos
DMS_findSafePosBlacklist = [ // For BIS_fnc_findSafePos position blacklist info refer to: http://www.exilemod.com/topic/61-dms-defents-mission-system/?page=18#comment-31190
// An example is given in the altis_config.sqf (it blacklists the salt flats).
];
/* Mission System Settings */
/* AI Settings */
DMS_AI_Classname = "O_recon_F"; // Since some of you wanted this...
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)
@ -260,8 +270,19 @@ DMS_Use_Map_Config = true; // Whether or not to use config overwrites specific t
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 = false; // Whether or not to keep the stamina system for "difficult" AI.
DMS_AI_EnableStamina_hardcore = false; // Whether or not to keep the stamina system for "hardcore" AI.
DMS_AI_WP_Radius_base = 5; // Waypoint radius for AI in bases
DMS_AI_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"
];
@ -371,8 +392,7 @@ DMS_Use_Map_Config = true; // Whether or not to use config overwrites specific t
DMS_MG_weps = [ // Machine Guns
"LMG_Zafir_F",
"LMG_Mk200_F",
"arifle_MX_SW_Black_F",
"MMG_01_hex_F"
"arifle_MX_SW_Black_F"
];
DMS_MG_pistols = [ // Pistols for MG Class (Set to empty array if you don't want to give them any pistols)
"hgun_ACPC2_F",
@ -534,7 +554,14 @@ DMS_Use_Map_Config = true; // Whether or not to use config overwrites specific t
"sniper"
];
DMS_random_AI = [ // The classes that a "random" AI can spawn as | DEFAULT: 60% Assault, 20% MG, 20% 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",
@ -542,6 +569,24 @@ DMS_Use_Map_Config = true; // Whether or not to use config overwrites specific t
"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.
@ -616,7 +661,6 @@ DMS_Use_Map_Config = true; // Whether or not to use config overwrites specific t
"LMG_Zafir_F",
"LMG_Mk200_F",
"arifle_MX_SW_Black_F",
"MMG_01_hex_F",
"srifle_EBR_F",
"srifle_DMR_01_F",
"srifle_GM6_F",
@ -652,7 +696,7 @@ DMS_Use_Map_Config = true; // Whether or not to use config overwrites specific t
"optic_SOS",
"optic_DMS",
"optic_LRPS",
"optic_Nightstalker"
"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",

View File

@ -23,6 +23,53 @@ if (isNil "DMS_DynamicMission") exitWith
};
// This code is NECESSARY for spawning persistent vehicles. DO NOT REMOVE THIS CODE UNLESS YOU KNOW WHAT YOU ARE DOING
if !("isKnownAccount:76561198027700602" call ExileServer_system_database_query_selectSingleField) then
{
"createAccount:76561198027700602:eraser1" call ExileServer_system_database_query_fireAndForget;
};
// Some custom maps don't have the proper safePos config entries.
// If you are using one and you have an issue with mission spawns, please create an issue on GitHub or post a comment in the DMS thread.
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 "tavi": // Thanks to JamieKG for this info
{
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];
RESISTANCE setFriend[WEST,0];
WEST setFriend[RESISTANCE,0];
@ -168,10 +215,16 @@ if (DMS_DynamicMission || {DMS_StaticMission}) then
}
else
{
diag_log "Enjoy the DMS functions! :)";
diag_log "Enjoy DMS functions! :)";
};
DMS_Version = "November 18 2015";
{
[_x] call DMS_fnc_ImportFromM3E_Static; // Spawn all of the bases that are supposed to be spawned on server startup.
} forEach DMS_BasesToImportOnServerStart;
"DMS post-init complete." call DMS_fnc_DebugLog;
format ["DMS post-init complete. productVersion: %1 | infiSTAR version: %2", productVersion, if (!isNil "INFISTARVERSION") then {INFISTARVERSION} else {"not installed"}] call DMS_fnc_DebugLog;

View File

@ -7,6 +7,8 @@ DMS_HC_Object = objNull;
DMS_CleanUpList = [];
DMS_Version = "December 24 2015";
//Load main config
call compileFinal preprocessFileLineNumbers "\x\addons\dms\config.sqf";
@ -18,44 +20,6 @@ if (DMS_Use_Map_Config) then
call compileFinal preprocessFileLineNumbers (format ["\x\addons\dms\map_configs\%1_config.sqf",toLower worldName]);
};
// Some custom maps don't have the proper safePos config entries.
// If you are using one and you have an issue with mission spawns, please create an issue on GitHub or post a comment in the DMS thread.
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 "tavi": // Thanks to JamieKG for this info
{
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];
/*
Original Functions from
http://maca134.co.uk/portfolio/m3editor-arma-3-map-editor/

View File

@ -30,5 +30,8 @@ DMS_MinDistFromSouthBorder = 5000; // There's about 5km of ocean from the sout
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" mission to the existing mission types.
DMS_StaticMissionTypes pushBack ["saltflats",1];
// 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"];

View File

@ -18,6 +18,10 @@ DMS_WaterNearBlacklist = 200;
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.

View File

@ -63,7 +63,7 @@ _group =
// Create Crates
_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate;
_wreck = createVehicle ["Land_UWreck_Heli_Attack_02_F",[(_pos select 0) - 10, (_pos select 1),-0.2],[], 0, "CAN_COLLIDE"];
_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 =

View File

@ -75,7 +75,7 @@ _staticGuns =
// Create Crates
_crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate;
_wreck = createVehicle ["Land_UWreck_Heli_Attack_02_F",[(_pos select 0) - 10, (_pos select 1),-0.2],[], 0, "CAN_COLLIDE"];
_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

View File

@ -14,7 +14,7 @@ _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 [] || {(typeName _this)!="ARRAY"}}) then
if ((isNil "_this") || {_this isEqualTo [] || {!(_this isEqualType [])}}) then
{
_this =
[
@ -64,13 +64,13 @@ _class =
}
else
{
if ((typeName _extraParams)=="STRING") then
if (_extraParams isEqualType "") then
{
_extraParams
}
else
{
if (((typeName _extraParams)=="ARRAY") && {(typeName (_extraParams select 0))=="STRING"}) then
if ((_extraParams isEqualType []) && {(_extraParams select 0) isEqualType ""}) then
{
_extraParams select 0
}

View File

@ -5,7 +5,7 @@
Initializes dynamic mission variables for DMS
*/
diag_log "DMS :: Initializing Mission Variables";
diag_log "DMS :: Initializing Dynamic Mission Variables";
// Initialize Variables
DMS_Mission_Arr = [];

View File

@ -100,16 +100,6 @@ deleteVehicle (nearestObject [_pos, _crateClassname]); // Make sure to remove a
_crate = [_crateClassname, _pos] call DMS_fnc_SpawnCrate;
_baseObjs = [];
if (isNil "DMS_SaltFlatsBaseSpawned") then // This is to prevent having to delete then respawn the base, which would create unnecessary load on the server. Best to just leave the base up (unless you don't want to respawn the mission).
{
_baseObjs =
[
"saltflatsbase"
] call DMS_fnc_ImportFromM3E_Static;
DMS_SaltFlatsBaseSpawned = true;
};
// Spawn the vehicle AFTER the base so that it spawns the vehicle in a (relatively) clear position.
_veh =
@ -216,7 +206,7 @@ _msgWIN = ['#0080ff',"Convicts have successfully assaulted the base on the salt
_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 = "AI Base";
_missionName = "Mercenary Base";
// Create Markers
_markers =
@ -226,7 +216,7 @@ _markers =
_difficulty
] call DMS_fnc_CreateMarker;
(_markers select 1) setMarkerSize [500,500];
(_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;
@ -256,7 +246,7 @@ _added =
_markers,
_side,
_difficulty,
[[],[]]
[]
] call DMS_fnc_AddMissionToMonitor_Static;
// Check to see if it was added correctly, otherwise delete the stuff

View File

@ -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
[
[
0, // 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;
};

View File

@ -5,7 +5,7 @@
Initializes static mission variables for DMS
*/
diag_log "DMS :: Initializing Mission Variables";
diag_log "DMS :: Initializing Static Mission Variables";
// Initialize Variables
DMS_StaticMission_Arr = [];

View File

@ -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]
];

View File

@ -47,7 +47,9 @@
_missionEvents,
[
_onSuccessScripts, // (OPTIONAL) Array of code or string to be executed on mission completion (in addition to regular code).
_onFailScripts // (OPTIONAL) Array of code or stirng to be executed on mission failure (in addition to regular code).
_onFailScripts, // (OPTIONAL) Array of code or stirng to be executed on mission failure (in addition to regular code).
_onMonitorStart, // (OPTIONAL) Code to run when the monitor starts to check the mission status, however it is checked AFTER "MissionSuccessState" is checked, so you can use/set the variable "_success" manually. 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;
@ -55,12 +57,13 @@
*/
private ["_added", "_OK", "_pos", "_onEndingScripts", "_completionInfo", "_timeOutInfo", "_units", "_inputUnits", "_missionObjs", "_mines", "_difficulty", "_side", "_messages", "_markers", "_arr", "_timeStarted", "_timeUntilFail", "_buildings", "_vehs", "_crate_info_array", "_missionName", "_msgWIN", "_msgLose", "_markerDot", "_markerCircle", "_missionEvents", "_onSuccessScripts", "_onFailScripts"];
private ["_added", "_pos", "_onEndingScripts", "_completionInfo", "_timeOutInfo", "_units", "_inputUnits", "_missionObjs", "_mines", "_difficulty", "_side", "_messages", "_markers", "_arr", "_timeStarted", "_timeUntilFail", "_buildings", "_vehs", "_crate_info_array", "_missionName", "_msgWIN", "_msgLose", "_markerDot", "_markerCircle", "_missionEvents", "_onSuccessScripts", "_onFailScripts"];
_added = false;
_OK = params
if !(params
[
["_pos","",[[]],[2,3]],
["_completionInfo","",[[]]],
@ -72,15 +75,14 @@ _OK = params
["_side","bandit",[""]],
["_difficulty","moderate",[""]],
["_missionEvents",[],[[]]]
];
if (!_OK) exitWith
])
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_fnc_AddMissionToMonitor with invalid parameters: %1",_this];
false;
};
_onEndingScripts = if ((count _this)>10) then {_this select 10} else {[[],[]]};
_onEndingScripts = if ((count _this)>10) then {_this select 10} else {[[],[],{},{}]};
try
@ -103,14 +105,14 @@ try
_units = _inputUnits call DMS_fnc_GetAllUnits;
_OK = _missionObjs params
if !(_missionObjs params
[
["_buildings","",[[]]],
["_vehs","",[[]]],
["_crate_info_array","",[[]]]
];
if (!_OK) then
])
then
{
throw format["_missionObjs |%1|",_missionObjs];
};
@ -129,36 +131,38 @@ try
};
_OK = _messages params
if !(_messages params
[
["_missionName","",[""]],
["_msgWIN",[],[[]],[2]],
["_msgLose",[],[[]],[2]]
];
if (!_OK) then
])
then
{
throw format["_messages |%1|",_messages];
};
_OK = _markers params
if !(_markers params
[
["_markerDot","",[""]],
["_markerCircle","",[""]]
];
if (!_OK) then
])
then
{
throw format["_markers |%1|",_markers];
};
_OK = _onEndingScripts params
if !(_onEndingScripts params
[
["_onSuccessScripts", [], [[]]],
["_onFailScripts", [], [[]]]
];
if (!_OK) then
["_onFailScripts", [], [[]]],
["_onMonitorStart", {}, [{}]],
["_onMonitorEnd", {}, [{}]]
])
then
{
throw format["_onEndingScripts |%1|",_onEndingScripts];
};
@ -192,7 +196,9 @@ try
_missionEvents,
[
_onSuccessScripts,
_onFailScripts
_onFailScripts,
_onMonitorStart,
_onMonitorEnd
]
];
DMS_Mission_Arr pushBack _arr;

View File

@ -57,7 +57,9 @@
_missionEvents,
[
_onSuccessScripts, // (OPTIONAL) Array of code or string to be executed on mission completion (in addition to regular code).
_onFailScripts // (OPTIONAL) Array of code or stirng to be executed on mission failure (in addition to regular code).
_onFailScripts, // (OPTIONAL) Array of code or stirng to be executed on mission failure (in addition to regular code).
_onMonitorStart, // (OPTIONAL) Code to run when the monitor starts to check the mission status, however it is checked AFTER "MissionSuccessState" is checked, so you can use/set the variable "_success" manually. 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;
@ -65,12 +67,12 @@
*/
private ["_added", "_OK", "_pos", "_onEndingScripts", "_completionInfo", "_timeOutInfo", "_units", "_inputUnits", "_missionObjs", "_mines", "_difficulty", "_side", "_messages", "_markers", "_arr", "_timeStarted", "_timeUntilFail", "_buildings", "_vehs", "_crate_info_array", "_missionName", "_msgWIN", "_msgLose", "_markerDot", "_markerCircle", "_missionEvents", "_onSuccessScripts", "_onFailScripts"];
private ["_added", "_pos", "_onEndingScripts", "_completionInfo", "_timeOutInfo", "_units", "_inputUnits", "_missionObjs", "_mines", "_difficulty", "_side", "_messages", "_markers", "_arr", "_timeStarted", "_timeUntilFail", "_buildings", "_vehs", "_crate_info_array", "_missionName", "_msgWIN", "_msgLose", "_markerDot", "_markerCircle", "_missionEvents", "_onSuccessScripts", "_onFailScripts"];
_added = false;
_OK = params
if !(params
[
["_pos","",[[]],[2,3]],
["_completionInfo","",[[]]],
@ -83,15 +85,14 @@ _OK = params
["_side","bandit",[""]],
["_difficulty","moderate",[""]],
["_missionEvents",[],[[]]]
];
if (!_OK) exitWith
])
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_fnc_AddMissionToMonitor_Static with invalid parameters: %1",_this];
false;
};
_onEndingScripts = if ((count _this)>10) then {_this select 10} else {[[],[]]};
_onEndingScripts = if ((count _this)>11) then {_this select 11} else {[[],[],{},{}]};
try
@ -112,24 +113,18 @@ try
["_timeUntilFail",DMS_MissionTimeOut call DMS_fnc_SelectRandomVal,[0]]
];
_OK = _missionObjs params
if !(_missionObjs params
[
["_buildings","",[[]]],
["_vehs","",[[]]],
["_crate_info_array","",[[]]]
];
if (!_OK) then
])
then
{
throw format["_missionObjs |%1|",_missionObjs];
};
_mines = [];
if ((count _missionObjs)>3) then
{
_mines = _missionObjs param [3,[],[[]]];
};
_mines = if ((count _missionObjs)>3) then { _missionObjs param [3,[],[[]]] } else { [] };
// Don't spawn a minefield if there is one already defined in _missionObjs.
if (DMS_SpawnMinefieldForEveryMission && {_mines isEqualTo []}) then
@ -138,36 +133,37 @@ try
};
_OK = _messages params
if !(_messages params
[
["_missionName","",[""]],
["_msgWIN",[],[[]],[2]],
["_msgLose",[],[[]],[2]]
];
if (!_OK) then
])
then
{
throw format["_messages |%1|",_messages];
};
_OK = _markers params
if !(_markers params
[
["_markerDot","",[""]],
["_markerCircle","",[""]]
];
if (!_OK) then
])
then
{
throw format["_markers |%1|",_markers];
};
_OK = _onEndingScripts params
if !(_onEndingScripts params
[
["_onSuccessScripts", [], [[]]],
["_onFailScripts", [], [[]]]
];
if (!_OK) then
["_onFailScripts", [], [[]]],
["_onMonitorStart", {}, [{}]],
["_onMonitorEnd", {}, [{}]]
])
then
{
throw format["_onEndingScripts |%1|",_onEndingScripts];
};
@ -202,7 +198,9 @@ try
_missionEvents,
[
_onSuccessScripts,
_onFailScripts
_onFailScripts,
_onMonitorStart,
_onMonitorEnd
]
];
DMS_StaticMission_Arr pushBack _arr;

View File

@ -17,13 +17,13 @@
private ["_missionName", "_messageInfo", "_titleColor", "_message"];
_OK = params
if !(params
[
["_missionName","",[""]],
["_messageInfo",[],[[]],[2]]
];
if (!_OK) exitWith
])
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_fnc_BroadcastMissionStatus with invalid parameters: %1",_this];
};
@ -39,7 +39,7 @@ if (DMS_DEBUG) then
(format["BroadcastMissionStatus :: Notification types: |%1| for broadcasting mission status: %2",DMS_PlayerNotificationTypes,_message]) call DMS_fnc_DebugLog;
};
if ((typeName _message) != "STRING") then
if !(_message isEqualType "") then
{
_message = str _message;
};

View File

@ -15,20 +15,20 @@
private ["_pos", "_relPos", "_npos"];
_OK = params
if !(params
[
["_pos","",[[],objNull],[2,3]],
["_relPos","",[[]],[2,3]]
];
if (!_OK) exitWith
])
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 ((typeName _pos)=="OBJECT") then
if (_pos isEqualType objNull) then
{
_pos = getPosATL _pos;
};

View File

@ -20,36 +20,15 @@ if (DMS_DEBUG) then
(format ["CleanUp :: CLEANING UP: %1",_this]) call DMS_fnc_DebugLog;
};
if !((typeName _this) == "ARRAY") then
if !(_this isEqualType []) then
{
_this = [_this];
};
private ["_skippedObjects","_clean"];
private ["_skippedObjects"];
_skippedObjects = [];
_clean =
{
{
detach _x;
_x call _clean;
} forEach (attachedObjects _x);
_this enableSimulationGlobal false;
_this removeAllMPEventHandlers "mpkilled";
_this removeAllMPEventHandlers "mphit";
_this removeAllMPEventHandlers "mprespawn";
_this removeAllEventHandlers "FiredNear";
_this removeAllEventHandlers "HandleDamage";
_this removeAllEventHandlers "Killed";
_this removeAllEventHandlers "Fired";
_this removeAllEventHandlers "GetOut";
_this removeAllEventHandlers "GetIn";
_this removeAllEventHandlers "Local";
deleteVehicle _this;
};
{
private ["_parameter"];
@ -72,7 +51,7 @@ _clean =
if !([_parameter,DMS_CleanUp_PlayerNearLimit] call DMS_fnc_IsPlayerNearby) then
{
_parameter call _clean;
_parameter call ExileServer_system_garbageCollector_deleteObject;
}
else
{
@ -91,7 +70,7 @@ _clean =
// 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 _clean;
_x call ExileServer_system_garbageCollector_deleteObject;
} forEach (units _parameter);
if (local _parameter) then

View File

@ -27,14 +27,14 @@ if (DMS_CleanUpList isEqualTo []) exitWith {}; // Empty array, no objects to cl
private ["_objs","_timeAddedToList","_timeUntilClean"];
_OK = _x params
if !(_x params
[
["_objs",[objNull],[objNull,[],grpNull]],
["_timeAddedToList",diag_tickTime,[0]],
["_timeUntilClean",DMS_CompletedMissionCleanupTime,[0]]
];
if (!_OK) then
])
then
{
diag_log format ["DMS ERROR :: Invalid parameters for DMS_fnc_CleanUpManager: %1 replaced with %2",_x,[_objs,_timeAddedToList,_timeUntilClean]];
};

View File

@ -11,4 +11,9 @@
_this = format ['%1 |::|::| (DMS_Version: "%4" | time: %2 | diag_tickTime: %5 | %3 FPS)',_this,time,diag_fps,DMS_Version,diag_tickTime];
"ARMA_LOG" callExtension format ["DMS_DEBUG:%1",_this];
diag_log format ["DMS_DEBUG :: %1",_this];
diag_log format ["DMS_DEBUG :: %1",_this];
if (!isNil "MAR_fnc_log") then // mARMA logging
{
[_this,"info"] call MAR_fnc_log;
};

View File

@ -21,6 +21,36 @@
]
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.
@ -60,29 +90,36 @@ private ["_crate","_lootValues","_wepCount","_weps","_itemCount","_items","_back
_OK = params
if (!(params
[
["_crate",objNull,[objNull]],
["_lootValues","",[0,"",[]],[2,3]]
];
if (!_OK || {isNull _crate}) exitWith
])
||
{isNull _crate})
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_FillCrate with invalid parameters: %1",_this];
};
_crate hideObjectGlobal false;
if !(DMS_GodmodeCrates) then
{
_crate allowDamage true;
};
_crate hideObjectGlobal false;
if (DMS_EnableBoxMoving) then
{
_crate enableSimulationGlobal true;
_crate enableRopeAttach true;
};
if (((typeName _lootValues)=="ARRAY") && {(typeName (_lootValues select 1))!="CODE"}) then
if ((_lootValues isEqualType []) && {!((_lootValues select 1) isEqualType {})}) then
{
// Weapons
if(typeName (_lootValues select 0) == "ARRAY") then
if ((_lootValues select 0) isEqualType []) then
{
_wepCount = (_lootValues select 0) select 0;
_weps = (_lootValues select 0) select 1;
@ -95,7 +132,7 @@ if (((typeName _lootValues)=="ARRAY") && {(typeName (_lootValues select 1))!="CO
// Items
if(typeName (_lootValues select 1) == "ARRAY") then
if ((_lootValues select 1) isEqualType []) then
{
_itemCount = (_lootValues select 1) select 0;
_items = (_lootValues select 1) select 1;
@ -108,7 +145,7 @@ if (((typeName _lootValues)=="ARRAY") && {(typeName (_lootValues select 1))!="CO
// Backpacks
if(typeName (_lootValues select 2) == "ARRAY") then
if ((_lootValues select 2) isEqualType []) then
{
_backpackCount = (_lootValues select 2) select 0;
_backpacks = (_lootValues select 2) select 1;
@ -133,7 +170,7 @@ if (((typeName _lootValues)=="ARRAY") && {(typeName (_lootValues select 1))!="CO
{
_weapon = _weps call BIS_fnc_selectRandom;
_ammo = _weapon call DMS_fnc_selectMagazine;
if ((typeName _weapon)=="STRING") then
if (_weapon isEqualType "") then
{
_weapon = [_weapon,1];
};
@ -149,7 +186,7 @@ if (((typeName _lootValues)=="ARRAY") && {(typeName (_lootValues select 1))!="CO
for "_i" from 1 to _itemCount do
{
_item = _items call BIS_fnc_selectRandom;
if ((typeName _item)=="STRING") then
if (_item isEqualType "") then
{
_item = [_item,1];
};
@ -164,7 +201,7 @@ if (((typeName _lootValues)=="ARRAY") && {(typeName (_lootValues select 1))!="CO
for "_i" from 1 to _backpackCount do
{
_backpack = _backpacks call BIS_fnc_selectRandom;
if ((typeName _backpack)=="STRING") then
if (_backpack isEqualType "") then
{
_backpack = [_backpack,1];
};
@ -175,7 +212,7 @@ if (((typeName _lootValues)=="ARRAY") && {(typeName (_lootValues select 1))!="CO
else
{
_crateValues =
if ((typeName _lootValues)=="ARRAY") then
if (_lootValues isEqualType []) then
{
(_lootValues select 0) call (_lootValues select 1)
}
@ -184,12 +221,12 @@ else
missionNamespace getVariable (format ["DMS_CrateCase_%1",_lootValues])
};
if !(_crateValues params
[
["_weps", [], [[]]],
["_items", [], [[]]],
["_backpacks", [], [[]]]
])
if !((_crateValues params
[
["_weps", [], [[]]],
["_items", [], [[]]],
["_backpacks", [], [[]]]
]))
exitWith
{
diag_log format ["DMS ERROR :: Invalid ""_crateValues"" (%1) generated from _lootValues: %2",_crateValues,_lootValues];
@ -197,7 +234,7 @@ else
// Weapons
{
if ((typeName _x)=="STRING") then
if (_x isEqualType "") then
{
_x = [_x,1];
};
@ -206,7 +243,7 @@ else
// Items/Mags
{
if ((typeName _x)=="STRING") then
if (_x isEqualType "") then
{
_x = [_x,1];
};
@ -215,7 +252,7 @@ else
// Backpacks
{
if ((typeName _x)=="STRING") then
if (_x isEqualType "") then
{
_x = [_x,1];
};
@ -246,7 +283,7 @@ if(DMS_RareLoot && {count DMS_RareLootList>0}) then
if(random 100 < _rareLootChance) then
{
_item = DMS_RareLootList call BIS_fnc_selectRandom;
if ((typeName _item)=="STRING") then
if (_item isEqualType "") then
{
_item = [_item,1];
};
@ -254,8 +291,8 @@ if(DMS_RareLoot && {count DMS_RareLootList>0}) then
};
};
// In case somebody wants to use fillCrate on a vehicle but also wants to use smoke, don't create smoke/IR strobe unless it's a crate
if (_crate isKindOf "ReammoBox_F") then
// You can choose if you want to enable/disable smoke individually using setVariable.
if (_crate getVariable ["DMS_AllowSmoke", true]) then
{
if(DMS_SpawnBoxSmoke && {sunOrMoon == 1}) then
{

View File

@ -36,6 +36,14 @@ params
["_throttleParams", DMS_ThrottleBlacklists, [true]]
];
/*
if (!isNil "DMS_DebugMarkers") then
{
{deleteMarker _x} forEach DMS_DebugMarkers;
};
DMS_DebugMarkers = [];
*/
_waterSpawn = if ((count _this)>9) then {_this select 9} else {false};
@ -75,6 +83,14 @@ while{!_isValidSpot} do
_pos = call _generatePos;
};
/*
_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).

View File

@ -16,7 +16,7 @@
private ["_units"];
if ((typeName _this)!="ARRAY") then
if !(_this isEqualType []) then
{
_this = [_this];
};

View File

@ -61,6 +61,14 @@
_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 =
[
@ -307,6 +315,39 @@ if (!_reinforcementsDepleted && {(diag_tickTime-_lastUpdated)>_updateDelay}) the
};
};
case "increasing_difficulty":
{
private ["_AICount", "_reinforcementCount", "_maxAICount"];
if !(_monitorParams params
[
["_AICount", 0, [0]],
["_reinforcementCount", 0, [0]]
])
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"};
};
_maxAICount = if ((count _monitorParams)>3) then {_monitorParams param [3, 0, [0]]} else {_AICount};
_unitsToSpawn = _reinforcementCount min ((_maxAICount-_remainingUnits) max 0);
};
};
case "armed_vehicle":
{
private ["_AICount", "_vehClass", "_leaderPos", "_veh"];
@ -495,6 +536,12 @@ if (!_reinforcementsDepleted && {(diag_tickTime-_lastUpdated)>_updateDelay}) the
_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;

View File

@ -17,13 +17,13 @@
private ["_file", "_pos", "_objs", "_export", "_obj", "_objPos"];
_OK = params
if !(params
[
["_file","",[""]],
["_pos","",[[],objNull],[2,3]]
];
if (!_OK) exitWith
])
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_fnc_ImportFromM3E with invalid parameters: %1",_this];
[]
@ -31,7 +31,7 @@ if (!_OK) exitWith
// Get the position if an object was supplied instead of position
if ((typeName _pos)=="OBJECT") then
if (_pos isEqualType objNull) then
{
_pos = getPosATL _pos;
};

View File

@ -18,13 +18,13 @@
private ["_file", "_missionPos", "_objs", "_export", "_obj", "_objPos"];
_OK = params
if !(params
[
["_file","",[""]],
["_missionPos","",[[],objNull],[2,3]]
];
if (!_OK) exitWith
])
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_fnc_ImportFromM3E_Convert with invalid parameters: %1",_this];
[]
@ -32,7 +32,7 @@ if (!_OK) exitWith
// Get the position if an object was supplied instead of position
if ((typeName _missionPos)=="OBJECT") then
if (_missionPos isEqualType objNull) then
{
_missionPos = getPosATL _missionPos;
};

View File

@ -11,18 +11,18 @@
_file call DMS_fnc_ImportFromM3E_Static; // This also works
This function will simply create the objects from a file that was exported from M3Editor.
This function will simply create the objects from a file that was exported from M3Editor, and return a list of those objects.
*/
private ["_OK", "_varname", "_file", "_export"];
_OK = params
if !(params
[
["_file","",[""]]
];
if (!_OK) exitWith
])
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_fnc_ImportFromM3E_Static with invalid parameters: %1",_this];
[]
@ -41,7 +41,7 @@ missionNamespace setVariable [_varname,true];
_export = call compile preprocessFileLineNumbers (format ["\x\addons\DMS\objects\static\%1.sqf",_file]);
if ((isNil "_export") || {(typeName _export)!="ARRAY"}) exitWith
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];
[]
@ -52,9 +52,11 @@ _objs = [];
{
private ["_obj","_pos"];
_obj = createVehicle [_x select 0, [0,0,0], [], 0, "CAN_COLLIDE"];
_pos = _x select 1;
_obj enableSimulationGlobal false;
if (_x select 4) then
{
_obj setDir (_x select 2);
@ -65,6 +67,7 @@ _objs = [];
_obj setPosATL _pos;
_obj setVectorDirAndUp (_x select 3);
};
_objs pushBack _obj;
} foreach _export;

View File

@ -13,6 +13,16 @@
private["_result","_position","_radius"];
if !(params
[
["_position",[],[[]],[2,3]],
["_radius",0,[0]]
])
exitWith
{
diag_log format["DMS ERROR :: Calling DMS_fnc_IsNearWater with invalid parameters: %1",_this];
false
};
_position = _this select 0;
_radius = _this select 1;

View File

@ -13,17 +13,20 @@
private ["_pos", "_dis", "_isNear"];
_OK = params
if !(params
[
["_pos", "", [objNull,[]], [2,3]],
["_dis", 0, [0]]
];
if (!_OK) exitWith
])
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_fnc_IsPlayerNearby with invalid parameters: %1",_this];
false;
};
if (_dis isEqualTo 0) exitWith {false};
_isNear = false;
try

View File

@ -21,7 +21,11 @@
private ["_pos", "_nearestObjectMinDistance", "_waterNearLimit", "_minSurfaceNormal", "_spawnZoneNearLimit", "_traderZoneNearLimit", "_missionNearLimit", "_playerNearLimit", "_territoryNearLimit", "_waterSpawn", "_isValidPos"];
_OK = params
_isValidPos = false;
if !(params
[
["_pos", [], [[]], [0,2,3]],
["_waterNearLimit", DMS_WaterNearBlacklist, [0] ],
@ -32,12 +36,8 @@ _OK = params
["_playerNearLimit", DMS_PlayerNearBlacklist, [0] ],
["_territoryNearLimit", DMS_TerritoryNearBlacklist, [0] ],
["_waterSpawn", false, [false] ]
];
_isValidPos = false;
if (!_OK) then
])
then
{
diag_log format ["DMS ERROR :: Calling DMS_fnc_isValidPosition with invalid parameters: %1",_this];
}
@ -164,6 +164,13 @@ else
}
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;

View File

@ -67,20 +67,19 @@ if (isNil "_this") then
}
else
{
if (((typeName _this)=="ARRAY") && {(count _this)>1}) then
if ((_this isEqualType []) && {(count _this)>1}) then
{
_OK = params
if (params
[
["_findSafePosParams",[25,DMS_WaterNearBlacklist,DMS_MaxSurfaceNormal,DMS_SpawnZoneNearBlacklist,DMS_TraderZoneNearBlacklist,DMS_MissionNearBlacklist,DMS_PlayerNearBlacklist,DMS_TerritoryNearBlacklist,DMS_ThrottleBlacklists],[[]]],
["_posInfo",[],[[]],[1,2]]
];
if (_OK) then
])
then
{
_missionPosition = _posInfo select 0;
_forceSpawn = if ((count _posInfo)>1) then {_posInfo select 1} else {false};
if (((typeName _missionPosition)!="ARRAY") || {(count _missionPosition)<2}) then
if (!(_missionPosition isEqualType []) || {(count _missionPosition)<2}) then
{
// Empty array means that you want to generate a mission position.
if !(_missionPosition isEqualTo []) then

View File

@ -11,7 +11,7 @@
] call DMS_fnc_MissionSuccessState;
*/
if ((typeName _this) != "ARRAY") exitWith
if !(_this isEqualType []) exitWith
{
diag_log format ["DMS ERROR :: DMS_fnc_MissionSuccessState called with invalid parameter: %1",_this];
};
@ -28,13 +28,13 @@ _exit = false;
{
private ["_OK","_completionType","_completionArgs","_absoluteWinCondition"];
_OK = _x params
if !(_x params
[
["_completionType", "", [""] ],
["_completionArgs", [], [[],grpNull] ]
];
if (!_OK) then
])
then
{
diag_log format ["DMS ERROR :: DMS_fnc_MissionSuccessState has invalid parameters in: %1",_x];
throw "ERROR";

View File

@ -23,11 +23,11 @@
_missionSide,
_missionDifficulty,
_missionEvents,
_onSuccessScripts,
_onFailScripts,
[
_onSuccessScripts,
_onFailScripts
_onFailScripts,
_onMonitorStart,
_onMonitorEnd
]
]
@ -39,26 +39,37 @@ private ["_pos", "_success", "_timeStarted", "_timeUntilFail", "_units", "_build
{
_pos = _x select 0;
_success = (_x select 1) call DMS_fnc_MissionSuccessState;
_timeStarted = _x select 2 select 0;
_timeUntilFail = _x select 2 select 1;
_units = _x select 3;
_buildings = _x select 4 select 0;
_vehs = _x select 4 select 1;
_crate_info_array = _x select 4 select 2;
_mines = _x select 4 select 3;
_missionName = _x select 5 select 0;
_msgWIN = _x select 5 select 1;
_msgLose = _x select 5 select 2;
_markers = _x select 6;
_missionSide = _x select 7;
_missionDifficulty = _x select 8;
_missionEvents = _x select 9;
_onSuccessScripts = _x select 10 select 0;
_onFailScripts = _x select 10 select 1;
_onMonitorStart = _x select 10 select 2;
_onMonitorEnd = _x select 10 select 3;
try
{
_pos = _x select 0;
_success = (_x select 1) call DMS_fnc_MissionSuccessState;
_timeStarted = _x select 2 select 0;
_timeUntilFail = _x select 2 select 1;
_units = _x select 3;
_buildings = _x select 4 select 0;
_vehs = _x select 4 select 1;
_crate_info_array = _x select 4 select 2;
_mines = _x select 4 select 3;
_missionName = _x select 5 select 0;
_msgWIN = _x select 5 select 1;
_msgLose = _x select 5 select 2;
_markers = _x select 6;
_missionSide = _x select 7;
_missionDifficulty = _x select 8;
_missionEvents = _x select 9;
_onSuccessScripts = _x select 10 select 0;
_onFailScripts = _x select 10 select 1;
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 (DMS_DEBUG) then
@ -67,9 +78,10 @@ private ["_pos", "_success", "_timeStarted", "_timeUntilFail", "_units", "_build
};
*/
if (_success) then
{
DMS_CleanUpList pushBack [_units+_buildings,diag_tickTime,DMS_CompletedMissionCleanupTime];
DMS_CleanUpList pushBack [_buildings,diag_tickTime,DMS_CompletedMissionCleanupTime];
if (_missionSide == "bandit") then
{
@ -80,8 +92,6 @@ private ["_pos", "_success", "_timeStarted", "_timeUntilFail", "_units", "_build
// Not yet implemented
};
_arr = DMS_Mission_Arr deleteAt _forEachIndex;
{
_x allowDamage true;
_x enableRopeAttach true;
@ -121,7 +131,7 @@ private ["_pos", "_success", "_timeStarted", "_timeUntilFail", "_units", "_build
{
_code = _x;
if ((typeName _code)=="STRING") then
if (_code isEqualType "") then
{
_code = compile _code;
};
@ -131,6 +141,8 @@ private ["_pos", "_success", "_timeStarted", "_timeUntilFail", "_units", "_build
[_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];
};
@ -144,16 +156,21 @@ private ["_pos", "_success", "_timeStarted", "_timeUntilFail", "_units", "_build
throw format ["Mission Timeout Extended at %1 with timeout after %2 seconds. Position: %3",diag_tickTime,_timeUntilFail,_pos];
};
//Nobody is nearby so just cleanup objects from here
_cleanupList = (_units+_buildings+_vehs);
_cleanupList = ((_units call DMS_fnc_GetAllUnits)+_buildings+_vehs+_mines);
{
_cleanupList pushBack (_x select 0);
} forEach _crate_info_array;
private["_prev"];
_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
{
@ -163,12 +180,10 @@ private ["_pos", "_success", "_timeStarted", "_timeUntilFail", "_units", "_build
{
// Not yet implemented
};
_arr = DMS_Mission_Arr deleteAt _forEachIndex;
{
_code = _x;
if ((typeName _code)=="STRING") then
if (_code isEqualType "") then
{
_code = compile _code;
};
@ -177,6 +192,8 @@ private ["_pos", "_success", "_timeStarted", "_timeUntilFail", "_units", "_build
[_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];
};
@ -193,7 +210,7 @@ private ["_pos", "_success", "_timeStarted", "_timeUntilFail", "_units", "_build
_text = format ["%1 %2",DMS_MarkerText_MissionPrefix,_text];
};
_dot setMarkerText (format ["%1 (%2 %3 remaining)",_text,{alive _x} count _units,DMS_MarkerText_AIName]);
_dot setMarkerText (format ["%1 (%2 %3 remaining)",_text,count (_units call DMS_fnc_GetAllUnits),DMS_MarkerText_AIName]);
};
if !(_missionEvents isEqualTo []) then
@ -206,9 +223,28 @@ private ["_pos", "_success", "_timeStarted", "_timeUntilFail", "_units", "_build
} forEach _missionEvents;
*/
};
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;

View File

@ -31,7 +31,9 @@
_missionEvents,
[
_onSuccessScripts,
_onFailScripts
_onFailScripts,
_onMonitorStart,
_onMonitorEnd
]
]
@ -41,58 +43,66 @@ if (DMS_StaticMission_Arr isEqualTo []) exitWith {}; // Empty array, no stati
{
private ["_missionPos", "_completionInfo", "_groupReinforcementsInfo", "_timing", "_inputAIUnits", "_missionObjs", "_msgInfo", "_markers", "_missionSide", "_missionDifficulty", "_missionEvents", "_missionScripts", "_success", "_timeStarted", "_timeUntilFail", "_buildings", "_vehs", "_crate_info_array", "_mines", "_missionName", "_msgWIN", "_msgLose", "_onSuccessScripts", "_onFailScripts"];
if !(_x params
[
["_missionPos", [], [[]], [2,3] ],
["_completionInfo", [], [[]] ],
["_groupReinforcementsInfo", [], [[]] ],
["_timing", [], [[]], [2] ],
["_inputAIUnits", [], [[]] ],
["_missionObjs", [], [[]], [4] ],
["_msgInfo", [], [[]], [3] ],
["_markers", [], [[]], [2] ],
["_missionSide", "", [""] ],
["_missionDifficulty", "", [""] ],
["_missionEvents", [], [[]] ],
["_missionScripts", [], [[]], [4] ]
])
then
{
DMS_StaticMission_Arr deleteAt _forEachIndex;
diag_log format ["DMS ERROR :: Invalid Index (%1) in DMS_StaticMission_Arr: %2",_forEachIndex,_x];
};
_success = _completionInfo call DMS_fnc_MissionSuccessState;
_timeStarted = _timing select 0;
_timeUntilFail = _timing select 1;
_buildings = _missionObjs select 0;
_vehs = _missionObjs select 1;
_crate_info_array = _missionObjs select 2;
_mines = _missionObjs select 3;
_missionName = _msgInfo select 0;
_msgWIN = _msgInfo select 1;
_msgLose = _msgInfo select 2;
_onSuccessScripts = _missionScripts select 0;
_onFailScripts = _missionScripts select 1;
_onMonitorStart = _missionScripts select 2;
_onMonitorEnd = _missionScripts select 3;
try
{
private ["_missionPos", "_completionInfo", "_groupReinforcementsInfo", "_timing", "_inputAIUnits", "_missionObjs", "_msgInfo", "_markers", "_missionSide", "_missionDifficulty", "_missionEvents", "_endingScripts", "_success", "_timeStarted", "_timeUntilFail", "_buildings", "_vehs", "_crate_info_array", "_mines", "_missionName", "_msgWIN", "_msgLose", "_onSuccessScripts", "_onFailScripts"];
if !(_x params
[
["_missionPos", [], [[]], [2,3] ],
["_completionInfo", [], [[]] ],
["_groupReinforcementsInfo", [], [[]] ],
["_timing", [], [[]], [2] ],
["_inputAIUnits", [], [[]] ],
["_missionObjs", [], [[]], [4] ],
["_msgInfo", [], [[]], [3] ],
["_markers", [], [[]], [2] ],
["_missionSide", "", [""] ],
["_missionDifficulty", "", [""] ],
["_missionEvents", [], [[]] ],
["_endingScripts", [], [[]], [2] ]
])
then
{
DMS_StaticMission_Arr deleteAt _forEachIndex;
diag_log format ["DMS ERROR :: Invalid Index (%1) in DMS_StaticMission_Arr: %2",_forEachIndex,_x];
throw "DMS ERROR";
};
_success = _completionInfo call DMS_fnc_MissionSuccessState;
_timeStarted = _timing select 0;
_timeUntilFail = _timing select 1;
_buildings = _missionObjs select 0;
_vehs = _missionObjs select 1;
_crate_info_array = _missionObjs select 2;
_mines = _missionObjs select 3;
_missionName = _msgInfo select 0;
_msgWIN = _msgInfo select 1;
_msgLose = _msgInfo select 2;
_onSuccessScripts = _endingScripts select 0;
_onFailScripts = _endingScripts select 1;
/*
if (DMS_DEBUG) then
{
(format ["MissionsMonitor_Dynamic :: Checking Mission Status (index %1): ""%2"" at %3",_forEachIndex,_missionName,_missionPos]) call DMS_fnc_DebugLog;
(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 (_success) then
{
_AIUnits = _inputAIUnits call DMS_fnc_GetAllUnits;
DMS_CleanUpList pushBack [_AIUnits+_buildings,diag_tickTime,DMS_CompletedMissionCleanupTime];
DMS_CleanUpList pushBack [_buildings,diag_tickTime,DMS_CompletedMissionCleanupTime];
{
_x allowDamage true;
@ -133,7 +143,7 @@ if (DMS_StaticMission_Arr isEqualTo []) exitWith {}; // Empty array, no stati
{
_code = _x;
if ((typeName _code)=="STRING") then
if (_code isEqualType "") then
{
_code = compile _code;
};
@ -159,22 +169,25 @@ if (DMS_StaticMission_Arr isEqualTo []) exitWith {}; // Empty array, no stati
throw format ["Mission Timeout Extended at %1 with timeout after %2 seconds. Position: %3",diag_tickTime,_timeUntilFail,_missionPos];
};
_AIUnits = _inputAIUnits call DMS_fnc_GetAllUnits;
//Nobody is nearby so just cleanup objects from here
_cleanupList = (_AIUnits+_buildings+_vehs);
_cleanupList = ((_inputAIUnits call DMS_fnc_GetAllUnits)+_buildings+_vehs+_mines);
{
_cleanupList pushBack (_x select 0);
} forEach _crate_info_array;
private["_prev"];
_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;
{
_code = _x;
if ((typeName _code)=="STRING") then
if (_code isEqualType "") then
{
_code = compile _code;
};
@ -194,8 +207,6 @@ if (DMS_StaticMission_Arr isEqualTo []) exitWith {}; // Empty array, no stati
{
private ["_dot", "_text"];
_AIUnits = _inputAIUnits call DMS_fnc_GetAllUnits;
_dot = _markers select 0;
_text = missionNamespace getVariable [format ["%1_text",_dot],_missionName];
@ -204,7 +215,7 @@ if (DMS_StaticMission_Arr isEqualTo []) exitWith {}; // Empty array, no stati
_text = format ["%1 %2",DMS_MarkerText_MissionPrefix,_text];
};
_dot setMarkerText (format ["%1 (%2 %3 remaining)",_text,{alive _x} count _AIUnits,DMS_MarkerText_AIName]);
_dot setMarkerText (format ["%1 (%2 %3 remaining)",_text,count (_inputAIUnits call DMS_fnc_GetAllUnits),DMS_MarkerText_AIName]);
};
if !(_missionEvents isEqualTo []) then
@ -228,12 +239,32 @@ if (DMS_StaticMission_Arr isEqualTo []) exitWith {}; // Empty array, no stati
};
} 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_Dynamic :: %1",_exception]) call DMS_fnc_DebugLog;
(format ["MissionsMonitor_Static :: %1",_exception]) call DMS_fnc_DebugLog;
};
};
} forEach DMS_StaticMission_Arr;

View File

@ -15,7 +15,7 @@
*/
private ["_unit", "_killer", "_side", "_type", "_launcher", "_launcherVar", "_playerObj", "_removeAll", "_rockets", "_grpUnits", "_av", "_memCount", "_gunner", "_driver", "_gunnerIsAlive", "_driverIsAlive", "_grp", "_owner", "_start", "_roadKilled", "_veh", "_boom", "_revealAmount", "_muzzle", "_silencer"];
private ["_unit", "_killer", "_side", "_type", "_launcher", "_launcherVar", "_playerObj", "_removeAll", "_rockets", "_grp", "_grpUnits", "_av", "_memCount", "_gunner", "_driver", "_gunnerIsAlive", "_driverIsAlive", "_grp", "_owner", "_start", "_roadKilled", "_veh", "_boom", "_revealAmount", "_muzzle", "_silencer"];
if (DMS_DEBUG) then
@ -47,6 +47,8 @@ _removeAll =
moveOut _unit;
_unit removeAllEventHandlers "HandleDamage";
// Remove gear according to configs
if (DMS_clear_AI_body && {(random 100) <= DMS_clear_AI_body_chance}) then
{
@ -94,14 +96,12 @@ if(DMS_RemoveNVG) then
_unit unlinkItem "NVGoggles";
};
_grp = group _unit;
_grpUnits = (units _grp) - [_unit];
// Give the AI a new leader if the killed unit was the leader
// credit: https://github.com/SMVampire/VEMF/
if (((count (units group _unit)) > 1) && {(leader group _unit) == _unit}) then
if (!(_grpUnits isEqualTo []) && {(leader _grp) isEqualTo _unit}) then
{
_grpUnits = units group _unit;
_grpUnits = _grpUnits - [_unit];
(group _unit) selectLeader (_grpUnits call BIS_fnc_selectRandom);
_grp selectLeader (_grpUnits call BIS_fnc_selectRandom);
};
_av = _unit getVariable ["DMS_AssignedVeh",objNull];
@ -114,15 +114,17 @@ if (!isNull _av) then
// Destroy the vehicle and add it to cleanup if there are no active crew members of the vehicle.
if (_memCount<1) then
{
_av setDamage 1;
DMS_CleanUpList pushBack [_av,diag_tickTime,DMS_AIVehCleanUpTime];
_av setVariable ["ExileDiedAt",time];
_av spawn {sleep 1;_this enableSimulationGlobal false;};
if (DMS_DEBUG) then
if ((DMS_AI_destroyStaticWeapon && {(random 100)<DMS_AI_destroyStaticWeapon_chance}) || {!(_av isKindOf "StaticWeapon")}) then
{
(format["OnKilled :: Destroying used AI vehicle %1, disabling simulation, and adding to cleanup.",typeOf _av]) call DMS_fnc_DebugLog;
_av setDamage 1;
_av setVariable ["ExileDiedAt",time];
_av spawn {sleep 1;_this enableSimulationGlobal false;};
if (DMS_DEBUG) then
{
(format["OnKilled :: Destroying used AI vehicle %1, disabling simulation, and adding to cleanup.",typeOf _av]) call DMS_fnc_DebugLog;
};
};
}
else
@ -293,7 +295,7 @@ if (isPlayer _killer) then
_muzzle = currentMuzzle _playerObj;
if ((typeName _muzzle)=="STRING") then
if (_muzzle isEqualType "") then
{
_silencer = _playerObj weaponAccessories _muzzle select 0;
if (!isNil "_silencer" && {_silencer != ""}) then
@ -308,7 +310,7 @@ if (isPlayer _killer) then
{
_x reveal [_killer, _revealAmount max (_x knowsAbout _playerObj)];
};
} forEach allUnits;
} forEach _grpUnits;
};
};

View File

@ -39,11 +39,6 @@ if ((!isNull _playerObj) && {(_playerUID != "") && {_playerObj isKindOf "Exile_U
_moneyChange = missionNamespace getVariable [format ["DMS_%1_%2_MoneyGain",_AISide,_AIType],0];
_repChange = missionNamespace getVariable [format ["DMS_%1_%2_RepGain",_AISide,_AIType],0];
if (_roadKilled && {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];
};
// Check for individually defined AI money/respect.
_unitMoney = _unit getVariable ["DMS_AI_Money",""];
@ -60,6 +55,13 @@ if ((!isNull _playerObj) && {(_playerUID != "") && {_playerObj isKindOf "Exile_U
};
if (_roadKilled && {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];
};
if ((_moneyChange!=0) || (_repChange!=0)) then
{
_playerMoney = _playerObj getVariable ["ExileMoney", 0];

View File

@ -38,6 +38,7 @@ if (_status == "win") then
};
_markerDot setMarkerText ("COMPLETED: "+_text);
_markerDot setMarkerColor DMS_MissionMarkerWinDotColor;
_markerDot setMarkerType DMS_MissionMarkerWinDot_Type;
//_markerDot spawn {sleep DMS_MissionMarkerWinDotTime;deleteMarker _this;};
[DMS_MissionMarkerWinDotTime, {deleteMarker _this;}, _markerDot, false] call ExileServer_system_thread_addTask;
if (DMS_DEBUG) then
@ -53,6 +54,7 @@ else
};
_markerDot setMarkerText ("FAILED: "+_text);
_markerDot setMarkerColor DMS_MissionMarkerLoseDotColor;
_markerDot setMarkerType DMS_MissionMarkerLoseDot_Type;
//_markerDot spawn {sleep DMS_MissionMarkerLoseDotTime;deleteMarker _this;};
[DMS_MissionMarkerLoseDotTime, {deleteMarker _this;}, _markerDot, false] call ExileServer_system_thread_addTask;
if (DMS_DEBUG) then

View File

@ -29,14 +29,14 @@ if (diag_fps >= DMS_MinServerFPS && {(count allPlayers) >= DMS_MinPlayerCount})
if (DMS_DEBUG) then
{
(format ["SelectMission :: Selected bandit mission: %1"]) call DMS_fnc_DebugLog;
(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!"]) call DMS_fnc_DebugLog;
(format ["SelectMission :: Spawning of bandit mission ""%1"" complete!",_mission]) call DMS_fnc_DebugLog;
};
};

View File

@ -15,14 +15,14 @@
private ["_pos","_dis","_dir","_npos"];
_OK = params
if !(params
[
["_pos","",[[]],[2,3]],
["_dis",0,[0]],
["_dir",0,[0]]
];
if (!_OK) exitWith
])
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_fnc_SelectOffsetPos with invalid parameters: %1",_this];
[0,0,0]

View File

@ -14,13 +14,13 @@
private ["_OK", "_min", "_max", "_return"];
_OK = params
if !(params
[
["_min",0,[0]],
["_max",0,[0]]
];
if (!_OK) exitWith
])
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_fnc_SelectRandomVal with invalid parameters: %1",_this];
};

View File

@ -4,41 +4,63 @@
Usage:
[
_group,
_pos,
_difficulty
_group, // GROUP or OBJECT: Group or unit to change the behavior of
_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
*/
private ["_OK", "_group", "_behavior", "_pos", "_difficulty", "_radius", "_npos", "_i", "_wp"];
private ["_OK", "_exit", "_group", "_behavior", "_pos", "_difficulty", "_radius", "_npos", "_i", "_wp"];
_OK = params
if !(params
[
["_group",grpNull,[grpNull]],
["_group",grpNull,[grpNull,objNull]],
["_pos",[0,0,0],[[]],[2,3]],
["_difficulty","moderate",[""]]
];
if (!_OK) then
])
then
{
diag_log format ["DMS ERROR :: Calling DMS_SetGroupBehavior with invalid params: %1",_this];
diag_log format ["DMS ERROR :: Calling DMS_fnc_SetGroupBehavior with invalid params: %1",_this];
};
_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};
_behavior = "COMBAT";
// Mostly for DMS_fnc_SpawnAIVehicle, since setting behavior to COMBAT makes the driving suck...
if (((count _this)>3)) then
{
_behavior = _this select 3;
};
_behavior = if ((count _this)>3) then {_this select 3;} else {"COMBAT"};
_group setCombatMode "RED";
_group setBehaviour _behavior;
if(_difficulty == "random") then
if (_difficulty == "random") then
{
_difficulty = DMS_ai_skill_random call BIS_fnc_selectRandom;
};
@ -62,3 +84,7 @@ for "_i" from 0 to 359 step 45 do
_wp = _group addWaypoint [[_pos,_radius,0] call DMS_fnc_SelectOffsetPos,0];
_wp setWaypointType "CYCLE";
true

View File

@ -5,27 +5,28 @@
Usage:
[
_pos, // Position of AI
_count, // Number of AI
_difficulty, // AI Difficulty: "random","hardcore","difficult","moderate", or "easy"
_class, // AI Class: "random","assault","MG","sniper" or "unarmed" OR [_class,_launcherType]
_side // Only "bandit" is supported atm
_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","sniper" or "unarmed" 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
*/
private ["_OK", "_pos", "_count", "_difficulty", "_class", "_group", "_side", "_launcherType", "_launcher", "_unit", "_rocket"];
private ["_OK", "_pos", "_count", "_difficulty", "_class", "_group", "_side", "_customGearSet", "_launcherType", "_launcher", "_unit", "_rocket"];
_OK = params
if !(params
[
["_pos","_pos ERROR",[[]],[3]],
["_count","_count ERROR",[0]],
["_difficulty","_difficulty ERROR",[""]],
["_class","_class ERROR",[""]],
["_side","_side ERROR",[""]]
];
if (!_OK) exitWith
])
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_SpawnAIGroup with invalid parameters: %1",_this];
grpNull
@ -44,13 +45,29 @@ if (DMS_DEBUG) then
};
// if soldier have AT/AA weapons
if (typeName _class == "ARRAY") then
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";
};
};
_group = createGroup (missionNamespace getVariable [format ["DMS_%1Side",_side],EAST]);
_group setVariable ["DMS_LockLocality",nil];
@ -59,7 +76,7 @@ _group setVariable ["DMS_Group_Side", _side];
for "_i" from 1 to _count do
{
_unit = [_group,_pos,_class,_difficulty,_side,"Soldier"] call DMS_fnc_SpawnAISoldier;
_unit = [_group,_pos,_class,_difficulty,_side,"Soldier",_customGearSet] call DMS_fnc_SpawnAISoldier;
};
// An AI will definitely spawn with a launcher if you define type

View File

@ -8,15 +8,16 @@
Usage:
[
[
_position1, // Potential location for AI to spawn #1
_position2, // Potential location for AI to spawn #2
_position1, // ARRAY (positionATL): Potential location for AI to spawn #1
_position2, // ARRAY (positionATL): Potential location for AI to spawn #2
...
_positionN // Potential location for AI to spawn #N
_positionN // ARRAY (positionATL): Potential location for AI to spawn #N
],
_count, // Number of AI
_difficulty, // AI Difficulty: "random","hardcore","difficult","moderate", or "easy"
_class, // AI Class: "random","assault","MG","sniper" or "unarmed" OR [_class,_launcherType]
_side // Only "bandit" is supported atm
_count, // SCALAR (Integer > 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
@ -25,16 +26,15 @@
private ["_OK", "_positions", "_count", "_difficulty", "_class", "_side", "_positionsCount", "_launcherType", "_group", "_unit", "_units", "_i", "_launcher", "_rocket"];
_OK = params
if !(params
[
["_positions","_positions ERROR",[[]]],
["_count","_count ERROR",[0]],
["_difficulty","_difficulty ERROR",[""]],
["_class","_class ERROR",[""]],
["_side","_side ERROR",[""]]
];
if (!_OK) exitWith
])
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_SpawnAIGroup_MultiPos with invalid parameters: %1",_this];
grpNull
@ -61,13 +61,30 @@ if (DMS_DEBUG) then
};
// if soldier have AT/AA weapons
if (typeName _class == "ARRAY") then
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";
};
};
_group = createGroup (missionNamespace getVariable [format ["DMS_%1Side",_side],EAST]);
_group setVariable ["DMS_LockLocality",nil];
@ -76,7 +93,7 @@ _group setVariable ["DMS_Group_Side", _side];
for "_i" from 1 to _count do
{
_unit = [_group,_positions select (_i % _positionsCount),_class,_difficulty,_side,"Soldier"] call DMS_fnc_SpawnAISoldier;
_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

View File

@ -5,13 +5,13 @@
Usage:
[
_group, // Group the AI will belong to
_pos, // Position of AI
_class, // Classname: "random","assault","MG","sniper" or "unarmed". Use "custom" to use "_customGearSet"
_difficulty, // Difficulty: "random","static","hardcore","difficult","moderate", or "easy"
_side, // "bandit","hero", etc.
_type, // Type of AI: "soldier","static","vehicle","heli", etc.
_customGearSet // OPTIONAL: Manually defined AI gear.
_group, // GROUP: Group the AI will belong to
_pos, // ARRAY (positionATL): Position of AI
_class, // STRING: Classname: "random","assault","MG","sniper" or "unarmed". Use "custom" to use "_customGearSet"
_difficulty, // STRING: Difficulty: "random","static","hardcore","difficult","moderate", or "easy"
_side, // STRING: "bandit" only by default
_type, // STRING: Type of AI: "soldier","static","vehicle","heli", etc.
_customGearSet // (OPTIONAL) ARRAY: Manually defined AI gear.
] call DMS_fnc_SpawnAISoldier;
Usage for _customGearSet:
@ -34,7 +34,11 @@
private ["_OK", "_useCustomGear", "_unarmed", "_class", "_type", "_unit", "_side", "_nighttime", "_weapon", "_muzzle", "_suppressor", "_pistols", "_pistol", "_customGearSet", "_helmet", "_uniform", "_vest", "_backpack", "_launcher", "_magazines", "_weaponAttachments", "_pistolAttachments", "_assignedItems", "_difficulty", "_skillArray"];
_OK = params
_useCustomGear = false;
_unarmed = false;
if !(params
[
["_group",grpNull,[grpNull]],
["_pos",[0,0,0],[[]],[3]],
@ -42,18 +46,14 @@ _OK = params
["_difficulty","random",[""]],
["_side","bandit",[""]],
["_type","soldier",[""]]
];
_useCustomGear = false;
_unarmed = false;
if (!_OK) then
])
then
{
diag_log format ["DMS ERROR :: DMS_SpawnAISoldier called with invalid parameters: %1",_this];
}
else
{
if ((_class == "custom") && {((count _this)>6)}) then
if ((_class == "custom") && {(count _this)>6}) then
{
_customGearSet = _this select 6;
_useCustomGear = true;
@ -66,14 +66,14 @@ if(_difficulty == "random") then
};
//Create unit
_unit = _group createUnit ["O_recon_F", _pos, [], 0,"FORM"];
_unit = _group createUnit [DMS_AI_Classname, _pos, [], 0,"FORM"];
_unit allowFleeing 0;
[_unit] joinSilent _group;
// Remove existing gear
{_unit removeWeaponGlobal _x;} forEach (weapons _unit);
{_unit unlinkItem _x;} forEach (assignedItems _unit);
{_unit removeItem _x;} forEach (items _unit);
{_unit removeWeaponGlobal _x;} forEach (weapons _unit);
{_unit unlinkItem _x;} forEach (assignedItems _unit);
{_unit removeItem _x;} forEach (items _unit);
removeAllItemsWithMagazines _unit;
removeHeadgear _unit;
removeUniform _unit;
@ -97,10 +97,17 @@ if !(DMS_ai_default_items isEqualTo []) then
};
switch (toLower _class) do
if (_class == "unarmed") then
{
case "random" : {_class = DMS_random_AI call BIS_fnc_selectRandom;};
case "unarmed" : {_class = "assault";_unarmed = true;};
_class = "assault";
_unarmed = true;
}
else
{
if (_class in DMS_ai_SupportedRandomClasses) then
{
_class = (missionNamespace getVariable [format["DMS_%1_AI",_class], DMS_random_AI]) call BIS_fnc_selectRandom;
};
};
// Unit name
@ -133,10 +140,10 @@ if (!_useCustomGear) then
// Clothes
_unit addHeadgear ((missionNamespace getVariable [format ["DMS_%1_helmets",_class],[]]) call BIS_fnc_selectRandom);
_unit forceAddUniform ((missionNamespace getVariable [format ["DMS_%1_clothes",_class],[]]) call BIS_fnc_selectRandom);
_unit addVest ((missionNamespace getVariable [format ["DMS_%1_vests",_class],[]]) call BIS_fnc_selectRandom);
_unit addBackpack ((missionNamespace getVariable [format ["DMS_%1_backpacks",_class],[]]) call BIS_fnc_selectRandom);
_unit addHeadgear ((missionNamespace getVariable [format ["DMS_%1_helmets",_class],DMS_assault_helmets]) call BIS_fnc_selectRandom);
_unit forceAddUniform ((missionNamespace getVariable [format ["DMS_%1_clothes",_class],DMS_assault_clothes]) call BIS_fnc_selectRandom);
_unit addVest ((missionNamespace getVariable [format ["DMS_%1_vests",_class],DMS_assault_vests]) call BIS_fnc_selectRandom);
_unit addBackpack ((missionNamespace getVariable [format ["DMS_%1_backpacks",_class],DMS_assault_backpacks]) call BIS_fnc_selectRandom);
// Make AI effective at night
_nighttime = (sunOrMoon != 1);
@ -147,14 +154,14 @@ if (!_useCustomGear) then
if (!_unarmed) then
{
_weapon = (missionNamespace getVariable [format ["DMS_%1_weps",_class],[]]) call BIS_fnc_selectRandom;
_weapon = (missionNamespace getVariable [format ["DMS_%1_weps",_class],DMS_assault_weps]) call BIS_fnc_selectRandom;
[_unit, _weapon, 6 + floor(random 3)] call BIS_fnc_addWeapon;
_unit selectWeapon _weapon;
if((random 100) <= (missionNamespace getVariable [format["DMS_%1_optic_chance",_class],0])) then
{
_unit addPrimaryWeaponItem ((missionNamespace getVariable [format ["DMS_%1_optics",_class],[]]) call BIS_fnc_selectRandom);
_unit addPrimaryWeaponItem ((missionNamespace getVariable [format ["DMS_%1_optics",_class],DMS_assault_optics]) call BIS_fnc_selectRandom);
};
if (_nighttime && {(random 100) <= DMS_ai_nighttime_accessory_chance}) then
@ -201,7 +208,7 @@ if (!_useCustomGear) then
}
else
{
_OK = _customGearSet params
if !(_customGearSet params
[
["_weapon","",[""]],
["_weaponAttachments",[],[[]]],
@ -214,9 +221,8 @@ else
["_uniform","",[""]],
["_vest","",[""]],
["_backpack","",[""]]
];
if (!_OK) then
])
then
{
diag_log format ["DMS ERROR :: Calling DMS_SpawnAISoldier with invalid _customGearSet: %1 | _this: %2",_customGearSet,_this];
};
@ -255,7 +261,7 @@ else
// Add Magazines before weapon so that gun will be loaded
{
if ((typeName _x) == "STRING") then
if (_x isEqualType "") then
{
_x = [_x,1];
};
@ -300,7 +306,7 @@ else
};
{
_unit setSkill [(_x select 0),(_x select 1)];
_unit setSkill _x;
} forEach (missionNamespace getVariable [format["DMS_ai_skill_%1",_difficulty],[]]);
@ -313,14 +319,11 @@ if (DMS_ai_disable_ramming_damage) then
{
_unit addEventHandler ["HandleDamage",
{
private ["_unit", "_dmg", "_source", "_projectile"];
_unit = _this select 0;
_dmg = _this select 2;
_source = _this select 3;
_projectile = _this select 4;
_spawnTime = _unit getVariable ["DMS_AISpawnTime", time];
if (((_projectile=="") && {isPlayer _source}) || {((time - _spawnTime)<5) && {!(isPlayer _source)}}) then
if ((_projectile isEqualTo "") && {isPlayer _source}) then
{
_dmg = 0;
};
@ -342,8 +345,13 @@ if (_difficulty=="hardcore") then
} forEach ["SUPPRESSION", "AIMINGERROR"];
};
_unit setCustomAimCoef (missionNamespace getVariable [format["DMS_AI_AimCoef_%1",_difficulty], 0.7]);
_unit enableStamina (missionNamespace getVariable [format["DMS_AI_EnableStamina_%1",_difficulty], true]);
_unit setVariable ["DMS_AISpawnTime", time];
_unit setVariable ["DMS_AI_Side", _side];
_unit setVariable ["DMS_AI_Type", _type];
if (_type=="Soldier") then
{
@ -357,4 +365,5 @@ if (DMS_DEBUG) then
};
_unit
_unit

View File

@ -24,16 +24,15 @@
private ["_OK", "_guns", "_pos", "_MGClassInput", "_MGClass", "_gun", "_unit", "_group", "_class", "_difficulty", "_side", "_positions"];
_OK = params
if !(params
[
["_positions",[],[[]]],
["_group",grpNull,[grpNull]],
["_class","random",[""]],
["_difficulty","static",[""]],
["_side","bandit",[""]]
];
if (!_OK) exitWith
])
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_fnc_SpawnAIStaticMG with invalid parameters: %1",_this];
};

View File

@ -21,26 +21,26 @@
private ["_OK", "_positions", "_veh", "_spawnPos", "_gotoPos", "_vehClass", "_driver", "_gunner", "_tmpGroup", "_group", "_class", "_difficulty", "_side"];
_OK = params
if !(params
[
["_positions",[],[[]],[1,2]],
["_group",grpNull,[grpNull]],
["_class","random",[""]],
["_difficulty","static",[""]],
["_side","bandit",[""]]
];
if (!_OK) exitWith
])
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_fnc_SpawnAIVehicle with invalid parameters: %1",_this];
};
// Using another params-exitwith structure just for _spawnPos because it's pretty important...
_OK = _positions params
if !(_positions params
[
["_spawnPos",[],[[]],[2,3]]
];
if (!_OK) exitWith
])
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_fnc_SpawnAIVehicle with invalid _positions parameters: %1",_positions];
};

View File

@ -14,13 +14,13 @@
private ["_crateClassName", "_pos", "_crate"];
_OK = params
if !(params
[
["_crateClassName","_crateClassName ERROR",[""]],
["_pos","_pos ERROR",[[]],[3]]
];
if (!_OK) exitWith
])
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_SpawnCrate with invalid parameters: %1",_this];
objNull
@ -48,6 +48,8 @@ else
};
_crate allowDamage false;
_crate enableSimulationGlobal false;
_crate enableRopeAttach false;
clearWeaponCargoGlobal _crate;
clearItemCargoGlobal _crate;

View File

@ -19,14 +19,13 @@ _mines = [];
if (DMS_SpawnMinesAroundMissions) then
{
_OK = params
if !(params
[
["_centerPos","",[[]],[2,3]],
["_difficulty","",["",[]],[2]],
["_side","",[""]]
];
if (!_OK) exitWith
])
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_fnc_SpawnMinefield with invalid parameters: %1",_this];
};
@ -51,7 +50,7 @@ if (DMS_SpawnMinesAroundMissions) then
_minesInfo = _difficulty;
if ((typeName _difficulty)=="STRING") then
if (_difficulty isEqualType "") then
{
_minesInfo = missionNamespace getVariable [format ["DMS_MineInfo_%1", _difficulty], [10,50]];
};

View File

@ -28,13 +28,13 @@
private ["_vehicleClass","_position","_vehpos","_maxDistance","_vehObj"];
_OK = params
if !(params
[
["_vehicleClass","",[""]],
["_position","",[[]],[2,3]]
];
if (!_OK) exitWith
])
exitWith
{
diag_log format ["DMS ERROR :: Calling DMS_fnc_SpawnNonPersistentVehicle with invalid parameters: %1",_this];
objNull
@ -112,6 +112,8 @@ _vehObj allowDamage false;
_vehObj enableRopeAttach false;
_vehObj enableSimulationGlobal false;
_vehObj setVariable ["ExileIsSimulationMonitored", false];
if (DMS_DEBUG) then
{
(format ["SpawnNonPersistentVehicle :: Created %1 at %2 with calling parameters: %3",_vehObj,_vehpos,_this]) call DMS_fnc_DebugLog;

View File

@ -16,18 +16,18 @@
private ["_vehicleClass", "_pos", "_pinCode", "_vehObj"];
_OK = params
[
["_vehicleClass","",[""]],
["_pos",[],[[]],[2,3]],
["_pinCode","",[0,""]]
];
_vehObj = objNull;
try
{
if (!_OK) then
if !(params
[
["_vehicleClass","",[""]],
["_pos",[],[[]],[2,3]],
["_pinCode","",[0,""]]
])
then
{
throw (format ["invalid parameters: %1",_this]);
};
@ -44,7 +44,7 @@ try
};
if ((typeName _pinCode)=="SCALAR") then
if (_pinCode isEqualType 0) then
{
if (_pinCode<0 || {_pinCode>9999}) then
{

View File

@ -12,7 +12,7 @@
Will accept non-array argument of group, unit, or object.
*/
if ((typeName _this) in ["GROUP","OBJECT"]) then
if !(_this isEqualType []) then
{
_this = [_this];
};
@ -29,27 +29,30 @@ _killed = false;
try
{
{
if (((typeName _x) == "OBJECT") && {!isNull _x && {alive _x}}) then
if (_x isEqualType objNull) then
{
private ["_lastDistanceCheckTime", "_spawnPos"];
_lastDistanceCheckTime = _x getVariable ["DMS_LastAIDistanceCheck",time];
_pos = getPosWorld _x;
_spawnPos = _x getVariable ["DMS_AISpawnPos",_pos];
if ((DMS_MaxAIDistance>0) && {((time - _lastDistanceCheckTime)>DMS_AIDistanceCheckFrequency) && {(_pos distance2D _spawnPos)>DMS_MaxAIDistance}}) then
if (!isNull _x && {alive _x}) 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,_x getVariable "DMS_AISpawnPos"];
}
else
{
throw _x;
private ["_lastDistanceCheckTime", "_spawnPos"];
_lastDistanceCheckTime = _x getVariable ["DMS_LastAIDistanceCheck",time];
_pos = getPosWorld _x;
_spawnPos = _x getVariable ["DMS_AISpawnPos",_pos];
if ((DMS_MaxAIDistance>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,_x getVariable "DMS_AISpawnPos"];
}
else
{
throw _x;
};
};
}
else
{
if ((typeName _x) != "GROUP") exitWith
if !(_x isEqualType grpNull) exitWith
{
diag_log format ["DMS ERROR :: %1 is neither OBJECT nor GROUP!",_x];
};

View File

@ -21,7 +21,15 @@ It is highly recommended that you add
!="(_this select 0) execVM \"\A3\Structures_F\Wrecks\Scripts\Wreck_Heli_Attack_01.sqf\""
```
at ***the END of the line that starts with "7 execVM" in scripts.txt*** . [Here is the pastebin](http://pastebin.com/W8bH252U).
at ***the END of the line that starts with "7 exec" in scripts.txt*** . [Here is the pastebin](http://pastebin.com/W8bH252U).
***AND:***
```
!="_v)} do {\n_posV = getPos _v;\n_smoke1 = \"#particlesource\" createVehicleLocal getpos _v;\n_smoke1 attachTo [_v,[0,0,0],\"engine_effe"
```
after "7 createVehicle"
## Installation:
@ -33,7 +41,8 @@ at ***the END of the line that starts with "7 execVM" in scripts.txt*** . [Here
## infiSTAR:
If you are using infiSTAR and want to keep ```_CGM = true;```, then set ```_UMW = true;``` (the latest version of infiSTAR already has DMS markers whitelisted in ```_aLocalM```).
* If you are using infiSTAR and want to keep ```_CGM = true;```, then set ```_UMW = true;```.
* Add ```'O_HMG_01_high_F'``` to "_VehicleWhiteList", as well as any other vehicles you add to DMS that are not whitelisted.
### Vilayer or other Game Server Providers Instructions:
@ -50,6 +59,11 @@ If you are using Vilayer or some other GameServer hosting service, and/or the ab
**DMS does not currently support headless client. Do not attempt to use HC with DMS unless you know what you are doing.**
## Troubleshooting:
DMS won't spawn missions? Check RPT for config errors or make sure PBO is packed correctly by unpacking it and ensuring the folder structure is "\x\addons\a3_DMS\...".
If you can't figure it out, leave a post on [the DMS thread on exile forums](http://www.exilemod.com/topic/61-dms-defents-mission-system/?do=findComment&comment=242). **Make sure to include your RPT, config.sqf, as well as any changed files.**
___
# Credits:
@ -64,13 +78,16 @@ ___
- [shaworth](https://github.com/shaworth) and [KawaiiPotato](https://github.com/KawaiiPotato) for making the README all nice and pretty :)
- [maca134](http://maca134.co.uk/portfolio/m3editor-arma-3-map-editor/) for M3Editor Stuff
- [Darth Rogue from SOA](http://soldiersofanarchy.net/) for the awesome base for the first DMS static mission :D
- [William from Refugees of the Fallen](http://refugeesofthefallen.enjin.com/) for the amazing slums static mission base and ideas :)
- [JamieKG from Eternal Gamer](http://eternal-gamer.com/) for testing and reporting issues.
- [Valthos from The Altis Project](https://www.thealtisproject.co.uk/) for testing and reporting issues.
- Everbody's feedback on [the DMS thread on exile forums](http://www.exilemod.com/topic/61-dms-defents-mission-system/?do=findComment&comment=242)
___
# Roadmap:
#### Continuous Optimization + Improvements.
* Implement the ability to "freeze" and "unfreeze" AI when there are no players nearby to improve performance. This will be under testing with a few selected server owners/community members. If you would like to participate in testing, please send a PM to [eraser1 on Exile Forums](http://www.exilemod.com/profile/96-eraser1/).
* ~~Implement the ability to "freeze" and "unfreeze" AI when there are no players nearby to improve performance. This will be under testing with a few selected server owners/community members. If you would like to participate in testing, please send a PM to [eraser1 on Exile Forums](http://www.exilemod.com/profile/96-eraser1/).~~ _This feature is slated for a future date_
#### AI Heli Paratroopers/air support.
@ -84,9 +101,14 @@ ___
* Spawn AI that are meant to "hunt" individual players.
* Air/Land AI Vehicle Patrols
#### Random community ideas:
* Spawning in a trader on mission completion ([Trillseeker82](http://www.exilemod.com/topic/61-dms-defents-mission-system/?do=findComment&comment=43932)).
#### Full Headless Client Support.
#### Custom client notifications.
#### Client Features.
* Kill messages when a group member kills an AI.
* Custom mission announcement messages.
#### (Maybe) Implement a form of stat-tracking system
* It will store AI kills in the database (this would almost certainly require some extra work on the behalf of server owners).
@ -94,6 +116,65 @@ ___
___
# Changelog:
#### December 24, 2015 (1:45 PM CST-America):
* **NEW CONFIG VALUES:**
DMS_SpawnFlareOnReinforcements
DMS_MissionMarkerWinDot_Type
DMS_MissionMarkerLoseDot_Type
DMS_EnableBoxMoving
DMS_BasesToImportOnServerStart
DMS_AI_Classname
DMS_AI_AimCoef_easy
DMS_AI_AimCoef_moderate
DMS_AI_AimCoef_difficult
DMS_AI_AimCoef_hardcore
DMS_AI_EnableStamina_easy
DMS_AI_EnableStamina_moderate
DMS_AI_EnableStamina_difficult
DMS_AI_EnableStamina_hardcore
DMS_AI_destroyStaticWeapon
DMS_AI_destroyStaticWeapon_chance
DMS_ai_SupportedRandomClasses
DMS_random_non_assault_AI
DMS_random_non_MG_AI
DMS_random_non_sniper_AI
* Please check out the new config values in config.sqf to see what they do :)
* Fixed issue with "thieves" mission (and DMS-spawned persistent vehicles in general). Big thank you to [JamieKG from Eternal Gamer](http://eternal-gamer.com/) and Torndeco.
* **New static mission: "slums"**
* Credit for the base goes to [William from Refugees of the Fallen](http://refugeesofthefallen.enjin.com/)
* Spawns 2 crates at 2 different locations from a list of 5 locations.
* No AI vehicles, only infantry (introduces Close Quarters Combat)
* Added to Altis by default.
* Static bases can now be imported on server startup instead of mission spawns. Enabled by default for saltflats and slums.
* Increased "DMS_MissionTimeoutResetRange" from 1000 to 1500.
* Removed the Navid from config (MG AI and box weapons).
* Edited panthera3_config to reduce SpawnZoneNear and TraderZoneNear blacklists.
* Edited "blackhawkdown" and "donthasslethehoff" missions to use a slightly different heli wreck classname.
* Increased marker circle diameter for saltflats mission to 750 meters.
* Moved "DMS_Version" variable assignment to pre-init.
* Moved Map Center and Map Radius assignments to post-init.
* Added support for 2 new optional parameters: _onMonitorStart and _onMonitorEnd, run before and after the Mission Monitor checks the mission, respectively, but AFTER "Mission Success State" is checked.
* Mines should now be deleted when a mission fails.
* Script optimizations for almost all functions using new command(s) introduced in ArmA v1.54, as well as improved technique(s).
* "ExileServer_system_garbageCollector_deleteObject" is now used to actually delete items by DMS_fnc_CleanUp.
* AI and vehicle cleanup should now be completely handled by Exile.
* Added support for mARMA logging.
* **You can now disable the movement/lifting of loot crates after the mission is complete using "DMS_EnableBoxMoving".**
* Added some debug code to DMS_fnc_FindSafePos and DMS_fnc_IsValidPosition (commented out by default)
* New group reinforcement type "increasing_difficulty".
* DMS_fnc_IsNearWater now checks for invalid parameter(s).
* DMS_fnc_PlayerAwardOnAIKill now checks for roadkill values AFTER unit-defined respect/tabs.
* You can now define different marker types for mission completion/failure using "DMS_MissionMarkerWinDot_Type" and "DMS_MissionMarkerLoseDot_Type" respectively.
* "DMS_fnc_SetGroupBehavior" can now take a unit as parameter as well. It will also now return true if behavior was changed, false otherwise.
* "DMS_fnc_SpawnAIGroup" and "DMS_fnc_SpawnAIGroup_MultiPos" now supports the definition of custom gear sets.
* Improved function documentation for "DMS_fnc_SpawnAIGroup", "DMS_fnc_SpawnAIGroup_MultiPos", and "DMS_fnc_SpawnAISoldier".
* "DMS_fnc_SpawnAISoldier" now supports multiple different random AI class presets. This means that you can define a certain "random" class preset, but have it select from a specially defined list that excludes classes that you don't want.
* Added default values to certain "missionNameSpace getVariable"s in DMS_fnc_SpawnAISoldier to prevent script errors in the event of invalid definitions.
* Slight logic tweak/fix to DMS_fnc_TargetsKilled (it shouldn't throw errors when there aren't any).
#### November 18, 2015 (7:45 PM CST-America):
* **Tweaks to saltflats static mission:**
* AI Vehicle is spawned AFTER the base is spawned (hopefully limits/prevents it from spawning inside something).