diff --git a/1. Installation Package/@A3XAI/addons/a3xai.pbo b/1. Installation Package/@A3XAI/addons/a3xai.pbo index df9392f..646d364 100644 Binary files a/1. Installation Package/@A3XAI/addons/a3xai.pbo and b/1. Installation Package/@A3XAI/addons/a3xai.pbo differ diff --git a/1. Installation Package/@A3XAI/addons/a3xai_config.pbo b/1. Installation Package/@A3XAI/addons/a3xai_config.pbo index f5db277..69c83d7 100644 Binary files a/1. Installation Package/@A3XAI/addons/a3xai_config.pbo and b/1. Installation Package/@A3XAI/addons/a3xai_config.pbo differ diff --git a/4. SQF/addons/a3xai/compile/A3XAI_behavior/A3XAI_reinforce_begin.sqf b/4. SQF/addons/a3xai/compile/A3XAI_behavior/A3XAI_reinforce_begin.sqf index 12f1959..bc293d2 100644 --- a/4. SQF/addons/a3xai/compile/A3XAI_behavior/A3XAI_reinforce_begin.sqf +++ b/4. SQF/addons/a3xai/compile/A3XAI_behavior/A3XAI_reinforce_begin.sqf @@ -1,6 +1,6 @@ #include "\A3XAI\globaldefines.hpp" -private ["_unitGroup", "_waypoint", "_vehicle", "_endTime", "_vehiclePos", "_nearUnits", "_vehPos", "_despawnPos", "_reinforcePos","_vehicleArmed","_paraDrop","_reinforceTime"]; +private ["_unitGroup", "_waypoint", "_vehicle", "_endTime", "_vehiclePos", "_nearUnits", "_vehPos", "_despawnPos", "_reinforcePos","_vehicleArmed","_paraDrop","_reinforceTime","_unitLevel","_canDeploy"]; _unitGroup = _this; @@ -8,14 +8,25 @@ _unitGroup = _this; if (!hasInterface && !isDedicated) exitWith {diag_log format ["Error: %1 executed on headless client.",__FILE__];}; if !((typeName _unitGroup) isEqualTo "GROUP") exitWith {diag_log format ["A3XAI Error: Invalid group %1 provided to %2.",_unitGroup,__FILE__];}; -_vehicle = _unitGroup getVariable ["assignedVehicle",objNull]; -_vehicleArmed = ((({_x call A3XAI_checkIsWeapon} count (weapons _vehicle)) > 0) || {({_x call A3XAI_checkIsWeapon} count (_vehicle weaponsTurret [-1])) > 0} || {(_vehicle call A3XAI_countVehicleGunners) > 0}); -_reinforcePos = _unitGroup getVariable ["ReinforcePos",[0,0,0]]; +_vehicle = _unitGroup getVariable ["assignedVehicle",objNull]; +_vehicleArmed = ((({_x call A3XAI_checkIsWeapon} count (weapons _vehicle)) > 0) || {({_x call A3XAI_checkIsWeapon} count (_vehicle weaponsTurret [-1])) > 0} || {(_vehicle call A3XAI_countVehicleGunners) > 0}); +_reinforcePos = _unitGroup getVariable ["ReinforcePos",[0,0,0]]; +_canDeploy = true; if (_vehicleArmed) then { + _unitLevel = _unitGroup getVariable ["unitLevel",0]; + _canDeploy = (missionNamespace getVariable [format ["A3XAI_airReinforceDeployChance%1",_unitLevel],0.00]) call A3XAI_chance; +}; + +if (_canDeploy) then { + _paraDrop = [_unitGroup,_vehicle,objNull] spawn A3XAI_heliParaDrop; + waitUntil {uiSleep 0.1; scriptDone _paraDrop}; +} else { _waypoint = [_unitGroup,0]; _waypoint setWaypointStatements ["true",""]; - _waypoint setWaypointType "GUARD"; + + //Original: + _waypoint setWaypointType "SAD"; _waypoint setWaypointBehaviour "AWARE"; _waypoint setWaypointCombatMode "RED"; @@ -37,7 +48,14 @@ if (_vehicleArmed) then { _vehiclePos = getPosATL _vehicle; _vehiclePos set [2,0]; _nearUnits = _vehiclePos nearEntities [[PLAYER_UNITS,"LandVehicle"],DETECT_RANGE_AIR_REINFORCE]; - if ((count _nearUnits) > 5) then {_nearUnits resize 5}; + + { + if !(isPlayer _x) then { + _nearUnits deleteAt _forEachIndex; + }; + if (_forEachIndex > 4) exitWith {}; + } forEach _nearUnits; + { if ((isPlayer _x) && {(_unitGroup knowsAbout _x) < 3} && {(lineIntersectsSurfaces [(aimPos _vehicle),(eyePos _x),_vehicle,_x,true,1]) isEqualTo []}) then { _unitGroup reveal [_x,3]; @@ -47,14 +65,11 @@ if (_vehicleArmed) then { }; } forEach _nearUnits; }; - uiSleep 15; + uiSleep 10; }; _unitGroup setSpeedMode "NORMAL"; if (A3XAI_debugLevel > 0) then {diag_log format ["A3XAI Debug: Group %1 reinforcement timer complete.",_unitGroup];}; -} else { - _paraDrop = [_unitGroup,_vehicle,objNull] spawn A3XAI_heliParaDrop; - waitUntil {uiSleep 0.1; scriptDone _paraDrop}; }; if (((_unitGroup getVariable ["GroupSize",-1]) < 1) or {!((_unitGroup getVariable ["unitType",""]) isEqualTo "air_reinforce")}) exitWith { @@ -82,4 +97,4 @@ waitUntil {uiSleep 15; (((getPosATL _vehicle) distance2D _vehPos) > 1200) or {!( _unitGroup call A3XAI_cleanupReinforcementGroup; A3XAI_reinforcedPositions = A3XAI_reinforcedPositions - _reinforcePos; -true +true \ No newline at end of file diff --git a/4. SQF/addons/a3xai/compile/A3XAI_utilities/A3XAI_generateVehicleLoot.sqf b/4. SQF/addons/a3xai/compile/A3XAI_utilities/A3XAI_generateVehicleLoot.sqf new file mode 100644 index 0000000..3a6f4bd --- /dev/null +++ b/4. SQF/addons/a3xai/compile/A3XAI_utilities/A3XAI_generateVehicleLoot.sqf @@ -0,0 +1,37 @@ +#include "\A3XAI\globaldefines.hpp" + +private ["_vehicle", "_unitLevel", "_weapon", "_magazine", "_lootItem"]; + +_vehicle = _this; + +if (isNull _vehicle) exitWith {}; + +_unitLevel = A3XAI_unitLevels call A3XAI_selectRandom; + +for "_i" from 1 to A3XAI_weaponLootVehicleCount do { + _weapon = _unitLevel call A3XAI_getWeapon; + _magazine = getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines") select 0; + _vehicle addWeaponCargoGlobal [_weapon,1]; + _vehicle addMagazineCargoGlobal [_magazine,A3XAI_ammoLootPerWeapon]; +}; + +for "_i" from 1 to A3XAI_foodLootVehicleCount do { + _lootItem = (A3XAI_foodLoot call A3XAI_selectRandom); + _vehicle addItemCargoGlobal [_lootItem,1]; +}; + +for "_i" from 1 to A3XAI_miscLootVehicleCount do { + _lootItem = (A3XAI_miscLoot call A3XAI_selectRandom); + _vehicle addItemCargoGlobal [_lootItem,1]; +}; + +for "_i" from 1 to A3XAI_medicalLootVehicleCount do { + _lootItem = (A3XAI_medicalLoot call A3XAI_selectRandom); + _vehicle addItemCargoGlobal [_lootItem,1]; +}; + +if (A3XAI_debugLevel > 1) then { + diag_log format ["A3XAI Debug: Generated loot for AI %1 at %2 with unitLevel %3.",(typeOf _vehicle),(getPosATL _vehicle),_unitLevel]; +}; + +true \ No newline at end of file diff --git a/4. SQF/addons/a3xai/compile/A3XAI_utilities/A3XAI_releaseVehicleAllow.sqf b/4. SQF/addons/a3xai/compile/A3XAI_utilities/A3XAI_releaseVehicleAllow.sqf index fcec871..571d9b7 100644 --- a/4. SQF/addons/a3xai/compile/A3XAI_utilities/A3XAI_releaseVehicleAllow.sqf +++ b/4. SQF/addons/a3xai/compile/A3XAI_utilities/A3XAI_releaseVehicleAllow.sqf @@ -9,6 +9,7 @@ if ((toLower _vehicleClass) isEqualTo "autonomous") exitWith {}; _object removeAllEventHandlers "GetIn"; if (isDedicated) then { + _object call A3XAI_generateVehicleLoot; _object addEventHandler ["GetIn",{ if (isPlayer (_this select 2)) then { (_this select 0) call A3XAI_releaseVehicleNow; diff --git a/4. SQF/addons/a3xai/init/A3XAI_functions.sqf b/4. SQF/addons/a3xai/init/A3XAI_functions.sqf index 497d7c6..bb22662 100644 --- a/4. SQF/addons/a3xai/init/A3XAI_functions.sqf +++ b/4. SQF/addons/a3xai/init/A3XAI_functions.sqf @@ -117,6 +117,7 @@ A3XAI_deleteGroup = compileFinal preprocessFileLineNumbers format ["%1\compile\A A3XAI_deleteCustomSpawn = compileFinal preprocessFileLineNumbers format ["%1\compile\A3XAI_utilities\A3XAI_deleteCustomSpawn.sqf",A3XAI_directory]; A3XAI_findSpawnPos = compileFinal preprocessFileLineNumbers format ["%1\compile\A3XAI_utilities\A3XAI_findSpawnPos.sqf",A3XAI_directory]; A3XAI_fixStuckGroup = compileFinal preprocessFileLineNumbers format ["%1\compile\A3XAI_utilities\A3XAI_fixStuckGroup.sqf",A3XAI_directory]; +A3XAI_generateVehicleLoot = compileFinal preprocessFileLineNumbers format ["%1\compile\A3XAI_utilities\A3XAI_generateVehicleLoot.sqf",A3XAI_directory]; A3XAI_getNoAggroStatus = compileFinal preprocessFileLineNumbers format ["%1\compile\A3XAI_utilities\A3XAI_getNoAggroStatus.sqf",A3XAI_directory]; A3XAI_getSafePosReflected = compileFinal preprocessFileLineNumbers format ["%1\compile\A3XAI_utilities\A3XAI_getSafePosReflected.sqf",A3XAI_directory]; A3XAI_getSpawnParams = compileFinal preprocessFileLineNumbers format ["%1\compile\A3XAI_utilities\A3XAI_getSpawnParams.sqf",A3XAI_directory]; diff --git a/4. SQF/addons/a3xai/init/loadSettings.sqf b/4. SQF/addons/a3xai/init/loadSettings.sqf index 8343b90..0977f1c 100644 --- a/4. SQF/addons/a3xai/init/loadSettings.sqf +++ b/4. SQF/addons/a3xai/init/loadSettings.sqf @@ -191,6 +191,10 @@ _fnc_getConfigValue = { ["airReinforcementSpawnChance2",0.20], ["airReinforcementSpawnChance3",0.30], ["airReinforcementAllowedFor",["static","dynamic","random"]], + ["airReinforceDeployChance0",0.60], + ["airReinforceDeployChance1",0.70], + ["airReinforceDeployChance2",0.80], + ["airReinforceDeployChance3",0.90], ["airReinforcementDuration0",120], ["airReinforcementDuration1",180], ["airReinforcementDuration2",240], @@ -300,6 +304,12 @@ _fnc_getConfigValue = { ["underbarrelChance3",0.90], ["foodLootCount",2], ["miscLootCount",2], + ["weaponLootVehicleCount",6], + ["ammoLootPerWeapon",3], + ["foodLootVehicleCount",6], + ["miscLootVehicleCount",6], + ["medicalLootVehicleCount",3], + ["medicalLoot",["Exile_Item_InstaDoc","Exile_Item_Bandage","Exile_Item_Vishpirin"]], ["firstAidKitChance",0.25], ["lootPullChance0",0.20,true], ["lootPullChance1",0.40,true], diff --git a/4. SQF/addons/a3xai/scripts/verifyClassnames.sqf b/4. SQF/addons/a3xai/scripts/verifyClassnames.sqf index f390e42..3cd20a9 100644 --- a/4. SQF/addons/a3xai/scripts/verifyClassnames.sqf +++ b/4. SQF/addons/a3xai/scripts/verifyClassnames.sqf @@ -301,8 +301,9 @@ if (A3XAI_pistolList isEqualTo []) then {A3XAI_pistolList = ["hgun_ACPC2_F","hgu if (A3XAI_rifleList isEqualTo []) then {A3XAI_rifleList = ["arifle_Katiba_C_F","arifle_Katiba_F","arifle_Katiba_GL_F","arifle_Mk20_F","arifle_Mk20_GL_F","arifle_Mk20_GL_plain_F","arifle_Mk20_plain_F","arifle_Mk20C_F","arifle_Mk20C_plain_F","arifle_MX_Black_F","arifle_MX_F","arifle_MX_GL_Black_F","arifle_MX_GL_F","arifle_MXC_Black_F","arifle_MXC_F","arifle_SDAR_F","arifle_TRG20_F","arifle_TRG21_F","arifle_TRG21_GL_F"]}; if (A3XAI_machinegunList isEqualTo []) then {A3XAI_machinegunList = ["arifle_MX_SW_Black_F","arifle_MX_SW_F","LMG_Mk200_F","LMG_Zafir_F","MMG_01_hex_F","MMG_01_tan_F","MMG_02_black_F","MMG_02_camo_F","MMG_02_sand_F"]}; if (A3XAI_sniperList isEqualTo []) then {A3XAI_sniperList = ["arifle_MXM_Black_F","arifle_MXM_F","srifle_DMR_01_F","srifle_DMR_02_camo_F","srifle_DMR_02_F","srifle_DMR_02_sniper_F","srifle_DMR_03_F","srifle_DMR_03_khaki_F","srifle_DMR_03_multicam_F","srifle_DMR_03_tan_F","srifle_DMR_03_woodland_F","srifle_DMR_04_F","srifle_DMR_04_Tan_F","srifle_DMR_05_blk_F","srifle_DMR_05_hex_F","srifle_DMR_05_tan_f","srifle_DMR_06_camo_F","srifle_DMR_06_olive_F","srifle_EBR_F","srifle_GM6_camo_F","srifle_GM6_F","srifle_LRR_camo_F","srifle_LRR_F"]}; -if (A3XAI_foodLoot isEqualTo []) then {A3XAI_foodLootCount = 0}; -if (A3XAI_MiscLoot isEqualTo []) then {A3XAI_miscLootCount = 0}; +if (A3XAI_foodLoot isEqualTo []) then {A3XAI_foodLootCount = 0; A3XAI_foodLootVehicleCount = 0;}; +if (A3XAI_miscLoot isEqualTo []) then {A3XAI_miscLootCount = 0; A3XAI_miscLootVehicleCount = 0;}; +if (A3XAI_medicalLoot isEqualTo []) then {A3XAI_medicalLootCount = 0; A3XAI_medicalLootVehicleCount = 0;}; if (A3XAI_airReinforcementVehicles isEqualTo []) then {A3XAI_maxAirReinforcements = 0; A3XAI_airReinforcementSpawnChance1 = 0; A3XAI_airReinforcementSpawnChance2 = 0; A3XAI_airReinforcementSpawnChance3 = 0;}; diag_log format ["[A3XAI] Verified %1 unique classnames in %2 seconds.",(count _verified),(diag_tickTime - _startTime)]; diff --git a/4. SQF/addons/a3xai_config/config.cpp b/4. SQF/addons/a3xai_config/config.cpp index ae02251..952cfc4 100644 --- a/4. SQF/addons/a3xai_config/config.cpp +++ b/4. SQF/addons/a3xai_config/config.cpp @@ -424,7 +424,14 @@ class CfgA3XAISettings { //AI types permitted to summon reinforcements. Default: airReinforcementAllowedFor[] = {"static","dynamic","random"}; //Usable AI types: "static", "dynamic", "random", "air", "land", "staticcustom", "aircustom", "landcustom", "vehiclecrew" - airReinforcementAllowedFor[] = {"static","dynamic","random"}; + airReinforcementAllowedFor[] = {"static","dynamic","random","vehiclecrew","land","air"}; + + //Probability to deploy infantry AI. If chance roll fails, air vehicle will remain in area for duration defined by airReinforcementDuration0-3 and engage detected players + //Unarmed air vehicle will always have a 1.00 probability to deploy at least 1 infantry AI unit. + airReinforceDeployChance0 = 0.60; + airReinforceDeployChance1 = 0.70; + airReinforceDeployChance2 = 0.80; + airReinforceDeployChance3 = 0.90; //Maximum time for reinforcement for armed air vehicles in seconds. AI air vehicle will leave the area after this time if not destroyed. airReinforcementDuration0 = 120; @@ -635,6 +642,25 @@ class CfgA3XAISettings { //Maximum number of items to select from MiscLoot (generic loot) table. (Default: 2) miscLootCount = 2; + /* AI loot quantity settings (Vehicle) + + Note: A3XAI_vehiclesAllowedForPlayers = 1; must be set in order to enable the settings in this section + --------------------------------------------------------------------------------------------------------------------*/ + + //Maximum number of weapons from pistolList, rifleList, machinegunList, sniperList found in vehicles recovered by players. (Default: 5) + weaponLootVehicleCount = 5; + + //Maximum number of magazines to generate for each weapon loot added to vehicle inventory (Default: 3) + ammoLootPerWeapon = 3; + + //Maximum number of food loot items from foodLoot found in vehicles recovered by players. (Default: 10) + foodLootVehicleCount = 2; + + //Maximum number of items to select from miscLoot found in vehicles recovered by players. (Default: 10) + miscLootVehicleCount = 10; + + //Maximum number of items to select from medicalLoot found in vehicles recovered by players. (Default: 5) + medicalLootVehicleCount = 3; /* AI loot probability settings. AI loot is pre-generated into a pool for each unit and randomly pulled to units as time passes. --------------------------------------------------------------------------------------------------------------------*/ @@ -731,6 +757,11 @@ class CfgA3XAISettings { foodLoot[] = {"Exile_Item_GloriousKnakworst","Exile_Item_SausageGravy","Exile_Item_ChristmasTinner","Exile_Item_BBQSandwich","Exile_Item_Surstromming","Exile_Item_Catfood","Exile_Item_PlasticBottleFreshWater","Exile_Item_Beer","Exile_Item_Energydrink"}; miscLoot[] = {"Exile_Item_Rope","Exile_Item_DuctTape","Exile_Item_ExtensionCord","Exile_Item_FuelCanisterEmpty","Exile_Item_JunkMetal","Exile_Item_LightBulb","Exile_Item_MetalBoard","Exile_Item_MetalPole","Exile_Item_CamoTentKit"}; + //AI Medical item types. + // Note: medicalLoot will not be read if generateMedicalFood is enabled. + //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + medicalLoot[] = {"Exile_Item_InstaDoc","Exile_Item_Bandage","Exile_Item_Vishpirin"}; + //AI toolbelt item types. Toolbelt items are added to AI inventory upon death. Format: [item classname, item probability] //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ diff --git a/5. Changelogs/0.2.2.txt b/5. Changelogs/0.2.2.txt new file mode 100644 index 0000000..d56cd7c --- /dev/null +++ b/5. Changelogs/0.2.2.txt @@ -0,0 +1,11 @@ +A3XAI 0.2.2 + +Files changed: +A3XAI.pbo update required: Yes +A3XAI_config.pbo update required: Yes +Headless Client Files/Keys update required: Removed +A3XAI Client Addon update required: No + +[Changed] AI Reinforcement to allow for paratroopers +[Added] Randomised configurable vehicle loot +[Fixed] Fixed vehicle type detection (Air, Land) for kill types (was updated prior to now but I forget to update it here diff --git a/6. Headless Client/@A3XAI_HC/addons/a3xai.pbo b/6. Headless Client/@A3XAI_HC/addons/a3xai.pbo index 0094c2e..646d364 100644 Binary files a/6. Headless Client/@A3XAI_HC/addons/a3xai.pbo and b/6. Headless Client/@A3XAI_HC/addons/a3xai.pbo differ diff --git a/README.md b/README.md index b010b2d..11e3389 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ -A3XAI - Current Version: 0.2.1 +A3XAI - Current Version: 0.2.2 ===== +Updated to include vehicle loot and paratrooper reinforcements by Porkeld +--- Introduction --- diff --git a/Special thanks and credits.txt b/Special thanks and credits.txt deleted file mode 100644 index bfbdd18..0000000 --- a/Special thanks and credits.txt +++ /dev/null @@ -1,15 +0,0 @@ -Listed in absolutely no particular order: - -1. Prerelease Build Test Volunteers: -Darth Rogue -Dirty Sanchez -Tobias Solem -Dobrowney -Skare - -2. Other works used: -BIN_taskPatrol: BIS, Binesi, Wolffy.au -SHK_Pos: Shuko -Code excerpts used to support Exile features: Exile Mod devs @ http://www.exilemod.com/ - -If you have contributed your effort or works towards development of A3XAI and were not credited, please notify me ASAP. Username on Exile mod forums: http://www.exilemod.com/profile/66-face/