Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion addons/common/script_component.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#define COMPONENT_BEAUTIFIED Common
#include "\u\uksf\addons\main\script_mod.hpp"

// #define DEBUG_MODE_FULL
#define DEBUG_MODE_FULL
// #define DISABLE_COMPILE_CACHE
// #define CBA_DEBUG_SYNCHRONOUS

Expand Down
1 change: 1 addition & 0 deletions addons/populate/$PBOPREFIX$
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
u\uksf\addons\populate
11 changes: 11 additions & 0 deletions addons/populate/CfgEventHandlers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Extended_PreStart_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
};
};

class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preInit));
};
};
6 changes: 6 additions & 0 deletions addons/populate/CfgFactionClasses.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class CfgFactionClasses {
class EGVAR(common,eden);
class ADDON: EGVAR(common,eden){
displayName = "Auto Populate Area";
};
};
102 changes: 102 additions & 0 deletions addons/populate/CfgVehicles.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
class CfgVehicles {
class Module_F;
class GVAR(module) : Module_F {
scope = 1;
is3DEN = 1;
functionPriority = 1;
category = ADDON;
class AttributesBase;
};
class GVAR(populateAreaModule) : GVAR(module) {
scope = 2;
displayName = "Auto Populate)";
icon = "A3\ui_f\data\map\markers\nato\o_inf.paa";
portrait = "A3\ui_f\data\map\markers\nato\o_inf.paa";
function = QFUNC(modulePopulateArea);
canSetArea = 1;
canSetAreaHeight = 0;
canSetAreaShape = 1;
class AttributeValues {
size3[] = { 200, 200, -1 };
isRectangle = 1;
};
class Attributes : AttributesBase {
class GVAR(numberOfUnits) {
property = QGVAR(numberOfUnits);
displayName = "Number of Units";
tooltip = "The number of units to spawn";
control = "EditShort";
validate = "NUMBER";
defaultValue = 30;
expression = QUOTE(_this setVariable [ARR_3(QQGVAR(numberOfUnits),_value,true)]);
};
class GVAR(patrolRadius) {
property = QGVAR(patrolRadius);
displayName = "Patrol Radius";
tooltip = "The radius any left over units will patrol around the module location. Used for when positions to occupy isn't 100%";
control = "EditShort";
validate = "NUMBER";
defaultValue = 50;
expression = QUOTE(_this setVariable [ARR_3(QQGVAR(patrolRadius),_value,true)]);
};
class GVAR(patrolSize) {
property = QGVAR(patrolSize);
displayName = "Patrol Size";
tooltip = "The number of units in each patrol. Patrols occur once all building positions are filled.";
control = "EditShort";
validate = "NUMBER";
defaultValue = 6;
expression = QUOTE(_this setVariable [ARR_3(QQGVAR(patrolSize),_value,true)]);
};
class GVAR(unitPoolString) {
property = QGVAR(unitPoolString);
displayName = "Unit Pool";
tooltip = "Class names of units to spawn for counter-mortar groups. Comma-separated list of class names in single quotes, no spaces";
control = "Edit";
defaultValue = "[]";
expression = QUOTE(_this setVariable [ARR_3(QQGVAR(unitPoolString),_value,true)]);
};
class GVAR(occupyStaticGunsBool) {
property = QGVAR(occupyStaticGunsBool);
displayName = "Occupy Static Weapons";
tooltip = "Should units man placed static weapons";
control = "CheckBox";
typeName = "BOOL";
defaultValue = "(false)";
expression = QUOTE(_this setVariable [ARR_3(QQGVAR(occupyStaticGunsBool),_value,true)]);
};
class GVAR(percentageOfPositionsToOccupy) {
property = QGVAR(percentageOfPositionsToOccupy);
displayName = "Percentage of Positions to Occupy";
tooltip = "What percentage of the total positions will be occupied - low % may result in units being spread out";
control = "EditShort";
validate = "NUMBER";
defaultValue = 30;
expression = QUOTE(_this setVariable [ARR_3(QQGVAR(percentageOfPositionsToOccupy),_value,true)]);
};
class GVAR(side) {
property = QGVAR(side);
displayName = "Side";
tooltip = "Side of spawned units";
control = "Combo";
expression = QUOTE(_this setVariable [ARR_3(QQGVAR(side),_value,true)]);
typeName = "NUMBER";
defaultValue = 0;
class values {
class East {
name = "OPFOR";
value = 0;
};
class Guer {
name = "INDEPENDENT";
value = 1;
};
class West {
name = "BLUFOR";
value = 2;
};
};
};
};
};
};
5 changes: 5 additions & 0 deletions addons/populate/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Auto Populate

