mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Merged main
This commit is contained in:
commit
7586048e22
@ -191,3 +191,4 @@ YetheSamartaka
|
|||||||
xrufix
|
xrufix
|
||||||
Zakant <Zakant@gmx.de>
|
Zakant <Zakant@gmx.de>
|
||||||
zGuba
|
zGuba
|
||||||
|
Zman6258
|
||||||
|
@ -22,7 +22,8 @@ GVAR(lastSortDirectionRight) = DESCENDING;
|
|||||||
params ["_object"];
|
params ["_object"];
|
||||||
|
|
||||||
// If the arsenal is already open, refresh arsenal display
|
// If the arsenal is already open, refresh arsenal display
|
||||||
if (!isNil QGVAR(currentBox) && {GVAR(currentBox) isEqualTo _object}) then {
|
// Deliberate == check, fail on objNull
|
||||||
|
if (!isNil QGVAR(currentBox) && {GVAR(currentBox) == _object}) then {
|
||||||
[true, true] call FUNC(refresh);
|
[true, true] call FUNC(refresh);
|
||||||
};
|
};
|
||||||
}] call CBA_fnc_addEventHandler;
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
@ -25,6 +25,11 @@ if (canSuspend) exitWith {
|
|||||||
[{_this call FUNC(refresh)}, _this] call CBA_fnc_directCall;
|
[{_this call FUNC(refresh)}, _this] call CBA_fnc_directCall;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private _display = findDisplay IDD_ace_arsenal;
|
||||||
|
|
||||||
|
// Exit quietly if no display found
|
||||||
|
if (isNull _display) exitWith {};
|
||||||
|
|
||||||
if (_updateItems) then {
|
if (_updateItems) then {
|
||||||
// Update current item list
|
// Update current item list
|
||||||
call FUNC(updateCurrentItemsList);
|
call FUNC(updateCurrentItemsList);
|
||||||
@ -65,6 +70,4 @@ if (!_animate) then {
|
|||||||
[{GVAR(refreshing) = false}, nil, 3] call CBA_fnc_execAfterNFrames;
|
[{GVAR(refreshing) = false}, nil, 3] call CBA_fnc_execAfterNFrames;
|
||||||
};
|
};
|
||||||
|
|
||||||
private _display = findDisplay IDD_ace_arsenal;
|
|
||||||
|
|
||||||
[_display, _display displayCtrl GVAR(currentLeftPanel), _animate] call FUNC(fillLeftPanel);
|
[_display, _display displayCtrl GVAR(currentLeftPanel), _animate] call FUNC(fillLeftPanel);
|
||||||
|
@ -42,8 +42,14 @@ if (_global && {isMultiplayer} && {!isNil "_id"}) then {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// If the arsenal is already open and not ignoring content (see FUNC(openBox)), close arsenal display
|
// If the arsenal is already open and not ignoring content (see FUNC(openBox)), close arsenal display
|
||||||
if (!isNil QGVAR(currentBox) && {GVAR(currentBox) isEqualTo _object} && {isNil QGVAR(ignoredVirtualItems)}) then {
|
// Deliberate == check, fail on objNull
|
||||||
|
if (!isNil QGVAR(currentBox) && {GVAR(currentBox) == _object} && {isNil QGVAR(ignoredVirtualItems)}) then {
|
||||||
|
// Delay a frame in case this is running on display open/close
|
||||||
|
[{
|
||||||
|
private _display = findDisplay IDD_ace_arsenal;
|
||||||
|
if (isNull _display) exitWith {};
|
||||||
|
|
||||||
[LLSTRING(noVirtualItems), false, 5, 1] call EFUNC(common,displayText);
|
[LLSTRING(noVirtualItems), false, 5, 1] call EFUNC(common,displayText);
|
||||||
// Delay a frame in case this is running on display open
|
_display closeDisplay 0;
|
||||||
[{(findDisplay IDD_ace_arsenal) closeDisplay 0}] call CBA_fnc_execNextFrame;
|
}] call CBA_fnc_execNextFrame;
|
||||||
};
|
};
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
params ["_name"];
|
params ["_name"];
|
||||||
|
|
||||||
if !(_name in GVAR(syncedEvents)) exitWith {
|
if !(_name in GVAR(syncedEvents)) exitWith {
|
||||||
ERROR_1("Synced event key [%1] not found (removeSyncedEventHandler).", _name);
|
ERROR_1("Synced event key [%1] not found (removeSyncedEventHandler)",_name);
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
params ["_name", "_args", ["_ttl", 0]];
|
params ["_name", "_args", ["_ttl", 0]];
|
||||||
|
|
||||||
if !(_name in GVAR(syncedEvents)) exitWith {
|
if !(_name in GVAR(syncedEvents)) exitWith {
|
||||||
ERROR_1("Synced event key [%1] not found (syncedEvent).", _name);
|
ERROR_1("Synced event key [%1] not found (syncedEvent)",_name);
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
1
addons/compat_cup_terrains/$PBOPREFIX$
Normal file
1
addons/compat_cup_terrains/$PBOPREFIX$
Normal file
@ -0,0 +1 @@
|
|||||||
|
z\ace\addons\compat_cup_terrains
|
5
addons/compat_cup_terrains/CfgEventHandlers.hpp
Normal file
5
addons/compat_cup_terrains/CfgEventHandlers.hpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
class Extended_PostInit_EventHandlers {
|
||||||
|
class ADDON {
|
||||||
|
init = QUOTE(call COMPILE_SCRIPT(XEH_postInit));
|
||||||
|
};
|
||||||
|
};
|
48
addons/compat_cup_terrains/CfgVehicles.hpp
Normal file
48
addons/compat_cup_terrains/CfgVehicles.hpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
class CfgVehicles {
|
||||||
|
class House;
|
||||||
|
class House_Small_F;
|
||||||
|
class Strategic;
|
||||||
|
class House_EP1: House {};
|
||||||
|
|
||||||
|
class Land_Benzina_schnell: House {
|
||||||
|
transportFuel = 0;
|
||||||
|
EGVAR(refuel,hooks)[] = {{-1.5,-3.93,-1.25}, {2.35,-3.93,-1.25}};
|
||||||
|
EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL;
|
||||||
|
class ACE_Actions {
|
||||||
|
class ACE_MainActions {
|
||||||
|
displayName = ECSTRING(interaction,MainAction);
|
||||||
|
position = "[0,-3.93,-1.25]";
|
||||||
|
distance = 5;
|
||||||
|
condition = "true";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
class Land_A_FuelStation_Feed: Strategic {
|
||||||
|
transportFuel = 0;
|
||||||
|
EGVAR(refuel,hooks)[] = {{-0.34,0,0}, {0.34,0,0}};
|
||||||
|
EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL;
|
||||||
|
};
|
||||||
|
class Land_Ind_FuelStation_Feed_EP1: House_EP1 {
|
||||||
|
transportFuel = 0;
|
||||||
|
EGVAR(refuel,hooks)[] = {{-0.34,0,0}, {0.34,0,0}};
|
||||||
|
EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL;
|
||||||
|
};
|
||||||
|
class Land_FuelStation_Feed_PMC: Strategic {
|
||||||
|
transportFuel = 0;
|
||||||
|
EGVAR(refuel,hooks)[] = {{-0.34,0,0}, {0.34,0,0}};
|
||||||
|
EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL;
|
||||||
|
};
|
||||||
|
class FuelStation: House_Small_F {
|
||||||
|
transportFuel = 0;
|
||||||
|
EGVAR(refuel,hooks)[] = {{1.25, .2, -1.1}};
|
||||||
|
EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL;
|
||||||
|
class ACE_Actions {
|
||||||
|
class ACE_MainActions {
|
||||||
|
displayName = ECSTRING(interaction,MainAction);
|
||||||
|
position = "[1.25, .2, -1]";
|
||||||
|
distance = 5;
|
||||||
|
condition = "true";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
5
addons/compat_cup_terrains/XEH_postInit.sqf
Normal file
5
addons/compat_cup_terrains/XEH_postInit.sqf
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
if (["CUP_Terrains_ACE_compat"] call EFUNC(common,isModLoaded)) exitWith {
|
||||||
|
ERROR_WITH_TITLE("Duplicate CUP/ACE Compats","Compats are now part of ACE - Uninstall 'CUP ACE3 Compatibility Addon - Terrains'");
|
||||||
|
};
|
27
addons/compat_cup_terrains/config.cpp
Normal file
27
addons/compat_cup_terrains/config.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
#include "\z\ace\addons\refuel\defines.hpp"
|
||||||
|
|
||||||
|
class CfgPatches {
|
||||||
|
class ADDON {
|
||||||
|
name = COMPONENT_NAME;
|
||||||
|
units[] = {};
|
||||||
|
weapons[] = {};
|
||||||
|
requiredVersion = REQUIRED_VERSION;
|
||||||
|
requiredAddons[] = {
|
||||||
|
"CABuildings",
|
||||||
|
"CAStructuresHouse_A_FuelStation",
|
||||||
|
"CAStructures_E_Ind_Ind_FuelStation",
|
||||||
|
"CAStructures_PMC_FuelStation",
|
||||||
|
"CUP_Buildings_Config",
|
||||||
|
"ace_refuel" // not a sub-component because it's all this compat does
|
||||||
|
};
|
||||||
|
skipWhenMissingDependencies = 1;
|
||||||
|
author = ECSTRING(common,ACETeam);
|
||||||
|
authors[] = {"Community Upgrade Project", "Mike"};
|
||||||
|
url = ECSTRING(main,URL);
|
||||||
|
VERSION_CONFIG;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "CfgVehicles.hpp"
|
||||||
|
#include "CfgEventHandlers.hpp"
|
5
addons/compat_cup_terrains/script_component.hpp
Normal file
5
addons/compat_cup_terrains/script_component.hpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#define COMPONENT compat_cup_terrains
|
||||||
|
#define COMPONENT_BEAUTIFIED CUP Terrains Compatibility
|
||||||
|
|
||||||
|
#include "\z\ace\addons\main\script_mod.hpp"
|
||||||
|
#include "\z\ace\addons\main\script_macros.hpp"
|
@ -31,5 +31,4 @@ if (_typeOfDamage in GVAR(damageTypeDetails)) then {
|
|||||||
TRACE_1("Return invalid, terminating wound handling",_damageData);
|
TRACE_1("Return invalid, terminating wound handling",_damageData);
|
||||||
};
|
};
|
||||||
} forEach _woundHandlers;
|
} forEach _woundHandlers;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
BIN
addons/medical_gui/ui/painkillers.paa
Normal file
BIN
addons/medical_gui/ui/painkillers.paa
Normal file
Binary file not shown.
@ -605,10 +605,13 @@ class ADDON {
|
|||||||
incompatibleMedication[] = {};
|
incompatibleMedication[] = {};
|
||||||
};
|
};
|
||||||
class PainKillers {
|
class PainKillers {
|
||||||
painReduce = 0.1;
|
painReduce = 0.35;
|
||||||
timeInSystem = 600;
|
hrIncreaseLow[] = {-5, -10};
|
||||||
|
hrIncreaseNormal[] = {-5, -15};
|
||||||
|
hrIncreaseHigh[] = {-5, -17};
|
||||||
|
timeInSystem = 420;
|
||||||
timeTillMaxEffect = 60;
|
timeTillMaxEffect = 60;
|
||||||
maxDose = 10;
|
maxDose = 6;
|
||||||
incompatibleMedication[] = {};
|
incompatibleMedication[] = {};
|
||||||
viscosityChange = 5;
|
viscosityChange = 5;
|
||||||
};
|
};
|
||||||
|
@ -141,6 +141,19 @@ class GVAR(actions) {
|
|||||||
litter[] = {{"ACE_MedicalLitter_epinephrine"}};
|
litter[] = {{"ACE_MedicalLitter_epinephrine"}};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// - Generic Medication ---------------------------------------------------
|
||||||
|
class Painkillers: Morphine {
|
||||||
|
displayName = CSTRING(Administer_Painkillers);
|
||||||
|
displayNameProgress = CSTRING(Administering_Painkillers);
|
||||||
|
icon = QPATHTOEF(medical_gui,ui\painkillers.paa);
|
||||||
|
allowedSelections[] = {"Head"};
|
||||||
|
medicRequired = 0;
|
||||||
|
items[] = {"ACE_painkillers"};
|
||||||
|
treatmentTime = 4;
|
||||||
|
sounds[] = {{QPATHTO_R(sounds\Pills.ogg),1,1,50}};
|
||||||
|
litter[] = {{"Land_PainKillers_F"}}; // just use BI's model as litter
|
||||||
|
};
|
||||||
|
|
||||||
// - IV Bags --------------------------------------------------------------
|
// - IV Bags --------------------------------------------------------------
|
||||||
class BloodIV: BasicBandage {
|
class BloodIV: BasicBandage {
|
||||||
displayName = CSTRING(Actions_Blood4_1000);
|
displayName = CSTRING(Actions_Blood4_1000);
|
||||||
|
@ -284,6 +284,16 @@ class CfgVehicles {
|
|||||||
MACRO_ADDITEM(ACE_bodyBag,1);
|
MACRO_ADDITEM(ACE_bodyBag,1);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
class ACE_painkillersItem: Item_Base_F {
|
||||||
|
scope = 2;
|
||||||
|
scopeCurator = 2;
|
||||||
|
displayName = CSTRING(painkillers_Display);
|
||||||
|
author = "Alganthe";
|
||||||
|
vehicleClass = "Items";
|
||||||
|
class TransportItems {
|
||||||
|
MACRO_ADDITEM(ACE_painkillers,1);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// Medical supply crates
|
// Medical supply crates
|
||||||
class ThingX;
|
class ThingX;
|
||||||
@ -305,6 +315,7 @@ class CfgVehicles {
|
|||||||
author = ECSTRING(common,ACETeam);
|
author = ECSTRING(common,ACETeam);
|
||||||
class TransportItems {
|
class TransportItems {
|
||||||
MACRO_ADDITEM(ACE_fieldDressing,50);
|
MACRO_ADDITEM(ACE_fieldDressing,50);
|
||||||
|
MACRO_ADDITEM(ACE_painkillers,25);
|
||||||
MACRO_ADDITEM(ACE_morphine,25);
|
MACRO_ADDITEM(ACE_morphine,25);
|
||||||
MACRO_ADDITEM(ACE_epinephrine,25);
|
MACRO_ADDITEM(ACE_epinephrine,25);
|
||||||
MACRO_ADDITEM(ACE_bloodIV,15);
|
MACRO_ADDITEM(ACE_bloodIV,15);
|
||||||
@ -352,6 +363,7 @@ class CfgVehicles {
|
|||||||
MACRO_ADDITEM(ACE_elasticBandage,25);
|
MACRO_ADDITEM(ACE_elasticBandage,25);
|
||||||
MACRO_ADDITEM(ACE_tourniquet,15);
|
MACRO_ADDITEM(ACE_tourniquet,15);
|
||||||
MACRO_ADDITEM(ACE_splint,15);
|
MACRO_ADDITEM(ACE_splint,15);
|
||||||
|
MACRO_ADDITEM(ACE_painkillers,15);
|
||||||
MACRO_ADDITEM(ACE_morphine,15);
|
MACRO_ADDITEM(ACE_morphine,15);
|
||||||
MACRO_ADDITEM(ACE_adenosine,15);
|
MACRO_ADDITEM(ACE_adenosine,15);
|
||||||
MACRO_ADDITEM(ACE_epinephrine,15);
|
MACRO_ADDITEM(ACE_epinephrine,15);
|
||||||
|
@ -310,4 +310,17 @@ class CfgWeapons {
|
|||||||
hiddenSelectionsTextures[] = {QPATHTOF(data\bodybagItem_white_co.paa)};
|
hiddenSelectionsTextures[] = {QPATHTOF(data\bodybagItem_white_co.paa)};
|
||||||
GVAR(bodyBagObject) = "ACE_bodyBagObject_white";
|
GVAR(bodyBagObject) = "ACE_bodyBagObject_white";
|
||||||
};
|
};
|
||||||
|
class ACE_painkillers: ACE_ItemCore {
|
||||||
|
scope = 2;
|
||||||
|
author = "Alganthe";
|
||||||
|
displayName = CSTRING(painkillers_Display);
|
||||||
|
model = "\A3\Structures_F_EPA\Items\Medical\PainKillers_F.p3d";
|
||||||
|
picture = QPATHTOF(ui\painkillers_ca.paa);
|
||||||
|
descriptionShort = CSTRING(painkillers_Desc_Short);
|
||||||
|
descriptionUse = CSTRING(painkillers_Desc_Use);
|
||||||
|
ACE_isMedicalItem = 1;
|
||||||
|
class ItemInfo: CBA_MiscItem_ItemInfo {
|
||||||
|
mass = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
@ -11,8 +11,8 @@ ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP)
|
|||||||
class CfgPatches {
|
class CfgPatches {
|
||||||
class ADDON {
|
class ADDON {
|
||||||
name = COMPONENT_NAME;
|
name = COMPONENT_NAME;
|
||||||
units[] = {"ACE_fieldDressingItem","ACE_packingBandageItem","ACE_elasticBandageItem","ACE_tourniquetItem","ACE_splintItem","ACE_morphineItem","ACE_adenosineItem","ACE_epinephrineItem","ACE_plasmaIVItem","ACE_bloodIVItem","ACE_salineIVItem","ACE_quikClotItem","ACE_personalAidKitItem","ACE_surgicalKitItem","ACE_sutureItem","ACE_bodyBagItem","ACE_medicalSupplyCrate","ACE_medicalSupplyCrate_advanced"};
|
units[] = {"ACE_fieldDressingItem","ACE_packingBandageItem","ACE_elasticBandageItem","ACE_tourniquetItem","ACE_splintItem","ACE_painkillersItem","ACE_morphineItem","ACE_adenosineItem","ACE_epinephrineItem","ACE_plasmaIVItem","ACE_bloodIVItem","ACE_salineIVItem","ACE_quikClotItem","ACE_personalAidKitItem","ACE_surgicalKitItem","ACE_sutureItem","ACE_bodyBagItem","ACE_medicalSupplyCrate","ACE_medicalSupplyCrate_advanced"};
|
||||||
weapons[] = {"ACE_fieldDressing","ACE_packingBandage","ACE_elasticBandage","ACE_tourniquet","ACE_splint","ACE_morphine","ACE_adenosine","ACE_epinephrine","ACE_plasmaIV","ACE_plasmaIV_500","ACE_plasmaIV_250","ACE_bloodIV","ACE_bloodIV_500","ACE_bloodIV_250","ACE_salineIV","ACE_salineIV_500","ACE_salineIV_250","ACE_quikclot","ACE_personalAidKit","ACE_surgicalKit","ACE_suture","ACE_bodyBag","ACE_bodyBag_blue","ACE_bodyBag_white"};
|
weapons[] = {"ACE_fieldDressing","ACE_packingBandage","ACE_elasticBandage","ACE_tourniquet","ACE_splint","ACE_painkillers","ACE_morphine","ACE_adenosine","ACE_epinephrine","ACE_plasmaIV","ACE_plasmaIV_500","ACE_plasmaIV_250","ACE_bloodIV","ACE_bloodIV_500","ACE_bloodIV_250","ACE_salineIV","ACE_salineIV_500","ACE_salineIV_250","ACE_quikclot","ACE_personalAidKit","ACE_surgicalKit","ACE_suture","ACE_bodyBag","ACE_bodyBag_blue","ACE_bodyBag_white"};
|
||||||
requiredVersion = REQUIRED_VERSION;
|
requiredVersion = REQUIRED_VERSION;
|
||||||
requiredAddons[] = {"ace_medical_status", "ace_medical_damage", "ace_apl"};
|
requiredAddons[] = {"ace_medical_status", "ace_medical_damage", "ace_apl"};
|
||||||
author = ECSTRING(common,ACETeam);
|
author = ECSTRING(common,ACETeam);
|
||||||
|
BIN
addons/medical_treatment/sounds/Pills.ogg
Normal file
BIN
addons/medical_treatment/sounds/Pills.ogg
Normal file
Binary file not shown.
@ -4933,5 +4933,33 @@
|
|||||||
<Japanese>Zeus操作中は、すべての治療時間にこの係数を掛けます。</Japanese>
|
<Japanese>Zeus操作中は、すべての治療時間にこの係数を掛けます。</Japanese>
|
||||||
<Korean>제우스일 때 모든 치료 시간에 이 계수를 곱합니다.</Korean>
|
<Korean>제우스일 때 모든 치료 시간에 이 계수를 곱합니다.</Korean>
|
||||||
</Key>
|
</Key>
|
||||||
|
<Key ID="STR_ACE_Medical_Treatment_painkillers_Display">
|
||||||
|
<English>Painkillers</English>
|
||||||
|
<Czech>Léky proti bolesti</Czech>
|
||||||
|
<German>Schmerztabellen</German>
|
||||||
|
<Russian>Болеутоляющее</Russian>
|
||||||
|
<Polish>Środki przeciwbólowe</Polish>
|
||||||
|
<Italian>Antidolorifici</Italian>
|
||||||
|
<Spanish>Analgésicos</Spanish>
|
||||||
|
<French>Analgésiques</French>
|
||||||
|
<Chinese>止痛藥</Chinese>
|
||||||
|
<Japanese>鎮痛剤</Japanese>
|
||||||
|
<Korean>진통제</Korean>
|
||||||
|
<Portuguese>Analgésicos</Portuguese>
|
||||||
|
<Chinesesimp>止痛药</Chinesesimp>
|
||||||
|
<Turkish>Ağrı kesici</Turkish>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_Medical_Treatment_Administer_Painkillers">
|
||||||
|
<English>Administer Painkillers</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_Medical_Treatment_Administering_Painkillers">
|
||||||
|
<English>Administering Painkillers...</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_Medical_Treatment_painkillers_Desc_Short">
|
||||||
|
<English>Over-the-counter analgesic used to combat light to moderate pain experiences.</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_Medical_Treatment_painkillers_Desc_Use">
|
||||||
|
<English>Over-the-counter analgesic used to combat light to moderate pain experiences.</English>
|
||||||
|
</Key>
|
||||||
</Package>
|
</Package>
|
||||||
</Project>
|
</Project>
|
||||||
|
BIN
addons/medical_treatment/ui/painkillers_ca.paa
Normal file
BIN
addons/medical_treatment/ui/painkillers_ca.paa
Normal file
Binary file not shown.
@ -1,56 +1,27 @@
|
|||||||
#define TOW_ACTION \
|
#define CONCAT(a,b) a##b
|
||||||
|
#define TOW_ACTION(length) \
|
||||||
|
class GVAR(CONCAT(startTow,length)) {\
|
||||||
|
displayName = CSTRING(CONCAT(start,length));\
|
||||||
|
condition = QUOTE([ARR_2(_player,'CONCAT(ACE_rope,length)')] call DEFUNC(common,hasItem));\
|
||||||
|
statement = QUOTE([ARR_3(_player,_target,'CONCAT(ACE_rope,length)')] call DFUNC(startTow));\
|
||||||
|
exceptions[] = { INTERACTION_EXCEPTIONS };\
|
||||||
|
}
|
||||||
|
#define TOW_ACTIONS \
|
||||||
class ACE_Actions {\
|
class ACE_Actions {\
|
||||||
class ACE_MainActions {\
|
class ACE_MainActions {\
|
||||||
class ADDON {\
|
class ADDON {\
|
||||||
displayName = CSTRING(displayName);\
|
displayName = CSTRING(displayName);\
|
||||||
distance = TOW_ACTION_DISTANCE;\
|
distance = TOW_ACTION_DISTANCE;\
|
||||||
condition = QUOTE([ARR_1(_target)] call FUNC(isSuitableSimulation));\
|
condition = QUOTE(alive _target && {_target call DFUNC(isSuitableSimulation)});\
|
||||||
statement = "";\
|
|
||||||
exceptions[] = { INTERACTION_EXCEPTIONS };\
|
exceptions[] = { INTERACTION_EXCEPTIONS };\
|
||||||
showDisabled = 0;\
|
insertChildren = QUOTE(_target call DFUNC(getDetachActions));\
|
||||||
icon = "";\
|
TOW_ACTION(3);\
|
||||||
class GVAR(startTow3) {\
|
TOW_ACTION(6);\
|
||||||
displayName = CSTRING(start3);\
|
TOW_ACTION(12);\
|
||||||
condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope3')] call EFUNC(common,hasItem));\
|
TOW_ACTION(15);\
|
||||||
statement = QUOTE([ARR_3(_player,_target,'ACE_rope3')] call FUNC(startTow));\
|
TOW_ACTION(18);\
|
||||||
exceptions[] = { INTERACTION_EXCEPTIONS };\
|
TOW_ACTION(27);\
|
||||||
};\
|
TOW_ACTION(36);\
|
||||||
class GVAR(startTow6) {\
|
|
||||||
displayName = CSTRING(start6);\
|
|
||||||
condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope6')] call EFUNC(common,hasItem));\
|
|
||||||
statement = QUOTE([ARR_3(_player,_target,'ACE_rope6')] call FUNC(startTow));\
|
|
||||||
exceptions[] = { INTERACTION_EXCEPTIONS };\
|
|
||||||
};\
|
|
||||||
class GVAR(startTow12) {\
|
|
||||||
displayName = CSTRING(start12);\
|
|
||||||
condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope12')] call EFUNC(common,hasItem));\
|
|
||||||
statement = QUOTE([ARR_3(_player,_target,'ACE_rope12')] call FUNC(startTow));\
|
|
||||||
exceptions[] = { INTERACTION_EXCEPTIONS };\
|
|
||||||
};\
|
|
||||||
class GVAR(startTow15) {\
|
|
||||||
displayName = CSTRING(start15);\
|
|
||||||
condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope15')] call EFUNC(common,hasItem));\
|
|
||||||
statement = QUOTE([ARR_3(_player,_target,'ACE_rope15')] call FUNC(startTow));\
|
|
||||||
exceptions[] = { INTERACTION_EXCEPTIONS };\
|
|
||||||
};\
|
|
||||||
class GVAR(startTow18) {\
|
|
||||||
displayName = CSTRING(start18);\
|
|
||||||
condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope18')] call EFUNC(common,hasItem));\
|
|
||||||
statement = QUOTE([ARR_3(_player,_target,'ACE_rope18')] call FUNC(startTow));\
|
|
||||||
exceptions[] = { INTERACTION_EXCEPTIONS };\
|
|
||||||
};\
|
|
||||||
class GVAR(startTow27) {\
|
|
||||||
displayName = CSTRING(start27);\
|
|
||||||
condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope27')] call EFUNC(common,hasItem));\
|
|
||||||
statement = QUOTE([ARR_3(_player,_target,'ACE_rope27')] call FUNC(startTow));\
|
|
||||||
exceptions[] = { INTERACTION_EXCEPTIONS };\
|
|
||||||
};\
|
|
||||||
class GVAR(startTow36) {\
|
|
||||||
displayName = CSTRING(start36);\
|
|
||||||
condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope36')] call EFUNC(common,hasItem));\
|
|
||||||
statement = QUOTE([ARR_3(_player,_target,'ACE_rope36')] call FUNC(startTow));\
|
|
||||||
exceptions[] = { INTERACTION_EXCEPTIONS };\
|
|
||||||
};\
|
|
||||||
};\
|
};\
|
||||||
};\
|
};\
|
||||||
}
|
}
|
||||||
@ -58,27 +29,33 @@ class ACE_Actions {\
|
|||||||
class CfgVehicles {
|
class CfgVehicles {
|
||||||
class LandVehicle;
|
class LandVehicle;
|
||||||
class Car: LandVehicle {
|
class Car: LandVehicle {
|
||||||
TOW_ACTION;
|
TOW_ACTIONS;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Tank: LandVehicle {
|
class Tank: LandVehicle {
|
||||||
TOW_ACTION;
|
TOW_ACTIONS;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Ship;
|
||||||
|
class Ship_F: Ship {
|
||||||
|
TOW_ACTIONS;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThingX;
|
class ThingX;
|
||||||
class GVAR(hook): ThingX {
|
class GVAR(helper): ThingX {
|
||||||
displayName = "hook"; // not publicly visible, no stringtable needed
|
displayName = "helper"; // not publicly visible, no stringtable needed
|
||||||
scope = 1;
|
scope = 1;
|
||||||
scopeCurator = 1;
|
scopeCurator = 1;
|
||||||
model = "\a3\Structures_F_Orange\VR\Helpers\Sign_sphere10cm_Geometry_F.p3d";
|
model = "\A3\Weapons_f\empty";
|
||||||
destrType = "DestructNo";
|
destrType = "DestructNo";
|
||||||
|
};
|
||||||
|
class GVAR(hook): GVAR(helper) {
|
||||||
|
displayName = "hook";
|
||||||
class ACE_Actions {
|
class ACE_Actions {
|
||||||
class ACE_MainActions {
|
class ACE_MainActions {
|
||||||
displayName = CSTRING(detach);
|
displayName = CSTRING(detach);
|
||||||
condition = "true";
|
statement = QUOTE([ARR_2(_player,_target)] call DFUNC(detachRope));
|
||||||
statement = QUOTE(private _parent = _target getVariable [ARR_2(QQGVAR(parent),objNull)]; private _child = _target getVariable [ARR_2(QQGVAR(child),objNull)]; [ARR_3(_player,_parent,_child)] call FUNC(detach));
|
distance = TOW_ACTION_DISTANCE;
|
||||||
distance = 2;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
PREP(addRopeToVehicle);
|
PREP(addRopeToVehicle);
|
||||||
PREP(attachRopePFH);
|
PREP(attachRopePFH);
|
||||||
PREP(canStartTow);
|
PREP(attachVehicles);
|
||||||
PREP(detach);
|
PREP(detachChild);
|
||||||
|
PREP(detachRope);
|
||||||
|
PREP(getDetachActions);
|
||||||
PREP(isSuitableSimulation);
|
PREP(isSuitableSimulation);
|
||||||
PREP(onMouseButtonDown);
|
PREP(onMouseButtonDown);
|
||||||
PREP(onMouseButtonUp);
|
PREP(onMouseButtonUp);
|
||||||
|
@ -1,14 +1,40 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
["MouseButtonDown", LINKFUNC(onMouseButtonDown)] call CBA_fnc_addDisplayHandler;
|
|
||||||
["MouseButtonUp", LINKFUNC(onMouseButtonUp)] call CBA_fnc_addDisplayHandler;
|
["MouseButtonUp", LINKFUNC(onMouseButtonUp)] call CBA_fnc_addDisplayHandler;
|
||||||
GVAR(mouseLeft) = false;
|
GVAR(mouseLeft) = false;
|
||||||
GVAR(mouseRight) = false;
|
GVAR(mouseRight) = false;
|
||||||
GVAR(blockFireEHID) = -1;
|
GVAR(blockFireEHID) = -1;
|
||||||
|
|
||||||
GVAR(cancel) = false;
|
[QGVAR(ropeAttachTo), {
|
||||||
GVAR(canAttach) = false;
|
params ["_child", "_relativeAttachPos", "_rope", "_helper"];
|
||||||
|
TRACE_4("ropeAttachTo",_child,_relativeAttachPos,_rope,_helper);
|
||||||
[QGVAR(setTowParent), {
|
_helper ropeDetach _rope;
|
||||||
params ["_parent", "_child"];
|
[_child, _relativeAttachPos] ropeAttachTo _rope;
|
||||||
_child setTowParent _parent;
|
deleteVehicle _helper;
|
||||||
}] call CBA_fnc_addEventHandler;
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
[QGVAR(attachVehicles), LINKFUNC(attachVehicles)] call CBA_fnc_addEventHandler;
|
||||||
|
[QGVAR(detachChild), LINKFUNC(detachChild)] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
if (!isServer) exitWith {};
|
||||||
|
|
||||||
|
[QGVAR(cleanupParent), {
|
||||||
|
params ["_parent"];
|
||||||
|
TRACE_1("cleanupParent",_parent);
|
||||||
|
_parent removeEventHandler ["RopeBreak", _parent getVariable [QGVAR(RopeBreakEHID), -1]];
|
||||||
|
_parent setVariable [QGVAR(RopeBreakEHID), -1];
|
||||||
|
private _parentParentHooks = _parent getVariable [QGVAR(parentHooks), []];
|
||||||
|
if (_parentParentHooks isEqualTo []) then {
|
||||||
|
TRACE_1("remove Deleted EH",_parent);
|
||||||
|
_parent removeEventHandler ["Deleted", _parent getVariable [QGVAR(DeletedEHID), -1]];
|
||||||
|
_parent setVariable [QGVAR(DeletedEHID), -1];
|
||||||
|
};
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
|
addMissionEventHandler ["PlayerConnected", {
|
||||||
|
if (GVAR(allChildren) isEqualTo []) exitWith {};
|
||||||
|
params ["", "", "", "_jip", "_owner"];
|
||||||
|
if (!_jip) exitWith {};
|
||||||
|
TRACE_2("pushing children",_owner,GVAR(allChildren));
|
||||||
|
[QGVAR(setTowParentAllChildren), [GVAR(allChildren)], _owner] call CBA_fnc_ownerEvent;
|
||||||
|
}];
|
||||||
|
@ -8,4 +8,20 @@ PREP_RECOMPILE_END;
|
|||||||
|
|
||||||
#include "initSettings.inc.sqf"
|
#include "initSettings.inc.sqf"
|
||||||
|
|
||||||
|
// handle JIP
|
||||||
|
if (isServer) then {
|
||||||
|
GVAR(allChildren) = [];
|
||||||
|
} else {
|
||||||
|
// can't use CBA EH in postInit because too late for server PlayerConnected EH
|
||||||
|
[QGVAR(setTowParentAllChildren), {
|
||||||
|
params ["_children"];
|
||||||
|
TRACE_1("setTowParentAllChildren",_children);
|
||||||
|
{
|
||||||
|
private _parent = _x getVariable QGVAR(parent);
|
||||||
|
TRACE_2("setTowParent",_x,_parent);
|
||||||
|
_x setTowParent _parent;
|
||||||
|
} forEach _children;
|
||||||
|
}] call CBA_fnc_addEventHandler;
|
||||||
|
};
|
||||||
|
|
||||||
ADDON = true;
|
ADDON = true;
|
||||||
|
@ -40,13 +40,32 @@ if (_intersections isNotEqualTo []) then {
|
|||||||
|
|
||||||
_intersectionToUse params ["_intersectPosition", "", "_intersectObject"];
|
_intersectionToUse params ["_intersectPosition", "", "_intersectObject"];
|
||||||
|
|
||||||
|
GVAR(canAttach) =
|
||||||
|
_intersectObject isNotEqualTo _ignoreParent
|
||||||
|
&& {
|
||||||
// if we have a target object, we assume we are attaching to the parent. If no target object, we are attaching to child
|
// if we have a target object, we assume we are attaching to the parent. If no target object, we are attaching to child
|
||||||
GVAR(canAttach) = (_intersectObject isNotEqualTo _ignoreParent) && { (!isNull _target && { _intersectObject isEqualTo _target }) || { isNull _target && { [_intersectObject] call FUNC(isSuitableSimulation) }}} && { !(_intersectObject getVariable [QGVAR(towing), false]) };
|
if (!isNull _target) then {
|
||||||
|
_intersectObject isEqualTo _target
|
||||||
|
} else {
|
||||||
|
[_intersectObject] call FUNC(isSuitableSimulation)
|
||||||
|
&& { // ignore _intersectObject which has parent != _ignoreParent
|
||||||
|
private _intersectObjectParent = _intersectObject getVariable [QGVAR(parent), objNull];
|
||||||
|
isNull _intersectObjectParent || {_intersectObjectParent == _ignoreParent}
|
||||||
|
} && { // arma prevents making rings (ropeAttachTo silently fails)
|
||||||
|
private _ancestor = _ignoreParent getVariable [QGVAR(parent), objNull];
|
||||||
|
while {!isNull _ancestor && {_ancestor != _intersectObject}} do {
|
||||||
|
_ancestor = _ancestor getVariable [QGVAR(parent), objNull];
|
||||||
|
};
|
||||||
|
isNull _ancestor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
if (GVAR(canAttach)) then {
|
if (GVAR(canAttach)) then {
|
||||||
TRACE_4("can attach",_target,_intersectObject,_ignoreParent,_ignoreRope);
|
// TRACE_4("can attach",_target,_intersectObject,_ignoreParent,_ignoreRope);
|
||||||
GVAR(attachHelper) setPosASL _intersectPosition;
|
GVAR(attachHelper) setPosASL _intersectPosition;
|
||||||
_hintLMB = localize LSTRING(attach);
|
_hintLMB = LLSTRING(attach);
|
||||||
|
|
||||||
GVAR(attachHelper) setVariable [QGVAR(object), _intersectObject];
|
GVAR(attachHelper) setVariable [QGVAR(object), _intersectObject];
|
||||||
};
|
};
|
||||||
@ -76,4 +95,3 @@ if (_hint isNotEqualTo (_unit getVariable [QGVAR(hint), []])) then {
|
|||||||
_unit setVariable [QGVAR(hint), _hint];
|
_unit setVariable [QGVAR(hint), _hint];
|
||||||
_hint call EFUNC(interaction,showMouseHint);
|
_hint call EFUNC(interaction,showMouseHint);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
65
addons/towing/functions/fnc_attachVehicles.sqf
Normal file
65
addons/towing/functions/fnc_attachVehicles.sqf
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
/*
|
||||||
|
* Author: Dystopian
|
||||||
|
* Attaches child to parent vehicle.
|
||||||
|
* Run globally.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Vehicle to tow from <OBJECT>
|
||||||
|
* 1: Vehicle to tow <OBJECT>
|
||||||
|
* 2: Rope End Position <ARRAY>
|
||||||
|
* 3: Rope <OBJECT>
|
||||||
|
* 4: Attached Helper Object <OBJECT>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [parent, cursorObject, [0,0,0], ropes parent select 0] call ace_towing_fnc_attachVehicles
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
params ["_parent", "_child", "_relativeAttachPos", "_rope", "_helper"];
|
||||||
|
TRACE_5("attachVehicles",_parent,_child,_relativeAttachPos,_rope,_helper);
|
||||||
|
|
||||||
|
if (local _parent) then {
|
||||||
|
_helper ropeDetach _rope;
|
||||||
|
[_child, _relativeAttachPos] ropeAttachTo _rope;
|
||||||
|
deleteVehicle _helper;
|
||||||
|
};
|
||||||
|
|
||||||
|
_child setTowParent _parent;
|
||||||
|
if (!isServer) exitWith {};
|
||||||
|
|
||||||
|
_child setVariable [QGVAR(parent), _parent, true];
|
||||||
|
GVAR(allChildren) pushBack _child;
|
||||||
|
|
||||||
|
{
|
||||||
|
if (-1 == _x getVariable [QGVAR(DeletedEHID), -1]) then {
|
||||||
|
_x setVariable [QGVAR(DeletedEHID), _x addEventHandler ["Deleted", {
|
||||||
|
params ["_entity"];
|
||||||
|
private _childHooks = _entity getVariable [QGVAR(childHooks), []];
|
||||||
|
private _parentHooks = _entity getVariable [QGVAR(parentHooks), []];
|
||||||
|
TRACE_3("Deleted EH",_entity,_childHooks,_parentHooks);
|
||||||
|
{
|
||||||
|
[objNull, _x, _entity] call FUNC(detachRope);
|
||||||
|
} forEach (_childHooks + _parentHooks);
|
||||||
|
if (_childHooks isNotEqualTo []) then { // only for parent
|
||||||
|
// because deleting lasts for several frames we have to delete RB EH to fix double cleanup
|
||||||
|
_entity removeEventHandler ["RopeBreak", _entity getVariable QGVAR(RopeBreakEHID)];
|
||||||
|
};
|
||||||
|
}]];
|
||||||
|
};
|
||||||
|
} forEach [_parent, _child];
|
||||||
|
|
||||||
|
if (-1 == _parent getVariable [QGVAR(RopeBreakEHID), -1]) then {
|
||||||
|
_parent setVariable [QGVAR(RopeBreakEHID), _parent addEventHandler ["RopeBreak", {
|
||||||
|
params ["_parent", "_rope", "_child"];
|
||||||
|
if (isNull _rope) exitWith {}; // happens
|
||||||
|
private _hook = _rope getVariable [QGVAR(hook), objNull];
|
||||||
|
private _hookChild = _hook getVariable [QGVAR(vars), []] param [1, objNull];
|
||||||
|
if (isNull _hook || {_child != _hookChild}) exitWith {}; // handle helper detach
|
||||||
|
TRACE_4("RopeBreak EH",_parent,_rope,_child,_hook);
|
||||||
|
[objNull, _hook] call FUNC(detachRope);
|
||||||
|
}]];
|
||||||
|
};
|
@ -1,21 +0,0 @@
|
|||||||
#include "..\script_component.hpp"
|
|
||||||
/*
|
|
||||||
* Author: tcvm
|
|
||||||
* Condition for whether or not we can tow from this object
|
|
||||||
*
|
|
||||||
* Arguments:
|
|
||||||
* 0: Unit wanting to start towing <OBJECT>
|
|
||||||
* 1: Vehicle to tow from <OBJECT>
|
|
||||||
*
|
|
||||||
* Return Value:
|
|
||||||
* Whether or not we can start towing <BOOLEAN>
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
* [player, cursorObject] call ace_towing_fnc_canStartTow
|
|
||||||
*
|
|
||||||
* Public: No
|
|
||||||
*/
|
|
||||||
params ["_unit", "_target"];
|
|
||||||
private _isTowing = _target getVariable [QGVAR(towing), false];
|
|
||||||
TRACE_1("is towing",_isTowing);
|
|
||||||
!_isTowing
|
|
@ -1,48 +0,0 @@
|
|||||||
#include "..\script_component.hpp"
|
|
||||||
/*
|
|
||||||
* Author: tcvm
|
|
||||||
* Detaches child from parent, and gives rope item back
|
|
||||||
*
|
|
||||||
* Arguments:
|
|
||||||
* 0: Parent <OBJECT>
|
|
||||||
* 1: Child <OBJECT>
|
|
||||||
*
|
|
||||||
* Return Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
* [player, cursorObject] call ace_towing_fnc_detach
|
|
||||||
*
|
|
||||||
* Public: No
|
|
||||||
*/
|
|
||||||
params ["_unit", "_parent", "_child"];
|
|
||||||
TRACE_3("detach",_unit,_parent,_child);
|
|
||||||
|
|
||||||
private _hook = _child getVariable [QGVAR(hook), objNull];
|
|
||||||
|
|
||||||
_parent removeEventHandler ["Deleted", _hook getVariable QGVAR(parentDeleteEventHandler)];
|
|
||||||
_hook setVariable [QGVAR(parentDeleteEventHandler), -1];
|
|
||||||
|
|
||||||
_child removeEventHandler ["Deleted", _hook getVariable QGVAR(childDeleteEventHandler)];
|
|
||||||
_hook setVariable [QGVAR(childDeleteEventHandler), -1];
|
|
||||||
|
|
||||||
_parent removeEventHandler ["RopeBreak", _parent getVariable QGVAR(ropeBreakEventHandler)];
|
|
||||||
_parent setVariable [QGVAR(ropeBreakEventHandler), -1];
|
|
||||||
|
|
||||||
private _rope = _child getVariable [QGVAR(rope), objNull];
|
|
||||||
ropeDestroy _rope;
|
|
||||||
|
|
||||||
private _ropeClass = _hook getVariable [QGVAR(ropeClass), ""];
|
|
||||||
deleteVehicle _hook;
|
|
||||||
|
|
||||||
TRACE_1("rope",_ropeClass);
|
|
||||||
|
|
||||||
if (_ropeClass isNotEqualTo "") then {
|
|
||||||
[_unit, _ropeClass, true] call CBA_fnc_addItem;
|
|
||||||
};
|
|
||||||
|
|
||||||
[QGVAR(setTowParent), [objNull, _child], _child] call CBA_fnc_targetEvent;
|
|
||||||
|
|
||||||
_child setVariable [QGVAR(towing), false, true];
|
|
||||||
_parent setVariable [QGVAR(towing), false, true];
|
|
||||||
|
|
33
addons/towing/functions/fnc_detachChild.sqf
Normal file
33
addons/towing/functions/fnc_detachChild.sqf
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
/*
|
||||||
|
* Author: Dystopian
|
||||||
|
* Detaches child.
|
||||||
|
* Run globally.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Child <OBJECT>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* cursorObject call ace_towing_fnc_detachChild
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
params ["_child"];
|
||||||
|
TRACE_1("detachChild",_child);
|
||||||
|
|
||||||
|
_child setTowParent objNull;
|
||||||
|
|
||||||
|
if (!isServer) exitWith {};
|
||||||
|
|
||||||
|
_child setVariable [QGVAR(parent), objNull, true];
|
||||||
|
GVAR(allChildren) = GVAR(allChildren) - [_child];
|
||||||
|
|
||||||
|
private _childChildHooks = _child getVariable [QGVAR(childHooks), []];
|
||||||
|
if (_childChildHooks isEqualTo []) then {
|
||||||
|
TRACE_1("remove Deleted EH",_child);
|
||||||
|
_child removeEventHandler ["Deleted", _child getVariable [QGVAR(DeletedEHID), -1]];
|
||||||
|
_child setVariable [QGVAR(DeletedEHID), -1];
|
||||||
|
};
|
60
addons/towing/functions/fnc_detachRope.sqf
Normal file
60
addons/towing/functions/fnc_detachRope.sqf
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
/*
|
||||||
|
* Author: Dystopian
|
||||||
|
* Detaches rope of given hook and gives rope item back.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Player <OBJECT>
|
||||||
|
* 1: Rope Hook <OBJECT>
|
||||||
|
* 2: Deleted object <OBJECT> (default: objNull)
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [player, cursorObject] call ace_towing_fnc_detachRope
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
params ["_unit", "_hook", ["_deletedObject", objNull]];
|
||||||
|
|
||||||
|
private _hookVars = _hook getVariable QGVAR(vars);
|
||||||
|
if (isNil "_hookVars") then { // this is hookParent
|
||||||
|
_hook = _hook getVariable QGVAR(hook);
|
||||||
|
_hookVars = _hook getVariable QGVAR(vars);
|
||||||
|
};
|
||||||
|
|
||||||
|
_hookVars params ["_parent", "_child", "_rope", "_ropeClass", "_hookParent"];
|
||||||
|
|
||||||
|
TRACE_8("detachRope",_unit,_parent,_child,_hook,_hookParent,_rope,_ropeClass,_deletedObject);
|
||||||
|
|
||||||
|
ropeDestroy _rope; // can run on client
|
||||||
|
|
||||||
|
if (!isNull _unit && {_ropeClass isNotEqualTo ""}) then {
|
||||||
|
[_unit, _ropeClass, true] call CBA_fnc_addItem;
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
detach _x;
|
||||||
|
deleteVehicle _x;
|
||||||
|
} forEach [_hook, _hookParent];
|
||||||
|
|
||||||
|
// cleanup object variables and EHs only if function isn't called from Deleted EH
|
||||||
|
if (isNull _deletedObject || {_parent isNotEqualTo _deletedObject}) then {
|
||||||
|
private _parentChildHooks = _parent getVariable [QGVAR(childHooks), []];
|
||||||
|
_parentChildHooks = _parentChildHooks - [_hook];
|
||||||
|
_parent setVariable [QGVAR(childHooks), _parentChildHooks, true];
|
||||||
|
|
||||||
|
if (_parentChildHooks isEqualTo []) then {
|
||||||
|
[QGVAR(cleanupParent), _parent] call CBA_fnc_serverEvent;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if (isNull _deletedObject || {_child isNotEqualTo _deletedObject}) then {
|
||||||
|
private _childParentHooks = _child getVariable [QGVAR(parentHooks), []];
|
||||||
|
_childParentHooks = _childParentHooks - [_hook];
|
||||||
|
_child setVariable [QGVAR(parentHooks), _childParentHooks, true];
|
||||||
|
|
||||||
|
if (_childParentHooks isEqualTo []) then {
|
||||||
|
[QGVAR(detachChild), _child] call CBA_fnc_globalEvent;
|
||||||
|
};
|
||||||
|
};
|
40
addons/towing/functions/fnc_getDetachActions.sqf
Normal file
40
addons/towing/functions/fnc_getDetachActions.sqf
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
/*
|
||||||
|
* Author: Dystopian
|
||||||
|
* Creates vehicle detach actions for attached ropes.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Vehicle <OBJECT>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* Detach actions <ARRAY>
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* cursorObject call ace_towing_fnc_getDetachActions
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
params ["_vehicle"];
|
||||||
|
|
||||||
|
private _statement = {
|
||||||
|
params ["", "_player", "_hook"];
|
||||||
|
[_player, _hook] call FUNC(detachRope);
|
||||||
|
};
|
||||||
|
|
||||||
|
private _parentHooks = _vehicle getVariable [QGVAR(parentHooks), []];
|
||||||
|
private _childHooks = _vehicle getVariable [QGVAR(childHooks), []];
|
||||||
|
|
||||||
|
(_parentHooks + _childHooks) apply {
|
||||||
|
private _hook = _x;
|
||||||
|
_hook getVariable QGVAR(vars) params ["_hookParent", "_hookChild"];
|
||||||
|
private _partner = [_hookParent, _hookChild] select (_vehicle == _hookParent);
|
||||||
|
private _partnerName = getText (configOf _partner >> "displayName");
|
||||||
|
private _partnerOwnerName = [_partner, true] call EFUNC(common,getName);
|
||||||
|
if (_partnerOwnerName != "") then {
|
||||||
|
_partnerName = format ["%1, %2", _partnerName, _partnerOwnerName];
|
||||||
|
};
|
||||||
|
private _name = format ["%1 (%2)", LLSTRING(detach), _partnerName];
|
||||||
|
private _icon = [_partner] call EFUNC(common,getVehicleIcon);
|
||||||
|
private _action = [format ["%1", _hook], _name, _icon, _statement, {true}, {}, _hook] call EFUNC(interact_menu,createAction);
|
||||||
|
[_action, [], _vehicle]
|
||||||
|
}
|
@ -19,8 +19,7 @@ params ["_target"];
|
|||||||
|
|
||||||
// need toLower since apparently this isn't case sensitive
|
// need toLower since apparently this isn't case sensitive
|
||||||
private _simulationType = getText ((configOf _target) >> "simulation");
|
private _simulationType = getText ((configOf _target) >> "simulation");
|
||||||
TRACE_1("sim type",_simulationType);
|
// TRACE_1("sim type",_simulationType);
|
||||||
|
|
||||||
// Biki lies, you can both tow and tow as either TankX or CarX
|
// Biki lies, you can both tow and tow as either TankX or CarX
|
||||||
(toLower _simulationType) in ["tankx", "carx"]
|
(toLower _simulationType) in ["tankx", "carx", "shipx"]
|
||||||
|
|
||||||
|
@ -32,5 +32,6 @@ GVAR(isSwimming) = _unit call EFUNC(common,isSwimming);
|
|||||||
GVAR(putWeaponAwayNextFrame) = false;
|
GVAR(putWeaponAwayNextFrame) = false;
|
||||||
GVAR(cancel) = false;
|
GVAR(cancel) = false;
|
||||||
GVAR(canAttach) = false;
|
GVAR(canAttach) = false;
|
||||||
|
GVAR(onMouseButtonDownEHID) = ["MouseButtonDown", LINKFUNC(onMouseButtonDown)] call CBA_fnc_addDisplayHandler;
|
||||||
[LINKFUNC(towStateMachinePFH), 0, [TOW_STATE_ATTACH_PARENT, _unit, _target, objNull, _ropeLength, _ropeClass]] call CBA_fnc_addPerFrameHandler;
|
[LINKFUNC(towStateMachinePFH), 0, [TOW_STATE_ATTACH_PARENT, _unit, _target, objNull, _ropeLength, _ropeClass]] call CBA_fnc_addPerFrameHandler;
|
||||||
[QGVAR(ropeDeployed), [_unit, _target, _ropeClass]] call CBA_fnc_localEvent;
|
[QGVAR(ropeDeployed), [_unit, _target, _ropeClass]] call CBA_fnc_localEvent;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: tcvm
|
* Author: tcvm
|
||||||
* Called per frame. Handles current unit state for attaching a rope to two vehicles
|
* Called per frame. Handles current unit state for attaching a rope to two vehicles.
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: PFEH Args <ARRAY>
|
* 0: PFEH Args <ARRAY>
|
||||||
@ -62,14 +62,16 @@ if (_exitCondition && {_state < TOW_STATE_CANCEL}) then {
|
|||||||
|
|
||||||
switch (_state) do {
|
switch (_state) do {
|
||||||
case TOW_STATE_ATTACH_PARENT: {
|
case TOW_STATE_ATTACH_PARENT: {
|
||||||
TRACE_2("state attach parent",_unit,_parent);
|
// TRACE_2("state attach parent",_unit,_parent);
|
||||||
[_unit, _parent, objNull, objNull, [0, 0, 0], _length] call FUNC(attachRopePFH);
|
[_unit, _parent, objNull, objNull, [0, 0, 0], _length] call FUNC(attachRopePFH);
|
||||||
|
|
||||||
if (GVAR(canAttach) && { GVAR(mouseLeft) }) then {
|
if (GVAR(canAttach) && { GVAR(mouseLeft) }) then {
|
||||||
_args set [0, TOW_STATE_ATTACH_CHILD];
|
_args set [0, TOW_STATE_ATTACH_CHILD];
|
||||||
_rope = ropeCreate [_parent, _parent worldToModelVisual ASLtoAGL getPosASLVisual GVAR(attachHelper), _length];
|
// can't use unit hand because rope doesn't change position when hand moving
|
||||||
[GVAR(attachHelper), [0, 0, 0]] ropeAttachTo _rope;
|
// can't use createVehicleLocal because rope can be non-local (like parent) and it must be attached to global vehicle
|
||||||
|
GVAR(helper) = createVehicle [QGVAR(helper), [0, 0, 0], [], 0, "CAN_COLLIDE"];
|
||||||
|
GVAR(helper) attachTo [_unit, [0, 0, 0], "LeftHand", true];
|
||||||
|
_rope = ropeCreate [_parent, _parent worldToModelVisual ASLtoAGL getPosASLVisual GVAR(attachHelper), GVAR(helper), [0, 0, 0], _length];
|
||||||
_args set [3, _rope];
|
_args set [3, _rope];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -79,7 +81,7 @@ switch (_state) do {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
case TOW_STATE_ATTACH_CHILD: {
|
case TOW_STATE_ATTACH_CHILD: {
|
||||||
TRACE_3("state attach child",_unit,_parent,_rope);
|
// TRACE_3("state attach child",_unit,_parent,_rope);
|
||||||
[_unit, objNull, _parent, _rope, getPosASLVisual _rope, _length] call FUNC(attachRopePFH);
|
[_unit, objNull, _parent, _rope, getPosASLVisual _rope, _length] call FUNC(attachRopePFH);
|
||||||
|
|
||||||
if (GVAR(canAttach) && { GVAR(mouseLeft) }) then {
|
if (GVAR(canAttach) && { GVAR(mouseLeft) }) then {
|
||||||
@ -108,60 +110,42 @@ switch (_state) do {
|
|||||||
GVAR(cancel) = false;
|
GVAR(cancel) = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
[QGVAR(setTowParent), [_parent, _child], _parent] call CBA_fnc_targetEvent;
|
detach GVAR(helper);
|
||||||
|
// can't delete GVAR(helper) without ropeDetach which requires local rope (==parent), so pass it to owner
|
||||||
|
if (isNull (_child getVariable [QGVAR(parent), objNull])) then {
|
||||||
|
[QGVAR(attachVehicles), [_parent, _child, _relativeAttachPos, _rope, GVAR(helper)]] call CBA_fnc_globalEvent;
|
||||||
|
} else {
|
||||||
|
[QGVAR(ropeAttachTo), [_child, _relativeAttachPos, _rope, GVAR(helper)], _parent] call CBA_fnc_targetEvent;
|
||||||
|
};
|
||||||
|
|
||||||
GVAR(attachHelper) ropeDetach _rope;
|
private _hookParent = createVehicle [QGVAR(hook), [0, 0, 0], [], 0, "CAN_COLLIDE"];
|
||||||
[_child, _relativeAttachPos] ropeAttachTo _rope;
|
_hookParent attachTo [_parent, _parent worldToModelVisual ASLtoAGL getPosASLVisual _rope];
|
||||||
|
|
||||||
private _hook = createVehicle [QGVAR(hook), [0, 0, 0], [], 0, "NONE"];
|
private _hook = createVehicle [QGVAR(hook), [0, 0, 0], [], 0, "CAN_COLLIDE"];
|
||||||
_hook attachTo [_child, _relativeAttachPos];
|
_hook attachTo [_child, _relativeAttachPos];
|
||||||
|
|
||||||
_hook setVariable [QGVAR(parent), _parent, true];
|
// use array to decrease public setVar count
|
||||||
_hook setVariable [QGVAR(child), _child, true];
|
private _hookVars = [_parent, _child, _rope, _ropeClass, _hookParent];
|
||||||
_child setVariable [QGVAR(rope), _rope, true];
|
_hook setVariable [QGVAR(vars), _hookVars, true];
|
||||||
_child setVariable [QGVAR(hook), _hook, true];
|
|
||||||
|
|
||||||
_parent setVariable [QGVAR(hook), _hook, true];
|
_hookParent setVariable [QGVAR(hook), _hook, true];
|
||||||
|
_rope setVariable [QGVAR(hook), _hook, true];
|
||||||
|
|
||||||
_hook setVariable [QGVAR(ropeClass), _ropeClass, true];
|
private _childParentHooks = _child getVariable [QGVAR(parentHooks), []];
|
||||||
|
_childParentHooks pushBack _hook;
|
||||||
|
_child setVariable [QGVAR(parentHooks), _childParentHooks, true];
|
||||||
|
|
||||||
_child setVariable [QGVAR(towing), true, true];
|
private _parentChildHooks = _parent getVariable [QGVAR(childHooks), []];
|
||||||
_parent setVariable [QGVAR(towing), true, true];
|
_parentChildHooks pushBack _hook;
|
||||||
|
_parent setVariable [QGVAR(childHooks), _parentChildHooks, true];
|
||||||
_hook setVariable [QGVAR(parentDeleteEventHandler), _parent addEventHandler ["Deleted", {
|
|
||||||
params ["_entity"];
|
|
||||||
|
|
||||||
private _hook = _entity getVariable [QGVAR(hook), objNull];
|
|
||||||
private _child = _hook getVariable [QGVAR(child), objNull];
|
|
||||||
private _parent = _hook getVariable [QGVAR(parent), objNull];
|
|
||||||
|
|
||||||
[objNull, _parent, _child] call FUNC(detach);
|
|
||||||
}], true];
|
|
||||||
|
|
||||||
_hook setVariable [QGVAR(childDeleteEventHandler), _child addEventHandler ["Deleted", {
|
|
||||||
params ["_entity"];
|
|
||||||
|
|
||||||
private _hook = _entity getVariable [QGVAR(hook), objNull];
|
|
||||||
private _child = _hook getVariable [QGVAR(child), objNull];
|
|
||||||
private _parent = _hook getVariable [QGVAR(parent), objNull];
|
|
||||||
|
|
||||||
[objNull, _parent, _child] call FUNC(detach);
|
|
||||||
}], true];
|
|
||||||
|
|
||||||
_parent setVariable [QGVAR(ropeBreakEventHandler), _parent addEventHandler ["RopeBreak", {
|
|
||||||
params ["_parent", "_rope", "_child"];
|
|
||||||
|
|
||||||
[objNull, _parent, _child] call FUNC(detach);
|
|
||||||
|
|
||||||
_parent removeEventHandler ["RopeBreak", _parent getVariable QGVAR(ropeBreakEventHandler)];
|
|
||||||
_parent setVariable [QGVAR(ropeBreakEventHandler), -1];
|
|
||||||
}], true];
|
|
||||||
|
|
||||||
_args set [0, TOW_STATE_CLEANUP];
|
_args set [0, TOW_STATE_CLEANUP];
|
||||||
};
|
};
|
||||||
case TOW_STATE_CANCEL: {
|
case TOW_STATE_CANCEL: {
|
||||||
TRACE_1("state cancel",_rope);
|
TRACE_1("state cancel",_rope);
|
||||||
if !(isNull _rope) then {
|
if !(isNull _rope) then {
|
||||||
|
detach GVAR(helper);
|
||||||
|
deleteVehicle GVAR(helper);
|
||||||
ropeDestroy _rope;
|
ropeDestroy _rope;
|
||||||
};
|
};
|
||||||
[_unit, _ropeClass, true] call CBA_fnc_addItem;
|
[_unit, _ropeClass, true] call CBA_fnc_addItem;
|
||||||
@ -174,6 +158,7 @@ switch (_state) do {
|
|||||||
TRACE_2("state cleanup",GVAR(attachHelper),_handle);
|
TRACE_2("state cleanup",GVAR(attachHelper),_handle);
|
||||||
deleteVehicle GVAR(attachHelper);
|
deleteVehicle GVAR(attachHelper);
|
||||||
[_handle] call CBA_fnc_removePerFrameHandler;
|
[_handle] call CBA_fnc_removePerFrameHandler;
|
||||||
|
["MouseButtonDown", GVAR(onMouseButtonDownEHID)] call CBA_fnc_removeDisplayHandler;
|
||||||
_unit setVariable [QGVAR(hint), []];
|
_unit setVariable [QGVAR(hint), []];
|
||||||
call EFUNC(interaction,hideMouseHint);
|
call EFUNC(interaction,hideMouseHint);
|
||||||
if (GVAR(blockFireEHID) != -1) then {
|
if (GVAR(blockFireEHID) != -1) then {
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
{
|
{
|
||||||
if !(_this && {isServer} && {isNil QGVAR(addRopeToVehicleInventory_initialized)}) exitWith {};
|
if !(_this && {isServer} && {isNil QGVAR(addRopeToVehicleInventory_initialized)}) exitWith {};
|
||||||
GVAR(addRopeToVehicleInventory_initialized) = true;
|
GVAR(addRopeToVehicleInventory_initialized) = true;
|
||||||
["Tank", "initPost", LINKFUNC(addRopeToVehicle), true, [], true] call CBA_fnc_addClassEventHandler;
|
{
|
||||||
["Car", "initPost", LINKFUNC(addRopeToVehicle), true, [], true] call CBA_fnc_addClassEventHandler;
|
[_x, "initPost", LINKFUNC(addRopeToVehicle), true, [], true] call CBA_fnc_addClassEventHandler;
|
||||||
|
} forEach ["Car", "Ship", "Tank"];
|
||||||
}
|
}
|
||||||
] call CBA_fnc_addSetting;
|
] call CBA_fnc_addSetting;
|
||||||
|
@ -24,4 +24,3 @@
|
|||||||
#define TOW_STATE_ATTACH 2
|
#define TOW_STATE_ATTACH 2
|
||||||
#define TOW_STATE_CANCEL 3
|
#define TOW_STATE_CANCEL 3
|
||||||
#define TOW_STATE_CLEANUP 4
|
#define TOW_STATE_CLEANUP 4
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user