System [System] VoteKick System

Joker(Div)

Always Here..
Reaction score
86
I got tired of all these GUI kick systems, so I decided to make a JASS one myself.

Enjoy. :)

Code (Text Version):

JASS:
//==============================================================================
//                    VOTEKICK SYSTEM BY JOKER(DIV) -- v1.11
//==============================================================================
//
//  PURPOSE:
//       * To kick annoying players with majority vote.
//
//
//  HOW TO USE:
//       * My Vote Kick system is just a simple trigger.
//         
//       * Just Type: "-kick player ##"  (i.e. -kick player 12) to kick that player.
//        
//       * Everyone is able to request a kick.               
//
//  PROS: 
//       * Extremelly easy to use
//       * Somewhat configurable (not that you need to anyway...)
//
//  CONS:
//       * Limited to a certain extent. (I suppose...)
//
//  CREDITS:
//       * Cohadar (I Stole this outline from him <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />)
//       * All you darn GUI&#039;ers, enough GUI already <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite7" alt=":p" title="Stick Out Tongue    :p" loading="lazy" data-shortname=":p" />
//         
//  REQUIREMENTS:
//       * Dialogs system by Cohadar (Requires ABC)
//       * NewGen Editor by Vexorian/PitzerMike
//
//  HOW TO IMPORT:
//       * Just create a trigger named VK
//       * convert it to text and replace the whole trigger text with this one
//
//==============================================================================
library VK uses Dialogs

globals
    //====================================
    private constant real SECONDS_BETWEEN_VOTES = 25. //Only thing you need to touch. 
    private constant string YesColor = &quot;|cFFFF0000&quot;   //(Unless you know what you are doing.) 
    private constant string NoColor = &quot;|cFF00FF00&quot;
    //====================================
    
    //I set it to 16 since Player(16) doesn&#039;t exist, incase this bugs...somehow.
    private integer WhichPlayer = 16
    
    private Dialog Dlog = 0 //Dialogs
    private boolean Running = false
    
    private integer AllVote = 0
    private integer Yes = 0
    private integer No = 0
    
    private timer Timer = CreateTimer()
    
    //Maybe you can find this global useful.
    public integer CountPlayers = 0
endglobals

//===========================================================================
private function AllowVote takes nothing returns nothing
    //Have to set everything back to default
    set Running = false
    set AllVote = 0
    set Yes = 0
    set No = 0
    call PauseTimer(Timer)
endfunction

//===========================================================================
private function VoteAction takes nothing returns nothing
    local integer Result = Dlog.GetResult()  //Dialogs
    local player TPlayer = GetTriggerPlayer()
    set AllVote = AllVote + 1
    call Dlog.Hide(TPlayer) //Dialogs
    
    if Result == HK_1 then
        set Yes = Yes + 1
        call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,3.5, YesColor + GetPlayerName(TPlayer) + &quot; has voted yes. (&quot; + I2S(AllVote) + &quot;/&quot; + I2S(CountPlayers) + &quot;)&quot; )
    elseif Result == HK_2 then
        set No = No + 1
        call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,3.5, NoColor + GetPlayerName(TPlayer) + &quot; has voted no. (&quot; + I2S(AllVote) + &quot;/&quot; + I2S(CountPlayers) + &quot;)&quot; )
    elseif Result == HK_3 then
        call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,3.5, NoColor + GetPlayerName(TPlayer) + &quot; will not vote. (&quot; + I2S(AllVote) + &quot;/&quot; + I2S(CountPlayers) + &quot;)&quot; )
    endif
    
        if AllVote == CountPlayers then
            call TimerStart( Timer, SECONDS_BETWEEN_VOTES, false, function AllowVote )
            call ClearTextMessages()
            call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,2.5, &quot;|cFFC0C000Vote Count:|r&quot;+YesColor +&quot; Yes: &quot;+I2S(Yes)+&quot;|r&quot;+NoColor+&quot; No: &quot;+I2S(No)+&quot;|r Null: &quot;+I2S(CountPlayers-(Yes+No)) )
            
            if Yes &gt; No then
                call CustomDefeatBJ(Player(WhichPlayer), &quot;You have been kicked.&quot;)
                call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,2., GetPlayerName(Player(WhichPlayer)) + &quot; has been kicked.&quot; )
            else
                call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,2., GetPlayerName(Player(WhichPlayer)) + &quot; will not be kicked.&quot; )
            endif
        endif
endfunction

//===========================================================================
private function Vote takes nothing returns nothing
    //Dialogs
    if Dlog == 0 then
        set Dlog = Dialog.create()
        call Dlog.AddButton( &quot;Yes&quot;, HK_1 ) 
        call Dlog.AddButton( &quot;No&quot;, HK_2 )
        call Dlog.AddButton( &quot;Not Voting&quot;, HK_3 )
        call Dlog.AddAction(function VoteAction)
    endif
    call Dlog.SetMessage(&quot;Kick &quot; + GetPlayerName(Player(WhichPlayer)) + &quot;?&quot;)
    call Dlog.ShowAll()
endfunction

//===========================================================================
private function Request takes nothing returns nothing
    local player TPlayer = GetTriggerPlayer()
    set WhichPlayer = (S2I(SubString(GetEventPlayerChatString(), 13, 15))) - 1
    
    //I&#039;m using all these if/then&#039;s so that I can put in messages.
    if not Running then
    
        if 0 &lt;= WhichPlayer and WhichPlayer &lt;= 11 then

            if GetPlayerSlotState(Player(WhichPlayer)) == PLAYER_SLOT_STATE_PLAYING then
                set Running = true
                call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,2., GetPlayerName(TPlayer) + &quot; has requested to kick player &quot; + I2S(WhichPlayer+1) + &quot;.&quot;)
                call Vote()
            else
                call DisplayTimedTextToPlayer(TPlayer, 0,0,1.,&quot;|c00FF0000Player(&quot; + I2S(WhichPlayer+1) + &quot;) is not playing!&quot;)
            endif
        else
            call DisplayTimedTextToPlayer(TPlayer, 0,0,1.,&quot;|c00FF0000Player(&quot; + I2S(WhichPlayer+1) + &quot;) does not exist!&quot;)
        endif
    else
        //This is the only reason why I have a global timer.
        call DisplayTimedTextToPlayer(TPlayer, 0,0,1.,&quot;|c00FF0000Please wait &quot; + I2S(R2I(TimerGetRemaining(Timer)+0.5)) + &quot; more seconds to request a new vote.&quot;)
    endif
endfunction

//===========================================================================
private function PlayerGone takes nothing returns nothing
    set CountPlayers = CountPlayers-1
endfunction

public function InitTrig takes nothing returns nothing
    local trigger trig = CreateTrigger()
    local integer count = 16
    
    //----------------------
    loop
        set count = count - 1
        call TriggerRegisterPlayerChatEvent( trig, Player(count), &quot;-kick player&quot;, false )
        
            if GetPlayerSlotState(Player(count)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(count)) == MAP_CONTROL_USER then
                set CountPlayers = CountPlayers + 1
            endif
            
        exitwhen count == 0
    endloop
    call TriggerAddAction(trig, function Request)
    
    //-----------------------
    set trig = CreateTrigger()
    loop
        call TriggerRegisterPlayerEvent(trig, Player(count), EVENT_PLAYER_LEAVE)
        set count = count + 1
        exitwhen count == 12
    endloop
    call TriggerAddAction(trig, function PlayerGone)
        
