Skip to content

Commit

Permalink
adding HiddenUnitSpawner
Browse files Browse the repository at this point in the history
  • Loading branch information
Madin authored and Madin committed May 9, 2024
1 parent df71d41 commit 508ca31
Show file tree
Hide file tree
Showing 30 changed files with 769 additions and 0 deletions.
1 change: 1 addition & 0 deletions addons/hiddenUnitSpawner/$PBOPREFIX$
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
z\afmf\addons\staticspawn
41 changes: 41 additions & 0 deletions addons/hiddenUnitSpawner/CfgEden.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

class Cfg3DEN
{
class Group
{
class AttributeCategories
{
class MAI_Attributes
{
displayName = "MAI";
collapsed = 0;

class Attributes
{
class MAI_AIgroupEnableAi
{
//--- Mandatory properties
displayName = "$STR_MAI_AIgroupEnableAi";
tooltip = "$STR_MAI_AIgroupEnableAiTip";
property = QGVAR(tickets);
control = "Checkbox";
expression = "_this setVariable ['%s',_value];";
defaultValue = "true";
condition = "objectBrain"; // https://community.bistudio.com/wiki/Eden_Editor:_Configuring_Attributes#Condition
typeName = "BOOL";
};
};
};
};
};
};

{
displayName = "$STR_MAI_sphereDespawnDistance";
tooltip = "$STR_MAI_sphereDespawnDistanceShort";
defaultValue = "50";
property = QGVAR(sphereDespawnDistance);
expression = "_this setVariable ['%s',_value];";
typeName = "NUMBER";
control = "EditShort";
};
23 changes: 23 additions & 0 deletions addons/hiddenUnitSpawner/CfgEventHandlers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class Extended_PreStart_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_FILE(XEH_preStart));
};
};
class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_FILE(XEH_preInit));
};
};
class Extended_PostInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_FILE(XEH_postInit));
};
};

class Extended_Killed_EventHandlers {
class CAManBase {
class MAI_hidden_Unit_EH_killed {
killed = QUOTE(call FUNC(EH));
};
};
};
235 changes: 235 additions & 0 deletions addons/hiddenUnitSpawner/CfgModuleCategories.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
#include "script_component.hpp"

class CfgFactionClasses
{
class NO_CATEGORY;
class MAI_Modules: NO_CATEGORY
{
displayName = "Armaforces - MAI";
//side = 7;
};
};

