Merge branch 'master' into macroSTR

Conflicts:
	addons/interact_menu/ACE_Settings.hpp
This commit is contained in:
jonpas 2015-05-30 19:54:32 +02:00
commit d934c25b78
171 changed files with 2840 additions and 781 deletions

View File

@ -24,22 +24,30 @@ VKing <kauestad@gmail.com>
Walter Pearce <jaynus@gmail.com>
# CONTRIBUTORS
11RDP-LoupVert <loupvert@11rdp.fr>
[BIG]Bull
11RDP-LoupVert <loupvert@11rdp.fr>
ACCtomeek <tomeek99@gmail.com>
adam3adam <br.ada@seznam.cz>
Adanteh
aeroson
alef <alefor@gmail.com>
Aggr094 <bastards4glory@gmail.com>
alef <alefor@gmail.com>
Aleksey EpMAK Yermakov <epmak777@gmail.com>
Alganthe <alganthe@live.fr>
Anthariel <Contact@storm-simulation.com>
Asgar Serran <piechottaf@web.de>
Bla1337
BlackPixxel
BlackQwar
Brakoviejo
Brisse <brisse@outlook.com>
BullHorn <bullhorn7@gmail.com>
Clon1998 <ps.patti1998@gmail.com>
Codingboy
Coren <coren4@gmail.com>
Crusty
Dharma Bellamkonda <dharma.bellamkonda@gmail.com>
Dimaslg <dimaslg@telecable.e>
eRazeri
evromalarkey <evromalarkey@gmail.com>
Falke75
@ -49,31 +57,37 @@ Filip Basara <filip.basara93@googlemail.com>
FreeZbe <freeseb@gmail.com>
geraldbolso1899
Ghost
Gianmarco Varriale (TeamNuke) <admin@forhost.org>
GieNkoV <gienkov.grzegorz@gmail.com>
gpgpgpgp
Grzegorz
Gianmarco Varriale (TeamNuke) <admin@forhost.org>
Hamburger SV
Harakhti <shadowdragonphd@gmail.com>
havena <silveredenis@gmail.com>
Hawkins
jokoho48
Jonpas <jonpas33@gmail.com>
Kavinsky <nmunozfernandez@gmail.com>
Kllrt <kllrtik@gmail.com>
legman <juicemelon@msn.com>
Legolasindar "Viper" <legolasindar@gmail.com>
licht-im-Norden87 <lichtimnorden87@gmail.com>
MarcBook
meat <p.humberdroz@gmail.com>
Michail Nikolaev
nic547 <nic547@outlook.com>
nikolauska <nikolauska1@gmail.com>
nomisum <nomisum@gmail.com>
OnkelDisMaster <onkeldismaster@gmail.com>
oscarmolinadev
pokertour
Professor <lukas.trneny@wo.cz>
rakowozz
ramius86 <pasini86@hotmail.com>
Raspu86
Riccardo Petricca <petriccarcc@gmail.com>
Robert Boklahánics <bokirobi@gmail.com>
ramius86 <pasini86@hotmail.com>
ruPaladin <happyworm24@rambler.ru>
SilentSpike <SilentSpike100@gmail.com>
simon84 <badguy360th@gmail.com>
Sniperwolf572 <tenga6@gmail.com>
@ -82,20 +96,6 @@ Toaster <jonathan.pereira@gmail.com>
Tonic
Tourorist <tourorist@gmail.com>
Valentin Torikian <valentin.torikian@gmail.com>
zGuba
Aleksey EpMAK Yermakov <epmak777@gmail.com>
ruPaladin <happyworm24@rambler.ru>
BlackPixxel
Asgar Serran <piechottaf@web.de>
Kavinsky <nmunozfernandez@gmail.com>
Coren <coren4@gmail.com>
OnkelDisMaster <onkeldismaster@gmail.com>
Dimaslg <dimaslg@telecable.e>
VyMajoris(W-Cephei)<vycanismajoriscsa@gmail.com>
Bla1337
nikolauska <nikolauska1@gmail.com>
adam3adam <br.ada@seznam.cz>
Professor <lukas.trneny@wo.cz>
Winter <simon@agius-muscat.net>
Dharma Bellamkonda <dharma.bellamkonda@gmail.com>
legman <juicemelon@msn.com>
zGuba

BIN
ace_medical.dll Normal file

Binary file not shown.

View File

@ -139,4 +139,4 @@
<Polish>Moduł ten pozwala aktywować zaawansowaną balistykę biorącą przy obliczeniach trajektorii lotu pocisku pod uwagę takie rzeczy jak temperatura powietrza, ciśnienie atmosferyczne, wilgotność powietrza, siły Coriolisa i Eotvosa, grawitację a także broń z jakiej wykonywany jest strzał oraz rodzaj amunicji. Wszystko to sprowadza się na bardzo dokładne odwzorowanie balistyki.</Polish>
</Key>
</Package>
</Project>
</Project>

View File

@ -47,7 +47,7 @@ _temperature = GVAR(temperature);
_barometricPressure = GVAR(barometricPressure);
_relativeHumidity = GVAR(relativeHumidity);
if (!GVAR(atmosphereModeTBH)) then {
_barometricPressure = 1013.25 * exp(-(_altitude) / 7990);
_barometricPressure = 1013.25 * (1 - (0.0065 * _altitude) / (273.15 + _temperature + 0.0065 * _altitude)) ^ 5.255754495;
_relativeHumidity = 50;
};

View File

@ -47,7 +47,7 @@ _temperature = GVAR(temperature);
_barometricPressure = GVAR(barometricPressure);
_relativeHumidity = GVAR(relativeHumidity);
if (!GVAR(atmosphereModeTBH)) then {
_barometricPressure = 1013.25 * exp(-(_altitude) / 7990);
_barometricPressure = 1013.25 * (1 - (0.0065 * _altitude) / (273.15 + _temperature + 0.0065 * _altitude)) ^ 5.255754495;
_relativeHumidity = 50;
};

View File

