Advertisement
Guest User

Untitled

a guest
Jan 19th, 2019
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.72 KB | None | 0 0
  1. /*//
  2. */// File : fn_hostileInit.sqf
  3. /*// Version : 1.4
  4. */// Author : Dmitry Yuri
  5. /*// Description : Finds all triggers that are defined as hostile spawn points and sets up the spawning loop.
  6. */// Usage :
  7. /*//
  8. *///
  9.  
  10. /*
  11. _targets <array> <groups> list of groups that can be targeted by spawned squads
  12. _locations <array> <sting> prefix for spawn locations, prefix for spawn locations near objects with building positions
  13. _classes <array> <string> list of unit classnames // Or array of arrays of strings. array of strings is chosen at random and group is spawned in the order of the array. _size flag is ignored in this mode.
  14. _size <array> <int> number of units + random number to spawn
  15. _side <side> the side the units will be spawned as. this will override the side of the group, You could have a blufor group spawn as side EAST (redfor)
  16. _skill <float> number between 0 and 1, This will be the skill of the spawned units.
  17. _maxNumber <int> maximum number of units on the map. Includes players. If this number is reached, no more units will spawn
  18. _condition <code> the condition that is evaluated before any hostile groups are spawned. If the condition is false the units will not spawn. If the condition becomes true again the spawning will then continue.
  19. _delay <float> the time in seconds that we will wait before spawning another group
  20. _minDist <float> If any human player is found within this radius around the spawn area then the units will not spawn. // Can be overRidden on a case by case basis by executing the following code on the trigger in question. - myTrigger setVariable ["zeu_hostile_minDist",300];
  21. _maxDist <float> If there are no targets found within this radius around the spawn area we will not spawn the units. - myTrigger setVariable ["zeu_hostile_maxDist",1600];
  22. _exitCondition <code> code that if true will exit the loop and stop the spawning of any more units.
  23. _spawnCode <code> code that will be executed when a new group is spawned. Passed vars are [hostile group,target group]. code is called.
  24. _stalk <any> default: true. If bool units will stalk. If string then units will be sent to the marker with that name. If object units will be sent to the position of that object.
  25. */
  26.  
  27. // We only want the server running this
  28. if !(isServer) exitWith {};
  29.  
  30. // Debug thing
  31. if (isNil "DM_Debug") then {DM_Debug = false;};
  32.  
  33. params [["_targets",[grpNull]],["_locations",["hostile_spawn_","hostile_town_"]],["_classes",["I_C_Soldier_Para_2_F","I_C_Soldier_Para_7_F"]],["_size",[2,2]],["_side",independent],["_skill",0.2],["_maxNumber",150],["_condition",{true}],["_delay",40],["_minDist",300],["_maxDist",1600],["_exitCondition",{false}],["_spawnCode",{true}],["_stalk",true]];
  34.  
  35. private _spawnAreas = [];
  36. private _spawnTowns = [];
  37.  
  38.  
  39. // Radius used when finding building positions around triggers when attempting to spawn units in buildings
  40. private _radius = 60;
  41.  
  42. _locations params ["_sa","_st"];
  43.  
  44. // populate our possible spawn location arrays.
  45. for "_i" from 1 to 1000 do {
  46. _area = format["%1%2", _sa, _i];
  47. if !(isNil _area) then {
  48. _spawnAreas append [(call compile _area)];
  49. };
  50. _town = format["%1%2", _st, _i];
  51. if !(isNil _town) then {
  52. _obj = (call compile _town);
  53. _spawnTowns append [_obj];
  54. _obj setVariable ["zeu_hostile_isTown",true];
  55. };
  56. if ((isNil _area) && (isNil _town)) exitWith {};
  57. };
  58.  
  59. while {true} do {
  60. private _time = 5;
  61. // if the exit condition is true then exit the loop.
  62. if (call _exitCondition) exitWith {if (dm_debug) then {systemChat "_exitCondition called. hostileInit exiting.";};};
  63. // if the condition returns true then continue. Else go round the loop again.
  64. if (call _condition) then {
  65.  
  66. // Do we need to spawn any more enemies?
  67. if ((count allUnits) < _maxNumber) then {
  68. private _location = objNull;
  69. // find our spawn location
  70.  
  71. // refine our list of groups by only selecting ones that have units in them
  72. private _groups = (_targets select {!(isNull _x) && {(count units _x) > 0}});
  73.  
  74. // if we have no target groups then exit and run the loop again.
  75. if !((count _groups) > 0) exitWith {_time = 10;};
  76.  
  77. // only select spawn areas that are valid.
  78. private _enabled_arr = ((_spawnAreas + _spawnTowns) select {_x getVariable ["valid_Hostile_Spawn", true]});
  79.  
  80. // select all the objects that are within a cirtain distance from any squad.
  81. private _withinDist_arr = (_enabled_arr select { _loc = _x; (({((leader _x) distance _loc) < (_loc getVariable ["zeu_hostile_maxDist",_maxDist])} count _groups) > 0)});
  82.  
  83. // if there are no viable locations then exit this scope and go round the loop again.
  84. if (count _withinDist_arr == 0) exitWith {_time = 10; if (dm_debug) then {systemChat "No nearby locations found";};};
  85.  
  86. // Refine that list to only show the areas that have no human players within _minDist
  87. private _valid_arr = (_withinDist_arr select { _loc = _x; (({(_x distance _loc) > (_loc getVariable ["zeu_hostile_minDist",_minDist])} count allPlayers) == (count allPlayers))});
  88.  
  89. // if there are no viable locations then exit this scope and go round the loop again.
  90. if (count _valid_arr == 0) exitWith {_time = 10; if (dm_debug) then {systemChat "No valid locations with no players nearby found";};};
  91.  
  92. // define _location with a randomly selected a valid zone
  93. private _location = selectRandom _valid_arr;
  94.  
  95. // if _location is null then exit this scope and go round the loop again.
  96. if (isNull _location) exitWith {
  97. _time = 10;
  98. if (dm_debug) then {systemChat "_location is undefined";};
  99. };
  100.  
  101. // Find the nearest target group to the location
  102. private _groupDist = _groups apply {(leader _x) distance _location};
  103. private _distMin = selectMin _groupDist;
  104. private _groupIndex = _groupDist find _distMin;
  105. private _target = _groups # _groupIndex;
  106.  
  107. // compile our list of units to spawn depending on our input classes structure
  108. private _units = if ((typeName (_classes # 0)) == "STRING") then {
  109. _size params ["_count","_extra"];
  110. private _out = [];
  111. for "_i" from 1 to (_count + round (random _extra)) do {
  112. private _class = (selectRandom _classes);
  113. _out append [_class];
  114. };
  115. _out;
  116. } else {
  117. selectRandom _classes;
  118. };
  119.  
  120. // if the location is a town then we want to try and spawn these guys in a building, otherwise just spawn them ontop of the location.
  121. private _hostileGroup = (createGroup _side);
  122. if (_location getVariable ["zeu_hostile_isTown",false]) then {
  123. private _positions = [_location,_radius] call zeu_fnc_findBuildingPos;
  124. if ((count _positions) > 0) then {
  125. {
  126. private _pos = (selectRandom _positions);
  127. private _unit = _hostileGroup createUnit [_x, _pos, [], 0, "NONE"];
  128. _unit setPosATL _pos;
  129. } forEach _units;
  130. } else {
  131. private _position = (getPos _location);
  132. {
  133. private _pos = _position;
  134. private _unit = _hostileGroup createUnit [_x, _pos, [], 0, "NONE"];
  135. } forEach _units;
  136. };
  137. } else {
  138. private _position = (getPos _location);
  139. {
  140. private _pos = _position;
  141. private _unit = _hostileGroup createUnit [_x, _pos, [], 0, "NONE"];
  142. } forEach _units;
  143. };
  144.  
  145. // Make the AI a bit more aggressive.
  146. {
  147. private _unit = _x;
  148. _unit disableAI "COVER";
  149. //_unit disableAI "AIMINGERROR";
  150. _unit disableAI "FSM";
  151. _unit disableAI "AUTOCOMBAT";
  152.  
  153. _unit setSkill _skill;
  154. {
  155. _unit setSkill _x;
  156. } forEach [["aimingAccuracy", 0.37],["aimingShake", 0.4],["aimingSpeed", 0.6],["spotDistance", 0.6],["spotTime", 0.7],["courage", 0.9],["reloadSpeed", _skill],["commanding", 0.9]];
  157. } forEach (units _hostileGroup);
  158.  
  159. // Make the hostile group stalk one of the target groups
  160. switch (typeName _stalk) do {
  161. case "BOOL" : { [_hostileGroup, _target, 25, 10, {false}, 1] spawn bis_fnc_stalk; };
  162. case "OBJECT" : { _hostileGroup move (getPos _stalk); };
  163. case "STRING" : { _hostileGroup move (getMarkerPos _stalk); };
  164. default { [_hostileGroup, _target, 40, 12, {false},station] spawn bis_fnc_stalk;
  165. };
  166.  
  167. // call the _spawnCode
  168. [_hostileGroup,_target] call _spawnCode;
  169.  
  170. // set the sleep time to the full delay ammount;
  171. _time = _delay;
  172. } else {
  173. if (DM_Debug) then {systemChat format["%1 allUnits. Cap of %2 Reached.", count allUnits, _maxNumber];};
  174. };
  175. } else {
  176. if (DM_Debug) then {systemChat "Condition not met."};
  177. };
  178.  
  179. // short delay before we run the loop again
  180. sleep _time;
  181. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement