Merge pull request #9 from Ghostrider-DbD-/v6.44

Build 15
This commit is contained in:
Ghostrider-DbD- 2016-11-17 07:42:17 -05:00 committed by GitHub
commit 74f220a5b3
41 changed files with 1403 additions and 159 deletions

View File

@ -1,12 +1,14 @@
//This script sends Message Information to allplayers
// Last modified 9/3/15 by Ghostrider-DBD-
// Last modified 11/14/15 by Ghostrider-DBD-
blck_Message = _this;
//diag_log format["AIM.sqf ===] _this = %1",_this];
//blck_Message = _this;
params["_msg",["_players",playableUnits]];
diag_log format["AIM.sqf ===] _this = %1 | _msg = %2 | _players = %3",_this,_msg, _players];
blck_Message = _msg;
{
//diag_log format["AIM.sqf ===] (owner _x) = %1", (owner _x)];
diag_log format["AIM.sqf ===] _ = %2, and (owner _x) = %1", (owner _x), _x];
(owner _x) publicVariableClient "blck_Message";
} forEach playableUnits;
} forEach _players;
/*
if (_modType isEqualTo "Exile") then
{

View File

@ -0,0 +1,16 @@
/*
call as [] call blck_fnc_cleanEmptyGroups;
Deletes any empty groups and thereby prevents errors resulting from createGroup returning nullGroup.
By Ghostrider-DbD-
11/16/16
*/
if (blck_debugON) then
{
diag_log format ["_fnc_cleanEmptyGroups:: -- >> group count = %1 ",(count allGroups)];
};
{
//diag_log format["_fnc_cleanEmptyGroups:: - >> type of object _x = %1",typeName _x];
if ((count units _x) isEqualTo 0) then {deleteGroup _x};
}forEach allGroups;

View File

