#Dice roller 3.5 to 4.0 conversion trouble

4 messages · Page 1 of 1 (latest)

severe nebula
#

Okay so this is a pickle for those who like math, probability and coding. I'm converting this diceroller plugin from godot 3.5 to 4.0. It's a pretty big deal since i can publish it to the asset store!

Most of the functions converts fine. However at least one of them does not work after converting to 4.0 and the scripts seem to look excactly the same.

So the function rolls two twentysided dice (d20) and returns the highest number (called advantage in D&D lingo). However the advantage isn't working. When i roll the dice a lot it evens out randomly like i'm only rolling one die or it picks the same one everytime. I should get better than average results and somehow that only happens in godot 3.5. Not in Godot 4.0. Even though the scripts are identical.

Hope someone can help. The script is in the first reply due to message length.

#
#Roll one or more dice with advantage or disadvantage (if advantage is not true rolls are disadvantaged). Returns the num_results sum of the highest (advantage) or lowest (disadvantage) value of all rolls.
func roll_special_dice(num_sides = 6, advantage = true, num_dice = 2, num_results = 1) -> int:
    var rolls = []
    var num_rolls = 0
    var roll

    var replace_value
    var replace_id

    for i in range(0, num_dice):
        roll = roll_dice(1, num_sides)

        num_rolls = rolls.size()

        if num_rolls < num_results:
            rolls.append(roll)
        elif advantage:
            replace_value = num_sides - 1
            replace_id = null
            for j in range(1, num_rolls):
                if roll > rolls[j - 1] && rolls[j - 1] < replace_value:
                    replace_id = j - 1
                    replace_value = rolls[j - 1]

            if replace_id:
                rolls[replace_id] = roll
        else:
            replace_value = 0
            replace_id = null
            for j in range(1, num_rolls):
                if roll < rolls[j - 1] && rolls[j - 1] > replace_value:
                    replace_id = j - 1
                    replace_value = rolls[j - 1]

            if replace_id:
                rolls[replace_id] = roll
    
    var result = 0

    for i in range(0, num_rolls):
        result += rolls[i]

    return result

I call the function with

var advantage_attack = dicebag.roll_special_dice(20, true, 2, 1)```
fluid mantle
#

I don't know how godot 4 implants range but in 3.5 range(1,1) should not loop. You would need range(0,1) or range(1,2)

fluid mantle
#

Personally I would use built in functions for array. Like min() to get the smallest roll. And find() to get its index. It's clearer and cleaner