Skip to content

Commit

Permalink
populate area function
Browse files Browse the repository at this point in the history
  • Loading branch information
McDiod committed Sep 8, 2017
1 parent 1fcfe95 commit e9caafd
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 1 deletion.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,13 @@ Used to manually initialize module. Has to be executed on clients and server. Ef
Parameter | Explanation
----------|-----------------------------------------------------------
headgear | Array - All classnames of clothes that civilians may wear.

## grad_civs_fnc_populateArea
Manually populates an area with civilians. These civilians count towards the maximum amount, but will get cleaned up when no players are near enough.

### Syntax
`[area] call grad_civs_fnc_populateArea`

Parameter | Explanation
----------|-------------------------------------------------------------------------------------------------------------------------------------------------
area | Array / Object - Area array in format `[a, b, angle, isRectangle]` or array of area arrays or gamelogic synchronzed to one or multiple triggers.
5 changes: 5 additions & 0 deletions cfgFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ class grad_civs {
class common {
file = MODULES_DIRECTORY\grad-civs\functions\common;

class findBuildings {};
class findPositionOfInterest {};
class findRandomPos {};
class findRandomPosArea {};
class populateArea {};
class setBackpacks {};
class setClothes {};
class setDebugMode {};
Expand Down Expand Up @@ -54,6 +57,8 @@ class grad_civs {

class spawnCivilian {};
class cleanup {};
class createSideRoadVehicles {};
class deleteIfDamaged {};
class dressAndBehave {};
class findSpawnPosition {};
class addToVehicle {};
Expand Down
34 changes: 34 additions & 0 deletions functions/common/fn_findBuildings.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "..\..\component.hpp"

params ["_searchPos","_radius"];

//exclusion list for houses
_exclusionList = [
"Land_Pier_F",
"Land_Pier_small_F",
"Land_NavigLight",
"Land_LampHarbour_F",
"Land_runway_edgelight"
];

if (count _searchPos == 0) exitWith {[]};

//HOUSE LIST ===================================================================
_houseList = nearestObjects [_searchPos,["House"],_radius];

//Clean up house list (remove buildings that have no positions)
_cleanUpCounter = 0;
{
_buildingPos = _x buildingPos 0;
if ((str _buildingPos) == "[0,0,0]") then {
_houseList = _houseList - [_x];
_cleanUpCounter = _cleanUpCounter + 1;
} else {
if (typeOf _x in _exclusionList) then {
_houseList = _houseList - [_x];
_cleanUpCounter = _cleanUpCounter + 1;
};
};
}forEach _houseList;

_houseList
18 changes: 18 additions & 0 deletions functions/common/fn_findRandomPosArea.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "..\..\component.hpp"

params ["_area",["_vehicleType","B_Soldier_F"],["_findWaterPos",false],["_findRoadPos",false]];

_pos = [];
for [{private _i=0}, {_i<25}, {_i=_i+1}] do {
_searchPos = _area call BIS_fnc_randomPosTrigger;

if (_findRoadPos) then {
_nearRoads = _searchPos nearRoads 50;
_searchPos = if (count _nearRoads > 0) then {getPos (_nearRoads select 0)} else {[]};
};

_pos = if (_vehicleType != "" && {count _searchPos > 0}) then {_searchPos findEmptyPosition [0,10,_vehicleType]} else {_searchPos};
if (count _pos > 0 && {(surfaceIsWater _pos) isEqualTo _findWaterPos}) exitWith {};
};

_pos
39 changes: 39 additions & 0 deletions functions/common/fn_populateArea.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include "..\..\component.hpp"

if (!isServer) exitWith {};
if (!canSuspend) exitWith {_this spawn grad_civs_fnc_populateArea};

params ["_area",["_amount",20]];

private _areas = if (_area isEqualType objNull) then {synchronizedObjects _area} else {[_area]};
private _maxLoops = _amount * 5;
{
_amountSpawned = 0;
for [{_i=0},{_i<1000},{_i=_i+1}] do {

_spawnPos = [_x] call grad_civs_fnc_findRandomPosArea;
if (count _spawnPos > 0) then {
_civ = [_spawnPos] call grad_civs_fnc_spawnCivilian;
_civ setVariable ["grad_civs_excludeFromCleanup",true];
GRAD_CIVS_ONFOOTUNITS pushBack _civ;
GRAD_CIVS_ONFOOTCOUNT = GRAD_CIVS_ONFOOTCOUNT + 1;
[_civ,_spawnPos,300 - (random 250),[3,6],[0,2,10],true] spawn grad_civs_fnc_taskPatrol;
_amountSpawned = _amountSpawned + 1;
};

if (_amountSpawned >= _amount) exitWith {};
if (_i > _maxLoops) exitWith {};
};

_vehAmount = if (_x isEqualType objNull) then {
(triggerArea _x) params [["_a",0],["_b",0]];
[getPos _x,_a max _b,1,30,15] call grad_civs_fnc_createSideRoadVehicles
} else {
_x params ["_center",["_a",0],["_b",0]];
[_center,_a max _b,1,1,15] call grad_civs_fnc_createSideRoadVehicles
};

INFO_2("Populated area with %1 civilians and %2 static cars.",_amountSpawned,_vehAmount);

false
} count _areas;
4 changes: 4 additions & 0 deletions functions/spawn/fn_cleanup.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ if (count _civsArray == 0) exitWith {};

private _id = missionNamespace getVariable [_idVar,0];
_id = if (_id >= (count _civsArray)-1) then {0} else {_id+1};
for [{_i=0},{_i<count _civsArray},{_i=_i+1}] do {
if !((_civsArray select _id) getVariable ["grad_civs_excludeFromCleanup",false]) exitWith {};
_id = if (_id >= (count _civsArray)-1) then {0} else {_id+1};
};
missionNamespace setVariable [_idVar,_id];

private _civ = _civsArray select _id;
Expand Down
83 changes: 83 additions & 0 deletions functions/spawn/fn_createSideRoadVehicles.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#include "..\..\component.hpp"

params ["_locationPosition","_locationRadius","_amountFactor","_houseFactor","_minDistance"];

if (count GRAD_CIVS_VEHICLES == 0) exitWith {};
private _vehiclePositions = [];

//LOCAL FUNCTIONS ==============================================================
private _fnc_nearbyVehiclePositions = {
params ["_pos"];

_nearbyVehiclePositions = [];
{if (_pos distance2D _x < _minDistance) then {_nearbyVehiclePositions pushBack _x}} forEach _vehiclePositions;
_nearbyVehiclePositions
};

private _fnc_isSafe = {
params ["_pos"];
!(([_pos,0,1,0,0,0.6,0,[],[[0,0,0],[0,0,0]]] call BIS_fnc_findSafePos) isEqualTo [0,0,0])
};


//MAIN =========================================================================
private _thesePositions = [];
private _roads = _locationPosition nearRoads _locationRadius;
private _vehiclesToCreate = (round ((count _roads) * 0.07 * _amountFactor));
_vehiclesToCreate = round (2 max (_vehiclesToCreate + ((random (_vehiclesToCreate * 0.4)) - _vehiclesToCreate * 0.2)));

while {count _roads > 0 && count _thesePositions < _vehiclesToCreate} do {
private ["_vehPos","_canCreate","_chosenDirection","_offRoadFound"];

_randomRoadID = round (random ((count _roads)-1));
_road = _roads deleteAt _randomRoadID;

if (!isNull _road) then {
if (count (roadsConnectedTo _road) == 0) exitWith {};
_roadDir = _road getDir ((roadsConnectedTo _road) select 0);
_boundingBox = boundingBox _road;
_width = ((_boundingBox select 1) select 0) - ((_boundingBox select 0) select 0);

_startDirection = selectRandom [1,-1];
{
_chosenDirection = _x;
_offRoadFound = false;
for [{_i=1}, {_i<50}, {_i=_i+1}] do {
_testPos = _road getRelPos [1.5 + _i*0.2,_roadDir+90*_chosenDirection];
_vehPos = _testPos;
if (!isOnRoad _testPos) exitWith {_offRoadFound = true};
};

_enoughHouses = if (_houseFactor < 0) then {true} else {(count ([_vehPos,20] call grad_civs_fnc_findBuildings)) * _houseFactor > random 100};

_canCreate = switch (true) do {
case (!_offRoadFound): {"ONROAD"};
case (count (getPos _road nearRoads 10) > 2): {"ONINTERSECTION"};
case (!_enoughHouses): {"NOHOUSES"};
case (count ([_vehPos] call _fnc_nearbyVehiclePositions) > 0): {"TOOCLOSE"};
case (!([_vehPos] call _fnc_isSafe)): {"UNSAFE"};
default {"CANCREATE"};
};

if (_forEachIndex == 1) then {_roadDir = _roadDir + 180};
if (_canCreate == "CANCREATE") exitWith {};
} forEach [_startDirection,-_startDirection];

if (_canCreate == "CANCREATE") then {
_type = selectRandom GRAD_CIVS_VEHICLES;
_thesePositions pushBack _vehPos;
_vehiclePositions pushBack _vehPos;
_veh = createVehicle [_type,[0,0,0],[],0,"CAN_COLLIDE"];
[{!isNull (_this select 0)}, {
params ["_veh","_roadDir","_chosenDirection","_vehPos"];
_veh setDir _roadDir + (90 + 90*_chosenDirection);
_veh setPos _vehPos;
_veh setVelocity [0,0,1];
_veh lock 2;
[_veh] call grad_civs_fnc_deleteIfDamaged;
}, [_veh,_roadDir,_chosenDirection,_vehPos]] call CBA_fnc_waitUntilAndExecute;
};
};
};

count _vehiclePositions
10 changes: 10 additions & 0 deletions functions/spawn/fn_deleteIfDamaged.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "..\..\component.hpp"

[{!isNull (_this select 0)}, {
[{
params ["_object"];
if (damage _object > 0) then {
deleteVehicle _object;
};
}, _this, 5] call CBA_fnc_waitAndExecute;
}, _this] call CBA_fnc_waitUntilAndExecute;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "grad-civs",
"description": "ambient civilians",
"version": "0.2.5",
"version": "0.3.0",
"contributors": [
{
"name": "nomisum"
Expand Down

0 comments on commit e9caafd

Please sign in to comment.