Getting Weapon Id That a Player is Holding.

I am currently making a gamemode where players start with common weapons. To upgrade the weapons to a higher rarity, you have to use a machine, similar to like a pack a punch. I have so many weapons available inside the gamemode that using a conditional button for each weapon and each rarity would more than likely use too much rarity. Is there a way I can get the name of the item a player is holding and then through verse code, give the player the ugraded version of it.

Example: If it detects the player is holding Assault Rifle L1, then it gives them Assault Rifle L2, so on.

Hey @Overseeing_Industry how are you?

First of all, I want to clarify that you cannot access to player’s inventory or equipped weapons, so you will need to create a way to identify that through verse with different resources.

They way I chose to do it is to create some tracker variables (maps) to assign values to the player such as the type and rarity of the last weapon obtained.

Let me show you how to do it:

  1. First of all, you will need to create a new verse file called “utils” and paste this code in it:
using { /Verse.org/Simulation }
using { /Verse.org/Random }

# Code from Unreal documentation
(Listenable : listenable(agent)).SubscribeAgent(OutputFunc : tuple(agent, t)->void, ExtraData : t where t:type) : cancelable =
    Wrapper := wrapper_agent(t){ExtraData := ExtraData, OutputFunc := OutputFunc}
    Listenable.Subscribe(Wrapper.InputFunc)

wrapper_agent(t : type) := class():
    ExtraData : t;
    OutputFunc : tuple(agent, t) -> void
    InputFunc(Agent : agent):void = OutputFunc(Agent, ExtraData)

(Listenable : listenable(tuple())).SubscribeEmpty(OutputFunc : t -> void, ExtraData : t where t:type) : cancelable =
    Wrapper := wrapper_empty(t) {ExtraData := ExtraData, OutputFunc := OutputFunc}
    Listenable.Subscribe(Wrapper.InputFunc)

wrapper_empty(t : type) := class():
    ExtraData : t;
    OutputFunc : t -> void
    InputFunc():void = OutputFunc(ExtraData)

This code will allow you to use the “SubscribeAgent” wrapper, which makes possible to add a value to the normal “Subscribe” (you will see this in a moment).

  1. Now you need to create a new custom device and paste the following code in it:

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

# A Verse-authored creative device that can be placed in a level
Weapon_Escalation := class(creative_device):

    # List of available weapon types (Rifle and Shotgun)
    var WeaponTypes : []string = array{"Rifle", "Shotgun"}
    
    # Maps to store the type of weapon and its rarity for each player (agent)
    var PlayerWeaponType : [agent]string = map{}
    var PlayerWeaponRarity : [agent]int = map{}

    # Editable properties that allow setting item granter devices for rifles and shotguns
    @editable
    var RifleGranters : []item_granter_device = array{}
    @editable
    var ShotgunGranters : []item_granter_device = array{}

    
    # This function is called when the device is started in a running game
    OnBegin<override>()<suspends>:void=

        # Subscribe to the item granted event for each RifleGranter
        for(X := 0..RifleGranters.Length - 1):
            if(RifleGranter := RifleGranters[X]):
                RifleGranter.ItemGrantedEvent.SubscribeAgent(OnRifleGranted, X)

        # Subscribe to the item granted event for each ShotgunGranter
        for(X := 0..ShotgunGranters.Length - 1):
            if(ShotgunGranter := ShotgunGranters[X]):
                ShotgunGranter.ItemGrantedEvent.SubscribeAgent(OnShotgunGranted, X)


    # Grants the next weapon to a player (agent) based on the weapon they are currently equipped with
    GrantNextWeapon(Agent:agent):void=
        CheckEquipedWeapon(Agent)
    
    # This function checks the currently equipped weapon type and rarity for the given agent
    CheckEquipedWeapon(Agent:agent):void=
        # Retrieve the player's current weapon type and rarity
        if(CurrentWeaponType : string = PlayerWeaponType[Agent]):
            if(CurrentWeaponRarity : int = PlayerWeaponRarity[Agent]):
                
                # Based on the current weapon type, grant the next weapon with higher rarity
                case ( CurrentWeaponType ):
                    "Rifle" => GrantWeapon(Agent, "Rifle", CurrentWeaponRarity, RifleGranters)
                    "Shotgun" => GrantWeapon(Agent, "Shotgun", CurrentWeaponRarity, ShotgunGranters)
                    _ => {} # Do nothing for other weapon types

    # Grants a new weapon to the agent based on their current weapon's rarity (+1)
    GrantWeapon(Agent : agent, CurrentType: string, CurrentRarity : int, GranterDevices : []item_granter_device):void=
        # Check if the next rarity level exists within the available granter devices
        if(CurrentRarity < GranterDevices.Length):
            # Increase the rarity by 1
            NewWeaponRarity := 1 + CurrentRarity
            
            # Grant the item using the granter device for the new rarity level
            if(WeaponGranter := GranterDevices[NewWeaponRarity]):
                WeaponGranter.GrantItem(Agent)
    
    # This function is called when a Rifle is granted to the player, and updates the player's weapon type and rarity
    OnRifleGranted(Agent:agent, Rarity : int):void=
        # Update the player's weapon type and rarity to "Rifle" and the given rarity
        if(set PlayerWeaponType[Agent] = "Rifle"):
        if(set PlayerWeaponRarity[Agent] = Rarity):

    # This function is called when a Shotgun is granted to the player, and updates the player's weapon type and rarity
    OnShotgunGranted(Agent:agent, Rarity : int):void=
        # Update the player's weapon type and rarity to "Shotgun" and the given rarity
        if(set PlayerWeaponType[Agent] = "Shotgun"):
        if(set PlayerWeaponRarity[Agent] = Rarity):

