mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Merge branch 'master' into network_lasers
This commit is contained in:
commit
e4c459132b
@ -40,6 +40,7 @@ Falke75
|
||||
Ferenczi
|
||||
Ferenzi
|
||||
Filip Basara <filip.basara93@googlemail.com> (Logo)
|
||||
FreeZbe <freeseb@gmail.com>
|
||||
geraldbolso1899
|
||||
Ghost
|
||||
gienkov
|
||||
@ -66,3 +67,4 @@ Sniperwolf572 <tenga6@gmail.com>
|
||||
Tonic
|
||||
Tourorist <tourorist@gmail.com>
|
||||
Valentin Torikian <valentin.torikian@gmail.com>
|
||||
zGuba
|
||||
|
@ -39,6 +39,7 @@ PREP(displayText);
|
||||
PREP(displayTextPicture);
|
||||
PREP(displayTextStructured);
|
||||
PREP(doAnimation);
|
||||
PREP(dropBackpack);
|
||||
PREP(endRadioTransmission);
|
||||
PREP(eraseCache);
|
||||
PREP(execNextFrame);
|
||||
@ -181,6 +182,9 @@ PREP(waitAndExecute);
|
||||
PREP(translateToWeaponSpace);
|
||||
PREP(translateToModelSpace);
|
||||
|
||||
// Model and drawing helpers
|
||||
PREP(worldToScreenBounds);
|
||||
|
||||
// config items
|
||||
PREP(getConfigType);
|
||||
PREP(getItemType);
|
||||
|
34
addons/common/functions/fnc_dropBackpack.sqf
Normal file
34
addons/common/functions/fnc_dropBackpack.sqf
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Author: commy2
|
||||
*
|
||||
* Drops a backback. Also returns the ground wepaon holder object of the dropped backpack.
|
||||
*
|
||||
* Argument:
|
||||
* 0: Unit that has a backpack (Object)
|
||||
*
|
||||
* Return value:
|
||||
* Ground wepaon holder with backpack (Object)
|
||||
*
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private "_unit";
|
||||
|
||||
_unit = _this select 0;
|
||||
|
||||
private "_backpackObject";
|
||||
_backpackObject = backpackContainer _unit;
|
||||
|
||||
_unit addBackpack "Bag_Base";
|
||||
removeBackpack _unit;
|
||||
|
||||
private "_holder";
|
||||
_holder = objNull;
|
||||
|
||||
{
|
||||
if (_backpackObject in everyBackpack _x) exitWith {
|
||||
_holder = _x;
|
||||
};
|
||||
} forEach (position _unit nearObjects ["WeaponHolder", 5]);
|
||||
|
||||
_holder
|
@ -14,10 +14,10 @@
|
||||
|
||||
// ACRE
|
||||
if (isClass (configFile >> "CfgPatches" >> "acre_main")) then {
|
||||
[-1] call acre_core_fnc_handleMultiPttKeyPressUp;
|
||||
[0] call acre_core_fnc_handleMultiPttKeyPressUp;
|
||||
[1] call acre_core_fnc_handleMultiPttKeyPressUp;
|
||||
[2] call acre_core_fnc_handleMultiPttKeyPressUp;
|
||||
[-1] call acre_sys_core_fnc_handleMultiPttKeyPressUp;
|
||||
[0] call acre_sys_core_fnc_handleMultiPttKeyPressUp;
|
||||
[1] call acre_sys_core_fnc_handleMultiPttKeyPressUp;
|
||||
[2] call acre_sys_core_fnc_handleMultiPttKeyPressUp;
|
||||
};
|
||||
|
||||
// TFAR
|
||||
|
@ -27,7 +27,7 @@ if (_setVolume) then {
|
||||
player setVariable ["tf_unable_to_use_radio", false];
|
||||
|
||||
// ACRE2
|
||||
player setVariable ["acre_sys_core_globalVolume", NORMAL_LEVEL];
|
||||
[NORMAL_LEVEL] call acre_api_fnc_setGlobalVolume;
|
||||
player setVariable ["acre_sys_core_isDisabled", false, true];
|
||||
|
||||
} else {
|
||||
@ -40,7 +40,7 @@ if (_setVolume) then {
|
||||
player setVariable ["tf_unable_to_use_radio", true];
|
||||
|
||||
// ACRE2
|
||||
player setVariable ["acre_sys_core_globalVolume", MUTED_LEVEL];
|
||||
[MUTED_LEVEL] call acre_api_fnc_setGlobalVolume;
|
||||
player setVariable ["acre_sys_core_isDisabled", true, true];
|
||||
|
||||
};
|
||||
|
52
addons/common/functions/fnc_worldToScreenBounds.sqf
Normal file
52
addons/common/functions/fnc_worldToScreenBounds.sqf
Normal file
@ -0,0 +1,52 @@
|
||||
// (c) zGuba 2011
|
||||
// Function helper for framing objects on screen.
|
||||
// Input: [_object,_margins3D,_offset3D] (object, 3 * float array, 3 * float array)
|
||||
// Output: [_minX,_minY,_minY,_maxY] (4 * float)
|
||||
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_minX","_minY","_maxX","_maxY"];
|
||||
|
||||
PARAMS_3(_object,_margins,_offsets);
|
||||
|
||||
_minX = 10;
|
||||
_minY = 10;
|
||||
_maxX = -10;
|
||||
_maxY = -10;
|
||||
|
||||
if (true) then {
|
||||
_bounds = boundingBox _object;
|
||||
|
||||
_boundsMin = _bounds select 0;
|
||||
_boundsMinX = (_boundsMin select 0) - (_margins select 0) + (_offsets select 0);
|
||||
_boundsMinY = (_boundsMin select 1) - (_margins select 1) + (_offsets select 1);
|
||||
_boundsMinZ = (_boundsMin select 2) - (_margins select 2) + (_offsets select 2);
|
||||
_boundsMax = _bounds select 1;
|
||||
_boundsMaxX = (_boundsMax select 0) + (_margins select 0) + (_offsets select 0);
|
||||
_boundsMaxY = (_boundsMax select 1) + (_margins select 1) + (_offsets select 1);
|
||||
_boundsMaxZ = (_boundsMax select 2) + (_margins select 2) + (_offsets select 2);
|
||||
|
||||
_boundsCorners = [
|
||||
[_boundsMinX,_boundsMinY,_boundsMinZ],
|
||||
[_boundsMinX,_boundsMinY,_boundsMaxZ],
|
||||
[_boundsMinX,_boundsMaxY,_boundsMinZ],
|
||||
[_boundsMinX,_boundsMaxY,_boundsMaxZ],
|
||||
[_boundsMaxX,_boundsMinY,_boundsMinZ],
|
||||
[_boundsMaxX,_boundsMinY,_boundsMaxZ],
|
||||
[_boundsMaxX,_boundsMaxY,_boundsMinZ],
|
||||
[_boundsMaxX,_boundsMaxY,_boundsMaxZ]
|
||||
];
|
||||
|
||||
|
||||
{
|
||||
_ppos = worldToScreen (_object modelToWorld _x);
|
||||
_pposX = _ppos select 0;
|
||||
_pposY = _ppos select 1;
|
||||
if (_pposX < _minX) then {_minX = _pposX};
|
||||
if (_pposX > _maxX) then {_maxX = _pposX};
|
||||
if (_pposY < _minY) then {_minY = _pposY};
|
||||
if (_pposY > _maxY) then {_maxY = _pposY};
|
||||
} forEach _boundsCorners;
|
||||
};
|
||||
|
||||
[_minX,_minY,_maxX,_maxY]
|
@ -276,6 +276,7 @@
|
||||
<French>Désactiver Menu Commande</French>
|
||||
<Russian>Выключить командное меню</Russian>
|
||||
<Hungarian>Parancsnoki menü kikapcsolása</Hungarian>
|
||||
<Italian>Disabilita Menù di comando</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Common_Unknown">
|
||||
<English>Unknown</English>
|
||||
@ -285,6 +286,7 @@
|
||||
<Czech>Neznámý</Czech>
|
||||
<Russian>Неизвестно</Russian>
|
||||
<Hungarian>Ismeretlen</Hungarian>
|
||||
<Italian>Sconosciuto</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Common_NoVoice">
|
||||
<English>No Voice</English>
|
||||
@ -294,80 +296,95 @@
|
||||
<Czech>Žádný hlas</Czech>
|
||||
<Russian>Без голоса</Russian>
|
||||
<Hungarian>Nincs hang</Hungarian>
|
||||
<Italian>Senza voce</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_ACTION_ACCEPT_REQUEST_KEY_TITLE">
|
||||
<English>Accept Requests</English>
|
||||
<German>Anfrage annehmen</German>
|
||||
<Spanish>Aceptar peticiones</Spanish>
|
||||
<Polish>Akceptuj prośby</Polish>
|
||||
<Italian>Accetta Richieste</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_ACTION_DECLINE_REQUEST_KEY_TITLE">
|
||||
<English>Decline Requests</English>
|
||||
<German>Anfrage ablehnen</German>
|
||||
<Spanish>Rechazar peticiones</Spanish>
|
||||
<Polish>Ignoruj prośby</Polish>
|
||||
<Italian>Rifiuta Richieste</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_ACTION_ACCEPT_REQUEST_KEY_TOOLTIP">
|
||||
<English>Accept Requests send by other players. These can be requests to use / share equipment, perform certain actions.</English>
|
||||
<German>Anfragen anderer Spieler annehmen. Diese Anfragen können sich auf das Benutzen / Teilen von Equipment beziehen oder das Ausführen bestimmter Aktionen.</German>
|
||||
<Spanish>Acepta peticiones de otros jugadores. Pueden ser solicitudes para usar / compartir equipamiento, realizar ciertas acciones.</Spanish>
|
||||
<Polish>Akceptuj prośby wysłane przez innych graczy. Akceptacji wymagają między innymi akcje używania / współdzielenia wyposażenia, wykonywania określonych czynności.</Polish>
|
||||
<Italian>Accetta le richieste degli altri giocatori. Queste possono riguardare l'uso o la condivisione dell'equipaggiamento, o di determinate azioni.</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_ACTION_DECLINE_REQUEST_KEY_TOOLTIP">
|
||||
<English>Decline Requests send by other players. These can be requests to use / share equipment, perform certain actions.</English>
|
||||
<German>Anfragen anderer Spieler ablehnen. Diese Anfragen können sich auf das Benutzen / Teilen von Equipment beziehen oder das Ausführen bestimmter Aktionen.</German>
|
||||
<Spanish>Rechazar peticiones de otros jugadores. Pueden ser solicitudes para usar / compartir equipamiento, realizar ciertas acciones.</Spanish>
|
||||
<Polish>Ignoruj prośby wysłane przez innych graczy. Akceptacji wymagają między innymi akcje używania / współdzielenia wyposażenia, wykonywania określonych czynności.</Polish>
|
||||
<Italian>Rifiuta le richieste degli altri giocatori. Queste possono riguardare l'uso o la condivisione dell'equipaggiamento, o di determinate azioni.</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Common_SettingFeedbackIconsName">
|
||||
<English>Feedback icons</English>
|
||||
<German>Feedback-Icons</German>
|
||||
<Spanish>Iconos de respuesta</Spanish>
|
||||
<Italian>Icone informative</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Common_SettingFeedbackIconsDesc">
|
||||
<English>Select the position of or disable the feedback icons on your screen. These icons will show to provide extra feedback on your character status and actions performed.</English>
|
||||
<German>Wähle die Position der Feedback-Icons aus oder deaktiviere Sie. Die Feedback-Icons zeigen den Status deiner Einheit an, oder die ausgeführte Aktion.</German>
|
||||
<Spanish>Seleccionar la posición de o desactivar los íconos de respuesta en la pantalla. Estos iconos se mostrarán para proporcionar información adicional sobre el estado de su personaje y las acciones a realizar.</Spanish>
|
||||
<Italian>Seleziona la posizione o disabilita le icone informative sul tuo schermo. Queste saranno mostrate per fornire informazioni aggiuntive sullo stato o sulle azioni del giocatore.</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Common_SettingProgressbarLocationName">
|
||||
<English>Progress bar location</English>
|
||||
<German>Position des Fortschrittsanzeige</German>
|
||||
<Spanish>Ubicación de la barra de progreso</Spanish>
|
||||
<Italian>Posizione della barra di avanzamento</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Common_SettingProgressbarLocationDesc">
|
||||
<English>Set the desired location of the progress bar on your screen.</English>
|
||||
<German>Wähle die Position der Fortschrittsanzeige.</German>
|
||||
<Spanish>Seleccionar la ubicación deseada de la barra de progreso en tu pantalla</Spanish>
|
||||
<Italian>Modifica la posizione su schermo della barra di avanzamento.</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Common_SettingDisplayTextColorName">
|
||||
<English>Hint Background color</English>
|
||||
<German>Hinweis Hintergrundfarbe</German>
|
||||
<Spanish>Color de fondo de las notificaciones</Spanish>
|
||||
<Italian>Sfondo dei Suggerimenti</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Common_SettingDisplayTextColorDesc">
|
||||
<English>The color of the background from the ACE hints.</English>
|
||||
<German>Wähle die Hintergrundfarbe für ACE-Hinweise.</German>
|
||||
<Spanish>El color de fondo de las notificaciones del ACE</Spanish>
|
||||
<Italian>Il colore di sfondo dei suggerimenti dell'ACE.</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Common_SettingDisplayTextFontColorName">
|
||||
<English>Hint text font color</English>
|
||||
<German>Hinweis Textfarbe</German>
|
||||
<Spanish>Color del texto de las notificaciones</Spanish>
|
||||
<Italian>Testo dei Suggerimenti</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Common_SettingDisplayTextFontColorDesc">
|
||||
<English>The color of the text font from the ACE hints. This color is the default color for all text displayed through the ACE Hint system, if the hint text has no other color specified.</English>
|
||||
<German>Wähle die Textfarbe für ACE-Hinweise. </German>
|
||||
<Spanish>El color del texto de las notificaciones del ACE. Este es el color predeterminado para todo el texto que se muestra a través del sistema de notificaciones del ACE, si el texto de notificación no tiene otro color especificado.</Spanish>
|
||||
<Italian>Il colore del testo dei suggerimenti dell'ACE. Questo è il colore standard per tutti i caratteri mostrati dal sistema di suggerimenti dell'ACE, se questo non è altrimenti specificato.</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Common_bananaDisplayName">
|
||||
<English>Banana</English>
|
||||
<German>Banane</German>
|
||||
<Spanish>Banana</Spanish>
|
||||
<Italian>Banana</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Common_bananaDescr">
|
||||
<English>A banana is an edible fruit, botanically a berry, produced by several kinds of large herbaceous flowering plants in the genus Musa.</English>
|
||||
<German>Die Bananen (Musa) sind eine Pflanzengattung in der Familie der Bananengewächse (Musaceae) innerhalb der Einkeimblättrigen Pflanzen (Monokotyledonen).</German>
|
||||
<Spanish>Una banana es una fruta comestible, botanicamente una baya, producida por varios tipos de grandes plantas herbáceas del género Musa.</Spanish>
|
||||
<Italian>Una banana è un frutto commestibile, nello specifico una bacca cuoiosa, prodotto da un gran numero di grandi pianti erbacee dotate di fiori, della famiglia delle Musaceae.</Italian>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
||||
|
1
addons/disarming/$PBOPREFIX$
Normal file
1
addons/disarming/$PBOPREFIX$
Normal file
@ -0,0 +1 @@
|
||||
z\ace\addons\disarming
|
11
addons/disarming/CfgEventHandlers.hpp
Normal file
11
addons/disarming/CfgEventHandlers.hpp
Normal 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));
|
||||
};
|
||||
};
|
17
addons/disarming/CfgVehicles.hpp
Normal file
17
addons/disarming/CfgVehicles.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
class CfgVehicles {
|
||||
class Man;
|
||||
class CAManBase: Man {
|
||||
class ACE_Actions {
|
||||
class ACE_MainActions {
|
||||
class ACE_DisarmInventory {
|
||||
displayName = "$STR_ACE_Disarming_OpenInventory";
|
||||
distance = 3.5;
|
||||
condition = QUOTE([ARR_2(_player,_target)] call FUNC(canPlayerDisarmUnit));
|
||||
statement = QUOTE([ARR_2(_player,_target)] call FUNC(openDisarmDialog));
|
||||
icon = "\a3\Modules_F_Curator\Data\portraitRespawnInventory_ca.paa";
|
||||
exceptions[] = {};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
14
addons/disarming/CfgWeapons.hpp
Normal file
14
addons/disarming/CfgWeapons.hpp
Normal file
@ -0,0 +1,14 @@
|
||||
class CfgWeapons {
|
||||
class ACE_ItemCore;
|
||||
class InventoryItem_Base_F;
|
||||
|
||||
class ACE_DebugPotato: ACE_ItemCore {
|
||||
displayName = "ACE Potato (debug)";
|
||||
descriptionShort = "Glorious Potato<br/>If you see this in game it means someone fucked up";
|
||||
picture = QUOTE(PATHTOF(UI\potato_ca.paa));
|
||||
scope = 1;
|
||||
class ItemInfo: InventoryItem_Base_F {
|
||||
mass = 1;
|
||||
};
|
||||
};
|
||||
};
|
11
addons/disarming/README.md
Normal file
11
addons/disarming/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
ace_disarming
|
||||
============
|
||||
|
||||
Adds ability to make units drop items/weapons/magazines.
|
||||
|
||||
|
||||
## Maintainers
|
||||
|
||||
The people responsible for merging changes to this component or answering potential questions.
|
||||
|
||||
- [PabstMirror](https://github.com/PabstMirror)
|
BIN
addons/disarming/UI/potato_ca.paa
Normal file
BIN
addons/disarming/UI/potato_ca.paa
Normal file
Binary file not shown.
4
addons/disarming/XEH_postInit.sqf
Normal file
4
addons/disarming/XEH_postInit.sqf
Normal file
@ -0,0 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
["DisarmDropItems", {_this call FUNC(eventTargetStart)}] call EFUNC(common,addEventHandler);
|
||||
["DisarmDebugCallback", {_this call FUNC(eventCallerFinish)}] call EFUNC(common,addEventHandler);
|
17
addons/disarming/XEH_preInit.sqf
Normal file
17
addons/disarming/XEH_preInit.sqf
Normal file
@ -0,0 +1,17 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
ADDON = false;
|
||||
|
||||
PREP(canBeDisarmed);
|
||||
PREP(canPlayerDisarmUnit);
|
||||
PREP(disarmDropItems);
|
||||
PREP(eventCallerFinish);
|
||||
PREP(eventTargetFinish);
|
||||
PREP(eventTargetStart);
|
||||
PREP(getAllGearContainer);
|
||||
PREP(getAllGearUnit);
|
||||
PREP(openDisarmDialog);
|
||||
PREP(showItemsInListbox);
|
||||
PREP(verifyMagazinesMoved);
|
||||
|
||||
ADDON = true;
|
19
addons/disarming/config.cpp
Normal file
19
addons/disarming/config.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
class CfgPatches {
|
||||
class ADDON {
|
||||
units[] = {};
|
||||
weapons[] = {"ACE_DebugPotato"};
|
||||
requiredVersion = REQUIRED_VERSION;
|
||||
requiredAddons[] = {"ACE_Interaction"};
|
||||
author[] = {"PabstMirror"};
|
||||
authorUrl = "https://github.com/PabstMirror/";
|
||||
VERSION_CONFIG;
|
||||
};
|
||||
};
|
||||
|
||||
#include "CfgEventHandlers.hpp"
|
||||
#include "CfgVehicles.hpp"
|
||||
#include "CfgWeapons.hpp"
|
||||
|
||||
#include "gui_disarm.hpp"
|
34
addons/disarming/functions/fnc_canBeDisarmed.sqf
Normal file
34
addons/disarming/functions/fnc_canBeDisarmed.sqf
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Checks the conditions for being able to disarm a unit
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Target <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Can Be Disarmed <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [cursorTarget] call ace_disarming_fnc_canBeDisarmed
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
PARAMS_1(_target);
|
||||
|
||||
//Check animationState for putDown anim
|
||||
//This ensures the unit doesn't have to actualy do any animation to drop something
|
||||
//This should always be true for the 3 possible status effects that allow disarming
|
||||
_animationStateCfgMoves = getText (configFile >> "CfgMovesMaleSdr" >> "States" >> (animationState _target) >> "actions");
|
||||
if (_animationStateCfgMoves == "") exitWith {false};
|
||||
_putDownAnim = getText (configFile >> "CfgMovesBasic" >> "Actions" >> _animationStateCfgMoves >> "PutDown");
|
||||
if (_putDownAnim != "") exitWith {false};
|
||||
|
||||
|
||||
(alive _target) &&
|
||||
{(abs (speed _target)) < 1} &&
|
||||
{(vehicle _target) == _target} &&
|
||||
{(_target getVariable ["ACE_isUnconscious", false]) ||
|
||||
{_target getVariable [QEGVAR(captives,isHandcuffed), false]} ||
|
||||
{_target getVariable [QEGVAR(captives,isSurrendering), false]}}
|
22
addons/disarming/functions/fnc_canPlayerDisarmUnit.sqf
Normal file
22
addons/disarming/functions/fnc_canPlayerDisarmUnit.sqf
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Checks the conditions for being able to disarm a unit
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Player <OBJECT>
|
||||
* 1: Target <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Can Be Disarm Target <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [player, cursorTarget] call ace_disarming_fnc_canPlayerDisarmUnit
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
PARAMS_2(_player,_target);
|
||||
|
||||
([_target] call FUNC(canBeDisarmed)) &&
|
||||
{([_player, _target, []] call EFUNC(common,canInteractWith))}
|
252
addons/disarming/functions/fnc_disarmDropItems.sqf
Normal file
252
addons/disarming/functions/fnc_disarmDropItems.sqf
Normal file
@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Makes a unit drop items
|
||||
*
|
||||
* Arguments:
|
||||
* 0: caller (player) <OBJECT>
|
||||
* 1: target <OBJECT>
|
||||
* 2: classnamess <ARRAY>
|
||||
* 3: Do Not Drop Ammo <BOOL><OPTIONAL>
|
||||
*
|
||||
* Return Value:
|
||||
* Nothing
|
||||
*
|
||||
* Example:
|
||||
* [player, cursorTarget, ["ace_bandage"]] call ace_disarming_fnc_disarmDropItems
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
#define TIME_MAX_WAIT 5
|
||||
|
||||
PARAMS_3(_caller,_target,_listOfItemsToRemove);
|
||||
DEFAULT_PARAM(3,_doNotDropAmmo,false); //By default units drop all weapon mags when dropping a weapon
|
||||
|
||||
_fncSumArray = {
|
||||
_return = 0;
|
||||
{_return = _return + _x;} forEach (_this select 0);
|
||||
_return
|
||||
};
|
||||
|
||||
//Sanity Checks
|
||||
if (!([_target] call FUNC(canBeDisarmed))) exitWith {
|
||||
[_caller, _target, "Debug: Cannot disarm target"] call FUNC(eventTargetFinish);
|
||||
};
|
||||
if (_doNotDropAmmo && {({_x in _listOfItemsToRemove} count (magazines _target)) > 0}) exitWith {
|
||||
[_caller, _target, "Debug: Trying to drop magazine with _doNotDropAmmo flag"] call FUNC(eventTargetFinish);
|
||||
};
|
||||
|
||||
_holder = objNull;
|
||||
|
||||
//If not dropping ammo, don't use an existing container
|
||||
if (!_doNotDropAmmo) then {
|
||||
{
|
||||
if ((_x getVariable [QGVAR(disarmUnit), objNull]) == _target) exitWith {
|
||||
_holder = _x;
|
||||
};
|
||||
} forEach ((getpos _target) nearObjects [DISARM_CONTAINER, 3]);
|
||||
};
|
||||
|
||||
//Create a new weapon holder
|
||||
if (isNull _holder) then {
|
||||
_dropPos = _target modelToWorld [0.4, 0.75, 0]; //offset someone unconscious isn't lying over it
|
||||
_dropPos set [2, ((getPosASL _target) select 2)];
|
||||
_holder = createVehicle [DISARM_CONTAINER, _dropPos, [], 0, "CAN_COLLIDE"];
|
||||
_holder setPosASL _dropPos;
|
||||
_holder setVariable [QGVAR(disarmUnit), _target, true];
|
||||
};
|
||||
|
||||
//Verify holder created
|
||||
if (isNull _holder) exitWith {
|
||||
[_caller, _target, "Debug: Null Holder"] call FUNC(eventTargetFinish);
|
||||
};
|
||||
//Make sure only one drop operation at a time (using PFEH system as a queue)
|
||||
if (_holder getVariable [QGVAR(holderInUse), false]) exitWith {
|
||||
[{
|
||||
_this call FUNC(disarmDropItems);
|
||||
}, _this, 0, 0] call EFUNC(common,waitAndExecute);
|
||||
};
|
||||
_holder setVariable [QGVAR(holderInUse), true];
|
||||
|
||||
|
||||
//Remove Magazines
|
||||
_targetMagazinesStart = magazinesAmmo _target;
|
||||
_holderMagazinesStart = magazinesAmmoCargo _holder;
|
||||
|
||||
{
|
||||
EXPLODE_2_PVT(_x,_xClassname,_xAmmo);
|
||||
if ((_xClassname in _listOfItemsToRemove) && {!(_xClassname in UNIQUE_MAGAZINES)}) then {
|
||||
_holder addMagazineAmmoCargo [_xClassname, 1, _xAmmo];
|
||||
_target removeMagazine _xClassname;
|
||||
};
|
||||
} forEach _targetMagazinesStart;
|
||||
|
||||
_targetMagazinesEnd = magazinesAmmo _target;
|
||||
_holderMagazinesEnd = magazinesAmmoCargo _holder;
|
||||
|
||||
//Verify Mags dropped from unit:
|
||||
if ( ({((_x select 0) in _listOfItemsToRemove) && {!((_x select 0) in UNIQUE_MAGAZINES)}} count _targetMagazinesEnd) != 0) exitWith {
|
||||
_holder setVariable [QGVAR(holderInUse), false];
|
||||
[_caller, _target, "Debug: Didn't Remove Magazines"] call FUNC(eventTargetFinish);
|
||||
};
|
||||
//Verify holder has mags unit had
|
||||
if (!([_targetMagazinesStart, _targetMagazinesEnd, _holderMagazinesStart, _holderMagazinesEnd] call FUNC(verifyMagazinesMoved))) then {
|
||||
ERR = [_targetMagazinesStart, _targetMagazinesEnd, _holderMagazinesStart, _holderMagazinesEnd];
|
||||
_holder setVariable [QGVAR(holderInUse), false];
|
||||
[_caller, _target, "Debug: Crate Magazines not in holder"] call FUNC(eventTargetFinish);
|
||||
};
|
||||
|
||||
//Remove Items, Assigned Items and NVG
|
||||
_holderItemsStart = getitemCargo _holder;
|
||||
_targetItemsStart = (assignedItems _target) + (items _target);
|
||||
if ((headgear _target) != "") then {_targetItemsStart pushBack (headgear _target);};
|
||||
if ((goggles _target) != "") then {_targetItemsStart pushBack (goggles _target);};
|
||||
|
||||
|
||||
_addToCrateClassnames = [];
|
||||
_addToCrateCount = [];
|
||||
{
|
||||
if (_x in _listOfItemsToRemove) then {
|
||||
if (_x in (items _target)) then {
|
||||
_target removeItem _x;
|
||||
} else {
|
||||
_target unlinkItem _x;
|
||||
};
|
||||
_index = _addToCrateClassnames find _x;
|
||||
if (_index != -1) then {
|
||||
_addToCrateCount set [_index, ((_addToCrateCount select _index) + 1)];
|
||||
} else {
|
||||
_addToCrateClassnames pushBack _x;
|
||||
_addToCrateCount pushBack 1;
|
||||
};
|
||||
};
|
||||
} forEach _targetItemsStart;
|
||||
|
||||
//Add the items to the holder (combined to reduce addItemCargoGlobal calls)
|
||||
{
|
||||
_holder addItemCargoGlobal [(_addToCrateClassnames select _forEachIndex), (_addToCrateCount select _forEachIndex)];
|
||||
} forEach _addToCrateClassnames;
|
||||
|
||||
_holderItemsEnd = getitemCargo _holder;
|
||||
_targetItemsEnd = (assignedItems _target) + (items _target);
|
||||
if ((headgear _target) != "") then {_targetItemsEnd pushBack (headgear _target);};
|
||||
if ((goggles _target) != "") then {_targetItemsEnd pushBack (goggles _target);};
|
||||
|
||||
//Verify Items Added
|
||||
if (((count _targetItemsStart) - (count _targetItemsEnd)) != ([_addToCrateCount] call _fncSumArray)) exitWith {
|
||||
_holder setVariable [QGVAR(holderInUse), false];
|
||||
[_caller, _target, "Debug: Items Not Removed From Player"] call FUNC(eventTargetFinish);
|
||||
};
|
||||
if ((([_holderItemsEnd select 1] call _fncSumArray) - ([_holderItemsStart select 1] call _fncSumArray)) != ([_addToCrateCount] call _fncSumArray)) exitWith {
|
||||
_holder setVariable [QGVAR(holderInUse), false];
|
||||
[_caller, _target, "Debug: Items Not Added to Holder"] call FUNC(eventTargetFinish);
|
||||
};
|
||||
|
||||
|
||||
//If holder is still empty, it will be 'garbage collected' while we wait for the drop 'action' to take place
|
||||
//So add a dummy item and just remove at the end
|
||||
_holderIsEmpty = ([_holder] call FUNC(getAllGearContainer)) isEqualTo [[],[]];
|
||||
if (_holderIsEmpty) then {
|
||||
TRACE_1("Debug: adding dummy item to holder",_holder);
|
||||
_holder addItemCargoGlobal [DUMMY_ITEM, 1];
|
||||
};
|
||||
|
||||
//Start the PFEH to do the actions (which could take >1 frame)
|
||||
[{
|
||||
PARAMS_2(_args,_pfID);
|
||||
EXPLODE_8_PVT(_args,_caller,_target,_listOfItemsToRemove,_holder,_holderIsEmpty,_maxWaitTime,_doNotDropAmmo,_startingMagazines);
|
||||
|
||||
_needToRemoveWeapon = ({_x in _listOfItemsToRemove} count (weapons _target)) > 0;
|
||||
_needToRemoveMagazines = ({_x in _listOfItemsToRemove} count (magazines _target)) > 0;
|
||||
_needToRemoveBackpack = ((backPack _target) != "") && {(backPack _target) in _listOfItemsToRemove};
|
||||
_needToRemoveVest = ((vest _target) != "") && {(vest _target) in _listOfItemsToRemove};
|
||||
_needToRemoveUniform = ((uniform _target) != "") && {(uniform _target) in _listOfItemsToRemove};
|
||||
|
||||
if ((time < _maxWaitTime) && {[_target] call FUNC(canBeDisarmed)} && {_needToRemoveWeapon || _needToRemoveMagazines || _needToRemoveBackpack}) then {
|
||||
//action drop weapons (keeps loaded magazine and attachements)
|
||||
{
|
||||
if (_x in _listOfItemsToRemove) then {
|
||||
_target action ["DropWeapon", _holder, _x];
|
||||
};
|
||||
} forEach (weapons _target);
|
||||
|
||||
//Drop magazine (keeps unique ID)
|
||||
{
|
||||
if (_x in _listOfItemsToRemove) then {
|
||||
_target action ["DropMagazine", _holder, _x];
|
||||
};
|
||||
} forEach (magazines _target);
|
||||
|
||||
//Drop backpack (Keeps variables for ACRE/TFR)
|
||||
if (_needToRemoveBackpack) then {_target action ["DropBag", _holder, (backPack _target)];};
|
||||
} else {
|
||||
[_pfID] call CBA_fnc_removePerFrameHandler;
|
||||
|
||||
if (_doNotDropAmmo) then {
|
||||
_error = false;
|
||||
|
||||
_magsToPickup = +_startingMagazines;
|
||||
{
|
||||
_index = _magsToPickup find _x;
|
||||
if (_index == -1) exitWith {_error = true; ERROR("More mags than when we started?")};
|
||||
_magsToPickup deleteAt _index;
|
||||
} forEach (magazinesAmmo _target);
|
||||
|
||||
_magazinesInHolder = magazinesAmmoCargo _holder;
|
||||
{
|
||||
_index = _magazinesInHolder find _x;
|
||||
if (_index == -1) exitWith {_error = true; ERROR("Missing mag not in holder")};
|
||||
_magazinesInHolder deleteAt _index;
|
||||
} forEach _magsToPickup;
|
||||
|
||||
//No Error (all the ammo in the container is ammo we should have);
|
||||
if ((!_error) && {_magazinesInHolder isEqualTo []}) then {
|
||||
{
|
||||
_target addMagazine _x;
|
||||
} forEach (magazinesAmmoCargo _holder);
|
||||
clearMagazineCargoGlobal _holder;
|
||||
};
|
||||
};
|
||||
|
||||
//If we added a dummy item, remove it now
|
||||
if (_holderIsEmpty && {!((getItemCargo _holder) isEqualTo [[DUMMY_ITEM],[1]])}) exitWith {
|
||||
_holder setVariable [QGVAR(holderInUse), false];
|
||||
[_caller, _target, "Debug: Holder should only have dummy item"] call FUNC(eventTargetFinish);
|
||||
};
|
||||
if (_holderIsEmpty) then {
|
||||
TRACE_1("Debug: removing dummy item from holder",_holder);
|
||||
clearItemCargoGlobal _holder;
|
||||
};
|
||||
//Verify we didn't timeout waiting on drop action
|
||||
if (time >= _maxWaitTime) exitWith {
|
||||
_holder setVariable [QGVAR(holderInUse), false];
|
||||
[_caller, _target, "Debug: Drop Actions Timeout"] call FUNC(eventTargetFinish);
|
||||
};
|
||||
//If target lost disarm status:
|
||||
if (!([_target] call FUNC(canBeDisarmed))) exitWith {
|
||||
_holder setVariable [QGVAR(holderInUse), false];
|
||||
[_caller, _target, "Debug: Target cannot be disarmed"] call FUNC(eventTargetFinish);
|
||||
};
|
||||
if (_needToRemoveVest && {!((vestItems _target) isEqualTo [])}) exitWith {
|
||||
_holder setVariable [QGVAR(holderInUse), false];
|
||||
[_caller, _target, "Debug: Vest Not Empty"] call FUNC(eventTargetFinish);
|
||||
};
|
||||
if (_needToRemoveVest) then {
|
||||
_holder addItemCargoGlobal [(vest _target), 1];
|
||||
removeVest _target;
|
||||
};
|
||||
if (_needToRemoveUniform && {!((uniformItems _target) isEqualTo [])}) exitWith {
|
||||
_holder setVariable [QGVAR(holderInUse), false];
|
||||
[_caller, _target, "Debug: Uniform Not Empty"] call FUNC(eventTargetFinish);
|
||||
};
|
||||
if (_needToRemoveUniform) then {
|
||||
_holder addItemCargoGlobal [(uniform _target), 1];
|
||||
removeUniform _target;
|
||||
};
|
||||
|
||||
_holder setVariable [QGVAR(holderInUse), false];
|
||||
[_caller, _target, ""] call FUNC(eventTargetFinish);
|
||||
};
|
||||
|
||||
}, 0.0, [_caller,_target, _listOfItemsToRemove, _holder, _holderIsEmpty, (time + TIME_MAX_WAIT), _doNotDropAmmo, _targetMagazinesEnd]] call CBA_fnc_addPerFrameHandler;
|
25
addons/disarming/functions/fnc_eventCallerFinish.sqf
Normal file
25
addons/disarming/functions/fnc_eventCallerFinish.sqf
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Recieves a possible error code from FUNC(eventTargetFinish)
|
||||
*
|
||||
* Arguments:
|
||||
* 0: caller (player) <OBJECT>
|
||||
* 1: target <OBJECT>
|
||||
* 2: error message <STRING>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player1, player2, "Someting fucked up"] call ace_disarming_fnc_eventCallerFinish
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
PARAMS_3(_caller,_target,_errorMsg);
|
||||
|
||||
if (_caller != ACE_player) exitWith {};
|
||||
|
||||
systemChat format ["Debug-Caller: Disarm finished from [%1] with code [%2]", _target, _errorMsg];
|
||||
diag_log text format ["[ACE_Disarming] %1 - eventCallerFinish: %2", time, _this];
|
26
addons/disarming/functions/fnc_eventTargetFinish.sqf
Normal file
26
addons/disarming/functions/fnc_eventTargetFinish.sqf
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* After FUNC(disarmDropItems) has completed, passing a possible error code.
|
||||
* Passes that error back to orginal caller.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: caller <OBJECT>
|
||||
* 1: target <OBJECT>
|
||||
* 2: errorMsg <STRING>
|
||||
*
|
||||
* Return Value:
|
||||
* Nothing
|
||||
*
|
||||
* Example:
|
||||
* [player1, player2, "Someting fucked up"] call ace_disarming_fnc_eventTargetFinish
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
PARAMS_3(_caller,_target,_errorMsg);
|
||||
|
||||
if (_errorMsg != "") then {
|
||||
diag_log text format ["[ACE_Disarming] %1 - eventTargetFinish: %2", time, _this];
|
||||
["DisarmDebugCallback", [_caller], [_caller, _target, _errorMsg]] call EFUNC(common,targetEvent);
|
||||
};
|
39
addons/disarming/functions/fnc_eventTargetStart.sqf
Normal file
39
addons/disarming/functions/fnc_eventTargetStart.sqf
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Disarm Event Handler, Starting func, called on the target.
|
||||
* If target has to remove uniform/vest, this will add all uniform/vest items to the drop list.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: caller (player) <OBJECT>
|
||||
* 1: target <OBJECT>
|
||||
* 2: type of disarm <STRING>
|
||||
*
|
||||
* Return Value:
|
||||
* Nothing
|
||||
*
|
||||
* Example:
|
||||
* eventTargetStart
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
PARAMS_3(_caller,_target,_listOfObjectsToRemove);
|
||||
|
||||
_itemsToAdd = [];
|
||||
{
|
||||
if (_x == (uniform _target)) then {
|
||||
_itemsToAdd = _itemsToAdd + (uniformItems _target);
|
||||
};
|
||||
if (_x == (vest _target)) then {
|
||||
_itemsToAdd = _itemsToAdd + (vestItems _target);
|
||||
};
|
||||
} forEach _listOfObjectsToRemove;
|
||||
|
||||
{
|
||||
if (!(_x in _listOfObjectsToRemove)) then {
|
||||
_listOfObjectsToRemove pushBack _x;
|
||||
};
|
||||
} forEach _itemsToAdd;
|
||||
|
||||
[_caller, _target, _listOfObjectsToRemove] call FUNC(disarmDropItems);
|
29
addons/disarming/functions/fnc_getAllGearContainer.sqf
Normal file
29
addons/disarming/functions/fnc_getAllGearContainer.sqf
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Helper function to get all gear of a container
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Container <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Array of 2 arrays, classnames and count<ARRAY>
|
||||
*
|
||||
* Example:
|
||||
* [["ace_bandage"],[2]] = [box] call ace_disarming_fnc_getAllGearContainer
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
PARAMS_1(_target);
|
||||
|
||||
private ["_allGear"];
|
||||
|
||||
_allGear = [[],[]];
|
||||
|
||||
{
|
||||
(_allGear select 0) append (_x select 0);
|
||||
(_allGear select 1) append (_x select 1);
|
||||
} forEach [(getWeaponCargo _target), (getItemCargo _target), (getMagazineCargo _target), (getBackpackCargo _target)];
|
||||
|
||||
_allGear
|
52
addons/disarming/functions/fnc_getAllGearUnit.sqf
Normal file
52
addons/disarming/functions/fnc_getAllGearUnit.sqf
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Helper function to get all gear of a unit.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Target <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Array of 2 arrays, classnames and count<ARRAY>
|
||||
*
|
||||
* Example:
|
||||
* [["ace_bandage"],[2]] = [bob] call ace_disarming_fnc_getAllGearUnit
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
PARAMS_1(_target);
|
||||
|
||||
_allItems = ((weapons _target) + (magazines _target) + (items _target) + (assignedItems _target));
|
||||
|
||||
if ((backpack _target) != "") then {
|
||||
_allItems pushBack (backpack _target);
|
||||
};
|
||||
if ((vest _target) != "") then {
|
||||
_allItems pushBack (vest _target);
|
||||
};
|
||||
if ((uniform _target) != "") then {
|
||||
_allItems pushBack (uniform _target);
|
||||
};
|
||||
if ((headgear _target) != "") then {
|
||||
_allItems pushBack (headgear _target);
|
||||
};
|
||||
//What kind of asshole takes a man's glasses?
|
||||
if ((goggles _target) != "") then {
|
||||
_allItems pushBack (goggles _target);
|
||||
};
|
||||
|
||||
_uniqueClassnames = [];
|
||||
_classnamesCount = [];
|
||||
//Filter unique and count
|
||||
{
|
||||
_index = _uniqueClassnames find _x;
|
||||
if (_index != -1) then {
|
||||
_classnamesCount set [_index, ((_classnamesCount select _index) + 1)];
|
||||
} else {
|
||||
_uniqueClassnames pushBack _x;
|
||||
_classnamesCount pushBack 1;
|
||||
};
|
||||
} forEach _allItems;
|
||||
|
||||
[_uniqueClassnames, _classnamesCount]
|
106
addons/disarming/functions/fnc_openDisarmDialog.sqf
Normal file
106
addons/disarming/functions/fnc_openDisarmDialog.sqf
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Opens the disarm dialog (allowing a person to remove items)
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Caller (player) <OBJECT>
|
||||
* 1: Target <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player, bob] call ace_disarming_fnc_openDisarmDialog
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#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" \
|
||||
]
|
||||
|
||||
PARAMS_2(_caller,_target);
|
||||
|
||||
//Sanity Checks
|
||||
if (_caller != ACE_player) exitwith {ERROR("Player isn't caller?");};
|
||||
if (!([_player, _target] call FUNC(canPlayerDisarmUnit))) exitWith {ERROR("Can't Disarm Unit");};
|
||||
if (dialog) then {ERROR("Dialog open when trying to open disarm dialog"); closeDialog 0;};
|
||||
|
||||
disableSerialization;
|
||||
|
||||
createDialog QGVAR(remoteInventory);
|
||||
|
||||
_display = uiNamespace getVariable ["ACE_remoteInventory", displayNull];
|
||||
if (isNull _display) exitWith {ERROR("Display is Null");};
|
||||
|
||||
GVAR(disarmTarget) = _target;
|
||||
|
||||
//Setup Drop Event (on right pannel)
|
||||
(_display displayCtrl 632) ctrlAddEventHandler ["LBDrop", {
|
||||
if (isNull GVAR(disarmTarget)) exitWith {};
|
||||
PARAMS_5(_ctrl,_xPos,_yPos,_idc,_itemInfo);
|
||||
EXPLODE_3_PVT((_itemInfo select 0),_displayText,_value,_data);
|
||||
|
||||
if (isNull GVAR(disarmTarget)) exitWith {ERROR("disarmTarget is null");};
|
||||
|
||||
TRACE_2("Debug: Droping %1 from %2",_data,GVAR(disarmTarget));
|
||||
["DisarmDropItems", [GVAR(disarmTarget)], [ACE_player, GVAR(disarmTarget), [_data]]] call EFUNC(common,targetEvent);
|
||||
|
||||
false //not sure what this does
|
||||
}];
|
||||
|
||||
//Setup PFEH
|
||||
[{
|
||||
disableSerialization;
|
||||
EXPLODE_2_PVT(_this,_args,_pfID);
|
||||
EXPLODE_3_PVT(_args,_player,_target,_display);
|
||||
|
||||
if ((!([_player, _target] call FUNC(canPlayerDisarmUnit))) ||
|
||||
{isNull _display} ||
|
||||
{_player != ACE_player}) then {
|
||||
|
||||
[_pfID] call CBA_fnc_removePerFrameHandler;
|
||||
GVAR(disarmTarget) = objNull;
|
||||
if (!isNull _display) then {closeDialog 0;}; //close dialog if still open
|
||||
} else {
|
||||
_groundContainer = _display displayCtrl 632;
|
||||
_targetContainer = _display displayCtrl 633;
|
||||
_playerName = _display displayCtrl 111;
|
||||
_rankPicture = _display displayCtrl 1203;
|
||||
|
||||
//Show rank and name (just like BIS's inventory)
|
||||
_rankIndex = ((["PRIVATE", "CORPORAL", "SERGEANT", "LIEUTENANT", "CAPTAIN", "MAJOR", "COLONEL"] find (rank _target)) + 1);
|
||||
_rankPicture ctrlSetText (TEXTURES_RANKS select _rankIndex);
|
||||
_playerName ctrlSetText ([GVAR(disarmTarget)] call EFUNC(common,getName));
|
||||
|
||||
//Clear both inventory lists:
|
||||
lbClear _groundContainer;
|
||||
lbClear _targetContainer;
|
||||
|
||||
//Show the items in the ground disarmTarget's inventory
|
||||
_targetUniqueItems = [GVAR(disarmTarget)] call FUNC(getAllGearUnit);
|
||||
[_targetContainer, _targetUniqueItems] call FUNC(showItemsInListbox);
|
||||
|
||||
//Try to find a holder that the target is using to drop items into:
|
||||
_holder = objNull;
|
||||
{
|
||||
if ((_x getVariable [QGVAR(disarmUnit), objNull]) == _target) exitWith {
|
||||
_holder = _x;
|
||||
};
|
||||
} forEach ((getpos _target) nearObjects [DISARM_CONTAINER, 3]);
|
||||
|
||||
//If a holder exists, show it's inventory
|
||||
if (!isNull _holder) then {
|
||||
_holderUniqueItems = [_holder] call FUNC(getAllGearContainer);
|
||||
[_groundContainer, _holderUniqueItems] call FUNC(showItemsInListbox);
|
||||
};
|
||||
};
|
||||
}, 0, [_caller, _target, _display]] call CBA_fnc_addPerFrameHandler;
|
60
addons/disarming/functions/fnc_showItemsInListbox.sqf
Normal file
60
addons/disarming/functions/fnc_showItemsInListbox.sqf
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Shows a list of inventory items in a listBox control.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: RscListBox <CONTROL>
|
||||
* 1: ItemArray [["itemClassnames"],[counts]] <ARRAY>
|
||||
*
|
||||
* Return Value:
|
||||
* Nothing
|
||||
*
|
||||
* Example:
|
||||
* [theListBox, [["ace_bandage"],[2]]] call ace_disarming_fnc_showItemsInListbox
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
disableSerialization;
|
||||
PARAMS_2(_listBoxCtrl,_itemsCountArray);
|
||||
|
||||
private "_classname";
|
||||
|
||||
{
|
||||
_displayName = "";
|
||||
_picture = "";
|
||||
|
||||
_classname = _x;
|
||||
_count = (_itemsCountArray select 1) select _forEachIndex;
|
||||
|
||||
if (_classname != DUMMY_ITEM) then { //Don't show the dummy potato
|
||||
|
||||
switch (true) do {
|
||||
case (isClass (configFile >> "CfgWeapons" >> _classname)): {
|
||||
_displayName = getText (configFile >> "CfgWeapons" >> _classname >> "displayName");
|
||||
_picture = getText (configFile >> "CfgWeapons" >> _classname >> "picture");
|
||||
};
|
||||
case (isClass (configFile >> "CfgMagazines" >> _classname)): {
|
||||
_displayName = getText (configFile >> "CfgMagazines" >> _classname >> "displayName");
|
||||
_picture = getText (configFile >> "CfgMagazines" >> _classname >> "picture");
|
||||
};
|
||||
case (isClass (configFile >> "CfgVehicles" >> _classname)): {
|
||||
_displayName = getText (configFile >> "CfgVehicles" >> _classname >> "displayName");
|
||||
_picture = getText (configFile >> "CfgVehicles" >> _classname >> "picture");
|
||||
};
|
||||
case (isClass (configFile >> "CfgGlasses" >> _classname)): {
|
||||
_displayName = getText (configFile >> "CfgGlasses" >> _classname >> "displayName");
|
||||
_picture = getText (configFile >> "CfgGlasses" >> _classname >> "picture");
|
||||
};
|
||||
default {
|
||||
ERROR(format ["[%1] - bad classname", _classname]);
|
||||
};
|
||||
};
|
||||
|
||||
_listBoxCtrl lbAdd format ["%1", _displayName];
|
||||
_listBoxCtrl lbSetData [_forEachIndex, _classname];
|
||||
_listBoxCtrl lbSetPicture [_forEachIndex, _picture];
|
||||
_listBoxCtrl lbSetTextRight [_forEachIndex, str _count];
|
||||
};
|
||||
} forEach (_itemsCountArray select 0);
|
41
addons/disarming/functions/fnc_verifyMagazinesMoved.sqf
Normal file
41
addons/disarming/functions/fnc_verifyMagazinesMoved.sqf
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Verifies magazines moved with exact ammo counts preserved.
|
||||
* Arrays will be in format from magazinesAmmo/magazinesAmmoCargo
|
||||
* e.g.: [["30Rnd_65x39_caseless_mag",15], ["30Rnd_65x39_caseless_mag",30]]
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Start on container A <ARRAY>
|
||||
* 1: End on container A <ARRAY>
|
||||
* 2: Start on container B <ARRAY>
|
||||
* 3: End on container B <ARRAY>
|
||||
*
|
||||
* Return Value:
|
||||
* Verified Good <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [stuff] call ace_disarming_fnc_verifyMagazinesMoved
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_problem", "_beginingArray"];
|
||||
|
||||
PARAMS_4(_startA,_endA,_startB,_endB);
|
||||
|
||||
//Quick Lazy Count Check
|
||||
if (((count _startA) + (count _startB)) != ((count _endA) + (count _endB))) exitWith {
|
||||
false
|
||||
};
|
||||
|
||||
_beginingArray = (_startA + _startB);
|
||||
|
||||
_problem = false;
|
||||
{
|
||||
_index = _beginingArray find _x;
|
||||
if (_index == -1) exitWith {_problem = true;};
|
||||
_beginingArray deleteAt _index;
|
||||
} forEach (_endA + _endB);
|
||||
|
||||
(!_problem) && {_beginingArray isEqualTo []}
|
1
addons/disarming/functions/script_component.hpp
Normal file
1
addons/disarming/functions/script_component.hpp
Normal file
@ -0,0 +1 @@
|
||||
#include "\z\ace\addons\disarming\script_component.hpp"
|
162
addons/disarming/gui_disarm.hpp
Normal file
162
addons/disarming/gui_disarm.hpp
Normal file
@ -0,0 +1,162 @@
|
||||
//The disarming dialog
|
||||
//Meant to mimic the real BIS inventory (so people understand how to use it)
|
||||
|
||||
class RscText;
|
||||
class RscPicture;
|
||||
class RscActiveText;
|
||||
class RscListBox;
|
||||
|
||||
//Use the definese from
|
||||
#define X_BIS(num) (num * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2))
|
||||
#define Y_BIS(num) (num * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2))
|
||||
#define W_BIS(num) (num * (((safezoneW / safezoneH) min 1.2) / 40))
|
||||
#define H_BIS(num) (num * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25))
|
||||
|
||||
#define X_MAKEITBIGGA(num) (num * (safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH)/2))
|
||||
#define Y_MAKEITBIGGA(num) (num * (safeZoneH / 30) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2))
|
||||
#define W_MAKEITBIGGA(num) (num * (safeZoneH / 40))
|
||||
#define H_MAKEITBIGGA(num) (num * (safeZoneH / 30))
|
||||
|
||||
#define X_PART(num) QUOTE(linearConversion [ARR_5(0, 2, (missionNamespace getVariable [ARR_2(QUOTE(QEGVAR(inventory,inventoryDisplaySize)), 0)]), X_BIS(num), X_MAKEITBIGGA(num))])
|
||||
#define Y_PART(num) QUOTE(linearConversion [ARR_5(0, 2, (missionNamespace getVariable [ARR_2(QUOTE(QEGVAR(inventory,inventoryDisplaySize)), 0)]), Y_BIS(num), Y_MAKEITBIGGA(num))])
|
||||
#define W_PART(num) QUOTE(linearConversion [ARR_5(0, 2, (missionNamespace getVariable [ARR_2(QUOTE(QEGVAR(inventory,inventoryDisplaySize)), 0)]), W_BIS(num), W_MAKEITBIGGA(num))])
|
||||
#define H_PART(num) QUOTE(linearConversion [ARR_5(0, 2, (missionNamespace getVariable [ARR_2(QUOTE(QEGVAR(inventory,inventoryDisplaySize)), 0)]), H_BIS(num), H_MAKEITBIGGA(num))])
|
||||
|
||||
class GVAR(remoteInventory) {
|
||||
idd = -1;
|
||||
movingEnable = 0;
|
||||
enableSimulation = 1;
|
||||
enableDisplay = 1;
|
||||
onLoad = "uiNamespace setVariable ['ACE_remoteInventory', _this select 0];";
|
||||
duration = 2147483647;
|
||||
fadein = 0;
|
||||
fadeout = 0;
|
||||
|
||||
class Colors {
|
||||
dragValidBgr[] = {"(profilenamespace getvariable ['IGUI_TEXT_RGB_R',0])","(profilenamespace getvariable ['IGUI_TEXT_RGB_G',1])","(profilenamespace getvariable ['IGUI_TEXT_RGB_B',1])",0.5};
|
||||
dragInvalidBgr[] = {"(profilenamespace getvariable ['IGUI_ERROR_RGB_R',0.8])","(profilenamespace getvariable ['IGUI_ERROR_RGB_G',0.0])","(profilenamespace getvariable ['IGUI_ERROR_RGB_B',0.0])",0.5};
|
||||
dragValidBar[] = {"(profilenamespace getvariable ['IGUI_WARNING_RGB_R',0.8])","(profilenamespace getvariable ['IGUI_WARNING_RGB_G',0.5])","(profilenamespace getvariable ['IGUI_WARNING_RGB_B',0.0])",0.5};
|
||||
dragInvalidBar[] = {"(profilenamespace getvariable ['IGUI_ERROR_RGB_R',0.8])","(profilenamespace getvariable ['IGUI_ERROR_RGB_G',0.0])","(profilenamespace getvariable ['IGUI_ERROR_RGB_B',0.0])",0.5};
|
||||
progressBar[] = {"(profilenamespace getvariable ['IGUI_TEXT_RGB_R',0])","(profilenamespace getvariable ['IGUI_TEXT_RGB_G',1])","(profilenamespace getvariable ['IGUI_TEXT_RGB_B',1])",1};
|
||||
progressBarBgr[] = {"(profilenamespace getvariable ['IGUI_BCG_RGB_R',0])","(profilenamespace getvariable ['IGUI_BCG_RGB_G',1])","(profilenamespace getvariable ['IGUI_BCG_RGB_B',1])",0.75};
|
||||
highlight[] = {"(profilenamespace getvariable ['IGUI_TEXT_RGB_R',0])","(profilenamespace getvariable ['IGUI_TEXT_RGB_G',1])","(profilenamespace getvariable ['IGUI_TEXT_RGB_B',1])",0.5};
|
||||
};
|
||||
|
||||
class controlsBackground {};
|
||||
|
||||
class controls {
|
||||
class CA_ContainerBackground: RscText {
|
||||
idc = -1;
|
||||
x = X_PART(1);
|
||||
y = Y_PART(1);
|
||||
w = W_PART(12);
|
||||
h = H_PART(22.5);
|
||||
colorBackground[] = {0.05,0.05,0.05,0.7};
|
||||
};
|
||||
class CA_PlayerBackground: RscText {
|
||||
idc = -1;
|
||||
x = X_PART(14.6);
|
||||
y = Y_PART(2);
|
||||
w = W_PART(24.4);
|
||||
h = H_PART(21.5);
|
||||
colorBackground[] = {0.05,0.05,0.05,0.7};
|
||||
};
|
||||
class TitleBackground: RscText {
|
||||
idc = -1;
|
||||
x = X_PART(14.6);
|
||||
y = Y_PART(1);
|
||||
w = W_PART(24.4);
|
||||
h = H_PART(1);
|
||||
colorBackground[] = {0.1,0.1,0.1,1};
|
||||
};
|
||||
class PlayersName: RscText {
|
||||
idc = 111;
|
||||
// text = "Player name here:";
|
||||
x = X_PART(15.6);
|
||||
y = Y_PART(1);
|
||||
w = W_PART(19.8);
|
||||
h = H_PART(1);
|
||||
};
|
||||
class RankBackground: RscText {
|
||||
idc = -1;
|
||||
x = X_PART(15.1);
|
||||
y = Y_PART(1.25);
|
||||
w = W_PART(0.6);
|
||||
h = H_PART(0.6);
|
||||
colorBackground[] = {1,1,1,0.2};
|
||||
};
|
||||
class RankPicture: RscPicture {
|
||||
idc = 1203;
|
||||
// text = "\A3\Ui_f\data\GUI\Cfg\Ranks\corporal_gs.paa";
|
||||
x = X_PART(15.1);
|
||||
y = Y_PART(1.25);
|
||||
w = W_PART(0.6);
|
||||
h = H_PART(0.6);
|
||||
};
|
||||
class ButtonBack: RscActiveText {
|
||||
idc = -1;
|
||||
style = 48;
|
||||
color[] = {1,1,1,0.7};
|
||||
text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArcadeMap\icon_exit_cross_ca.paa";
|
||||
x = X_PART(38);
|
||||
y = Y_PART(1);
|
||||
w = W_PART(1);
|
||||
h = H_PART(1);
|
||||
colorText[] = {1,1,1,0.7};
|
||||
colorActive[] = {1,1,1,1};
|
||||
tooltip = "$STR_DISP_OPT_CLOSE";
|
||||
onButtonClick = "closeDialog 0";
|
||||
};
|
||||
class ExternalContainerBackground: RscPicture {
|
||||
colorText[] = {1,1,1,0.1};
|
||||
idc = -1;
|
||||
x = X_PART(1.5);
|
||||
y = Y_PART(3.7);
|
||||
w = W_PART(11);
|
||||
h = H_PART(18.4);
|
||||
};
|
||||
class PlayerContainerBackground: ExternalContainerBackground {
|
||||
idc = -1;
|
||||
x = X_PART(15.1);
|
||||
y = Y_PART(6);
|
||||
w = W_PART(11);
|
||||
h = H_PART(14);
|
||||
};
|
||||
class GroundTitleBackground: RscText {
|
||||
idc = -1;
|
||||
x = X_PART(1);
|
||||
y = Y_PART(1);
|
||||
w = W_PART(12);
|
||||
h = H_PART(1);
|
||||
colorBackground[] = {0.1,0.1,0.1,1};
|
||||
};
|
||||
class GroundName: RscText {
|
||||
idc = -1;
|
||||
text = "$STR_cfgVehicles_WeaponHolder0"; //"ground"
|
||||
x = X_PART(1);
|
||||
y = Y_PART(1);
|
||||
w = W_PART(12);
|
||||
h = H_PART(1);
|
||||
};
|
||||
class GroundContainer: RscListBox {
|
||||
idc = 632;
|
||||
sizeEx = "0.8 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
|
||||
sizeEx2 = "0.8 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
|
||||
rowHeight = "1.75 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
|
||||
canDrag = 0;
|
||||
colorText[] = {1,1,1,1};
|
||||
colorBackground[] = {0,0,0,0};
|
||||
itemBackground[] = {1,1,1,0.2};
|
||||
itemSpacing = 0.001;
|
||||
x = X_PART(1.5);
|
||||
y = Y_PART(2.5);
|
||||
w = W_PART(11);
|
||||
h = H_PART(21);
|
||||
};
|
||||
class UniformContainer: GroundContainer {
|
||||
idc = 633;
|
||||
canDrag = 1;
|
||||
x = X_PART(15.1);
|
||||
};
|
||||
};
|
||||
};
|
16
addons/disarming/script_component.hpp
Normal file
16
addons/disarming/script_component.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#define COMPONENT disarming
|
||||
#include "\z\ace\addons\main\script_mod.hpp"
|
||||
|
||||
#ifdef DEBUG_ENABLED_DISARMING
|
||||
#define DEBUG_MODE_FULL
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_SETTINGS_DISARMING
|
||||
#define DEBUG_SETTINGS DEBUG_SETTINGS_DISARMING
|
||||
#endif
|
||||
|
||||
#include "\z\ace\addons\main\script_macros.hpp"
|
||||
|
||||
#define DISARM_CONTAINER "GroundWeaponHolder"
|
||||
#define DUMMY_ITEM "ACE_DebugPotato"
|
||||
#define UNIQUE_MAGAZINES ["ACE_key_customKeyMagazine"]
|
9
addons/disarming/stringtable.xml
Normal file
9
addons/disarming/stringtable.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Edited with tabler - 2015-03-17 -->
|
||||
<Project name="ACE">
|
||||
<Package name="Disarming">
|
||||
<Key ID="STR_ACE_Disarming_OpenInventory">
|
||||
<English>Open Inventory</English>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
@ -1,10 +1,10 @@
|
||||
class CfgACE_Triggers {
|
||||
class ACE_Triggers {
|
||||
/* onPlace parameters:
|
||||
0: OBJECT - unit placing
|
||||
1: OBJECT - Placed explosive
|
||||
2: STRING - Magazine classname
|
||||
3: ARRAY - vars
|
||||
Last Index: CfgACE_Triggers config of trigger type.
|
||||
Last Index: ACE_Triggers config of trigger type.
|
||||
onSetup parameters:
|
||||
0: STRING - Magazine Classname
|
||||
*/
|
@ -18,7 +18,8 @@ class CfgPatches {
|
||||
#include "CfgMagazines.hpp"
|
||||
#include "CfgWeapons.hpp"
|
||||
#include "CfgVehicles.hpp"
|
||||
#include "CfgACE_Triggers.hpp"
|
||||
|
||||
#include "ACE_Triggers.hpp"
|
||||
#include "ExplosivesUI.hpp"
|
||||
|
||||
class CfgActions {
|
||||
|
@ -12,7 +12,7 @@
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player, _explosive, "SatchelCharge_Remote_Mag", [ConfigFile >> "CfgACE_Triggers" >> "Command"]] call ACE_Explosives_fnc_addClacker;
|
||||
* [player, _explosive, "SatchelCharge_Remote_Mag", [ConfigFile >> "ACE_Triggers" >> "Command"]] call ACE_Explosives_fnc_addClacker;
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
|
@ -24,7 +24,7 @@ _result = [_unit] call FUNC(getPlacedExplosives);
|
||||
_children = [];
|
||||
{
|
||||
if (!isNull(_x select 0)) then {
|
||||
_required = getArray (ConfigFile >> "CfgACE_Triggers" >> (_x select 4) >> "requires");
|
||||
_required = getArray (ConfigFile >> "ACE_Triggers" >> (_x select 4) >> "requires");
|
||||
if (_detonator in _required) then {
|
||||
_item = ConfigFile >> "CfgMagazines" >> (_x select 3);
|
||||
|
||||
|
@ -20,7 +20,7 @@ private ["_unit", "_clackerList", "_adjustedList", "_list", "_filter"];
|
||||
_unit = _this select 0;
|
||||
_filter = nil;
|
||||
if (count _this > 1) then {
|
||||
_filter = ConfigFile >> "CfgACE_Triggers" >> (_this select 1);
|
||||
_filter = ConfigFile >> "ACE_Triggers" >> (_this select 1);
|
||||
};
|
||||
_clackerList = [];
|
||||
_adjustedList = false;
|
||||
@ -31,7 +31,7 @@ _list = [];
|
||||
_clackerList set [_foreachIndex, "X"];
|
||||
_adjustedList = true;
|
||||
} else {
|
||||
if (isNil "_filter" || {(ConfigFile >> "CfgACE_Triggers" >> (_x select 4)) == _filter}) then {
|
||||
if (isNil "_filter" || {(ConfigFile >> "ACE_Triggers" >> (_x select 4)) == _filter}) then {
|
||||
_list pushBack _x;
|
||||
};
|
||||
};
|
||||
|
@ -33,7 +33,7 @@ if (isNil "_triggerConfig") exitWith {
|
||||
};
|
||||
|
||||
_magazineTrigger = ConfigFile >> "CfgMagazines" >> _magazineClass >> "ACE_Triggers" >> _triggerConfig;
|
||||
_triggerConfig = ConfigFile >> "CfgACE_Triggers" >> _triggerConfig;
|
||||
_triggerConfig = ConfigFile >> "ACE_Triggers" >> _triggerConfig;
|
||||
|
||||
if (isNil "_triggerConfig") exitWith {
|
||||
diag_log format ["ACE_Explosives: Error config not found in PlaceExplosive: %1", _this];
|
||||
|
@ -19,7 +19,7 @@
|
||||
private ["_config"];
|
||||
|
||||
EXPLODE_3_PVT(_this,_explosive,_magazine,_trigger);
|
||||
_config = ConfigFile >> "CfgACE_Triggers" >> _trigger;
|
||||
_config = ConfigFile >> "ACE_Triggers" >> _trigger;
|
||||
|
||||
// If the onSetup function returns true, it is handled elsewhere
|
||||
if (isText(_config >> "onSetup") && {[_explosive,_magazine] call compile getText (_config >> "onSetup")}) exitWith {};
|
||||
|
@ -6,7 +6,7 @@
|
||||
* 0: Explosive magazine <STRING>
|
||||
*
|
||||
* Return Value:
|
||||
* Supported triggers as CfgACE_Triggers config entries <ARRAY>
|
||||
* Supported triggers as ACE_Triggers config entries <ARRAY>
|
||||
*
|
||||
* Example:
|
||||
* _supports = ["SatchelCharge_Remote_Mag"] call ACE_Explosives_fnc_TriggerType
|
||||
@ -20,6 +20,6 @@ _config = getArray (ConfigFile >> "CfgMagazines" >> (_this select 0) >> "ACE_Tri
|
||||
_count = count _config;
|
||||
|
||||
for "_index" from 0 to (_count - 1) do {
|
||||
_result set [_index, ConfigFile >> "CfgACE_Triggers" >> (_config select _index)];
|
||||
_result set [_index, ConfigFile >> "ACE_Triggers" >> (_config select _index)];
|
||||
};
|
||||
_result
|
||||
|
@ -7,6 +7,8 @@ class CfgVehicles {
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_B,5);
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_smg_01,5);
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_smg_02,5);
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_338,5);
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_93mmg,5);
|
||||
};
|
||||
};
|
||||
|
||||
@ -17,6 +19,8 @@ class CfgVehicles {
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_B,5);
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_smg_01,5);
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_smg_02,5);
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_338,5);
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_93mmg,5);
|
||||
};
|
||||
};
|
||||
|
||||
@ -28,6 +32,8 @@ class CfgVehicles {
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_L,5);
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_smg_01,5);
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_smg_02,5);
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_338,5);
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_93mmg,5);
|
||||
};
|
||||
};
|
||||
|
||||
@ -38,6 +44,8 @@ class CfgVehicles {
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_L,2);
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_smg_01,2);
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_smg_02,2);
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_338,5);
|
||||
MACRO_ADDITEM(ACE_muzzle_mzls_93mmg,5);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,5 +1,231 @@
|
||||
|
||||
class MuzzleSlot;
|
||||
|
||||
class CfgWeapons {
|
||||
|
||||
/* MX */
|
||||
|
||||
class Rifle;
|
||||
class Rifle_Base_F: Rifle {
|
||||
class WeaponSlotsInfo;
|
||||
};
|
||||
|
||||
class arifle_MX_Base_F: Rifle_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_H"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class arifle_MX_SW_F: arifle_MX_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
// Shit is broken again
|
||||
//compatibleItems[] += {"ACE_muzzle_mzls_H"};
|
||||
compatibleItems[] = {"muzzle_snds_H","muzzle_snds_H_SW","ACE_muzzle_mzls_H"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/* Katiba */
|
||||
|
||||
class arifle_katiba_Base_F: Rifle_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_H"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/* Other */
|
||||
|
||||
class Rifle_Long_Base_F: Rifle_Base_F {
|
||||
class WeaponSlotsInfo;
|
||||
};
|
||||
|
||||
class EBR_base_F: Rifle_Long_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_B"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class DMR_01_base_F: Rifle_Long_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_B"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class DMR_02_base_F: Rifle_Long_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_338"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class DMR_03_base_F: Rifle_Long_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_B"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class DMR_05_base_F: Rifle_Long_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_93mmg"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class DMR_06_base_F: Rifle_Long_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_B"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class MMG_01_base_F: Rifle_Long_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_93mmg"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class MMG_02_base_F: Rifle_Long_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_338"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class LMG_Mk200_F: Rifle_Long_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_H"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class LMG_Zafir_F: Rifle_Long_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_B"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/* Assault Rifles */
|
||||
|
||||
class Tavor_base_F: Rifle_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_L"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class mk20_base_F: Rifle_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_L"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/* SMGs */
|
||||
|
||||
class pdw2000_base_F: Rifle_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_smg_02"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class SMG_01_Base: Rifle_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_smg_01"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class SMG_02_base_F: Rifle_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_smg_02"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/* Pistols */
|
||||
|
||||
class Pistol;
|
||||
class Pistol_Base_F: Pistol {
|
||||
class WeaponSlotsInfo;
|
||||
};
|
||||
|
||||
class hgun_P07_F: Pistol_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
linkProxy = "\A3\data_f\proxies\weapon_slots\MUZZLE";
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_smg_02"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class hgun_Rook40_F: Pistol_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
linkProxy = "\A3\data_f\proxies\weapon_slots\MUZZLE";
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_smg_02"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class hgun_ACPC2_F: Pistol_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_smg_01"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class hgun_Pistol_heavy_01_F: Pistol_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_smg_01"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/*class hgun_Pistol_heavy_02_F: Pistol_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot {
|
||||
linkProxy = "\A3\data_f\proxies\weapon_slots\MUZZLE";
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_smg_01"};
|
||||
};
|
||||
};
|
||||
};*/
|
||||
|
||||
|
||||
/* Flashsuppressors */
|
||||
|
||||
class ItemCore;
|
||||
class InventoryMuzzleItem_Base_F;
|
||||
|
||||
@ -239,4 +465,96 @@ class CfgWeapons {
|
||||
|
||||
inertia = 0.1;
|
||||
};
|
||||
|
||||
class ACE_muzzle_mzls_338: ACE_muzzle_mzls_H {
|
||||
author = "$STR_ACE_Common_ACETeam";
|
||||
_generalMacro = "ACE_muzzle_mzls_338";
|
||||
displayName = "$STR_ACE_muzzle_mzls_338";
|
||||
picture = "\A3\weapons_F\Data\UI\gear_acca_mzls_h_ca.paa";
|
||||
model = "\A3\weapons_f\acc\acca_mzls_H_F";
|
||||
|
||||
class ItemInfo: ItemInfo {
|
||||
mass = 8;
|
||||
soundTypeIndex = 0;
|
||||
muzzleEnd = "zaslehPoint";
|
||||
alternativeFire = "Zasleh2";
|
||||
|
||||
class MagazineCoef {
|
||||
initSpeed = 1.0;
|
||||
};
|
||||
|
||||
class AmmoCoef {
|
||||
hit = 1.0;
|
||||
visibleFire = 0.5;
|
||||
audibleFire = 1.0;
|
||||
visibleFireTime = 0.5;
|
||||
audibleFireTime = 1.0;
|
||||
cost = 1.0;
|
||||
typicalSpeed = 1.0;
|
||||
airFriction = 1.0;
|
||||
};
|
||||
|
||||
class MuzzleCoef {
|
||||
dispersionCoef = "0.9f";
|
||||
artilleryDispersionCoef = "1.0f";
|
||||
fireLightCoef = "0.5f";
|
||||
recoilCoef = "1.0f";
|
||||
recoilProneCoef = "1.0f";
|
||||
minRangeCoef = "1.0f";
|
||||
minRangeProbabCoef = "1.0f";
|
||||
midRangeCoef = "1.0f";
|
||||
midRangeProbabCoef = "1.0f";
|
||||
maxRangeCoef = "1.0f";
|
||||
maxRangeProbabCoef = "1.0f";
|
||||
};
|
||||
};
|
||||
|
||||
inertia = 0.2;
|
||||
};
|
||||
|
||||
class ACE_muzzle_mzls_93mmg: ACE_muzzle_mzls_H {
|
||||
author = "$STR_ACE_Common_ACETeam";
|
||||
_generalMacro = "ACE_muzzle_mzls_93mmg";
|
||||
displayName = "$STR_ACE_muzzle_mzls_93mmg";
|
||||
picture = "\A3\weapons_F\Data\UI\gear_acca_mzls_h_ca.paa";
|
||||
model = "\A3\weapons_f\acc\acca_mzls_H_F";
|
||||
|
||||
class ItemInfo: ItemInfo {
|
||||
mass = 8;
|
||||
soundTypeIndex = 0;
|
||||
muzzleEnd = "zaslehPoint";
|
||||
alternativeFire = "Zasleh2";
|
||||
|
||||
class MagazineCoef {
|
||||
initSpeed = 1.0;
|
||||
};
|
||||
|
||||
class AmmoCoef {
|
||||
hit = 1.0;
|
||||
visibleFire = 0.5;
|
||||
audibleFire = 1.0;
|
||||
visibleFireTime = 0.5;
|
||||
audibleFireTime = 1.0;
|
||||
cost = 1.0;
|
||||
typicalSpeed = 1.0;
|
||||
airFriction = 1.0;
|
||||
};
|
||||
|
||||
class MuzzleCoef {
|
||||
dispersionCoef = "0.9f";
|
||||
artilleryDispersionCoef = "1.0f";
|
||||
fireLightCoef = "0.5f";
|
||||
recoilCoef = "1.0f";
|
||||
recoilProneCoef = "1.0f";
|
||||
minRangeCoef = "1.0f";
|
||||
minRangeProbabCoef = "1.0f";
|
||||
midRangeCoef = "1.0f";
|
||||
midRangeProbabCoef = "1.0f";
|
||||
maxRangeCoef = "1.0f";
|
||||
maxRangeProbabCoef = "1.0f";
|
||||
};
|
||||
};
|
||||
|
||||
inertia = 0.2;
|
||||
};
|
||||
};
|
||||
|
@ -3,7 +3,15 @@
|
||||
class CfgPatches {
|
||||
class ADDON {
|
||||
units[] = {};
|
||||
weapons[] = {"ACE_muzzle_mzls_H","ACE_muzzle_mzls_B","ACE_muzzle_mzls_L","ACE_muzzle_mzls_smg_01","ACE_muzzle_mzls_smg_02"};
|
||||
weapons[] = {
|
||||
"ACE_muzzle_mzls_H",
|
||||
"ACE_muzzle_mzls_B",
|
||||
"ACE_muzzle_mzls_L",
|
||||
"ACE_muzzle_mzls_smg_01",
|
||||
"ACE_muzzle_mzls_smg_02",
|
||||
"ACE_muzzle_mzls_338",
|
||||
"ACE_muzzle_mzls_93mmg"
|
||||
};
|
||||
requiredVersion = REQUIRED_VERSION;
|
||||
requiredAddons[] = {"ace_common"};
|
||||
author[] = {"commy2"};
|
||||
|
@ -4,3 +4,5 @@ ACE_muzzle_mzls_B
|
||||
ACE_muzzle_mzls_L
|
||||
ACE_muzzle_mzls_smg_01
|
||||
ACE_muzzle_mzls_smg_02
|
||||
ACE_muzzle_mzls_338
|
||||
ACE_muzzle_mzls_93mmg
|
||||
|
@ -62,5 +62,29 @@
|
||||
<Russian>Пламегаситель (9 мм)</Russian>
|
||||
<Spanish>Supresor (9 mm)</Spanish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_muzzle_mzls_338">
|
||||
<English>Flash Suppressor (.338)</English>
|
||||
<Hungarian>Lángrejtő (.338)</Hungarian>
|
||||
<German>Mündungsfeuerdämpfer (.338)</German>
|
||||
<Italian>Soppressore di fiamma (.338)</Italian>
|
||||
<Portuguese>Supressor de Clarão (.338)</Portuguese>
|
||||
<Polish>Tłumik płomieni (.338)</Polish>
|
||||
<Czech>Tlumič záblesku (.338)</Czech>
|
||||
<French>Cache-flamme (.338)</French>
|
||||
<Russian>Пламегаситель (.338)</Russian>
|
||||
<Spanish>Supresor (.338)</Spanish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_muzzle_mzls_93mmg">
|
||||
<English>Flash Suppressor (9.3 mm)</English>
|
||||
<Hungarian>Lángrejtő (9,3 mm)</Hungarian>
|
||||
<German>Mündungsfeuerdämpfer (9,3 mm)</German>
|
||||
<Italian>Soppressore di fiamma (9.3mm)</Italian>
|
||||
<Portuguese>Supressor de Clarão (9,3mm)</Portuguese>
|
||||
<Polish>Tłumik płomieni (9,3 mm)</Polish>
|
||||
<Czech>Tlumič záblesku (9,3 mm)</Czech>
|
||||
<French>Cache-flamme (9,3 mm)</French>
|
||||
<Russian>Пламегаситель (9,3 мм)</Russian>
|
||||
<Spanish>Supresor (9,3 mm)</Spanish>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
||||
|
@ -32,7 +32,7 @@ GVAR(openedMenuType) = _menuType;
|
||||
|
||||
GVAR(useCursorMenu) = (vehicle ACE_player != ACE_player) ||
|
||||
visibleMap ||
|
||||
{(_menuType == 1) && {(isWeaponDeployed ACE_player) || GVAR(AlwaysUseCursorSelfInteraction)}};
|
||||
{(_menuType == 1) && {(isWeaponDeployed ACE_player) || GVAR(AlwaysUseCursorSelfInteraction) || {cameraView == "GUNNER"}}};
|
||||
if (GVAR(useCursorMenu)) then {
|
||||
createDialog QGVAR(cursorMenu);
|
||||
// The dialog sets:
|
||||
|
@ -23,7 +23,7 @@ _fnc_renderNearbyActions = {
|
||||
#define MAXINTERACTOBJECTS 3
|
||||
|
||||
_numInteractObjects = 0;
|
||||
_nearestObjects = nearestObjects [(getPos ACE_player), ["All"], 15];
|
||||
_nearestObjects = nearestObjects [ACE_player, ["All"], 15];
|
||||
{
|
||||
_target = _x;
|
||||
|
||||
|
1
addons/javelin/$PBOPREFIX$
Normal file
1
addons/javelin/$PBOPREFIX$
Normal file
@ -0,0 +1 @@
|
||||
z\ace\addons\javelin
|
13
addons/javelin/CfgWeapons.hpp
Normal file
13
addons/javelin/CfgWeapons.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
class CfgWeapons {
|
||||
class Launcher;
|
||||
class Launcher_Base_F : Launcher {
|
||||
class WeaponSlotsInfo;
|
||||
};
|
||||
|
||||
class launch_Titan_base : Launcher_Base_F {
|
||||
weaponInfoType = "ACE_RscOptics_javelin";
|
||||
|
||||
lockingTargetSound[] = {"",0,1};
|
||||
lockedTargetSound[] = {"",0,1};
|
||||
};
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
ace_wep_javelin
|
||||
ace_javelin
|
||||
===============
|
||||
|
||||
Adds the Javelin AT launcher.
|
||||
@ -9,4 +9,3 @@ Adds the Javelin AT launcher.
|
||||
The people responsible for merging changes to this component or answering potential questions.
|
||||
|
||||
- [jaynus](https://github.com/walterpearce)
|
||||
- [NouberNou](https://github.com/NouberNou)
|
@ -10,9 +10,9 @@ class RscLine;
|
||||
// Taken from AGM for optics management.
|
||||
|
||||
class RscInGameUI {
|
||||
class RscOptics_titan {
|
||||
class ACE_RscOptics_javelin {
|
||||
idd = 300;
|
||||
controls[] = {"ACE_javelin_elements_group"};
|
||||
controls[] = { "ACE_javelin_elements_group", "CA_Distance", "ACE_Targeting" }; //, "ACE_TargetingConstrains", "ACE_TargetingGate", "ACE_TargetingLines"};
|
||||
onLoad = QUOTE(_this call FUNC(onOpticLoad));
|
||||
onUnload = "uiNameSpace setVariable ['ACE_RscOptics_javelin',nil];";
|
||||
|
||||
@ -94,6 +94,7 @@ class RscInGameUI {
|
||||
x = "((SafezoneW -SafezoneH*3/4)/2)+ (0.307/4)*3*SafezoneH - SafezoneX";
|
||||
colorText[] = {0.2941,0.8745,0.2157,1};
|
||||
};
|
||||
/*
|
||||
class StadiaL: RscLine {
|
||||
x = "0.4899*SafezoneW - SafezoneX";
|
||||
y = "0.171*SafezoneH - SafezoneY";
|
||||
@ -136,6 +137,7 @@ class RscInGameUI {
|
||||
h = 0;
|
||||
colorText[] = {0.2941,0.8745,0.2157,1};
|
||||
};
|
||||
*/
|
||||
};
|
||||
};
|
||||
class ACE_javelin_NFOV_mode_off: ACE_javelin_Day_mode_off {
|
||||
@ -167,6 +169,7 @@ class RscInGameUI {
|
||||
y = "0.031*SafezoneH - SafezoneY";
|
||||
colorText[] = {0.2941,0.8745,0.2157,1};
|
||||
};
|
||||
/*
|
||||
class StadiaL: RscLine {
|
||||
x = "0.4788*SafezoneW - SafezoneX";
|
||||
y = "0.171*SafezoneH - SafezoneY";
|
||||
@ -209,15 +212,83 @@ class RscInGameUI {
|
||||
h = "0.1895*SafezoneH";
|
||||
colorText[] = {0.2941,0.8745,0.2157,1};
|
||||
};
|
||||
*/
|
||||
};
|
||||
};
|
||||
/*
|
||||
class TargetingConstrains: RscControlsGroup {
|
||||
idc = 699100;
|
||||
|
||||
class ACE_javelin_SEEK_off: ACE_javelin_Day_mode_off {
|
||||
idc = 699000;
|
||||
x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (0.863/4)*3*SafezoneH - SafezoneX";
|
||||
text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\seek_co.paa";
|
||||
};
|
||||
class ACE_javelin_SEEK: ACE_javelin_SEEK_off {
|
||||
idc = 166;
|
||||
colorText[] = {0.2941,0.8745,0.2157,0};
|
||||
};
|
||||
class ACE_javelin_Missle_off: ACE_javelin_Day_mode_off {
|
||||
idc = 1032;
|
||||
x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (-0.134/4)*3*SafezoneH - SafezoneX";
|
||||
y = "(SafezoneY + 0.208*SafezoneH) - SafezoneY";
|
||||
colorText[] = {0.2941,0.2941,0.2941,1};
|
||||
text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\missle_co.paa";
|
||||
};
|
||||
class ACE_javelin_Missle: ACE_javelin_Missle_off {
|
||||
idc = 167;
|
||||
colorText[] = {0.9255,0.5216,0.1216,0};
|
||||
};
|
||||
class ACE_javelin_CLU_off: ACE_javelin_Missle_off {
|
||||
idc = 1027;
|
||||
y = "(SafezoneY + 0.436*SafezoneH) - SafezoneY";
|
||||
text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\clu_co.paa";
|
||||
};
|
||||
class ACE_javelin_HangFire_off: ACE_javelin_Missle_off {
|
||||
idc = 1028;
|
||||
y = "(SafezoneY + 0.669*SafezoneH) - SafezoneY";
|
||||
text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\hangfire_co.paa";
|
||||
};
|
||||
class ACE_javelin_TOP_off: ACE_javelin_Day_mode_off {
|
||||
idc = 699001;
|
||||
x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (1.023/4)*3*SafezoneH - SafezoneX";
|
||||
y = "(SafezoneY + 0.208*SafezoneH) - SafezoneY";
|
||||
text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\top_co.paa";
|
||||
colorText[] = {0.2941,0.8745,0.2157,1};
|
||||
};
|
||||
class ACE_javelin_DIR: ACE_javelin_Day_mode {
|
||||
idc = 699002;
|
||||
x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (1.023/4)*3*SafezoneH - SafezoneX";
|
||||
y = "(SafezoneY + 0.436*SafezoneH) - SafezoneY";
|
||||
text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\dir_co.paa";
|
||||
colorText[] = {0.2941,0.2941,0.2941,1};
|
||||
};
|
||||
class ACE_javelin_FLTR_mode_off: ACE_javelin_Day_mode_off {
|
||||
idc = 1002;
|
||||
x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (1.023/4)*3*SafezoneH - SafezoneX";
|
||||
y = "(SafezoneY + 0.669*SafezoneH) - SafezoneY";
|
||||
text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\fltr_co.paa";
|
||||
};
|
||||
class ACE_javelin_FLTR_mode: ACE_javelin_FLTR_mode_off {
|
||||
idc = 161;
|
||||
colorText[] = {0.2941,0.8745,0.2157,1};
|
||||
};
|
||||
};
|
||||
};
|
||||
class ACE_Targeting : RscControlsGroup {
|
||||
idc = 6999;
|
||||
|
||||
x = "SafezoneX";
|
||||
y = "SafezoneY";
|
||||
w = "SafezoneW";
|
||||
h = "SafezoneH";
|
||||
|
||||
enabled = 0;
|
||||
class Controls {
|
||||
class ACE_TargetingConstrains: RscControlsGroup {
|
||||
x = "SafezoneX";
|
||||
y = "SafezoneY";
|
||||
w = "SafezoneW-SafezoneX";
|
||||
h = "SafezoneH-SafezoneY";
|
||||
|
||||
enabled = 0;
|
||||
class VScrollbar {
|
||||
autoScrollSpeed = -1;
|
||||
autoScrollDelay = 5;
|
||||
@ -258,18 +329,18 @@ class RscInGameUI {
|
||||
idc = 699105;
|
||||
text = PATHTOF(data\javelin_ui_border_ca.paa);
|
||||
colorText[] = {0,0,0,1};
|
||||
x = "((SafezoneW -(3/4)*SafezoneH)/2) - SafezoneX";
|
||||
x = "((SafezoneW -(3.1/4)*SafezoneH)/2) - SafezoneX";
|
||||
y = "0.15*SafezoneH-SafezoneY";
|
||||
w = "(3/4)*SafezoneH";
|
||||
w = "(3.1/4)*SafezoneH";
|
||||
h = "0.7*SafezoneH";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class TargetingGate: TargetingConstrains {
|
||||
class ACE_TargetingGate : ACE_TargetingConstrains {
|
||||
idc = 699200;
|
||||
class Controls {
|
||||
class TargetingGateTL: TargetingConstrains {
|
||||
class TargetingGateTL: ACE_TargetingConstrains {
|
||||
x = "((SafezoneW -(3/4)*SafezoneH)/2) - SafezoneX";
|
||||
y = "0.15*SafezoneH - SafezoneY";
|
||||
idc = 699201;
|
||||
@ -351,8 +422,9 @@ class RscInGameUI {
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class TargetingLines: TargetingConstrains {
|
||||
|
||||
|
||||
class ACE_TargetingLines: ACE_TargetingConstrains {
|
||||
idc = 699300;
|
||||
class Controls {
|
||||
class LineH: RscLine {
|
||||
@ -373,62 +445,6 @@ class RscInGameUI {
|
||||
};
|
||||
};
|
||||
};
|
||||
*/
|
||||
|
||||
class ACE_javelin_SEEK_off: ACE_javelin_Day_mode_off {
|
||||
idc = 699000;
|
||||
x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (0.863/4)*3*SafezoneH - SafezoneX";
|
||||
text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\seek_co.paa";
|
||||
};
|
||||
class ACE_javelin_SEEK: ACE_javelin_SEEK_off {
|
||||
idc = 166;
|
||||
colorText[] = {0.2941,0.8745,0.2157,0};
|
||||
};
|
||||
class ACE_javelin_Missle_off: ACE_javelin_Day_mode_off {
|
||||
idc = 1032;
|
||||
x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (-0.134/4)*3*SafezoneH - SafezoneX";
|
||||
y = "(SafezoneY + 0.208*SafezoneH) - SafezoneY";
|
||||
colorText[] = {0.2941,0.2941,0.2941,1};
|
||||
text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\missle_co.paa";
|
||||
};
|
||||
class ACE_javelin_Missle: ACE_javelin_Missle_off {
|
||||
idc = 167;
|
||||
colorText[] = {0.9255,0.5216,0.1216,0};
|
||||
};
|
||||
class ACE_javelin_CLU_off: ACE_javelin_Missle_off {
|
||||
idc = 1027;
|
||||
y = "(SafezoneY + 0.436*SafezoneH) - SafezoneY";
|
||||
text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\clu_co.paa";
|
||||
};
|
||||
class ACE_javelin_HangFire_off: ACE_javelin_Missle_off {
|
||||
idc = 1028;
|
||||
y = "(SafezoneY + 0.669*SafezoneH) - SafezoneY";
|
||||
text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\hangfire_co.paa";
|
||||
};
|
||||
class ACE_javelin_TOP_off: ACE_javelin_Day_mode_off {
|
||||
idc = 699001;
|
||||
x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (1.023/4)*3*SafezoneH - SafezoneX";
|
||||
y = "(SafezoneY + 0.208*SafezoneH) - SafezoneY";
|
||||
text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\top_co.paa";
|
||||
colorText[] = {0.2941,0.8745,0.2157,1};
|
||||
};
|
||||
class ACE_javelin_DIR: ACE_javelin_Day_mode {
|
||||
idc = 699002;
|
||||
x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (1.023/4)*3*SafezoneH - SafezoneX";
|
||||
y = "(SafezoneY + 0.436*SafezoneH) - SafezoneY";
|
||||
text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\dir_co.paa";
|
||||
colorText[] = {0.2941,0.2941,0.2941,1};
|
||||
};
|
||||
class ACE_javelin_FLTR_mode_off: ACE_javelin_Day_mode_off {
|
||||
idc = 1002;
|
||||
x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (1.023/4)*3*SafezoneH - SafezoneX";
|
||||
y = "(SafezoneY + 0.669*SafezoneH) - SafezoneY";
|
||||
text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\fltr_co.paa";
|
||||
};
|
||||
class ACE_javelin_FLTR_mode: ACE_javelin_FLTR_mode_off {
|
||||
idc = 161;
|
||||
colorText[] = {0.2941,0.8745,0.2157,1};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
@ -1,8 +1,5 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
PREP(translateToWeaponSpace);
|
||||
PREP(translateToModelSpace);
|
||||
|
||||
PREP(lockKeyDown);
|
||||
PREP(lockKeyUp);
|
||||
|
@ -12,4 +12,5 @@ class CfgPatches {
|
||||
|
||||
#include "CfgEventhandlers.hpp"
|
||||
#include "RscInGameUI.hpp"
|
||||
#include "CfgSounds.hpp"
|
||||
#include "CfgSounds.hpp"
|
||||
#include "CfgWeapons.hpp"
|
211
addons/javelin/functions/fnc_onOpticDraw.sqf
Normal file
211
addons/javelin/functions/fnc_onOpticDraw.sqf
Normal file
@ -0,0 +1,211 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
//TRACE_1("enter", _this);
|
||||
|
||||
#define __TRACKINTERVAL 0 // how frequent the check should be.
|
||||
#define __LOCKONTIME 3.0 // Lock on won't occur sooner
|
||||
#define __LOCKONTIMERANDOM 0.3 // Deviation in lock on time
|
||||
#define __SENSORSQUARE 1 // Locking on sensor square side in angles
|
||||
|
||||
#define __OffsetX ((ctrlPosition __JavelinIGUITargetingLineV) select 0) - 0.5
|
||||
#define __OffsetY ((ctrlPosition __JavelinIGUITargetingLineH) select 1) - 0.5
|
||||
|
||||
private["_args", "_lastTick", "_runTime", "_soundTime", "_lockTime", "_newTarget", "_currentTarget", "_range", "_pos", "_targetArray"];
|
||||
|
||||
// Reset arguments if we havnt rendered in over a second
|
||||
_args = uiNamespace getVariable[QGVAR(arguments), [] ];
|
||||
if( (count _args) > 0) then {
|
||||
_lastTick = _args select 0;
|
||||
if(diag_tickTime - _lastTick > 1) then {
|
||||
[] call FUNC(onOpticLoad);
|
||||
};
|
||||
};
|
||||
|
||||
// Pull the arguments
|
||||
_currentTarget = _args select 1;
|
||||
_runTime = _args select 2;
|
||||
_lockTime = _args select 3;
|
||||
_soundTime = _args select 4;
|
||||
|
||||
// Find a target within the optic range
|
||||
_newTarget = objNull;
|
||||
|
||||
// Bail on fast movement
|
||||
if ((velocity ACE_player) distance [0,0,0] > 0.5 && {cameraView == "GUNNER"} && {cameraOn == ACE_player}) exitWith { // keep it steady.
|
||||
ACE_player switchCamera "INTERNAL";
|
||||
};
|
||||
|
||||
// Refresh the firemode
|
||||
[] call FUNC(showFireMode);
|
||||
|
||||
// Only start locking on holding tab
|
||||
if(!GVAR(isLockKeyDown)) exitWith { false };
|
||||
|
||||
_range = parseNumber (ctrlText __JavelinIGUIRangefinder);
|
||||
if (_range > 50 && {_range < 2500}) then {
|
||||
_pos = positionCameraToWorld [0,0,_range];
|
||||
_targetArray = _pos nearEntities ["AllVehicles", _range/25];
|
||||
if (count (_targetArray) > 0) then {
|
||||
_newTarget = _targetArray select 0;
|
||||
};
|
||||
};
|
||||
|
||||
if (isNull _newTarget) then {
|
||||
_newTarget = cursorTarget;
|
||||
};
|
||||
|
||||
// Create constants
|
||||
_constraintTop = __ConstraintTop;
|
||||
_constraintLeft = __ConstraintLeft;
|
||||
_constraintBottom = __ConstraintBottom;
|
||||
_constraintRight = __ConstraintRight;
|
||||
|
||||
_offsetX = __OffsetX;
|
||||
_offsetY = __OffsetY;
|
||||
|
||||
__JavelinIGUITargeting ctrlShow true;
|
||||
__JavelinIGUITargetingConstrains ctrlShow true;
|
||||
|
||||
if (isNull _newTarget) then {
|
||||
// No targets found
|
||||
_currentTarget = objNull;
|
||||
_lockTime = 0;
|
||||
|
||||
__JavelinIGUISeek ctrlSetTextColor __ColorGray;
|
||||
__JavelinIGUINFOV ctrlSetTextColor __ColorGreen;
|
||||
__JavelinIGUITargetingGate ctrlShow false;
|
||||
__JavelinIGUITargetingLines ctrlShow false;
|
||||
|
||||
ACE_player setVariable ["ace_missileguidance_target",nil, false];
|
||||
|
||||
// Disallow fire
|
||||
//if (ACE_player ammo "Javelin" > 0 || {ACE_player ammo "ACE_Javelin_Direct" > 0}) then {ACE_player setWeaponReloadingTime //[player, "Javelin", 0.2];};
|
||||
} else {
|
||||
if (_newTarget distance ACE_player < 2500
|
||||
// && {(call CBA_fnc_getFoV) select 1 > 7}
|
||||
// && { (currentVisionMode ACE_player == 2)}
|
||||
) then {
|
||||
// Lock on after 3 seconds
|
||||
if(_currentTarget != _newTarget) then {
|
||||
TRACE_1("New Target, reseting locking", _newTarget);
|
||||
_lockTime = diag_tickTime;
|
||||
_currentTarget = _newTarget;
|
||||
|
||||
playSound "ACE_Javelin_Locking";
|
||||
} else {
|
||||
if(diag_tickTime - _lockTime > __LOCKONTIME) then {
|
||||
TRACE_2("LOCKED!", _currentTarget, _lockTime);
|
||||
|
||||
__JavelinIGUISeek ctrlSetTextColor __ColorGreen;
|
||||
__JavelinIGUINFOV ctrlSetTextColor __ColorNull;
|
||||
__JavelinIGUITargeting ctrlShow true;
|
||||
__JavelinIGUITargetingConstrains ctrlShow true;
|
||||
__JavelinIGUITargetingGate ctrlShow true;
|
||||
__JavelinIGUITargetingLines ctrlShow true;
|
||||
|
||||
_zamerny = if (_currentTarget isKindOf "CAManBase") then {_currentTarget selectionPosition "body"} else {_currentTarget selectionPosition "zamerny"};
|
||||
_randomPosWithinBounds = [(_zamerny select 0) + 1 - (random 2.0),(_zamerny select 1) + 1 - (random 2.0),(_zamerny select 2) + 0.5 - (random 1.0)];
|
||||
|
||||
_apos = worldToScreen (_currentTarget modelToWorld _randomPosWithinBounds);
|
||||
|
||||
_aposX = 0;
|
||||
_aposY = 0;
|
||||
if (count _apos < 2) then {
|
||||
_aposX = 1;
|
||||
_aposY = 0;
|
||||
} else {
|
||||
_aposX = (_apos select 0) + _offsetX;
|
||||
_aposY = (_apos select 1) + _offsetY;
|
||||
};
|
||||
|
||||
// Move target marker to coords.
|
||||
__JavelinIGUITargetingLineV ctrlSetPosition [_aposX,ctrlPosition __JavelinIGUITargetingLineV select 1];
|
||||
__JavelinIGUITargetingLineH ctrlSetPosition [ctrlPosition __JavelinIGUITargetingLineH select 0,_aposY];
|
||||
{_x ctrlCommit __TRACKINTERVAL} forEach [__JavelinIGUITargetingLineH,__JavelinIGUITargetingLineV];
|
||||
|
||||
_boundsInput = if (_currentTarget isKindOf "CAManBase") then {
|
||||
[_currentTarget,[-1,-1,-2],_currentTarget selectionPosition "body"];
|
||||
} else {
|
||||
[_currentTarget,[-1,-1,-2],_currentTarget selectionPosition "zamerny"];
|
||||
};
|
||||
|
||||
_bpos = _boundsInput call EFUNC(common,worldToScreenBounds);
|
||||
|
||||
_minX = ((_bpos select 0) + _offsetX) max _constraintLeft;
|
||||
_minY = ((_bpos select 1) + _offsetY) max _constraintTop;
|
||||
_maxX = ((_bpos select 2) + _offsetX) min (_constraintRight - 0.025*(3/4)*SafezoneH);
|
||||
_maxY = ((_bpos select 3) + _offsetY) min (_constraintBottom - 0.025*SafezoneH);
|
||||
|
||||
TRACE_4("", _boundsInput, _bpos, _minX, _minY);
|
||||
|
||||
__JavelinIGUITargetingGateTL ctrlSetPosition [_minX,_minY];
|
||||
__JavelinIGUITargetingGateTR ctrlSetPosition [_maxX,_minY];
|
||||
__JavelinIGUITargetingGateBL ctrlSetPosition [_minX,_maxY];
|
||||
__JavelinIGUITargetingGateBR ctrlSetPosition [_maxX,_maxY];
|
||||
|
||||
{_x ctrlCommit __TRACKINTERVAL} forEach [__JavelinIGUITargetingGateTL,__JavelinIGUITargetingGateTR,__JavelinIGUITargetingGateBL,__JavelinIGUITargetingGateBR];
|
||||
|
||||
ACE_player setVariable["ace_missileguidance_target", _currentTarget, false];
|
||||
|
||||
if(diag_tickTime > _soundTime) then {
|
||||
playSound "ACE_Javelin_Locked";
|
||||
_soundTime = diag_tickTime + 0.25;
|
||||
};
|
||||
} else {
|
||||
__JavelinIGUITargeting ctrlShow true;
|
||||
__JavelinIGUITargetingGate ctrlShow true;
|
||||
__JavelinIGUITargetingLines ctrlShow false;
|
||||
|
||||
ACE_player setVariable["ace_missileguidance_target", nil, false];
|
||||
|
||||
_boundsInput = if (_currentTarget isKindOf "CAManBase") then {
|
||||
[_newTarget,[-1,-1,-2],_currentTarget selectionPosition "body"];
|
||||
} else {
|
||||
[_newTarget,[-1,-1,-1],_currentTarget selectionPosition "zamerny"];
|
||||
};
|
||||
|
||||
_bpos = _boundsInput call EFUNC(common,worldToScreenBounds);
|
||||
|
||||
_minX = ((_bpos select 0) + _offsetX) max _constraintLeft;
|
||||
_minY = ((_bpos select 1) + _offsetY) max _constraintTop;
|
||||
_maxX = ((_bpos select 2) + _offsetX) min (_constraintRight - 0.025*(3/4)*SafezoneH);
|
||||
_maxY = ((_bpos select 3) + _offsetY) min (_constraintBottom - 0.025*SafezoneH);
|
||||
|
||||
__JavelinIGUITargetingGateTL ctrlSetPosition [_minX,_minY];
|
||||
__JavelinIGUITargetingGateTR ctrlSetPosition [_maxX,_minY];
|
||||
__JavelinIGUITargetingGateBL ctrlSetPosition [_minX,_maxY];
|
||||
__JavelinIGUITargetingGateBR ctrlSetPosition [_maxX,_maxY];
|
||||
|
||||
{_x ctrlCommit __TRACKINTERVAL} forEach [__JavelinIGUITargetingGateTL,__JavelinIGUITargetingGateTR,__JavelinIGUITargetingGateBL,__JavelinIGUITargetingGateBR];
|
||||
|
||||
if(diag_tickTime > _soundTime) then {
|
||||
playSound "ACE_Javelin_Locking";
|
||||
_soundTime = diag_tickTime + 0.25;
|
||||
};
|
||||
};
|
||||
};
|
||||
} else {
|
||||
// Something is wrong with our seek
|
||||
_currentTarget = objNull;
|
||||
|
||||
__JavelinIGUISeek ctrlSetTextColor __ColorGray;
|
||||
__JavelinIGUINFOV ctrlSetTextColor __ColorGray;
|
||||
__JavelinIGUITargetingConstrains ctrlShow false;
|
||||
__JavelinIGUITargetingGate ctrlShow false;
|
||||
__JavelinIGUITargetingLines ctrlShow false;
|
||||
|
||||
ACE_player setVariable ["ace_missileguidance_target",nil, false];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
//TRACE_2("", _newTarget, _currentTarget);
|
||||
|
||||
// Save arguments for next run
|
||||
_args set[0, diag_tickTime];
|
||||
_args set[1, _currentTarget];
|
||||
_args set[2, _runTime];
|
||||
_args set[3, _lockTime];
|
||||
_args set[4, _soundTime];
|
||||
|
||||
uiNamespace setVariable[QGVAR(arguments), _args ];
|
@ -11,6 +11,11 @@ ACE_player setVariable ["ace_missileguidance_target",nil, false];
|
||||
__JavelinIGUISeek ctrlSetTextColor __ColorGray;
|
||||
__JavelinIGUINFOV ctrlSetTextColor __ColorGray;
|
||||
|
||||
__JavelinIGUITargeting ctrlShow false;
|
||||
__JavelinIGUITargetingConstrains ctrlShow false;
|
||||
__JavelinIGUITargetingGate ctrlShow false;
|
||||
__JavelinIGUITargetingLines ctrlShow false;
|
||||
|
||||
uiNameSpace setVariable [QGVAR(arguments),
|
||||
[
|
||||
0, // Last runtime
|
1
addons/javelin/functions/script_component.hpp
Normal file
1
addons/javelin/functions/script_component.hpp
Normal file
@ -0,0 +1 @@
|
||||
#include "\z\ace\addons\javelin\script_component.hpp"
|
@ -1,6 +1,6 @@
|
||||
// by commy2
|
||||
|
||||
["ACE3", QGVAR(lockTarget), localize "STR_ACE_WEP_JAVELIN_LockTarget",
|
||||
["ACE3", QGVAR(lockTarget), localize "STR_ACE_JAVELIN_LockTarget",
|
||||
{
|
||||
if (GETGVAR(isLockKeyDown,false)) exitWith {false};
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
},
|
||||
[15, [false, false, false]], false] call cba_fnc_addKeybind; //Tab Key
|
||||
|
||||
["ACE3", QGVAR(cycleFireMode), localize "STR_ACE_WEP_JAVELIN_CycleFireMode",
|
||||
["ACE3", QGVAR(cycleFireMode), localize "STR_ACE_JAVELIN_CycleFireMode",
|
||||
{ false },
|
||||
{
|
||||
[ACE_player] call FUNC(cycleFireMode);
|
@ -1,12 +1,12 @@
|
||||
#define COMPONENT wep_javelin
|
||||
#define COMPONENT javelin
|
||||
#include "\z\ace\Addons\main\script_mod.hpp"
|
||||
|
||||
#ifdef DEBUG_ENABLED_WEP_JAVELIN
|
||||
#ifdef DEBUG_ENABLED_JAVELIN
|
||||
#define DEBUG_MODE_FULL
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_SETTINGS_WEP_JAVELIN
|
||||
#define DEBUG_SETTINGS DEBUG_SETTINGS_WEP_JAVELIN
|
||||
#ifdef DEBUG_SETTINGS_JAVELIN
|
||||
#define DEBUG_SETTINGS DEBUG_SETTINGS_JAVELIN
|
||||
#endif
|
||||
|
||||
#include "\z\ace\Addons\main\script_macros.hpp"
|
||||
@ -19,6 +19,8 @@
|
||||
#define __JavelinIGUI (uinamespace getVariable "ACE_RscOptics_javelin")
|
||||
|
||||
// Custom controls
|
||||
#define __JavelinIGUITargeting (__JavelinIGUI displayCtrl 6999)
|
||||
|
||||
#define __JavelinIGUISeek (__JavelinIGUI displayCtrl 699000)
|
||||
#define __JavelinIGUITop (__JavelinIGUI displayCtrl 699001)
|
||||
#define __JavelinIGUIDir (__JavelinIGUI displayCtrl 699002)
|
||||
@ -51,10 +53,6 @@
|
||||
#define __ConstraintLeft (((ctrlPosition __JavelinIGUITargetingConstrainLeft) select 0) + ((ctrlPosition (__JavelinIGUITargetingConstrainLeft)) select 2))
|
||||
#define __ConstraintRight ((ctrlPosition __JavelinIGUITargetingConstrainRight) select 0)
|
||||
|
||||
#define __OffsetX ((ctrlPosition __JavelinIGUITargetingLineV) select 0) - 0.5
|
||||
#define __OffsetY ((ctrlPosition __JavelinIGUITargetingLineH) select 1) - 0.5
|
||||
|
||||
|
||||
// Colors for controls
|
||||
#define __ColorOrange [0.9255,0.5216,0.1216,1]
|
||||
#define __ColorGreen [0.2941,0.8745,0.2157,1]
|
24
addons/javelin/stringtable.xml
Normal file
24
addons/javelin/stringtable.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Edited with tabler - 2014-12-19 -->
|
||||
<Project name="ACE">
|
||||
<Package name="JAVELIN">
|
||||
<Key ID="STR_ACE_JAVELIN_LockTarget">
|
||||
<English>Lock Target (Javelin)</English>
|
||||
<German></German>
|
||||
<French></French>
|
||||
<Polish></Polish>
|
||||
<Czech></Czech>
|
||||
<Spanish></Spanish>
|
||||
<Russian></Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_JAVELIN_CycleFireMode">
|
||||
<English>Cycle Attack Mode (Javelin)</English>
|
||||
<German></German>
|
||||
<French></French>
|
||||
<Polish></Polish>
|
||||
<Czech></Czech>
|
||||
<Spanish></Spanish>
|
||||
<Russian></Russian>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
@ -1,29 +1,29 @@
|
||||
class CfgVehicles {
|
||||
class Helicopter_Base_F;
|
||||
class UAV_01_base_F: Helicopter_Base_F {
|
||||
class ACE_Actions {
|
||||
class ACE_MainActions {
|
||||
class GVAR(RefuelUAV) {
|
||||
displayName = "$STR_ACE_logistics_uavbattery_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; \
|
||||
icon = QUOTE(PATHTOF(ui\UAV_battery.paa));
|
||||
class Helicopter_Base_F;
|
||||
class UAV_01_base_F: Helicopter_Base_F {
|
||||
class ACE_Actions {
|
||||
class ACE_MainActions {
|
||||
class GVAR(RefuelUAV) {
|
||||
displayName = "$STR_ACE_logistics_uavbattery_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; \
|
||||
icon = QUOTE(PATHTOF(ui\UAV_battery_ca.paa));
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
// Misc box content
|
||||
class Box_NATO_Support_F;
|
||||
class ACE_Box_Misc: Box_NATO_Support_F {
|
||||
class TransportItems {
|
||||
class _xx_ACE_UAVBattery {
|
||||
count = 6;
|
||||
name = "ACE_UAVBattery";
|
||||
};
|
||||
// Misc box content
|
||||
class Box_NATO_Support_F;
|
||||
class ACE_Box_Misc: Box_NATO_Support_F {
|
||||
class TransportItems {
|
||||
class _xx_ACE_UAVBattery {
|
||||
count = 6;
|
||||
name = "ACE_UAVBattery";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,15 +1,15 @@
|
||||
class CfgWeapons {
|
||||
class InventoryItem_Base_F;
|
||||
class ACE_ItemCore;
|
||||
class InventoryItem_Base_F;
|
||||
class ACE_ItemCore;
|
||||
|
||||
class ACE_UAVBattery: ACE_ItemCore {
|
||||
scope = 2;
|
||||
displayName = "$STR_ACE_logistics_uavbattery_Battery_Name";
|
||||
descriptionShort = "$STR_ACE_logistics_uavbattery_Battery_Description";
|
||||
model = QUOTE(PATHTOF(models\ace_battery.p3d));
|
||||
picture = QUOTE(PATHTOF(ui\UAV_battery.paa));
|
||||
class ItemInfo: InventoryItem_Base_F {
|
||||
mass = 20;
|
||||
class ACE_UAVBattery: ACE_ItemCore {
|
||||
scope = 2;
|
||||
displayName = "$STR_ACE_logistics_uavbattery_Battery_Name";
|
||||
descriptionShort = "$STR_ACE_logistics_uavbattery_Battery_Description";
|
||||
model = QUOTE(PATHTOF(models\ace_battery.p3d));
|
||||
picture = QUOTE(PATHTOF(ui\UAV_battery_ca.paa));
|
||||
class ItemInfo: InventoryItem_Base_F {
|
||||
mass = 20;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
Binary file not shown.
BIN
addons/logistics_uavbattery/ui/UAV_battery_ca.paa
Normal file
BIN
addons/logistics_uavbattery/ui/UAV_battery_ca.paa
Normal file
Binary file not shown.
@ -1,15 +1,9 @@
|
||||
class SlotInfo;
|
||||
class MuzzleSlot;
|
||||
|
||||
class CfgWeapons {
|
||||
|
||||
/* MX */
|
||||
|
||||
class Rifle;
|
||||
class Rifle_Base_F: Rifle {
|
||||
class WeaponSlotsInfo;
|
||||
};
|
||||
|
||||
class Rifle_Base_F;
|
||||
class arifle_MX_Base_F: Rifle_Base_F {
|
||||
magazines[] += {
|
||||
"ACE_30Rnd_65x39_caseless_mag_Tracer_Dim",
|
||||
@ -18,12 +12,6 @@ class CfgWeapons {
|
||||
"100Rnd_65x39_caseless_mag",
|
||||
"100Rnd_65x39_caseless_mag_Tracer"
|
||||
};
|
||||
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_H"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class arifle_MX_SW_F: arifle_MX_Base_F {
|
||||
@ -31,14 +19,6 @@ class CfgWeapons {
|
||||
"30Rnd_65x39_caseless_mag",
|
||||
"30Rnd_65x39_caseless_mag_Tracer"
|
||||
};
|
||||
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
// Shit is broken again
|
||||
//compatibleItems[] += {"ACE_muzzle_mzls_H"};
|
||||
compatibleItems[] = {"muzzle_snds_H","muzzle_snds_H_SW","ACE_muzzle_mzls_H"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class arifle_MXM_F: arifle_MX_Base_F {
|
||||
@ -57,51 +37,6 @@ class CfgWeapons {
|
||||
"ACE_30Rnd_65x39_caseless_green_mag_SD",
|
||||
"ACE_30Rnd_65x39_caseless_green_mag_AP"
|
||||
};
|
||||
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_H"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/* Other */
|
||||
|
||||
class Rifle_Long_Base_F: Rifle_Base_F {
|
||||
class WeaponSlotsInfo;
|
||||
};
|
||||
|
||||
class EBR_base_F: Rifle_Long_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_B"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class DMR_01_base_F: Rifle_Long_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_B"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class LMG_Mk200_F: Rifle_Long_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_H"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class LMG_Zafir_F: Rifle_Long_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_B"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -113,12 +48,6 @@ class CfgWeapons {
|
||||
"ACE_30Rnd_556x45_Stanag_SD",
|
||||
"ACE_30Rnd_556x45_Stanag_AP"
|
||||
};
|
||||
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_L"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class mk20_base_F: Rifle_Base_F {
|
||||
@ -127,12 +56,6 @@ class CfgWeapons {
|
||||
"ACE_30Rnd_556x45_Stanag_SD",
|
||||
"ACE_30Rnd_556x45_Stanag_AP"
|
||||
};
|
||||
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_L"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -146,81 +69,6 @@ class CfgWeapons {
|
||||
};
|
||||
};
|
||||
|
||||
class pdw2000_base_F: Rifle_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_smg_02"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class SMG_01_Base: Rifle_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_smg_01"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class SMG_02_base_F: Rifle_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_smg_02"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/* Pistols */
|
||||
|
||||
class Pistol;
|
||||
class Pistol_Base_F: Pistol {
|
||||
class WeaponSlotsInfo;
|
||||
};
|
||||
|
||||
class hgun_P07_F: Pistol_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
linkProxy = "\A3\data_f\proxies\weapon_slots\MUZZLE";
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_smg_02"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class hgun_Rook40_F: Pistol_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
linkProxy = "\A3\data_f\proxies\weapon_slots\MUZZLE";
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_smg_02"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class hgun_ACPC2_F: Pistol_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_smg_01"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class hgun_Pistol_heavy_01_F: Pistol_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot: MuzzleSlot {
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_smg_01"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/*class hgun_Pistol_heavy_02_F: Pistol_Base_F {
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
class MuzzleSlot {
|
||||
linkProxy = "\A3\data_f\proxies\weapon_slots\MUZZLE";
|
||||
compatibleItems[] += {"ACE_muzzle_mzls_smg_01"};
|
||||
};
|
||||
};
|
||||
};*/
|
||||
|
||||
|
||||
/* Silencers */
|
||||
|
||||
|
@ -5,7 +5,7 @@ class CfgVehicles {
|
||||
class Turrets {
|
||||
class MainTurret;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class ACE_Comanche_Test : B_Heli_Attack_01_F {
|
||||
displayName = "ACE_Comanche_Test";
|
||||
|
@ -230,6 +230,7 @@ class CfgWeapons {
|
||||
class Snip: Snip {
|
||||
modelOptics[] = {QUOTE(PATHTOF(models\ace_optics_pip.p3d)),QUOTE(PATHTOF(models\ace_optics_pip.p3d))};
|
||||
};
|
||||
class Iron: Iron {};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -3,7 +3,6 @@
|
||||
<Project name="ACE">
|
||||
<Package name="Optics">
|
||||
<Key ID="STR_ACE_optic_hamr">
|
||||
<Original>RCO (2D)</Original>
|
||||
<English>RCO (2D)</English>
|
||||
<Czech>RCO (2D)</Czech>
|
||||
<French>RCO (2D)</French>
|
||||
@ -16,7 +15,6 @@
|
||||
</Key>
|
||||
|
||||
<Key ID="STR_ACE_optic_hamr_pip">
|
||||
<Original>RCO (PIP)</Original>
|
||||
<English>RCO (PIP)</English>
|
||||
<Czech>RCO (PIP)</Czech>
|
||||
<French>RCO (PIP)</French>
|
||||
@ -29,7 +27,6 @@
|
||||
</Key>
|
||||
|
||||
<Key ID="STR_ACE_optic_arco">
|
||||
<Original>ARCO (2D)</Original>
|
||||
<English>ARCO (2D)</English>
|
||||
<Czech>ARCO (2D)</Czech>
|
||||
<French>ARCO (2D)</French>
|
||||
@ -42,7 +39,6 @@
|
||||
</Key>
|
||||
|
||||
<Key ID="STR_ACE_optic_arco_pip">
|
||||
<Original>ARCO (PIP)</Original>
|
||||
<English>ARCO (PIP)</English>
|
||||
<Czech>ARCO (PIP)</Czech>
|
||||
<French>ARCO (PIP)</French>
|
||||
@ -55,7 +51,6 @@
|
||||
</Key>
|
||||
|
||||
<Key ID="STR_ACE_optic_valdada">
|
||||
<Original>MRCO (2D)</Original>
|
||||
<English>MRCO (2D)</English>
|
||||
<Czech>MRCO (2D)</Czech>
|
||||
<French>MRCO (2D)</French>
|
||||
@ -68,7 +63,6 @@
|
||||
</Key>
|
||||
|
||||
<Key ID="STR_ACE_optic_valdada_pip">
|
||||
<Original>MRCO (PIP)</Original>
|
||||
<English>MRCO (PIP)</English>
|
||||
<Czech>MRCO (PIP)</Czech>
|
||||
<French>MRCO (PIP)</French>
|
||||
@ -81,7 +75,6 @@
|
||||
</Key>
|
||||
|
||||
<Key ID="STR_ACE_optic_sos">
|
||||
<Original>MOS (2D)</Original>
|
||||
<English>MOS (2D)</English>
|
||||
<Czech>MOS (2D)</Czech>
|
||||
<French>MOS (2D)</French>
|
||||
@ -94,7 +87,6 @@
|
||||
</Key>
|
||||
|
||||
<Key ID="STR_ACE_optic_sos_pip">
|
||||
<Original>MOS (PIP)</Original>
|
||||
<English>MOS (PIP)</English>
|
||||
<Czech>MOS (PIP)</Czech>
|
||||
<French>MOS (PIP)</French>
|
||||
@ -107,7 +99,6 @@
|
||||
</Key>
|
||||
|
||||
<Key ID="STR_ACE_optic_lrps">
|
||||
<Original>LRPS (2D)</Original>
|
||||
<English>LRPS (2D)</English>
|
||||
<Czech>LRPS (2D)</Czech>
|
||||
<French>LRPS (2D)</French>
|
||||
@ -120,7 +111,6 @@
|
||||
</Key>
|
||||
|
||||
<Key ID="STR_ACE_optic_lrps_pip">
|
||||
<Original>LRPS (PIP)</Original>
|
||||
<English>LRPS (PIP)</English>
|
||||
<Czech>LRPS (PIP)</Czech>
|
||||
<French>LRPS (PIP)</French>
|
||||
|
@ -13,16 +13,16 @@ class CfgVehicles {
|
||||
icon = QUOTE(PATHTOF(UI\spare_barrel_ca.paa));
|
||||
hotkey = "B";
|
||||
};
|
||||
};
|
||||
class ACE_CheckTemperature {
|
||||
displayName = "$STR_ACE_Overheating_CheckTemperatureShort";
|
||||
condition = "switch (currentWeapon _player) do {case (''): {false}; case (primaryWeapon _player); case (secondaryWeapon _player); case (handgunWeapon _player): {true}; default {false}}";
|
||||
exceptions[] = {"isNotInside"};
|
||||
statement = QUOTE( [ARR_2(_player, currentWeapon _player)] call FUNC(CheckTemperature); );
|
||||
showDisabled = 0;
|
||||
priority = 3.1;
|
||||
icon = QUOTE(PATHTOF(UI\temp_ca.paa));
|
||||
hotkey = "P";
|
||||
class ACE_CheckTemperature {
|
||||
displayName = "$STR_ACE_Overheating_CheckTemperatureShort";
|
||||
condition = "switch (currentWeapon _player) do {case (''): {false}; case (primaryWeapon _player); case (secondaryWeapon _player); case (handgunWeapon _player): {true}; default {false}}";
|
||||
exceptions[] = {"isNotInside"};
|
||||
statement = QUOTE( [ARR_2(_player, currentWeapon _player)] call FUNC(CheckTemperature); );
|
||||
showDisabled = 0;
|
||||
priority = 2.9;
|
||||
icon = QUOTE(PATHTOF(UI\temp_ca.paa));
|
||||
hotkey = "P";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -119,16 +119,8 @@
|
||||
<Russian>Проверить температуру оружия</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Overheating_CheckTemperatureShort">
|
||||
<English>Check<br/>temperature</English>
|
||||
<German>Temperatur<br/>prüfen</German>
|
||||
<Spanish>Verificar<br/>temperatura</Spanish>
|
||||
<Polish>Sprawdź<br/>temperaturę</Polish>
|
||||
<French>Vérifier la<br/>température</French>
|
||||
<Hungarian>Hőmérséklet<br/>ellenőrzése</Hungarian>
|
||||
<Czech>Zjistit<br/>teplotu</Czech>
|
||||
<Portuguese>Conferir<br/>temperatura</Portuguese>
|
||||
<Italian>Controlla la<br/>temperatura</Italian>
|
||||
<Russian>Проверить<br/>температуру</Russian>
|
||||
<English>Check weapon<br/>temperature</English>
|
||||
<Spanish>Verificar temperatura<br/>del arma</Spanish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Overheating_CheckingTemperature">
|
||||
<English>Checking temperature ...</English>
|
||||
|
@ -4,10 +4,12 @@
|
||||
<Package name="Reload">
|
||||
<Key ID="STR_ACE_reload_SettingDisplayTextName">
|
||||
<English>Check ammo on weapon reload</English>
|
||||
<French>Vérifier munitions au rechargement</French>
|
||||
<Spanish>Comprovar munición al recargar el arma</Spanish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_reload_SettingDisplayTextDesc">
|
||||
<English>Check the ammo in your new magazine on magazine reload.</English>
|
||||
<French>Vérifie les munitions disponibles dans le nouveau chargeur</French>
|
||||
<Spanish>Comprueva la munición del nuevo cargador al recargar.</Spanish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Reload_checkAmmo">
|
||||
@ -36,10 +38,12 @@
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Reload_LinkBelt">
|
||||
<English>Link belt</English>
|
||||
<French>Attacher bande</French>
|
||||
<Spanish>Enlazar cinta</Spanish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Reload_LinkingBelt">
|
||||
<English>Linking belt...</English>
|
||||
<French>Attachement de la bande ..</French>
|
||||
<Spanish>Enlazando cinta...</Spanish>
|
||||
</Key>
|
||||
</Package>
|
||||
|
@ -1 +0,0 @@
|
||||
z\ace\addons\wep_javelin
|
@ -1,125 +0,0 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
//TRACE_1("enter", _this);
|
||||
|
||||
#define __TRACKINTERVAL 0.1 // how frequent the check should be.
|
||||
#define __LOCKONTIME 1.85 // Lock on won't occur sooner
|
||||
#define __LOCKONTIMERANDOM 0.3 // Deviation in lock on time
|
||||
#define __SENSORSQUARE 1 // Locking on sensor square side in angles
|
||||
|
||||
private["_args", "_lastTick", "_runTime", "_soundTime", "_lockTime", "_newTarget", "_currentTarget", "_range", "_pos", "_targetArray"];
|
||||
|
||||
// Reset arguments if we havnt rendered in over a second
|
||||
_args = uiNamespace getVariable[QGVAR(arguments), [] ];
|
||||
if( (count _args) > 0) then {
|
||||
_lastTick = _args select 0;
|
||||
if(diag_tickTime - _lastTick > 1) then {
|
||||
[] call FUNC(onOpticLoad);
|
||||
};
|
||||
};
|
||||
|
||||
// Pull the arguments
|
||||
_currentTarget = _args select 1;
|
||||
_runTime = _args select 2;
|
||||
_lockTime = _args select 3;
|
||||
_soundTime = _args select 4;
|
||||
|
||||
// Find a target within the optic range
|
||||
_newTarget = objNull;
|
||||
|
||||
// Bail on fast movement
|
||||
if ((velocity ACE_player) distance [0,0,0] > 0.5 && {cameraView == "GUNNER"} && {cameraOn == ACE_player}) exitWith { // keep it steady.
|
||||
ACE_player switchCamera "INTERNAL";
|
||||
};
|
||||
|
||||
// Refresh the firemode
|
||||
[] call FUNC(showFireMode);
|
||||
|
||||
// Only start locking on holding tab
|
||||
if(!GVAR(isLockKeyDown)) exitWith { false };
|
||||
|
||||
_range = parseNumber (ctrlText __JavelinIGUIRangefinder);
|
||||
if (_range > 50 && {_range < 2500}) then {
|
||||
_pos = positionCameraToWorld [0,0,_range];
|
||||
_targetArray = _pos nearEntities ["AllVehicles", _range/25];
|
||||
if (count (_targetArray) > 0) then {
|
||||
_newTarget = _targetArray select 0;
|
||||
};
|
||||
};
|
||||
|
||||
if (isNull _newTarget) then {
|
||||
_newTarget = cursorTarget;
|
||||
};
|
||||
|
||||
if (isNull _newTarget) then {
|
||||
// No targets found
|
||||
_currentTarget = objNull;
|
||||
_lockTime = 0;
|
||||
|
||||
__JavelinIGUISeek ctrlSetTextColor __ColorGray;
|
||||
__JavelinIGUINFOV ctrlSetTextColor __ColorGreen;
|
||||
__JavelinIGUITargetingConstrains ctrlShow false;
|
||||
__JavelinIGUITargetingGate ctrlShow false;
|
||||
__JavelinIGUITargetingLines ctrlShow false;
|
||||
|
||||
ACE_player setVariable ["ace_missileguidance_target",nil, false];
|
||||
|
||||
// Disallow fire
|
||||
//if (ACE_player ammo "Javelin" > 0 || {ACE_player ammo "ACE_Javelin_Direct" > 0}) then {ACE_player setWeaponReloadingTime //[player, "Javelin", 0.2];};
|
||||
} else {
|
||||
if (_newTarget distance ACE_player < 2500
|
||||
// && {(call CBA_fnc_getFoV) select 1 > 7}
|
||||
// && { (currentVisionMode ACE_player == 2)}
|
||||
) then {
|
||||
// Lock on after 3 seconds
|
||||
if(_currentTarget != _newTarget) then {
|
||||
TRACE_1("New Target, reseting locking", _newTarget);
|
||||
_lockTime = diag_tickTime;
|
||||
_currentTarget = _newTarget;
|
||||
|
||||
playSound "ACE_Javelin_Locking";
|
||||
} else {
|
||||
if(diag_tickTime - _lockTime > 3) then {
|
||||
TRACE_2("LOCKED!", _currentTarget, _lockTime);
|
||||
__JavelinIGUISeek ctrlSetTextColor __ColorGreen;
|
||||
__JavelinIGUINFOV ctrlSetTextColor __ColorNull;
|
||||
__JavelinIGUITargetingConstrains ctrlShow true;
|
||||
|
||||
ACE_player setVariable["ace_missileguidance_target", _currentTarget, false];
|
||||
|
||||
if(diag_tickTime > _soundTime) then {
|
||||
playSound "ACE_Javelin_Locked";
|
||||
_soundTime = diag_tickTime + 0.25;
|
||||
};
|
||||
} else {
|
||||
if(diag_tickTime > _soundTime) then {
|
||||
playSound "ACE_Javelin_Locking";
|
||||
_soundTime = diag_tickTime + 0.25;
|
||||
};
|
||||
};
|
||||
};
|
||||
} else {
|
||||
// Something is wrong with our seek
|
||||
_currentTarget = objNull;
|
||||
|
||||
__JavelinIGUISeek ctrlSetTextColor __ColorGray;
|
||||
__JavelinIGUINFOV ctrlSetTextColor __ColorGray;
|
||||
__JavelinIGUITargetingConstrains ctrlShow false;
|
||||
__JavelinIGUITargetingGate ctrlShow false;
|
||||
__JavelinIGUITargetingLines ctrlShow false;
|
||||
|
||||
ACE_player setVariable ["ace_missileguidance_target",nil, false];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
//TRACE_2("", _newTarget, _currentTarget);
|
||||
|
||||
// Save arguments for next run
|
||||
_args set[0, diag_tickTime];
|
||||
_args set[1, _currentTarget];
|
||||
_args set[2, _runTime];
|
||||
_args set[3, _lockTime];
|
||||
_args set[4, _soundTime];
|
||||
|
||||
uiNamespace setVariable[QGVAR(arguments), _args ];
|
@ -1,20 +0,0 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
TRACE_1("enter", _this);
|
||||
|
||||
_object = _this select 0;
|
||||
_origin = getPosASL _object;
|
||||
_matrix = _this select 1;
|
||||
_xVec = _matrix select 0;
|
||||
_yVec = _matrix select 1;
|
||||
_zVec = _matrix select 2;
|
||||
|
||||
_offset = _this select 2;
|
||||
|
||||
_x = _offset select 0;
|
||||
_y = _offset select 1;
|
||||
_z = _offset select 2;
|
||||
|
||||
_out = (((_xVec vectorMultiply _x) vectorAdd (_yVec vectorMultiply _y)) vectorAdd (_zVec vectorMultiply _z)) vectorAdd _origin;
|
||||
|
||||
_out;
|
@ -1,26 +0,0 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
TRACE_1("enter", _this);
|
||||
|
||||
_object = _this select 0;
|
||||
_origin = getPosASL _object;
|
||||
_matrix = _this select 1;
|
||||
_xVec = _matrix select 0;
|
||||
_yVec = _matrix select 1;
|
||||
_zVec = _matrix select 2;
|
||||
|
||||
_offset = _this select 2;
|
||||
|
||||
_offset = _offset vectorDiff _origin;
|
||||
|
||||
_x = _offset select 0;
|
||||
_y = _offset select 1;
|
||||
_z = _offset select 2;
|
||||
|
||||
_out = [
|
||||
((_xVec select 0)*_x) + ((_xVec select 1)*_y) + ((_xVec select 2)*_z),
|
||||
((_yVec select 0)*_x) + ((_yVec select 1)*_y) + ((_yVec select 2)*_z),
|
||||
((_zVec select 0)*_x) + ((_zVec select 1)*_y) + ((_zVec select 2)*_z)
|
||||
];
|
||||
|
||||
_out;
|
@ -1 +0,0 @@
|
||||
#include "\z\ace\addons\wep_javelin\script_component.hpp"
|
@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Edited with tabler - 2014-12-19 -->
|
||||
<Project name="ACE">
|
||||
<Package name="WEP_JAVELIN">
|
||||
<Key ID="STR_ACE_WEP_JAVELIN_LockTarget">
|
||||
<English>Lock Target (Hold)</English>
|
||||
<German>Lock Target (Hold)</German>
|
||||
<French>Lock Target (Hold)</French>
|
||||
<Polish>Lock Target (Hold)</Polish>
|
||||
<Czech>Lock Target (Hold)</Czech>
|
||||
<Spanish>Fijar objetivo (Mantener)</Spanish>
|
||||
<Russian>Lock Target (Hold)</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_WEP_JAVELIN_CycleFireMode">
|
||||
<English>Cycle Fire Mode</English>
|
||||
<German>Cycle Fire Mode</German>
|
||||
<French>Cycle Fire Mode</French>
|
||||
<Polish>Cycle Fire Mode</Polish>
|
||||
<Czech>Cycle Fire Mode</Czech>
|
||||
<Spanish>Cambiar modo de fuego</Spanish>
|
||||
<Russian>Cycle Fire Mode</Russian>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
828
tools/make64.py
Normal file
828
tools/make64.py
Normal file
@ -0,0 +1,828 @@
|
||||
#!/usr/bin/env python
|
||||
# vim: set fileencoding=utf-8 :
|
||||
|
||||
# make.py
|
||||
# An Arma 3 addon build system
|
||||
|
||||
###############################################################################
|
||||
|
||||
# The MIT License (MIT)
|
||||
|
||||
# Copyright (c) 2013-2014 Ryan Schultz
|
||||
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
###############################################################################
|
||||
|
||||
__version__ = "0.3dev"
|
||||
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] == 2:
|
||||
print("Python 3 is required.")
|
||||
sys.exit(1)
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import shutil
|
||||
import platform
|
||||
import glob
|
||||
import subprocess
|
||||
import hashlib
|
||||
import configparser
|
||||
import json
|
||||
import traceback
|
||||
import time
|
||||
import re
|
||||
|
||||
if sys.platform == "win32":
|
||||
import winreg
|
||||
|
||||
###############################################################################
|
||||
# http://akiscode.com/articles/sha-1directoryhash.shtml
|
||||
# Copyright (c) 2009 Stephen Akiki
|
||||
# MIT License (Means you can do whatever you want with this)
|
||||
# See http://www.opensource.org/licenses/mit-license.php
|
||||
# Error Codes:
|
||||
# -1 -> Directory does not exist
|
||||
# -2 -> General error (see stack traceback)
|
||||
def get_directory_hash(directory):
|
||||
directory_hash = hashlib.sha1()
|
||||
if not os.path.exists (directory):
|
||||
return -1
|
||||
|
||||
try:
|
||||
for root, dirs, files in os.walk(directory):
|
||||
for names in files:
|
||||
path = os.path.join(root, names)
|
||||
try:
|
||||
f = open(path, 'rb')
|
||||
except:
|
||||
# You can't open the file for some reason
|
||||
f.close()
|
||||
continue
|
||||
|
||||
while 1:
|
||||
# Read file in as little chunks
|
||||
buf = f.read(4096)
|
||||
if not buf: break
|
||||
new = hashlib.sha1(buf)
|
||||
directory_hash.update(new.digest())
|
||||
f.close()
|
||||
|
||||
except:
|
||||
# Print the stack traceback
|
||||
traceback.print_exc()
|
||||
return -2
|
||||
|
||||
return directory_hash.hexdigest()
|
||||
|
||||
# Copyright (c) André Burgaud
|
||||
# http://www.burgaud.com/bring-colors-to-the-windows-console-with-python/
|
||||
if sys.platform == "win32":
|
||||
from ctypes import windll, Structure, c_short, c_ushort, byref
|
||||
|
||||
SHORT = c_short
|
||||
WORD = c_ushort
|
||||
|
||||
class COORD(Structure):
|
||||
"""struct in wincon.h."""
|
||||
_fields_ = [
|
||||
("X", SHORT),
|
||||
("Y", SHORT)]
|
||||
|
||||
class SMALL_RECT(Structure):
|
||||
"""struct in wincon.h."""
|
||||
_fields_ = [
|
||||
("Left", SHORT),
|
||||
("Top", SHORT),
|
||||
("Right", SHORT),
|
||||
("Bottom", SHORT)]
|
||||
|
||||
class CONSOLE_SCREEN_BUFFER_INFO(Structure):
|
||||
"""struct in wincon.h."""
|
||||
_fields_ = [
|
||||
("dwSize", COORD),
|
||||
("dwCursorPosition", COORD),
|
||||
("wAttributes", WORD),
|
||||
("srWindow", SMALL_RECT),
|
||||
("dwMaximumWindowSize", COORD)]
|
||||
|
||||
# winbase.h
|
||||
STD_INPUT_HANDLE = -10
|
||||
STD_OUTPUT_HANDLE = -11
|
||||
STD_ERROR_HANDLE = -12
|
||||
|
||||
# wincon.h
|
||||
FOREGROUND_BLACK = 0x0000
|
||||
FOREGROUND_BLUE = 0x0001
|
||||
FOREGROUND_GREEN = 0x0002
|
||||
FOREGROUND_CYAN = 0x0003
|
||||
FOREGROUND_RED = 0x0004
|
||||
FOREGROUND_MAGENTA = 0x0005
|
||||
FOREGROUND_YELLOW = 0x0006
|
||||
FOREGROUND_GREY = 0x0007
|
||||
FOREGROUND_INTENSITY = 0x0008 # foreground color is intensified.
|
||||
|
||||
BACKGROUND_BLACK = 0x0000
|
||||
BACKGROUND_BLUE = 0x0010
|
||||
BACKGROUND_GREEN = 0x0020
|
||||
BACKGROUND_CYAN = 0x0030
|
||||
BACKGROUND_RED = 0x0040
|
||||
BACKGROUND_MAGENTA = 0x0050
|
||||
BACKGROUND_YELLOW = 0x0060
|
||||
BACKGROUND_GREY = 0x0070
|
||||
BACKGROUND_INTENSITY = 0x0080 # background color is intensified.
|
||||
|
||||
stdout_handle = windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
|
||||
SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute
|
||||
GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo
|
||||
|
||||
def get_text_attr():
|
||||
"""Returns the character attributes (colors) of the console screen
|
||||
buffer."""
|
||||
csbi = CONSOLE_SCREEN_BUFFER_INFO()
|
||||
GetConsoleScreenBufferInfo(stdout_handle, byref(csbi))
|
||||
return csbi.wAttributes
|
||||
|
||||
def set_text_attr(color):
|
||||
"""Sets the character attributes (colors) of the console screen
|
||||
buffer. Color is a combination of foreground and background color,
|
||||
foreground and background intensity."""
|
||||
SetConsoleTextAttribute(stdout_handle, color)
|
||||
###############################################################################
|
||||
|
||||
def find_bi_tools(work_drive):
|
||||
"""Find BI tools."""
|
||||
|
||||
reg = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER)
|
||||
try:
|
||||
k = winreg.OpenKey(reg, r"Software\bohemia interactive\arma 3 tools")
|
||||
arma3tools_path = winreg.QueryValueEx(k, "path")[0]
|
||||
winreg.CloseKey(k)
|
||||
except:
|
||||
raise Exception("BadTools","Arma 3 Tools are not installed correctly or the P: drive needs to be created.")
|
||||
|
||||
addonbuilder_path = os.path.join(arma3tools_path, "AddonBuilder", "AddonBuilder.exe")
|
||||
dssignfile_path = os.path.join(arma3tools_path, "DSSignFile", "DSSignFile.exe")
|
||||
dscreatekey_path = os.path.join(arma3tools_path, "DSSignFile", "DSCreateKey.exe")
|
||||
cfgconvert_path = os.path.join(arma3tools_path, "CfgConvert", "CfgConvert.exe")
|
||||
|
||||
if os.path.isfile(addonbuilder_path) and os.path.isfile(dssignfile_path) and os.path.isfile(dscreatekey_path) and os.path.isfile(cfgconvert_path):
|
||||
return [addonbuilder_path, dssignfile_path, dscreatekey_path, cfgconvert_path]
|
||||
else:
|
||||
raise Exception("BadTools","Arma 3 Tools are not installed correctly or the P: drive needs to be created.")
|
||||
|
||||
def find_depbo_tools(regKey):
|
||||
"""Use registry entries to find DePBO-based tools."""
|
||||
stop = False
|
||||
|
||||
if regKey == "HKCU":
|
||||
reg = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER)
|
||||
stop = True
|
||||
else:
|
||||
reg = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
|
||||
|
||||
try:
|
||||
k = winreg.OpenKey(reg, r"Software\Wow6432Node\Mikero\pboProject")
|
||||
try:
|
||||
pboproject_path = winreg.QueryValueEx(k, "exe")[0]
|
||||
winreg.CloseKey(k)
|
||||
print("Found pboproject.")
|
||||
except:
|
||||
print_error("ERROR: Could not find pboProject.")
|
||||
|
||||
k = winreg.OpenKey(reg, r"Software\Wow6432Node\Mikero\rapify")
|
||||
try:
|
||||
rapify_path = winreg.QueryValueEx(k, "exe")[0]
|
||||
winreg.CloseKey(k)
|
||||
print("Found rapify.")
|
||||
except:
|
||||
print_error("Could not find rapify.")
|
||||
|
||||
k = winreg.OpenKey(reg, r"Software\Wow6432Node\Mikero\MakePbo")
|
||||
try:
|
||||
makepbo_path = winreg.QueryValueEx(k, "exe")[0]
|
||||
winreg.CloseKey(k)
|
||||
print("Found makepbo.")
|
||||
except:
|
||||
print_error("Could not find makepbo.")
|
||||
except:
|
||||
if stop == True:
|
||||
raise Exception("BadDePBO", "DePBO tools not installed correctly")
|
||||
return -1
|
||||
|
||||
|
||||
#Strip any quotations from the path due to a MikeRo tool bug which leaves a trailing space in some of its registry paths.
|
||||
return [pboproject_path.strip('"'),rapify_path.strip('"'),makepbo_path.strip('"')]
|
||||
|
||||
def color(color):
|
||||
"""Set the color. Works on Win32 and normal terminals."""
|
||||
if sys.platform == "win32":
|
||||
if color == "green":
|
||||
set_text_attr(FOREGROUND_GREEN | get_text_attr() & 0x0070 | FOREGROUND_INTENSITY)
|
||||
elif color == "red":
|
||||
set_text_attr(FOREGROUND_RED | get_text_attr() & 0x0070 | FOREGROUND_INTENSITY)
|
||||
elif color == "blue":
|
||||
set_text_attr(FOREGROUND_BLUE | get_text_attr() & 0x0070 | FOREGROUND_INTENSITY)
|
||||
elif color == "reset":
|
||||
set_text_attr(FOREGROUND_GREY | get_text_attr() & 0x0070)
|
||||
elif color == "grey":
|
||||
set_text_attr(FOREGROUND_GREY | get_text_attr() & 0x0070)
|
||||
else :
|
||||
if color == "green":
|
||||
sys.stdout.write('\033[92m')
|
||||
elif color == "red":
|
||||
sys.stdout.write('\033[91m')
|
||||
elif color == "blue":
|
||||
sys.stdout.write('\033[94m')
|
||||
elif color == "reset":
|
||||
sys.stdout.write('\033[0m')
|
||||
|
||||
def print_error(msg):
|
||||
color("red")
|
||||
print ("ERROR: " + msg)
|
||||
color("reset")
|
||||
|
||||
def print_green(msg):
|
||||
color("green")
|
||||
print(msg)
|
||||
color("reset")
|
||||
|
||||
def print_blue(msg):
|
||||
color("blue")
|
||||
print(msg)
|
||||
color("reset")
|
||||
|
||||
def print_yellow(msg):
|
||||
color("yellow")
|
||||
print(msg)
|
||||
color("reset")
|
||||
|
||||
###############################################################################
|
||||
|
||||
def main(argv):
|
||||
"""Build an Arma addon suite in a directory from rules in a make.cfg file."""
|
||||
print_blue(("\nmake.py for Arma, v" + __version__))
|
||||
|
||||
if sys.platform != "win32":
|
||||
print_error("Non-Windows platform (Cygwin?). Please re-run from cmd.")
|
||||
sys.exit(1)
|
||||
|
||||
reg = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER)
|
||||
try:
|
||||
k = winreg.OpenKey(reg, r"Software\bohemia interactive\arma 3 tools")
|
||||
arma3tools_path = winreg.QueryValueEx(k, "path")[0]
|
||||
winreg.CloseKey(k)
|
||||
except:
|
||||
raise Exception("BadTools","Arma 3 Tools are not installed correctly or the P: drive needs to be created.")
|
||||
|
||||
# Default behaviors
|
||||
test = False # Copy to Arma 3 directory?
|
||||
arg_modules = False # Only build modules on command line?
|
||||
make_release = False # Make zip file from the release?
|
||||
release_version = 0 # Version of release
|
||||
use_pboproject = True # Default to pboProject build tool
|
||||
make_target = "DEFAULT" # Which section in make.cfg to use for the build
|
||||
new_key = False # Make a new key and use it to sign?
|
||||
quiet = False # Suppress output from build tool?
|
||||
|
||||
# Parse arguments
|
||||
if "help" in argv or "-h" in argv or "--help" in argv:
|
||||
print ("""
|
||||
make.py [help] [test] [force] [key <name>] [target <name>] [release <version>]
|
||||
[module name] [module name] [...]
|
||||
|
||||
test -- Copy result to Arma 3.
|
||||
release <version> -- Make archive with <version>.
|
||||
force -- Ignore cache and build all.
|
||||
target <name> -- Use rules in make.cfg under heading [<name>] rather than
|
||||
default [Make]
|
||||
key <name> -- Use key in working directory with <name> to sign. If it does not
|
||||
exist, create key.
|
||||
quiet -- Suppress command line output from build tool.
|
||||
|
||||
If module names are specified, only those modules will be built.
|
||||
|
||||
Examples:
|
||||
make.py force test
|
||||
Build all modules (ignoring cache) and copy the mod folder to the Arma 3
|
||||
directory.
|
||||
make.py mymodule_gun
|
||||
Only build the module named 'mymodule_gun'.
|
||||
make.py force key MyNewKey release 1.0
|
||||
Build all modules (ignoring cache), sign them with NewKey, and pack them
|
||||
into a zip file for release with version 1.0.
|
||||
|
||||
|
||||
If a file called $NOBIN$ is found in the module directory, that module will not be binarized.
|
||||
|
||||
See the make.cfg file for additional build options.
|
||||
""")
|
||||
sys.exit(0)
|
||||
|
||||
if "force" in argv:
|
||||
argv.remove("force")
|
||||
force_build = True
|
||||
else:
|
||||
force_build = False
|
||||
|
||||
if "test" in argv:
|
||||
test = True
|
||||
argv.remove("test")
|
||||
|
||||
if "release" in argv:
|
||||
make_release = True
|
||||
release_version = argv[argv.index("release") + 1]
|
||||
argv.remove(release_version)
|
||||
argv.remove("release")
|
||||
|
||||
if "target" in argv:
|
||||
make_target = argv[argv.index("target") + 1]
|
||||
argv.remove("target")
|
||||
argv.remove(make_target)
|
||||
force_build = True
|
||||
|
||||
if "key" in argv:
|
||||
new_key = True
|
||||
key_name = argv[argv.index("key") + 1]
|
||||
argv.remove("key")
|
||||
argv.remove(key_name)
|
||||
|
||||
if "quiet" in argv:
|
||||
quiet = True
|
||||
argv.remove("quiet")
|
||||
|
||||
# Get the directory the make script is in.
|
||||
make_root = os.path.dirname(os.path.realpath(__file__))
|
||||
make_root_parent = os.path.abspath(os.path.join(os.getcwd(), os.pardir))
|
||||
os.chdir(make_root)
|
||||
|
||||
# Get latest commit ID
|
||||
try:
|
||||
gitpath = os.path.join(os.path.dirname(make_root), ".git")
|
||||
assert os.path.exists(gitpath)
|
||||
|
||||
commit_id = subprocess.check_output(["git", "rev-parse", "HEAD"])
|
||||
commit_id = str(commit_id, "utf-8")[:8]
|
||||
except:
|
||||
print_error("FAILED TO DETERMINE COMMIT ID.")
|
||||
commit_id = "NOGIT"
|
||||
|
||||
cfg = configparser.ConfigParser();
|
||||
try:
|
||||
cfg.read(os.path.join(make_root, "make.cfg"))
|
||||
|
||||
# Project name (with @ symbol)
|
||||
project = cfg.get(make_target, "project", fallback="@"+os.path.basename(os.getcwd()))
|
||||
|
||||
# Private key path
|
||||
key = cfg.get(make_target, "key", fallback=None)
|
||||
|
||||
# Project prefix (folder path)
|
||||
prefix = cfg.get(make_target, "prefix", fallback="")
|
||||
|
||||
# Should we autodetect modules on a complete build?
|
||||
module_autodetect = cfg.getboolean(make_target, "module_autodetect", fallback=True)
|
||||
|
||||
# Manual list of modules to build for a complete build
|
||||
modules = cfg.get(make_target, "modules", fallback=None)
|
||||
# Parse it out
|
||||
if modules:
|
||||
modules = [x.strip() for x in modules.split(',')]
|
||||
else:
|
||||
modules = []
|
||||
|
||||
# List of directories to ignore when detecting
|
||||
ignore = [x.strip() for x in cfg.get(make_target, "ignore", fallback="release").split(',')]
|
||||
|
||||
# BI Tools work drive on Windows
|
||||
work_drive = cfg.get(make_target, "work_drive", fallback="P:\\")
|
||||
|
||||
# Which build tool should we use?
|
||||
build_tool = cfg.get(make_target, "build_tool", fallback="addonbuilder").lower()
|
||||
|
||||
# Release/build directory, relative to script dir
|
||||
release_dir = cfg.get(make_target, "release_dir", fallback="release")
|
||||
|
||||
# Project PBO file prefix (files are renamed to prefix_name.pbo)
|
||||
pbo_name_prefix = cfg.get(make_target, "pbo_name_prefix", fallback=None)
|
||||
|
||||
# Project module Root
|
||||
module_root_parent = os.path.abspath(os.path.join(os.path.join(work_drive, prefix), os.pardir))
|
||||
module_root = cfg.get(make_target, "module_root", fallback=os.path.join(make_root_parent, "addons"))
|
||||
print_green ("module_root: " + module_root)
|
||||
if (os.path.isdir(module_root)):
|
||||
os.chdir(module_root)
|
||||
else:
|
||||
print_error ("Directory " + module_root + " does not exist.")
|
||||
sys.exit()
|
||||
|
||||
except:
|
||||
raise
|
||||
print_error("Could not parse make.cfg.")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
||||
# See if we have been given specific modules to build from command line.
|
||||
if len(argv) > 1 and not make_release:
|
||||
arg_modules = True
|
||||
modules = argv[1:]
|
||||
|
||||
# Find the tools we need.
|
||||
try:
|
||||
tools = find_bi_tools(work_drive)
|
||||
addonbuilder = tools[0]
|
||||
dssignfile = tools[1]
|
||||
dscreatekey = tools[2]
|
||||
cfgconvert = tools[3]
|
||||
|
||||
except:
|
||||
print_error("Arma 3 Tools are not installed correctly or the P: drive has not been created.")
|
||||
sys.exit(1)
|
||||
|
||||
if build_tool == "pboproject":
|
||||
try:
|
||||
depbo_tools = find_depbo_tools("HKLM")
|
||||
if depbo_tools == -1:
|
||||
depbo_tools = find_depbo_tools("HKCU")
|
||||
pboproject = depbo_tools[0]
|
||||
rapifyTool = depbo_tools[1]
|
||||
makepboTool = depbo_tools[2]
|
||||
except:
|
||||
raise
|
||||
print_error("Could not find dePBO tools. Download the needed tools from: https://dev.withsix.com/projects/mikero-pbodll/files")
|
||||
sys.exit(1)
|
||||
|
||||
# Try to open and deserialize build cache file.
|
||||
try:
|
||||
cache = {}
|
||||
with open(os.path.join(make_root, "make.cache"), 'r') as f:
|
||||
cache_raw = f.read()
|
||||
|
||||
cache = json.loads(cache_raw)
|
||||
|
||||
except:
|
||||
print ("No cache found.")
|
||||
cache = {}
|
||||
|
||||
# Get list of subdirs in make root.
|
||||
dirs = next(os.walk(module_root))[1]
|
||||
|
||||
# Autodetect what directories to build.
|
||||
if module_autodetect and not arg_modules:
|
||||
modules = []
|
||||
for path in dirs:
|
||||
# Any dir that has a config.cpp in its root is an addon to build.
|
||||
config_path = os.path.join(path, 'config.cpp')
|
||||
if os.path.isfile(config_path) and not path in ignore:
|
||||
modules.append(path)
|
||||
|
||||
# Make the key specified from command line if necessary.
|
||||
if new_key:
|
||||
if not os.path.isfile(os.path.join(module_root, key_name + ".biprivatekey")):
|
||||
print_green("\nRequested key does not exist.")
|
||||
ret = subprocess.call([dscreatekey, key_name]) # Created in make_root
|
||||
if ret == 0:
|
||||
print_blue("Created: " + os.path.join(module_root, key_name + ".biprivatekey"))
|
||||
else:
|
||||
print_error("Failed to create key!")
|
||||
|
||||
try:
|
||||
print_blue("Copying public key to release directory.")
|
||||
|
||||
try:
|
||||
os.makedirs(os.path.join(module_root, release_dir, "Keys"))
|
||||
except:
|
||||
pass
|
||||
|
||||
shutil.copyfile(os.path.join(module_root, key_name + ".bikey"), os.path.join(module_root, release_dir, "Keys", key_name + ".bikey"))
|
||||
|
||||
except:
|
||||
raise
|
||||
print_error("Could not copy key to release directory.")
|
||||
|
||||
else:
|
||||
print_green("\nNOTE: Using key " + os.path.join(module_root, key_name + ".biprivatekey"))
|
||||
|
||||
key = os.path.join(module_root, key_name + ".biprivatekey")
|
||||
|
||||
|
||||
# For each module, prep files and then build.
|
||||
for module in modules:
|
||||
print_green("\nMaking " + module + "-"*max(1, (60-len(module))))
|
||||
|
||||
# Cache check
|
||||
if module in cache:
|
||||
old_sha = cache[module]
|
||||
else:
|
||||
old_sha = ""
|
||||
|
||||
# Hash the module
|
||||
new_sha = get_directory_hash(os.path.join(module_root, module))
|
||||
|
||||
# Check if it needs rebuilt
|
||||
# print ("Hash:", new_sha)
|
||||
if old_sha == new_sha:
|
||||
if not force_build:
|
||||
print("Module has not changed.")
|
||||
# Skip everything else
|
||||
continue
|
||||
|
||||
# Only do this if the project isn't stored directly on the work drive.
|
||||
# Split the path at the drive name and see if they are on the same drive (usually P:)
|
||||
if os.path.splitdrive(module_root)[0] != os.path.splitdrive(work_drive)[0]:
|
||||
try:
|
||||
# Remove old work drive version (ignore errors)
|
||||
shutil.rmtree(os.path.join(work_drive, prefix, module), True)
|
||||
|
||||
# Copy module to the work drive
|
||||
shutil.copytree(module, os.path.join(work_drive, prefix, module))
|
||||
|
||||
except:
|
||||
raise
|
||||
print_error("ERROR: Could not copy module to work drive. Does the module exist?")
|
||||
input("Press Enter to continue...")
|
||||
print("Resuming build...")
|
||||
continue
|
||||
#else:
|
||||
#print("WARNING: Module is stored on work drive (" + work_drive + ").")
|
||||
|
||||
try:
|
||||
# Remove the old pbo, key, and log
|
||||
old = os.path.join(module_root, release_dir, project, "Addons", module) + "*"
|
||||
files = glob.glob(old)
|
||||
for f in files:
|
||||
os.remove(f)
|
||||
|
||||
if pbo_name_prefix:
|
||||
old = os.path.join(module_root, release_dir, project, "Addons", pbo_name_prefix+module) + "*"
|
||||
files = glob.glob(old)
|
||||
for f in files:
|
||||
os.remove(f)
|
||||
except:
|
||||
raise
|
||||
print_error("ERROR: Could not copy module to work drive. Does the module exist?")
|
||||
input("Press Enter to continue...")
|
||||
print("Resuming build...")
|
||||
continue
|
||||
|
||||
# Build the module into a pbo
|
||||
print_blue("Building: " + os.path.join(work_drive, prefix, module))
|
||||
print_blue("Destination: " + os.path.join(module_root, release_dir, project, "Addons"))
|
||||
|
||||
# Make destination folder (if needed)
|
||||
try:
|
||||
os.makedirs(os.path.join(module_root, release_dir, project, "Addons"))
|
||||
except:
|
||||
pass
|
||||
|
||||
# Run build tool
|
||||
build_successful = False
|
||||
if build_tool == "pboproject":
|
||||
try:
|
||||
#PABST: Convert config (run the macro'd config.cpp through CfgConvert twice to produce a de-macro'd cpp that pboProject can read without fucking up:
|
||||
shutil.copyfile(os.path.join(work_drive, prefix, module, "config.cpp"), os.path.join(work_drive, prefix, module, "config.backup"))
|
||||
|
||||
os.chdir("P:\\")
|
||||
|
||||
cmd = [os.path.join(arma3tools_path, "CfgConvert", "CfgConvert.exe"), "-bin", "-dst", os.path.join(work_drive, prefix, module, "config.bin"), os.path.join(work_drive, prefix, module, "config.cpp")]
|
||||
ret = subprocess.call(cmd)
|
||||
if ret != 0:
|
||||
print_error("CfgConvert -bin return code == " + str(ret))
|
||||
input("Press Enter to continue...")
|
||||
|
||||
cmd = [os.path.join(arma3tools_path, "CfgConvert", "CfgConvert.exe"), "-txt", "-dst", os.path.join(work_drive, prefix, module, "config.cpp"), os.path.join(work_drive, prefix, module, "config.bin")]
|
||||
ret = subprocess.call(cmd)
|
||||
if ret != 0:
|
||||
print_error("CfgConvert -txt) return code == " + str(ret))
|
||||
input("Press Enter to continue...")
|
||||
|
||||
# Include build number
|
||||
try:
|
||||
configpath = os.path.join(work_drive, prefix, module, "config.cpp")
|
||||
f = open(configpath, "r")
|
||||
configtext = f.read()
|
||||
f.close()
|
||||
|
||||
patchestext = re.search(r"class CfgPatches\n\{(.*?)\n\}", configtext, re.DOTALL).group(1)
|
||||
patchestext = re.sub(r'version(.*?)="(.*?)"', r'version\1="\2-{}"'.format(commit_id), patchestext)
|
||||
configtext = re.sub(r"class CfgPatches\n\{(.*?)\n\}", "class CfgPatches\n{"+patchestext+"\n}", configtext, flags=re.DOTALL)
|
||||
|
||||
f = open(configpath, "w")
|
||||
f.write(configtext)
|
||||
f.close()
|
||||
except:
|
||||
raise
|
||||
print_error("Failed to include build number")
|
||||
continue
|
||||
|
||||
if os.path.isfile(os.path.join(work_drive, prefix, module, "$NOBIN$")):
|
||||
print_green("$NOBIN$ Found. Proceeding with non-binarizing!")
|
||||
cmd = [makepboTool, "-P","-A","-L","-N","-G", os.path.join(work_drive, prefix, module),os.path.join(module_root, release_dir, project,"Addons")]
|
||||
|
||||
else:
|
||||
cmd = [pboproject, "-P", os.path.join(work_drive, prefix, module), "+Engine=Arma3", "-S","+Noisy", "+X", "+Clean", "+Mod="+os.path.join(module_root, release_dir, project), "-Key"]
|
||||
|
||||
color("grey")
|
||||
if quiet:
|
||||
devnull = open(os.devnull, 'w')
|
||||
ret = subprocess.call(cmd, stdout=devnull)
|
||||
devnull.close()
|
||||
else:
|
||||
ret = subprocess.call(cmd)
|
||||
color("reset")
|
||||
|
||||
if ret == 0:
|
||||
print_green("pboProject return code == " + str(ret))
|
||||
# Prettyprefix rename the PBO if requested.
|
||||
if pbo_name_prefix:
|
||||
try:
|
||||
os.rename(os.path.join(module_root, release_dir, project, "Addons", module+".pbo"), os.path.join(module_root, release_dir, project, "Addons", pbo_name_prefix+module+".pbo"))
|
||||
except:
|
||||
raise
|
||||
print_error("Could not rename built PBO with prefix.")
|
||||
# Sign result
|
||||
if key:
|
||||
print("Signing with " + key + ".")
|
||||
if pbo_name_prefix:
|
||||
ret = subprocess.call([dssignfile, key, os.path.join(module_root, release_dir, project, "Addons", pbo_name_prefix + module + ".pbo")])
|
||||
else:
|
||||
ret = subprocess.call([dssignfile, key, os.path.join(module_root, release_dir, project, "Addons", module + ".pbo")])
|
||||
|
||||
if ret == 0:
|
||||
build_successful = True
|
||||
else:
|
||||
build_successful = True
|
||||
|
||||
if not build_successful:
|
||||
print_error("pboProject return code == " + str(ret))
|
||||
print_error("Module not successfully built/signed.")
|
||||
input("Press Enter to continue...")
|
||||
print ("Resuming build...")
|
||||
continue
|
||||
|
||||
#PABST: cleanup config BS (you could comment this out to see the "de-macroed" cpp
|
||||
#print_green("\Pabst (restoring): " + os.path.join(work_drive, prefix, module, "config.cpp"))
|
||||
os.remove(os.path.join(work_drive, prefix, module, "config.cpp"))
|
||||
os.remove(os.path.join(work_drive, prefix, module, "config.bin"))
|
||||
os.rename(os.path.join(work_drive, prefix, module, "config.backup"), os.path.join(work_drive, prefix, module, "config.cpp"))
|
||||
|
||||
# Back to the root
|
||||
os.chdir(module_root)
|
||||
|
||||
except:
|
||||
raise
|
||||
print_error("Could not run Addon Builder.")
|
||||
input("Press Enter to continue...")
|
||||
print ("Resuming build...")
|
||||
continue
|
||||
|
||||
elif build_tool== "addonbuilder":
|
||||
# Detect $NOBIN$ and do not binarize if found.
|
||||
if os.path.isfile(os.path.join(work_drive, prefix, module, "$NOBIN$")):
|
||||
do_binarize = False
|
||||
print("$NOBIN$ file found in module, packing only.")
|
||||
else:
|
||||
do_binarize = True
|
||||
try:
|
||||
# Call AddonBuilder
|
||||
os.chdir("P:\\")
|
||||
|
||||
cmd = [addonbuilder, os.path.join(work_drive, prefix, module), os.path.join(make_root, release_dir, project, "Addons"), "-clear", "-project="+work_drive]
|
||||
if not do_binarize:
|
||||
cmd.append("-packonly")
|
||||
|
||||
if quiet:
|
||||
previousDirectory = os.getcwd()
|
||||
os.chdir(arma3tools_path)
|
||||
devnull = open(os.devnull, 'w')
|
||||
ret = subprocess.call(cmd, stdout=devnull)
|
||||
devnull.close()
|
||||
os.chdir(previousDirectory)
|
||||
else:
|
||||
previousDirectory = os.getcwd()
|
||||
os.chdir(arma3tools_path)
|
||||
print_error("Current directory - " + os.getcwd())
|
||||
ret = subprocess.call(cmd)
|
||||
os.chdir(previousDirectory)
|
||||
print_error("Current directory - " + os.getcwd())
|
||||
color("reset")
|
||||
print_green("completed")
|
||||
# Prettyprefix rename the PBO if requested.
|
||||
if pbo_name_prefix:
|
||||
try:
|
||||
os.rename(os.path.join(make_root, release_dir, project, "Addons", module+".pbo"), os.path.join(make_root, release_dir, project, "Addons", pbo_name_prefix+module+".pbo"))
|
||||
except:
|
||||
raise
|
||||
print_error("Could not rename built PBO with prefix.")
|
||||
|
||||
if ret == 0:
|
||||
# Sign result
|
||||
if key:
|
||||
print("Signing with " + key + ".")
|
||||
if pbo_name_prefix:
|
||||
ret = subprocess.call([dssignfile, key, os.path.join(make_root, release_dir, project, "Addons", pbo_name_prefix + module + ".pbo")])
|
||||
else:
|
||||
ret = subprocess.call([dssignfile, key, os.path.join(make_root, release_dir, project, "Addons", module + ".pbo")])
|
||||
|
||||
if ret == 0:
|
||||
build_successful = True
|
||||
else:
|
||||
build_successful = True
|
||||
|
||||
if not build_successful:
|
||||
print_error("Module not successfully built.")
|
||||
|
||||
# Back to the root
|
||||
os.chdir(make_root)
|
||||
|
||||
except:
|
||||
raise
|
||||
print_error("Could not run Addon Builder.")
|
||||
input("Press Enter to continue...")
|
||||
print ("Resuming build...")
|
||||
continue
|
||||
|
||||
else:
|
||||
print_error("Unknown build_tool " + build_tool + "!")
|
||||
|
||||
# Update the hash for a successfully built module
|
||||
if build_successful:
|
||||
cache[module] = new_sha
|
||||
|
||||
# Done building all modules!
|
||||
|
||||
# Write out the cache state
|
||||
cache_out = json.dumps(cache)
|
||||
with open(os.path.join(make_root, "make.cache"), 'w') as f:
|
||||
f.write(cache_out)
|
||||
|
||||
# Delete the pboproject temp files if building a release.
|
||||
if make_release and build_tool == "pboproject":
|
||||
try:
|
||||
shutil.rmtree(os.path.join(module_root, release_dir, project, "temp"), True)
|
||||
except:
|
||||
print_error("ERROR: Could not delete pboProject temp files.")
|
||||
|
||||
print_green("\nDone.")
|
||||
|
||||
# Make release
|
||||
if make_release:
|
||||
print_blue("\nMaking release: " + project + "-" + release_version + ".zip")
|
||||
|
||||
try:
|
||||
# Delete all log files
|
||||
for root, dirs, files in os.walk(os.path.join(module_root, release_dir, project, "Addons")):
|
||||
for currentFile in files:
|
||||
if currentFile.lower().endswith("log"):
|
||||
os.remove(os.path.join(root, currentFile))
|
||||
|
||||
# Create a zip with the contents of release/ in it
|
||||
shutil.make_archive(project + "-" + release_version, "zip", os.path.join(module_root, release_dir))
|
||||
except:
|
||||
raise
|
||||
print_error("Could not make release.")
|
||||
|
||||
# Copy to Arma 3 folder for testing
|
||||
if test:
|
||||
print_blue("\nCopying to Arma 3.")
|
||||
|
||||
if sys.platform == "win32":
|
||||
reg = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
|
||||
try:
|
||||
k = winreg.OpenKey(reg, r"SOFTWARE\Wow6432Node\Bohemia Interactive\Arma 3")
|
||||
a3_path = winreg.EnumValue(k, 1)[1]
|
||||
winreg.CloseKey(k)
|
||||
except:
|
||||
print_error("Could not find Arma 3's directory in the registry.")
|
||||
else:
|
||||
a3_path = cygwin_a3path
|
||||
|
||||
if os.path.exists(a3_path):
|
||||
try:
|
||||
shutil.rmtree(os.path.join(a3_path, project), True)
|
||||
shutil.copytree(os.path.join(module_root, release_dir, project), os.path.join(a3_path, project))
|
||||
except:
|
||||
print_error("Could not copy files. Is Arma 3 running?")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv)
|
||||
input("Press Enter to continue...")
|
Loading…
Reference in New Issue
Block a user