Merge pull request #397 from KoffeinFlummi/master-docs

Add documentation to master branch
This commit is contained in:
Felix Wiegand 2015-04-09 21:17:30 +02:00
commit d81ed9f969
15 changed files with 1492 additions and 0 deletions

View File

@ -0,0 +1,98 @@
---
layout: wiki
title: ACE3 Config Entries
group: dev
parent: wiki
order: 2
---
### CfgVehicles
```c++
ace_nightvision_grain
ace_nightvision_blur
ace_recoil_enablecamshake
ace_dragging_cancarry
ace_dragging_carryposition
ace_dragging_carrydirection
ace_dragging_candrag
ace_dragging_dragposition
ace_dragging_dragdirection
ace_gforcecoef
ace_offset
```
### CfgWeapons
```c++
ace_recoil_shakemultiplier
ace_overpressure_angle
ace_overpressure_range
ace_overpressure_damage
ace_overheating_dispersion
ace_overheating_slowdownfactor
ace_overheating_jamchance
ace_nightvision_grain
ace_nightvision_blur
ace_nightvision_radblur
ace_usedtube
ace_reloadlaunchers_enabled
ace_bipod
ace_overheating_allowswapbarrel
ace_clearjamaction
ace_checktemperatureaction
ace_gforcecoef
ace_protection
ace_scopeadjust_horizontal
ace_scopeadjust_vertical
ace_isusedlauncher
ace_attachable
ace_range
ace_detonator
```
### CfgAmmo
```c++
ace_bulletmass
ace_recoil_shakemultiplier
ace_frag_skip
ace_frag_force
ace_frag_classes
ace_frag_metal
ace_frag_charge
ace_frag_gurney_c
ace_frag_gurney_k
ace_explodeondefuse
ace_explosive
ace_fcs_airburst
```
### CfgGlasses
```c++
ace_color
ace_tintamount
ace_overlay
ace_overlaydirt
ace_overlaycracked
ace_resistance
ace_protection
ace_dustpath
```
### CfgMagazines
```c++
ace_isbelt
ace_attachable
ace_placeable
ace_setupobject
ace_delaytime
ace_triggers
ace_magazines_forcemagazinemuzzlevelocity
```

View File

