Solved Voting system

  • Welcome to skUnity!

    Welcome to skUnity! This is a forum where members of the Skript community can communicate and interact. Skript Resource Creators can post their Resources for all to see and use.

    If you haven't done so already, feel free to join our official Discord server to expand your level of interaction with the comminuty!

    Now, what are you waiting for? Join the community now!

  • LOOKING FOR A VERSION OF SKRIPT?

    You can always check out skUnity Downloads for downloads and any other information about Skript!

Status
Not open for further replies.

Aralwen

Active Member
May 26, 2017
164
14
18
25
Hello, I am trying to make a voting system. The vote is open for 2 minutes, the result is announced after this time. The player who has been voted the most receives a private message.

I do not know how detect the person who has received the most votes.
I would also like to know how to detect an equality


My old code (look down for the new)


code_language.skript:
command /openvote:
    description: Open the votes
    trigger:
        set {vote} to now
        clear {votep::*}
        broadcast "The votes are open for two minutes! /vote PSEUDO"
        wait 2 minutes
        broadcast "The most voted player is: ...."

command /vote [<player>]:
    description: Vote a player
    trigger:
        if difference between {vote} and now is less than 2 minutes:
            if {vote::%player%} is not set:
                set {votep::%player%} to now
                add 1 to {ListVote.%arg-player%}
                send "&aYour vote has been counted"
            else:
                send "&cYou have already voted."
        else:
            send "&cThe votes are not open yet"

Thanks,
Aralwen.
[doublepost=1535053421,1535053381][/doublepost]Hello ! I modified my code a bit, but it still does not work and I do not understand why.
So I'm summarizing what I would like my code to do :
  • A player starts the vote with /openvote, the players have 2 minutes to vote.
  • After 2 minutes, the most voted player is announced with the number of votes he has
  • In case of a tie, it sends a message of the style "The players have not managed to decide"
  • If no one has voted, it says so
Thank's in advance for your help !

New code:

code_language.skript:
command /openvote:
    description: Open the votes
    trigger:
        set {VoteTimer} to now
        clear {vote::*}
        clear {VoteList::*}
        broadcast "&aThe votes are open for two minutes! Use &a&l/vote PSEUDO"

every 1 second:
    if difference between {VoteTimer} and now is more than 2 minutes:
        clear {VoteTimer}
        loop {VoteList::*}:
            if loop-value is higher than 0:
                set {_vote} to loop-value
                set {_voteplayer} to loop-index parsed as player
        if {_voteplayer} is set:
            broadcast "&eThe most voted player is: &e&l%{_voteplayer}% &e- Voted by &e&l%{VoteList::%{_voteplayer}%}% people"
        else:
            broadcast "&cNobody voted!"


