From c512ef72d253d00acdbb4a1a09aacfd760b0f185 Mon Sep 17 00:00:00 2001 From: eraser1 Date: Fri, 18 Sep 2015 18:26:36 -0500 Subject: [PATCH] Finally another update... * NEW CONFIG VALUE: "DMS_HideBox". * Loot vehicles cannot be lifted, pushed, or damaged until the mission is completed successfully. Then the vehicle will be added to the Exile simulation monitor. * AI in vehicles will be automatically ejected on death. * Another potential fix for launchers not despawning off of AI sometimes. * When an AI gunner from an armed ground vehicle is killed, the driver will be switched to the gunner seat after 5-10 seconds. This prevents the driver from driving around aimlessly and trolling. * The above feature should now also work on AI that have been offloaded now (doing so was a major, major pain in the ass, and is the reason why there was no update yesterday). --- @ExileServer/addons/a3_dms/config.sqf | 3 +- .../a3_dms/scripts/fn_AILocalityManager.sqf | 11 +- .../addons/a3_dms/scripts/fn_FillCrate.sqf | 2 + .../a3_dms/scripts/fn_MissionsMonitor.sqf | 3 + .../addons/a3_dms/scripts/fn_OnKilled.sqf | 153 ++++++++++++++---- .../addons/a3_dms/scripts/fn_SpawnAIGroup.sqf | 4 + .../addons/a3_dms/scripts/fn_SpawnCrate.sqf | 5 + .../scripts/fn_SpawnNonPersistentVehicle.sqf | 27 +++- Pre-Packed PBO/a3_dms.pbo | Bin 189181 -> 192324 bytes README.md | 9 ++ 10 files changed, 176 insertions(+), 41 deletions(-) diff --git a/@ExileServer/addons/a3_dms/config.sqf b/@ExileServer/addons/a3_dms/config.sqf index dc6b83d..ca0e36b 100644 --- a/@ExileServer/addons/a3_dms/config.sqf +++ b/@ExileServer/addons/a3_dms/config.sqf @@ -47,6 +47,7 @@ DMS_DEBUG = false; DMS_MinWaterDepth = 20; // Minimum depth of water that an underwater mission can spawn at. + DMS_HideBox = false; // "Hide" the box from being visible by players until the mission is completed. 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 @@ -581,7 +582,7 @@ DMS_DEBUG = false; // Debug Overwrites if(DMS_DEBUG) then { - DMS_TimeBetweenMissions = [30,40]; + DMS_TimeBetweenMissions = [10,15]; DMS_MissionTimeOut = [60,70]; DMS_MissionTypes = [["testmission",1]]; //DMS_MissionTypes = [["mercbase",1]]; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_AILocalityManager.sqf b/@ExileServer/addons/a3_dms/scripts/fn_AILocalityManager.sqf index 473bda5..e7cc826 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_AILocalityManager.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_AILocalityManager.sqf @@ -10,7 +10,7 @@ if !(DMS_ai_offload_to_client) exitWith {}; { // Exile already has a group cleanup system, so we'll leave empty groups for it - if ((count (units _x))>1) then + if (((count (units _x))>1) && {!(_x getVariable ["DMS_LockLocality",false])}) then { private ["_leader", "_group", "_owner"]; _leader = leader _x; @@ -39,11 +39,14 @@ if !(DMS_ai_offload_to_client) exitWith {}; } else { - if (DMS_DEBUG) then + if !((groupOwner _group) isEqualTo (owner DMS_HC_Object)) then { - diag_log format ["DMS_DEBUG AILocalityManager :: Setting ownership of group %1 to HC (%2)",_group,DMS_HC_Object]; + _transferSuccess = _group setGroupOwner (owner DMS_HC_Object); + if (DMS_DEBUG) then + { + diag_log format ["DMS_DEBUG AILocalityManager :: Setting ownership of group %1 to HC (%2). Success: %3",_group,DMS_HC_Object,_transferSuccess]; + }; }; - _group setGroupOwner (owner DMS_HC_Object); }; }; }; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_FillCrate.sqf b/@ExileServer/addons/a3_dms/scripts/fn_FillCrate.sqf index 1b7a36c..b015763 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_FillCrate.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_FillCrate.sqf @@ -45,6 +45,8 @@ if !(DMS_GodmodeCrates) then _crate allowDamage true; }; +_crate hideObjectGlobal false; + if ((typeName _lootValues)=="ARRAY") then { diff --git a/@ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor.sqf b/@ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor.sqf index cc7293f..5ccfd7c 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_MissionsMonitor.sqf @@ -66,6 +66,9 @@ private ["_pos", "_success", "_timeStarted", "_timeUntilFail", "_units", "_build { _x lock 0; _x allowDamage true; + _x enableRopeAttach true; + _x enableSimulationGlobal true; + _x call ExileServer_system_simulationMonitor_addVehicle; } forEach _vehs; { diff --git a/@ExileServer/addons/a3_dms/scripts/fn_OnKilled.sqf b/@ExileServer/addons/a3_dms/scripts/fn_OnKilled.sqf index 95e6eb3..8afadc7 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_OnKilled.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_OnKilled.sqf @@ -15,7 +15,7 @@ */ -private ["_unit", "_player", "_side", "_type", "_launcher", "_playerObj", "_rockets", "_grpUnits", "_av", "_memCount", "_gunner", "_driver", "_veh", "_moneyGain", "_repGain", "_money", "_respect"]; +private ["_unit", "_killer", "_side", "_type", "_launcher", "_playerObj", "_rockets", "_grpUnits", "_av", "_memCount", "_gunner", "_driver", "_veh", "_moneyGain", "_repGain", "_money", "_respect"]; if (DMS_DEBUG) then @@ -23,12 +23,13 @@ if (DMS_DEBUG) then diag_log format ["DMS_DEBUG OnKilled :: Logging AI death with parameters: %1",_this]; }; -_unit = _this select 0 select 0; -_player = _this select 0 select 1; -_side = _this select 1; -_type = _this select 2; -_launcher = secondaryWeapon _unit; -_playerObj = objNull; +_unit = _this select 0 select 0; +_killer = _this select 0 select 1; +_side = _this select 1; +_type = _this select 2; +_launcher = secondaryWeapon _unit; +_launcherVar = _unit getVariable ["DMS_AI_Launcher",""]; +_playerObj = objNull; // Some of the previously used functions work with non-local argument. Some don't. BIS is annoying _removeAll = @@ -44,14 +45,32 @@ _removeAll = removeBackpackGlobal _unit; }; +moveOut _unit; + // Remove gear according to configs if (DMS_clear_AI_body && {(random 100) <= DMS_clear_AI_body_chance}) then { _unit call _removeAll; }; -if(DMS_ai_remove_launchers && {_launcher != ""}) then +if(DMS_ai_remove_launchers && {(_launcherVar != "") || {_launcher != ""}}) then { + // Because arma is stupid sometimes + if (_launcher=="") then + { + _launcher = _launcherVar; + + diag_log "sneaky launchers..."; + + { + if (_launcherVar in (weaponCargo _x)) exitWith + { + deleteVehicle _x; + diag_log "gotcha"; + }; + } forEach (nearestObjects [_unit, ["GroundWeaponHolder","WeaponHolderSimulated"], 5]); + }; + _rockets = _launcher call DMS_fnc_selectMagazine; _unit removeWeaponGlobal _launcher; @@ -82,14 +101,12 @@ _av = _unit getVariable ["DMS_AssignedVeh",objNull]; if (!isNull _av) then { // Determine whether or not the vehicle has any active crew remaining. - _memCount = {alive _x} count (crew _av); + _memCount = {[(alive _x),false] select (_unit isEqualTo _x);} count (crew _av); // Destroy the vehicle and add it to cleanup if there are no active crew members of the vehicle. if (_memCount<1) then { - moveOut _unit; - _av setDamage 1; DMS_CleanUpList pushBack [_av,diag_tickTime,DMS_AIVehCleanUpTime]; _av spawn {sleep 1;_this enableSimulationGlobal false;}; @@ -108,36 +125,112 @@ if (!isNull _av) then _gunner = gunner _av; _driver = driver _av; + + // The fact that I have to do this in the FUCKING ONKILLED EVENTHANDLER is a testament to why ArmA will make me die prematurely + _gunnerIsAlive = alive _gunner; + _driverIsAlive = alive _driver; + + if (_unit isEqualTo _gunner) then + { + _gunnerIsAlive = false; + }; + if (_unit isEqualTo _driver) then + { + _driverIsAlive = false; + }; + // If the gunner is dead but the driver is alive, then the driver becomes the gunner. // Helps with troll AI vehicles driving around aimlessly after the gunner is shot off. More realistic imo - if (((isNull _gunner) || {!(alive _gunner)}) && {!(isNull _driver) && {alive _driver}}) then + if (!_gunnerIsAlive && {_driverIsAlive}) then { - [_driver,_av] spawn + [_driver,_av,_killer] spawn { - _driver = _this select 0; - _av = _this select 1; - _av setVehicleAmmoDef 1; - sleep 5+(random 3); // 3 to 6 seconds delay after gunner death, to simulate reaction/switching time. + _driver = _this select 0; + _av = _this select 1; + _killer = _this select 2; + _grp = group _driver; + _owner = groupOwner _grp; - // The unit has to be local or else some of the commands won't work. Might as well eject the driver from the vehicle and make him useful. + _grp setVariable ["DMS_LockLocality",true]; + + // The AI has to be local in order for these commands to work, so I reset locality, just because it's really difficult to deal with otherwise + if (_owner!=2) then + { + diag_log format ["Temporarily setting owner of %1 to server from %2. Success: %3",_grp,_owner,_grp setGroupOwner 2]; + }; + + sleep 5+(random 3); // 5 to 8 seconds delay after gunner death + + if !(alive _driver) exitWith {}; + + unassignVehicle _driver; moveOut _driver; - if (!local _driver) exitWith {}; + + _driver disableCollisionWith _av; - //doGetOut _driver; - //unassignVehicle _driver; - waitUntil {(vehicle _driver)==_driver}; + _av setVehicleAmmoDef 1; + + waitUntil + { + unassignVehicle _driver; + doGetOut _driver; + moveOut _driver; + (vehicle _driver)==_driver + }; _driver assignAsGunner _av; [_driver] orderGetIn true; sleep 1.5; + if !(alive _driver) exitWith {}; _driver moveInGunner _av; + + _driver enableCollisionWith _av; if (DMS_DEBUG) then { - diag_log format["DMS_DEBUG OnKilled :: Switching driver of AI Vehicle (%1) to gunner.",typeOf _av]; + diag_log format["DMS_DEBUG OnKilled :: Switched driver of AI Vehicle (%1) to gunner.",typeOf _av]; }; + + if (_owner!=2) then + { + _start = time; + + // Controlling AI... yes. I have to do this + waitUntil + { + _driver assignAsGunner _av; + [_driver] orderGetIn true; + + _driver moveInGunner _av; + + (((gunner _av) isEqualTo _driver) || {(time-_start)>30}) + }; + + sleep 3; + + _start = time; + + waitUntil + { + _driver assignAsGunner _av; + [_driver] orderGetIn true; + + _driver moveInGunner _av; + + (((gunner _av) isEqualTo _driver) || {(time-_start)>30}) + }; + + _driver doTarget _killer; + _driver doFire _killer; + + sleep 15; + + diag_log format ["Resetting ownership of %1 to %2. Success: %3",_grp,_owner,_grp setGroupOwner _owner]; + }; + + _grp setVariable ["DMS_LockLocality",false]; }; }; }; @@ -145,11 +238,11 @@ if (!isNull _av) then }; -if (isPlayer _player) then +if (isPlayer _killer) then { - _veh = vehicle _player; + _veh = vehicle _killer; - _playerObj = _player; + _playerObj = _killer; // Reveal the killer to the AI units if (DMS_ai_share_info) then @@ -157,19 +250,19 @@ if (isPlayer _player) then { if (((position _x) distance2D (position _unit)) <= DMS_ai_share_info_distance ) then { - _x reveal [_player, 4.0]; + _x reveal [_killer, 4.0]; }; } forEach allUnits; }; // Fix for players killing AI from mounted vehicle guns - if (!(_player isKindOf "Exile_Unit_Player") && {!isNull (gunner _player)}) then + if (!(_killer isKindOf "Exile_Unit_Player") && {!isNull (gunner _killer)}) then { - _playerObj = gunner _player; + _playerObj = gunner _killer; }; - if (!(_veh isEqualTo _player) && {(driver _veh) isEqualTo _player}) then + if (!(_veh isEqualTo _killer) && {(driver _veh) isEqualTo _killer}) then { _playerObj = driver _veh; diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup.sqf index 317aec9..a9cc607 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnAIGroup.sqf @@ -73,6 +73,8 @@ if(_pos_z == 0) then _group = createGroup (missionNamespace getVariable [format ["DMS_%1Side",_side],EAST]); +_group setVariable ["DMS_LockLocality",nil]; + for "_i" from 1 to _count do { _unit = [_group,[_pos_x,_pos_y,_pos_z],_class,_difficulty,_side,"Soldier"] call DMS_fnc_SpawnAISoldier; @@ -93,6 +95,8 @@ if ((!isNil "_launcher") || {DMS_ai_use_launchers && {(random 100) <= DMS_ai_use _rocket = _launcher call DMS_fnc_selectMagazine; [_unit, _launcher, DMS_AI_launcher_ammo_count,_rocket] call BIS_fnc_addWeapon; + + _unit setVariable ["DMS_AI_Launcher",_launcher]; if(DMS_DEBUG) then { diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnCrate.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnCrate.sqf index 62f336f..7b8db7f 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_SpawnCrate.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnCrate.sqf @@ -33,4 +33,9 @@ clearItemCargoGlobal _crate; clearMagazineCargoGlobal _crate; clearBackpackCargoGlobal _crate; +if (DMS_HideBox) then +{ + _crate hideObjectGlobal true; +}; + _crate; \ No newline at end of file diff --git a/@ExileServer/addons/a3_dms/scripts/fn_SpawnNonPersistentVehicle.sqf b/@ExileServer/addons/a3_dms/scripts/fn_SpawnNonPersistentVehicle.sqf index f74dc97..00390aa 100644 --- a/@ExileServer/addons/a3_dms/scripts/fn_SpawnNonPersistentVehicle.sqf +++ b/@ExileServer/addons/a3_dms/scripts/fn_SpawnNonPersistentVehicle.sqf @@ -38,19 +38,34 @@ _maxDistance = 10; while{count _vehpos < 1} do { _vehpos = _position findEmptyPosition [20,_maxDistance,_vehicleClass]; - _maxDistance = (_maxDistance + 15); + _maxDistance = (_maxDistance + 5); }; -_vehObj = [_vehicleClass, _vehpos, (random 360), true] call ExileServer_object_vehicle_createNonPersistentVehicle; -_vehObj allowDamage false; -_vehObj setFuel 1; -_vehObj lock 2; +_vehpos set [2, 0.1]; + +_vehObj = createVehicle [_vehicleClass, _vehpos, [], 0, "CAN_COLLIDE"]; + +clearBackpackCargoGlobal _vehObj; +clearItemCargoGlobal _vehObj; +clearMagazineCargoGlobal _vehObj; +clearWeaponCargoGlobal _vehObj; + +_vehObj setVariable ["ExileIsPersistent", false]; + +_vehObj setFuel (0.75+(random 0.25)); +_vehObj setDir (random 360); +_vehObj setPosATL _vehpos; _vehObj setVectorUp (surfaceNormal _vehpos); +_vehObj lock 2; +_vehObj allowDamage false; +_vehObj enableRopeAttach false; +_vehObj enableSimulationGlobal false; + if (DMS_DEBUG) then { diag_log format ["DMS_DEBUG SpawnNonPersistentVehicle :: Created %1 at %2 with calling parameters: %3",_vehObj,_vehpos,_this]; }; -_vehObj +_vehObj \ No newline at end of file diff --git a/Pre-Packed PBO/a3_dms.pbo b/Pre-Packed PBO/a3_dms.pbo index 2884e852ba3bbe62092f902d9cf9846d14132f88..331b0a04860b8905f358bc3a7d6e1f0643e4df97 100644 GIT binary patch delta 3845 zcmcgvUu;`f8Lv;4G&hZnAZdS(c(olVFoZ<%t7i5(6Q4STzYE<}n`Vq@Xd02LxURak@;yd@; z>o`t_#0ytSeD68m`Tl>u?>l#XeQ5K&L*IJF`+D|({rqu#C;9sIGHrNyeP^T5^Ff1e zy;1C39o|W`wB9rj1BT=y3D6nkIvENh-^y+YMl6z!Y@F{n`*>qdG~CmF z?YUCrxsvB6SJ{u#$j83=k*B$_s|&CA*-!t1+S?N}m4iP;Q?2DdIHPDLnF*~{MnCdY zkjKyddfU^*UfuTiSoF5%aGPuyO5V&6<3cf&BBqH4F#F!NC(1T8bU(ZKlE=$tZ+nig z#I`4Re*`;J58}?gKvu?WtB zTLkr(M&}d_+e)7EwlM#@sIBs@AKi)uBzXywyaHaDq6HGOEG3o2mQf@?C&42xvB&1o zXT5uuzFtJfK4+?WQBy4N;iELKTGWu0bowI6swu7V$`opBy(gz?TBY(N>h&;X33VLg z-^9Rdb_pFn)B_S^6LiE9i_W5xEHR5d&lYCUiD6AC=2KZ>TvQBc0Lw+-j^~L5pDNcB zUk-3*#Nu+oAq<2Aff>$Egc+=sD$mcN-*~(_T_lr5OE6(mbLiEzpj^Wr`v-6!5W-JA zg;%QUVsUjf#1kd&ZCL?doH>IBNlGc21S^KF@U$_lVnIz~lj_7$bz%aQn!&s52L?E2 z!9wCZBrbuy^j*}vR+R-tf#Q5Ktt#`fM(1(B%o8QIj9oR&NF)+)h-@}{#Q+Da=5eq@ zlmg8UDaJg-@=_>-$&zYaQmrg!F64s{!V~?X-wqQ2I^fIWyeoX3TB)oOVE%{E(J4^G zAf_eK$i$cJScD+}V~~^i^d(#5IMvd`fEd(%UJ%(q(t(*U?w<*9Ijium;!mOGhBKFg zP&tcSfsj)?*aX#57WmJOw`z`DDJt5uZOb{>IW)5Wp~fSfkK9s6m-GSJwZ?DVR4k6=?xG$+(+kZtvH zT>yZ1^H9LgT^S0Q^$dYuy^eMKT#v^y;L&fZXfxoiQ-R~>UM}p)zdUU$xPV&k4a))_ zX0TaMN>Fw@FIU8mE1P{dijFk%4M|oO*_m0?&aN(?rZopzI9%9Kb&{!9n8|%%6tD!_ zHke{ZiRvybL4bDmC+$yu1}Iz&I0thd3W+|j<~9P3lN^bhLr(t1c-omfZRQBpc-P=* zM-3<&oS_C!K)@AfL%Nbr+jJ#rgO`P$lh2${@yAHDC>8z!c9yU*zigXFLoyf{o@BYbo2`jcPGf;7L&J)A*yLG5YRlw zL=5Qzda$QK7A?2L>GJ z4i6U7&=aR@`~SN|oUo1EfPdXKwR7IJMfB=Drm)vE^dur_c1%YP3D|QA+l_HeDeqR4 zBm?thiKk1xYHmLVsU6fc$t`y{SfLN;r{zftpi2%vM~*HGY!&= z{ZKx2D&*VT<^nodK@h6;D!uNny;2=Sf(ooZAypj8Ttt1(WP+tUwA?0pR##kPXuchtMjThQ|b8* zdJnOWe}zsSsTn7$!(Njk&CbYXySH-hC79>*KJP)@e)wE#R353PXVXumy z`)HA9I2etb?LQra>rEQ&UC~Hye~26ES^{Lls)618z6YXpyXUDHn@(U(4=!;|vTtso zu+QZI4Ks&(+29uH-hWqdXAp;&-&Q)<&$iHw%Iu%eHx3>y9r%4$Eb;T-{_Ty&azFAN L9s0ok&M*E0KHZ;L delta 1251 zcmYLIT}&KR6n4%6%kHw9QlLtqaF)6-t1G({C6-E)QiH9gkcMtd{mD2iciDm28JHiI z?H2rLV}lQ-%`~|&eX#XG6Q49BPGXFjSVNO)O!dhZ5{#h)OF~it77Ovt&Jym!%y+(f ze(w41xwjVr+dl`cei%HRd7`-N*jDoNHB0r}I=eAf&i(BPEtI)Co6<^hp=@rmteOig z?{~SbnTN^c{nmkssOSAxH?7`^2cgxfy{*+M>m_e8v|jI0_0Mi4*X!p#^+q_)i~Sqc zeC7Gjjexti+P0Ov5wNcLYOP*h!2^LU>qp<=;4JKAo3++_iO^uV%Y+-Yl7r=Q?fz)( z+?}Sx`SQ+0?D@o{?VP=x^pFTqd$EBhrEtWG^C3nL}<+=sHqT){5U}x9s;DjL(t%JU05~y))3s` zXki$>t`}s{R8koh8t%cCmgy)O8KMOJ1^c@+RC+2!S(+rQ6Z%ks3-serz7Q*c}ed#Wf_GLQ&ET(#fulQ5avs1N+he&+Un4|&chn3!kitp zv`vL(+ONVPDyz^~-GhRWk#y9F%tXVEW3*3$FrAoy#)?ifRP3VG1ccv>Iarsn zrYsr+H6o@ANmb%{PBKy%Nf|*y%98e=-xb{#kK?%vL8l|kh`JLzL{L^!qKvABMAixF zYL=jyb_Bwdn$3#Ju#P!ZX*1YY8*9fi(n!WY7M&wUnFPeS)}puD3#K(STeK%hMoP&9 zSq99CV+1o&7EPU`O}U-!OhA)gN+TaGmZ$R*(A*f0538>bqbR$Ztu!X=svw4f0Kj?>l0Tm!vYfB;>{fxkFl z^g#}qTojsu11{pH;I@m_ra*I1IuBhgx|xSI7v0T6#6|0Q2p5rEe*tEAd;T-{6DoX6 zdMQosH9#AkX@x2~^f`RrZC5SA51tbpFGN{`&RYoj1=bFmTI|6$9q1@`QWkYRhK@O| zGQew0N+xb+S0c)8UNZ^3R|Pe7YVm39MhPi42L_=Xf5DUVlO=fipiYcFlgMn0_R28T z$M6VEE