diff --git a/addons/humor/$PBOPREFIX$ b/addons/humor/$PBOPREFIX$
new file mode 100644
index 0000000..429d822
--- /dev/null
+++ b/addons/humor/$PBOPREFIX$
@@ -0,0 +1 @@
+cnto\additions\humor
\ No newline at end of file
diff --git a/addons/humor/$PREFIX$ b/addons/humor/$PREFIX$
new file mode 100644
index 0000000..429d822
--- /dev/null
+++ b/addons/humor/$PREFIX$
@@ -0,0 +1 @@
+cnto\additions\humor
\ No newline at end of file
diff --git a/addons/humor/yeetgun/cnto_hgun_Pistol_Yeetgun.paa b/addons/humor/yeetgun/cnto_hgun_Pistol_Yeetgun.paa
new file mode 100644
index 0000000..a79e579
Binary files /dev/null and b/addons/humor/yeetgun/cnto_hgun_Pistol_Yeetgun.paa differ
diff --git a/addons/humor/yeetgun/cnto_hgun_Pistol_Yeetgun_shot.wss b/addons/humor/yeetgun/cnto_hgun_Pistol_Yeetgun_shot.wss
new file mode 100644
index 0000000..c28b68d
Binary files /dev/null and b/addons/humor/yeetgun/cnto_hgun_Pistol_Yeetgun_shot.wss differ
diff --git a/addons/humor/yeetgun/config.cpp b/addons/humor/yeetgun/config.cpp
new file mode 100644
index 0000000..a155596
--- /dev/null
+++ b/addons/humor/yeetgun/config.cpp
@@ -0,0 +1,117 @@
+class CfgPatches
+{
+ class cnto_humor_yeetgun
+ {
+ units[] = {};
+ weapons[] = {"cnto_hgun_Pistol_Yeetgun"};
+ requiredAddons[] = {
+ "A3_Weapons_F_Pistols_Pistol_Heavy_02",
+ "A3_Weapons_F",
+ "A3_Sounds_F",
+ "A3_Sounds_F_Enoch"
+ };
+ };
+};
+
+class CfgFunctions
+{
+ class cnto_humor_yeetgun
+ {
+ class all
+ {
+ file = "cnto\additions\humor\yeetgun";
+ class yeetGunFired;
+ }
+ };
+};
+
+class Mode_SemiAuto;
+class CfgWeapons
+{
+ class hgun_Pistol_heavy_02_F;
+ class cnto_hgun_Pistol_Yeetgun: hgun_Pistol_heavy_02_F
+ {
+ author = "Seb";
+ baseWeapon = "cnto_hgun_Pistol_Yeetgun";
+ picture = "\A3\Weapons_F_EPA\Pistols\Pistol_Heavy_02\data\UI\gear_Pistol_heavy_02_X_CA.paa";
+ magazines[] = {"cnto_Yeetgun_Cannister"};
+ magazineWell[] = {""};
+ displayname = "The Yeet Gun™";
+ descriptionShort = "Handgun..?
Caliber: Air";
+ hiddenSelectionsTextures[] = {"\cnto\additions\humor\yeetgun\cnto_hgun_Pistol_Yeetgun","\A3\Weapons_F_EPA\Pistols\Pistol_Heavy_02\data\Pistol_Heavy_02_mag_co"};
+ class Library
+ {
+ libTextDesc = "Nobody is really sure how this works. The inventor was killed when this weapon was fired for the first time as his house collapsed in on him. RIP big G.";
+ };
+ class EventHandlers
+ {
+ fired = "_this call cnto_humor_yeetgun_fnc_yeetGunFired";
+ };
+ class Single: Mode_SemiAuto
+ {
+ class BaseSoundModeType;
+ class StandardSound: BaseSoundModeType
+ {
+ soundSetShot[] = {"cnto_Yeetgun_Shot_SoundSet","Zubr_Tail_SoundSet","Zubr_InteriorTail_SoundSet"};
+ };
+ class SilencedSound: BaseSoundModeType
+ {
+ };
+ };
+ };
+};
+
+class CfgMagazines
+{
+ class 6Rnd_45ACP_Cylinder;
+ class cnto_Yeetgun_Cannister: 6Rnd_45ACP_Cylinder
+ {
+ author = "Seb";
+ displayName = "CNTO Certified Yeetgun Cannister";
+ descriptionShort = "Caliber: Air
Rounds: 6
Used in: The Yeet Gun™";
+ ammo = "cnto_Yeetgun_Round";
+ };
+};
+
+
+class CfgAmmo
+{
+ class B_45ACP_Ball;
+ class cnto_Yeetgun_Round: B_45ACP_Ball
+ {
+ };
+};
+
+class CfgSoundSets
+{
+ class Pistol_Shot_Base_SoundSet;
+ class cnto_Yeetgun_Shot_SoundSet: Pistol_Shot_Base_SoundSet
+ {
+ soundShaders[] = {"Zubr_Closure_SoundShader","cnto_Yeetgun_closeShot_SoundShader","cnto_Yeetgun_midShot_SoundShader","cnto_Yeetgun_distShot_SoundShader"};
+ };
+};
+
+class CfgSoundShaders
+{
+ class cnto_Yeetgun_closeShot_SoundShader
+ {
+ samples[] = {{"\cnto\additions\humor\yeetgun\cnto_hgun_Pistol_Yeetgun_shot",1}};
+ volume = 0.8;
+ range = 50;
+ rangeCurve = "closeShotCurve";
+ };
+ class cnto_Yeetgun_midShot_SoundShader
+ {
+ samples[] = {{"\cnto\additions\humor\yeetgun\cnto_hgun_Pistol_Yeetgun_shot",1}};
+ volume = 0.707946;
+ range = 1200;
+ rangeCurve[] = {{0,0.2},{50,1},{150,0},{1200,0}};
+ };
+ class cnto_Yeetgun_distShot_SoundShader
+ {
+ samples[] = {{"\cnto\additions\humor\yeetgun\cnto_hgun_Pistol_Yeetgun_shot",1}};
+ volume = 1;
+ range = 1200;
+ rangeCurve[] = {{0,0},{50,0},{150,1},{1200,1}};
+ };
+};
diff --git a/addons/humor/yeetgun/fn_yeetGunFired.sqf b/addons/humor/yeetgun/fn_yeetGunFired.sqf
new file mode 100644
index 0000000..fbf4c8e
--- /dev/null
+++ b/addons/humor/yeetgun/fn_yeetGunFired.sqf
@@ -0,0 +1,95 @@
+params ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_gunner"];
+private _barrelPos = eyePos _unit;
+if (local _unit) then {
+ // Shitty hack for 0 damage bullets, as AI refuse to shoot 0 damage ammo.
+ deleteVehicle _projectile;
+};
+private _range = 85;
+private _pressureBase = 13500; // Wind pressure of 335mph wind
+private _barrelFOV = 45;
+private _nearby = nearestObjects [_unit, ["Static", "CAManBase", "AllVehicles"], _range] - [_unit];
+private _weaponDirVec = _unit weaponDirection currentWeapon _unit;
+{
+ private _target = _x;
+ if !(local _target) then {continue};
+ private _vectorDirTo = _barrelPos vectorFromTo getPosWorld _target;
+ private _distanceToTarget = _target distance _unit;
+ private _distanceCoef = 0 max (1 - _distanceToTarget/_range);
+ private _weaponDirTo = (_vectorDirTo vectorDiff _weaponDirVec);
+ private _weaponDirToMagnitude = vectorMagnitude _weaponDirTo;
+ private _effectiveAngle = deg pi*_weaponDirToMagnitude/2;
+ private _angle = _barrelFOV min _effectiveAngle;
+ private _angleCoef = 1 - (_angle/_barrelFOV);
+ if (_distanceCoef == 0 || _angleCoef == 0) then {continue};
+
+ // Visiblity check
+ private _bbr = 0 boundingBoxReal _target;
+ private _p1 = _bbr select 0;
+ private _p2 = _bbr select 1;
+ private _canHit = false;
+ // Checks the 8 bounding box points to see if any part of the object is visible. Horrible, right?
+ for "_i" from 0 to 1 do {
+ private _posX = [_p1#0, _p2#0]#_i;
+ for "_j" from 0 to 1 do {
+ private _posY = [_p1#1, _p2#1]#_j;
+ for "_k" from 0 to 1 do {
+ private _posZ = [_p1#2, _p2#2]#_k;
+ private _pos = AGLtoASL (_target modelToWorld [_posX, _posY, _posZ]);
+ if !(lineIntersects [_barrelPos, _pos, _unit, _target]) exitWith {_canHit = true}
+ };
+ if (_canHit) exitWith {}
+ };
+ if (_canHit) exitWith {};
+ };
+ if !(_canHit) then {continue};
+
+ private _case = ["Static", "CAManBase", "AllVehicles"] findIf {_target isKindOf _x};
+ switch (_case) do {
+ case 0: {
+ // Terrain objects are always local, this fixes that!
+ if !(isServer) then {continue};
+ _damageDealt = 1 * _angleCoef * _distanceCoef;
+ _target setDamage (damage _target + _damageDealt);
+ };
+ case 1: {
+ private _targetArea = 0.75;
+ private _pressure = _pressureBase * _distanceCoef * _angleCoef;
+ private _force = _pressure * _targetArea;
+ private _forceVector = _vectorDirTo vectorMultiply _force;
+ _target addForce [_forceVector, [0, 0, 0]];
+ [_target, {
+ params ["_target"];
+ sleep 7;
+ waitUntil {speed _target < 1};
+ _target setUnconscious false;
+ }] remoteExec ["spawn"];
+ };
+ case 2: {
+ private _maxWidth = abs ((_p2 select 0) - (_p1 select 0));
+ private _maxLength = abs ((_p2 select 1) - (_p1 select 1));
+ private _maxHeight = abs ((_p2 select 2) - (_p1 select 2));
+ private _targetArea = _maxWidth * _maxHeight + _maxLength * _maxHeight;
+ private _pressure = _pressureBase * _distanceCoef * _angleCoef;
+ private _force = _pressure * _targetArea;
+ if (_force != 0) then {
+ private _forceVector = _vectorDirTo vectorMultiply _force;
+ _target addForce [_forceVector, [0, 0, 0]];
+ };
+ };
+ };
+} forEach _nearby;
+
+// Smonk
+private _direction = getDir _unit;
+private _particleDirection = [[0, 25, 3], _direction, 2] call BIS_fnc_rotateVector3D;
+private _particleDirectionRandom = [[4, 5, 1], _direction, 2] call BIS_fnc_rotateVector3D;
+private _emitter = "#particleSource" createVehicleLocal ASLtoAGL _barrelPos;
+_emitter setParticleParams [["\A3\data_f\ParticleEffects\Universal\Universal.p3d",16,12,13,0],"","Billboard",1,15,[0,5,0],_particleDirection,0,0.15,0.03,0.075,[13,10],[[0.1,0.067,0.052,0.147318],[0.6,0.5,0.4,0.0966888],[0.6,0.5,0.4,0.0730617],[0.6,0.5,0.4,0.0460592],[0.6,0.5,0.4,0.0190566],[0.6,0.5,0.4,0]],[25,0,0,0],0,0,"","","",0,false,0,[[0,0,0,0]]];
+_emitter setParticleRandom [5,[0,3,0],_particleDirectionRandom,20,0.3,[0,0,0,0],0,0,0,0];
+_emitter setParticleCircle [5,[3,3,0]];
+_emitter setParticleFire [0,0,0];
+_emitter setDropInterval 0.01;
+_emitter spawn {
+ sleep ((random 0.2) + 0.1);
+ deleteVehicle _this;
+};