command /vote [<player>]:
    description: Vote a player
    trigger:
        if difference between {VoteTimer} and now is less than 2 minutes:
            if {Vote::%player's uuid%} is not set:
                set {Vote::%player's uuid%} to now
                add 1 to {VoteList::%arg-player%}
                send "&aYour vote has been counted"
            else:
                send "&cYou have already voted."
        else:
            send "&cThe votes are not open yet"
 
  • Like
Reactions: DavidZar
You can use https://skriptlang.github.io/Skript/expressions.html#ExprSortedList to sort the list which contains the votes. After that you can get the last element from the list. After that you loop the original list, since the sorted expression doesn't keep indices (as far as I know). In the loop you check if the loop-value matches the last element of the sorted list, if it does, set a variable to the loop-index. Don't exit the loop here, because when you continue looping and the loop-value matches the last element again, it's a tie. You can check this by checking if the variable for the winner is set. If it is, it's a tie. After that you can use broadcast or whatevet you want to announce the winner
 
  • Like
Reactions: DavidZar
You can use https://skriptlang.github.io/Skript/expressions.html#ExprSortedList to sort the list which contains the votes. After that you can get the last element from the list. After that you loop the original list, since the sorted expression doesn't keep indices (as far as I know). In the loop you check if the loop-value matches the last element of the sorted list, if it does, set a variable to the loop-index. Don't exit the loop here, because when you continue looping and the loop-value matches the last element again, it's a tie. You can check this by checking if the variable for the winner is set. If it is, it's a tie. After that you can use broadcast or whatevet you want to announce the winner
Hello ! First of all thank you, thanks to your help I managed to do for the most voted player.
The problem is that other people are also announced

By cons I admit not knowing how to detect a tie :/

code_language.skript:
command /openvote:
  description: Open the votes
  trigger:
    set {VoteTimer} to now
    clear {vote::*}
    clear {VoteList::*}
    broadcast "&aThe votes are open for two minutes! Use &a&l/vote PSEUDO"

every 1 second:
  if difference between {VoteTimer} and now is more than 1 minutes:
    clear {VoteTimer}
    loop {VoteList::*}:
      if loop-value is higher than 0:
        set {_sorted::*} to {VoteList::*} sorted from highest to lowest with output "@index &ewith &e&l@value &evotes !"
        broadcast "&eThe most voted player is: &e&l%{_sorted::*}%"
      else:
        broadcast "&cNobody voted!"


command /vote [<player>]:
  trigger:
    if difference between {VoteTimer} and now is less than 2 minutes:
      if {Vote::%player's uuid%} is not set:
        #set {Vote::%player's uuid%} to now
        add 1 to {VoteList::%arg-player%}
        send "&aYour vote has been counted"
      else:
        send "&cYou have already voted."
    else:
      send "&cThe votes are not open yet"
 
Last edited:
  • Like
Reactions: DavidZar
Hello ! First of all thank you, thanks to your help I managed to do for the most voted player.
The problem is that other people are also announced

By cons I admit not knowing how to detect a tie :/

code_language.skript:
command /openvote:
  description: Open the votes
  trigger:
    set {VoteTimer} to now
    clear {vote::*}
    clear {VoteList::*}
    broadcast "&aThe votes are open for two minutes! Use &a&l/vote PSEUDO"

every 1 second:
  if difference between {VoteTimer} and now is more than 1 minutes:
    clear {VoteTimer}
    loop {VoteList::*}:
      if loop-value is higher than 0:
        set {_sorted::*} to {VoteList::*} sorted from highest to lowest with output "@index &ewith &e&l@value &evotes !"
        broadcast "&eThe most voted player is: &e&l%{_sorted::*}%"
      else:
        broadcast "&cNobody voted!"


command /vote [<player>]:
  trigger:
    if difference between {VoteTimer} and now is less than 2 minutes:
      if {Vote::%player's uuid%} is not set:
        #set {Vote::%player's uuid%} to now
        add 1 to {VoteList::%arg-player%}
        send "&aYour vote has been counted"
      else:
        send "&cYou have already voted."
    else:
      send "&cThe votes are not open yet"
Try this:
code_language.skript:
every 1 second:
    if difference between {VoteTimer} and now is more than 1 minutes:
        clear {VoteTimer}
        set {_sorted::*} to sorted {VoteList::*}
        set {_top} to last element out of {_sorted::*}
        if {_top} is not set:
            broadcast "Noone voted!"
            stop
        loop {VoteList::*}:
            loop-value is {_top}
            if {_p} is set:
                broadcast "Tie!"
                stop
            set {_p} to loop-index
        broadcast "Winner: %{_p}% with %{_top}% votes"
 
  • Like
Reactions: DavidZar
Try this:
code_language.skript:
every 1 second:
    if difference between {VoteTimer} and now is more than 1 minutes:
        clear {VoteTimer}
        set {_sorted::*} to sorted {VoteList::*}
        set {_top} to last element out of {_sorted::*}
        if {_top} is not set:
            broadcast "Noone voted!"
            stop
        loop {VoteList::*}:
            loop-value is {_top}
            if {_p} is set:
                broadcast "Tie!"
                stop
            set {_p} to loop-index
        broadcast "Winner: %{_p}% with %{_top}% votes"
Thank you very much for your help, it works perfectly!
I have one last question: How to define life to the most voted person?

I tried :

code_language.skript:
        broadcast "Winner: %{_p}% with %{_top}% votes"
        set {ActualVote} to {_p}
        set {ActualVote}'s max health to 5

But it does not work :/
 
  • Like
Reactions: DavidZar
  • Like
Reactions: DavidZar
Yes I know, but although the variable is on the name of the player it does not work.

This may be related to the fact that the vote result gives the nickname without the uppercase in front of the nickname
(Aralwen -> aralwen)

code_language.skript:
        [...]
        broadcast "Winner: %{_p}% with %{_top}% votes"
        set {ActualVote} to {_p}
        wait 1 second
        set {ActualVote}'s max health to 5 #Does not work
        set the maximum health of {ActualVote} to 5 #Does not work
        set {_health} to {ActualVote} health
        damage {ActualVote} by %{_health} /2% hearts #Does not work
 
Last edited:
  • Like
Reactions: DavidZar
Yes I know, but although the variable is on the name of the player it does not work.

This may be related to the fact that the vote result gives the nickname without the uppercase in front of the nickname
(Aralwen -> aralwen)

code_language.skript:
        [...]
        broadcast "Winner: %{_p}% with %{_top}% votes"
        set {ActualVote} to {_p}
        wait 1 second
        set {ActualVote}'s max health to 5 #Does not work
        set the maximum health of {ActualVote} to 5 #Does not work
        set {_health} to {ActualVote} health
        damage {ActualVote} by %{_health} /2% hearts #Does not work
Oh wait ofcourse (index of a list is always a text). Use
code_language.skript:
set {ActualVote} to {_p} parsed as a offline player
[doublepost=1535128677,1535128620][/doublepost]Oh and you should broadcast with the variable I just mentioned so it has the right capital letters
 
  • Like
Reactions: DavidZar
Oh wait ofcourse (index of a list is always a text). Use
code_language.skript:
set {ActualVote} to {_p} parsed as a offline player
[doublepost=1535128677,1535128620][/doublepost]Oh and you should broadcast with the variable I just mentioned so it has the right capital letters
Thank you, I fixed the problem for capitalization. However, the rest still does not work :/

code_language.skript:
every 1 second:
    if difference between {VoteTimer} and now is more than 1 minutes:
        clear {VoteTimer}
        set {_sorted::*} to sorted {VoteList::*}
        set {_top} to last element out of {_sorted::*}
        if {_top} is not set:
            broadcast "Noone voted!"
            stop
        loop {VoteList::*}:
            loop-value is {_top}
            if {_p} is set:
                broadcast "Tie!"
                stop
            set {_p} to loop-index parsed as a offline player
        broadcast "Winner: %{_p}% with %{_top}% votes"
        set {ActualVote} to {_p} parsed as a offline player #Does not work
        wait 1 second
        set {ActualVote}'s max health to 5 #Does not work
        damage {ActualVote} by %{_health} /2% hearts #Does not work
[doublepost=1535129688][/doublepost]
Thank you, I fixed the problem for capitalization. However, the rest still does not work :/

code_language.skript:
every 1 second:
    if difference between {VoteTimer} and now is more than 1 minutes:
        clear {VoteTimer}
        set {_sorted::*} to sorted {VoteList::*}
        set {_top} to last element out of {_sorted::*}
        if {_top} is not set:
            broadcast "Noone voted!"
            stop
        loop {VoteList::*}:
            loop-value is {_top}
            if {_p} is set:
                broadcast "Tie!"
                stop
            set {_p} to loop-index parsed as a offline player
        broadcast "Winner: %{_p}% with %{_top}% votes"
        set {ActualVote} to {_p} parsed as a offline player #Does not work
        wait 1 second
        set {ActualVote}'s max health to 5 #Does not work
        damage {ActualVote} by %{_health} /2% hearts #Does not work

It's my fault, it works. However, this condition still does not work : damage {ActualVote} by %{_health} /2% hearts

code_language.skript:
every 1 second:
    if difference between {VoteTimer} and now is more than 1 minutes:
        clear {VoteTimer}
        set {_sorted::*} to sorted {VoteList::*}
        set {_top} to last element out of {_sorted::*}
        if {_top} is not set:
            broadcast "Noone voted!"
            stop
        loop {VoteList::*}:
            loop-value is {_top}
            if {_p} is set:
                broadcast "Tie!"
                stop
            set {_p} to loop-index parsed as a offline player
        broadcast "Winner: %{_p}% with %{_top}% votes"
        set {ActualVote} to {_p}
        wait 1 second
        set {ActualVote}'s max health to 5
        damage {ActualVote} by %{_health} /2% hearts #Does not work
        broadcast "%{ActualVote}%"
 
Last edited:
  • Like
Reactions: DavidZar
Thank you, I fixed the problem for capitalization. However, the rest still does not work :/

code_language.skript:
every 1 second:
    if difference between {VoteTimer} and now is more than 1 minutes:
        clear {VoteTimer}
        set {_sorted::*} to sorted {VoteList::*}
        set {_top} to last element out of {_sorted::*}
        if {_top} is not set:
            broadcast "Noone voted!"
            stop
        loop {VoteList::*}:
            loop-value is {_top}
            if {_p} is set:
                broadcast "Tie!"
                stop
            set {_p} to loop-index parsed as a offline player
        broadcast "Winner: %{_p}% with %{_top}% votes"
        set {ActualVote} to {_p} parsed as a offline player #Does not work
        wait 1 second
        set {ActualVote}'s max health to 5 #Does not work
        damage {ActualVote} by %{_health} /2% hearts #Does not work
[doublepost=1535129688][/doublepost]

It's my fault, it works. However, this condition still does not work : damage {ActualVote} by %{_health} /2% hearts

code_language.skript:
every 1 second:
    if difference between {VoteTimer} and now is more than 1 minutes:
        clear {VoteTimer}
        set {_sorted::*} to sorted {VoteList::*}
        set {_top} to last element out of {_sorted::*}
        if {_top} is not set:
            broadcast "Noone voted!"
            stop
        loop {VoteList::*}:
            loop-value is {_top}
            if {_p} is set:
                broadcast "Tie!"
                stop
            set {_p} to loop-index parsed as a offline player
        broadcast "Winner: %{_p}% with %{_top}% votes"
        set {ActualVote} to {_p}
        wait 1 second
        set {ActualVote}'s max health to 5
        damage {ActualVote} by %{_health} /2% hearts #Does not work
        broadcast "%{ActualVote}%"
Use
code_language.skript:
damage {ActualVote} by {_health} / 2 hearts
but the {_health} variable isn't set anywhere so you will have to add that
 
  • Like
Reactions: DavidZar
Use
code_language.skript:
damage {ActualVote} by {_health} / 2 hearts
but the {_health} variable isn't set anywhere so you will have to add that
Actually, I realized after ! However, it still does not work :/
damage {ActualVote} by {_health} / 2 hearts #Does not work

code_language.skript:
every 1 second:
    if difference between {VoteTimer} and now is more than 1 minutes:
        clear {VoteTimer}
        set {_sorted::*} to sorted {VoteList::*}
        set {_top} to last element out of {_sorted::*}
        if {_top} is not set:
            broadcast "Noone voted!"
            stop
        loop {VoteList::*}:
            loop-value is {_top}
            if {_p} is set:
                broadcast "Tie!"
                stop
            set {_p} to loop-index parsed as a offline player
        broadcast "Winner: %{_p}% with %{_top}% votes"
        set {ActualVote} to {_p}
        wait 1 second
        set {ActualVote}'s max health to 5
        wait 1 second
        set {_health} to {ActualVote}'s health
        damage {ActualVote} by {_health} / 2 hearts #Does not work
 
Last edited:
  • Like
Reactions: DavidZar
Actually, I realized after ! However, it still does not work :/
damage {ActualVote} by {_health} / 2 hearts #Does not work

code_language.skript:
every 1 second:
    if difference between {VoteTimer} and now is more than 1 minutes:
        clear {VoteTimer}
        set {_sorted::*} to sorted {VoteList::*}
        set {_top} to last element out of {_sorted::*}
        if {_top} is not set:
            broadcast "Noone voted!"
            stop
        loop {VoteList::*}:
            loop-value is {_top}
            if {_p} is set:
                broadcast "Tie!"
                stop
            set {_p} to loop-index parsed as a offline player
        broadcast "Winner: %{_p}% with %{_top}% votes"
        set {ActualVote} to {_p}
        wait 1 second
        set {ActualVote}'s max health to 5
        wait 1 second
        set {_health} to {ActualVote}'s health
        damage {ActualVote} by {_health} / 2 hearts #Does not work
Try setting the health variable to the player's health / 2 and remove the / 2 part from the damage effect
 
  • Like
Reactions: DavidZar
Try setting the health variable to the player's health / 2 and remove the / 2 part from the damage effect
It still does not work :c

code_language.skript:
        set {_health} to {ActualVote}'s health / 2
        damage {ActualVote} by {_health} hearts
 
  • Like
Reactions: DavidZar
It still does not work :c

code_language.skript:
        set {_health} to {ActualVote}'s health / 2
        damage {ActualVote} by {_health} hearts
Try broadcast the {_health} variable to test if that part works
 
  • Like
Reactions: DavidZar
Try broadcast the {_health} variable to test if that part works
I do not understand, because if I make an command and I set it to player it works

work :
code_language.skript:
damage player by {_health} hearts
doesn't work :
code_language.skript:
damage {ActualVote} by {_health} hearts
 
  • Like
Reactions: DavidZar
I do not understand, because if I make an command and I set it to player it works

work :
code_language.skript:
damage player by {_health} hearts
doesn't work :
code_language.skript:
damage {ActualVote} by {_health} hearts
Add
code_language.skript:
broadcast "health: %{_health}%"
to the code
 
  • Like
Reactions: DavidZar
Add
code_language.skript:
broadcast "health: %{_health}%"
to the code
code_language.skript:
command /debug:
    trigger:
        set {ActualVote} to player
        set {ActualVote}'s max health to 10
        set {_health} to {ActualVote}'s health / 2
        damage {ActualVote} by {_health} hearts
        send "&aDebug: %{ActualVote}% - %{_health}%"

eESgMl9.png
 
  • Like
Reactions: DavidZar
code_language.skript:
command /debug:
    trigger:
        set {ActualVote} to player
        set {ActualVote}'s max health to 10
        set {_health} to {ActualVote}'s health / 2
        damage {ActualVote} by {_health} hearts
        send "&aDebug: %{ActualVote}% - %{_health}%"

eESgMl9.png
Try testing if the damage effect works
 
  • Like
Reactions: DavidZar
Yes, as I told you:

work :
code_language.skript:
damage player by {_health} hearts
doesn't work :
code_language.skript:
damage {ActualVote} by {_health} hearts
Try setting a local variable to the player variable as a string, parsing it as a player and than use the damage effect on that
 
  • Like
Reactions: DavidZar
Status
Not open for further replies.