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; +};