Merge branch 'master' into network_lasers

This commit is contained in:
Nou 2015-04-11 18:36:57 -07:00
commit e4c459132b
89 changed files with 2688 additions and 518 deletions

View File

@ -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

View File

@ -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);

View 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

View File

@ -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

View File

@ -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];
};

View 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]

View File

@ -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>

View File

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

View File

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

View File

@ -0,0 +1,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[] = {};
};
};
};
};
};

View 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;
};
};
};

View 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)

Binary file not shown.

View 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);

View 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;

View 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"

View 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]}}

View 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))}

View 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;

View 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];

View 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);
};

View 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);

View 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

View 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]

View 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;

View 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);

View 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 []}

View File

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

View 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);
};
};
};

View 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"]

View 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>

View File

@ -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
*/

View File

@ -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 {

View File

@ -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
*/

View File

@ -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);

View File

@ -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;
};
};

View File

@ -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];

View File

@ -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 {};

View File

@ -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

View File

@ -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);
};
};
};

View File

@ -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;
};
};

View File

@ -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"};

View File

@ -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

View File

@ -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>

View File

@ -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:

View File

@ -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;

View File

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

View 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};
};
};

View File

@ -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)

View File

@ -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};
};
};
};
};

View File

@ -1,8 +1,5 @@
#include "script_component.hpp"
PREP(translateToWeaponSpace);
PREP(translateToModelSpace);
PREP(lockKeyDown);
PREP(lockKeyUp);

View File

@ -12,4 +12,5 @@ class CfgPatches {
#include "CfgEventhandlers.hpp"
#include "RscInGameUI.hpp"
#include "CfgSounds.hpp"
#include "CfgSounds.hpp"
#include "CfgWeapons.hpp"

View 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 ];

View File

@ -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

View File

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

View File

@ -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);

View File

@ -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]

View 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>

View File

@ -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";
};
};
};
};
};

View File

@ -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.

View File

@ -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 */

View File

@ -5,7 +5,7 @@ class CfgVehicles {
class Turrets {
class MainTurret;
};
}
};
class ACE_Comanche_Test : B_Heli_Attack_01_F {
displayName = "ACE_Comanche_Test";

View File

@ -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 {};
};
};
};

View File

@ -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>

View File

@ -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";
};
};
};
};

View File

@ -119,16 +119,8 @@
<Russian>Проверить температуру оружия</Russian>
</Key>
<Key ID="STR_ACE_Overheating_CheckTemperatureShort">
<English>Check&lt;br/&gt;temperature</English>
<German>Temperatur&lt;br/&gt;prüfen</German>
<Spanish>Verificar&lt;br/&gt;temperatura</Spanish>
<Polish>Sprawdź&lt;br/&gt;temperaturę</Polish>
<French>Vérifier la&lt;br/&gt;température</French>
<Hungarian>Hőmérséklet&lt;br/&gt;ellenőrzése</Hungarian>
<Czech>Zjistit&lt;br/&gt;teplotu</Czech>
<Portuguese>Conferir&lt;br/&gt;temperatura</Portuguese>
<Italian>Controlla la&lt;br/&gt;temperatura</Italian>
<Russian>Проверить&lt;br/&gt;температуру</Russian>
<English>Check weapon&lt;br/&gt;temperature</English>
<Spanish>Verificar temperatura&lt;br/&gt;del arma</Spanish>
</Key>
<Key ID="STR_ACE_Overheating_CheckingTemperature">
<English>Checking temperature ...</English>

View File

@ -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>

View File

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

View File

@ -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 ];

View File

@ -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;

View File

@ -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;

View File

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

View File

@ -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
View 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...")