mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Merge remote-tracking branch 'upstream/master' into corpse-carry-continued2
This commit is contained in:
commit
68f9ea2d2f
@ -41,7 +41,11 @@ if (_initSpeedCoef > 0) then {
|
||||
};
|
||||
|
||||
private _abAdjustText = "";
|
||||
if (_magIsForCurrentWeapon && {["ace_advanced_ballistics"] call EFUNC(common,isModLoaded)}) then {
|
||||
if (
|
||||
_magIsForCurrentWeapon &&
|
||||
{missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]} &&
|
||||
{missionNamespace getVariable [QEGVAR(advanced_ballistics,barrelLengthInfluenceEnabled), false]} // this can be on while AB is off or vice-versa
|
||||
) then {
|
||||
private _configAmmo = (configFile >> "CfgAmmo" >> (getText (_configMagazine >> "ammo")));
|
||||
private _barrelLength = getNumber (_configWeapon >> "ACE_barrelLength");
|
||||
private _muzzleVelocityTable = getArray (_configAmmo >> "ACE_muzzleVelocities");
|
||||
|
@ -37,7 +37,10 @@ if (_magazine isEqualTo "") then {
|
||||
};
|
||||
|
||||
private _abAdjustText = "";
|
||||
if (["ace_advanced_ballistics"] call EFUNC(common,isModLoaded)) then {
|
||||
if (
|
||||
missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] &&
|
||||
{missionNamespace getVariable [QEGVAR(advanced_ballistics,barrelLengthInfluenceEnabled), false]} // this can be on while AB is off or vice-versa
|
||||
) then {
|
||||
private _configAmmo = (configFile >> "CfgAmmo" >> (getText (_configMagazine >> "ammo")));
|
||||
private _barrelLength = getNumber (_configWeapon >> "ACE_barrelLength");
|
||||
private _muzzleVelocityTable = getArray (_configAmmo >> "ACE_muzzleVelocities");
|
||||
|
@ -1,7 +1,8 @@
|
||||
#include "..\script_component.hpp"
|
||||
#include "\a3\ui_f_curator\ui\defineResinclDesign.inc"
|
||||
#include "\a3\ui_f\hpp\defineDIKCodes.inc"
|
||||
/*
|
||||
* Author: commy2
|
||||
* Author: commy2, johnb43
|
||||
* Disables key input. ESC can still be pressed to open the menu.
|
||||
*
|
||||
* Arguments:
|
||||
@ -27,7 +28,7 @@ if (_state) then {
|
||||
if (!isNull (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull])) exitWith {};
|
||||
if (!isNil QGVAR(disableInputPFH)) exitWith {};
|
||||
|
||||
// end TFAR and ACRE2 radio transmissions
|
||||
// End TFAR and ACRE2 radio transmissions
|
||||
call FUNC(endRadioTransmission);
|
||||
|
||||
// Close map
|
||||
@ -45,38 +46,120 @@ if (_state) then {
|
||||
private _map = _display displayCtrl 101;
|
||||
_map ctrlMapCursor ["", QGVAR(blank)];
|
||||
|
||||
GVAR(keyboardInputMain) = createHashMap;
|
||||
GVAR(keyboardInputCombo) = createHashMap;
|
||||
|
||||
_display displayAddEventHandler ["KeyDown", {
|
||||
// If input is enabled again, ignore
|
||||
if (isNil QGVAR(keyboardInputMain)) exitWith {};
|
||||
|
||||
params ["", "_key"];
|
||||
|
||||
if (_key == 1 && {alive player}) then {
|
||||
createDialog (["RscDisplayInterrupt", "RscDisplayMPInterrupt"] select isMultiplayer);
|
||||
// Get key info; Stored as [isPressed, pressedCount]
|
||||
private _keyPressedInfo = GVAR(keyboardInputMain) getOrDefault [_key, [false, 0], true];
|
||||
_keyPressedInfo params ["_keyPressed", "_keyPressedCount"];
|
||||
|
||||
// For regular keys: If pressed, set to release and remove one key press
|
||||
if (!_keyPressed) then {
|
||||
_keyPressedInfo set [0, true];
|
||||
_keyPressedInfo set [1, _keyPressedCount + 1];
|
||||
};
|
||||
|
||||
// For combo keys, register only if pushed or released (no keypress count)
|
||||
if !(GVAR(keyboardInputCombo) getOrDefault [_key, false]) then {
|
||||
GVAR(keyboardInputCombo) set [_key, true];
|
||||
};
|
||||
|
||||
// Look if keybinds of various actions have been pressed
|
||||
private _action = "";
|
||||
private _comboDikPressed = false;
|
||||
private _return = false;
|
||||
|
||||
// This technique has a limitation: It can't process the Escape key properly (KeyUp EH does not fire)
|
||||
(["TeamSwitch", "CuratorInterface", "ShowMap", "DefaultAction", "Throw", "Chat", "PrevChannel", "NextChannel"] apply {
|
||||
_action = _x;
|
||||
|
||||
{
|
||||
_x params ["_mainKeyArray", "_comboKeyArray", "_isDoubleTap"];
|
||||
_mainKeyArray params ["_mainDik", "_mainDevice"];
|
||||
|
||||
// If keybind doesn't contain key combo, it returns empty array; Therefore, return true
|
||||
_comboDikPressed = if (_comboKeyArray isEqualTo []) then {
|
||||
true
|
||||
} else {
|
||||
_comboKeyArray params ["_comboDik", "_comboDevice"];
|
||||
|
||||
_comboDevice == "KEYBOARD" && {GVAR(keyboardInputCombo) getOrDefault [_comboDik, false]}
|
||||
};
|
||||
|
||||
// Check if the necessary keys were pressed for a keybind
|
||||
_return = _comboDikPressed &&
|
||||
{_mainDevice == "KEYBOARD"} &&
|
||||
{((GVAR(keyboardInputMain) getOrDefault [_mainDik, [false, 0]]) select 1) > ([0, 1] select _isDoubleTap)}; // check how many times the main key was pressed
|
||||
|
||||
// Keybind was detected
|
||||
if (_return) exitWith {
|
||||
TRACE_1("Action triggered: ",_action);
|
||||
};
|
||||
} forEach (actionKeysEx _action);
|
||||
|
||||
_return
|
||||
}) params ["_teamSwitch", "_curatorInterface", "_showMap", "_defaultAction", "_throw", "_chat", "_prevChannel", "_nextChannel"];
|
||||
|
||||
// Handle Escape separately because of limitation mentioned above
|
||||
if (_key == DIK_ESCAPE && {alive player}) then {
|
||||
disableSerialization;
|
||||
|
||||
private _isMultiplayer = isMultiplayer;
|
||||
private _is3DENPreview = is3DENPreview;
|
||||
|
||||
createDialog (["RscDisplayInterrupt", "RscDisplayMPInterrupt"] select _isMultiplayer);
|
||||
|
||||
private _dlg = findDisplay 49;
|
||||
|
||||
for "_index" from 100 to 2000 do {
|
||||
(_dlg displayCtrl _index) ctrlEnable false;
|
||||
};
|
||||
|
||||
private _ctrl = _dlg displayctrl 103;
|
||||
_ctrl ctrlSetEventHandler ["buttonClick", QUOTE(while {!isNull (uiNamespace getVariable [ARR_2(QUOTE(QGVAR(dlgDisableMouse)),displayNull)])} do {closeDialog 0}; failMission 'LOSER'; [false] call DFUNC(disableUserInput))];
|
||||
private _ctrl = _dlg displayCtrl 103;
|
||||
_ctrl ctrlSetEventHandler ["ButtonClick", toString {
|
||||
while {!isNull (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull])} do {
|
||||
closeDialog 0
|
||||
};
|
||||
|
||||
failMission "LOSER";
|
||||
|
||||
[false] call FUNC(disableUserInput);
|
||||
}];
|
||||
_ctrl ctrlEnable true;
|
||||
_ctrl ctrlSetText "ABORT";
|
||||
_ctrl ctrlSetTooltip "Abort.";
|
||||
_ctrl ctrlSetText localize (["str_disp_int_abort", "STR_3DEN_RscDisplayInterrupt_ButtonAbort_3DEN_text"] select (_is3DENPreview && !_isMultiplayer));
|
||||
_ctrl ctrlSetTooltip localize ([
|
||||
"STR_TOOLTIP_MAIN_ABORT_CAMPAIGN",
|
||||
"STR_3DEN_RscDisplayInterrupt_ButtonAbort_3DEN_tooltip",
|
||||
"STR_TOOLTIP_MAIN_ABORT"
|
||||
] select (([_is3DENPreview, _isMultiplayer] call FUNC(toBitmask)) min 2));
|
||||
|
||||
_ctrl = _dlg displayCtrl ([104, 1010] select _isMultiplayer);
|
||||
_ctrl ctrlSetEventHandler ["ButtonClick", toString {
|
||||
closeDialog 0;
|
||||
|
||||
_ctrl = _dlg displayctrl ([104, 1010] select isMultiplayer);
|
||||
if (["ace_medical"] call FUNC(isModLoaded)) then {
|
||||
_ctrl ctrlSetEventHandler ["buttonClick", 'closeDialog 0; [player, "respawn_button"] call EFUNC(medical_status,setDead); [false] call DFUNC(disableUserInput);'];
|
||||
[player, "respawn_button"] call EFUNC(medical_status,setDead);
|
||||
} else {
|
||||
_ctrl ctrlSetEventHandler ["buttonClick", QUOTE(closeDialog 0; player setDamage 1; [false] call DFUNC(disableUserInput))];
|
||||
};
|
||||
_ctrl ctrlEnable ((getMissionConfigValue ["respawnButton", -1]) != 0); // handles 3den attribute or description.ext
|
||||
_ctrl ctrlSetText localize "$str_3den_multiplayer_attributecategory_respawn_displayname";
|
||||
_ctrl ctrlSetTooltip "Respawn.";
|
||||
player setDamage 1;
|
||||
};
|
||||
|
||||
if (_key in actionKeys "TeamSwitch" && {teamSwitchEnabled}) then {
|
||||
[false] call FUNC(disableUserInput);
|
||||
}];
|
||||
|
||||
private _respawnEnabled = (getMissionConfigValue ["respawnButton", -1]) != 0;
|
||||
|
||||
_ctrl ctrlEnable _respawnEnabled; // handles 3den attribute or description.ext
|
||||
_ctrl ctrlSetText localize "str_disp_int_respawn";
|
||||
_ctrl ctrlSetTooltip localize (["str_3den_attributes_respawn_none_tooltip", "str_disp_int_respawn"] select _respawnEnabled);
|
||||
};
|
||||
|
||||
if (_teamSwitch && teamSwitchEnabled) then {
|
||||
(uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull]) closeDisplay 0;
|
||||
|
||||
private _acc = accTime;
|
||||
@ -84,18 +167,20 @@ if (_state) then {
|
||||
setAccTime _acc;
|
||||
};
|
||||
|
||||
if (_key in actionKeys "CuratorInterface" && {getAssignedCuratorLogic player in allCurators}) then {
|
||||
if (_curatorInterface && {!isNull getAssignedCuratorLogic player}) then {
|
||||
(uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull]) closeDisplay 0;
|
||||
|
||||
openCuratorInterface;
|
||||
};
|
||||
|
||||
if (_key in actionKeys "ShowMap" && {player getVariable ["ACE_canSwitchUnits", false]}) then {
|
||||
if (_showMap && {player getVariable ["ACE_canSwitchUnits", false]}) then {
|
||||
(uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull]) closeDisplay 0;
|
||||
|
||||
openMap true;
|
||||
};
|
||||
|
||||
if (isServer || {serverCommandAvailable "#kick"}) then {
|
||||
if (!(_key in (actionKeys "DefaultAction" + actionKeys "Throw")) && {_key in (actionKeys "Chat" + actionKeys "PrevChannel" + actionKeys "NextChannel")}) then {
|
||||
if (isMultiplayer && {isServer || {serverCommandAvailable "#kick"}}) then {
|
||||
if (!(_defaultAction || _throw) && {_chat || _prevChannel || _nextChannel}) then {
|
||||
_key = 0;
|
||||
};
|
||||
};
|
||||
@ -103,7 +188,41 @@ if (_state) then {
|
||||
_key > 0
|
||||
}];
|
||||
|
||||
_display displayAddEventHandler ["KeyUp", {true}];
|
||||
_display displayAddEventHandler ["KeyUp", {
|
||||
// If input is enabled again, ignore
|
||||
if (isNil QGVAR(keyboardInputMain)) exitWith {};
|
||||
|
||||
params ["", "_key"];
|
||||
|
||||
// For combo keys: If pressed, release
|
||||
if (GVAR(keyboardInputCombo) getOrDefault [_key, false]) then {
|
||||
GVAR(keyboardInputCombo) deleteAt _key;
|
||||
};
|
||||
|
||||
private _keyPressedInfo = GVAR(keyboardInputMain) getOrDefault [_key, [false, 0]];
|
||||
|
||||
// If pressed, release it
|
||||
if (_keyPressedInfo select 0) then {
|
||||
_keyPressedInfo set [0, false];
|
||||
};
|
||||
|
||||
// Cache keystrokes of regular keys for a small amount of time
|
||||
[{
|
||||
// If input is enabled again, ignore
|
||||
if (isNil QGVAR(keyboardInputMain)) exitWith {};
|
||||
|
||||
params ["_key"];
|
||||
|
||||
private _keyPressedInfo = GVAR(keyboardInputMain) getOrDefault [_key, [false, 0]];
|
||||
|
||||
// Release it
|
||||
_keyPressedInfo set [1, ((_keyPressedInfo select 1) - 1) max 0];
|
||||
|
||||
if (_keyPressedInfo isEqualTo [false, 0]) then {
|
||||
GVAR(keyboardInputMain) deleteAt _key,
|
||||
};
|
||||
}, _key, 0.5] call CBA_fnc_waitAndExecute;
|
||||
}];
|
||||
};
|
||||
|
||||
GVAR(disableInputPFH) = [{
|
||||
@ -133,4 +252,7 @@ if (_state) then {
|
||||
};
|
||||
|
||||
(uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull]) closeDisplay 0;
|
||||
|
||||
GVAR(keyboardInputMain) = nil;
|
||||
GVAR(keyboardInputCombo) = nil;
|
||||
};
|
||||
|
@ -15,6 +15,8 @@
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
#define TEMPERATURE_SLOT_INDEX 5
|
||||
|
||||
private _playerDir = getDir ACE_player;
|
||||
private _playerAltitude = (getPosASL ACE_player) select 2;
|
||||
private _temperature = _playerAltitude call EFUNC(weather,calculateTemperatureAtHeight);
|
||||
@ -41,9 +43,10 @@ if (isNil QGVAR(MIN) || isNil QGVAR(MAX)) then {
|
||||
[0, _playerDir] call FUNC(updateMemory);
|
||||
|
||||
if (GVAR(MinAvgMaxMode) == 1) then {
|
||||
private _useAB = missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false];
|
||||
{
|
||||
GVAR(ENTRIES) set [_x, (GVAR(ENTRIES) select _x) + 1];
|
||||
} count [2, 3, 4];
|
||||
} forEach [2, 3, 4];
|
||||
|
||||
// Wind SPD
|
||||
private _windSpeed = call FUNC(measureWindSpeed);
|
||||
@ -51,7 +54,7 @@ if (GVAR(MinAvgMaxMode) == 1) then {
|
||||
|
||||
// CROSSWIND
|
||||
private _crosswind = 0;
|
||||
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
|
||||
if (_useAB) then {
|
||||
_crosswind = abs(sin(GVAR(RefHeading) - _playerDir) * _windSpeed);
|
||||
} else {
|
||||
_crosswind = abs(sin(GVAR(RefHeading)) * _windSpeed);
|
||||
@ -60,7 +63,7 @@ if (GVAR(MinAvgMaxMode) == 1) then {
|
||||
|
||||
// HEADWIND
|
||||
private _headwind = 0;
|
||||
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
|
||||
if (_useAB) then {
|
||||
_headwind = cos(GVAR(RefHeading) - _playerDir) * _windSpeed;
|
||||
} else {
|
||||
_headwind = cos(GVAR(RefHeading)) * _windSpeed;
|
||||
@ -74,4 +77,18 @@ if (GVAR(MinAvgMaxMode) == 1) then {
|
||||
GVAR(TOTAL) set [4, (GVAR(TOTAL) select 4) + _headwind];
|
||||
};
|
||||
|
||||
{ _x call FUNC(updateMemory); true } count [[5, _temperature],[6, _chill],[7, _humidity],[8, _heatIndex],[9, _dewPoint],[10, _wetBulb],[11, _barometricPressure],[12, _altitude],[13, _densityAltitude]];
|
||||
private _data = [
|
||||
_temperature,
|
||||
_chill,
|
||||
_humidity,
|
||||
_heatIndex,
|
||||
_dewPoint,
|
||||
_wetBulb,
|
||||
_barometricPressure,
|
||||
_altitude,
|
||||
_densityAltitude
|
||||
];
|
||||
|
||||
{
|
||||
[TEMPERATURE_SLOT_INDEX + _forEachIndex, _x] call FUNC(updateMemory);
|
||||
} forEach _data;
|
||||
|
@ -99,7 +99,11 @@
|
||||
#define TYPE_SCUBA 604 // not implemented
|
||||
#define TYPE_HEADGEAR 605
|
||||
#define TYPE_FACTOR 607
|
||||
#define TYPE_MAP 608
|
||||
#define TYPE_COMPASS 609
|
||||
#define TYPE_WATCH 610
|
||||
#define TYPE_RADIO 611
|
||||
#define TYPE_GPS 612
|
||||
#define TYPE_HMD 616
|
||||
#define TYPE_BINOCULAR 617
|
||||
#define TYPE_MEDIKIT 619
|
||||
|
@ -1,62 +1,204 @@
|
||||
#define EXCEPTIONS exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}
|
||||
|
||||
class CfgVehicles {
|
||||
class Man;
|
||||
class CAManBase: Man {
|
||||
class ACE_SelfActions {
|
||||
class ACE_MapGpsShow {
|
||||
displayName = CSTRING(MapGpsShow);
|
||||
condition = QUOTE((!GVAR(mapGpsShow)) && {call FUNC(canUseMapGPS)});
|
||||
statement = QUOTE(GVAR(mapGpsShow) = true;);
|
||||
exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"};
|
||||
condition = QUOTE(!GVAR(mapGpsShow) && {call FUNC(canUseMapGPS)});
|
||||
statement = QUOTE(GVAR(mapGpsShow) = true);
|
||||
EXCEPTIONS;
|
||||
showDisabled = 0;
|
||||
};
|
||||
class ACE_MapGpsHide {
|
||||
displayName = CSTRING(MapGpsHide);
|
||||
condition = QUOTE((GVAR(mapGpsShow)) && {call FUNC(canUseMapGPS)});
|
||||
statement = QUOTE(GVAR(mapGpsShow) = false;);
|
||||
exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"};
|
||||
condition = QUOTE(GVAR(mapGpsShow) && {call FUNC(canUseMapGPS)});
|
||||
statement = QUOTE(GVAR(mapGpsShow) = false);
|
||||
EXCEPTIONS;
|
||||
showDisabled = 0;
|
||||
};
|
||||
class ACE_MapTools {
|
||||
displayName = CSTRING(MapTools_Menu);
|
||||
condition = QUOTE(call FUNC(canUseMapTools));
|
||||
statement = "";
|
||||
exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"};
|
||||
EXCEPTIONS;
|
||||
showDisabled = 0;
|
||||
|
||||
class ACE_MapToolsHide {
|
||||
displayName = CSTRING(MapToolsHide);
|
||||
condition = QUOTE(GVAR(mapTool_Shown) != 0);
|
||||
statement = QUOTE(GVAR(mapTool_Shown) = 0;);
|
||||
exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"};
|
||||
statement = QUOTE(GVAR(mapTool_Shown) = 0);
|
||||
EXCEPTIONS;
|
||||
showDisabled = 1;
|
||||
};
|
||||
class ACE_MapToolsShowNormal {
|
||||
displayName = CSTRING(MapToolsShowNormal);
|
||||
condition = QUOTE(GVAR(mapTool_Shown) != 1);
|
||||
statement = QUOTE(if (GVAR(mapTool_Shown) == 0) then {GVAR(mapTool_moveToMouse) = true}; GVAR(mapTool_Shown) = 1;);
|
||||
exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"};
|
||||
statement = QUOTE(if (GVAR(mapTool_Shown) == 0) then {GVAR(mapTool_moveToMouse) = true}; GVAR(mapTool_Shown) = 1);
|
||||
EXCEPTIONS;
|
||||
showDisabled = 1;
|
||||
};
|
||||
class ACE_MapToolsShowSmall {
|
||||
displayName = CSTRING(MapToolsShowSmall);
|
||||
condition = QUOTE(GVAR(mapTool_Shown) != 2);
|
||||
statement = QUOTE(if (GVAR(mapTool_Shown) == 0) then {GVAR(mapTool_moveToMouse) = true}; GVAR(mapTool_Shown) = 2;);
|
||||
exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"};
|
||||
statement = QUOTE(if (GVAR(mapTool_Shown) == 0) then {GVAR(mapTool_moveToMouse) = true}; GVAR(mapTool_Shown) = 2);
|
||||
EXCEPTIONS;
|
||||
showDisabled = 1;
|
||||
};
|
||||
class ACE_MapToolsAlignNorth {
|
||||
displayName = CSTRING(MapToolsAlignNorth);
|
||||
class ACE_MapToolsAlign {
|
||||
displayName = CSTRING(AlignTo);
|
||||
condition = QUOTE(GVAR(mapTool_Shown) != 0);
|
||||
statement = QUOTE(GVAR(mapTool_angle) = 0;);
|
||||
exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"};
|
||||
statement = "";
|
||||
EXCEPTIONS;
|
||||
showDisabled = 0;
|
||||
|
||||
class ACE_MapToolsAlignToPlottingBoardRuler {
|
||||
displayName = CSTRING(ToPlottingBoardRulerLabel);
|
||||
condition = QUOTE(GVAR(mapTool_Shown) != 0 && GVAR(plottingBoard_Shown) == 2);
|
||||
statement = QUOTE(GVAR(mapTool_angle) = GVAR(plottingBoard_rulerAngle));
|
||||
EXCEPTIONS;
|
||||
showDisabled = 1;
|
||||
};
|
||||
class ACE_MapToolsAlignToPlottingBoardAcrylic {
|
||||
displayName = CSTRING(ToPlottingBoardAcrylicLabel);
|
||||
condition = QUOTE(GVAR(mapTool_Shown) != 0 && GVAR(plottingBoard_Shown) != 0);
|
||||
statement = QUOTE(GVAR(mapTool_angle) = GVAR(plottingBoard_acrylicAngle));
|
||||
EXCEPTIONS;
|
||||
showDisabled = 1;
|
||||
};
|
||||
class ACE_MapToolsAlignToPlottingBoard {
|
||||
displayName = CSTRING(ToPlottingBoardLabel);
|
||||
condition = QUOTE(GVAR(mapTool_Shown) != 0 && GVAR(plottingBoard_Shown) != 0);
|
||||
statement = QUOTE(GVAR(mapTool_angle) = GVAR(plottingBoard_angle));
|
||||
EXCEPTIONS;
|
||||
showDisabled = 1;
|
||||
};
|
||||
class ACE_MapToolsAlignCompass {
|
||||
displayName = CSTRING(MapToolsAlignCompass);
|
||||
condition = QUOTE(GVAR(mapTool_Shown) != 0 && {getUnitLoadout ACE_player param [ARR_2(9,[])] param [ARR_2(3,'')] != ''});
|
||||
statement = QUOTE(GVAR(mapTool_angle) = getDir ACE_player;);
|
||||
exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"};
|
||||
displayName = CSTRING(ToCompassLabel);
|
||||
condition = QUOTE(GVAR(mapTool_Shown) != 0 && {ACE_player getSlotItemName TYPE_COMPASS != ''});
|
||||
statement = QUOTE(GVAR(mapTool_angle) = getDir ACE_player);
|
||||
EXCEPTIONS;
|
||||
showDisabled = 1;
|
||||
};
|
||||
class ACE_MapToolsAlignNorth {
|
||||
displayName = CSTRING(ToNorthLabel);
|
||||
condition = QUOTE(GVAR(mapTool_Shown) != 0);
|
||||
statement = QUOTE(GVAR(mapTool_angle) = 0);
|
||||
EXCEPTIONS;
|
||||
showDisabled = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
class ACE_PlottingBoard {
|
||||
displayName = CSTRING(ShowPlottingBoard);
|
||||
condition = QUOTE(GVAR(plottingBoard_Shown) < 1 && {call FUNC(canUsePlottingBoard)});
|
||||
statement = QUOTE(GVAR(plottingBoard_Shown) = 1);
|
||||
EXCEPTIONS;
|
||||
showDisabled = 0;
|
||||
};
|
||||
class ACE_PlottingBoardHide {
|
||||
displayName = CSTRING(HidePlottingBoard);
|
||||
condition = QUOTE(GVAR(plottingBoard_Shown) != 0 && {call FUNC(canUsePlottingBoard)});
|
||||
statement = QUOTE(GVAR(plottingBoard_Shown) = 0);
|
||||
EXCEPTIONS;
|
||||
showDisabled = 0;
|
||||
|
||||
class ACE_PlottingBoardRulerShow {
|
||||
displayName = CSTRING(TogglePlottingBoardRuler);
|
||||
condition = QUOTE(GVAR(plottingBoard_Shown) == 1);
|
||||
statement = QUOTE(GVAR(plottingBoard_Shown) = 2);
|
||||
EXCEPTIONS;
|
||||
showDisabled = 1;
|
||||
};
|
||||
class ACE_PlottingBoardRulerHide {
|
||||
displayName = CSTRING(TogglePlottingBoardRuler);
|
||||
condition = QUOTE(GVAR(plottingBoard_Shown) == 2);
|
||||
statement = QUOTE(GVAR(plottingBoard_Shown) = 1);
|
||||
EXCEPTIONS;
|
||||
showDisabled = 1;
|
||||
};
|
||||
class ACE_PlottingBoardWipe {
|
||||
displayName = CSTRING(WipeBoard);
|
||||
condition = QUOTE(GVAR(plottingBoard_markers) isNotEqualTo createHashMap);
|
||||
statement = QUOTE(call FUNC(wipeMarkers));
|
||||
EXCEPTIONS;
|
||||
showDisabled = 1;
|
||||
};
|
||||
class ACE_PlottingBoardAlign {
|
||||
displayName = CSTRING(AlignTo);
|
||||
condition = QUOTE(GVAR(plottingBoard_Shown) > 0);
|
||||
statement = "";
|
||||
EXCEPTIONS;
|
||||
showDisabled = 0;
|
||||
|
||||
class ACE_PlottingBoardAlignBoard {
|
||||
displayName = CSTRING(PlottingBoardLabel);
|
||||
condition = QUOTE(true);
|
||||
statement = "";
|
||||
EXCEPTIONS;
|
||||
showDisabled = 0;
|
||||
|
||||
class ACE_PlottingBoardAlignBoardMaptool {
|
||||
displayName = CSTRING(Name);
|
||||
condition = QUOTE(GVAR(mapTool_Shown) > 0 && GVAR(plottingBoard_angle) != GVAR(mapTool_angle));
|
||||
statement = QUOTE(GVAR(plottingBoard_angle) = GVAR(mapTool_angle));
|
||||
EXCEPTIONS;
|
||||
showDisabled = 0;
|
||||
};
|
||||
class ACE_PlottingBoardAlignBoardUp {
|
||||
displayName = CSTRING(ToUpLabel);
|
||||
condition = QUOTE(GVAR(plottingBoard_angle) != 0);
|
||||
statement = QUOTE(GVAR(plottingBoard_angle) = 0);
|
||||
EXCEPTIONS;
|
||||
showDisabled = 0;
|
||||
};
|
||||
};
|
||||
class ACE_PlottingBoardAlignAcrylic {
|
||||
displayName = CSTRING(PlottingBoardAcrylicLabel);
|
||||
condition = QUOTE(true);
|
||||
statement = "";
|
||||
EXCEPTIONS;
|
||||
showDisabled = 0;
|
||||
|
||||
class ACE_PlottingBoardAlignAcrylicMaptool {
|
||||
displayName = CSTRING(Name);
|
||||
condition = QUOTE(GVAR(mapTool_Shown) > 0 && GVAR(plottingBoard_acrylicAngle) != GVAR(mapTool_angle));
|
||||
statement = QUOTE(GVAR(plottingBoard_acrylicAngle) = GVAR(mapTool_angle));
|
||||
EXCEPTIONS;
|
||||
showDisabled = 0;
|
||||
};
|
||||
class ACE_PlottingBoardAlignAcrylicUp {
|
||||
displayName = CSTRING(ToUpLabel);
|
||||
condition = QUOTE(GVAR(plottingBoard_acrylicAngle) != 0);
|
||||
statement = QUOTE(GVAR(plottingBoard_acrylicAngle) = 0);
|
||||
EXCEPTIONS;
|
||||
showDisabled = 0;
|
||||
};
|
||||
};
|
||||
class ACE_PlottingBoardAlignRuler {
|
||||
displayName = CSTRING(PlottingBoardRulerLabel);
|
||||
condition = QUOTE(GVAR(plottingBoard_Shown) == 2);
|
||||
statement = "";
|
||||
EXCEPTIONS;
|
||||
showDisabled = 0;
|
||||
|
||||
class ACE_PlottingBoardAlignRulerMaptool {
|
||||
displayName = CSTRING(Name);
|
||||
condition = QUOTE(GVAR(mapTool_Shown) > 0 && GVAR(plottingBoard_rulerAngle) != GVAR(mapTool_angle));
|
||||
statement = QUOTE(GVAR(plottingBoard_rulerAngle) = GVAR(mapTool_angle));
|
||||
EXCEPTIONS;
|
||||
showDisabled = 0;
|
||||
};
|
||||
class ACE_PlottingBoardAlignRulerUp {
|
||||
displayName = CSTRING(ToUpLabel);
|
||||
condition = QUOTE(GVAR(plottingBoard_rulerAngle) != 0);
|
||||
statement = QUOTE(GVAR(plottingBoard_rulerAngle) = 0);
|
||||
EXCEPTIONS;
|
||||
showDisabled = 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -69,30 +211,35 @@ class CfgVehicles {
|
||||
class Box_NATO_Support_F: NATO_Box_Base {
|
||||
class TransportItems {
|
||||
MACRO_ADDITEM(ACE_MapTools,12);
|
||||
MACRO_ADDITEM(ACE_PlottingBoard,12);
|
||||
};
|
||||
};
|
||||
|
||||
class Box_East_Support_F: EAST_Box_Base {
|
||||
class TransportItems {
|
||||
MACRO_ADDITEM(ACE_MapTools,12);
|
||||
MACRO_ADDITEM(ACE_PlottingBoard,12);
|
||||
};
|
||||
};
|
||||
|
||||
class Box_IND_Support_F: IND_Box_Base {
|
||||
class TransportItems {
|
||||
MACRO_ADDITEM(ACE_MapTools,12);
|
||||
MACRO_ADDITEM(ACE_PlottingBoard,12);
|
||||
};
|
||||
};
|
||||
|
||||
class Box_FIA_Support_F: FIA_Box_Base_F {
|
||||
class TransportItems {
|
||||
MACRO_ADDITEM(ACE_MapTools,12);
|
||||
MACRO_ADDITEM(ACE_PlottingBoard,12);
|
||||
};
|
||||
};
|
||||
|
||||
class ACE_Box_Misc: Box_NATO_Support_F {
|
||||
class TransportItems {
|
||||
MACRO_ADDITEM(ACE_MapTools,12);
|
||||
MACRO_ADDITEM(ACE_PlottingBoard,12);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -14,4 +14,17 @@ class CfgWeapons {
|
||||
mass = 0.2;
|
||||
};
|
||||
};
|
||||
|
||||
class ACE_PlottingBoard: ACE_ItemCore {
|
||||
displayName = CSTRING(PlottingBoard_Name);
|
||||
author = ECSTRING(common,ACETeam);
|
||||
descriptionShort = CSTRING(Description);
|
||||
model = QPATHTOF(data\ace_MapTools.p3d);
|
||||
picture = QPATHTOF(UI\plottingboard_item.paa);
|
||||
scope = 2;
|
||||
ACE_isTool = 1;
|
||||
class ItemInfo: CBA_MiscItem_ItemInfo {
|
||||
mass = 0.5;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -5,3 +5,4 @@ Adds the following map tools:
|
||||
- Roamer
|
||||
- Map drawing
|
||||
- Showing GPS on map
|
||||
- Plotting Board
|
||||
|
BIN
addons/maptools/UI/plottingboard_item.paa
Normal file
BIN
addons/maptools/UI/plottingboard_item.paa
Normal file
Binary file not shown.
@ -7,3 +7,8 @@ PREP(handleMouseMove);
|
||||
PREP(isInsideMapTool);
|
||||
PREP(openMapGpsUpdate);
|
||||
PREP(updateMapToolMarkers);
|
||||
|
||||
PREP(canUsePlottingBoard);
|
||||
PREP(isInsidePlottingBoard);
|
||||
PREP(handlePlottingBoardMarkers);
|
||||
PREP(wipeMarkers);
|
||||
|
@ -1,4 +1,4 @@
|
||||
// by esteldunedain
|
||||
// by esteldunedain, LorenLuke
|
||||
|
||||
#include "script_component.hpp"
|
||||
|
||||
@ -15,6 +15,16 @@ GVAR(mapTool_isDragging) = false;
|
||||
GVAR(mapTool_isRotating) = false;
|
||||
GVAR(mapTool_moveToMouse) = true; // used to display it in center of screen when opened
|
||||
|
||||
GVAR(plottingBoard_Shown) = 0;
|
||||
GVAR(plottingBoard_pos) = [0, 0];
|
||||
GVAR(plottingBoard_angle) = 0;
|
||||
GVAR(plottingBoard_acrylicAngle) = 0;
|
||||
GVAR(plottingBoard_rulerAngle) = 0;
|
||||
GVAR(plottingBoard_isDragging) = false;
|
||||
GVAR(plottingBoard_isRotating) = -1;
|
||||
GVAR(plottingBoard_moveToMouse) = true; // used to display it in center of screen when opened
|
||||
GVAR(plottingBoard_markers) = createHashMap;
|
||||
|
||||
//Install the event handers for the map tools on the main in-game map
|
||||
[{!isNull findDisplay 12},
|
||||
{
|
||||
@ -32,7 +42,13 @@ GVAR(mapTool_moveToMouse) = true; // used to display it in center of screen whe
|
||||
};
|
||||
}] call CBA_fnc_addPlayerEventHandler;
|
||||
|
||||
addMissionEventHandler ["MarkerCreated", {
|
||||
[_this, false] call FUNC(handlePlottingBoardMarkers);
|
||||
}];
|
||||
|
||||
addMissionEventHandler ["MarkerDeleted", {
|
||||
[[_this select 0, -1, objNull, _this select 1], true] call FUNC(handlePlottingBoardMarkers);
|
||||
}];
|
||||
|
||||
GVAR(freeDrawingData) = [];
|
||||
GVAR(freedrawing) = false;
|
||||
|
||||
|
BIN
addons/maptools/data/plottingBoardAcrylic.paa
Normal file
BIN
addons/maptools/data/plottingBoardAcrylic.paa
Normal file
Binary file not shown.
BIN
addons/maptools/data/plottingBoardBack.paa
Normal file
BIN
addons/maptools/data/plottingBoardBack.paa
Normal file
Binary file not shown.
BIN
addons/maptools/data/plottingBoardRuler.paa
Normal file
BIN
addons/maptools/data/plottingBoardRuler.paa
Normal file
Binary file not shown.
22
addons/maptools/functions/fnc_canUsePlottingBoard.sqf
Normal file
22
addons/maptools/functions/fnc_canUsePlottingBoard.sqf
Normal file
@ -0,0 +1,22 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: LorenLuke
|
||||
* Returns if the plotting board can be used.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* Plotting board can be used <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* call ace_maptools_fnc_canUsePlottingBoard
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
visibleMap &&
|
||||
{alive ACE_player} &&
|
||||
{[ACE_player, "ACE_PlottingBoard"] call EFUNC(common,hasItem)} &&
|
||||
{!GVAR(plottingBoard_isDragging)} &&
|
||||
{GVAR(plottingBoard_isRotating) == -1}
|
@ -1,17 +1,17 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: esteldunedain
|
||||
* Author: esteldunedain, LorenLuke
|
||||
* Handle mouse buttons.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: 1 if mouse down down, 0 if mouse button up <Number>
|
||||
* 0: 1 if mouse down down, 0 if mouse button up <NUMBER>
|
||||
* 1: Parameters of the mouse button event <ARRAY>
|
||||
*
|
||||
* Return Value:
|
||||
* true if event was handled <BOOL>
|
||||
* True if event was handled <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [0, [array]] call ACE_maptools_fnc_handleMouseButton
|
||||
* [0, []] call ace_maptools_fnc_handleMouseButton
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
@ -24,20 +24,27 @@ TRACE_2("params",_dir,_params);
|
||||
if ((_button == 0) && {GVAR(freedrawing) || _ctrlKey}) exitWith {
|
||||
if (GVAR(freedrawing) && {_dir == 0}) then {
|
||||
GVAR(freedrawing) = false;
|
||||
|
||||
if (_shiftKey) exitWith {
|
||||
TRACE_1("using vanilla straight line",_shiftKey);
|
||||
};
|
||||
|
||||
TRACE_2("Ending Line",GVAR(freedrawing),GVAR(freeDrawingData));
|
||||
|
||||
[{
|
||||
if (allMapMarkers isEqualTo []) exitWith {};
|
||||
private _markerName = allMapMarkers select (count allMapMarkers - 1);
|
||||
if (GVAR(freeDrawingData) isEqualTo []) exitWith {TRACE_1("never touched roamer",GVAR(freeDrawingData))};
|
||||
|
||||
private _allMarkers = allMapMarkers;
|
||||
|
||||
if (_allMarkers isEqualTo []) exitWith {};
|
||||
|
||||
private _markerName = _allMarkers select -1;
|
||||
private _markerPos = getMarkerPos _markerName;
|
||||
private _distanceCheck = _markerPos distance2d GVAR(drawPosStart);
|
||||
private _distanceCheck = _markerPos distance2D GVAR(drawPosStart);
|
||||
|
||||
TRACE_3("Line Drawn",_markerName,_markerPos,_distanceCheck);
|
||||
|
||||
if (_distanceCheck > 1) exitWith {WARNING("Wrong Marker!");};
|
||||
if ((count GVAR(freeDrawingData)) != 3) exitWith {TRACE_1("never touched roamer",GVAR(freeDrawingData));};
|
||||
if (_distanceCheck > 1) exitWith {WARNING("Wrong Marker!")};
|
||||
|
||||
GVAR(freeDrawingData) params ["", "_startStraightPos", "_endStraightPos"];
|
||||
|
||||
@ -54,17 +61,20 @@ if ((_button == 0) && {GVAR(freedrawing) || _ctrlKey}) exitWith {
|
||||
TRACE_2("Starting Line",GVAR(freedrawing),GVAR(drawPosStart));
|
||||
} else {
|
||||
GVAR(freedrawing) = false;
|
||||
TRACE_1("weird - reseting",GVAR(freedrawing));
|
||||
TRACE_1("weird - resetting",GVAR(freedrawing));
|
||||
};
|
||||
};
|
||||
false
|
||||
|
||||
false // return
|
||||
};
|
||||
|
||||
// If it's not a left button event, exit
|
||||
if (_button != 0) exitWith {
|
||||
false // return
|
||||
};
|
||||
|
||||
private _handled = false;
|
||||
|
||||
// If it's not a left button event, exit
|
||||
if (_button != 0) exitWith {_handled};
|
||||
|
||||
// If releasing
|
||||
if (_dir != 1) then {
|
||||
if (GVAR(mapTool_isDragging) || GVAR(mapTool_isRotating)) then {
|
||||
@ -72,45 +82,99 @@ if (_dir != 1) then {
|
||||
GVAR(mapTool_isRotating) = false;
|
||||
_handled = true;
|
||||
};
|
||||
|
||||
if (GVAR(plottingBoard_isDragging) || GVAR(plottingBoard_isRotating) > -1) then {
|
||||
GVAR(plottingBoard_isDragging) = false;
|
||||
GVAR(plottingBoard_isRotating) = -1;
|
||||
_handled = true;
|
||||
};
|
||||
} else {
|
||||
// If clicking
|
||||
if !(call FUNC(canUseMapTools)) exitWith {};
|
||||
|
||||
// Transform mouse screen position to coordinates
|
||||
private _pos = _control ctrlMapScreenToWorld [_screenPosX, _screenPosY];
|
||||
_pos set [count _pos, 0];
|
||||
|
||||
if (call FUNC(canUseMapTools)) then {
|
||||
GVAR(mapTool_isDragging) = false;
|
||||
GVAR(mapTool_isRotating) = false;
|
||||
|
||||
// If no map tool marker then exit
|
||||
if (GVAR(mapTool_Shown) == 0) exitWith {};
|
||||
if (GVAR(mapTool_Shown) != 0) then {
|
||||
// Transform mouse screen position to coordinates
|
||||
private _pos = _control ctrlMapScreenToWorld [_screenPosX, _screenPosY];
|
||||
|
||||
// Check if clicking the maptool
|
||||
if (_pos call FUNC(isInsideMapTool)) exitWith {
|
||||
if (_pos call FUNC(isInsideMapTool)) then {
|
||||
// Store data for dragging
|
||||
GVAR(mapTool_startPos) = +GVAR(mapTool_pos);
|
||||
GVAR(mapTool_startDragPos) = + _pos;
|
||||
GVAR(mapTool_startDragPos) = _pos;
|
||||
|
||||
private _rotateKeyPressed = switch (GVAR(rotateModifierKey)) do {
|
||||
case (1): {_altKey};
|
||||
case (2): {_ctrlKey};
|
||||
case (3): {_shiftKey};
|
||||
case 1: {_altKey};
|
||||
case 2: {_ctrlKey};
|
||||
case 3: {_shiftKey};
|
||||
default {false};
|
||||
};
|
||||
|
||||
if (_rotateKeyPressed) then {
|
||||
// Store data for rotating
|
||||
GVAR(mapTool_startAngle) = + GVAR(mapTool_angle);
|
||||
GVAR(mapTool_startDragAngle) = (180 + ((GVAR(mapTool_startDragPos) select 0) - (GVAR(mapTool_startPos) select 0)) atan2 ((GVAR(mapTool_startDragPos) select 1) - (GVAR(mapTool_startPos) select 1)) mod 360);
|
||||
GVAR(mapTool_startAngle) = GVAR(mapTool_angle);
|
||||
|
||||
private _pos = GVAR(mapTool_startDragPos) vectorDiff GVAR(mapTool_startPos);
|
||||
GVAR(mapTool_startDragAngle) = ((_pos select 0) atan2 (_pos select 1) + 360) % 360;
|
||||
|
||||
// Start rotating
|
||||
GVAR(mapTool_isRotating) = true;
|
||||
} else {
|
||||
// Start dragging
|
||||
GVAR(mapTool_isDragging) = true;
|
||||
};
|
||||
|
||||
_handled = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
if (call FUNC(canUsePlottingBoard)) then {
|
||||
GVAR(plottingBoard_isDragging) = false;
|
||||
GVAR(plottingBoard_isRotating) = -1;
|
||||
|
||||
if (GVAR(plottingBoard_Shown) != 0) then {
|
||||
// Transform mouse screen position to coordinates
|
||||
private _pos = _control ctrlMapScreenToWorld [_screenPosX, _screenPosY];
|
||||
private _click = _pos call FUNC(isInsidePlottingBoard);
|
||||
|
||||
if (_click > -1) then {
|
||||
GVAR(plottingBoard_startPos) = +GVAR(plottingBoard_pos);
|
||||
GVAR(plottingBoard_startDragPos) = _pos;
|
||||
|
||||
private _rotateKeyPressed = switch (GVAR(rotateModifierKey)) do {
|
||||
case 1: {_altKey};
|
||||
case 2: {_ctrlKey};
|
||||
case 3: {_shiftKey};
|
||||
default {false};
|
||||
};
|
||||
|
||||
if (_rotateKeyPressed) then {
|
||||
// Store data for rotating
|
||||
private _ang = switch (_click) do {
|
||||
case 1: {GVAR(plottingBoard_acrylicAngle)};
|
||||
case 2: {GVAR(plottingBoard_rulerAngle)};
|
||||
default {GVAR(plottingBoard_angle)};
|
||||
};
|
||||
|
||||
GVAR(plottingBoard_startAngle) = _ang;
|
||||
|
||||
private _pos = GVAR(plottingBoard_startDragPos) vectorDiff GVAR(plottingBoard_startPos);
|
||||
GVAR(plottingBoard_startDragAngle) = ((_pos select 0) atan2 (_pos select 1) + 360) % 360;
|
||||
|
||||
// Start rotating
|
||||
GVAR(plottingBoard_isRotating) = _click;
|
||||
} else {
|
||||
// Start dragging
|
||||
GVAR(plottingBoard_isDragging) = true;
|
||||
};
|
||||
|
||||
_handled = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
_handled
|
||||
|
@ -1,47 +1,75 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: esteldunedain
|
||||
* Handle mouse movement over the map tool.
|
||||
* Author: esteldunedain, LorenLuke
|
||||
* Handle mouse movement over the map tool and plotting board.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Map Control <CONTROL>
|
||||
* 0: Map control <CONTROL>
|
||||
* 1: Mouse position on screen coordinates <ARRAY>
|
||||
*
|
||||
* Return Value:
|
||||
* true if event was handled <BOOL>
|
||||
* If the event was handled <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [CONTROL, [0, 5, 1]] call ACE_maptools_fnc_handleMouseMove
|
||||
* [CONTROL, [0, 5]] call ace_maptools_fnc_handleMouseMove
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_control", "_mousePosX", "_mousePosY"];
|
||||
TRACE_3("params",_control,_mousePosX,_mousePosY);
|
||||
params ["_mapCtrl", "_mousePosX", "_mousePosY"];
|
||||
TRACE_3("params",_mapCtrl,_mousePosX,_mousePosY);
|
||||
|
||||
// If have no map tools, then exit
|
||||
if (((isNull ACE_player) || {!("ACE_MapTools" in (ACE_player call EFUNC(common,uniqueItems)))})) exitWith {
|
||||
if (isNull ACE_player || {
|
||||
private _uniqueItems = ACE_player call EFUNC(common,uniqueItems);
|
||||
|
||||
!(("ACE_MapTools" in _uniqueItems) || {"ACE_PlottingBoard" in _uniqueItems})
|
||||
}) exitWith {
|
||||
false
|
||||
};
|
||||
|
||||
// If map tools not shown, then exit
|
||||
if (GVAR(mapTool_Shown) == 0) exitWith {false};
|
||||
if (GVAR(mapTool_Shown) == 0 && {GVAR(plottingBoard_Shown) == 0}) exitWith {false};
|
||||
|
||||
private _mousePosition = _control ctrlMapScreenToWorld [_mousePosX, _mousePosY];
|
||||
private _mousePosition = _mapCtrl ctrlMapScreenToWorld [_mousePosX, _mousePosY];
|
||||
|
||||
// Translation
|
||||
// Map tools - translation
|
||||
if (GVAR(mapTool_isDragging)) exitWith {
|
||||
GVAR(mapTool_pos) set [0, (GVAR(mapTool_startPos) select 0) + (_mousePosition select 0) - (GVAR(mapTool_startDragPos) select 0)];
|
||||
GVAR(mapTool_pos) set [1, (GVAR(mapTool_startPos) select 1) + (_mousePosition select 1) - (GVAR(mapTool_startDragPos) select 1)];
|
||||
GVAR(mapTool_pos) = GVAR(mapTool_startPos) vectorAdd _mousePosition vectorDiff GVAR(mapTool_startDragPos);
|
||||
|
||||
true
|
||||
};
|
||||
|
||||
// Rotation
|
||||
// Map tools - rotation
|
||||
if (GVAR(mapTool_isRotating)) exitWith {
|
||||
// Get new angle
|
||||
private _angle = (180 + ((_mousePosition select 0) - (GVAR(mapTool_startPos) select 0)) atan2 ((_mousePosition select 1) - (GVAR(mapTool_startPos) select 1)) mod 360);
|
||||
GVAR(mapTool_angle) = GVAR(mapTool_startAngle) + _angle - GVAR(mapTool_startDragAngle);
|
||||
private _pos = _mousePosition vectorDiff GVAR(mapTool_startPos);
|
||||
private _angle = (_pos select 0) atan2 (_pos select 1);
|
||||
|
||||
GVAR(mapTool_angle) = ((GVAR(mapTool_startAngle) + _angle - GVAR(mapTool_startDragAngle)) % 360 + 360) % 360;
|
||||
|
||||
true
|
||||
};
|
||||
|
||||
// Plotting board - translation
|
||||
if (GVAR(plottingBoard_isDragging)) exitWith {
|
||||
GVAR(plottingBoard_pos) = GVAR(plottingBoard_startPos) vectorAdd _mousePosition vectorDiff GVAR(plottingBoard_startDragPos);
|
||||
|
||||
true
|
||||
};
|
||||
|
||||
// Plotting board - rotation
|
||||
if (GVAR(plottingBoard_isRotating) > -1) exitWith {
|
||||
// Get new angle
|
||||
private _pos = _mousePosition vectorDiff GVAR(plottingBoard_startPos);
|
||||
private _angle = (_pos select 0) atan2 (_pos select 1);
|
||||
private _returnAngle = ((GVAR(plottingBoard_startAngle) + _angle - GVAR(plottingBoard_startDragAngle)) % 360 + 360) % 360;
|
||||
|
||||
switch (GVAR(plottingBoard_isRotating)) do {
|
||||
case 0: {GVAR(plottingBoard_angle) = _returnAngle};
|
||||
case 1: {GVAR(plottingBoard_acrylicAngle) = _returnAngle};
|
||||
case 2: {GVAR(plottingBoard_rulerAngle) = _returnAngle};
|
||||
};
|
||||
|
||||
true
|
||||
};
|
||||
|
219
addons/maptools/functions/fnc_handlePlottingBoardMarkers.sqf
Normal file
219
addons/maptools/functions/fnc_handlePlottingBoardMarkers.sqf
Normal file
@ -0,0 +1,219 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: LorenLuke, johnb43
|
||||
* Handle map marker creation.
|
||||
* If a marker is (partially) on the plotting board, the parts on the plotting board are attached to the plotting board
|
||||
* and move with the board accordingly.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Arguments <ARRAY>
|
||||
* - 0: Marker name <STRING>
|
||||
* - 1: Chat channel number <NUMBER>
|
||||
* - 2: Marker owner <OBJECT>
|
||||
* - 3: Local origin <BOOL>
|
||||
* 1: Deleted <BOOL>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [CONTROL, [0, 5]] call ace_maptools_fnc_handlePlottingBoardMarkers
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_args", "_deleted"];
|
||||
_args params ["_marker", "_channelNumber", "_owner", "_local"];
|
||||
|
||||
if (_deleted) exitWith {
|
||||
GVAR(plottingBoard_markers) deleteAt _marker;
|
||||
};
|
||||
|
||||
// Do not process non-local or already processed markers, don't check if the plotting board isn't shown
|
||||
if (!_local || {GVAR(plottingBoard_Shown) < 1} || {QUOTE(ADDON) in _marker}) exitWith {};
|
||||
|
||||
// Check if the channel the marker was made in can be marked on the plotting board
|
||||
private _continue = true;
|
||||
|
||||
if (isMultiplayer) then {
|
||||
switch (GVAR(plottingBoardAllowChannelDrawing)) do {
|
||||
case 0: {
|
||||
if (_channelNumber != 5) then {_continue = false};
|
||||
};
|
||||
case 1: {
|
||||
if !(_channelNumber in [3, 5]) then {_continue = false};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
if (!_continue) exitWith {};
|
||||
|
||||
private _boardPos = GVAR(plottingBoard_pos);
|
||||
private _boardAng = GVAR(plottingBoard_acrylicAngle);
|
||||
|
||||
private _markerPolyline = markerPolyline _marker;
|
||||
private _count = count _markerPolyline;
|
||||
|
||||
// If the marker is not a polyline marker
|
||||
if (_count == 0) exitWith {
|
||||
private _diffPos = (getMarkerPos _marker) vectorDiff _boardPos;
|
||||
|
||||
// If the marker is on the acrylic or ruler of the plotting board, save it
|
||||
if (vectorMagnitude _diffPos < PLOTTINGBOARD_DRAWRANGE) then {
|
||||
private _relPos = [[0, 0], _diffPos, _boardAng] call CBA_fnc_vectRotate2D;
|
||||
|
||||
GVAR(plottingBoard_markers) set [_marker, [_relPos, [], _boardAng, +_boardPos, 1]];
|
||||
};
|
||||
};
|
||||
|
||||
// If the marker is a polyline marker, but doesn't have enough components (happens when you ctrl-left click on the map), ignore
|
||||
if (_count <= 4) exitWith {};
|
||||
|
||||
// Polyine markers (lines)
|
||||
private _startPos = [];
|
||||
private _endPos = [];
|
||||
private _dir = [];
|
||||
private _diffPos = [];
|
||||
|
||||
private _a = 0;
|
||||
private _b = 0;
|
||||
private _c = 0;
|
||||
private _t1 = nil;
|
||||
private _t2 = nil;
|
||||
private _delta = 0;
|
||||
|
||||
private _intersectionValid1 = false;
|
||||
private _intersectionValid2 = false;
|
||||
private _intersectPoint1 = [];
|
||||
private _intersectPoint2 = [];
|
||||
private _intersectClose = [];
|
||||
private _intersectFar = [];
|
||||
|
||||
private _polylineIndex = 0;
|
||||
private _markerArray = [[]];
|
||||
private _insideArray = [];
|
||||
|
||||
for "_i" from 0 to _count - 1 - 2 step 2 do {
|
||||
_startPos = [_markerPolyline select _i, _markerPolyline select (_i + 1)];
|
||||
_endPos = [_markerPolyline select (_i + 2), _markerPolyline select (_i + 3)];
|
||||
_dir = _endPos vectorDiff _startPos;
|
||||
_diffPos = _startPos vectorDiff _boardPos;
|
||||
|
||||
// Circle-line intersection: Check for intersections between plotting board and current piece of polyline
|
||||
// https://stackoverflow.com/a/1084899
|
||||
_a = _dir vectorDotProduct _dir;
|
||||
_b = 2 * (_diffPos vectorDotProduct _dir);
|
||||
_c = (_diffPos vectorDotProduct _diffPos) - PLOTTINGBOARD_DRAWRANGE^2;
|
||||
|
||||
_delta = _b^2 - 4 * _a * _c;
|
||||
|
||||
// Stretch factors
|
||||
_t1 = nil;
|
||||
_t2 = nil;
|
||||
|
||||
if (_delta > 0) then {
|
||||
_t1 = (-_b + sqrt _delta) / (2 * _a);
|
||||
_t2 = (-_b - sqrt _delta) / (2 * _a);
|
||||
|
||||
// Don't look for intersection points beyond the start or end points
|
||||
if (_t1 < 0 || _t1 > 1) then {
|
||||
_t1 = nil;
|
||||
};
|
||||
|
||||
if (_t2 < 0 || _t2 > 1) then {
|
||||
_t2 = nil;
|
||||
};
|
||||
};
|
||||
|
||||
// The current point is always part of a polyline
|
||||
(_markerArray param [_polylineIndex, []]) append _startPos;
|
||||
_insideArray set [_polylineIndex, vectorMagnitude _diffPos < PLOTTINGBOARD_DRAWRANGE]; // keep track if point is within plotting board
|
||||
|
||||
_intersectionValid1 = !isNil "_t1";
|
||||
_intersectionValid2 = !isNil "_t2";
|
||||
|
||||
// If no valid intersection points, continue
|
||||
if (!_intersectionValid1 && {!_intersectionValid2}) then {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Extremely rare case if the marker is tangential to the plotting board: Ignore
|
||||
if (_intersectionValid1 && {_intersectionValid2} && {_t1 == _t2}) then {
|
||||
continue;
|
||||
};
|
||||
|
||||
if (_intersectionValid1) then {
|
||||
_intersectPoint1 = _startPos vectorAdd (_dir vectorMultiply _t1);
|
||||
};
|
||||
|
||||
if (_intersectionValid2) then {
|
||||
_intersectPoint2 = _startPos vectorAdd (_dir vectorMultiply _t2);
|
||||
};
|
||||
|
||||
// When a marker crosses the plotting board entirely (one straight line through the plotting board)
|
||||
if (_intersectionValid1 && {_intersectionValid2}) then {
|
||||
// Take the closer point first
|
||||
_intersectClose = [_intersectPoint1, _intersectPoint2] select (_t1 > _t2);
|
||||
|
||||
// Finish previous polyline with the last point being the intersection
|
||||
(_markerArray select _polylineIndex) append _intersectClose;
|
||||
|
||||
// Create a new polyline, with the first point being the closest intersection
|
||||
_polylineIndex = _polylineIndex + 1;
|
||||
_markerArray set [_polylineIndex, _intersectClose];
|
||||
|
||||
// Now take the point further away
|
||||
_intersectFar = [_intersectPoint1, _intersectPoint2] select (_t1 < _t2);
|
||||
|
||||
// Make a polyline between the intersection points
|
||||
(_markerArray select _polylineIndex) append _intersectClose;
|
||||
(_markerArray select _polylineIndex) append _intersectFar;
|
||||
_insideArray set [_polylineIndex, true]; // with 2 intersections, this part of the polyline must be inside
|
||||
|
||||
// Create a new polyline, with the first point being the furthest intersection
|
||||
_polylineIndex = _polylineIndex + 1;
|
||||
_markerArray set [_polylineIndex, _intersectFar];
|
||||
} else {
|
||||
// Only 1 intersection (either point 1 or 2, exclusive or)
|
||||
if (_intersectionValid2) then {
|
||||
_intersectPoint1 = _intersectPoint2;
|
||||
};
|
||||
|
||||
// Finish previous polyline with the last point being the intersection
|
||||
(_markerArray select _polylineIndex) append _intersectPoint1;
|
||||
|
||||
// Create a new polyline, with the first point being the intersection
|
||||
_polylineIndex = _polylineIndex + 1;
|
||||
_markerArray set [_polylineIndex, _intersectPoint1];
|
||||
};
|
||||
};
|
||||
|
||||
// If there were no polyline intersections and the marker was not on the plotting board, don't create new markers
|
||||
if (_insideArray isEqualTo [false]) exitWith {};
|
||||
|
||||
private _color = getMarkerColor _marker;
|
||||
private _name = "";
|
||||
private _polylineRelative = [];
|
||||
private _relPos = [];
|
||||
|
||||
{
|
||||
_name = format ["%1-%2-%3", _marker, _forEachIndex, QUOTE(ADDON)]; // adding an identifier allow to check if marker was already processed
|
||||
createMarkerLocal [_name, [0, 0], _channelNumber, _owner];
|
||||
_name setMarkerColorLocal _color;
|
||||
_name setMarkerPolyline _x; // global marker broadcast
|
||||
|
||||
// If the marker was on the plotting board, take it's unrotated position and store it
|
||||
if (_insideArray select _forEachIndex) then {
|
||||
_polylineRelative = [];
|
||||
|
||||
for "_i" from 0 to count _x - 1 step 2 do {
|
||||
_relPos = [[0, 0], [_x select _i, _x select (_i + 1)] vectorDiff _boardPos, _boardAng] call CBA_fnc_vectRotate2D;
|
||||
_polylineRelative append _relPos;
|
||||
};
|
||||
|
||||
GVAR(plottingBoard_markers) set [_name, [[0, 0], +_polylineRelative, _boardAng, +_boardPos, 1]];
|
||||
};
|
||||
} forEach _markerArray;
|
||||
|
||||
// Delete original marker
|
||||
deleteMarker _marker;
|
54
addons/maptools/functions/fnc_isInsidePlottingBoard.sqf
Normal file
54
addons/maptools/functions/fnc_isInsidePlottingBoard.sqf
Normal file
@ -0,0 +1,54 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: LorenLuke
|
||||
* Return if the position is inside the map marker (to allow dragging) or not.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: x Position (in meters) <NUMBER>
|
||||
* 1: y Position (in meters) <NUMBER>
|
||||
*
|
||||
* Return Value:
|
||||
* Where in the plotting board it is <NUMBER>
|
||||
* -1 - Nowhere, 0 - In the Board, 1 - In the Acrylic, 2 - In the Ruler
|
||||
*
|
||||
* Example:
|
||||
* [0, 5] call ace_maptools_fnc_isInsidePlottingBoard
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
if (GVAR(plottingBoard_Shown) == 0) exitWith {-1};
|
||||
|
||||
private _relPos = _this vectorDiff GVAR(plottingBoard_pos);
|
||||
private _dist = vectorMagnitude _relPos;
|
||||
|
||||
private _isRuler = if (GVAR(plottingBoard_Shown) == 2) then {
|
||||
// If it's within these bounds, it's going to be on the ruler
|
||||
if (_dist <= PLOTTINGBOARD_RULERCENTER) exitWith {true};
|
||||
|
||||
private _rulerVector = [sin GVAR(plottingBoard_rulerAngle), cos GVAR(plottingBoard_rulerAngle)];
|
||||
private _dirRightVector = [_dirVector select 1, -(_dirVector select 0)];
|
||||
private _rulerAng = acos (_rulerVector vectorCos _relPos);
|
||||
|
||||
if (cos _rulerAng > 0 && {tan (_rulerAng) * _dist < PLOTTINGBOARD_RULERHALFWIDTH}) exitWith {true};
|
||||
|
||||
_dist > PLOTTINGBOARD_RULERINNERCIRCLE && {_dist < PLOTTINGBOARD_RULEROUTERCIRCLE && {abs (_rulerAng * DEGTOMILS) < PLOTTINGBOAR_RULEROUTERHALFANGLE}}
|
||||
};
|
||||
|
||||
if (_isRuler) exitWith {2};
|
||||
|
||||
// If it's within 3000 meters, it's going to be on the acrylic
|
||||
if (_dist < PLOTTINGBOARD_RULEROUTERCIRCLE) exitWith {1};
|
||||
|
||||
private _dirVector = [sin GVAR(plottingBoard_angle), cos GVAR(plottingBoard_angle)];
|
||||
private _dirRightVector = [_dirVector select 1, -(_dirVector select 0)];
|
||||
|
||||
// Projection of the relative position over the longitudinal axis of the map tool
|
||||
private _ang = _dirVector vectorCos _relPos;
|
||||
private _ang2 = _dirRightVector vectorCos _relPos;
|
||||
|
||||
private _relPosAdjusted = [_ang2 * _dist / PLOTTINGBOARD_DRAWRANGE, _ang * _dist / PLOTTINGBOARD_DRAWRANGE];
|
||||
|
||||
if ((_relPosAdjusted select 0 > 0) && (_relPosAdjusted select 0 < 1) && (abs (_relPosAdjusted select 1) < 1)) exitWith {0};
|
||||
|
||||
-1
|
@ -1,33 +1,112 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: esteldunedain
|
||||
* Update the map tool markers, position, size, rotation and visibility.
|
||||
* Author: esteldunedain, LorenLuke
|
||||
* Update the map tool and plotting board markers. Update their position, size, rotation and visibility.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: The Map <CONTROL>
|
||||
* 0: Map control <CONTROL>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [CONTROL] call ACE_maptools_fnc_updateMapToolMarkers
|
||||
* [CONTROL] call ace_maptools_fnc_updateMapToolMarkers
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_theMap"];
|
||||
params ["_mapCtrl"];
|
||||
|
||||
if ((GVAR(mapTool_Shown) == 0) || {!("ACE_MapTools" in (ACE_player call EFUNC(common,uniqueItems)))}) exitWith {};
|
||||
if (GVAR(plottingBoard_Shown) == 0) then {
|
||||
// Hide all plotting board markers when board is put away
|
||||
{
|
||||
if (_y select 4 != 0) then {
|
||||
_x setMarkerAlpha 0;
|
||||
_y set [4, 0];
|
||||
};
|
||||
} forEach GVAR(plottingBoard_markers);
|
||||
};
|
||||
|
||||
// open map tools in center of screen when toggled to be shown
|
||||
if (((GVAR(mapTool_Shown) == 0) && {GVAR(plottingBoard_Shown) == 0}) || {
|
||||
private _uniqueItems = ACE_player call EFUNC(common,uniqueItems);
|
||||
|
||||
!(("ACE_MapTools" in _uniqueItems) || {"ACE_PlottingBoard" in _uniqueItems})
|
||||
}) exitWith {};
|
||||
|
||||
if (GVAR(plottingBoard_Shown) > 0) then {
|
||||
if (GVAR(plottingBoard_moveToMouse)) then {
|
||||
GVAR(plottingBoard_pos) = _mapCtrl ctrlMapScreenToWorld getMousePosition;
|
||||
GVAR(plottingBoard_moveToMouse) = false; // we only need to do this once after opening the map tool
|
||||
};
|
||||
|
||||
getResolution params ["_resWidth", "_resHeight", "", "", "_aspectRatio"];
|
||||
private _scaleX = 32 * PLOTTINGBOARD_TEXTUREWIDTH * CONSTANT_SCALE * (call FUNC(calculateMapScale));
|
||||
private _scaleY = _scaleX * ((_resWidth / _resHeight) / _aspectRatio); // handle bad aspect ratios
|
||||
|
||||
_mapCtrl drawIcon [QPATHTOF(data\plottingBoardBack.paa), [1, 1, 1, 1], GVAR(plottingBoard_pos), _scaleX, _scaleY, GVAR(plottingBoard_angle), "", 0];
|
||||
_mapCtrl drawIcon [QPATHTOF(data\plottingBoardAcrylic.paa), [1, 1, 1, 1], GVAR(plottingBoard_pos), _scaleX, _scaleY, GVAR(plottingBoard_acrylicAngle), "", 0];
|
||||
|
||||
// Show ruler
|
||||
if (GVAR(plottingBoard_Shown) == 2) then {
|
||||
_mapCtrl drawIcon [QPATHTOF(data\plottingBoardRuler.paa), [1, 1, 1, 1], GVAR(plottingBoard_pos), _scaleX, _scaleY, GVAR(plottingBoard_rulerAngle), "", 0];
|
||||
};
|
||||
|
||||
private _marker = "";
|
||||
private _angle = GVAR(plottingBoard_acrylicAngle);
|
||||
private _boardPos = GVAR(plottingBoard_pos);
|
||||
private _count = -1;
|
||||
private _rotatedPolyPos = [];
|
||||
private _rotatedPos = [];
|
||||
|
||||
{
|
||||
_marker = _x;
|
||||
_y params ["_markerPos", "_polyline", "_lastAngle", "_lastBoardPos", "_lastAlpha"];
|
||||
|
||||
// Show all plotting board markers when the board is shown
|
||||
if (_lastAlpha != 1) then {
|
||||
_marker setMarkerAlpha 1;
|
||||
_y set [4, 1];
|
||||
};
|
||||
|
||||
// If nothing has changed, don't update marker
|
||||
if (_angle == _lastAngle && {_boardPos isEqualTo _lastBoardPos}) then {
|
||||
continue;
|
||||
};
|
||||
|
||||
_count = count _polyline;
|
||||
|
||||
// Rotate all points of polyline
|
||||
if (_count >= 4) then { // polylines need at least 2 points (2 components per point)
|
||||
_rotatedPolyline = [];
|
||||
|
||||
for "_i" from 0 to _count - 1 step 2 do {
|
||||
_rotatedPolyPos = [[0, 0], [_polyline select _i, _polyline select (_i + 1)], -_angle] call CBA_fnc_vectRotate2D;
|
||||
_rotatedPolyline append (_rotatedPolyPos vectorAdd _boardPos);
|
||||
};
|
||||
|
||||
_marker setMarkerPolyline _rotatedPolyline;
|
||||
};
|
||||
|
||||
// Rotate marker position, regardless of marker type
|
||||
_rotatedPos = [[0, 0], _markerPos, -_angle] call CBA_fnc_vectRotate2D;
|
||||
|
||||
_marker setMarkerPos (_boardPos vectorAdd _rotatedPos);
|
||||
|
||||
_y set [2, _angle];
|
||||
_y set [3, +_boardPos];
|
||||
} forEach GVAR(plottingBoard_markers);
|
||||
};
|
||||
|
||||
if (GVAR(mapTool_Shown) > 0) then {
|
||||
// Open map tools in center of screen when toggled to be shown
|
||||
if (GVAR(mapTool_moveToMouse)) then {
|
||||
private _mousePosition = _theMap ctrlMapScreenToWorld getMousePosition;
|
||||
GVAR(mapTool_pos) = _mousePosition;
|
||||
GVAR(mapTool_pos) = _mapCtrl ctrlMapScreenToWorld getMousePosition;
|
||||
GVAR(mapTool_moveToMouse) = false; // we only need to do this once after opening the map tool
|
||||
};
|
||||
|
||||
private _rotatingTexture = "";
|
||||
private _textureWidth = 0;
|
||||
|
||||
if (GVAR(mapTool_Shown) == 1) then {
|
||||
_rotatingTexture = QPATHTOF(data\mapToolRotatingNormal.paa);
|
||||
_textureWidth = TEXTURE_WIDTH_IN_M;
|
||||
@ -36,21 +115,22 @@ if (GVAR(mapTool_Shown) == 1) then {
|
||||
_textureWidth = TEXTURE_WIDTH_IN_M / 2;
|
||||
};
|
||||
|
||||
if (GVAR(freedrawing)) then {[_theMap, _textureWidth] call FUNC(drawLinesOnRoamer);};
|
||||
if (GVAR(freedrawing)) then {
|
||||
[_mapCtrl, _textureWidth] call FUNC(drawLinesOnRoamer);
|
||||
};
|
||||
|
||||
// Update scale of both parts
|
||||
getResolution params ["_resWidth", "_resHeight", "", "", "_aspectRatio"];
|
||||
private _scaleX = 32 * _textureWidth * CONSTANT_SCALE * (call FUNC(calculateMapScale));
|
||||
private _scaleY = _scaleX;
|
||||
private _scaleY = _scaleX * ((_resWidth / _resHeight) / _aspectRatio); // handle bad aspect ratios
|
||||
|
||||
// Position of the fixed part
|
||||
private _xPos = GVAR(mapTool_pos) select 0;
|
||||
private _yPos = (GVAR(mapTool_pos) select 1) + _textureWidth * CENTER_OFFSET_Y_PERC;
|
||||
private _pos = GVAR(mapTool_pos) vectorAdd [0, _textureWidth * CENTER_OFFSET_Y_PERC];
|
||||
|
||||
_theMap drawIcon [QPATHTOF(data\mapToolFixed.paa), [1,1,1,1], [_xPos,_yPos], _scaleX, _scaleY, 0, "", 0];
|
||||
_mapCtrl drawIcon [QPATHTOF(data\mapToolFixed.paa), [1, 1, 1, 1], _pos, _scaleX, _scaleY, 0, "", 0];
|
||||
|
||||
// Position and rotation of the rotating part
|
||||
_xPos = (GVAR(mapTool_pos) select 0) + sin(GVAR(mapTool_angle)) * _textureWidth * CENTER_OFFSET_Y_PERC;
|
||||
_yPos = (GVAR(mapTool_pos) select 1) + cos(GVAR(mapTool_angle)) * _textureWidth * CENTER_OFFSET_Y_PERC;
|
||||
_pos = GVAR(mapTool_pos) vectorAdd ([sin GVAR(mapTool_angle), cos GVAR(mapTool_angle)] vectorMultiply (_textureWidth * CENTER_OFFSET_Y_PERC));
|
||||
|
||||
_theMap drawIcon [_rotatingTexture, [1,1,1,1], [_xPos,_yPos], _scaleX, _scaleY, GVAR(mapTool_angle), "", 0];
|
||||
_mapCtrl drawIcon [_rotatingTexture, [1, 1, 1, 1], _pos, _scaleX, _scaleY, GVAR(mapTool_angle), "", 0];
|
||||
};
|
||||
|
23
addons/maptools/functions/fnc_wipeMarkers.sqf
Normal file
23
addons/maptools/functions/fnc_wipeMarkers.sqf
Normal file
@ -0,0 +1,23 @@
|
||||
#include "../script_component.hpp"
|
||||
/*
|
||||
* Author: LorenLuke
|
||||
* Delete all markers on the plotting board.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* call ace_maptools_fnc_wipeMarkers
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
{
|
||||
deleteMarker _x;
|
||||
} forEach (keys GVAR(plottingBoard_markers));
|
||||
|
||||
// Reset list
|
||||
GVAR(plottingBoard_markers) = createHashMap;
|
@ -15,3 +15,11 @@ private _category = format ["ACE %1", localize LSTRING(Name)];
|
||||
true,
|
||||
0
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(plottingBoardAllowChannelDrawing), "LIST",
|
||||
[LSTRING(allowChannelDrawing_displayName), LSTRING(allowChannelDrawing_description)],
|
||||
_category,
|
||||
[[0, 1], [LSTRING(allowDirectCommsOnly), LSTRING(allowDirectGroupComms)], 1],
|
||||
0
|
||||
] call CBA_fnc_addSetting;
|
||||
|
@ -16,9 +16,19 @@
|
||||
|
||||
#include "\z\ace\addons\main\script_macros.hpp"
|
||||
|
||||
#define DEGTOMILS 17.7777778
|
||||
|
||||
#define TEXTURE_WIDTH_IN_M 6205
|
||||
#define CENTER_OFFSET_Y_PERC 0.1606
|
||||
#define CONSTANT_SCALE 0.2
|
||||
#define DIST_BOTTOM_TO_CENTER_PERC -0.33
|
||||
#define DIST_TOP_TO_CENTER_PERC 0.65
|
||||
#define DIST_LEFT_TO_CENTER_PERC 0.30
|
||||
|
||||
#define PLOTTINGBOARD_DRAWRANGE 3000
|
||||
#define PLOTTINGBOARD_TEXTUREWIDTH 6000
|
||||
#define PLOTTINGBOARD_RULERCENTER 450
|
||||
#define PLOTTINGBOARD_RULERHALFWIDTH 100
|
||||
#define PLOTTINGBOARD_RULERINNERCIRCLE 2900
|
||||
#define PLOTTINGBOARD_RULEROUTERCIRCLE 3000
|
||||
#define PLOTTINGBOARD_RULEROUTERHALFANGLE 100
|
||||
|
@ -35,6 +35,12 @@
|
||||
<Chinese>地圖工具能夠讓你在地圖上測量距離與角度</Chinese>
|
||||
<Turkish>Harita Araçları, haritadaki mesafeleri ve açıları ölçmenize olanak tanır.</Turkish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_PlottingBoard_Name">
|
||||
<English>Plotting Board</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_PlottingBoard_Description">
|
||||
<English>The Plotting Board is a map tool designed for use in the directing of short range indirect fires.</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_MapTools_Menu">
|
||||
<English>Map Tools</English>
|
||||
<Spanish>Herramientas de mapa</Spanish>
|
||||
@ -252,5 +258,89 @@
|
||||
<Turkish>Düz çizgiler çizmek için maptools'un kenarına çizin. Not: Silmek için orta noktada fareyle üzerine gelmeniz gerekir.</Turkish>
|
||||
<Spanish>Dibujar sobre el borde de las herramientas de mapa para dibujar líneas rectas. Nota: Debe situarse en el punto intermedio para eliminarla.</Spanish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_allowChannelDrawing_displayName">
|
||||
<English>Allow Plotting Board Drawing channels</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_allowChannelDrawing_description">
|
||||
<English>Channels in which plotting board drawing is enabled.</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_allowDirectCommsOnly">
|
||||
<English>Allow Direct Comms Only (Polylines Only)</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_allowDirectGroupComms">
|
||||
<English>Allow Direct/Group Comms (Polylines and Group Markers)</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_PlottingBoardLabel">
|
||||
<English>Plotting Board</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_PlottingBoardAcrylicLabel">
|
||||
<English>Plotting Board Acrylic</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_PlottingBoardRulerLabel">
|
||||
<English>Plotting Board Ruler</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_ToPlottingBoardLabel">
|
||||
<English>To Plotting Board</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_ToPlottingBoardAcrylicLabel">
|
||||
<English>To Plotting Board Acrylic</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_ToPlottingBoardRulerLabel">
|
||||
<English>To Plotting Board Ruler</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_WipeBoard">
|
||||
<English>Wipe all markers off Plotting Board</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_ShowPlottingBoard">
|
||||
<English>Show Plotting Board</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_HidePlottingBoard">
|
||||
<English>Hide Plotting Board</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_TogglePlottingBoardRuler">
|
||||
<English>Toggle Plotting Board Ruler</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_AlignTo">
|
||||
<English>Align</English>
|
||||
<German>Ausrichten</German>
|
||||
<Spanish>Alinear</Spanish>
|
||||
<French>Aligner</French>
|
||||
<Italian>Allinea</Italian>
|
||||
<Portuguese>Alinhar</Portuguese>
|
||||
<Hungarian>Állítása</Hungarian>
|
||||
<Polish>Wyrównaj</Polish>
|
||||
<Czech>Srovnat</Czech>
|
||||
<Russian>Выровнять</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_ToNorthLabel">
|
||||
<English>To North</English>
|
||||
<German>Nach Norden</German>
|
||||
<Spanish>Al norte</Spanish>
|
||||
<French>Sur le nord</French>
|
||||
<Italian>Con il Nord</Italian>
|
||||
<Portuguese>Com o Norte</Portuguese>
|
||||
<Hungarian>Északhoz</Hungarian>
|
||||
<Polish>Do północy</Polish>
|
||||
<Czech>Na sever</Czech>
|
||||
<Russian>На север</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_ToCompassLabel">
|
||||
<English>To Compass</English>
|
||||
<German>Am Kompass</German>
|
||||
<Spanish>A la brújula</Spanish>
|
||||
<French>Sur la boussole</French>
|
||||
<Italian>Con la bussola</Italian>
|
||||
<Portuguese>Com a Bússola</Portuguese>
|
||||
<Hungarian>Iránytűhöz</Hungarian>
|
||||
<Polish>Do kompasu</Polish>
|
||||
<Czech>Ke kompasu</Czech>
|
||||
<Russian>По компасу</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_ToUpLabel">
|
||||
<English>Up</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MapTools_ToMapToolLabel">
|
||||
<English>To Maptool</English>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Freddo
|
||||
* Author: Freddo, Daniël H., johnb43
|
||||
* When the confirm button is pressed.
|
||||
*
|
||||
* Arguments:
|
||||
@ -14,40 +14,100 @@
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_buttonOk"];
|
||||
|
||||
private _display = ctrlParent _buttonOk;
|
||||
private _description = _display displayctrl IDC_INSERT_MARKER;
|
||||
private _description = _display displayCtrl IDC_INSERT_MARKER;
|
||||
private _aceTimestamp = _display displayCtrl IDC_ACE_INSERT_MARKER_TIMESTAMP;
|
||||
|
||||
// handle timestamp
|
||||
// Handle timestamp
|
||||
if (cbChecked _aceTimestamp && {ACE_player call FUNC(canTimestamp)}) then {
|
||||
private _time = daytime;
|
||||
// Determine marker timestamp based on time settings
|
||||
private _time = switch (GVAR(timestampTimezone)) do {
|
||||
case 1: {
|
||||
systemTime select [3]
|
||||
};
|
||||
case 2: {
|
||||
systemTimeUTC params ["", "", "", "_hour", "_min", "_sec", "_msec"];
|
||||
|
||||
// add timestamp suffix
|
||||
private _hourOffset = round GVAR(timestampUTCOffset);
|
||||
_hour = _hour + _hourOffset;
|
||||
|
||||
// Add or subtract minutes offset based on the negative or positive timezone
|
||||
if (GVAR(timestampUTCMinutesOffset) != 0) then {
|
||||
_min = if (_hourOffset < 0) then { _min - GVAR(timestampUTCMinutesOffset) } else { _min + GVAR(timestampUTCMinutesOffset) };
|
||||
|
||||
// Add/remove extra hours from minutes
|
||||
_hour = _hour + floor (_min / 60);
|
||||
_min = (_min % 60 + 60) % 60; // ensure that minutes are between 0 and 59 (included)
|
||||
};
|
||||
|
||||
[(_hour % 24 + 24) % 24, _min, _sec, _msec] // ensure that hours are between 0 and 23 (included)
|
||||
};
|
||||
default {
|
||||
private _daytime = dayTime;
|
||||
|
||||
private _hour = floor _daytime;
|
||||
private _min = floor ((_daytime - _hour) * 60);
|
||||
private _sec = floor ((((_daytime - _hour) * 60) - _min) * 60);
|
||||
private _msec = floor ((((((_daytime - _hour) * 60) - _min) * 60) - _sec) * 1000);
|
||||
|
||||
[_hour, _min, _sec, _msec]
|
||||
};
|
||||
};
|
||||
|
||||
_time params ["_hour", "_min", "_sec", "_msec"];
|
||||
|
||||
// Add timestamp suffix
|
||||
private _periodPostfix = "";
|
||||
|
||||
if (GVAR(timestampHourFormat) == 12) then {
|
||||
if (floor _time == 0) exitWith {
|
||||
_time = _time + 12;
|
||||
if (_hour == 0) exitWith {
|
||||
_hour = _hour + 12;
|
||||
_periodPostfix = " am";
|
||||
};
|
||||
|
||||
if (floor _time == 12) exitWith {
|
||||
if (_hour == 12) exitWith {
|
||||
_periodPostfix = " pm";
|
||||
};
|
||||
|
||||
if (_time < 12) then {
|
||||
if (_hour < 12) then {
|
||||
_periodPostfix = " am";
|
||||
} else {
|
||||
_time = _time - 12;
|
||||
_hour = _hour - 12;
|
||||
_periodPostfix = " pm";
|
||||
};
|
||||
};
|
||||
|
||||
private _format = switch (GVAR(timestampFormat)) do {
|
||||
case "HH": {"%1"};
|
||||
case "HH:MM": {"%1:%2"};
|
||||
case "HH:MM:SS": {"%1:%2:%3"};
|
||||
case "HH:MM:SS:MM": { // milliseconds are displayed as 0 to 59
|
||||
_msec = [_msec * 60 / 1000, 2] call CBA_fnc_formatNumber;
|
||||
|
||||
"%1:%2:%3:%4"
|
||||
};
|
||||
case "HH:MM:SS.mmm": { // milliseconds are displayed as 0 to 999
|
||||
_msec = [_msec, 3] call CBA_fnc_formatNumber;
|
||||
|
||||
"%1:%2:%3.%4"
|
||||
};
|
||||
};
|
||||
|
||||
_time = format [
|
||||
_format,
|
||||
[_hour, 2] call CBA_fnc_formatNumber,
|
||||
[_min, 2] call CBA_fnc_formatNumber,
|
||||
[_sec, 2] call CBA_fnc_formatNumber,
|
||||
_msec
|
||||
];
|
||||
|
||||
_description ctrlSetText format [
|
||||
"%1 [%2%3]",
|
||||
ctrlText _description,
|
||||
[_time, GVAR(timestampFormat)] call BIS_fnc_timeToString,
|
||||
_time,
|
||||
_periodPostfix
|
||||
];
|
||||
};
|
||||
|
@ -32,6 +32,37 @@ private _categoryName = format ["ACE %1", localize ELSTRING(map,Module_DisplayNa
|
||||
true
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(timestampTimezone), "LIST",
|
||||
[LSTRING(TimestampTimezone), LSTRING(TimestampTimezoneDescription)],
|
||||
[_categoryName, LLSTRING(Module_DisplayName)],
|
||||
[
|
||||
[0, 1, 2],
|
||||
[LSTRING(TimestampTimezoneIngameTime), LSTRING(TimestampTimezoneSystemTime), LSTRING(TimestampTimezoneUTCTime)],
|
||||
0
|
||||
],
|
||||
true
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(timestampUTCOffset), "SLIDER",
|
||||
[LSTRING(TimestampUTCOffset), LSTRING(TimestampUTCOffsetDescription)],
|
||||
[_categoryName, LLSTRING(Module_DisplayName)],
|
||||
[-12, 14, 0, 0],
|
||||
true
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(TimestampUTCMinutesOffset), "LIST",
|
||||
[LSTRING(TimestampUTCMinutesOffset), LSTRING(TimestampUTCMinutesOffsetDescription)],
|
||||
[_categoryName, LLSTRING(Module_DisplayName)],
|
||||
[
|
||||
[0, 15, 30, 45],
|
||||
[0, 15, 30, 45],
|
||||
0
|
||||
]
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(timestampHourFormat), "LIST",
|
||||
[LSTRING(TimestampHourFormat), LSTRING(TimestampHourFormatDescription)],
|
||||
@ -48,7 +79,8 @@ private _formatDescription = [
|
||||
LLSTRING(TimestampFormatDescription1),
|
||||
LLSTRING(TimestampFormatDescription2),
|
||||
LLSTRING(TimestampFormatDescription3),
|
||||
LLSTRING(TimestampFormatDescription4)
|
||||
LLSTRING(TimestampFormatDescription4),
|
||||
LLSTRING(TimestampFormatDescription5)
|
||||
] joinString endl;
|
||||
|
||||
[
|
||||
@ -56,8 +88,8 @@ private _formatDescription = [
|
||||
[LSTRING(timestampFormat), _formatDescription],
|
||||
[_categoryName, LLSTRING(Module_DisplayName)],
|
||||
[
|
||||
["HH", "HH:MM", "HH:MM:SS", "HH:MM:SS:MM"],
|
||||
["HH", "HH:MM", "HH:MM:SS", "HH:MM:SS:MM"],
|
||||
["HH", "HH:MM", "HH:MM:SS", "HH:MM:SS:MM", "HH:MM:SS.mmm"],
|
||||
["HH", "HH:MM", "HH:MM:SS", "HH:MM:SS:MM", "HH:MM:SS.mmm"],
|
||||
1
|
||||
]
|
||||
] call CBA_fnc_addSetting;
|
||||
|
@ -239,6 +239,105 @@
|
||||
<Korean>시계 필요함</Korean>
|
||||
<Portuguese>Relógio necessário</Portuguese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Markers_TimestampTimezone">
|
||||
<English>Time Zone</English>
|
||||
<Russian>Часовой пояс</Russian>
|
||||
<French>Fuseau horaire</French>
|
||||
<Japanese>時間帯</Japanese>
|
||||
<Spanish>Zona horaria</Spanish>
|
||||
<Polish>Strefa czasowa</Polish>
|
||||
<German>Zeitzone</German>
|
||||
<Chinesesimp>时区</Chinesesimp>
|
||||
<Korean>시간대</Korean>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Markers_TimestampTimezoneDescription">
|
||||
<English>Changes the time zone for the timestamp</English>
|
||||
<Russian>Измените часовой пояс для метки времени</Russian>
|
||||
<French>Modifiez le fuseau horaire pour l'horodatage</French>
|
||||
<Japanese>タイムスタンプの時間帯を変更します</Japanese>
|
||||
<Spanish>Cambie la zona horaria para la marca de tiempo</Spanish>
|
||||
<Polish>Zmień strefę czasową dla znaczników czasu</Polish>
|
||||
<German>Ändern Sie die Zeitzone für den Zeitstempel</German>
|
||||
<Chinesesimp>更改时间戳的时区</Chinesesimp>
|
||||
<Korean>타임스탬프의 시간대를 변경하십시오</Korean>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Markers_TimestampTimezoneIngameTime">
|
||||
<English>In-game Time</English>
|
||||
<Russian>Время в игре</Russian>
|
||||
<French>Heure de jeu</French>
|
||||
<Japanese>ゲーム内時刻</Japanese>
|
||||
<Spanish>Hora del juego</Spanish>
|
||||
<Polish>Czas gry</Polish>
|
||||
<German>Ingame-Zeit</German>
|
||||
<Chinesesimp>游戏内时间</Chinesesimp>
|
||||
<Korean>게임 시간</Korean>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Markers_TimestampTimezoneSystemTime">
|
||||
<English>System Time</English>
|
||||
<Russian>Системное время</Russian>
|
||||
<French>Heure système</French>
|
||||
<Japanese>システム時刻</Japanese>
|
||||
<Spanish>Hora del sistema</Spanish>
|
||||
<Polish>Czas systemowy</Polish>
|
||||
<German>Systemzeit</German>
|
||||
<Chinesesimp>系统时间</Chinesesimp>
|
||||
<Korean>시스템 시간</Korean>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Markers_TimestampTimezoneUTCTime">
|
||||
<English>UTC Time</English>
|
||||
<Russian>Время UTC</Russian>
|
||||
<French>Heure UTC</French>
|
||||
<Japanese>UTC時刻</Japanese>
|
||||
<Spanish>Hora UTC</Spanish>
|
||||
<Polish>Czas UTC</Polish>
|
||||
<German>UTC-Zeit</German>
|
||||
<Chinesesimp>UTC时间</Chinesesimp>
|
||||
<Korean>UTC 시간</Korean>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Markers_TimestampUTCOffset">
|
||||
<English>UTC Offset</English>
|
||||
<Russian>Смещение UTC</Russian>
|
||||
<French>Décalage UTC</French>
|
||||
<Japanese>UTCオフセット</Japanese>
|
||||
<Spanish>Desplazamiento UTC</Spanish>
|
||||
<Polish>Przesunięcie UTC</Polish>
|
||||
<German>UTC-Verschiebung</German>
|
||||
<Chinesesimp>UTC偏移量</Chinesesimp>
|
||||
<Korean>UTC 오프셋</Korean>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Markers_TimestampUTCOffsetDescription">
|
||||
<English>Changes the time offset for the UTC timestamp</English>
|
||||
<Russian>Измените смещение времени для метки времени UTC</Russian>
|
||||
<French>Modifier le décalage horaire pour l'horodatage UTC</French>
|
||||
<Japanese>UTCタイムスタンプの時差を変更する</Japanese>
|
||||
<Spanish>Cambiar el desplazamiento horario para la marca de tiempo UTC</Spanish>
|
||||
<Polish>Zmień przesunięcie czasu dla sygnatury czasowej UTC</Polish>
|
||||
<German>Ändere die Zeitverschiebung für den UTC-Zeitstempel</German>
|
||||
<Chinesesimp>更改UTC时间戳的时间偏移量</Chinesesimp>
|
||||
<Korean>UTC 타임 스탬프의 시간 오프셋을 변경하십시오</Korean>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Markers_TimestampUTCMinutesOffset">
|
||||
<English>UTC Minutes Offset</English>
|
||||
<Russian>UTC Минутное Смещение</Russian>
|
||||
<French>Décalage des minutes UTC</French>
|
||||
<Japanese>UTC分オフセット</Japanese>
|
||||
<Spanish>Desplazamiento de minutos UTC</Spanish>
|
||||
<Polish>Przesunięcie minut UTC</Polish>
|
||||
<German>UTC-Minutenversatz</German>
|
||||
<Chinesesimp>UTC分钟偏移量</Chinesesimp>
|
||||
<Korean>UTC 분 오프셋</Korean>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Markers_TimestampUTCMinutesOffsetDescription">
|
||||
<English>Change the minute offset for the UTC timestamp</English>
|
||||
<Russian>Изменить минутное смещение для времени UTC</Russian>
|
||||
<French>Modifier le décalage des minutes pour l'horodatage UTC</French>
|
||||
<Japanese>UTCタイムスタンプの分差を変更する</Japanese>
|
||||
<Spanish>Cambiar el desplazamiento de minutos para la marca de tiempo UTC</Spanish>
|
||||
<Polish>Zmień przesunięcie minut dla sygnatury czasowej UTC</Polish>
|
||||
<German>Ändere den Minutenversatz für den UTC-Zeitstempel</German>
|
||||
<Chinesesimp>更改UTC时间戳的分钟偏移量</Chinesesimp>
|
||||
<Korean>UTC 타임 스탬프의 분 오프셋을 변경하십시오</Korean>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Markers_TimestampFormat">
|
||||
<English>Timestamp Format</English>
|
||||
<Russian>Формат времени</Russian>
|
||||
@ -305,17 +404,16 @@
|
||||
<Portuguese>SS - Segundos</Portuguese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Markers_TimestampFormatDescription4">
|
||||
<English>"MM" - Milliseconds</English>
|
||||
<Russian>"МС" - Миллисекунда</Russian>
|
||||
<French>"MM" - Millisecondes</French>
|
||||
<Japanese>"MM" - ミリ秒</Japanese>
|
||||
<Spanish>"MM" - Milisegundos</Spanish>
|
||||
<Polish>"MM" - Milisekundy</Polish>
|
||||
<German>"MS" - Milisekunden</German>
|
||||
<Italian>"MS" - Millisecondi</Italian>
|
||||
<Chinesesimp>"MS"—毫秒</Chinesesimp>
|
||||
<Korean>"MS" - 밀리초</Korean>
|
||||
<Portuguese>MM - Milisegundos</Portuguese>
|
||||
<English>"MM" - Milliseconds (from 0 to 59)</English>
|
||||
<French>"MM" - Millisecondes (de 0 à 59)</French>
|
||||
<German>"MS" - Milisekunden (von 0 bis 59)</German>
|
||||
<Portuguese>"MS" - Milissegundos (de 0 a 59)</Portuguese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Markers_TimestampFormatDescription5">
|
||||
<English>"mmm" - Milliseconds (from 0 to 999)</English>
|
||||
<French>"mmm" - Millisecondes (de 0 à 999)</French>
|
||||
<German>"mmm" - Milisekunden (von 0 bis 999)</German>
|
||||
<Portuguese>"mmm" - Milissegundos (de 0 a 999)</Portuguese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Markers_TimestampHourFormat">
|
||||
<English>Timestamp Hour Format</English>
|
||||
|
21
addons/overheating/ACE_Arsenal_Stats.hpp
Normal file
21
addons/overheating/ACE_Arsenal_Stats.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
class EGVAR(arsenal,stats) {
|
||||
class statBase;
|
||||
class ACE_allowSwapBarrel: statBase {
|
||||
scope = 2;
|
||||
priority = -1;
|
||||
stats[] = {QGVAR(allowSwapBarrel)};
|
||||
displayName = CSTRING(statBarrelType);
|
||||
showText = 1;
|
||||
textStatement = QUOTE(call FUNC(statTextStatement_allowSwapBarrel));
|
||||
tabs[] = {{0,1}, {}};
|
||||
};
|
||||
class ACE_boltType: statBase {
|
||||
scope = 2;
|
||||
priority = -1.1;
|
||||
stats[] = {QGVAR(closedBolt)};
|
||||
displayName = CSTRING(statBoltType);
|
||||
showText = 1;
|
||||
textStatement = QUOTE(call FUNC(statTextStatement_boltType));
|
||||
tabs[] = {{0,1}, {}};
|
||||
};
|
||||
};
|
@ -25,6 +25,8 @@ PREP(overheat);
|
||||
PREP(sendSpareBarrelsTemperaturesHint);
|
||||
PREP(setAmmoTemperature);
|
||||
PREP(setWeaponTemperature);
|
||||
PREP(statTextStatement_boltType);
|
||||
PREP(statTextStatement_allowSwapBarrel);
|
||||
PREP(swapBarrel);
|
||||
PREP(swapBarrelAssistant);
|
||||
PREP(swapBarrelCallback);
|
||||
|
@ -26,6 +26,8 @@ class CfgPatches {
|
||||
|
||||
#include "ACE_Settings.hpp"
|
||||
|
||||
#include "ACE_Arsenal_Stats.hpp"
|
||||
|
||||
class CfgMovesBasic {
|
||||
class ManActions {
|
||||
GVAR(GestureMountMuzzle) = QGVAR(GestureMountMuzzle);
|
||||
|
@ -0,0 +1,21 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: drofseh
|
||||
* Barrel Type statement.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Not used
|
||||
* 1: Item config path <CONFIG>
|
||||
*
|
||||
* Return Value:
|
||||
* Stat Text <STRING>
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["", "_config"];
|
||||
TRACE_1("statTextStatement_allowSwapBarrel",_config);
|
||||
|
||||
if ((getNumber (_config >> QGVAR(allowSwapBarrel))) == 1) exitWith {LLSTRING(statBarrelType_removeable)};
|
||||
|
||||
LLSTRING(statBarrelType_nonRemoveable)
|
@ -0,0 +1,21 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: drofseh
|
||||
* Bolt Type statement.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Not used
|
||||
* 1: Item config path <CONFIG>
|
||||
*
|
||||
* Return Value:
|
||||
* Stat Text <STRING>
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["", "_config"];
|
||||
TRACE_1("statTextStatement_boltType",_config);
|
||||
|
||||
if ((getNumber (_config >> QGVAR(closedBolt))) == 1) exitWith {LLSTRING(statBoltType_closedBolt)};
|
||||
|
||||
LLSTRING(statBoltType_openBolt)
|
@ -875,5 +875,23 @@
|
||||
<Chinesesimp>备用枪管温度非常热</Chinesesimp>
|
||||
<Chinese>備用槍管溫度超級熱</Chinese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Overheating_statBoltType">
|
||||
<English>Bolt Type</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Overheating_statBoltType_openBolt">
|
||||
<English>Open Bolt</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Overheating_statBoltType_closedBolt">
|
||||
<English>Closed Bolt</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Overheating_statBarrelType">
|
||||
<English>Barrel Type</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Overheating_statBarrelType_nonRemoveable">
|
||||
<English>Non-Removeable</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Overheating_statBarrelType_removeable">
|
||||
<English>Quick Change</English>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
||||
|
@ -49,7 +49,8 @@ private _bulletSpeed = 0;
|
||||
private _gravity = [0, sin(_scopeBaseAngle) * -GRAVITY, cos(_scopeBaseAngle) * -GRAVITY];
|
||||
private _deltaT = 1 / _simSteps;
|
||||
private _speedOfSound = 0;
|
||||
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
|
||||
private _isABenabled = missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false];
|
||||
if (_isABenabled) then {
|
||||
_speedOfSound = _temperature call EFUNC(weather,calculateSpeedOfSound);
|
||||
};
|
||||
|
||||
@ -68,7 +69,7 @@ if (_useABConfig) then {
|
||||
};
|
||||
|
||||
private _airFrictionCoef = 1;
|
||||
if (!_useABConfig && (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) then {
|
||||
if (!_useABConfig && _isABenabled) then {
|
||||
private _airDensity = [_temperature, _barometricPressure, _relativeHumidity] call EFUNC(weather,calculateAirDensity);
|
||||
_airFrictionCoef = _airDensity / 1.22498;
|
||||
};
|
||||
|
@ -107,12 +107,17 @@ private _transonicStabilityCoef = _ammoConfig select 4;
|
||||
private _dragModel = _ammoConfig select 5;
|
||||
private _atmosphereModel = _ammoConfig select 8;
|
||||
|
||||
private _useABConfig = (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]);
|
||||
if (_bc == 0) then {
|
||||
_useABConfig = false;
|
||||
};
|
||||
private _isABenabled = (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) && (_bc != 0);
|
||||
private _useBarrelLengthInfluence = (
|
||||
_isABenabled &&
|
||||
{missionNamespace getVariable [QEGVAR(advanced_ballistics,barrelLengthInfluenceEnabled), false]}
|
||||
);
|
||||
private _useAmmoTemperatureInfluence = (
|
||||
_isABenabled &&
|
||||
{missionNamespace getVariable [QEGVAR(advanced_ballistics,ammoTemperatureEnabled), false]}
|
||||
);
|
||||
|
||||
if (_barrelLength > 0 && _useABConfig) then {
|
||||
if (_barrelLength > 0 && _useBarrelLengthInfluence) then {
|
||||
_muzzleVelocity = [_barrelLength, _ammoConfig select 10, _ammoConfig select 11, 0] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift);
|
||||
} else {
|
||||
private _initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "initSpeed");
|
||||
@ -128,7 +133,7 @@ if (_barrelLength > 0 && _useABConfig) 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) then {
|
||||
if (_useABConfig && _barrelTwist > 0) then {
|
||||
if (_useBarrelLengthInfluence && _barrelTwist > 0) then {
|
||||
ctrlSetText [770002, format["Barrel: %1'' 1:%2'' twist", round(2 * _barrelLength * 0.0393700787) / 2, round(_barrelTwist * 0.0393700787)]];
|
||||
} else {
|
||||
ctrlSetText [770002, format["Barrel: %1''", round(2 * _barrelLength * 0.0393700787) / 2]];
|
||||
@ -136,7 +141,7 @@ if (_barrelLength > 0) then {
|
||||
};
|
||||
|
||||
lnbAddRow [770100, ["4mps Wind(MRADs)", "1mps LEAD(MRADs)"]];
|
||||
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
|
||||
if (_isABenabled) 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"]];
|
||||
@ -145,7 +150,7 @@ if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) t
|
||||
|
||||
ctrlSetText [77003, format["%1m ZERO", round(_zeroRange)]];
|
||||
|
||||
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
|
||||
if (_isABenabled) then {
|
||||
ctrlSetText [770001, format["Drop Tables for B.P.: %1mb; Corrected for MVV at Air/Ammo Temperatures -15-35 °C", round(EGVAR(scopes,zeroReferenceBarometricPressure) * 100) / 100]];
|
||||
ctrlSetText [77004 , format["B.P.: %1mb", round(EGVAR(scopes,zeroReferenceBarometricPressure) * 100) / 100]];
|
||||
} else {
|
||||
@ -153,30 +158,30 @@ if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) t
|
||||
ctrlSetText [77004 , ""];
|
||||
};
|
||||
|
||||
private _cacheEntry = missionNamespace getVariable format[QGVAR(%1_%2_%3_%4_%5), _zeroRange, _boreHeight, _ammoClass, _weaponClass, missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]];
|
||||
if (isNil {_cacheEntry}) then {
|
||||
private _scopeBaseAngle = if (!_useABConfig) then {
|
||||
private _cacheEntry = missionNamespace getVariable format [QGVAR(%1_%2_%3_%4_%5_%6_%7), _zeroRange, _boreHeight, _ammoClass, _weaponClass, _isABenabled, _useBarrelLengthInfluence, _useAmmoTemperatureInfluence];
|
||||
if (isNil "_cacheEntry") then {
|
||||
private _scopeBaseAngle = if (!_isABenabled) then {
|
||||
private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight];
|
||||
(parseNumber _zeroAngle)
|
||||
} else {
|
||||
private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZeroAB:%1:%2:%3:%4:%5:%6:%7:%8:%9", _zeroRange, _muzzleVelocity, _boreHeight, EGVAR(scopes,zeroReferenceTemperature), EGVAR(scopes,zeroReferenceBarometricPressure), EGVAR(scopes,zeroReferenceHumidity), _bc, _dragModel, _atmosphereModel];
|
||||
(parseNumber _zeroAngle)
|
||||
};
|
||||
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] && missionNamespace getVariable [QEGVAR(advanced_ballistics,ammoTemperatureEnabled), false]) then {
|
||||
if (_useAmmoTemperatureInfluence) then {
|
||||
{
|
||||
private _mvShift = [_ammoConfig select 9, _x] call EFUNC(advanced_ballistics,calculateAmmoTemperatureVelocityShift);
|
||||
private _mv = _muzzleVelocity + _mvShift;
|
||||
|
||||
[_scopeBaseAngle,_boreHeight,_airFriction,_mv,_x,EGVAR(scopes,zeroReferenceBarometricPressure),EGVAR(scopes,zeroReferenceHumidity),200,4,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,_transonicStabilityCoef,_forEachIndex,_useABConfig] call FUNC(calculateRangeCard);
|
||||
[_scopeBaseAngle,_boreHeight,_airFriction,_mv,_x,EGVAR(scopes,zeroReferenceBarometricPressure),EGVAR(scopes,zeroReferenceHumidity),200,4,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,_transonicStabilityCoef,_forEachIndex,_isABenabled] call FUNC(calculateRangeCard);
|
||||
} forEach [-15, -5, 5, 10, 15, 20, 25, 30, 35];
|
||||
} else {
|
||||
[_scopeBaseAngle,_boreHeight,_airFriction,_muzzleVelocity,15,EGVAR(scopes,zeroReferenceBarometricPressure),EGVAR(scopes,zeroReferenceHumidity),200,4,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,_transonicStabilityCoef,3,_useABConfig] call FUNC(calculateRangeCard);
|
||||
[_scopeBaseAngle,_boreHeight,_airFriction,_muzzleVelocity,15,EGVAR(scopes,zeroReferenceBarometricPressure),EGVAR(scopes,zeroReferenceHumidity),200,4,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,_transonicStabilityCoef,3,_isABenabled] call FUNC(calculateRangeCard);
|
||||
};
|
||||
|
||||
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 {
|
||||
if (_isABenabled) then {
|
||||
(GVAR(rangeCardDataElevation) select _i) pushBack "###";
|
||||
(GVAR(rangeCardDataWindage) select _i) pushBack "##";
|
||||
(GVAR(rangeCardDataLead) select _i) pushBack "##";
|
||||
@ -188,7 +193,7 @@ if (isNil {_cacheEntry}) then {
|
||||
};
|
||||
};
|
||||
|
||||
missionNamespace setVariable [format[QGVAR(%1_%2_%3_%4_%5), _zeroRange, _boreHeight, _ammoClass, _weaponClass, missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]], [GVAR(rangeCardDataElevation), GVAR(rangeCardDataWindage), GVAR(rangeCardDataLead), GVAR(rangeCardDataMVs), GVAR(lastValidRow)]];
|
||||
missionNamespace setVariable [format [QGVAR(%1_%2_%3_%4_%5_%6_%7), _zeroRange, _boreHeight, _ammoClass, _weaponClass, _isABenabled, _useBarrelLengthInfluence, _useAmmoTemperatureInfluence], [GVAR(rangeCardDataElevation), GVAR(rangeCardDataWindage), GVAR(rangeCardDataLead), GVAR(rangeCardDataMVs), GVAR(lastValidRow)]];
|
||||
} else {
|
||||
GVAR(rangeCardDataElevation) = _cacheEntry select 0;
|
||||
GVAR(rangeCardDataWindage) = _cacheEntry select 1;
|
||||
|
@ -24,7 +24,6 @@ private _key = format ["weaponInfoCache-%1-%2-%3",_weaponClass,_magazineClass,_a
|
||||
private _weaponInfo = GVAR(data) getOrDefault [_key, []];
|
||||
if ((_weaponInfo isEqualTo []) && {_magazineClass != ""}) then {
|
||||
TRACE_3("new weapon/mag",_weaponClass,_magazineClass,_ammoClass);
|
||||
private _useABConfig = (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]);
|
||||
|
||||
private _zeroRange = 100;
|
||||
private _boreHeight = [_unit, 0] call EFUNC(scopes,getBoreHeight);
|
||||
@ -35,8 +34,14 @@ if ((_weaponInfo isEqualTo []) && {_magazineClass != ""}) then {
|
||||
_weaponConfig params ["_barrelTwist", "_twistDirection", "_barrelLength"];
|
||||
private _bc = if (_ballisticCoefficients isEqualTo []) then { 0 } else { _ballisticCoefficients # 0 };
|
||||
|
||||
private _useAB = (
|
||||
missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] &&
|
||||
{missionNamespace getVariable [QEGVAR(advanced_ballistics,barrelLengthInfluenceEnabled), false]} &&
|
||||
{_bc != 0}
|
||||
);
|
||||
|
||||
// Get Muzzle Velocity
|
||||
private _muzzleVelocity = if (_barrelLength > 0 && _useABConfig && {_bc != 0}) then {
|
||||
private _muzzleVelocity = if (_barrelLength > 0 && _useAB) then {
|
||||
[_barrelLength, _muzzleVelocityTable, _barrelLengthTable, 0] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift)
|
||||
} else {
|
||||
private _initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "initSpeed");
|
||||
|
@ -21,7 +21,10 @@ This adds the possibility to draw accurate lines on the map screen.
|
||||
### 1.2 Map tools
|
||||
This adds map tools that can be used to measure distances between two points or bearings on the map.
|
||||
|
||||
### 1.3 GPS on map
|
||||
### 1.3 Plotting Board
|
||||
This adds a plotting board that can be used to aid in the rapid usage and adjustment of short-ranged indirect fires, as well as quick measurements of directions and distances between points, and general land-navigation.
|
||||
|
||||
### 1.4 GPS on map
|
||||
If you are equipped with a vanilla GPS it will be shown on the map. (You don't need the `Map Tools` item in your inventory for this.)
|
||||
|
||||
## 2. Usage
|
||||
@ -39,3 +42,15 @@ If you are equipped with a vanilla GPS it will be shown on the map. (You don't n
|
||||
- Press <kbd>ALT</kbd> + <kbd>LMB</kbd> to start the line, left click again to end it.
|
||||
- To delete a line press <kbd>Del</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).
|
||||
|
||||
### 2.3 Using the plotting board
|
||||
- To use map tools the `Plotting Board` item is required.
|
||||
- Open the map <kbd>M</kbd> (Arma 3 default key bind `Map`).
|
||||
- Press the self interaction key <kbd>Ctrl</kbd> + <kbd>⊞ Win</kbd> (ACE3 default key bind `Self Interaction Key`).
|
||||
- Select `Show Plotting Board`.
|
||||
- Note that you can drag the Plotting Board around with <kbd>LMB</kbd> and rotate the different parts of the Plotting Board, each independently from each other, with <kbd>Ctrl</kbd> + <kbd>LMB</kbd>.
|
||||
|
||||
### 2.4 Drawing lines
|
||||
- You can draw lines on the plotting board.
|
||||
- These lines are removed from the map once the plotting board is hidden, but they restored when the plotting board is shown again.
|
||||
- These lines are moved along with the plotting board when the plotting board is dragged.
|
||||
|
Loading…
Reference in New Issue
Block a user