endfunction

endlibrary
Code (Dialog Version) -UPDATED:
JASS:
//==============================================================================
//                    VOTEKICK SYSTEM BY JOKER(DIV) -- v1.00D
//==============================================================================
//
//  PURPOSE:
//       * To kick annoying players with majority vote.
//
//
//  HOW TO USE:
//       * My Vote Kick system is just a simple trigger.
//         
//       * Just Type: &quot;-votekick&quot; and a Dialog will show with a list of all players
//                     Select the player you wish to kick, and a vote box will appear
//                     for all players
//        
//       * Everyone is able to request a kick. (Can be configurable)          
//
//  PROS: 
//       * Extremelly easy to use
//       * Somewhat configurable (not that you need to anyway...)
//
//  CONS:
//       * Limited to a certain extent. (I suppose...)
//
//  CREDITS:
//       * Cohadar (I Stole this outline from him <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />)
//       * Cohadar (Yes, he deserves to be written twice)
//       * All you darn GUI&#039;ers, enough GUI already <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite7" alt=":p" title="Stick Out Tongue    :p" loading="lazy" data-shortname=":p" />
//         
//  REQUIREMENTS:
//       * Dialogs system by Cohadar (Requires ABC)
//       * NewGen Editor by Vexorian/PitzerMike
//
//  HOW TO IMPORT:
//       * Just create a trigger named VK
//       * convert it to text and replace the whole trigger text with this one
//
//==============================================================================
library VK uses Dialogs

globals
    //====================================
    private constant real   SECONDS_BETWEEN_VOTES   = 30.         //Time between a votes
    private constant real   SECONDS_ALLOWED_TO_VOTE = 10.        //Time given to vote

    private constant string YesColor                = &quot;|cFFFF0000&quot;          
    private constant string NoColor                 = &quot;|cFF00FF00&quot;
    
    private boolean RedOnly = false  //Only allows red to request.
    //====================================
    
    
    //I set it to 16 since Player(16) doesn&#039;t exist, incase this bugs...somehow.
    private integer WhichPlayer = 16
    
    private Dialog Dlog = 0 //Dialogs
    private Dialog Dlog2 = 0 //Dialogs
    private boolean Running = false
    private boolean array IsPlayerGone
    
    private integer AllVote = 0
    private integer Yes = 0
    private integer No = 0
    
    private integer Counter = 0
    
    private timer Timer = CreateTimer()
    
    //Maybe you can find this global useful.
    public integer CountPlayers = 0
endglobals

//===========================================================================
private function AllowVote takes nothing returns nothing
    //Have to set everything back to default
    set Running = false
    set Counter = 0
    set AllVote = 0
    set Yes = 0
    set No = 0
    call PauseTimer(Timer)
endfunction

//===========================================================================
private function VotingLimit takes nothing returns nothing
    set Counter = Counter + 1
    
    if SECONDS_ALLOWED_TO_VOTE &lt;= Counter then
        call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,5.,&quot;|c00FF0000Time has run out to vote. Vote canceled.&quot; )
        call Dlog.HideAll()
        call Dlog2.HideAll()
        call PauseTimer( Timer )
        call TimerStart( Timer, SECONDS_BETWEEN_VOTES, false, function AllowVote )
    endif
endfunction

//===========================================================================
private function VoteAction takes nothing returns nothing
    local integer Result = Dlog.GetResult()  //Dialogs
    local player TPlayer = GetTriggerPlayer()
    set AllVote = AllVote + 1
    call Dlog.Hide(TPlayer) //Dialogs
    
    if Result == HK_1 then
        set Yes = Yes + 1
        call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,3.5, YesColor + GetPlayerName(TPlayer) + &quot; has voted yes. (&quot; + I2S(AllVote) + &quot;/&quot; + I2S(CountPlayers) + &quot;)&quot; )
    elseif Result == HK_2 then
        set No = No + 1
        call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,3.5, NoColor + GetPlayerName(TPlayer) + &quot; has voted no. (&quot; + I2S(AllVote) + &quot;/&quot; + I2S(CountPlayers) + &quot;)&quot; )
    elseif Result == HK_3 then
        call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,3.5, NoColor + GetPlayerName(TPlayer) + &quot; will not vote. (&quot; + I2S(AllVote) + &quot;/&quot; + I2S(CountPlayers) + &quot;)&quot; )
    endif
    
        if AllVote == CountPlayers then
            set Counter = 0
            call PauseTimer( Timer )
            call TimerStart( Timer, SECONDS_BETWEEN_VOTES, false, function AllowVote )
            call ClearTextMessages()
            call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,2.5, &quot;|cFFC0C000Vote Count:|r&quot;+YesColor +&quot; Yes: &quot;+I2S(Yes)+&quot;|r&quot;+NoColor+&quot; No: &quot;+I2S(No)+&quot;|r Null: &quot;+I2S(CountPlayers-(Yes+No)) )
            
            if Yes &gt; No then
                set IsPlayerGone[WhichPlayer] = true
                call CustomDefeatBJ(Player(WhichPlayer), &quot;You have been kicked.&quot;)
                call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,2., GetPlayerName(Player(WhichPlayer)) + &quot; has been kicked.&quot; )
            else
                call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,2., GetPlayerName(Player(WhichPlayer)) + &quot; will not be kicked.&quot; )
            endif
        endif
endfunction

//===========================================================================
private function Vote takes nothing returns nothing
    //Dialogs
    if Dlog == 0 then
        set Dlog = Dialog.create()
        call Dlog.AddButton( &quot;Yes&quot;, HK_1 ) 
        call Dlog.AddButton( &quot;No&quot;, HK_2 )
        call Dlog.AddButton( &quot;Not Voting&quot;, HK_3 )
        call Dlog.AddAction(function VoteAction)
    endif
    call Dlog.SetMessage(&quot;Kick &quot; + GetPlayerName(Player(WhichPlayer)) + &quot;?&quot;)
    call Dlog.ShowAll()
endfunction

//===========================================================================
private function RequestAction takes nothing returns nothing
    local integer Result = Dlog2.GetResult()  //Dialogs
    local integer Count = 0
    local player TPlayer = GetTriggerPlayer()
    
    loop
        if Result == HK_A+Count then
            set WhichPlayer = Count
            if IsPlayerGone[WhichPlayer] == true then
                call DisplayTimedTextToPlayer(TPlayer, 0,0,1.,&quot;|c00FF0000Player(&quot; + I2S(WhichPlayer+1) + &quot;) is not playing!&quot;)
                set Running = false
                exitwhen Count == Count
            else
                call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,2., GetPlayerName(TPlayer) + &quot; has requested to kick player &quot; + I2S(WhichPlayer+1) + &quot;.&quot;)
                call Vote()
                exitwhen Count == Count
            endif
        endif
        set Count = Count + 1
    endloop
    
    if Result == HK_ESC then
        call AllowVote()
    else
        call TimerStart( Timer, 1., true, function VotingLimit )
    endif
