Difference between revisions of "Script Snippets"
(→Spawn Group Script By Jman) |
(→Adding ARTY units post-init) |
||
(73 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
− | === Spawn Group Script By Jman === | + | |
− | <syntaxhighlight> | + | |
+ | =Profiles= | ||
+ | |||
+ | === Spawn & Profile Group Script By Jman === | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | /* | ||
Filename: fnc_spawnProfileGroup.sqf | Filename: fnc_spawnProfileGroup.sqf | ||
Locality: Runs on server | Locality: Runs on server | ||
Line 36: | Line 42: | ||
Example(s): | Example(s): | ||
* [getMarkerPos "nmeGrp01_spawn_pos", false, getMarkerPos "nmeGrp01_dest_pos", "10_men_ME", "caf_ag_me"] call ALIVE_spawnProfileGroup; | * [getMarkerPos "nmeGrp01_spawn_pos", false, getMarkerPos "nmeGrp01_dest_pos", "10_men_ME", "caf_ag_me"] call ALIVE_spawnProfileGroup; | ||
− | * [getMarkerPos "nmeGrp01_spawn_pos", false, getMarkerPos "nmeGrp01_dest_pos", "10_men_ME", "caf_ag_me", true, 0, "Move", "Full", 0, [0,0,0], " | + | * [getMarkerPos "nmeGrp01_spawn_pos", false, getMarkerPos "nmeGrp01_dest_pos", "10_men_ME", "caf_ag_me", true, 0, "Move", "Full", 0, [0,0,0], "Wedge", "Red", "Aware", ""] call ALIVE_spawnProfileGroup; |
Credits: ALiVE functions: The ALiVE team. Web: http://www.alivemod.com | Credits: ALiVE functions: The ALiVE team. Web: http://www.alivemod.com | ||
Line 43: | Line 49: | ||
* Email: [email protected] | * Email: [email protected] | ||
* Web: http://www.kellys-heroes.eu | * Web: http://www.kellys-heroes.eu | ||
+ | */ | ||
− | |||
// ==================================================================================== | // ==================================================================================== | ||
if (!isServer) exitWith {}; | if (!isServer) exitWith {}; | ||
Line 70: | Line 76: | ||
_waypointCompletionRadius = if(count _this > 9) then {_this select 9} else {0}; | _waypointCompletionRadius = if(count _this > 9) then {_this select 9} else {0}; | ||
_waypointTimeoutCounters = if(count _this > 10) then {_this select 10} else {[0,0,0]}; | _waypointTimeoutCounters = if(count _this > 10) then {_this select 10} else {[0,0,0]}; | ||
− | _waypointFormation = if(count _this > 11) then {_this select 11} else {" | + | _waypointFormation = if(count _this > 11) then {_this select 11} else {"Wedge"}; |
− | _waypointCombatMode = if(count _this > 12) then {_this select 12} else {" | + | _waypointCombatMode = if(count _this > 12) then {_this select 12} else {"Red"}; |
_waypointBehaviour = if(count _this > 13) then {_this select 13} else {"Aware"}; | _waypointBehaviour = if(count _this > 13) then {_this select 13} else {"Aware"}; | ||
_waypointDescription = if(count _this > 14) then {_this select 14} else {""}; | _waypointDescription = if(count _this > 14) then {_this select 14} else {""}; | ||
Line 102: | Line 108: | ||
// ==================================================================================== | // ==================================================================================== | ||
− | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 120: | Line 125: | ||
It doesnt matter if they are spawned or not. | It doesnt matter if they are spawned or not. | ||
− | |||
− | + | === Profiling all non profiled units on the map === | |
− | < | + | You can trigger the profiler to profile all non profiled units (handy for MCC and Zeus or scripts that spawn units during gameplay). This function needs to be called on the server locality after a short pause to enable ALiVE to finish initialising: |
+ | |||
+ | <syntaxhighlight lang="php"> | ||
if (isServer) then { | if (isServer) then { | ||
− | + | [] spawn { | |
− | + | while {true} do { | |
− | + | sleep 60; | |
− | + | [] call ALiVE_fnc_createProfilesFromUnitsRuntime; | |
− | + | }; | |
− | + | }; | |
− | + | }; | |
− | ] call ALiVE_fnc_OPCOM; | + | </syntaxhighlight> |
− | + | ||
− | + | ||
+ | === Adding Custom Inits to Spawned Units === | ||
+ | |||
+ | The following is one method for adding custom scripts to every spawned unit or object of that class, for example running a script that adds custom gear to a class of units. This will work for units spawned with MP/MCP, the Profiles system and any other spawning method such as Zeus. | ||
+ | |||
+ | '''HEALTH WARNING:''' you will need to know the basics of scripting to setup the gear script so it only applies to AI (and not players) or specific factions. Place the following in ''description.ext'' and create ''my_code.sqf'' with whatever code you want to add to the spawned units. Also be aware that anything added to player units will duplicate if player persistence is on, so it's better to use regular methods for players (or include ''isPlayer'' check in your script). | ||
+ | |||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | |||
+ | class Extended_Init_EventHandlers { | ||
+ | class Man { | ||
+ | init = "_this call (compile preprocessFileLineNumbers 'my_script.sqf')"; | ||
+ | }; | ||
+ | }; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | This is an example my_script.sqf thanks to SpyderBlack723 on the BI Forums: | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | private "_this"; | ||
+ | _this = _this select 0; | ||
+ | |||
+ | if ((side _this == west) and (!isPlayer _this)) then { | ||
+ | removeallweapons _this; | ||
+ | removeGoggles _this;removeHeadgear _this;removeVest _this;removeUniform _this;removeAllAssignedItems _this;removeBackpack _this; | ||
+ | _this addHeadgear 'Helmet_ACU';_this addUniform 'Uniform_ACU';_this addVest 'Vest_ACU';_this addBackPack 'ACU_Backpack'; | ||
+ | { _this addItemToBackpack"rhs_mag_30Rnd_556x45_M855A1_Stanag"; } forEach [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,18, 19, 20, 21]; | ||
+ | { _this addItemToBackpack "rhs_mag_m67"; } forEach [1, 2, 3, 4]; | ||
+ | { _this addItemToBackpack "SmokeShell"; } forEach [1, 2, 3, 4]; | ||
+ | { _this addItem "FirstAidKit"; } forEach [1, 2, 3, 4, 5]; | ||
+ | _this addweapon 'rhs_m4_grip_acog';_this addPrimaryWeaponItem 'rhsusf_acc_ACOG';_this linkItem "ItemMap"; | ||
+ | }; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | === Profile Counter === | ||
+ | |||
+ | Great for debugging your missions. Counts all profiles for all sides. | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | if (isServer) then { | ||
+ | _profilesBySide = [ALiVE_profileHandler,"profilesBySide"] call ALIVE_fnc_hashGet; | ||
+ | _profilesBySide = _profilesBySide select 2; | ||
+ | |||
+ | systemchat format ["Profile Count OPFOR - %1", count (_profilesBySide select 0)]; | ||
+ | systemchat format ["Profile Count BLUFOR - %1", count (_profilesBySide select 1)]; | ||
+ | systemchat format ["Profile Count INDEPENDANT - %1", count (_profilesBySide select 2)]; | ||
+ | }; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | === Spawning player group AI members after persistent save === | ||
+ | |||
+ | If you use the ALiVE saving feature one 'issue' is that AI members in the player's group do not get saved or restored. If they are editor-placed units then they will spawn at their original editor start location instead of wherever the player is. To work around this do the following: | ||
+ | |||
+ | Place the following code at the bottom of your mission's init.sqf file: | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | waituntil {(player getvariable ["alive_sys_player_playerloaded",false])}; | ||
+ | sleep 2; | ||
+ | { | ||
+ | if !(isPlayer _x) then { | ||
+ | if !(_x getVariable ["Persistent_Teleport", false]) then { | ||
+ | _x setPos (getPos player); | ||
+ | _x setVariable ["Persistent_Teleport", true, true]; | ||
+ | sleep .5; | ||
+ | }; | ||
+ | }; | ||
+ | } forEach units group player; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | =OPCOM= | ||
+ | === Add a Custom OPCOM Objective === | ||
+ | |||
+ | This will register a position as an objective to all OPCOMs in the current mission. | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | |||
+ | Parameters: | ||
+ | |||
+ | select 0: _id (String); | ||
+ | select 1: _position (Array); | ||
+ | select 2: _size (Integer); | ||
+ | select 3: _type (String of "MIL" or "CIV"); | ||
+ | select 4: _priority (Integer); | ||
+ | |||
+ | Code: | ||
+ | |||
+ | if (isServer) then {{[_x,"addObjective", ["OPCOM_custom_1", [25657.2,22175.8,0.00129318], 100, "MIL", 200] ] call ALiVE_fnc_OPCOM; } foreach OPCOM_INSTANCES}; | ||
+ | |||
+ | </syntaxhighlight> | ||
Example: | Example: | ||
Place these lines of code (without the comments) in the on activation field of a "detected by..."-trigger (500mtrs radius). As the trigger fires your base will be registered to all OPCOMs, who will then send troops there (either to attack or defend). You can use these in combination with triggers and tasks. For example if you are detected by a trigger within a certain radius of your base, your base will be registered to OPCOM! OPCOMs will send their troops there and if you don't manage to defend your base the mission will fail. | Place these lines of code (without the comments) in the on activation field of a "detected by..."-trigger (500mtrs radius). As the trigger fires your base will be registered to all OPCOMs, who will then send troops there (either to attack or defend). You can use these in combination with triggers and tasks. For example if you are detected by a trigger within a certain radius of your base, your base will be registered to OPCOM! OPCOMs will send their troops there and if you don't manage to defend your base the mission will fail. | ||
+ | |||
+ | This little gem comes from Cameroon on the BI Forum. It enables you to set a custom objective on the fly for one side only. The first parameter is an array that is passed straight to ALiVE_fnc_OPCOM - set it as you would when calling addObjective. The second argument is an array of strings for the factions that should get the objective. | ||
+ | |||
+ | It's worth noting that the OPCOM may not immediately notice the new objective and of course it's still prioritized so there might not be any units to send. Also, if you have a marker with the same name as the first argument ("opfoComRetake_obj"), ALIVE will take it over. It is recommended that you do not use a marker name same as the objective name. | ||
+ | |||
+ | Example:[["opforComRetake_obj", getMarkerPos "opforComRetake", 200,"MIL"],["EAST"]] call cjb_addObjectiveToSides; | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | cjb_addObjectiveToSides = { | ||
+ | private["_objectiveParams","_factions","_faction","_opcom","_opcomSide"]; | ||
+ | _objectiveParams = _this select 0; | ||
+ | _factions = _this select 1; | ||
+ | { | ||
+ | _opcom = _x; | ||
+ | { | ||
+ | _faction = _x; | ||
+ | _opcomSide = [_opcom,"side",""] call ALiVE_fnc_HashGet; | ||
+ | |||
+ | if( _opcomSide == _faction) then { | ||
+ | [_opcom, "addObjective", _objectiveParams] call ALiVE_fnc_OPCOM; | ||
+ | }; | ||
+ | } forEach _factions; | ||
+ | } forEach OPCOM_INSTANCES; | ||
+ | }; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Assign a Custom Group & Vehicle to OPCOM === | ||
+ | |||
+ | <syntaxhighlight lang="php">[your_editor_unit, your_editor_vehicle] spawn ALiVE_fnc_createProfileVehicleAssignment</syntaxhighlight> | ||
+ | |||
+ | Can either have an object or a hash passed to it. Note that if OPCOM already has enough groups it may take some time until it uses the newly assigned groups. | ||
+ | |||
+ | For example: | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | _customVehicleAssignments = [[leader1,vehicle1]]; | ||
+ | { | ||
+ | _leader = _x select 0; | ||
+ | _vehicle = _x select 1; | ||
+ | _group = group _leader; | ||
+ | [_group, _vehicle, true] call ALIVE_fnc_vehicleAssignGroup; | ||
+ | } forEach _customVehicleAssignments; | ||
+ | }; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | === Jump To The Action! === | ||
+ | |||
+ | ''ALiVE_fnc_JoinNearestGroup'' will select the most important objective that is currently being attacked/defended by your forces and join you to an AI group that is on an assault or defend mission. This will send you directly into the action! Execute the function locally on any player client. Possible params are "attacking" or "defending". | ||
+ | |||
+ | <syntaxhighlight lang="php">[player,"attacking"] call ALiVE_fnc_OPCOMjoinNearestGroup</syntaxhighlight> | ||
+ | |||
+ | ''ALiVE_fnc_OPCOMJoinObjective'' will display all objectives that are currently being attacked/defended, lets you select the objective of choice and HALO drops your group to an AI group that is currently ordered to assault/defend this objective! Execute the function locally on any player client. Possible params are "attacking" or "defending". | ||
+ | |||
+ | <syntaxhighlight lang="php">[player,"attacking"] call ALiVE_fnc_OPCOMjoinObjective</syntaxhighlight> | ||
+ | |||
+ | Example: put in the Init field of a unit or object in editor | ||
+ | |||
+ | <syntaxhighlight lang="php">this addAction ["Select Assault Mission",{[_this select 1,"attacking"] call ALiVE_fnc_OPCOMJoinObjective},[],1,false,true,"","true"];</syntaxhighlight> | ||
+ | |||
+ | =Compositions= | ||
+ | |||
+ | === Add Custom Roadblock to Civ placement === | ||
+ | |||
+ | 1.0 Release includes the ability to add custom roadblocks. Define your custom roadblocks at init on the server: | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | ALIVE_compositions_roadblocks = ["YOUR_ROADBLOCK_CLASS1","YOUR_ROADBLOCK_CLASS2",etc]; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Spawning a Custom Composition via Script === | ||
+ | |||
+ | Use the following function: | ||
+ | |||
+ | |||
+ | <syntaxhighlight lang="php">Function: ALIVE_fnc_spawnRandomPopulatedComposition | ||
+ | |||
+ | Description: | ||
+ | Spawn a composition | ||
+ | Spawns a random populated composition | ||
+ | |||
+ | Parameters: | ||
+ | Position - Array | ||
+ | Type - String - Civilian, Military, Guerrilla | ||
+ | Category - String | ||
+ | Civilian Categories - airports, checkpointsbarricades, construction, constructionSupplies, communications, fuel, general, heliports, industrial, marine, mining_oil, power, rail, settlements | ||
+ | Guerrilla Categories - camps, checkpointsbarricades, constructionsupplies, commnunications, fieldhq, fort, fuel, hq, marine, medical, outposts, power, supports | ||
+ | Military Categories - airports, camps, checkpointsbarricades, constructionsupplies, communications, crashsites, fieldhq, fort, fuel, heliports, hq, marine, medical, outposts, power, supports, supplies | ||
+ | Faction - String (OPTIONAL) | ||
+ | Size - String (Large, Medium, Small, ANY) | ||
+ | Infantry groups - Integer (OPTIONAL) | ||
+ | Mot Groups - Integer (OPTIONAL) | ||
+ | Mech Groups - Integer (OPTIONAL) | ||
+ | Armoured Groups - Integer (OPTIONAL) | ||
+ | SpecOps Groups - Integer (OPTIONAL) | ||
+ | |||
+ | Returns: None | ||
+ | |||
+ | Examples: | ||
+ | |||
+ | // spawn a small fortification composition with 2 OPF_F groups | ||
+ | _result = [_position, "Military", "Fort", "OPF_F", "Small", 2] call ALIVE_fnc_spawnRandomPopulatedComposition;</syntaxhighlight> | ||
+ | |||
+ | =Modules= | ||
=== Wait for Player Persistence to Initialise === | === Wait for Player Persistence to Initialise === | ||
Line 149: | Line 353: | ||
Use this in init.sqf if you have a player-depended scripts and use "player persistence"; | Use this in init.sqf if you have a player-depended scripts and use "player persistence"; | ||
− | === | + | === Pausing Modules === |
− | + | Use the following code on the server to pause and un pause modules completely. Pausing sys_profile will stop all simulation of profiles, and prevent spawning / despawning. Pausing OPCOM will stop OPCOM from issuing orders and running battlefield analysis. Pausing civ_population will stop all civilian AI commands and prevent spawning / despawning. | |
− | + | Pause and unpause the profile system | |
+ | <syntaxhighlight lang="php"> | ||
+ | |||
+ | ["ALIVE_SYS_PROFILE"] call ALiVE_fnc_pauseModule; | ||
+ | |||
+ | ["ALIVE_SYS_PROFILE"] call ALiVE_fnc_unPauseModule; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | Pause and unpause a whole lot of modules | ||
+ | <syntaxhighlight lang="php"> | ||
+ | |||
+ | ["ALIVE_SYS_PROFILE","ALIVE_MIL_OPCOM","ALIVE_AMB_CIV_POPULATION","ALIVE_MIL_LOGISTICS","ALIVE_SYS_AISKILL"] call ALiVE_fnc_pauseModule; | ||
+ | |||
+ | ["ALIVE_SYS_PROFILE","ALIVE_MIL_OPCOM","ALIVE_AMB_CIV_POPULATION","ALIVE_MIL_LOGISTICS","ALIVE_SYS_AISKILL"] call ALiVE_fnc_unPauseModule; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | This is an example script from dixon13 on our forums for automatically pausing OPCOM when players disconnect using initServer.sqf (see BI Community Wiki for further details on using init event scripts) | ||
+ | <syntaxhighlight lang="php"> | ||
+ | ["someId", "onPlayerConnected", { | ||
+ | if (({isPlayer _x} count playableUnits) > 0 || OPCOM_TOGGLE) then { ["ALIVE_MIL_OPCOM"] call ALiVE_fnc_unPauseModule; OPCOM_TOGGLE = false; }; | ||
+ | }] call BIS_fnc_addStackedEventHandler; | ||
+ | |||
+ | ["someId", "onPlayerDisconnected", { | ||
+ | if ( ({isPlayer _x} count playableUnits) == 0 ) then { ["ALIVE_MIL_OPCOM"] call ALiVE_fnc_pauseModule; OPCOM_TOGGLE = true; }; | ||
+ | }] call BIS_fnc_addStackedEventHandler; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ===Adjust Logistics Force Pool=== | ||
+ | |||
+ | Military Logistics and the Player Resupply module both work from the Global Force Pool to establish the allowed reinforcement levels for a faction. You can adjust this value on the fly in your own missions to add or remove from the global force pool. If running on a dedicated server, this must be performed on the server side only. | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | |||
+ | if(isServer) then { | ||
+ | |||
+ | // example: get the global force pool count for the BLU_F faction | ||
+ | _currentBLUFORForcepool = [ALIVE_globalForcePool,"BLU_F"] call ALIVE_fnc_hashGet; | ||
+ | |||
+ | // example: alter the current BLU_F force pool | ||
+ | [ALIVE_globalForcePool,"BLU_F",20] call ALIVE_fnc_hashSet; | ||
− | |||
− | |||
− | |||
− | |||
− | |||
}; | }; | ||
− | </code> | + | |
+ | </syntaxhighlight> | ||
+ | |||
+ | ===Adjust Force Size post init=== | ||
+ | |||
+ | Specify side (side== xxxx) and number of each group/profile type. Fire the code via script, trigger etc and the OPCOM will now have force cap set to those values and bring in "replacements" to get up to strength. | ||
+ | <syntaxhighlight lang="php"> | ||
+ | { | ||
+ | private _side = [_x, "side", ""] call ALIVE_fnc_hashGet; | ||
+ | |||
+ | if (_side == "WEST") then { | ||
+ | [ | ||
+ | _x, | ||
+ | "startForceStrength", | ||
+ | [ | ||
+ | 0, // Infantry | ||
+ | 0, // Motorized | ||
+ | 0, // Mechanized | ||
+ | 0, // Armored | ||
+ | 0, // Artillery | ||
+ | 0, // AAA | ||
+ | 0, // Air | ||
+ | 0 // Sea | ||
+ | ] | ||
+ | ] call ALIVE_fnc_hashSet; | ||
+ | }; | ||
+ | } forEach OPCOM_INSTANCES; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Add Custom Variables to ALiVE Database === | ||
+ | |||
+ | 0.9.8 Release includes the ability to save and retrieve custom values to the ALiVE database using the following funcs: | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | ["key", _value] call ALiVE_fnc_setData | ||
+ | _value = ["key"] call ALiVE_fnc_getData | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Adding CAS units post-init === | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | [_type, _settings] call ALiVE_fnc_combatSupportAdd; | ||
+ | |||
+ | _type - The type of combat support, can be "CAS", "TRANSPORT" or "ARTY" | ||
+ | _settings - Array of settings | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | {| role="presentation" class="wikitable mw-collapsible mw-collapsed" | ||
+ | | <strong>CAS</strong> | ||
+ | |- | ||
+ | | | ||
+ | <strong>Settings</strong> | ||
+ | {| class="wikitable" | ||
+ | ! index || type || description | ||
+ | |- | ||
+ | | 0 || array || Position of vehicle | ||
+ | |- | ||
+ | | 1 || number || Direction of vehicle | ||
+ | |- | ||
+ | | 2 || string || Classname of vehicle | ||
+ | |- | ||
+ | | 3 || string || Callsign of vehicle | ||
+ | |- | ||
+ | | 4 || string || Code to be ran on vehicle spawn | ||
+ | |- | ||
+ | | 5 || string || Height of vehicle | ||
+ | |} | ||
+ | <strong>Example</strong> | ||
+ | <syntaxhighlight lang="php"> | ||
+ | [ | ||
+ | "CAS", | ||
+ | [ | ||
+ | [1849.21,5805.27,0], | ||
+ | 60, | ||
+ | "B_Heli_Attack_01_F", | ||
+ | "Phantom 1", | ||
+ | "", | ||
+ | "" | ||
+ | ] | ||
+ | ] Call ALiVE_fnc_combatSupportAdd; | ||
+ | </syntaxhighlight> | ||
+ | |} | ||
+ | |||
+ | {| role="presentation" class="wikitable mw-collapsible mw-collapsed" | ||
+ | | <strong>TRANSPORT</strong> | ||
+ | |- | ||
+ | | | ||
+ | <strong>Settings</strong> | ||
+ | {| class="wikitable" | ||
+ | ! index || type || description | ||
+ | |- | ||
+ | | 0 || array || Position of vehicle | ||
+ | |- | ||
+ | | 1 || number || Direction of vehicle | ||
+ | |- | ||
+ | | 2 || string || Classname of vehicle | ||
+ | |- | ||
+ | | 3 || string || Callsign of vehicle (string) | ||
+ | |- | ||
+ | | 4 || string || Code to be ran on vehicle spawn | ||
+ | |- | ||
+ | | 5 || string || Height of vehicle | ||
+ | |- | ||
+ | | 6 || boolean || Allow slingloading | ||
+ | |- | ||
+ | | 7 || number || Number of slingloading boxes to spawn around vehicle | ||
+ | |} | ||
+ | <strong>Example</strong> | ||
+ | <syntaxhighlight lang="php"> | ||
+ | [ | ||
+ | "TRANSPORT", | ||
+ | [ | ||
+ | [26672,24523,0], | ||
+ | 60, | ||
+ | "B_Heli_Transport_01_F", | ||
+ | "VICTOR 1" | ||
+ | "(group (_this select 0)) setVariable ['Vcm_Disable',true]", | ||
+ | "0", | ||
+ | true, | ||
+ | 3 | ||
+ | ] | ||
+ | ] Call ALiVE_fnc_combatSupportAdd; | ||
+ | </syntaxhighlight> | ||
+ | |} | ||
+ | |||
+ | {| role="presentation" class="wikitable mw-collapsible mw-collapsed" | ||
+ | | <strong>ARTY</strong> | ||
+ | |- | ||
+ | | | ||
+ | <strong>Settings</strong> | ||
+ | {| class="wikitable" | ||
+ | ! index || type || description | ||
+ | |- | ||
+ | | 0 || array || Position of vehicle | ||
+ | |- | ||
+ | | 1 || string || Classname of vehicle | ||
+ | |- | ||
+ | | 2 || string || Callsign of vehicle (string) | ||
+ | |- | ||
+ | | 3 || number || Number of vehicles to spawn | ||
+ | |- | ||
+ | | 4 || array || Array of available rounds | ||
+ | |- | ||
+ | | 5 || string || Code to be ran on vehicle spawn | ||
+ | |} | ||
+ | <strong>Example</strong> | ||
+ | <syntaxhighlight lang="php"> | ||
+ | [ | ||
+ | "ARTY", | ||
+ | [ | ||
+ | [21197.36, 7371.373, 0], | ||
+ | "B_MBT_01_arty_F", | ||
+ | "Sholef", | ||
+ | 3, | ||
+ | [ | ||
+ | ["HE", 10], | ||
+ | ["ILLUM", 10], | ||
+ | ["SMOKE", 10], | ||
+ | ["SADARM", 10], | ||
+ | ["CLUSTER", 10], | ||
+ | ["LASER", 10], | ||
+ | ["MINE", 10], | ||
+ | ["AT MINE", 10], | ||
+ | ["ROCKETS", 10] | ||
+ | ], | ||
+ | "" | ||
+ | ] | ||
+ | ] call ALiVE_fnc_combatSupportAdd; | ||
+ | </syntaxhighlight> | ||
+ | |} | ||
+ | |||
+ | === Removing CAS units post-init === | ||
+ | <syntaxhighlight lang="php"> | ||
+ | [_side,_type,_callsign] call ALiVE_fnc_combatSupportRemove; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Example: | ||
+ | <syntaxhighlight lang="php"> | ||
+ | ["WEST","CAS","EAGLE ONE"] call ALiVE_fnc_combatSupportRemove; | ||
+ | |||
+ | ["WEST","TRANSPORT","VICTOR 1"] Call ALiVE_fnc_combatSupportRemove; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | =Third Party Scripts= | ||
+ | |||
+ | === Disable VCOM_AI === | ||
+ | Globally disable VCOM_AI for Air units including Combat Support and Logistics. Put the following in init.sqf | ||
+ | <syntaxhighlight lang="php"> | ||
+ | [{{Driver _x setvariable ["NOAI",true];} foreach (vehicles select {_x isKindOf 'air'});}, 1, []] call CBA_fnc_addPerFrameHandler; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Since VCOM 3.0 you may have to use this instead (in the units init field): | ||
+ | <syntaxhighlight lang="php"> | ||
+ | (group this) setVariable ["Vcm_Disable",true]; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | =Other= | ||
+ | |||
+ | Snippets taken from ALiVE forum posts | ||
+ | |||
+ | Note that these are not guaranteed to work and may be outdated. | ||
+ | |||
+ | |||
+ | === Captured Units and ALiVE === | ||
+ | |||
+ | This will prevent captured prisoners from de-spawning in a trigger area and lower their hostility every 60 minutes (de-spawning bit only works for ACE handcuffs, to use a different system it would have to be replaced) | ||
+ | |||
+ | paste code in init.sqf and replace `prison_marker_or_trigger_name` with the name of a marker or trigger with a size overlapping the area | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | if (isServer) then { | ||
+ | ["ace_captiveStatusChanged", { | ||
+ | params ["_unit", "_state", "_reason"]; | ||
+ | |||
+ | if ((getPos _unit) inArea prison_marker_or_trigger_name) then { | ||
+ | _unit setVariable ["detained", true, true]; | ||
+ | }; | ||
+ | }] call CBA_fnc_addEventHandler; | ||
+ | |||
+ | [{ | ||
+ | [getPos prison_marker_or_trigger_name, [side player], -10] call ALIVE_fnc_updateSectorHostility; | ||
+ | }, 3600, []] call CBA_fnc_addPerFrameHandler; | ||
+ | }; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Detecting ALiVE Events === | ||
+ | |||
+ | Possible Usage: Reward system for players | ||
+ | |||
+ | |||
+ | '''Example 1:''' | ||
+ | |||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | SAV_fnc_taskSucceeded = { | ||
+ | params ["_logic", "_operation", "_args"]; | ||
+ | |||
+ | switch (_operation) do { | ||
+ | case "handleEvent": { | ||
+ | // do your reward stuff here | ||
+ | // task data is in _args | ||
+ | }; | ||
+ | }; | ||
+ | }; | ||
+ | |||
+ | private _listener = [nil, "create"] call ALIVE_fnc_baseClass; | ||
+ | _listener setVariable ["class", SAV_fnc_taskSucceeded]; | ||
+ | |||
+ | private _listenerID = [ALIVE_eventLog, "addListener", [_listener, ["TASK_SUCCEEDED"]]] call ALIVE_fnc_eventLog; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | '''Example 2:''' | ||
+ | |||
+ | |||
+ | In init.sqf | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | _listener = [nil,"create"] call ALiVE_fnc_baseClass; | ||
+ | _listener setVariable ["class","somefunction"]; | ||
+ | |||
+ | _listenerID = [ALiVE_eventLog,"addListener",[_listener, ["OPCOM_CAPTURE"]]] call ALIVE_fnc_eventLog; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Inside a function: | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | params ["_logic","_operation","_args"]; | ||
+ | |||
+ | switch (_operation) do { | ||
+ | case "handleEvent": { | ||
+ | _event = _args; | ||
+ | _id = [_event, "id"] call ALIVE_fnc_hashGet; | ||
+ | _data = [_event, "data"] call ALIVE_fnc_hashGet; | ||
+ | |||
+ | _data params ["_side","_objective"]; // not sure if _objective is an ID or actual objective hash/array | ||
+ | |||
+ | if (_side == "WEST") then { // or whatever side as a string | ||
+ | private _objectiveID = [_objective,"id"] call ALiVE_fnc_hashGet; | ||
+ | private _objectivePos = [_objective,"center"] call ALiVE_fnc_hashGet; | ||
+ | |||
+ | // do magic here | ||
+ | }; | ||
+ | }; | ||
+ | }; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | '''Example 3:''' | ||
+ | |||
+ | |||
+ | Sample from Highhead for init.sqf | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | /////////////////////////////////////////////////////////////////////////////////////////////////// | ||
+ | //Put in init.sqf | ||
+ | //only use on an ALiVE mission with virtual AI module placed | ||
+ | waituntil {!isnil "ALiVE_eventLog"}; | ||
+ | |||
+ | //Leave alone | ||
+ | _fnc_custom = { | ||
+ | |||
+ | //Do not touch that | ||
+ | params ["_logic","_operation","_args"]; | ||
+ | |||
+ | //Also do not touch that | ||
+ | switch (_operation) do { | ||
+ | case "handleEvent": { | ||
+ | _event = _args; | ||
+ | |||
+ | _event params ["_id","_data"]; | ||
+ | _id = [_event, "id"] call ALIVE_fnc_hashGet; | ||
+ | _data = [_event, "data"] call ALIVE_fnc_hashGet; | ||
+ | |||
+ | _data params ["_side","_objective"]; | ||
+ | |||
+ | |||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | ///// | ||
+ | ///// | ||
+ | ///// | ||
+ | //// This is the part you can put your code in | ||
+ | ///// | ||
+ | // | ||
+ | // | ||
+ | /* Example objective data from _objective call ALiVE_fnc_InspectHash; | ||
+ | ---------------- Inspecting Hash -------------------- | ||
+ | k [0]: objectiveID v: OPCOM_2390318919_objective_0 | ||
+ | k [1]: center v: [23334.9,19291.6,0] | ||
+ | k [2]: size v: 50 | ||
+ | k [3]: objectiveType v: MIL | ||
+ | k [4]: priority v: 50 | ||
+ | k [5]: opcom_state v: idle | ||
+ | k [6]: clusterID v: CUSTOM_42626 | ||
+ | k [7]: opcomID v: 2390318919 | ||
+ | k [8]: _rev v: | ||
+ | k [9]: opcom_orders v: none | ||
+ | k [10]: danger v: -1 | ||
+ | k [11]: sectionAssist v: ["BLU_F-entity_12"] | ||
+ | k [12]: section v: ["BLU_F-entity_12"] | ||
+ | k [13]: tacom_state v: reserve | ||
+ | ---------------- Inspection Complete -------------------- | ||
+ | */ | ||
+ | |||
+ | //Get objective id and position | ||
+ | private _objectiveID = [_objective,"objectiveID","empty"] call ALiVE_fnc_hashGet; | ||
+ | private _objectivePos = [_objective,"center",[]] call ALiVE_fnc_hashGet; | ||
+ | |||
+ | //If objective is of side east ("GUER" for resistance) | ||
+ | if (_side == "EAST") then { | ||
+ | ["ALiVE - objective %1 reserved at position %2 side %3 - id %4!",_objectiveID,_objectivePos,_side,_id] call ALiVE_fnc_DumpR; | ||
+ | }; | ||
+ | |||
+ | //// | ||
+ | /////////////////////////////////////////////////////////////////////////// | ||
+ | }; | ||
+ | }; | ||
+ | }; | ||
+ | |||
+ | //Register function | ||
+ | _listener = [nil,"create"] call ALiVE_fnc_baseClass; | ||
+ | _listener setVariable ["class",_fnc_custom]; | ||
+ | |||
+ | //Will always fire the function above if one of the events below is fired | ||
+ | //Possible values are: "OPCOM_RESERVE","OPCOM_RECON","OPCOM_CAPTURE","OPCOM_DEFEND","OPCOM_TERRORIZE" | ||
+ | _listenerID = [ALiVE_eventLog,"addListener",[_listener, ["OPCOM_RESERVE"]]] call ALIVE_fnc_eventLog; | ||
+ | |||
+ | // | ||
+ | /////////////////////////////////////////////////////////////////////////////////////////////////// | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | === CBA Eventhandlers === | ||
+ | |||
+ | |||
+ | Possible Usage - Adding CBA event handlers to spawned units | ||
+ | |||
+ | http://alivemod.com/forum/3582-cba-eventhandlers-not-triggered/0#p24240 | ||
+ | |||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | if !(hasInterface or isServer) then { | ||
+ | ["All", "Hit", {_this call alive_fnc_handleHit;}] call CBA_fnc_addClassEventHandler; | ||
+ | ["All", "Killed", {_this call alive_fnc_handleKill;}] call CBA_fnc_addClassEventHandler; | ||
+ | } else { | ||
+ | ["CAManBase", "Fired", {_this call alive_fnc_handleFired;}] call CBA_fnc_addClassEventHandler; | ||
+ | ["CAManBase", "Respawn", {_this call alive_fnc_handleRespawn;}] call CBA_fnc_addClassEventHandler; | ||
+ | }; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | === Finding if a particular profiled unit is alive === | ||
+ | |||
+ | "Any way I can detect whether he is alive when he is profiled but not actually spawned?" | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | sb_fnc_profileExists = { | ||
+ | private _profileID = _this; | ||
+ | |||
+ | private _profile = [ALiVE_sysProfile,"getProfile", _profileID] call ALiVE_fnc_hashGet; | ||
+ | |||
+ | !(isnil "_profile") | ||
+ | }; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | You can determine the profileID using many ways. If you create the profile directly using one of our functions listed on the wiki then it will return either the profileID or the profile hash which can be used to grab the ID. You can also use our ALiVE_fnc_getNearProfiles directly on the man's position and give it a small radius so it only finds the desired profile. | ||
+ | If you have the unit object after the unit has been profiled already, you can grab the ID of the profile he belongs to using: | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | private _unitObject = ...; | ||
+ | private _profileID = _unitObject getvariable ["profileID", ""]; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Persist ACEX Fortify Objects === | ||
+ | In initServer.sqf (or wherever you choose to execute server-only code): | ||
+ | |||
+ | <syntaxhighlight lang="php"> | ||
+ | ["acex_fortify_objectPlaced", { | ||
+ | [ALiVE_SYS_LOGISTICS, "updateObject", [(_this select 2)]] call ALIVE_fnc_logistics; | ||
+ | }] call CBA_fnc_addEventHandler; | ||
+ | |||
+ | ["acex_fortify_objectDeleted", { | ||
+ | [ALiVE_SYS_LOGISTICS, "removeObject", [(_this select 2)]] call ALIVE_fnc_logistics; | ||
+ | }] call CBA_fnc_addEventHandler; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | If you choose to make this event handler client side, be sure to make it only be triggered by the user that moved the object. |
Latest revision as of 07:57, 7 June 2020
Profiles
Spawn & Profile Group Script By Jman
/* Filename: fnc_spawnProfileGroup.sqf Locality: Runs on server Description: Spawns a group faction and sends them to a waypoint. Params: * _spawnPosition -> Array. Position to spawn group * _spawnExactLocation -> Boolean. Set to false if you want to spawn it in an exact position. * _destinationPosition -> Array. Position of waypoint destination. * _group -> String. CfgGroups name * _faction -> String. CfgGroups faction Optional Params: * _debug -> Boolean. Enable debug output * _waypointPlacementRadius -> Scalar. Random placement radius. http://community.bistudio.com/wiki/Mission_Editor:_Waypoints#Placement_Radius * _waypointType -> String. Type of waypoint. NOTE: at the moment only MOVE is supported by the profiler. http://community.bistudio.com/wiki/Mission_Editor:_Waypoints#Select_Type * _waypointMovement -> String. Speed of waypoint movement. http://community.bistudio.com/wiki/Mission_Editor:_Waypoints#Speed * _waypointCompletionRadius -> Scalar. Completion radius of waypoint. http://community.bistudio.com/wiki/Mission_Editor:_Waypoints#Completion_Radius * _waypointTimeoutCounters -> Array. Timeout counters. http://community.bistudio.com/wiki/Mission_Editor:_Waypoints#Timeout_Counters * _waypointFormation -> String. Formation type. http://community.bistudio.com/wiki/Mission_Editor:_Waypoints#Formation * _waypointCombatMode -> String. Combat mode. http://community.bistudio.com/wiki/Mission_Editor:_Waypoints#Combat_Mode * _waypointBehaviour -> String. Behaviour type. http://community.bistudio.com/wiki/Mission_Editor:_Waypoints#Behaviour * _waypointDescription -> String. Description. http://community.bistudio.com/wiki/Mission_Editor:_Waypoints#Description * Usage: init.sqf: * ALIVE_spawnProfileGroup = compile (preprocessFileLineNumbers "fnc_spawnProfileGroup.sqf"); Create a trigger or call in script: Syntax: [array, boolean, array, string, string, boolean, scalar, string, string, scalar, array, string, string, string, string] call ALIVE_spawnProfileGroup; Example(s): * [getMarkerPos "nmeGrp01_spawn_pos", false, getMarkerPos "nmeGrp01_dest_pos", "10_men_ME", "caf_ag_me"] call ALIVE_spawnProfileGroup; * [getMarkerPos "nmeGrp01_spawn_pos", false, getMarkerPos "nmeGrp01_dest_pos", "10_men_ME", "caf_ag_me", true, 0, "Move", "Full", 0, [0,0,0], "Wedge", "Red", "Aware", ""] call ALIVE_spawnProfileGroup; Credits: ALiVE functions: The ALiVE team. Web: http://www.alivemod.com * Script Created by [KH]Jman * Creation date: 06/02/2014 * Email: [email protected] * Web: http://www.kellys-heroes.eu */ // ==================================================================================== if (!isServer) exitWith {}; // ==================================================================================== // SCOPE ------------------------------------------------------------------------------------- private["_spawnposition","_spawnExactLocation","_destinationPosition","_faction","_profile","_profiles","_profileWaypoint","_group","_debug", "_waypointPlacementRadius","_waypointType","_waypointMovement","_waypointCompletionRadius","_waypointTimeoutCounters","_waypointFormation", "_waypointCombatMode","_waypointBehaviour","_waypointDescription","_groupName", "_groupName","_config"]; _config = []; // SCOPE ------------------------------------------------------------------------------------- waitUntil {!isNil "ALIVE_profileSystemInit"}; // PARMS ------------------------------------------------------------------------------------- _spawnPosition = _this select 0; _spawnExactLocation = _this select 1; _destinationPosition = _this select 2; _group = _this select 3; _faction = _this select 4; _debug = if(count _this > 5) then {_this select 5} else {false}; _waypointPlacementRadius = if(count _this > 6) then {_this select 6} else {0}; _waypointType = if(count _this > 7) then {_this select 7} else {"Move"}; _waypointMovement = if(count _this > 8) then {_this select 8} else {"Full"}; _waypointCompletionRadius = if(count _this > 9) then {_this select 9} else {0}; _waypointTimeoutCounters = if(count _this > 10) then {_this select 10} else {[0,0,0]}; _waypointFormation = if(count _this > 11) then {_this select 11} else {"Wedge"}; _waypointCombatMode = if(count _this > 12) then {_this select 12} else {"Red"}; _waypointBehaviour = if(count _this > 13) then {_this select 13} else {"Aware"}; _waypointDescription = if(count _this > 14) then {_this select 14} else {""}; // PARMS ------------------------------------------------------------------------------------- // DEBUG ------------------------------------------------------------------------------------- if(_debug) then { ["ALIVE_spawnProfileGroup -> _spawnPosition: %1, _spawnExactLocation: %2, _destinationPosition: %3, _group: %4, _faction: %5, _debug: %6, _waypointPlacementRadius: %7, _waypointType: %8, _waypointMovement: %9, _waypointCompletionRadius: %10, _waypointTimeoutCounters: %11, _waypointFormation: %12, _waypointCombatMode: %13, _waypointBehaviour: %14, _waypointDescription: %15,", _spawnPosition,_spawnExactLocation,_destinationPosition,_group,_faction,_debug,_waypointPlacementRadius, _waypointType,_waypointMovement,_waypointCompletionRadius,_waypointTimeoutCounters,_waypointFormation,_waypointCombatMode, _waypointBehaviour,_waypointDescription] call ALIVE_fnc_dump; }; // DEBUG ------------------------------------------------------------------------------------- // MAIN ------------------------------------------------------------------------------------- _profiles = [_group, _spawnposition, random(360), _spawnExactLocation, _faction] call ALIVE_fnc_createProfilesFromGroupConfig; if(_debug) then { ["ALIVE_spawnProfileGroup -> _groupData: %1, _config: %2, _groupName: %3", _groupData, _config, _groupName] call ALIVE_fnc_dump; }; _profileWaypoint = [_destinationPosition, _waypointPlacementRadius, _waypointType, _waypointMovement, _waypointCompletionRadius, _waypointTimeoutCounters,_waypointFormation, _waypointCombatMode, _waypointBehaviour, _waypointDescription] call ALIVE_fnc_createProfileWaypoint; { _profile = _x;_profileType = _profile select 2 select 5; if(_profileType == "entity") then {[_profile, "addWaypoint", _profileWaypoint] call ALIVE_fnc_profileEntity;}; } forEach _profiles; // MAIN ------------------------------------------------------------------------------------- // ====================================================================================
Detect Virtual Units (Profiles) in a Trigger Area
Will be true if there are virtualized AI groups of side EAST (string) within 50 mtrs of the triggers position EAST
((count ([getposATL thisTrigger, 50, ["EAST","entity"]] call ALIVE_fnc_getNearProfiles)) > 0);
Will be true if there are virtualized vehicles of side EAST (string) within 500 mtrs of trigger position EAST
((count ([getposATL thisTrigger, 500, ["EAST","vehicle"]] call ALIVE_fnc_getNearProfiles)) > 0);
Example: Place this line of code in the condition field of an end mission (f.e. lose) trigger, optionally with timeout. It will fire when there are virtualized groups in the selected area (for a certain amount of time). It doesnt matter if they are spawned or not.
Profiling all non profiled units on the map
You can trigger the profiler to profile all non profiled units (handy for MCC and Zeus or scripts that spawn units during gameplay). This function needs to be called on the server locality after a short pause to enable ALiVE to finish initialising:
if (isServer) then { [] spawn { while {true} do { sleep 60; [] call ALiVE_fnc_createProfilesFromUnitsRuntime; }; }; };
Adding Custom Inits to Spawned Units
The following is one method for adding custom scripts to every spawned unit or object of that class, for example running a script that adds custom gear to a class of units. This will work for units spawned with MP/MCP, the Profiles system and any other spawning method such as Zeus.
HEALTH WARNING: you will need to know the basics of scripting to setup the gear script so it only applies to AI (and not players) or specific factions. Place the following in description.ext and create my_code.sqf with whatever code you want to add to the spawned units. Also be aware that anything added to player units will duplicate if player persistence is on, so it's better to use regular methods for players (or include isPlayer check in your script).
class Extended_Init_EventHandlers { class Man { init = "_this call (compile preprocessFileLineNumbers 'my_script.sqf')"; }; };
This is an example my_script.sqf thanks to SpyderBlack723 on the BI Forums:
private "_this"; _this = _this select 0; if ((side _this == west) and (!isPlayer _this)) then { removeallweapons _this; removeGoggles _this;removeHeadgear _this;removeVest _this;removeUniform _this;removeAllAssignedItems _this;removeBackpack _this; _this addHeadgear 'Helmet_ACU';_this addUniform 'Uniform_ACU';_this addVest 'Vest_ACU';_this addBackPack 'ACU_Backpack'; { _this addItemToBackpack"rhs_mag_30Rnd_556x45_M855A1_Stanag"; } forEach [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,18, 19, 20, 21]; { _this addItemToBackpack "rhs_mag_m67"; } forEach [1, 2, 3, 4]; { _this addItemToBackpack "SmokeShell"; } forEach [1, 2, 3, 4]; { _this addItem "FirstAidKit"; } forEach [1, 2, 3, 4, 5]; _this addweapon 'rhs_m4_grip_acog';_this addPrimaryWeaponItem 'rhsusf_acc_ACOG';_this linkItem "ItemMap"; };
Profile Counter
Great for debugging your missions. Counts all profiles for all sides.
if (isServer) then { _profilesBySide = [ALiVE_profileHandler,"profilesBySide"] call ALIVE_fnc_hashGet; _profilesBySide = _profilesBySide select 2; systemchat format ["Profile Count OPFOR - %1", count (_profilesBySide select 0)]; systemchat format ["Profile Count BLUFOR - %1", count (_profilesBySide select 1)]; systemchat format ["Profile Count INDEPENDANT - %1", count (_profilesBySide select 2)]; };
Spawning player group AI members after persistent save
If you use the ALiVE saving feature one 'issue' is that AI members in the player's group do not get saved or restored. If they are editor-placed units then they will spawn at their original editor start location instead of wherever the player is. To work around this do the following:
Place the following code at the bottom of your mission's init.sqf file:
waituntil {(player getvariable ["alive_sys_player_playerloaded",false])}; sleep 2; { if !(isPlayer _x) then { if !(_x getVariable ["Persistent_Teleport", false]) then { _x setPos (getPos player); _x setVariable ["Persistent_Teleport", true, true]; sleep .5; }; }; } forEach units group player;
OPCOM
Add a Custom OPCOM Objective
This will register a position as an objective to all OPCOMs in the current mission.
Parameters: select 0: _id (String); select 1: _position (Array); select 2: _size (Integer); select 3: _type (String of "MIL" or "CIV"); select 4: _priority (Integer); Code: if (isServer) then {{[_x,"addObjective", ["OPCOM_custom_1", [25657.2,22175.8,0.00129318], 100, "MIL", 200] ] call ALiVE_fnc_OPCOM; } foreach OPCOM_INSTANCES};
Example: Place these lines of code (without the comments) in the on activation field of a "detected by..."-trigger (500mtrs radius). As the trigger fires your base will be registered to all OPCOMs, who will then send troops there (either to attack or defend). You can use these in combination with triggers and tasks. For example if you are detected by a trigger within a certain radius of your base, your base will be registered to OPCOM! OPCOMs will send their troops there and if you don't manage to defend your base the mission will fail.
This little gem comes from Cameroon on the BI Forum. It enables you to set a custom objective on the fly for one side only. The first parameter is an array that is passed straight to ALiVE_fnc_OPCOM - set it as you would when calling addObjective. The second argument is an array of strings for the factions that should get the objective.
It's worth noting that the OPCOM may not immediately notice the new objective and of course it's still prioritized so there might not be any units to send. Also, if you have a marker with the same name as the first argument ("opfoComRetake_obj"), ALIVE will take it over. It is recommended that you do not use a marker name same as the objective name.
Example:[["opforComRetake_obj", getMarkerPos "opforComRetake", 200,"MIL"],["EAST"]] call cjb_addObjectiveToSides;
cjb_addObjectiveToSides = { private["_objectiveParams","_factions","_faction","_opcom","_opcomSide"]; _objectiveParams = _this select 0; _factions = _this select 1; { _opcom = _x; { _faction = _x; _opcomSide = [_opcom,"side",""] call ALiVE_fnc_HashGet; if( _opcomSide == _faction) then { [_opcom, "addObjective", _objectiveParams] call ALiVE_fnc_OPCOM; }; } forEach _factions; } forEach OPCOM_INSTANCES; };
Assign a Custom Group & Vehicle to OPCOM
[your_editor_unit, your_editor_vehicle] spawn ALiVE_fnc_createProfileVehicleAssignment
Can either have an object or a hash passed to it. Note that if OPCOM already has enough groups it may take some time until it uses the newly assigned groups.
For example:
_customVehicleAssignments = [[leader1,vehicle1]]; { _leader = _x select 0; _vehicle = _x select 1; _group = group _leader; [_group, _vehicle, true] call ALIVE_fnc_vehicleAssignGroup; } forEach _customVehicleAssignments; };
Jump To The Action!
ALiVE_fnc_JoinNearestGroup will select the most important objective that is currently being attacked/defended by your forces and join you to an AI group that is on an assault or defend mission. This will send you directly into the action! Execute the function locally on any player client. Possible params are "attacking" or "defending".
[player,"attacking"] call ALiVE_fnc_OPCOMjoinNearestGroup
ALiVE_fnc_OPCOMJoinObjective will display all objectives that are currently being attacked/defended, lets you select the objective of choice and HALO drops your group to an AI group that is currently ordered to assault/defend this objective! Execute the function locally on any player client. Possible params are "attacking" or "defending".
[player,"attacking"] call ALiVE_fnc_OPCOMjoinObjective
Example: put in the Init field of a unit or object in editor
this addAction ["Select Assault Mission",{[_this select 1,"attacking"] call ALiVE_fnc_OPCOMJoinObjective},[],1,false,true,"","true"];
Compositions
Add Custom Roadblock to Civ placement
1.0 Release includes the ability to add custom roadblocks. Define your custom roadblocks at init on the server:
ALIVE_compositions_roadblocks = ["YOUR_ROADBLOCK_CLASS1","YOUR_ROADBLOCK_CLASS2",etc];
Spawning a Custom Composition via Script
Use the following function:
Function: ALIVE_fnc_spawnRandomPopulatedComposition Description: Spawn a composition Spawns a random populated composition Parameters: Position - Array Type - String - Civilian, Military, Guerrilla Category - String Civilian Categories - airports, checkpointsbarricades, construction, constructionSupplies, communications, fuel, general, heliports, industrial, marine, mining_oil, power, rail, settlements Guerrilla Categories - camps, checkpointsbarricades, constructionsupplies, commnunications, fieldhq, fort, fuel, hq, marine, medical, outposts, power, supports Military Categories - airports, camps, checkpointsbarricades, constructionsupplies, communications, crashsites, fieldhq, fort, fuel, heliports, hq, marine, medical, outposts, power, supports, supplies Faction - String (OPTIONAL) Size - String (Large, Medium, Small, ANY) Infantry groups - Integer (OPTIONAL) Mot Groups - Integer (OPTIONAL) Mech Groups - Integer (OPTIONAL) Armoured Groups - Integer (OPTIONAL) SpecOps Groups - Integer (OPTIONAL) Returns: None Examples: // spawn a small fortification composition with 2 OPF_F groups _result = [_position, "Military", "Fort", "OPF_F", "Small", 2] call ALIVE_fnc_spawnRandomPopulatedComposition;
Modules
Wait for Player Persistence to Initialise
Will wait until the persistent data of a player has been loaded (place in init.sqf f.e.)
waituntil {(player getvariable ["alive_sys_player_playerloaded",false])};
Example: Use this in init.sqf if you have a player-depended scripts and use "player persistence";
Pausing Modules
Use the following code on the server to pause and un pause modules completely. Pausing sys_profile will stop all simulation of profiles, and prevent spawning / despawning. Pausing OPCOM will stop OPCOM from issuing orders and running battlefield analysis. Pausing civ_population will stop all civilian AI commands and prevent spawning / despawning.
Pause and unpause the profile system
["ALIVE_SYS_PROFILE"] call ALiVE_fnc_pauseModule; ["ALIVE_SYS_PROFILE"] call ALiVE_fnc_unPauseModule;
Pause and unpause a whole lot of modules
["ALIVE_SYS_PROFILE","ALIVE_MIL_OPCOM","ALIVE_AMB_CIV_POPULATION","ALIVE_MIL_LOGISTICS","ALIVE_SYS_AISKILL"] call ALiVE_fnc_pauseModule; ["ALIVE_SYS_PROFILE","ALIVE_MIL_OPCOM","ALIVE_AMB_CIV_POPULATION","ALIVE_MIL_LOGISTICS","ALIVE_SYS_AISKILL"] call ALiVE_fnc_unPauseModule;
This is an example script from dixon13 on our forums for automatically pausing OPCOM when players disconnect using initServer.sqf (see BI Community Wiki for further details on using init event scripts)
["someId", "onPlayerConnected", { if (({isPlayer _x} count playableUnits) > 0 || OPCOM_TOGGLE) then { ["ALIVE_MIL_OPCOM"] call ALiVE_fnc_unPauseModule; OPCOM_TOGGLE = false; }; }] call BIS_fnc_addStackedEventHandler; ["someId", "onPlayerDisconnected", { if ( ({isPlayer _x} count playableUnits) == 0 ) then { ["ALIVE_MIL_OPCOM"] call ALiVE_fnc_pauseModule; OPCOM_TOGGLE = true; }; }] call BIS_fnc_addStackedEventHandler;
Adjust Logistics Force Pool
Military Logistics and the Player Resupply module both work from the Global Force Pool to establish the allowed reinforcement levels for a faction. You can adjust this value on the fly in your own missions to add or remove from the global force pool. If running on a dedicated server, this must be performed on the server side only.
if(isServer) then { // example: get the global force pool count for the BLU_F faction _currentBLUFORForcepool = [ALIVE_globalForcePool,"BLU_F"] call ALIVE_fnc_hashGet; // example: alter the current BLU_F force pool [ALIVE_globalForcePool,"BLU_F",20] call ALIVE_fnc_hashSet; };
Adjust Force Size post init
Specify side (side== xxxx) and number of each group/profile type. Fire the code via script, trigger etc and the OPCOM will now have force cap set to those values and bring in "replacements" to get up to strength.
{ private _side = [_x, "side", ""] call ALIVE_fnc_hashGet; if (_side == "WEST") then { [ _x, "startForceStrength", [ 0, // Infantry 0, // Motorized 0, // Mechanized 0, // Armored 0, // Artillery 0, // AAA 0, // Air 0 // Sea ] ] call ALIVE_fnc_hashSet; }; } forEach OPCOM_INSTANCES;
Add Custom Variables to ALiVE Database
0.9.8 Release includes the ability to save and retrieve custom values to the ALiVE database using the following funcs:
["key", _value] call ALiVE_fnc_setData _value = ["key"] call ALiVE_fnc_getData
Adding CAS units post-init
[_type, _settings] call ALiVE_fnc_combatSupportAdd; _type - The type of combat support, can be "CAS", "TRANSPORT" or "ARTY" _settings - Array of settings
CAS | |||||||||||||||||||||
Settings
Example [ "CAS", [ [1849.21,5805.27,0], 60, "B_Heli_Attack_01_F", "Phantom 1", "", "" ] ] Call ALiVE_fnc_combatSupportAdd; |
TRANSPORT | |||||||||||||||||||||||||||
Settings
Example [ "TRANSPORT", [ [26672,24523,0], 60, "B_Heli_Transport_01_F", "VICTOR 1" "(group (_this select 0)) setVariable ['Vcm_Disable',true]", "0", true, 3 ] ] Call ALiVE_fnc_combatSupportAdd; |
ARTY | |||||||||||||||||||||
Settings
Example [ "ARTY", [ [21197.36, 7371.373, 0], "B_MBT_01_arty_F", "Sholef", 3, [ ["HE", 10], ["ILLUM", 10], ["SMOKE", 10], ["SADARM", 10], ["CLUSTER", 10], ["LASER", 10], ["MINE", 10], ["AT MINE", 10], ["ROCKETS", 10] ], "" ] ] call ALiVE_fnc_combatSupportAdd; |
Removing CAS units post-init
[_side,_type,_callsign] call ALiVE_fnc_combatSupportRemove;
Example:
["WEST","CAS","EAGLE ONE"] call ALiVE_fnc_combatSupportRemove; ["WEST","TRANSPORT","VICTOR 1"] Call ALiVE_fnc_combatSupportRemove;
Third Party Scripts
Disable VCOM_AI
Globally disable VCOM_AI for Air units including Combat Support and Logistics. Put the following in init.sqf
[{{Driver _x setvariable ["NOAI",true];} foreach (vehicles select {_x isKindOf 'air'});}, 1, []] call CBA_fnc_addPerFrameHandler;
Since VCOM 3.0 you may have to use this instead (in the units init field):
(group this) setVariable ["Vcm_Disable",true];
Other
Snippets taken from ALiVE forum posts
Note that these are not guaranteed to work and may be outdated.
Captured Units and ALiVE
This will prevent captured prisoners from de-spawning in a trigger area and lower their hostility every 60 minutes (de-spawning bit only works for ACE handcuffs, to use a different system it would have to be replaced)
paste code in init.sqf and replace `prison_marker_or_trigger_name` with the name of a marker or trigger with a size overlapping the area
if (isServer) then { ["ace_captiveStatusChanged", { params ["_unit", "_state", "_reason"]; if ((getPos _unit) inArea prison_marker_or_trigger_name) then { _unit setVariable ["detained", true, true]; }; }] call CBA_fnc_addEventHandler; [{ [getPos prison_marker_or_trigger_name, [side player], -10] call ALIVE_fnc_updateSectorHostility; }, 3600, []] call CBA_fnc_addPerFrameHandler; };
Detecting ALiVE Events
Possible Usage: Reward system for players
Example 1:
SAV_fnc_taskSucceeded = { params ["_logic", "_operation", "_args"]; switch (_operation) do { case "handleEvent": { // do your reward stuff here // task data is in _args }; }; }; private _listener = [nil, "create"] call ALIVE_fnc_baseClass; _listener setVariable ["class", SAV_fnc_taskSucceeded]; private _listenerID = [ALIVE_eventLog, "addListener", [_listener, ["TASK_SUCCEEDED"]]] call ALIVE_fnc_eventLog;
Example 2:
In init.sqf
_listener = [nil,"create"] call ALiVE_fnc_baseClass; _listener setVariable ["class","somefunction"]; _listenerID = [ALiVE_eventLog,"addListener",[_listener, ["OPCOM_CAPTURE"]]] call ALIVE_fnc_eventLog;
Inside a function:
params ["_logic","_operation","_args"]; switch (_operation) do { case "handleEvent": { _event = _args; _id = [_event, "id"] call ALIVE_fnc_hashGet; _data = [_event, "data"] call ALIVE_fnc_hashGet; _data params ["_side","_objective"]; // not sure if _objective is an ID or actual objective hash/array if (_side == "WEST") then { // or whatever side as a string private _objectiveID = [_objective,"id"] call ALiVE_fnc_hashGet; private _objectivePos = [_objective,"center"] call ALiVE_fnc_hashGet; // do magic here }; }; };
Example 3:
Sample from Highhead for init.sqf
/////////////////////////////////////////////////////////////////////////////////////////////////// //Put in init.sqf //only use on an ALiVE mission with virtual AI module placed waituntil {!isnil "ALiVE_eventLog"}; //Leave alone _fnc_custom = { //Do not touch that params ["_logic","_operation","_args"]; //Also do not touch that switch (_operation) do { case "handleEvent": { _event = _args; _event params ["_id","_data"]; _id = [_event, "id"] call ALIVE_fnc_hashGet; _data = [_event, "data"] call ALIVE_fnc_hashGet; _data params ["_side","_objective"]; /////////////////////////////////////////////////////////////////////////// ///// ///// ///// //// This is the part you can put your code in ///// // // /* Example objective data from _objective call ALiVE_fnc_InspectHash; ---------------- Inspecting Hash -------------------- k [0]: objectiveID v: OPCOM_2390318919_objective_0 k [1]: center v: [23334.9,19291.6,0] k [2]: size v: 50 k [3]: objectiveType v: MIL k [4]: priority v: 50 k [5]: opcom_state v: idle k [6]: clusterID v: CUSTOM_42626 k [7]: opcomID v: 2390318919 k [8]: _rev v: k [9]: opcom_orders v: none k [10]: danger v: -1 k [11]: sectionAssist v: ["BLU_F-entity_12"] k [12]: section v: ["BLU_F-entity_12"] k [13]: tacom_state v: reserve ---------------- Inspection Complete -------------------- */ //Get objective id and position private _objectiveID = [_objective,"objectiveID","empty"] call ALiVE_fnc_hashGet; private _objectivePos = [_objective,"center",[]] call ALiVE_fnc_hashGet; //If objective is of side east ("GUER" for resistance) if (_side == "EAST") then { ["ALiVE - objective %1 reserved at position %2 side %3 - id %4!",_objectiveID,_objectivePos,_side,_id] call ALiVE_fnc_DumpR; }; //// /////////////////////////////////////////////////////////////////////////// }; }; }; //Register function _listener = [nil,"create"] call ALiVE_fnc_baseClass; _listener setVariable ["class",_fnc_custom]; //Will always fire the function above if one of the events below is fired //Possible values are: "OPCOM_RESERVE","OPCOM_RECON","OPCOM_CAPTURE","OPCOM_DEFEND","OPCOM_TERRORIZE" _listenerID = [ALiVE_eventLog,"addListener",[_listener, ["OPCOM_RESERVE"]]] call ALIVE_fnc_eventLog; // ///////////////////////////////////////////////////////////////////////////////////////////////////
CBA Eventhandlers
Possible Usage - Adding CBA event handlers to spawned units
http://alivemod.com/forum/3582-cba-eventhandlers-not-triggered/0#p24240
if !(hasInterface or isServer) then { ["All", "Hit", {_this call alive_fnc_handleHit;}] call CBA_fnc_addClassEventHandler; ["All", "Killed", {_this call alive_fnc_handleKill;}] call CBA_fnc_addClassEventHandler; } else { ["CAManBase", "Fired", {_this call alive_fnc_handleFired;}] call CBA_fnc_addClassEventHandler; ["CAManBase", "Respawn", {_this call alive_fnc_handleRespawn;}] call CBA_fnc_addClassEventHandler; };
Finding if a particular profiled unit is alive
"Any way I can detect whether he is alive when he is profiled but not actually spawned?"
sb_fnc_profileExists = { private _profileID = _this; private _profile = [ALiVE_sysProfile,"getProfile", _profileID] call ALiVE_fnc_hashGet; !(isnil "_profile") };
You can determine the profileID using many ways. If you create the profile directly using one of our functions listed on the wiki then it will return either the profileID or the profile hash which can be used to grab the ID. You can also use our ALiVE_fnc_getNearProfiles directly on the man's position and give it a small radius so it only finds the desired profile. If you have the unit object after the unit has been profiled already, you can grab the ID of the profile he belongs to using:
private _unitObject = ...; private _profileID = _unitObject getvariable ["profileID", ""];
Persist ACEX Fortify Objects
In initServer.sqf (or wherever you choose to execute server-only code):
["acex_fortify_objectPlaced", { [ALiVE_SYS_LOGISTICS, "updateObject", [(_this select 2)]] call ALIVE_fnc_logistics; }] call CBA_fnc_addEventHandler; ["acex_fortify_objectDeleted", { [ALiVE_SYS_LOGISTICS, "removeObject", [(_this select 2)]] call ALIVE_fnc_logistics; }] call CBA_fnc_addEventHandler;
If you choose to make this event handler client side, be sure to make it only be triggered by the user that moved the object.