Takes all building positions and AI Building Positions and populates them with units
If the number of AI to spawn is more than 10, group sizes will be 10
Runs once at mission start
7 changes: 7 additions & 0 deletions addons/populate/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
PREP(createPatrols);
PREP(getValidPositions);
PREP(getValidStatics);
PREP(modulePopulateArea);
PREP(selectSpawnPosition);
PREP(populateBuildingPositions);
PREP(populateStatics);
11 changes: 11 additions & 0 deletions addons/populate/XEH_preInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "script_component.hpp"

ADDON = false;

#include "XEH_PREP.hpp"

// #include "initSettings.sqf"

GVAR(groupSize) = 10;

ADDON = true;
3 changes: 3 additions & 0 deletions addons/populate/XEH_preStart.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "script_component.hpp"

#include "XEH_PREP.hpp"
24 changes: 24 additions & 0 deletions addons/populate/config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "script_component.hpp"

class CfgPatches {
class ADDON {
name = COMPONENT_NAME;
units[] = {
QGVAR(populateAreaModule)
};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {
"uksf_mission"
};
author = QUOTE(UKSF);
authors[] = { "Bridgford.A" };
url = URL;
VERSION_CONFIG;
};
};

// #include "Cfg3den.hpp"
#include "CfgEventHandlers.hpp"
#include "CfgFactionClasses.hpp"
#include "CfgVehicles.hpp"
59 changes: 59 additions & 0 deletions addons/populate/functions/fnc_createPatrols.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include "script_component.hpp"
/*
Author:
Bridg

Description:
Spawns a unit at the passed position

Parameters:
0: _numberOfUnitsToSpawn <NUMBER>
1: _module <OBJECT>
2: _group <GROUP>

Return value:
Nothing
*/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could simplify this quite a bit by making use of common,spawnGroupInfantry.
Take the nubmer of units remaining and divide by the patrol size. Do that many iterations plus one more for the remainder.
The spawning can be staggered by using a waitAndExecute with the time based on the index of an array multiplied by seconds

params ["_numberOfUnitsToSpawn", "_side", "_module", "_unitPoolArray"];

private _group = grpNull;
private _currenGrouptUnitCount = 0;
private _patrolSize = _module getVariable [QGVAR(patrolSize), 0];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 is a bad default, should exit if value from the module is 0 otherwise the patrols will never be tasked

private _patrolRadius = _module getVariable [QGVAR(patrolRadius), 0];

[{
params ["_args", "_idPFH"];
_args params ["_numberOfUnitsToSpawn", "_side", "_module", "_unitPoolArray", "_currenGrouptUnitCount", "_patrolRadius", "_group", "_patrolSize"];

if (_numberOfUnitsToSpawn <= 0) exitWith {
[_idPFH] call cba_fnc_removePerFrameHandler;
[QEGVAR(virtualisation,include), _group] call CBA_fnc_serverEvent;
};

// create a group if the _currenGrouptUnitCount is == 0, set previous group to patrol
if (_currenGrouptUnitCount == 0) then {
_group = createGroup _side;
[QEGVAR(virtualisation,exclude), _group] call CBA_fnc_serverEvent;
};

private _unitType = selectRandom _unitPoolArray;
private _unit = _group createUnit [_unitType, [0,0,0], [], 0, "NONE"];
_unit setPos (getPos _module);

_currenGrouptUnitCount = _currenGrouptUnitCount + 1;
_numberOfUnitsToSpawn = _numberOfUnitsToSpawn - 1;
if (_currenGrouptUnitCount == _patrolSize) then {
[_group, _group, _patrolRadius, 6] call lambs_wp_fnc_taskPatrol; // infantry only
_currenGrouptUnitCount = 0;
};

_args set [0, _numberOfUnitsToSpawn];
_args set [4, _currenGrouptUnitCount];
_args set [6, _group];

}, 1, [_numberOfUnitsToSpawn, _side, _module, _unitPoolArray, _currenGrouptUnitCount, _patrolRadius, _group, _patrolSize]] call cba_fnc_addPerFrameHandler;

