voting system

sur uefn comment faire en sorte que a la fin d’un chrono les joueurs passe à un vote pour savoir qui est l’imposteur et le joueur récoltant le plus de vote sera éliminer

1 Like

Hey @zvxs7 comment ça va?

I don’t speak franch so forgive me if I say something weird!
Je ne parle pas français, alors pardonne-moi si je dis quelque chose de bizarre!

I’m working on this! I will have something to share with you by tomorrow probably!
Je travaille là-dessus ! J’aurai probablement quelque chose à partager avec toi d’ici demain!

Hey @zvxs7 comment ça va?

First I tried to do it using the Pop-up dialog device, but it was not an elegant option, so I decided to use a different approach.

To create a flexible voting system, which will allow you to modify the amount of max players without change any Verse code, you will need to use Player Reference Devices, Score Manager Devices, and Button Devices, as well as a custom device to manage all the feature.

But before we continue with that, I need to clarify that this is an intermediate/advanced complexity feature and you will need to watch this video first to understand the first part.

After watching the video, create a new verse file called “utilities” and paste the code suggested by
Graeme Bull there. You can find the code here.

Ok, now we are ready to start working on our custom feature!

We will use a Player Reference Device to display the characters available for beaing voted, a Score Manager Device to show how many votes a character has, and Button Device to add a vote to that character. We will have a group of those three devices for each player on the Island. It will work as in the following video:

  1. Add as many Player Reference Devices, Score Manager Devices, and Button Devices as you want. We will use them to display the characters, to show the votes that character has accumulated and to vote for that character. You will probably want to add as many of each as Max Players you can host in your Island. You will need to add a Timer Device as well (Only one!).


  2. Ensure that all Score Manager Devices have the correct configuration:

  3. Create a new Verse file for the feature, I called it “impostor_vote_system”, and paste the following code inside:

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

