diff --git a/@ExileServer/addons/a3_dms/config.cpp b/@ExileServer/addons/a3_dms/config.cpp index 102150f..638b63a 100644 --- a/@ExileServer/addons/a3_dms/config.cpp +++ b/@ExileServer/addons/a3_dms/config.cpp @@ -49,6 +49,7 @@ class CfgFunctions class SetGroupBehavior {}; class SpawnAIGroup {}; class SpawnAISoldier {}; + class SpawnAIStatic {}; class SpawnCrate {}; class SpawnNonPersistentVehicle {}; class TargetsKilled {}; diff --git a/@ExileServer/addons/a3_dms/config.sqf b/@ExileServer/addons/a3_dms/config.sqf index b4d69ae..1391dc1 100644 --- a/@ExileServer/addons/a3_dms/config.sqf +++ b/@ExileServer/addons/a3_dms/config.sqf @@ -21,9 +21,6 @@ DMS_DEBUG = false; DMS_AI_KillPercent = 100; // The percent amount of AI that need to be killed for "killPercent" mission requirement (NOT IMPLEMENTED) - DMS_BanditMoneyGainOnKill = 50; // The amount of Poptabs gained for killing a bandit - DMS_BanditRepGainOnKill = 10; // The amount of Respect gained for killing a bandit - 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_MissionMarkerWinDotTime = 30; // How many seconds the "win" mission dot will remain on the map @@ -84,9 +81,15 @@ DMS_DEBUG = false; /* AI Settings */ + DMS_Bandit_Soldier_MoneyGain = 50; // The amount of Poptabs gained for killing a bandit soldier + DMS_Bandit_Soldier_RepGain = 10; // The amount of Respect gained for killing a bandit soldier + DMS_Bandit_Static_MoneyGain = 100; // The amount of Poptabs gained for killing a bandit static gunner + DMS_Bandit_Static_RepGain = 25; // The amount of Respect gained for killing a bandit static gunner + DMS_banditSide = EAST; // The side (team) that AI Bandits will spawn on DMS_clear_AI_body = false; // Clear AI body as soon as they die DMS_clear_AI_body_chance = 50; // Percentage chance that AI bodies will be cleared when they die + DMS_ai_disable_ramming_damage = true; // Disables damage due to ramming into AI. !!!NOTE: THIS WILL NOT BE RELIABLE WITH "DMS_ai_offload_to_client"!!! DMS_credit_roadkill = false; // Credit players with respect/poptabs if they kill an AI by running it over DMS_remove_roadkill = true; // Remove gear from AI bodies that are roadkilled DMS_remove_roadkill_chance = 50; // Percentage chance that roadkilled AI bodies will be deleted @@ -101,7 +104,6 @@ DMS_DEBUG = false; DMS_ai_enable_water_equipment = true; // Enable/disable overriding default weapons of an AI if it spawns on/in water // https://community.bistudio.com/wiki/AI_Sub-skills#general - DMS_ai_static_skills = true; // Use "DMS_ai_skill_static" for AI on static guns DMS_ai_skill_static = [["aimingAccuracy",0.20],["aimingShake",0.70],["aimingSpeed",0.75],["spotDistance",0.70],["spotTime",0.50],["courage",1.00],["reloadSpeed",1.00],["commanding",1.00],["general",1.00]]; // Static AI Skills DMS_ai_skill_easy = [["aimingAccuracy",0.30],["aimingShake",0.50],["aimingSpeed",0.50],["spotDistance",0.50],["spotTime",0.50],["courage",1.00],["reloadSpeed",1.00],["commanding",1.00],["general",0.50]]; // Easy DMS_ai_skill_moderate = [["aimingAccuracy",0.60],["aimingShake",0.60],["aimingSpeed",0.60],["spotDistance",0.60],["spotTime",0.60],["courage",1.00],["reloadSpeed",1.00],["commanding",1.00],["general",0.60]]; // Moderate @@ -533,5 +535,6 @@ DMS_DEBUG = false; if(DMS_DEBUG) then { DMS_TimeBetweenMissions = [30,60]; DMS_MissionTimeOut = [60,90]; + //DMS_MissionTypes = [["testmission",1]]; diag_log format ["DMS_DEBUG CONFIG :: Overriding DMS_TimeBetweenMissions (%1) and DMS_MissionTimeOut (%2)",DMS_TimeBetweenMissions,DMS_MissionTimeOut]; }; diff --git a/@ExileServer/addons/a3_dms/missions/cardealer.sqf b/@ExileServer/addons/a3_dms/missions/cardealer.sqf index 0cbb88a..405326d 100644 --- a/@ExileServer/addons/a3_dms/missions/cardealer.sqf +++ b/@ExileServer/addons/a3_dms/missions/cardealer.sqf @@ -42,8 +42,8 @@ _crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; _wreck = createVehicle ["Land_FuelStation_Build_F",[(_pos select 0) - 10, (_pos select 1),-0.2],[], 0, "CAN_COLLIDE"]; -_vehicle1 = ["Exile_Car_SUV_Red",_pos] call DMS_fnc_SpawnNonPersistentVehicle; -_vehicle2 = ["Exile_Car_SUV_Grey",_pos] call DMS_fnc_SpawnNonPersistentVehicle; +_vehicle1 = ["Exile_Car_SUV_Red",[(_pos select 0) + -1*(5+(random 5)),(_pos select 1) + -1*(5+(random 5)),0]] call DMS_fnc_SpawnNonPersistentVehicle; +_vehicle2 = ["Exile_Car_SUV_Grey",[(_pos select 0)+(5+(random 5)),(_pos select 1)+(5+(random 5)),0]] call DMS_fnc_SpawnNonPersistentVehicle; diff --git a/@ExileServer/addons/a3_dms/missions/donthasslethehoff.sqf b/@ExileServer/addons/a3_dms/missions/donthasslethehoff.sqf index 032d648..38e6105 100644 --- a/@ExileServer/addons/a3_dms/missions/donthasslethehoff.sqf +++ b/@ExileServer/addons/a3_dms/missions/donthasslethehoff.sqf @@ -36,6 +36,18 @@ _group = _side // "bandit","hero", etc. ] call DMS_fnc_SpawnAIGroup; +_staticGuns = +[ + [ + [(_pos select 0)+(5+(random 5)),(_pos select 1)+(5+(random 5)),0], + [(_pos select 0) + -1*(5+(random 5)),(_pos select 1) + -1*(5+(random 5)),0] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStatic; + // Create Crates _crate1 = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; @@ -62,7 +74,7 @@ _missionAIUnits = // Define mission-spawned objects and loot values _missionObjs = [ - [_wreck], + [_wreck]+_staticGuns, [_vehicle], [[_crate1,_crate_loot_values1]] ]; diff --git a/@ExileServer/addons/a3_dms/missions/testmission.sqf b/@ExileServer/addons/a3_dms/missions/testmission.sqf new file mode 100644 index 0000000..3ee162c --- /dev/null +++ b/@ExileServer/addons/a3_dms/missions/testmission.sqf @@ -0,0 +1,161 @@ +/* + Sample mission (duplicate for testing purposes) +*/ + +private ["_num", "_side", "_pos", "_difficulty", "_AICount", "_group", "_crate", "_crate_loot_values", "_msgStart", "_msgWIN", "_msgLOSE", "_missionName", "_missionAIUnits", "_missionObjs", "_markers", "_time", "_added","_vehicle"]; + +// For logging purposes +_num = DMS_MissionCount; + + +// Set mission side (only "bandit" is supported for now) +_side = "bandit"; + + +// find position +_pos = call DMS_fnc_findSafePos; + + +// Set general mission difficulty +_difficulty = "moderate"; + + +// Create AI +// TODO: Spawn AI only when players are nearby +_AICount = 4 + (round (random 2)); + +_group = +[ + _pos, // Position of AI + _AICount, // Number of AI + "random", // "random","hardcore","difficult","moderate", or "easy" + "random", // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _side // "bandit","hero", etc. +] call DMS_fnc_SpawnAIGroup; + +_staticGuns = +[ + [ + [(_pos select 0)+(5+(random 5)),(_pos select 1)+(5+(random 5)),0], + [(_pos select 0) + -1*(5+(random 5)),(_pos select 1) + -1*(5+(random 5)),0] + ], + _group, + "assault", + "static", + "bandit" +] call DMS_fnc_SpawnAIStatic; + + +// Create Crate +_crate = ["Box_NATO_Wps_F",_pos] call DMS_fnc_SpawnCrate; +_vehicle = ["Exile_Car_Offroad_Armed_Guerilla01",_pos] call DMS_fnc_SpawnNonPersistentVehicle; + +// Set crate loot values +_crate_loot_values = +[ + 5, // Weapons + 10, // Items + 3 // Backpacks +]; + + +// Define mission-spawned AI Units +_missionAIUnits = +[ + _group // We only spawned the single group for this mission +]; + +// Define mission-spawned objects and loot values +_missionObjs = +[ + _staticGuns, // We only spawn the static guns + [_vehicle], + [[_crate,_crate_loot_values]] +]; + +// Define Mission Start message +_msgStart = format["Armed Bandits!
A heavily armed bandit group has been spotted, take them out and claim their vehicle!"]; + +// Define Mission Win message +_msgWIN = format["Armed Bandits!
Convicts have successfully taken care of the bandit group!"]; + +// Define Mission Lose message +_msgLOSE = format["Armed Bandits!
The bandits have taken their vehicle and drove off, no loot today!"]; + +// Define mission name (for map marker and logging) +_missionName = "Armed Bandits"; + +// Create Markers +_markers = +[ + _pos, + _missionName, + _difficulty +] call DMS_fnc_CreateMarker; + +// Record time here (for logging purposes, otherwise you could just put "diag_tickTime" into the "DMS_AddMissionToMonitor" parameters directly) +_time = diag_tickTime; + +// Parse and add mission info to missions monitor +_added = +[ + _pos, + [ + [ + "kill", + _group + ], + [ + "playerNear", + [_pos,DMS_playerNearRadius] + ] + ], + [ + _time, + (DMS_MissionTimeOut select 0) + random((DMS_MissionTimeOut select 1) - (DMS_MissionTimeOut select 0)) + ], + _missionAIUnits, + _missionObjs, + [_msgWIN,_msgLOSE], + _markers, + _side +] call DMS_fnc_AddMissionToMonitor; + +// Check to see if it was added correctly, otherwise delete the stuff +if !(_added) exitWith +{ + diag_log format ["DMS ERROR :: Attempt to set up mission %1 with invalid parameters for DMS_AddMissionToMonitor! Deleting mission objects and resetting DMS_MissionCount.",_missionName]; + + // Delete AI units and the crate. I could do it in one line but I just made a little function that should work for every mission (provided you defined everything correctly) + _cleanup = []; + { + _cleanup pushBack _x; + } forEach _missionAIUnits; + + _cleanup pushBack ((_missionObjs select 0)+(_missionObjs select 1)); + + { + _cleanup pushBack (_x select 0); + } foreach (_missionObjs select 2); + + _cleanup call DMS_fnc_CleanUp; + + + // Delete the markers directly + {deleteMarker _x;} forEach _markers; + + + // Reset the mission count + DMS_MissionCount = DMS_MissionCount - 1; +}; + + +// Notify players +_msgStart call DMS_fnc_BroadcastMissionStatus; + + + +if (DMS_DEBUG) then +{ + diag_log format ["DMS_DEBUG MISSION: (%1) :: Mission #%2 started at %3 with %4 AI units and %5 difficulty at time %6",_missionName,_num,_pos,_AICount,_difficulty,_time]; +}; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/scripts/fn_OnKilled.sqf b/@ExileServer/addons/a3_dms/scripts/fn_OnKilled.sqf index 2782d31..5b2e153 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_OnKilled.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_OnKilled.sqf @@ -10,12 +10,12 @@ _killer ], _side, // "bandit" only for now - _type // not currently used + _type // Type of AI: "soldier","static","vehicle","heli", etc. ] call DMS_fnc_OnKilled; */ -private ["_unit", "_player", "_playerObj", "_side", "_type", "_launcher", "_rockets", "_money", "_respect", "_moneyGain", "_repGain"]; +private ["_unit", "_player", "_side", "_type", "_launcher", "_playerObj", "_rockets", "_grpUnits", "_veh", "_moneyGain", "_repGain", "_money", "_respect"]; if (DMS_DEBUG) then @@ -124,8 +124,8 @@ if (isPlayer _player) then if ((!isNull _playerObj) && {((getPlayerUID _playerObj) != "")}) then { - _moneyGain = missionNamespace getVariable [format ["DMS_%1MoneyGainOnKill",_side],0]; - _repGain = missionNamespace getVariable [format ["DMS_%1RepGainOnKill",_side],0]; + _moneyGain = missionNamespace getVariable [format ["DMS_%1_%2_MoneyGain",_side,_type],0]; + _repGain = missionNamespace getVariable [format ["DMS_%1_%2_RepGain",_side,_type],0]; if ((_moneyGain>0) || (_repGain>0)) then { diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup.sqf index 908bddc..9a03504 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup.sqf @@ -7,21 +7,21 @@ [ _pos, // Position of AI _count, // Number of AI - _difficulty, // "random","hardcore","difficult","moderate", or "easy" - _type // "random","assault","MG","sniper" or "unarmed" OR [_type,_launcher] + _difficulty, // AI Difficulty: "random","hardcore","difficult","moderate", or "easy" + _class // AI Class: "random","assault","MG","sniper" or "unarmed" OR [_class,_launcher] _side // Only "bandit" is supported atm ] call DMS_fnc_SpawnAIGroup; Returns AI Group */ -private ["_OK", "_pos", "_count", "_difficulty", "_type", "_side", "_pos_x", "_pos_y", "_pos_z", "_launcher", "_unit", "_client"]; +private ["_OK", "_pos", "_count", "_difficulty", "_class", "_side", "_pos_x", "_pos_y", "_pos_z", "_launcher", "_unit", "_client"]; _OK = params [ ["_pos",[0,0,0],[[]],[3]], ["_count",0,[0]], ["_difficulty","random",[""]], - ["_type","random",[""]], + ["_class","random",[""]], ["_side","bandit",[""]] ]; @@ -42,14 +42,14 @@ _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]; + diag_log format["DMS_DEBUG SpawnAIGroup :: Spawning %1 %2 %3 AI at %4 with %5 difficulty.",_count,_class,_side,_pos,_difficulty]; }; // if soldier have AT/AA weapons -if (typeName _type == "ARRAY") then +if (typeName _class == "ARRAY") then { - _launcher = _type select 1; - _type = _type select 0; + _launcher = _class select 1; + _class = _class select 0; }; // Randomize position @@ -74,7 +74,7 @@ if(_pos_z == 0) then _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_fnc_SpawnAISoldier; + _unit = [_group,[_pos_x,_pos_y,_pos_z],_class,_difficulty,_side,"Soldier"] call DMS_fnc_SpawnAISoldier; }; // An AI will definitely spawn with a launcher if you define type diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAISoldier.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAISoldier.sqf index 807b9ef..f27449d 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAISoldier.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAISoldier.sqf @@ -7,10 +7,11 @@ [ _group, // Group the AI will belong to _pos, // Position of AI - _type, // "random","assault","MG","sniper" or "unarmed" - _difficulty, // "random","hardcore","difficult","moderate", or "easy" + _class, // Classname: "random","assault","MG","sniper" or "unarmed" + _difficulty, // Difficulty: "random","static","hardcore","difficult","moderate", or "easy" _side, // "bandit","hero", etc. - _customGearSet // OPTIONAL: Manually defined AI gear. + _type, // Type of AI: "soldier","static","vehicle","heli", etc. + _customGearSet // OPTIONAL: Manually defined AI gear. ] call DMS_fnc_SpawnAIGroup; Usage for _customGearSet: @@ -21,6 +22,7 @@ _pistol, // String | EG: "hgun_Pistol_heavy_01_snds_F" _pistolAttachments, // Array of strings | EG: ["optic_MRD","muzzle_snds_acp"] _items, // Array of strings | EG: ["Rangefinder","ItemGPS","Exile_Item_InstaDoc"] + _launcher, // String | EG: "launch_RPG32_F" _helmet, // String | EG: "H_HelmetLeaderO_ocamo" _uniform, // String | EG: "U_O_GhillieSuit" _vest, // String | EG: "V_PlateCarrierGL_blk" @@ -30,16 +32,18 @@ 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"]; +private ["_OK", "_useCustomGear", "_unarmed", "_class", "_customGear", "_type", "_unit", "_side", "_nighttime", "_weapon", "_muzzle", "_suppressor", "_pistols", "_pistol", "_customGearSet", "_helmet", "_uniform", "_vest", "_backpack", "_launcher", "_magazines", "_weaponAttachments", "_pistolAttachments", "_items", "_difficulty", "_skillArray"]; _OK = params [ ["_group",grpNull,[grpNull]], ["_pos",[0,0,0],[[]],[3]], - ["_type","random",[""]], + ["_class","random",[""]], ["_difficulty","random",[""]], - ["_side","bandit",[""]] + ["_side","bandit",[""]], + ["_type","soldier",[""]] ]; + _useCustomGear = false; _unarmed = false; @@ -49,7 +53,7 @@ if (!_OK) then } else { - if ((_type == "custom") && {((count _this)>5)}) then + if ((_class == "custom") && {((count _this)>6)}) then { _customGear = _this select 5; _useCustomGear = true; @@ -93,20 +97,20 @@ if !(DMS_ai_default_items isEqualTo []) then }; -switch (toLower _type) do +switch (toLower _class) do { - case "random" : {_type = DMS_random_AI call BIS_fnc_selectRandom;}; - case "unarmed" : {_type = "assault";_unarmed = true;}; + case "random" : {_class = DMS_random_AI call BIS_fnc_selectRandom;}; + case "unarmed" : {_class = "assault";_unarmed = true;}; }; // Unit name -_unit setName format["[DMS_Unit_%1%2]",_type,floor(random 1000)]; +_unit setName format["[DMS_Unit_%1%2]",_class,floor(random 1000)]; if (!_useCustomGear) then { - if !(_type in DMS_ai_SupportedClasses) exitWith + if !(_class in DMS_ai_SupportedClasses) exitWith { - diag_log format ["DMS ERROR :: DMS_SpawnAISoldier called with unsupported _type: %1 | _this: %2",_type,_this]; + diag_log format ["DMS ERROR :: DMS_SpawnAISoldier called with unsupported _class: %1 | _this: %2",_class,_this]; }; @@ -120,18 +124,18 @@ if (!_useCustomGear) then { _unit linkItem _x; }; - } forEach (missionNamespace getVariable [format ["DMS_%1_equipment",_type],[]]); + } forEach (missionNamespace getVariable [format ["DMS_%1_equipment",_class],[]]); // Items (Loot stuff that goes in uniform/vest/backpack) - {_unit addItem _x;} forEach (missionNamespace getVariable [format ["DMS_%1_items",_type],[]]); + {_unit addItem _x;} forEach (missionNamespace getVariable [format ["DMS_%1_items",_class],[]]); // Clothes - _unit addHeadgear ((missionNamespace getVariable [format ["DMS_%1_helmets",_type],[]]) call BIS_fnc_selectRandom); - _unit forceAddUniform ((missionNamespace getVariable [format ["DMS_%1_clothes",_type],[]]) call BIS_fnc_selectRandom); - _unit addVest ((missionNamespace getVariable [format ["DMS_%1_vests",_type],[]]) call BIS_fnc_selectRandom); - _unit addBackpack ((missionNamespace getVariable [format ["DMS_%1_backpacks",_type],[]]) call BIS_fnc_selectRandom); + _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); // Make AI effective at night _nighttime = (sunOrMoon != 1); @@ -142,14 +146,14 @@ if (!_useCustomGear) then if (!_unarmed) then { - _weapon = (missionNamespace getVariable [format ["DMS_%1_weps",_type],[]]) call BIS_fnc_selectRandom; + _weapon = (missionNamespace getVariable [format ["DMS_%1_weps",_class],[]]) 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",_type],0])) then + if((random 100) <= (missionNamespace getVariable [format["DMS_%1_optic_chance",_class],0])) then { - _unit addPrimaryWeaponItem ((missionNamespace getVariable [format ["DMS_%1_optics",_type],[]]) call BIS_fnc_selectRandom); + _unit addPrimaryWeaponItem ((missionNamespace getVariable [format ["DMS_%1_optics",_class],[]]) call BIS_fnc_selectRandom); }; if (_nighttime && {(random 100) <= DMS_ai_nighttime_accessory_chance}) then @@ -157,12 +161,12 @@ if (!_useCustomGear) then _unit addPrimaryWeaponItem (["acc_pointer_IR","acc_flashlight"] call BIS_fnc_selectRandom); }; - if((random 100) <= (missionNamespace getVariable [format["DMS_%1_bipod_chance",_type],0])) then + if((random 100) <= (missionNamespace getVariable [format["DMS_%1_bipod_chance",_class],0])) then { _unit addPrimaryWeaponItem (DMS_ai_BipodList call BIS_fnc_selectRandom); }; - if((random 100) <= (missionNamespace getVariable [format["DMS_%1_suppressor_chance",_type],0])) then + if((random 100) <= (missionNamespace getVariable [format["DMS_%1_suppressor_chance",_class],0])) then { _suppressor = _weapon call DMS_fnc_FindSuppressor; if(_suppressor != "") then @@ -182,7 +186,7 @@ if (!_useCustomGear) then [_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",_class],[]]; if !(_pistols isEqualTo []) then { _pistol = _pistols call BIS_fnc_selectRandom; @@ -204,6 +208,7 @@ else ["_pistol","",[""]], ["_pistolAttachments",[],[[]]], ["_items",[],[[]]], + ["_launcher","",[""]], ["_helmet","",[""]], ["_uniform","",[""]], ["_vest","",[""]], @@ -241,6 +246,11 @@ else _unit addBackpack _backpack; }; + if !(_launcher isEqualTo "") then + { + [_unit, _launcher, 0] call BIS_fnc_addWeapon; + }; + // Add Magazines before weapon so that gun will be loaded { @@ -255,7 +265,7 @@ else // Add gun and attachments if !(_weapon isEqualTo "") then { - _muzzle = [_unit, _weapon, 0] call BIS_fnc_addWeapon; + [_unit, _weapon, 0] call BIS_fnc_addWeapon; { _unit addPrimaryWeaponItem _x; @@ -268,7 +278,7 @@ else // Add pistol and attachments if !(_pistol isEqualTo "") then { - _muzzle = [_unit, _pistol, 0] call BIS_fnc_addWeapon; + [_unit, _pistol, 0] call BIS_fnc_addWeapon; { _unit addPrimaryWeaponItem _x; @@ -287,7 +297,21 @@ else // Soldier killed event handler -_unit addMPEventHandler ["MPKilled",'if (isServer) then {[_this, '+str _side+', "soldier"] call DMS_fnc_OnKilled;};']; +_unit addMPEventHandler ["MPKilled",'if (isServer) then {[_this, '+str _side+', '+str _type+'] call DMS_fnc_OnKilled;};']; + +// Remove ramming damage from players. Will not work if unit is not local (offloaded) +if (DMS_ai_disable_ramming_damage) then +{ + _unit addEventHandler ["HandleDamage", + { + _dmg = _this select 2; + if (isPlayer (_this select 3) && {(_this select 4)==""}) then + { + _dmg = 0; + }; + _dmg + }]; +}; _unit enableAI "TARGET"; _unit enableAI "AUTOTARGET"; @@ -297,7 +321,7 @@ _unit enableAI "FSM"; if (DMS_DEBUG) then { - diag_log format ["DMS_DEBUG SpawnAISoldier :: Spawned a %1 %2 AI at %3 with %4 difficulty to group %5",_type,_side,_pos,_difficulty,_group]; + diag_log format ["DMS_DEBUG SpawnAISoldier :: Spawned a %1 %2 %6 AI at %3 with %4 difficulty to group %5",_class,_side,_pos,_difficulty,_group,_type]; }; _unit diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIStatic.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIStatic.sqf new file mode 100644 index 0000000..5a53684 --- /dev/null +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIStatic.sqf @@ -0,0 +1,71 @@ +/* + DMS_fnc_SpawnAIStatic + Created by eraser1 + Influenced by WAI + + Usage: + [ + [ // Array of static gun positions + _pos1, + _pos2, + ... + _pos3 + ], + _group, // Group to which the AI unit(s) belongs to + _class, // Class: "random","assault","MG","sniper" or "unarmed" + _difficulty, // Difficulty: "random","static","hardcore","difficult","moderate", or "easy" + _side // "bandit","hero", etc. + ] call DMS_fnc_SpawnAIStatic; + + Returns an array of static gun objects. +*/ + +private ["_OK", "_guns", "_pos", "_gun", "_unit", "_group", "_class", "_difficulty", "_side", "_positions"]; + + +_OK = params +[ + ["_positions",[],[[]]], + ["_group",grpNull,[grpNull]], + ["_class","random",[""]], + ["_difficulty","static",[""]], + ["_side","bandit",[""]] +]; + +if (!_OK) exitWith +{ + diag_log format ["DMS ERROR :: Calling DMS_fnc_SpawnAIStatic with invalid parameters: %1",_this]; +}; + + +_guns = []; + +{ + _pos = _x; + + _gun = createVehicle [(DMS_static_weapons call BIS_fnc_selectRandom), _pos, [], 0, "CAN_COLLIDE"]; + _gun setDir (random 360); + _gun setPosATL _pos; + _gun addEventHandler ["GetOut",{(_this select 0) setDamage 1;}]; + _gun lock 2; + + _guns pushBack _gun; + + _unit = [_group,_pos,_class,_difficulty,_side,"Static"] call DMS_fnc_SpawnAISoldier; + + _unit moveingunner _gun; + reload _unit; + + if (DMS_DEBUG) then + { + diag_log format ["DMS_DEBUG SpawnAIStatic :: Created unit %1 at %2 as static gunner in %3",_unit,_pos,_gun]; + }; +} forEach _positions; + + +if (DMS_DEBUG) then +{ + diag_log format ["DMS_DEBUG SpawnAIStatic :: Created %1 static AI with parameters: %2",count _positions,_this]; +}; + +_guns \ No newline at end of file diff --git a/Pre-Packed PBO/a3_dms.pbo b/Pre-Packed PBO/a3_dms.pbo index 7b20c44..16230d2 100644 Binary files a/Pre-Packed PBO/a3_dms.pbo and b/Pre-Packed PBO/a3_dms.pbo differ diff --git a/README.md b/README.md index 38f4aae..9735f24 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,14 @@ if (!hasInterface && !isServer) then ## Changelog: +#### September 9, 2015 (10:00 PM CST-America): +* Added static AI! The "donthasslethehoff" mission has them included by default. :D +* New config values: ```DMS_Bandit_Static_MoneyGain``` and ```DMS_Bandit_Static_RepGain```. +* Future-proofed ```DMS_fnc_OnKilled```. As a result, "DMS_BanditMoneyGainOnKill" is now ```DMS_Bandit_Soldier_MoneyGain```, and "DMS_BanditRepGainOnKill" is now ```DMS_Bandit_Soldier_RepGain```. +* Added config value ```DMS_ai_disable_ramming_damage```. Check the comment for more info :) +* Removed config value "DMS_ai_static_skills" +* Randomized vehicle spawn position for "cardealer" mission. + #### September 8, 2015 (11:00 PM CST-America): * AI Bodies should now be properly cleaned when run over (if configured to do so with ```DMS_remove_roadkill``` and ```DMS_remove_roadkill_chance```). * Added config option ```DMS_credit_roadkill```. If set to true, players will get poptabs/respect for running over AI. Default: false.