Adds Crew Served Static Weapons (#5652)

* Initial Commit

* Got rid of unneeded translation values

* Updated Strings

* "Fixed" issue where when you deploy the tripid and weapon on slope it freaked out.

* Fixed locality issues. Added timers to relavent functions.

* Added weights to all magazines/tripod. Weights to weapons coming soon when I transfer them to the launcher slot

* Fixed bug regarding localized strings. Created new tripod model

* Added timers for deploying/picking up the tripod. Changed ammo-box model from custom to one already in ARMA. Changed gun-bag model for a more generic one. Created a texture for the tripod and gunbag

* Removed ability to disassemble weapons via the addAction. Added  ACE Action to get in due to a memory point issue. Changed from a static deploy/dismount time to one based in the weapon configs

* Created forward-compatability. Made it so I can define a base plate for any weapon if I ever want to expand from the generic M3 Tripod.

* Fixed bug where tripod wouldn't deploy with the correct times. Fixed bug where if you moved the tripod into the ground it would go flying.

* Added mortar compatability. Will probably shift whole mortar ammo loading to CSW one day

* Added icons to each relavent item

* Added README, possibly fixed bug where if you are in a weapon others cant load/unload ammo. Changed distance you can interact with weapons

* Added checks for when deploying the gun as well as unloading ammo to prevent duplication/deletion of items.

* Added documentation

* Added order to doc

* Explained why things are the way they are

* Remove temp files

* Removed redundant files

* Converted tabs->spaces. Added newlines at end of all files. Changed broken line in fnc_tripodDeploy.sqf.

* 100% newlines at end of file

* Added newlines to files that didnt get the change. Fixed README. Changed from GVAR(cswOptions) to GVAR(options). Changed from tabs to spaces in wiki

* Fixed issue with UAV assembling with enableWeaponDisassembling. Fixed bug where game would crash if you disassembled static weapon with more than 1 magazine

* Tabs->Spaces

* Added CSW options to base StaticWeapon class to allow for easier additions. Switched default mortar away from CSW system due to incompatabilities

* Lazy Evaluations and macros to describe how things work.

* Added newlines to script_component. Fix no-texture issue on tripod. "Fix" 20mm HE saying 40mm HE. Add custom icons to all weapons. Move "Check Ammo" to CSW menu

* abc

* Revert "abc"

This reverts commit bcb4214bd9.

* Update to current commit

* Revert changes to fortify.md

* Updated UI Icon to Crew Served Ammo branch UI

* Added Pabst's CrewServedAmmo to handle ammo loading/unloading instead of my solution

* Fixed bug where currentWeaponTurret returned a blank string when a player hasent entered hte weapon to select the current weapon

* Re-added ammo loading time

* Tabs->Spaces

* Newline at end of files

* Removed replaced functions

* Remove redundant strings. Move ammo handling to appropiate section

* Tabs->Spaces

* Update wiki

* Updated to fix crash with default weapons and disable CSW ability on default static weapons

* Added editor attributes to enable/disable CSW at edit time

* Change how ammo is removed from the CSW. Uses math instead of iteration

* Fix bug where assembled weapon did not get rid of default actions

* Added support for multiple types of ammo in one CSW

* Add tracer magazines for .50 cal

* Fix bug where you could load ammo even if the gun couldnt take any more

* Disable debug and enable compile cache

* Changed weapon deploy/pickup time. Removed custom Titan missiles. Using ACE Dragging now. Added progress bar check for pickupTripod. Updated documentation

* Removed check if CSW is full to unload ammo

* Fix bug where items would spawn underneath other items on wepaon dismount

* Change some things

* Configure base statics, improve returnAmmo

* Add mortar baseplate

* Remove explicit inheritance

* Fix bug where unloading ammo would duplicate it if you had room in your person.

* Tab->Space

* Player couldnt pickup tripod due to legacy code

* Fix GMG_01_base_F inheritce

* Port of ACE 2 tripod + ACE 2 CSW Bag

* Move ACE 2 Data to APL folder

* Adjust weights to make them more accurate to how ARMA uses it and the real life equivalents

* Fix bug where error was thrown on esc from picking up tripod. Tripod rotated 180

* Fix bug where if you called ace_common_claim the weapon could be set to be disassembled even though it may not be wanted via CSW

* Added ability to toggle ammo handling when weaponAssembly is disabled.

* Add Proxy Weapons for all Vanilla static weapons. These serve as a way to allow for realistic ammo reload times without having to modify base classes if you want feautres turned off. Adjusted reload and mount times to be more "realistic"

* Fix Shadow RPT Spam

* Update wiki

* Change order of setDir and setPos

* Change all setDir/setPos orientations. Remove redundant check. Ensure that weapon locked state reflects it with the "getIn" command. Add a way to pass in a specific classname for the weapon assemble type. Add a callback function onDisassemble if user wants to set the state of the new tripod using the old weapon as a reference

* Actually check for the carryWeaponClassname in the deployWeapon check

* Ai Compatiblity

* Add stringtable entries

* Formatting fixes

* Stringtables for settings, fix setMagazineTurretAmmo

* inherit ammo for mags, reorder stringtable

displays correct ammo and descriptionShort

* don't require ace_javelin

* Tweaks, cleanup, localzation, ace_reload changes

change weapon tag to [CSW]
tweak localization strings
minor cleanup
simplify some ace_reload funcs

* delete moved dev func

* Hopefully fix issue where to-be deleted tripod intersects with newly created weapon and vice versa. Remove PBOPREFIX newline

* cleanup/proxyWeapon/mk6 compat
This commit is contained in:
Brandon Danyluk 2019-06-07 22:47:39 -06:00 committed by PabstMirror
parent dc30d2a128
commit b1d5bbe450
86 changed files with 3193 additions and 429 deletions

View File

@ -51,6 +51,7 @@ Bla1337
BlackPixxel <blackpixxel96@gmail.com>
BlackQwar
Brakoviejo
Brandon (TCVM) <brandondanyluk366@gmail.com>
Brisse <brisse@outlook.com>
Brostrom.A | Evul <andreas.brostrom.ce@gmail.com>
BullHorn <bullhorn7@gmail.com>

BIN
addons/apl/ACE_CSW_Bag.p3d Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,98 @@
#define _ARMA_
ambient[] = {1,1,1,1.0};
diffuse[] = {1,1,1,1.0};
forcedDiffuse[] = {0.0,0.0,0.0,0.0};
emmisive[] = {0.0,0.0,0.0,1.0};
specular[] = {1,1,1,1.0};
specularPower = 40.0;
PixelShaderID = "super";
VertexShaderID = "super";
class Stage1
{
texture = "z\ace\addons\apl\data\m3tripod_nohq.paa";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0,0.0,0.0};
up[] = {0.0,1.0,0.0};
dir[] = {0.0,0.0,0.0};
pos[] = {0.0,0.0,0.0};
};
};
class Stage2
{
texture = "a3\weapons_f\Data\DetailMaps\metal_detail_dt.paa";
uvSource = "tex";
class uvTransform
{
aside[] = {8.0,0.0,0.0};
up[] = {0.0,8.0,0.0};
dir[] = {0.0,0.0,0.0};
pos[] = {0.0,0.0,0.0};
};
};
class Stage3
{
texture = "#(argb,8,8,3)color(0,0,0,0,MC)";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0,0.0,0.0};
up[] = {0.0,1.0,0.0};
dir[] = {0.0,0.0,0.0};
pos[] = {0.0,0.0,0.0};
};
};
class Stage4
{
texture = "#(argb,8,8,3)color(1,1,1,1,AS)";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0,0.0,0.0};
up[] = {0.0,1.0,0.0};
dir[] = {0.0,0.0,0.0};
pos[] = {0.0,0.0,0.0};
};
};
class Stage5
{
texture = "z\ace\addons\apl\data\m3tripod_SMDI.paa";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0,0.0,0.0};
up[] = {0.0,1.0,0.0};
dir[] = {0.0,0.0,0.0};
pos[] = {0.0,0.0,0.0};
};
};
class Stage6
{
texture = "#(ai,32,128,1)fresnel(3.38,5.33)";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0,0.0,0.0};
up[] = {0.0,1.0,0.0};
dir[] = {0.0,0.0,0.0};
pos[] = {0.0,0.0,0.0};
};
};
class Stage7
{
texture = "a3\data_f\env_land_co.paa";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0,0.0,0.0};
up[] = {0.0,1.0,0.0};
dir[] = {0.0,0.0,0.0};
pos[] = {0.0,0.0,0.0};
};
};
class StageTI
{
texture = "a3\data_f\default_vehicle_ti_ca.paa";
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,95 @@
ambient[]={1,1,1,1.000000};
diffuse[]={1,1,1,1.000000};
forcedDiffuse[]={0.000000,0.000000,0.000000,0.000000};
emmisive[]={0.000000,0.000000,0.000000,1.000000};
specular[]={1,1,1,1.000000};
specularPower=40.000000;
PixelShaderID="super";
VertexShaderID="super";
class Stage1
{
texture="z\ace\addons\apl\data\mortarBaseplate_nohq.paa";
uvSource="tex";
class uvTransform
{
aside[]={1.000000,0.000000,0.000000};
up[]={0.000000,1.000000,0.000000};
dir[]={0.000000,0.000000,0.000000};
pos[]={0.000000,0.000000,0.000000};
};
};
class Stage2
{
texture="a3\weapons_f\Data\DetailMaps\metal_detail_dt.paa";
uvSource="tex";
class uvTransform
{
aside[]={8.0000,0.000000,0.000000};
up[]={0.000000,8.0000,0.000000};
dir[]={0.000000,0.000000,0.000000};
pos[]={0.000000,0.000000,0.000000};
};
};
class Stage3
{
texture="#(argb,8,8,3)color(0,0,0,0,MC)";
uvSource="tex";
class uvTransform
{
aside[]={1.000000,0.000000,0.000000};
up[]={0.000000,1.000000,0.000000};
dir[]={0.000000,0.000000,0.000000};
pos[]={0.000000,0.000000,0.000000};
};
};
class Stage4
{
texture="z\ace\addons\apl\data\mortarBaseplate_as.paa";
uvSource="tex";
class uvTransform
{
aside[]={1.000000,0.000000,0.000000};
up[]={0.000000,1.000000,0.000000};
dir[]={0.000000,0.000000,0.000000};
pos[]={0.000000,0.000000,0.000000};
};
};
class Stage5
{
texture="z\ace\addons\apl\data\mortarBaseplate_smdi.paa";
uvSource="tex";
class uvTransform
{
aside[]={1.000000,0.000000,0.000000};
up[]={0.000000,1.000000,0.000000};
dir[]={0.000000,0.000000,0.000000};
pos[]={0.000000,0.000000,0.000000};
};
};
class Stage6
{
texture = "#(ai,32,128,1)fresnel(3.38,5.33)";
uvSource="tex";
class uvTransform
{
aside[]={1.000000,0.000000,0.000000};
up[]={0.000000,1.000000,0.000000};
dir[]={0.000000,0.000000,0.000000};
pos[]={0.000000,0.000000,0.000000};
};
};
class Stage7
{
texture="a3\data_f\env_land_co.paa";
uvSource="tex";
class uvTransform
{
aside[]={1.000000,0.000000,0.000000};
up[]={0.000000,1.000000,0.000000};
dir[]={0.000000,0.000000,0.000000};
pos[]={0.000000,0.000000,0.000000};
};
};
class StageTI {
texture = "a3\data_f\default_vehicle_ti_ca.paa";
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,98 @@
#define _ARMA_
class StageTI
{
texture = "a3\weapons_f\ammoboxes\bags\data\backpacks_ti_ca.paa";
};
ambient[] = {1.0,1.0,1.0,1.0};
diffuse[] = {1.0,1.0,1.0,1.0};
forcedDiffuse[] = {0.0,0.0,0.0,0.0};
emmisive[] = {0.0,0.0,0.0,1.0};
specular[] = {0.0,0.0,0.0,1.0};
specularPower = 0.0;
PixelShaderID = "Super";
VertexShaderID = "Super";
class Stage1
{
texture = "z\ace\addons\apl\data\static_nohq.paa";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0,0.0,0.0};
up[] = {0.0,1.0,0.0};
dir[] = {0.0,0.0,0.0};
pos[] = {0.0,0.0,0.0};
};
};
class Stage2
{
texture = "#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0,0.0,0.0};
up[] = {0.0,1.0,0.0};
dir[] = {0.0,0.0,0.0};
pos[] = {0.0,0.0,0.0};
};
};
class Stage3
{
texture = "#(argb,8,8,3)color(0,0,0,0,MC)";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0,0.0,0.0};
up[] = {0.0,1.0,0.0};
dir[] = {0.0,0.0,0.0};
pos[] = {0.0,0.0,0.0};
};
};
class Stage4
{
texture = "#(argb,8,8,3)color(1,1,1,1,AS)";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0,0.0,0.0};
up[] = {0.0,1.0,0.0};
dir[] = {0.0,0.0,0.0};
pos[] = {0.0,0.0,0.0};
};
};
class Stage5
{
texture = "#(argb,8,8,3)color(0,0,1,1,SMDI)";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0,0.0,0.0};
up[] = {0.0,1.0,0.0};
dir[] = {0.0,0.0,0.0};
pos[] = {0.0,0.0,0.0};
};
};
class Stage6
{
texture = "#(ai,32,128,1)fresnel(1.58,0.71)";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0,0.0,0.0};
up[] = {0.0,1.0,0.0};
dir[] = {0.0,0.0,0.0};
pos[] = {0.0,0.0,0.0};
};
};
class Stage7
{
texture = "a3\data\env2_co.paa";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0,0.0,0.0};
up[] = {0.0,1.0,0.0};
dir[] = {0.0,0.0,0.0};
pos[] = {0.0,0.0,0.0};
};
};

Binary file not shown.

Binary file not shown.

View File