@ -15,7 +15,7 @@
*/
#include "script_component.hpp"
private ["_range", "_elevation", "_windage1", "_windage2", "_clickSize", "_clickNumber", "_clickInterval", "_lead", "_TOF", "_velocity", "_kineticEnergy", "_rangeOutput", "_elevationOutput", "_windageOutput", "_lastColumnOutput"];
private ["_range", "_elevation", "_windage1", "_windage2", "_clickSize", "_clickNumber", "_clickInterval", "_lead", "_TOF", "_velocity", "_kineticEnergy", "_rangeOutput", "_elevationOutput", "_windageOutput", "_lastColumnOutput", "_speedOfSound"];
_lastColumnOutput = "";
if (GVAR(showWind2) && GVAR(rangeCardCurrentColumn) == 0) then {
@ -32,6 +32,8 @@ if (GVAR(currentUnit) == 1) then {
lnbClear 5007;
_speedOfSound = GVAR(temperature) call EFUNC(weather,calculateSpeedOfSound);
{
_range = _x select 0;
_elevation = _x select 1;
@ -72,7 +74,7 @@ lnbClear 5007;
_windageOutput = Str(Round(_windage1 * 100) / 100);
_rangeOutput = Str(_range);
if (_velocity < 340.29) then {
if (_velocity < _speedOfSound) then {
_rangeOutput = _rangeOutput + "*";
};

View File

@ -3,12 +3,6 @@
//IGNORE_PRIVATE_WARNING("_handleNetEvent", "_handleRequestAllSyncedEvents", "_handleRequestSyncedEvent", "_handleSyncedEvent");
// Load settings from profile
if (hasInterface) then {
call FUNC(loadSettingsFromProfile);
call FUNC(loadSettingsLocalizedText);
};
// Listens for global "SettingChanged" events, to update the force status locally
["SettingChanged", {
PARAMS_2(_name,_value);
@ -253,3 +247,37 @@ if(isMultiplayer && { ACE_time > 0 || isNull player } ) then {
};
}, 0, []] call cba_fnc_addPerFrameHandler;
};
GVAR(commonPostInited) = true;
// Create a pfh to wait until all postinits are ready and settings are initialized
[{
PARAMS_1(_args);
EXPLODE_1_PVT(_args,_waitingMsgSent);
// If post inits are not ready then wait
if !(SLX_XEH_MACHINE select 8) exitWith {};
// If settings are not initialized then wait
if (isNil QGVAR(settings)) exitWith {
if (!_waitingMsgSent) then {
_args set [0, true];
diag_log text format["[ACE] Waiting on settings from server"];
};
};
[(_this select 1)] call cba_fnc_removePerFrameHandler;
diag_log text format["[ACE] Settings received from server"];
// Load user settings from profile
if (hasInterface) then {
call FUNC(loadSettingsFromProfile);
call FUNC(loadSettingsLocalizedText);
};
diag_log text format["[ACE] Settings initialized"];
//Event that settings are safe to use:
["SettingsInitialized", []] call FUNC(localEvent);
}, 0, [false]] call cba_fnc_addPerFrameHandler;

View File

@ -180,6 +180,7 @@ PREP(toHex);
PREP(toNumber);
PREP(uniqueElementsOnly);
PREP(unloadPerson);
PREP(unloadPersonLocal);
PREP(unmuteUnit);
PREP(useItem);
PREP(useMagazine);
@ -293,7 +294,7 @@ GVAR(waitAndExecArray) = [];
//Debug
ACE_COUNTERS = [];
// Load settings
// Load settings on the server and broadcast them
if (isServer) then {
call FUNC(loadSettingsOnServer);
};

View File

@ -10,12 +10,12 @@
*
* Public: No
*/
//#define DEBUG_MODE_FULL
#include "script_component.hpp"
#define GROUP_SWITCH_ID QUOTE(FUNC(loadPerson))
private ["_vehicle", "_loaded", "_emptyPos"];
private ["_vehicle","_emptyPos"];
PARAMS_1(_unit);
_vehicle = vehicle _unit;
@ -25,20 +25,8 @@ if !(speed _vehicle <1 && (((getpos _vehicle) select 2) < 2)) exitwith {false;};
_emptyPos = ((getPos _vehicle) findEmptyPosition [0, 10, typeof _unit]);
if (count _emptyPos == 0) exitwith {false};
_unit setPos _emptyPos;
unassignVehicle _unit;
if (!alive _unit) then {
_unit action ["Eject", vehicle _unit];
};
[_unit, false, GROUP_SWITCH_ID, side group _unit] call FUNC(switchToGroupSide);
_loaded = _vehicle getvariable [QGVAR(loaded_persons),[]];
_loaded = _loaded - [_unit];
_vehicle setvariable [QGVAR(loaded_persons),_loaded,true];
if (!([_unit] call FUNC(isAwake))) then {
[_unit,([_unit] call FUNC(getDeathAnim)), 1, true] call FUNC(doAnimation);
if (!isNull _vehicle) then {
[[_unit], QUOTE(FUNC(unloadPersonLocal)), _unit, false] call EFUNC(common,execRemoteFnc);
};
true;

View File

@ -0,0 +1,44 @@
/*
* Author: ViperMaul
* Unload a person from a vehicle, local
*
* Arguments:
* 0: unit <OBJECT>
*
* Return Value:
* Returns true if succesfully unloaded person <BOOL>
*
* Public: No
*/
//#define DEBUG_MODE_FULL
#include "script_component.hpp"
#define GROUP_SWITCH_ID QUOTE(FUNC(loadPerson))
private ["_vehicle", "_loaded", "_emptyPos"];
PARAMS_1(_unit);
_vehicle = vehicle _unit;
if (_vehicle == _unit) exitwith {false;};
if !(speed _vehicle <1 && (((getpos _vehicle) select 2) < 2)) exitwith {false;};
_emptyPos = ((getPos _vehicle) findEmptyPosition [0, 10, typeof _unit]);
if (count _emptyPos == 0) exitwith {false};
_unit setPos _emptyPos;
unassignVehicle _unit;
if (!alive _unit) then {
_unit action ["Eject", vehicle _unit];
};
[_unit, false, GROUP_SWITCH_ID, side group _unit] call FUNC(switchToGroupSide);
_loaded = _vehicle getvariable [QGVAR(loaded_persons),[]];
_loaded = _loaded - [_unit];
_vehicle setvariable [QGVAR(loaded_persons),_loaded,true];
if (!([_unit] call FUNC(isAwake))) then {
[_unit,([_unit] call FUNC(getDeathAnim)), 1, true] call FUNC(doAnimation);
};
true;

View File

@ -9,12 +9,19 @@ class Extended_PostInit_EventHandlers {
};
};
/*
TODO: Move the addEventHandlers out of PostInit into here or separate eventHandlers,
to enable them on all units, so unit switching works for explosives properly.
class Extended_Init_EventHandlers {
class CAManBase {
init = "";
}
}
*/
class Extended_Killed_EventHandlers {
class CAManBase {
GVAR(killedHandler) = QUOTE(_this call FUNC(onKilled));
};
};
class Extended_Take_EventHandlers {
class CAManBase {
GVAR(takeHandler) = QUOTE([ARR_3(_this select 0, _this select 1, _this select 2)] call FUNC(onInventoryChanged));
};
};
class Extended_Put_EventHandlers {
class CAManBase {
GVAR(takeHandler) = QUOTE([ARR_3(_this select 1, _this select 0, _this select 2)] call FUNC(onInventoryChanged));
};
};

View File

@ -50,47 +50,3 @@ GVAR(CurrentSpeedDial) = 0;
}] call EFUNC(common,addEventHandler);
[{(_this select 0) call FUNC(handleScrollWheel);}] call EFUNC(Common,addScrollWheelEventHandler);
player addEventHandler ["Killed", {
private "_deadman";
call FUNC(place_Cancel);
_deadman = [(_this select 0), "DeadManSwitch"] call FUNC(getPlacedExplosives);
{
[(_this select 0), -1, _x, true] call FUNC(detonateExplosive);
} count _deadman;
}];
player addEventHandler ["Take", {
private ["_item", "_getter", "_giver", "_config", "_detonators"];
_item = _this select 2;
_getter = _this select 0;
_giver = _this select 1;
_config = ConfigFile >> "CfgWeapons" >> _item;
if (isClass _config && {getNumber(_config >> "ACE_Detonator") == 1}) then {
private ["_clackerItems"];
_clackerItems = _giver getVariable [QGVAR(Clackers), []];
_getter SetVariable [QGVAR(Clackers), (_getter getVariable [QGVAR(Clackers), []]) + _clackerItems, true];
_detonators = [_giver] call FUNC(getDetonators);
if (count _detonators == 0) then {
_giver setVariable [QGVAR(Clackers), nil, true];
};
};
}];
player addEventHandler ["Put", {
private ["_item", "_getter", "_giver", "_config"];
_item = _this select 2;
_getter = _this select 1;
_giver = _this select 0;
_config = ConfigFile >> "CfgWeapons" >> _item;
if (isClass _config && {getNumber(_config >> "ACE_Detonator") == 1}) then {
private ["_clackerItems"];
_clackerItems = _giver getVariable [QGVAR(Clackers), []];
_getter SetVariable [QGVAR(Clackers), (_getter getVariable [QGVAR(Clackers), []]) + _clackerItems, true];
_detonators = [_giver] call FUNC(getDetonators);
if (count _detonators == 0) then {
_giver setVariable [QGVAR(Clackers), nil, true];
};
};
}];

View File

@ -42,6 +42,8 @@ PREP(getSpeedDialExplosive);
PREP(module);
PREP(onInventoryChanged);
PREP(onKilled);
PREP(onLanded);
PREP(openTimerSetUI);

View File

@ -0,0 +1,35 @@
/*
* Author: Garth 'L-H' de Wet
* When a take/put event handler fires and a detonator is changed hands.
* Then take "attached" explosives.
*
* Arguments:
* 0: Receiver <OBJECT>
* 1: Giver <OBJECT>
* 2: Item <STRING>
*
* Return Value:
* None
*
* Example:
* Handled by CBA
*
* Public: No
*/
#include "script_component.hpp"
private ["_config", "_detonators"];
PARAMS_3(_receiver,_giver,_item);
if (_receiver != ace_player) exitWith {};
_config = ConfigFile >> "CfgWeapons" >> _item;
if (isClass _config && {getNumber(_config >> "ACE_Detonator") == 1}) then {
private ["_clackerItems"];
_clackerItems = _giver getVariable [QGVAR(Clackers), []];
_receiver SetVariable [QGVAR(Clackers), (_receiver getVariable [QGVAR(Clackers), []]) + _clackerItems, true];
_detonators = [_giver] call FUNC(getDetonators);
if (count _detonators == 0) then {
_giver setVariable [QGVAR(Clackers), nil, true];
};
};

View File

@ -0,0 +1,26 @@
/*
* Author: Garth 'L-H' de Wet
* Detonates all attached deadman's switched triggered explosives.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* None
*
* Example:
* Handled by CBA
*
* Public: No
*/
#include "script_component.hpp"
private ["_deadman"];
_unit = _this select 0;
if (_unit == ACE_player) then {
call FUNC(place_Cancel);
};
if (!isServer) exitWith{};
_deadman = [_unit, "DeadManSwitch"] call FUNC(getPlacedExplosives);
{
[_unit, -1, _x, true] call FUNC(detonateExplosive);
} foreach _deadman;

View File

@ -47,6 +47,8 @@ GVAR(DustHandler) = -1;
GVAR(RainDrops) = objNull;
GVAR(RainActive) = false;
GVAR(RainLastLevel) = 0;
GVAR(surfaceCache) = "";
GVAR(surfaceCacheIsDust) = false;
FUNC(CheckGlasses) = {
if (GVAR(Current) != (goggles ace_player)) then {

View File

@ -15,7 +15,7 @@
* Public: No
*/
#include "script_component.hpp"
private ["_bullets", "_position", "_surface", "_found", "_weapon", "_cloudType", "_unit"];
private ["_bullets", "_position", "_surface", "_weapon", "_cloudType", "_unit"];
EXPLODE_2_PVT(_this,_unit,_weapon);
if (_unit != ace_player) exitWith {true};
_cloudType = "";
@ -39,12 +39,14 @@ if (surfaceIsWater _position) exitWith {};
if ((_position select 2) > 0.2) exitWith {};
_surface = surfaceType _position;
_surface = ([_surface, "#"] call CBA_fnc_split) select 1;
_found = false;
_found = getNumber (ConfigFile >> "CfgSurfaces" >> _surface >> "dust") >= 0.1;
if (_surface != GVAR(surfaceCache)) then {
GVAR(surfaceCache) = _surface;
_surface = ([_surface, "#"] call CBA_fnc_split) select 1;
GVAR(surfaceCacheIsDust) = getNumber (ConfigFile >> "CfgSurfaces" >> _surface >> "dust") >= 0.1;
};
if (!_found) exitWith {};
if (!GVAR(surfaceCacheIsDust)) exitWith {};
_bullets = GETDUSTT(DBULLETS);

View File

@ -4,7 +4,7 @@ class ACE_Settings {
typeName = "BOOL";
isClientSettable = 1;
displayName = CSTRING(AlwaysUseCursorSelfInteraction);
};
};
class GVAR(cursorKeepCentered) {
value = 0;
typeName = "BOOL";
@ -54,14 +54,14 @@ class ACE_Settings {
isClientSettable = 1;
displayName = CSTRING(textSize);
values[] = {"$str_very_small", "$str_small", "$str_medium", "$str_large", "$str_very_large"};
};
};
class GVAR(shadowSetting) {
value = 2;
typeName = "SCALAR";
isClientSettable = 1;
displayName = CSTRING(shadowSetting);
description = CSTRING(shadowSettingDescription);
values[] = {"$STR_A3_OPTIONS_DISABLED", "$STR_A3_OPTIONS_ENABLED", STRING(shadowOutline)};
values[] = {"$STR_A3_OPTIONS_DISABLED", "$STR_A3_OPTIONS_ENABLED", CSTRING(shadowOutline)};
};
class GVAR(actionOnKeyRelease) {
value = 1;
@ -69,4 +69,11 @@ class ACE_Settings {
isClientSettable = 1;
displayName = CSTRING(ActionOnKeyRelease);
};
class GVAR(blurScreen) {
value = 0;
typeName = "BOOL";
isClientSettable = 1;
displayName = CSTRING(blurScreen);
description = CSTRING(blurScreenDesc);
};
};

View File

@ -62,3 +62,6 @@ addMissionEventHandler ["Draw3D", DFUNC(render)];
// disable firing while the interact menu is is is opened
["playerChanged", {_this call FUNC(handlePlayerChanged)}] call EFUNC(common,addEventHandler);
["interactMenuOpened", { if (GVAR(blurScreen)) then {[QGVAR(blurScreen), true] call EFUNC(common,blurScreen);}; }] call EFUNC(common,addEventHandler);
["interactMenuClosed", { if (GVAR(blurScreen)) then {[QGVAR(blurScreen), false] call EFUNC(common,blurScreen);}; }] call EFUNC(common,addEventHandler);

View File

@ -28,12 +28,12 @@ if !(isNil {missionNamespace getVariable [_actionsVarName, nil]}) exitWith {};
private "_recurseFnc";
_recurseFnc = {
private ["_actions", "_displayName", "_distance", "_icon", "_statement", "_position", "_condition", "_showDisabled", "_enableInside", "_canCollapse", "_runOnHover", "_children", "_entry", "_entryCfg", "_insertChildren", "_modifierFunction", "_i"];
private ["_actions", "_displayName", "_distance", "_icon", "_statement", "_position", "_condition", "_showDisabled", "_enableInside", "_canCollapse", "_runOnHover", "_children", "_entry", "_entryCfg", "_insertChildren", "_modifierFunction"];
EXPLODE_1_PVT(_this,_actionsCfg);
_actions = [];
for "_i" from 0 to (count _actionsCfg) - 1 do {
_entryCfg = _actionsCfg select _i;
{
_entryCfg = _x;
if(isClass _entryCfg) then {
_displayName = getText (_entryCfg >> "displayName");
_distance = getNumber (_entryCfg >> "distance");
@ -92,7 +92,7 @@ _recurseFnc = {
];
_actions pushBack _entry;
};
};
} forEach (configProperties [_actionsCfg, "isClass _x", true]);
_actions
};

View File

@ -33,8 +33,8 @@ _recurseFnc = {
EXPLODE_1_PVT(_this,_actionsCfg);
_actions = [];
for "_i" from 0 to (count _actionsCfg) - 1 do {
_entryCfg = _actionsCfg select _i;
{
_entryCfg = _x;
if(isClass _entryCfg) then {
_displayName = getText (_entryCfg >> "displayName");
@ -76,7 +76,7 @@ _recurseFnc = {
];
_actions pushBack _entry;
};
};
} forEach (configProperties [_actionsCfg, "isClass _x", true]);
_actions
};

View File

@ -217,5 +217,11 @@
<Hungarian>Körvonal</Hungarian>
<Italian>Contorno</Italian>
</Key>
<Key ID="STR_ACE_Interact_Menu_blurScreen">
<English>Blur screen on interaction</English>
</Key>
<Key ID="STR_ACE_Interact_Menu_blurScreenDesc">
<English>Blur the background while the interaction menu is open.</English>
</Key>
</Package>
</Project>

View File

@ -1,15 +1,25 @@
class CfgVehicles {
class Helicopter_Base_F;
class UAV_01_base_F: Helicopter_Base_F {
class Air;
class Helicopter: Air {
class ACE_Actions {
class ACE_MainActions {
class ACE_MainActions {};
};
};
class Helicopter_Base_F: Helicopter {
class ACE_Actions: ACE_Actions{
class ACE_MainActions: ACE_MainActions {};
};
};
class UAV_01_base_F: Helicopter_Base_F {
class ACE_Actions: ACE_Actions{
class ACE_MainActions: ACE_MainActions {
class GVAR(RefuelUAV) {
displayName = CSTRING(Recharge);
distance = 4;
condition = QUOTE([ARR_2(_player, _target)] call FUNC(canRefuelUAV));
statement = QUOTE([ARR_2(_player, _target)] call FUNC(refuelUAV));
showDisabled = 0; \
priority = 1.245; \
showDisabled = 0;
priority = 1.245;
icon = QUOTE(PATHTOF(ui\UAV_battery_ca.paa));
};
};

View File

@ -206,8 +206,9 @@ class ACE_Medical_Actions {
items[] = {"ACE_surgicalKit"};
treatmentLocations[] = {QGVAR(useLocation_SurgicalKit)};
requiredMedic = QGVAR(medicSetting_SurgicalKit);
treatmentTime = 10;
callbackSuccess = QUOTE(DFUNC(treatmentAdvanced_surgicalKit));
treatmentTime = "(count ((_this select 1) getVariable ['ACE_Medical_bandagedWounds', []]) * 5)";
callbackSuccess = "";
callbackProgress = QUOTE(DFUNC(treatmentAdvanced_surgicalKit_onProgress));
itemConsumed = QGVAR(consumeItem_SurgicalKit);
animationCaller = "AinvPknlMstpSnonWnonDnon_medic1";
litter[] = { {"All", "", {"ACE_MedicalLitter_gloves"} }};

View File

@ -156,7 +156,7 @@ class CfgWeapons {
class ACE_salineIV_500: ACE_salineIV {
displayName = $STR_ACE_Medical_Saline_IV_500;
class ItemInfo: InventoryItem_Base_F {
mass = 2.5;
mass = 5;
};
};
class ACE_salineIV_250: ACE_salineIV {

View File

@ -78,6 +78,7 @@ PREP(treatmentAdvanced_fullHeal);
PREP(treatmentAdvanced_fullHealLocal);
PREP(treatmentAdvanced_medication);
PREP(treatmentAdvanced_medicationLocal);
PREP(treatmentAdvanced_surgicalKit_onProgress);
PREP(treatmentBasic_bandage);
PREP(treatmentBasic_bloodbag);
PREP(treatmentBasic_bloodbagLocal);

View File

@ -21,3 +21,7 @@ class CfgPatches {
#include "ACE_Settings.hpp"
#include "UI\RscTitles.hpp"
#include "UI\triagecard.hpp"
class ACE_Extensions {
extensions[] += {"ace_medical"};
};

View File

@ -22,12 +22,6 @@ _drag = if (count _this > 2) then {_this select 2} else {false};
// cannot unload a unit not in a vehicle.
if (vehicle _target == _target) exitwith {};
if (([_target] call cse_fnc_isAwake)) exitwith {};
if (([_target] call EFUNC(common,isAwake))) exitwith {};
if ([_target] call EFUNC(common,unloadPerson)) then {
if (_drag) then {
if ((vehicle _caller) == _caller) then {
[[_caller, _target, true], QUOTE(DFUNC(actionDragUnit)), _caller, false] call EFUNC(common,execRemoteFnc); // TODO replace by event
};
};
};
[_target] call EFUNC(common,unloadPerson)

View File

@ -24,120 +24,43 @@ _damage = _this select 2;
_typeOfProjectile = _this select 3;
_typeOfDamage = _this select 4;
// Convert the selectionName to a number and ensure it is a valid selection.
_bodyPartn = [_selectionName] call FUNC(selectionNameToNumber);
if (_bodyPartn < 0) exitwith {};
// Get the injury type information. Format: [typeDamage thresholds, selectionSpecific, woundTypes]
_injuryTypeInfo = missionNamespace getvariable [format[QGVAR(woundInjuryType_%1), _typeOfDamage],[[], false, []]];
// This are the available injuries for this damage type. Format [[classtype, selections, bloodloss, minimalDamage, pain], ..]
_allInjuriesForDamageType = _injuryTypeInfo select 2;
// It appears we are dealing with an unknown type of damage.
if (count _allInjuriesForDamageType == 0) then {
// grabbing the configuration for unknown damage type
_injuryTypeInfo = missionNamespace getvariable [QGVAR(woundInjuryType_unknown),[[], false, []]];
_allInjuriesForDamageType = _injuryTypeInfo select 2;
};
// find the available injuries for this damage type and damage amount
_highestPossibleSpot = -1;
_highestPossibleDamage = -1;
_allPossibleInjuries = [];
{
_damageLevels = _x select 4;
_minDamage = _damageLevels select 0;
_maxDamage = _damageLevels select 1;
// Check if the damage is higher as the min damage for the specific injury
if (_damage >= _minDamage && {_damage <= _maxDamage || _maxDamage < 0}) then {
//_classType = _x select 0;
_selections = _x select 1;
//_bloodLoss = _x select 2;
//_pain = _x select 3;
// Check if the injury can be applied to the given selection name
if ("All" in _selections || _selectionName in _selections) then {
// Find the wound which has the highest minimal damage, so we can use this later on for adding the correct injuries
if (_minDamage > _highestPossibleDamage) then {
_highestPossibleSpot = _foreachIndex;
_highestPossibleDamage = _minDamage;
};
// Store the valid possible injury for the damage type, damage amount and selection
_allPossibleInjuries pushback _x;
};
};
}foreach _allInjuriesForDamageType;
// No possible wounds available for this damage type or damage amount.
if (_highestPossibleSpot < 0) exitwith {};
// Administration for open wounds and ids
_openWounds = _unit getvariable[QGVAR(openWounds), []];
_woundID = _unit getvariable[QGVAR(lastUniqueWoundID), 1];
_extensionOutput = "ace_medical" callExtension format ["HandleDamageWounds,%1,%2,%3,%4", _selectionName, _damage, _typeOfDamage, _woundID];
_painToAdd = 0;
_woundsCreated = [];
call compile _extensionOutput;
_foundIndex = -1;
{
if (_x select 0 <= _damage) exitwith {
for "_i" from 0 to (1+ floor(random(_x select 1)-1)) /* step +1 */ do {
// Find the injury we are going to add. Format [ classID, allowdSelections, bloodloss, painOfInjury, minimalDamage]
_toAddInjury = if (random(1) >= 0.85) then {_allInjuriesForDamageType select _highestPossibleSpot} else {_allPossibleInjuries select (floor(random (count _allPossibleInjuries)));};
_toAddClassID = _toAddInjury select 0;
_foundIndex = -1;
_bodyPartNToAdd = if (_injuryTypeInfo select 1) then {_bodyPartn} else {floor(random(6))};
// If the injury type is selection part specific, we will check if one of those injury types already exists and find the spot for it..
if ((_injuryTypeInfo select 1)) then {
{
// Check if we have an id of the given class on the given bodypart already
if (_x select 1 == _toAddClassID && {_x select 2 == _bodyPartNToAdd}) exitwith {
_foundIndex = _foreachIndex;
};
}foreach _openWounds;
};
_injury = [];
if (_foundIndex < 0) then {
// Create a new injury. Format [ID, classID, bodypart, percentage treated, bloodloss rate]
_injury = [_woundID, _toAddInjury select 0, _bodyPartNToAdd, 1, _toAddInjury select 2];
// Since it is a new injury, we will have to add it to the open wounds array to store it
_openWounds pushback _injury;
// New injuries will also increase the wound ID
_woundID = _woundID + 1;
} else {
// We already have one of these, so we are just going to increase the number that we have of it with a new one.
_injury = _openWounds select _foundIndex;
_injury set [3, (_injury select 3) + 1];
};
// Store the injury so we can process it later correctly.
_woundsCreated pushback _injury;
// Collect the pain that is caused by this injury
_painToAdd = _painToAdd + (_toAddInjury select 3);
_toAddClassID = _x select 1;
_bodyPartNToAdd = _x select 2;
{
// Check if we have an id of the given class on the given bodypart already
if (_x select 1 == _toAddClassID && {_x select 2 == _bodyPartNToAdd}) exitwith {
_foundIndex = _foreachIndex;
};
};
}foreach (_injuryTypeInfo select 0); // foreach damage thresholds
}foreach _openWounds;
_unit setvariable [QGVAR(openWounds), _openWounds, !USE_WOUND_EVENT_SYNC];
if (_foundIndex < 0) then {
// Since it is a new injury, we will have to add it to the open wounds array to store it
_openWounds pushback _x;
} else {
// We already have one of these, so we are just going to increase the number that we have of it with a new one.
_injury = _openWounds select _foundIndex;
_injury set [3, (_injury select 3) + 1];
};
}foreach _woundsCreated;
_unit setvariable [QGVAR(openWounds), _openWounds, true];
// Only update if new wounds have been created
if (count _woundsCreated > 0) then {
_unit setvariable [QGVAR(lastUniqueWoundID), _woundID, true];
};
if (USE_WOUND_EVENT_SYNC) then {
// Broadcast the new injuries across the net in parts. One broadcast per injury. Prevents having to broadcast one massive array of injuries.
{
["medical_propagateWound", [_unit, _x]] call EFUNC(common,globalEvent);
}foreach _woundsCreated;
};
_painLevel = _unit getvariable [QGVAR(pain), 0];
_unit setvariable [QGVAR(pain), _painLevel + _painToAdd];

View File

@ -118,4 +118,58 @@ _selectionSpecific = getNumber(_damageTypesConfig >> "selectionSpecific");
if (isNumber(_damageTypesConfig >> _x >> "selectionSpecific")) then { _selectionSpecificType = getNumber(_damageTypesConfig >> _x >> "selectionSpecific");};
};
missionNamespace setvariable [_varName, [_typeThresholds, _selectionSpecificType > 0, _woundTypes]];
private ["_minDamageThresholds", "_amountThresholds"];
// extension loading
_minDamageThresholds = "";
_amountThresholds = "";
{
_minDamageThresholds = _minDamageThresholds + str(_x select 0);
_amountThresholds = _amountThresholds + str(_x select 1);
if (_forEachIndex < (count _typeThresholds) - 1) then {
_minDamageThresholds = _minDamageThresholds + ":";
_amountThresholds = _amountThresholds + ":";
};
}foreach _typeThresholds;
"ace_medical" callExtension format ["addDamageType,%1,%2,%3,%4,%5", _type, GVAR(minLethalDamages) select _foreachIndex, _minDamageThresholds, _amountThresholds, _selectionSpecificType];
}foreach _allFoundDamageTypes;
// Extension loading
{
private ["_classID", "_className", "_allowedSelections", "_bloodLoss", "_pain", "_minDamage", "_maxDamage", "_causes", "_classDisplayName", "_extensionInput", "_selections", "_causesArray"];
// add shit to addInjuryType
_classID = _x select 0;
_className = GVAR(woundClassNames) select _forEachIndex;
_allowedSelections = "";
_selections = _x select 1;
{
_allowedSelections = _allowedSelections + _x;
if (_forEachIndex < (count _selections) - 1) then {
_allowedSelections = _allowedSelections + ":";
};
}foreach _selections;
_bloodLoss = _x select 2;
_pain = _x select 3;
_minDamage = (_x select 4) select 0;
_maxDamage = (_x select 4) select 1;
_causes = "";
_causesArray = (_x select 5);
{
_causes = _causes + _x;
if (_forEachIndex < (count _causesArray) - 1) then {
_causes = _causes + ":";
};
}foreach _causesArray;
_classDisplayName = _x select 6;
"ace_medical" callExtension format["addInjuryType,%1,%2,%3,%4,%5,%6,%7,%8,%9", _classID, _className, _allowedSelections, _bloodLoss, _pain, _minDamage, _maxDamage, _causes, _classDisplayName];
}foreach _allWoundClasses;
"ace_medical" callExtension "ConfigComplete";

View File

@ -16,7 +16,7 @@
#include "script_component.hpp"
private ["_caller", "_target", "_selectionName", "_className", "_config", "_medicRequired", "_items", "_locations", "_return", "_callbackProgress", "_treatmentTime", "_callerAnim", "_patientAnim", "_iconDisplayed", "_return", "_usersOfItems", "_consumeItems", "_condition", "_displayText", "_wpn"];
private ["_caller", "_target", "_selectionName", "_className", "_config", "_medicRequired", "_items", "_locations", "_return", "_callbackProgress", "_treatmentTime", "_callerAnim", "_patientAnim", "_iconDisplayed", "_return", "_usersOfItems", "_consumeItems", "_condition", "_displayText", "_wpn", "_treatmentTimeConfig"];
_caller = _this select 0;
_target = _this select 1;
_selectionName = _this select 2;
@ -174,8 +174,26 @@ if (vehicle _caller == _caller && {_callerAnim != ""}) then {
[_caller, _callerAnim] call EFUNC(common,doAnimation);
};
//Get treatment time
_treatmentTime = if (isNumber (_config >> "treatmentTime")) then {
getNumber (_config >> "treatmentTime");
} else {
if (isText (_config >> "treatmentTime")) exitwith {
_treatmentTimeConfig = getText(_config >> "treatmentTime");
if (isnil _treatmentTimeConfig) then {
_treatmentTimeConfig = compile _treatmentTimeConfig;
} else {
_treatmentTimeConfig = missionNamespace getvariable _treatmentTimeConfig;
};
if (typeName _treatmentTimeConfig == "SCALAR") exitwith {
_treatmentTimeConfig;
};
[_caller, _target, _selectionName, _className] call _treatmentTimeConfig;
};
0;
};
// Start treatment
_treatmentTime = getNumber (_config >> "treatmentTime");
[
_treatmentTime,
[_caller, _target, _selectionName, _className, _items, _usersOfItems],

View File

@ -0,0 +1,28 @@
/*
* Author: BaerMitUmlaut
* Handles treatment via surgical kit per frame.
*
* Public: No
*/
#include "script_component.hpp"
private ["_args", "_target", "_caller", "_elapsedTime", "_totalTime", "_bandagedWounds"];
_args = _this select 0;
_caller = _args select 0;
_target = _args select 1;
_elapsedTime = _this select 1;
_totalTime = _this select 2;
_bandagedWounds = _target getVariable [QGVAR(bandagedWounds), []];
//In case two people stitch up one patient and the last wound has already been closed we can stop already
if (count _bandagedWounds == 0) exitWith {false};
//Has enough time elapsed that we can close another wound?
if ((_totalTime - _elapsedTime) <= (((count _bandagedWounds) - 1) * 5)) then {
_bandagedWounds deleteAt 0;
_target setVariable [QGVAR(bandagedWounds), _bandagedWounds, true];
};
true

View File

@ -54,4 +54,12 @@ class ACE_Settings {
typeName = "SCALAR";
isClientSettable = 0;
};
class GVAR(tagSize) {
value = 2;
typeName = "SCALAR";
isClientSettable = 1;
displayName = "$STR_ACE_nametags_tagsize_name";
description = "$STR_ACE_nametags_tagsize_description";
values[] = {"$str_very_small", "$str_small", "$str_medium", "$str_large", "$str_very_large"};
};
};

View File

@ -58,5 +58,8 @@ GVAR(ShowNamesTime) = -10;
};
}, 5, []] call CBA_fnc_addPerFrameHandler;
// Draw handle
addMissionEventHandler ["Draw3D", {_this call FUNC(onDraw3d);}];
// Wait until the colors are defined before starting to draw the nametags
["SettingsInitialized", {
// Draw handle
addMissionEventHandler ["Draw3D", {_this call FUNC(onDraw3d);}];
}] call EFUNC(common,addEventHandler);

View File

@ -16,24 +16,27 @@
#include "script_component.hpp"
#define TEXTURES_RANKS [ \
"", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\private_gs.paa", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\corporal_gs.paa", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\sergeant_gs.paa", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\lieutenant_gs.paa", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\captain_gs.paa", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\major_gs.paa", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\colonel_gs.paa" \
]
private ["_height", "_position", "_color", "_name", "_rank", "_size", "_icon"];
PARAMS_5(_player,_target,_alpha,_heightOffset,_iconType);
if (_alpha < 0) exitWith {}; //Don't waste ACE_time if not visable
if (_iconType == ICON_NONE) exitWith {}; //Don't waste ACE_time if not visable
private ["_position", "_color", "_name", "_rank", "_size", "_icon", "_scale"];
if (_iconType == ICON_NONE) exitWith {}; //Don't waste time if not visable
//Set Icon:
_icon = "";
_size = 0;
if ((_iconType == ICON_NAME_SPEAK) || (_iconType == ICON_SPEAK)) then {
_icon = QUOTE(PATHTOF(UI\soundwave)) + str (floor (random 10)) + ".paa";
_size = 1;
_alpha = _alpha max 0.6;//Boost alpha when speaking
} else {
if (_iconType == ICON_NAME_RANK) then {
_icon = TEXTURES_RANKS select ((["PRIVATE", "CORPORAL", "SERGEANT", "LIEUTENANT", "CAPTAIN", "MAJOR", "COLONEL"] find (rank _target)) + 1);
_size = 1;
};
};
if (_alpha < 0) exitWith {}; //Don't waste time if not visable
//Set Text:
_name = if (_iconType in [ICON_NAME, ICON_NAME_RANK, ICON_NAME_SPEAK]) then {
@ -42,41 +45,28 @@ _name = if (_iconType in [ICON_NAME, ICON_NAME_RANK, ICON_NAME_SPEAK]) then {
""
};
//Set Icon:
_icon = "";
_size = 0;
if ((_iconType == ICON_NAME_SPEAK) || (_iconType == ICON_SPEAK)) then {
_icon = QUOTE(PATHTOF(UI\soundwave)) + str (floor (random 10)) + ".paa";
_size = 0.75;
_alpha = _alpha + 0.6;//Boost alpha when speaking
} else {
if (_iconType == ICON_NAME_RANK) then {
_icon = TEXTURES_RANKS select ((["PRIVATE", "CORPORAL", "SERGEANT", "LIEUTENANT", "CAPTAIN", "MAJOR", "COLONEL"] find (rank _target)) + 1);
_size = 0.75;
};
};
//Set Color:
if !(group _target == group _player) then {
_color = +GVAR(defaultNametagColor); //Make a copy, then multiply both alpha values (allows client to decrease alpha in settings)
_color set [3, (_color select 3) * _alpha];
} else {
_color = [[1, 1, 1, _alpha], [1, 0, 0, _alpha], [0, 1, 0, _alpha], [0, 0, 1, _alpha], [1, 1, 0, _alpha]] select (["MAIN", "RED", "GREEN", "BLUE", "YELLOW"] find (if (_target == _player) then {0} else {assignedTeam _target})) max 0
_color = [[1, 1, 1, _alpha], [1, 0, 0, _alpha], [0, 1, 0, _alpha], [0, 0, 1, _alpha], [1, 1, 0, _alpha]] select ((["MAIN", "RED", "GREEN", "BLUE", "YELLOW"] find (assignedTeam _target)) max 0);
};
_height = [2, 1.5, 1, 1.5, 1] select (["STAND", "CROUCH", "PRONE", "UNDEFINED", ""] find (stance _target));
// Convert position to ASLW (expected by drawIcon3D) and add height offsets
_position = _target modelToWorldVisual [0, 0, (_height + _heightOffset)];
_position = _target modelToWorldVisual ((_target selectionPosition "pilot") vectorAdd [0,0,(_heightOffset + .35)]);
_scale = [0.333, 0.5, 0.666, 0.83333, 1] select GVAR(tagSize);
drawIcon3D [
_icon,
_color,
_position,
_size,
_size,
(_size * _scale),
(_size * _scale),
0,
_name,
2,
0.033,
(0.05 * _scale),
"PuristaMedium"
];

View File

@ -1,9 +1,12 @@
#include "script_component.hpp"
private ["_onKeyPressAlphaMax", "_defaultIcon", "_distance", "_alpha", "_icon", "_targets", "_pos2", "_vecy", "_relPos", "_projDist", "_pos", "_target"];
private ["_onKeyPressAlphaMax", "_defaultIcon", "_distance", "_alpha", "_icon", "_targets", "_pos2", "_vecy", "_relPos", "_projDist", "_pos", "_target", "_targetEyePosASL", "_ambientBrightness", "_maxDistance"];
//don't show nametags in spectator
if (!alive ACE_player) exitWith {};
if ((isNull ACE_player) || {!alive ACE_player}) exitWith {};
_ambientBrightness = ((([] call EFUNC(common,ambientBrightness)) + ([0, 0.4] select ((currentVisionMode ace_player) != 0))) min 1) max 0;
_maxDistance = _ambientBrightness * GVAR(PlayerNamesViewDistance);
_onKeyPressAlphaMax = if ((GVAR(showPlayerNames) in [3,4])) then {
2 + (GVAR(ShowNamesTime) - ACE_time); //after release 1 second of full opacity, 1 second of fading to 0
@ -29,8 +32,7 @@ if (GVAR(showCursorTagForVehicles) && {_onKeyPressAlphaMax > 0}) then {
{GVAR(ShowNamesForAI) || {[_target] call EFUNC(common,isPlayer)}} &&
{!(_target getVariable ["ACE_hideName", false])}) then {
_distance = ACE_player distance _target;
_alpha = ((1 - 0.2 * (_distance - GVAR(PlayerNamesViewDistance))) min 1) * GVAR(PlayerNamesMaxAlpha);
_alpha = _alpha min _onKeyPressAlphaMax;
_alpha = (((1 - 0.2 * (_distance - _maxDistance)) min 1) * GVAR(PlayerNamesMaxAlpha)) min _onKeyPressAlphaMax;
[ACE_player, _target, _alpha, _distance * 0.026, _defaultIcon] call FUNC(drawNameTagIcon);
};
};
@ -46,8 +48,7 @@ if ((GVAR(showPlayerNames) in [2,4]) && {_onKeyPressAlphaMax > 0}) then {
{GVAR(ShowNamesForAI) || {[_target] call EFUNC(common,isPlayer)}} &&
{!(_target getVariable ["ACE_hideName", false])}) then {
_distance = ACE_player distance _target;
_alpha = ((1 - 0.2 * (_distance - GVAR(PlayerNamesViewDistance))) min 1) * GVAR(PlayerNamesMaxAlpha);
_alpha = _alpha min _onKeyPressAlphaMax;
_alpha = (((1 - 0.2 * (_distance - _maxDistance)) min 1) * GVAR(PlayerNamesMaxAlpha)) min _onKeyPressAlphaMax;
_icon = ICON_NONE;
if (GVAR(showSoundWaves) == 2) then { //icon will be drawn below, so only show name here
_icon = if (([_target] call FUNC(isSpeaking)) && {(vehicle _target) == _target}) then {ICON_NAME} else {_defaultIcon};
@ -61,7 +62,7 @@ if ((GVAR(showPlayerNames) in [2,4]) && {_onKeyPressAlphaMax > 0}) then {
if (((GVAR(showPlayerNames) in [1,3]) && {_onKeyPressAlphaMax > 0}) || {GVAR(showSoundWaves) == 2}) then {
_pos = positionCameraToWorld [0, 0, 0];
_targets = _pos nearObjects ["CAManBase", GVAR(PlayerNamesViewDistance) + 5];
_targets = _pos nearObjects ["CAManBase", _maxDistance + 5];
if (!surfaceIsWater _pos) then {
_pos = ATLtoASL _pos;
@ -89,18 +90,14 @@ if (((GVAR(showPlayerNames) in [1,3]) && {_onKeyPressAlphaMax > 0}) || {GVAR(sho
{GVAR(ShowNamesForAI) || {[_target] call EFUNC(common,isPlayer)}} &&
{!(_target getVariable ["ACE_hideName", false])}) then {
if (lineIntersects [_pos, (visiblePositionASL _target) vectorAdd [0,0,1], vehicle ACE_player, _target]) exitWith {}; // Check if there is line of sight
_targetEyePosASL = eyePos _target;
if (lineIntersects [_pos, _targetEyePosASL, ACE_player, _target]) exitWith {}; // Check if there is line of sight
_relPos = (visiblePositionASL _target) vectorDiff _pos;
_distance = vectorMagnitude _relPos;
_projDist = _relPos vectorDistance (_vecy vectorMultiply (_relPos vectorDotProduct _vecy));
_alpha = ((1 - 0.2 * (_distance - GVAR(PlayerNamesViewDistance))) min (1 - 0.15 * (_projDist * 5 - _distance - 3)) min 1) * GVAR(PlayerNamesMaxAlpha);
if ((GVAR(showSoundWaves) == 2) && {([_target] call FUNC(isSpeaking)) && {(vehicle _target) == _target}}) then {
_alpha = 1;
} else {
_alpha = _alpha min _onKeyPressAlphaMax;
};
_alpha = (((1 - 0.2 * (_distance - _maxDistance)) min 1) * GVAR(PlayerNamesMaxAlpha)) min _onKeyPressAlphaMax;
[ACE_player, _target, _alpha, _distance * 0.026, _icon] call FUNC(drawNameTagIcon);
};

View File

@ -2,11 +2,11 @@
#include "\z\ace\addons\main\script_mod.hpp"
#ifdef DEBUG_ENABLED_NAMETAGS
#define DEBUG_MODE_FULL
#define DEBUG_MODE_FULL
#endif
#ifdef DEBUG_SETTINGS_NAMETAGS
#define DEBUG_SETTINGS DEBUG_SETTINGS_NAMETAGS
#define DEBUG_SETTINGS DEBUG_SETTINGS_NAMETAGS
#endif
#include "\z\ace\addons\main\script_macros.hpp"
@ -16,3 +16,15 @@
#define ICON_NAME_RANK 2
#define ICON_NAME_SPEAK 3
#define ICON_SPEAK 4
//todo?: custom rank icons??
#define TEXTURES_RANKS [ \
"", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\private_gs.paa", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\corporal_gs.paa", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\sergeant_gs.paa", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\lieutenant_gs.paa", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\captain_gs.paa", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\major_gs.paa", \
"\A3\Ui_f\data\GUI\Cfg\Ranks\colonel_gs.paa" \
]

View File

@ -216,5 +216,11 @@
<English></English>
<Polish>Opcja ta pozwala dostosować sposób wyświetlania efektu fal dźwiękowych nad głowami mówiących graczy, wyświetlanych po przytrzymaniu klawisza PTT. Opcja ta współpracuje z TFAR oraz ACRE2.</Polish>
</Key>
<Key ID="STR_ACE_nametags_tagsize_name">
<English>Nametags Size</English>
</Key>
<Key ID="STR_ACE_nametags_tagsize_description">
<English>Text and Icon Size Scaling</English>
</Key>
</Package>
</Project>

View File

@ -41,7 +41,7 @@ class RscInGameUI {
};
class ACE_RscWeapon_base: RscWeaponZeroing {
controls[] = {"CA_Zeroing","CA_FOVMode","ACE_DrawReticleHelper","ReticleDay","ReticleNight","BodyNight","BodyDay"}; // don't change this order
controls[] = {"CA_Zeroing","CA_FOVMode","ACE_DrawReticleHelper","ReticleDay","ReticleNight","BodyNight","BodyDay", "trippleHeadLeft", "trippleHeadRight"}; // don't change this order
class CA_FOVMode: RscOpticsValue { // idea by Taosenai. Apparently this can be used via isNil check to determine wheter the scope or the kolimator is used
idc = 154;
@ -70,9 +70,9 @@ class RscInGameUI {
colorText[] = {1,1,1,0};
colorBackground[] = {0,0,0,0};
x = safezoneX+0.5*safezoneW-0.5*SIZEX;
y = safezoneY+0.5*safezoneH-0.5*SIZEX*safezoneW/safezoneH*(16/9)/(getResolution select 4);
y = safezoneY+0.5*safezoneH-0.5*SIZEX*(4/3);
w = SIZEX;
h = SIZEX*safezoneW/safezoneH*(16/9)/(getResolution select 4);
h = SIZEX*(4/3);
};
class ReticleNight: ReticleDay {
@ -86,15 +86,32 @@ class RscInGameUI {
idc = 1713005;
text = "";
x = safezoneX+0.5*safezoneW-0.5*SIZEX;
y = safezoneY+0.5*safezoneH-0.5*SIZEX*safezoneW/safezoneH*(16/9)/(getResolution select 4);
y = safezoneY+0.5*safezoneH-0.5*SIZEX*(4/3);
w = SIZEX;
h = SIZEX*safezoneW/safezoneH*(16/9)/(getResolution select 4);
h = SIZEX*(4/3);
};
class BodyNight: BodyDay {
idc = 1713006;
text = "";
};
//These are just black side panels to cover the areas that the optics p3d doesn't cover
//It will ONLY effect tripple head users as (safezoneX == safeZoneXAbs) for everyone else
//Reference PR #1156:
class trippleHeadLeft: RscText {
idc = 1713010;
x = "safeZoneXAbs";
Y = "safezoneY";
W = "(safezoneX - safeZoneXAbs) * ((getResolution select 4)/(16/3))";
H = "safeZoneH";
colorBackground[] = {0,0,0,1};
};
class trippleHeadRight: trippleHeadLeft {
idc = 1713011;
x = "safeZoneXAbs + safeZoneWAbs - (safezoneX - safeZoneXABS) * ((getResolution select 4)/(16/3))";
colorBackground[] = {0,0,0,1};
};
};
class ACE_RscWeapon_Hamr: ACE_RscWeapon_base {
@ -177,12 +194,12 @@ _ctrl = (D displayCtrl 1713006);
_sizeX = 1.54/(getResolution select 5);
_sizeY = _sizeX*safezoneW/safezoneH;
_ctrl ctrlSetPosition [
_ctrl ctrlSetPosition [
safezoneX+0.5*safezoneW-0.5*_sizeX,
safezoneY+0.5*safezoneH-0.5*_sizeY,
_sizeX,
_sizeY
_sizeX,
_sizeY
];
_ctrl ctrlCommit 0
*/
*/

View File

@ -52,7 +52,7 @@ _scopeShiftY = _recoilCoef * linearConversion [0, 1, random 1, SCOPE_SHIFT_Y_MIN
private ["_sizeX", "_sizeY"];
_sizeX = (0.75+_recoilScope)/(getResolution select 5);
_sizeY = _sizeX*safezoneW/safezoneH*(16/9)/(getResolution select 4);
_sizeY = _sizeX*(4/3);
private "_positionReticle";
_positionReticle = [
@ -83,7 +83,7 @@ _positionBody = [
// Bring them all back
_sizeX = 0.75/(getResolution select 5);
_sizeY = _sizeX*safezoneW/safezoneH*(16/9)/(getResolution select 4);
_sizeY = _sizeX*(4/3);
_positionReticle = [
safezoneX+0.5*safezoneW-0.5*_sizeX,

View File

@ -12,24 +12,29 @@ if (!ctrlShown (_display displayCtrl 154)) exitWith {
(_display displayCtrl 1713002) ctrlShow false;
(_display displayCtrl 1713005) ctrlShow false;
(_display displayCtrl 1713006) ctrlShow false;
};
GVAR(camera) setposATL positioncameratoworld [0,0,0.4];
GVAR(camera) camPrepareTarget positioncameratoworld [0,0,50];
GVAR(camera) camCommitPrepared 0;
// @todo, check if that needs to be done at all
if (cameraView == "GUNNER") then {
GVAR(camera) camsetFOV 0.7;
GVAR(camera) camcommit 0;
} else {
GVAR(camera) camsetFOV 0.01;
GVAR(camera) camcommit 0;
(_display displayCtrl 1713010) ctrlShow false;
(_display displayCtrl 1713011) ctrlShow false;
};
// @todo, all weapon types
private "_optic";
private ["_optic", "_isPIP"];
_optic = (primaryWeaponItems ACE_player) select 2;
_isPIP = (getText (configFile >> "CfgWeapons" >> _optic >> "ItemInfo" >> "modelOptics")) == QUOTE(PATHTOF(models\ace_optics_pip.p3d));
if (_isPIP) then {
GVAR(camera) setposATL positioncameratoworld [0,0,0.4];
GVAR(camera) camPrepareTarget positioncameratoworld [0,0,50];
GVAR(camera) camCommitPrepared 0;
// @todo, check if that needs to be done at all
if (cameraView == "GUNNER") then {
GVAR(camera) camsetFOV 0.7;
GVAR(camera) camcommit 0;
} else {
GVAR(camera) camsetFOV 0.01;
GVAR(camera) camcommit 0;
};
};
// calculate lighting
private ["_dayOpacity", "_nightOpacity"];
@ -48,9 +53,11 @@ _nightOpacity = [1,0] select (_dayOpacity == 1);
(_display displayCtrl 1713002) ctrlCommit 0;
(_display displayCtrl 1713005) ctrlCommit 0;
(_display displayCtrl 1713006) ctrlCommit 0;
*/
*/
(_display displayCtrl 1713001) ctrlShow true;
(_display displayCtrl 1713002) ctrlShow true;
(_display displayCtrl 1713005) ctrlShow true;
(_display displayCtrl 1713006) ctrlShow true;
(_display displayCtrl 1713010) ctrlShow _isPIP;
(_display displayCtrl 1713011) ctrlShow _isPIP;

View File

@ -18,8 +18,6 @@
private ["_compiledConfig", "_name", "_typeName", "_isClientSetable", "_localizedName", "_localizedDescription", "_possibleValues", "_defaultValue", "_value", "_compiledConfigEntry"];
_compiledConfig = "
";
{
/*_settingData = [
_name,
@ -55,25 +53,11 @@ class %1 {
force = 1;
};", _name, _value, format['"%1"', _typeName]];
_compiledConfig = _compiledConfig + _compiledConfigEntry;
"ace_clipboard" callExtension _compiledConfigEntry;
};
} forEach EGVAR(common,settings);
FUNC(clipboardExport) = {
private["_chunks"];
_chunks = [];
_chunks = [_this select 0, ";"] call CBA_fnc_split;
{
private["_chunk"];
_chunk = _x + ";";
"ace_clipboard" callExtension format["%1", _chunk];
} forEach _chunks;
"ace_clipboard" callExtension "--COMPLETE--";
};
[_compiledConfig] call FUNC(clipboardExport);
"ace_clipboard" callExtension "--COMPLETE--";
[LSTRING(settingsExported)] call EFUNC(common,displayTextStructured);

View File

@ -40,7 +40,21 @@ class CfgWeapons {
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class MMG_02_base_F : rifle_Base_F {
ACE_Overheating_allowSwapBarrel = 1;
ACE_Overheating_Dispersion[] = {0, -0.001, 0.001, 0.004};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class MMG_01_base_F : rifle_Base_F {
ACE_Overheating_allowSwapBarrel = 1;
ACE_Overheating_Dispersion[] = {0, -0.001, 0.001, 0.004};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class arifle_MX_SW_F : arifle_MX_Base_F {
ACE_clearJamAction = ""; // Custom jam clearing action. Use empty string to undefine.
ACE_Overheating_allowSwapBarrel = 1; // 1 to enable barrel swap. 0 to disable. Meant for machine guns where you can easily swap the barrel without dismantling the whole weapon.

View File

@ -0,0 +1 @@
z\ace\addons\rangecard

View File

@ -0,0 +1,11 @@
class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE( call COMPILE_FILE(XEH_preInit) );
};
};
class Extended_PostInit_EventHandlers {
class ADDON {
init = QUOTE( call COMPILE_FILE(XEH_postInit) );
};
};

View File

@ -0,0 +1,60 @@
class CfgVehicles {
class Man;
class CAManBase: Man {
class ACE_Actions {
class ACE_Weapon {
class GVAR(copyRangeCard) {
displayName = "$STR_ACE_RangeCard_CopyRangeCard";
distance = 2.0;
condition = QUOTE(_target call FUNC(canCopy));
statement = QUOTE(_target call FUNC(updateClassNames));
icon = QUOTE(PATHTOF(UI\RangeCard_Icon.paa));
};
};
};
class ACE_SelfActions {
class ACE_Equipment {
class GVAR(open) {
displayName = "$STR_ACE_RangeCard_OpenRangeCard";
condition = QUOTE(call FUNC(canShow) && !GVAR(RangeCardOpened));
statement = QUOTE(false call FUNC(openRangeCard));
showDisabled = 0;
priority = 0.1;
icon = QUOTE(PATHTOF(UI\RangeCard_Icon.paa));
exceptions[] = {"notOnMap"};
};
class GVAR(openCopy) {
displayName = "$STR_ACE_RangeCard_OpenRangeCardCopy";
condition = QUOTE(call FUNC(canShowCopy) && !GVAR(RangeCardOpened));
statement = QUOTE(true call FUNC(openRangeCard));
showDisabled = 0;
priority = 0.1;
icon = QUOTE(PATHTOF(UI\RangeCard_Icon.paa));
exceptions[] = {"notOnMap"};
};
};
};
};
class Item_Base_F;
class ACE_Item_RangeCard: Item_Base_F {
author = "Ruthberg";
scope = 2;
scopeCurator = 2;
displayName = "Range Card";
vehicleClass = "Items";
class TransportItems {
class ACE_RangeCard {
name = "ACE_RangeCard";
count = 1;
};
};
};
class Box_NATO_Support_F;
class ACE_Box_Misc: Box_NATO_Support_F {
class TransportItems {
MACRO_ADDITEM(ACE_RangeCard,6);
};
};
};

View File

@ -0,0 +1,19 @@
class CfgWeapons {
class ACE_ItemCore;
class InventoryItem_Base_F;
class ACE_RangeCard: ACE_ItemCore {
author[] = {"Ruthberg"};
scope = 2;
displayName = "$STR_ACE_RangeCard_Name";
descriptionShort = "$STR_ACE_RangeCard_Description";
picture = PATHTOF(UI\RangeCard_Icon.paa);
icon = "iconObject_circle";
mapSize = 0.034;
class ItemInfo: InventoryItem_Base_F {
mass = 1;
};
};
};

View File

@ -0,0 +1,10 @@
ace_rangecards
===============
Adds range cards
## Maintainers
The people responsible for merging changes to this component or answering potential questions.
- [Ruthberg] (http://github.com/Ulteq)

View File

@ -0,0 +1,198 @@
#define ST_LEFT 0
#define ST_RIGHT 1
#define ST_CENTER 2
class RscListNBox;
class ScrollBar;
class RangeCard_RscText {
idc=-1;
type=0;
style=ST_CENTER;
colorDisabled[]={0,0,0,0.0};
colorBackground[]={0,0,0,0};
colorText[]={0,0,0,1};
text="";
x=0;
y=0;
h=0.028;
w=0.06;
font="TahomaB";
SizeEx=0.025;
shadow=0;
};
class RangeCard_RscListNBox: RscListNBox {
idc=-1;
type=102;
style=0;
font="TahomaB";
sizeEx=0.026;
rowHeight=0.027;
colorDisabled[]={0,0,0,0.0};
colorBackground[]={1,1,1,1};
colorText[]={0,0,0,1};
colorScrollbar[]={0.95,0.95,0.95,1};
colorSelect[]={0,0,0,1};
colorSelect2[]={0,0,0,1};
colorSelectBackground[]={1,1,1,0};
colorSelectBackground2[]={1,1,1,0};
period=0;
LineSpacing=0;
maxHistoryDelay=1.0;
autoScrollSpeed=-1;
autoScrollDelay=5;
autoScrollRewind=0;
soundSelect[]={"",0.09,1};
drawSideArrows=0;
idcLeft=-1;
idcRight=-1;
class ScrollBar {
color[]={1,1,1,0.6};
colorActive[]={1,1,1,1};
colorDisabled[]={1,1,1,0.3};
};
class ListScrollBar : ScrollBar {
};
};
class ACE_RangeCard_Dialog {
idd = -1;
movingEnable = 1;
onLoad = "uiNamespace setVariable ['RangleCard_Display', (_this select 0)]";
onUnload = QUOTE(_this call FUNC(onCloseDialog));
objects[] = {};
class controls {
class BACKGROUND {
moving=1;
type=0;
font="TahomaB";
SizeEX=0.025;
idc=-1;
style=48;
x="safezoneX";
y="safezoneY+0.181889";
w="1.62727*3/4";
h="1.62727";
colorBackground[]={1,1,1,1};
colorText[]={1,1,1,1};
text=QUOTE(PATHTOF(UI\RangeCard.paa));
};
class CAPTION_TEXT_1: RangeCard_RscText {
idc=770000;
style=ST_LEFT;
x="safezoneX+0.18";
y="safezoneY+0.181889+0.0";
w="0.56*1.62727*3/4";
text=".408 CheyTac - 410 gr Predator Projectiles";
};
class CAPTION_TEXT_2: CAPTION_TEXT_1 {
idc=770001;
SizeEx=0.022;
y="safezoneY+0.181889+0.03";
text="Drop Tables for B.P.: 1013.25mb; Corrected for MVV at Air/Ammo Temperatures -15-35 °C";
};
class CAPTION_TEXT_3: CAPTION_TEXT_2 {
idc=770002;
y="safezoneY+0.181889+0.06";
text="CheyTac Intervention - 29'' 1:13'' twist (M-200)";
};
class ZERO_RANGE_TEXT: RangeCard_RscText {
idc=77003;
style=ST_LEFT;
SizeEx=0.028;
x="safezoneX+0.885";
y="safezoneY+0.181889+0.01";
w="0.125*1.62727*3/4";
text="100m ZERO";
};
class BAROMETRIC_PRESSURE_TEXT: ZERO_RANGE_TEXT {
idc=77004;
colorText[]={1,0,0,0.8};
y="safezoneY+0.181889+0.05";
text="B.P.: 1013.25mb";
};
class TARGET_RANGE_TEXT_1: RangeCard_RscText {
idc=770010;
colorText[]={1,1,1,1};
x="safezoneX+0.185";
y="safezoneY+0.181889+0.098";
text="Target";
};
class TARGET_RANGE_TEXT_2: TARGET_RANGE_TEXT_1 {
idc=770011;
SizeEx=0.03;
y="safezoneY+0.181889+0.125";
text="Range";
};
class TARGET_RANGE_TEXT_3: TARGET_RANGE_TEXT_1 {
idc=770012;
y="safezoneY+0.181889+0.152";
text="(m)";
};
class BULLET_DROP_TEXT_1: RangeCard_RscText {
idc=770013;
x="safezoneX+0.25";
y="safezoneY+0.181889+0.095";
w="0.405*1.62727*3/4";
text="Bullet Drop (MRADs)";
};
class WIND_LEAD_CAPTION_LIST: RangeCard_RscListNBox {
idc=770100;
sizeEx=0.021;
x="safezoneX+0.728";
y="safezoneY+0.181889+0.091";
w="0.25*1.62727*3/4";
h="0.0909445";
columns[]={(0.03/2), (0.985/2)};
idcLeft=770101;
idcRight=770102;
};
class TEMPERATURE_CAPTION_LIST_1: RangeCard_RscListNBox {
idc=770200;
x="safezoneX+0.24";
y="safezoneY+0.181889+0.125";
w="0.405*1.62727*3/4";
h="0.0909445";
columns[]={(0/9), (1/9), (2/9), (3/9), (4/9), (5/9), (5.9/9), (6.9/9), (7.8/9)};
idcLeft=770201;
idcRight=770202;
};
class TEMPERATURE_CAPTION_LIST_2: RangeCard_RscListNBox {
idc=770300;
x="safezoneX+0.728";
y="safezoneY+0.181889+0.15";
w="0.25*1.62727*3/4";
h="0.0909445";
columns[]={(0/6), (0.9/6), (1.8/6), (2.9/6), (3.8/6), (4.8/6)};
idcLeft=770301;
idcRight=770302;
};
class RANGE_CARD_DATA: RangeCard_RscListNBox {
idc=770400;
x="safezoneX+0.182";
y="safezoneY+0.181889+0.194";
w="0.72*1.62727*3/4";
h="1.62727";
columns[]={(0/16), (1.2/16), (2.2/16), (3.2/16), (4.2/16), (5.1/16), (6.1/16), (7.1/16), (8.1/16),
(9/16), (10.2/16), (11/16), (11.9/16), (12.8/16), (13.7/16), (14.6/16)};
idcLeft=770401;
idcRight=770402;
};
class FOOTNOTE_TEXT_1: CAPTION_TEXT_1 {
idc=770020;
SizeEx=0.022;
y="safezoneY+1.72431";
w="0.705*1.62727*3/4";
text="For best results keep ammunition at ambient air temperature. Tables calculated for the above listed barrel";
};
class FOOTNOTE_TEXT_2: FOOTNOTE_TEXT_1 {
idc=770021;
y="safezoneY+1.72431+0.024";
text="and load with optic mounted 1.5'' above line of bore.";
};
};
};

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,15 @@
#include "script_component.hpp"
#include "initKeybinds.sqf"
GVAR(RangeCardOpened) = false;
GVAR(controls) = [];
GVAR(ammoClass) = "B_65x39_Caseless";
GVAR(magazineClass) = "30Rnd_65x39_caseless_mag";
GVAR(weaponClass) = "arifle_MXM_F";
GVAR(ammoClassCopy) = "";//"ACE_762x51_Ball_M118LR";
GVAR(magazineClassCopy) = "";//"ACE_20Rnd_762x51_M118LR_Mag";
GVAR(weaponClassCopy) = "";//srifle_DMR_06_olive_F";

View File

@ -0,0 +1,14 @@
#include "script_component.hpp"
ADDON = false;
PREP(calculateSolution);
PREP(canCopy);
PREP(canShow);
PREP(canShowCopy);
PREP(onCloseDialog);
PREP(openRangeCard);
PREP(updateClassNames);
PREP(updateRangeCard);
ADDON = true;

View File

@ -0,0 +1,17 @@
#include "script_component.hpp"
class CfgPatches {
class ADDON {
units[] = {"ACE_Item_RangeCard"};
weapons[] = {"ACE_RangeCard"};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ACE_Advanced_Ballistics"};
author = "Ruthberg";
VERSION_CONFIG;
};
};
#include "CfgEventHandlers.hpp"
#include "CfgVehicles.hpp"
#include "CfgWeapons.hpp"
#include "RscTitles.hpp"

View File

@ -0,0 +1,208 @@
/*
* Author: Ruthberg
* Calculates the range card data
*
* Arguments:
* 0: Scope base angle <NUMBER>
* 1: Bullet mass <NUMBER>
* 2: Bore height <NUMBER>
* 3: air friction <NUMBER>
* 4: muzzle velocity <NUMBER>
* 5: temperature <NUMBER>
* 6: barometric pressure <NUMBER>
* 7: relative humidity <NUMBER>
* 8: simulation steps <NUMBER>
* 9: wind speed <ARRAY>
* 10: wind direction <NUMBER>
* 11: inclination angle <NUMBER>
* 12: target speed <NUMBER>
* 13: target range <NUMBER>
* 14: ballistic coefficient <NUMBER>
* 15: drag model <NUMBER>
* 16: atmosphere model <STRING>
* 17: Store range card data? <BOOL>
* 18: Stability factor <NUMBER>
* 19: Twist Direction <NUMBER>
* 20: Latitude <NUMBER>
* 21: Range Card Slot <NUMBER>
*
* Return Value:
* 0: Elevation (MOA) <NUMBER>
* 1: Windage (MOA) <ARRAY>
* 2: Lead (MOA) <NUMBER>
* 3: Time of fligth (SECONDS) <NUMBER>
* 4: Remaining velocity (m/s) <NUMBER>
* 5: Remaining kinetic energy (ft·lb) <NUMBER>
* 6: Vertical coriolis drift (MOA) <NUMBER>
* 7: Horizontal coriolis drift (MOA) <NUMBER>
* 8: Spin drift (MOA) <NUMBER>
*
* Example:
* call ace_rangecard_calculate_range_card_data
*
* Public: No
*/
#include "script_component.hpp"
private ["_scopeBaseAngle", "_bulletMass", "_boreHeight", "_airFriction", "_muzzleVelocity", "_temperature", "_barometricPressure", "_relativeHumidity", "_simSteps", "_windSpeed1", "_windSpeed2", "_windDirection", "_inclinationAngle", "_targetSpeed", "_targetRange", "_drag", "_bc", "_dragModel", "_atmosphereModel", "_storeRangeCardData", "_stabilityFactor", "_twistDirection", "_latitude", "_directionOfFire", "_rangeCardSlot"];
_scopeBaseAngle = _this select 0;
_bulletMass = _this select 1;
_boreHeight = _this select 2;
_airFriction = _this select 3;
_muzzleVelocity = _this select 4;
_temperature = _this select 5;
_barometricPressure = _this select 6;
_relativeHumidity = _this select 7;
_simSteps = _this select 8;
_windSpeed1 = (_this select 9) select 0;
_windSpeed2 = (_this select 9) select 1;
_windDirection = _this select 10;
_inclinationAngle = _this select 11;
_targetSpeed = _this select 12;
_targetRange = _this select 13;
_bc = _this select 14;
_dragModel = _this select 15;
_atmosphereModel = _this select 16;
_storeRangeCardData = _this select 17;
_stabilityFactor = _this select 18;
_twistDirection = _this select 19;
_latitude = _this select 20;
_directionOfFire = _this select 21;
_rangeCardSlot = _this select 22;
if (_storeRangeCardData) then {
GVAR(rangeCardDataMVs) set [_rangeCardSlot, format[" %1", round(_muzzleVelocity)]];
};
private ["_bulletPos", "_bulletVelocity", "_bulletAccel", "_bulletSpeed", "_gravity", "_deltaT", "_speedOfSound"];
_bulletPos = [0, 0, 0];
_bulletVelocity = [0, 0, 0];
_bulletAccel = [0, 0, 0];
_bulletSpeed = 0;
_gravity = [0, sin(_scopeBaseAngle + _inclinationAngle) * -9.80665, cos(_scopeBaseAngle + _inclinationAngle) * -9.80665];
_deltaT = 1 / _simSteps;
_speedOfSound = 0;
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
_speedOfSound = _temperature call EFUNC(weather,calculateSpeedOfSound);
};
private ["_elevation", "_windage1", "_windage2", "_lead", "_TOF", "_trueVelocity", "_trueSpeed", "_kineticEnergy", "_verticalCoriolis", "_verticalDeflection", "_horizontalCoriolis", "_horizontalDeflection", "_spinDrift", "_spinDeflection"];
_elevation = 0;
_windage1 = 0;
_windage2 = 0;
_lead = 0;
_TOF = 0;
_trueVelocity = [0, 0, 0];
_trueSpeed = 0;
_verticalCoriolis = 0;
_verticalDeflection = 0;
_horizontalCoriolis = 0;
_horizontalDeflection = 0;
_spinDrift = 0;
_spinDeflection = 0;
private ["_n", "_range"];
_n = 0;
_range = 0;
private ["_wind1", "_wind2", "_windDrift"];
_wind1 = [cos(270 - _windDirection * 30) * _windSpeed1, sin(270 - _windDirection * 30) * _windSpeed1, 0];
_wind2 = [cos(270 - _windDirection * 30) * _windSpeed2, sin(270 - _windDirection * 30) * _windSpeed2, 0];
_windDrift = 0;
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
_bc = [_bc, _temperature, _barometricPressure, _relativeHumidity, _atmosphereModel] call EFUNC(advanced_ballistics,calculateAtmosphericCorrection);
};
private ["_speedTotal", "_stepsTotal", "_speedAverage"];
_speedTotal = 0;
_stepsTotal = 0;
_speedAverage = 0;
_bulletPos set [0, 0];
_bulletPos set [1, 0];
_bulletPos set [2, -(_boreHeight / 100)];
_bulletVelocity set [0, 0];
_bulletVelocity set [1, Cos(_scopeBaseAngle) * _muzzleVelocity];
_bulletVelocity set [2, Sin(_scopeBaseAngle) * _muzzleVelocity];
while {_TOF < 6 && (_bulletPos select 1) < _targetRange} do {
_bulletSpeed = vectorMagnitude _bulletVelocity;
_speedTotal = _speedTotal + _bulletSpeed;
_stepsTotal = _stepsTotal + 1;
_speedAverage = (_speedTotal / _stepsTotal);
if (_speedAverage > 450 && _bulletSpeed < _speedOfSound) exitWith {};
if (atan((_bulletPos select 2) / (abs(_bulletPos select 1) + 1)) < -2.254) exitWith {};
_trueVelocity = _bulletVelocity vectorDiff _wind1;
_trueSpeed = vectorMagnitude _trueVelocity;
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
_drag = if (missionNamespace getVariable [QEGVAR(advanced_ballistics,extensionAvailable), false]) then {
parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3", _dragModel, _bc, _trueSpeed]))
} else {
([_dragModel, _bc, _trueSpeed] call EFUNC(advanced_ballistics,calculateRetardation))
};
_bulletAccel = (vectorNormalized _trueVelocity) vectorMultiply (-1 * _drag);
} else {
_bulletAccel = _trueVelocity vectorMultiply (_trueSpeed * _airFriction);
};
_bulletAccel = _bulletAccel vectorAdd _gravity;
_bulletVelocity = _bulletVelocity vectorAdd (_bulletAccel vectorMultiply _deltaT);
_bulletPos = _bulletPos vectorAdd (_bulletVelocity vectorMultiply _deltaT);
_TOF = _TOF + _deltaT;
if (_storeRangeCardData) then {
_range = GVAR(rangeCardStartRange) + _n * GVAR(rangeCardIncrement);
if ((_bulletPos select 1) >= _range && _range <= GVAR(rangeCardEndRange)) then {
if ((_bulletPos select 1) > 0) then {
_elevation = - atan((_bulletPos select 2) / (_bulletPos select 1));
_windage1 = - atan((_bulletPos select 0) / (_bulletPos select 1));
};
if (_range != 0) then {
_lead = (_targetSpeed * _TOF) / (Tan(3.38 / 60) * _range);
};
private ["_elevationString", "_windageString", "_leadString"];
_elevationString = Str(round(-_elevation * 60 / 3.38 * 10) / 10);
if (_elevationString == "0") then {
_elevationString = "-0.0";
};
if (_elevationString find "." == -1) then {
_elevationString = _elevationString + ".0";
};
_windageString = Str(round(_windage1 * 60 / 3.38 * 10) / 10);
if (_windageString find "." == -1) then {
_windageString = _windageString + ".0";
};
_leadString = Str(round(_lead * 10) / 10);
if (_leadString find "." == -1) then {
_leadString = _leadString + ".0";
};
(GVAR(rangeCardDataElevation) select _rangeCardSlot) set [_n, _elevationString];
(GVAR(rangeCardDataWindage) select _rangeCardSlot) set [_n, _windageString];
(GVAR(rangeCardDataLead) select _rangeCardSlot) set [_n, _leadString];
_n = _n + 1;
};
};
};
if ((_bulletPos select 1) > 0) then {
_elevation = - atan((_bulletPos select 2) / (_bulletPos select 1));
_windage1 = - atan((_bulletPos select 0) / (_bulletPos select 1));
_windDrift = (_wind2 select 0) * (_TOF - _targetRange / _muzzleVelocity);
_windage2 = - atan(_windDrift / (_bulletPos select 1));
};
if (_targetRange != 0) then {
_lead = (_targetSpeed * _TOF) / (Tan(3.38 / 60) * _targetRange);
};
_kineticEnergy = 0.5 * (_bulletMass / 1000 * (_bulletSpeed ^ 2));
_kineticEnergy = _kineticEnergy * 0.737562149;
[_elevation * 60, [_windage1 * 60, _windage2 * 60], _lead, _TOF, _bulletSpeed, _kineticEnergy, _verticalCoriolis * 60, _horizontalCoriolis * 60, _spinDrift * 60]

View File

@ -0,0 +1,18 @@
/*
* Authors: Ruthberg
* Checks if the target has a copyable range card
*
* Arguments:
* unit <OBJECT>
*
* Return Value:
* canShow (bool)
*
* Example:
* [] call ace_rangecard_fnc_canCopy
*
* Public: No
*/
#include "script_component.hpp"
((primaryWeapon _this) != "" && [_this] call EFUNC(common,isPlayer) && [_this, "ACE_RangeCard"] call EFUNC(common,hasItem))

View File

@ -0,0 +1,18 @@
/*
* Authors: Ruthberg
* Tests if the Range Card can be shown
*
* Arguments:
* Nothing
*
* Return Value:
* canShow (bool)
*
* Example:
* [] call ace_rangecard_fnc_canShow
*
* Public: No
*/
#include "script_component.hpp"
(GVAR(ammoClass) != "" && GVAR(magazineClass) != "" && GVAR(weaponClass) != "" && !GVAR(RangeCardOpened) && !(underwater ACE_player) && ("ACE_RangeCard" in (uniformItems ACE_player)) || ("ACE_RangeCard" in (vestItems ACE_player)))

View File

@ -0,0 +1,18 @@
/*
* Authors: Ruthberg
* Tests if the Range Card copy can be shown
*
* Arguments:
* Nothing
*
* Return Value:
* canShow (bool)
*
* Example:
* [] call ace_rangecard_fnc_canShowCopy
*
* Public: No
*/
#include "script_component.hpp"
(GVAR(ammoClassCopy) != "" && GVAR(magazineClassCopy) != "" && GVAR(weaponClassCopy) != "" && !GVAR(RangeCardOpened) && !(underwater ACE_player) && ("ACE_RangeCard" in (uniformItems ACE_player)) || ("ACE_RangeCard" in (vestItems ACE_player)))

View File

@ -0,0 +1,4 @@
#include "script_component.hpp"
uiNamespace setVariable ['RangleCard_Display', nil];
GVAR(RangeCardOpened) = false;

View File

@ -0,0 +1,36 @@
/*
* Authors: Ruthberg
* Opens the range card dialog
*
* Arguments:
* Open copy? <BOOLEAN>
*
* Return Value:
* Nothing
*
* Example:
* call ace_rangecard_fnc_openRangeCard
*
* Public: No
*/
#include "script_component.hpp"
if (GVAR(RangeCardOpened)) exitWith {};
if (_this) then {
if (GVAR(ammoClassCopy) != "" && GVAR(magazineClassCopy) != "" && GVAR(weaponClassCopy) != "") then {
GVAR(RangeCardOpened) = true;
createDialog "ACE_RangeCard_Dialog";
[GVAR(ammoClassCopy), GVAR(magazineClassCopy), GVAR(weaponClassCopy)] call FUNC(updateRangeCard);
};
} else {
if (ACE_player call FUNC(updateClassNames)) then {
GVAR(RangeCardOpened) = true;
createDialog "ACE_RangeCard_Dialog";
[GVAR(ammoClass), GVAR(magazineClass), GVAR(weaponClass)] call FUNC(updateRangeCard);
};
};

View File

@ -0,0 +1,49 @@
/*
* Authors: Ruthberg
* Updates the ammo and weapon class names
*
* Arguments:
* unit <OBJECT>
*
* Return Value:
* Update successful? <BOOLEAN>
*
* Example:
* unit call ace_rangecard_fnc_updateClassNames
*
* Public: No
*/
#include "script_component.hpp"
private ["_unit", "_ammoClass", "_magazineClass", "_weaponClass", "_ammo", "_ammoConfig", "_parentClasses"];
_unit = _this;
_ammoClass = "";
_magazineClass = "";
_weaponClass = primaryWeapon _unit;
if (_weaponClass == "") exitWith { (GVAR(ammoClass) != "" && GVAR(magazineClass) != "" && GVAR(weaponClass) != "") };
{
_ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo");
_ammoConfig = (configFile >> "CfgAmmo" >> _ammo);
_parentClasses = [_ammoConfig, true] call BIS_fnc_returnParents;
if ("BulletBase" in _parentClasses) exitWith {
_ammoClass = _ammo;
_magazineClass = _x;
};
} forEach (primaryWeaponMagazine _unit);
if (_ammoClass == "") exitWith { (GVAR(ammoClass) != "" && GVAR(magazineClass) != "" && GVAR(weaponClass) != "") };
if (_unit == ACE_player) then {
GVAR(ammoClass) = _ammoClass;
GVAR(magazineClass) = _magazineClass;
GVAR(weaponClass) = _weaponClass;
} else {
GVAR(ammoClassCopy) = _ammoClass;
GVAR(magazineClassCopy) = _magazineClass;
GVAR(weaponClassCopy) = _weaponClass;
};
true

View File

@ -0,0 +1,243 @@
/*
* Authors: Ruthberg
* Updates the range card data
*
* Arguments:
* 0: ammo class <STRING>
* 1: magazine class <STRING>
* 2: weapon class <STRING>
*
* Return Value:
* Nothing
*
* Example:
* [mode] call ace_rangecard_fnc_openRangeCard
*
* Public: No
*/
#include "script_component.hpp"
disableSerialization;
#define __dsp (uiNamespace getVariable "RangleCard_Display")
private ["_airFriction", "_ammoConfig", "_atmosphereModel", "_barometricPressure", "_barrelLength", "_barrelTwist", "_bc", "_boreHeight", "_cacheEntry", "_column", "_control", "_dragModel", "_i", "_muzzleVelocity", "_mv", "_mvShift", "_offset", "_relativeHumidity", "_result", "_row", "_scopeBaseAngle", "_weaponConfig", "_zeroRange", "_initSpeed", "_initSpeedCoef"];
PARAMS_3(_ammoClass,_magazineClass,_weaponClass);
if (_ammoClass == "" || _magazineClass == "" || _weaponClass == "") exitWith {};
{
ctrlDelete _x;
} forEach GVAR(controls);
GVAR(controls) = [];
for "_row" from 0 to 49 do {
_offset = if (_row < 5) then {0} else {0.003};
_control = (__dsp ctrlCreate ["RangeCard_RscText", 790000 + _row]);
_control ctrlSetPosition [safeZoneX + 0.183, safeZoneY + 0.374 + 0.027 * _row + _offset, 0.062, 0.025];
if (_row in [0, 8, 18, 28, 38, 48]) then {
_control ctrlSetTextColor [1, 1, 1, 1];
} else {
_control ctrlSetTextColor [0, 0, 0, 1];
};
_control ctrlCommit 0;
_control ctrlSetText Str(100 + _row * 50);
GVAR(controls) pushBack _control;
};
for "_column" from 0 to 8 do {
for "_row" from 0 to 49 do {
_offset = if (_row < 5) then {0} else {0.003};
_control = (__dsp ctrlCreate ["RangeCard_RscText", 90000 + _column * 100 + _row]);
_control ctrlSetPosition [safeZoneX + 0.249 + _column * 0.055, safeZoneY + 0.374 + 0.027 * _row + _offset, 0.052, 0.025];
_control ctrlCommit 0;
_control ctrlSetText "-0.0";
GVAR(controls) pushBack _control;
};
};
for "_column" from 0 to 2 do {
for "_row" from 0 to 49 do {
_offset = if (_row < 5) then {0} else {0.003};
_control = (__dsp ctrlCreate ["RangeCard_RscText", 90000 + (9 +_column) * 100 + _row]);
_control ctrlSetPosition [safeZoneX + 0.743 + _column * 0.049, safeZoneY + 0.374 + 0.027 * _row + _offset, 0.047, 0.025];
_control ctrlCommit 0;
_control ctrlSetText "-0.0";
GVAR(controls) pushBack _control;
};
};
for "_column" from 0 to 2 do {
for "_row" from 0 to 49 do {
_offset = if (_row < 5) then {0} else {0.003};
_control = (__dsp ctrlCreate ["RangeCard_RscText", 90000 + (12 +_column) * 100 + _row]);
_control ctrlSetPosition [safeZoneX + 0.892 + _column * 0.049, safeZoneY + 0.374 + 0.027 * _row + _offset, 0.047, 0.025];
_control ctrlCommit 0;
_control ctrlSetText "-0.0";
GVAR(controls) pushBack _control;
};
};
lnbClear 770100;
lnbClear 770200;
lnbClear 770300;
lnbClear 770400;
lnbAddRow [770100, ["4mps Wind(MRADs)", "1mps LEAD(MRADs)"]];
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
lnbAddRow [770100, ["Air/Ammo Temp", "Air/Ammo Temp"]];
lnbAddRow [770200, ["-15°C", " -5°C", " 5°C", " 10°C", " 15°C", " 20°C", " 25°C", " 30°C", " 35°C"]];
lnbAddRow [770300, ["-15°C", " 10°C", " 35°C", "-15°C", " 10°C", " 35°C"]];
};
GVAR(rangeCardDataElevation) = [[], [], [], [], [], [], [], [], []];
GVAR(rangeCardDataWindage) = [[], [], [], [], [], [], [], [], []];
GVAR(rangeCardDataLead) = [[], [], [], [], [], [], [], [], []];
GVAR(rangeCardDataMVs) = ["", "", "", "", "", "", "", "", ""];
GVAR(lastValidRow) = [];
GVAR(currentUnit) = 2;
GVAR(rangeCardStartRange) = 100;
GVAR(rangeCardIncrement) = 50;
GVAR(rangeCardEndRange) = GVAR(rangeCardStartRange) + 49 * GVAR(rangeCardIncrement);
_ammoConfig = _ammoClass call EFUNC(advanced_ballistics,readAmmoDataFromConfig);
_weaponConfig = _weaponClass call EFUNC(advanced_ballistics,readWeaponDataFromConfig);
_airFriction = _ammoConfig select 0;
_barrelTwist = _weaponConfig select 0;
_barrelLength = _weaponConfig select 2;
_muzzleVelocity = 0;
if (_barrelLength > 0 && missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
_muzzleVelocity = [_barrelLength, _ammoConfig select 10, _ammoConfig select 11, 0] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift);
} else {
_initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "initSpeed");
_initSpeedCoef = getNumber (configFile >> "CfgWeapons" >> _weaponClass >> "initSpeed");
if (_initSpeedCoef < 0) then {
_initSpeed = _initSpeed * -_initSpeedCoef;
};
if (_initSpeedCoef > 0) then {
_initSpeed = _initSpeedCoef;
};
_muzzleVelocity = _initSpeed;
};
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
ctrlSetText [770000, format["%1'' - %2 gr (%3)", round((_ammoConfig select 1) * 39.3700787) / 1000, round((_ammoConfig select 3) * 15.4323584), _ammoClass]];
if (_barrelLength > 0 && _barrelTwist > 0) then {
ctrlSetText [770002, format["Barrel: %1'' 1:%2'' twist", round(_barrelLength * 0.0393700787), round(_barrelTwist * 0.0393700787)]];
} else {
ctrlSetText [770002, ""];
};
} else {
ctrlSetText [770000, getText (configFile >> "CfgMagazines" >> _magazineClass >> "displayNameShort")];
ctrlSetText [770002, ""];
};
_bc = (_ammoConfig select 6) select 0;
_dragModel = _ammoConfig select 5;
_atmosphereModel = _ammoConfig select 8;
_boreHeight = 3.81;
_zeroRange = 100;
_barometricPressure = 1013.25;
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
_barometricPressure = 1013.25 * (1 - (0.0065 * EGVAR(weather,altitude)) / 288.15) ^ 5.255754495;
};
_relativeHumidity = 0.5;
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
ctrlSetText [770001, format["Drop Tables for B.P.: %1mb; Corrected for MVV at Air/Ammo Temperatures -15-35 °C", round(_barometricPressure * 100) / 100]];
ctrlSetText [77004 , format["B.P.: %1mb", round(_barometricPressure * 100) / 100]];
} else {
ctrlSetText [770001, getText (configFile >> "CfgWeapons" >> _weaponClass >> "displayName")];
ctrlSetText [77004 , ""];
};
_cacheEntry = missionNamespace getVariable format[QGVAR(%1_%2_%3), _ammoClass, _weaponClass, missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]];
if (isNil {_cacheEntry}) then {
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
{
_mvShift = [_ammoConfig select 9, _x] call EFUNC(advanced_ballistics,calculateAmmoTemperatureVelocityShift);
_mv = _muzzleVelocity + _mvShift;
_result = [0, 0, _boreHeight, _airFriction, _mv, _x, 1013.25, 0.5, 1000, [0, 0], 0, 0, 0, _zeroRange, _bc, _dragModel, _atmosphereModel, false, 1.5, 0, 0, 0] call FUNC(calculateSolution);
_scopeBaseAngle = (_result select 0) / 60;
[_scopeBaseAngle,27,_boreHeight,_airFriction,_mv,_x,_barometricPressure,_relativeHumidity,1000,[4,0],3,0,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,true,1.5,1,46,23,_forEachIndex] call FUNC(calculateSolution);
} forEach [-15, -5, 5, 10, 15, 20, 25, 30, 35];
} else {
_result = [0, 0, _boreHeight, _airFriction, _muzzleVelocity, _x, 1013.25, 0.5, 1000, [0, 0], 0, 0, 0, _zeroRange, _bc, _dragModel, _atmosphereModel, false, 1.5, 0, 0, 0] call FUNC(calculateSolution);
_scopeBaseAngle = (_result select 0) / 60;
[_scopeBaseAngle,27,_boreHeight,_airFriction,_muzzleVelocity,_x,_barometricPressure,_relativeHumidity,1000,[4,0],3,0,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,true,1.5,1,46,23,3] call FUNC(calculateSolution);
};
for "_i" from 0 to 9 do {
GVAR(lastValidRow) pushBack count (GVAR(rangeCardDataElevation) select _i);
while {count (GVAR(rangeCardDataElevation) select _i) < 50} do {
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
(GVAR(rangeCardDataElevation) select _i) pushBack "###";
(GVAR(rangeCardDataWindage) select _i) pushBack "##";
(GVAR(rangeCardDataLead) select _i) pushBack "##";
} else {
(GVAR(rangeCardDataElevation) select _i) pushBack "";
(GVAR(rangeCardDataWindage) select _i) pushBack "";
(GVAR(rangeCardDataLead) select _i) pushBack "";
};
};
};
missionNamespace setVariable [format[QGVAR(%1_%2_%3), _ammoClass, _weaponClass, missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]], [GVAR(rangeCardDataElevation), GVAR(rangeCardDataWindage), GVAR(rangeCardDataLead), GVAR(rangeCardDataMVs), GVAR(lastValidRow)]];
} else {
GVAR(rangeCardDataElevation) = _cacheEntry select 0;
GVAR(rangeCardDataWindage) = _cacheEntry select 1;
GVAR(rangeCardDataLead) = _cacheEntry select 2;
GVAR(rangeCardDataMVs) = _cacheEntry select 3;
GVAR(lastValidRow) = _cacheEntry select 4;
};
lnbAddRow [770200, GVAR(rangeCardDataMVs)];
for "_column" from 0 to 8 do {
for "_row" from 0 to 49 do {
_control = (__dsp displayCtrl (90000 + _column * 100 + _row));
_control ctrlSetText ((GVAR(rangeCardDataElevation) select _column) select _row);
if (_row >= (GVAR(lastValidRow) select _column)) then {
_control ctrlSetTextColor [0, 0, 0, 0.6];
} else {
_control ctrlSetTextColor [0, 0, 0, 1.0];
};
_control ctrlCommit 0;
};
};
{
for "_row" from 0 to 49 do {
_control = (__dsp displayCtrl (90000 + (9 + _forEachIndex) * 100 + _row));
_control ctrlSetText ((GVAR(rangeCardDataWindage) select _x) select _row);
if (_row >= (GVAR(lastValidRow) select _x)) then {
_control ctrlSetTextColor [0, 0, 0, 0.6];
} else {
_control ctrlSetTextColor [0, 0, 0, 1.0];
};
_control ctrlCommit 0;
};
} forEach [0, 3, 8];
{
for "_row" from 0 to 49 do {
_control = (__dsp displayCtrl (90000 + (12 + _forEachIndex) * 100 + _row));
_control ctrlSetText ((GVAR(rangeCardDataLead) select _x) select _row);
if (_row >= (GVAR(lastValidRow) select _x)) then {
_control ctrlSetTextColor [0, 0, 0, 0.6];
} else {
_control ctrlSetTextColor [0, 0, 0, 1.0];
};
_control ctrlCommit 0;
};
} forEach [0, 3, 8];
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
ctrlSetText [770020, "For best results keep ammunition at ambient air temperature. Tables calculated for the above listed barrel"];
ctrlSetText [770021, "and load with optic mounted 1.5'' above line of bore."];
} else {
ctrlSetText [770020, ""];
ctrlSetText [770021, ""];
};

View File

@ -0,0 +1 @@
#include "\z\ace\addons\rangecard\script_component.hpp"

View File

@ -0,0 +1,31 @@
["ACE3 Equipment", QGVAR(RangeCardDialogKey), localize "STR_ACE_RangeCard_RangeCardDialogKey",
{
// Conditions: canInteract, canShow
if !([ACE_player, objNull, []] call EFUNC(common,canInteractWith)) exitWith {false};
if (GVAR(RangeCardOpened)) exitWith {
closeDialog 0;
false
};
if !(call FUNC(canShow)) exitWith {false};
// Statement
false call FUNC(openRangeCard);
true
},
{false},
[0, [false, false, false]], false, 0] call CBA_fnc_addKeybind; // (empty default key)
["ACE3 Equipment", QGVAR(RangeCardCopyDialogKey), localize "STR_ACE_RangeCard_RangeCardCopyDialogKey",
{
// Conditions: canInteract, canShowCopy
if !([ACE_player, objNull, []] call EFUNC(common,canInteractWith)) exitWith {false};
if (GVAR(RangeCardOpened)) exitWith {
closeDialog 0;
false
};
if !(call FUNC(canShowCopy)) exitWith {false};
// Statement
true call FUNC(openRangeCard);
true
},
{false},
[0, [false, false, false]], false, 0] call CBA_fnc_addKeybind; // (empty default key)

View File

@ -0,0 +1,12 @@
#define COMPONENT rangecard
#include "\z\ace\addons\main\script_mod.hpp"
#ifdef DEBUG_ENABLED_RANGECARD
#define DEBUG_MODE_FULL
#endif
#ifdef DEBUG_SETTINGS_RANGECARD
#define DEBUG_SETTINGS DEBUG_SETTINGS_RANGECARD
#endif
#include "\z\ace\addons\main\script_macros.hpp"

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<Project name="ACE">
<Package name="RangeCard">
<Key ID="STR_ACE_RangeCard_Name">
<English>Range Card</English>
</Key>
<Key ID="STR_ACE_RangeCard_Description">
<English>50 METER increments -- MRAD/MRAD (reticle/turrets)</English>
</Key>
<Key ID="STR_ACE_RangeCard_OpenRangeCard">
<English>Open Range Card</English>
</Key>
<Key ID="STR_ACE_RangeCard_OpenRangeCardCopy">
<English>Open Range Card Copy</English>
</Key>
<Key ID="STR_ACE_RangeCard_RangeCardDialogKey">
<English>Open Range Card</English>
</Key>
<Key ID="STR_ACE_RangeCard_RangeCardCopyDialogKey">
<English>Open Range Card Copy</English>
</Key>
<Key ID="STR_ACE_RangeCard_CopyRangeCard">
<English>Copy Range Card</English>
</Key>
</Package>
</Project>

View File

@ -8,6 +8,7 @@ PREP(calculateBarometricPressure);
PREP(calculateDewPoint);
PREP(calculateHeatIndex);
PREP(calculateRoughnessLength);
PREP(calculateSpeedOfSound);
PREP(calculateTemperatureAtHeight);
PREP(calculateWetBulb);
PREP(calculateWindChill);

View File

@ -14,4 +14,4 @@
*/
#include "script_component.hpp"
(1013.25 * exp(-(GVAR(Altitude) + _this) / 7990) - 10 * overcast)
((1013.25 - 10 * overcast) * (1 - (0.0065 * (GVAR(Altitude) + _this)) / (KELVIN(GVAR(currentTemperature)) + 0.0065 * GVAR(Altitude))) ^ 5.255754495);

View File

@ -0,0 +1,17 @@
/*
* Author: Ruthberg
*
* Calculates the speed of sound for a given temperature
*
* Arguments:
* temperature - degrees celcius <NUMBER>
*
* Return Value:
* speed of sound - m/s <NUMBER>
*
* Return value:
* None
*/
#include "script_component.hpp"
(331.3 + (0.6 * _this))

View File

@ -7,13 +7,13 @@ parent: wiki
order: 4
---
### Modularity
## 1. Modularity
Main principles:
- As much stuff as possible should be modular
- Strive to make as much stuff as possible run-time togglable. Adding/removing PBOS would still be requiring to toggle any feature relying on config changes.
### PBO Structure
## 2. PBO Structure
Main principles:
@ -29,3 +29,14 @@ Main -> Common -> Config things
Main -> Common -> 3D Models |
Interaction | -> Feature
```
## 3. Optional .PBOs for 3rd Party Mods
- ACE3 policy is to NOT take care of compatibility with third party addons single handely. The current compatible .PBOs were kickstarted by the ACE3 team as an example to mod creators so it's clear which entries are needed for compatibility. The authors of those addons have been contacted and many of those pbos are due to be included in their respective mods eventually.
<div class="panel callout">
<h5>Notice for 3rd party mod creators:</h5>
<p>Most of the config entries are inert if ACE3 is not present, so addons can be made ACE3 compatible without explicitly requiring ACE3. However, for addons that are not inert (for example, scope configs), it is best to create and distribute compatibility .PBOs along with the original mod content; feel free to consult with ACE3 devs about how to correctly implement this. All existing compatibility .PBOs are examples and thus no further compatibility .PBOs will be provided by the ACE3 team.</p>
</div>

View File

@ -9,8 +9,8 @@ parent: wiki
## 1. Overview
The Advanced Ballistics module improves internal and external ballistics.
## 2. Features
- Drag modeling based on real-world ballistic coefficients.
## 1.1 Features
- Drag modelling based on real-world ballistic coefficients.
- Ambient air density (air pressure, temperature, humidity) affects drag.
- Wind affects drag and deflects the trajectory.
- Wind speed varies with altitude.
@ -22,10 +22,10 @@ The Advanced Ballistics module improves internal and external ballistics.
- Bullet trace effect for supersonic bullets (light refraction due to air pressure waves).
- A protractor for quickly measuring the inclination angle.
## 3. Usage
## 2. Usage
### 3.1 Protractor
### 2.1 Protractor
Press <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>K</kbd> while using a compatible weapon to toggle the protractor. The red line indicates the current inclination angle in degrees. The protractor will disappear if you lower or holster your weapon.
## 4. Dependencies
## 3. Dependencies
`ace_ballistics`, `ace_weather`, `ace_modules`

View File

@ -1,6 +1,6 @@
---
layout: wiki
title: AI (Artifical Intelligence)
title: AI (Artificial Intelligence)
description: Config based changes to AI to ensure compatibility with advanced AI modifications
group: feature
order: 5
@ -10,7 +10,7 @@ parent: wiki
## 1. Overview
### 1.1 Adjusted AI skill values
The idea here is to reduce the AI's godlike aiming capabilties while retaining it's high intelligence. The AI should be smart enough to move through a town, but also be 'human' in their reaction time and aim.
The idea here is to reduce the AI's godlike aiming capabilities while retaining it's high intelligence. The AI should be smart enough to move through a town, but also be 'human' in their reaction time and aim.
Note: All these values can still be adjusted via scripts, these arrays just change what 0 & 1 are for setSkill.
### 1.2 Firing in burst mode

View File

@ -1,7 +1,7 @@
---
layout: wiki
title: Aircraft
description: Changes the flight behaviour of various aircraft
description: Aircraft overhaul
group: feature
order: 5
parent: wiki
@ -35,7 +35,7 @@ Adds a HUD to the AH-9 based on the Comanche's HUD.
## 2. Usage
### 2.1 Switching flare modes
Press <kbd>Ctrl</kbd>+<kbd>C</kbd> to switch between flare firing modes
Press <kbd>CTRL</kbd>+<kbd>C</kbd> to switch between flare firing modes (ARMA3 default keybind `countermeasure mode`)
## 3. Dependencies

View File

@ -1,7 +1,7 @@
---
layout: wiki
title: Attach
description: Allows players to attach items to objects
description: Allow players to attach items to vehicles or themselves
group: feature
parent: wiki
---
@ -17,17 +17,17 @@ Adds an attachable IR strobe, which is only visible using night vision devices a
## 2. Usage
### 2.1 Attaching to yourself
- Use Self Interact <kbd>Ctrl</kbd>+<kbd>Left Windows</kbd>.
- Choose `Equipment`.
- Choose `Attach item`.
- Use Self Interact <kbd>CTRL</kbd>+<kbd>Left Windows</kbd> (ACE3 default keybind `Self Interaction Key`).
- Select `Equipment`.
- Select `Attach item`.
- Select which item you want to attach.
- Repeat to detach.
- Repeat the process to detach.
### 2.2 Attaching to a vehicle
- Interact with the vehicle <kbd>Left Windows</kbd>.
- Choose `Attach item`.
- Interact with the vehicle <kbd>Left Windows</kbd> (ACE3 default keybind `Interact Key`).
- Select `Attach item`.
- Select your item and follow the instructions on the screen.
- Repeat to detach.
- Repeat the process to detach.
## 3. Dependencies

View File

@ -12,25 +12,19 @@ parent: wiki
### 1.1 Realistic ballistics
Changes include adjusted muzzle velocity, air friction and dispersion based on real life values.
### 1.2 Weaker body armor
Decreases protection values of vests, CSAT uniforms and various campaign only gear to better represent realism.
### 1.3 Realistic silencers and subsonic ammunition
### 1.2 Realistic silencers and subsonic ammunition
Silencers no longer decrease the muzzle velocity and are generally less effective when used with normal ammunition. They now only remove the muzzle blast and flash. To prevent the crack caused by supersonic projectiles, ACE3 introduces subsonic ammunition for the 7.62mm caliber. This is also fully compatible with AI.
### 1.4 Flash suppressors
Flash suppressors are devices that reduce the muzzle flash while firing by cooling or dispersing the burning gases that exit the muzzle. Its intent is to reduce the chances that the shooter will be blinded in low-light shooting conditions as well as reducing the intensity of the flash visible to the enemy.
### 1.5 Armor piercing ammunition
### 1.3 Armor piercing ammunition
Armor piercing rounds have higher penetration values against light armored targets and other obstacles on the battlefield. Their drawback is a slightly decreased man-stopping power. AP rounds are available in multiple calibers incudling 5.56mm and 7.62mm.
### 1.6 IR-Dim tracer ammunition
### 1.4 IR-Dim tracer ammunition
IR-Dim ammunition is similar to tracer rounds, but these tracers are only visible using night vision devices.
### 1.7 M118 long range ammunition
### 1.5 M118 long range ammunition
The M14 EBR now uses ammunition with decreased muzzle velocity and air friction to improve precision and energy retention at long ranges.
### 1.8 Fully config-based
### 1.6 Fully config-based
This module applies configuration changes only and does not decrease game performance.
## 2. Dependencies

View File

@ -24,14 +24,14 @@ You can surrender. While surrendering AI will cease fire.
### 2.1 Taking a unit into captivity
- You need `Cable Tie`.
- Approach the unit and Interact <kbd>Left Windows</kbd>.
- Approach the unit and Interact <kbd>Left Windows</kbd> (ACE3 default keybind `Interact Key`).
- The interaction is located around the hands in the form of a handcuffs icon.
- Repeat to release.
### 2.2 Escorting a captive
- Interact with the captive <kbd>Left Windows</kbd>.
- Select the `Escort prisoner` option.
- To stop escorting, use the mousewheel and select `Release` or use Self Interaction <kbd>Ctrl</kbd>+<kbd>Left windows</kbd> and select `Release`.
- To stop escorting, use the mousewheel and select `Release` or use Self Interaction <kbd>CTRL</kbd>+<kbd>Left windows</kbd> and select `Release`.
### 2.3 Loading and unloading a captive into/from a vehicle
- Escort the captive.

View File

@ -13,3 +13,5 @@ Common functions and systems used by most other components.
## 2. Dependencies
`ace_main`
Note: The Common module is required by nearly all other modules. Do NOT remove it!

View File

@ -14,7 +14,7 @@ You can search the inventory and disarm captured or unconscious units.
## 2. Usage
### 2.1 Searching and disarming
- Interact with the captured or unconscious unit <kbd>Ctrl</kbd>+<kbd>Left Windows</kbd>.
- Interact with the captured or unconscious unit <kbd>Left Windows</kbd> (ACE3 default keybind `Interaction Key`).
- Select `Open inventory`.
- Drag & Drop the items you wish to remove from the unit.

View File

@ -14,9 +14,9 @@ This adds the option to drag or carry units or objects.
### 2.1 Dragging / Carrying units and objects
- You can only drag or carry an unconscious unit.
- Interact with the unit or object <kbd>Left Windows</kbd>
- Choose `Drag` or `Carry`
- To release, use the mousewheel and select `Release` or use Self Interaction <kbd>Ctrl</kbd>+<kbd>Left windows</kbd> and select `Release`.
- Interact with the unit or object <kbd>Left Windows</kbd> (ACE3 default keybind `Interact Key`).
- Select `Drag` or `Carry`.
- To release, use the mousewheel and select `Release` or use Self Interaction <kbd>CTRL</kbd>+<kbd>Left windows</kbd> and select `Release`.
## 3. Dependencies

View File

@ -20,19 +20,19 @@ Enables attaching explosives to vehicles.
## 2. Usage
### 2.1 Placing explosives
- Use self interaction <kbd>Ctrl</kbd>+<kbd>Left Windows</kbd>
- Select `Explosives`
- Choose your explosive type and follow the instructions on the screen
- Use self interaction <kbd>CTRL</kbd>+<kbd>Left Windows</kbd> (ACE3 default keybind `Self Interaction Key`).
- Select `Explosives`.
- Choose your explosive type and follow the instructions on the screen.
### 2.2 Arming and detonating explosives
- Interact with the explosive <kbd>Left Windows</kbd>
- Choose the arming method
- For clackers use Self Interaction `Explosives` -> `Detonate` and choose the corresponding Firing Device
- Interact with the explosive <kbd>Left Windows</kbd> (ACE3 default keybind `Interact Key`).
- Choose the arming method.
- For clackers use Self Interaction `Explosives` -> `Detonate` and choose the corresponding Firing Device.
### 2.3 Defusing explosives
- A `Defusal Kit` is required
- Interact with the explosive <kbd>Left Windows</kbd>
- Choose `Disarm`
- A `Defusal Kit` is required.
- Interact with the explosive <kbd>Left Windows</kbd>.
- Select `Disarm`.
- You are safe to pick it up after the action is complete.
## 3. Dependencies

View File

@ -17,20 +17,19 @@ Changes the default rangefinders, including those in vehicles, to require manual
### 1.3 Air burst ammunition
Anti air cannons can now use airburst ammunition. It will explode on the FCS' zeroed in range.
## 2. Usage
### 2.1 Engaging moving targets
- Place the crosshair on the enemy vehicle.
- Press and hold <kbd> tab </kbd> (by default) and follow the target for about 2 seconds.
- Release <kbd> tab </kbd>
- Press and hold <kbd>TAB</kbd> (ACE 3 default keybind `Lock Target [Hold]`) and follow the target for about 2 seconds.
- Release <kbd>TAB</kbd>.
- The optic is now adjusted sideways to ensue a hit.
### 2.2 Ranging stationary targets
- Place the crosshair on the object to range.
- Tap <kbd> tab </kbd> (by default) the optic is now adjusted.
- Tap <kbd>TAB</kbd> the optic is now adjusted.
NOTE: GBU guidance is **DISABLED** as of ACE3 3.0.1
## 3. Dependencies

View File

@ -8,7 +8,9 @@ parent: wiki
## 1. Overview
Adds flash suppressors, they reduce the muzzle flash of your weapon.
This adds the ability to use the flash suppressors that are already in game but not accessible.
Flash suppressors are devices that reduce the muzzle flash while firing by cooling or dispersing the burning gases that exit the muzzle. Its intent is to reduce the chances that the shooter will be blinded in low-light shooting conditions as well as reducing the intensity of the flash visible to the enemy.
## 2. Dependencies

View File

@ -17,7 +17,7 @@ nearby (e.g. explosions, rotor wash, bullet impacts, muzzle blast).
## 2. Usage
### 2.1 Cleaning your goggles
-To clean your goggles press <kbd>shift+alt+T</kbd>(default keybind)
- To clean your goggles press <kbd>SHIFT</kbd> + <kbd>ALT</kbd> + <kbd>T</kbd>(ACE3 deault keybind `Wipe goggles`)
## 3. Dependencies

View File

@ -17,16 +17,14 @@ Adds throwable hand flares in the colors white, red, green and yellow. Additiona
### 1.3 M84 stun grenade
Adds stun grenade. This will also affect AI.
## 2. Usage
### 2.1 Switching between throw modes
- Press <kbd>8</kbd> (by default)
- Press <kbd>8</kbd> (ACE3 default keybind `Switch Grenade Mode`)
### 2.2 Switching between grenades
- Press <kbd>6</kbd> (by default) to switch between `LETHAL` grenades
- Press <kbd>7</kbd> (by default) to switch between `NON LETHAL` grenades
- Press <kbd>6</kbd> (ACE3 default keybind `Select frag`) to switch between `LETHAL` grenades
- Press <kbd>7</kbd> (ACE3 default keybind `Select non-frag`) to switch between `NON LETHAL` grenades
## 3. Dependencies

View File

@ -15,12 +15,11 @@ Introduces hearing damage caused by nearby explosions and large-caliber weapons.
Adds ear plugs to mitigate that effect. Soldiers with high caliber weapons or
missile launchers will be equipped with those, but remember to put them in.
## 2. Usage
### 2.1 Equipping earplugs
- For this you obviously need `Ear plugs`.
- Press the self interaction key <kbd> ctrl+left windows </kbd> (by default).
- Press the self interaction key <kbd>CTRL</kbd> + <kbd>left windows</kbd> (ACE3 default keybind `Self Interaction Key`).
- Select `equipment`.
- Select `Earplugs in`.
- Same method to remove them but the option is `Earplugs out`.

View File

@ -10,7 +10,7 @@ parent: wiki
### 1.1 Falling under fire
If a unit is shot while running it falls to the ground in a prone position, the area where the shot lands does not matters.
Note that the shot needs to inflict a certain amout of damage to make the unit fall, a small cut won't make the unit stumble.
Note that the shot needs to inflict a certain amount of damage to make the unit fall, a small cut won't make the unit stumble.
## 2. Dependencies

View File

@ -1,7 +1,7 @@
---
layout: wiki
title: Inventory
description:
description:
group: feature
parent: wiki
---
@ -11,17 +11,15 @@ parent: wiki
### 1.1 Resized inventory UI
Makes the inventory dialog bigger and increases the number of items that can be seen in the list at once.
## 2. Usage
### 2.1 Changing the size of the UI
- Press <kbd> escape </kbd>.
- Press <kbd>escape</kbd>.
- Click on `ACE OPTIONS` on the top left corner of the screen.
- Click on `Make Inventory Display Bigger`.
- Choose the size desired on the right drop down menu.
- Press the `Close` button, your changes are automatically saved.
## 3. Dependencies
`ace_common`

View File

@ -14,22 +14,20 @@ The locking capabilities of the Titan and Javelin got improved, you can now lock
### 1.2 Fire mode switching
The Titan / Javelin now posses the ability to be used in top down attack or direct.
## 2. Usage
### 2.1 Locking with the Titan / Javelin
- For this feature you need to have a compatible launcher.
- Fully zoom with the launcher.
- Switch to thermals <kbd> n </kbd> (by default).
- While keeping your aim steadily on target press and hold <kbd> tab </kbd>.
- Switch to thermals <kbd>N</kbd> (ARMA3 default keybind `Night vision`).
- While keeping your aim steadily on target press and hold <kbd>TAB</kbd> (ACE3 default keybind `Lock Target [Hold]`).
- When the sound changes and a cross appears on the screen it's time to fire.
### 2.2 Switching fire mode
- For this feature you need to have a compatible launcher.
- When aiming with your launcher press <kbd> ctrl+tab </kbd> (by default).
- When aiming with your launcher press <kbd>CTRL</kbd> + <kbd>TAB</kbd>.
- On the right side of the screen (for most launchers) you should see that `TOP`is now in green that means that your missile will be fired in top down mode.
## 3. Dependencies
`ace_main`, `ace_common`, `ace_missileguidance`

View File

@ -1,7 +1,7 @@
---
layout: wiki
title: Laser Pointer
description:
description: Switching laser modes, daylight lasers
group: feature
parent: wiki
---
@ -15,7 +15,7 @@ ACE3 adds visible light laser. This feature is compatible with BI's lasers as we
### 2.1 Switching laser mode
- For this feature you need to have a compatible side attachment.
- Press <kbd> ctrl+L </kbd> (by default).
- Press <kbd> ctrl </kbd> + <kbd> L </kbd> (ACE3 default keybind `Switch Laser / IR Laser`).
- A hint indicating the mode switch will appear in the top right corner.
## 3. Dependencies

View File

@ -1,7 +1,7 @@
---
layout: wiki
title: Logistics - UAV Battery
description:
description: UAV recharging
group: feature
parent: wiki
---
@ -9,13 +9,14 @@ parent: wiki
## 1. Overview
### 1.1 Rechargeable darters.
Adds an item `ACE_UAVBattery` that allows refuelling/recharging of the "Darter" quadcopter UAVs.
Adds an item `ACE_UAVBattery` that allows refuelling/recharging of the "Darter" quad-copter UAVs.
## 2. Usage
### 2.1 Recharging the darter
- For this you need a `UAV battery` and the UAV needs to be a quadcopter.
- INTERACTION LAYER NOT IMPLEMENTED YET TO BE COMPLETED.
- For this you need a `UAV battery` and the UAV needs to be a quad-copter.
- Interact with the UAV <kbd>left windows</kbd> (ACE3 default keybind `Interact Key`)
- Select `recharge`
## 3. Dependencies

View File

@ -16,7 +16,7 @@ Adds an item `ACE_wirecutter` that allows cutting of fences in A3 and AiA maps.
### 2.1 Using the wirecutter
- For this you need a `Wirecutter`.
- Approach the fence you want to cut.
- Press the interaction key <kbd> left windows </kbd> (by default).
- Press the interaction key <kbd>left windows</kbd> (ACE3 default keybind `Interaction Key`).
- Find the interaction point and select `cut fence` (the only option).
## 3. Dependencies

View File

@ -1,7 +1,7 @@
---
layout: wiki
title: Magazine Repack
description:
description: Repacking magazines, and maybe your bananas.
group: feature
parent: wiki
---
@ -16,7 +16,7 @@ Adds the ability to repack magazines of the same type.
### 2.1 Repacking
- For this you need multiple half empty mags of the same type.
- Press the self interaction button <kbd> ctrl+left windows </kbd> (by default).
- Press the self interaction button <kbd>CTRL</kbd> + <kbd>left windows</kbd> (ACE3 default keybind `Self Interaction Key`).
- Select `Repack magazines`.
- Select the type of magazines you want to repack.

View File

@ -1,7 +1,7 @@
---
layout: wiki
title: Main
description:
description: main module
group: feature
parent: wiki
---
@ -10,7 +10,6 @@ parent: wiki
Main module which acts as the ACE core module.
## 2. Dependencies
`Arma 3` and `CBA (RC6 minimum)`

View File

@ -1,7 +1,7 @@
---
layout: wiki
title: Map
description:
description: Map improvements
group: feature
parent: wiki
---
@ -18,7 +18,7 @@ The mission maker / server owner can restrict the maximum zoom level of the map.
While walking your map will move all around the place.
### 1.4 Map illumination (optional)
The map illumination will be the same as your surroundings meaning that in a dark night you'll either need a lightsource or NVGs to see your map.
The map illumination will be the same as your surroundings meaning that in a dark night you'll either need a light source or NVGs to see your map.
### 1.5 Blufor tracker (optional)
With blufor tracker you'll never loose your leader anymore, it marks the position of your faction group leader on the map.

View File

@ -1,7 +1,7 @@
---
layout: wiki
title: Map Tools
description:
description: Map tools, a roamer and pens
group: feature
parent: wiki
---
@ -21,17 +21,17 @@ If you are equipped with a vanilla GPS it will be shown on the map. (You don't n
### 2.1 Using map tools
- For this you need to have `Map Tools`.
- Open the map <kbd> M </kbd> (by default).
- Press the self interaction key <kbd> ctrl+left windows </kbd> (by default).
- Open the map <kbd>M</kbd> (ARMA3 default keybind `Map`).
- Press the self interaction key <kbd>CTRL</kbd> + <kbd>left windows</kbd> (ACE3 default keybind `Self Interaction Key`).
- Select `Map tools`.
- Select the type of tools you want to use.
- Note that you can drag the Roamer (map tool) around with <kdd> LMB </kbd> and rotate it with <kbd> ctrl+LMB </kbd>.
- Note that you can drag the Roamer (map tool) around with <kdd> LMB </kbd> and rotate it with <kbd>CTRL</kbd> + <kbd>LMB</kbd>.
### 2.2 Drawing lines
- To draw lines `Map Tools` are not required.
- Press <kbd> alt+left click </kbd> (by default) to start the line, left click again to end it.
- To delete a line simply press <kbd> delete </kbd> around the center of the line.
- Press <kbd>ALT</kbd> + <kbd>LMB</kbd> to start the line, left click again to end it.
- To delete a line simply press <kbd>delete</kbd> around the center of the line.
- Note that you can change the color of the lines by clicking on one of the coloured column on top of the screen (While the map is opened)
## 3. Dependencies

View File

@ -1,7 +1,7 @@
---
layout: wiki
title: Markers
description:
description: improved markers
group: feature
parent: wiki
---

View File

@ -6,21 +6,10 @@ group: feature
parent: wiki
---
## Overview
## 1. Overview
### Sub-feature 1
Short description of sub-feature 1.
Adds the AMG framework, for more information about it refer to the [AMG framework documentation] (http://ace3mod.com/wiki/framework/advanced-missile-guidance.html)
### Sub-feature 2
Short description of sub-feature 2.
## Usage
Short overview of how to use the feature, e.g. menu options, key bindings,
instructions. May not apply to all modules.
## Dependencies
## 2. Dependencies
`ace_laser`

View File

@ -1,26 +1,19 @@
---
layout: wiki
title: Mission Modules
description:
description: modules that can be used by mission makers.
group: feature
parent: wiki
---
## Overview
## 1. Overview
### Sub-feature 1
Short description of sub-feature 1.
Add modules that can be used by mission makers.
### Sub-feature 2
Short description of sub-feature 2.
### 1.1 Ambient sounds
That module can be used to add ambient sounds around players, it let you choose the sounds and some parameters (distance, volume interval).
## Usage
Short overview of how to use the feature, e.g. menu options, key bindings,
instructions. May not apply to all modules.
## Dependencies
## 2. Dependencies
`ace_common`

View File

@ -9,45 +9,56 @@ parent: wiki
## 1. Overview
### 1.1 mk6 mortar overhaul
ACE3 adds wind deflection for shells as well as a rangetable to accurately take out your target without the artillery computer.
## 2. Usage
### 2.1 Switching charge
- Press <kbd> F </kbd> (fire mode switch) to switch between charges
- Press <kbd>F</kbd> (ARMA3 default keybind `fire mode switch`) to switch between charges
### 2.2 Working with the rangetable
- To open the table:
- Self interact <kbd> ctrl </kbd> + <kbd> left windows </kbd> (by default).
- Self interact <kbd>CTRL</kbd> + <kbd>left windows</kbd>
- Select `equipment`.
- Select `Open 82mm Rangetable`.
- Using the table:
- Get the distance and elevation difference between you and the target for this you can use map tools. For this example we'll say we're 2 000m away and 50m below (we're at 20m they are at 70m, 70-20=50).
- Select the charge you want to use (0 = close / 1 = medium / 2 = far). For this case we're using charge 2.
- Check the range column on the table, we're at 2 000 then look at the corresponding entry in the column on the right (ELEV = elevation) For this example it's 1339.
- After that's done move by one column on the right that's the elevation for 100m heigh so in our case we're subtracting 2 (4:2 = 2) if our target was 300m above us we would have to subtract 12 from our elevation (3x4 = 12).
- After you finished your maths, it's time to aim, get the cross of the mortar on target, if you don't see it use a waypoint if possible. In our case ELEV is 1339-2 = 1337.
- On the right side of the screen, while looking through the mk6 scope you should see ELV, we need to match this number with the one we found.
- To adjust the ELV use <kbd> pageUp </kbd> and <kbd> pageDown </kbd>.
- Select the charge you want to use (0 = close / 1 = medium / 2 = far). For this case we're using charge 2.
- Check the range column on the table, we're at 2 000 then look at the corresponding entry in the column on the right (ELEV = elevation) For this example it's 1339.
- After that's done move by one column on the right that's the elevation for 100m heigh so in our case we're subtracting 2 (4:2 = 2) if our target was 300m above us we would have to subtract 12 from our elevation (3x4 = 12).
- Once you finished your maths, it's time to aim, get the cross of the mortar on target, if you don't see it use a waypoint if possible. In our case ELEV is 1339-2 = 1337.
- On the right side of the screen, while looking through the mk6 scope you should see ELV, we need to match this number with the one we found.
- To adjust the ELV use <kbd>pageUP</kbd> and <kbd>pageDOWN</kbd>.
- Once the number you found and ELV are the same FIRE !
- On top of that you can calculate the time the shell will take to land by using the third row from the left, in our case the shell need to travel 2000m that's 20xthe number indicated. so 20x0,5 = 10s.
### 2.3 Working with the rangetable (Crosswinds enabled)
- Same as above there's just an extra step, I'll provide an other example in case you forgot.
- Get the distance and elevation difference between you and the target for this you can use map tools. For this example we'll say we're 2 400m away and 223m below (we're at 2m they are at 225, 225-2=223)
- Select the charge you want to use (0 = close / 1 = medium / 2 = far). For this case we're using charge 2.
- Check the range column on the table, we're 2 400m a then look at the corresponding entry in the column on the right (ELEV = elevation) For this example it's 1145.
- After that's done move by one column on the right that's the elevation for 100m heigh so in our case we're subtracting 22 (2,2 x 10 (2,2 because we're around 220m below)).
- Get the distance and elevation difference between you and the target for this you can use map tools. For this example we'll say we're 2 400m away and 223m below (we're at 2m they are at 225, 225-2=223)
- Select the charge you want to use (0 = close / 1 = medium / 2 = far). For this case we're using charge 2.
- Check the range column on the table, we're 2 400m a then look at the corresponding entry in the column on the right (ELEV = elevation) For this example it's 1145.
- After that's done move by one column on the right that's the elevation for 100m heigh so in our case we're subtracting 22 (2,2 x 10 (2,2 because we're around 220m below)).
- Extra step needed here, a kestrel 4500 IS NEEDED.
- Pick the crosswind on your kestrel (for this refer to the kestrel documentation).
- For this example the crosswind is of 2 MPS on my table I can see under Azimuth correction that for each 1MPS I need to correct by 2.5 mill.
- So in this case i'm subtracting 5 mill from the ELV.
- It's MATH TIME the ELV given by the table is 1 145, we subtract 22 because of the heigh, we also subtract 5 for the crosswind ( 1 145-22-5 = 1 118 ).
- After you finished your maths, it's time to aim, get the cross of the mortar on target, if you don't see it use a waypoint if possible. In our case ELEV is 1 118.
- On the right side of the screen, while looking through the mk6 scope you should see ELV, we need to match this number with the one we found.
- FIREEEE !!!!
- Little advantage of having crosswind enabled is that you don't have to calculate the flight time, it's marked on the table in this case it's 33,8s.
- Pick the crosswind on your kestrel (for this refer to the kestrel documentation).
- For this example the crosswind is of 2 MPS on my table I can see under Azimuth correction that for each 1MPS I need to correct by 2.5 mill.
- So in this case i'm subtracting 5 mill from the ELV.
- It's MATH TIME the ELV given by the table is 1 145, we subtract 22 because of the heigh, we also subtract 5 for the crosswind ( 1 145-22-5 = 1 118 ).
- After you finished your maths, it's time to aim, get the cross of the mortar on target, if you don't see it use a waypoint if possible. In our case ELEV is 1 118.
- On the right side of the screen, while looking through the mk6 scope you should see ELV, we need to match this number with the one we found.
- FIREEEE !!!!
- Little advantage of having crosswind enabled is that you don't have to calculate the flight time, it's marked on the table in this case it's 33,8s.
## 3. Dependencies

View File

@ -1,34 +1,39 @@
---
layout: wiki
title: Movement
description:
description: Movement improvements
group: feature
parent: wiki
---
## Overview
## 1. Overview
### Jumping
### 1.1 Jumping
Adds the ability to jump when pressing the vault key while moving. (V - key)
### Minor animation tweaks
### 1.2 Minor animation tweaks
Walking slowly with the weapon lowered now has a less silly looking animation.
### Fatigue adjustments
### 1.3 Fatigue adjustments
Soldiers get fatigued slower, but regain their stamina slower aswell. Fatigued soldiers have a faster walking speed and no longer turn into snails.
### Weight display
### 1.4 Weight display
Adds a weight of the current loadout display in the inventory to estimate the fatigue gain while moving in combat. Can be adjusted to display lb. instead of kg in the ACE Options Menu.
### Optics view in all stances
### 1.5 Optics view in all stances
The player can now use the sights of rifles and pistols in all prone stances.
## Usage
## 2. Usage
Short overview of how to use the feature, e.g. menu options, key bindings,
instructions. May not apply to all modules.
### 2.1 Jumping
- For this you need your weapon up
- While jogging or running press <kbd>V</kbd>
### 2.2 Climbing
- Approach what you want to climb.
- Press <kbd>ctrl</kbd> + <kbd>V</kbd> (ACE3 default keybind `Climb`).
- Note that when climbing your character will put his weapon on his back.
## Dependencies

Some files were not shown because too many files have changed in this diff Show More