endfunction

//===========================================================================
private function Request takes nothing returns nothing
    local integer Count = -1
    local player TPlayer = GetTriggerPlayer()
    
    if not Running then
        set Running = true
    
        if Dlog2 == 0 then
            set Dlog2 = Dialog.create()
            call Dlog2.AddAction(function RequestAction)
    
            loop
                set Count = Count + 1
                if GetPlayerSlotState(Player(Count)) == PLAYER_SLOT_STATE_PLAYING then
                    call Dlog2.AddButton( GetPlayerName(Player(Count)), HK_A+Count )
                endif
                exitwhen Count == 11
            endloop
            call Dlog2.AddButton( &quot;Esc&quot;, HK_ESC )
        endif
    
        call Dlog2.Show(TPlayer)
    else
         //This is the only reason why I have a global timer.
        call DisplayTimedTextToPlayer(TPlayer, 0,0,1.,&quot;|c00FF0000Please wait &quot; + I2S(R2I(TimerGetRemaining(Timer)+0.5)) + &quot; more seconds to request a new vote.&quot;)
    endif   
endfunction

//===========================================================================
private function PlayerGone takes nothing returns nothing
    set CountPlayers = CountPlayers-1
    set IsPlayerGone[GetPlayerId(GetTriggerPlayer())] = true
endfunction

public function InitTrig takes nothing returns nothing
    local trigger trig = CreateTrigger()
    local integer count = 12
    
    //----------------------
    if RedOnly then
        call TriggerRegisterPlayerChatEvent( trig, Player(0), &quot;-Votekick&quot;, true )
        
        loop
            set count = count - 1
        
                if GetPlayerSlotState(Player(count)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(count)) == MAP_CONTROL_USER then
                    set CountPlayers = CountPlayers + 1
                else
                    set IsPlayerGone[count] = true
                endif
            
            exitwhen count == 0
        endloop
    else
    
        loop
            set count = count - 1
            call TriggerRegisterPlayerChatEvent( trig, Player(count), &quot;-Votekick&quot;, true )
        
                if GetPlayerSlotState(Player(count)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(count)) == MAP_CONTROL_USER then
                    set CountPlayers = CountPlayers + 1
                else
                    set IsPlayerGone[count] = true
                endif
            
            exitwhen count == 0
        endloop
    endif
    call TriggerAddAction(trig, function Request)
    
    //-----------------------
    set trig = CreateTrigger()
    loop
        call TriggerRegisterPlayerEvent(trig, Player(count), EVENT_PLAYER_LEAVE)
        set count = count + 1
        exitwhen count == 12
    endloop
    call TriggerAddAction(trig, function PlayerGone)
endfunction

endlibrary


Dialog System:
JASS:
//==============================================================================
//                    DIALOG SYSTEM BY COHADAR -- v2.1b
//==============================================================================
//
//  PURPOUSE:
//       * Displaying dialogs the easy way
//       * Retrieving dialog results the easy way
//
//
//  HOW TO USE:
//       * Dialog is basically a struct wrapper around native dialog 
//
//       * First create a dialog,
//            # local Dialog d = NewDialog()
//
//         than we add a title,
//            # call d.SetMessage(&quot;Some Text&quot;)
//
//         and than we add couple of buttons
//            #	call d.AddButton(&quot;First Button&quot;,  HK_A)
//            #	call d.AddButton(&quot;Second Button&quot;, HK_B)
//            #	call d.AddButton(&quot;Third&quot;,         HK_C)
//
//         HK_X is a hotkey constant for a button,
//         there are constants for all letters + numbers 0..9
//         hotkeys are not case-sensitive
//
//         now we add a callback method for our dialog
//            # call d.AddAction( function SomeFunction )
//         this is the function witch will be called when a player presses a button
//
//         And finally we show the dialog in one of two ways:
//            # call d.ShowAll()      // Displays dialog to all human players
//            # call d.Show( player ) // Displays dialog to specified player
//
//         Inside your callback function you can get the clicked Dialog struct like this
//         local Dialog d = GetTriggerDialog() 
//         and then use d.GetResult() to get the hotkey of a clicked button
//
//         You can also use GetTriggerPlayer() to find out witch player pressed the button
//
//  PROS: 
//       * Extremelly easy to use compared to native dialogs
//       * It is fool-proof and will warn you if you try to do something stupid
//
//  CONS:
//       * You can have a maximum of 16 dialog buttons, lol 
//
//  DETAILS:
//
//       * Don&#039;t release Dialogs before you are sure user has selected something
//         I recommend to never destroy Dialogs, 
//         just create them when they are first time called and then show/hide them as needed
//         
//  REQUIREMENTS:
//       * ABC v5.1 or higher
//
//  HOW TO IMPORT:
//       * Just create a trigger named Dialogs
//       * convert it to text and replace the whole trigger text with this one
//
//==============================================================================
library Dialogs uses ABC

globals
    // Dialog button hotkey constants
    constant integer HK_ESC = 512
    
    constant integer HK_0 = 48
    constant integer HK_1 = 49
    constant integer HK_2 = 50
    constant integer HK_3 = 51
    constant integer HK_4 = 52
    constant integer HK_5 = 53
    constant integer HK_6 = 54
    constant integer HK_7 = 55
    constant integer HK_8 = 56
    constant integer HK_9 = 57
    
    constant integer HK_A = 65
    constant integer HK_B = 66
    constant integer HK_C = 67
    constant integer HK_D = 68
    constant integer HK_E = 69
    constant integer HK_F = 70
    constant integer HK_G = 71
    constant integer HK_H = 72
    constant integer HK_I = 73
    constant integer HK_J = 74
    constant integer HK_K = 75
    constant integer HK_L = 76
    constant integer HK_M = 77
    constant integer HK_N = 78
    constant integer HK_O = 79
    constant integer HK_P = 80
    constant integer HK_Q = 81
    constant integer HK_R = 82
    constant integer HK_S = 83
    constant integer HK_T = 84
    constant integer HK_U = 85
    constant integer HK_V = 86
    constant integer HK_W = 87
    constant integer HK_X = 88
    constant integer HK_Y = 89
    constant integer HK_Z = 90
endglobals

globals
    private constant integer MAX_BUTTONS = 16 // maximum of buttons on dialog
endglobals


//===========================================================================
//  Use this inside dialog action function
//===========================================================================
function GetTriggerDialog takes nothing returns Dialog
    return GetDialogStructA(GetClickedDialog()) // ABC
endfunction