The code is full of comments that will let you know how it works, but let me explain!

First of all, you need a list of the weapon types you want to implement, in my case I used Rifles and Shotguns. Then you need to create two maps to track which Type and Rarity belongs to the current equipped weapon.

The way to grant weapons will be ONLY by using Item Granters, and those granters will be separated in as many arrays as weapon types you want on your island (in my case, two arrays, one for Rifles and one for Shotguns). As an additional comment for this, it is REALLY important to put those Item Granters in the correct order when assigning them to your device, as its order in the array should match the increment in rarity.

Then, you want to use the SubscribeAgent I mentioned to subscribe to all your Item Granters “ItemGrantedEvent” events. Here we use the structure “X := 0..RifleGranters.Length - 1” instead of “RifleGranter : RifleGranters” because we will want to use the X to know the index of that specific Item Granter later on the code.

And then you only need the functions shown in the code above to make it work!

Keep in mind that you can add as many weapon types as you want, as long as you add them to the WeaponTypes array, the item granters array, you subscribe to those new granters in the OnBegin, you add the corresponding line to the case in CheckEquipedWeapon function, and you create a function On*****Granted (where ***** is the new type’s name) copy of OnRifleGranted or OnShotgunGranted.

The last thing to clarify, is that you will need to be sure that every time you grant a weapon to the player, you should grant it by using one of the registered Item Granters instead of using a different method. This is to trigger the corresponding On*****Granted function to add the type and rarity to the player and don’t break the system!

Hope this helps you with your island! Let me know if you need more help with this!

Thank you for responding! I read your comment and your code and I have a question before attempting to implement your code. When you mean weapon type, do I need to make a new weapon type for each and every weapon. Example being one weapon type for Assault Rifle, Heavy assault Rifle, and the rest of the assault rifles all be in one item spawner, or do I need to make a new weapon type for each and every weapon separately? I wanted to have a good amount of weapons and I am worried about memory.

Hello again!

With this code, “weapon type” refers to the category the weapon belongs to. For example, all assault rifles should be of weapon type “Assault Rifle”, all shotguns should be of type “Shotgun”, all sniper rifles should be of type “Sniper Rifle”, and so on.

What you need to do is to create 1 array for each weapon type and one Item Granter for each weapon individually.
For example, lets suppose you want 3 Assault Rifles, 4 Shotguns and 5 Sniper Rifles. You will need to create an Item Granter array for Assault Rifles, another Item Granter array for Shotguns, and Item Granter array for Sniper Rifles, all of them editable. And then create 3 item granters for your 3 different Assault Rifles rarities, 4 item granters for your 4 different Shotgun rarities, and 5 item granters for your 5 different Sniper Rifle Rarities. Then, add those item granters to the corresponding arrays.

Also keep in mind that, with this code, players will be able to carry only one weapon type and rarity at a time. This doesn’t work with multiple weapons in player’s inventory, as you cannot be sure which weapons is equipped if the player changes it.

Hope this answer your question! Let me know if you have any other doubts!