@ -30,7 +30,7 @@ _target setVariable [QGVAR(owner), _unit, true];
// lock target object
if (_lockTarget) then {
private _canBeDisassembled = !([] isEqualTo getArray (_target call CBA_fnc_getObjectConfig >> "assembleInfo" >> "dissasembleTo"));
private _canBeDisassembled = !([] isEqualTo getArray (_target call CBA_fnc_getObjectConfig >> "assembleInfo" >> "dissasembleTo")) && { !([false, true] select (_target getVariable [QEGVAR(csw,assemblyMode), 0])) };
if (!isNull _unit) then {
[QGVAR(lockVehicle), _target, _target] call CBA_fnc_targetEvent;
if (_canBeDisassembled) then {

View File

@ -1298,5 +1298,37 @@
<Polish>Flaga (ACE - Biała)</Polish>
<Russian>Флаг (ACE - Белый)</Russian>
</Key>
<Key ID="STR_ACE_Common_playerOnly">
<English>Players only</English>
<Russian>Игроков</Russian>
<Polish>Tylko dla graczy</Polish>
<Spanish>Solo jugadores</Spanish>
<German>Nur Spieler</German>
<Czech>Pouze hráči</Czech>
<Portuguese>Somente jogadores</Portuguese>
<French>Joueur uniquement</French>
<Hungarian>Csak játékosok</Hungarian>
<Italian>Solo giocatori</Italian>
<Japanese>プレイヤーのみ</Japanese>
<Korean>플레이어만</Korean>
<Chinesesimp>只限玩家</Chinesesimp>
<Chinese>只限玩家</Chinese>
</Key>
<Key ID="STR_ACE_Common_playersAndAI">
<English>Players and AI</English>
<Russian>Игроков и ботов</Russian>
<Polish>Gracze oraz AI</Polish>
<Spanish>Jugadores e IA</Spanish>
<German>Spieler und KI</German>
<Czech>Hráči a AI</Czech>
<Portuguese>Jogadores e IA</Portuguese>
<French>Joueurs et IA</French>
<Hungarian>Játékosok és AI</Hungarian>
<Italian>Giocatori ed IA</Italian>
<Japanese>プレイヤーと AI</Japanese>
<Korean>플레이어 및 인공지능</Korean>
<Chinesesimp>玩家与AI</Chinesesimp>
<Chinese>玩家與AI</Chinese>
</Key>
</Package>
</Project>

1
addons/csw/$PBOPREFIX$ Normal file
View File

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

View File

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

View File

@ -0,0 +1,81 @@
class GVAR(groups) {
// A3 .50 BMG (12.7x99mm)
class GVAR(100Rnd_127x99_mag) {
500Rnd_127x99_mag = 1;
200Rnd_127x99_mag = 1;
100Rnd_127x99_mag = 1;
rhs_mag_100rnd_127x99_mag = 1;
rhs_mag_200rnd_127x99_mag = 1;
CUP_100Rnd_127x99_M = 1;
};
class GVAR(100Rnd_127x99_mag_red) {
500Rnd_127x99_mag_Tracer_Red = 1;
200Rnd_127x99_mag_Tracer_Red = 1;
100Rnd_127x99_mag_Tracer_Red = 1;
rhs_mag_100rnd_127x99_mag_Tracer_Red = 1;
rhs_mag_200rnd_127x99_mag_Tracer_Red = 1;
CUP_100Rnd_TE4_Red_Tracer_127x99_M = 1;
};
class GVAR(100Rnd_127x99_mag_green) {
500Rnd_127x99_mag_Tracer_Green = 1;
200Rnd_127x99_mag_Tracer_Green = 1;
100Rnd_127x99_mag_Tracer_Green = 1;
rhs_mag_100rnd_127x99_mag_Tracer_Green = 1;
CUP_100Rnd_TE4_Green_Tracer_127x99_M = 1;
};
class GVAR(100Rnd_127x99_mag_yellow) {
500Rnd_127x99_mag_Tracer_Yellow = 1;
200Rnd_127x99_mag_Tracer_Yellow = 1;
100Rnd_127x99_mag_Tracer_Yellow = 1;
rhs_mag_100rnd_127x99_mag_Tracer_Yellow = 1;
CUP_100Rnd_TE4_Yellow_Tracer_127x99_M = 1;
};
// Soviet HMG (12.7x108mm)
class GVAR(50Rnd_127x108_mag) {
rhs_mag_127x108mm_50 = 1;
rhs_mag_127x108mm_100 = 1;
rhs_mag_127x108mm_150 = 1;
CUP_150Rnd_127x108_KORD_M = 1;
CUP_50Rnd_127x108_KORD_M = 1;
CUP_50Rnd_TE3_LRT5_127x107_DSHKM_M = 1; // not sure why cup uses 107 for the DSHKM?
CUP_150Rnd_TE3_LRT5_127x107_DSHKM_M = 1;
};
// A3 20mm GMG
class GVAR(20Rnd_20mm_G_belt) {
40Rnd_20mm_G_belt = 1;
200Rnd_20mm_G_belt = 1;
};
// A3 82mm mortar shells (Allows the normal mk6 to be reloaded from the mk6 ammo handling mags)
class ACE_1Rnd_82mm_Mo_HE {
ACE_1Rnd_82mm_Mo_HE = 1;
8Rnd_82mm_Mo_shells = 1;
};
class ACE_1Rnd_82mm_Mo_Smoke {
ACE_1Rnd_82mm_Mo_Smoke = 1;
8Rnd_82mm_Mo_Smoke_white = 1;
};
class ACE_1Rnd_82mm_Mo_Illum {
ACE_1Rnd_82mm_Mo_Illum = 1;
8Rnd_82mm_Mo_Flare_white = 1;
};
class ACE_1Rnd_82mm_Mo_HE_Guided {
ACE_1Rnd_82mm_Mo_HE_Guided = 1;
8Rnd_82mm_Mo_guided = 1;
};
class ACE_1Rnd_82mm_Mo_HE_LaserGuided {
ACE_1Rnd_82mm_Mo_HE_LaserGuided = 1;
8Rnd_82mm_Mo_LG = 1;
};
// A3 Titans (Spike) - just use handheld magazines
class Titan_AT {
1Rnd_GAT_missiles = 1;
};
class Titan_AA {
1Rnd_GAA_missiles = 1;
};
};

View File

@ -0,0 +1,65 @@
class CfgMagazines {
class 100Rnd_127x99_mag;
class GVAR(100Rnd_127x99_mag): 100Rnd_127x99_mag {
author = ECSTRING(common,ACETeam);
displayName = CSTRING(127x99_displayName);
model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d";
picture = QPATHTOF(UI\ammoBox_50bmg_ca.paa);
type = 256;
mass = 96;
ACE_isBelt = 1;
};
class 100Rnd_127x99_mag_Tracer_Red;
class GVAR(100Rnd_127x99_mag_red): 100Rnd_127x99_mag_Tracer_Red {
author = ECSTRING(common,ACETeam);
displayName = CSTRING(127x99_red_displayName);
model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d";
picture = QPATHTOF(UI\ammoBox_50bmg_ca.paa);
type = 256;
mass = 96;
ACE_isBelt = 1;
};
class 100Rnd_127x99_mag_Tracer_Green;
class GVAR(100Rnd_127x99_mag_green): 100Rnd_127x99_mag_Tracer_Green {
author = ECSTRING(common,ACETeam);
displayName = CSTRING(127x99_green_displayName);
model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d";
picture = QPATHTOF(UI\ammoBox_50bmg_ca.paa);
type = 256;
mass = 96;
ACE_isBelt = 1;
};
class 100Rnd_127x99_mag_Tracer_Yellow;
class GVAR(100Rnd_127x99_mag_yellow): 100Rnd_127x99_mag_Tracer_Yellow {
author = ECSTRING(common,ACETeam);
displayName = CSTRING(127x99_yellow_displayName);
model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d";
picture = QPATHTOF(UI\ammoBox_50bmg_ca.paa);
type = 256;
mass = 96;
ACE_isBelt = 1;
};
class 50Rnd_127x108_Ball;
class GVAR(50Rnd_127x108_mag): 50Rnd_127x108_Ball {
author = ECSTRING(common,ACETeam);
displayName = CSTRING(127x108_displayName);
model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d";
picture = QPATHTOF(UI\ammoBox_50bmg_ca.paa);
type = 256;
mass = 50;
ACE_isBelt = 1;
};
class 40Rnd_20mm_G_belt;
class GVAR(20Rnd_20mm_G_belt): 40Rnd_20mm_G_belt {
author = ECSTRING(common,ACETeam);
displayName = CSTRING(GMGBelt_displayName);
model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d";
picture = QPATHTOF(UI\ammoBox_50bmg_ca.paa);
type = 256;
count = 20;
mass = 96;
ACE_isBelt = 1;
};
};

217
addons/csw/CfgVehicles.hpp Normal file
View File

@ -0,0 +1,217 @@
#define ENABLE_CSW_ATTRIBUTE class Attributes { \
class GVAR(enableCSW) { \
property = QGVAR(enableCSW); \
control = "Checkbox"; \
displayName = CSTRING(eden_enableCSW); \
tooltip = CSTRING(eden_enableCSW_tooltip); \
expression = QUOTE(_this setVariable[ARR_3(QQGVAR(enableCSW), _value, true)];); \
typeName = "BOOL"; \
condition = "objectVehicle"; \
defaultValue = true; \
}; \
}
class CfgVehicles {
class Man;
class CAManBase: Man {
class ACE_SelfActions {
class GVAR(deploy) {
displayName = CSTRING(PlaceTripod_displayName);
condition = QUOTE(call FUNC(assemble_canDeployTripod));
statement = QUOTE(call FUNC(assemble_deployTripod));
exceptions[] = {};
};
};
};
// Tripods:
class ThingX;
class GVAR(baseTripod): ThingX {
side = 3;
typicalCargo[] = {};
armor = 500000;
mapSize = 0.4;
nameSound = "Bunker";
accuracy = 1000;
destrType = "DestructDefault";
ace_dragging_canDrag = 1;
ace_dragging_dragPosition[] = {0, 2, 0};
ace_dragging_canCarry = 1;
ace_dragging_carryPosition[] = {0, 2, 0};
class ACE_Actions {
class ACE_MainActions {
displayName = CSTRING(Tripod_displayName);
selection = "";
distance = 2.5;
condition = "true";
class GVAR(pickUp) {
displayName = CSTRING(Pickup_displayName);
condition = QUOTE(call FUNC(assemble_canPickupTripod));
statement = QUOTE(call FUNC(assemble_pickupTripod));
};
class GVAR(mountWeapon) {
displayName = CSTRING(MountWeapon_displayName);
condition = QUOTE(call FUNC(assemble_canDeployWeapon));
statement = QUOTE(call FUNC(assemble_deployWeapon));
modifierFunction = QUOTE(call FUNC(assemble_deployWeaponModifier));
};
};
};
};
class GVAR(m3Tripod): GVAR(baseTripod) {
author = ECSTRING(common,ACETeam);
scope = 2;
model = QPATHTOEF(apl,ACE_CSW_m3_tripod.p3d);
displayName = CSTRING(Tripod_displayName);
class ADDON {
disassembleTo = QGVAR(m3CarryTripod);
};
};
class GVAR(m3TripodLow): GVAR(m3Tripod) {
author = ECSTRING(common,ACETeam);
scope = 2;
model = QPATHTOEF(apl,ACE_CSW_m3_tripod.p3d);
displayName = CSTRING(Tripod_displayName);
class ADDON {
disassembleTo = QGVAR(m3CarryTripodLow);
};
};
class GVAR(mortarBaseplate): GVAR(m3Tripod) {
author = ECSTRING(common,ACETeam);
scope = 2;
model = QPATHTOEF(apl,ACE_CSW_mortarBaseplate.p3d);
displayName = CSTRING(mortarBaseplate_displayName);
class ADDON {
disassembleTo = QGVAR(carryMortarBaseplate);
};
};
// Static Weapons:
class LandVehicle;
class StaticWeapon: LandVehicle {
class ACE_Actions {
class ACE_MainActions {
class GVAR(getIn) {
displayName = CSTRING(GetIn_displayName);
condition = QUOTE(call FUNC(canGetIn));
statement = QUOTE(call FUNC(getIn));
};
};
};
};
class StaticMGWeapon: StaticWeapon {};
class HMG_01_base_F: StaticMGWeapon {
class ADDON {
enabled = 1;
proxyWeapon = QGVAR(HMG_Static);
magazineLocation = "_target selectionPosition 'magazine'";
disassembleWeapon = QGVAR(staticHMGCarry); // carry weapon [CfgWeapons]
disassembleTurret = QGVAR(m3TripodLow); // turret [CfgVehicles]
desiredAmmo = 100;
ammoLoadTime = 7;
ammoUnloadTime = 5;
};
};
class HMG_01_high_base_F: HMG_01_base_F {
class ADDON {
enabled = 1;
proxyWeapon = QGVAR(HMG_Static);
magazineLocation = "_target selectionPosition 'magazine'";
disassembleWeapon = QGVAR(staticHMGCarry); // carry weapon [CfgWeapons]
disassembleTurret = QGVAR(m3Tripod); // turret [CfgVehicles]
desiredAmmo = 100;
ammoLoadTime = 7;
ammoUnloadTime = 5;
};
};
class HMG_01_A_base_F: HMG_01_base_F {
class ADDON {
enabled = 0;
};
};
class GMG_TriPod;
class GMG_01_base_F: GMG_TriPod {
class ADDON {
enabled = 1;
proxyWeapon = QGVAR(GMG_20mm); // Weapon Proxy (Shorter Reload Time) [CfgWeapons]
magazineLocation = "_target selectionPosition 'magazine'";
disassembleWeapon = QGVAR(staticGMGCarry); // carry weapon [CfgWeapons]
disassembleTurret = QGVAR(m3TripodLow); // turret [CfgVehicles]
desiredAmmo = 40;
ammoLoadTime = 7;
ammoUnloadTime = 5;
};
};
class GMG_01_high_base_F: GMG_01_base_F {
class ADDON {
enabled = 1;
proxyWeapon = QGVAR(GMG_20mm); // Weapon Proxy (Shorter Reload Time) [CfgWeapons]
magazineLocation = "_target selectionPosition 'magazine'";
disassembleWeapon = QGVAR(staticGMGCarry); // carry weapon [CfgWeapons]
disassembleTurret = QGVAR(m3Tripod); // turret [CfgVehicles]
desiredAmmo = 40;
ammoLoadTime = 7;
ammoUnloadTime = 5;
};
};
class GMG_01_A_base_F: GMG_01_base_F {
class ADDON {
enabled = 0;
};
};
class AT_01_base_F: StaticMGWeapon {
class ADDON {
enabled = 1;
proxyWeapon = QGVAR(Titan_AT_Static);
magazineLocation = "_target selectionPosition 'magazine'";
disassembleWeapon = QGVAR(staticATCarry); // carry weapon [CfgWeapons]
disassembleTurret = QGVAR(m3Tripod); // turret [CfgVehicles]
desiredAmmo = 40;
ammoLoadTime = 15; // 4 rounds per minute
ammoUnloadTime = 10;
};
};
class AA_01_base_F: StaticMGWeapon {
class ADDON {
enabled = 1;
proxyWeapon = QGVAR(Titan_AA_Static); // Weapon Proxy (Shorter Reload Time) [CfgWeapons]
magazineLocation = "_target selectionPosition 'magazine'";
disassembleWeapon = QGVAR(staticAACarry); // carry weapon [CfgWeapons]
disassembleTurret = QGVAR(m3Tripod); // turret [CfgVehicles]
desiredAmmo = 40;
ammoLoadTime = 15; // 4 rounds per minute
ammoUnloadTime = 10;
};
};
class StaticMortar: StaticWeapon {};
class Mortar_01_base_F: StaticMortar {
class ADDON {
enabled = 1;
magazineLocation = "";
disassembleWeapon = QGVAR(staticMortarCarry); // carry weapon [CfgWeapons]
disassembleTurret = QGVAR(mortarBaseplate); // turret [CfgVehicles]
desiredAmmo = 1;
ammoLoadTime = 3;
ammoUnloadTime = 3;
};
};
};

221
addons/csw/CfgWeapons.hpp Normal file
View File

@ -0,0 +1,221 @@
class CfgWeapons {
class Launcher;
class Launcher_Base_F: Launcher {
class WeaponSlotsInfo;
};
// Tripods:
class GVAR(m3CarryTripod): Launcher_Base_F {
class ADDON {
type = "mount";
deployTime = 4;
pickupTime = 4;
deploy = QGVAR(m3Tripod);
};
class WeaponSlotsInfo: WeaponSlotsInfo {
mass = 440;
};
displayName = CSTRING(TripodFolded_displayName);
author = ECSTRING(common,ACETeam);
scope = 2;
model = QPATHTOEF(apl,ACE_CSW_Bag.p3d);
modes[] = {};
picture = QPATHTOF(UI\Tripod_Icon.paa);
};
class GVAR(m3CarryTripodLow): GVAR(m3CarryTripod) {
class ADDON: ADDON {
deploy = QGVAR(m3TripodLow);
};
displayName = CSTRING(TripodLowFolded_displayName);
};
class GVAR(carryMortarBaseplate): Launcher_Base_F {
class ADDON {
type = "mount";
deployTime = 2;
pickupTime = 2;
deploy = QGVAR(mortarBaseplate);
};
class WeaponSlotsInfo: WeaponSlotsInfo {
mass = 290; // M3A1 baseblate weight
};
displayName = CSTRING(mortarBaseplate_displayName);
author = ECSTRING(common,ACETeam);
scope = 2;
model = QPATHTOEF(apl,ACE_CSW_Bag.p3d);
modes[] = {};
picture = QPATHTOF(UI\Tripod_Icon.paa); // todo
};
// Weapons:
class GVAR(staticATCarry): Launcher_Base_F {
class ADDON {
type = "weapon";
deployTime = 15;
pickupTime = 20;
class assembleTo {
GVAR(m3Tripod) = "B_static_AT_F";
};
};
class WeaponSlotsInfo: WeaponSlotsInfo {
mass = 320; // 9M113 Konkurs Weight
};
displayName = CSTRING(StaticATBag_displayName);
author = ECSTRING(common,ACETeam);
scope = 2;
model = QPATHTOEF(apl,ACE_CSW_Bag.p3d);
modes[] = {};
picture = QPATHTOF(UI\StaticAT_Icon.paa);
};
class GVAR(staticAACarry): GVAR(staticATCarry) {
class ADDON {
type = "weapon";
deployTime = 15;
pickupTime = 20;
class assembleTo {
GVAR(m3Tripod) = "B_static_AA_F";
};
};
class WeaponSlotsInfo: WeaponSlotsInfo {
mass = 320;
};
displayName = CSTRING(StaticAABag_displayName);
author = ECSTRING(common,ACETeam);
scope = 2;
model = QPATHTOEF(apl,ACE_CSW_Bag.p3d);
modes[] = {};
picture = QPATHTOF(UI\StaticAT_Icon.paa);
};
class GVAR(staticHMGCarry): Launcher_Base_F {
class ADDON {
type = "weapon";
deployTime = 7;
pickupTime = 10;
class assembleTo {
GVAR(m3Tripod) = "B_HMG_01_high_F";
GVAR(m3TripodLow) = "B_HMG_01_F";
};
};
class WeaponSlotsInfo: WeaponSlotsInfo {
mass = 840;
};
displayName = CSTRING(StaticHMGBag_displayName);
author = ECSTRING(common,ACETeam);
scope = 2;
model = QPATHTOEF(apl,ACE_CSW_Bag.p3d);
modes[] = {};
picture = QPATHTOF(UI\StaticHGMG_Icon.paa);
};
class GVAR(staticGMGCarry): Launcher_Base_F {
class ADDON {
type = "weapon";
deployTime = 5;
pickupTime = 6;
class assembleTo {
GVAR(m3Tripod) = "B_GMG_01_high_F";
GVAR(m3TripodLow) = "B_GMG_01_F";
};
};
class WeaponSlotsInfo: WeaponSlotsInfo {
mass = 780;
};
displayName = CSTRING(StaticGMGBag_displayName);
author = ECSTRING(common,ACETeam);
scope = 2;
model = QPATHTOEF(apl,ACE_CSW_Bag.p3d);
modes[] = {};
picture = QPATHTOF(UI\StaticHGMG_Icon.paa);
};
class GVAR(staticMortarCarry): Launcher_Base_F {
class ADDON {
type = "weapon";
deployTime = 20;
pickupTime = 25;
class assembleTo {
GVAR(mortarBaseplate) = "B_Mortar_01_F";
};
};
class WeaponSlotsInfo: WeaponSlotsInfo {
mass = 620; // M252 Mortar Weight
};
displayName = CSTRING(StaticMortarBag_displayName);
author = ECSTRING(common,ACETeam);
scope = 2;
model = QPATHTOEF(apl,ACE_CSW_Bag.p3d);
modes[] = {};
picture = QPATHTOF(UI\StaticHGMG_Icon.paa);
};
// Proxy Weapons
class HMG_static;
class GVAR(HMG_Static): HMG_Static {
magazineReloadTime = 0.5;
};
class GMG_20mm;
class GVAR(GMG_20mm): GMG_20mm {
magazineReloadTime = 0.5;
};
class missiles_titan_static;
class EGVAR(javelin,Titan_Static): missiles_titan_static {}; // if ace_javelin does not exist, this will just inherit from the base weapon
class GVAR(Titan_AT_Static): EGVAR(javelin,Titan_Static) {
EGVAR(javelin,enabled) = 1; // needs to be explicitly enabled
magazineReloadTime = 0.5;
};
class GVAR(Titan_AA_Static) : missiles_titan_static {
magazineReloadTime = 0.5;
};
/*
class GVAR(staticAutoHMGCarry): Launcher_Base_F {
class ADDON {
type = "weapon";
deployTime = 4;
pickupTime = 4;
class assembleTo {
GVAR(m3Tripod) = GVAR(staticAutoHMGWeapon);
};
};
class WeaponSlotsInfo: WeaponSlotsInfo {
mass = 840;
};
displayName = CSTRING(StaticAutoHMGBag_displayName);
author = ECSTRING(common,ACETeam);
scope = 2;
model = QPATHTOEF(apl,ACE_CSW_Bag.p3d);
modes[] = {};
picture = QPATHTOF(UI\StaticHGMG_Icon.paa);
};
class GVAR(staticAutoGMGCarry): Launcher_Base_F {
class GVAR(options) {
assembleTo = QGVAR(staticAutoGMGWeapon);
baseTripod = QGVAR(m3Tripod);
type = "weapon";
};
class WeaponSlotsInfo: WeaponSlotsInfo {
mass = 780;
};
displayName = CSTRING(StaticAutoGMGBag_displayName);
author = ECSTRING(common,ACETeam);
scope = 2;
model = QPATHTOEF(apl,ACE_CSW_Bag.p3d);
modes[] = {};
picture = QPATHTOF(UI\StaticHGMG_Icon.paa);
};
*/
};

12
addons/csw/README.md Normal file
View File

@ -0,0 +1,12 @@
ace_csw
===============
Crew Served Weapons - Static weapons that are served by multiple people
## Maintainers
The people responsible for merging changes to this component or answering potential questions.
- [TCVM](https://github.com/TheCandianVendingMachine)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

32
addons/csw/XEH_PREP.hpp Normal file
View File

@ -0,0 +1,32 @@
TRACE_1("",QUOTE(ADDON));
PREP(ai_handleFired);
PREP(assemble_canDeployTripod);
PREP(assemble_canDeployWeapon);
PREP(assemble_canPickupTripod);
PREP(assemble_canPickupWeapon);
PREP(assemble_deployTripod);
PREP(assemble_deployWeapon);
PREP(assemble_deployWeaponModifier);
PREP(assemble_pickupTripod);
PREP(assemble_pickupWeapon);
PREP(canGetIn);
PREP(getIn);
PREP(proxyWeapon);
PREP(reload_actionsLoad);
PREP(reload_actionsUnload);
PREP(reload_canLoadMagazine);
PREP(reload_canUnloadMagazine);
PREP(reload_getLoadableMagazines);
PREP(reload_getVehicleMagazine);
PREP(reload_handleAddTurretMag);
PREP(reload_handleRemoveTurretMag);
PREP(reload_handleReturnAmmo);
PREP(reload_loadMagazine);
PREP(staticWeaponInit);
PREP(staticWeaponInit_unloadExtraMags);

View File

@ -0,0 +1,26 @@
#include "script_component.hpp"
GVAR(vehicleMagCache) = call CBA_fnc_createNamespace;
["ace_settingsInitialized", {
TRACE_3("settingsInit",GVAR(defaultAssemblyMode),GVAR(handleExtraMagazines),GVAR(ammoHandling));
["StaticWeapon", "init", LINKFUNC(staticWeaponInit), true, [], true] call CBA_fnc_addClassEventHandler;
}] call CBA_fnc_addEventHandler;
// Event handlers:
[QGVAR(disableVanillaAssembly), {
params ["_staticWeapon"];
TRACE_1("disableVanillaAssembly eh",_staticWeapon);
_staticWeapon enableWeaponDisassembly false;
}] call CBA_fnc_addEventHandler;
[QGVAR(addTurretMag), LINKFUNC(reload_handleAddTurretMag)] call CBA_fnc_addEventHandler;
[QGVAR(removeTurretMag), LINKFUNC(reload_handleRemoveTurretMag)] call CBA_fnc_addEventHandler;
[QGVAR(returnAmmo), LINKFUNC(reload_handleReturnAmmo)] call CBA_fnc_addEventHandler;
#ifdef DEBUG_MODE_FULL
call compile preprocessFileLineNumbers QPATHTOF(dev\checkStaticWeapons.sqf);
#endif

View File

@ -0,0 +1,14 @@
#include "script_component.hpp"
ADDON = false;
PREP_RECOMPILE_START;
#include "XEH_PREP.hpp"
PREP_RECOMPILE_END;
#include "initSettings.sqf"
GVAR(initializedStaticTypes) = [];
ADDON = true;

View File

@ -0,0 +1,3 @@
#include "script_component.hpp"
#include "XEH_PREP.hpp"

22
addons/csw/config.cpp Normal file
View File

@ -0,0 +1,22 @@
#include "script_component.hpp"
class CfgPatches {
class ADDON {
name = COMPONENT_NAME;
units[] = {};
weapons[] = {"ace_csw_carryTripod", "ace_csw_staticATWeapon"};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ace_interaction"};
author = ECSTRING(common,ACETeam);
authors[] = {"TCVM"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
};
};
#include "CfgEventHandlers.hpp"
#include "CfgVehicles.hpp"
#include "CfgWeapons.hpp"
#include "CfgMagazines.hpp"
#include "CfgMagazineGroups.hpp"

53
addons/csw/cswDesign.txt Normal file
View File

@ -0,0 +1,53 @@
Settings:
defaultBehaviour:
Normal - Untouched [full mags, normal backpack disassemble]
Advanced - [Realistic mags, side unloading]
handleExtraMagazines
Extra magazines on ground
Ignore extra magazines
Vehicle:
3den attribute controls if [useSetting, normal or advanced]
configs:
CfgWeapons:
class GVAR(m3CarryTripod): Launcher_Base_F {
class ADDON {
type = "mount";
deployTime = 3;
pickupTime = 3;
deploy = QGVAR(m3Tripod);
};
class GVAR(staticATCarry): Launcher_Base_F {
class ADDON {
type = "weapon";
deployTime = 8;
pickupTime = 15;
class assembleTo {
tripodCfgVehicle = staticCfgVehicle;
};
};
CfgVehicles:
class GVAR(m3Tripod): // Tripod Example
class ADDON {
disassembleTo = QGVAR(m3CarryTripod);
class Mortar_01_base_F: // Static Weapon Example
class ADDON {
enabled = 1;
magazineLocation = "";
disassembleWeapon = ""; // secondary weapon classname
disassembleTurret = ""; // CfgVehicle
desiredAmmo = 100; //
ammoLoadTime = 5;
ammoUnloadTime = 5;

51
addons/csw/data/model.cfg Normal file
View File

@ -0,0 +1,51 @@
class CfgSkeletons {
class Default {
isDiscrete = 1;
skeletonInherit = "";
skeletonBones[] = {};
};
class ACE_CSW_Tripod_Skeleton: Default {};
class ACE_CSW_M3_Tripod_Skeleton: Default {};
// class ACE_CSW_FoldedTripod_Skeleton: Default {};
// class ACE_CSW_ammoBox_Skeleton: Default {};
class ACE_CSW_WeaponBag_Skeleton: Default {};
class ACE_CSW_mortarBaseplate_Skeleton: Default {};
};
class CfgModels {
class Default {
sectionsInherit = "";
sections[] = {};
skeletonName = "";
};
class ACE_CSW_Tripod : Default {
sectionsInherit = "";
sections[] = {};
skeletonName = "ACE_CSW_Tripod_Skeleton";
};
class ACE_CSW_M3_Tripod : Default {
sectionsInherit = "";
sections[] = {};
skeletonName = "ACE_CSW_M3_Tripod_Skeleton";
};
/* class ACE_CSW_FoldedTripod: Default {
sectionsInherit = "";
sections[] = {};
skeletonName = "ACE_CSW_FoldedTripod_Skeleton";
};
class ACE_CSW_ammoBox: Default {
sectionsInherit = "";
sections[] = {};
skeletonName = "ACE_CSW_ammoBox_Skeleton";
}; */
class ACE_CSW_Bag: Default {
sectionsInherit = "";
sections[] = {};
skeletonName = "ACE_CSW_WeaponBag_Skeleton";
};
class ACE_CSW_mortarBaseplate: Default {
sectionsInherit = "";
sections[] = {};
skeletonName = "ACE_CSW_mortarBaseplate_Skeleton";
};
};

View File

@ -0,0 +1,76 @@
#define DEBUG_MODE_FULL
#include "\z\ace\addons\csw\script_component.hpp"
// Dev only function to search for weapons used by static weapons
// and check if their magazinese are compatible
INFO("Checking static weapons");
private _staticWeaponConfigs = configProperties [configFile >> "CfgVehicles", "(isClass _x) && {(configName _x) isKindOf 'StaticWeapon'}", true];
private _staticPublic = _staticWeaponConfigs select {(getNumber (_x >> "scope")) == 2};
INFO_2("Static Weapons [%1] - CSW Enabled [%2]",count _staticPublic, {(getNumber (_x >> "ace_csw" >> "enabled")) == 1} count _staticPublic);
INFO("------ Checking static weapons inheritance ------");
private _explicitBases = [];
private _inherited = [];
{
private _config = _x;
private _configEnabled = (getNumber (_config >> "ace_csw" >> "enabled")) == 1;
if (_configEnabled) then {
private _configExplicit = (count configProperties [_config, "configName _x == 'ace_csw'", false]) == 1;
if (_configExplicit) then {
_explicitBases pushBack (configName _config);
_inherited pushBack [];
} else {
if ((getNumber (_config >> "scope")) < 2) exitWith {};
private _parent = inheritsFrom _config;
while {isClass _parent} do {
private _className = configName _parent;
private _index = _explicitBases findIf {_className == _x};
if (_index > -1) exitWith {
(_inherited select _index) pushBack (configName _config);
};
_parent = inheritsFrom _parent;
};
};
};
} forEach _staticWeaponConfigs;
{
INFO_2("%1 inherited by %2",_x,_inherited select _forEachIndex);
} forEach _explicitBases;
INFO("------ Logging static magazines with no carry version -------");
private _hash = [] call CBA_fnc_hashCreate;
// private _logAll = true; // logs all possible weapon magazines (even if not used in a static weapon)
private _logAll = false;
{
private _vehicleType = configName _x;
private _turretConfig = [_vehicleType, [0]] call CBA_fnc_getTurret;
private _weapons = getArray (_turretConfig >> "weapons");
private _loadedMags = getArray (_turretConfig >> "magazines");
{
private _weapMags = getArray (configFile >> "CfgWeapons" >> _x >> "magazines");
{
private _xMag = _x;
private _groups = "getNumber (_x >> _xMag) == 1" configClasses (configFile >> QGVAR(groups));
private _carryMag = configName (_groups param [0, configNull]);
if ((_carryMag == "") && {_logAll || {_xMag in _loadedMags}}) then {
private _vehs = [_hash, _xMag] call CBA_fnc_hashGet;
if (isNil "_vehs") then {_vehs = [];};
if (_xMag in _loadedMags) then {
_vehs pushBack _vehicleType;
};
[_hash, _xMag, _vehs] call CBA_fnc_hashSet;
};
} forEach _weapMags;
} forEach _weapons;
} forEach _staticWeaponConfigs;
[_hash, {
//IGNORE_PRIVATE_WARNING ["_key", "_value"];
INFO_2("[%1] has no carry varient - Used in %2",_key,_value);
}] call CBA_fnc_hashEachPair;
INFO("------ End -------");

View File

@ -0,0 +1,96 @@
#include "script_component.hpp"
/*
* Author: PabstMirror
* Initializes weapon to disable weapon disassembling
*
* Arguments:
* 0: Weapon <OBJECT>
*
* Return Value:
* None
*
* Example:
* [weapon] call ace_csw_fnc_ai_handleFired
*
* Public: No
*/
params ["_staticWeapon", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_gunner"];
TRACE_8("firedEH:",_staticWeapon, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _gunner);
if ((!local _gunner) || {[_gunner] call EFUNC(common,isPlayer)}) exitWith {};
if (someAmmo _staticWeapon) exitWith {};
TRACE_2("need ammo",someAmmo _staticWeapon,magazinesAllTurrets _staticWeapon);
private _turretPath = [_gunner] call EFUNC(common,getTurretIndex);
private _reloadSource = objNull;
private _reloadMag = "";
private _reloadNeededAmmo = -1;
// Find if there is anything we can reload with
{
scopeName "findSource";
private _xSource = _x;
private _cswMagazines = [];
{
if (isClass (configFile >> QGVAR(groups) >> _x)) then { _cswMagazines pushBackUnique _x; };
} forEach (if (_xSource isKindOf "CaManBase") then {magazines _x} else {magazineCargo _x});
TRACE_2("",_xSource,_cswMagazines);
private _compatibleMags = [_magazine] + ([_weapon] call CBA_fnc_compatibleMagazines); // Check current mag first
{
private _xWeaponMag = _x;
{
if ((getNumber (configFile >> QGVAR(groups) >> _x >> _xWeaponMag)) == 1) then {
private _loadInfo = [_staticWeapon, _turretPath, _reloadMag, objNull] call FUNC(reload_canLoadMagazine);
if (_loadInfo select 0) then {
_reloadMag = _x;
_reloadSource = _xSource;
_reloadNeededAmmo = _loadInfo select 2;
TRACE_3("found mag",_reloadMag,_reloadSource,_x);
breakOut "findSource";
};
};
} forEach _cswMagazines;
} forEach _compatibleMags;
} forEach ([_gunner] + (_staticWeapon nearEntities [["groundWeaponHolder", "ReammoBox_F"], 10]));
if (_reloadMag == "") exitWith {TRACE_1("could not find mag",_reloadMag);};
// Figure out what we can add from the magazines we have
private _bestAmmoToSend = -1;
{
_x params ["_xMag", "_xAmmo"];
TRACE_2("",_xMag,_xAmmo);
if (_xMag == _reloadMag) then {
if ((_bestAmmoToSend == -1) || {(_xAmmo > _bestAmmoToSend) && {_xAmmo <= _reloadNeededAmmo}}) then {
_bestAmmoToSend = _xAmmo;
};
};
} forEach (if (_reloadSource isKindOf "CaManBase") then {magazinesAmmo _reloadSource} else {magazinesAmmoCargo _reloadSource});
TRACE_4("",_reloadSource,_reloadMag,_reloadNeededAmmo,_bestAmmoToSend);
if (_bestAmmoToSend == -1) exitWith {ERROR("No ammo");};
// Remove the mag from the source
if (_reloadSource isKindOf "CaManBase") then {
[_reloadSource, _reloadMag, _bestAmmoToSend] call ace_common_fnc_removeSpecificMagazine;
} else {
[_reloadSource, _reloadMag, 1, _bestAmmoToSend] call CBA_fnc_removeMagazineCargo;
};
private _timeToLoad = 1;
if (!isNull(configFile >> "CfgVehicles" >> (typeOf _staticWeapon) >> QUOTE(ADDON) >> "ammoLoadTime")) then {
_timeToLoad = getNumber(configFile >> "CfgVehicles" >> (typeOf _staticWeapon) >> QUOTE(ADDON) >> "ammoLoadTime");
};
TRACE_1("Reloading in progress",_timeToLoad);
[{
params ["_staticWeapon", "_turretPath", "_gunner", "_reloadMag", "_bestAmmoToSend"];
if ((!alive _staticWeapon) || {!alive _gunner} || {(_staticWeapon distance _gunner) > 10}) exitWith {TRACE_1("invalid state",_this);};
// Reload the static weapon
TRACE_5("calling addTurretMag event",_staticWeapon, _turretPath, _gunner, _reloadMag, _bestAmmoToSend);
[QGVAR(addTurretMag), _this] call CBA_fnc_globalEvent;
}, [_staticWeapon, _turretPath, _gunner, _reloadMag, _bestAmmoToSend], _timeToLoad] call CBA_fnc_waitAndExecute;

View File

@ -0,0 +1,21 @@
#include "script_component.hpp"
/*
* Author: TCVM
* Checks if the player can deploy the tripod.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* Can deploy <BOOL>
*
* Example:
* [player] call ace_csw_fnc_canDeployTripod
*
* Public: No
*/
params ["_player"];
(getText(configFile >> "CfgWeapons" >> (secondaryWeapon _player) >> QUOTE(ADDON) >> "type") == "mount")

View File

@ -0,0 +1,25 @@
#include "script_component.hpp"
/*
* Author: TCVM
* Checks if you can deploy a weapon on the tripod
*
* Arguments:
* 0: Target Tripod <OBJECT>
* 0: Player <OBJECT>
*
* Return Value:
* Wether or not you can deploy the weapon <BOOL>
*
* Example:
* [cursorObject, player] call ace_csw_fnc_assemble_canDeployWeapon
*
* Public: No
*/
params ["_target", "_player", "", "_carryWeaponClassname"];
if (isNil "_carryWeaponClassname") then { _carryWeaponClassname = secondaryWeapon _player };
// If the current launcher has a config-value that defines the tripod, it is a CSW
(alive _target) &&
{(getText(configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "assembleTo" >> (typeOf _target))) != ""}

View File

@ -0,0 +1,22 @@
#include "script_component.hpp"
/*
* Author: TCVM
* Checks if the player can pick-up the tripod.
*
* Arguments:
* 0: Tripod <OBJECT>
* 1: Unit <OBJECT>
*
* Return Value:
* Can pickup <BOOL>
*
* Example:
* [tripod, player] call ace_csw_fnc_assemble_canPickupTripod
*
* Public: No
*/
params ["_tripod", "_player"];
((secondaryWeapon _player) isEqualTo "") && {alive _tripod}

View File

@ -0,0 +1,25 @@
#include "script_component.hpp"
/*
* Author: TCVM
* If the CSW is mounted or in use this will not allow you to dismount the weapon
*
* Arguments:
* 0: Static Weapon <OBJECT>
*
* Return Value:
* Can Dismount <BOOL>
*
* Example:
* [cursorObject] call ace_csw_fnc_assemble_canPickupWeapon
*
* Public: No
*/
params ["_staticWeapon"];
private _assemblyMode = [false, true, GVAR(defaultAssemblyMode)] select (_staticWeapon getVariable [QGVAR(assemblyMode), 2]);
private _crewed = (crew _staticWeapon) isEqualTo [];
private _deadCrew = !(alive (gunner _staticWeapon)); // need to eject body???
_assemblyMode && {(!_crewed) || _deadCrew}

View File

@ -0,0 +1,66 @@
#include "script_component.hpp"
/*
* Author: TCVM
* Deploys the tripod
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player] call ace_csw_fnc_assemble_deployTripod
*
* Public: No
*/
[{
params ["_player"];
TRACE_1("assemble_deployTripod",_player);
// Remove the tripod from the launcher slot
private _secondaryWeaponClassname = secondaryWeapon _player;
_player removeWeaponGlobal (secondaryWeapon _player);
private _onFinish = {
params ["_args"];
_args params ["_player", "_secondaryWeaponClassname"];
TRACE_2("deployTripod finish",_player,_secondaryWeaponClassname);
private _tripodClassname = getText(configFile >> "CfgWeapons" >> _secondaryWeaponClassname >> QUOTE(ADDON) >> "deploy");
// Create a tripod
private _cswTripod = createVehicle [_tripodClassname, [0, 0, 0], [], 0, "NONE"];
private _posATL = _player getRelPos [2, 0];
_posATL set [2, ((getPosATL _player) select 2) + 0.5];
_cswTripod setDir (direction _player);
_cswTripod setPosATL _posATL;
_cswTripod setVectorUp (surfaceNormal _posATL);
[_player, "PutDown"] call EFUNC(common,doGesture);
// drag after deploying
if ((missionNamespace getVariable [QGVAR(dragAfterDeploying), false]) && {["ACE_dragging"] call EFUNC(common,isModLoaded)}) then {
if ([_player, _cswTripod] call EFUNC(dragging,canCarry)) then {
TRACE_1("starting carry",_cswTripod);
[_player, _cswTripod] call EFUNC(dragging,startCarry);
} else {
TRACE_1("cannot carry",_cswTripod);
};
};
};
private _onFailure = {
params ["_args"];
_args params ["_player", "_secondaryWeaponClassname"];
TRACE_2("deployTripod failure",_player,_secondaryWeaponClassname);
_player addWeaponGlobal _secondaryWeaponClassname;
};
private _deployTime = getNumber(configFile >> "CfgWeapons" >> _secondaryWeaponClassname >> QUOTE(ADDON) >> "deployTime");
[TIME_PROGRESSBAR(_deployTime), [_player, _secondaryWeaponClassname], _onFinish, _onFailure, localize LSTRING(PlaceTripod_progressBar)] call EFUNC(common,progressBar);
}, _this] call CBA_fnc_execNextFrame;

View File

@ -0,0 +1,74 @@
#include "script_component.hpp"
/*
* Author: TCVM
* Deploys the current CSW
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player] call ace_csw_fnc_assemble_deployWeapon
*
* Public: No
*/
[{
params ["_tripod", "_player", "", "_carryWeaponClassname"];
if (isNil "_carryWeaponClassname") then { _carryWeaponClassname = secondaryWeapon _player };
TRACE_3("assemble_deployWeapon_carryWeaponClassname",_tripod,_player,_carryWeaponClassname);
private _tripodClassname = typeOf _tripod;
_player removeWeaponGlobal _carryWeaponClassname;
private _assembledClassname = getText(configfile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "assembleTo" >> _tripodClassname);
private _deployTime = getNumber(configfile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "deployTime");
if (!isClass (configFile >> "CfgVehicles" >> _assembledClassname)) exitWith {ERROR_1("bad static classname [%1]",_assembledClassname);};
TRACE_4("",_carryWeaponClassname,_tripodClassname,_assembledClassname,_deployTime);
private _onFinish = {
params ["_args"];
_args params ["_tripod", "_player", "_assembledClassname"];
TRACE_3("deployWeapon finish",_tripod,_player,_assembledClassname);
private _tripodPos = getPosATL _tripod;
private _tripodDir = getDir _tripod;
deleteVehicle _tripod;
_tripodPos set [2, (_tripodPos select 2) + 0.1];
// Delay a frame so tripod has a chance to be deleted
[{
params ["_assembledClassname", "_tripodDir", "_tripodPos"];
private _csw = createVehicle [_assembledClassname, [0, 0, 0], [], 0, "NONE"];
_csw setVariable [QGVAR(assemblyMode), 1, true]; // Explicitly set advanced assembly mode and broadcast
_csw setVariable [QGVAR(emptyWeapon), true, false]; // unload gun, shouldn't need broadcast for this as it will be local to us
if (!GVAR(defaultAssemblyMode)) then {
TRACE_1("global disableVanillaAssembly event",_csw); // handles it being assembled when setting is disabled
[QGVAR(disableVanillaAssembly), [_csw]] call CBA_fnc_globalEvent;
};
_csw setDir _tripodDir;
_csw setPosATL _tripodPos;
_csw setVectorUp (surfaceNormal _tripodPos);
}, [_assembledClassname, _tripodDir, _tripodPos]] call CBA_fnc_execNextFrame;
};
private _onFailure = {
params ["_args"];
_args params ["", "_player", "", "_carryWeaponClassname"];
TRACE_2("deployWeapon failure",_player,_carryWeaponClassname);
_player addWeaponGlobal _carryWeaponClassname;
};
private _codeCheck = {
params ["_args"];
_args params ["_tripod"];
!isNull _tripod;
};
[TIME_PROGRESSBAR(_deployTime), [_tripod, _player, _assembledClassname, _carryWeaponClassname], _onFinish, _onFailure, localize LSTRING(AssembleCSW_progressBar), _codeCheck] call EFUNC(common,progressBar);
}, _this] call CBA_fnc_execNextFrame;

View File

@ -0,0 +1,28 @@
#include "script_component.hpp"
/*
* Author: PabstMirror
* Modifies interaction for deploying weapon
*
* Arguments:
* 0: Target <OBJECT>
* 1: Player <OBJECT>
* 2: Args <ANY>
* 3: Action Data <ARRAY>
*
* Return Value:
* None
*
* Example:
* [cursorObject, player, [], []] call ace_csw_fnc_assemble_deployWeaponModifier
*
* Public: No
*/
params ["_target", "_player", "", "_actionData"];
private _carryWeaponClassname = secondaryWeapon _player;
private _assembleTo = (getText(configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "assembleTo" >> (typeOf _target)));
private _icon = getText (configFile >> "CfgVehicles" >> _assembleTo >> "picture");
TRACE_2("",_assembleTo,_icon);
_actionData set [2, _icon];

View File

@ -0,0 +1,47 @@
#include "script_component.hpp"
/*
* Author: TCVM
* Picks up the tripod and adds it to the player launcher slot
*
* Arguments:
* 0: Tripod <OBJECT>
* 1: Unit <OBJECT>
*
* Return Value:
* None
*
* Example:
* [tripod, player] call ace_csw_fnc_assemble_pickupTripod
*
* Public: No
*/
[{
params ["_tripod", "_player"];
TRACE_2("assemble_pickupTripod",_tripod,_player);
private _tripodClassname = getText(configFile >> "CfgVehicles" >> (typeof _tripod) >> QUOTE(ADDON) >> "disassembleTo");
private _pickupTime = getNumber(configFile >> "CfgWeapons" >> _tripodClassname >> QUOTE(ADDON) >> "pickupTime");
private _onFinish = {
params ["_args"];
_args params ["_tripod", "_player", "_tripodClassname"];
TRACE_3("assemble_pickupTripod finish",_tripod,_player,_tripodClassname);
deleteVehicle _tripod;
_player addWeaponGlobal _tripodClassname;
[_player, "PutDown"] call EFUNC(common,doGesture);
};
private _condition = {
params ["_args"];
_args params ["_tripod", "_player"];
!(isNull _tripod) && { (secondaryWeapon _player) isEqualTo "" }
};
TRACE_3("",_pickupTime,typeOf _tripod,_tripodClassname);
[TIME_PROGRESSBAR(_pickupTime), [_tripod, _player, _tripodClassname], _onFinish, {}, localize LSTRING(PickupTripod_progressBar), _condition] call EFUNC(common,progressBar);
}, _this] call CBA_fnc_execNextFrame;

View File

@ -0,0 +1,91 @@
#include "script_component.hpp"
/*
* Author: TCVM
* Dismounts the weapon from the tripod and drops its backpack beside
*
* Arguments:
* 0: Static Weapon <OBJECT>
*
* Return Value:
* None
*
* Example:
* [weapon] call ace_csw_fnc_assemble_pickupWeapon
*
* Public: No
*/
[{
params ["_staticWeapon", "_player"];
TRACE_2("assemble_pickupWeapon",_staticWeapon,_player);
private _onDisassembleFunc = getText(configFile >> "CfgVehicles" >> (typeOf _staticWeapon) >> QUOTE(ADDON) >> "disassembleFunc");
private _carryWeaponClassname = getText(configFile >> "CfgVehicles" >> (typeOf _staticWeapon) >> QUOTE(ADDON) >> "disassembleWeapon");
private _turretClassname = getText(configFile >> "CfgVehicles" >> (typeOf _staticWeapon) >> QUOTE(ADDON) >> "disassembleTurret");
private _pickupTime = getNumber(configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "pickupTime");
TRACE_4("",typeOf _staticWeapon,_carryWeaponClassname,_turretClassname,_pickupTime);
if (!isClass (configFile >> "CfgWeapons" >> _carryWeaponClassname)) exitWith {ERROR_1("bad weapon classname [%1]",_carryWeaponClassname);};
if (!isClass (configFile >> "CfgVehicles" >> _turretClassname)) exitWith {ERROR_1("bad turret classname [%1]",_turretClassname);};
private _onFinish = {
params ["_args"];
_args params ["_staticWeapon", "_player", "_carryWeaponClassname", "_turretClassname", "_onDisassembleFunc"];
TRACE_4("disassemble finish",_staticWeapon,_player,_carryWeaponClassname,_turretClassname);
private _weaponPos = getPosATL _staticWeapon;
_weaponPos set [2, (_weaponPos select 2) + 0.1];
private _weaponDir = getDir _staticWeapon;
LOG("remove ammo");
{
_x params ["_xMag", "", "_xAmmo"];
private _carryMag = GVAR(vehicleMagCache) getVariable _xMag;
if (isNil "_carryMag") then {
private _groups = "getNumber (_x >> _xMag) == 1" configClasses (configFile >> QGVAR(groups));
_carryMag = configName (_groups param [0, configNull]);
GVAR(vehicleMagCache) setVariable [_xMag, _carryMag];
TRACE_2("setting cache",_xMag,_carryMag);
};
if ((_xAmmo > 0) && {_carryMag != ""}) then {
TRACE_2("Removing ammo",_xMag,_carryMag);
[_player, _carryMag, _xAmmo] call FUNC(reload_handleReturnAmmo);
};
} forEach (magazinesAllTurrets _staticWeapon);
private _cswTripod = createVehicle [_turretClassname, [0, 0, 0], [], 0, "NONE"];
[_cswTripod, _staticWeapon] call (missionNamespace getVariable _onDisassembleFunc);
LOG("delete weapon");
deleteVehicle _staticWeapon;
// Delay a frame so weapon has a chance to be deleted
[{
params ["_player", "_cswTripod", "_weaponDir", "_weaponPos", "_carryWeaponClassname"];
_cswTripod setDir _weaponDir;
_cswTripod setPosATL _weaponPos;
_cswTripod setVelocity [0, 0, -0.05];
_cswTripod setVectorUp (surfaceNormal _weaponPos);
if ((alive _player) && {(secondaryWeapon _player) == ""}) exitWith {
_player addWeapon _carryWeaponClassname;
};
private _weaponRelPos = _cswTripod getRelPos RELATIVE_DIRECTION(90);
private _weaponHolder = createVehicle ["groundWeaponHolder", [0, 0, 0], [], 0, "NONE"];
_weaponHolder setDir random [0, 180, 360];
_weaponHolder setPosATL [_weaponRelPos select 0, _weaponRelPos select 1, _weaponPos select 2];
_weaponHolder addWeaponCargoGlobal [_carryWeaponClassname, 1];
}, [_player, _cswTripod, _weaponDir, _weaponPos, _carryWeaponClassname]] call CBA_fnc_execNextFrame;
LOG("end");
};
private _condition = {
params ["_args"];
_args params ["_staticWeapon"];
((crew _staticWeapon) isEqualTo []) && (alive _staticWeapon)
};
[TIME_PROGRESSBAR(_pickupTime), [_staticWeapon, _player, _carryWeaponClassname, _turretClassname, _onDisassembleFunc], _onFinish, {}, localize LSTRING(DisassembleCSW_progressBar), _condition] call EFUNC(common,progressBar);
}, _this] call CBA_fnc_execNextFrame;

View File

@ -0,0 +1,28 @@
#include "script_component.hpp"
/*
* Author: TCVM
* Checks if the player can get in the weapon
*
* Arguments:
* 0: Static Weapon <OBJECT>
*
* Return Value:
* None
*
* Example:
* [cursorObject] call ace_csw_fnc_canGetIn
*
* Public: No
*/
// hide this action if quick mount is enabled
if ((missionNamespace getVariable [QEGVAR(quickmount,enabled), false]) && {(missionNamespace getVariable [QEGVAR(quickmount,enableMenu), -1]) in [1, 3]}) exitWith {
false
};
params ["_staticWeapon"];
alive _staticWeapon
&& {!(alive (gunner _staticWeapon))}
&& {(locked _staticWeapon) < 2}
&& {0.3 < ((vectorUp _staticWeapon) select 2)}

View File

@ -0,0 +1,24 @@
#include "script_component.hpp"
/*
* Author: TCVM
* An action for the player to get in the CSW
* Due to the fact that the default static weapons "Get In" memory point is at the front of
* the gun and can't be acssesed from the back, I am implementing this to get around that issue.
*
* Arguments:
* 0: Static Weapon <OBJECT>
* 1: Unit <OBJECT>
*
* Return Value:
* None
*
* Example:
* [cursorObject, player] call ace_csw_fnc_getIn
*
* Public: No
*/
params ["_staticWeapon", "_player"];
TRACE_2("getIn",_staticWeapon,_player);
_player moveInTurret [_staticWeapon, [0]];

View File

@ -0,0 +1,41 @@
#include "script_component.hpp"
/*
* Author: Brandon (TCVM), PabstMirror
* Handles the use of proxy weapons to fix engine-reload times
*
* Arguments:
* 0: Weapon <OBJECT>
* 1: Turret <ARRAY>
* 2: Proxy weapon needed <BOOL>
*
* Return Value:
* None
*
* Example:
* [weapon, [0], true] call ace_csw_fnc_proxyWeapon
*
* Public: No
*/
params ["_staticWeapon", "_turret", "_needed"];
if (_staticWeapon getVariable [format [QGVAR(proxyHandled_%1), _turret], false]) exitWith { TRACE_1("proxy weapon already handled",_staticWeapon); };
private _typeOf = typeOf _staticWeapon;
private _proxyWeapon = getText(configFile >> "CfgVehicles" >> _typeOf >> "ace_csw" >> "proxyWeapon");
TRACE_5("proxyWeapon",_staticWeapon,_turret,_needed,_typeOf,_proxyWeapon);
if (_proxyWeapon == "") exitWith { TRACE_1("proxyWeapon not defined",_proxyWeapon); };
private _currentWeapon = (_staticWeapon weaponsTurret [0]) param [0, "#none"];
if ((missionNamespace getVariable [_proxyWeapon, objNull]) isEqualType {}) then { // check if string is a function
TRACE_1("Calling proxyWeapon function",_proxyWeapon);
_proxyWeapon = [_staticWeapon, _turret, _currentWeapon, _needed] call (missionNamespace getVariable _proxyWeapon);
_needed = _proxyWeapon != "";
};
if (!_needed) exitWith { TRACE_2("not needed",_needed,_proxyWeapon); };
TRACE_2("swapping to proxy weapon",_currentWeapon,_proxyWeapon);
_staticWeapon removeWeaponTurret [_currentWeapon, _turret];
_staticWeapon addWeaponTurret [_proxyWeapon, _turret];
_staticWeapon setVariable [format [QGVAR(proxyHandled_%1), _turret], true, true];

View File

@ -0,0 +1,56 @@
#include "script_component.hpp"
/*
* Author: PabstMirror
* Gets sub actions for what the player can load into the static weapon
*
* Arguments:
* 0: Static Weapon <OBJECT>
* 1: Player <OBJECT>
*
* Return Value:
* Actions <ARRAY>
*
* Example:
* [cursorObject, player] call ace_csw_fnc_reload_actionsLoad
*
* Public: No
*/
params ["_vehicle", "_player"];
private _actions = [];
private _loadableMagazines = [_vehicle, _player] call FUNC(reload_getLoadableMagazines);
private _statement = {
params ["_target", "_player", "_params"];
_params params ["_carryMag", "_turretPath"];
[_target, _turretPath, _carryMag, _player] call FUNC(reload_loadMagazine);
};
private _condition = {
params ["_target", "_player", "_params"];
_params params ["_carryMag", "_turretPath"];
([_target, _turretPath, _carryMag, _player] call FUNC(reload_canLoadMagazine)) select 0
};
{
_x params ["_carryMag", "_turretPath", "_loadInfo"];
_loadInfo params ["", "", "", "_isBeltLinking"];
private _displayName = getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName");
private _picture = getText (configFile >> "CfgMagazines" >> _carryMag >> "picture");
private _text = if (_isBeltLinking) then {
format [localize LSTRING(actionLink), _displayName];
} else {
format [localize LSTRING(loadX), _displayName];
};
private _action = [format ["load_%1", _forEachIndex], _text, _picture, _statement, _condition, {}, _x] call EFUNC(interact_menu,createAction);
_actions pushBack [_action, [], _vehicle];
} forEach _loadableMagazines;
TRACE_1("loadActions",count _actions);
_actions

View File

@ -0,0 +1,81 @@
#include "script_component.hpp"
/*
* Author: PabstMirror
* Gets sub actions for what the player can load into the static weapon
*
* Arguments:
* 0: Target <OBJECT>
* 1: Player <OBJECT>
*
* Return Value:
* Actions <ARRAY>
*
* Example:
* [cursorObject, player] call ace_csw_fnc_reload_actionsUnload
*
* Public: No
*/
params ["_vehicle", "_player"];
private _statement = {
params ["_target", "_player", "_params"];
_params params ["_vehMag", "_turretPath", "_carryMag"];
TRACE_5("starting unload",_target,_turretPath,_player,_carryMag,_vehMag);
private _timeToUnload = 1;
if (!isNull(configFile >> "CfgVehicles" >> (typeOf _target) >> QUOTE(ADDON) >> "ammoUnloadTime")) then {
_timeToUnload = getNumber(configFile >> "CfgVehicles" >> (typeOf _target) >> QUOTE(ADDON) >> "ammoUnloadTime");
};
[
TIME_PROGRESSBAR(_timeToUnload),
[_target, _turretPath, _player, _carryMag, _vehMag],
{
(_this select 0) params ["_target", "_turretPath", "", "_carryMag", "_vehMag"];
TRACE_5("unload progressBar finish",_target,_turretPath,_carryMag,_vehMag,_player);
[QGVAR(removeTurretMag), [_target, _turretPath, _carryMag, _vehMag, _player]] call CBA_fnc_globalEvent;
},
{TRACE_1("unload progressBar fail",_this);},
format [localize LSTRING(unloadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")],
{(_this select 0) call FUNC(reload_canUnloadMagazine)},
["isNotInside"]
] call EFUNC(common,progressBar);
};
private _condition = {
params ["_target", "_player", "_params"];
_params params ["_vehMag", "_turretPath", "_carryMag"];
[_target, _turretPath, _player, _carryMag, _vehMag] call FUNC(reload_canUnloadMagazine)
};
private _actions = [];
private _handeledMagTypes = [];
// Go through magazines on static weapon and check if any are unloadable
{
_x params ["_xMag", "_xTurret", "_xAmmo"];
if ((_xAmmo > 0) && {!(_xMag in _handeledMagTypes)}) then {
_handeledMagTypes pushBack _xMag;
private _carryMag = GVAR(vehicleMagCache) getVariable _xMag;
if (isNil "_carryMag") then {
private _groups = "getNumber (_x >> _xMag) == 1" configClasses (configFile >> QGVAR(groups));
_carryMag = configName (_groups param [0, configNull]);
GVAR(vehicleMagCache) setVariable [_xMag, _carryMag];
TRACE_2("setting cache",_xMag,_carryMag);
};
if (_carryMag == "") exitWith {};
private _displayName = getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName");
private _text = format [LLSTRING(unloadX), _displayName];
private _picture = getText (configFile >> "CfgMagazines" >> _carryMag >> "picture");
private _action = [format ["unload_%1", _forEachIndex], _text, _picture, _statement, _condition, {}, [_xMag, _xTurret, _carryMag]] call EFUNC(interact_menu,createAction);
_actions pushBack [_action, [], _vehicle];
};
} forEach (magazinesAllTurrets _vehicle);
TRACE_1("unloadActions",count _actions);
_actions

View File

@ -0,0 +1,59 @@
#include "script_component.hpp"
/*
* Author: PabstMirror & TCVM
* Tests if unit can load a magazine into a static weapon.
*
* Arguments:
* 0: Static Weapon <OBJECT>
* 1: Turret Path <ARRAY>
* 2: Carryable Magazine <STRING>
* 3: Player <OBJECT>
*
* Return Value:
* [CanLoad<BOOL>, LoadedMag<STRING>, AmmoNeeded<NUMBER>, IsBeltLinking<BOOL>]<ARRAY>
*
* Example:
* [cursorObject, [0], "ACE_csw_100Rnd_127x99_mag_red", player] call ace_csw_fnc_reload_canLoadMagazine
*
* Public: No
*/
params ["_vehicle", "_turret", "_carryMag", ["_unit", objNull]];
// TRACE_4("reload_canLoadMagazine",_vehicle,_turret,_carryMag,_unit);
// Handle disassembled or deleted
if (!alive _vehicle) exitWith { [false, "", -1, false] };
// Verify unit has carry magazine
if ((!isNull _unit) && {((_vehicle distance _unit) > 5) || {((magazines _unit) findIf {_x == _carryMag}) == -1}}) exitWith { [false, "", -2, false] };
private _desiredAmmo = getNumber (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> QUOTE(ADDON) >> "desiredAmmo");
if (_desiredAmmo == 0) then { _desiredAmmo = 100; };
private _ammoNeeded = _desiredAmmo min getNumber (configFile >> "CfgMagazines" >> _carryMag >> "count"); // assume it needs full carry mag
private _loadedMag = "";
private _isBeltLinking = false;
scopeName "main";
{
_x params ["_xMag", "_xTurret", "_xAmmo"];
if (_xTurret isEqualTo _turret) then {
if (_loadedMag != "") exitWith { [false, _loadedMag, -3, false] breakOut "main"; }; // Exit if static has multiple mags
_loadedMag = _xMag;
if (_xAmmo > 0) then {
// There is a magazine with ammo loaded in the turret (are there any multi-muzzle static weapons??), see if we can add to this mag
if (getNumber (configFile >> QGVAR(groups) >> _carryMag >> _xMag) != 1) exitWith {
[false, _loadedMag, -4, false] breakOut "main"; // Carry mag cannot be added to existing vehicle mag (e.g. red to green tracers)
};
if (getNumber (configFile >> "CfgMagazines" >> _carryMag >> "ACE_isBelt") == 0) exitWith {
[false, _loadedMag, -5, false] breakOut "main"; // Non-linkable mag loaded, can't add any more
};
private _maxMagazineAmmo = _desiredAmmo min getNumber (configFile >> "CfgMagazines" >> _xMag >> "count");
if (_xAmmo >= _maxMagazineAmmo) exitWith {
[false, _loadedMag, -6, false] breakOut "main"; // Already at capicity
};
_ammoNeeded = _maxMagazineAmmo - _xAmmo;
_isBeltLinking = true;
};
};
} forEach (magazinesAllTurrets _vehicle);
[true, _loadedMag, _ammoNeeded, _isBeltLinking]

View File

@ -0,0 +1,33 @@
#include "script_component.hpp"
/*
* Author: PabstMirror
* Tests if unit can unload a magazine from a static weapon.
*
* Arguments:
* 0: Static Weapon <OBJECT>
* 1: Turret Path <ARRAY>
* 2: Player <OBJECT>
* 3: Carryable Magazine <STRING>
* 4: Vehicle Magazine <STRING>
*
* Return Value:
* <BOOL>
*
* Example:
* [cursorTarget, [0], player, "ACE_csw_100Rnd_127x99_mag_red", "200Rnd_127x99_mag_Tracer_Red"] call ace_csw_fnc_reload_canUnloadMagazine
*
* Public: No
*/
params ["_vehicle", "_turretPath", "_unit", "_carryMag", "_vehMag"];
// handle disassembled or deleted
if ((!alive _vehicle) || {(_vehicle distance _unit) > 5}) exitWith {false};
private _return = false;
{
_x params ["_xMag", "_xTurret", "_xAmmo"];
if ((_xMag == _vehMag) && {_xTurret isEqualTo _turretPath} && {_xAmmo > 0}) exitWith { _return = true };
} forEach (magazinesAllTurrets _vehicle);
_return

View File

@ -0,0 +1,52 @@
#include "script_component.hpp"
/*
* Author: PabstMirror
* Gets magazines that the player is carrying that can be loaded into the static weapon
*
* Arguments:
* 0: Vehicle <OBJECT>
* 1: Player <OBJECT>
*
* Return Value:
* Mags <ARRAY>
* [Carry Magazine <STRING>, Turret Path <ARRAY>, Ammo Needed <NUMBER>]
*
* Example:
* [cursorObject, player] call ace_csw_fnc_reload_getLoadableMagazines
*
* Public: No
*/
params ["_vehicle", "_player"];
private _carriedMagazines = [];
{
if (isClass (configFile >> QGVAR(groups) >> _x)) then {
_carriedMagazines pushBackUnique _x;
};
} forEach (magazines _player);
if (_carriedMagazines isEqualTo []) exitWith { [] }; // fast exit if no carry mags
private _loadInfo = [];
private _return = [];
// Go through turrets and find weapons that we could reload
{
private _turretPath = _x;
{
private _weapon = _x;
{
private _carryMag = _x;
private _carryGroup = configFile >> QGVAR(groups) >> _carryMag;
{
if (((getNumber (_carryGroup >> _x)) == 1) && {_loadInfo = [_vehicle, _turretPath, _carryMag, _player] call FUNC(reload_canLoadMagazine); _loadInfo select 0}) exitWith {
_return pushBack [_carryMag, _turretPath, _loadInfo];
};
} forEach (getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines"));
} forEach _carriedMagazines;
} forEach (_vehicle weaponsTurret _turretPath);
} forEach (allTurrets _vehicle);
// Note: these nested forEach's looks terrible, but most only have one element
_return

View File

@ -0,0 +1,45 @@
#include "script_component.hpp"
/*
* Author: PabstMirror
* Finds the best vehicle magazines to create from a carryable magazine for a given weapon.
*
* Arguments:
* 0: Weapon <STRING>
* 1: Magazine that is carryable <STRING>
*
* Return Value:
* Vehicle Magazine <STRING>
*
* Example:
* [cursorObject, [0], "ace_csw_100Rnd_127x99_mag"] call ace_csw_fnc_reload_getVehicleMagazine
*
* Public: No
*/
params ["_vehicle", "_turret", "_carryMag"];
TRACE_3("reload_getVehicleMagazine",_vehicle,_turret,_carryMag);
private _carryGroupCfg = configFile >> QGVAR(groups) >> _carryMag;
private _desiredAmmo = getNumber (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> QUOTE(ADDON) >> "desiredAmmo");
if (_desiredAmmo == 0) then { _desiredAmmo = 100; };
private _bestMag = "#";
private _bestMagCount = -1;
{
private _weapon = _x;
{
if ((getNumber (_carryGroupCfg >> _x)) == 1) then {
private _xAmmo = getNumber (configFile >> "CfgMagazines" >> _x >> "ammo");
if (((_xAmmo >= _bestMagCount) && {_bestMagCount < _desiredAmmo}) || {(_xAmmo >= _desiredAmmo) && {_xAmmo < _bestMagCount}}) then {
_bestMag = _x;
_bestMagCount = _xAmmo;
};
};
} forEach (getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines"));
} forEach (_vehicle weaponsTurret _turret);
TRACE_3("best fit",_desiredAmmo,_bestMag,_bestMagCount);
if (_bestMag == "#") then { ERROR_1("veh mag not found for %1",_carryMag); };
_bestMag

View File

@ -0,0 +1,66 @@
#include "script_component.hpp"
/*
* Author: TCVM, PabstMirror
* Handles adding ammo to a turret
* Called from a global event but only runs where turret is local
*
* Arguments:
* 0: Static Weapon <OBJECT>
* 1: Turret Path <ARRAY>
* 2: Unit doing action <OBJECT>
* 3: Vehicle Magazine <STRING>
* 4: Ammo in magazine <NUMBER>
*
* Return Value:
* None
*
* Example:
* [cursorTarget, [0], player, "200Rnd_127x99_mag_Tracer_Red", 70] call ace_csw_fnc_reload_handleAddTurretMag
*
* Public: No
*/
params ["_vehicle", "_turret", "_unit", "_carryMag" ,"_ammoRecieved"];
TRACE_5("reload_handleAddTurretMag",_vehicle,_turret,_unit,_carryMag,_ammoRecieved);
TRACE_2("",local _vehicle, _vehicle turretLocal _turret);
if (!(_vehicle turretLocal _turret)) exitWith {};
([_vehicle, _turret, _carryMag] call FUNC(reload_canLoadMagazine)) params ["_canAdd", "_loadedMag", "_neededAmmo", "_isBeltLinking"];
TRACE_4("canLoad",_canAdd,_loadedMag,_neededAmmo,_isBeltLinking);
private _ammoRemaining = _ammoRecieved;
if (_canAdd) then {
private _ammoUsed = _neededAmmo min _ammoRecieved;
_ammoRemaining = _ammoRemaining - _ammoUsed;
if (_isBeltLinking) then {
private _currentAmmo = _vehicle magazineTurretAmmo [_loadedMag, _turret];
_currentAmmo = _currentAmmo + _ammoUsed;
TRACE_2("Setting mag ammo",_loadedMag,_currentAmmo);
// _vehicle setMagazineTurretAmmo [_loadedMag, _currentAmmo, _turret];
// setMagazineTurretAmmo is broken on split locality, use setAmmo for now (this may not work for multi turret vehicles)
private _weapon = (_vehicle weaponsTurret _turret) param [0, ""];
TRACE_3("setAmmo",_vehicle,_weapon, _currentAmmo);
_vehicle setAmmo [_weapon, _currentAmmo];
private _currentAmmo = _vehicle magazineTurretAmmo [_loadedMag, _turret];
if ((_weapon == "") || {_currentAmmo != _currentAmmo}) then { ERROR_1("failed to setAmmo - %1", _this); };
} else {
if (_loadedMag != "") then {
TRACE_1("Removing emtpy mag",_loadedMag);
_vehicle removeMagazinesTurret [_loadedMag, _turret];
};
[_vehicle, _turret, true] call FUNC(proxyWeapon); // Check if we need to add proxy weapon now
private _newMag = [_vehicle, _turret, _carryMag] call FUNC(reload_getVehicleMagazine);
TRACE_2("Adding new mag",_newMag,_ammoUsed);
_vehicle addMagazineTurret [_newMag, _turret, _ammoUsed];
};
};
if (_ammoRemaining > 0) then {
TRACE_3("Returning ammo",_unit,_carryMag,_ammoRemaining);
[QGVAR(returnAmmo), [_unit, _carryMag, _ammoRemaining], _unit] call CBA_fnc_targetEvent;
};

View File

@ -0,0 +1,79 @@
#include "script_component.hpp"
/*
* Author: TCVM
* Handles removing ammo from a turret
* Called from a global event but only runs where turret is local
*
* Arguments:
* 0: Static Weapon <OBJECT>
* 1: Turret Path <ARRAY>
* 2: Magainze Unit Can Carry <STRING>
* 3: Magazine To Remove From Static <STRING>
* 4: Unit to unload to <OBJECT>
*
* Return Value:
* None
*
* Example:
* [cursorTarget, [0], "ACE_csw_100Rnd_127x99_mag_red", "500Rnd_127x99_mag_Tracer_Green", player] call ace_csw_fnc_reload_handleRemoveTurretMag
*
* Public: No
*/
params ["_vehicle", "_turretPath", "_carryMag", "_vehMag", "_unit"];
TRACE_6("removeTurretMag EH",_vehicle,_turretPath,_carryMag,_vehMag,_unit);
TRACE_3("",local _vehicle, _vehicle turretLocal _turretPath,local _unit);
if (!(_vehicle turretLocal _turretPath)) exitWith {};
private _magsInWeapon = []; // Check how much ammo it has now:
{
_x params ["_xMag", "_xTurret", "_xAmmo"];
if ((_xMag == _vehMag) && {_xTurret isEqualTo _turretPath}) then {
_magsInWeapon pushBack _xAmmo;
};
} forEach (magazinesAllTurrets _vehicle);
TRACE_1("",_magsInWeapon);
// Remove any empty mags from start:
private _ammoInFirstMag = 0;
while {(!(_magsInWeapon isEqualTo [])) && {_ammoInFirstMag = _magsInWeapon deleteAt 0; (_ammoInFirstMag == 0)}} do {
TRACE_1("Removing empty mag",_ammoInFirstMag);
_vehicle removeMagazineTurret [_vehMag, _turretPath];
};
TRACE_2("",_magsInWeapon,_ammoInFirstMag);
if ((_magsInWeapon isEqualTo []) && {_ammoInFirstMag == 0}) exitWith {};
private _maxAmmo = getNumber (configFile >> "CfgMagazines" >> _carryMag >> "count");
private _ammoRemoved = _ammoInFirstMag min _maxAmmo;
private _ammoLeft = _ammoInFirstMag - _ammoRemoved;
if ((_magsInWeapon isEqualTo []) && {_ammoInFirstMag > _ammoRemoved}) then {
// Only one mag in gun, and we're just taking out a partial ammount (unlinking)
TRACE_2("Setting mag ammo",_ammoRemoved,_ammoLeft);
// _vehicle setMagazineTurretAmmo [_vehMag, _ammoLeft, _turretPath];
// setMagazineTurretAmmo is broken on split locality, use setAmmo for now
private _weapon = (_vehicle weaponsTurret _turretPath) param [0, ""];
TRACE_3("setAmmo",_vehicle,_weapon, _ammoLeft);
_vehicle setAmmo [_weapon, _ammoLeft];
private _currentAmmo = _vehicle magazineTurretAmmo [_vehMag, _turretPath];
if ((_weapon == "") || {_currentAmmo != _ammoLeft}) then { ERROR_1("failed to setAmmo - %1", _this); };
} else {
// Because of command limitations, we need to remove mags to change their ammo
// This will cause the gun to need to be reloaded if more than one is loaded (only a problem for non-assembly mode guns)
TRACE_2("Removing magazine",_ammoRemoved,_ammoLeft);
_vehicle removeMagazinesTurret [_vehMag, _turretPath];
if (_ammoLeft > 0) then {
_magsInWeapon pushBack _ammoLeft;
TRACE_1("Re-adding partial",_ammoLeft);
};
{
if (_x > 0) then { _vehicle addMagazineTurret [_vehMag, _turretPath, _x]; };
} forEach _magsInWeapon;
};
TRACE_3("Returning ammo",_unit,_carryMag,_ammoRemoved);
[QGVAR(returnAmmo), [_unit, _carryMag, _ammoRemoved], _unit] call CBA_fnc_targetEvent;

View File

@ -0,0 +1,70 @@
#include "script_component.hpp"
/*
* Author: TCVM and PabstMirror
* Handles returned ammo (either from unloading or leftovers from linking)
*
* Arguments:
* 0: Man or Vehicle <OBJECT>
* 1: Carry Magazine <STRING>
* 2: Ammo in magazine <NUMBER>
*
* Return Value:
* None
*
* Example:
* [player, "ace_csw_100Rnd_127x99_mag", 70] call ace_csw_fnc_reload_handleReturnAmmo
*
* Public: No
*/
params ["_unloadTo", "_carryMag", "_ammo"];
TRACE_3("reload_handleReturnAmmo",_unloadTo,_carryMag,_ammo);
private _carryMaxAmmo = getNumber (configFile >> "CfgMagazines" >> _carryMag >> "count");
private _fullMagazines = floor (_ammo / _carryMaxAmmo);
private _bulletsRemaining = _ammo % _carryMaxAmmo;
if (_unloadTo isKindOf "CaManBase") then {
while {(_fullMagazines > 0) && {_unloadTo canAdd _carryMag}} do {
_unloadTo addMagazine [_carryMag, _carryMaxAmmo];
_fullMagazines = _fullMagazines - 1;
};
if ((_bulletsRemaining > 0) && {_unloadTo canAdd _carryMag}) then {
_unloadTo addMagazine [_carryMag, _bulletsRemaining];
_bulletsRemaining = 0;
};
};
if ((_fullMagazines == 0) && {_bulletsRemaining == 0}) exitWith {};
// Try to use existing container
private _container = _unloadTo getVariable [QGVAR(container), objNull];
if ((_container distance _unloadTo) > 4) then { _container = objNull; };
if (isNull _container) then {
_container = (nearestObjects [_unloadTo, ["groundWeaponHolder"], 4]) param [0, objNull];
};
if (isNull _container) then {
// Create ground weapon holder container
private _weaponRelPos = _unloadTo getRelPos RELATIVE_DIRECTION(270);
_weaponRelPos set [2, ((getPosATL _unloadTo) select 2) + 0.05];
_container = createVehicle ["groundWeaponHolder", [0, 0, 0], [], 0, "NONE"];
// ToDo: Unload to ammo box??
_unloadTo setVariable [QGVAR(container), container, true];
_container setDir random [0, 180, 360];
_container setPosATL _weaponRelPos;
if ((_weaponRelPos select 2) < 0.5) then {
_container setVectorUp (surfaceNormal _weaponRelPos);
};
TRACE_2("Creating NEW Container",_container,_weaponRelPos);
};
TRACE_3("adding to container",_container,_fullMagazines,_bulletsRemaining);
if (_fullMagazines > 0) then {
_container addMagazineAmmoCargo [_carryMag, _fullMagazines, _carryMaxAmmo];
};
if (_bulletsRemaining > 0) then {
_container addMagazineAmmoCargo [_carryMag, 1, _bulletsRemaining];
};

View File

@ -0,0 +1,66 @@
#include "script_component.hpp"
/*
* Author: PabstMirror
* Loads a magazine into a static weapon from a magazine carried by the player.
*
* Arguments:
* 0: Vehicle <OBJECT>
* 1: Turret <ARRAY>
* 2: Unit Carried Magazine <STRING>
* 3: Player <OBJECT>
*
* Return Value:
* None
*
* Example:
* [cursorTarget, [0], "ACE_csw_100Rnd_127x99_mag_red", player] call ace_csw_fnc_reload_loadMagazine
*
* Public: No
*/
params ["_vehicle", "_turret", "_carryMag", "_unit"];
TRACE_4("loadMagazine",_vehicle,_turret,_carryMag,_unit);
private _timeToLoad = 1;
if (!isNull(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> QUOTE(ADDON) >> "ammoLoadTime")) then {
_timeToLoad = getNumber(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> QUOTE(ADDON) >> "ammoLoadTime");
};
private _displayName = format [localize LSTRING(loadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")];
private _onFinish = {
(_this select 0) params ["_vehicle", "_turret", "_carryMag", "_unit"];
TRACE_4("load progressBar finish",_vehicle,_turret,_carryMag,_unit);
([_vehicle, _turret, _carryMag, _unit] call FUNC(reload_canLoadMagazine)) params ["", "", "_neededAmmo", ""];
if (_neededAmmo <= 0) exitWith { ERROR_1("Can't load ammo - %1",_this); };
// Figure out what we can add from the magazines we have
private _bestAmmoToSend = -1;
{
_x params ["_xMag", "_xAmmo"];
if (_xMag == _carryMag) then {
if ((_bestAmmoToSend == -1) || {(_xAmmo > _bestAmmoToSend) && {_xAmmo <= _neededAmmo}}) then {
_bestAmmoToSend = _xAmmo;
};
};
} forEach (magazinesAmmo _unit);
if (_bestAmmoToSend == -1) exitWith {ERROR_2("No ammo [%1 - %2]?",_xMag,_bestAmmoToSend);};
[_unit, _carryMag, _bestAmmoToSend] call EFUNC(common,removeSpecificMagazine);
if (_bestAmmoToSend == 0) exitWith {};
TRACE_5("calling addTurretMag event",_vehicle,_turret,_unit,_carryMag,_bestAmmoToSend);
[QGVAR(addTurretMag), [_vehicle, _turret, _unit, _carryMag, _bestAmmoToSend]] call CBA_fnc_globalEvent;
};
[
TIME_PROGRESSBAR(_timeToLoad),
[_vehicle, _turret, _carryMag, _unit],
_onFinish,
{TRACE_1("load progressBar fail",_this);},
_displayName,
{((_this select 0) call FUNC(reload_canLoadMagazine)) select 0},
["isNotInside"]
] call EFUNC(common,progressBar);

View File

@ -0,0 +1,92 @@
#include "script_component.hpp"
/*
* Author: Brandon (TCVM)
* Initializes weapon to disable weapon disassembling
*
* Arguments:
* 0: Weapon <OBJECT>
*
* Return Value:
* None
*
* Example:
* [weapon] call ace_csw_fnc_staticWeaponInit
*
* Public: No
*/
params ["_staticWeapon"];
private _typeOf = typeOf _staticWeapon;
private _configEnabled = (getNumber (configFile >> "CfgVehicles" >> _typeOf >> "ace_csw" >> "enabled")) == 1;
private _assemblyConfig = _configEnabled && {(getText (configFile >> "CfgVehicles" >> _typeOf >> "ace_csw" >> "disassembleWeapon")) != ""};
TRACE_4("staticWeaponInit",_staticWeapon,_typeOf,_configEnabled,_assemblyConfig);
if (_configEnabled && {GVAR(ammoHandling) == 2}) then {
TRACE_1("adding AI fired handler",_staticWeapon);
_staticWeapon addEventHandler ["Fired", LINKFUNC(ai_handleFired)];
};
TRACE_2("",local _staticWeapon,_staticWeapon turretLocal [0]);
if (_configEnabled && {_staticWeapon turretLocal [0]}) then { // if turret is local to us, then handle mags/weapon
[{
params ["_staticWeapon"];
if (!alive _staticWeapon) exitWith { TRACE_1("dead/deleted",_staticWeapon); };
private _assemblyMode = [false, true, GVAR(defaultAssemblyMode)] select (_staticWeapon getVariable [QGVAR(assemblyMode), 2]);
TRACE_2("turretLocal",_staticWeapon,_assemblyMode);
[_staticWeapon, [0], _assemblyMode] call FUNC(proxyWeapon);
[_staticWeapon, _assemblyMode] call FUNC(staticWeaponInit_unloadExtraMags);
}, [_staticWeapon]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly
};
if (_assemblyConfig) then {
[{
params ["_staticWeapon"];
if (!alive _staticWeapon) exitWith { TRACE_1("dead/deleted",_staticWeapon); };
private _assemblyMode = [false, true, GVAR(defaultAssemblyMode)] select (_staticWeapon getVariable [QGVAR(assemblyMode), 2]);
TRACE_2("assemblyConfig present",_staticWeapon,_assemblyMode);
if (_assemblyMode) then { // Disable vanilla assembly if assemblyMode eanbled
[QGVAR(disableVanillaAssembly), [_staticWeapon]] call CBA_fnc_localEvent;
};
}, [_staticWeapon]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly
};
// Add interactions for players
if (hasInterface && {!(_typeOf in GVAR(initializedStaticTypes))}) then {
GVAR(initializedStaticTypes) pushBack _typeOf;
TRACE_1("Adding Actions",_typeOf);
if (_assemblyConfig) then {
private _disassembleAction = [QGVAR(disassemble), localize LSTRING(DisassembleCSW_displayName), "", {call FUNC(assemble_pickupWeapon)}, {call FUNC(assemble_canPickupWeapon)}] call EFUNC(interact_menu,createAction);
[_typeOf, 0, ["ACE_MainActions"], _disassembleAction] call EFUNC(interact_menu,addActionToClass);
};
private _ammoActionPath = [];
private _magazineLocation = getText (configFile >> "CfgVehicles" >> _typeOf >> QUOTE(ADDON) >> "magazineLocation");
private _condition = { //IGNORE_PRIVATE_WARNING ["_target", "_player"];
// If magazine handling is enabled or weapon assembly/disassembly is enabled we enable ammo handling
if ((GVAR(ammoHandling) == 0) && {!([false, true, GVAR(defaultAssemblyMode)] select (_staticWeapon getVariable [QGVAR(assemblyMode), 2]))}) exitWith { false };
[_player, _target, ["isNotSwimming", "isNotSitting"]] call EFUNC(common,canInteractWith)
};
private _childenCode = {
BEGIN_COUNTER(getActions); // can remove for final release
private _ret = (call FUNC(reload_actionsLoad)) + (call FUNC(reload_actionsUnload));
END_COUNTER(getActions);
_ret
};
if (_configEnabled && {_magazineLocation != ""}) then {
private _positionCode = compile _magazineLocation;
private _ammoAction = [QGVAR(magazine), localize LSTRING(AmmoHandling_displayName), "", {}, _condition, _childenCode, [], _positionCode, 4] call EFUNC(interact_menu,createAction);
_ammoActionPath = [_typeOf, 0, [], _ammoAction] call EFUNC(interact_menu,addActionToClass);
} else {
private _ammoAction = [QGVAR(magazine), localize LSTRING(AmmoHandling_displayName), "", {}, _condition, _childenCode] call EFUNC(interact_menu,createAction);
_ammoActionPath = [_typeOf, 0, ["ACE_MainActions"], _ammoAction] call EFUNC(interact_menu,addActionToClass);
};
if (["ACE_reload"] call EFUNC(common,isModLoaded)) then {
// move reload's check ammo action to the ammo handling point (remove and re-add)
[_typeOf, 0, ["ACE_MainActions", QEGVAR(reload,CheckAmmo)]] call EFUNC(interact_menu,removeActionFromClass);
private _checkAmmoAction = [QGVAR(checkAmmo), localize ELSTRING(reload,checkAmmo), "", EFUNC(reload,checkAmmo), EFUNC(reload,canCheckAmmo)] call EFUNC(interact_menu,createAction);
[_typeOf, 0, _ammoActionPath, _checkAmmoAction] call EFUNC(interact_menu,addActionToClass);
};
};

View File

@ -0,0 +1,88 @@
#include "script_component.hpp"
/*
* Author: Brandon (TCVM), PabstMirror
* Dumps ammo to container
*
* Arguments:
* 0: Weapon <OBJECT>
*
* Return Value:
* None
*
* Example:
* [weapon] call ace_csw_fnc_staticWeaponInit_unloadExtraMags
*
* Public: No
*/
params ["_staticWeapon"];
TRACE_1("staticWeaponInit_unloadExtraMags",_staticWeapon);
if (!alive _staticWeapon) exitWith {TRACE_1("dead/deleted",alive _staticWeapon);};
private _assemblyMode = [false, true, GVAR(defaultAssemblyMode)] select (_staticWeapon getVariable [QGVAR(assemblyMode), 2]);
private _emptyWeapon = _staticWeapon getVariable [QGVAR(emptyWeapon), false];
TRACE_2("",_assemblyMode,_emptyWeapon);
if (!_assemblyMode) exitWith {};
private _desiredAmmo = getNumber (configFile >> "CfgVehicles" >> (typeOf _staticWeapon) >> QUOTE(ADDON) >> "desiredAmmo");
private _storeExtraMagazines = GVAR(handleExtraMagazines);
if (_emptyWeapon) then {
_desiredAmmo = 0;
_storeExtraMagazines = false;
};
TRACE_2("settings",_desiredAmmo,_storeExtraMagazines);
private _magsToRemove = [];
private _loadedMagazineInfo = [];
private _containerMagazineClassnames = [];
private _containerMagazineCount = [];
{
_x params ["_xMag", "_xTurret", "_xAmmo"];
private _carryMag = GVAR(vehicleMagCache) getVariable _xMag;
if (isNil "_carryMag") then {
private _groups = "getNumber (_x >> _xMag) == 1" configClasses (configFile >> QGVAR(groups));
_carryMag = configName (_groups param [0, configNull]);
GVAR(vehicleMagCache) setVariable [_xMag, _carryMag];
TRACE_2("setting cache",_xMag,_carryMag);
};
if (_carryMag != "") then {
if ((_desiredAmmo > 0) && {_loadedMagazineInfo isEqualTo []}) then {
private _loadedMagAmmo = _desiredAmmo min _xAmmo;
_loadedMagazineInfo = [_xMag, _xTurret, _loadedMagAmmo];
_xAmmo = _xAmmo - _loadedMagAmmo;
TRACE_1("",_loadedMagAmmo);
};
if (_xAmmo > 0) then {
_magsToRemove pushBackUnique [_xMag, _xTurret];
private _index = _containerMagazineClassnames find _carryMag;
if (_index < 0) then {
_index = _containerMagazineClassnames pushBack _carryMag;
_containerMagazineCount pushBack 0;
};
_containerMagazineCount set [_index, (_containerMagazineCount select _index) + _xAmmo];
};
} else {
if ((_xMag select [0,4]) != "fake") then { WARNING_1("Unable to unload [%1] - No matching carry mag",_xMag); };
};
} forEach (magazinesAllTurrets _staticWeapon);
TRACE_1("Remove all loaded magazines",_magsToRemove);
{
_staticWeapon removeMagazinesTurret _x;
if ((_loadedMagazineInfo select [0,2]) isEqualTo _x) then {
TRACE_1("Re-add the starting mag",_loadedMagazineInfo);
_staticWeapon addMagazineTurret _loadedMagazineInfo;
};
} forEach _magsToRemove;
if (_storeExtraMagazines) then {
TRACE_1("saving extra mags to container",_containerMagazineCount);
{
[_staticWeapon, _x, _containerMagazineCount select _forEachIndex] call FUNC(reload_handleReturnAmmo);
} forEach _containerMagazineClassnames;
};

View File

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

View File

@ -0,0 +1,43 @@
// CBA Settings [ADDON: ace_csw]:
private _categoryArray = [format ["ACE %1", localize LSTRING(DisplayName)]];
[
QGVAR(defaultAssemblyMode), "CHECKBOX",
[LSTRING(defaultAssemblyMode_displayName), LSTRING(defaultAssemblyMode_description)],
_categoryArray,
false, // default value
true, // isGlobal
{[QGVAR(defaultAssemblyMode), _this] call EFUNC(common,cbaSettings_settingChanged)},
true // Needs mission restart
] call CBA_settings_fnc_init;
[
QGVAR(handleExtraMagazines), "CHECKBOX",
[LSTRING(handleExtraMagazines_displayName), LSTRING(handleExtraMagazines_description)],
_categoryArray,
true, // default value
true, // isGlobal
{[QGVAR(handleExtraMagazines), _this] call EFUNC(common,cbaSettings_settingChanged)},
true // Needs mission restart
] call CBA_settings_fnc_init;
[
QGVAR(ammoHandling), "LIST",
[LSTRING(ammoHandling_displayName), LSTRING(ammoHandling_description)],
_categoryArray,
[[0, 1, 2], [LELSTRING(common,Disabled), LELSTRING(common,playerOnly), LELSTRING(common,playersAndAI)], 2], // [_values, _valueTitles, _defaultIndex]
true, // isGlobal
{[QGVAR(ammoHandling), _this] call EFUNC(common,cbaSettings_settingChanged)},
true // Needs mission restart
] call CBA_settings_fnc_init;
[
QGVAR(progressBarTimeCoefficent), "SLIDER",
[LSTRING(progressBarTimeCoefficent_displayName), LSTRING(progressBarTimeCoefficent_description)],
_categoryArray,
[0,2,1,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)]
true, // isGlobal
{[QGVAR(progressBarTimeCoefficent), _this] call EFUNC(common,cbaSettings_settingChanged)},
false // Needs mission restart
] call CBA_settings_fnc_init;

View File

@ -0,0 +1,28 @@
#define COMPONENT csw
#define COMPONENT_BEAUTIFIED Crew-Served Weapons
#include "\z\ace\addons\main\script_mod.hpp"
#define FAST_PROGRESSBARS
#define DEBUG_MODE_FULL
#define DISABLE_COMPILE_CACHE
#define ENABLE_PERFORMANCE_COUNTERS
#ifdef DEBUG_ENABLED_CSW
#define DEBUG_MODE_FULL
#endif
#ifdef DEBUG_SETTINGS_CSW
#define DEBUG_SETTINGS DEBUG_SETTINGS_CSW
#endif
#include "\z\ace\addons\main\script_macros.hpp"
#define DISTANCE_FROM_GUN 1.5
#define RELATIVE_DIRECTION(direction) [DISTANCE_FROM_GUN, direction]
#ifdef FAST_PROGRESSBARS
#define TIME_PROGRESSBAR(X) ((X) * 0.075)
#else
#define TIME_PROGRESSBAR(X) ((X) * GVAR(progressBarTimeCoefficent))
#endif

220
addons/csw/stringtable.xml Normal file
View File

@ -0,0 +1,220 @@
<?xml version="1.0" encoding="utf-8"?>
<Project name="ACE">
<Package name="CSW">
<Key ID="STR_ACE_CSW_displayName">
<English>Crew Served Weapons</English>
</Key>
<Key ID="STR_ACE_CSW_Tripod_displayName">
<English>CSW Tripod</English>
</Key>
<Key ID="STR_ACE_CSW_PlaceTripod_displayName">
<English>Place Tripod</English>
</Key>
<Key ID="STR_ACE_CSW_DisassembleCSW_displayName">
<English>Disassemble</English>
<Czech>Rozložit</Czech>
<French>Démonter</French>
<German>%1 demontieren</German>
<Italian>Disassemblare</Italian>
<Polish>Złóż</Polish>
<Portuguese>Desmontar</Portuguese>
<Russian>Разобрать</Russian>
<Spanish>Desmonta</Spanish>
</Key>
<Key ID="STR_ACE_CSW_GetIn_displayName">
<English>Get In</English>
<Czech>Nastup</Czech>
<French>Embarquer</French>
<German>Einsteigen</German>
<Italian>A bordo</Italian>
<Polish>Wsiadać</Polish>
<Portuguese>Entrar</Portuguese>
<Russian>Войти</Russian>
<Spanish>Entrar</Spanish>
</Key>
<Key ID="STR_ACE_CSW_loadX">
<English>Load %1</English>
<German>Lade %1</German>
<Spanish>Load %1</Spanish>
<Czech>Nabít %1</Czech>
<French>Load %1</French>
<Polish>Załaduj %1</Polish>
<Italian>Load %1</Italian>
<Russian>Загрузить %1</Russian>
<Hungarian>Load %1</Hungarian>
</Key>
<Key ID="STR_ACE_CSW_unloadX">
<English>Unload %1</English>
<German>Entlade %1</German>
<Spanish>Unload %1</Spanish>
<Czech>Vytáhnout zásobník z %1</Czech>
<French>Unload %1</French>
<Polish>Rozładuj %1</Polish>
<Italian>Unload %1</Italian>
<Russian>Разгрузить %1</Russian>
<Hungarian>Unload %1</Hungarian>
</Key>
<Key ID="STR_ACE_CSW_actionLink">
<English>Link %1</English>
</Key>
<Key ID="STR_ACE_CSW_defaultAssemblyMode_displayName">
<English>Advanced assembly</English>
</Key>
<Key ID="STR_ACE_CSW_defaultAssemblyMode_description">
<English>Use ace for Assemble/Disassemble of supported static weapons. Loaded ammo is reduced to a single magazine.</English>
</Key>
<Key ID="STR_ACE_CSW_handleExtraMagazines_displayName">
<English>Save extra ammo</English>
</Key>
<Key ID="STR_ACE_CSW_handleExtraMagazines_description">
<English>Store extra magazines next to static weapon</English>
</Key>
<Key ID="STR_ACE_CSW_ammoHandling_displayName">
<English>Ammo handling</English>
</Key>
<Key ID="STR_ACE_CSW_ammoHandling_description">
<English>Allow loading and unloading magazines</English>
</Key>
<Key ID="STR_ACE_CSW_aiReloading_displayName">
<English>AI Reloading</English>
</Key>
<Key ID="STR_ACE_CSW_aiReloading_description">
<English>AI will attempt to reload static weapons with available ammo</English>
</Key>
<Key ID="STR_ACE_CSW_progressBarTimeCoefficent_displayName">
<English>Interaction Time Coefficent</English>
</Key>
<Key ID="STR_ACE_CSW_progressBarTimeCoefficent_description">
<English>Scales time required to assemble and reload static weapons</English>
</Key>
<Key ID="STR_ACE_CSW_Pickup_displayName">
<English>Pickup Tripod</English>
</Key>
<Key ID="STR_ACE_CSW_Move_displayName">
<English>Move Tripod</English>
</Key>
<Key ID="STR_ACE_CSW_MountWeapon_displayName">
<English>Mount Weapon</English>
</Key>
<Key ID="STR_ACE_CSW_DisassembleCSW_progressBar">
<English>Disassembling Gun...</English>
</Key>
<Key ID="STR_ACE_CSW_AssembleCSW_progressBar">
<English>Assembling Gun...</English>
</Key>
<Key ID="STR_ACE_CSW_LoadingAmmo_progressBar">
<English>Loading Ammo...</English>
</Key>
<Key ID="STR_ACE_CSW_UnloadingAmmo_progressBar">
<English>Unloading Ammo...</English>
</Key>
<Key ID="STR_ACE_CSW_PickupTripod_progressBar">
<English>Picking Up Tripod...</English>
</Key>
<Key ID="STR_ACE_CSW_PlaceTripod_progressBar">
<English>Placing Tripod...</English>
</Key>
<Key ID="STR_ACE_CSW_eden_enableCSW">
<English>Enable CSW</English>
</Key>
<Key ID="STR_ACE_CSW_eden_enableCSW_tooltip">
<English>Enables Crew Served ability on this weapon</English>
</Key>
<Key ID="STR_ACE_CSW_genericDescription">
<English>Used to reload crew served weapons</English>
</Key>
<Key ID="STR_ACE_CSW_TripodFolded_displayName">
<English>[CSW] Deployable Tripod</English>
</Key>
<Key ID="STR_ACE_CSW_TripodLowFolded_displayName">
<English>[CSW] Deployable Tripod (Low)</English>
</Key>
<Key ID="STR_ACE_CSW_mortarBaseplate_displayName">
<English>[CSW] Mk6 Mortar Baseplate</English>
</Key>
<Key ID="STR_ACE_CSW_StaticMortarBag_displayName">
<English>[CSW] Mk6 Mortar Tube</English>
</Key>
<Key ID="STR_ACE_CSW_StaticATWeapon_displayName">
<English>[CSW] Mini-Spike Launcher (AT)</English>
</Key>
<Key ID="STR_ACE_CSW_StaticAAWeapon_displayName">
<English>[CSW] Mini-Spike Launcher (AA)</English>
</Key>
<Key ID="STR_ACE_CSW_StaticHMGWeapon_displayName">
<English>[CSW] XM312</English>
</Key>
<Key ID="STR_ACE_CSW_StaticAutoHMGWeapon_displayName">
<English>[CSW] XM312A</English>
</Key>
<Key ID="STR_ACE_CSW_StaticHMGTallWeapon_displayName">
<English>[CSW] XM312 (High)</English>
</Key>
<Key ID="STR_ACE_CSW_StaticGMGWeapon_displayName">
<English>[CSW] XM307</English>
</Key>
<Key ID="STR_ACE_CSW_StaticAutoGMGWeapon_displayName">
<English>[CSW] XM307A</English>
</Key>
<Key ID="STR_ACE_CSW_StaticGMGTallWeapon_displayName">
<English>[CSW] XM307 (High)</English>
</Key>
<Key ID="STR_ACE_CSW_StaticATBag_displayName">
<English>[CSW] Static Mini-Spike Launcher (AT)</English>
</Key>
<Key ID="STR_ACE_CSW_StaticAABag_displayName">
<English>[CSW] Static Mini-Spike Launcher (AA)</English>
</Key>
<Key ID="STR_ACE_CSW_StaticHMGBag_displayName">
<English>[CSW] Static XM312 Gun</English>
</Key>
<Key ID="STR_ACE_CSW_StaticAutoHMGBag_displayName">
<English>[CSW] Static XM312 Gun (Autonomous)</English>
</Key>
<Key ID="STR_ACE_CSW_StaticHMGTallBag_displayName">
<English>[CSW] Static XM312 Gun (High)</English>
</Key>
<Key ID="STR_ACE_CSW_StaticGMGBag_displayName">
<English>[CSW] Static XM307 Gun</English>
</Key>
<Key ID="STR_ACE_CSW_StaticAutoGMGBag_displayName">
<English>[CSW] Static XM307 Gun (Autonomous)</English>
</Key>
<Key ID="STR_ACE_CSW_StaticGMGTallBag_displayName">
<English>[CSW] Static XM307 Gun (High)</English>
</Key>
<Key ID="STR_ACE_CSW_HMGStatic_displayName">
<English>[CSW] HMG Static</English>
</Key>
<Key ID="STR_ACE_CSW_GMGStatic_displayName">
<English>[CSW] GMG Static</English>
</Key>
<Key ID="STR_ACE_CSW_ATStatic_displayName">
<English>[CSW] AT Static</English>
</Key>
<Key ID="STR_ACE_CSW_AAStatic_displayName">
<English>[CSW] AA Static</English>
</Key>
<Key ID="STR_ACE_CSW_127x108_displayName">
<English>[CSW] 12.7x108mm HMG Belt</English>
</Key>
<Key ID="STR_ACE_CSW_127x99_displayName">
<English>[CSW] 12.7x99mm HMG Belt</English>
</Key>
<Key ID="STR_ACE_CSW_127x99_red_displayName">
<English>[CSW] 12.7x99mm Tracer HMG Belt (Red)</English>
</Key>
<Key ID="STR_ACE_CSW_127x99_green_displayName">
<English>[CSW] 12.7x99mm Tracer HMG Belt (Green)</English>
</Key>
<Key ID="STR_ACE_CSW_127x99_yellow_displayName">
<English>[CSW] 12.7x99mm Tracer HMG Belt (Yellow)</English>
</Key>
<Key ID="STR_ACE_CSW_GMGBelt_displayName">
<English>[CSW] 20mm Grenade GMG Belt</English>
</Key>
<Key ID="STR_ACE_CSW_mag_127x108">
<English>[CSW] 12.7 x 108 mm Ammo Belt</English>
</Key>
</Package>
</Project>

View File

@ -24,9 +24,12 @@ class CfgVehicles {
class Turrets: Turrets {
class MainTurret: MainTurret {};
};
class ACE_Actions;
};
class Mortar_01_base_F: StaticMortar {
class ace_csw {
proxyWeapon = QFUNC(csw_getProxyWeapon);
magazineLocation = "_target selectionPosition 'usti hlavne'";
};
class Turrets: Turrets {
class MainTurret: MainTurret {
turretInfoType = "ACE_Mk6_RscWeaponRangeArtillery";
@ -34,54 +37,6 @@ class CfgVehicles {
discreteDistanceInitIndex = 0;
};
};
class ACE_Actions: ACE_Actions {
class GVAR(unloadMagazine) {
displayName = CSTRING(unloadMortar);
distance = 2;
condition = QUOTE(_this call FUNC(canUnloadMagazine));
statement = QUOTE([ARR_3(_target,_player,5)] call FUNC(unloadMagazineTimer));
icon = "";
selection = "usti hlavne";
};
class GVAR(LoadActions) {
displayName = CSTRING(loadMortar);
distance = 2;
condition = QUOTE([ARR_2(_target,_player)] call FUNC(canLoadMagazine));
statement = "";
icon = "";
selection = "usti hlavne";
class GVAR(loadMagazine_HE_Guided) {
displayName = CSTRING(loadMagazine_HE_Guided);
condition = QUOTE([ARR_3(_target,_player,'ACE_1Rnd_82mm_Mo_HE_Guided')] call FUNC(canLoadMagazine));
statement = QUOTE([ARR_4(_target,_player,8,'ACE_1Rnd_82mm_Mo_HE_Guided')] call FUNC(loadMagazineTimer));
icon = "";
};
class GVAR(loadMagazine_HE_LaserGuided) {
displayName = CSTRING(loadMagazine_HE_LaserGuided);
condition = QUOTE([ARR_3(_target,_player,'ACE_1Rnd_82mm_Mo_HE_LaserGuided')] call FUNC(canLoadMagazine));
statement = QUOTE([ARR_4(_target,_player,8,'ACE_1Rnd_82mm_Mo_HE_LaserGuided')] call FUNC(loadMagazineTimer));
icon = "";
};
class GVAR(loadMagazine_Illum) {
displayName = CSTRING(loadMagazine_Illum);
condition = QUOTE([ARR_3(_target,_player,'ACE_1Rnd_82mm_Mo_Illum')] call FUNC(canLoadMagazine));
statement = QUOTE([ARR_4(_target,_player,5,'ACE_1Rnd_82mm_Mo_Illum')] call FUNC(loadMagazineTimer));
icon = "";
};
class GVAR(loadMagazine_Smoke) {
displayName = CSTRING(loadMagazine_Smoke);
condition = QUOTE([ARR_3(_target,_player,'ACE_1Rnd_82mm_Mo_Smoke')] call FUNC(canLoadMagazine));
statement = QUOTE([ARR_4(_target,_player,2.5,'ACE_1Rnd_82mm_Mo_Smoke')] call FUNC(loadMagazineTimer));
icon = "";
};
class GVAR(loadMagazine_HE) {
displayName = CSTRING(loadMagazine_HE);
condition = QUOTE([ARR_3(_target,_player,'ACE_1Rnd_82mm_Mo_HE')] call FUNC(canLoadMagazine));
statement = QUOTE([ARR_4(_target,_player,2.5,'ACE_1Rnd_82mm_Mo_HE')] call FUNC(loadMagazineTimer));
icon = "";
};
};
};
class ACE_SelfActions {
class GVAR(toggleMils) {
displayName = "Toggle MILS";

View File

@ -5,19 +5,14 @@ PREP(dev_simulateCalcRangeTableLine);
PREP(dev_simulateFindSolution);
PREP(dev_simulateShot);
PREP(canLoadMagazine);
PREP(canUnloadMagazine);
PREP(csw_getProxyWeapon);
PREP(handleFired);
PREP(handlePlayerVehicleChanged);
PREP(loadMagazine);
PREP(loadMagazineTimer);
PREP(moduleInit);
PREP(mortarInit);
PREP(rangeTableCanUse);
PREP(rangeTableOpen);
PREP(rangeTablePageChange);
PREP(rangeTablePreCalculatedValues);
PREP(toggleMils);
PREP(turretDisplayLoaded);
PREP(unloadMagazine);
PREP(unloadMagazineTimer);

View File

@ -1,22 +1,5 @@
#include "script_component.hpp"
[QGVAR(addMagazine), {
params ["_static", "_magazine"];
_static addMagazineTurret [_magazine,[0]];
}] call CBA_fnc_addEventHandler;
[QGVAR(removeMagazine), {
params ["_static", "_magazine"];
_static removeMagazineTurret [_magazine,[0]];
}] call CBA_fnc_addEventHandler;
[QGVAR(setAmmo), {
params ["_static", "_magazine","_ammoCount"];
_static setMagazineTurretAmmo [_magazine, _ammoCount, [0]];
}] call CBA_fnc_addEventHandler;
["ace_initMortar", {_this call FUNC(mortarInit);}] call CBA_fnc_addEventHandler;
if (hasInterface) then {
["ace_infoDisplayChanged", FUNC(turretDisplayLoaded)] call CBA_fnc_addEventHandler;
};
@ -25,17 +8,4 @@ if (hasInterface) then {
TRACE_1("ace_settingsInitialized",GVAR(useAmmoHandling));
["vehicle", FUNC(handlePlayerVehicleChanged), true] call CBA_fnc_addPlayerEventHandler;
if (GVAR(useAmmoHandling)) then {
["Mortar_01_base_F", "init", {
TRACE_2("mortar init",_this,(_this select 0) turretLocal [0]);
//wait for proper turret locality change
[{
TRACE_2("after delay",_this,(_this select 0) turretLocal [0]);
["ace_initMortar", _this] call CBA_fnc_localEvent;
}, _this, 0.5] call CBA_fnc_waitAndExecute;
}, true, [], true] call CBA_fnc_addClassEventHandler;
};
}] call CBA_fnc_addEventHandler;

View File

@ -7,7 +7,7 @@ class CfgPatches {
"ACE_Box_82mm_Mo_Illum","ACE_Box_82mm_Mo_Combo"};
weapons[] = {"ACE_RangeTable_82mm","ace_mortar_82mm"};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ace_interaction"};
requiredAddons[] = {"ace_csw"};
author = ECSTRING(common,ACETeam);
authors[] = {"PabstMirror","Grey","VKing"};
url = ECSTRING(main,URL);

View File

@ -1,52 +0,0 @@
#include "script_component.hpp"
/*
* Author: Grey
* Checks whether magazine can be loaded into static weapon
*
* Arguments:
* 0: static <OBJECT>
* 1: unit <OBJECT>
* 2: magazine class to check; if not given having any compatible magazine returns true <STRING> (default: "")
*
* Return Value:
* canLoadMagazine <BOOL>
*
* Example:
* [_target,_player,"ACE_1Rnd_82mm_Mo_HE"] call ace_mk6mortar_fnc_canLoadMagazine
*
* Public: Yes
*/
params ["_static","_unit",["_magazineClassOptional","",[""]]];
if !(alive _static && GVAR(useAmmoHandling)) exitWith {false};
if (_static getVariable [QGVAR(inUse), false]) exitWith {false};
private _canLoadMagazine = false;
private _hasCompatibleMagazine = false;
private _currentMagazine = (magazinesAllTurrets _static) select 1;
private _weapon = (_static weaponsTurret [0]) select 0;
private _listOfMagNames = getArray(configFile >> "cfgWeapons" >> _weapon >> "magazines");
private _count = 0;
//If function is called with an optional string then check if player has that magzine otherwise check all magazines of the player to see if they are compatible with the static weapon
if (_magazineClassOptional != "") then {
if ([_unit,_magazineClassOptional] call EFUNC(common,hasMagazine)) then {
_hasCompatibleMagazine = true;
};
} else {
{
if ([_unit,_x] call EFUNC(common,hasMagazine)) exitWith {_hasCompatibleMagazine = true};
} forEach _listOfMagNames;
};
//If static weapon has a magazine then find the ammo count
if (count (_static magazinesTurret [0]) > 0) then {
_count = _currentMagazine select 2;
};
//If the static weapon doesn't have a magzine or a magazine with no bullets, the player has a compatible magazine and the static weapon has a barrel then you can load a magazine
if ((count (_static magazinesTurret [0]) == 0 || _count == 0) && _hasCompatibleMagazine) then {
_canLoadMagazine = true;
};
_canLoadMagazine

View File

@ -1,30 +0,0 @@
#include "script_component.hpp"
/*
* Author: Grey
* Checks whether magazine can be unloaded from static weapon
*
* Arguments:
* 0: static <OBJECT>
* 1: unit <OBJECT>
*
* Return Value:
* canUnloadMagazine <BOOL>
*
* Example:
* [_target,_player] call ace_mk6mortar_fnc_canUnloadMagazine
*
* Public: Yes
*/
params ["_static","_unit"];
if !(alive _static && GVAR(useAmmoHandling) && _static getVariable [QGVAR(initialized),false]) exitWith {false};
if (_static getVariable [QGVAR(inUse), false]) exitWith {false};
private _canUnloadMagazine = false;
private _ammoCount = ((magazinesAllTurrets _static) select 1) select 2;
if (_ammoCount > 0) then {
_canUnloadMagazine = true;
};
_canUnloadMagazine

View File

@ -0,0 +1,68 @@
#include "script_component.hpp"
/*
* Author: PabstMirror
* Compatibility With ACE_CSW (will be called by ace_csw, no dependency)
* Setting Init has finished, and this runs before csw attempts to unload weapon, should replicate functionality of mk6_fnc_mortarInit
*
* Arguments:
* 0: static <OBJECT>
* 1: Turret <ARRAY>
* 2: current weapon <STRING>
* 3: need proxy weapon (either assembly mode is true, or weapon has been emptied and is being reloaded) <BOOL>
*
* Return Value:
* Proxy Weapon <STRING>
*
* Example:
* [mortar, "mortar_82mm", true] call ace_mk6mortar_fnc_csw_getProxyWeapon
*
* Public: No
*/
params ["_mortar", "_turret", "_currentWeapon", "_proxyWeaponNeeded"];
TRACE_4("csw_getProxyWeapon",_mortar,_turret,_currentWeapon,_proxyWeaponNeeded);
private _newWeapon = "";
if (_proxyWeaponNeeded || GVAR(useAmmoHandling)) then {
if (_currentWeapon != "mortar_82mm") exitWith { ERROR_2("unknown weapon [%1 - %2]",typeOf _mortar,_currentWeapon); };
// Replace weapon with fast reloading version
_newWeapon = "ace_mortar_82mm";
TRACE_1("replacing weapon",_newWeapon);
// need to convert 8rnd mags to 1rnd mags for new weapon (we need to do this so the weapon is loaded with a compatible mag)
private _magsToRemove = [];
private _convertedMags = [];
{
_x params ["_xMag", "_xTurret", "_xAmmo"];
if (_xTurret isEqualTo _turret) then {
private _replaceMag = switch (true) do {
case (_xMag == "8Rnd_82mm_Mo_shells"): {"ACE_1Rnd_82mm_Mo_HE"};
case (_xMag == "8Rnd_82mm_Mo_Smoke_white"): {"ACE_1Rnd_82mm_Mo_Smoke"};
case (_xMag == "8Rnd_82mm_Mo_Flare_white"): {"ACE_1Rnd_82mm_Mo_Illum"};
case (_xMag == "8Rnd_82mm_Mo_guided"): {"ACE_1Rnd_82mm_Mo_HE_Guided"};
case (_xMag == "8Rnd_82mm_Mo_LG"): {"ACE_1Rnd_82mm_Mo_HE_LaserGuided"};
default {""};
};
if (_replaceMag != "") then {
_magsToRemove pushBackUnique [_xMag, _xTurret];
if (!GVAR(useAmmoHandling)) then {
TRACE_3("replacing",_xMag,_replaceMag,_xAmmo);
for "_i" from 1 to _xAmmo do {
_convertedMags pushBack [_replaceMag, _xTurret, 1];
};
};
} else {
WARNING("unknown mag %1", _xMag);
};
};
} forEach (magazinesAllTurrets _mortar);
// remove orignal mags and add 1rnd versions:
{ _staticWeapon removeMagazinesTurret _x; } forEach _magsToRemove;
{ _mortar addMagazineTurret _x; } forEach _convertedMags;
};
_newWeapon

View File

@ -23,13 +23,6 @@
params ["_vehicle", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile"];
if (GVAR(useAmmoHandling) && {_vehicle getVariable [QGVAR(initialized),false] && !(_vehicle getVariable [QGVAR(exclude),false])}) then {
// if !(_vehicle getVariable [QGVAR(exclude),false]) then {
_vehicle removeMagazineGlobal (_vehicle magazinesTurret [0] select 0);
TRACE_1("",_vehicle magazinesTurret [0]);
// };
};
if (!GVAR(airResistanceEnabled)) exitWith {};
// Large enough distance to not simulate any wind deflection

View File

@ -21,20 +21,6 @@ params ["_player", "_newVehicle"];
if (isNull _newVehicle) exitWith {};
if (!(_newVehicle isKindOf "Mortar_01_base_F")) exitWith {};
// Run magazine handling initialization if enabled
if (!(_newVehicle getVariable [QGVAR(initialized),false]) && !(_newVehicle getVariable [QGVAR(exclude),false])) then {
// Make sure that mortar init is executed after settings init
[{
params ["_mortar"];
if (GVAR(useAmmoHandling) && {!(_mortar getVariable [QGVAR(initialized),false]) && !(_mortar getVariable [QGVAR(exclude),false])}) then {
//wait for proper turret locality change
[{
["ace_initMortar", [_this], [_this]] call CBA_fnc_globalEvent;
}, _mortar, 0.05] call CBA_fnc_waitAndExecute;
};
}, _newVehicle] call EFUNC(common,runAfterSettingsInit);
};
private _tubeWeaponName = (weapons _newVehicle) select 0;
private _fireModes = getArray (configFile >> "CfgWeapons" >> _tubeWeaponName >> "modes");

View File

@ -1,62 +0,0 @@
#include "script_component.hpp"
/*
* Author: Grey
* Loads Magazine into static weapon
*
* Arguments:
* 0: static <OBJECT>
* 1: unit <OBJECT>
* 2: magazine class to load; if not given the first compatible magazine is loaded <STRING> (default: "")
*
* Return Value:
* None
*
* Example:
* [_target,_player,"ACE_1Rnd_82mm_Mo_HE"] call ace_mk6mortar_fnc_loadMagazine
*
* Public: Yes
*/
params ["_static","_unit",["_magazineClassOptional","",[""]]];
//If function has been called with an optional classname hten add that magazine to the static weapon. Otherwise add the compatible magazine
if(_magazineClassOptional != "") then {
_unit removeMagazine _magazineClassOptional;
[QGVAR(addMagazine), [_static, _magazineClassOptional]] call CBA_fnc_globalEvent;
} else {
//Get weapon & magazine information of static weapon
private _weapon = (_static weaponsTurret [0]) select 0;
private _currentMagazine = (magazinesAllTurrets _static) select 1;
private _currentMagazineClass = _currentMagazine select 0;
private _count = _currentMagazine select 2;
//Check all of the players magazines to see if they are compatible with the static weapon. First magazine that is compatible is chosen
//VKing: This section ought to be double checked.
private _magazines = magazines _unit;
private _magazineDetails = magazinesDetail _unit;
private _listOfMagNames = getArray(configFile >> "cfgWeapons" >> _weapon >> "magazines");
private _magazineClass = "";
private _magazineClassDetails = "";
private _roundsLeft = 0;
{
if (_x in _listOfMagNames) exitWith {
_magazineClass = _x;
_magazineClassDetails = _magazineDetails select _forEachIndex;
};
} forEach _magazines;
//If the static weapon already has an empty magazine then remove it
if (_count == 0) then {
[QGVAR(removeMagazine), [_static, _currentMagazineClass]] call CBA_fnc_globalEvent;
};
//Find out the ammo count of the compatible magazine found
if (_magazineClassDetails != "") then{
private _parsed = _magazineClassDetails splitString "([]/: )";
_parsed params ["_type", "", "", "_roundsLeftText", "_maxRoundsText"];
_roundsLeft = parseNumber _roundsLeftText;
_magType = _type;
};
_unit removeMagazine _magazineClass;
[QGVAR(addMagazine), [_static, _magazineClass]] call CBA_fnc_globalEvent;
[QGVAR(setAmmo), [_static, _magazineClass,_roundsLeft], _static] call CBA_fnc_targetEvent;
};

View File

@ -1,30 +0,0 @@
#include "script_component.hpp"
/*
* Author: Grey
* Loads Magazine into static weapon using a timer.
*
* Arguments:
* 0: Static <OBJECT>
* 1: Unit <OBJECT>
* 2: Time to load <NUMBER>
* 3: Magazine Class <STRING> (default: "")
*
* Return Value:
* None
*
* Example:
* [_target,_player,"ACE_1Rnd_82mm_Mo_HE"] call ace_mk6mortar_fnc_loadMagazineTimer
*
* Public: Yes
*/
params ["_static","_unit","_timeToLoad",["_magazineClassOptional","",[""]]];
_static setVariable [QGVAR(inUse), true, true];
// Move player into animation if player is standing
if ((_unit call CBA_fnc_getUnitAnim) select 0 == "stand") then {
[_unit, "AmovPercMstpSrasWrflDnon_diary", 1] call EFUNC(common,doAnimation);
};
[_timeToLoad, [_static,_unit,_magazineClassOptional], {(_this select 0) call FUNC(loadMagazine); ((_this select 0) select 0) setVariable [QGVAR(inUse), nil, true]}, {((_this select 0) select 0) setVariable [QGVAR(inUse), nil, true]}, localize LSTRING(loadingMortar)] call EFUNC(common,progressBar);

View File

@ -1,46 +0,0 @@
#include "script_component.hpp"
/*
* Author: VKing
* Initializes mortar for use with ammunition handling magazines.
*
* Arguments:
* 0: Mortar <OBJECT>
*
* Return Value:
* None
*
* Example:
* [mortar1] call ace_mk6mortar_fnc_mortarInit
*
* Public: No
*/
params ["_mortar"];
if (_mortar getVariable [QGVAR(initialized),false] || _mortar getVariable [QGVAR(exclude),false]) exitWith {TRACE_1("Exit",_mortar)};
if (!(_mortar turretLocal [0])) exitWith {TRACE_1("Exit - turret not local",_mortar)};
// Remove all magazines from turret
if (count magazines _mortar > 0) then {
{
_mortar removeMagazineTurret [_x,[0]];
} forEach magazines _mortar;
};
// Replace current turret weapon with ammo handling weapon
private _currentWeapon = _mortar weaponsTurret [0] select 0;
private _newWeapon = "";
if (_currentWeapon == "mortar_82mm") then {
_newWeapon = "ace_mortar_82mm";
} else {
_newWeapon = getText (configFile >> "CfgWeapons" >> _currentWeapon >> QGVAR(replaceWith));
};
if (_newWeapon != "") then {
_mortar removeWeaponTurret [_currentWeapon,[0]];
_mortar addWeaponTurret [_newWeapon,[0]];
};
_mortar setVariable [QGVAR(initialized),true,true];
TRACE_1("Init complete",_mortar);

View File

@ -1,38 +0,0 @@
#include "script_component.hpp"
/*
* Author: Grey
*
* Unload current magazine from static weapon
*
* Arguments:
* 0: static <OBJECT>
* 1: unit <OBJECT>
*
* Return Value:
* None
*
* Example:
* [_target, _player] call ace_mk6mortar_fnc_unloadMagazine
*
* Public: Yes
*/
params ["_static","_unit"];
//Get weapon & magazine information about static weapon
private _currentMagazine = (magazinesAllTurrets _static) select 1;
private _currentMagazineClass = _currentMagazine select 0;
private _ammoCount = _currentMagazine select 2;
// Try to add the round to player inventory, otherwise place it on the ground near the player
if (_ammoCount > 0) then {
if (_unit canAdd _currentMagazineClass) then {
_unit addMagazineGlobal _currentMagazineClass;
} else {
_pos = _unit modelToWorldVisual [0.5,0.5,0]; // Front right of player
_unit = createVehicle ["WeaponHolder_Single_F",_pos,[],0,"NONE"];
_unit addMagazineAmmoCargo [_currentMagazineClass, 1, _ammoCount];
_unit setPosATL _pos;
};
[QGVAR(removeMagazine), [_static, _currentMagazineClass]] call CBA_fnc_globalEvent;
};

View File

@ -1,30 +0,0 @@
#include "script_component.hpp"
/*
* Author: Grey
*
* Unload current magazine from static weapon using a timer
*
* Arguments:
* 0: static <OBJECT>
* 1: unit <OBJECT>
* 2: time to unload <NUMBER>
*
* Return Value:
* None
*
* Example:
* [_target, _player, 5] call ace_mk6mortar_fnc_unloadMagazineTimer
*
* Public: Yes
*/
params ["_static","_unit","_timeToUnload"];
_static setVariable [QGVAR(inUse), true, true];
//Move player into animation if player is standing
if ((_unit call CBA_fnc_getUnitAnim) select 0 == "stand") then {
[_unit, "AmovPercMstpSrasWrflDnon_diary", 1] call EFUNC(common,doAnimation);
};
[_timeToUnload, [_static,_unit], {(_this select 0) call FUNC(unloadMagazine); ((_this select 0) select 0) setVariable [QGVAR(inUse), nil, true]}, {((_this select 0) select 0) setVariable [QGVAR(inUse), nil, true]}, localize LSTRING(unloadingMortar)] call EFUNC(common,progressBar);

View File

@ -13,8 +13,8 @@ class CfgVehicles {
class GVAR(CheckAmmo) {
displayName = CSTRING(checkAmmo);
distance = 2.0;
condition = QUOTE([ARR_2(_player, _target)] call FUNC(canCheckAmmo));
statement = QUOTE([ARR_2(_player, _target)] call FUNC(checkAmmo));
condition = QUOTE(call FUNC(canCheckAmmo));
statement = QUOTE(call FUNC(checkAmmo));
exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"};
};
};
@ -28,8 +28,8 @@ class CfgVehicles {
class GVAR(CheckAmmo) {
displayName = CSTRING(checkAmmo);
distance = 2.0;
condition = QUOTE([ARR_2(_player, _target)] call FUNC(canCheckAmmo));
statement = QUOTE([ARR_2(_player, _target)] call FUNC(checkAmmo));
condition = QUOTE(call FUNC(canCheckAmmo));
statement = QUOTE(call FUNC(checkAmmo));
exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"};
};
};

View File

@ -13,7 +13,7 @@ if (!hasInterface) exitWith {};
if (!isNull (ACE_controlledUAV param [0, objNull])) exitWith {false};
// Statement
[ACE_player] call FUNC(checkAmmo);
[ACE_player, ACE_player] call FUNC(checkAmmo);
true
}, {false}, [19, [false, true, false]], false] call CBA_fnc_addKeybind;

View File

@ -4,19 +4,18 @@
* Check if the player can check the ammo of the target.
*
* Arguments:
* 0: Unit <OBJECT>
* 1: Target <OBJECT>
* 0: Target <OBJECT>
*
* Return Value:
* Can link belt<BOOL>
*
* Example:
* [player, bob] call ace_reload_fnc_canCheckAmmo
* [cursorObject] call ace_reload_fnc_canCheckAmmo
*
* Public: No
*/
params ["", "_target"];
params ["_target"];
// Return true for static weapons if they have been fired once, @todo 1.40 this work-around doesn't work anymore
if (_target isKindOf "StaticWeapon") exitWith {

View File

@ -4,39 +4,25 @@
* Count the ammo of the currently loaded magazine or count rifle grenades. Play animation and display message.
*
* Arguments:
* 0: Player <OBJECT>
* 1: Target. Optional, if not suplied the player counts his personal or static weapon ammo <OBJECT>
* 0: Target. <OBJECT>
* 1: Player <OBJECT>
*
* Return Value:
* None
*
* Example:
* [bob, kevin] call ace_reload_fnc_checkAmmo
* [cursorObject, player] call ace_reload_fnc_checkAmmo
*
* Public: No
*/
#define COUNT_BARS 12
params ["_target", "_player"];
params ["_unit"];
private _target = vehicle _unit;
if (count _this > 1) then {
_target = _this select 1;
} else {
// If the unit is on foot, count it's own ammo
if (_unit == _target) exitWith {};
// If it's mounted on a movile weapon, count it's own ammo
if !(_target isKindOf "StaticWeapon") then {
_target = _unit;
if (_player == _target) then {
if ((vehicle _target) isKindOf "StaticWeapon") then {
_target = vehicle _target;
};
};
if (_unit == _target) then {
[_unit, "Gear", 1] call EFUNC(common,doGesture);
};
[FUNC(displayAmmo), [_target], 1, 0.1] call CBA_fnc_waitAndExecute;
[FUNC(displayAmmo), [_target], 1] call CBA_fnc_waitAndExecute;

View File

@ -0,0 +1,78 @@
---
layout: wiki
title: Crew Served Weapons
description: Static weapons that require multiple people to crew
group: feature
category: equipment
parent: wiki
mod: ace
version:
major: 3
minor: ?
patch: 0
---
## 1. Overview
Crew Served Weapons are static weapons that require multiple people to crew them.
### 1.1 Loading/Unloading of ammo into static weapons
Static weapons need to be manually loaded with ammo when placed down. The user can also unload ammo from static weapons, and place the ammo into their inventory for transport
### 1.2 Assembling/Disassembling of static weapons
Static weapons are assembled when a tripod is placed down, and the weapon mounted ontop. The user can then disassemble the weapon back into the tripod and weapon-bag and carry it around for the next deployment.
## 2. Usage
### 2.1 Loading Ammo
- Apporach the static weapon with the relavent ammo in your inventory
- Interact with the weapon using <kbd>&nbsp;Win</kbd> (ACE3 default) and navigate to the `CSW` menu.
- Select `Handle Ammo`
- Select `Load X` where X is the ammo you want loaded and wait for the timer to complete
### 2.2 Unloading ammo
- Apporach the static weapon and interact <kbd>&nbsp;Win</kbd> (ACE3 default)
- Navigate to the `CSW` menu
- Select `Unload Ammo` and wait for the timer to complete
- The ammo will be placed to the left of the gun
### 2.3 Assembling Weapon
- Have the tripod and the relavent weapon in your launcher slot
- Place down tripod in the self-interact menu <kbd>Ctrl</kbd> + <kbd>&nbsp;Win</kbd> (ACE3 default)
- Approach the tripod with the wanted weapon, and interact <kbd>&nbsp;Win</kbd> (ACE3 default)
- Navigate to the `CSW` menu, and select `Assemble Weapon`
- Wait for the timer to complete, and the weapon will be assembled in the direction the tripod is facing
### 2.4 Disassembling Weapon
- Approach the static weapon and interact <kbd>&nbsp;Win</kbd> (ACE3 default)
- Navigate to the `CSW` menu
- Select `Disassemble Weapon`
- Wait for the timer to complete
- The tripod, ammo, and weapon will spawn where the static weapon was
## 3. Addon Options
### 3.1 defaultAssemblyMode
- Enables/Disables the ability to assemble the CSW through the addon (Non-Vanilla assembly)
- Default: Off
### 3.2 handleExtraMagazines
- Enables/Disables the magazines in the CSW will appear next to the gun on weapon initialization when using defaultAssemblyMode and you have a pre-placed static weapon
- Default: On
### 3.3 ammoHandling
- Whether or not you want to handle ammo using the CSW way. Does nothing if using defaultAssemblyMode
- Default: On
## 4. Dependencies
{% include dependencies_list.md component="csw" %}

View File

@ -0,0 +1,142 @@
---
layout: wiki
title: Crew Served Weapons Framework
description: Explains how to add new Crew Served Weapons to ACE3
group: framework
order: 5
parent: wiki
mod: ace
version:
major: 3
minor: 13
patch: 0
---
## 1. Making a new Crew Served Weapon
### 1.1 CfgVehicles
```cpp
class CfgVehicles {
class LandVehicle;
class StaticWeapon: LandVehicle {
class ACE_Actions;
};
class StaticMGWeapon: StaticWeapon {
class Turrets {
class MainTurret;
};
class ACE_Actions: ACE_Actions {
class ACE_MainActions;
};
};
class banana_csw: StaticMGWeapon {
class ace_csw {
enabled = 1; // whether or not the weapon is affected by CSW
proxyWeapon = QGVAR(HMG_Static); // The weapon that will be added to the CSW on initialization. Used to ensure lower ammo-reload time when using Ammo Handling
magazineLocation = "_target selectionPosition 'magazine'"; // The location of the magazine. Where the action for ammo-handling will appear on the weapon
disassembleWeapon = QGVAR(staticHMGCarry); // What the weapon will disassemble to
disassembleTurret = QGVAR(m3TripodLow); // Which tripod will appear when weapon has been disassembled
ammoLoadTime = 7; // How long it takes in seconds to load ammo into the weapon
ammoUnloadTime = 5; // How long it takes in seconds to unload ammo from the weapon
disassembleFunc = "myCoolFunction.sqf"; // A callback function for when the CSW gets disassembled. Arguments: [tripod, staticWeapon]
};
};
};
```
### 1.2 CfgMagazines
```cpp
class CfgMagazines {
class 100Rnd_127x99_mag; // Example magazine used - does not have to be this
class banana_ammo: 100Rnd_127x99_mag {
scope=2; // Needs to be 2 to make sure it shows up in Arsenal
type=256; // Must be 256 to show up in Arsenal
count = 100; // How much ammo gets added per "Load Ammo" selection
model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; // default ammo box model
};
};
```
### 1.3 CfgWeapons
```cpp
class CfgWeapons {
class ace_csw_base_carry;
class banana_carry_weapon: ace_csw_base_carry {
class ace_csw_options {
assembleTo = "banana_csw"; // What the weapon will assemble into
baseTripod = "banana_tripod"; // The tripod which the weapon can be assembled onto (Default is "ace_csw_m3Tripod")
type = "weapon"; // What type of carry it is. Must always be "weapon" for the carry weapon
};
};
class HMG_Static;
class banana_weapon: HMG_Static {
class ace_csw_options {
deployTime = 10; // Time in seconds it takes to mount the weapon on the tripod
pickupTime = 12; // Time in seconds it takes to dismount the weapon from the tripod
};
magazines[] = { banana_ammo }; // You must have both the dummy and real ammunition
};
};
```
### 1.4 CfgMagazineGroups
```cpp
class ace_csw_groups { // Ammo that can be loaded into this CSW
class banana_ammo { // The magazine which will be loaded into the weapon
banana_dummy_ammo = 1; // Ammo that is loaded into the weapon as per CfgWeapons >> weapon >> magazines
};
// Optional
class ace_csw_100Rnd_127x99_mag { // default magazine that CSW already implements
banana_dummy_ammo = 1;
};
/*
Ammo types already defined by CSW:
- ace_csw_100Rnd_127x99_mag
- ace_csw_50Rnd_127x108_mag
- ace_csw_20Rnd_20mm_G_belt
- ACE_1Rnd_82mm_Mo_HE
- ACE_1Rnd_82mm_Mo_Smoke
- ACE_1Rnd_82mm_Mo_Illum
- ACE_1Rnd_82mm_Mo_HE_Guided
- ACE_1Rnd_82mm_Mo_HE_LaserGuided
- Titan_AT
- Titan_AA
*/
};
```
## 2. Making a new Tripod
### 2.1 CfgVehicles
```cpp
class CfgVehicles {
class ace_csw_baseTripod;
class banana_tripod: ace_csw_baseTripod {
class ace_csw { disassembleTo = "banana_carry_tripod"; }; // What will be spawned when "Pickup Tripod" is selected
};
};
```
### 2.2 CfgWeapons
```cpp
class CfgWeapons {
class ace_csw_base_carry;
class banana_carry_tripod: ace_csw_base_carry {
class GVAR(options) {
deployTime = 166; // How much time in seconds it takes to deploy the tripod
pickupTime = 12; // How much time in seconds it takes to pickup the tripod
type = "mount"; // What type of carry it is. Must always be "mount" for the carry tripod
deploy = "banana_tripod"; // What will be deployed when "Deploy Tripod" is selected
};
};
};
```