class FSM { fsmName = "sapper swarm member"; class States { class sapper { name = "sapper"; itemno = ; init = "_unit = _this select 0;" \n "_destination = _this select 1;" \n "" \n "_t = diag_tickTime;" \n "_p = _t;" \n "" \n "_nextPos = [];" \n "_roughDir = 0;" \n "_callDispose = false;" \n "_decisionMade = false;" \n "_c = diag_tickTime;" \n "_sFreqCheck = 1.5;" \n "_lFreqCheck = 12;" \n "_doneCheck = false;" \n "_canSee = false;" \n "_newTrgt = false;" \n "_detonateDist = 2.8;" \n "_stuckCount = 0;" \n "_trgt = player;" \n "_trgtPos = getPosATL _trgt;" \n "_sTrgt = objNull;" \n "_charging = false;" \n "_tDist = 999;" \n "_uMoveTo = [];" \n "EPOCH_SapperCanSee = false;" \n "_sapperWalkHandle = -1;" \n "_sapperDisposeHandle = -1;" \n "_lastPos = getPosATL _unit;" \n "_stuckCount = 0;" \n "_beenFollowed = false;" \n "" \n "_bomb = createVehicle [""Sapper_Charge_Ammo"", (getposATL _unit), [], 0, ""CAN_COLLIDE""] ; " \n "_bomb attachTo [_unit, [0,0,0],""Pelvis""];" \n "" \n "_unit setVariable [""sTarget"",objNull];" \n "" \n "//initial move" \n "_nextPos = _trgtPos findEmptyPosition [0,50,typeOf _unit];" \n "_unit moveTo _nextPos;" \n "" \n "" \n "if !(isNull _unit) then {" \n " EPOCH_TEMPOBJ_PVS = _unit;" \n " publicVariableServer ""EPOCH_TEMPOBJ_PVS"";" \n "};" \n "" \n "_randomGroan = {" \n "_sounds = [""sapper_groan0"",""sapper_groan1"",""sapper_groan2""];" \n "_sound = _sounds select (floor (random (count _sounds)));" \n "" \n "_unit say3D _sound;" \n "EPOCH_say3D_PVS = [player, _unit,(EPOCH_sounds find _sound), Epoch_personalToken];" \n "publicVariableServer ""EPOCH_say3D_PVS"";" \n "};" \n "" \n "_sMarker = objNull;" \n "_mHeight = 2.5;" \n "" \n "" \n "//Debug" \n "_doDebug = false;" \n "" \n "" \n "_doMarker = {" \n "deleteVehicle _sMarker;" \n "_mPos = getPosATL _unit;" \n "_mPos set [2,_mHeight];" \n "_sMarker = createVehicle [""Sign_Arrow_Green_F"", _mPos, [], 0, ""CAN_COLLIDE""];" \n "_sMarker attachTo [_unit,[0,0,_mHeight]];" \n "};" \n "" \n "_doMarkerChase = {" \n "deleteVehicle _sMarker;" \n "_mPos = getPosATL _unit;" \n "_mPos set [2,_mHeight];" \n "_sMarker = createVehicle [""Sign_Arrow_Yellow_F"", _mPos, [], 0, ""CAN_COLLIDE""];" \n "_sMarker attachTo [_unit,[0,0,_mHeight]];" \n "};" \n "" \n "_doMarkerCharge = {" \n "deleteVehicle _sMarker;" \n "_mPos = getPosATL _unit;" \n "_mPos set [2,_mHeight];" \n "_sMarker = createVehicle [""Sign_Arrow_F"", _mPos, [], 0, ""CAN_COLLIDE""];" \n "_sMarker attachTo [_unit,[0,0,_mHeight]];" \n "};" \n "" \n "_doMarkerMove = {" \n "deleteVehicle _sMarker;" \n "_mPos = getPosATL _unit;" \n "_mPos set [2,_mHeight];" \n "_sMarker = createVehicle [""Sign_Arrow_Cyan_F"", _mPos, [], 0, ""CAN_COLLIDE""];" \n "_sMarker attachTo [_unit,[0,0,_mHeight]];" \n "};" \n "" \n "_sAnger = 0;" \n "_sHit = [];" \n "_sFiredNear = [];" \n "_mkrName3 = """";" \n "_mkrName4 = """";" \n "_showDebug = {" \n "hint format [""SAPPER\nAnger: %2\nCanSee: %3\nTarget: %4\nHit: %5\nNear: %6\nFPS:%1"",diag_fps,_sAnger,_canSee,_trgt,_sHit,_sFiredNear];" \n "};" \n "" \n "" \n "axeSapper = _unit;" \n "" \n ""; precondition = ""; class Links { class _ { itemno = ; priority = 0.000000; to="reset___control"; precondition = ""; condition=""; action=""; }; }; }; class instinct { name = "instinct"; itemno = ; init = "//systemchat format [""I:%1"",diag_tickTime];"; precondition = ""; class Links { class check_status { itemno = ; priority = 110.000000; to="checking_status"; precondition = ""; condition="diag_tickTime > _c + _sFreqCheck;"; action="_checkEntry = ""instinct"";" \n "_sanityCheck = 100;" \n "" \n ""; }; class instinct_done { itemno = ; priority = 100.000000; to="action"; precondition = ""; condition="_decisionMade;"; action="_decisionMade = false;"; }; class dispose { itemno = ; priority = 90.000000; to="instinct"; precondition = ""; condition="!alive _unit || _callDispose;"; action="_doDispose = true;" \n "_decisionMade = true;" \n "" \n "" \n ""; }; }; }; class action { name = "action"; itemno = ; init = "//systemchat format [""A:%1"",diag_tickTime];"; precondition = ""; class Links { class dispose { itemno = ; priority = 120.000000; to="end"; precondition = ""; condition="_doDispose;"; action=""; }; class check_status { itemno = ; priority = 110.000000; to="checking_status"; precondition = ""; condition="diag_tickTime > _c + _sFreqCheck;"; action="_checkEntry = ""action"";" \n "_sanityCheck = 100;" \n "" \n "" \n ""; }; class complete { itemno = ; priority = 100.000000; to="reset___control"; precondition = ""; condition="_actionDone && ((call compile _criteria) || (diag_tickTime > (_t + _sWait)));"; action="" \n "if(!isNil ""_criteriaMetAction"")then{" \n "call _criteriaMetAction;" \n "};" \n "" \n "" \n "" \n "" \n "" \n "" \n "" \n "" \n "" \n ""; }; }; }; class reset___control { name = "reset___control"; itemno = ; init = "//Brain Vars" \n "_criteria =""(false)"";" \n "_criteriaMetAction = nil;" \n "_actionDone = false;" \n "_sWait = 0;" \n "" \n "" \n "if(_sapperWalkHandle < 0)then{" \n "_startLoad = diag_tickTime;" \n "_sapperWalkHandle = [_unit, _trgt] execFSM ""\x\addons\a3_epoch_code\System\sapperSwarmMemberWalking.fsm"";" \n "" \n "axeWalkHandle = _sapperWalkHandle;" \n "//systemchat format[""Call Walking in %1"",diag_tickTime - _startLoad];" \n "};" \n "" \n "" \n "" \n ""; precondition = ""; class Links { class _ { itemno = ; priority = 0.000000; to="instinct"; precondition = ""; condition=""; action=""; }; }; }; class end { name = "end"; itemno = ; init = "//hint ""Dispose Sapper Brain"";" \n "" \n "if(_sapperWalkHandle > -1)then{" \n "_sapperWalkHandle setFSMVariable [""_callDispose"", true];" \n "};" \n "" \n "if(_sapperDisposeHandle < 0)then{" \n "_startLoad = diag_tickTime;" \n "_sapperDisposeHandle = [_unit, _bomb, _detTrgt] execFSM ""\x\addons\a3_epoch_code\System\sapperSwarmMemberDispose.fsm"";" \n "//systemchat format[""Call Dispose in %1"",diag_tickTime - _startLoad];" \n "};" \n "" \n "" \n ""; precondition = ""; class Links { }; }; class checking_status { name = "checking_status"; itemno = ; init = "" \n "//Put vars to check in here - only run once per check session." \n "if!(_doneCheck)then{" \n "" \n "" \n "if(_doDebug)then{" \n "//systemchat format [""C:%1"",diag_tickTime];" \n "//[] call _showDebug;" \n "" \n "//deleteMarkerLocal _mkrName3;" \n "//_mkrName3 = format[""axe%1"", _unit];" \n "_mPos = getPos _unit;" \n "//_mkr = createMarkerLocal [_mkrName3, _mPos];" \n "//_mkrName3 setMarkerShapeLocal ""ICON"";" \n "//_mkrName3 setMarkerTypeLocal ""mil_dot"";" \n "//_mkrName3 setMarkerColorLocal ""COLORGREEN"";" \n "};" \n "_doneCheck = true;" \n "};" \n "" \n ""; precondition = ""; class Links { class pre_vars { itemno = ; priority = 95.000000; to="checking_status"; precondition = ""; condition="_sanityCheck > 95;"; action="_pos = getPosATL _unit;" \n "_dist = _pos distance _destination;" \n "_trgtPos = [];" \n "" \n "_nrPlyrs = nearestObjects [_pos, [""Epoch_Female_base_F"",""Epoch_Man_base_F""],42];" \n "_nrSappers = nearestObjects [_pos, [""Epoch_Sapper_F""],42];" \n "" \n "_sanityCheck = 95;"; }; class swarm { itemno = ; priority = 90.000000; to="checking_status"; precondition = ""; condition="_sanityCheck > 90;" \n ""; action="_sTrgt = objNull;" \n "_newTrgt = false;" \n "" \n "if(count _nrSappers > 0)then{" \n "" \n " {" \n "" \n " if(_x != _unit)then{" \n "" \n " if!(lineIntersects [eyePos _unit, aimPos _x, _unit, _x])then{" \n "" \n " if!(isNull (_x getVariable [""sTarget"",objNull]))then{" \n " " \n " _sTrgt = _x;" \n " " \n " if(_unit distance _x < 5)then{" \n " _newTrgt = true;" \n " _trgtPos = getPosATL _sTrgt;" \n " };" \n "" \n " };" \n "" \n " };" \n "" \n " }else{" \n " _x setVariable [""sTarget"",objNull,false];" \n " };" \n "" \n " }forEach _nrSappers;" \n "" \n "};" \n "" \n "_sanityCheck = 90;"; }; class target { itemno = ; priority = 80.000000; to="checking_status"; precondition = ""; condition="_sanityCheck > 80;"; action="_canSee = false;" \n "_trgt = objNull;" \n "_detTrgt = objNull;" \n "_trgtDist = 999;" \n "" \n "" \n "if(count _nrPlyrs > 0)then{" \n "" \n " {" \n "" \n " if!(lineIntersects [eyePos _unit, aimPos _x, _unit, _x])then{" \n "" \n " if (isNull _sTrgt)then{" \n " _canSee = true;" \n " _trgt = _x;" \n " _unit setVariable [""sTarget"",_x,false];" \n " _trgtPos = getPosATL _trgt;" \n " _trgtDist = _x distance _unit;" \n " _newTrgt = true;" \n " };" \n "" \n " " \n " };" \n "" \n " if(_x distance _unit < _detonateDist)then{" \n " _detTrgt = _x;" \n " };" \n "" \n "" \n " " \n "" \n " }forEach _nrPlyrs;" \n "" \n "};" \n "" \n "" \n "_sanityCheck = 80;"; }; class movement { itemno = ; priority = 70.000000; to="checking_status"; precondition = ""; condition="_sanityCheck > 70;" \n ""; action="" \n "if(_canSee || _newTrgt)then{" \n "_nextPos = _trgtPos;" \n "};" \n "" \n "if!(_canSee) then {" \n " _newTrgt = false;" \n " if(count _trgtPos > 0)then{" \n " _nextPos = _trgtPos findEmptyPosition [0,50,typeOf _unit];" \n " }else{" \n " if(_dist > 20)then{" \n " _dirToF = [_pos,_destination,44] call EPOCH_fnc_dirToFuzzy;" \n " _trgtPos = [_unit, 48, _dirToF] call BIS_fnc_relPos;" \n " _nextPos = _trgtPos findEmptyPosition [0,50,typeOf _unit];" \n " " \n " }else{" \n " _nextPos = _destination;" \n " };" \n " };" \n "};" \n "_sanityCheck = 70;"; }; class stuck { itemno = ; priority = 60.000000; to="checking_status"; precondition = ""; condition="_sanityCheck > 60;" \n ""; action="if(_stuckCount > 3)then{" \n "_nextPos = _trgtPos findEmptyPosition [0,50,typeOf _unit];" \n "_lastPos = _pos;" \n "_stuckCount = 0;" \n "};" \n "" \n "if(_lastPos distance _pos < 3)then{" \n "_stuckCount = _stuckCount + 1;" \n "};" \n "" \n "_sanityCheck = 60;"; }; class final_checks { itemno = ; priority = 10.000000; to="checking_status"; precondition = ""; condition="_sanityCheck > 10;"; action="" \n "_unit setUnitPos ""UP"";" \n "if(behaviour _unit !=""COMBAT"")then{" \n " _unit setBehaviour ""COMBAT"";" \n " };" \n "" \n "" \n "" \n "if(_sapperWalkHandle > -1)then{" \n "" \n "if(moveToCompleted _unit || _newTrgt)then{" \n "_sapperWalkHandle setFSMVariable [""_nextPos"",_nextPos];" \n "};" \n "" \n "if(_newTrgt)then{" \n "if(random 100 < 16)then{" \n "call _randomGroan;" \n "};" \n "_sapperWalkHandle setFSMVariable [""_newTrgt"",_newTrgt];" \n "};" \n "};" \n "" \n "if(!(isnull _detTrgt) || _dist < 6 || surfaceIsWater _pos)then{" \n "_callDispose = true;" \n "};" \n "" \n "" \n "" \n "" \n "" \n "if(_doDebug)then{" \n "" \n "//hint format [""%1"",_newTrgt];" \n "" \n "" \n " if!(isNull (_unit getVariable [""sTarget"",objNull]))then{" \n "" \n " call _doMarkerCharge;" \n " " \n " }else{" \n "" \n " if!(isNull _sTrgt)then{" \n "" \n " call _doMarkerChase;" \n "" \n " }else{" \n " " \n " " \n " call _doMarker;" \n "" \n " };" \n "" \n " };" \n "" \n "deleteMarkerLocal _mkrName4;" \n "_mkrName4 = format[""axeD%1"", _unit];" \n "_mkr2 = createMarkerLocal [_mkrName4, _nextPos];" \n "_mkrName4 setMarkerShapeLocal ""ICON"";" \n "_mkrName4 setMarkerTypeLocal ""mil_dot"";" \n "_mkrName4 setMarkerColorLocal ""COLORYELLOW"";" \n "};" \n "" \n "" \n "_sanityCheck = 0;" \n "" \n "" \n "" \n ""; }; class _ { itemno = ; priority = 5.000000; to="return"; precondition = ""; condition=""; action="_doneCheck = false;"; }; }; }; class return { name = "return"; itemno = ; init = "_c = diag_tickTime;" \n "_sanityCheck = 100;" \n ""; precondition = ""; class Links { class to_instinct { itemno = ; priority = 0.000000; to="instinct"; precondition = ""; condition="(_checkEntry == ""instinct"");"; action="_checkEntry = """";" \n ""; }; class to_action { itemno = ; priority = 0.000000; to="action"; precondition = ""; condition="(_checkEntry == ""action"");"; action="_checkEntry = """";"; }; }; }; class ____FAKE____ { name = "____FAKE____"; itemno = ; init = ""; precondition = ""; class Links { class _ { itemno = ; priority = 0.000000; to="action"; precondition = ""; condition=""; action=""; }; }; }; }; initState="sapper"; finalStates[] = { "end" }; };