diff --git a/@ExileServer/addons/a3_dms/config.sqf b/@ExileServer/addons/a3_dms/config.sqf index 033aea8..b1d8dee 100644 --- a/@ExileServer/addons/a3_dms/config.sqf +++ b/@ExileServer/addons/a3_dms/config.sqf @@ -69,10 +69,7 @@ DMS_DEBUG = false; DMS_ai_share_info = true; // Share info about killer DMS_ai_share_info_distance = 300; // The distance killer's info will be shared to other AI - DMS_ai_use_launchers = true; // Enable/disable spawning an AI in a group with a launcher - DMS_ai_use_launchers_chance = 50; // Percentage chance to actually spawn the launcher (per-group) DMS_ai_nighttime_accessory_chance = 75; // Percentage chance that AI will have a flashlight or laser pointer on their guns if spawned during nighttime - DMS_ai_remove_launchers = false; // Remove rocket launchers on AI death DMS_ai_enable_water_equipment = true; // Enable/disable overriding default weapons of an AI if it spawns on/in water // https://community.bistudio.com/wiki/AI_Sub-skills#general @@ -83,6 +80,10 @@ DMS_DEBUG = false; DMS_ai_skill_difficult = [["aimingAccuracy",0.70],["aimingShake",0.70],["aimingSpeed",0.70],["spotDistance",0.70],["spotTime",0.80],["courage",1.00],["reloadSpeed",1.00],["commanding",1.00],["general",0.70]]; // Difficult DMS_ai_skill_hardcore = [["aimingAccuracy",1.00],["aimingShake",1.00],["aimingSpeed",1.00],["spotDistance",1.00],["spotTime",1.00],["courage",1.00],["reloadSpeed",1.00],["commanding",1.00],["general",1.00]]; // Hardcore DMS_ai_skill_random = ["hardcore","difficult","difficult","difficult","moderate","moderate","moderate","moderate","easy","easy"]; // Skill frequencies for "random" AI skills | Default: 10% hardcore, 30% difficult, 40% moderate, and 20% easy + DMS_AI_WP_Radius_easy = 20; // Waypoint radius for "easy" AI + DMS_AI_WP_Radius_moderate = 40; // Waypoint radius for "moderate" AI + DMS_AI_WP_Radius_difficult = 75; // Waypoint radius for "difficult" AI + DMS_AI_WP_Radius_hardcore = 150; // Waypoint radius for "hardcore" AI DMS_static_weapons = [ // Static weapons for AI "O_HMG_01_F", @@ -340,7 +341,19 @@ DMS_DEBUG = false; "sniper" ]; - DMS_AI_wep_launchers = ["Exile_Melee_Axe"]; + DMS_ai_use_launchers = true; // Enable/disable spawning an AI in a group with a launcher + DMS_ai_use_launchers_chance = 50; // Percentage chance to actually spawn the launcher (per-group) + DMS_AI_launcher_ammo_count = 2; // How many rockets an AI will get with its launcher + DMS_ai_remove_launchers = false; // Remove rocket launchers on AI death + + DMS_AI_wep_launchers_AT = [ // AT Launchers + "launch_NLAW_F", + "launch_RPG32_F", + "launch_B_Titan_short_F" + ]; + DMS_AI_wep_launchers_AA = [ // AA Launchers + "launch_B_Titan_F" + ]; /* AI Settings */ diff --git a/@ExileServer/addons/a3_dms/fn_DMS_preInit.sqf b/@ExileServer/addons/a3_dms/fn_DMS_preInit.sqf index 7d478af..c43265a 100644 --- a/@ExileServer/addons/a3_dms/fn_DMS_preInit.sqf +++ b/@ExileServer/addons/a3_dms/fn_DMS_preInit.sqf @@ -33,6 +33,7 @@ DMS_TargetsKilled = compileFinal preprocessFileLineNumbers "\x\addons\dms\sc DMS_SpawnAIGroup = compileFinal preprocessFileLineNumbers "\x\addons\dms\scripts\SpawnAIGroup.sqf"; DMS_SpawnAISoldier = compileFinal preprocessFileLineNumbers "\x\addons\dms\scripts\SpawnAISoldier.sqf"; DMS_OnKilled = compileFinal preprocessFileLineNumbers "\x\addons\dms\scripts\OnKilled.sqf";//<--- TODO +DMS_SetGroupBehavior = compileFinal preprocessFileLineNumbers "\x\addons\dms\scripts\SetGroupBehavior.sqf"; //Load config #include "config.sqf"; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/scripts/SetGroupBehavior.sqf b/@ExileServer/addons/a3_dms/scripts/SetGroupBehavior.sqf new file mode 100644 index 0000000..6a757fd --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/SetGroupBehavior.sqf @@ -0,0 +1,46 @@ +/* + DMS_SetGroupBehavior + Created by eraser1 + + Usage: + [ + _group, + _pos, + _difficulty + ] call DMS_SetGroupBehavior; + +*/ + +private ["_OK", "_group", "_pos", "_difficulty", "_radius", "_npos", "_i", "_wp"]; + +_OK = params +[ + ["_group",grpNull,[grpNull]], + ["_pos",[0,0,0],[[]],[2,3]], + ["_difficulty","moderate",[""]] +]; + +if (!_OK) then +{ + diag_log format ["DMS ERROR :: Calling DMS_SetGroupBehavior with invalid params: %1",_this]; +}; + +_group setCombatMode "RED"; +_group setBehaviour "COMBAT"; + + +if(_difficulty == "random") then +{ + _difficulty = DMS_ai_skill_random call BIS_fnc_selectRandom; +}; + +_radius = missionNamespace getVariable [format["DMS_AI_WP_Radius_%1"],40]; + +for "_i" from 0 to 359 step 45 do { + _npos = [(_pos select 0) + (sin(_i)*_radius), (_pos select 1) + (cos(_i)*_radius)]; + _wp = _group addWaypoint [_npos,(_radius/5)]; + _wp setWaypointType "MOVE"; +}; + +_wp = _group addWaypoint [_pos,_radius]; +_wp setWaypointType "CYCLE"; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/scripts/SpawnAIGroup.sqf b/@ExileServer/addons/a3_dms/scripts/SpawnAIGroup.sqf index 41ade2f..3061117 100644 --- a/@ExileServer/addons/a3_dms/scripts/SpawnAIGroup.sqf +++ b/@ExileServer/addons/a3_dms/scripts/SpawnAIGroup.sqf @@ -8,81 +8,113 @@ _pos, // Position of AI _count, // Number of AI _difficulty, // "random","hardcore","difficult","moderate", or "easy" - _type // "random","assault","MG","sniper" or "unarmed" + _type // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] _side // "bandit","hero", etc. ] call DMS_SpawnAIGroup; + + Returns AI Group */ -//<------ TODO +private ["_OK", "_pos", "_count", "_difficulty", "_type", "_side", "_pos_x", "_pos_y", "_pos_z", "_launcher", "_unit", "_client"]; -_position = _this select 0; - _pos_x = _position select 0; - _pos_y = _position select 1; - _pos_z = _position select 2; -_count = _this select 1; -_difficulty = _this select 2; -_type = _this select 3; -_side = _this select 4; +_OK = params +[ + ["_pos",[0,0,0],[[]],[3]], + ["_count",0,[0]], + ["_difficulty","random",[""]], + ["_type","random",[""]], + ["_side","bandit",[""]] +]; - -if(debug_mode) then { diag_log("WAI: Spawning AI " + str(_side)); }; - -// if soldier have AT/AA weapons -if (typeName _type == "ARRAY") then { - _launcher = _type select 1; - _type = _type select 0; +if (!_OK) then +{ + diag_log format ["DMS ERROR :: Calling DMS_SpawnAIGroup with invalid parameters: %1",_this]; }; -// Create AI group -_unitGroup = createGroup wai_bandit_side; +if (_count < 1) exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_SpawnAIGroup with less than 1 _count! _this: %1",_this]; +}; + +_pos_x = _pos select 0; +_pos_y = _pos select 1; +_pos_z = _pos select 2; + + +if(DMS_DEBUG) then +{ + diag_log format["DMS_DEBUG SpawnAIGroup :: Spawning %1 %2 %3 AI at %4 with %5 difficulty.",_count,_type,_side,_pos,_difficulty]; +}; + +// if soldier have AT/AA weapons +if (typeName _type == "ARRAY") then +{ + _launcher = _type select 1; + _type = _type select 0; +}; -// Find position -if(_pos_z == 0) then { - if(floor(random 2) == 1) then { +// Randomize position +if(_pos_z == 0) then +{ + if(round(random 1) == 1) then + { _pos_x = _pos_x - (5 + random(10)); } else { _pos_x = _pos_x + (5 + random(10)); }; - if(floor(random 2) == 1) then { + if(round(random 1) == 1) then + { _pos_y = _pos_y - (5 + random(10)); } else { _pos_y = _pos_y + (5 + random(10)); }; }; -// spawn X numvbers of AI in the group -for "_x" from 1 to _count do { - _unit = [_unitGroup,[_pos_x,_pos_y,_pos_z],_type,_difficulty,_side] call DMS_SpawnAISoldier; - ai_ground_units = (ai_ground_units + 1); + +_group = createGroup (missionNamespace getVariable [format ["DMS_%1Side",_side],EAST]); + +for "_i" from 1 to _count do { + _unit = [_group,[_pos_x,_pos_y,_pos_z],_type,_difficulty,_side] call DMS_SpawnAISoldier; }; -if (!isNil "_launcher" && wai_use_launchers) then { - call { - if (_launcher == "at") exitWith { _launcher = ai_wep_launchers_AT call BIS_fnc_selectRandom; }; - if (_launcher == "aa") exitWith { _launcher = ai_wep_launchers_AA call BIS_fnc_selectRandom; }; - }; - _rocket = _launcher call find_suitable_ammunition; - _unit addItemToBackpack _rocket; - _unit addItemToBackpack _rocket; - _unit addWeapon _launcher; + +if (DMS_ai_use_launchers && {(!isNil "_launcher") && {(random 100) <= DMS_ai_use_launchers_chance}}) then +{ + _launcher = ((missionNamespace getVariable [format ["DMS_AI_wep_launchers_%1",_launcher],["launch_NLAW_F"]]) call BIS_fnc_selectRandom); + _unit addBackpack "B_Carryall_mcamo"; + + [_unit, _launcher, DMS_AI_launcher_ammo_count] call BIS_fnc_addWeapon; - if(debug_mode) then { diag_log("WAI: AI "+str(_unit) + " have " + str(_rocket)); }; + if(DMS_DEBUG) then + { + diag_log format["DMS_DEBUG SpawnAIGroup :: Giving %1 a %2 launcher.",_unit,_launcher]; + }; }; -_unitGroup setFormation "ECH LEFT"; -_unitGroup selectLeader ((units _unitGroup) select 0); -if (!isNil "_mission") then { - if(debug_mode) then { diag_log("WAI: mission nr " + str(_mission)); }; - [_unitGroup, _mission] spawn bandit_behaviour; -} else { - [_unitGroup] spawn bandit_behaviour; +_group selectLeader ((units _group) select 0); +_group setFormation "WEDGE"; + + +if(_pos_z == 0) then +{ + [_group,_pos,_difficulty] call DMS_SetGroupBehavior; }; -if(_pos_z == 0) then { - [_unitGroup,[_pos_x,_pos_y,_pos_z],_difficulty] spawn group_waypoints; -}; -diag_log format ["WAI: Spawned a group of %1 AI at %2",_count,_position]; -_unitGroup \ No newline at end of file +/* +if (DMS_ai_offload_to_client) then +{ + _client = (allPlayers call BIS_fnc_selectRandom); + ExileServerOwnershipSwapQueue pushBack [_client,_group]; + if(DMS_DEBUG) then + { + diag_log format["DMS_DEBUG SpawnAIGroup :: Swapping group ownership of %1 to %2",_group,_client]; + }; +}; +*/ + +diag_log format ["DMS_SpawnAIGroup :: Spawned %1 AI at %2.",_count,_pos]; + +_group \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/scripts/SpawnAISoldier.sqf b/@ExileServer/addons/a3_dms/scripts/SpawnAISoldier.sqf index ae6bc50..45ca50a 100644 --- a/@ExileServer/addons/a3_dms/scripts/SpawnAISoldier.sqf +++ b/@ExileServer/addons/a3_dms/scripts/SpawnAISoldier.sqf @@ -26,6 +26,8 @@ _vest, // String | EG: "V_PlateCarrierGL_blk" _backpack // String | EG: "B_Carryall_oli" ] + + Returns AI Unit */ private ["_OK", "_useCustomGear", "_unarmed", "_type", "_customGear", "_unit", "_side", "_nighttime", "_weapon", "_muzzle", "_suppressor", "_pistols", "_pistol", "_customGearSet", "_helmet", "_uniform", "_vest", "_backpack", "_magazines", "_weaponAttachments", "_pistolAttachments", "_items", "_difficulty", "_skillArray"]; @@ -80,13 +82,6 @@ if !(DMS_ai_default_items isEqualTo []) then {_unit linkItem _x;false;} count DMS_ai_default_items; }; -/* -call { - if(_side == "bandit") exitWith { _unit setVariable ["Bandit",true];}; - if(_side == "hero") exitWith { _unit setVariable ["Hero",true];}; - if(_side == "special") exitWith { _unit setVariable ["Special",true];}; -}; -*/ call { @@ -123,7 +118,7 @@ if (!_useCustomGear) then if (!_unarmed) then { _weapon = (missionNamespace getVariable [format ["DMS_%1_weps",_type],[]) call BIS_fnc_selectRandom; - _muzzle = [_unit, _weapon, 4 + floor(random 3)] call BIS_fnc_addWeapon; + [_unit, _weapon, 4 + floor(random 3)] call BIS_fnc_addWeapon; _unit selectWeapon _weapon; @@ -141,7 +136,6 @@ if (!_useCustomGear) then { _unit addPrimaryWeaponItem (DMS_ai_BipodList call BIS_fnc_selectRandom); }; - if((random 100) <= (missionNamespace getVariable [format["DMS_%1_suppressor_chance",_type],0])) then { @@ -160,14 +154,14 @@ if (!_useCustomGear) then _unit forceAddUniform "U_O_Wetsuit"; _unit addVest "V_RebreatherIA"; _unit addGoggles "G_Diving"; - _muzzle = [_unit, "arifle_SDAR_F", 4 + floor(random 3), "20Rnd_556x45_UW_mag"] call BIS_fnc_addWeapon; + [_unit, "arifle_SDAR_F", 4 + floor(random 3), "20Rnd_556x45_UW_mag"] call BIS_fnc_addWeapon; }; - _pistols = missionNamespace getVariable [format ["DMS_%1_pistols",_type],[]; + _pistols = missionNamespace getVariable [format ["DMS_%1_pistols",_type],[]]; if !(_pistols isEqualTo []) then { _pistol = _pistols call BIS_fnc_selectRandom; - _muzzle = [_unit, _pistol, 2 + floor(random 2)] call BIS_fnc_addWeapon; + [_unit, _pistol, 2 + floor(random 2)] call BIS_fnc_addWeapon; }; // Infinite Ammo @@ -273,7 +267,6 @@ else // Soldier killed event handler _unit addEventHandler ["Killed",{[_this, "soldier"] call DMS_OnKilled;}]; -//_unit addEventHandler ["Killed",{[_unit, _group, "soldier"] call TargetsKilled;}]; _unit enableAI "TARGET"; _unit enableAI "AUTOTARGET";