• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[vJass]VoteKick System

Level 3
Joined
May 10, 2007
Messages
26
I'm Joker(Div) on the Helper, in case your wondering why my names don't match.

I got tired of all these GUI kick systems, so I decided to make a JASS one myself.

Enjoy. :)

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 :D)
//       * All you darn GUI'ers, enough GUI already :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 = "|cFFFF0000"   //(Unless you know what you are doing.) 
    private constant string NoColor = "|cFF00FF00"
    //====================================
    
    //I set it to 16 since Player(16) doesn'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) + " has voted yes. (" + I2S(AllVote) + "/" + I2S(CountPlayers) + ")" )
    elseif Result == HK_2 then
        set No = No + 1
        call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,3.5, NoColor + GetPlayerName(TPlayer) + " has voted no. (" + I2S(AllVote) + "/" + I2S(CountPlayers) + ")" )
    elseif Result == HK_3 then
        call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,3.5, NoColor + GetPlayerName(TPlayer) + " will not vote. (" + I2S(AllVote) + "/" + I2S(CountPlayers) + ")" )
    endif
    
        if AllVote == CountPlayers then
            call TimerStart( Timer, SECONDS_BETWEEN_VOTES, false, function AllowVote )
            call ClearTextMessages()
            call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,2.5, "|cFFC0C000Vote Count:|r"+YesColor +" Yes: "+I2S(Yes)+"|r"+NoColor+" No: "+I2S(No)+"|r Null: "+I2S(CountPlayers-(Yes+No)) )
            
            if Yes > No then
                call CustomDefeatBJ(Player(WhichPlayer), "You have been kicked.")
                call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,2., GetPlayerName(Player(WhichPlayer)) + " has been kicked." )
            else
                call DisplayTimedTextToForce( bj_FORCE_ALL_PLAYERS,2., GetPlayerName(Player(WhichPlayer)) + " will not be kicked." )
            endif
        endif
endfunction

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

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

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

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("Some Text")
//
//         and than we add couple of buttons
//            #	call d.AddButton("First Button",  HK_A)
//            #	call d.AddButton("Second Button", HK_B)
//            #	call d.AddButton("Third",         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'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 = ""
    
    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 >= MAX_BUTTONS
            if b == this.buttons[i] then
                return this.hotkeys[i]
            endif
            set i = i + 1
        endloop
        call BJDebugMsg("|c00FF0000ERROR: Unknown dialog hotkey")
        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 >= MAX_BUTTONS then
            call BJDebugMsg("|c00FF0000ERROR: Maximum number of dialog buttons is " + 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("|c00FF0000ERROR: Dialog.AddAction - you cannot set more than one dialog action")
        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("|c00FF0000WARNING: You forgot to set a dialog action")
        endif
        if this.button_count == 0 then
            call BJDebugMsg("|c00FF0000ERROR: You cannot show dialog with no buttons")
        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>=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>=12 // maximum of human players is 12
                call this.Hide(Player(i))            
            set i = i + 1
        endloop
    endmethod
    
endstruct

endlibrary
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) -> struct
//    GetTimerStructB(timer) -> struct
//    GetTimerStructC(timer) -> struct
//
//    GetTriggerStructA(trigger) -> struct
//    GetTriggerStructB(trigger) -> struct
//    GetTriggerStructC(trigger) -> struct
//
//    GetDialogStructA(dialog) -> struct
//    GetDialogStructB(dialog) -> struct
//    GetDialogStructC(dialog) -> struct
//
//    ----------------------------------------------------------------------
//      Clear Functions - these functions clear and return attached value
//    ----------------------------------------------------------------------
//    ClearTimerStructA(timer) -> struct
//    ClearTimerStructB(timer) -> struct
//    ClearTimerStructC(timer) -> struct
//
//    ClearTriggerStructA(trigger) -> struct
//    ClearTriggerStructB(trigger) -> struct
//    ClearTriggerStructC(trigger) -> struct
//
//    ClearDialogStructA(dialog) -> struct
//    ClearDialogStructB(dialog) -> struct
//    ClearDialogStructC(dialog) -> struct
//
//==============================================================================




