mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Ported the ACE2 Tripod
This commit is contained in:
parent
97a4fefe60
commit
e7add69556
1
addons/tripod/$PBOPREFIX$
Normal file
1
addons/tripod/$PBOPREFIX$
Normal file
@ -0,0 +1 @@
|
|||||||
|
z\ace\addons\concertina_wire
|
19
addons/tripod/CfgEventHandlers.hpp
Normal file
19
addons/tripod/CfgEventHandlers.hpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
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) );
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Extended_Init_EventHandlers {
|
||||||
|
class ACE_TripodObject {
|
||||||
|
class ADDON {
|
||||||
|
init = QUOTE(_this call DEFUNC(dragging,initObject));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
93
addons/tripod/CfgVehicles.hpp
Normal file
93
addons/tripod/CfgVehicles.hpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
|
||||||
|
class CfgVehicles {
|
||||||
|
class Man;
|
||||||
|
class CAManBase: Man {
|
||||||
|
class ACE_SelfActions {
|
||||||
|
class ACE_Equipment {
|
||||||
|
class GVAR(place) {
|
||||||
|
displayName = CSTRING(Placedown);
|
||||||
|
condition = QUOTE([ARR_2(_player,'ACE_Tripod')] call EFUNC(common,hasItem));
|
||||||
|
statement = QUOTE([ARR_2(_player,'ACE_Tripod')] call FUNC(place));
|
||||||
|
showDisabled = 0;
|
||||||
|
priority = 2;
|
||||||
|
icon = PATHTOF(UI\w_sniper_tripod_ca.paa);
|
||||||
|
exceptions[] = {"isNotInside"};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Item_Base_F;
|
||||||
|
class ACE_Item_Tripod: Item_Base_F {
|
||||||
|
author[] = {"Rocko", "Scubaman3D"};
|
||||||
|
scope = 2;
|
||||||
|
scopeCurator = 2;
|
||||||
|
displayName = CSTRING(DisplayName);
|
||||||
|
vehicleClass = "Items";
|
||||||
|
class TransportItems {
|
||||||
|
class ACE_Tripod {
|
||||||
|
name = "ACE_Tripod";
|
||||||
|
count = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Box_NATO_Support_F;
|
||||||
|
class ACE_Box_Misc: Box_NATO_Support_F {
|
||||||
|
class TransportItems {
|
||||||
|
MACRO_ADDITEM(ACE_Tripod,2);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class thingX;
|
||||||
|
class ACE_TripodObject: thingX {
|
||||||
|
XEH_ENABLED;
|
||||||
|
scope = 2;
|
||||||
|
displayName = CSTRING(DisplayName);
|
||||||
|
model = PATHTOF(data\sniper_tripod.p3d);
|
||||||
|
class AnimationSources {
|
||||||
|
class slide_down_tripod {
|
||||||
|
source = "user";
|
||||||
|
animPeriod = 0.02;
|
||||||
|
initPhase = 0;
|
||||||
|
minValue = 0;
|
||||||
|
maxValue = 1;
|
||||||
|
};
|
||||||
|
class retract_leg_1: slide_down_tripod {};
|
||||||
|
class retract_leg_2: retract_leg_1 {};
|
||||||
|
class retract_leg_3: retract_leg_2 {};
|
||||||
|
};
|
||||||
|
EGVAR(dragging,canDrag) = 1;
|
||||||
|
EGVAR(dragging,dragPosition[]) = {0,1,1.5};
|
||||||
|
EGVAR(dragging,dragDirection) = 0;
|
||||||
|
class ACE_Actions {
|
||||||
|
class ACE_MainActions {
|
||||||
|
selection = "";
|
||||||
|
distance = 5;
|
||||||
|
condition = "true";
|
||||||
|
class ACE_Pickup {
|
||||||
|
selection = "";
|
||||||
|
displayName = CSTRING(PickUp);
|
||||||
|
distance = 5;
|
||||||
|
condition = "true";
|
||||||
|
statement = QUOTE([ARR_2(_target,_player)] call FUNC(pickup));
|
||||||
|
showDisabled = 0;
|
||||||
|
exceptions[] = {};
|
||||||
|
priority = 5;
|
||||||
|
icon = PATHTOF(UI\w_sniper_tripod_ca.paa);
|
||||||
|
};
|
||||||
|
class ACE_Adjust {
|
||||||
|
selection = "";
|
||||||
|
displayName = CSTRING(Adjust);
|
||||||
|
distance = 5;
|
||||||
|
condition = "true";
|
||||||
|
statement = QUOTE(_target call FUNC(adjust));
|
||||||
|
showDisabled = 0;
|
||||||
|
exceptions[] = {};
|
||||||
|
priority = 5;
|
||||||
|
icon = PATHTOF(UI\w_sniper_tripod_ca.paa);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
18
addons/tripod/CfgWeapons.hpp
Normal file
18
addons/tripod/CfgWeapons.hpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
class CfgWeapons {
|
||||||
|
class ACE_ItemCore;
|
||||||
|
class InventoryItem_Base_F;
|
||||||
|
|
||||||
|
class ACE_Tripod: ACE_ItemCore {
|
||||||
|
author[] = {"Rocko", "Scubaman3D"};
|
||||||
|
scope = 2;
|
||||||
|
displayName = CSTRING(DisplayName);
|
||||||
|
descriptionShort = "";
|
||||||
|
model = PATHTOF(data\w_sniper_tripod.p3d);
|
||||||
|
picture = PATHTOF(UI\w_sniper_tripod_ca.paa);
|
||||||
|
|
||||||
|
class ItemInfo: InventoryItem_Base_F {
|
||||||
|
mass = 40;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
10
addons/tripod/README.md
Normal file
10
addons/tripod/README.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
ace_tripod
|
||||||
|
===============
|
||||||
|
|
||||||
|
Adds a packable tripod.
|
||||||
|
|
||||||
|
## Maintainers
|
||||||
|
|
||||||
|
The people responsible for merging changes to this component or answering potential questions.
|
||||||
|
|
||||||
|
- [Ruthberg] (http://github.com/Ulteq)
|
BIN
addons/tripod/UI/w_sniper_tripod_ca.paa
Normal file
BIN
addons/tripod/UI/w_sniper_tripod_ca.paa
Normal file
Binary file not shown.
16
addons/tripod/XEH_postInit.sqf
Normal file
16
addons/tripod/XEH_postInit.sqf
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
GVAR(adjuster) = objNull;
|
||||||
|
GVAR(adjusting) = false;
|
||||||
|
GVAR(adjustPFH) = -1;
|
||||||
|
|
||||||
|
GVAR(height) = 0;
|
||||||
|
|
||||||
|
// Cancel adjustment if interact menu opens
|
||||||
|
["interactMenuOpened", {
|
||||||
|
if (GVAR(adjustPFH) != -1 && GVAR(adjusting)) then {
|
||||||
|
GVAR(adjusting) = false;
|
||||||
|
};
|
||||||
|
}] call EFUNC(common,addEventHandler);
|
||||||
|
|
||||||
|
[{(_this select 0) call FUNC(handleScrollWheel);}] call EFUNC(Common,addScrollWheelEventHandler);
|
10
addons/tripod/XEH_preInit.sqf
Normal file
10
addons/tripod/XEH_preInit.sqf
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
ADDON = false;
|
||||||
|
|
||||||
|
PREP(adjust);
|
||||||
|
PREP(handleScrollWheel);
|
||||||
|
PREP(pickup);
|
||||||
|
PREP(place);
|
||||||
|
|
||||||
|
ADDON = true;
|
16
addons/tripod/config.cpp
Normal file
16
addons/tripod/config.cpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
class CfgPatches {
|
||||||
|
class ADDON {
|
||||||
|
units[] = {"ACE_Item_Tripod"};
|
||||||
|
weapons[] = {"ACE_Tripod"};
|
||||||
|
requiredVersion = REQUIRED_VERSION;
|
||||||
|
requiredAddons[] = {"ace_interaction"};
|
||||||
|
author[] = {"Rocko", "Scubaman3D", "Ruthberg"};
|
||||||
|
VERSION_CONFIG;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "CfgEventHandlers.hpp"
|
||||||
|
#include "CfgVehicles.hpp"
|
||||||
|
#include "CfgWeapons.hpp"
|
64
addons/tripod/data/model.cfg
Normal file
64
addons/tripod/data/model.cfg
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
class CfgSkeletons
|
||||||
|
{
|
||||||
|
class Default {
|
||||||
|
isDiscrete = 1;
|
||||||
|
skeletonInherit = "";
|
||||||
|
skeletonBones[] = {};
|
||||||
|
};
|
||||||
|
class ace_snipertripod_skeleton: Default {
|
||||||
|
isDiscrete = 1;
|
||||||
|
skeletonInherit = "Default";
|
||||||
|
skeletonBones[] = {
|
||||||
|
"tripod","",
|
||||||
|
"leg_1","tripod",
|
||||||
|
"leg_2","tripod",
|
||||||
|
"leg_3","tripod",
|
||||||
|
"leg_slide_1","leg_1",
|
||||||
|
"leg_slide_2","leg_2",
|
||||||
|
"leg_slide_3","leg_3"
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
class CfgModels {
|
||||||
|
class Default {
|
||||||
|
sectionsInherit = "";
|
||||||
|
sections[] = {};
|
||||||
|
skeletonName = "";
|
||||||
|
};
|
||||||
|
class sniper_tripod: Default {
|
||||||
|
skeletonName = "ace_snipertripod_skeleton";
|
||||||
|
sectionsInherit = "Default";
|
||||||
|
class animations {
|
||||||
|
class slide_down_tripod {
|
||||||
|
type = "translation";
|
||||||
|
selection = "tripod";
|
||||||
|
source = "user";
|
||||||
|
begin = "slide_end";
|
||||||
|
end = "slide_start";
|
||||||
|
memory = 1;
|
||||||
|
minValue = 0;
|
||||||
|
maxValue = 1;
|
||||||
|
sourceAddress = "clamp";
|
||||||
|
offset0 = 0;
|
||||||
|
offset1 = 0.855;
|
||||||
|
};
|
||||||
|
class retract_leg_1: slide_down_tripod {
|
||||||
|
selection = "leg_slide_1";
|
||||||
|
begin = "slide_end_1";
|
||||||
|
end = "slide_start_1";
|
||||||
|
offset0 = 0;
|
||||||
|
offset1 = -0.95;
|
||||||
|
};
|
||||||
|
class retract_leg_2: retract_leg_1 {
|
||||||
|
selection = "leg_slide_2";
|
||||||
|
begin = "slide_end_2";
|
||||||
|
end = "slide_start_2";
|
||||||
|
};
|
||||||
|
class retract_leg_3: retract_leg_2 {
|
||||||
|
selection = "leg_slide_3";
|
||||||
|
begin = "slide_end_3";
|
||||||
|
end = "slide_start_3";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
BIN
addons/tripod/data/nipertripod_co.paa
Normal file
BIN
addons/tripod/data/nipertripod_co.paa
Normal file
Binary file not shown.
BIN
addons/tripod/data/sniper_tripod.p3d
Normal file
BIN
addons/tripod/data/sniper_tripod.p3d
Normal file
Binary file not shown.
BIN
addons/tripod/data/w_sniper_tripod.p3d
Normal file
BIN
addons/tripod/data/w_sniper_tripod.p3d
Normal file
Binary file not shown.
43
addons/tripod/functions/fnc_adjust.sqf
Normal file
43
addons/tripod/functions/fnc_adjust.sqf
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Author: Ruthberg
|
||||||
|
*
|
||||||
|
* Adjust tripod height
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: tripod <OBJECT>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* Nothing
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* None
|
||||||
|
*/
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
PARAMS_1(_tripod);
|
||||||
|
|
||||||
|
GVAR(adjuster) = ACE_player;
|
||||||
|
GVAR(adjusting) = true;
|
||||||
|
|
||||||
|
GVAR(adjustPFH) = [{
|
||||||
|
EXPLODE_1_PVT(_this select 0,_tripod);
|
||||||
|
|
||||||
|
if (GVAR(adjuster) != ACE_player || !GVAR(adjusting)) exitWith {
|
||||||
|
call EFUNC(interaction,hideMouseHint);
|
||||||
|
[ACE_player, "DefaultAction", ACE_player getVariable [QGVAR(Adjust), -1]] call EFUNC(Common,removeActionEventHandler);
|
||||||
|
[_this select 1] call cba_fnc_removePerFrameHandler;
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
_tripod animate [_x, 1 - GVAR(height)];
|
||||||
|
} foreach ["slide_down_tripod", "retract_leg_1", "retract_leg_2", "retract_leg_3"];
|
||||||
|
|
||||||
|
}, 0, [_tripod]] call CBA_fnc_addPerFrameHandler;
|
||||||
|
|
||||||
|
[localize "STR_ACE_Tripod_Done", "", localize "STR_ACE_Tripod_ScrollAction"] call EFUNC(interaction,showMouseHint);
|
||||||
|
|
||||||
|
ACE_player setVariable [QGVAR(Adjust),
|
||||||
|
[ACE_player, "DefaultAction",
|
||||||
|
{GVAR(adjustPFH) != -1 && GVAR(adjusting)},
|
||||||
|
{GVAR(adjusting) = false;}
|
||||||
|
] call EFUNC(common,AddActionEventHandler)];
|
24
addons/tripod/functions/fnc_handleScrollWheel.sqf
Normal file
24
addons/tripod/functions/fnc_handleScrollWheel.sqf
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Author: Garth 'L-H' de Wet, Ruthberg
|
||||||
|
* Handles sandbag rotation
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: scroll amount <NUMBER>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* handled <BOOL>
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* 1.2 call ace_tripod_fnc_handleScrollWheel;
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
PARAMS_1(_scroll);
|
||||||
|
|
||||||
|
if (GETMVAR(ACE_Modifier,0) == 0 || GVAR(adjustPFH) == -1) exitWith { false };
|
||||||
|
|
||||||
|
GVAR(height) = 0 max (GVAR(height) + (_scroll / 20)) min 1;
|
||||||
|
|
||||||
|
true
|
30
addons/tripod/functions/fnc_pickup.sqf
Normal file
30
addons/tripod/functions/fnc_pickup.sqf
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Author: Rocko, Ruthberg
|
||||||
|
*
|
||||||
|
* Pick up tripod
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: tripod <OBJECT>
|
||||||
|
* 1: unit <OBJECT>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* Nothing
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* None
|
||||||
|
*/
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
PARAMS_2(_tripod,_unit);
|
||||||
|
|
||||||
|
if ((_unit call CBA_fnc_getUnitAnim) select 0 == "stand") then {
|
||||||
|
_unit playMove "AmovPercMstpSrasWrflDnon_diary";
|
||||||
|
};
|
||||||
|
|
||||||
|
[{
|
||||||
|
PARAMS_2(_tripod,_unit);
|
||||||
|
|
||||||
|
_unit addItem "ACE_Tripod";
|
||||||
|
deleteVehicle _tripod;
|
||||||
|
|
||||||
|
}, [_tripod, _unit], 1, 0]call EFUNC(common,waitAndExecute);
|
50
addons/tripod/functions/fnc_place.sqf
Normal file
50
addons/tripod/functions/fnc_place.sqf
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Author: Rocko, Ruthberg
|
||||||
|
*
|
||||||
|
* Place down tripod
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: unit <OBJECT>
|
||||||
|
* 1: tripod class <STRING>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* Nothing
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* None
|
||||||
|
*/
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
PARAMS_2(_unit,_tripodClass);
|
||||||
|
|
||||||
|
_unit removeItem _tripodClass;
|
||||||
|
|
||||||
|
if ((_unit call CBA_fnc_getUnitAnim) select 0 == "stand") then {
|
||||||
|
_unit playMove "AmovPercMstpSrasWrflDnon_diary";
|
||||||
|
};
|
||||||
|
|
||||||
|
[{
|
||||||
|
PARAMS_1(_unit);
|
||||||
|
|
||||||
|
private ["_direction", "_position", "_tripod"];
|
||||||
|
_direction = getDir _unit;
|
||||||
|
_position = (getPosASL _unit) vectorAdd [0.8 * sin(_direction), 0.8 * cos(_direction), 0.02];
|
||||||
|
|
||||||
|
_tripod = "ACE_TripodObject" createVehicle [0, 0, 0];
|
||||||
|
{
|
||||||
|
_tripod animate [_x, 1];
|
||||||
|
} foreach ["slide_down_tripod", "retract_leg_1", "retract_leg_2", "retract_leg_3"];
|
||||||
|
|
||||||
|
[{
|
||||||
|
EXPLODE_3_PVT(_this select 0,_tripod,_direction,_position);
|
||||||
|
if (_tripod animationPhase "slide_down_tripod" == 1) then {
|
||||||
|
_tripod setDir _direction;
|
||||||
|
_tripod setPosASL _position;
|
||||||
|
if ((getPosATL _tripod select 2) - (getPos _tripod select 2) < 1E-5) then {
|
||||||
|
_tripod setVectorUp (surfaceNormal (position _tripod));
|
||||||
|
};
|
||||||
|
[_this select 1] call CBA_fnc_removePerFrameHandler;
|
||||||
|
};
|
||||||
|
}, 0, [_tripod, _direction, _position]] call CBA_fnc_addPerFrameHandler;
|
||||||
|
|
||||||
|
}, [_unit], 1, 0] call EFUNC(common,waitAndExecute);
|
1
addons/tripod/functions/script_component.hpp
Normal file
1
addons/tripod/functions/script_component.hpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "\z\ace\addons\tripod\script_component.hpp"
|
12
addons/tripod/script_component.hpp
Normal file
12
addons/tripod/script_component.hpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#define COMPONENT tripod
|
||||||
|
#include "\z\ace\addons\main\script_mod.hpp"
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED_TRIPOD
|
||||||
|
#define DEBUG_MODE_FULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_SETTINGS_TRIPOD
|
||||||
|
#define DEBUG_SETTINGS DEBUG_SETTINGS_TRIPOD
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "\z\ace\addons\main\script_macros.hpp"
|
39
addons/tripod/stringtable.xml
Normal file
39
addons/tripod/stringtable.xml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project name="ACE">
|
||||||
|
<Package name="tripod">
|
||||||
|
<Key ID="STR_ACE_Tripod_DisplayName">
|
||||||
|
<English>SSWT Kit</English>
|
||||||
|
<German>Scharfschützenzweibein</German>
|
||||||
|
<Russian>Снайперский штатив</Russian>
|
||||||
|
<Polish>Trójnóg snajperski</Polish>
|
||||||
|
<Spanish>SSWT Kit</Spanish>
|
||||||
|
<French>SSWT Kit</French>
|
||||||
|
<Czech>SSWT sada</Czech>
|
||||||
|
<Italian>SSWT Kit</Italian>
|
||||||
|
<Hungarian>SSWT Kit</Hungarian>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_Tripod_PlaceDown">
|
||||||
|
<English>Place SSWT Kit</English>
|
||||||
|
<German>Scharfschützenzweibein aufstellen</German>
|
||||||
|
<Russian>Установить снайперский штатив</Russian>
|
||||||
|
<Polish>Postaw trójnóg snajperski</Polish>
|
||||||
|
<Spanish>Place SSWT Kit</Spanish>
|
||||||
|
<French>Place SSWT Kit</French>
|
||||||
|
<Czech>Rozlož sadu SSWT</Czech>
|
||||||
|
<Italian>Place SSWT Kit</Italian>
|
||||||
|
<Hungarian>Place SSWT Kit</Hungarian>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_Tripod_PickUp">
|
||||||
|
<English>Pick up SSWT Kit</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_Tripod_Adjust">
|
||||||
|
<English>Adjust SSWT Kit</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_Tripod_Done">
|
||||||
|
<English>Done</English>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_Tripod_ScrollAction">
|
||||||
|
<English>+ Modifier, adjust</English>
|
||||||
|
</Key>
|
||||||
|
</Package>
|
||||||
|
</Project>
|
Loading…
Reference in New Issue
Block a user