Firing Modes (Single shot / Burst mode / Full auto & Safety toggle)

Firing Modes

Update 17-12-2018

I will no longer be maintaining/supporting this resource. The GitHub repo has been archived. Fork it if you want to update it yourself.

This resource allows you to toggle between full automatic fire, burst fire (about 3 bullets each time) or single shot mode firing mode.
To switch between these modes, press L on your keyboard (there’s currently no controller option for this).

There’s also an implemented gun safety feature. Press K (also, keyboard only) to enable it and you won’t be able to fire your weapon.

I originally got this idea from this topic: Firing Mode (Single Shot,Burst)


Note, currently these firing modes and the safety mode only work on (S)MG’s and Rifles. Soon™ there will be an option for you to choose your own weapons that have these features enabled.


Version history

v1.0

Working features in this release

  • Press K to toggle on/off the weapon safety feature.
  • Press L to switch between firing modes (full auto, burst, single shot).
  • Disabled while in vehicles (intentional for now).
  • Current firing mode indicator below your ammo count (top right of the screen).
  • Only available on (S)MG’s and rifles.

v1.1

  • Added 3 configuration options:
    • Configure a custom key for the safety toggle.
    • Configure a custom key for the switch-firing modes button.
    • You can now disable the icon showing in the top right of your screen, indicating the current firing mode & safety toggle status.

Demo

Video Preview (File is too big to be displayed inline, so just click the link.)


Download

Click here for the latest release and the source code on GitHub.


Or if you’re lazy, download the zip file directly using the link below.

firingmode v1.0.zip (17.1 KB)

firingmode_v1.1.zip (17.7 KB)

Notes

Planned features:

  • Support for using these modes while in a vehicle.
  • Support for your own list of weapons.
  • Maybe other improvements I come across along the way.

Known Bugs

  • None atm

Configuration options for v1.1+ only, change these options in the __resource.lua file

  1. disableIcons 'false'
    Change this to ‘true’ if you want to hide/disable the icon in the top right corner of your screen.
  2. safetyToggleKey '7'
    Change the '7' to any valid control id if you want to change the “Toggle Safety Mode” button.
  3. switchFiringModeKey '311'
    Change the '311' to any valid control id if you want to change the “Switch Firing Mode” button.

Enjoy :mascot:

21 Likes

Thanks for tagging my post! Im gunna test how it works!

It works amazingly! Maybe add the message in your chat when you change modes instead of on screen.

Why in the chat instead? That’d just permanently be there when this subtitle text disappears after 3 seconds, which in my opinion is way better. Besides, if you look at the top right of your screen just near your ammo count, it’ll show your current firing mode anyway as long as you’re holding an smg/rifle :wink:

Maybe above the map? I just dont like the look it it on screen. Just my preference.

You mean notifications instead of the subtitles? That’s also an option yeah. Will probably have it as a custom setting for the next version when also adding support for custom weapons.

Quick question, where exactly would I go about changing it to having just single shot fire and safety feature, removing burst and full, once I have decompiled it.

Yea I also was looking to remove fully auto and keep single fire and safety.

I’m changing it now, I’ll let you know if this works.

1 Like

Love it!
20 characters

No need to decompile anything, just fork my GitHub repository and change whatever you need. It includes comments for every part of the code so you’ll know exactly where you’d need to change things.

1 Like

Hey man!
Awesome Script…
But i have a question, since English is not my Main language.
Can you so not maybe do a local file in the Script, where we can translate it maybe to our own language :slight_smile:

  • Cheers
1 Like

Can I use the files without building it in Visual Studio as mine is broke.

This is gunna sound stupid but I have made changes to the .cs how do I recompile it I assume visual studio?

Once I figure some of this stuff out yeah I’ll add this.

Nope you’ll need to compile it into the dll file, you can’t use the source files without compiling.

Yes you need to use Visual Studio to build/compile this.

Thank you for this release. Brilliant.

Yeah I thought so, mine gives out build errors unfortunately.

This is what I’ve got so far,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CitizenFX.Core;
using static CitizenFX.Core.Native.API;

