Arma scripting can be finicky and make no sense unless you’re experienced with it. Luckily, Bohemia has a wiki full of documentation of mixed quality on many functions or commands you can use in scripts. Never be afraid to google what you need and just throw it into a test mission to learn it.
If you find a script that does something cool, crack it open. Don’t copy the code if it wasn’t meant to be copied. Instead, examine it and figure out how it works. You’ll learn a lot about scripting in Arma, and will probably avoid having your missions fail because the script you ripped from something else didn’t work.
<marker name='MARKERVARIABLE'>Text</marker>
Place this inside of a briefing with a marker variable name in the proper position will make the briefing “hyperlink” to the marker when clicked in the mission. Very useful for quality of life when people are using in-game briefings.
<img image='picture.jpg' width='200' height='200'/>
To add pictures to a section of your briefing, simply put the picture in the mission folder, and then add this script in your briefing where you want to picture to appear, replacing picture.jpg with your picture's filename, and the width and height values with your own values.
respawn_west = createMarker ["respawn_west", position player];
Use the Zeus Code Execution module in Zeus Enhanced to create this marker mid-mission. This is a useful line if you forgot to create a respawn marker when making your mission, but you still have the respawn attributes set up properly.
"respawn_west" setMarkerPos (getMarkerPos "changeSpawn_1");
Making your respawn marker move mid-mission is easy and useful. Using the above code, “respawn_west” will move to the position of a marker named “changeSpawn_1”.. Using an Empty marker will allow you to do this without filling the map screen with markers that aren’t relevant. Interestingly, you have to make sure both marker names are in quotation marks for this code. It can be modified to move other positions or markers too.
_leaderName = leader group _player;
_respawnPos = format["respawn_%1", _leaderName];
_respawnPos setMarkerPos (getPos _player);
Arma knows that it should look in a specific order for respawns. Killzone Kid has a good list for how it works located here. In this case, we are fixing a problem that can occur if you use respawn_groupleader and the normal group leader is not in the mission when the marker is made. This will grab the current group leader so that units can spawn. It could be run on the init of units so that when the actual group leader joins, it properly updates the respawn. It still may require some tweaking to get working.
this addEventHandler ["Respawn", {
player moveInCargo vehRespawn;
}];
Placing this in the init of a unit will make it so upon respawn they will move to the passenger seats of a vehicle with the variable name “vehRespawn”. If this vehicle explodes it can sometimes cause issues, but if it respawns via a module, it will continue to work properly.
"respawn_west" setMarkerPosLocal [markerPos "respawn_west" select 0, markerPos "respawn_west" select 1, 52.5];
Adding this to your “initPlayerLocal.sqf” will change the height of your respawn marker, which is especially useful for player respawns on aircraft carriers. In this example “52.5” is the height of the respawn. To find altitude, place an object on the deck of the ship (or whatever you want players to spawn on), open the attributes, find the “Z” value, and add 0.5 to avoid clipping.
_randomElement = selectRandom[1,2,3,4,5];
sleep 5;
titleText [ _randomElement ,"PLAIN"];
titleFadeOut 14;
sleep 16;
cutText ["", "BLACK IN", 1];
Putting this in onPlayerKilled will make it so the player’s screen, which is black at this point, will display text that is selected randomly. “titleFadeOut” time adjusts how quickly the text fades, while the second “sleep” statement will decide how long the black screen stays before fading to reality. Replace the numbers in “_randomElement” with strings of your quotes.
class CfgMusic
{
sounds[] = {01,02};
class 01
{
name = "01";
sound[] = {"music\sound1.ogg", db+10, 1.0};
titles[] = {0,""};
};
class 02
{
name = "02";
sound[] = {"music\sound2.ogg", db+10, 1.0};
titles[] = {0,""};
};
};
To add music to a mission, you must first find the music you want as a .ogg file, I use This Site to convert MP3s to .OGGs, and to compress the .ogg files to a more manageable size. Create a folder in the mission file named Music, and add your .ogg files to that folder. In the example code above, there are two files named sound1 and sound2. In game, the songs will appear named 01 and 02. These songs can now be activated by a trigger, script, or any other method of playing music in Arma.
Babel can be customized via scripting to change the name of languages from things like “BLUFOR” to “English”. It can also assign translators to people via scripting, and, if you’re not that lazy, you can assign two different languages to people on the same side. This section will quickly go through how it all works.
["en", "English"] call acre_api_fnc_babelAddLanguageType;
["fr", "French"] call acre_api_fnc_babelAddLanguageType;
["ru", "Russian"] call acre_api_fnc_babelAddLanguageType;
["af", "Afrikaans"] call acre_api_fnc_babelAddLanguageType;
The code above is how you “create” languages. So, if you want to include Afrikaans, you need to call that line of code in your init.sqf or equivalent. You can create any language you want. The two letters before the name of the language are just used by ACRE to refer to it in future scripts.
[ [west, "English", "French"], [east, "Russian", "Afrikaans"], [civilian, "French", "Afrikaans"] ] call acre_api_fnc_babelSetupMission;
This code will assign languages based on sides. In this example, it gives ALL players on the BLUFOR side “English” and “French”, ALL players on the OPFOR side “Russian” and “Afrikaans”, and ALL players on the CIVILIAN side “French” and “Afrikaans”. This can be used to do essentially what the module does, but just with a bit more customization.
["en", "fr", "af"] call acre_api_fnc_babelSetSpokenLanguages;
This code can be used for translators or to assign different languages to a side. Use the above code in the INIT of the unit. In this case, the translator will be able to speak three languages: English, French, and Afrikaans. This is where those two letter abbreviations are used. Keep in mind this will OVERWRITE the languages assigned by side. So, in the above example of a BLUFOR translator, I need to still assign it English in this code.
call{this && ({_x isKindOf "Air"} count thisList != Count thislist)}
Placing this code in the condition of a trigger should make it so air is not able to activate the trigger. This can be helpful for triggers that air might accidentally hit.
this forceFlagTexture "flags\FLAGNAME.paa"
Make a new folder named “flags” in your root folder. Copy the PAA files from this ZIP into the “flags” folder. Placing the above code into the init of the vehicle will result in that vehicle flying said flag when it’s initialized (with some exceptions; Always test before publishing your mission!).
If you want the flag to reapply on respawn, in your respawn module the same code into the expression field, but replace “this” with “(_this select 0)” so that it applies on respawn. If you want to use it in a script, you’re probably smart enough to figure out where to put it already.
ACE_maxWeightCarry = 3500;
ACE_maxWeightDrag = 5000;
Put the above code into the player init of every player you want to be able to carry the heavy items. Simple enough, but it makes it possible to have a Logistics team with large crates.
To use RHS's paaradrop WP without RHS, place the move waypoints for your plane, place a scripted waypoint where you want your paradrop to start, in the On Activation Field, put:
[yourplanevariable] execVM "infParadrop.sqf";
Make sure to place a move waypoint after the paradrop.
Place this into your mission folder
TCS_var_individualTickets = TCS_var_individualTickets + amount;
TCS_var_eastTickets = TCS_var_eastTickets + amount;
Replace “east” in the line with “west”, “independent”, or “civilian”.
"End1" call BIS_fnc_endMissionServer
“End1” can be replaced by any class name in “CfgDebriefing.hpp”.
regroupPoints = 0;
publicVariable "regroupPoints";
_condition = {
(regroupPoints < 3) && (backpack _player) == "B_RadioBag_01_wdl_F"
};
_statement = {
"respawn_guerrila" setMarkerPos (getPos _player);
regroupPoints = regroupPoints + 1;
};
_action = ["Regroup Point","Deploy Regroup Point","regroup.jpg",_statement,_condition] call ace_interact_menu_fnc_createAction;
[(typeOf player), 1, ["ACE_SelfActions"], _action] call ace_interact_menu_fnc_addActionToClass;
This script is used to give people with a specific object the ability to Self Ace Interact and place a rally point. This “rally point” will move the respawn marker for the side up to the user. The type of object is a backpack, in this case, the Contact Woodland Radio Pack. It will not pick up the Z position, so if it’s used in a building players will spawn in the floor.
At the moment, it is customizable, but not user friendly in that respect.
//Sets Up Parent Water
_actionParent = ["water", "Water", "", {}, {true}] call ace_interact_menu_fnc_createAction;
[(typeOf player), 1, ["ACE_SelfActions", "ACE_Equipment"], _actionParent] call ace_interact_menu_fnc_addActionToClass;
//Full Bottle of Water
_condition = {
"ACE_WaterBottle" in (items player)
};
_statement = {
[_player] spawn{
_stanceUpper = stance (_this select 0);
_stance = format["acex_field_rations_drink%1%2", (_stanceUpper select [0,1]), toLower(_stanceUpper select [1])];
(_this select 0) setAnimSpeedCoef 2.5;
(_this select 0) playMove _stance;
sleep 5;
(_this select 0) setAnimSpeedCoef 1;
};
_player setStamina (getStamina _player) + 30;
_player removeItem "ACE_WaterBottle";
_player addItem "ACE_WaterBottle_Half";
};
_actionChildFull = ["drinkWater","Drink Water from Full Bottle","",_statement,_condition] call ace_interact_menu_fnc_createAction;
[(typeOf player), 1, ["ACE_SelfActions", "ACE_Equipment", "water"], _actionChildFull] call ace_interact_menu_fnc_addActionToClass;
//Half Bottle of Water
_condition = {
"ACE_WaterBottle_Half" in (items player)
};
_statement = {
[_player] spawn{
_stanceUpper = stance (_this select 0);
_stance = format["acex_field_rations_drink%1%2", (_stanceUpper select [0,1]), toLower(_stanceUpper select [1])];
(_this select 0) setAnimSpeedCoef 2.5;
(_this select 0) playMove _stance;
sleep 5;
(_this select 0) setAnimSpeedCoef 1;
};
_player setStamina (getStamina _player) + 30;
_player removeItem "ACE_WaterBottle_Half";
_player addItem "ACE_WaterBottle_Empty";
};
_actionChildHalf = ["drinkWaterHalf","Drink Water from Half Bottle","",_statement,_condition] call ace_interact_menu_fnc_createAction;
[(typeOf player), 1, ["ACE_SelfActions", "ACE_Equipment", "water"], _actionChildHalf] call ace_interact_menu_fnc_addActionToClass;
When placed in the initPlayer or init of a unit, this script will make it so ACE water bottles can be used to refill vanilla stamina. The script takes into account player stance and speeds the animation of ACEX Drinking up. It will replace full bottles with half bottles and half bottles with empty bottles. There is no refilling function at this time.
/*Cover Creating Grenades === Script By MexterInfinite
This script will detect when a player throws a grenade, wait until it lands, wait 3 more seconds, then deploy cover and delete the grenade.
Grenades will still do what they're programmed to do, so be careful about any grenade like a Frag, which deletes itself after exploding.
*/
["ace_firedPlayer", {
_nul = _this spawn {
//Change "B_IRStrobe" here to whatever grenade you want and find in CfgMagazines
if (typeOf (_this select 6) == "B_IRStrobe") then{
//Detects when grenade is essentially stopped
waitUntil{ vectorMagnitude velocity (_this select 6) < 0.02 };
sleep 3;
//Change "Land_BagFence_Round_F" to whatever object you want to spawn when the grenade lands
_cover = createVehicle [ "Land_BagFence_Round_F", (_this select 6), [], 0, "CAN_COLLIDE"];
//Gets direction of player in relation to object. Swap "_cover" and "(_this select 0)" if your object is turned the wrong way
_coverDir = _cover getRelDir (_this select 0);
_cover setDir _coverDir;
//Deletes grenades because we're environmentally friendly and want to clean up our garbage.
deleteVehicle (_this select 6);
};
};
}] call CBA_fnc_addEventHandler;
This script is a first, but working, draft of a grenade that will create cover. The code is commented as is, but I can describe it more here. If this is thrown into the init.sqf or its equivalent, it will add a new “eventHandler” for when a grenade is thrown via Ace or Vanilla throwing. In this case, it uses the NATO IR Grenade, and it spawns the Round Sandbag as its piece of cover. The cover always orients towards the player even if it’s bounced off walls. The grenade is deleted to prevent confusion and clutter. The cover and grenades can be swapped for anything, whether it be vehicles for cover or frag grenades for grenades.
/*
Author: Bravo Zero One development
- John_Spartan & Jiri Wainar
- Edited by MexterInfinite
Description:
- On demand function to invoke acceleration of vehicle in vehicle's direction.
Execution:
- Call the function via code/script
[_launchObject, _speed] execVM "launch.sqf";
Parameter(s):
_this select 0: mode (Scalar)
0: plane/object
1: velocity (Optional | Default: 100)
Returns: nothing
Result: Vehicle will be accelerated to required speed
*/
private _launchObject = param [0, objNull]; if (!local _launchObject) exitWith {};
private _speed = param [1, 100];
private _dirCatapult = vectorDir _launchObject;
private _configPath = configFile >> "CfgVehicles" >> typeOf _launchObject;
private _velocityLaunch = 210;
private _velocityIncrease = 75;
private _accelerationStep = 0.001;
{_x allowDamage false;} forEach units _launchObject;
_launchObject allowDamage false;
_launchObject engineOn true;
_launchObject setVectorDir _dirCatapult;
private _velocity = 0;
private _timeStart = time;
private _timeDelta = 0;
while
{
speed _launchObject < _velocityLaunch && {isEngineOn _launchObject && {((getPos _launchObject) param [2,0]) < 1}}
}
do
{
_launchObject setVectorDir _dirCatapult;
_timeDelta = time - _timeStart;
_velocity = _velocityIncrease * _timeDelta;
_launchObject setVelocityModelSpace [0, _speed, 0];
sleep _accelerationStep;
};
sleep 1;
{_x allowDamage true;} forEach units _launchObject;
_launchObject allowDamage true;
_launchObject setDamage 0;
waitUntil {(getpos _launchObject select 2) < 5};
{_x allowDamage false;} forEach units _launchObject;
_launchObject allowDamage false;
sleep 5;
{_x allowDamage true;} forEach units _launchObject;
_launchObject allowDamage true;
Have you ever wanted to catapult something off a ramp at the speeds of the carrier catapult? Now you can. I’d throw this script into a file and name it something like “catapult.sqf”. You can then call it with execVM and give it parameters. So, as an example, launch an apc at a speed of 150.
[apcVariable, 150] execVM "launch.sqf";
params ["_newUnit", "_oldUnit", "_respawn", "_respawnDelay"];
_newUnit allowDamage false;
[_newUnit] call zade_boc_fnc_actionOnChest;
_pos = getPos _newUnit;
_newUnit setPos [_pos select 0, _pos select 1, 400];
_chute = createVehicle ['Steerable_Parachute_F', [_pos select 0, _pos select 1, 400],[],0,'Fly'];
_newUnit moveIndriver _chute;
_chute allowDamage false;
sleep 15;
_newUnit allowDamage true;
This script is put in onPlayerRespawn and uses the Respawn on Position of Death option. It spawns a parachute 400m in the sky and will make the unit invincible for 15 seconds, which should be enough to reach the ground.
This sets up a marker on the map that will change color when a player respawns, letting the Air Team know when to go back for a pickup.
Create the desired marker somewhere easily visible, I like to set it to 1.25x1.25 size to make it a little easier. Name the marker “ResMarker”
Place a trigger set to “Any Player Present” covering the respawn area.
In Condition
This lets the pilot know if everyone is in the helicopter at base before taking off
call{this && ({_x isKindOf "Air"} count thisList != Count thislist)}
In On Activation
"ResMarker" setMarkerColor "ColorRed";
In On Deactivation
"ResMarker" setMarkerColor "ColorGrey";
With this, the marker will turn red when a player is present, and grey when there is no one present.
civ_kill = 0;
addMissionEventHandler ["EntityKilled",
{
params ["_killed", "_killer", "_instigator"];
if (isNull _instigator) then {_instigator = UAVControl vehicle _killer select 0}; // UAV/UGV player operated road kill
if (isNull _instigator) then {_instigator = _killer}; // player driven vehicle road kill
if (!(side group _killed == opfor) && (isPlayer _instigator)) then {
civ_kill = civ_kill + 1;
hint format ["%1 killed a civilian. %2 civilians have died tonight.", name _instigator, civ_kill];
};
}];
Place this script in the init.sqf, and it will create a variable that tracks the number of units killed, and displays who killed the unit, and how many of the units have been killed in the op. You can change what type of unit is tracked by changing the
if (!(side group _killed == opfor) && (isPlayer _instigator))
This example tracks the Civ Presence module because the units created by that are game logic and not tracked as units, and it checks that the unit killed was not opfor, and was killed by a player. You can change that to whatever side you want, but keep it restricted to the unit’s side as when a unit dies it becomes a civilian. But the group that the unit belongs to will always be the original side, even when the last unit dies.
thislist select 0 setPos (getMarkerPos selectRandom ["Exit_1", "Exit_2", "Exit_3", "Exit_4", "Exit_5"]);
this say3d "SparklesWreck2";
Put this in the activation field of the trigger, set the trigger to “Blufor Present”, “Repeatable”, “Server Only”, and place Exit_# markers wherever you want a possible exit to be
Make two triggers and set them to cover the same area, name the first trigger “Blu_1” and set it to Player Present, and repeatable.
Condition:
this && ({_x isKindOf "Air"} count thisList != Count thislist)
This will not activate anything by itself, but it is used to activate the second trigger. Set the second trigger to Opfor Present and set it to activate whatever objective or script you want
Condition:
triggerActivated Blu_1 && (east countryside thisList) < 5
Now, the second trigger will only activate if players are present and there are less than the chosen number in the trigger area.
removeGoggles this;
this addGoggles "G_CBRN_M50_Hood";
Place this into the init of every unit you want to force facewear onto, but fill the quotations with the name of the facewear you want
[this] call TCS_fnc_vehicleRespawn;
Using the most up to date framework, drop this into the vehicle’s init field for it to respawn. Here’s the link to the script’s site: https://forums.bohemia.net/forums/topic/202108-release-light-advanced-vehicle-respawn/
To run a script on a specific vehicle when it respawns (Custom pylons, squad flags, etc) paste this in the init instead and put your script in the SCRIPTSCRIPTSCRIPT.
[this, 5, {_this SCRIPTSCRIPTSCRIPT }, false] call TCS_fnc_vehicleRespawn;
removeFromRemainsCollector [this];
Courtesy of Walcheg, place this in the Init of a Unit and they’re body will not be deleted.
params ["_newUnit", "_oldUnit", "_respawn", "_respawnDelay"];
_newUnit allowDamage false;
_dir = round random 360;
_dis = round random 150;
[_newUnit] call zade_boc_fnc_actionOnChest;
_pos = _newUnit getRelPos [_dis, _dir];
_newUnit setPos [_pos select 0, _pos select 1, 400];
_chute = createVehicle ['Steerable_Parachute_F', [_pos select 0, _pos select 1, 400],[],0,'Fly'];
_newUnit moveIndriver _chute;
_chute allowDamage false;
sleep 15;
_newUnit allowDamage true;
This is an edit of Sherman’s Parachute Respawn. This does virtually the same thing, only it chooses a random point within 150m of the spawn point and parachutes you there.
Place this script in the On_Player_Respawn.SQF and choose the Respawn on Dead Body option in the game attributes.
Use to allow players to access the dressup system at any point in an OP.
Replace the file fn_createDressUp in framework\tcs\extra with this file.
this setPylonLoadout [1,"My_Pylon_Here", true];
You can rearm forced pylons through both trucks & shermans RRR zone. Can also use this in the vic respawn script to have vics respawn with set loadouts. Works 85% of the time, some specific vehicles can be finicky regarding rearm.
In single seaters you're best off removing all pylons on the vehicle first. With gunners tho, you may have to set weapons on the pylons and set who controls what first. This however may cause ‘ghost’ weapons to appear in the crew's selection, with no ammo, and these ghost weapons won't rearm (but the applied ones should).
!alive my_Things_Var_Name
Will return ‘true’ if the target is dead, or has been picked up (in the case of intel)
[0, 1] call TCS_fnc_addTicketsIndividual;
With the ‘1’ value being how many tickets. Can work in any server-only trigger.
[] spawn {
{TCS_var_individualTickets = 1} remoteExec ["call", 0];
uiSleep 35;
{TCS_var_individualTickets = 0} remoteExec ["call", 0];
};
Can be used in a server-only trigger.
[this, false, [0,0,0], 0] call ace_dragging_fnc_setCarryable;
[this, false, [0,0,0], 0] call ace_dragging_fnc_setDraggable;
[this, true, [0,-0.75,0],90] call ace_dragging_fnc_setDraggable;
Should Ignore box weight. Removing the 1st 2 lines should take weight back into account and even re-enable carrying if the box is light enough.
daytime > 18 && daytime < 20
Use a min and max to avoid potential issues with multi-days, and don't use =_time to avoid time acceleration skipping between trigger checks. make sure the trigger is nonrepeatable.
["my_task", "Succeeded", true] call BIS_fnc_taskSetState;
As the task ‘modules’ tend to break in a populated server.
True/false is whether or not you want the update to give everyone an alert.
Acceptable conditions are "Created" "Assigned" "Succeeded" "Failed" "Canceled"
["my_task",getPos my_objective_thing] call BIS_fnc_taskSetDestination;
{(player) enableInfoPanelComponent [_x,"MineDetectorDisplayComponent",false]} forEach ["left","right"];
Place in framework tcs/fn_initPlayer
mine_1 = "APERSMineDispenser_Ammo_Scripted" createVehicle (position this);
mine_1 setDir (getDir this);
Drop this in the init of a ‘game logic’ entity (the vanilla/zeus icon one, not the CBA one)(find it in F5/Systems). Mine faces the direction of the game object. Detonate with a trigger by putting
mine_1 setDamage damage 1;
In the triggers ‘on activation’ field (you can have 1 trigger touch off multiple mines)
[my_item, my_crate_or_vehicle, true] call ace_cargo_fnc_loadItem;
It seems the best practice is to make sure the vehicle or crates ACE cargo is totally empty at mission start. Take into account the ACE Cargo size of all crates, and the ACE Cargo space of the destination (you can change both), and make sure it all fits.
Do not do this on an immediate trigger or init, seems to fail to load some items. Either in the framework or on a delayed trigger, add it after the pre-init freeze.
{ deleteVehicle _x } forEach ( synchronizedObjects my_actionpoint );
Deletes the ActionPoint and everything syncronized with it (i.e. Repeaters, Portals, and Waypoints)