@ -5,7 +5,7 @@
for DBD Clan
By Ghostrider-DBD-
Copyright 2016
Last Modified 8-13-16
Last Modified 11-16-16
*/
private["_findNew","_coords","_blackListCenter","_blackListRadius","_dist","_xpos","_ypos","_newPos","_townPos"];
@ -19,7 +19,7 @@ while {_findNew} do {
//diag_log format["<<--->> _coords = %1",_coords];
{
if ((_x distance _coords) < MinDistanceFromMission) then {
if ((_x distance _coords) < blck_MinDistanceFromMission) then {
_FindNew = true;
};
}forEach DBD_HeliCrashSites;
@ -34,7 +34,7 @@ while {_findNew} do {
//diag_log format["#- findSafePosn -# blck_ActiveMissionCoords isEqualTo %1", blck_ActiveMissionCoords];
{
//diag_log format["#- findSafePosn -# blck_ActiveMissionCoords active mission item is %1", _x];
if ( (_x distance _coords) < MinDistanceFromMission) exitWith
if ( (_x distance _coords) < blck_MinDistanceFromMission) exitWith
{
_FindNew = true;
};
@ -54,7 +54,7 @@ while {_findNew} do {
if !(_ignore) then
{
//diag_log format["-# findSafePosn.sqf -# testing _coords against Old Mission coords is %1", _x select 0];
if ( ((_x select 0) distance _coords) < MinDistanceFromMission) then
if ( ((_x select 0) distance _coords) < blck_MinDistanceFromMission) then
{
_FindNew = true;
//diag_log format["-# findSafePosn.sqf -# Too Close to Old Mission element: %1", _x];
@ -85,12 +85,16 @@ while {_findNew} do {
} forEach blck_townLocations;
// check for nearby plot pole/freq jammer within 800 meters
_mod = call blck_fnc_getModType;
_pole = "";
if (_mod isEqualTo "Epoch") then {_pole = "PlotPole_EPOCH"};
if (_mod isEqualTo "Exile") then {_pole = "Exile_Construction_Flag_Static"};
{
if ((_x distance _coords) < 600) then
{
_FindNew = true;
};
}forEach nearestObjects[player, ["PlotPole_EPOCH"], 800];
}forEach nearestObjects[player, [_pole], 800];
// check to be sure we do not spawn a mission on top of a player.
{

View File

@ -0,0 +1,120 @@
// self explanatory. Checks to see if the position is in either a black listed location or near a player spawn.
// As written this relies on BIS_fnc_findSafePos to ensure that the spawn point is not on water or an excessively steep slope.
//
/*
for DBD Clan
By Ghostrider-DBD-
Copyright 2016
Last Modified 11-16-16
*/
private["_findNew","_coords","_blackListCenter","_blackListRadius","_dist","_xpos","_ypos","_newPos","_townPos"];
_findNew = true;
while {_findNew} do {
_findNew = false;
//[_centerForSearch,_minDistFromCenter,_maxDistanceFromCenter,_minDistanceFromNearestObj,_waterMode,_maxTerainGradient,_shoreMode] call BIS_fnc_findSafePos
// https://community.bistudio.com/wiki/BIS_fnc_findSafePos
_coords = [blck_mapCenter,0,blck_mapRange,30,0,5,0] call BIS_fnc_findSafePos;
//diag_log format["<<--->> _coords = %1",_coords];
{
if ((_x distance _coords) < blck_MinDistanceFromMission) then {
_FindNew = true;
};
}forEach DBD_HeliCrashSites;
{
if ( ((_x select 0) distance _coords) < (_x select 1)) exitWith
{
_FindNew = true;
};
} forEach blck_locationBlackList;
//diag_log format["#- findSafePosn -# blck_ActiveMissionCoords isEqualTo %1", blck_ActiveMissionCoords];
{
//diag_log format["#- findSafePosn -# blck_ActiveMissionCoords active mission item is %1", _x];
if ( (_x distance _coords) < blck_MinDistanceFromMission) exitWith
{
_FindNew = true;
};
} forEach blck_ActiveMissionCoords;
//diag_log format["#- findSafePosn -# blck_recentMissionCoords isEqualTo %1", blck_recentMissionCoords];
{
private["_oldPos","_ignore"];
_ignore = false;
//diag_log format["-# findSafePosn.sqf -# Old Mission element is %1", _x];
if (diag_tickTime > ((_x select 1) + 1200)) then // if the prior mission was completed more than 20 min ago then delete it from the list and ignore the check for this location.
{
_ignore = true;
blck_recentMissionCoords= blck_recentMissionCoords - _x;
//diag_log format["-# findSafePosn.sqf -# Removing Old Mission element: %1", _x];
};
if !(_ignore) then
{
//diag_log format["-# findSafePosn.sqf -# testing _coords against Old Mission coords is %1", _x select 0];
if ( ((_x select 0) distance _coords) < blck_MinDistanceFromMission) then
{
_FindNew = true;
//diag_log format["-# findSafePosn.sqf -# Too Close to Old Mission element: %1", _x];
};
};
} forEach blck_recentMissionCoords;
// test for water nearby
private ["_i"];
_dist = 100;
for [{_i=0}, {_i<360}, {_i=_i+20}] do
{
_xpos = (_coords select 0) + sin (_i) * _dist;
_ypos = (_coords select 1) + cos (_i) * _dist;
_newPos = [_xpos,_ypos,0];
if (surfaceIsWater _newPos) then
{
_FindNew = true;
_i = 361;
};
};
// check that missions spawn at least 1 kkm from towns
{
_townPos = [((locationPosition _x) select 0), ((locationPosition _x) select 1), 0];
if (_townPos distance _coords < 200) exitWith {
_FindNew = true;
};
} forEach blck_townLocations;
// check for nearby plot pole/freq jammer within 800 meters
if (call blck_getModType isEqualTo "Epoch") then {_pole = "PlotPole_EPOCH"};
if (call blck_getModType isEqualTo "Exile") then {_pole = "Exile_Construction_Flag_Static"};
{
if ((_x distance _coords) < 600) then
{
_FindNew = true;
};
}forEach nearestObjects[player, [_pole], 800];
// check to be sure we do not spawn a mission on top of a player.
{
if (isPlayer _x && (_x distance _coords) < 600) then
{
_FindNew = true;
};
}forEach playableUnits;
if (toLower(worldName) isEqualTo "taviana") then
{
_tavTest = createVehicle ["SmokeShell",_coords,[], 0, "CAN_COLLIDE"];
_tavHeight = (getPosASL _tavTest) select 2;
deleteVehicle _tavTest;
if (_tavHeight > 100) then {_FindNew = true;};
};
};
if ((count _coords) > 2) then
{
private["_temp"];
_temp = [_coords select 0, _coords select 1];
_coords = _temp;
};
_coords;

View File

@ -9,7 +9,7 @@ private["_blck_WorldName"];
_blck_WorldName = toLower format ["%1", worldName];
_blck_worldSize = worldSize;
private["_modType"];
_modType = [] call blck_getModType;
_modType = [] call blck_fnc_getModType;
diag_log format["[blckeagls] Loading Map-specific settings with worldName = %1 and modType = %2",_blck_WorldName,_modType];

View File

@ -0,0 +1,85 @@
/*
Determine the map name, set the map center and size, and return the map name.
Trader coordinates were pulled from the config.cfg
Inspired by the Vampire and DZMS
Last Modified 9/3/16
*/
private["_blck_WorldName"];
_blck_WorldName = toLower format ["%1", worldName];
_blck_worldSize = worldSize;
private["_modType"];
_modType = [] call blck_getModType;
diag_log format["[blckeagls] Loading Map-specific settings with worldName = %1 and modType = %2",_blck_WorldName,_modType];
if (_modType isEqualTo "Epoch") then
{
switch (_blck_WorldName) do {// These may need some adjustment - including a test for shore or water should help as well to avoid missions spawning on water.
case "altis":{
diag_log "[blckeagls] Altis-specific settings for Epoch loaded";
blck_mapCenter = [6322,7801,0];
blck_mapRange = 21000;
};
case "stratis":{
diag_log "[blckeagls] Stratis-specific settings loaded";
blck_mapCenter = [6322,7801,0];
blck_mapRange = 4500;
}; // Add Central, East and West respawns/traders
case "chernarus":{
diag_log "[blckeagls] Chernarus-specific settings loaded";
blck_mapCenter = [7100, 7750, 0]; //centerPosition = {7100, 7750, 300};
blck_mapRange = 5300;
};
case "chernarus_summer":{blck_mapCenter = [7100, 7750, 0]; blck_mapRange = 6000;};
case "bornholm":{
//diag_log "Bornholm-specific settings loaded";
blck_mapCenter = [11240, 11292, 0];
blck_mapRange = 14400;
};
case "esseker":{
diag_log "Esseker-specific settings loaded";
blck_mapCenter = [6144, 6144, 0]; //centerPosition = {7100, 7750, 300};
blck_mapRange = 5300;
};
case "taviana":{blck_mapCenter = [10370, 11510, 0];blck_mapRange = 14400;};
case "namalsk":{blck_mapCenter = [4352, 7348, 0];blck_mapRange = 10000;};
case "napf": {blck_mapCenter = [10240,10240,0]; blck_mapRange = 14000}; // {_centerPos = [10240, 10240, 0];_isMountainous = true;_maxHeight = 50;};
case "australia": {blck_mapCenter = [20480,20480, 150];blck_mapRange = 40960;};
case "panthera2":{blck_mapCenter = [4400, 4400, 0];blck_mapRange = 4400;};
case "isladuala":{blck_mapCenter = [4400, 4400, 0];blck_mapRange = 4400;};
case "sauerland":{blck_mapCenter = [12800, 12800, 0];blck_mapRange = 12800;};
case "trinity":{blck_mapCenter = [6400, 6400, 0];blck_mapRange = 6400;};
case "utes":{blck_mapCenter = [3500, 3500, 0];blck_mapRange = 3500;};
case "zargabad":{blck_mapCenter = [4096, 4096, 0];blck_mapRange = 4096;};
case "fallujah":{blck_mapCenter = [3500, 3500, 0];blck_mapRange = 3500;};
case "tavi":{blck_mapCenter = [10370, 11510, 0];blck_mapRange = 14090;};
case "lingor":{blck_mapCenter = [4400, 4400, 0];blck_mapRange = 4400;};
case "takistan":{blck_mapCenter = [5500, 6500, 0];blck_mapRange = 5000;};
default {_blck_WorldName = "default";blck_mapCenter = [6322,7801,0]; blck_mapRange = 12000};
};
};
if (_modType isEqualTo "Exile") then
{
switch (_blck_WorldName) do {
// These may need some adjustment - including a test for shore or water should help as well to avoid missions spawning on water.
case "altis":{diag_log "Altis-specific settings loaded";blck_mapCenter = [6322,7801,0];blck_mapRange = 21000;};
case "taviana":{blck_mapCenter = [10370, 11510, 0];blck_mapRange = 14400;};
case "namalsk":{blck_mapCenter = [4352, 7348, 0];blck_mapRange = 10000;};
case "napf": {blck_mapCenter = [10240,10240,0]; blck_mapRange = 14000}; // {_centerPos = [10240, 10240, 0];_isMountainous = true;_maxHeight = 50;};
case "tanoa": {blck_mapCenter = [ (_blck_worldSize/2),(_blck_worldSize/2),0];blck_mapRange = _blck_worldSize;};
case "panthera2":{blck_mapCenter = [4400, 4400, 0];blck_mapRange = 4400;};
case "isladuala":{blck_mapCenter = [4400, 4400, 0];blck_mapRange = 4400;};
case "sauerland":{blck_mapCenter = [12800, 12800, 0];blck_mapRange = 12800;};
case "trinity":{blck_mapCenter = [6400, 6400, 0];blck_mapRange = 6400;};
case "utes":{blck_mapCenter = [3500, 3500, 0];blck_mapRange = 3500;};
case "zargabad":{blck_mapCenter = [4096, 4096, 0];blck_mapRange = 4096;};
case "fallujah":{blck_mapCenter = [3500, 3500, 0];blck_mapRange = 3500;};
case "tavi":{blck_mapCenter = [10370, 11510, 0];blck_mapRange = 14090;};
case "lingor":{blck_mapCenter = [4400, 4400, 0];blck_mapRange = 4400;};
case "takistan":{blck_mapCenter = [5500, 6500, 0];blck_mapRange = 5000;};
default {_blck_WorldName = "default";blck_mapCenter = [6322,7801,0]; blck_mapRange = 12000;};
};
};
blck_worldSet = true;

View File

@ -1,33 +1,48 @@
/*
Call as : [] call blck_fnc_mainThread;
Run a loop that checks data arrays regarding:
- whether it is time to delete the mission objects at a specific location
- whether it is time to delete live AI associated with a specific mission
By Ghostrider-DbD-
Last modified 10-22-16
Last modified 11-16-16
*/
private _index = 0;
_timeAccelUpdated = diag_tickTime;
_timer1min = diag_tickTime;
_timer5min = diag_tickTime;
while {true} do
{
//diag_log format["_fnc_mainTread::-->> pass %1",_index];
//_index = _index + 1;
uiSleep blck_mainThreadUpdateInterval;
if ((diag_tickTime - _timer1min) > 60) then
{
if (diag_tickTime > (_x select 1) ) then {
//diag_log format["_fnc_mainTread:: cleaning up AI group %1",_x];
[_x select 0] call blck_fnc_cleanupAliveAI;
};
}forEach blck_liveMissionAI;
{
//diag_log format["mainThread::-->> missionObjects _x = %1",_x];
if (diag_tickTime > (_x select 1) ) then {
//diag_log format["_fnc_mainTread:: cleaning up mission objects %1",_x];
[_x select 0] call blck_fnc_cleanupObjects;
};
}forEach blck_oldMissionObjects;
[] call GMS_fnc_cleanupDeadAI;
[] call blck_fnc_timeAcceleration;
if (blck_useHC) then {[] call blck_fnc_monitorHC;};
{
if (diag_tickTime > (_x select 1) ) then {
//diag_log format["_fnc_mainTread:: cleaning up AI group %1",_x];
[_x select 0] call blck_fnc_cleanupAliveAI;
};
}forEach blck_liveMissionAI;
{
//diag_log format["mainThread::-->> missionObjects _x = %1",_x];
if (diag_tickTime > (_x select 1) ) then {
//diag_log format["_fnc_mainTread:: cleaning up mission objects %1",_x];
[_x select 0] call blck_fnc_cleanupObjects;
};
}forEach blck_oldMissionObjects;
[] call GMS_fnc_cleanupDeadAI;
if ((diag_tickTime - _timeAccelUpdated) > 300) then
{
[] call blck_fnc_timeAcceleration;
_timeAccelUpdated = diag_tickTime;
};
if (blck_useHC) then {[] call blck_fnc_monitorHC;};
[] call blck_fnc_cleanEmptyGroups;
};
/*
{
if (_x select 6 > 0) then // The mission is not running, check the time left till it is spawned

View File

@ -8,6 +8,6 @@ _traderCites = allMapMarkers;
if (_x in ["center","respawn_east","respawn_west","respawn_north"] && blck_blacklistTraderCities) then
{
blck_locationBlackList pushback [getMarkerPos _x,1000];
if (blck_debugON) then {diag_log format["[blckeagls] _fnc_getTraderCitiesEpoch:: -- >> Added epoch trader city location at %1", (getMarkerPos _x)];};
//if (blck_debugON) then {diag_log format["[blckeagls] _fnc_getTraderCitiesEpoch:: -- >> Added epoch trader city location at %1", (getMarkerPos _x)];};
};
}forEach _traderCites;
}forEach _traderCites;

View File

@ -0,0 +1,72 @@
/*
Spawn and configure a group
for DBD Clan
By Ghostrider-DBD-
Copyright 2016
Last Modified 9-12-16
*/
//Sets Private Variables to they don't interfere when this script is called more than once
private["_numbertospawn","_i","_groupSpawned","_safepos","_x","_weaponList","_useLauncher","_launcherType","_aiSkills"];
params["_pos", ["_numai1",5], ["_numai2",10], ["_skillLevel","red"], "_center", ["_minDist",20], ["_maxDist",35], ["_uniforms",blck_SkinList], ["_headGear",blck_headgear] ];
if (blck_debugON) then
{
diag_log format["[blckeagls] _fnc_spawnGroup called parameters: _numai1 %1, _numbai2 %2, _skillLevel %3, _center %4",_numai1,_numai2,_skillLevel,_center];
};
//Spawns correct number of AI
if (_numai2 > _numai1) then {
_numbertospawn = floor( (random (_numai2 - _numai1) + _numai1 ) );
} else {
_numbertospawn = _numai2;
};
if (blck_debugON) then
{
diag_log format["spawnGroup.sqf: _numbertospawn = %1",_numbertospawn];
};
//Creates a group to make them attack players
_groupSpawned = createGroup blck_AI_Side; // ; Group changed for Exile for which player is RESISTANCE.
_groupSpawned setcombatmode blck_combatMode;
_groupSpawned allowfleeing 0;
_groupSpawned setspeedmode "FULL";
_groupSpawned setFormation blck_groupFormation;
_groupSpawned setVariable ["blck_group",true,true];
//diag_log format["spawnGroup:: group is %1",_groupSpawned];
// Determines whether or not the group has launchers
_useLauncher = blck_useLaunchers;
// define weapons list for the group
switch (_skillLevel) do {
case "blue": {_weaponList = blck_WeaponList_Blue;};
case "red": {_weaponList = blck_WeaponList_Red;};
case "green": {_weaponList = blck_WeaponList_Green;};
case "orange": {_weaponList = blck_WeaponList_Orange;};
default {_weaponList = blck_WeaponList_Blue;};
};
//Spawns the correct number of AI Groups, each with the correct number of units
//Counter variable
_i = 0;
while {_i < _numbertospawn} do {
_i = _i + 1;
if (blck_useLaunchers && _i <= blck_launchersPerGroup) then
{
_launcherType = selectRandom blck_launcherTypes;
} else {
_launcherType = "none";
};
//Finds a safe positon to spawn the AI in the area given
_safepos = [_pos,0,30,2,0,20,0] call BIS_fnc_findSafePos;
//Spawns the AI unit
//diag_log format["spawnGroup:: spawning unit #%1",_i];
// params["_pos","_weaponList","_aiGroup",["_skillLevel","red"],["_Launcher","none"],["_uniforms",blck_SkinList],["_headGear",blck_BanditHeadgear]];
[_safepos,_weaponList,_groupSpawned,_skillLevel,_launcherType,_uniforms,_headGear] call blck_fnc_spawnAI;
};
_groupSpawned selectLeader (units _groupSpawned select 0);
[_pos,_minDist,_maxDist,_groupSpawned] spawn blck_fnc_setupWaypoints;
//diag_log format["fnc_spawnGroup:: Group spawned was %1 with units of %2",_groupSpawned, units _groupSpawned];
_groupSpawned

View File

@ -9,15 +9,20 @@
private["_numbertospawn","_i","_groupSpawned","_safepos","_x","_weaponList","_useLauncher","_launcherType","_aiSkills"];
params["_pos", ["_numai1",5], ["_numai2",10], ["_skillLevel","red"], "_center", ["_minDist",20], ["_maxDist",35], ["_uniforms",blck_SkinList], ["_headGear",blck_headgear] ];
if (blck_debugON) then
{
diag_log format["[blckeagls] _fnc_spawnGroup called parameters: _numai1 %1, _numbai2 %2, _skillLevel %3, _center %4",_numai1,_numai2,_skillLevel,_center];
};
//Spawns correct number of AI
if (_numai2 > _numai1) then {
_numbertospawn = floor( (random (_numai2 - _numai1) + _numai1 ) );
} else {
_numbertospawn = _numai2;
};
//diag_log format["spawnGroup.sqf: _numbertospawn = %1",_numbertospawn];
if (blck_debugON) then
{
diag_log format["spawnGroup.sqf: _numbertospawn = %1",_numbertospawn];
};
//Creates a group to make them attack players
_groupSpawned = createGroup blck_AI_Side; // ; Group changed for Exile for which player is RESISTANCE.
_groupSpawned setcombatmode blck_combatMode;

View File

@ -0,0 +1,43 @@
/*
Depends on blck_fnc_addItemToCrate
call as:
[_item,_crate] call blck_fnc_loadLootFromItemsArray;
where
_crate is a container such as ammo box or vehicle
_loadout is an array containing either 2 or 3 elements. The first array is always an array of items to add. Items can be formated as ["item1","item1"], as [["item1",3],["item2",2]] or as [["item1",2,4],["item2",3,5]].
See GMS_fnc_addItemToCrate for information about the acceptable formates for the items "item1" ... "itemN".
The second and optional third element in the array specify the number of times the script will randomly select an item from the array of items and load it into the crate.
For example:
case 1: [["item1",...,"itemN"],6]; The script will randomly select from the array of item names 6 times and call the loot loader each time.
case 2: [["item1",...,"itemN"],6, 9]; As above except that an item will be selected a minimum of 6 and maximum of 9 times.
by Ghostrider-DbD-
11/14/16
*/
params["_loadout","_crate",["_addAmmo",0]];
if ((_loadout select 0) isEqualTo []) exitWith {};
{
private["_tries","_q","_item"];
_tries = 0;
//diag_log format["_fn_loadLoot:: -- >> now loading for %1",_x];
_q = _x select 1; // this can be a number or array.
if ( (typeName _q) isEqualTo "ARRAY") then // Assume the array contains a min/max number to add
{
if ((count _q) isEqualTo 2) then {_tries = (_q select 0) + round(random(((_q select 1) - (_q select 0))));} else {_tries = 0;};
};
if ((typeName _q) isEqualTo "SCALAR") then
{
_tries = _q;
};
for "_i" from 1 to _tries do
{
_item = selectRandom (_x select 0);
[_item,_crate,_addAmmo] call blck_fnc_addItemToCrate;
};
}forEach _loadout;

View File

@ -0,0 +1,53 @@
/*
[_item,_crate] call blck_addItemToCrate;
where
_crate is a container such as ammo box or vehicle
_item is a string or array.
If _item is a string then add 1 of that item to the container.
If _item is an array with 2 elements ["itemName",3] then assume that the first element is a string and is the name of the item, and the second is the number to add.
if _item is an array with 3 elements ["itemName",2,6] assume that the first element is the item name (string), the second the min # to add and the third the max # to add.
by Ghostrider-DbD-
11/14/16
*/
params["_itemInfo","_crate",["_addAmmo",0]];
private["_isRifle","_isMagazine","_isBackpack"];
_isWeapon = false;
_isMagazine = false;
_isBackpack = false;
_quant = 0;
//diag_log format["_fn_addItemToCrate:: -- >> itemInfor = %1",_itemInfo];
if (typeName _itemInfo isEqualTo "STRING") then {_item = _itemInfo; _quant = 1}; // case where only the item descriptor was provided
if (typeName _itemInfo isEqualTo "ARRAY") then {
if (count _itemInfo isEqualTo 2) then {_item = _itemInfo select 0; _quant = _itemInfo select 1;}; // case where item descriptor and quantity were provided
if (count _itemInfo isEqualto 3) then {
_item = _itemInfo select 0;
_quant = (_itemInfo select 1) + round(random((_itemInfo select 2) - (_itemInfo select 1)));
}; // case where item descriptor, min number and max number were provided.
};
if (((typeName _item) isEqualTo "STRING") && (_item != "")) then
{
if (isClass(configFile >> "CfgWeapons" >> _item)) then {
_crate addWeaponCargoGlobal [_item,_quant];
_isWeapon = true;
_count = 0;
if (typeName _addAmmo isEqualTo "SCALAR") then
{
_count = _addAmmo;
};
if (typeName _addAmmo isEqualto "ARRAY") then
{
_count = (_addAmmo select 0) + (round(random((_addAmmo select 1) - (_addAmmo select 0))));
};
_ammo = getArray (configFile >> "CfgWeapons" >> _item >> "magazines");
for "_i" from 1 to _count do
{
_crate addMagazineCargoGlobal [selectRandom _ammo,1];
};
};
if (_item isKindOf ["Bag_Base", configFile >> "CfgVehicles"]) then {_crate addBackpackCargoGlobal [_item,_quant]; _isBackpack = true;};
if (isClass(configFile >> "CfgMagazines" >> _item)) then {_crate addMagazineCargoGlobal [_item,_quant]; _isMagazine = true;};
if (!_isWeapon && !_isMagazine && _isBackpack && isClass(configFile >> "CfgVehicles" >> _item)) then {_crate addItemCargoGlobal [_item,_quant]};
};

View File

@ -86,7 +86,7 @@ if !(blck_preciseMapMarkers) then
_blck_localMissionMarker set [1,[_coords,75] call blck_fnc_randomPosition];
};
_blck_localMissionMarker set [3,blck_labelMapMarkers select 1]; // Use an arrow labeled with the mission name?
["start",_startMsg,_blck_localMissionMarker select 2] call blck_fnc_messageplayers;
[["start",_startMsg,_blck_localMissionMarker select 2]] call blck_fnc_messageplayers;
[_blck_localMissionMarker] execVM "debug\spawnMarker.sqf";
_fn_timedOut = {
@ -121,19 +121,25 @@ _missionTimedOut = false;
_wait = true;
while {_wait} do
{
if ([_coords] call _fn_playerWithinRange) then
if (blck_debugLevel isEqualTo 3) then
{
_wait = false;
_playerInRange = true;
} else
{
if ((diag_tickTime - _missionStartTime) > blck_MissionTimout) then
} else {
if ([_coords] call _fn_playerWithinRange) then
{
_wait = false;
_missionTimedOut = true;
_playerInRange = true;
} else
{
if ((diag_tickTime - _missionStartTime) > blck_MissionTimout) then
{
_wait = false;
_missionTimedOut = true;
};
};
uiSleep 1;
};
uiSleep 1;
};
//waitUntil{ { (isPlayer _x && _x distance _coords <= blck_TriggerDistance /*&& vehicle _x == _x*/) || ([_missionStartTime] call _fn_timedOut) } count playableunits > 0 };
@ -170,7 +176,7 @@ if (_playerInRange) then
_crates = [_coords,[[selectRandom blck_crateTypes /*"Box_NATO_Wps_F"*/,[0,0,0],_crateLoot,_lootCounts]]] call blck_fnc_spawnMissionCrates;
};
_objects append _crates;
//_objects append _crates;
if (blck_debugON) then
{
@ -406,21 +412,27 @@ if (_playerInRange) then
_locations = [_coords] + _crates;
//diag_log format["missionSpawner:: Waiting for player to satisfy mission end criteria of _endIfPlayerNear %1 with _endIfAIKilled %2",_endIfPlayerNear,_endIfAIKilled];
while {_missionComplete == -1} do
while {_missionComplete isEqualTo -1} do
{
if (_endIfPlayerNear) then {
if ( { (isPlayer _x) && ([_x,_locations,20] call blck_fnc_playerInRange) && (vehicle _x == _x) } count playableunits > 0) then {
_missionComplete = 1;
if (blck_debugLevel isEqualTo 3) then
{
uiSleep 120;
_missionComplete = 1;
} else {
if (_endIfPlayerNear) then {
if ( { (isPlayer _x) && ([_x,_locations,20] call blck_fnc_playerInRange) && (vehicle _x == _x) } count playableunits > 0) then {
_missionComplete = 1;
};
};
};
//diag_log format["missionSpawner:: count alive _blck_AllMissionAI = %1",{alive _x} count _blck_AllMissionAI];
if (_endIfAIKilled) then {
if (({alive _x} count _blck_AllMissionAI) < 1 ) then {
_missionComplete = 1;
//diag_log format["missionSpawner:: _blck_AllMissionAI = %1","testing case _endIfAIKilled"];
//diag_log format["missionSpawner:: count alive _blck_AllMissionAI = %1",{alive _x} count _blck_AllMissionAI];
if (_endIfAIKilled) then {
if (({alive _x} count _blck_AllMissionAI) < 1 ) then {
_missionComplete = 1;
//diag_log format["missionSpawner:: _blck_AllMissionAI = %1","testing case _endIfAIKilled"];
};
};
uiSleep 2;
};
uiSleep 2;
};
if (blck_debugON) then
@ -441,7 +453,7 @@ if (_playerInRange) then
[_mines] spawn blck_fnc_clearMines;
[_objects, blck_cleanupCompositionTimer] call blck_fnc_addObjToQue;
[_blck_AllMissionAI,blck_AliveAICleanUpTime] call blck_fnc_addLiveAItoQue;
["end",_endMsg,_blck_localMissionMarker select 2] call blck_fnc_messageplayers;
[["end",_endMsg,_blck_localMissionMarker select 2]] call blck_fnc_messageplayers;
[_blck_localMissionMarker select 1, _missionType] execVM "debug\missionCompleteMarker.sqf";
[_blck_localMissionMarker select 0] execVM "debug\deleteMarker.sqf";
//[_blck_localMissionMarker select 0,"Completed"] call blck_fnc_updateMissionQue;

View File

@ -26,7 +26,7 @@ _offset = _supplyHeli getPos [10, _dir];
//open parachute and attach to crate
_chute = createVehicle ["I_Parachute_02_F", [100, 100, 200], [], 0, "FLY"];
private["_modType"];
_modType = call blck_getModType;
_modType = call blck_fnc_getModType;
if (_modType isEqualTo "Epoch") then
{
[_chute] call blck_fnc_protectVehicle;

View File

@ -0,0 +1,91 @@
/*
Author: Ghostrider-DbD-
Inspiration: blckeagls / A3EAI / VEMF / IgiLoad / SDROP
License: Attribution-NonCommercial-ShareAlike 4.0 International
call with
[
_supplyHeli, // heli from which they should para
_skillAI, // Skill [blue, red, green, orange]
] call blck_spawnHeliParaCrate
*/
params["_supplyHeli","_lootCounts","_skillAI"];
private ["_chute","_crate"];
_crate = "";
_chute = "";
diag_log "blck_spawnHeliParaCrate:: spawning crate";
private["_dir","_offset"];
_dir = getDir _supplyHeli;
_dir = if (_dir < 180) then {_dir + 210} else {_dir - 210};
_offset = _supplyHeli getPos [10, _dir];
//open parachute and attach to crate
_chute = createVehicle ["I_Parachute_02_F", [100, 100, 200], [], 0, "FLY"];
private["_modType"];
_modType = call blck_getModType;
if (_modType isEqualTo "Epoch") then
{
[_chute] call blck_fnc_protectVehicle;
};
_chute setPos [_offset select 0, _offset select 1, 250 ]; //(_offset select 2) - 10];
diag_log format["blck_spawnHeliParaCrate:: chute spawned yielding object %1 at postion %2", _chute, getPos _chute];
//create the parachute and crate
private["_crateSelected"];
_crateSelected = selectRandom["Box_FIA_Ammo_F","Box_FIA_Support_F","Box_FIA_Wps_F","I_SupplyCrate_F","Box_IND_AmmoVeh_F","Box_NATO_AmmoVeh_F","Box_East_AmmoVeh_F","IG_supplyCrate_F"];
_crate = [getPos _chute, _crateSelected] call blck_fnc_spawnCrate;
//_crate = createVehicle [_crateSelected, position _chute, [], 0, "CAN_COLLIDE"];
_crate setPos [position _supplyHeli select 0, position _supplyHeli select 1, 250]; //(position _supplyHeli select 2) - 10];
_crate attachTo [_chute, [0, 0, -1.3]];
_crate allowdamage false;
_crate enableRopeAttach true; // allow slingloading where possible
diag_log format["heliSpawnCrate:: crate spawned %1 at position %2 and attached to %3",_crate, getPos _crate, attachedTo _crate];
switch (_skillAI) do
{
case "orange": {[_crate, blck_BoxLoot_Orange, _lootCounts] call blck_fnc_fillBoxes;};
case "green": {[_crate, blck_BoxLoot_Green, _lootCounts] call blck_fnc_fillBoxes;};
case "red": {[_crate, blck_BoxLoot_Red, _lootCounts] call blck_fnc_fillBoxes;};
case "blue": {[_crate, blck_BoxLoot_Blue, _lootCounts] call blck_fnc_fillBoxes;};
default {[_crate, blck_BoxLoot_Red, _lootCounts] call blck_fnc_fillBoxes;};
};
diag_log format["heliSpawnCrate:: crate loaded and now at position %1 and attached to %2", getPos _crate, attachedTo _crate];
_fn_monitorCrate = {
params["_crate","_chute"];
uiSleep 30;
private["_crateOnGround"];
_crateOnGround = false;
while {!_crateOnGround} do
{
uiSleep 1;
diag_log format["heliSpawnCrate:: Crate Altitude: %1 Crate Velocity: %2 Crate Position: %3 Crate attachedTo %4", getPos _crate select 2, velocityModelSpace _crate select 2, getPosATL _crate, attachedTo _crate];
if ( (((velocity _crate) select 2) < 0.1) || ((getPosATL _crate select 2) < 0.1) ) then
{
uiSleep 5; // give some time for everything to settle
_crateOnGround = true;
_spawnCrate = false;
//delete the chute for clean-up purposes
detach _crate;
deleteVehicle _chute;
if (surfaceIsWater (getPos _crate)) then
{
deleteVehicle _crate;
} else
{
[_crate] call blck_fnc_signalEnd;
};
};
};
};
[_crate,_chute] spawn _fn_monitorCrate;

View File

@ -76,7 +76,7 @@ for "_i" from 1 to _numAI do
_offset = _supplyHeli getPos [10, _dir];
_chute = createVehicle ["I_Parachute_02_F", [100, 100, 200], [], 0, "FLY"];
private["_modType"];
_modType = call blck_getModType;
_modType = call blck_fnc_getModType;
if (_modType isEqualTo "Epoch") then
{
[_chute] call blck_fnc_protectVehicle;

View File

@ -0,0 +1,148 @@
/*
Author: Ghostrider-DbD-
Inspiration: blckeagls / A3EAI / VEMF / IgiLoad / SDROP
License: Attribution-NonCommercial-ShareAlike 4.0 International
call with
[
_pos, // the position which AI should patrol
_supplyHeli, // heli from which they should para
_numAI, // Number to spawn
_skillAI, // Skill [blue, red, green, orange]
_weapons, // array of weapons to select from
_uniforms, // array of uniform choices
_headgear // array of uniform choices
] call blck_spawnHeliParaTroops
*/
params["_pos","_supplyHeli","_numAI","_skillAI","_weapons","_uniforms","_headGear"];
// create a group for our paratroops
private["_paraGroup"];
_paraGroup = createGroup blck_AI_Side; // ; Group changed for Exile for which player is RESISTANCE.
_paraGroup setcombatmode blck_combatMode;
_paraGroup allowfleeing 0;
_paraGroup setspeedmode "FULL";
_paraGroup setFormation blck_groupFormation;
_paraGroup setVariable ["blck_group",true,true];
diag_log format["spawnHeliParatroops:: paratrooper group created; spawning %1 units",_numAI];
//https://forums.bistudio.com/topic/127341-how-to-get-cargo-capacity-and-costweight-of-stuff-into-sqf/
//_veh = TypeOf (_supplyHeli); //for example
//_maxpeople = getNumber (configFile >> "CfgVehicles" >> _veh >> "transportSoldier");
//if ( (_maxpeople - 1) < _numAI) then {_numAI = _maxpeople - 1;}; // calculate the max troops carried by the chopper minus 1 for the pilot who is already on board and adjust the number of AI to spawn as needed.
_launcherType = "none";
_sniperExists = false;
/*
for "_i" from 1 to _numAI do
{
//Spawns the AI unit
diag_log format["spawnGroup:: spawning unit #%1",_i];
_unit = [[getPos _supplyHeli select 0, getPos _supplyHeli select 1,(getPos _supplyHeli select 2) - 10],_weapons,_paraGroup,_skillAI,_launcherType,_uniforms,_headGear] call blck_fnc_spawnAI;
if !(_sniperExists) then
{
if ((random(1) < 0.2)) then
{
_sniperExists = true;
_unit setBehaviour "STEALTH";
};
};
_unit assignAsCargo _supplyHeli;
[_unit] orderGetIn true;
diag_log format["reinforcements:: spawned unit %1, at location %2",_unit,getPos _unit];
uiSleep 0.5;
};
*/
/*
diag_log "reinforcements:: eject paratroops";
{
unassignvehicle _x;
_x action ["EJECT", _supplyHeli];
sleep 0.5;
} foreach units _paraGroup;
*/
private["_dir","_offset"];
_dir = getDir _supplyHeli;
_dir = if (_dir < 180) then {_dir + 150} else {_dir - 150};
for "_i" from 1 to _numAI do
{
_offset = _supplyHeli getPos [10, _dir];
_chute = createVehicle ["I_Parachute_02_F", [100, 100, 200], [], 0, "FLY"];
private["_modType"];
_modType = call blck_getModType;
if (_modType isEqualTo "Epoch") then
{
[_chute] call blck_fnc_protectVehicle;
};
_unit = [[_offset select 0, _offset select 1, 180],_weapons,_paraGroup,_skillAI,_launcherType,_uniforms,_headGear] call blck_fnc_spawnAI;
_unit setDir (getDir _supplyHeli) - 90;
_chute setPos [_offset select 0, _offset select 1, 250]; //(_offset select 2) - 10];
_unit disableCollisionWith _supplyHeli;
_chute disableCollisionWith _supplyHeli;
_unit assignAsDriver _chute;
_unit moveInDriver _chute;
_unit allowDamage true;
uiSleep 1;
//diag_log format["reinforcements:: spawned unit %1, at location %2 and vehicle _unit %1",_unit,getPos _unit, vehicle _unit];
};
_paraGroup selectLeader ((units _paraGroup) select 0);
//diag_log "spawnHeliParatroops:: paratroops created";
_wpRendevous =_paraGroup addWaypoint [_pos, 25];
_wpRendevous setWaypointCombatMode "RED";
_wpRendevous setWaypointType "MOVE";
_wpRendevous setWaypointSpeed "NORMAL";
_wpRendevous setWaypointBehaviour "COMBAT";
_wpRendevous setWaypointCompletionRadius 25;
[_pos, 30, 45, _paraGroup] call blck_fnc_setupWaypoints;
//diag_log "spawnParatroops:: Additional waypoints added to _paraGroup";
_fn_cleanupTroops = {
private["_troopsOnGround"];
params["_group"];
_troopsOnGround = false;
while {!_troopsOnGround} do
{
_troopsOnGround = true;
{
//diag_log format["reinforments:: Tracking Paratroops unit %1 position %4 altitue %2 velocity %3 attachedTo %4",_x, (getPos _x select 2), (velocity _x select 2), getPosATL _x, attachedTo _x];
if ( (getPosATL _x select 2) < 0.1) then {
if (surfaceIsWater (position _x)) then {
diag_log format["spawnParatroops:: unit %1 at %2 deleted",_x, getPos _x];
private["_unit"];
_unit = _x;
{
_unit removeAllEventHandlers _x;
}forEach ["Killed","Fired","HandleDamage","HandleHeal","FiredNear"]
};
}
else
{_troopsOnGround = false;};
}forEach units _group;
uiSleep 1;
};
};
[_paraGroup] spawn _fn_cleanupTroops;
diag_log "spawnParatroops:: All Units on the Ground";
// Return the group spawned for book keeping purposes
diag_log format["spawnParatroops:: typeName _paraGroup = %1", (typeName _paraGroup)];
_paraGroup;

View File

@ -42,7 +42,7 @@ clearItemCargoGlobal _patrolHeli;
clearBackpackCargoGlobal _patrolHeli;
private["_modType"];
_modType = call blck_getModType;
_modType = call blck_fnc_getModType;
if (_modType isEqualTo "Epoch") then
{
[_patrolHeli,blck_ModType] call blck_fnc_protectVehicle;
@ -83,7 +83,7 @@ _wpDestination setWaypointCompletionRadius 60;
//Announce reinforcements are inbound to nearby players
private["_message"];
_message = "A Helicopter Gunship was Spotted Near You!";
["reinforcements",_message,_pos] call blck_fnc_messageplayers;
[["reinforcements",_message,_pos]] call blck_fnc_messageplayers;
diag_log "HeliPatrol:: helispawned and inbound, message sent";

View File

@ -0,0 +1,213 @@
/*
Author: Ghostrider-DbD-
Inspiration: blckeagls / A3EAI / VEMF / IgiLoad / SDROP / WAI for Arma 3 Epoch
License: Attribution-NonCommercial-ShareAlike 4.0 International
call with
[
_pos,
_skillAI,
_timeout
] call blck_spawnReinforcements
*/
params["_pos","_skillAI","_weapons"];
diag_log format["HeliPatrol:: Called with parameters _pos %1 _skillAI %2 _weapons %3",_pos,_skillAI,_weapons];
private["_chopperType","_chopperTypeArmed","_spawnPos","_spawnVector","_spawnDistance"];
_chopperType = selectRandom ["B_Heli_Light_01_armed_F","O_Heli_Light_02_F","O_Heli_Light_02_v2_F","B_Heli_Transport_03_F"];
diag_log format["HeliPatrol:: _chopperType seleted = %1 ",_chopperType];
_spawnVector = round(random(360));
_spawnDistance = 200 + floor(random(1500));
_spawnPos = _pos getPos [_spawnDistance,_spawnVector];
diag_log format["HeliPatrol:: vector was %1 with distance %2 yielding a spawn position of %3 at distance from _pos of %4",_spawnVector,_spawnDistance,_spawnPos, (_pos distance2d _spawnPos)];
private["_patrolHeli"];
//create helicopter and spawn it
_patrolHeli = createVehicle [_chopperType, _spawnPos, [], 90, "FLY"];
_patrolHeli setDir (_spawnVector -180);
_patrolHeli setFuel 1;
_patrolHeli engineOn true;
_patrolHeli flyInHeight 150;
_patrolHeli setVehicleLock "LOCKED";
_patrolHeli addEventHandler ["GetOut",{(_this select 0) setFuel 0;(_this select 0) setDamage 1;}];
clearWeaponCargoGlobal _patrolHeli;
clearMagazineCargoGlobal _patrolHeli;
clearItemCargoGlobal _patrolHeli;
clearBackpackCargoGlobal _patrolHeli;
private["_modType"];
_modType = call blck_getModType;
if (_modType isEqualTo "Epoch") then
{
[_patrolHeli,blck_ModType] call blck_fnc_protectVehicle;
};
private["_grpPilot","_unitPilot"];
// add pilot to helicopter //add pilot (single group) to supply helicopter
_grpPilot = createGroup blck_AI_Side;
_grpPilot setBehaviour "CARELESS";
_grpPilot setCombatMode "RED";
_grpPilot setSpeedMode "FULL";
_grpPilot allowFleeing 0;
_unitPilot = _grpPilot createUnit ["I_helipilot_F", getPos _patrolHeli, [], 0, "FORM"];
_unitPilot setSkill 1;
_unitPilot assignAsDriver _patrolHeli;
_unitPilot moveInDriver _patrolHeli;
_gunner = [[100, 100, 300],blck_WeaponList_Blue,_grpPilot,_skillAI] call blck_fnc_spawnAI;
_gunner assignAsCargo _patrolHeli;
_gunner moveInCargo [_patrolHeli,2];
_gunner enablePersonTurret [2, true];
_gunner2 = [[100, 100, 300],blck_WeaponList_Blue,_grpPilot,_skillAI] call blck_fnc_spawnAI;
_gunner2 assignAsCargo _patrolHeli;
_gunner2 moveInCargo [_patrolHeli,4];
_gunner2 enablePersonTurret [4, true];
_grpPilot selectLeader _unitPilot;
//set waypoint for helicopter
private["_wpDestination"];
_wpDestination =_grpPilot addWaypoint [_pos, 0];
_wpDestination setWaypointType "MOVE";
_wpDestination setWaypointSpeed "FULL";
_wpDestination setWaypointBehaviour "CARELESS";
_wpDestination setWaypointCompletionRadius 60;
//Announce reinforcements are inbound to nearby players
private["_message"];
_message = "A Helicopter Gunship was Spotted Near You!";
[["reinforcements",_message,_pos]] call blck_fnc_messageplayers;
diag_log "HeliPatrol:: helispawned and inbound, message sent";
//Waits until heli gets near the position to drop crate, or if waypoint timeout has been triggered
_destinationDone = false;
_startTime = diag_tickTime;
_timoutTime = 600;
while {true} do {
if ( (( (getPos _patrolHeli) distance2D _pos) < 100) || ((diag_tickTime - _startTime) > _timoutTime) ) exitWith { };
uiSleep 2;
//diag_log format["HeliPatrol:: heli %1 is %2 from mission center",_patrolHeli,_pos distance (getPos _patrolHeli)];
};
if ( (diag_tickTime - _startTime) > _timoutTime) exitWith
{
// HeliPatrol took too long so lets delete them.
deleteVehicle _patrolHeli;
deleteVehicle _unitPilot;
deleteGroup _grpPilot;
diag_log "[blckeagls] HeliPatrol failed to reach the mission site: heli and crew deleted";
};
diag_log "HeliPatrol:: heli on station";
for "_i" from 1 to 5 do
{
private["_dir","_wpPos","_wpPatrol"];
_dir = floor(random(360));
_wpPos = _pos getPos [50,_dir];
_wpPatrol =_grpPilot addWaypoint [_pos, 100];
_wpPatrol setWaypointType "LOITER";
_wpPatrol setWaypointSpeed "NORMAL";
_patrolHeli limitSpeed 45;
_wpPatrol setWaypointBehaviour "COMBAT";
_wpPatrol setWaypointLoiterType "CIRCLE";
_wpPatrol setWaypointTimeout [60, 90, 120];
//_wpPatrol setWaypointCompletionRadius 100;
_wpPatrol setWaypointName "Loiter";
/*
_wpPatrol setWaypointType "MOVE":
_wpPatrol setWaypointCompletionRadius 50;
_wpPatrol setWaypointStatements
["true",
"
(Vehicle this) flyinheight 50;
(Vehicle this) limitSpeed 45;
if(true) then {diag_log('WAI: Heli height ' + str((position Vehicle this) select 2) + '/ Heli speed ' + str(speed this)); };
"];
diag_log format["HeliPatrol:: Waypoint #1 with identity %2 added", _i, _wpPatrol]; ;
_wpPatrol setWaypointTimeout [10,15,20];
};
/*
if (_spawnPatrol) then
{
diag_log "HeliPatrol:: heli will patrol the area, setting up waypoints";
private["_wpPatrol"];
_wpPatrol setWaypointType "LOITER";
_wpPatrol setWaypointSpeed "NORMAL";
_wpPatrol setWaypointBehaviour "COMBAT";
_wpPatrol setWaypointLoiterType "CIRCLE";
_wpPatrol setWaypointTimeout [60, 90, 120];
_wpPatrol setWaypointCompletionRadius 100;
_wpPatrol setWaypointName "Loiter";
while { (waypointTimeoutCurrent _grpPilot) > 0} do
{
uiSleep 1;
diag_log format["HeliPatrol:: patrol waypoint time at %1", waypointTimeoutCurrent _grpPilot];
};
}
else
{
diag_log "HeliPatrol:: Heli will not patrol, no patrol waypoints were added";
};
*/
diag_log "HeliPatrol:: send heli back to spawn";
// Send the heli back to base
private["_wpHome"];
_wpHome =_grpPilot addWaypoint [_spawnPos, 200];
_wpHome setWaypointType "MOVE";
_wpHome setWaypointSpeed "FULL";
_wpHome setWaypointBehaviour "CASUAL";
_wpHome setWaypointCompletionRadius 200;
_wpHome setWaypointName "GoHome";
_wpHome setWaypointStatements ["true", "{deleteVehicle _x} forEach units group this;deleteVehicle (vehicle this);diag_log ""helicopter and crew deleted"""];
diag_log "HeliPatrol:: sending Heli Home";
// End of sending heli home
////////////////////////
_fn_cleanupHeli = {
params["_patrolHeli","_homePos","_grpPilot"];
// run some tests to be sure everything went OK
_heliHome = false;
_startTime = diag_tickTime;
while { !(_heliHome) } do
{
_heliHome = (_patrolHeli distance _homePos) < 300;
if ( !_heliHome && ((diag_tickTime - _startTime) > 300) ) then
{
_heliHome = true;
deleteVehicle _patrolHeli;
{
deleteVehicle _x;
}forEach units _grpPilot;
deleteGroup _grpPilot;
};
uiSleep 2;
};
};
[_patrolHeli,_spawnPos,_grpPilot] spawn _fn_cleanupHeli;
diag_log "HeliPatrol:: script done";
// Return the group used for AI reinforcements for book keeping purposes in the Mission Spawner.
diag_log format["HeliPatrol:: typeName _grpToops = %1", typeName _grpToops];
_grpToops;

View File

@ -78,7 +78,7 @@ _wpDestination setWaypointCompletionRadius 60;
//Announce reinforcements are inbound to nearby players
private["_message"];
_message = "A Helicopter Carrying Reinforcements was Spotted Near You!";
["reinforcements",_message,_pos] call blck_fnc_messageplayers;
[["reinforcements",_message,_pos]] call blck_fnc_messageplayers;
diag_log "reinforcements:: helispawned and inbound, message sent";

View File

@ -31,7 +31,7 @@ params["_aiList"];
deleteVehicle _x;
}forEach nearestObjects [getPos _ai,["WeaponHolderSimulated","GroundWeapoonHolder"],3];
_group = group _ai;
//_group = group _ai;
[_ai] joinSilent grpNull;
if (count units group _ai < 1) then

View File

@ -40,7 +40,7 @@ if (blck_useKilledAIName) then
};
_message =_message + _killstreakMsg;
//diag_log format["[blck] unit killed message is %1",_message,""];
["aikilled",_message,"victory"] call blck_fnc_messageplayers;
[["aikilled",_message,"victory"]] call blck_fnc_messageplayers;
{
_unit removeAllEventHandlers _x;
}forEach ["Killed","Fired","HandleDamage","HandleHeal","FiredNear"]

View File

@ -9,7 +9,7 @@ params["_unit","_killer"];
_launcher = _unit getVariable ["Launcher",""];
_legal = true;
fn_targetVehicle = { // force AI to fire on the vehicle with launchers if equiped
fn_targetVehicle = { // force AI to fire on the vehicle with launchers if equiped
params["_vk","_unit"];
{
if (((position _x) distance (position _unit)) <= 350) then
@ -20,7 +20,7 @@ _legal = true;
if (_launcher != "") then
{
_x selectWeapon (secondaryWeapon _unit);
x fireAtTarget [_vk,_launcher];
_x fireAtTarget [_vk,_launcher];
} else {
_x doFire _vk;
};
@ -44,9 +44,9 @@ fn_deleteAIGear = {
fn_msgIED = {
params["_killer"];
blck_Message = ["IED","",0,0];
diag_log format["fn_msgIED:: -- >> msg = %1 and owner _killer = %2",blck_Message, (owner _killer)];
(owner _killer) publicVariableClient "blck_Message";
[["IED","",0,0],[_killer]] call blck_fnc_MessagePlayers;
//(owner _killer) publicVariableClient "blck_Message";
};
if (typeOf _killer != typeOf (vehicle _killer)) then // AI was killed by a vehicle

View File

@ -10,7 +10,7 @@ params["_unit","_killer","_kills"];
//diag_log format["rewardKiller:: _unit = %1 and _killer %2",_unit,_killer];
private["_modType","_reward"];
_modType = call blck_getModType;
_modType = call blck_fnc_getModType;
//diag_log format["[blckeagles] rewardKiller:: - _modType = %1",_modType];

View File

@ -0,0 +1,66 @@
/*
calculate a reward player for AI Kills in crypto.
Code fragment adapted from VEMF
call as [_unit,_killer] call blck_fnc_rewardKiller;
NOTE the dependency on HALV_server_takegive_crypto !!
*/
params["_unit","_killer","_kills"];
//diag_log format["rewardKiller:: _unit = %1 and _killer %2",_unit,_killer];
private["_modType","_reward"];
_modType = call blck_getModType;
//diag_log format["[blckeagles] rewardKiller:: - _modType = %1",_modType];
if (_modType isEqualTo "Epoch") then
{
//diag_log "calculating reward for Epoch";
if ( (vehicle _killer) in blck_forbidenVehicles || (currentWeapon _killer) in blck_forbidenVehicleGuns ) then
{
_reward = 0;
}
else
{
// Give the player money for killing an AI
_maxReward = 50;
_dist = _unit distance _killer;
_reward = 0;
if (_dist < 50) then { _reward = _maxReward - (_maxReward / 1.25); _reward };
if (_dist < 100) then { _reward = _maxReward - (_maxReward / 1.5); _reward };
if (_dist < 800) then { _reward = _maxReward - (_maxReward / 2); _reward };
if (_dist > 800) then { _reward = _maxReward - (_maxReward / 4); _reward };
_reward=+(_kills*2);
//diag_log format["fnd_rewardKiller:: _bonus returned will be %1",_reward];
[_killer,_reward] call blck_fnc_giveTakeCrypto;
};
};
if (_modType isEqualTo "Exile") then
{
private["_distanceBonus","_overallRespectChange","_newKillerScore","_newKillerFrags","_maxReward","_money","_message"];
_distanceBonus = floor((_unit distance _killer)/100);
_overallRespectChange = 50 + _distanceBonus;
_newKillerScore = _killer getVariable ["ExileScore", 0];
_newKillerScore = _newKillerScore + (_overallRespectChange/2);
_killer setVariable ["ExileScore", _newKillerScore];
format["setAccountScore:%1:%2", _newKillerScore,getPlayerUID _killer] call ExileServer_system_database_query_fireAndForget;
_newKillerFrags = _killer getVariable ["ExileKills", 0];
_newKillerFrags = _newKillerFrags + 1;
_killer setVariable ["ExileKills", _newKillerFrags];
format["addAccountKill:%1", getPlayerUID _killer] call ExileServer_system_database_query_fireAndForget;
_money = _killer getVariable ["ExileMoney", 0];
_money = _money + (_overallRespectChange/2) + (_kills * 2);
_killer setVariable ["ExileMoney", _money];
format["setAccountMoney:%1:%2", _money, (getPlayerUID _killer)] call ExileServer_system_database_query_fireAndForget;
_message = ["showFragRequest",_overallRespectChange];
//_message remoteExecCall ["ExileClient_system_network_dispatchIncomingMessage", (owner _killer)];
_killer call ExileServer_object_player_sendStatsUpdate;
};
//_reward

View File

@ -22,18 +22,20 @@ params["_pos","_weaponList","_aiGroup",["_skillLevel","red"],["_Launcher","none"
//_uniforms = [_this, 5, blck_SkinList] call BIS_fnc_param; // skins to add to AI
//_headGear = [_this, 6, _shemag] call BIS_fnc_param;// headGear to add to AI
if (isNull _aiGroup) exitWith {diag_log "[blckeagls] ERROR CONDITION:-->> NULL-GROUP Provided to _fnc_spawnUnit"};
_ai1 = ObjNull;
_modType = call blck_getModType;
_modType = call blck_fnc_getModType;
if (_modType isEqualTo "Epoch") then
{
"I_Soldier_EPOCH" createUnit [_pos, _aiGroup, "_ai1 = this", 0.7, "COLONEL"];
/*switch(_skillLevel) do
switch(_skillLevel) do
{
case "blue":{_ai1 setVariable["Crypto",1 + floor(random(blck_maxMoneyBlue)),true];};
case "red":{_ai1 setVariable["Crypto",2 + floor(random(blck_maxMoneyRed)),true];};
case "green":{_ai1 setVariable["Crypto",3 + floor(random(blck_maxMoneyGreen)),true];};
case "orange":{_ai1 setVariable["Crypto",4 + floor(random(blck_maxMoneyOrange)),true];};
}; */
};
};
if (_modType isEqualTo "Exile") then
{

View File

@ -0,0 +1,186 @@
/*
Original Code by blckeagls
Modified by Ghostrider
Logic for adding AI Ammo, GL Shells and Attachments addapted from that by Buttface (A3XAI).
Infinite Ammo fix by Narines.
Code to delete dead AI bodies moved to AIKilled.sqf
Everything having to do with spawning and configuring an AI should happen here
Last Modified 11/12/16
*/
//Defines private variables so they don't interfere with other scripts
private ["_pos","_i","_weap","_ammo","_other","_skin","_aiGroup","_ai1","_magazines","_players","_owner","_ownerOnline","_nearEntities","_skillLevel","_aiSkills","_specialItems",
"_Launcher","_launcherRound","_vest","_index","_WeaponAttachments","_Meats","_Drink","_Food","_aiConsumableItems","_weaponList","_ammoChoices","_attachment","_attachments",
"_headGear","_uniforms","_pistols","_specialItems","_noItems"];
params["_pos","_weaponList","_aiGroup",["_skillLevel","red"],["_Launcher","none"],["_uniforms", blck_SkinList],["_headGear",blck_headgear],["_underwater",false]];
//_pos = _this select 0; // Position at which to spawn AI
//_weaponList = _this select 1; // List of weapons with which to arm the AI
//_aiGroup = _this select 2; // Group to which AI belongs
//_skillLevel = [_this,3,"red"] call BIS_fnc_param; // Assign a skill level in case one was not passed."blue", "red", "green", "orange"
//_Launcher = [_this, 4, "none"] call BIS_fnc_param; // Set launchers to "none" if no setting was passed.
//_uniforms = [_this, 5, blck_SkinList] call BIS_fnc_param; // skins to add to AI
//_headGear = [_this, 6, _shemag] call BIS_fnc_param;// headGear to add to AI
if (isNull _aiGroup) exitWith {diag_log "[blckeagls] ERROR CONDITION:-->> NULL-GROUP Provided to _fnc_spawnUnit"};
_ai1 = ObjNull;
_modType = call blck_getModType;
if (_modType isEqualTo "Epoch") then
{
"I_Soldier_EPOCH" createUnit [_pos, _aiGroup, "_ai1 = this", 0.7, "COLONEL"];
switch(_skillLevel) do
{
case "blue":{_ai1 setVariable["Crypto",1 + floor(random(blck_maxMoneyBlue)),true];};
case "red":{_ai1 setVariable["Crypto",2 + floor(random(blck_maxMoneyRed)),true];};
case "green":{_ai1 setVariable["Crypto",3 + floor(random(blck_maxMoneyGreen)),true];};
case "orange":{_ai1 setVariable["Crypto",4 + floor(random(blck_maxMoneyOrange)),true];};
};
};
if (_modType isEqualTo "Exile") then
{
"i_g_soldier_unarmed_f" createUnit [_pos, _aiGroup, "_ai1 = this", 0.7, "COLONEL"];
switch(_skillLevel) do
{
case "blue":{_ai1 setVariable["ExileMoney",floor(random(blck_maxMoneyBlue)),true];};
case "red":{_ai1 setVariable["ExileMoney",floor(random(blck_maxMoneyRed)),true];};
case "green":{_ai1 setVariable["ExileMoney",floor(random(blck_maxMoneyGreen)),true];};
case "orange":{_ai1 setVariable["ExileMoney",floor(random(blck_maxMoneyOrange)),true];};
};
};
[_ai1] call blck_fnc_removeGear;
_skin = "";
_counter = 1;
while {_skin isEqualTo "" && _counter < 10} do
{
_skin = selectRandom _uniforms; // call BIS_fnc_selectRandom;
//_ai1 forceAddUniform _skin;
_ai1 forceAddUniform _skin;
_skin = uniform _ai1;
//diag_log format["_fnc_spawnUnit::-->> for unit _ai1 % uniform is %2",_ai1, uniform _ai1];
_counter =+1;
};
//Stops the AI from being cleaned up
_ai1 setVariable["DBD_AI",1];
//Sets AI Tactics
_ai1 enableAI "TARGET";
_ai1 enableAI "AUTOTARGET";
_ai1 enableAI "MOVE";
_ai1 enableAI "ANIM";
_ai1 enableAI "FSM";
_ai1 allowDammage true;
_ai1 setBehaviour "COMBAT";
_ai1 setunitpos "AUTO";
if (_modType isEqualTo "Epoch") then
{
// do this so the AI or corpse hangs around on Epoch servers.
_ai1 setVariable ["LAST_CHECK",28800,true];
};
_ai1 addHeadgear (selectRandom _headGear);
// Add a vest to AI for storage
//_vest = selectRandom blck_vests; // call BIS_fnc_selectRandom;
_ai1 addVest selectRandom blck_vests;
if ( random (1) < blck_chanceBackpack) then
{
//_bpck = selectRandom blck_backpack;
_ai1 addBackpack selectRandom blck_backpacks;
};
_weap = selectRandom _weaponList;
_ai1 addWeaponGlobal _weap;
_ammoChoices = getArray (configFile >> "CfgWeapons" >> _weap >> "magazines");
//_muzzles = getArray (configFile >> "CfgWeapons" >> _weap >> "muzzles");
_optics = getArray (configfile >> "CfgWeapons" >> _weap >> "WeaponSlotsInfo" >> "CowsSlot" >> "compatibleItems");
_pointers = getArray (configFile >> "CfgWeapons" >> _weap >> "WeaponSlotsInfo" >> "PointerSlot" >> "compatibleItems");
_muzzles = getArray (configFile >> "CfgWeapons" >> _weap >> "WeaponSlotsInfo" >> "MuzzleSlot" >> "compatibleItems");
_underbarrel = getArray (configFile >> "CfgWeapons" >> _weap >> "WeaponSlotsInfo" >> "UnderBarrelSlot" >> "compatibleItems");
_legalOptics = [];
{
if !(_x in blck_blacklistedOptics) then {_legalOptics pushback _x};
}forEach _optics;
_ammo = selectRandom _ammoChoices;
//diag_log format["[spawnUnit.sqf] _ammo returned as %1",_ammo];
for "_i" from 2 to (floor(random 3)) do {
_ai1 addMagazine _ammo;
};
//if (random 1 < 0.3) then {_unit addPrimaryWeaponItem (selectRandom _muzzles)};
_ai1 addPrimaryWeaponItem (selectRandom _legalOptics);
_ai1 addPrimaryWeaponItem (selectRandom _pointers);
_ai1 addPrimaryWeaponItem (selectRandom _muzzles);
_ai1 addPrimaryWeaponItem (selectRandom _underbarrel);
if ((count(getArray (configFile >> "cfgWeapons" >> _weap >> "muzzles"))) > 1) then {
_ai1 addMagazine "1Rnd_HE_Grenade_shell";
};
_weap = selectRandom blck_Pistols;
//diag_log format["[spawnUnit.sqf] _weap os %1",_weap];
_ai1 addWeaponGlobal _weap;
_ammoChoices = getArray (configFile >> "CfgWeapons" >> _weap >> "magazines");
_ai1 addMagazine selectRandom _ammoChoices;
//add random items to AI. _other = ["ITEM","COUNT"]
for "_i" from 1 to (1+floor(random(3))) do {
_i = _i + 1;
_ai1 addItem (selectRandom blck_ConsumableItems);
};
// Add an First Aid or Grenade 50% of the time
if (round(random 10) <= 5) then
{
//_item = selectRandom blck_specialItems;
//diag_log format["spawnUnit.sqf] -- Item is %1", _item];
_ai1 addItem selectRandom blck_specialItems;
};
if (_Launcher != "none") then
{
private["_bpck"];
_ai1 addWeaponGlobal _Launcher;
for "_i" from 1 to 3 do
{
_ai1 addItemToBackpack (getArray (configFile >> "CfgWeapons" >> _Launcher >> "magazines") select 0); // call BIS_fnc_selectRandom;
};
_ai1 setVariable["Launcher",_launcher];
};
if(sunOrMoon < 0.2 && blck_useNVG)then
{
_ai1 addWeapon selectRandom blck_NVG;
_ai1 setVariable ["hasNVG", true];
}
else
{
_ai1 setVariable ["hasNVG", false];
};
// Infinite ammo
_ai1 addeventhandler ["fired", {(_this select 0) setvehicleammo 1;}];
_ai1 addEventHandler ["killed",{ [(_this select 0), (_this select 1)] execVM blck_EH_AIKilled;}]; // changed to reduce number of concurrent threads, but also works as spawn blck_AIKilled; }];
//_ai addEventHandler ["HandleDamage",{ [(_this select 0), (_this select 1)] execVM blck_EH_AIHandleDamage;}];
switch (_skillLevel) do
{
case "blue": {_index = 0;_aiSkills = blck_SkillsBlue;};
case "red": {_index = 1;_aiSkills = blck_SkillsRed;};
case "green": {_index = 2;_aiSkills = blck_SkillsGreen;};
case "orange": {_index = 3;_aiSkills = blck_SkillsOrange;};
default {_index = 0;_aiSkills = blck_SkillsBlue;};
};
//_alertDist = blck_AIAlertDistance select _index;
//_intelligence = blck_AIIntelligence select _index;
[_ai1,_aiSkills] call blck_fnc_setSkill;
_ai1 setVariable ["alertDist",blck_AIAlertDistance select _index,true];
_ai1 setVariable ["intelligence",blck_AIIntelligence select _index,true];
_ai1 setVariable ["GMS_AI",true,true];
_ai1

View File

@ -4,7 +4,7 @@
params["_Vehicle"];
private["_modType"];
_modType = call blck_getModType;
_modType = call blck_fnc_getModType;
switch (_ModType) do {
case "_modType":
{

View File

@ -0,0 +1,17 @@
// Protect Vehicles from being cleaned up by the server
// Last modified 2/26/16 by Ghostrider-DBD-
params["_Vehicle"];
private["_modType"];
_modType = call blck_getModType;
switch (_ModType) do {
case "_modType":
{
diag_log format["GMS_fnc_protectVehicle:: Tokens set for vehicle %1",_Vehicle];
//_Vehicle call EPOCH_server_vehicleInit;
_Vehicle call EPOCH_server_setVToken;
};
};

View File

@ -12,7 +12,7 @@ params["_vehType","_pos"];
//diag_log format["spawnVehicle.sqf: _this = %1",_this];
_veh = createVehicle[_vehType, _pos, [], 0, "NONE"];
_modType = call blck_getModType;
_modType = call blck_fnc_getModType;
if (_modType isEqualTo "Epoch") then
{
//_veh call EPOCH_server_vehicleInit;

View File

@ -0,0 +1,24 @@
/*
Spawn a vehicle and protect it against cleanup by Epoch
Returns the object (vehicle) created.
By Ghostrider-DBD-
Last modified 10-24-16
*/
private["_veh","_modType"];
params["_vehType","_pos"];
//_vehType = _this select 0; // type of vehicle to be spawned
//_pos = _this select 1; // position at which vehicle is to be spawned
//diag_log format["spawnVehicle.sqf: _this = %1",_this];
_veh = createVehicle[_vehType, _pos, [], 0, "NONE"];
_modType = call blck_getModType;
if (_modType isEqualTo "Epoch") then
{
//_veh call EPOCH_server_vehicleInit;
_veh call EPOCH_server_setVToken;
};
[_veh] call blck_fnc_configureMissionVehicle;
_veh

View File

@ -16,7 +16,7 @@ params["_center","_pos",["_vehType","I_G_Offroad_01_armed_F"],["_minDis",30],["_
//_maxDis = maximum distance from the center of the mission for vehicle waypoints
//_groupForVehiclePatrol = The group with which to man the vehicle
if (isNull _group) exitWith {};
if (isNull _group) exitWith {diag_log "[blckeagls] ERROR CONDITION:-->> NULL-GROUP Provided to _fnc_spawnVehiclePatrol"};
_safepos = [_pos,0,25,0,0,20,0] call BIS_fnc_findSafePos;
_veh = [_vehType,_safepos] call blck_fnc_spawnVehicle;
@ -61,4 +61,4 @@ _wp setWaypointType "CYCLE";
waitUntil { count crew _veh > 0};
blck_missionVehicles pushback _veh;
_veh
_veh

View File

@ -2,7 +2,7 @@
AI Mission for Epoch Mod for Arma 3
By Ghostrider
Functions and global variables used by the mission system.
Last modified 11/12/16
Last modified 11/16/16
*/
blck_functionsCompiled = false;
@ -14,13 +14,15 @@ blck_fnc_findPositionsAlongARadius = compileFinal preprocessFileLineNumbers "\
blck_fnc_giveTakeCrypto = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Functions\GMS_fnc_giveTakeCrypto.sqf";
blck_fnc_monitorHC = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Functions\GMS_fnc_monitorHC.sqf";
blck_fnc_timeAcceleration = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\TimeAccel\GMS_fnc_Time.sqf";
blck_getModType = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Functions\GMS_getModType.sqf"; // Test if Epoch or Exile is loaded
blck_fnc_getModType = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Functions\GMS_getModType.sqf"; // Test if Epoch or Exile is loaded
// Player-related functions
blck_fnc_rewardKiller = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Units\GMS_fnc_rewardKiller.sqf";
blck_fnc_MessagePlayers = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Functions\GMS_fnc_AIM.sqf"; // Send messages to players regarding Missions
// Mission-related functions
blck_fnc_missionTimer = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_missionTimer.sqf";
//blck_fnc_addMissionToQue = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_addMissionToQue.sqf"; //
//blck_fnc_updateMissionQue = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_updateMissionQue.sqf"; //
blck_fnc_addLiveAItoQue = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_addLiveAItoQue.sqf";
@ -30,7 +32,10 @@ blck_fnc_spawnCrate = compileFinal preprocessFileLineNumbers "\q\addons\custom_
blck_fnc_spawnMissionCrates = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_spawnMissionCrates.sqf"; // Spawn loot crates at specific positions relative to the mission center; these will be filled with loot following the parameters in the composition array for the mission
blck_fnc_cleanupObjects = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_cleanUpObjects.sqf";
blck_fnc_spawnCompositionObjects = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_spawnBaseObjects.sqf";
blck_fnc_spawnRandomLandscape = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_spawnRandomLandscape.sqf";
blck_fnc_spawnRandomLandscape = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_spawnRandomLandscape.sqf";
blck_fnc_addItemToCrate = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_addItemToCrate.sqf";
blck_fnc_loadLootItemsFromArray = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc__loadLootItemsFromArray.sqf";
blck_fnc_fillBoxes = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_fillBoxes.sqf"; // Adds items to an object according to passed parameters. See the script for details.
blck_fnc_smokeAtCrates = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_smokeAtCrates.sqf"; // Spawns a wreck and adds smoke to it
blck_fnc_spawnMines = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_spawnMines.sqf"; // Deploys mines at random locations around the mission center
@ -40,8 +45,7 @@ blck_fnc_signalEnd = compileFinal preprocessFileLineNumbers "\q\addons\custom_s
// Group-related functions
blck_fnc_spawnGroup = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Groups\GMS_fnc_spawnGroup.sqf"; // Spawn a single group and populate it with AI units]
blck_fnc_setupWaypoints = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Groups\GMS_fnc_setWaypoints.sqf"; // Set default waypoints for a group
//blck_fnc_spawnGroups = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Groups\GMS_fnc_spawnGroups.sqf"; // Call spawnGroup multiple times using specific parameters for group positioning
//blck_fnc_endCondition = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Groups\GMS_fnc_endCondition.sqf"; //GRMS_fnc_endCondition
blck_fnc_cleanEmptyGroups = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Functions\GMS_fnc_cleanEmptyGroups.sqf"; // GMS_fnc_cleanEmptyGroups
// Functions specific to vehicles, whether wheeled or static
blck_fnc_spawnEmplacedWeapon = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Vehicles\GMS_fnc_spawnEmplaced.sqf"; // Self-evident

View File

@ -0,0 +1,120 @@
/*
AI Mission for Epoch Mod for Arma 3
By Ghostrider
Functions and global variables used by the mission system.
Last modified 11/14/16
*/
blck_functionsCompiled = false;
// General functions
blck_fnc_waitTimer = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Functions\GMS_fnc_waitTimer.sqf";
blck_fnc_FindSafePosn = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Functions\GMS_fnc_findSafePosn.sqf";
blck_fnc_randomPosition = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Functions\GMS_fnc_randomPosn.sqf";// find a randomPosn. see script for details.
blck_fnc_findPositionsAlongARadius = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Functions\GMS_fnc_findPositionsAlongARadius.sqf";
blck_fnc_giveTakeCrypto = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Functions\GMS_fnc_giveTakeCrypto.sqf";
blck_fnc_monitorHC = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Functions\GMS_fnc_monitorHC.sqf";
blck_fnc_timeAcceleration = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\TimeAccel\GMS_fnc_Time.sqf";
blck_getModType = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Functions\GMS_getModType.sqf"; // Test if Epoch or Exile is loaded
// Player-related functions
blck_fnc_rewardKiller = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Units\GMS_fnc_rewardKiller.sqf";
blck_fnc_MessagePlayers = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Functions\GMS_fnc_AIM.sqf"; // Send messages to players regarding Missions
// Mission-related functions
blck_fnc_missionTimer = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_missionTimer.sqf";
//blck_fnc_addMissionToQue = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_addMissionToQue.sqf"; //
//blck_fnc_updateMissionQue = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_updateMissionQue.sqf"; //
blck_fnc_addLiveAItoQue = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_addLiveAItoQue.sqf";
blck_fnc_addObjToQue = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_addObjToQue.sqf"; //
blck_fnc_playerInRange = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_playerInRange.sqf";
blck_fnc_spawnCrate = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_spawnCrate.sqf"; // Simply spawns a crate of a specified type at a specific position.
blck_fnc_spawnMissionCrates = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_spawnMissionCrates.sqf"; // Spawn loot crates at specific positions relative to the mission center; these will be filled with loot following the parameters in the composition array for the mission
blck_fnc_cleanupObjects = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_cleanUpObjects.sqf";
blck_fnc_spawnCompositionObjects = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_spawnBaseObjects.sqf";
blck_fnc_spawnRandomLandscape = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_spawnRandomLandscape.sqf";
blck_fnc_addItemToCrate = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_addItemToCrate.sqf";
blck_fnc_loadLootItemsFromArray = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc__loadLootItemsFromArray.sqf";
blck_fnc_fillBoxes = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_fillBoxes.sqf"; // Adds items to an object according to passed parameters. See the script for details.
blck_fnc_smokeAtCrates = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_smokeAtCrates.sqf"; // Spawns a wreck and adds smoke to it
blck_fnc_spawnMines = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_spawnMines.sqf"; // Deploys mines at random locations around the mission center
blck_fnc_clearMines = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_clearMines.sqf"; // clears mines in an array passed as a parameter
blck_fnc_signalEnd = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Missions\GMS_fnc_signalEnd.sqf"; // deploy smoke grenades at loot crates at the end of the mission.
// Group-related functions
blck_fnc_spawnGroup = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Groups\GMS_fnc_spawnGroup.sqf"; // Spawn a single group and populate it with AI units]
blck_fnc_setupWaypoints = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Groups\GMS_fnc_setWaypoints.sqf"; // Set default waypoints for a group
blck_fnc_cleanEmptyGroups = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Groups\GMS_fnc_cleanEmptyGroups.sqf"; // GMS_fnc_cleanEmptyGroups
// Functions specific to vehicles, whether wheeled or static
blck_fnc_spawnEmplacedWeapon = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Vehicles\GMS_fnc_spawnEmplaced.sqf"; // Self-evident
blck_fnc_spawnVehicle = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Vehicles\GMS_fnc_spawnVehicle.sqf"; // Spawn a temporary vehicle of a specified type at a specific position
blck_fnc_spawnVehiclePatrol = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Vehicles\GMS_fnc_spawnVehiclePatrol.sqf"; // Spawn an AI vehicle control and have it patrol the mission perimeter
//blck_fnc_vehicleMonitor = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Vehicles\GMS_fnc_vehicleMonitor.sqf"; // Process events wherein all AI in a vehicle are killed
//blck_fnc_spawnMissionVehicles = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Vehicles\GMS_fnc_spawnMissionVehicles.sqf"; // Spawn non-AI vehicles at missions; these will be filled with loot following the parameters in the composition array for the mission
blck_fnc_Reinforcements = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Reinforcements\GMS_fnc_reinforcements.sqf";
blck_spawnHeliParaTroops = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Reinforcements\GMS_fnc_heliSpawnParatroops.sqf";
blck_spawnHeliParaCrate = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Reinforcements\GMS_fnc_heliSpawnCrate.sqf";
blck_spawnHeliPatrol = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Reinforcements\GMS_fnc_heliSpawnPatrol.sqf";
blck_fnc_protectVehicle = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Vehicles\GMS_fnc_protectVehicle.sqf";
blck_fnc_configureMissionVehicle = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Vehicles\GMS_fnc_configureMissionVehicle.sqf";
// functions to support Units
blck_fnc_removeGear = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Units\GMS_fnc_removeGear.sqf"; // Strip an AI unit of all gear.
blck_fnc_spawnAI = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Units\GMS_fnc_spawnUnit.sqf"; // spawn individual AI
blck_EH_AIKilled = "\q\addons\custom_server\Compiles\Units\GMS_EH_AIKilled.sqf"; // Event handler to process AI deaths
//blck_EH_AIHandleDamage = "\q\addons\custom_server\Compiles\Units\GMS_EH_AIHandleDamage.sqf"; // GRMS_EH_AIHandleDamage
blck_fnc_processAIKill = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Units\GMS_fnc_processAIKill.sqf";
blck_fnc_removeLaunchers = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Units\GMS_fnc_removeLaunchers.sqf";
blck_fnc_removeNVG = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Units\GMS_fnc_removeNVG.sqf";
blck_fnc_alertNearbyUnits = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Units\GMS_fnc_alertNearbyUnits.sqf";
blck_fnc_processIlleagalAIKills = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Units\GMS_fnc_processIlleagalAIKills.sqf";
GMS_fnc_cleanupDeadAI = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Units\GMS_fnc_cleanupDeadAI.sqf"; // handles deletion of AI bodies and gear when it is time.
blck_fnc_setSkill = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Units\GMS_fnc_setSkill.sqf";
blck_fnc_cleanupAliveAI = compileFinal preprocessFileLineNumbers "\q\addons\custom_server\Compiles\Units\GMS_fnc_cleanupAliveAI.sqf";
// Event handlers
"blck_PVS_aiKilled" addPublicVariableEventHandler {
diag_log format["blck_PVS_aiKilled handler:: unit = %1 and killer = %2 and this = #3",_this select 1 select 0,_this select 1 select 1, _this];
[_this select 1 select 0,_this select 1 select 1] call blck_fnc_processAIKill;
};
"blck_PVS_aiVehicleEmpty" addPublicVariableEventHandler {
private ["_veh"];
_veh = _this select 1;
//diag_log format["blck_PVS_aiVehicleEmpty:: _this = %1 and _veh = %2",_this,0];
if (typeOf _veh in blck_staticWeapons) then // always destroy mounted weapons
{
//diag_log format["vehicleMonitor.sqf: _veh %1 is (in blck_staticWeapons) = true",_veh];
_veh removealleventhandlers "GetIn";
_veh removealleventhandlers "GetOut";
_veh setDamage 1;
} else {
//diag_log format["vehicleMonitor.sqf: _veh %1 is (in blck_staticWeapons) = false",_veh];
if (blck_killEmptyAIVehicles) then
{
//diag_log format["vehicleMonitor.sqf: _veh %1 is about to be killed",_veh];
_veh removealleventhandlers "GetIn";
_veh removealleventhandlers "GetOut";
_veh setVehicleLock "UNLOCKED" ;
uiSleep 1;
_veh setDamage 1.1;
uiSleep 15;
deleteVehicle _veh;
}
else
{
//diag_log format["vehicleMonitor.sqf: make vehicle available to players; stripping eventHandlers from_veh %1",_veh];
_veh removealleventhandlers "GetIn";
_veh removealleventhandlers "GetOut";
_veh setVehicleLock "UNLOCKED" ;
};
};
};
diag_log "[blckeagls] Functions Loaded";
blck_functionsCompiled = true;

View File

@ -7,12 +7,9 @@
*/
//blck_variablesLoaded = false;
blck_debugON = false;
blck_debugLevel = 3;
blck_debugLevel = 0; // Reserved for future use.
blck_minFPS = 10;
//Minimum distance for between missions
MinDistanceFromMission = 1500;
////////////////////////////////////////////////
// Do Not Touch Anything Below This Line
///////////////////////////////////////////////

View File

@ -47,6 +47,9 @@ Last modified 8/1/15
blck_labelMapMarkers = [true,"center"];
blck_preciseMapMarkers = true; // Map markers are/are not centered at the loot crate
//Minimum distance between missions
blck_MinDistanceFromMission = 2000;
// Options to spawn a smoking wreck near the mission. When the first parameter is true, a wreck or junk pile will be spawned.
// It's position can be either "center" or "random". smoking wreck will be spawned at a random location between 15 and 50 m from the mission.
blck_SmokeAtMissions = [false,"random"]; // set to [false,"anything here"] to disable this function altogether.
@ -262,10 +265,7 @@ AI WEAPONS, UNIFORMS, VESTS AND GEAR
"arifle_Katiba_F","arifle_Katiba_C_F","arifle_Katiba_GL_F","arifle_MXC_F","arifle_MX_F","arifle_MX_GL_F","arifle_MXM_F"
];
blck_RifleAsault = [
"arifle_Katiba_F","arifle_Katiba_C_F","arifle_Katiba_GL_F","arifle_MXC_F","arifle_MX_F","arifle_MX_GL_F","arifle_MXM_F","arifle_SDAR_F",
"arifle_TRG21_F","arifle_TRG20_F","arifle_TRG21_GL_F","arifle_Mk20_F","arifle_Mk20C_F","arifle_Mk20_GL_F","arifle_Mk20_plain_F","arifle_Mk20C_plain_F","arifle_Mk20_GL_plain_F"
];
blck_RifleAsault = blck_RifleAsault_556 + blck_RifleAsault_650;
blck_RifleLMG = [
"LMG_Mk200_F","LMG_Zafir_F"
@ -371,9 +371,8 @@ AI WEAPONS, UNIFORMS, VESTS AND GEAR
"H_ShemagOpen_khk",
"H_ShemagOpen_tan",
"H_TurbanO_blk",
,
//Apex
"H_MilCap_tna_F",
"H_MilCap_ghex_F",
"H_Booniehat_tna_F",
@ -436,7 +435,7 @@ AI WEAPONS, UNIFORMS, VESTS AND GEAR
"H_HelmetSpecO_ghex_F",
"H_HelmetLeaderO_ghex_F",
"H_HelmetO_ghex_F",
"H_HelmetCrew_O_ghex_F",
"H_HelmetCrew_O_ghex_F"
];
blck_headgearList = blck_headgear + blck_helmets;
//This defines the skin list, some skins are disabled by default to permit players to have high visibility uniforms distinct from those of the AI.

View File

@ -45,6 +45,9 @@ Last modified 8/1/15
// When set to true,"dot", ext will be to the right of a black dot at the center the mission marker.
blck_labelMapMarkers = [true,"center"];
blck_preciseMapMarkers = true; // Map markers are/are not centered at the loot crate
//Minimum distance between missions
blck_MinDistanceFromMission = 2000;
// Options to spawn a smoking wreck near the mission. When the first parameter is true, a wreck or junk pile will be spawned.
// It's position can be either "center" or "random". smoking wreck will be spawned at a random location between 15 and 50 m from the mission.

View File

@ -42,7 +42,7 @@ if (blck_debugON) then
blck_cleanupCompositionTimer = 10; // Time after mission completion at which items in the composition are deleted.
blck_AliveAICleanUpTime = 10; // Time after mission completion at which any remaining live AI are deleted.
blck_bodyCleanUpTimer = 20;
blck_bodyCleanUpTimer = 180;
blck_SpawnEmplaced_Orange = 4; // Number of static weapons at Orange Missions
blck_SpawnEmplaced_Green = 3; // Number of static weapons at Green Missions
@ -55,13 +55,7 @@ if (blck_debugON) then
blck_SpawnVeh_Red = 2;
//blck_reinforcementsBlue = [0, 0, 0.0, 0]; // Chance of reinforcements, number of reinforcements, Chance of reinforcing heli patrols, chance of dropping supplies for the reinforcements
//blck_AIGrps_Blue = 1;
//blck_AIGrps_Red = 2;
//blck_AIGrps_Green = 3;
//blck_TMin_Major = 5;
//blck_TMin_Major2 = 6;
blck_TMin_Blue = 7;
blck_TMin_Red = 20;
blck_TMin_Green = 23;
@ -71,8 +65,6 @@ if (blck_debugON) then
blck_TMin_Crashes = 5;
//Maximum Spawn time between missions in seconds
//blck_TMax_Major = 10;
//blck_TMax_Major2 = 11;
blck_TMax_Blue = 12;
blck_TMax_Red = 35;
blck_TMax_Green = 38;

View File

@ -1,6 +1,6 @@
//Based on the Random Loot Crates addon by Darth_Rogue & Chisel (tdwhite)
// Re-written by Ghostrider-DBD- to add features and clean up code
// Last updated 11-12-16
// Last updated 11-14-16
// Do not touch anything below this line.
/// ********************************************************************************************************************************************************************************************************************************
@ -59,56 +59,6 @@ _fn_spawnCrate = {
_crate
};
_fn_addItemToCrate = {
params["_itemInfo","_crate"];
private["_isRifle","_isMagazine","_isBackpack"];
_isWeapon = false;
_isMagazine = false;
_isBackpack = false;
_quant = 0;
diag_log format["_fn_addItemToCrate:: -- >> itemInfor = %1",_itemInfo];
if (typeName _itemInfo isEqualTo "STRING") then {_item = _itemInfo; _quant = 1}; // case where only the item descriptor was provided
if (typeName _itemInfo isEqualTo "ARRAY") then {
if (count _itemInfo isEqualTo 2) then {_item = _itemInfo select 0; _quant = _itemInfo select 1;}; // case where item descriptor and quantity were provided
if (count _itemInfo isEqualto 3) then {
_item = _itemInfo select 0;
_quant = (_itemInfo select 1) + round(random((_itemInfo select 2) - (_itemInfo select 1)));
}; // case where item descriptor, min number and max number were provided.
};
if (((typeName _item) isEqualTo "STRING") && (_item != "")) then
{
if (isClass(configFile >> "CfgWeapons" >> _item)) then {_crate addWeaponCargoGlobal [_item,_quant]; _isWeapon = true;};
if (_item isKindOf ["Bag_Base", configFile >> "CfgVehicles"]) then {_crate addBackpackCargoGlobal [_item,_quant]; _isBackpack = true;};
if (isClass(configFile >> "CfgMagazines" >> _item)) then {_crate addMagazineCargoGlobal [_item,_quant]; _isMagazine = true;};
if (!_isWeapon && !_isMagazine && _isBackpack && isClass(configFile >> "CfgVehicles" >> _item)) then {_crate addItemCargoGlobal [_item,_quant]};
};
};
_fn_loadLoot = {
params["_loadout","_crate"];
if ((_loadout select 0) isEqualTo []) exitWith {};
{
private["_tries","_q","_item"];
_tries = 0;
diag_log format["_fn_loadLoot:: -- >> now loading for %1",_x];
_q = _x select 1; // this can be a number or array.
if ( (typeName _q) isEqualTo "ARRAY") then // Assume the array contains a min/max number to add
{
if ((count _q) isEqualTo 2) then {_tries = (_q select 0) + round(random(((_q select 1) - (_q select 0))));} else {_tries = 0;};
};
if ((typeName _q) isEqualTo "SCALAR") then
{
_tries = _q;
};
for "_i" from 1 to _tries do
{
_item = selectRandom (_x select 0);
[_item,_crate] call _fn_addItemToCrate;
};
}forEach _loadout;
};
_fn_setupCrates = {
params["_location","_lootType","_randomPos","_useSmoke"];
private["_crate"];
@ -117,9 +67,10 @@ _fn_setupCrates = {
if (_lootType isEqualTo 0) then {_lootType = round(random(3));};
switch(_lootType) do
{
case 1:{[_box1_loadout,_crate] call _fn_loadLoot;};
case 2:{[_box2_loadout, _crate] call _fn_loadLoot;};
case 3:{[_box3_loadout, _crate] call _fn_loadLoot;};
// format here is [_arrayOfLoot, crateToLoad, magazinesToAddForEachWeaponLoaded]
case 1:{[_box1_loadout,_crate,3] call blck_fnc_loadLootItemsFromArray;};
case 2:{[_box2_loadout, _crate,3] call blck_fnc_loadLootItemsFromArray;};
case 3:{[_box3_loadout, _crate,3] call blck_fnc_loadLootItemsFromArray;};
};
if (_useSmoke) then {[getPos _crate] call _fn_smokeAtCrate;};
if (blck_debugON) then

View File

@ -5,16 +5,20 @@ Contributions by Narines: bug fixes, testing, 'fired' event handler
Ideas or code from that by Vampire and KiloSwiss have been used for certain functions.
11/14/16 Version 6.44 Build 13
Definitions of blacklist locations such as spawns moved from GMS_findWorld.sqf to the blck_configs_(epoch|exile).
Added parameters
blck_blacklistTraderCities=true; // the locations of the Epoch/Exile trader cities will be pulled from the config and added to the location blacklist for the mission system.
blcklistConcreteMixerZones = true; // Locations of the concrete mixers will be pulled from the configs; no missions will be spawned within 1000 m of these locations.
blck_blacklistSpawns = true; // Locations of Exile spawns will be pulled from the config. No missions will spawn within 1000 m of these locations.
Divided rifles and optics into subcategories to better enable assigning weapons to AI difficulties in a sort of class-based way, e.g., 556, 6.5, or LMG are separate classes.
Completed adding EDEN weapons, optics, bipods, optics to AI configurations and mission loot crates.
Added: Completed adding EDEN weapons, optics, bipods, optics to AI configurations and mission loot crates.
Added APEX headgear and uniforms. (Note, you would need to add any of these you wished for players to sell to Epoch\<Map Name>\epoch_config\CfgPricing.hpp on Epoch)
Changed: Definitions of blacklist locations such as spawns moved from GMS_findWorld.sqf to the blck_configs_(epoch|exile).
Changed: Divided rifles and optics into subcategories to better enable assigning weapons to AI difficulties in a sort of class-based way, e.g., 556, 6.5, or LMG are separate classes.
Changed: DLS crate loader (not publically available yet) now uses blck_fnc_loadLootItemsFromArray rather than the prior approach for which specific crate loading functions were called depending on the loadout type (weapons, building supplies, foord etc).
Fixed: You can now loot AI bodies in Epoch.
11/12/16 Version 6.43 Build 12
Added: MapAddons - use this to spawn AI strongholds or other compositions you generate with Eden editor at server startup.
Added: Loot Crate Spawner - Spawn loot crates at prespecified points. This is designed so that you can spawn crates inside buildings or other structures spawned through the map-addons.

View File

@ -1,3 +1,3 @@
private ["_version","_versionDate"];
_blck_version = "6.44 Build 13";
_blck_versionDate = "11-14-16 11:00 AM";
_blck_version = "6.44 Build 15";
_blck_versionDate = "11-15-16 6:00 AM";