no-rollback effect struggle

Hello there,
trying my first steps into verse but stumbling here and there. So far I’ve been able to save myself with tutorials or Google, but no approach has helped here yet.

With the line “RollItem(pool, Agent)” I get the error “This invocation calls a function that has the ‘no_rollback’ effect, which is not allowed by its context.(3512)”

What am I doing wrong?

Here is the whole code:

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


loot_pool_manager := class(creative_device):

    @editable
    Button: button_device = button_device{}

    @editable
    ItemGranter: item_granter_device = item_granter_device{}

    @editable
    Pools: [] loot_pool = array{loot_pool{}}


    OnBegin<override>()<suspends>: void=
        Button.InteractedWithEvent.Subscribe(OnTestButton)


    OnTestButton(Agent: agent) : void=
        Print("Grant Item")
        if:
            var pool :loot_pool = Pools[0]
            RollItem(pool, Agent)   # <-- THIS LINE FAILS
            
        else:
            Print("Roll failed")

    
    RollItem(Pool: loot_pool, Agent: agent)<decides> : void =
        var roll : int = GetRandomInt(1, 100)
        
        for (i -> Item : Pool.DropChances):
            if (100 - Item.Chance >= roll):
                Print("Item {Item.Chance} rolled {roll}")
                Pool.ItemGranter.GrantItemIndex(Agent, i)        
    

loot_pool := class<concrete>():
    @editable
    Name: string = ""

    @editable
    ItemGranter: item_granter_device = item_granter_device{}

    @editable
    DropChances: [] drop_chance = array{drop_chance{}}


drop_chance := class<concrete>():
    @editable
    Chance : int = 0

    @editable
    Amount : vector2 = vector2{X := 1.0, Y := 2.0}
1 Like

replace with RollItem[pool,Agent]

Because GrantItemIndex() is <no_rollback> you can’t make your method <decides>, even though it would make sense, I don’t think it’s possible as of v32.00, they’re making changes to the specifiers though

What you can do for now is either trigger an event when the roll succeeds or make the method return a logic

Logic method

RollItem(Agent: agent):logic=
    Granter := GetGranter()
    
    if (false?):
        Granter.GrantItem(Agent)
        true
    else:
        false

Test(Agent: agent)<suspends>:void=
    DidRoll := RollItem(Agent)
    if(DidRoll?):
        # Roll Succeeded

Event method

RollSucceededEvent : event(agent) = event(agent){}

RollItem(Agent: agent):void=
    Granter := GetGranter()

    if (false?):
        Granter.GrantItem(Agent)
        RollSucceededEvent.Signal(Agent)

OnBegin()<suspends>:void=
    loop:
        Agent := RollSucceededEvent.Await()
        # Roll Succeeded
1 Like