//===========================================================================
struct Dialog
    private trigger t = CreateTrigger()
    private dialog  d = DialogCreate()
    private boolean isActionSet = false

    private string messageText = &quot;&quot;
    
    private integer button_count = 0
    private button  array buttons[MAX_BUTTONS]
    private integer array hotkeys[MAX_BUTTONS]
    
    static method create takes nothing returns Dialog
        local Dialog ret = Dialog.allocate()
        call TriggerRegisterDialogEvent( ret.t, ret.d )
        call SetDialogStructA(ret.d, ret) // ABC
        return ret
    endmethod
    
    method onDestroy takes nothing returns nothing
        call DestroyTrigger(.t)
        call ClearDialogStructA(.d) // ABC
        call DialogDestroy(.d)
    endmethod    
    
    method GetResult takes nothing returns integer
        local button b = GetClickedButton()
        local integer i = 0
        loop
            exitwhen i &gt;= MAX_BUTTONS
            if b == this.buttons<i> then
                return this.hotkeys<i>
            endif
            set i = i + 1
        endloop
        call BJDebugMsg(&quot;|c00FF0000ERROR: Unknown dialog hotkey&quot;)
        return 0
    endmethod
    
    method SetMessage takes string messageText returns nothing
        set .messageText = messageText
    endmethod
    
    method AddButton takes string buttonText, integer hotkey returns nothing
        if this.button_count &gt;= MAX_BUTTONS then
            call BJDebugMsg(&quot;|c00FF0000ERROR: Maximum number of dialog buttons is &quot; + I2S(MAX_BUTTONS))
        else
            set this.buttons[this.button_count] = DialogAddButton( this.d,  buttonText , hotkey )
            set this.hotkeys[this.button_count] = hotkey
            set  this.button_count = this.button_count + 1
        endif
    endmethod    
    
    method AddAction takes code actionFunc returns nothing
        if this.isActionSet == true then
            call BJDebugMsg(&quot;|c00FF0000ERROR: Dialog.AddAction - you cannot set more than one dialog action&quot;)
        else
            set this.isActionSet = true
            call TriggerAddAction( this.t, actionFunc )
        endif
    endmethod
    
    method Show takes player whichPlayer returns nothing
        if this.isActionSet == false then
            call BJDebugMsg(&quot;|c00FF0000WARNING: You forgot to set a dialog action&quot;)
        endif
        if this.button_count == 0 then
            call BJDebugMsg(&quot;|c00FF0000ERROR: You cannot show dialog with no buttons&quot;)
        else
            // message must be set before every display because of some bug.
            call DialogSetMessage( this.d, this.messageText )
            call DialogDisplay(whichPlayer, this.d, true) 
        endif
    endmethod
    
    method ShowAll takes nothing returns nothing
        local integer i = 0
        loop
            exitwhen i&gt;=12 // maximum of human players is 12
            if GetPlayerController(Player(i)) == MAP_CONTROL_USER and GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING  then
                call this.Show(Player(i))            
            endif
            set i = i + 1
        endloop
    endmethod
    
    method Hide takes player whichPlayer returns nothing
        call DialogDisplay(whichPlayer, this.d, false) 
    endmethod

    method HideAll takes nothing returns nothing
        local integer i = 0
        loop
            exitwhen i&gt;=12 // maximum of human players is 12
                call this.Hide(Player(i))            
            set i = i + 1
        endloop
    endmethod
    
endstruct

endlibrary</i></i>


ABC System:

JASS:
//==============================================================================
//  ABC -- STRUCT ATTACHMENT SYSTEM BY COHADAR -- v5.1b
//==============================================================================



//==============================================================================
//  Quick function index:
//==============================================================================
//
//    ----------------------------------------------------------------------
//      Set Functions - these functions attach struct to a handle
//    ----------------------------------------------------------------------
//    SetTimerStructA(timer, struct)
//    SetTimerStructB(timer, struct)
//    SetTimerStructC(timer, struct)
//
//    SetTriggerStructA(trigger, struct)
//    SetTriggerStructB(trigger, struct)
//    SetTriggerStructC(trigger, struct)
//
//    SetDialogStructA(dialog, struct)
//    SetDialogStructB(dialog, struct)
//    SetDialogStructC(dialog, struct)
//
//    ----------------------------------------------------------------------
//      Get Functions - these functions retrieve attached structs
//    ----------------------------------------------------------------------
//    GetTimerStructA(timer) -&gt; struct
//    GetTimerStructB(timer) -&gt; struct
//    GetTimerStructC(timer) -&gt; struct
//
//    GetTriggerStructA(trigger) -&gt; struct
//    GetTriggerStructB(trigger) -&gt; struct
//    GetTriggerStructC(trigger) -&gt; struct
//
//    GetDialogStructA(dialog) -&gt; struct
//    GetDialogStructB(dialog) -&gt; struct
//    GetDialogStructC(dialog) -&gt; struct
//
//    ----------------------------------------------------------------------
//      Clear Functions - these functions clear and return attached value
//    ----------------------------------------------------------------------
//    ClearTimerStructA(timer) -&gt; struct
//    ClearTimerStructB(timer) -&gt; struct
//    ClearTimerStructC(timer) -&gt; struct
//
//    ClearTriggerStructA(trigger) -&gt; struct
//    ClearTriggerStructB(trigger) -&gt; struct
//    ClearTriggerStructC(trigger) -&gt; struct
//
//    ClearDialogStructA(dialog) -&gt; struct
//    ClearDialogStructB(dialog) -&gt; struct
//    ClearDialogStructC(dialog) -&gt; struct
//
//==============================================================================