@ -0,0 +1,171 @@
---
layout: wiki
title: ACE3 Events System
group: dev
parent: wiki
order: 3
---
## Event Handlers
Event handlers in ACE3 are implemented through our event system. They should be used to trigger or allow triggering of specific functionality.
The commands are listed below.
* `[eventName, eventCodeBlock] call ace_common_fnc_addEventHandler` <br/> adds an event handler with the event name and returns the event handler id.
* `[eventName, args] call ace_common_fnc_globalEvent` <br/> calls an event with the listed args on all machines, the local machine, and the server.
* `[eventName, args] call ace_common_fnc_serverEvent` <br/> calls an event just on the server computer (dedicated or self-hosted).
* `[eventName, targetObject(s), args] call ace_common_fnc_targetEvent` <br/> calls an event just on the targeted object or list of objects.
* `[eventName, args] call ace_common_fnc_localEvent` <br/> calls an event just on the local machine, useful for inter-module events.
Events can be removed or cleared with the following commands.
* `[eventName, eventHandlerId] call ace_common_fnc_removeEventHandler` <br/> will remove a specific event handler of the event name, using the ID returned from `ace_common_fnc_addEventHandler`.
* `[eventName] call ace_common_fnc_removeAllEventHandlers` <br/> will remove all event handlers for that type of event.
### Pattern:
```c++
// tapper machine
["tapShoulder", [_target], [otherArguments]] call EFUNC(common,targetEvent);
// target machine XEH_preInit.sqf
PREP(onTapShoulder);
["tapShoulder", FUNC(onTapShoulder) ] call EFUNC(common,addEventHandler);
```
### Listenable Event List:
<table>
<thead>
<tr>
<th>Event Key</th>
<th>Description</th>
<th>Source(s)</th>
<th>Locality</th>
</tr>
</thead>
<tbody>
<tr>
<td>"playerChanged"</td>
<td>`player` changed (zeus/respawn)</td>
<td>common</td>
<td>local</td>
</tr>
</tr>
<tr>
<td>"playerInventoryChanged"</td>
<td>Inventory changed</td>
<td>common</td>
<td>local</td>
</tr>
</tr>
<tr>
<td>"playerVisionModeChanged"</td>
<td>Vision mode changed (e.g. NVG on)</td>
<td>common</td>
<td>local</td>
</tr>
</tr>
<tr>
<td>"zeusDisplayChanged"</td>
<td>Zeus display opened/closed</td>
<td>common</td>
<td>local</td>
</tr>
</tr>
<tr>
<td>"cameraViewChanged"</td>
<td>Camera view changed</td>
<td>common</td>
<td>local</td>
</tr>
<tr>
<td>"playerVehicleChanged"</td>
<td>Player vehicle changed</td>
<td>common</td>
<td>local</td>
</tr>
<tr>
<td>"playerTurretChanged"</td>
<td>Player turret changed</td>
<td>common</td>
<td>local</td>
</tr>
<tr>
<td>"infoDisplayChanged"</td>
<td>On info box change (e.g. entering and leaving a vehicle)</td>
<td>common</td>
<td>local</td>
</tr>
<tr>
<td>"inventoryDisplayLoaded"</td>
<td>On opening the inventory display</td>
<td>common</td>
<td>local</td>
</tr>
<tr>
<td>"interactionMenuOpened"</td>
<td>Interaction Menu Opened</td>
<td>interaction</td>
<td>local</td>
</tr>
<tr>
<td>"killedByFriendly"</td>
<td>On TK/Civilian Killed</td>
<td>respawn</td>
<td>local</td>
</tr>
<tr>
<td>"drawing_requestMarkers"</td>
<td>Request Drawing Markers</td>
<td>map</td>
<td>target</td>
</tr>
<tr>
<td>"drawing_sendbackMarkers"</td>
<td>Send Drawing Markers</td>
<td>map</td>
<td>target</td>
</tr>
<tr>
<td>"drawing_addLineMarker"</td>
<td>Line Drawn</td>
<td>map</td>
<td>global</td>
</tr>
<tr>
<td>"drawing_removeLineMarker"</td>
<td>Line Deleted</td>
<td>map</td>
<td>global</td>
</tr>
<tr>
<td>"flashbangExplosion"</td>
<td>Flashbang Goes Bang</td>
<td>grenades</td>
<td>target</td>
</tr>
</tbody>
</table>
### Callable Event List:
<table>
<thead>
<tr>
<th>Event Key</th>
<th>Description</th>
<th>Parameters</th>
<th>Owner</th>
<th>Locality</th>
</tr>
</thead>
<tbody>
<tr>
<td>"ace_fcs_forceChange"</td>
<td>force FCS updates</td>
<td>fcs</td>
<td>fcs</td>
<td>local</td>
</tr>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,25 @@
---
layout: wiki
title: Arma 3 Issues
group: dev
parent: wiki
order: 6
---
Keeping track of Arma 3 issues that need to be fixed. If you want to support us and help raise Bohemia's awareness of those issues, please upvote them:
**Open:**
* [bux578: 0020997: MineDetector equipable in Launcher slot](http://feedback.arma3.com/view.php?id=20997)
* [bux578: 0021176: Zeus / Curator Add Remote Controlled Event](http://feedback.arma3.com/view.php?id=21176)
* [bux578: 0021469: Add script commands "addPrimaryWeaponMagazine" and "addSecondaryWeaponMagazine"](http://feedback.arma3.com/view.php?id=21469)
* [bux578: 0022000: Add/Alter script command to add perfectly configured weapons to cargo](http://feedback.arma3.com/view.php?id=22000)
* [commy2: 0021443: Unexpected behavior of += array in configs](http://feedback.arma3.com/view.php?id=21443)
* [commy2: 0022671: setVariable is not always JIP persistent](http://feedback.arma3.com/view.php?id=22671)
* [CorruptedHeart: 0022318: Can no longer use "MenuBack" shortcut in AddAction](http://feedback.arma3.com/view.php?id=22318)
**Resolved:**
* <del>[Nou: 0020761: Memory points rfemur, lfemur, and other leg memory points returned incorrectly with SQF command selectionPosition](http://feedback.arma3.com/view.php?id=20761)</del>
* <del>[commy2: 0023136: isLightOn doesn't recognize destroyed light bulbs for streetlamps](http://feedback.arma3.com/view.php?id=23136)</del>

View File

@ -0,0 +1,94 @@
---
layout: wiki
title: Arma 3 Scheduler And Our Practices
group: dev
parent: wiki
order: 8
---
## Terminology
#### Frame
A single rendered frame of Arma 3.
#### Scheduled Space
This refers to execution would is ruled by the Arma 3 default script scheduling engine. This would include:
* spawn
* execVM
#### Unscheduled Space
This refers to execution which is linear; what this means is that the code will run to completion prior to executing the current frame. It must complete, but is guaranteed to run within a given frame.
* perFrameHandler
* Extended_EventHandlers
* addEventHandler
## What is the scheduler and why do I care?
BIKI Article: https://community.bistudio.com/wiki/Biki2.0:Performance_Considerations
The Arma 3 script scheduler basically gives a fair-share execution to all running scripts, FSMs, and SQS files running on any given client or server at any given time. See the BIKI article for a in-depth explanation of this. What this basically means though, is that all scripts get a fair share; this also means scheduled execution is drastically affected by other poorly written mods. For example, if 2 different spawn's are running in a tight loop of `do { foo } while (true);`, they will both get exactly 50% of the scheduling time.
With the way mission makers and mod makers generally use spawn/execVM, this means you're actually getting drastically less execution time in the scheduled environment than you might think. This leads to visible delay issues all the way up to massive delay on execution. You can easily test and prove this by looping spawns and watching the execution times extend.
What does this all mean? It means we need to live outside of the spawn execution as much as possible. There are 2 places that the majority of our functionality should stem from, which means that as long as we strictly always perform calls between functions, we are executing within the same frame. If our execution is either stemming from the perFrameHandlers, or any default Extended_EventHandlers, than we can guarantee execution within a single frame. *ANY OTHER CIRCUMSTANCE IS NOT GUARANTEED.*
The scheduler will also actually halt your script mid-execution, usually at the end of a given control block, and pause you to yield to other scripts. This can lead to drastically incorrect results when performing calculations. Again, this is the reason we want all our given code to run to completion in a single given frame.
## Design Patterns
Because we are attempting to always run to completion; execution occurs from 2 places. Either PFH handles or event handlers; in both cases, we wish our code to run to completion. This takes a change in mind set for design to ensure your executing that way. In a nutshell though, this all distills down to the fact that you will always call other chunks of code; nothing will ever be spawned off. The only circumstance this really becomes a problem is for waiting or delay. If designed correctly, though, you can avoid those circumstances.
Rules of thumb for component design:
* If you need to wait for a value, don't wait, use a CBA event! This means everything should be designed and written with an event-driven model in mind.
* If you have to wait, use a PFH delay/diag_tickTime check.
### PFH-Design Pattern
Line Notes:
* PerFrameHandlers should be self-removing. If a PFH is no longer needed, it is responsible for removing itself.
### ACE3 General Rules
* Always use call whenever possible. We should be calling functions chains exclusive and not be relying on spawn/execVM ever. Consider spawn/execVM banned without good reason. All code should be a chain of execution which is traceable, and not triggered between seperate threads.
* waitUntil and sleep are banned. If you need to use them, use scheduled delay execution instead. **Reasoning** *Sleep/waituntil surrender about 5x the scheduler time than even normal execution does. *
* If we need a spawn or exec, we should utilize the perFrame scheduler. Spawn/execVM are subject to the Arma 3 scheduler and as such, cannot be relied upon. In order to give our players a consistent gameplay experience, we need to have total control over how and when all of our code runs.
* PFH should be utilized at all possible times when the player can see the result of whatever the code is. This applies to missile guidance, bullets, wind, optics, interactive UI, HUD's, and rendering. We should only consider scheduled execution if the code is running out of the visual range of the player.
### Code Examples
##### Generic PFH functions
See: https://dev.withsix.com/docs/cba/files/common/fnc_addPerFrameHandler-sqf.html for more details.
```c++
[{ code } , delayTime, [ARGS] ] call CBA_fnc_addPerFrameHandler;
```
##### PFH Wait
```c++
DFUNC(myDelayedFunction) = {
// Our argument array is passed in a PFH as select 0
_args = _this select 0;
// Print our arguments
diag_log text format["I received: %1", (_args select 0)];
// Delete this PFH, so it is only executed once
[_this select 1] call CBA_fnc_removePerFrameHandler;
};
// This runs the PFH once every 5 seconds, with the variable array ["balls"] being passed in
// This executes FUNC(myDelayedFunction), that could also be a { code } block.
// Parameter 2 is the delay (in seconds) for a PFH. This is "execute every N seconds", 0 will be every frame.
[FUNC(myDelayedFunction), 5, ["balls"] ] call CBA_fnc_addPerFrameHandler;
```

View File

@ -0,0 +1,274 @@
---
layout: wiki
title: Coding Guidelines
group: dev
parent: wiki
order: 1
---
## Table Of Contents
- [Indentation](#indentation)
- [Braces](#braces)
- [Modules](#how-to-create-a-new-module)
- [Macros](#macro-usage)
- [Events](#event-handlers)
- [Hashes](#hashes)
## Indentation
4 spaces for indentation.
```c++
class Something: Or {
....class Other {
........foo = "bar";
....};
};
```
#### Reasoning
Tabs can be tricky sometimes, especially when it comes to sharing code with others. Additionally, a lot of people tend to forget they're using tabs when they're aligning things after the first character, which causes things to fall apart when viewing the code at different tab lengths.
## Braces
- opening bracket on the same line as keyword
- closing bracket in own line, same level of indentation as keyword
**Yes:**
```c++
class Something: Or {
class Other {
foo = "bar";
};
};
```
**No:**
```c++
class Something : Or
{
class Other
{
foo = "bar";
};
};
```
**Also no:**
```c++
class Something : Or {
class Other {
foo = "bar";
};
};
```
When using `if`/`else`, it is encouraged to put `else` on the same line as the closing bracket to save space:
```c++
if (alive player) then {
player setDamage 1;
} else {
hint ":(";
};
```
In cases where you , e.g, have a lot of one-liner classes, it is allowed to use something like this to save space:
```c++
class One {foo = 1;};
class Two {foo = 2;};
class Three {foo = 3;};
```
#### Reasoning
Putting the opening bracket in it's own line wastes a lot of space, and keeping the closing bracket on the same level as the keyword makes it easier to recognize what exactly the bracket closes.
## How to create a new module
1. Copy the structure from `extras\blank` to the `addons\` folder and name it what you wish the new module to be named.
1. Edit `script_component.hpp`, change the `COMPONENT` definition to the name of the module. Also edit each of the `DEBUG` definitions to be the name of the module (for example, `DEBUG_SETTINGS_BLANK` should be `DEBUG_SETTINGS_BALLS` for module balls)
1. Edit the `script_component.hpp` file in the the `functions` directory to match the path of the new module, for example `#include "\z\ace\addons\blank\script_component.hpp"` for module called balls should now be `#include "\z\ace\addons\ballls\script_component.hpp"`.
1. The module is now prepared for development
### Function Definitions
Functions should be created in the functions\ subdirectory, named `fnc_FunctionName.sqf` They should then be indexed via the `PREP(FunctionName)` macro in the XEH_preInit.sqf file. The `PREP` macro allows for CBA function caching, which drastically speeds up load times. **Beware though that function caching is enabled by default and as such to disable it you need to `#define DISABLE_COMPILE_CACHE` above your `#include "script_components.hpp"` include!**
Every function should have a header of the following format:
```cpp
/*
* Author: [Name of Author(s)]
* [Description]
*
* Arguments:
* 0: The first argument <STRING>
* 1: The second argument <OBJECT>
*
* Return Value:
* The return value <BOOL>
*
* Example:
* _bool = ["something", player] call ace_common_fnc_imanexample
*
* Public: [Yes/No]
*/
```
## Macro Usage
### Module/PBO specific Macro Usage
The family of `GVAR` macro's define global variable strings or constants for use within a module. Please use these to make sure we follow naming conventions across all modules and also prevent duplicate/overwriting between variables in different modules. The macro family expands as follows, for the example of the module 'balls'
* `GVAR(face)` is `ace_balls_face`
* `QGVAR(face)` is `"ace_balls_face"`
* `EGVAR(balls,face)` is `ace_balls_face`
* `EGVAR(leg,face)` is `ace_leg_face`
* `QEGVAR(leg,face)` is `"ace_leg_face"`
There also exists the FUNC family of Macros
* `FUNC(face)` is `ace_balls_fnc_face` or the call trace wrapper for that function.
* `EFUNC(balls,face)` is `ace_balls_fnc_face` or the call trace wrapper for that function.
* `EFUNC(leg,face)` is `ace_leg_fnc_face` or the call trace wrapper for that function.
* `DFUNC(face)` is `ace_balls_fnc_face` and will ALWAYS be the function global variable.
* `DEFUNC(leg,face)` is `ace_leg_fnc_face` and will ALWAYS be the function global variable.
* `QFUNC(face)` is `"ace_balls_fnc_face"`
* `QEFUNC(leg,face)` is `"ace_leg_fnc_face"`
The `FUNC` and `EFUNC` macros should NOT be used inside `QUOTE` macros if the intention is to get the function name or assumed to be the function variable due to call tracing (see below). If you need to 100% always be sure that you are getting the function name or variable use the `DFUNC` or `DEFUNC` macros. For example `QUOTE(FUNC(face)) == "ace_balls_fnc_face"` would be an illegal use of `FUNC` inside `QUOTE`.
Using `FUNC` or `EFUNC` inside a `QUOTE` macro is fine if the intention is for it to be executed as a function.
#### FUNC Macros, Call Tracing, and Non-ACE/Anonymous Functions
ACE implements a basic call tracing system that can dump the call stack on errors or wherever you want. To do this the `FUNC` macros in debug mode will expand out to include metadata about the call including line numbers and files. This functionality is automatic with the use of calls via `FUNC` and `EFUNC`, but any calls to other functions need to use the following macros:
* `CALLSTACK(functionName)` example: `[] call CALLSTACK(cba_fnc_someFunction)`
* `CALLSTACK_NAMED(function,functionName)` example: `[] call CALLSTACK_NAMED(_anonymousFunction,'My anonymous function!')`
These macros will call these functions with the appropriate wrappers and enable call logging into them (but to no further calls inside obviously).
### General Purpose Macros
[CBA script_macros_common.hpp](https://gist.github.com/commy2/9ed6cc73fbe6a2b3f4e1)
* `QUOTE()` is utilized within configuration files for bypassing the quote issues in configuration macros. So, all code segments inside a given config should utilize wrapping in the QUOTE() macro instead of direct strings. This allows us to use our macros inside the string segments, such as `QUOTE(_this call FUNC(balls))`
#### setVariable, getVariable family macros
* `GETVAR(player,MyVarName,false)`
`player getVariable ["MyVarName", false]`
* `GETMVAR(MyVarName,objNull)`
`missionNamespace getVariable ["MyVarName", objNull]`
* `GETUVAR(MyVarName,displayNull)`
`uiNamespace getVariable ["MyVarName", displayNull]`
* `SETVAR(player,MyVarName,127)`
`player setVariable ["MyVarName", 127]`
* `SETPVAR(player,MyVarName,127)`
`player setVariable ["MyVarName", 127, true]`
* `SETMVAR(MyVarName,player)`
`missionNamespace setVariable ["MyVarName", player]`
* `SETUVAR(MyVarName,_control)`
`uiNamespace setVariable ["MyVarName", _control]`
## Event Handlers
Event handlers in ACE are implemented through our event system. They should be used to trigger or allow triggering of specific functionality.
The commands are listed below.
* `[eventName, eventCodeBlock] call ace_common_fnc_addEventHandler` adds an event handler with the event name and returns the event handler id.
* `[eventName, args] call ace_common_fnc_globalEvent` calls an event with the listed args on all machines, the local machine, and the server.
* `[eventName, args] call ace_common_fnc_serverEvent` calls an event just on the server computer (dedicated or self-hosted).
* `[eventName, targetObject(s), args] call ace_common_fnc_targetEvent` calls an event just on the targeted object or list of objects.
* `[eventName, args] call ace_common_fnc_localEvent` calls an event just on the local machine, useful for inter-module events.
Events can be removed or cleared with the following commands.
* `[eventName, eventHandlerId] call ace_common_fnc_removeEventHandler` will remove a specific event handler of the event name, using the ID returned from `ace_common_fnc_addEventHandler`.
* `[eventName] call ace_common_fnc_removeAllEventHandlers` will remove all event handlers for that type of event.
More information on the [ACE Events System](https://github.com/KoffeinFlummi/ACE3/wiki/ACE-Events-System) page.
## Hashes
Hashes are a variable type that store key value pairs. They are not implemented natively in SQF, so there are a number of macros and functions for their usage in ACE. If you are unfamiliar with the idea, they are similar in function to `setVariable`/`getVariable` but do not require an object to use.
The following example is a simple usage using our macros which will be explained further below.
```c++
_hash = HASHCREATE;
HASH_SET(_hash, "key", "value");
if(HASH_HASKEY(_hash, "key")) then {
player sideChat format["val: %1", HASH_GET(_hash, "key"); // will print out "val: value"
};
HASH_REM(_hash, "key");
if(HASH_HASKEY(_hash, "key")) then {
// this will never execute because we removed the hash key/val pair "key"
};
```
A description of the above macros is below.
* `HASHCREATE` is used to create an empty hash.
* `HASH_SET(hash, key, val)` will set the hash key to that value, a key can be anything, even objects.
* `HASH_GET(hash, key)` will return the value of that key (or nil if it doesn't exist).
* `HASH_HASKEY(hash, key)` will return true/false if that key exists in the hash.
* `HASH_REM(hash, key)` will remove that hash key.
### Hashlists
A hashlist is an extension of a hash. It is a list of hashes! The reason for having this special type of storage container rather than using a normal array is that an array of normal hashes that are are similar will duplicate a large amount of data in their storage of keys. A hashlist on the other hand uses a common list of keys and an array of unique value containers. The following will demonstrate it's usage.
```c++
_defaultKeys = ["key1","key2","key3"];
// create a new hashlist using the above keys as default
_hashList = HASHLIST_CREATELIST(_defaultKeys);
//lets get a blank hash template out of this hashlist
_hash = HASHLIST_CREATEHASH(_hashList);
//_hash is now a standard hash...
HASH_SET(_hash, "key1", "1");
//to store it to the list we need to push it to the list
HASHLIST_PUSH(_hashList, _hash);
//now lets get it out and store it in something else for fun
//it was pushed to an empty list, so it's index is 0
_anotherHash = HASHLIST_SELECT(_hashList, 0);
// this should print "val: 1"
player sideChat format["val: %1", HASH_GET(_anotherHash, "key1")];
//Say we need to add a new key to the hashlist
//that we didn't initialize it with? We can simply
//set a new key using the standard HASH_SET macro
HASH_SET(_anotherHash, "anotherKey", "another value");
```
As you can see above working with hashlists are fairly simple, a more in depth explanation of the macros is below.
* `HASHLIST_CREATELIST(keys)` creates a new hashlist with the default keys, pass [] for no default keys.
* `HASHLIST_CREATEHASH(hashlist)` returns a blank hash template from a hashlist.
* `HASHLIST_PUSH(hashList, hash)` pushes a new hash onto the end of the list.
* `HASHLIST_SELECT(hashlist, index)` returns the hash at that index in the list.
* `HASHLIST_SET(hashlist, index, hash)` sets a specific index to that hash.
#### A note on pass by reference and hashes
Hashes and hashlists are implemented with SQF arrays, and as such they are passed by reference to other functions. Remember to make copies (using the + operator) if you intend for the hash or hashlist to be modified with out the need for changing the original value.

View File

@ -0,0 +1,59 @@
---
layout: wiki
title: Extension Guidelines
group: dev
parent: wiki
order: 9
---
## Basics
### Requirements
- A compiler (VS/GCC/Clang)
- If starting with visual studio, you need to make sure to use the Visual studio command prompt
- cmake 3.0 or later in your path
### Cross-Platform Guidelines
### C++ basic style and naming guide
### ace_common cpp library
---
## Building Extensions on Windows
### Compiling
#### Windows - Creating a Visual Studio Project
1. Open your compiling command prompt (which has cmake and your compiler)
2. From this directory, you need to use cmake to build the appropriate build files. Change the -G property appropriately. run cmake --help to get a list of the options.
```
cd extensions\build
cmake .. -G "Visual Studio 2014"
```
A Visual studio project file will now be generated in your build directory.
#### Windows - Visual Studio - Compile only (nmake)
1. Open your compiling command prompt (which has cmake and your compiler)
2. From this directory, you need to use cmake to build the appropriate build files. Change the -G property appropriately. run cmake --help to get a list of the options.
```
cd extensions\build
cmake .. -G "NMake Makefiles"
nmake
```
The extensions will not be built in its appropriate project folder, for example:
```
extensions\
build\
fcs\ace_fcs.dll
somethingElse\ace_somethingElse.dll
```
### Creating a New Extension

View File

@ -0,0 +1,76 @@
---
layout: wiki
title: Fragmentation Configuration
group: dev
parent: wiki
order: 7
---
The fragmentation system (sys_frag) in ACE3 is a significant improvement over the fragmentation system in ACE2. Previously the system relied on fuzzy math from the values of `indirectHit` and `indirectHitRange` in CfgAmmo to calculate roughly the velocity and range of fragmentation. This had some serious drawbacks, especially in the case of smaller explosives such as hand grenades and 40mm grenades where casualty production was lower than desired.
In ACE3 the system has moved away from what "feels" right to actual explosive engineering equations, primarily the [Gurney equations](http://en.wikipedia.org/wiki/Gurney_equations). This allows us to get close to the actual fragmentation velocities that would be produced by an explosive configuration similar to type of ammo we are simulating.
The system for the end-developer is easy to use, and only requires minimal research into the type of ammo being represented. I will describe how to do this in this ticket.
Below is an example set of explosives configuration properties for sys_frag (in this case an M67 hand grenade):
```c++
ACE_FRAG_METAL = 210; // metal in grams
ACE_FRAG_CHARGE = 185; // explosive in grams
ACE_FRAG_GURNEY_C = 2843; // Gurney velocity constant for explosive type. See: http://en.wikipedia.org/wiki/Gurney_equations
ACE_FRAG_GURNEY_K = 3/5; // Gurney shape factor, in this case a sphere. See: http://en.wikipedia.org/wiki/Gurney_equations
```
`ACE_FRAG_METAL` is the amount of metal being fragmented (generally taken as the entire weight of the warhead, though in some cases you might want to only include the fragmentation jacket or body. `ACE_FRAG_CHARGE` is the amount of explosive filler in the warhead. `ACE_FRAG_METAL` and `ACE_FRAG_CHARGE` are dimensionless values, as long as they are both in the same unit (for example kg/kg g/g lbs/lbs).
`ACE_FRAG_GURNEY_C` is the Gurney constant for explosive force. You can find a list of common explosive types below. If you can not find it here, or want more accurate numbers, just google the type of explosive and Gurney constant and you can find substantial information. This is *NOT* the detonation velocity of the explosive, do not confuse them!
| Type | Speed |
|------------------|----------|
|Composition B | 2700 m/s |
|Composition C-3 | 2680 m/s |
|Cyclotol 75/25 | 2790 m/s |
|HMX | 2800 m/s |
|LX-14 | 2970 m/s |
|Octol 75/25 | 2800 m/s |
|PBX 9404 | 2900 m/s |
|PBX 9502 | 2377 m/s |
|PETN | 2930 m/s |
|RDX | 2830 m/s |
|Tetryl | 2500 m/s |
|TNT | 2440 m/s |
|Tritonal | 2320 m/s |
`ACE_FRAG_GURNEY_K` is the shape factor for the explosive configuration. You should choose it based on the general configuration of explosives/metal in the warhead. Most grenades for example are a sphere. Artillery and aircraft bombs are a cylinder. Mines generally a flat plate. Below is a list of the three common shapes and their factors.
```
Sphere = 3/5
Cylinder = 1/2
Plate = 3/5
```
There are other configurations but these are the most common. If you are interested in others check out the wikipedia link given above. Most of these will not correctly function in sys_frag though due to additional variables for the equation.
In addition to these variables there are different types of fragmentation fragments to choose from, and they can be defined in the config value `ACE_FRAG_CLASSES[]`. Below are a list of the types.
```
ACE_frag_tiny
ACE_frag_tiny_HD
ACE_frag_small
ACE_frag_small_HD
ACE_frag_medium
ACE_frag_medium_HD
ACE_frag_large
ACE_frag_large_HD
ACE_frag_huge
ACE_frag_huge_HD
```
The tinier the piece of fragmentation the shorter the distance of travel. The `_HD` variants are all even higher drag versions. Grenades generally should use the `_HD` variants. Experimentation here is important.
The final information needed is a couple of entries for forcing or ignoring fragmentation for this ammo.
If you set `ACE_FRAG_SKIP` to 1 then you will skip fragmentation for ammo of this type. This is useful for things that might cause high network load, such as FFAR rockets, or possibly even 40mm grenades from AGLs. Experimentation under network conditions is required.
If you set `ACE_FRAG_FORCE` to 1 it will force the fragmentation system to use frag on this ammo, ignoring sys_frags internal qualifications based on hit values.

View File

@ -0,0 +1,36 @@
---
layout: wiki
title: Merging Pull Requests
group: dev
parent: wiki
order: 5
---
Who's responsible for merging pull requests.
All authors must add themselves to the AUTHORS.txt file **with a valid email adress**.
#### Changes To Existing Addons
The people responsible for merging changes to existing addons are the maintainers listed in the README.md file of the respective addon folder.
If the changes consists of trivial changes, such as spelling or indentation fixes:
```diff
valueA = 12;
valueB = 31;
- valueC =2;
+ valueC = 2;
```
... the PR can be merged right away by one of the maintainers.
Non-trivial pull requests remain open for a minimum of 48 hours, to give all other contributors time to comment on potential issues, and are then merged by a maintainer, should no issues arise.
#### New Addons / Other Changes
If a pull request adds a new addon, or changes something else, like the README, everyone has 72 hours to comment on the changes. After that, one of the team leads ([NouberNou](https://github.com/NouberNou), [KoffeinFlummi](https://github.com/KoffeinFlummi), [Glowbal](https://github.com/Glowbal)) will merge it.
Trivial changes such as spelling fixes can be merged immediately by any contributor.

View File

@ -0,0 +1,32 @@
---
layout: wiki
title: Modularity And PBO Structure
group: dev
parent: wiki
order: 4
---
### Modularity
Main principles:
- As much stuff as possible should be modular
- Strive to make as much stuff as possible run-time toogable. Adding/removing PBOS would still be requiring to toogle any feature relying on config changes.
### PBO Structure
Main principles:
- Try to keep single module dependencies as much as possible
- InteractionMenu would be the requirement for most modules.
- Anything that is 100% config should require common and not interaction.
```
Main -> Common -> OptionsMenu -> InteractionMenu -> Most things
Main -> Common -> Config things
Main -> Common -> 3D Models |
InteractionMenu | -> Feature
```

View File

@ -0,0 +1,122 @@
---
layout: wiki
title: Setting Up The Development Environment
group: dev
parent: wiki
order: 0
---
This page describes how you can setup your development environment for ACE3, allowing you to properly build ACE and utilize file patching.
## Table Of Contents
- [Requirements](#requirements)
- [Why so complicated?](#why-so-complicated)
- [Getting ACE](#getting-ace)
- [Initial Setup](#initial-setup)
- [Manual Setup](#manual-setup)
- [Creating a Test Build](#creating-a-test-build)
- [Creating a Release Build](#creating-a-release-build)
- [File Patching](#file-patching)
- [Enabling File Patching](#enabling-file-patching)
- [Restrictions of File Patching](#restrictions-of-file-patching)
## Requirements
- Arma 3 (duh)
- A proper installation of the Arma 3 Tools (available on Steam)
- A properly setup P-drive
- Python 3.x, available [here](http://www.python.org)
- The following Mikero Tools (available [here](https://dev.withsix.com/projects/mikero-pbodll/files)): DePBO, Rapify, MakePBO, PBOProject
- A properly setup PATH variable (containing Python and the Mikero tools)
## Why so complicated?
If you have contributed to AGM you might be used to an easier build process, where there was even an .exe you could use for building. ACE3, however, makes use of CBA macros to simplify things and give the developer access to a better debug process, which requires a stricter build environment. Additionally, Mikero's tools are stricter and report more errors than AddonBuilder does. The structure of this development environment also allows for [file patching](#file-patching), which is very useful for debugging.
Not offering .exes for the Python scripts we use allows us to make easy changes without the hassle of compiling self-extracting exes all the time.
## Getting ACE
To actually get the ACE source code on your machine, it is recommended that you use Git. Tutorials for this are all around the web, and it allows you to track your changes and easily update your local copy.
If you just want to create a quick and dirty build, you can also directly download the source code using the "Download ZIP" button on the front page of the GitHub repo.
## Initial Setup
After ensuring that you have installed all requirements, execute the `setup.py` script found in the `tools` folder. This will do most of the heavy lifting for you, create the links you need and copy the required CBA code to the proper place. Please note that these links are tied to the location of your ACE3 source code, so make sure that the project folder is where you want it to be. We recommend that you store the ACE3 project on your P-drive.
#### Manual Setup
Should the script fail, here is how you create the required links manually:
First, to set up the links, create `z` folders both in your Arma 3 directory and on your P-drive. Then run the following commands as admin, replacing the text in brackets with the appropriate paths:
Windows 8:
```
mklink /D /J "[Arma 3 installation folder]\z\ace" "[location of the ACE3 project]"
mklink /D /J "P:\z\ace" "[location of the ACE3 project]"
```
Windows 7 and Vista:
```
mklink /D "[Arma 3 installation folder]\z\ace" "[location of the ACE3 project]"
mklink /D "P:\z\ace" "[location of the ACE3 project]"
```
Then, copy the `cba` folder from the `tools` folder to `P:\x\cba`. Create the `x` folder if needed. That folder contains the part of the CBA source code that are required for the macros to work.
## Creating a Test Build
To create a development build of ACE to test changes or to debug something, run the `build.bat` file in the `tools` folder. This will populate the `addons` folder with binarized PBOs. These PBOs still point to the source files in their respective folders however, which allows you to use [file patching](#file-patching).
This also means that you cannot distribute this build to others.
To start the game using this build, you can use the following modline:
```
-mod=@cba_a3;z\ace
```
## Creating a Release Build
To create a complete build of ACE that you can use without the source files, run the `make.py` file in the `tools` folder. This will populate the `release` folder with binarized PBOs that you can redistribute. These handle like those of any other mod.
## File Patching
File Patching allows you to change the files in an addon while the game is running, requiring only a restart of the mission. This makes it great for debugging, as it cuts down the time required between tests. Note that this only works with PBOs created using MakePBO, as outlined in [Creating a Test Build](#creating-a-test-build).
#### Enabling File Patching
There are two ways to enable file patching:
- Load cba_cache_disable.pbo (included in CBA's optional folder)
- Add the following to your test missions description.ext:
```c++
class CfgSettings {
class CBA {
class Caching {
compile = 0;
xeh = 0;
functions = 0;
};
};
};
```
#### Restrictions of File Patching
Files must exist in the built PBOs for filepatching to work. If you create a new file you must rebuild the PBO or Arma will not find it in your file paths.
Configs are not patched during run time, only at load time. You do not have have to rebuild a PBO to make config changes, just restart Arma. You can get around this though if you are on the dev branch of Arma 3 and running the diagnostic exe. That includes `diag_mergeConfig` which takes a full system path (as in `p:\z\ace\addons\my_module\config.cpp`) and allows you selectivly reload config files.
If you need to add/remove files* Then you'll need to run build.bat again without the game running, and restart. That is all that is required to add new files to then further use in testing.

View File

@ -0,0 +1,202 @@
---
layout: wiki
title: Modules
group: missionMaker
order: 5
parent: wiki
---
## 1. Modules
### 1.1 BlueForceTracking
*Part of: ACE_Map*
When adding the "BlueForceTracking" module to your mission it adds map markers to every group on the players side and refreshes them in certain configurable interval (in seconds). The module takes the group type into account and uses the proper NATO icon for each marker.
**Settings:**
1. **Interval (Number)<br>**
How often the markers should be refreshed (in seconds).<br>
`Default value: 5`
2. **Hide AI Groups (Boolean)<br>**
Hide markers for "AI only" groups.<br>
`Default value: No`
### 1.2 Check PBOs
*Part of: ACE_Core*
If you are worried that players haven't updated ACE or other mods to the version you're using on the server, you can place the "Check PBOs" module on your map. You can choose one of three posible actions that are being executed when a player joins that has a wrong version of ACE or an other mod:
* Warn once
* Warn permanent
* Kick
**Settings:**
1. **Action (Option)<br>**
What to do with people who do not have the right PBOs.<br>
`Default value: "Warn once"`
2. **Check all addons (Boolean)<br>**
Check all addons instead of only those of ACE?<br>
`Default value: "No"`
3. **Whitelist<br>**
You can make a whitelist of addons that don't have to be on the server. If you want to use the "Check all addons" option of this module and allow the usage of client side modifications like Blastcore or JSRS, you have to list them here.
The list must be in the following format: `["ADDON1","ADDON2",...]` where the addons are CfgPatches references to all PBOs of the optional mod. To figure these out, you can use the scripting command `activatedAddons` in the editor while those mods are enabled.
Example 1: @Blastcore-A3:<br>
```sqf
["warfxpe","blastcore_vep"]
```
Example 2: @JSRS:<br>
```sqf
[TBD]
```
Example 3: @JSRS + @Blastcore-A3:<br>
```sqf
[TBD, "warfxpe","blastcore_vep"]
```
### 1.3 Explosive System
*Part of: ACE_Explosive*
The "Explosive System" module lets you tweak the settings for the new explosive system that ACE introduces.
**Settings:**
1. **Require explosive specialists? (Boolean)<br>**
Require explosive specialists to disable explosives.<br>
`Default value: No`
2. **Punish non-specialists? (Boolean)<br>**
Increase the time it takes to complete actions for non-specialists.<br>
`Default value: Yes`
### 1.4 Fatigue System (deprecated)
**Warning:**
*This module is deprecated and only in there not to break older missions that have used this module. It will be removed in a future update. It serves no purpose.*
### 1.5 Friendly Fire Messages
*Part of: ACE_Respawn*
The "Friendly Fire Messages" module triggers a message when a player kills a friendly or civilian unit. This module isn't needed on servers with a low difficulty setting.
### 1.6 Interaction
*Part of: ACE_Interaction*
This module allows you to tweak the settings for player names tags.
**Settings:**
1. **Player Names View Distance (Number)<br>**
Sets the distance (in meters) at which player name tags become visible.<br>
`Default value: 5`
### 1.7 Medical System
*Part of: ACE_Medical*
When using the medical system ACE offers you probably want to fine tune some aspects of the wounding, healing or gameplay mechanics and fit them to your needs. The "Medical System" module offers a lot of settings to do just that.
**Settings:**
1. **Bleeding Speed Coefficient (Number)<br>**
Multiplier for the rate of bleeding.<br>
`Default value: 1`
2. **Pain Effect Coefficient (Number)<br>**
Multiplier for the intensity of the pain effect (chromatic abberation).<br>
`Default value: 1`
3. **Max Unconscious Time (Number)<br>**
Maximum time (in seconds) for a unit to be unconscious before dying. -1 disables this.<br>
`Default value: -1`
4. **Allow non-medics? (Boolean)<br>**
This setting is used to allow non-medics to use epipens and bloodbags.<br>
`Default value: No`
5. **Punish non-medics? (Boolean)<br>**
Increase the time it takes to complete actions for non-medics.<br>
`Default value: Yes`
6. **Require diagnosis? (Boolean)<br>**
Require an unconscious patient to be diagnosed before allowing treatment.<br>
`Default value: No`
7. **Prevent instant death? (Boolean)<br>**
Prevent instant death and always put players in unconscious state instead.<br>
`Default value: No`
8. **Prevent death while unconscious? (Boolean)<br>**
Make unconscious units invulnerable.<br>
`Default value: No`
9. **Single Bandage (Boolean)<br>**
Use one bandage to heal the entire body.<br>
`Default value: No`
10. **Unconscious can chat? (Boolean)<br>**
Allow all players to use chat while unconcious? Admin can always use the chat regardless.<br>
`Default value: No`
### 1.8 Rallypoint System
*Part of: ACE_Respawn*
This module was introduced with 0.94 and enables Mission Makers to specificly enable units to move a rallypoint. Every unit that is synced with that module is able to move a rallypoint.
**Note:**
It's important to mention that this doesn't work for player who join during a mission (JIP = Join in progress). That's something we can't change because that's the way Bohemia has implemented their module framework. To enable JIP players to move rally points have a look at [3.1 ACE Rallypoints](#31-ace-rallypoints).
### 1.9 Repair System
*Part of: ACE_Logistics*
Placing the "Repair System" module makes it possible to define the time it takes for certain repair actions.
**Settings:**
1. **Heavy Repair Time (Number)<br>**
Time to repair engine/turret/body/fuel components (in seconds).<br>
`Default value: 10`
2. **Wheel Replace Time (Number)<br>**
Time to replace a wheel (in seconds).<br>
`Default value: 10`
3. **Track Replace Time (Number)<br>**
Time to replace a track (in seconds).<br>
`Default value: 10`
4. **Maximum Repaired Damage (Number)<br>**
Limits the amount of damage that can be repaired. 0 = Repair all damage, 1 = Cannot repair any damage.<br>
`Default value: 0`
### 1.10 Respawn System
*Part of: ACE_Respawn*
The "Respawn System" module enables players to respawn with the gear they had before dying and to remove bodies of players after a configurable interval (in seconds).
**Settings:**
1. **Save Gear? (Boolean)<br>**
Respawn with the gear a player had just before his death.<br>
`Default value: No`
### 1.11 SwitchUnits System
*Part of: ACE_SwitchUnits*
The [SwitchUnits System](#32-ace-switchunits) enables players to control certain AI units on the map.
**Settings:**
1. **Switch To West? (Boolean)<br>**
Allow switching to west units?<br>
`Default value: No`
2. **Switch To East? (Boolean)<br>**
Allow switching to east units?<br>
`Default value: No`
3. **Switch To Independent? (Boolean)<br>**
Allow switching to independent units?<br>
`Default value: No`
4. **Switch To Civilian? (Boolean)<br>**
Allow switching to civilian units?<br>
`Default value: No`
5. **Enable Safe Zone? (Boolean)<br>**
Enable a safe zone around enemy units? Players can't switch to units inside of the safe zone.<br>
`Default value: Yes`
6. **Safe Zone Radius (Number)<br>**
The safe zone around players from a different team (in meters)<br>
`Default value: 200`
### 1.12 LSD Vehicles
*Part of: ACE_Core*
And then there's the "LSD Vehicles" module &hellip; it does 'something' to all vehicles synced to that module.
http://youtu.be/X3e0LTexEok

View File

@ -0,0 +1,16 @@
---
layout: wiki
title: Getting Started
group: user
order: 0
parent: wiki
---
## Table of Contents
1. [xx](#xx)
2. [yy](#yy)
3. [zz](#zz)
## What ACE3 has to offer

View File

@ -0,0 +1,49 @@
---
layout: wiki
title: How to report an issue
group: user
order: 10
parent: wiki
---
### Before reporting
If you've found an issue with ACE3 please make sure that ACE3 is really the cause of the problem. To do this try to reproduce the issue with using only `@cba_a3` and `@ACE3` on a newly created mission.
<div class="panel callout">
<h5>Please note:</h5>
<p>It's not a valid to simply remove <code>@ACE3</code> from the mod list to confirm that ACE3 is the culprit.</p>
<p>If the error happens when using a <b>third-party mod</b> contact the author of the appropriate mod and report the issue there.</p>
</div>
### Reporting the issue
Head over to the <a href="{{ site.githubUrl }}/issues" target="_blank">ACE3 GitHub issue tracker</a> and press the <a href="{{ site.githubUrl }}/issues/new" target="_blank">"New issue"</a> button in the top right corner. Add a descriptive title and copy the following issue template in to the text area:
```
ACE3 Version: 3.x.x
**Mods:**
* @cba_a3
* @ace3
**Placed ACE3 Modules:**
* *Add the list of modules you have placed on the map. Use 'None' if the error occurs without using any modules.*
**Description:**
*Add a detailed description of the error. This makes it easier for us to fix the issue.*
**Steps to reproduce:**
* *Add the steps needed to reproduce the issue.*
**Where did the issue occur?**
*A possible answer might be "Multiplayer", "Singleplayer"*
**RPT log file:**
*Add a link (pastebin.com) to the client or server RPT file.*
```
A video of the issue might be helpful in resolving it faster.
Github uses <a href="http://daringfireball.net/projects/markdown/syntax" target="_blank">"Markdown"</a> to style the output. If you want to know more about it (e.g. how to <a href="https://help.github.com/articles/markdown-basics/#styling-text" target="_blank">turn text bold</a>, how to denote <a href="https://help.github.com/articles/markdown-basics/#inline-formats" target="_blank">code blocks</a> or <a href="https://help.github.com/articles/markdown-basics/#multiple-lines" target="_blank">inline code</a>) have a look at the <a href="https://help.github.com/articles/github-flavored-markdown/" target="_blank">GitHub markdown documentation</a>.

View File

@ -0,0 +1,34 @@
---
layout: wiki
title: Promotional Material
group: user
order: 20
parent: wiki
---
You are hereby granted to use the ACE3 logos and imagery for promotional purposes. You are NOT allowed to use it commercially.
## Colors
![white](https://cloud.githubusercontent.com/assets/1235520/6618806/d19959e4-c8c5-11e4-85f4-814c93ec7778.jpg) White: `#ffffff, rgb(255, 255, 255)`<br/>
![black](https://cloud.githubusercontent.com/assets/1235520/6618807/d2c7bf0e-c8c5-11e4-8c43-6de02d47898c.jpg) Black: `#000000, rgb(0, 0, 0)`<br/>
![red](https://cloud.githubusercontent.com/assets/1235520/6618808/d3e6a62a-c8c5-11e4-9313-4db522a40117.jpg) Red: `#ba2619, rgb(186, 38, 25)`
## Logo
When using the ACE3 logo please do not stretch or skew it.
### Black
<img src="{{ site.baseurl }}/img/ace3-logo-black-small.png" height="30" />
* [JPG (white background)](https://github.com/KoffeinFlummi/ACE3/blob/master/extras/assets/logo/black/ACE3-Logo.jpg)
* [PNG (transparent background)](https://github.com/KoffeinFlummi/ACE3/blob/master/extras/assets/logo/black/ACE3-Logo.png)
* [EPS (vector file)](https://github.com/KoffeinFlummi/ACE3/blob/master/extras/assets/logo/black/ACE3-Logo.eps)
### White
<img src="{{ site.baseurl }}/img/ace3-logo-white-small.png" height="30" style="background-color: black; padding: 2px;" />
* [JPG (black background)](https://github.com/KoffeinFlummi/ACE3/blob/master/extras/assets/logo/white/ACE3-Logo.jpg)
* [PNG (transparent background)](https://github.com/KoffeinFlummi/ACE3/blob/master/extras/assets/logo/white/ACE3-Logo.png)
* [EPS (vector file)](https://github.com/KoffeinFlummi/ACE3/blob/master/extras/assets/logo/white/ACE3-Logo.eps)

View File

@ -0,0 +1,204 @@
---
layout: wiki
title: Shortcuts
group: user
order: 5
parent: wiki
---
<table>
<thead>
<tr>
<th>PBO</th>
<th>Command</th>
<th>Shortcut</th>
</tr>
</thead>
<tbody>
<tr>
<td>ACE_Interaction</td>
<td>Interaction Menu</td>
<td><kbd>Win_Left</kbd></td>
</tr>
<tr>
<td>ACE_Interaction</td>
<td>Interaction Menu (Self)</td>
<td><kbd>Ctrl</kbd> <kbd>Win_Left</kbd></td>
</tr>
<tr>
<td>ACE_Interaction</td>
<td>Open / Close Door</td>
<td><kbd>Ctrl</kbd> <kbd>Space</kbd></td>
</tr>
<tr>
<td>ACE_Interaction</td>
<td>Tap Shoulder</td>
<td><kbd>Ctrl</kbd> <kbd>T</kbd></td>
</tr>
<tr>
<td>ACE_Logistics</td>
<td>Modifier Key</td>
<td><kbd>Ctrl_Left</kbd></td>
</tr>
<tr>
<td>ACE_Goggles</td>
<td>Wipe Goggles</td>
<td><kbd>Ctrl</kbd> <kbd>Shift</kbd> <kbd>T</kbd></td>
</tr>
<tr>
<td>ACE_Grenades</td>
<td>Switch Grenade Mode</td>
<td><kbd>8</kbd></td>
</tr>
<tr>
<td>ACE_NameTags</td>
<td>Show Names</td>
<td><kbd>Ctrl_Left</kbd></td>
</tr>
<tr>
<td>ACE_NightVision</td>
<td>Increase NVG Brightness</td>
<td><kbd>Alt</kbd> <kbd>Page Up</kbd></td>
</tr>
<tr>
<td>ACE_NightVision</td>
<td>Decrease NVG Brightness</td>
<td><kbd>Alt</kbd> <kbd>Page Down</kbd></td>
</tr>
<tr>
<td>ACE_Overheating</td>
<td>Clear jam</td>
<td><kbd>Shift</kbd> <kbd>R</kbd></td>
</tr>
<tr>
<td>ACE_Parachute</td>
<td>Show Altimeter</td>
<td><kbd>O</kbd></td>
</tr>
<tr>
<td>ACE_Reload</td>
<td>Check Ammo</td>
<td><kbd>Ctrl</kbd> <kbd>R</kbd></td>
</tr>
<tr>
<td>ACE_SafeMode</td>
<td>Safe Mode</td>
<td><kbd>`</kbd>(en) | <kbd>^</kbd>(de)</td>
</tr>
<tr>
<td>ACE_Scopes</td>
<td>Adjust Elevation Up</td>
<td><kbd>Page Up</kbd></td>
</tr>
<tr>
<td>ACE_Scopes</td>
<td>Adjust Elevation Down</td>
<td><kbd>Page Down</kbd></td>
</tr>
<tr>
<td>ACE_Scopes</td>
<td>Adjust Windage Left</td>
<td><kbd>Ctrl</kbd> <kbd>Page Up</kbd></td>
</tr>
<tr>
<td>ACE_Scopes</td>
<td>Adjust Windage Right</td>
<td><kbd>Ctrl</kbd> <kbd>Page Down</kbd></td>
</tr>
<tr>
<td>ACE_Vector</td>
<td>Vector - Azimuth Key</td>
<td><kbd>Tab</kbd></td>
</tr>
<tr>
<td>ACE_Vector</td>
<td>Vector - Distance Key</td>
<td><kbd>R</kbd></td>
</tr>
<tr>
<td>ACE_Vehicles</td>
<td>Speed Limiter</td>
<td><kbd>Del</kbd></td>
</tr>
<tr>
<td>ACE_WeaponSelect</td>
<td>Select Pistol</td>
<td><kbd>1</kbd></td>
</tr>
<tr>
<td>ACE_WeaponSelect</td>
<td>Select Rifle</td>
<td><kbd>2</kbd></td>
</tr>
<tr>
<td>ACE_WeaponSelect</td>
<td>Select Grenade Launcher</td>
<td><kbd>3</kbd></td>
</tr>
<tr>
<td>ACE_WeaponSelect</td>
<td>Select Binoculars</td>
<td><kbd>5</kbd></td>
</tr>
<tr>
<td>ACE_WeaponSelect</td>
<td>Select Frag Grenade</td>
<td><kbd>6</kbd></td>
</tr>
<tr>
<td>ACE_WeaponSelect</td>
<td>Select Non-Frag Grenade</td>
<td><kbd>7</kbd></td>
</tr>
<tr>
<td>ACE_WeaponSelect</td>
<td>Holster Weapon</td>
<td><kbd>0</kbd></td>
</tr>
<tr>
<td>ACE_WeaponSelect</td>
<td>Engine on</td>
<td><kbd>2</kbd></td>
</tr>
<tr>
<td>ACE_WeaponSelect</td>
<td>Engine off</td>
<td><kbd>1</kbd></td>
</tr>
<tr>
<td>ACE_WeaponSelect</td>
<td>Select Main Gun</td>
<td><kbd>3</kbd></td>
</tr>
<tr>
<td>ACE_WeaponSelect</td>
<td>Select Machine Gun</td>
<td><kbd>4</kbd></td>
</tr>
<tr>
<td>ACE_WeaponSelect</td>
<td>Select Missiles</td>
<td><kbd>5</kbd></td>
</tr>
<tr>
<td>ACE_WeaponSelect</td>
<td>Fire Smoke Launcher</td>
<td><kbd>9</kbd></td>
</tr>
<tr>
<td>ACE_FireControlSsystem</td>
<td>Lase Target / Measure Distance</td>
<td><kbd>Tab</kbd></td>
</tr>
<tr>
<td>ACE_FireControlSsystem</td>
<td>Adjust FCS Range (Up)</td>
<td><kbd>Page Up</kbd></td>
</tr>
<tr>
<td>ACE_FireControlSsystem</td>
<td>Adjust FCS Range (Down)</td>
<td><kbd>Page Down</kbd></td>
</tr>
</tbody>
</table>