class CfgVehicles
{
class Logic;
class Module_F: Logic
{
class AttributesBase
{
class Default;
class Edit; // Default edit box (i.e., text input field)
class Combo; // Default combo box (i.e., drop-down menu)
class Checkbox; // Default checkbox (returned value is Bool)
class CheckboxNumber; // Default checkbox (returned value is Number)
class ModuleDescription; // Module description
class Units; // Selection of units on which the module is applied
};
// Description base classes, for more information see below
class ModuleDescription
{
class AnyBrain;
};
};
class MAI_Modulestaticspawn: Module_F
{
// Standard object definitions
scope = 2; // Editor visibility; 2 will show it in the menu, 1 will hide it.
displayName = "Static Spawn"; // Name displayed in the menu
category = "MAI_Modules";

// Name of function triggered once conditions are met
function = QFUNC(initCall);
// Execution priority, modules with lower number are executed first. 0 is used when the attribute is undefined
functionPriority = 1;
// 0 for server only execution, 1 for global execution, 2 for persistent global execution
isGlobal = 0;
// 1 for module waiting until all synced triggers are activated
isTriggerActivated = 0;
// 1 if modules is to be disabled once it's activated (i.e., repeated trigger activation won't work)
isDisposable = 1;
// // 1 to run init function in Eden Editor as well
is3DEN = 1;

// Menu displayed when the module is placed or double-clicked on by Zeus
//curatorInfoType = "RscDisplayAttributeModuleNuke";

// Module attributes, uses https://community.bistudio.com/wiki/Eden_Editor:_Configuring_Attributes#Entity_Specific
class Attributes: AttributesBase
{
// Arguments shared by specific module type (have to be mentioned in order to be present)
class GVAR(tickets): Default
{
displayName = "$STR_MAI_tickets";
tooltip = "$STR_MAI_tickets";
defaultValue = "1";
property = QGVAR(tickets);
expression = "_this setVariable ['%s',_value];";
typeName = "NUMBER";
control = "EditShort";
};
class GVAR(sphereSize): Default
{
displayName = "$STR_MAI_sphereSize";
tooltip = "$STR_MAI_sphereSizeShort";
defaultValue = "250";
property = QGVAR(sphereSize);
expression = "_this setVariable ['%s',_value];";
typeName = "NUMBER";
control = "EditShort";
};
class GVAR(sphereDespawnDistance): Default
{
displayName = "$STR_MAI_sphereDespawnDistance";
tooltip = "$STR_MAI_sphereDespawnDistanceShort";
defaultValue = "50";
property = QGVAR(sphereDespawnDistance);
expression = "_this setVariable ['%s',_value];";
typeName = "NUMBER";
control = "EditShort";
};
class GVAR(checkVisibility): Checkbox
{
displayName = "$STR_MAI_checkVisibility";
tooltip = "$STR_MAI_checkVisibilityShort";
property = QGVAR(checkVisibility);
defaultValue = "true";
expression = "_this setVariable ['%s', _value];";
typeName = "BOOL";
};
class GVAR(sphereBackDistance): Default
{
displayName = "$STR_MAI_sphereBackDistance";
tooltip = "$STR_MAI_sphereBackDistanceShort";
defaultValue = "35";
property = QGVAR(sphereBackDistance);
expression = "_this setVariable ['%s',_value];";
typeName = "NUMBER";
control = "EditShort";
};
class GVAR(forceSpawnDistance): Default
{
displayName = "$STR_MAI_sphereBackDistance";
tooltip = "$STR_MAI_sphereBackDistanceShort";
defaultValue = "0.35";
property = QGVAR(forceSpawnDistance);
expression = "_this setVariable ['%s',_value max 0 min 1];";
typeName = "NUMBER";
control = "EditShort";
};
class GVAR(interval): Default
{
displayName = "$STR_MAI_interval";
tooltip = "$STR_MAI_intervalShort";
defaultValue = "0.1";
property = QGVAR(interval);
expression = "_this setVariable ['%s',_value max 0];";
typeName = "NUMBER";
control = "EditShort";
};
class GVAR(unitsPerInterval): Default
{
displayName = "$STR_MAI_unitsPerInterval";
tooltip = "$STR_MAI_unitsPerIntervalShort";
defaultValue = "1";
property = QGVAR(unitsPerInterval);
expression = "_this setVariable ['%s',_value max 0];";
typeName = "NUMBER";
control = "EditShort";
};
class GVAR(deleteVehicles): Checkbox
{
displayName = "$STR_MAI_deleteVehicles";
tooltip = "$STR_MAI_deleteVehiclesShort";
property = QGVAR(deleteVehicles);
defaultValue = "false";
expression = "_this setVariable ['%s', _value];";
typeName = "BOOL";
};
class GVAR(checkBuildings): Checkbox
{
displayName = "$STR_MAI_checkBuildings";
tooltip = "$STR_MAI_checkBuildingsShort";
property = QGVAR(checkBuildings);
defaultValue = "true";
expression = "_this setVariable ['%s', _value];";
typeName = "BOOL";
};
class GVAR(activateCondition)
{
displayName = "$STR_MAI_activateCondition";
tooltip = "$STR_MAI_activateConditionShort";
property = QGVAR(activateCondition);
control = "EditCodeMulti5";
expression = "_this setVariable ['%s',compile _value];";
defaultValue = "'true'";
value = 0;
validate = "none";
wikiType = "[[String]]";
};
class GVAR(deleteTrigger): Checkbox
{
displayName = "$STR_MAI_deleteTrigger";
tooltip = "$STR_MAI_deleteTriggerShort";
property = QGVAR(deleteTrigger);
defaultValue = "false";
expression = "_this setVariable ['%s', _value];";
typeName = "BOOL";
};
class GVAR(forceActivate): Checkbox
{
displayName = "$STR_MAI_forceActivate";
tooltip = "$STR_MAI_forceActivateShort";
property = QGVAR(forceActivate);
defaultValue = "false";
expression = "_this setVariable ['%s', _value];";
typeName = "BOOL";
};
class GVAR(executionCodeUnit)
{
displayName = "$STR_MAI_executionCodeUnit";
tooltip = "$STR_MAI_executionCodeUnitShort";
property = QGVAR(executionCodeUnit);
control = "EditCodeMulti5";
expression = "_this setVariable ['%s',compile _value];";
defaultValue = "''";
value = 0;
validate = "none";
wikiType = "[[String]]";
};
class GVAR(executionCodeGroup)
{
displayName = "$STR_MAI_executionCodePatrol";
tooltip = "$STR_MAI_executionCodePatrolShort";
property = QGVAR(executionCodeGroup);
control = "EditCodeMulti5";
expression = "_this setVariable ['%s',compile _value];";
defaultValue = "''";
value = 0;
validate = "none";
wikiType = "[[String]]";
};
class ModuleDescription: ModuleDescription{}; // Module description should be shown last
};

// Module description. Must inherit from base class, otherwise pre-defined entities won't be available
class ModuleDescription: ModuleDescription
{
description = "Simple spawn for AI. AI will be only spawned when AI will be closer than set distance. Only one unit from group need to be synchronized. Supports vehicles – Vehicle will stay, but crew will be spawned. Synchronize vehicle or unit."; // Short description, will be formatted as structured text
sync[] = {"LocationArea_F"}; // Array of synced entities (can contain base classes)

class LocationArea_F
{
description[] = { // Multi-line descriptions are supported
"First line",
"Second line"
};
position = 1; // Position is taken into effect
direction = 0; // Direction is taken into effect
optional = 0; // Synced entity is optional
duplicate = 0; // Multiple entities of this type can be synced
synced[] = {"AnyBrain"}; // Pre-define entities like "AnyBrain" can be used. See the list below
};
};
};
};
12 changes: 12 additions & 0 deletions addons/hiddenUnitSpawner/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
PREP(despawn);
PREP(despawnLoop);
PREP(firstState);
PREP(getGroups);
PREP(init);
PREP(initCall);
PREP(loop);
PREP(waitUntil);
PREP(spawnUnit);
PREP(checkSpawnConditions);
PREP(addEH);
PREP(despawnAddToLogic);
1 change: 1 addition & 0 deletions addons/hiddenUnitSpawner/XEH_postInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "script_component.hpp"
4 changes: 4 additions & 0 deletions addons/hiddenUnitSpawner/XEH_preInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include "script_component.hpp"
ADDON = false;
#include "XEH_PREP.hpp"
ADDON = true;
2 changes: 2 additions & 0 deletions addons/hiddenUnitSpawner/XEH_preStart.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#include "script_component.hpp"
#include "XEH_PREP.hpp"
17 changes: 17 additions & 0 deletions addons/hiddenUnitSpawner/config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "script_component.hpp"
class CfgPatches {
class ADDON {
name = COMPONENT;
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {};
author = "Madin";
VERSION_CONFIG;
};
};