//==============================================================================
//  DOCUMENTATION:
//==============================================================================
//
//  PURPOUSE OF ABC:
//       * Attaching multiple structs to a &lt;handle&gt;
//       * Not using stupid game cache.
//      
//       * Currently supported &lt;handle&gt; types are timer, trigger and dialog
//         ABC can NOT be used to attach things to units,
//         Systems that can attach stuff to units require a mission key
//         ABC does not have mission keys, witch is one of the reasons it is so fast.
//
//       * These are the only 3 handle types I found that need attaching (except units)
//         If you have the need for some other handle types please let me know
//
//  HOW TO USE:
//       * Lets assume you want to attach some spell data to a timer.
//         You would do the following:
//
//         1. Create struct that will contain all your data.
//         2. call SetTimerStructA(myTimer, myStruct) 
//
//         and then you decide you need one more struct on that timer...
// 
//         call SetTimerStructB(myTimer, myStruct2) 
//
//         Then in a periodic timer you just get the stored value
//         set myStruct = GetTimerStructA(myTimer)
//     
//         In your final itearation of periodic timer
//         you need to clear stored values
//         ClearTimerStructA(myTimer)
//         ClearTimerStructB(myTimer)
//         If you don&#039;t system will start to overflow
//
//  DIFFERENCE FROM v5.0:
//       * You cannot use SetStructA two times on the same &lt;handle&gt;
//         without clearing the previous value. 
//
//       * ABC v5.0 used to overwrite the old values when you did that.
//         This caused errors when collisions get over 3
//         Since collisions almost never happen in real maps noone noticed this before
//         Only some hardcore tests will detect this
//         
//       * New version of ABC treats overwrite as an error.
//         BAD:  SetStructA(X, value1); SetStructA(X, value2) 
//         GOOD: SetStructA(X, value1); ClearStructA(X); SetStructA(X, value2)
//
//       * HASH_COLLISION_LIMIT is reduced from 8 to 7 to simplyfy algorithms
//         (using null borders at modulo 8)
//         This effectively means that you can store around 6000 attachments per hash
//         before you get an overflow. (used to be 7000)
//         
//       * This simplyfication increased ABC speed a little.
//
//  PROS: 
//       * ABC is faster than any gamecache based system.
//
//       * you can attach any struct to any supported &lt;handle&gt; type
//
//       * you CAN attach up to 3 structs on the same &lt;handle&gt;
//         but only if you use different functions, for example
//         SetTriggerStructA(), SetTriggerStructB(), SetTriggerStructC()
//         
//       * get and set functions are extremelly fast (using hash algorithm)
//
//       * System reports collision, overwrite and overflow.
//         Basically if you do anything stupid system will tell you.
//
//       * This system will work even if your map leaks
//         and will NOT slow down because of it.
//
//       * This is the system that spits torment test in the eye.
//
//       * For compatibility with ABC v4.6 look at ABCC library
//         
//
//  CONS:
//       * you must manually clean the stored value - REMEMBER THIS RULE!!!
//         Don&#039;t forget to use ClearStruct() functions
//
//       * you should NOT use Get without a Set - REMEMBER THIS RULE!!!  
//         It will simply return a zero and nothing bad will happen,
//         but it will lag really really bad
//         (system will report this as an error)
//
//       * System starts to collide if you have more than 1024 structs in one hash.
//         (you can see this very obviosly with -overload test)
//         If that happens it can mean one of 2 things:
//           1. you are using more than 1024 timers, triggers or dialogs - !?
//           2. you forgot to use ClearStruct and you are leaking handles somewhere
//             if this is the case simply do a search on your code and find
//             what trigger uses ABC but has no ClearStruct calls.
//
//  DETAILS:
//       * when struct is detached from &lt;handle&gt; it is not destroyed
//         you still have to do that manually if necessary
//
//       * ABC will not interfere with other attachemt systems
//         You can freely use any other system alongside ABC
//         But if you use only ABC for attachments in your map
//         you don&#039;t have to null local variables.
//         The reason for this is that gamecache gets abnormaly slow
//         when you don&#039;t null locals, ABC does not have this flaw.
//
//
//  SPECIAL THANKS TO: 
//       * NagelBagel - for finding errors in versions 4.3 and 4.4
//       * Here-b-Trollz - for testing ABC and for making cool spells with it.
//       * Toadcop - for being pain in the ass and for pushing me to improve ABC.
//       * emjlr3 - for pointing out the need for non-generic trigger attachments
//       * PandaMine - I found a bug in ABC by examining his HSAS vs ABC test
//       * All those people out there who use and support ABC
//         Thank you guys.
//
//  HOW TO IMPORT:
//       * Just create a trigger named ABC
//       * convert it to text and replace the whole trigger text with this one
//
//==============================================================================


//------------------------------------------------------------------------------
//  We will use textmacros to create multiple instances of system
//------------------------------------------------------------------------------
//! textmacro ABC takes X, NAME, TYPE

//------------------------------------------------------------------------------
// Global arrays represent our hash tables.
// System is currently using 3 hash tables per handle type. (A, B, C)
//------------------------------------------------------------------------------
globals
    private $TYPE$    array $TYPE$Key$X$
    private integer  array $TYPE$Value$X$
	private integer  $TYPE$maxCollision$X$ = 0
endglobals

//------------------------------------------------------------------------------
// returns the maximum collision so far
//------------------------------------------------------------------------------
function Get$NAME$Collision$X$ takes nothing returns integer
    return $TYPE$maxCollision$X$
endfunction


//------------------------------------------------------------------------------
// initializes hash arrays to prevent lag when ABC is used for the first time
//------------------------------------------------------------------------------
private function Init$NAME$Hash$X$ takes nothing returns nothing
    set $TYPE$Key$X$[HASH_INDEX_LIMIT]   = null
	set $TYPE$Value$X$[HASH_INDEX_LIMIT] = 0
endfunction