namespace FiringModeClient
{
    public class FiringModeClient : BaseScript
    {
        #region General variables
        private bool weaponSafety = false;
        private int firemode = 0;
        List<string> automaticWeapons = new List<string>{
            "WEAPON_MICROSMG",
            "WEAPON_MACHINEPISTOL",
            "WEAPON_MINISMG",
            "WEAPON_SMG",
            "WEAPON_SMG_MK2",
            "WEAPON_ASSAULTSMG",
            "WEAPON_ASSAULTSMG",
            "WEAPON_COMBATPDW",
            "WEAPON_MG",
            "WEAPON_COMBATMG",
            "WEAPON_COMBATMG_MK2",
            "WEAPON_GUSENBERG",
            "WEAPON_ASSAULTRIFLE",
            "WEAPON_ASSAULTRIFLE_MK2",
            "WEAPON_CARBINERIFLE",
            "WEAPON_CARBINERIFLE_MK2",
            "WEAPON_ADVANCEDRIFLE",
            "WEAPON_SPECIALCARBINE",
            "WEAPON_BULLPUPRIFLE",
            "WEAPON_COMPACTRIFLE",
        };
        #endregion


        /// <summary>
        /// Constructor.
        /// </summary>
        public FiringModeClient()
        {
            Tick += OnTick;
            Tick += ShowCurrentMode;
        }

        /// <summary>
        /// OnTick async Task.
        /// </summary>
        /// <returns></returns>
        private async Task OnTick()
        {
            // Load the texture dictionary.
            if (!HasStreamedTextureDictLoaded("mpweaponsgang0"))
            {
                RequestStreamedTextureDict("mpweaponsgang0", true);
                while (!HasStreamedTextureDictLoaded("mpweaponsgang0"))
                {
                    await Delay(0);
                }
            }

            // Only run the rest of the code when the player is holding an automatic weapon.
            if (IsAutomaticWeapon(GetSelectedPedWeapon(PlayerPedId())))
            {

                // If the weapon safety feature is turned on, disable the weapon from firing.
                if (weaponSafety)
                {
                    // Disable shooting.
                    DisablePlayerFiring(PlayerId(), true);

                    // If the user tries to shoot while the safety is enabled, notify them.
                    if (IsDisabledControlJustPressed(0, 24))
                    {
                        CitizenFX.Core.UI.Screen.ShowNotification("~r~Weapon safety mode is enabled!~n~~w~Press ~y~K ~w~to switch it off.", true);
                        PlaySoundFrontend(-1, "Place_Prop_Fail", "DLC_Dmod_Prop_Editor_Sounds", false);
                    }
                }

                // If the player pressed L (7/Slowmotion Cinematic Camera Button) ON KEYBOARD ONLY(!) then switch to the next firing mode.
                if (IsInputDisabled(2) && IsControlJustPressed(0, 7))
                {
                    // Switch case for the firemode, setting it to the different options and notifying the user via a subtitle.
                    switch (firemode) {

                        // If it's currently 0, make it 1 and notify the user.
                        case 0:
                            firemode = 1;
                            CitizenFX.Core.UI.Screen.ShowSubtitle("Weapon firing mode switched to ~b~burst fire~w~.", 3000);
                            PlaySoundFrontend(-1, "Place_Prop_Success", "DLC_Dmod_Prop_Editor_Sounds", false);
                            break;

                        // If it's currently 1, make it 2 and notify the user.
                        case 1:
                            firemode = 2;
                            CitizenFX.Core.UI.Screen.ShowSubtitle("Weapon firing mode switched to ~b~single shot~w~.", 3000);
                            PlaySoundFrontend(-1, "Place_Prop_Success", "DLC_Dmod_Prop_Editor_Sounds", false);
                            break;
                        
                        // If it's currently 2 or somehow anything else, make it 0 and notify the user.
                        case 2:
                        default:
                            firemode = 0;
                            CitizenFX.Core.UI.Screen.ShowSubtitle("Weapon firing mode switched to ~b~full auto~w~.", 3000);
                            PlaySoundFrontend(-1, "Place_Prop_Success", "DLC_Dmod_Prop_Editor_Sounds", false);
                            break;
                    }
                }

                // If the player pressed K (311/Rockstar Editor Keyframe Help display button) ON KEYBOARD ONLY(!) then toggle the safety mode.
                if (IsInputDisabled(2) && IsControlJustPressed(0, 311))
                {
                    weaponSafety = !weaponSafety;
                    CitizenFX.Core.UI.Screen.ShowSubtitle("~y~Weapon safety mode ~g~" + (weaponSafety ? "~g~enabled" : "~r~disabled") + "~y~.", 3000);
                    PlaySoundFrontend(-1, "Place_Prop_Success", "DLC_Dmod_Prop_Editor_Sounds", false);
                }

                // Now on to the handling of the different firing modes.
                // (1) Burst shot firing mode
                if (firemode == 1)
                {
                    // If the player starts shooting... 
                    if (IsControlJustPressed(0, 24))
                    {
                        // ...wait 300ms(for most guns this allows about 3 bullets to be shot when holding down the trigger)
                        await Delay(300);

                        // After that, if the user is still pulling the trigger, disable shooting for the player while still allowing them to aim.
                        // As soon as the user lets go of the trigger, this while loop will be stopped and the user can pull the trigger again.
                        while (IsControlPressed(0, 24) || IsDisabledControlPressed(0, 24))
                        {
                            DisablePlayerFiring(PlayerId(), true);
                            
                            // Because we're now in a while loop, we need to add a delay to prevent the game from freezing up/crashing.
                            await Delay(0);
                        }
                    }
                }
                // (2) Single shot firing mode
                else if (firemode == 2)
                {
                    // If the player starts shooting...
                    if (IsControlJustPressed(0, 24))
                    {
                        // ...disable the weapon after the first shot and keep it disabled as long as the trigger is being pulled.
                        // once the player lets go of the trigger, the loop will stop and they can pull it again.
                        while (IsControlPressed(0, 24) || IsDisabledControlPressed(0, 24))
                        {
                            DisablePlayerFiring(PlayerId(), true);
                            
                            // Because we're now in a while loop, we need to add a delay to prevent the game from freezing up/crashing.
                            await Delay(0);
                        }
                    }
                }
                // We don't need to have a function that handles firing mode 0, since that's full auto mode and that's enabled by default anyway.
            }
        }