#include "CfgEventHandlers.hpp"

#include "CfgModuleCategories.hpp"
8 changes: 8 additions & 0 deletions addons/hiddenUnitSpawner/functions/fn_EHkilled.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "script_component.hpp"

params ["_unit", "_killer", "_instigator", "_useEffects"];
private _tickets = _unit getVariable [QGVAR(tickets), 1];
if (_tickets <= 1) exitWith {};

private _unitLoadout = _unit getVariable [QGVAR(unitLoadout), []];
[getposATL _unit, group _unit, typeOf _unit, _unitLoadout, _tickets, 5000] call AF_fnc_findHiddenPos;
7 changes: 7 additions & 0 deletions addons/hiddenUnitSpawner/functions/fn_checkNearDeadUnit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "script_component.hpp"

// return true if unit is dead and closer than 15m
params [["_pos", [0,0,0]], ["_unit", objNull]];
if (alive _unit) exitWith {false};
if (_pos distance _unit < 15) exitWith {true};
false
17 changes: 17 additions & 0 deletions addons/hiddenUnitSpawner/functions/fn_findHiddenPos.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "script_component.hpp"

params [["_pos", [0,0,0]], ["_group", grpNull], ["_type", "B_Soldier_F"], ["_loadout", []], ["_tickets", 1], ["_maxDistance", 500], ["_minDistance", 50]];
if (units _group isEqualTo []) exitWith {
// no group or no units in group, exit
};
private _players = allPlayers select {_x distance _pos < _maxDistance};
if (_players isEqualTo []) then {_players = allPlayers};
private _averagePosUnitGroup = [units _group] call AF_fnc_getAveragePos;
if (_averagePosUnitGroup isEqualTo [0,0,0]) then {_averagePosUnitGroup = _pos};
private _averagePosPlayers = [_players] call AF_fnc_getAveragePos;
private _dirToUnit = _averagePosPlayers getDir _averagePosUnitGroup;
private _centerPos = _averagePosUnitGroup getPos [_minDistance , _dirToUnit];
_centerPos = _centerPos vectorAdd [_minDistance/2 - random _minDistance, _minDistance/2 - random _minDistance, 0];
_nearObjects = nearestTerrainObjects [_centerPos, ["Tree", "Bush", "ROCK"], 75, false];
// if (_nearObjects isEqualTo []) exitWith {};
[_pos, _group, _type, _loadout, _tickets, _maxDistance, _minDistance, _nearObjects, _players] call AF_fnc_findHiddenPosPerFrame;
Loading

0 comments on commit 508ca31

Please sign in to comment.