//------------------------------------------------------------------------------
// attaches struct to a handle by using hash table
//------------------------------------------------------------------------------
function Set$NAME$Struct$X$ takes $TYPE$ t, integer s returns nothing
	debug local integer collision
	
	// hash using 32-bit integer overflow
    local integer i = (H2I(t) * HASH_UP) / HASH_DOWN + HASH_BIAS

	if $TYPE$Key$X$<i> == null then
	    set $TYPE$Value$X$<i> = s
		set $TYPE$Key$X$<i> = t
		return
	endif

    debug if $TYPE$Key$X$<i> == t then
        debug call BJDebugMsg(&quot;|cFFFF0000ERROR: $NAME$_Hash[$X$] attachment overwrite on #&quot; +I2S(H2I(t)))
        debug return
    debug endif        
    
	// if function gets below this line we have a collision
    debug set collision = 1
    loop
		debug if collision &gt;= HASH_COLLISION_LIMIT then
            debug call BJDebugMsg(&quot;|cFFFF0000ERROR: $NAME$_Hash[$X$] overflow&quot;)
            debug return
		debug endif    
        debug set collision = collision + 1
    
        set i = i + 1    
	    exitwhen $TYPE$Key$X$<i> == null

        debug if $TYPE$Key$X$<i> == t then
            debug call BJDebugMsg(&quot;|cFFFF0000ERROR: $NAME$_Hash[$X$] attachment overwrite on #&quot; +I2S(H2I(t)))
            debug return
        debug endif    
	endloop

	debug if collision &gt; $TYPE$maxCollision$X$ then
	debug 	call BJDebugMsg(&quot;|cFFFF4444Warning: $NAME$_Hash[$X$] maximum collision is now: &quot; + I2S(collision))
	debug 	set $TYPE$maxCollision$X$ = collision
	debug endif
	
    set $TYPE$Value$X$<i> = s
    set $TYPE$Key$X$<i> = t

    return
endfunction

//------------------------------------------------------------------------------
// gets stored struct from a handle 
//------------------------------------------------------------------------------
function Get$NAME$Struct$X$ takes $TYPE$ t returns integer
	debug local integer collision
	
	// hash using 32-bit integer overflow
    local integer i = (H2I(t) * HASH_UP) / HASH_DOWN + HASH_BIAS
	
	if $TYPE$Key$X$<i> == t then
		return $TYPE$Value$X$<i>
	endif
	
	// if function gets below this line we have a collision
    debug set collision = 1
    loop
		debug if collision &gt;= HASH_COLLISION_LIMIT then
		debug   call BJDebugMsg(&quot;|cFFFF0000ERROR: $NAME$_Hash[$X$] : get request on unknown handle&quot;)
		debug   return 0
		debug endif		
        debug set collision = collision + 1      
    
        set i = i + 1
	    exitwhen $TYPE$Key$X$<i> == t
	endloop	
	
    return $TYPE$Value$X$<i>
endfunction


//------------------------------------------------------------------------------
// clears stored struct from a handle, also returns cleared value
//------------------------------------------------------------------------------
function Clear$NAME$Struct$X$ takes $TYPE$ t returns integer
	debug local integer collision
    local integer ik
    local integer ret
	
	// hash using 32-bit integer overflow
    local integer i = (H2I(t) * HASH_UP) / HASH_DOWN + HASH_BIAS
	
    // first find the index on witch key is stored
    debug set collision = 0
    loop
		debug if collision &gt;= HASH_COLLISION_LIMIT then
		debug   call BJDebugMsg(&quot;|cFFFF0000ERROR: $NAME$_Hash[$X$] : clear request on unknown handle&quot;)
		debug   return 0
		debug endif        
        debug set collision = collision + 1       
    
        exitwhen $TYPE$Key$X$<i> == t
        set i = i + 1
    endloop
    
    set ik = i
    set ret = $TYPE$Value$X$[ik]
    
    // then find last used key index in bucket
    loop
        set i = i + 1
        // we use the fact bucket borders (mod 8 indexes) are always null
        exitwhen $TYPE$Key$X$<i> == null  
    endloop
    
    // shift last bucket entry to the place of removed one
    set $TYPE$Key$X$[ik] = $TYPE$Key$X$[i-1]
    set $TYPE$Value$X$[ik] = $TYPE$Value$X$[i-1]
    // clear the previous last bucket entry
    set $TYPE$Key$X$[i-1] = null
    
    return ret
endfunction

//! endtextmacro

//==============================================================================
//  Macro execution -- this is where real functions get created
//==============================================================================
library ABC initializer Init

globals
	public constant integer HASH_SIZE = 8192
	public constant integer HASH_INDEX_LIMIT = 8190
	public constant integer HASH_DOWN = 524288     // 2^19	
	public constant integer HASH_UP   = 2134900736 // 2^22 * 509
	public constant integer HASH_BIAS = 4096       // HASH_SIZE / 2
	public constant integer HASH_COLLISION_LIMIT = 7 // ABC v5.0 had limit 8
	// 509 is the prime closest to 512
endglobals


//------------------------------------------------------------------------------
// conversion function used by the system internally
// you will not need to use it directly
//------------------------------------------------------------------------------
public function H2I takes handle h returns integer
    return h
    return 0
endfunction

//! runtextmacro ABC(&quot;A&quot;,&quot;Timer&quot;,&quot;timer&quot;)
//! runtextmacro ABC(&quot;B&quot;,&quot;Timer&quot;,&quot;timer&quot;)
//! runtextmacro ABC(&quot;C&quot;,&quot;Timer&quot;,&quot;timer&quot;)

//! runtextmacro ABC(&quot;A&quot;,&quot;Trigger&quot;,&quot;trigger&quot;)
//! runtextmacro ABC(&quot;B&quot;,&quot;Trigger&quot;,&quot;trigger&quot;)
//! runtextmacro ABC(&quot;C&quot;,&quot;Trigger&quot;,&quot;trigger&quot;)

//! runtextmacro ABC(&quot;A&quot;,&quot;Dialog&quot;,&quot;dialog&quot;)
//! runtextmacro ABC(&quot;B&quot;,&quot;Dialog&quot;,&quot;dialog&quot;)
//! runtextmacro ABC(&quot;C&quot;,&quot;Dialog&quot;,&quot;dialog&quot;)

private function Init takes nothing returns nothing
	call InitTimerHashA()
	call InitTimerHashB()
	call InitTimerHashC()

	call InitTriggerHashA()
	call InitTriggerHashB()
	call InitTriggerHashC()       
    
	call InitDialogHashA()
	call InitDialogHashB()
	call InitDialogHashC()
endfunction


endlibrary
//==============================================================================
//  END OF ABC STRUCT ATTACHMENT SYSTEM
//==============================================================================
</i></i></i></i></i></i></i></i></i></i></i></i></i></i>


Changelog:
Code:
<<---  v1.00D --->>
   * Now uses a Dialog instead of text to pick a player
      (I am keeping the text version for those who like it better)
   * Can no longer kick Computers (Doesn't matter anyway)

<<---  v1.11 --->>
   * 1 possible bug fix
   * Few text changes
   * Added a null vote

<<---  v1.01  --->>
   * 2 bug fixes

<<---  v1.00  --->>
   * Initial Release

I'm aware there are extra systems in the demo. It might by just a tad tough to test a kick system on a demo map. :)
 

Attachments

  • Joker(Div) - VoteKick(Jass).w3x
    61.5 KB · Views: 260
  • Joker(Div) - VoteKick-Dialog(Jass).w3x
    62.4 KB · Views: 261

Andrewgosu

The Silent Pandaren Helper
Reaction score
716
What if I want to kick the player by typing in the colour or the name of the player?
 

Cohadar

master of fugue
Reaction score
209
LoL typing systems are too complicated to use.

Here is a better idea.

1. Host types: "-votekick"
2. A dialog appears listing all players
3. Host selects one noob from the dialog to be voted for kicking
4. All players (including the host and the noob player) get the yes/no dialog.
 

emjlr3

Change can be a good thing
Reaction score
395
maybe there should be a null vote option
and a cd between when a player requests, and the next time he can do so

not bad though
 

Joker(Div)

Always Here..
Reaction score
86
What if I want to kick the player by typing in the colour or the name of the player?
Uh...too bad?

LoL typing systems are too complicated to use.

Here is a better idea.
But that limits the requesting only to the host.

yes -1
no +1
cancel 0

Add up the results and if the player gets below zero kick it.
I'll look into this.

Oh definitely, I would even go with: every player can request a votekick but only once in a game.
I have a cd (that you can edit) between requests.
 

emjlr3

Change can be a good thing
Reaction score
395
that is period, I figured one for each player, why cant 8 try right after 4? though maybe that is better :p
 

Joker(Div)

Always Here..
Reaction score
86
Well, I don't see the purpose of letting player 4 requesting right have 8. You can always wait. :p

Edit: I need some math help

How do you find 2 numbers that are X numbers apart that adds up to X number of player?

I tried (TotalPlayers/2) - (X numbers apart/2)
and (TotalPlayers/2) + (X numbers apart/2)

But they only work when Totalplayers is an even number. :( I'm trying to find the Yes/no ratio using Cohadar's method.

Edit2: Well, I got everything else pretty much working and fine. I just need this math equation, and hopefully this will be approved.
 

Cohadar

master of fugue
Reaction score
209
Typing in the player name and/or color is a lame option when you can do it very easily with dialogs.

Seriously man why would anyone prefer typing -kick "some ugly R4Z0rltt177 name" over selecting a player from a list.

Just do it as I described earlier, don't be a lazy ass.
 

Joker(Div)

Always Here..
Reaction score
86
Fine, I'll change it over to a dialog tomorrow when i got some time.

There's not that much diff between -kick player # vs -votekick anyway.
 

Joker(Div)

Always Here..
Reaction score
86
Well, I added a Dialog version like you asked, Cohadar, but I think its efficiency went down quite a bit. I had a little trouble with the loops.

NEW UPDATE 3/22/08
 

Dem0n_Hunter

Active Member
Reaction score
2
Hi, there. this is an awsome system. but is it possible for the kicked player's units all be removed too? can someone tell me how to do it?
 

Joker(Div)

Always Here..
Reaction score
86
JASS:
//==============================================================================
//                    VOTEKICK SYSTEM BY JOKER(DIV) -- v1.00D
//==============================================================================
//
//  PURPOSE:
//       * To kick annoying players with majority vote.
//
//
//  HOW TO USE:
//       * My Vote Kick system is just a simple trigger.
//         
//       * Just Type: &quot;-votekick&quot; and a Dialog will show with a list of all players
//                     Select the player you wish to kick, and a vote box will appear
//                     for all players
//        
//       * Everyone is able to request a kick. (Can be configurable)          
//
//  PROS: 
//       * Extremelly easy to use
//       * Somewhat configurable (not that you need to anyway...)
//
//  CONS:
//       * Limited to a certain extent. (I suppose...)
//
//  CREDITS:
//       * Cohadar (I Stole this outline from him <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />)
//       * Cohadar (Yes, he deserves to be written twice)
//       * All you darn GUI&#039;ers, enough GUI already <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite7" alt=":p" title="Stick Out Tongue    :p" loading="lazy" data-shortname=":p" />
//         
//  REQUIREMENTS:
//       * Dialogs system by Cohadar (Requires ABC)
//       * NewGen Editor by Vexorian/PitzerMike
//
//  HOW TO IMPORT:
//       * Just create a trigger named VK
//       * convert it to text and replace the whole trigger text with this one
//
//==============================================================================
library VK uses Dialogs

globals
    //====================================
    private constant real   SECONDS_BETWEEN_VOTES   = 30.         //Time between a votes
    private constant real   SECONDS_ALLOWED_TO_VOTE = 10.        //Time given to vote

    private constant string YesColor                = &quot;|cFFFF0000&quot;          
    private constant string NoColor                 = &quot;|cFF00FF00&quot;
    
    private boolean RedOnly = false  //Only allows red to request.
    //====================================
    
    
    //I set it to 16 since Player(16) doesn&#039;t exist, incase this bugs...somehow.
    private integer WhichPlayer = 16
    
    private Dialog Dlog = 0 //Dialogs
    private Dialog Dlog2 = 0 //Dialogs
    private boolean Running = false
    private boolean array IsPlayerGone
    
    private group KickedUnits = null
    
    private integer AllVote = 0
    private integer Yes = 0
    private integer No = 0
    
    private integer Counter = 0
    
    private timer Timer = CreateTimer()
    
    //Maybe you can find this global useful.
    public integer CountPlayers = 0
endglobals

private function KickedUnit_Filter takes nothing returns boolean
    return true //Add what type of units of the kicked player you want to get 
                //rid of.
endfunction

//===========================================================================
private function AllowVote takes nothing returns nothing
    //Have to set everything back to default
    set Running = false
    set Counter = 0
    set AllVote = 0
    set Yes = 0
    set No = 0
    call PauseTimer(Timer)
endfunction

//===========================================================================
private function VotingLimit takes nothing returns nothing
    set Counter = Counter + 1
    
    if SECONDS_ALLOWED_TO_VOTE &lt;= Counter then
        call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,5.,&quot;|c00FF0000Time has run out to vote. Vote canceled.&quot; )
        call Dlog.HideAll()
        call Dlog2.HideAll()
        call PauseTimer( Timer )
        call TimerStart( Timer, SECONDS_BETWEEN_VOTES, false, function AllowVote )
    endif
endfunction

//===========================================================================
private function RemoveUnits takes nothing returns nothing
    call RemoveUnit( GetEnumUnit() )
    //call KillUnit( GetEnumUnit() ) You can kill the unit if you dont want to
    //                               use RemoveUnit
endfunction

private function VoteAction takes nothing returns nothing
    local integer Result = Dlog.GetResult()  //Dialogs
    local player TPlayer = GetTriggerPlayer()
    set AllVote = AllVote + 1
    call Dlog.Hide(TPlayer) //Dialogs
    
    if Result == HK_1 then
        set Yes = Yes + 1
        call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,3.5, YesColor + GetPlayerName(TPlayer) + &quot; has voted yes. (&quot; + I2S(AllVote) + &quot;/&quot; + I2S(CountPlayers) + &quot;)&quot; )
    elseif Result == HK_2 then
        set No = No + 1
        call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,3.5, NoColor + GetPlayerName(TPlayer) + &quot; has voted no. (&quot; + I2S(AllVote) + &quot;/&quot; + I2S(CountPlayers) + &quot;)&quot; )
    elseif Result == HK_3 then
        call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,3.5, NoColor + GetPlayerName(TPlayer) + &quot; will not vote. (&quot; + I2S(AllVote) + &quot;/&quot; + I2S(CountPlayers) + &quot;)&quot; )
    endif
    
        if AllVote == CountPlayers then
            set Counter = 0
            call PauseTimer( Timer )
            call TimerStart( Timer, SECONDS_BETWEEN_VOTES, false, function AllowVote )
            call ClearTextMessages()
            call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,2.5, &quot;|cFFC0C000Vote Count:|r&quot;+YesColor +&quot; Yes: &quot;+I2S(Yes)+&quot;|r&quot;+NoColor+&quot; No: &quot;+I2S(No)+&quot;|r Null: &quot;+I2S(CountPlayers-(Yes+No)) )
            
            if Yes &gt; No then
                set IsPlayerGone[WhichPlayer] = true
                
                call GroupEnumUnitsOfPlayer( KickedUnits, Player(WhichPlayer), Condition(function KickedUnit_Filter) )
                call ForGroup( KickedUnits, function RemoveUnits )
                
                call CustomDefeatBJ(Player(WhichPlayer), &quot;You have been kicked.&quot;)
                call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,2., GetPlayerName(Player(WhichPlayer)) + &quot; has been kicked.&quot; )
            else
                call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,2., GetPlayerName(Player(WhichPlayer)) + &quot; will not be kicked.&quot; )
            endif
        endif