// TODO: exclude virtualization until the group is spawned, then set to true


62 changes: 62 additions & 0 deletions addons/populate/functions/fnc_getValidPositions.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include "script_component.hpp"
/*
Author:
Bridg

Description:
Gets any valid building positions AND AI Building Positions in the area

Parameters:
0: _module <OBJECT>

Return value:
Nothing
*/
params ["_module"];

if !(isServer) exitWith {};

private _statics = [];

// get the area
private _areaParams = _module getVariable ["objectarea", []];
private _area = [getPos _module] + _areaParams;
if (_area isEqualTo []) exitWith {};

_area params ["", "_a", "_b"];

// get which dimension is largest to use as radius
private _radius = [_b, _a] select (_a > _b);

// get all buildings in radius then in area
private _allBuildingsInRadius = nearestTerrainObjects [_module, ["BUILDING", "HOUSE", "BUNKER"], _radius, false, true];
private _allBuildingsInArea = _allBuildingsInRadius select {_x inArea _area};

// get the building positions for the buildings
private _buildingPositions = [];
{
private _building = _x;
private _buildingPositionsArray = _building buildingPos -1;
{
private _buildingPosition = _x;
_buildingPositions pushBack _buildingPosition;
} forEach _buildingPositionsArray;
} forEach _allBuildingsInArea;

// get all ai buildings in the area
private _aiBuildingPositionsInArea = (_module nearObjects ["CBA_BuildingPos", _radius]) select {_x inArea _area};

// get statics in the area
private _occupyStatics = _module getVariable [QGVAR(occupyStaticGunsBool), false];
if (_occupyStatics) then {
_statics = [_module] call FUNC(getValidStatics);
};

// append building positions and ai building positions
private _spawnPositions = _buildingPositions + _aiBuildingPositionsInArea;

if (_spawnPositions isEqualTo [] && _statics isEqualTo []) exitWith {};

// call out to select position function
[_spawnPositions, _statics, _module] call FUNC(selectSpawnPosition);

36 changes: 36 additions & 0 deletions addons/populate/functions/fnc_getValidStatics.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include "script_component.hpp"
/*
Author:
Bridg

Description:
Gets any valid static guns in the area

Parameters:
0: _module <OBJECT>

Return value:
_statics
*/
params ["_module"];

if !(isServer) exitWith {};

// get the area
private _areaParams = _module getVariable ["objectarea", []];
private _area = [getPos _module] + _areaParams;
if (_area isEqualTo []) exitWith {};

_area params ["", "_a", "_b"];

// get which dimension is largest to use as radius
private _radius = [_b, _a] select (_a > _b);

// get all statics in the area
private _statics = [];
private _staticsInArea = (_module nearEntities [["StaticWeapon"], _radius]) select {_x inArea _area && (_x emptyPositions "" > 0)};
{
_statics pushBack _x;
} forEach _staticsInArea;

_statics
20 changes: 20 additions & 0 deletions addons/populate/functions/fnc_modulePopulateArea.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "script_component.hpp"
/*
Author:
Bridg

Description:
Sets the settings from the module up as global vars

Parameters:
0: The module object <OBJECT>

Return value:
Nothing
*/

(_this#1) params ["_module"];

if (!isServer) exitWith {};

[_module] call FUNC(getValidPositions);
Loading