# A Verse-authored creative device that can be placed in a level
impostor_vote_system := class(creative_device):
    # --------------------------------------------------------------------------------
    ## Reference Device and its corresponding button should be in the same array index
    # Editable array of Reference Devices (used to identify each player)
    @editable
    RefDevicesArray : []player_reference_device = array{}
    # Editable array of Button Devices (used for voting)
    @editable
    ButtonsArray : []button_device = array{}
    # Editable array of Score Manager Devices (used to track votes as scores)
    @editable
    ScoreManagerArray : []score_manager_device = array{}
    #---------------------------------------------------------------------------------

    #---------------------------------------------------------------------------------
    ## Maps to track relations between Player, Reference Device and Button
    # Map to track the number of votes each player has
    var VotesPerPlayer : [agent]int = map{}
    # Map to track which Reference Device corresponds to each player
    var RefDevToPlayer : [agent]player_reference_device = map{}
    # Map to track which Score Manager corresponds to each player
    var ScoreManToPlayer : [agent]score_manager_device = map{}
    # Map to track which Button corresponds to each player (by index in array)
    var ButtonToPlayer : [agent]int = map{}
    # Map to track whether a player has already voted
    var AlreadyVoted : [agent]logic = map{}
    #---------------------------------------------------------------------------------

    #---------------------------------------------------------------------------------
    # Variable to track total number of votes submitted
    var TotalVotes : int = 0
    # Timer device used to control voting duration
    @editable
    VotingTimer : timer_device = timer_device{}
    # Duration for the voting phase
    @editable
    VotingDuration : float = 0.0

    # Extra button to trigger voting (for testing purposes)
    @editable
    TestingButton : button_device = button_device{}

    OnBegin<override>()<suspends>:void=
        # Index trackers for devices
        var DeviceIndex : int = 0
        var ButtonIndex : int = 0
        # Initialize maps for all players in the playspace
        for ( Player : GetPlayspace().GetPlayers() ):
            InitializePlayersMap( Player )
            InitializeRefDeviceMap( Player, DeviceIndex )
            InitializeScoManDeviceMap( Player, DeviceIndex )
            InitializeButtonDeviceMap( Player, DeviceIndex )
            InitializeAlreadyVotedMap( Player )
            set DeviceIndex += 1
        # Subscribe each button to AddVote function
        for (ButtonDevice : ButtonsArray):
            # The following line uses the "utils.verse" file you created before 
            ButtonDevice.InteractedWithEvent.SubscribeAgent(AddVote, ButtonIndex)
            set ButtonIndex += 1
        # Subscribe the testing button to start voting
        TestingButton.InteractedWithEvent.Subscribe(StartVoting)
        # Disable all devices at the beginning after waitinf for 1 second to avoid errors
        Sleep(1.0)
        DisableAllDevices()

    # Function: Disables all voting devices and resets timer
    DisableAllDevices() : void =
        for ( RefDevice : RefDevicesArray ):
            RefDevice.Disable()
        for ( Button : ButtonsArray ):
            Button.Disable()
        for ( ScoreManager : ScoreManagerArray ):
            ScoreManager.Disable()
        VotingTimer.Reset()
        VotingTimer.Disable()
        VotingTimer.SetMaxDuration(VotingDuration)

    # Function: Enables each player's devices (Reference, Score Manager, Button)
    EnableCorrespondingDevices() : void =
        for ( Player -> RefDevice : RefDevToPlayer ):
            RefDevice.Enable()
            RefDevice.Register( Player ) # Register player with their reference device
        for ( Player -> ScoManDevice : ScoreManToPlayer ):
            ScoManDevice.Enable()
            ScoManDevice.Reset() # Reset scores before voting starts
        for ( Player -> ButtonDeviceIndex : ButtonToPlayer ):
            if( CurrentButton := ButtonsArray[ButtonDeviceIndex] ):
                CurrentButton.Enable()

    # Function: Initializes the votes map with 0 votes for a player
    InitializePlayersMap( Player : agent ) : void =
        if ( set VotesPerPlayer[ Player ] = 0 ):

    # Function: Links a player to their corresponding Reference Device
    InitializeRefDeviceMap( Player : agent, RefDeviceIndex : int) : void =
        if( CorrespondingRefDevice := RefDevicesArray[ RefDeviceIndex ] ):
            if ( set RefDevToPlayer[ Player ] = CorrespondingRefDevice ):
    
    # Function: Links a player to their corresponding Score Manager Device
    InitializeScoManDeviceMap( Player : agent, RefDeviceIndex : int) : void =
        if( CorrespondingScoManDevice := ScoreManagerArray[ RefDeviceIndex ] ):
            if ( set ScoreManToPlayer[ Player ] = CorrespondingScoManDevice ):

    # Function: Links a player to their corresponding Button (by index)
    InitializeButtonDeviceMap( Player : agent, ButtonIndex : int ) : void =
        if ( set ButtonToPlayer[ Player ] = ButtonIndex ):

    # Function: Initializes the AlreadyVoted map with "false" for a player
    InitializeAlreadyVotedMap( Player : agent ) : void =
        if ( set AlreadyVoted[ Player ] = false ):

    # Function: Starts the voting phase
    StartVoting( Agent : agent ) : void =
        EnableCorrespondingDevices()
        VotingTimer.Enable()
        VotingTimer.StartForAll()

    # Function: Handles a player's vote when they press a button
    AddVote(Agent : agent, ButtonIndex : int) : void =
        if ( VotingStatus := AlreadyVoted[Agent] ):
            if (VotingStatus = false):
                # Find which player corresponds to the pressed button
                for (KeyAgent -> Button : ButtonToPlayer):
                    if (Button = ButtonIndex):
                        # Increment that player's score
                        if ( CurrentScoMan := ScoreManToPlayer[ KeyAgent ]):
                            CurrentScoMan.Increment()
                        # Increment that player's vote count
                        if ( CurrentVotes := VotesPerPlayer[ KeyAgent ] ):
                            if ( set VotesPerPlayer[ KeyAgent ] = CurrentVotes + 1 ):

                # Increase total votes
                set TotalVotes += 1
                # If all players voted, check who got the most votes
                if ( TotalVotes >= VotesPerPlayer.Length ):
                    CheckAgentWithMostVotes()

    # Function: Determines which player has the most votes and eliminates them
    CheckAgentWithMostVotes() : void =
        var MostVotedPlayer : ?agent = false
        var HighestValue : int = -1

        # Find the player with the highest vote count
        for ( KeyAgent -> Value : VotesPerPlayer ):
            if  (Value > HighestValue ):
                set HighestValue = Value
                set MostVotedPlayer = option{ KeyAgent }

        # Eliminate the most voted player by damaging their character
        if( MostVotedAgent := MostVotedPlayer? ):
            if( MostVotedChar := MostVotedAgent.GetFortCharacter[] ):
                MostVotedChar.Damage(9999.0)
        # Reset votes and disable devices for the next round
        for ( Player : GetPlayspace().GetPlayers() ):
            InitializePlayersMap(Player)
        DisableAllDevices()
        set TotalVotes = 0
  1. Save, Compile the code and add the new device to your island together with a new Button Device to test it. Then add all the devices to this device as references. You will end with something like this:

That’s all! It is ready to play! But first, some clarifications:

A) This will NOT work if you don’t create the first file, the one from the video.
B) The three main devices of each group (Player Reference Device, Score Manager Device, and Button Device) should be in the same index on the custom device! Otherwise, when you interact with the button to vote for a player it will add a vote for a different player instead, causing conflicts.
C) Instead of using a button to trigger de voting feature, you can replace that button for any other thing and call the function “StartVoting” when you want.
D) With this system, you only need to put more groups of devices on your island and add them to the “impostor_vote_system” if you need to increase the Max Number of players, without the need to change the code!

With that, you are ready to start playing with it!

Let me know if you need more help with this!