From 6044ec5432a6a60b7750470f11b8fa3a0f11782c Mon Sep 17 00:00:00 2001 From: second_coming Date: Sat, 2 Apr 2016 20:06:53 +0100 Subject: [PATCH] all the updates --- config.sqf | 52 +++--- initServer.sqf | 12 +- scripts/deleteMapMarkers.sqf | 5 +- scripts/occupationHeliCrashes.sqf | 19 +- scripts/occupationLog.sqf | 12 ++ scripts/occupationLootCrates.sqf | 53 ++---- scripts/occupationMilitary.sqf | 113 ++++++++---- scripts/occupationPlaces.sqf | 232 +++++++++++++++++++++++++ scripts/occupationSky.sqf | 88 ++++++++-- scripts/occupationStatic.sqf | 62 +++++-- scripts/occupationVehicle.sqf | 147 ++++++++++++---- scripts/reactions/airHit.sqf | 92 +++++----- scripts/reactions/driverKilled.sqf | 96 ++++++---- scripts/reactions/getIn.sqf | 23 +++ scripts/reactions/reactUnit.sqf | 8 +- scripts/reactions/repairVehicle.sqf | 122 +++++++++---- scripts/reactions/vehicleDestroyed.sqf | 0 scripts/startOccupation.sqf | 19 +- 18 files changed, 858 insertions(+), 297 deletions(-) create mode 100644 scripts/occupationLog.sqf create mode 100644 scripts/occupationPlaces.sqf create mode 100644 scripts/reactions/getIn.sqf create mode 100644 scripts/reactions/vehicleDestroyed.sqf diff --git a/config.sqf b/config.sqf index 5067c25..28b2494 100644 --- a/config.sqf +++ b/config.sqf @@ -2,7 +2,7 @@ // // Server Occupation script by second_coming // -// Version 2.1 +// Version 3 // // http://www.exilemod.com/profile/60-second_coming/ // @@ -14,30 +14,30 @@ // Shared Config for each occupation monitor -SC_debug = false; // set to true for additional logging and to speed up the spawn rate for testing -SC_infiSTAR_log = true; // Use infiSTAR logging -SC_maxAIcount = 100; // the maximum amount of AI, if the AI count is above this then additional AI won't spawn +SC_debug = false; // set to true to turn on debug features (not for live servers) +SC_extendedLogging = true; // set to true for additional logging +SC_infiSTAR_log = true; // true Use infiSTAR logging, false logs to server rpt +SC_maxAIcount = 100; // the maximum amount of AI, if the AI count is above this then additional AI won't spawn -SC_mapMarkers = false; // Place map markers at the occupied areas (occupyPlaces and occupyMilitary only) true/false -SC_minFPS = 8; // any lower than minFPS on the server and additional AI won't spawn +SC_mapMarkers = false; // Place map markers at the occupied areas (occupyPlaces and occupyMilitary only) true/false +SC_minFPS = 5; // any lower than minFPS on the server and additional AI won't spawn -SC_scaleAI = 10; // any more than _scaleAI players on the server and _maxAIcount is reduced for each extra player +SC_scaleAI = 10; // any more than _scaleAI players on the server and _maxAIcount is reduced for each extra player -SC_useWaypoints = true; // When spawning AI create waypoints to make them enter buildings - // (can affect performance when the AI is spawned and the waypoints are calculated) +SC_useWaypoints = true; // When spawning AI create waypoints to make them enter buildings + // (can affect performance when the AI is spawned and the waypoints are calculated) -SC_occupyPlaces = true; // true if you want villages,towns,cities patrolled -SC_occupyMilitary = false; // true if you want military buildings patrolled (specify which types of building in occupationMilitary.sqf) -SC_occupyStatic = false; // true if you want to garrison AI in specific locations (not working yet) +SC_occupyPlaces = true; // true if you want villages,towns,cities patrolled +SC_occupyMilitary = false; // true if you want military buildings patrolled (specify which types of building in occupationMilitary.sqf) +SC_occupyStatic = false; // true if you want to garrison AI in specific locations (not working yet) SC_occupyVehicle = true; // true if you want to have roaming AI vehicles SC_occupySky = true; // true if you want to have roaming AI helis -SC_occupyLootCrates = true; // true if you want to have random loot crates with guards +SC_occupyLootCrates = true; // true if you want to have random loot crates with guards +SC_numberofLootCrates = 6; // if SC_occupyLootCrates = true spawn this many loot crates (overrided for Namalsk in occupationLootCrates.sqf) SC_occupyLootCratesMarkers = true; // true if you want to have markers on the loot crate spawns SC_occupyHeliCrashes = true; // true if you want to have Dayz style helicrashes -SC_statics = [ - [[1178,2524,0],4,100,true] - ]; //[[pos],ai count,radius,search buildings] +SC_statics = [ [[1178,2524,0],4,100,true] ]; //[[pos],ai count,radius,search buildings] // Which buildings to patrol with the occupyMilitary option (adding more classnames could affect server performance when the spawning occurs) SC_buildings = [ "Land_Cargo_Patrol_V1_F", @@ -71,17 +71,13 @@ SC_buildings = [ "Land_Cargo_Patrol_V1_F", ]; // Settings for roaming ground vehicle AI -SC_maxNumberofVehicles = 3; // Number of roaming vehicles required, randomly selected from VehicleClassToUse -SC_VehicleClassToUse = [ "Exile_Car_LandRover_Green", - "Exile_Car_UAZ_Open_Green", - "Exile_Car_UAZ_Green", - "Exile_Car_Offroad_Guerilla03" - ]; +SC_maxNumberofVehicles = 3; +SC_VehicleClassToUse = [ "Exile_Car_LandRover_Green","Exile_Car_UAZ_Open_Green","Exile_Car_Offroad_Guerilla03"]; -// Settings for roaming airborne AI -SC_maxNumberofHelis = 1; // Number of roaming vehicles required, randomly selected from HeliClassToUse (only use armed helis for now) +// Settings for roaming airborne AI (non armed helis will just fly around) +SC_maxNumberofHelis = 1; SC_HeliClassToUse = [ "Exile_Chopper_Huey_Armed_Green"]; @@ -89,12 +85,12 @@ SC_HeliClassToUse = [ "Exile_Chopper_Huey_Armed_Green"]; if (worldName == 'Namalsk') then { SC_maxAIcount = 80; - SC_occupySky = false; + SC_occupySky = false; }; // Don't alter anything below this point SC_liveVehicles = 0; -publicVariable "SC_liveVehicles"; +publicVariable "SC_liveVehicles"; SC_liveHelis = 0; -publicVariable "SC_liveHelis"; -publicVariable "SC_numberofLootCrates"; \ No newline at end of file +publicVariable "SC_liveHelis"; +publicVariable "SC_numberofLootCrates"; \ No newline at end of file diff --git a/initServer.sqf b/initServer.sqf index 392bd80..46d97de 100644 --- a/initServer.sqf +++ b/initServer.sqf @@ -2,7 +2,7 @@ // // Server Occupation script by second_coming // -// Version 2.1 +// Version 3 // // http://www.exilemod.com/profile/60-second_coming/ // @@ -20,16 +20,22 @@ // //////////////////////////////////////////////////////////////////////////////////////////// -diag_log format ["[OCCUPATION MOD]:: Initialised at %1",time]; +SC_occupationVersion = "3.0"; + +diag_log format ["[OCCUPATION MOD]:: Occupation v%2 Initialised at %1",time,SC_occupationVersion]; // EventHandlers for AI reactions SC_fnc_repairVehicle = compile preprocessFileLineNumbers "\x\addons\a3_exile_occupation\scripts\reactions\repairVehicle.sqf"; SC_fnc_reactUnit = compile preprocessFileLineNumbers "\x\addons\a3_exile_occupation\scripts\reactions\reactUnit.sqf"; SC_fnc_driverKilled = compile preprocessFileLineNumbers "\x\addons\a3_exile_occupation\scripts\reactions\driverKilled.sqf"; -SC_fnc_airHit = compile preprocessFileLineNumbers "\x\addons\a3_exile_occupation\scripts\reactions\airHit.sqf"; +SC_fnc_airHit = compile preprocessFileLineNumbers "\x\addons\a3_exile_occupation\scripts\reactions\airHit.sqf"; +SC_fnc_getIn = compile preprocessFileLineNumbers "\x\addons\a3_exile_occupation\scripts\reactions\getIn.sqf"; // Get the config for Occupation call compile preprocessFileLineNumbers "\x\addons\a3_exile_occupation\config.sqf"; +// Select the log style depending on config settings +SC_fnc_log = compile preprocessFileLineNumbers "\x\addons\a3_exile_occupation\scripts\occupationLog.sqf"; + // Start Occupation [] execVM "\x\addons\a3_exile_occupation\scripts\startOccupation.sqf"; \ No newline at end of file diff --git a/scripts/deleteMapMarkers.sqf b/scripts/deleteMapMarkers.sqf index 153f98e..864cb6d 100644 --- a/scripts/deleteMapMarkers.sqf +++ b/scripts/deleteMapMarkers.sqf @@ -1,3 +1,5 @@ +// Delete the map marker on a loot crate when a player gets in range + for "_i" from 1 to SC_numberofLootCrates do { _markerName = format ["loot_marker_%1", _i]; @@ -9,7 +11,8 @@ for "_i" from 1 to SC_numberofLootCrates do if(_nearPlayers > 0) then { deleteMarker _markerName; - diag_log format ["[OCCUPATION:LootCrates]:: marker %1 removed at %2",_markerName,time]; + _logDetail = format ["[OCCUPATION:LootCrates]:: marker %1 removed at %2",_markerName,time]; + [_logDetail] call SC_fnc_log; }; }; diff --git a/scripts/occupationHeliCrashes.sqf b/scripts/occupationHeliCrashes.sqf index b87ee80..aa1351d 100644 --- a/scripts/occupationHeliCrashes.sqf +++ b/scripts/occupationHeliCrashes.sqf @@ -7,19 +7,12 @@ if (worldName == 'Namalsk') then _numberofCrashes = 2; // lower number for a smaller map }; -_middle = worldSize/2; -_spawnCenter = [_middle,_middle,0]; -_max = _middle; -_min = 0; // minimum distance from the center position (Number) in meters -_mindist = 15; // minimum distance from the nearest object (Number) in meters, ie. spawn at least this distance away from anything within x meters.. -_water = 0; // water mode (Number) 0: cannot be in water , 1: can either be in water or not , 2: must be in water -_shoremode = 0; // 0: does not have to be at a shore , 1: must be at a shore -_markersize = 100; // Radius of the marker in meters -_displayMarkers = SC_debug; // only use for debug, no need for actual gameplay +_displayMarkers = SC_debug; // only use for debug, no need for actual gameplay private['_position']; -diag_log format ["[OCCUPATION:HeliCrashes]:: Initialised at %1",time]; +_logDetail = format ["[OCCUPATION:HeliCrashes]:: Initialised at %1",time]; +[_logDetail] call SC_fnc_log; for "_i" from 1 to _numberofCrashes do { @@ -27,7 +20,7 @@ for "_i" from 1 to _numberofCrashes do while{!_validspot} do { sleep 0.2; - _position = [_spawnCenter,_min,_max,_mindist,_water,20,_shoremode] call BIS_fnc_findSafePos; + _position = [ 0, 50, 1, 500, 500, 200, 200, 200, true, false ] call DMS_fnc_findSafePos; _validspot = true; // Check for nearby spawn points and traders @@ -49,7 +42,9 @@ for "_i" from 1 to _numberofCrashes do }; - diag_log format['[OCCUPATION:HeliCrashes] Crash %1 : Location %2',_i,_position]; + _logDetail = format['[OCCUPATION:HeliCrashes] Crash %1 : Location %2',_i,_position]; + [_logDetail] call SC_fnc_log; + _helicopter = "Land_UWreck_MV22_F"; _vehHeli = _helicopter createVehicle [0,0,0]; _heliFire = "test_EmptyObjectForFireBig" createVehicle (position _vehHeli); diff --git a/scripts/occupationLog.sqf b/scripts/occupationLog.sqf new file mode 100644 index 0000000..a0ceb28 --- /dev/null +++ b/scripts/occupationLog.sqf @@ -0,0 +1,12 @@ +// Logging function to use either infiSTAR logging function or server RPT + +_logDetail = _this select 0; + +if(SC_infiSTAR_log) then +{ + ['A3_EXILE_OCCUPATION',_logDetail] call FNC_A3_CUSTOMLOG; +} +else +{ + diag_log _logDetail; +}; \ No newline at end of file diff --git a/scripts/occupationLootCrates.sqf b/scripts/occupationLootCrates.sqf index 7d90a55..113d474 100644 --- a/scripts/occupationLootCrates.sqf +++ b/scripts/occupationLootCrates.sqf @@ -1,69 +1,36 @@ if (!isServer) exitWith {}; -diag_log format ["[OCCUPATION:LootCrates]:: Starting Occupation Loot Crates"]; +_logDetail = format ["[OCCUPATION:LootCrates]:: Starting Occupation Loot Crates"]; +[_logDetail] call SC_fnc_log; -_middle = worldSize/2; -_spawnCenter = [_middle,_middle,0]; -_max = _middle; -_numberofcrates = 3; // this is the number of crates that you want to spawn - -if (worldName == 'Altis') then +if (worldName == 'Namalsk') then { - _spawnCenter = [15834.2,15787.8,0]; - _max = 16000; - _numberofcrates = 6; // this is the number of crates that you want to spawn -}; -if (worldName == 'Chernarus') then -{ - _spawnCenter = [7652.9634, 7870.8076,0]; - _max = 7500; - _numberofcrates = 6; // this is the number of crates that you want to spawn -}; -if (worldName == 'Taviana') then -{ - _spawnCenter = [12800, 12800,0]; - _max = 12800; - _numberofcrates = 6; // this is the number of crates that you want to spawn + SC_numberofLootCrates = 3; // this is the number of crates that you want to spawn }; -SC_numberofLootCrates = _numberofcrates; - -diag_log format['[OCCUPATION:LootCrates]:: worldname: %1 Centre: %2 radius: %3',worldName,_spawnCenter,_max]; - -_min = 0; // minimum distance from the center position (Number) in meters -_mindist = 15; // minimum distance from the nearest object (Number) in meters, ie. spawn at least this distance away from anything within x meters.. -_water = 0; // water mode (Number) 0: cannot be in water , 1: can either be in water or not , 2: must be in water -_shoremode = 0; // 0: does not have to be at a shore , 1: must be at a shore -_marker = SC_occupyLootCratesMarkers; // Draw a green circle in which the crate will be spawned randomly +_logDetail = format['[OCCUPATION:LootCrates]:: worldname: %1 crates to spawn: %2',worldName,SC_numberofLootCrates]; +[_logDetail] call SC_fnc_log; private['_position']; -for "_i" from 1 to _numberofcrates do +for "_i" from 1 to SC_numberofLootCrates do { _validspot = false; while{!_validspot} do { sleep 0.2; - _position = [_spawnCenter,_min,_max,_mindist,_water,20,_shoremode] call BIS_fnc_findSafePos; + _position = [ 0, 50, 1, 500, 500, 200, 200, 200, true, false ] call DMS_fnc_findSafePos; _validspot = true; - // Check for nearby spawn points and traders - _nearestMarker = [allMapMarkers, _position] call BIS_fnc_nearestPosition; - _posNearestMarker = getMarkerPos _nearestMarker; - if(_position distance _posNearestMarker < 500) then { _validspot = false; }; - //Check if near another crate site _nearOtherCrate = (nearestObjects [_position,["CargoNet_01_box_F"],500]) select 0; if (!isNil "_nearOtherCrate") then { _validspot = false; }; - //Check if near player base - _nearBase = (nearestObjects [_position,["Exile_Construction_Flag_Static"],350]) select 0; - if (!isNil "_nearBase") then { _validspot = false; }; }; _mapMarkerName = format ["loot_marker_%1", _i]; - if (_marker) then + if (SC_occupyLootCratesMarkers) then { _event_marker = createMarker [ format ["loot_marker_%1", _i], _position]; @@ -88,7 +55,7 @@ for "_i" from 1 to _numberofcrates do _group setBehaviour "AWARE"; _group setCombatMode "RED"; - diag_log text format ["[OCCUPATION:LootCrates]:: Creating crate %3 @ drop zone %1 with %2 guards",_position,_AICount,_i]; + _logDetail = text format ["[OCCUPATION:LootCrates]:: Creating crate %3 @ drop zone %1 with %2 guards",_position,_AICount,_i]; _box = "CargoNet_01_box_F" createvehicle _position; clearMagazineCargoGlobal _box; diff --git a/scripts/occupationMilitary.sqf b/scripts/occupationMilitary.sqf index 1030b13..152321c 100644 --- a/scripts/occupationMilitary.sqf +++ b/scripts/occupationMilitary.sqf @@ -1,17 +1,13 @@ private["_wp","_wp2","_wp3"]; if (!isServer) exitWith {}; -diag_log format ["[OCCUPATION Military]:: Starting Monitor"]; +_logDetail = format ["[OCCUPATION Military]:: Starting Monitor"]; +[_logDetail] call SC_fnc_log; -_middle = worldSize/2; -_spawnCenter = [_middle,_middle,0]; // Centre point for the map -_maxDistance = _middle; // Max radius for the map - -_maxAIcount = SC_maxAIcount; -_minFPS = SC_minFPS; -_debug = SC_debug; +_maxAIcount = SC_maxAIcount; +_minFPS = SC_minFPS; _useLaunchers = DMS_ai_use_launchers; -_scaleAI = SC_scaleAI; +_scaleAI = SC_scaleAI; _buildings = SC_buildings; // Class names for the military buildings to patrol _building = []; @@ -22,23 +18,34 @@ if(_currentPlayerCount > _scaleAI) then _maxAIcount = _maxAIcount - (_currentPlayerCount - _scaleAI) ; }; - // Select an area to scan as nearObjects on the entire map is slooooooooow _areaToScan = [ 0, 900, 1, 500, 500, 0, 0, 0, true, false ] call DMS_fnc_findSafePos; // Don't spawn additional AI if the server fps is below 8 -if(diag_fps < _minFPS) exitWith { diag_log format ["[OCCUPATION Military]:: Held off spawning more AI as the server FPS is only %1",diag_fps]; }; +if(diag_fps < _minFPS) exitWith +{ + _logDetail = format ["[OCCUPATION Military]:: Held off spawning more AI as the server FPS is only %1",diag_fps]; + [_logDetail] call SC_fnc_log; +}; -_aiActive = count(_spawnCenter nearEntities ["O_recon_F", _maxDistance+1000]); -if(_aiActive > _maxAIcount) exitWith { diag_log format ["[OCCUPATION Military]:: %1 active AI, so not spawning AI this time",_aiActive]; }; +_aiActive = {alive _x && side _x == EAST} count allUnits; + +//_aiActive = count(_spawnCenter nearEntities ["O_recon_F", _maxDistance+1000]); +if(_aiActive > _maxAIcount) exitWith +{ + _logDetail = format ["[OCCUPATION Military]:: %1 active AI, so not spawning AI this time",_aiActive]; + [_logDetail] call SC_fnc_log; +}; for [{_i = 0},{_i < (count _buildings)},{_i =_i + 1}] do { - diag_log format ["[OCCUPATION Military]:: scanning buildings around %2 started at %1",time,_areaToScan]; + _logDetail = format ["[OCCUPATION Military]:: scanning buildings around %2 started at %1",time,_areaToScan]; + [_logDetail] call SC_fnc_log; _building = _areaToScan nearObjects [_buildings select _i, 750]; _currentBuilding = _buildings select _i; - diag_log format ["[OCCUPATION Military]:: scan for %2 building finished at %1",time,_currentBuilding]; + _logDetail = format ["[OCCUPATION Military]:: scan for %2 building finished at %1",time,_currentBuilding]; + [_logDetail] call SC_fnc_log; for [{_n = 0},{_n < (count _building)-1},{_n =_n + 1}] do { @@ -48,29 +55,73 @@ for [{_i = 0},{_i < (count _buildings)},{_i =_i + 1}] do _location = getPos _foundBuilding; _pos = [_location select 0, _location select 1, 0]; - if(_debug) then { diag_log format ["[OCCUPATION Military]:: Testing position: %1",_pos];}; + if(SC_extendedLogging) then + { + _logDetail = format ["[OCCUPATION Military]:: Testing position: %1",_pos]; + [_logDetail] call SC_fnc_log; + }; while{_okToSpawn} do { // Percentage chance to spawn (roll 60 or more to spawn AI) _spawnChance = round (random 100); - if(_spawnChance < 60) exitWith { _okToSpawn = false; if(_debug) then { diag_log format ["[OCCUPATION Military]:: Rolled %1 so not spawning AI this time",_spawnChance];};}; + if(_spawnChance < 60) exitWith + { + _okToSpawn = false; + if(SC_extendedLogging) then + { + _logDetail = format ["[OCCUPATION Military]:: Rolled %1 so not spawning AI this time",_spawnChance]; + [_logDetail] call SC_fnc_log; + }; + }; // Don't spawn if too near a player base _nearBase = (nearestObjects [_pos,["Exile_Construction_Flag_Static"],500]) select 0; - if (!isNil "_nearBase") exitwith { _okToSpawn = false; if(_debug) then { diag_log format ["[OCCUPATION Military]:: %1 is too close to player base",_pos];};}; + if (!isNil "_nearBase") exitwith + { + _okToSpawn = false; + if(SC_extendedLogging) then + { + _logDetail = format ["[OCCUPATION Military]:: %1 is too close to player base",_pos]; + [_logDetail] call SC_fnc_log; + }; + }; // Don't spawn AI near traders and spawn zones _nearestMarker = [allMapMarkers, _pos] call BIS_fnc_nearestPosition; // Nearest Marker to the Location _posNearestMarker = getMarkerPos _nearestMarker; - if(_pos distance _posNearestMarker < 500) exitwith { _okToSpawn = false; if(_debug) then { diag_log format ["[OCCUPATION Military]:: %1 is too close to a %2",_pos,_nearestMarker];}; }; + if(_pos distance _posNearestMarker < 500) exitwith + { + _okToSpawn = false; + if(SC_extendedLogging) then + { + _logDetail = format ["[OCCUPATION Military]:: %1 is too close to a %2",_pos,_nearestMarker]; + [_logDetail] call SC_fnc_log; + }; + }; // Don't spawn additional AI if there are already AI in range _aiNear = count(_pos nearEntities ["O_recon_F", 500]); - if(_aiNear > 0) exitwith { _okToSpawn = false; if(_debug) then { diag_log format ["[OCCUPATION Military]:: %1 already has %2 active AI patrolling",_pos,_aiNear];}; }; + if(_aiNear > 0) exitwith + { + _okToSpawn = false; + if(SC_extendedLogging) then + { + _logDetail = format ["[OCCUPATION Military]:: %1 already has %2 active AI patrolling",_pos,_aiNear]; + [_logDetail] call SC_fnc_log; + }; + }; // Don't spawn additional AI if there are players in range - if([_pos, 200] call ExileClient_util_world_isAlivePlayerInRange) exitwith { _okToSpawn = false; if(_debug) then { diag_log format ["[OCCUPATION Military]:: %1 has players too close",_pos];}; }; + if([_pos, 200] call ExileClient_util_world_isAlivePlayerInRange) exitwith + { + _okToSpawn = false; + if(SC_extendedLogging) then + { + _logDetail = format ["[OCCUPATION Military]:: %1 has players too close",_pos]; + [_logDetail] call SC_fnc_log; + }; + }; if(_okToSpawn) then { @@ -82,15 +133,11 @@ for [{_i = 0},{_i < (count _buildings)},{_i =_i + 1}] do _difficulty = "random"; _side = "bandit"; _spawnPosition = _pos; - - - + // Get the AI to shut the fuck up :) enableSentences false; enableRadio false; - - - + if(!SC_useWaypoints) then { DMS_ai_use_launchers = false; @@ -162,11 +209,9 @@ for [{_i = 0},{_i < (count _buildings)},{_i =_i + 1}] do }; }; - - - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - diag_log format ["[OCCUPATION Military]:: Spawning %1 AI in at %2 to patrol",_aiCount,_spawnPosition]; + _logDetail = format ["[OCCUPATION Military]:: Spawning %1 AI in at %2 to patrol",_aiCount,_spawnPosition]; + [_logDetail] call SC_fnc_log; if(SC_mapMarkers) then { @@ -178,11 +223,11 @@ for [{_i = 0},{_i < (count _buildings)},{_i =_i + 1}] do _marker setMarkerAlpha 0.5; _marker setMarkerColor "ColorRed"; _marker setMarkerText "Occupied Military Area"; - }; - + }; _okToSpawn = false; }; }; }; }; -diag_log "[OCCUPATION Military]: Ended"; \ No newline at end of file +_logDetail = "[OCCUPATION Military]: Ended"; +[_logDetail] call SC_fnc_log; \ No newline at end of file diff --git a/scripts/occupationPlaces.sqf b/scripts/occupationPlaces.sqf new file mode 100644 index 0000000..8d88417 --- /dev/null +++ b/scripts/occupationPlaces.sqf @@ -0,0 +1,232 @@ +//////////////////////////////////////////////////////////////////////// +// +// Server Occupation script by second_coming +// +// Version 2.0 +// +// http://www.exilemod.com/profile/60-second_coming/ +// +// This script uses the fantastic DMS by Defent and eraser1 +// +// http://www.exilemod.com/topic/61-dms-defents-mission-system/ +// +//////////////////////////////////////////////////////////////////////// + +private["_wp","_wp2","_wp3"]; + +if (!isServer) exitWith {}; +_logDetail = format ["[OCCUPATION]:: Starting Occupation Monitor"]; +[_logDetail] call SC_fnc_log; + +_middle = worldSize/2; +_spawnCenter = [_middle,_middle,0]; // Centre point for the map +_maxDistance = _middle; // Max radius for the map + +_maxAIcount = SC_maxAIcount; +_minFPS = SC_minFPS; +_useLaunchers = DMS_ai_use_launchers; +_scaleAI = SC_scaleAI; + +// more than _scaleAI players on the server and the max AI count drops per additional player +_currentPlayerCount = count playableUnits; +if(_currentPlayerCount > _scaleAI) then +{ + _maxAIcount = _maxAIcount - (_currentPlayerCount - _scaleAI) ; +}; + +// Don't spawn additional AI if the server fps is below _minFPS +if(diag_fps < _minFPS) exitWith +{ + _logDetail = format ["[OCCUPATION]:: Held off spawning more AI as the server FPS is only %1",diag_fps]; + [_logDetail] call SC_fnc_log; +}; + +_aiActive = count(_spawnCenter nearEntities ["O_recon_F", 20000]); +if(_aiActive > _maxAIcount) exitWith +{ + _logDetail = format ["[OCCUPATION]:: %1 active AI, so not spawning AI this time",_aiActive]; + [_logDetail] call SC_fnc_log; +}; + +_locations = (nearestLocations [_spawnCenter, ["NameVillage","NameCity", "NameCityCapital"], _maxDistance]); +{ + _okToSpawn = true; + _temppos = position _x; + _locationName = text _x; + _locationType = type _x; + _pos = [_temppos select 0, _temppos select 1, 0]; + + if(SC_extendedLogging) then + { + _logDetail = format ["[OCCUPATION]:: Testing location name: %1 position: %2",_locationName,_pos]; + [_logDetail] call SC_fnc_log; + }; + + while{_okToSpawn} do + { + // Percentage chance to spawn (roll 80 or more to spawn AI) + _spawnChance = round (random 100); + if(_spawnChance < 80) exitWith + { + _okToSpawn = false; + if(SC_extendedLogging) then + { + _logDetail = format ["[OCCUPATION]:: Rolled %1 so not spawning AI this time",_spawnChance,_locationName]; + [_logDetail] call SC_fnc_log; + }; + }; + + // Don't spawn if too near a player base + _nearBase = (nearestObjects [_pos,["Exile_Construction_Flag_Static"],500]) select 0; + if (!isNil "_nearBase") exitwith + { + _okToSpawn = false; + if(SC_extendedLogging) then + { + _logDetail = format ["[OCCUPATION]:: %1 is too close to player base",_locationName]; + [_logDetail] call SC_fnc_log; + }; + }; + + // Don't spawn AI near traders and spawn zones + _nearestMarker = [allMapMarkers, _pos] call BIS_fnc_nearestPosition; // Nearest Marker to the Location + _posNearestMarker = getMarkerPos _nearestMarker; + if(_pos distance _posNearestMarker < 500) exitwith + { + _okToSpawn = false; + if(SC_extendedLogging) then + { + _logDetail = format ["[OCCUPATION]:: %1 is too close to a %2",_locationName,_nearestMarker]; + [_logDetail] call SC_fnc_log; + }; + }; + + // Don't spawn additional AI if there are players in range + if([_pos, 200] call ExileClient_util_world_isAlivePlayerInRange) exitwith + { + _okToSpawn = false; + if(SC_extendedLogging) then + { + _logDetail = format ["[OCCUPATION]:: %1 has players too close",_locationName]; + [_logDetail] call SC_fnc_log; + }; + }; + + // Don't spawn additional AI if there are already AI in range + _aiNear = count(_pos nearEntities ["O_recon_F", 500]); + if(_aiNear > 0) exitwith + { + _okToSpawn = false; + if(SC_extendedLogging) then + { + _logDetail = format ["[OCCUPATION]:: %1 already has %2 active AI patrolling",_locationName,_aiNear]; + [_logDetail] call SC_fnc_log; + }; + }; + + if(_okToSpawn) then + { + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Get AI to patrol the town + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + _aiCount = 1; + _groupRadius = 100; + if(_locationType isEqualTo "NameCityCapital") then { _aiCount = 5; _groupRadius = 300; }; + if(_locationType isEqualTo "NameCity") then { _aiCount = 2 + (round (random 3)); _groupRadius = 200; }; + if(_locationType isEqualTo "NameVillage") then { _aiCount = 1 + (round (random 2)); _groupRadius = 100; }; + + if(_aiCount < 1) then { _aiCount = 1; }; + _difficulty = "random"; + _side = "bandit"; + _spawnPos = [_pos,10,100,5,0,20,0] call BIS_fnc_findSafePos; + _spawnPosition = [_spawnPos select 0, _spawnPos select 1,0]; + + DMS_ai_use_launchers = false; + _group = [_spawnPosition, _aiCount, "randomEasy", "assault", _side] call DMS_fnc_SpawnAIGroup; + DMS_ai_use_launchers = _useLaunchers; + + // Get the AI to shut the fuck up :) + enableSentences false; + enableRadio false; + + if(!SC_useWaypoints) then + { + [_group, _pos, _groupRadius] call bis_fnc_taskPatrol; + _group setBehaviour "COMBAT"; + _group setCombatMode "RED"; + } + else + { + [ _group,_pos,_difficulty,"COMBAT" ] call DMS_fnc_SetGroupBehavior; + + _buildings = _pos nearObjects ["building", _groupRadius]; + { + _buildingPositions = [_x, 10] call BIS_fnc_buildingPositions; + if(count _buildingPositions > 0) then + { + + // Find Highest Point + _highest = [0,0,0]; + { + if(_x select 2 > _highest select 2) then + { + _highest = _x; + }; + + } foreach _buildingPositions; + _spawnPosition = _highest; + + _i = _buildingPositions find _spawnPosition; + _wp = _group addWaypoint [_spawnPosition, 0] ; + _wp setWaypointFormation "Column"; + _wp setWaypointBehaviour "COMBAT"; + _wp setWaypointCombatMode "RED"; + _wp setWaypointCompletionRadius 1; + _wp waypointAttachObject _x; + _wp setwaypointHousePosition _i; + _wp setWaypointType "SAD"; + + }; + } foreach _buildings; + if(count _buildings > 0 && !isNil "_wp") then + { + _wp setWaypointType "CYCLE"; + }; + }; + + if(_locationType isEqualTo "NameCityCapital") then + { + DMS_ai_use_launchers = false; + _group2 = [_spawnPosition, 5, _difficulty, "random", _side] call DMS_fnc_SpawnAIGroup; + DMS_ai_use_launchers = _useLaunchers; + + // Get the AI to shut the fuck up :) + enableSentences false; + enableRadio false; + [_group2, _pos, _groupRadius] call bis_fnc_taskPatrol; + _group2 setBehaviour "DESTROY"; + _group2 setCombatMode "RED"; + + }; + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + if(SC_mapMarkers) then + { + _marker = createMarker [format ["%1", _spawnPosition],_pos]; + _marker setMarkerShape "Icon"; + _marker setMarkerSize [3,3]; + _marker setMarkerType "mil_dot"; + _marker setMarkerBrush "Solid"; + _marker setMarkerAlpha 0.5; + _marker setMarkerColor "ColorOrange"; + _marker setMarkerText "Occupied Area"; + }; + + _logDetail = format ["[OCCUPATION]:: Spawning %2 AI in at %3 to patrol %1",_locationName,_aiCount,_spawnPosition]; + [_logDetail] call SC_fnc_log; + _okToSpawn = false; + }; + + }; + sleep 0.2; +} forEach _locations; \ No newline at end of file diff --git a/scripts/occupationSky.sqf b/scripts/occupationSky.sqf index 11e7b5f..b274a6b 100644 --- a/scripts/occupationSky.sqf +++ b/scripts/occupationSky.sqf @@ -1,8 +1,17 @@ -diag_log format['[OCCUPATION:Sky] Started']; +_logDetail = format['[OCCUPATION:Sky] Started']; +[_logDetail] call SC_fnc_log; if (!isServer) exitWith {}; -if(SC_liveHelis >= SC_maxNumberofHelis) exitWith {}; +if(SC_liveHelis >= SC_maxNumberofHelis) exitWith +{ + if(SC_extendedLogging) then + { + _logDetail = format['[OCCUPATION:Sky] End check %1 currently active (max %2) @ %3',SC_liveHelis,SC_maxNumberofHelis,time]; + [_logDetail] call SC_fnc_log; + }; + +}; _vehiclesToSpawn = (SC_maxNumberofHelis - SC_liveHelis); _middle = worldSize/2; @@ -29,20 +38,24 @@ _i = 0; for "_i" from 1 to _vehiclesToSpawn do { - private["_group"]; - _Location = _locations call BIS_fnc_selectRandom; + private["_group"]; + _Location = _locations call BIS_fnc_selectRandom; + _pos = position _Location; + _position = [_pos select 0, _pos select 1, 300]; + _spawnLocation = [_position,10,100,5,0,20,0] call BIS_fnc_findSafePos; + _height = 250 + (round (random 200)); + _helispawnLocation = [_spawnLocation select 0, _spawnLocation select 1, _height]; - _position = position _Location; - _spawnLocation = [_position select 0, _position select 1, 300]; - _group = createGroup east; _HeliClassToUse = SC_HeliClassToUse call BIS_fnc_selectRandom; - _vehicle1 = [ [_spawnLocation], _group, "assault", "difficult", "resistance", _HeliClassToUse ] call DMS_fnc_SpawnAIVehicle; + _vehicle1 = [ [_helispawnLocation], _group, "assault", "difficult", "resistance", _HeliClassToUse ] call DMS_fnc_SpawnAIVehicle; + SC_liveHelis = SC_liveHelis + 1; _vehicle1 setVehicleLock "UNLOCKED"; + _vehicle1 setVariable ["ExileIsLocked", 0, true]; if(SC_infiSTAR_log) then { _logDetail = format['[OCCUPATION:Sky] %1 spawned @ %2',_HeliClassToUse,_spawnLocation]; - ['A3_EXILE_OCCUPATION',_logDetail] call FNC_A3_CUSTOMLOG; + [_logDetail] call SC_fnc_log; }; _vehicle1 setVehiclePosition [_spawnLocation, [], 0, "FLY"]; _vehicle1 setVariable ["vehicleID", _spawnLocation, true]; @@ -51,11 +64,61 @@ for "_i" from 1 to _vehiclesToSpawn do _vehicle1 engineOn true; _vehicle1 flyInHeight 150; sleep 0.2; + + + clearMagazineCargoGlobal _vehicle1; + clearWeaponCargoGlobal _vehicle1; + clearItemCargoGlobal _vehicle1; + + _vehicle1 addMagazineCargoGlobal ["HandGrenade", (random 2)]; + _vehicle1 addItemCargoGlobal ["ItemGPS", (random 1)]; + _vehicle1 addItemCargoGlobal ["Exile_Item_InstaDoc", (random 1)]; + _vehicle1 addItemCargoGlobal ["Exile_Item_PlasticBottleFreshWater", 2 + (random 2)]; + _vehicle1 addItemCargoGlobal ["Exile_Item_EMRE", 2 + (random 2)]; + + // Add weapons with ammo to the vehicle + _possibleWeapons = + [ + "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" + ]; + _amountOfWeapons = 1 + (random 3); + + for "_i" from 1 to _amountOfWeapons do + { + _weaponToAdd = _possibleWeapons call BIS_fnc_selectRandom; + _vehicle1 addWeaponCargoGlobal [_weaponToAdd,1]; + + _magazinesToAdd = getArray (configFile >> "CfgWeapons" >> _weaponToAdd >> "magazines"); + _vehicle1 addMagazineCargoGlobal [(_magazinesToAdd select 0),round random 3]; + }; + [_group, _spawnLocation, 2000] call bis_fnc_taskPatrol; - _group setBehaviour "AWARE"; + _group setBehaviour "CARELESS"; _group setCombatMode "RED"; - SC_liveHelis = SC_liveHelis + 1; + _vehicle1 addEventHandler ["getin", "_this call SC_fnc_claimVehicle;"]; _vehicle1 addMPEventHandler ["mpkilled", "SC_liveHelis = SC_liveHelis - 1;"]; _vehicle1 addMPEventHandler ["mphit", "_this call SC_fnc_airHit;"]; _vehicle1 setVariable ["SC_crewEjected", false,true]; @@ -64,4 +127,5 @@ for "_i" from 1 to _vehiclesToSpawn do }; -diag_log format['[OCCUPATION:Sky] Running']; \ No newline at end of file +_logDetail = format['[OCCUPATION:Sky] Running']; +[_logDetail] call SC_fnc_log; \ No newline at end of file diff --git a/scripts/occupationStatic.sqf b/scripts/occupationStatic.sqf index afe5cae..66da71d 100644 --- a/scripts/occupationStatic.sqf +++ b/scripts/occupationStatic.sqf @@ -1,20 +1,21 @@ private["_wp","_wp2","_wp3"]; if (!isServer) exitWith {}; -diag_log format ["[OCCUPATION Static]:: Starting Monitor"]; +_logDetail = format ["[OCCUPATION Static]:: Starting Monitor"]; +[_logDetail] call SC_fnc_log; -_middle = worldSize/2; -_spawnCenter = [_middle,_middle,0]; // Centre point for the map -_maxDistance = _middle; // Max radius for the map +_middle = worldSize/2; +_spawnCenter = [_middle,_middle,0]; // Centre point for the map +_maxDistance = _middle; // Max radius for the map _maxAIcount = SC_maxAIcount; _minFPS = SC_minFPS; -_debug = SC_debug; -_useLaunchers = DMS_ai_use_launchers; +_debug = SC_debug; +_useLaunchers = DMS_ai_use_launchers; _scaleAI = SC_scaleAI; -_statics = SC_statics; // details for the static spawns -_static = []; +_statics = SC_statics; // details for the static spawns +_static = []; _currentPlayerCount = count playableUnits; if(_currentPlayerCount > _scaleAI) then @@ -24,10 +25,18 @@ if(_currentPlayerCount > _scaleAI) then // Don't spawn additional AI if the server fps is below 8 -if(diag_fps < _minFPS) exitWith { diag_log format ["[OCCUPATION Static]:: Held off spawning more AI as the server FPS is only %1",diag_fps]; }; +if(diag_fps < _minFPS) exitWith +{ + _logDetail = format ["[OCCUPATION Static]:: Held off spawning more AI as the server FPS is only %1",diag_fps]; + [_logDetail] call SC_fnc_log; +}; _aiActive = count(_spawnCenter nearEntities ["O_recon_F", _maxDistance+1000]); -if(_aiActive > _maxAIcount) exitWith { diag_log format ["[OCCUPATION Static]:: %1 active AI, so not spawning AI this time",_aiActive]; }; +if(_aiActive > _maxAIcount) exitWith +{ + _logDetail = format ["[OCCUPATION Static]:: %1 active AI, so not spawning AI this time",_aiActive]; + [_logDetail] call SC_fnc_log; +}; for [{_i = 0},{_i < (count _statics)},{_i =_i + 1}] do { @@ -38,7 +47,8 @@ for [{_i = 0},{_i < (count _statics)},{_i =_i + 1}] do _staticSearch = _currentStatic select 3; _underground = _currentStatic select 4; - diag_log format ["[OCCUPATION Static]:: Adding %2 AI to static spawn @ %1",_spawnPosition,_aiCount]; + _logDetail = format ["[OCCUPATION Static]:: Adding %2 AI to static spawn @ %1",_spawnPosition,_aiCount]; + [_logDetail] call SC_fnc_log; _okToSpawn = true; Sleep 0.1; @@ -48,10 +58,26 @@ for [{_i = 0},{_i < (count _statics)},{_i =_i + 1}] do // Don't spawn additional AI if there are already AI in range _aiNear = count(_spawnPosition nearEntities ["O_recon_F", 125]); - if(_aiNear > 0) exitwith { _okToSpawn = false; if(_debug) then { diag_log format ["[OCCUPATION Static]:: %1 already has %2 active AI patrolling",_spawnPosition,_aiNear];}; }; + if(_aiNear > 0) exitwith + { + _okToSpawn = false; + if(_debug) then + { + _logDetail = format ["[OCCUPATION Static]:: %1 already has %2 active AI patrolling",_spawnPosition,_aiNear]; + [_logDetail] call SC_fnc_log; + }; + }; // Don't spawn additional AI if there are players in range - if([_spawnPosition, 200] call ExileClient_util_world_isAlivePlayerInRange) exitwith { _okToSpawn = false; if(_debug) then { diag_log format ["[OCCUPATION Static]:: %1 has players too close",_spawnPosition];}; }; + if([_spawnPosition, 400] call ExileClient_util_world_isAlivePlayerInRange) exitwith + { + _okToSpawn = false; + if(_debug) then + { + _logDetail = format ["[OCCUPATION Static]:: %1 has players too close",_spawnPosition]; + [_logDetail] call SC_fnc_log; + }; + }; if(_okToSpawn) then { @@ -103,12 +129,12 @@ for [{_i = 0},{_i < (count _statics)},{_i =_i + 1}] do _i = _buildingPositions find _spawnPosition; _wp = _group addWaypoint [_spawnPosition, 0] ; _wp setWaypointFormation "Column"; - _wp setWaypointBehaviour "SAD"; + _wp setWaypointBehaviour "COMBAT"; _wp setWaypointCombatMode "RED"; _wp setWaypointCompletionRadius 1; _wp waypointAttachObject _x; _wp setwaypointHousePosition _i; - _wp setWaypointType "MOVE"; + _wp setWaypointType "SAD"; }; } foreach _buildings; @@ -122,7 +148,8 @@ for [{_i = 0},{_i < (count _statics)},{_i =_i + 1}] do ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - diag_log format ["[OCCUPATION Static]:: Spawning %1 AI in at %2 to patrol",_aiCount,_spawnPosition]; + _logDetail = format ["[OCCUPATION Static]:: Spawning %1 AI in at %2 to patrol",_aiCount,_spawnPosition]; + [_logDetail] call SC_fnc_log; if(SC_mapMarkers) then { @@ -141,4 +168,5 @@ for [{_i = 0},{_i < (count _statics)},{_i =_i + 1}] do }; }; -diag_log "[OCCUPATION Static]: Ended"; \ No newline at end of file +_logDetail = "[OCCUPATION Static]: Ended"; +[_logDetail] call SC_fnc_log; \ No newline at end of file diff --git a/scripts/occupationVehicle.sqf b/scripts/occupationVehicle.sqf index a6a7304..5d0b0f4 100644 --- a/scripts/occupationVehicle.sqf +++ b/scripts/occupationVehicle.sqf @@ -1,26 +1,41 @@ if (!isServer) exitWith {}; -if(SC_liveVehicles >= SC_maxNumberofVehicles) exitWith {}; +_logDetail = format['[OCCUPATION:Vehicle] Started']; +[_logDetail] call SC_fnc_log; + +if(SC_liveVehicles >= SC_maxNumberofVehicles) exitWith +{ + if(SC_extendedLogging) then + { + _logDetail = format['[OCCUPATION:Vehicle] End check %1 currently active (max %2) @ %3',SC_liveVehicles,SC_maxNumberofVehicles,time]; + [_logDetail] call SC_fnc_log; + }; +}; _vehiclesToSpawn = (SC_maxNumberofVehicles - SC_liveVehicles); -if(_vehiclesToSpawn > 0) then +if(SC_extendedLogging) then { - diag_log format['[OCCUPATION:Vehicle] Started %2 currently active (max %3) spawning %1 extra vehicle(s) @ %4',_vehiclesToSpawn,SC_liveVehicles,SC_maxNumberofVehicles,time]; -} -else -{ - diag_log format['[OCCUPATION:Vehicle] Started %2 currently active (max %3) @ %4',_vehiclesToSpawn,SC_liveVehicles,SC_maxNumberofVehicles,time]; + if(_vehiclesToSpawn > 0) then + { + _logDetail = format['[OCCUPATION:Vehicle] Started %2 currently active (max %3) spawning %1 extra vehicle(s) @ %4',_vehiclesToSpawn,SC_liveVehicles,SC_maxNumberofVehicles,time]; + [_logDetail] call SC_fnc_log; + } + else + { + _logDetail = format['[OCCUPATION:Vehicle] Started %2 currently active (max %3) @ %4',_vehiclesToSpawn,SC_liveVehicles,SC_maxNumberofVehicles,time]; + [_logDetail] call SC_fnc_log; + }; + }; - _middle = worldSize/2; _spawnCenter = [_middle,_middle,0]; _maxDistance = _middle; if(_vehiclesToSpawn >= 1) then { - + _useLaunchers = DMS_ai_use_launchers; _locations = (nearestLocations [_spawnCenter, ["NameVillage","NameCity", "NameCityCapital"], _maxDistance]); _i = 0; { @@ -45,41 +60,113 @@ if(_vehiclesToSpawn >= 1) then _Location = _locations call BIS_fnc_selectRandom; _position = position _Location; _pos = [_position,10,100,5,0,20,0] call BIS_fnc_findSafePos; - _spawnLocation = [_pos select 0, _pos select 1, 150]; + // Get position of nearest roads - _nearRoads = _spawnLocation nearRoads 500; + _nearRoads = _pos nearRoads 500; _nearestRoad = _nearRoads select 0; _nearestRoad = position (_nearRoads select 0); - + _spawnLocation = [_nearestRoad select 0, _pos select 1, 0]; + _group = createGroup east; + SC_liveVehicles = SC_liveVehicles + 1; _VehicleClassToUse = SC_VehicleClassToUse call BIS_fnc_selectRandom; - _vehicleObject = [ [_nearestRoad], _group, "assault", "random", "bandit",_VehicleClassToUse ] call DMS_fnc_SpawnAIVehicle; - _vehicleObject setVehicleLock "UNLOCKED"; + _vehicle = createVehicle [_VehicleClassToUse, _spawnLocation, [], 0, "NONE"]; + _vehicle setFuel 1; + _vehicle engineOn true; + _vehicle lock 0; + _vehicle setVehicleLock "UNLOCKED"; + _vehicle setVariable ["ExileIsLocked", 0, true]; + _vehicle setSpeedMode "LIMITED"; + _vehicle limitSpeed 60; + _vehicle action ["LightOn", _vehicle]; + + _vehicle addEventHandler ["getin", "_this call SC_fnc_getIn;"]; + _vehicle addMPEventHandler ["mpkilled", "SC_liveVehicles = SC_liveVehicles - 1;"]; + _vehicle addMPEventHandler ["mphit", "_this call SC_fnc_repairVehicle;"]; + _vehicle setVariable ["SC_vehicleSpawnLocation", _spawnLocation,true]; + + _group addVehicle _vehicle; + _driver = [_group,_spawnLocation,"assault","random","bandit","Vehicle"] call DMS_fnc_SpawnAISoldier; + if(SC_debug) then + { + _tag = createVehicle ["Sign_Arrow_Green_F", position _driver, [], 0, "CAN_COLLIDE"]; + _tag attachTo [_driver,[0,0,0.6],"Head"]; + }; + sleep 1; + _driver setVariable ["DMS_AssignedVeh",_vehicle]; + _driver addMPEventHandler ["mpkilled", "_this call SC_fnc_driverKilled;"]; + _driver setVariable ["SC_drivenVehicle", _vehicle,true]; + _vehicle setVariable ["SC_assignedDriver", _driver,true]; + _driver action ["movetodriver", _vehicle]; + _driver assignAsDriver _vehicle; + sleep 0.2; + _crewCount = + { + private _unit = [_group,_spawnLocation,"assault","random","bandit","Vehicle"] call DMS_fnc_SpawnAISoldier; + _unit moveInTurret [_vehicle, _x]; + _unit setVariable ["DMS_AssignedVeh",_vehicle]; + _unit assignAsCargo _vehicle; + sleep 0.2; + true + } count (allTurrets [_vehicle, true]); + _group setBehaviour "CARELESS"; + _group setCombatMode "BLUE"; + sleep 10; + + // Get the AI to shut the fuck up :) enableSentences false; enableRadio false; - - diag_log format['[OCCUPATION:Vehicle] %1 spawned @ %2',_VehicleClassToUse,_spawnLocation]; - _vehicleObject addMPEventHandler ["mpkilled", "SC_liveVehicles = SC_liveVehicles - 1;"]; - _vehicleObject addMPEventHandler ["mphit", "_this call SC_fnc_repairVehicle;"]; - - _driverVeh = driver _vehicleObject; - _driverVeh addMPEventHandler ["mpkilled", "_this call SC_fnc_driverKilled;"]; - _driverVeh setVariable ["SC_drivenVehicle", _vehicleObject,true]; - - - _vehicleObject setSpeedMode "LIMITED"; - _vehicleObject limitSpeed 60; - _vehicleObject action ["LightOn", _vehicleObject]; + + if(SC_extendedLogging) then + { + _logDetail = format['[OCCUPATION:Vehicle] %1 spawned @ %2',_VehicleClassToUse,_spawnLocation]; + [_logDetail] call SC_fnc_log; + }; + + [_group, _spawnLocation, 2000] call bis_fnc_taskPatrol; _group setBehaviour "AWARE"; _group setCombatMode "RED"; - - SC_liveVehicles = SC_liveVehicles + 1; sleep 0.2; + + clearMagazineCargoGlobal _vehicle; + clearWeaponCargoGlobal _vehicle; + clearItemCargoGlobal _vehicle; + + _vehicle addMagazineCargoGlobal ["HandGrenade", (random 2)]; + _vehicle addItemCargoGlobal ["ItemGPS", (random 1)]; + _vehicle addItemCargoGlobal ["Exile_Item_InstaDoc", (random 1)]; + _vehicle addItemCargoGlobal ["Exile_Item_PlasticBottleFreshWater", 2 + (random 2)]; + _vehicle addItemCargoGlobal ["Exile_Item_EMRE", 2 + (random 2)]; + + // Add weapons with ammo to the vehicle + _possibleWeapons = + [ + "arifle_MXM_Black_F", + "arifle_MXM_F", + "arifle_MX_SW_Black_F", + "arifle_MX_SW_F", + "LMG_Mk200_F", + "LMG_Zafir_F" + ]; + _amountOfWeapons = 1 + (random 3); + + for "_i" from 1 to _amountOfWeapons do + { + _weaponToAdd = _possibleWeapons call BIS_fnc_selectRandom; + _vehicle addWeaponCargoGlobal [_weaponToAdd,1]; + + _magazinesToAdd = getArray (configFile >> "CfgWeapons" >> _weaponToAdd >> "magazines"); + _vehicle addMagazineCargoGlobal [(_magazinesToAdd select 0),round random 3]; + }; }; }; -diag_log format['[OCCUPATION:Vehicle] Running']; \ No newline at end of file +if(SC_extendedLogging) then +{ + _logDetail = format['[OCCUPATION:Vehicle] End check %1 currently active (max %2) @ %3',SC_liveVehicles,SC_maxNumberofVehicles,time]; + [_logDetail] call SC_fnc_log; +}; \ No newline at end of file diff --git a/scripts/reactions/airHit.sqf b/scripts/reactions/airHit.sqf index be4280b..e1994cd 100644 --- a/scripts/reactions/airHit.sqf +++ b/scripts/reactions/airHit.sqf @@ -1,40 +1,57 @@ _heli = _this select 0; +_heli removeAllMPEventHandlers "mphit"; _heliDamage = getDammage _heli; _heliPosition = getPosATL _heli; _heliHeight = getPosATL _heli select 2; _crewEjected = _heli getVariable "SC_crewEjected"; -if(SC_infiSTAR_log) then + +_damageLimit = 0.2; +_engineDamage = false; +_fueltankDamage = false; + +if(SC_extendedLogging) then { _logDetail = format ["[OCCUPATION:Sky]:: Air unit %2 hit by %3 at %1 (damage: %4)",time,_this select 0,_this select 1,_heliDamage]; - ['A3_EXILE_OCCUPATION',_logDetail] call FNC_A3_CUSTOMLOG; + [_logDetail] call SC_fnc_log; }; _ejectChance = round (random 100) + (_heliDamage * 100); -if(_heliDamage > 0 && _ejectChance > 70 && !_crewEjected) then + +_essentials = [ "HitAvionics","HitEngine1","HitEngine2","HitEngine","HitHRotor","HitVRotor","HitTransmission", + "HitHydraulics","HitGear","HitHStabilizerL1","HitHStabilizerR1","HitVStabilizer1","HitFuel"]; + +_damagedEssentials = 0; { - _heli removeAllMPEventHandlers "mphit"; + if ((_heli getHitPointDamage _x) > 0) then + { + _damage = _heli getHitPointDamage _x; + if(SC_extendedLogging) then + { + _logDetail = format ["[OCCUPATION:Sky]:: Heli %1 checking part %2 (damage: %4) @ %3",_heli, _x, time,_damage]; + [_logDetail] call SC_fnc_log; + }; + if(_damage > 0) then { _damagedEssentials = _damagedEssentials + 1; }; + }; +} forEach _essentials; + + +if(_damagedEssentials > 0 && !_crewEjected && _ejectChance > 80) then +{ + [_heli ] spawn { _veh = _this select 0; { - if(SC_infiSTAR_log) then + if(SC_extendedLogging) then { _heliPosition = getPosATL _veh; _logDetail = format ["[OCCUPATION:Sky]:: Air unit %2 ejecting passengers at %3 (time: %1)",time,_this select 0,_this select 1,_heliPosition]; - ['A3_EXILE_OCCUPATION',_logDetail] call FNC_A3_CUSTOMLOG; + [_logDetail] call SC_fnc_log; }; _unit = _x select 0; if (isNull driver _veh) then { - //moveOut _unit; - _parachute = "Steerable_Parachute_F" createVehicle getPos _unit; - _parachute setDir (getDir _unit); - _unit moveInDriver _parachute; - _heliPosition = getPosATL _heli; - _parachutePosition = [_heliPosition select 0, _heliPosition select 1, (_heliPosition select 2)-5]; - _parachute setPos _parachutePosition; - sleep 0.1; - _parachute enableSimulationGlobal true; + _unit action ["EJECT", _veh]; }; } forEach (fullCrew _veh); @@ -42,53 +59,46 @@ if(_heliDamage > 0 && _ejectChance > 70 && !_crewEjected) then _heli setVariable ["SC_crewEjected", true,true]; _target = _this select 1; _pilot = driver _heli; - _group = group _pilot; + _group = group _heli; _group reveal [_target,1.5]; _destination = getPos _target; [_group, _destination, 250] call bis_fnc_taskPatrol; - _group setBehaviour "COMBAT"; - _group setCombatMode "RED"; - - _group allowFleeing 0; _group setBehaviour "AWARE"; _group setSpeedMode "FULL"; - _group setCombatMode "RED"; + _group setCombatMode "RED"; _heli addMPEventHandler ["mphit", "_this call SC_fnc_airHit;"]; }; + -if(_heliDamage >= 0.5) then +if(_heliDamage > 0.5 && _damagedEssentials > 0) then { - if(SC_infiSTAR_log) then + if(SC_extendedLogging) then { _logDetail = format ["[OCCUPATION:Sky]:: Air unit %2 damaged and force landing at %3 (time: %1)",time,_this select 0,_this select 1,_heliPosition]; - ['A3_EXILE_OCCUPATION',_logDetail] call FNC_A3_CUSTOMLOG; + [_logDetail] call SC_fnc_log; }; _heli removeAllMPEventHandlers "mphit"; _heli removeAllMPEventHandlers "mpkilled"; + _currentHeliPos = getPos _heli; + _destination = [_currentHeliPos, 1, 150, 10, 0, 20, 0] call BIS_fnc_findSafePos; SC_liveHelis = SC_liveHelis - 1; _heli land "LAND"; _heli setVehicleLock "UNLOCKED"; _target = _this select 1; _pilot = driver _heli; - _group = group _pilot; + _group = group _heli; _group reveal [_target,1.5]; - _destination = getPos _target; - [_group, _destination, 250] call bis_fnc_taskPatrol; - _group setBehaviour "COMBAT"; - _group setCombatMode "RED"; - - _group allowFleeing 0; - _group setBehaviour "AWARE"; - _group setSpeedMode "FULL"; - _group setCombatMode "RED"; -}; - - - - - - \ No newline at end of file + _wp = _group addWaypoint [_destination, 0] ; + _wp setWaypointFormation "Column"; + _wp setWaypointBehaviour "COMBAT"; + _wp setWaypointCombatMode "RED"; + _wp setWaypointCompletionRadius 1; + _wp setWaypointType "SAD"; + [_group, _destination, 250] call bis_fnc_taskPatrol; + _group setBehaviour "COMBAT"; + _group setCombatMode "RED"; +}; \ No newline at end of file diff --git a/scripts/reactions/driverKilled.sqf b/scripts/reactions/driverKilled.sqf index 626829f..1766af3 100644 --- a/scripts/reactions/driverKilled.sqf +++ b/scripts/reactions/driverKilled.sqf @@ -1,46 +1,72 @@ -if(SC_infiSTAR_log) then +// Triggered when the designated driver for a vehicle is killed +// Attempts to select a new driver from the same group + +if(SC_extendedLogging) then { _logDetail = format ["[OCCUPATION:Vehicle]:: Unit %2 (driver) killed at %1",time,_this select 0]; - ['A3_EXILE_OCCUPATION',_logDetail] call FNC_A3_CUSTOMLOG; + [_logDetail] call SC_fnc_log; }; _deadDriver = _this select 0; - _deadDriver removeAllMPEventHandlers "mpkilled"; -_deadDriver removeAllMPEventHandlers "mphit"; +_vehicleDriven = _deadDriver getVariable "SC_drivenVehicle"; + + +if(SC_debug) then +{ + { detach _x; deleteVehicle _x; } forEach attachedObjects _deadDriver; +}; // Select a replacement driver -_vehicleDriven = _deadDriver getVariable "SC_drivenVehicle"; -_vehGroup = group _deadDriver; -[_deadDriver] join grpNull; -_nearAI = (position _vehicleDriven) nearEntities [["O_recon_F"], 100]; -_replacementDriver = _nearAI call BIS_fnc_selectRandom; - -if(SC_infiSTAR_log) then -{ - _logDetail = format ["[OCCUPATION:Vehicle]:: Replacement Driver found (%1) for vehicle %2",_replacementDriver,_vehicleDriven]; - ['A3_EXILE_OCCUPATION',_logDetail] call FNC_A3_CUSTOMLOG; -}; - -// add event handlers for the new driver -_replacementDriver addMPEventHandler ["mpkilled", "_this call SC_fnc_driverKilled;"]; -_replacementDriver setVariable ["SC_drivenVehicle", _vehicleDriven,true]; _vehicleDriven removeAllMPEventHandlers "mphit"; -_vehicleDriven addMPEventHandler ["mphit", "_this call SC_fnc_repairVehicle;"]; - -_replacementDriver assignAsDriver _vehicleDriven; -_vehicleDamage = getDammage _vehicleDriven; - -// If the vehicle is already damaged then fix it, otherwise get in as the driver -if(_vehicleDamage > 0) then +_vehGroup = group _vehicleDriven; +[_deadDriver] join grpNull; +if(count units _vehGroup > 0) then { - [_vehicleDriven] call SC_fnc_repairVehicle; -} -else -{ - [_replacementDriver] orderGetIn true; - //_replacementDriver moveInDriver _vehicleDriven; + _logDetail = format ["[OCCUPATION:Vehicle]:: vehicle: %1 group: %2 units left:%3",_vehicleDriven,_vehGroup,count units _vehGroup]; + [_logDetail] call SC_fnc_log; + _groupMembers = units _vehGroup; + _replacementDriver = _groupMembers call BIS_fnc_selectRandom; + + if(!alive _replacementDriver) exitWith { [_replacementDriver] call SC_fnc_driverKilled; }; + + if (isNil "_replacementDriver") exitWith + { + _logDetail = format ["[OCCUPATION:Vehicle]:: No replacement Driver found for vehicle %1",_vehicleDriven]; + [_logDetail] call SC_fnc_log; + }; + + if(SC_debug) then + { + _tag = createVehicle ["Sign_Arrow_Green_F", position _replacementDriver, [], 0, "CAN_COLLIDE"]; + _tag attachTo [_replacementDriver,[0,0,0.6],"Head"]; + }; + + _replacementDriver disableAI "TARGET"; + _replacementDriver disableAI "AUTOTARGET"; + _replacementDriver disableAI "AUTOCOMBAT"; + _replacementDriver disableAI "COVER"; + + _replacementDriver assignAsDriver _vehicleDriven; + + _vehicleDriven addMPEventHandler ["mphit", "_this call SC_fnc_repairVehicle;"]; + _replacementDriver addMPEventHandler ["mpkilled", "_this call SC_fnc_driverKilled;"]; + _replacementDriver setVariable ["DMS_AssignedVeh",_vehicleDriven]; + _replacementDriver setVariable ["SC_drivenVehicle", _vehicleDriven,true]; + _vehicleDriven setVariable ["SC_assignedDriver", _replacementDriver,true]; + _replacementDriver doMove (position _vehicleDriven); + _replacementDriver action ["movetodriver", _vehicleDriven]; + + + if(SC_extendedLogging) then + { + _logDetail = format ["[OCCUPATION:Vehicle]:: Replacement Driver found (%1) for vehicle %2",_replacementDriver,_vehicleDriven]; + [_logDetail] call SC_fnc_log; + }; + + if(damage _vehicleDriven > 0) then + { + [_replacementDriver] call SC_fnc_repairVehicle; + + }; }; - - - diff --git a/scripts/reactions/getIn.sqf b/scripts/reactions/getIn.sqf new file mode 100644 index 0000000..e499552 --- /dev/null +++ b/scripts/reactions/getIn.sqf @@ -0,0 +1,23 @@ +// Triggered if a player gets in a captured AI vehicle +// Marks the vehicle as claimed by a player and frees up a slot to spawn another AI controlled vehicle + +_unit = _this select 0; + +if(isPlayer _unit) then +{ + _vehicle = vehicle _unit; + _vehicle removeAllMPEventHandlers "mphit"; + _vehicle removeAllMPEventHandlers "mpkilled"; + SC_liveVehicles = SC_liveVehicles - 1; + + if(SC_extendedLogging) then + { + _logDetail = format ["[OCCUPATION:claimVehicle]:: Unit %3 has claimed vehicle %2 at %1",time,_vehicle,_unit]; + [_logDetail] call SC_fnc_log; + }; +}; + + + + + diff --git a/scripts/reactions/reactUnit.sqf b/scripts/reactions/reactUnit.sqf index e83963c..6c91d4b 100644 --- a/scripts/reactions/reactUnit.sqf +++ b/scripts/reactions/reactUnit.sqf @@ -1 +1,7 @@ -diag_log format ["[OCCUPATION]:: Unit %2 killed at %1",time,_this]; \ No newline at end of file +_logDetail = format ["[OCCUPATION]:: Unit %2 killed at %1",time,_this]; +[_logDetail] call SC_fnc_log; + +// Get the variables from the event handler +_unit = _this select 0; +_weaponFired = _this select 1; + diff --git a/scripts/reactions/repairVehicle.sqf b/scripts/reactions/repairVehicle.sqf index b4bf0ec..011f8d3 100644 --- a/scripts/reactions/repairVehicle.sqf +++ b/scripts/reactions/repairVehicle.sqf @@ -1,44 +1,106 @@ -_vehicle = _this select 0; -_vehicleDamage = getDammage _vehicle; +// Triggered when a ground vehicle takes damage +// Attempts to get the current vehicle driver to repair the vehicle -_wheels = ["HitLF2Wheel","HitLFWheel","HitRFWheel","HitRF2Wheel"]; +_vehicle = _this select 0; +_vehicle removeAllMPEventHandlers "mphit"; + +_vehicleDamage = damage _vehicle; +_damagedWheels = 0; +_damageLimit = 0.2; +_engineDamage = false; +_fueltankDamage = false; +_assignedDriver = _vehicle getVariable "SC_assignedDriver"; + +if(isNull assignedDriver _vehicle) exitWith { [_assignedDriver] call SC_fnc_driverKilled; }; + +_wheels = ["HitLFWheel","HitLF2Wheel","HitRFWheel","HitRF2Wheel","HitLBWheel","HitLMWheel","HitRBWheel","HitRMWheel"]; _damagedWheels = 0; { - if ((_vehicle getHitPointDamage _x) >= 0.5) then + if ((_vehicle getHitPointDamage _x) > 0) then { - _damagedWheels = _damagedWheels + 1; + _damage = _vehicle getHitPointDamage _x; + if(SC_extendedLogging) then + { + _logDetail = format ["[OCCUPATION:repairVehicle]:: Vehicle %1 checking wheel %2 (damage: %4) @ %3",_vehicle, _x, time,_damage]; + [_logDetail] call SC_fnc_log; + }; + if(_damage > 0) then { _damagedWheels = _damagedWheels + 1; }; }; } forEach _wheels; -if(_damagedWheels >= 1 && alive (driver _vehicle)) then +// Check Engine +if ((_vehicle getHitPointDamage "HitEngine") >= _damageLimit) then { _engineDamage = true; }; + +// Check Fuel Tank +if ((_vehicle getHitPointDamage "HitFuel") > 0) then { _fueltankDamage = true; }; + + +if(_damagedWheels > 0 OR _engineDamage OR _fueltankDamage) then { - if(SC_infiSTAR_log) then + if(SC_extendedLogging) then { - _logDetail = format ["[OCCUPATION:repairVehicle]:: Unit %2 repairing vehicle at %1",time,_this select 0]; - ['A3_EXILE_OCCUPATION',_logDetail] call FNC_A3_CUSTOMLOG; + _logDetail = format ["[OCCUPATION:repairVehicle]:: Unit %2 repairing vehicle at %1",time,_assignedDriver]; + [_logDetail] call SC_fnc_log; }; - _vehicle removeAllMPEventHandlers "mphit"; - [_vehicle ] spawn + + [_vehicle,_assignedDriver ] spawn { - _vehicleToFix = _this select 0; - _driverVeh = driver _vehicleToFix; - _vehicleToFix forceSpeed 0; - sleep 2; - _driverVeh action ["Eject", _vehicleToFix]; - _driverVeh doWatch (position _vehicleToFix); - _driverVeh playActionNow "medicStart"; - sleep 10; - _driverVeh switchMove ""; - _driverVeh playActionNow "medicStart"; - sleep 4; - _vehicleToFix setDamage 0; - _driverVeh switchMove ""; - _driverVeh playActionNow "medicStop"; - sleep 2; - _driverVeh assignAsDriver _vehicleToFix; - _driverVeh moveInDriver _vehicleToFix; - _vehicleToFix forceSpeed -1; - _vehicleToFix addMPEventHandler ["mphit", "_this call SC_fnc_repairVehicle;"]; + _vehicle = _this select 0; + _vehicle forceSpeed 0; + _vehGroup = group _vehicle; + _driver = _this select 1; + _driver action ["getOut", _vehicle]; + + if(SC_debug) then + { + _tag = createVehicle ["Sign_Arrow_Green_F", position _driver, [], 0, "CAN_COLLIDE"]; + _tag attachTo [_driver,[0,0,0.6],"Head"]; + }; + sleep 0.2; + _driver doMove (position _vehicle); + _driver disableAI "TARGET"; + _driver disableAI "AUTOTARGET"; + _driver disableAI "AUTOCOMBAT"; + _driver disableAI "COVER"; + _driverDir = _driver getDir _vehicle; + //_driver setDir _driverDir + 180; + _driver setUnitPos "MIDDLE"; + sleep 0.5; + _driver playMoveNow "Acts_carFixingWheel"; + sleep 2; + _driver playMoveNow "Acts_carFixingWheel"; + sleep 2; + _driver playMoveNow "Acts_carFixingWheel"; + sleep 2; + _driver switchMove ""; + if(alive _driver) then + { + _vehicle setDamage 0; + _driver playMoveNow "Acts_carFixingWheel"; + sleep 2; + _driver assignAsDriver _vehicle; + _driver action ["movetodriver", _vehicle]; + }; + _wp = _vehGroup addWaypoint [position _vehicle, 0] ; + _wp setWaypointFormation "Column"; + _wp setWaypointCompletionRadius 1; + _wp setWaypointType "GETIN"; + sleep 10; + _spawnLocation = _vehicle getVariable "SC_vehicleSpawnLocation"; + _driver action ["movetodriver", _vehicle]; + _vehicle forceSpeed -1; + [_vehGroup, _spawnLocation, 2000] call bis_fnc_taskPatrol; + _vehGroup setBehaviour "AWARE"; + _vehGroup setCombatMode "RED"; + }; +} +else +{ + _logDetail = format ["[OCCUPATION:repairVehicle]:: Not repairing %2, driver is %3 at %1",time,_vehicle,_assignedDriver]; + [_logDetail] call SC_fnc_log; + _logDetail = format ["[OCCUPATION:repairVehicle]:: vehicle:%1 damage:%2 engine:%3 fuelTank:%4",_vehicle,_vehicleDamage,_engineDamage,_fueltankDamage]; + [_logDetail] call SC_fnc_log; }; +_vehicle addMPEventHandler ["mphit", "_this call SC_fnc_repairVehicle;"]; \ No newline at end of file diff --git a/scripts/reactions/vehicleDestroyed.sqf b/scripts/reactions/vehicleDestroyed.sqf new file mode 100644 index 0000000..e69de29 diff --git a/scripts/startOccupation.sqf b/scripts/startOccupation.sqf index e725802..68757a4 100644 --- a/scripts/startOccupation.sqf +++ b/scripts/startOccupation.sqf @@ -1,6 +1,8 @@ -diag_log format ["[OCCUPATION]:: Giving the server time to start before starting [OCCUPATION] (%1)",time]; +_logDetail = format ["[OCCUPATION]:: Occupation v%2 Giving the server time to start before starting [OCCUPATION] (%1)",time,SC_occupationVersion]; +[_logDetail] call SC_fnc_log; uiSleep 30; -diag_log format ["[OCCUPATION]:: Initialised at %1",time]; +_logDetail = format ["[OCCUPATION]:: Occupation v%2 Initialised at %1",time,SC_occupationVersion]; +[_logDetail] call SC_fnc_log; if(SC_debug) then { SC_refreshTime = 60; }else{ SC_refreshTime = 300; }; @@ -19,7 +21,8 @@ if(SC_occupyLootCrates) then if(SC_occupyHeliCrashes) then { - call compile preprocessFileLineNumbers "\x\addons\a3_exile_occupation\scripts\occupationHeliCrashes.sqf"; + uiSleep 15; // delay the start + call compile preprocessFileLineNumbers "\x\addons\a3_exile_occupation\scripts\occupationHeliCrashes.sqf"; }; if(SC_occupyStatic) then @@ -46,12 +49,10 @@ if(SC_occupyVehicle) then if(SC_occupyPlaces) then { uiSleep 15; // delay the start - fnc_occupationMonitor = compile preprocessFileLineNumbers "\x\addons\a3_exile_occupation\scripts\occupation.sqf"; + fnc_occupationMonitor = compile preprocessFileLineNumbers "\x\addons\a3_exile_occupation\scripts\occupationPlaces.sqf"; [SC_refreshTime, fnc_occupationMonitor, [], true] call ExileServer_system_thread_addTask; }; - - if(SC_occupyMilitary) then { uiSleep 15; // delay the start @@ -59,7 +60,5 @@ if(SC_occupyMilitary) then [SC_refreshTime, fnc_occupationMilitaryMonitor, [], true] call ExileServer_system_thread_addTask; }; - - - -diag_log format ["[OCCUPATION]:: threads added at %1",time]; \ No newline at end of file +_logDetail = format ["[OCCUPATION]:: threads added at %1",time]; +[_logDetail] call SC_fnc_log; \ No newline at end of file