//==============================================================================
//  DOCUMENTATION:
//==============================================================================
//
//  PURPOUSE OF ABC:
//       * Attaching multiple structs to a <handle>
//       * Not using stupid game cache.
//      
//       * Currently supported <handle> 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't system will start to overflow
//
//  DIFFERENCE FROM v5.0:
//       * You cannot use SetStructA two times on the same <handle>
//         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 <handle> type
//
//       * you CAN attach up to 3 structs on the same <handle>
//         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'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 <handle> 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't have to null local variables.
//         The reason for this is that gamecache gets abnormaly slow
//         when you don'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("|cFFFF0000ERROR: $NAME$_Hash[$X$] attachment overwrite on #" +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 >= HASH_COLLISION_LIMIT then
            debug call BJDebugMsg("|cFFFF0000ERROR: $NAME$_Hash[$X$] overflow")
            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("|cFFFF0000ERROR: $NAME$_Hash[$X$] attachment overwrite on #" +I2S(H2I(t)))
            debug return
        debug endif    
	endloop

	debug if collision > $TYPE$maxCollision$X$ then
	debug 	call BJDebugMsg("|cFFFF4444Warning: $NAME$_Hash[$X$] maximum collision is now: " + 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 >= HASH_COLLISION_LIMIT then
		debug   call BJDebugMsg("|cFFFF0000ERROR: $NAME$_Hash[$X$] : get request on unknown handle")
		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 >= HASH_COLLISION_LIMIT then
		debug   call BJDebugMsg("|cFFFF0000ERROR: $NAME$_Hash[$X$] : clear request on unknown handle")
		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("A","Timer","timer")
//! runtextmacro ABC("B","Timer","timer")
//! runtextmacro ABC("C","Timer","timer")

//! runtextmacro ABC("A","Trigger","trigger")
//! runtextmacro ABC("B","Trigger","trigger")
//! runtextmacro ABC("C","Trigger","trigger")

//! runtextmacro ABC("A","Dialog","dialog")
//! runtextmacro ABC("B","Dialog","dialog")
//! runtextmacro ABC("C","Dialog","dialog")

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
//==============================================================================

Code:
<<---  v.1.11 --->>
   * 1 possible bug fix
   * Few text changes
   * Added a null vote

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

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

NEW UPDATE 3/21/008
 

Attachments

  • Joker(Div) - VoteKick(Jass).w3x
    61.5 KB · Views: 74
Last edited:
Level 11
Joined
Feb 18, 2004
Messages
394
#1: You use an InitTrig function in a library... Check the section on initializers: http://wc3campaigns.net/vexorian/jasshelpermanual.html#lib

#2:
JASS:
    loop
        set count = count - 1
        call TriggerRegisterPlayerChatEvent( trig, Player(count), "-kick player", 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

Why is that if indented? And why is the chat event registration line not in the if?

#3: I've always been far too lazy to remember player IDs. Why not use a syntax that allows colours, player names, or player IDs?

#4: the "-kick player" string is hard-coded in. Thats bad.

#5: Why do you use the DisplayTimedTextToForce() BJ function when you can just use the line call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, duration, message) ?

#6: There are far too few configuration options. No boolean to display or not display who voted? bah.

#7: CustomDefeatBJ() displays a message when not in single player. This is bad, considering you already display a "____ has been kicked" message.

JASS:
        if not bj_isSinglePlayer then
            call DisplayTimedTextFromPlayer(whichPlayer, 0, 0, 60, GetLocalizedString( "PLAYER_DEFEATED" ) )
        endif

#8: What happens if someone is AFK? The vote just hangs and nothing happens untill he comes back? lame.

#9: Player names aren't displayed with that players colour? Lame.

#10: Two dependencies for such a little system? mhhh. Not too awesome.
 
Top