        /// <summary>
        /// Checks if the given weapon hash (int) is present in the weapons list defined at the top of this file.
        /// This also returns false regardless of the weapon the player has equipped, if the player is in a vehicle.
        /// Meaning the fire mode in a vehicle will always be full auto for all weapons.
        /// </summary>
        /// <param name="weaponHash"></param>
        /// <returns>true/false (bool), true if the weapon is found in the list, false if it's not.</returns>
        private bool IsAutomaticWeapon(int weaponHash)
        {
            if (IsPedInAnyVehicle(PlayerPedId(), false))
            {
                return false;
            }
            else
            { 
                foreach (string weapon in automaticWeapons)
                {
                    if (GetHashKey(weapon) == weaponHash)
                    {
                        return true;
                    }
                }
                return false;
            }
        }

        /// <summary>
        /// Used to draw text ont the screen on the specified x,y
        /// </summary>
        /// <param name="text"></param>
        /// <param name="posx"></param>
        /// <param name="posy"></param>
        private void ShowText(string text, float posx, float posy)
        {
            SetTextFont(4);
            SetTextScale(0.0f, 0.31f);
            SetTextJustification(1);
            SetTextColour(250, 250, 120, 255);
            SetTextDropshadow(1, 255, 255, 255, 255);
            SetTextEdge(1, 0, 0, 0, 205);
            BeginTextCommandDisplayText("STRING");
            AddTextComponentSubstringPlayerName(text);
            EndTextCommandDisplayText(posx, posy);
        }

        /// <summary>
        /// Show the current firing mode visually just below the ammo count.
        /// Called every frame.
        /// </summary>
        private async Task ShowCurrentMode()
        {
            // Just add a wait in here when it's not being displayed, to remove the async warnings. 
            if (!IsAutomaticWeapon(GetSelectedPedWeapon(PlayerPedId())))
            {
                await Delay(0);
            }
            // If the weapon is a valid weapon that has different firing modes, then this will be shown.
            else
            {
                if (weaponSafety)
                {
                    ShowText(" ~r~X", 0.975f, 0.065f);
                }
                else
                {
                    switch (firemode)
                    {
                        case 1:
                            ShowText("||", 0.975f, 0.065f);
                            break;
                        case 2:
                            ShowText("|", 0.975f, 0.065f);
                            break;
                        case 0:
                        default:
                            ShowText("|||", 0.975f, 0.065f);
                            break;
                    }
                }
                DrawSprite("mpweaponsgang0", "w_ar_carbinerifle_mag1", 0.975f, 0.06f, 0.099f, 0.099f, 0.0f, 200, 200, 200, 255);
            }
        }
    }
}

I’m just trying to figure out how to set it so the default firing mode as single shot and have the safety mode on all guns.

So is there a way to set it to single shot by default? :confused:

Yes, but I am having compiling issues.

1 Like