Skip to content

Commit

Permalink
add disposable launcher framework (#1116)
Browse files Browse the repository at this point in the history
* add disposable launcher framework

* fix and simplify launcher dummy magazine

* rename 2doptics to optics

* rename 2doptics to optics

* add disposable component

* disposable arsenal handling

* fix a bug

* replace with used launcher script

* auto drop launcher

* disable secondary weapon magazine slot for disposable launchers

* disable secondary weapon magazine slot for disposable launchers

* fix a thing, delete unused

* fix addWeapon leeching magazines

* simplify setUnitLoadout

* cba_optics_fnc_addWeapon

* cba_optics_fnc_addWeapon

* optimize and keep weapon mode when toggling to pip / normal weapon with optic

* report mags of all muzzles

* replace loaded launcher mags with loaded launchers

* add shared function CBA_fnc_addWeaponWithoutMagazines

* add shared function CBA_fnc_addWeaponWithoutItems

* add launcher mags and attachments to dropped container

* handle prequipped backpacks

* handle prequipped backpacks stored themselves in cargo

* handle prequipped backpacks stored themselves in cargo

* drop used launcher setting

* handle Arsenal

* fix a problem with backpacks

* support for vehicle optics

* global to disable mag replacement
  • Loading branch information
commy2 committed Apr 27, 2019
1 parent e34dda3 commit e5c0eb4
Show file tree
Hide file tree
Showing 35 changed files with 635 additions and 72 deletions.
1 change: 1 addition & 0 deletions addons/common/CfgFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class CfgFunctions {

class Inventory {
PATHTO_FNC(addWeapon);
PATHTO_FNC(addWeaponWithoutItems);
PATHTO_FNC(addMagazine);
PATHTO_FNC(addItem);
PATHTO_FNC(compatibleMagazines);
Expand Down
81 changes: 81 additions & 0 deletions addons/common/fnc_addWeaponWithoutItems.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include "script_component.hpp"
/* ----------------------------------------------------------------------------
Function: CBA_fnc_addWeaponWithoutItems
Description:
Adds weapon to unit without attachments and without taking a magazine.
Does not work on vehicles.
Attempts to keep magazine ids for unrelated magazines.
Parameters:
_unit - Unit to add the weapon to <OBEJCT>
_weapon - Weapon to add <STRING>
Returns:
Nothing.
Examples:
(begin example)
[player, "arifle_mx_F"] CBA_fnc_addWeaponWithoutItems;
(end)
Author:
commy2
---------------------------------------------------------------------------- */

params ["_unit", "_weapon"];

// config case
private _compatibleMagazines = [_weapon, true] call CBA_fnc_compatibleMagazines;

private _uniform = uniformContainer _unit;
private _uniformMagazines = magazinesAmmoCargo _uniform select {
(_x select 0) in _compatibleMagazines // also config case
};

private _vest = vestContainer _unit;
private _vestMagazines = magazinesAmmoCargo _vest select {
(_x select 0) in _compatibleMagazines
};

private _backpack = backpackContainer _unit;
private _backpackMagazines = magazinesAmmoCargo _backpack select {
(_x select 0) in _compatibleMagazines
};

{
_unit removeMagazines _x;
} forEach _compatibleMagazines;

_unit addWeapon _weapon;

if (primaryWeapon _unit == _weapon) then {
removeAllPrimaryWeaponItems _unit;
};

if (secondaryWeapon _unit == _weapon) then {
// 'removeAllSecondaryWeaponItems' does not exist
{
_unit removeSecondaryWeaponItem _x;
} forEach secondaryWeaponItems _unit;
};

if (handgunWeapon _unit == _weapon) then {
removeAllHandgunItems _unit;
};

{
_x params ["_magazine", "_ammo"];
_uniform addMagazineAmmoCargo [_magazine, 1, _ammo];
} forEach _uniformMagazines;

{
_x params ["_magazine", "_ammo"];
_vest addMagazineAmmoCargo [_magazine, 1, _ammo];
} forEach _vestMagazines;

{
_x params ["_magazine", "_ammo"];
_backpack addMagazineAmmoCargo [_magazine, 1, _ammo];
} forEach _backpackMagazines;
6 changes: 6 additions & 0 deletions addons/common/stringtable.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,11 @@
<Japanese>ミッションを開始しておく必要があります。</Japanese>
<Italian>Prima deve far partire una missione.</Italian>
</Key>
<Key ID="STR_cba_common_WeaponsCategory">
<English>CBA Weapons</English>
<German>CBA Waffen</German>
<Polish>CBA Bronie</Polish>
<Italian>Armi CBA</Italian>
</Key>
</Package>
</Project>
1 change: 1 addition & 0 deletions addons/disposable/$PBOPREFIX$
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x\cba\addons\disposable
1 change: 1 addition & 0 deletions addons/disposable/CfgDisposableLaunchers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class CBA_DisposableLaunchers {};
17 changes: 17 additions & 0 deletions addons/disposable/CfgEventHandlers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
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_DisplayLoad_EventHandlers {
class RscDisplayInventory {
ADDON = QUOTE(_this call (uiNamespace getVariable 'FUNC(initDisplayInventory)'));
};
};
7 changes: 7 additions & 0 deletions addons/disposable/CfgFunctions.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class CfgFunctions {
class CBA {
class Weapons {
PATHTO_FNC(firedDisposable);
};
};
};
9 changes: 9 additions & 0 deletions addons/disposable/CfgMagazines.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class CfgMagazines {
class CA_LauncherMagazine;
class CBA_FakeLauncherMagazine: CA_LauncherMagazine {
scope = 1;
ammo = "RocketBase";
count = 0;
allowedSlots[] = {};
};
};
2 changes: 2 additions & 0 deletions addons/disposable/XEH_PREP.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
PREP(replaceMagazineCargo);
PREP(changeDisposableLauncherClass);
54 changes: 54 additions & 0 deletions addons/disposable/XEH_preInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "script_component.hpp"

ADDON = false;

#include "initSettings.sqf"

if (configProperties [configFile >> "CBA_DisposableLaunchers"] isEqualTo []) exitWith {};

#include "XEH_PREP.sqf"

["loadout", {
params ["_unit"];
_unit call FUNC(changeDisposableLauncherClass);
}] call CBA_fnc_addPlayerEventHandler;

["CAManBase", "InitPost", {
params ["_unit"];
_unit call FUNC(changeDisposableLauncherClass);
}] call CBA_fnc_addClassEventHandler;

["CAManBase", "Take", {
params ["_unit"];
_unit call FUNC(changeDisposableLauncherClass);
}] call CBA_fnc_addClassEventHandler;

GVAR(NormalLaunchers) = [] call CBA_fnc_createNamespace;
GVAR(LoadedLaunchers) = [] call CBA_fnc_createNamespace;
GVAR(UsedLaunchers) = [] call CBA_fnc_createNamespace;
GVAR(magazines) = [];
GVAR(MagazineLaunchers) = [] call CBA_fnc_createNamespace;

private _cfgWeapons = configFile >> "CfgWeapons";
private _cfgMagazines = configFile >> "CfgMagazines";

{
private _launcher = configName _x;
private _magazine = configName (_cfgMagazines >> (getArray (_cfgWeapons >> _launcher >> "magazines") select 0));
getArray _x params ["_loadedLauncher", "_usedLauncher"];

GVAR(LoadedLaunchers) setVariable [_launcher, _loadedLauncher];
GVAR(UsedLaunchers) setVariable [_launcher, _usedLauncher];

if (isNil {GVAR(NormalLaunchers) getVariable _loadedLauncher}) then {
GVAR(NormalLaunchers) setVariable [_loadedLauncher, [_launcher, _magazine]];
};

if (GVAR(magazines) pushBackUnique _magazine != -1) then {
GVAR(MagazineLaunchers) setVariable [_magazine, _loadedLauncher];
};
} forEach configProperties [configFile >> "CBA_DisposableLaunchers", "isArray _x"];

["All", "InitPost", FUNC(replaceMagazineCargo)] call CBA_fnc_addClassEventHandler;

ADDON = true;
8 changes: 8 additions & 0 deletions addons/disposable/XEH_preStart.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "script_component.hpp"

// Do not move this below these checks, or this missing function can be exploited.
PREP(initDisplayInventory);

if (configProperties [configFile >> "CBA_DisposableLaunchers"] isEqualTo []) exitWith {};

#include "XEH_PREP.sqf"
20 changes: 20 additions & 0 deletions addons/disposable/config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "script_component.hpp"

class CfgPatches {
class ADDON {
author = "$STR_CBA_Author";
name = CSTRING(component);
url = "$STR_CBA_URL";
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"cba_common","cba_events"};
version = VERSION;
authors[] = {"commy2"};
};
};

#include "CfgEventHandlers.hpp"
#include "CfgFunctions.hpp"
#include "CfgDisposableLaunchers.hpp"
#include "CfgMagazines.hpp"
47 changes: 47 additions & 0 deletions addons/disposable/fnc_changeDisposableLauncherClass.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "script_component.hpp"
/* ----------------------------------------------------------------------------
Internal Function: cba_disposable_fnc_changeDisposableLauncherClass
Description:
Switch loaded launcher class to class that can be fired with magazine.
Parameters:
_unit - The avatar <OBJECT>
Returns:
Nothing.
Examples:
(begin example)
player call cba_disposable_fnc_changeDisposableLauncherClass;
(end)
Author:
commy2
---------------------------------------------------------------------------- */

params ["_unit"];
if (!local _unit) exitWith {};

private _launcher = GVAR(NormalLaunchers) getVariable secondaryWeapon _unit;

if (!isNil "_launcher") then {
_launcher params ["_launcher", "_magazine"];

private _launcherItems = secondaryWeaponItems _unit;
private _launcherMagazines = WEAPON_MAGAZINES(_unit,secondaryWeapon _unit);

if (!isNil "_magazine") then {
_launcherMagazines pushBack _magazine;
};

[_unit, _launcher] call CBA_fnc_addWeaponWithoutItems;

{
_unit addSecondaryWeaponItem _x;
} forEach _launcherItems;

{
_unit addWeaponItem [_launcher, _x];
} forEach _launcherMagazines;
};
121 changes: 121 additions & 0 deletions addons/disposable/fnc_firedDisposable.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#include "script_component.hpp"
/* ----------------------------------------------------------------------------
Function: CBA_fnc_firedDisposable
Description:
Handles firing a disposable weapon.
Parameters:
_unit - Unit that fired the disposable weapon <OBEJCT>
_launcher - Disposable weapon <STRING>
_muzzle - Muzzle fired by the disposable weapon <STRING>
_mode - Current weapon mode of the disposable weapon <STRING>
_ammo - Ammo fired by the disposable weapon <STRING>
_magazine - Current magazine of the disposable weapon <STRING>
_projectile - Fired projectile <OBEJCT>
_unit - Always same as element 0 <OBEJCT>
Returns:
Nothing.
Examples:
(begin example)
class EventHandlers {
fired = "_this call CBA_fnc_firedDisposable";
};
(end)
Author:
commy2
---------------------------------------------------------------------------- */

params ["_unit", "_launcher", "_muzzle", "", "", "", "_projectile"];

private _usedLauncher = GVAR(UsedLaunchers) getVariable _launcher;
if (isNil "_usedLauncher") exitWith {};

[{
params ["_unit", "_launcher", "_usedLauncher", "_projectile"];

// switch to used tube
if (local _unit) then {
private _isSelected = currentWeapon _unit == _launcher;

private _launcherItems = secondaryWeaponItems _unit;
private _launcherMagazines = WEAPON_MAGAZINES(_unit,secondaryWeapon _unit);

[_unit, _usedLauncher] call CBA_fnc_addWeaponWithoutItems;

if (_isSelected) then {
_unit selectWeapon _usedLauncher;
};

{
_unit addSecondaryWeaponItem _x;
} forEach _launcherItems;

{
_unit addWeaponItem [_usedLauncher, _x];
} forEach _launcherMagazines;
};

// automatically drop
if (GVAR(dropUsedLauncher) isEqualTo 0) exitWith {};

[{
params ["_unit", "_usedLauncher", "_projectile"];

// quit if dead or weapon is gone
if (!alive _unit || secondaryWeapon _unit != _usedLauncher) exitWith {true};

if (local _unit && {
if (_unit == call CBA_fnc_currentUnit) then {
cameraView != "GUNNER"
} else {
isNull _projectile
};
}) exitWith {
if (GVAR(dropUsedLauncher) isEqualTo 1 && {_unit == call CBA_fnc_currentUnit}) exitWith {true};

private _launcherItems = secondaryWeaponItems _unit;
private _launcherMagazines = WEAPON_MAGAZINES(_unit,secondaryWeapon _unit);

_unit removeWeapon _usedLauncher;

private _dir = getDir _unit - 180;

private _container = createVehicle ["WeaponHolderSimulated", [0,0,0], [], 0, "CAN_COLLIDE"];
_container addWeaponCargoGlobal [_usedLauncher, 1];

_container setDir (_dir + 90);
_container setPosASL AGLToASL (_unit modelToWorld (_unit selectionPosition "rightshoulder" vectorAdd [0, 0.2, 0.1]));
_container setVelocity (velocity _unit vectorAdd ([sin _dir, cos _dir, 0] vectorMultiply 1.5));

/*
_container addWeaponWithAttachmentsCargoGlobal [
_usedLauncher,
_silencer, _pointer, _optic, _bipod, [
_magazine1, _ammo1,
_magazine2, _ammo2
],
1];
*/

{
_container addItemCargoGlobal [_x, 1];
} forEach _launcherItems;

{
_x params ["_magazine", "_ammo"];

if (_ammo > 0) then {
_container addMagazineAmmoCargo [_x, 1, _ammo];
};
} forEach _launcherMagazines;

true // quit
};

false // continue
}, {}, [_unit, _usedLauncher, _projectile]] call CBA_fnc_waitUntilAndExecute;
}, [_unit, _launcher, _usedLauncher, _projectile], 1] call CBA_fnc_waitAndExecute;
Loading

0 comments on commit e5c0eb4

Please sign in to comment.