How to change a player's class when he has an item "X" in his inventory?

Hi everyone,

I’m working on a project in UEFN and would like to implement a feature in Verse where a player’s class changes dynamically based on an item in their inventory.

Here’s what I’m trying to achieve:

  • If a player has the item “X” in their inventory, they should automatically switch to Class 2.
  • If they don’t have the item, they should remain in Class 1.

I’ve been struggling to figure out how to make this work. Does anyone have a solution, example, or advice on how to achieve this functionality? Any help would be greatly appreciated!

Thanks in advance for your support. :blush:

I don’t know how UEFN codes is but there is a logical solution to this. Every item has unique ID for itself. When character gets any item, check if it’s that the item you want. For example X Item must change the class, ID is 34. Make a if node, check if id is 34. If so; Change the class, And when character drops any item, check the item same way, if the item ID 34; switch to class 1.

Should do the trick. You can slap the utility methods in a module or a utils file

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Fortnite.com/Characters }
using { /Verse.org/Concurrency }

suspends_wrapper(payload:type) := class:
    InMethod:type{func(:payload)<suspends>:void}
    ProxyMethod(Payload:payload):void=
        spawn{InMethod(Payload)}

(S:subscribable(payload)).SubscribeSuspends(Callback:type{func(:payload)<suspends>:void} where payload:type)<transacts>:cancelable=
    DelayWrapper := suspends_wrapper(payload){InMethod := Callback}
    S.Subscribe(DelayWrapper.ProxyMethod)

(Awaitable:awaitable(t)).AwaitAndConfirm(ValToConfirm:t where t:subtype(comparable))<suspends>:t=
    loop:
        Value := Awaitable.Await()
        if(Value = ValToConfirm):
            return Value

dynamic_class_changer := class(creative_device):

    @editable DefaultClass : class_and_team_selector_device = class_and_team_selector_device{} # <- Default Class All Players Should Have When They Don't Have Required Item
    @editable ClassToChangeTo : class_and_team_selector_device = class_and_team_selector_device{} # <- Class Players Should Be Assigned When They Are Holding Required Item 
    @editable ItemTracker : conditional_button_device = conditional_button_device{} # <- Make sure this has ONLY the item you'd like to track in the conditional_button_device
    @editable ItemCheckFrequency : float = 0.1 #<- The frequency that we will check for a player holding the item at to change classes

    OnBegin<override>()<suspends>:void=
        for(Player:GetPlayspace().GetPlayers()):
            spawn{InitializePlayer(Player)}

        GetPlayspace().PlayerAddedEvent().SubscribeSuspends(InitializePlayer)

    #Wait for players recently joining to have a fort_character that IsActive[]
    #You'd need to write a fallback in the case this fails
    InitializePlayer(Player:player)<suspends>:void=
        TIMELIMIT := 30.0
        var Time : float = 0.0
        loop:
            if(Player.GetFortCharacter[].IsActive[]):
                spawn{Player.ClassTask()}
                break
            Sleep(0.1)
            set Time += 0.1
            if(Time >TIMELIMIT):
                break

    # Races 2 blocks | 
    # Block 1 -> 1 Waits for 'Player' to leave which will end the race automatically cleaning this task up
    # Block 2 -> Runs until the player leaves | checking every 'ItemCheckFrequency' Seconds for if the player has the item / changing classes when necessary 
    (Player:player).ClassTask()<suspends>:void=
        var IsDefaultClass : logic = true
        race:
            block:
                loop:
                    GetPlayspace().PlayerRemovedEvent().AwaitAndConfirm(Player)
                    Print("Player Left Stopping Class Task For Leaving Player..", ?Duration := 5.0)
            block:
                loop:
                    Sleep(ItemCheckFrequency)
                    if(ItemTracker.HasAllItems[Player], IsDefaultClass?):
                        ClassToChangeTo.ChangeClass(Player)
                        set IsDefaultClass = false
                    else:
                        if(not IsDefaultClass?):
                            DefaultClass.ChangeClass(Player)
                            set IsDefaultClass = true