Guest User

BIS_fnc_ambientAnim

a guest
Jan 29th, 2014
649
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.     Author: Jiri Wainar
  3.  
  4.     Description:
  5.     Play set of ambient animations on given unit.
  6.  
  7.     Remarks:
  8.     * Can handle several different anims and auto-switching between them.
  9.     * Detects nearby units with the same animation set and tries to select different animations.
  10.     * A game logic is created on units position and animated unit is then attached to it, to prevent possible problems, like player pushing units around.
  11.     * The unit can be snapped to a set snappoint to prevent game from repositioning the unit.
  12.         * The snappoint is automatically detected, snap distance is 2 meters (in top-down view, ignoring vertical info).
  13.         * To position unit vertically, move its snappoint up/down.
  14.         * A snappoint is a (cyan colored) helper "Sign_Pointer_Cyan_F".
  15.         * This is extremely handy if the unit needs to be placed near object(s) - like on chair near a table.
  16.  
  17.     Parameter(s):
  18.     0: OBJECT - unit the anim & gear changes are going to be applied to
  19.     1: STRING - animation set id, describing what the unit's action looks like.
  20.        > "STAND"        - standing still, slightly turning to the sides, with rifle weapon
  21.        > "STAND_IA"     - standing still, slightly turning to the sides, with rifle weapon
  22.        > "STAND_U1-3"   - standing still, slightly turning to the sides, no weapon
  23.        > "WATCH1-2"     - standing and turning around, with rifle weapon
  24.        > "GUARD"        - standing still, like on guard with hands behing the body
  25.        > "LISTEN_BRIEFING"  - standing still, hands behind back, recieving briefing / commands, no rifle.
  26.        > "LEAN_ON_TABLE"    - standing while leaning on the table
  27.        > "LEAN"     - standing while leaning (on wall)
  28.        > "BRIEFING"     - standing, playing ambient briefing loop with occasional random moves
  29.        > "BRIEFING_POINT_LEFT"  - contains 1 extra pointing animation, pointing left & high
  30.        > "BRIEFING_POINT_RIGHT" - contains 1 extra pointing animation, pointing right & high
  31.        > "BRIEFING_POINT_TABLE" - contains 1 extra pointing animation, pointing front & low, like at table
  32.        > "SIT1-3"       - sitting on chair or bench, with rifle weapon
  33.        > "SIT_U1-3"     - sitting on chair or bench, without weapon
  34.        > "SIT_AT_TABLE" - sitting @ table, hands on table
  35.        > "SIT_HIGH1-2"  - sitting on taller objects like a table or wall, legs not touching the ground. Needs a rifle!
  36.        > "SIT_LOW"      - sitting on the ground, with weapon.
  37.        > "SIT_LOW_U"    - sitting on the ground, without weapon.
  38.        > "SIT_SAD1-2"   - sitting on a chair, looking very sad.
  39.        > "KNEEL"        - kneeling, with weapon.
  40.        > "PRONE_INJURED_U1-2" - laying wounded, back on the ground, wothout weapon
  41.        > "PRONE_INJURED"    - laying wounded & still, back on the ground, with or without weapon
  42.        > "KNEEL_TREAT"  - kneeling while treating the wounded
  43.        > "REPAIR_VEH_PRONE" - repairing vehicle while laying on the ground (under the vehicle)
  44.        > "REPAIR_VEH_KNEEL" - repairing vehicle while kneeling (like changing a wheel)
  45.        > "REPAIR_VEH_STAND" - repairing/cleaning a vehicle while standing
  46.  
  47.     2: STRING - equipment level id, describing how heavily is the unit equipped.
  48.        > "NONE"         - no goggles, headgear, vest, weapon
  49.        > "LIGHT"        - no goggles, headgear, vest
  50.        > "MEDIUM"       - no goggles, headgear
  51.        > "FULL"         - no goggles
  52.        > "ASIS"         - no touches to the gear
  53.        > "RANDOM" (default) - gear is randomized according to the animation set
  54.  
  55.     3: OBJECT   - object unit to snap to; function won't try to search for the closest snappoint and will use this snappoint instead
  56.     4: BOOL     - function will try to interpolate into the ambient animation, if the interpolateTo link exists
  57.             - it is not officialy supported, so it's disabled by default
  58.             - works only for transitions from (some) default A3 stances to sets "STAND", "SIT_LOW" and "KNEEL"
  59.  
  60.     Returns:
  61.     -
  62.  
  63.     Example:
  64.     [this,"SIT_HIGH2"] call BIS_fnc_ambientAnim;
  65. */
  66.  
  67. //surpress the debuglog output
  68. private["_fnc_log_disable"];_fnc_log_disable = false;
  69.  
  70. if (isNil "BIS_fnc_ambientAnim__group") then
  71. {
  72.     BIS_fnc_ambientAnim__group = createGroup west;
  73. };
  74.  
  75. //do the immediate operations ----------------------------------------------------------------------
  76. private["_unit","_animset","_gear","_anims","_anim","_linked","_xSet","_azimutFix","_interpolate","_canInterpolate"];
  77. private["_attachOffset","_attachObj","_attachSpecsAuto","_attachSpecs","_attachSnap","_noBackpack","_noWeapon","_randomGear","_weapon","_forcedSnapPoint","_params"];
  78.  
  79. _unit        = [_this, 0, objNull, [objNull]] call BIS_fnc_param;
  80. _animset     = [_this, 1, "STAND", [""]] call BIS_fnc_param;
  81. _gear        = [_this, 2, "RANDOM", [""]] call BIS_fnc_param;
  82. _forcedSnapPoint = [_this, 3, objNull, [objNull]] call BIS_fnc_param;
  83. _interpolate     = [_this, 4, false, [true]] call BIS_fnc_param;
  84.  
  85. if (isNull _unit) exitWith
  86. {
  87.     //["Function terminated, unit doesn't exist!"] call BIS_fnc_logFormat;
  88. };
  89.  
  90. if (isNil "_forcedSnapPoint") then
  91. {
  92.     ["Forced snappoint doesn't exist!"] call BIS_fnc_error;
  93.  
  94.     _forcedSnapPoint = objNull;
  95. };
  96.  
  97. if ((_unit getVariable ["BIS_fnc_ambientAnim__animset",""]) != "") exitWith
  98. {
  99.     ["[%1] Trying to play an ambient animation [%3] while another [%2] is already playing!",_unit,_unit getVariable ["BIS_fnc_ambientAnim__animset",""],_animset] call BIS_fnc_logFormat;
  100.  
  101.     /*
  102.     _unit call BIS_fnc_ambientAnim__terminate;
  103.  
  104.     _this spawn
  105.     {
  106.         sleep 1;
  107.  
  108.         _this call BIS_fnc_ambientAnim;
  109.     };
  110.     */
  111. };
  112.  
  113. //surpress the unit "intelligence"
  114. {_unit disableAI _x} forEach ["ANIM","AUTOTARGET","FSM","MOVE","TARGET"];
  115.  
  116. //detach unit, if already attached to something
  117. detach _unit;
  118.  
  119. //store primary weapon
  120. _weapon = primaryWeapon _unit;
  121.  
  122. if (_weapon != "") then
  123. {
  124.     _unit setVariable ["BIS_fnc_ambientAnim__weapon",_weapon];
  125. };
  126.  
  127. /*--------------------------------------------------------------------------------------------------
  128.  
  129.     GET ANIMATION PARAMETERS
  130.  
  131. --------------------------------------------------------------------------------------------------*/
  132. _params = _animset call BIS_fnc_ambientAnimGetParams;
  133.  
  134. //defaults
  135. _anims      = _params select 0;
  136. _azimutFix  = _params select 1;
  137. _attachSnap     = _params select 2;
  138. _attachOffset   = _params select 3;
  139. _noBackpack     = _params select 4;
  140. _noWeapon   = _params select 5;
  141. _randomGear     = _params select 6;
  142. _canInterpolate = _params select 7;
  143.  
  144. if (count _anims == 0) exitWith {};
  145.  
  146. if (_gear == "RANDOM") then
  147. {
  148.     _gear = _randomGear call BIS_fnc_selectRandom;
  149. };
  150.  
  151. //setup the gear
  152. [_unit,_gear,_noWeapon,_noBackpack,_weapon] spawn
  153. {
  154.     private["_unit","_gear","_noWeapon","_noBackpack","_weapon"];
  155.  
  156.     _unit       = _this select 0;
  157.     _gear       = _this select 1;
  158.     _noWeapon   = _this select 2;
  159.     _noBackpack     = _this select 3;
  160.     _weapon     = _this select 4;
  161.  
  162.     sleep 1;
  163.  
  164.     switch (_gear) do
  165.     {
  166.         case "NONE":
  167.         {
  168.             removeGoggles _unit;
  169.             removeHeadgear _unit;
  170.             removeVest _unit;
  171.             removeAllWeapons _unit;
  172.  
  173.             _noBackpack = true;
  174.             _noWeapon = true;
  175.         };
  176.         case "LIGHT":
  177.         {
  178.             removeGoggles _unit;
  179.             removeHeadgear _unit;
  180.             removeVest _unit;
  181.  
  182.             _noBackpack = true;
  183.         };
  184.         case "MEDIUM":
  185.         {
  186.             removeGoggles _unit;
  187.             removeHeadgear _unit;
  188.         };
  189.         case "FULL":
  190.         {
  191.             removeGoggles _unit;
  192.         };
  193.         default
  194.         {
  195.         };
  196.     };
  197.  
  198.     //remove NV goggles from units without helmets
  199.     if (_gear != "ASIS") then
  200.     {
  201.         _unit unassignItem "nvgoggles";
  202.         _unit unassignItem "nvgoggles_opfor";
  203.         _unit unassignItem "nvgoggles_indep";
  204.     };
  205.  
  206.     //remove backpack for some anim sets
  207.     if (_noBackpack) then
  208.     {
  209.         removeBackpack _unit;
  210.     };
  211.  
  212.     //["[%1] _noWeapon = %2 | _storedWeapon = %3",_unit,_noWeapon,_unit getVariable ["BIS_fnc_ambientAnim__weapon",""]] call BIS_fnc_logFormat;
  213.  
  214.     //remove primary weapon for some anim sets
  215.     if (_noWeapon) then
  216.     {
  217.         _unit removeWeapon _weapon;
  218.     }
  219.     else
  220.     {
  221.         private["_storedWeapon"];
  222.  
  223.         _storedWeapon = _unit getVariable ["BIS_fnc_ambientAnim__weapon",""];
  224.  
  225.         if (primaryWeapon _unit == "" && _storedWeapon != "") then
  226.         {
  227.             //["Weapon [%1] provided to unit [%2].",_storedWeapon,_unit] call BIS_fnc_logFormat;
  228.  
  229.             _unit addWeapon _storedWeapon;
  230.             _unit selectWeapon _storedWeapon;
  231.         };
  232.     };
  233. };
  234.  
  235. //find linked units = nearby units playing same animation set
  236. _linked = _unit nearObjects ["man",5];
  237. _linked = _linked - [_unit];
  238.  
  239. //["[%1] RAW linked: %2",_unit,_linked] call BIS_fnc_logFormat;
  240.  
  241. {
  242.     _xSet = _x getVariable ["BIS_fnc_ambientAnim__animset",""];
  243.  
  244.     //["[%1] %2 has animset %3",_unit,_x,_xSet] call BIS_fnc_logFormat;
  245.  
  246.     if (_xSet != _animset || _xSet == "") then
  247.     {
  248.         _linked set [_forEachIndex,objNull];
  249.  
  250.         //["[%1] unit %2 removed from linked",_unit,_x] call BIS_fnc_logFormat;
  251.     }
  252.     else
  253.     {
  254.         //put a backlink into the linked unit
  255.         _xLinked = _x getVariable ["BIS_fnc_ambientAnim__linked",[]];
  256.  
  257.         //["[%1] %2 has linked units %3",_unit,_x,_xLinked] call BIS_fnc_logFormat;
  258.  
  259.         if !(_unit in _xLinked) then
  260.         {
  261.             _xLinked = _xLinked + [_unit];
  262.             _x setVariable ["BIS_fnc_ambientAnim__linked",_xLinked];
  263.  
  264.             //["[%1] %2 got a backlink to %1",_unit,_x] call BIS_fnc_logFormat;
  265.         };
  266.     };
  267. }
  268. forEach _linked; _linked = _linked - [objNull];
  269.  
  270. //["[%1] AFTER CLEAN linked: %2",_unit,_linked] call BIS_fnc_logFormat;
  271.  
  272. //get the auto snappoint specs
  273. _attachSpecsAuto = switch (_animset) do
  274. {
  275.     case "SIT_AT_TABLE":
  276.     {
  277.         [
  278.             ["Land_CampingChair_V2_F",[0,0.08,-0.02],-180],
  279.             ["Land_ChairPlastic_F",[0,0.08,-0.02],90],
  280.             ["Land_ChairWood_F",[0,0.02,-0.02],-180]
  281.         ];
  282.     };
  283.     case "SIT";
  284.     case "SIT1";
  285.     case "SIT2";
  286.     case "SIT3";
  287.     case "SIT_U1";
  288.     case "SIT_U2";
  289.     case "SIT_U3":
  290.     {
  291.         [
  292.             ["Land_CampingChair_V2_F",[0,0.08,0.05],-180],
  293.             ["Land_ChairPlastic_F",[0,0.08,0.05],90],
  294.             ["Land_ChairWood_F",[0,0.02,0.05],-180]
  295.         ];
  296.     };
  297.  
  298.     case "SIT_SAD1":
  299.     {
  300.         [
  301.             ["Box_NATO_Wps_F",[0,-0.27,0.03],0]
  302.         ];
  303.     };
  304.     case "SIT_SAD2":
  305.     {
  306.         [
  307.             ["Box_NATO_Wps_F",[0,-0.3,0.05],0]
  308.         ];
  309.     };
  310.     case "SIT_HIGH1":
  311.     {
  312.         [
  313.             ["Box_NATO_Wps_F",[0,-0.23,0.03],0]
  314.         ];
  315.     };
  316.     case "SIT_HIGH";
  317.     case "SIT_HIGH2":
  318.     {
  319.         [
  320.             ["Box_NATO_Wps_F",[0,-0.12,-0.20],0]
  321.         ];
  322.     };
  323.  
  324.  
  325.     default
  326.     {
  327.         [];
  328.     };
  329. };
  330.  
  331. //adjust the auto attach data according to the soldiers gear
  332. if ((count _attachSpecsAuto > 0) && !(_gear in ["NONE","LIGHT"])) then
  333. {
  334.     private["_attachPoint","_attachGearFix","_vest"];
  335.  
  336.     _attachGearFix = 0.06;
  337.     _vest = toLower (vest _unit);
  338.  
  339.     if (_vest in ["v_platecarrier1_rgr"]) then
  340.     {
  341.         _attachGearFix = _attachGearFix + 0.08;
  342.     };
  343.  
  344.     {
  345.         _attachPoint = _x select 1;
  346.         _attachPoint set [1, (_attachPoint select 1) + _attachGearFix];
  347.         _x set [1, _attachPoint];
  348.     }
  349.     forEach _attachSpecsAuto;
  350. };
  351.  
  352. //add the possible helper snappoint
  353. _attachSpecsAuto = _attachSpecsAuto + [["Sign_Pointer_Cyan_F",[0,0,_attachOffset],0]];
  354.  
  355. if !(isNull _forcedSnapPoint) then
  356. {
  357.     _attachObj = _forcedSnapPoint;
  358.     _attachSpecs = [typeOf _forcedSnapPoint,[0,0,_attachOffset],0];
  359.  
  360.     //get the attach specs
  361.     {
  362.         if ((_x select 0) == typeOf _forcedSnapPoint) exitWith
  363.         {
  364.             _attachSpecs = _x;
  365.         };
  366.     }
  367.     forEach _attachSpecsAuto;
  368. }
  369. else
  370. {
  371.     //default situation, snappoint not found = using unit position
  372.     _attachSpecs = [typeOf _unit,[0,0,_attachOffset],0];
  373.     _attachObj = _unit;
  374.  
  375.     //get the snappoint object
  376.     private["_obj"];
  377.  
  378.     {
  379.         _obj = nearestObject [_unit, _x select 0];
  380.  
  381.         if (([_obj,_unit] call BIS_fnc_distance2D) < _attachSnap) exitWith
  382.         {
  383.             _attachSpecs = _x;
  384.             _attachObj = _obj;
  385.         };
  386.     }
  387.     forEach _attachSpecsAuto;
  388. };
  389.  
  390.  
  391. //store linked units, won't be changed
  392. _unit setVariable ["BIS_fnc_ambientAnim__linked",_linked];      //array of units that should be checked for not playing same animation
  393.  
  394. //store persistant animation data in the units namespace
  395. _unit setVariable ["BIS_fnc_ambientAnim__anims",_anims];
  396. _unit setVariable ["BIS_fnc_ambientAnim__animset",_animset];
  397. _unit setVariable ["BIS_fnc_ambientAnim__interpolate",_interpolate && _canInterpolate];
  398.  
  399. //store variable animation data in the units namespace
  400. _unit setVariable ["BIS_fnc_ambientAnim__time",0];          //time when the animation has started
  401.  
  402. //disable collisions between unit and helper/attach object
  403. _attachObj disableCollisionWith _unit;
  404. _unit disableCollisionWith _attachObj;
  405.  
  406. //do the delayed operations ------------------------------------------------------------------------
  407. [_unit,_attachObj,_attachSpecs,_azimutFix] spawn
  408. {
  409.     private["_unit","_attachObj","_attachSpecs","_azimutFix","_group"];
  410.     private["_attachPos","_logic","_ehAnimDone","_ehKilled"];
  411.  
  412.     _unit       = _this select 0;
  413.     _attachObj  = _this select 1;
  414.     _attachSpecs    = _this select 2;
  415.     _azimutFix  = (_this select 3) + (_attachSpecs select 2);   //animation dir fix + snappoint (object) direction fix
  416.  
  417.     //wait for the simulation to start
  418.     waitUntil{time > 0};
  419.  
  420.     if (isNil "_unit") exitWith {};
  421.     if (isNull _unit) exitWith {};
  422.     if !(alive _unit && canMove _unit) exitWith {};
  423.  
  424.     _attachPos = getPosASL _attachObj;
  425.  
  426.     //create a logic for attaching of the unit
  427.     //_group = createGroup west;
  428.     //_group = group _unit;
  429.     _group = BIS_fnc_ambientAnim__group;
  430.  
  431.     _logic = _group createUnit ["Logic", _attachPos, [], 0, "NONE"];
  432.  
  433.     if (isNull _logic) exitWith
  434.     {
  435.         _unit call BIS_fnc_ambientAnim__playAnim;
  436.  
  437.         if (count units _group == 0) then
  438.         {
  439.             deleteGroup _group;
  440.         };
  441.     };
  442.  
  443.     _logic setPosASL _attachPos;
  444.     _logic setDir ((getDir _attachObj) + _azimutFix);
  445.  
  446.     //4debug
  447.     _unit setVariable ["BIS_fnc_ambientAnim__logic",_logic];
  448.     _unit setVariable ["BIS_fnc_ambientAnim__helper",_attachObj];
  449.  
  450.     //attach the unit to the game logic
  451.     _unit attachTo [_logic,_attachSpecs select 1];
  452.     _unit setVariable ["BIS_fnc_ambientAnim__attached",true];
  453.  
  454.     //"smart-select" animation that is not played on nearby unit and play it
  455.     _unit call BIS_fnc_ambientAnim__playAnim;
  456.  
  457.     //play next anim when previous finishes
  458.     _ehAnimDone = _unit addEventHandler
  459.     [
  460.         "AnimDone",
  461.         {
  462.             private["_unit","_anim","_pool"];
  463.  
  464.             _unit = _this select 0;
  465.             _anim = _this select 1;
  466.             _pool = _unit getVariable ["BIS_fnc_ambientAnim__anims",[]];
  467.  
  468.             //["[%1] Anim finished: %2",_unit,_anim] call BIS_fnc_logFormat;
  469.  
  470.             //ignore all non-animset animations
  471.             /*
  472.             if !(_anim in _pool) exitWith
  473.             {
  474.                 ["[i][%1] Anim '%2' not in unit's animset!",_unit,_anim] call BIS_fnc_logFormat;
  475.             };
  476.             */
  477.  
  478.             if (alive _unit) then
  479.             {
  480.                 _unit call BIS_fnc_ambientAnim__playAnim;
  481.             }
  482.             else
  483.             {
  484.                 _unit call BIS_fnc_ambientAnim__terminate;
  485.             };
  486.         }
  487.     ];
  488.     _unit setVariable ["BIS_EhAnimDone", _ehAnimDone];
  489.  
  490.     //free unit from anim loop if it is killed
  491.     _ehKilled = _unit addEventHandler
  492.     [
  493.         "Killed",
  494.         {
  495.             (_this select 0) call BIS_fnc_ambientAnim__terminate;
  496.         }
  497.     ];
  498.     _unit setVariable ["BIS_EhKilled", _ehKilled];
  499. };
  500.  
  501. //_unit call BIS_fnc_ambientAnim__playAnim;
  502. BIS_fnc_ambientAnim__playAnim =
  503. {
  504.     private["_unit","_anims","_anim","_available","_time","_linkedUnits","_linkedAnims","_xTime","_interpolate"];
  505.  
  506.     if (isNull _this) exitWith {};
  507.     if !(alive _this && canMove _this) exitWith {};
  508.  
  509.     _unit = _this;
  510.     _anims  = _unit getVariable ["BIS_fnc_ambientAnim__anims",[]];
  511.  
  512.     if (count _anims == 0) exitWith
  513.     {
  514.         ["Unit '%1' doesn't have defined ambient anims!",_unit,_anims] call BIS_fnc_logFormat;
  515.     };
  516.  
  517.     _linkedUnits = _unit getVariable ["BIS_fnc_ambientAnim__linked",[]];
  518.  
  519.     //find animations that are being played on linked units
  520.     _linkedAnims = [];
  521.  
  522.     _time = time - 10;
  523.  
  524.     {
  525.         _xTime = _x getVariable ["BIS_fnc_ambientAnim__time",_time];
  526.  
  527.         if (_xTime > _time) then
  528.         {
  529.             _linkedAnims = _linkedAnims + [animationState _x];
  530.         };
  531.     }
  532.     forEach _linkedUnits;
  533.  
  534.     //get animations available for player = not recently played by linked units
  535.     _available = _anims - _linkedAnims;
  536.  
  537.     if (count _available == 0) then
  538.     {
  539.         ["Unit '%1' doesn't have an available/free animation to play",_unit] call BIS_fnc_logFormat;
  540.  
  541.         _available = _anims;
  542.     };
  543.  
  544.     //select a random anim from the pool of available animations and play it
  545.     _anim = _available call BIS_fnc_selectRandom;
  546.  
  547.     _interpolate = _unit getVariable ["BIS_fnc_ambientAnim__interpolate",false];
  548.  
  549.     if (_interpolate) then
  550.     {
  551.         _unit playMoveNow _anim;
  552.     }
  553.     else
  554.     {
  555.         _unit switchMove _anim;
  556.     };
  557. };
  558.  
  559. //_unit call BIS_fnc_ambientAnim__terminate;
  560. BIS_fnc_ambientAnim__terminate =
  561. {
  562.     private["_unit","_ehAnimDone","_ehKilled","_fnc_log_disable","_detachCode"];
  563.  
  564.     _fnc_log_disable = false;
  565.  
  566.     if (typeName _this == typeName []) exitWith
  567.     {
  568.         {
  569.             _x call BIS_fnc_ambientAnim__terminate;
  570.         }
  571.         forEach _this;
  572.     };
  573.  
  574.     if (typeName _this != typeName objNull) exitWith {};
  575.  
  576.     if (isNull _this) exitWith {};
  577.  
  578.     _unit = _this;
  579.  
  580.     ["[%1] Terminating an ambient animation ...",_unit] call BIS_fnc_logFormat;
  581.  
  582.     /*
  583.     if !(alive _unit) exitWith
  584.     {
  585.         ["[%1] Ambient animation was not terminated, unit is dead!",_unit] call BIS_fnc_logFormat;
  586.     };
  587.     */
  588.  
  589.     /*
  590.     if !(_unit getVariable ["BIS_fnc_ambientAnim__attached",false]) exitWith
  591.     {
  592.         ["[%1] Ambient animation was not terminated, unit is not attached!",_unit] call BIS_fnc_logFormat;
  593.     };
  594.     */
  595.  
  596.     //enable the unit "intelligence"
  597.     {_unit enableAI _x} forEach ["ANIM", "AUTOTARGET", "FSM", "MOVE", "TARGET"];
  598.  
  599.     //remove the event handlers
  600.     _ehAnimDone     = _unit getVariable ["BIS_EhAnimDone",-1];
  601.     _ehKilled   = _unit getVariable ["BIS_EhKilled",-1];
  602.  
  603.     if (_ehAnimDone != -1) then
  604.     {
  605.         _unit removeEventHandler ["AnimDone",_ehAnimDone];
  606.         _unit setVariable ["BIS_EhAnimDone",-1];
  607.     };
  608.     if (_ehKilled != -1) then
  609.     {
  610.         _unit removeEventHandler ["Killed",_ehKilled];
  611.         _unit setVariable ["BIS_EhKilled",-1];
  612.     };
  613.  
  614.     _detachCode =
  615.     {
  616.         private["_logic"];
  617.  
  618.         //exit if object/unit doesn't exist
  619.         if (isNull _this) exitWith {};
  620.  
  621.         _logic = _this getVariable ["BIS_fnc_ambientAnim__logic",objNull];
  622.  
  623.         //delete the game logic
  624.         if !(isNull _logic) then
  625.         {
  626.             deleteVehicle _logic;
  627.         };
  628.  
  629.         ["[%1] Ambient animation-set [%2] terminated!",_this,_this getVariable ["BIS_fnc_ambientAnim__animset",""]] call BIS_fnc_logFormat;
  630.  
  631.         _this setVariable ["BIS_fnc_ambientAnim__attached",nil];
  632.         _this setVariable ["BIS_fnc_ambientAnim__animset",nil];
  633.         _this setVariable ["BIS_fnc_ambientAnim__anims",nil];
  634.         _this setVariable ["BIS_fnc_ambientAnim__interpolate",nil];
  635.         _this setVariable ["BIS_fnc_ambientAnim__time",nil];
  636.         _this setVariable ["BIS_fnc_ambientAnim__logic",nil];
  637.         _this setVariable ["BIS_fnc_ambientAnim__helper",nil];
  638.         //_this setVariable ["BIS_fnc_ambientAnim__weapon",nil];
  639.         _this setVariable ["BIS_fnc_ambientAnim__linked",nil];
  640.  
  641.         //detach unit, so it can freely move
  642.         detach _this; _this switchMove "";
  643.     };
  644.  
  645.     if (time > 0) then
  646.     {
  647.         _unit call _detachCode;
  648.     }
  649.     else
  650.     {
  651.         [_unit,_detachCode] spawn
  652.         {
  653.             sleep 0.3; (_this select 0) call (_this select 1);
  654.         };
  655.     };
  656. };
RAW Paste Data