endfunction

//===========================================================================
private function Vote takes nothing returns nothing
    //Dialogs
    if Dlog == 0 then
        set Dlog = Dialog.create()
        call Dlog.AddButton( &quot;Yes&quot;, HK_1 ) 
        call Dlog.AddButton( &quot;No&quot;, HK_2 )
        call Dlog.AddButton( &quot;Not Voting&quot;, HK_3 )
        call Dlog.AddAction(function VoteAction)
    endif
    call Dlog.SetMessage(&quot;Kick &quot; + GetPlayerName(Player(WhichPlayer)) + &quot;?&quot;)
    call Dlog.ShowAll()
endfunction

//===========================================================================
private function RequestAction takes nothing returns nothing
    local integer Result = Dlog2.GetResult()  //Dialogs
    local integer Count = 0
    local player TPlayer = GetTriggerPlayer()
    
    loop
        if Result == HK_A+Count then
            set WhichPlayer = Count
            if IsPlayerGone[WhichPlayer] == true then
                call DisplayTimedTextToPlayer(TPlayer, 0,0,1.,&quot;|c00FF0000Player(&quot; + I2S(WhichPlayer+1) + &quot;) is not playing!&quot;)
                set Running = false
                exitwhen Count == Count
            else
                call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,2., GetPlayerName(TPlayer) + &quot; has requested to kick player &quot; + I2S(WhichPlayer+1) + &quot;.&quot;)
                call Vote()
                exitwhen Count == Count
            endif
        endif
        set Count = Count + 1
    endloop
    
    if Result == HK_ESC then
        call AllowVote()
    else
        call TimerStart( Timer, 1., true, function VotingLimit )
    endif
