Merge pull request #123 from KoffeinFlummi/attachToVehicles

Attach to vehicles
This commit is contained in:
PabstMirror 2015-02-08 22:21:38 -06:00
commit 45c9b65bad
16 changed files with 581 additions and 283 deletions

View File

@ -1 +1 @@
z\ace\Addons\laser
z\ace\Addons\attach

View File

@ -1,5 +1,5 @@
class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE( call COMPILE_FILE(XEH_preInit) );
};
class ADDON {
init = QUOTE( call COMPILE_FILE(XEH_preInit) );
};
};

View File

@ -1,10 +1,10 @@
class CfgMagazines {
class CA_Magazine;
class B_IR_Grenade: CA_Magazine {
ACE_Attachable = 1;
};
class SmokeShell;
class Chemlight_green: SmokeShell {
ACE_Attachable = 1;
};
class CA_Magazine;
class B_IR_Grenade: CA_Magazine {
ACE_Attachable = 1;
};
class SmokeShell;
class Chemlight_green: SmokeShell {
ACE_Attachable = 1;
};
};

View File

@ -1,104 +1,147 @@
#define MACRO_ADDITEM(ITEM,COUNT) class _xx_##ITEM { \
name = #ITEM; \
count = COUNT; \
};
name = #ITEM; \
count = COUNT; \
};
#define MACRO_ATTACHTOVEHICLE \
class ACE_Actions { \
class GVAR(AttachVehicle) { \
displayName = "$STR_ACE_Attach_AttachDetach"; \
condition = QUOTE(([ARR_3(_player, _target, '')] call FUNC(canAttach))); \
statement = QUOTE( [ARR_2(_player, _target)] call FUNC(openAttachUI);); \
exceptions[] = {"ACE_Drag_isNotDragging"}; \
showDisabled = 0; \
priority = 0; \
icon = PATHTOF(UI\attach_ca.paa); \
distance = 4; \
}; \
class GVAR(DetachVehicle) { \
displayName = "$STR_ACE_Attach_Detach"; \
condition = QUOTE(([ARR_2(_player, _target)] call FUNC(canDetach))); \
statement = QUOTE( [ARR_2(_player, _target)] call FUNC(detach) ); \
exceptions[] = {"ACE_Drag_isNotDragging"}; \
showDisabled = 0; \
priority = 0; \
icon = PATHTOF(UI\detach_ca.paa); \
distance = 4; \
}; \
};
class CfgVehicles {
class Man;
class CAManBase: Man {
class ACE_SelfActions {
class ACE_Equipment {
class GVAR(Attach) {
displayName = "$STR_ACE_Attach_AttachDetach";
condition = QUOTE( [_player, ''] call FUNC(canAttach) );
statement = QUOTE( [_player] call FUNC(openAttachUI); );
exceptions[] = {"ACE_Drag_isNotDragging"};
showDisabled = 0;
priority = 5;
icon = PATHTOF(UI\attach_ca.paa);
hotkey = "T";
class LandVehicle;
class Car: LandVehicle {
MACRO_ATTACHTOVEHICLE
};
class Tank: LandVehicle {
MACRO_ATTACHTOVEHICLE
};
class Air;
class Helicopter: Air {
MACRO_ATTACHTOVEHICLE
};
class Plane: Air {
MACRO_ATTACHTOVEHICLE
};
class Ship;
class Ship_F: Ship {
MACRO_ATTACHTOVEHICLE
};
class Man;
class CAManBase: Man {
class ACE_SelfActions {
class ACE_Equipment {
class GVAR(Attach) {
displayName = "$STR_ACE_Attach_AttachDetach";
condition = QUOTE(([ARR_3(_player, _player, '')] call FUNC(canAttach)));
statement = QUOTE( [ARR_2(_player, _player)] call FUNC(openAttachUI); );
exceptions[] = {"ACE_Drag_isNotDragging"};
showDisabled = 0;
priority = 5;
icon = PATHTOF(UI\attach_ca.paa);
hotkey = "T";
};
class GVAR(Detach) {
displayName = "$STR_ACE_Attach_Detach";
condition = QUOTE(([ARR_2(_player, _player)] call FUNC(canDetach)));
statement = QUOTE( [ARR_2(_player, _player)] call FUNC(detach) );
exceptions[] = {"ACE_Drag_isNotDragging"};
showDisabled = 0;
priority = 5;
icon = PATHTOF(UI\detach_ca.paa);
hotkey = "T";
};
};
};
class GVAR(Detach) {
displayName = "$STR_ACE_Attach_Detach";
condition = QUOTE( [_player] call FUNC(canDetach) );
statement = QUOTE( [_player] call FUNC(detach) );
exceptions[] = {"ACE_Drag_isNotDragging"};
showDisabled = 0;
priority = 5;
icon = PATHTOF(UI\detach_ca.paa);
hotkey = "T";
};
class All;
class ACE_IR_Strobe_Effect: All {
scope = 1;
displayName = "IR Strobe";
model = "\A3\Weapons_F\empty.p3d";
simulation = "nvmarker";
class NVGMarker {
diffuse[] = {0,0,0};
ambient[] = {0,0,0};
brightness = 0.004;
name = "pozicni blik";
drawLight = 1;
drawLightSize = 0.005;
drawLightCenterSize = 0.003;
activeLight = 0;
blinking=1;
dayLight = 0;
onlyInNvg = 1;
useFlare = 0;
};
};
side = 7;//-1=NO_SIDE yellow box,3=CIV grey box,4=NEUTRAL yellow box,6=FRIENDLY green box,7=LOGIC no radar signature
accuracy = 1000;
cost = 0;
armor = 500;
threat[] = {0,0,0};
nameSound = "";
type = 0;
weapons[] = {};
magazines[] = {};
nvTarget = 1;
destrType = "DestructNo";
brightness = 20;
};
};
class All;
class ACE_IR_Strobe_Effect: All {
scope = 1;
displayName = "IR Strobe";
model = "\A3\Weapons_F\empty.p3d";
simulation = "nvmarker";
class NATO_Box_Base;
class EAST_Box_Base;
class IND_Box_Base;
class FIA_Box_Base_F;
class NVGMarker {
diffuse[] = {0,0,0};
ambient[] = {0,0,0};
brightness = 0.004;
name = "pozicni blik";
drawLight = 1;
drawLightSize = 0.005;
drawLightCenterSize = 0.003;
activeLight = 0;
blinking=1;
dayLight = 0;
onlyInNvg = 1;
useFlare = 0;
class Box_NATO_Support_F: NATO_Box_Base {
class TransportItems {
MACRO_ADDITEM(ACE_IR_Strobe_Item,12)
};
};
side = 7;//-1=NO_SIDE yellow box,3=CIV grey box,4=NEUTRAL yellow box,6=FRIENDLY green box,7=LOGIC no radar signature
accuracy = 1000;
cost = 0;
armor = 500;
threat[] = {0,0,0};
nameSound = "";
type = 0;
weapons[] = {};
magazines[] = {};
nvTarget = 1;
destrType = "DestructNo";
brightness = 20;
};
class NATO_Box_Base;
class EAST_Box_Base;
class IND_Box_Base;
class FIA_Box_Base_F;
class Box_NATO_Support_F: NATO_Box_Base {
class TransportItems {
MACRO_ADDITEM(ACE_IR_Strobe_Item,12)
class Box_East_Support_F: EAST_Box_Base {
class TransportItems {
MACRO_ADDITEM(ACE_IR_Strobe_Item,12)
};
};
};
class Box_East_Support_F: EAST_Box_Base {
class TransportItems {
MACRO_ADDITEM(ACE_IR_Strobe_Item,12)
class Box_IND_Support_F: IND_Box_Base {
class TransportItems {
MACRO_ADDITEM(ACE_IR_Strobe_Item,12)
};
};
};
class Box_IND_Support_F: IND_Box_Base {
class TransportItems {
MACRO_ADDITEM(ACE_IR_Strobe_Item,12)
class Box_FIA_Support_F: FIA_Box_Base_F {
class TransportItems {
MACRO_ADDITEM(ACE_IR_Strobe_Item,12)
};
};
};
class Box_FIA_Support_F: FIA_Box_Base_F {
class TransportItems {
MACRO_ADDITEM(ACE_IR_Strobe_Item,12)
class ACE_Box_Misc: Box_NATO_Support_F {
class TransportItems {
MACRO_ADDITEM(ACE_IR_Strobe_Item,12)
};
};
};
class ACE_Box_Misc: Box_NATO_Support_F {
class TransportItems {
MACRO_ADDITEM(ACE_IR_Strobe_Item,12)
};
};
};

View File

@ -1,16 +1,16 @@
class CfgWeapons {
class ACE_ItemCore;
class InventoryItem_Base_F;
class ACE_ItemCore;
class InventoryItem_Base_F;
class ACE_IR_Strobe_Item: ACE_ItemCore {
displayName = "$STR_ACE_IrStrobe_Name";
descriptionShort = "$STR_ACE_IrStrobe_Description";
model = "\A3\weapons_F\ammo\mag_univ.p3d";
picture = PATHTOF(UI\irstrobe_item.paa);
scope = 2;
ACE_attachable = 1;
class ItemInfo: InventoryItem_Base_F {
mass = 1;
class ACE_IR_Strobe_Item: ACE_ItemCore {
displayName = "$STR_ACE_IrStrobe_Name";
descriptionShort = "$STR_ACE_IrStrobe_Description";
model = "\A3\weapons_F\ammo\mag_univ.p3d";
picture = PATHTOF(UI\irstrobe_item.paa);
scope = 2;
ACE_attachable = 1;
class ItemInfo: InventoryItem_Base_F {
mass = 1;
};
};
};
};

View File

@ -1,7 +1,8 @@
ace_attach
==========
Introducing the ability to attach various throwables to yourself to mark your position and assist in IFF.
Introducing the ability to attach various throwables to yourself or vehicles, to mark your position and assist in IFF.
Adds item `ACE_IR_Strobe_Item`.
## Maintainers
@ -11,3 +12,4 @@ The people responsible for merging changes to this component or answering potent
- [esteldunedain](https://github.com/esteldunedain)
- [bux578](https://github.com/bux578)
- [KoffeinFlummi](https://github.com/KoffeinFlummi)
- [PabstMirror](https://github.com/PabstMirror)

View File

@ -7,5 +7,7 @@ PREP(canAttach);
PREP(canDetach);
PREP(detach);
PREP(openAttachUI);
PREP(placeApprove);
PREP(placeCancel);
ADDON = true;

View File

@ -1,15 +1,15 @@
#include "script_component.hpp"
class CfgPatches {
class ADDON {
units[] = {};
weapons[] = {"ACE_IR_Strobe_Item"};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ace_common", "ace_interaction"};
author[] = {"KoffeinFlummi", "eRazeri", "CAA-Picard"};
authorUrl = "https://github.com/KoffeinFlummi/";
VERSION_CONFIG;
};
class ADDON {
units[] = {};
weapons[] = {"ACE_IR_Strobe_Item"};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ace_common", "ace_interaction"};
author[] = {"KoffeinFlummi", "eRazeri", "CAA-Picard"};
authorUrl = "https://github.com/KoffeinFlummi/";
VERSION_CONFIG;
};
};
#include "CfgEventHandlers.hpp"

View File

@ -1,62 +1,88 @@
/*
* Author: eRazeri and CAA-Picard
* Attach an item to the unit
*
* Arguments:
* 0: unit doing the attach (player) <OBJECT>
* 1: vehicle that it will be attached to (player or vehicle) <OBJECT>
* 2: Name of the attachable item <STRING>
*
* Return Value:
* Nothing
*
* Example:
* Nothing
*
* Public: No
*/
#include "script_component.hpp"
/*
Author: eRazeri and CAA-Picard
PARAMS_3(_unit,_attachToVehicle,_itemName);
Attach an item to the unit
//Sanity Check (_unit has item in inventory, not over attach limit)
if (!([_unit,_attachToVehicle,_itemName] call FUNC(canAttach))) exitWith {ERROR("Tried to attach, but check failed");};
Arguments:
0: unit
1: Item name
_selfAttachPosition = [_unit, [-0.05,0,0.12], "rightshoulder"];
_itemVehClass = "";
_onAtachText = "";
Return Value:
none
*/
private ["_unit", "_itemName", "_attachedItem"];
_unit = _this select 0;
_itemName = _this select 1;
// Check if unit has an attached item
if (_unit getVariable [QGVAR(ItemName), ""] != "") exitWith {};
// Check if the unit still has the item
if !((_itemName in items _unit) or (_itemName in magazines _unit)) exitWith {};
// Attach item
switch true do {
case (_itemName == "ACE_IR_Strobe_Item") : {
_attachedItem = "ACE_IR_Strobe_Effect" createVehicle [0,0,0];
_attachedItem attachTo [_unit,[0,-0.11,0.16],"pilot"];//makes it attach to the head a bit better, shoulder is not good for visibility - eRazeri
[localize "STR_ACE_Attach_IrStrobe_Attached"] call EFUNC(common,displayTextStructured);
};
case (_itemName == "B_IR_Grenade") : {
_attachedItem = "B_IRStrobe" createVehicle [0,0,0];
_attachedItem attachTo [_unit,[-0.05,0,0.12],"rightshoulder"];
[localize "STR_ACE_Attach_IrGrenade_Attached"] call EFUNC(common,displayTextStructured);
};
case (_itemName == "O_IR_Grenade") : {
_attachedItem = "O_IRStrobe" createVehicle [0,0,0];
_attachedItem attachTo [_unit,[-0.05,0,0.12],"rightshoulder"];
[localize "STR_ACE_Attach_IrGrenade_Attached"] call EFUNC(common,displayTextStructured);
};
case (_itemName == "I_IR_Grenade") : {
_attachedItem = "I_IRStrobe" createVehicle [0,0,0];
_attachedItem attachTo [_unit,[-0.05,0,0.12],"rightshoulder"];
[localize "STR_ACE_Attach_IrGrenade_Attached"] call EFUNC(common,displayTextStructured);
};
case (_itemName == "Chemlight_blue" or {_itemName == "Chemlight_green"} or {_itemName == "Chemlight_red"} or {_itemName == "Chemlight_yellow"}) : {
_attachedItem = _itemName createVehicle [0,0,0];
_attachedItem attachTo [_unit,[-0.05,0,0.12],"rightshoulder"];
[localize "STR_ACE_Attach_Chemlight_Attached"] call EFUNC(common,displayTextStructured);;
};
default {
if (true) exitWith {};
};
case (_itemName == "ACE_IR_Strobe_Item"): {
_itemVehClass = "ACE_IR_Strobe_Effect";
_onAtachText = localize "STR_ACE_Attach_IrStrobe_Attached";
_selfAttachPosition = [_unit,[0,-0.11,0.16],"pilot"]; //makes it attach to the head a bit better, shoulder is not good for visibility - eRazeri
};
case (_itemName == "B_IR_Grenade"): {
_itemVehClass = "B_IRStrobe";
_onAtachText = localize "STR_ACE_Attach_IrGrenade_Attached";
};
case (_itemName == "O_IR_Grenade"): {
_itemVehClass = "O_IRStrobe";
_onAtachText = localize "STR_ACE_Attach_IrGrenade_Attached";
};
case (_itemName == "I_IR_Grenade"): {
_itemVehClass = "I_IRStrobe";
_onAtachText = localize "STR_ACE_Attach_IrGrenade_Attached";
};
case (_itemName == "Chemlight_blue" or {_itemName == "Chemlight_green"} or {_itemName == "Chemlight_red"} or {_itemName == "Chemlight_yellow"}): {
_itemVehClass = _itemName;
_onAtachText = localize "STR_ACE_Attach_Chemlight_Attached";
};
};
// Remove item
_unit removeItem _itemName;
_unit setVariable [QGVAR(ItemName), _itemName, true];
_unit setVariable [QGVAR(Item), _attachedItem, true];
if (_itemVehClass == "") exitWith {ERROR("no _itemVehClass for Item");};
if (_unit == _attachToVehicle) then { //Self Attachment
_unit removeItem _itemName; // Remove item
_attachedItem = _itemVehClass createVehicle [0,0,0];
_attachedItem attachTo _selfAttachPosition;
[_onAtachText] call EFUNC(common,displayTextStructured);
_attachToVehicle setVariable ["ACE_AttachedObjects", [_attachedItem], true];
_attachToVehicle setVariable ["ACE_AttachedItemNames", [_itemName], true];
} else {
GVAR(setupObject) = _itemVehClass createVehicleLocal [0,0,-10000];
GVAR(setupObject) enableSimulationGlobal false;
GVAR(SetupPlacmentText) = _onAtachText;
GVAR(SetupPlacmentItem) = _itemName;
GVAR(SetupAttachVehicle) = _attachToVehicle;
GVAR(placer) = _unit;
[_unit, QGVAR(vehAttach), true] call EFUNC(common,setForceWalkStatus);
[QGVAR(PlacementEachFrame),"OnEachFrame", {
private "_player";
_player = ACE_player;
//Stop if player switch or player gets to far from vehicle
if ((GVAR(placer) != _player) || {(_player distance GVAR(SetupAttachVehicle)) > 7}) exitWith {
call FUNC(placeCancel);
};
GVAR(pfeh_running) = true;
_pos = (ASLtoATL eyePos _player) vectorAdd (positionCameraToWorld [0,0,1] vectorDiff positionCameraToWorld [0,0,0]);
GVAR(setupObject) setPosATL _pos;
}] call BIS_fnc_addStackedEventHandler;
//had to delay the mouseHint, not sure why
[{[localize "STR_ACE_Attach_PlaceAction", localize "STR_ACE_Attach_CancelAction"] call EFUNC(interaction,showMouseHint)}, [], 0, 0] call EFUNC(common,waitAndExecute);
_unit setVariable [QGVAR(placeActionEH), [_unit, "DefaultAction", {GVAR(pfeh_running) AND !isNull (GVAR(setupObject))}, {call FUNC(placeApprove);}] call EFUNC(common,AddActionEventHandler)];
_unit setVariable [QGVAR(cancelActionEH), [_unit, "MenuBack", {GVAR(pfeh_running) AND !isNull (GVAR(setupObject))}, {call FUNC(placeCancel);}] call EFUNC(common,AddActionEventHandler)];
};

View File

@ -1,21 +1,25 @@
#include "script_component.hpp"
/*
* Author: commy2
*
* Check if a unit can attach a specific item.
*
* Argument:
* 0: Unit that wants to attach the object (Object)
* 1: Name of the attachable item (String)
*
* Return value:
* Boolean (Bool)
*
* Arguments:
* 0: unit doing the attach (player) <OBJECT>
* 1: vehicle that it will be attached to (player or vehicle) <OBJECT>
* 2: Name of the attachable item <STRING>
*
* Return Value:
* Boolean <BOOL>
*
* Example:
* Nothing
*
* Public: No
*/
#include "script_component.hpp"
private ["_unit", "_item"];
PARAMS_3(_unit,_attachToVehicle,_item);
_unit = _this select 0;
_item = _this select 1;
_attachLimit = if (_unit == _attachToVehicle) then {1} else {10};
_attachedObjects = _attachToVehicle getVariable ["ACE_AttachedObjects", []];
canStand _unit && {_unit getVariable [QGVAR(ItemName), ""] == ""} && {_item in (magazines _unit + items _unit + [""])}
canStand _unit && {alive _attachToVehicle} && {(count _attachedObjects) < _attachLimit} && {_item in ((magazines _unit) + (items _unit) + [""])}

View File

@ -1,19 +1,39 @@
#include "script_component.hpp"
/*
* Author: commy2
*
* Check if a unit has an item attached and if it can remove that item.
*
* Argument:
* 0: Unit that wants to detach something (Object)
*
* Return value:
* Boolean (Bool)
*
* Arguments:
* 0: unit doing the detaching (player) <STRING>
* 1: vehicle that it will be detached from (player or vehicle) <OBJECT>
*
* Return Value:
* Boolean <BOOL>
*
* Example:
* Nothing
*
* Public: No
*/
#include "script_component.hpp"
private "_unit";
private ["_attachedObjects", "_inRange", "_unitPos", "_objectPos"];
_unit = _this select 0;
PARAMS_2(_unit,_attachToVehicle);
canStand _unit && {_unit getVariable [QGVAR(ItemName), ""] != ""}
_attachedObjects = _attachToVehicle getVariable ["ACE_AttachedObjects", []];
_inRange = false;
if (_unit == _attachToVehicle) then {
_inRange = (count _attachedObjects) > 0;
} else {
//Scan if unit is within range (using 2d distance)
_unitPos = getPos _unit;
_unitPos set [2,0];
{
_objectPos = getPos _x;
_objectPos set [2, 0];
if ((_objectPos distance _unitPos) < 4) exitWith {_inRange = true};
} forEach _attachedObjects;
};
(canStand _unit) && _inRange && {alive _attachToVehicle}

View File

@ -1,63 +1,86 @@
/*
* Author: eRazeri and CAA-Picard
* Detach an item from a unit
*
* Arguments:
* 0: unit doing the attaching (player) <STRING>
* 1: vehicle that it will be detached from (player or vehicle) <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* Nothing
*
* Public: No
*/
#include "script_component.hpp"
/*
Author: eRazeri and CAA-Picard
private ["_itemName", "_count", "_attachedItem", "_fnc_detachDelay"];
Detach an item from a unit
PARAMS_2(_unit,_attachToVehicle);
Arguments:
unit
_attachedObjectsArray = _attachToVehicle getVariable ["ACE_AttachedObjects", []];
_attachedItemsArray = _attachToVehicle getVariable ["ACE_AttachedItemNames", []];
Return Value:
none
*/
_attachedObject = objNull;
_attachedIndex = -1;
_itemName = "";
private ["_unit", "_itemName", "_count", "_attachedItem", "_fnc_detachDelay"];
_unit = _this select 0;
_itemName = _unit getVariable [QGVAR(ItemName), ""];
_attachedItem = _unit getVariable [QGVAR(Item), objNull];
//Find closest attached object
_minDistance = 1000;
_unitPos = getPos _unit;
_unitPos set [2,0];
{
_objectPos = getPos _x;
_objectPos set [2, 0];
if ((_objectPos distance _unitPos) < _minDistance) then {
_minDistance = (_objectPos distance _unitPos);
_attachedObject = _x;
_itemName = _attachedItemsArray select _forEachIndex;
_attachedIndex = _forEachIndex;
};
} forEach _attachedObjectsArray;
// Check if unit has an attached item
if (_itemName == "") exitWith {};
if ((isNull _attachedObject) || {_itemName == ""}) exitWith {ERROR("Could not find attached object")};
// Add item to inventory
_count = (count items _unit) + (count magazines _unit);
_unit addItem _itemName;
if ((count items _unit) + (count magazines _unit) <= _count) exitWith {
[localize "STR_ACE_Attach_Inventory_Full"] call EFUNC(common,displayTextStructured);
[localize "STR_ACE_Attach_Inventory_Full"] call EFUNC(common,displayTextStructured);
};
if (_itemName == "B_IR_Grenade" or _itemName == "O_IR_Grenade" or _itemName == "I_IR_Grenade") then {
// Hack for dealing with X_IR_Grenade effect not dissapearing on deleteVehicle
detach _attachedItem;
_attachedItem setPos [getPos _unit select 0, getPos _unit select 1, ((getPos _unit select 2) - 1000)];
// Delete attached item after 0.5 seconds
_fnc_detachDelay = {
deleteVehicle (_this select 0);
};
[_fnc_detachDelay, [_attachedItem], 0.5, 0] call EFUNC(common,waitAndExecute);
// Hack for dealing with X_IR_Grenade effect not dissapearing on deleteVehicle
detach _attachedObject;
_attachedObject setPos [getPos _unit select 0, getPos _unit select 1, ((getPos _unit select 2) - 1000)];
// Delete attached item after 0.5 seconds
_fnc_detachDelay = {
deleteVehicle (_this select 0);
};
[_fnc_detachDelay, [_attachedObject], 0.5, 0] call EFUNC(common,waitAndExecute);
} else {
// Delete attached item
deleteVehicle _attachedItem;
// Delete attached item
deleteVehicle _attachedObject;
};
// Reset unit variables
_unit setVariable [QGVAR(ItemName),"", true];
_unit setVariable [QGVAR(Item),nil, true];
_attachedObjectsArray deleteAt _attachedIndex;
_attachedItemsArray deleteAt _attachedIndex;
_attachToVehicle setVariable ["ACE_AttachedObjects", _attachedObjectsArray, true];
_attachToVehicle setVariable ["ACE_AttachedItemNames", _attachedItemsArray, true];
// Display message
switch true do {
case (_itemName == "ACE_IR_Strobe_Item") : {
[localize "STR_ACE_Attach_IrStrobe_Detached"] call EFUNC(common,displayTextStructured);
};
case (_itemName == "B_IR_Grenade" or _itemName == "O_IR_Grenade" or _itemName == "I_IR_Grenade") : {
[localize "STR_ACE_Attach_IrGrenade_Detached"] call EFUNC(common,displayTextStructured);
};
case (_itemName == "Chemlight_blue" or {_itemName == "Chemlight_green"} or {_itemName == "Chemlight_red"} or {_itemName == "Chemlight_yellow"}) : {
[localize "STR_ACE_Attach_Chemlight_Detached"] call EFUNC(common,displayTextStructured);
};
default {
if (true) exitWith {};
};
case (_itemName == "ACE_IR_Strobe_Item") : {
[localize "STR_ACE_Attach_IrStrobe_Detached"] call EFUNC(common,displayTextStructured);
};
case (_itemName == "B_IR_Grenade" or _itemName == "O_IR_Grenade" or _itemName == "I_IR_Grenade") : {
[localize "STR_ACE_Attach_IrGrenade_Detached"] call EFUNC(common,displayTextStructured);
};
case (_itemName == "Chemlight_blue" or {_itemName == "Chemlight_green"} or {_itemName == "Chemlight_red"} or {_itemName == "Chemlight_yellow"}) : {
[localize "STR_ACE_Attach_Chemlight_Detached"] call EFUNC(common,displayTextStructured);
};
};

View File

@ -1,63 +1,67 @@
/*
* Author: Garth de Wet (LH)
* Opens the UI for attaching objects.
*
* Arguments:
* 0: unit <STRING>
* 1: target <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* Nothing
*
* Public: No
*/
#include "script_component.hpp"
/*
Author: Garth de Wet (LH)
private ["_actions", "_attachables", "_item"];
Description:
Opens the UI for attaching objects.
PARAMS_2(_unit,_target);
Parameters:
0: OBJECT - unit
Returns:
Nothing
Example:
[player] call ACE_Attach_fnc_openAttachUI;
*/
private ["_unit", "_actions", "_attachables", "_item"];
_unit = _this select 0;
GVAR(attachTarget) = _target;
_listed = [];
_attachables = magazines _unit;
_actions = [localize "STR_ACE_Attach_AttachDetach", localize "STR_ACE_Attach_Attach"] call EFUNC(interaction,prepareSelectMenu);
{
if !(_x in _listed) then {
_item = ConfigFile >> "CfgMagazines" >> _x;
if (getNumber (_item >> "ACE_Attachable") == 1) then {
_actions = [
_actions,
getText(_item >> "displayName"),
getText(_item >> "picture"),
_x
] call EFUNC(interaction,addSelectableItem);
if !(_x in _listed) then {
_item = ConfigFile >> "CfgMagazines" >> _x;
if (getNumber (_item >> "ACE_Attachable") == 1) then {
_actions = [
_actions,
getText(_item >> "displayName"),
getText(_item >> "picture"),
_x
] call EFUNC(interaction,addSelectableItem);
};
_listed pushBack _x;
};
_listed pushBack _x;
};
} forEach _attachables;
_attachables = items _unit;
{
if !(_x in _listed) then {
_item = ConfigFile >> "CfgWeapons" >> _x;
if (getNumber (_item >> "ACE_Attachable") == 1) then {
_actions = [
_actions,
getText(_item >> "displayName"),
getText(_item >> "picture"),
_x
] call EFUNC(interaction,addSelectableItem);
if !(_x in _listed) then {
_item = ConfigFile >> "CfgWeapons" >> _x;
if (getNumber (_item >> "ACE_Attachable") == 1) then {
_actions = [
_actions,
getText(_item >> "displayName"),
getText(_item >> "picture"),
_x
] call EFUNC(interaction,addSelectableItem);
};
_listed pushBack _x;
};
_listed pushBack _x;
};
} forEach _attachables;
[
_actions,
{
[ACE_player, _this] call FUNC(attach);
_actions,
{
[ACE_player, GVAR(attachTarget), _this] call FUNC(attach);
call EFUNC(interaction,hideMenu);
},
{
},
{
call EFUNC(interaction,hideMenu);
if !(profileNamespace getVariable [QEGVAR(interaction,AutoCloseMenu), false]) then {"Default" call EFUNC(interaction,openMenuSelf)};
}
}
] call EFUNC(interaction,openSelectMenu);

View File

@ -0,0 +1,110 @@
/*
* Author: Pabst Mirror (based on Explosive attach by Garth de Wet (LH))
* Approves placement of the lightObject, scans for an appropriate location and attaches
*
* Arguments:
* Nothing
*
* Return Value:
* Nothing
*
* Example:
* Nothing
*
* Public: No
*/
#include "script_component.hpp"
private ["_setupObject", "_setupClassname", "_itemClassname", "_placementText", "_attachToVehicle", "_placer", "_startingPosition", "_startingOffset", "_distanceFromCenter", "_closeInUnitVector", "_keepGoingCloser", "_closeInDistance", "_endPosTestOffset", "_endPosTest", "_startingPosShifted", "_startASL", "_endPosShifted", "_endASL", "_attachedObject", "_currentObjects", "_currentItemNames"];
if (GVAR(pfeh_running)) then {
[QGVAR(PlacementEachFrame),"OnEachFrame"] call BIS_fnc_removeStackedEventHandler;
GVAR(pfeh_running) = false;
};
_setupObject = GVAR(setupObject);
_setupClassname = typeOf _setupObject;
_itemClassname = GVAR(SetupPlacmentItem);
_placementText = GVAR(SetupPlacmentText);
_attachToVehicle = GVAR(SetupAttachVehicle);
_placer = GVAR(placer);
GVAR(SetupPlacmentItem) = "";
GVAR(SetupPlacmentText) = "";
GVAR(setupObject) = objNull;
GVAR(SetupAttachVehicle) = objNull;
GVAR(placer) = objNull;
[_placer, QGVAR(vehAttach), false] call EFUNC(common,setForceWalkStatus);
[_placer, "DefaultAction", _placer getVariable [QGVAR(placeActionEH), -1]] call EFUNC(common,removeActionEventHandler);
[_placer, "MenuBack", _placer getVariable [QGVAR(cancelActionEH), -1]] call EFUNC(common,removeActionEventHandler);
call EFUNC(interaction,hideMouseHint);
//A player can release the attachObject with it floating in mid-air.
//This will use lineIntersectsWith to scan towards the center of the vehicle to find a collision
//ArmA's collision detection is of couse terrible and often misses collisions (difference between what we see and collision LOD)
//So it does multiple scans at slighly different angles
//This is VERY computationaly intensive, but doesn't happen that often.
_startingPosition = _setupObject modelToWorld [0,0,0];
_startingOffset = _attachToVehicle worldToModel _startingPosition;
_distanceFromCenter = vectorMagnitude _startingOffset;
_closeInUnitVector = vectorNormalized (_startingOffset vectorFromTo [0,0,0]);
_keepGoingCloser = true;
_closeInDistance = 0;
while {_keepGoingCloser} do {
if (_closeInDistance >= _distanceFromCenter) exitWith {};
_closeInDistance = _closeInDistance + 0.01; //10mm each step
_endPosTestOffset = _startingOffset vectorAdd (_closeInUnitVector vectorMultiply _closeInDistance);
_endPosTestOffset set [2, (_startingOffset select 2)];
_endPosTest = _attachToVehicle modelToWorld _endPosTestOffset;
{
_startingPosShifted = _startingPosition vectorAdd _x;
_startASL = if (surfaceIsWater _startingPosShifted) then {_startingPosShifted} else {ATLtoASL _startingPosShifted};
{
_endPosShifted = _endPosTest vectorAdd _x;
_endASL = if (surfaceIsWater _startingPosShifted) then {_endPosShifted} else {ATLtoASL _endPosShifted};
//Uncomment to see the lazor show, and see how the scanning works:
drawLine3D [_startingPosShifted, _endPosShifted, [1,0,0,1]];
if (_attachToVehicle in lineIntersectsWith [_startASL, _endASL, _placer, _setupObject]) exitWith {_keepGoingCloser = false};
} forEach [[0,0,0.045], [0,0,-0.045], [0,0.045,0], [0,-0.045,0], [0.045,0,0], [-0.045,0,0]];
} forEach [[0,0,0], [0,0,0.05], [0,0,-0.05]];
};
//Delete Local Placement Object
deleteVehicle _setupObject;
//Checks
if ((_closeInDistance >= _distanceFromCenter) || (!([_placer,_attachToVehicle,_itemClassname] call FUNC(canAttach)))) exitWith {
TRACE_2("no valid spot found",_closeInDistance,_distanceFromCenter);
[localize "STR_ACE_Attach_Failed"] call EFUNC(common,displayTextStructured);
};
//Move it out slightly, for visability sake (better to look a little funny than be embedded//sunk in the hull)
_closeInDistance = (_closeInDistance - 0.0085);
//Create New 'real' Object
_endPosTestOffset = _startingOffset vectorAdd (_closeInUnitVector vectorMultiply _closeInDistance);
_endPosTestOffset set [2, (_startingOffset select 2)];
_attachedObject = _setupClassname createVehicle (getPos _placer);
_attachedObject attachTo [_attachToVehicle, _endPosTestOffset];
//Remove Item from inventory
_placer removeItem _itemClassname;
//Add Object to ACE_AttachedObjects and ACE_AttachedItemNames
_currentObjects = _attachToVehicle getVariable ["ACE_AttachedObjects", []];
_currentObjects pushBack _attachedObject;
_attachToVehicle setVariable ["ACE_AttachedObjects", _currentObjects, true];
_currentItemNames = _attachToVehicle getVariable ["ACE_AttachedItemNames", []];
_currentItemNames pushBack _itemClassname;
_attachToVehicle setVariable ["ACE_AttachedItemNames", _currentItemNames, true];
[_placementText] call EFUNC(common,displayTextStructured);

View File

@ -0,0 +1,35 @@
/*
* Author: Pabst Mirror (based on Explosive attach by Garth de Wet (LH))
* Cancels placement of the lightObject
*
* Arguments:
* Nothing
*
* Return Value:
* Nothing
*
* Example:
* Nothing
*
* Public: No
*/
#include "script_component.hpp"
if (GVAR(pfeh_running)) then {
[QGVAR(PlacementEachFrame),"OnEachFrame"] call BIS_fnc_removeStackedEventHandler;
GVAR(pfeh_running) = false;
};
if (!isNull (GVAR(setupObject))) then {
deleteVehicle GVAR(setupObject);
};
[GVAR(placer), QGVAR(vehAttach), false] call EFUNC(common,setForceWalkStatus);
call EFUNC(interaction,hideMouseHint);
[GVAR(placer), "DefaultAction", GVAR(placer) getVariable [QGVAR(placeActionEH), -1]] call EFUNC(common,removeActionEventHandler);
[GVAR(placer), "MenuBack", GVAR(placer) getVariable [QGVAR(cancelActionEH), -1]] call EFUNC(common,removeActionEventHandler);
GVAR(placer) = objNull;
GVAR(SetupPlacmentItem) = "";
GVAR(SetupPlacmentText) = "";
GVAR(setupObject) = objNull;
GVAR(SetupAttachVehicle) = objNull;

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Edited with tabler - 2014-12-12 -->
<!-- Edited with tabler - 2015-01-31 -->
<Project name="ACE">
<Package name="Attach">
<Key ID="STR_ACE_Attach_AttachDetach">
@ -146,5 +146,34 @@
<Hungarian>Az infravörös jeladóval megjelölheted a helyzetedet úgy, hogy annak pulzáló fénye csak éjjellátó készülékkel látható.</Hungarian>
<Russian>ИК строб позволяет сигнализировать свое местоположение через пульсирующий маяк, видимый только через ПНВ.</Russian>
</Key>
<Key ID="STR_ACE_Attach_PlaceAction">
<English>Place</English>
<German>Platzieren</German>
<Spanish>Colocar</Spanish>
<Polish>Umieść</Polish>
<French>Placer</French>
<Czech>Položit</Czech>
<Portuguese>Colocar</Portuguese>
<Italian>Posiziona</Italian>
<Hungarian>Elhelyez</Hungarian>
</Key>
<Key ID="STR_ACE_Attach_CancelAction">
<English>Cancel</English>
<German>Abbrechen</German>
<Spanish>Cancelar</Spanish>
<Polish>Anuluj</Polish>
<French>Annuler</French>
<Czech>Zrušit</Czech>
<Portuguese>Cancelar</Portuguese>
<Italian>Annulla</Italian>
<Hungarian>Mégse</Hungarian>
</Key>
<Key ID="STR_ACE_Attach_Failed">
<English>Attach Failed</English>
<French>Échec du Attacher</French>
<German>Befestigen Fehlgeschlagen</German>
<Russian>Присоединить Ошибка</Russian>
<Spanish>Error en Acoplar</Spanish>
</Key>
</Package>
</Project>