endfunction

//===========================================================================
private function Request takes nothing returns nothing
    local integer Count = -1
    local player TPlayer = GetTriggerPlayer()
    
    if not Running then
        set Running = true
    
        if Dlog2 == 0 then
            set Dlog2 = Dialog.create()
            call Dlog2.AddAction(function RequestAction)
    
            loop
                set Count = Count + 1
                if GetPlayerSlotState(Player(Count)) == PLAYER_SLOT_STATE_PLAYING then
                    call Dlog2.AddButton( GetPlayerName(Player(Count)), HK_A+Count )
                endif
                exitwhen Count == 11
            endloop
            call Dlog2.AddButton( &quot;Esc&quot;, HK_ESC )
        endif
    
        call Dlog2.Show(TPlayer)
    else
         //This is the only reason why I have a global timer.
        call DisplayTimedTextToPlayer(TPlayer, 0,0,1.,&quot;|c00FF0000Please wait &quot; + I2S(R2I(TimerGetRemaining(Timer)+0.5)) + &quot; more seconds to request a new vote.&quot;)
    endif   
endfunction

//===========================================================================
private function PlayerGone takes nothing returns nothing
    set CountPlayers = CountPlayers-1
    set IsPlayerGone[GetPlayerId(GetTriggerPlayer())] = true
endfunction

public function InitTrig takes nothing returns nothing
    local trigger trig = CreateTrigger()
    local integer count = 12
    
    set KickedUnits = CreateGroup()
    
    //----------------------
    if RedOnly then
        call TriggerRegisterPlayerChatEvent( trig, Player(0), &quot;-Votekick&quot;, true )
        
        loop
            set count = count - 1
        
                if GetPlayerSlotState(Player(count)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(count)) == MAP_CONTROL_USER then
                    set CountPlayers = CountPlayers + 1
                else
                    set IsPlayerGone[count] = true
                endif
            
            exitwhen count == 0
        endloop
    else
    
        loop
            set count = count - 1
            call TriggerRegisterPlayerChatEvent( trig, Player(count), &quot;-Votekick&quot;, true )
        
                if GetPlayerSlotState(Player(count)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(count)) == MAP_CONTROL_USER then
                    set CountPlayers = CountPlayers + 1
                else
                    set IsPlayerGone[count] = true
                endif
            
            exitwhen count == 0
        endloop
    endif
    call TriggerAddAction(trig, function Request)
    
    //-----------------------
    set trig = CreateTrigger()
    loop
        call TriggerRegisterPlayerEvent(trig, Player(count), EVENT_PLAYER_LEAVE)
        set count = count + 1
        exitwhen count == 12
    endloop
    call TriggerAddAction(trig, function PlayerGone)
endfunction

endlibrary


I did a rough edit through notepad. I don't know if it'll compile, hopefully it will.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Varine Varine:
    How can you tell the difference between real traffic and indexing or AI generation bots?
  • The Helper The Helper:
    The bots will show up as users online in the forum software but they do not show up in my stats tracking. I am sure there are bots in the stats but the way alot of the bots treat the site do not show up on the stats
  • Varine Varine:
    I want to build a filtration system for my 3d printer, and that shit is so much more complicated than I thought it would be
  • Varine Varine:
    Apparently ABS emits styrene particulates which can be like .2 micrometers, which idk if the VOC detectors I have can even catch that
  • Varine Varine:
    Anyway I need to get some of those sensors and two air pressure sensors installed before an after the filters, which I need to figure out how to calculate the necessary pressure for and I have yet to find anything that tells me how to actually do that, just the cfm ratings
  • Varine Varine:
    And then I have to set up an arduino board to read those sensors, which I also don't know very much about but I have a whole bunch of crash course things for that
  • Varine Varine:
    These sensors are also a lot more than I thought they would be. Like 5 to 10 each, idk why but I assumed they would be like 2 dollars
  • Varine Varine:
    Another issue I'm learning is that a lot of the air quality sensors don't work at very high ambient temperatures. I'm planning on heating this enclosure to like 60C or so, and that's the upper limit of their functionality
  • Varine Varine:
    Although I don't know if I need to actually actively heat it or just let the plate and hotend bring the ambient temp to whatever it will, but even then I need to figure out an exfiltration for hot air. I think I kind of know what to do but it's still fucking confusing
  • The Helper The Helper:
    Maybe you could find some of that information from AC tech - like how they detect freon and such
  • Varine Varine:
    That's mostly what I've been looking at
  • Varine Varine:
    I don't think I'm dealing with quite the same pressures though, at the very least its a significantly smaller system. For the time being I'm just going to put together a quick scrubby box though and hope it works good enough to not make my house toxic
  • Varine Varine:
    I mean I don't use this enough to pose any significant danger I don't think, but I would still rather not be throwing styrene all over the air
  • The Helper The Helper:
    New dessert added to recipes Southern Pecan Praline Cake https://www.thehelper.net/threads/recipe-southern-pecan-praline-cake.193555/
  • The Helper The Helper:
    Another bot invasion 493 members online most of them bots that do not show up on stats
  • Varine Varine:
    I'm looking at a solid 378 guests, but 3 members. Of which two are me and VSNES. The third is unlisted, which makes me think its a ghost.
    +1
  • The Helper The Helper:
    Some members choose invisibility mode
    +1
  • The Helper The Helper:
    I bitch about Xenforo sometimes but it really is full featured you just have to really know what you are doing to get the most out of it.
  • The Helper The Helper:
    It is just not easy to fix styles and customize but it definitely can be done
  • The Helper The Helper:
    I do know this - xenforo dropped the ball by not keeping the vbulletin reputation comments as a feature. The loss of the Reputation comments data when we switched to Xenforo really was the death knell for the site when it came to all the users that left. I know I missed it so much and I got way less interested in the site when that feature was gone and I run the site.
  • Blackveiled Blackveiled:
    People love rep, lol
    +1
  • The Helper The Helper:
    The recipe today is Sloppy Joe Casserole - one of my faves LOL https://www.thehelper.net/threads/sloppy-joe-casserole-with-manwich.193585/
  • The Helper The Helper:
    Decided to put up a healthier type recipe to mix it up - Honey Garlic Shrimp Stir-Fry https://www.thehelper.net/threads/recipe-honey-garlic-shrimp-stir-fry.193595/

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top