# CoinFlip-DiceRoll.tcl Version 1.0 by SpiKe^^ (30 Dec 2012) #
# author: SpiKe^^ #
# e-mail: spike<at>mytclscripts<dot>com #
# webpage: http://mytclscripts.com/ #
# This file is Copyrighted under the GNU Public License. #
# http://www.gnu.org/copyleft/gpl.html #
######### Coin flip commands #########
# !coin nick1 nick2
# example: !coin starr spike^^
# note: list any two nicks as the players
# !coin nick
# example: !coin starr
# note: command user will be the second player
# For help with the Coin flip command, use: !coin
######### Roll dice commands (with Default Dice) #########
# !roll nick1 nick2 nick3
# example: !roll starr bart spike^^
# note: list any two or more nicks as the players
# note: can use +me or your nick to include yourself
# example: !roll starr bart +me
# !roll nick
# example: !roll starr
# note: command user will be the second player
# !roll -all
# example: !roll -all
# this will roll the dice for every non-exempt nick in channel
# note: max players for -all controlled by cFdR(maxnk) setting
# note: list of players will always include the command user
# !roll <number of players>
# example: !roll 20
# this will roll the dice for 20 random non-exempt nicks
# note: list of players will always include the command user
# For help with the Roll dice command, use: !roll
######### Roll dice commands (with Custom Dice) #########
# note: All above Roll dice commands can be used with Custom Dice
# note: maximum of 20 dice, minimum of 4 dice sides
# !roll <number of dice>@<numbers on dice> <players>
# example: !roll 2@1-6 starr bart spike^^
# note: roll 2 dice, with standard 6-sided dice, for listed nicks
# example: !roll 4@1-10 starr
# note: roll 4 dice, using 10-sided dice, for starr & command user
# example: !roll 5@0-19 -all
# note: roll five, 20-sided dice (numbered 0 to 19), for all nicks
# example: !roll 2@1-50 45
# note: roll 2, 50-sided dice, for 45 random nicks (include cmd user)
# For help with the Roll custom dice command, use: !custom
################ Basic Settings ################
# Set the channel(s) for the CoinFlip-DiceRoll script #
# example: set cFdR(chans) {#mychan #chan2 #sumchan} #
# or set empty for all channels the bot is on #
set cFdR(chans) {}
################ !roll Settings ################
# Default number of Dice to roll (valid settings: 1 - 20) #
set cFdR(dcount) "5"
# Default numbers on the sides on the Dice #
# for standard six-sided dice, use: "1-6" #
# minimum of 4 sides: "1-4" :or: "0-3" #
# maximum of 100 sides: "1-100" :or: "0-99" #
set cFdR(dsides) "1-6"
# Exempt flags for !roll -all & !roll <number of players> #
set cFdR(xflag) "b|b"
# Exempt nicks for !roll -all & !roll <number of players> #
# example: set cFdR(xnick) {ted bart sam} #
set cFdR(xnick) {}
# Set def maximum number of nick for !roll -all #
# default number of random players for roll -all #
# note: will always include nick that did !roll -all #
set cFdR(maxnk) "50"
##########################################################
###################### End Settings ######################
##########################################################
# text for coin flip #
set cFdR(cointx) "\001action flips a coin, %nk1 has %ht1, %nk2 has %ht2... "
append cFdR(cointx) "and it's... %HT3... %nk3 wins.\001"
# text for dice roll #
# also available: %wpt = winnerpoints & %lpt = loserpoints #
set cFdR(dicetx) "\001action rolls the dice... %ls %wnk Wins! and %lnk Loses.\001"
set cFdR(dicels) "(%pnk: %pnt)... "
# max number of characters per line of text #
set cFdR(maxln) "400"
########### Binds ###########
bind pub - !coin coin:flip
bind pub - !roll dice:roll
bind pub - !custom dice:cust
proc dice:roll {nk uh hn ch tx} {
dice:roll $nk $uh $hn $ch @
return
}
proc dice:roll {nk uh hn ch tx} { set ch [string tolower $ch]
if {$::cFdR(chans) ne "" && [lsearch -exact $::cFdR(chans) $ch]=="-1"} {
return
}
set tx [rem:sp $tx] ; set help 0
if {$tx eq ""} { set help 1
} elseif {$tx eq "-help"} { set help 1 ; set tx ""
} elseif {$tx eq "-custom" || $tx eq "@" || [string match "-help c*" $tx]} {
set help 2 ; set tx ""
} else { set tx [split $tx] ; set idx -1 ; set doing nicks
set dcnt $::cFdR(dcount)
foreach {dsid1 dsid2} [split $::cFdR(dsides) -] { break }
foreach item [lrange $tx 0 1] {
if {[string match *@* $item]} { incr idx
foreach {d1 d2} [split $item @] { break }
set d1 [string trimleft $d1 0]
if {[string is digit -strict $d1]} {
if {$d1>"20"} { set d1 20 }
set dcnt $d1
}
if {$d2 ne ""} { set s1 "" ; set s2 ""
if {[string is digit -strict $d2]} {
if {$d2=="0"} { set s1 0
} else { set d2 [fix:num $d2]
if {$d2=="1"} { set s1 1
} elseif {$d2>"3"} { set s1 1 ; set s2 $d2
} elseif {$d2=="3"} { set s1 0 ; set s2 3 }
}
} elseif {[string match *-* $d2]} {
foreach {tm1 tm2} [split $d2 -] { break }
if {[set tm1 [fix:num $tm1]] ne ""} { set s1 $tm1 }
if {[set tm2 [fix:num $tm2]] ne ""} { set s2 $tm2 }
}
if {$s1 ne "" || $s2 ne ""} {
if {$s1 eq ""} { set s1 $dsid1 }
if {$s2 eq ""} { set s2 $dsid2 }
if {$s2>($s1 + 2)} { set custom 1
set dsid1 $s1 ; set dsid2 $s2
}
}
}
} elseif {$item eq "-all"} { incr idx ; set all 1
set doing $::cFdR(maxnk)
} elseif {[string is digit -strict $item]} { incr idx
set item [fix:num $item] ; set all 0
if {$item>"1"} { set doing $item }
} else { break }
}
if {$idx>"-1"} { set tx [lreplace $tx 0 $idx] }
if {$doing eq "nicks" && [llength $tx]<"2"} {
if {[llength $tx]=="0" || [string match -nocase $nk [lindex $tx 0]]} {
set help 1
} elseif {[lindex $tx 0] eq "+me"} { set help 1 }
}
}
if {$help=="0"} {
if {[set me [lsearch -exact $tx "+me"]]>"-1"} {
set tx [lreplace $tx $me $me $nk]
}
if {$doing eq "nicks"} {
if {[llength $tx]=="1"} { lappend tx $nk }
set niks [list:nk $ch $nk [llength $tx] 0 $tx]
} else {
if {[llength $tx]=="0"} { set niks [list:nk $ch $nk $doing]
} else { set niks [list:nk $ch $nk $doing 1 $tx] }
if {[llength $niks]<"2"} { set x "least 1 other non-exempt nick in $ch"
if {$all=="1"} {
puthelp "PRIVMSG $ch :Error: \002!roll -all\002 requires at $x"
} else {
puthelp "PRIVMSG $ch :Error: \002!roll <number>\002 requires at $x"
}
puthelp "PRIVMSG $ch :Use: \002!roll\002 :to see the Roll Dice Help."
return
}
}
}
if {$help>"0"} { set dcnt $::cFdR(dcount) ; set mx $::cFdR(maxnk)
if {$dcnt=="1"} { set dice "One die," } else { set dice "$dcnt dice," }
append dice " Numbered $::cFdR(dsides)" ; set x \002!roll
if {[llength $tx]=="0"} { set niks [list:nk $ch $nk 4 [rand 2]]
} else { set niks [list:nk $ch $nk 4] }
if {[llength $niks]=="4"} {
if {[lindex $niks 3] eq $nk} {
set niks [linsert [lrange $niks 0 2] [rand 3] $nk]
}
set nk4 [lindex $niks 3] ; set niks [lrange $niks 0 2]
} else { set nk4 nick1
if {[llength $niks]>"0"} { set tls $niks
while {[llength $tls]>"0"} { set rnd [rand [llength $tls]]
if {[set tnk [lindex $tls $rnd]] ne $nk} { set nk4 $tnk ; break
} else { set tls [lreplace $tls $rnd $rnd] }
}
}
if {[llength $niks]=="0"} { lappend niks $nk }
if {[llength $niks]=="1"} { lappend niks nick2 }
if {[llength $niks]=="2"} {
if {[lsearch -exact $niks $nk]=="-1"} { lappend niks $nk
} else { lappend niks nick3 }
}
}
}
if {$help=="1"} {
puthelp "PRIVMSG $ch :Roll Dice Commands (using $dice)"
puthelp "PRIVMSG $ch :1. List two or more nicks as the players."
puthelp "PRIVMSG $ch : Example: $x [string tolower [join $niks]]"
puthelp "PRIVMSG $ch : Use +me or your nick to include yourself."
puthelp "PRIVMSG $ch :2. Provide 1 nick & you will be the 2nd player."
puthelp "PRIVMSG $ch : Example: $x [string tolower $nk4]"
puthelp "PRIVMSG $ch :3. Roll for up to $mx random non-exempt nicks."
puthelp "PRIVMSG $ch : Example: $x -all"
puthelp "PRIVMSG $ch :4. Roll dice for the specified number of nicks."
puthelp "PRIVMSG $ch : Example: $x 20"
puthelp "PRIVMSG $ch :For help specifying custom dice, use: $x -custom"
return
}
if {$help=="2"} {
puthelp "PRIVMSG $ch :Roll Custom Dice Commands"
puthelp "PRIVMSG $ch :Correct syntax: <number of dice>@<numbers on dice>"
puthelp "PRIVMSG $ch :1. Roll 2 dice, with standard 6-sided dice."
puthelp "PRIVMSG $ch : Example: $x 2@1-6 [string tolower [join $niks]]"
puthelp "PRIVMSG $ch :2. Roll 4 dice, using 10-sided dice (1-10)."
puthelp "PRIVMSG $ch : Example: $x 4@1-10 [string tolower $nk4]"
puthelp "PRIVMSG $ch :3. Roll five, 20-sided dice (numbered 0 to 19)."
puthelp "PRIVMSG $ch : Example: $x 5@0-19 -all"
puthelp "PRIVMSG $ch :Note: Maximum of 20 dice, Minimum of 4 dice sides."
puthelp "PRIVMSG $ch :To see the main Roll Dice help, use: $x -help"
return
}
set rnum [expr {$dsid2-$dsid1+1}] ; set pls [list]
foreach nik $niks { set min $dsid1 ; set max $dsid2
lappend pls [list [expr {[rand $rnum]+$dsid1}] $nik]
}
if {$dcnt>"1"} { set roll 1
while {$roll<$dcnt} { set newls [list]
foreach player $pls {
foreach {pnt nik} $player { break }
lappend newls [list [expr {$pnt+[rand $rnum]+$dsid1}] $nik]
}
set pls $newls ; incr roll ; incr min $dsid1 ; incr max $dsid2
}
}
set sort [lsort -integer -index 0 $pls] ; set done 0
if {[set wpnt [lindex $sort end 0]]==[lindex $sort end-1 0]} { set tcnt 2
while {$tcnt<[llength $sort]} {
if {[lindex $sort end-$tcnt 0]==$wpnt} { incr tcnt } else { break }
}
set tiels [lrange $sort end-[expr {$tcnt-1}] end] ; set rnd [rand $tcnt]
set winnr [lindex $tiels $rnd]
if {$tcnt==[llength $sort]} {
if {$tcnt>"2"} { set done 2
set tiels [lreplace $tiels $rnd $rnd]
set loser [lindex $tiels [rand [llength $tiels]]]
} else { set done 1 }
} elseif {[lindex $sort 0 0]==[expr {$max-1}]} {
if {[set lpnt [lindex $sort 0 0]]==[lindex $sort 1 0]} { set tcnt 2
foreach itm [lrange $sort 2 end] {
if {[lindex $itm 0]==$lpnt} { incr tcnt } else { break }
}
set adj [lindex [lrange $sort 0 [expr {$tcnt-1}]] [rand $tcnt]]
} else { set adj [lindex $sort 0] }
}
if {[info exists adj]} { set pls [fix:list $pls $winnr "" $min $max $adj]
unset adj
} elseif {$done<"2"} { set pls [fix:list $pls $winnr "" $min $max]
} else { set pls [fix:list $pls $winnr $loser $min $max] }
set sort [lsort -integer -index 0 $pls]
} else { set winnr [lindex $sort end]
if {[lindex $winnr 0]==[expr {$min+1}]} { set adj $winnr }
}
if {[set lpnt [lindex $sort 0 0]]==[lindex $sort 1 0]} { set tcnt 2
foreach itm [lrange $sort 2 end] {
if {[lindex $itm 0]==$lpnt} { incr tcnt } else { break }
}
set loser [lindex [lrange $sort 0 [expr {$tcnt-1}]] [rand $tcnt]]
if {![info exists adj]} { set pls [fix:list $pls "" $loser $min $max]
} else { set pls [fix:list $pls "" $loser $min $max $adj] }
set sort [lsort -integer -index 0 $pls]
}
lappend map %lnk [lindex $sort 0 1] %wnk [lindex $sort end 1]
lappend map %lpt [lindex $sort 0 0] %wpt [lindex $sort end 0]
set text $::cFdR(dicetx) ; set each $::cFdR(dicels)
set pre "\001action" ; set aft "\001"
if {![string match $pre* $text]} { set pre "" ; set aft ""
} else { set pre "$pre : " }
if {[set idx [string first %ls $text]]>"-1"} { set max $::cFdR(maxln)
set rest [string map $map [string range $text [expr {$idx+3}] end]]
set text [string map $map [string range $text 0 [expr {$idx-1}]]]
foreach player $pls { set len [string length $text]
foreach {pt nk} $player { break }
set ptx [string map [list %pnk $nk %pnt $pt] $each]
if {($len+[string length $ptx])>$max} {
puthelp "PRIVMSG $ch :$text$aft" ; set text $pre$ptx
} else { append text $ptx }
}
set text [string trimright $text]
if {([string length $text]+[string length $rest])>$max} {
puthelp "PRIVMSG $ch :$text$aft"
puthelp "PRIVMSG $ch :$pre[string trimleft $rest]"
} else { puthelp "PRIVMSG $ch :$text$rest" }
} else { puthelp "PRIVMSG $ch :[string map $map $text]" }
return
}
proc coin:flip {nk uh hn ch tx} { set ch [string tolower $ch]
if {$::cFdR(chans) ne "" && [lsearch -exact $::cFdR(chans) $ch]=="-1"} {
return
}
set n1 "" ; set n2 ""
foreach {n1 n2} [split [rem:sp $tx]] { break }
if {$n1 eq "" || ($n2 eq "" && [string match -nocase $nk $n1])} {
if {$n1 eq ""} { set niks [list:nk $ch $nk 2 [rand 2]]
} else { set niks [list:nk $ch $nk 2] }
if {[llength $niks]=="0"} { lappend niks $nk }
if {[llength $niks]=="1" && [join $niks] ne $nk} { lappend niks $nk }
if {[llength $niks]=="1"} { lappend niks nick2 }
puthelp "PRIVMSG $ch :Correct syntax is: !coin nick1 ?nick2?"
puthelp "PRIVMSG $ch :!coin command with 2 nicks provided..."
puthelp "PRIVMSG $ch :Example: \002!coin [string tolower [join $niks]]"
puthelp "PRIVMSG $ch :Or: provide 1 nick & you will be the 2nd player."
return
}
if {$n2 eq ""} { set n2 $nk }
foreach {nk1 nk2} [list:nk $ch $nk 2 0 [list $n1 $n2]] { break }
set f1 [rand 20] ; set f2 [rand 30]
if {[string match {*[13579]} $f1] && [string match {*[13579]} $f2]} {
set reslt heads
} elseif {[string match {*[02468]} $f1] && [string match {*[02468]} $f2]} {
set reslt tails
} else { set f3 [rand 40]
if {[string match {*[13579]} $f3]} { set reslt heads
} else { set reslt tails }
}
lappend map %nk1 $nk1 %nk2 $nk2 %ht3 $reslt %HT3 [string toupper $reslt]
if {[string match {*[13579]} [rand 20]]} {
if {$reslt eq "heads"} { lappend map %ht1 heads %ht2 tails %nk3 $nk1
} else { lappend map %ht1 heads %ht2 tails %nk3 $nk2 }
} else {
if {$reslt eq "heads"} { lappend map %ht1 tails %ht2 heads %nk3 $nk2
} else { lappend map %ht1 tails %ht2 heads %nk3 $nk1 }
}
puthelp "PRIVMSG $ch :[string map $map $::cFdR(cointx)]"
return
}
proc fix:list {pls win los min max {adj ""} } {
set wnk "" ; set wpt -1 ; set lnk "" ; set lpt -1 ; set new [list]
if {$win ne ""} { foreach {mpt wnk} $win {break}
if {$mpt==$min && $los ne ""} {
set wpt [expr {$mpt+2}] ; set tpt [expr {$mpt+1}]
} elseif {$mpt==$max} { set wpt $mpt ; set tpt [expr {$mpt-1}]
} else { set wpt [expr {$mpt+1}] ; set tpt $mpt }
if {$los ne ""} { foreach {mpt lnk} $los {break}
set lpt [expr {$tpt-1}]
}
if {$adj ne ""} { foreach {ap an} $adj { break } ; set adj "-" }
} elseif {$los ne ""} { foreach {mpt lnk} $los {break}
if {$mpt==$min} { set lpt $mpt ; set tpt [expr {$mpt+1}]
} else { set lpt [expr {$mpt-1}] ; set tpt $mpt }
if {$adj ne ""} { foreach {ap an} $adj { break } ; set adj "+" }
}
foreach player $pls { foreach {pnt nik} $player {break}
if {$pnt==$mpt} {
if {$nik eq $wnk} { lappend new [list $wpt $nik]
} elseif {$nik eq $lnk} { lappend new [list $lpt $nik]
} else { lappend new [list $tpt $nik] }
} elseif {$adj ne "" && $nik eq $an && $pnt==$ap} {
if {$adj eq "+"} { lappend new [list [expr {$pnt+1}] $nik]
} else { lappend new [list [expr {$pnt-1}] $nik] }
} else { lappend new $player }
}
return $new
}
proc list:nk {ch nik num {iusr 1} {nls ""} } { set chanls [list]
if {$nls ne ""} { set nlow [split [string tolower [join $nls]]]
if {$iusr=="1"} { set iusr 0
if {[lsearch -exact $nlow [string tolower $nik]]=="-1"} {
lappend nls $nik ; lappend nlow [string tolower $nik]
}
}
}
foreach nk [chanlist $ch] {
if {$nls ne ""} {
if {[set idx [lsearch -exact $nlow [string tolower $nk]]]>"-1"} {
set nls [lreplace $nls $idx $idx $nk] ; continue
}
}
if {[isbotnick $nk]} { continue }
if {[lsearch -exact $::cFdR(xnick) [string tolower $nk]]>"-1"} { continue }
if {$::cFdR(xflag) ne ""} {
if {[matchattr [nick2hand $nk $ch] $::cFdR(xflag) $ch]} { continue }
}
lappend chanls $nk
}
if {$nls ne ""} {
if {[llength $nls]<$num} { set num [expr {$num-[llength $nls]}]
} else { set chanls $nls ; set nls "" ; set num [llength $nls] }
}
set newls [list] ; set cnt 0
while {[llength $chanls]>"0"} { incr cnt
lappend newls [lindex $chanls [set lidx [rand [llength $chanls]]]]
set chanls [lreplace $chanls $lidx $lidx]
if {$cnt==$num} { break }
}
if {$nls ne ""} {
while {[llength $nls]>"0"} { set nk [lindex $nls 0]
if {$cnt>"0"} {
set newls [linsert $newls [rand [expr {[llength $newls]+1}]] $nk]
} else { lappend newls $nk ; incr cnt }
set nls [lreplace $nls 0 0]
}
}
if {$iusr=="1" && [lsearch -exact $newls $nik]=="-1"} {
if {[llength $newls]>=$num} {
set newls [lreplace $newls [set lidx [rand [llength $newls]]] $lidx $nik]
} else {
set newls [linsert $newls [rand [expr {[llength $newls]+1}]] $nik]
}
}
return $newls
}
proc fix:num {num} {
if {![string is digit -strict $num]} { return "" }
set num [string trimleft $num 0]
if {$num eq ""} { set num 0 } ; return $num
}
proc rem:sp {st} { return [string trim [regsub -all -- {\s{2,}} $st { }]] }
foreach frSet {chans xnick} {
set cFdR($frSet) [rem:sp [string tolower $cFdR($frSet)]]
if {$cFdR($frSet) ne ""} { set cFdR($frSet) [split $cFdR($frSet)] }
}
set cFdR(xflag) [string trim $cFdR(xflag)]
foreach frSet {maxnk dcount maxln} {
set cFdR($frSet) [fix:num [string trim $cFdR($frSet)]]
}
if {![string is digit -strict $cFdR(maxnk)]} { set cFdR(maxnk) 18 }
if {$cFdR(maxnk)<"4"} { set cFdR(maxnk) 4 }
if {![string is digit -strict $cFdR(dcount)]} { set cFdR(dcount) 5 }
if {$cFdR(dcount)>"20"} { set cFdR(dcount) 20 }
if {![string is digit -strict $cFdR(maxln)]} { set cFdR(maxln) 400 }
if {$cFdR(maxln)<"60"} { set cFdR(maxln) 60 }
if {[string match *?-?* [string trim $cFdR(dsides)]]} {
set cFdR(dsides) [split $cFdR(dsides) -]
foreach {frSet frSe2} $cFdR(dsides) { break }
set frSet [string trim $frSet] ; set frSe2 [string trim $frSe2]
if {[string is digit -strict $frSet] && [string is digit -strict $frSe2]} {
if {$frSet>"0"} { set frSet [fix:num $frSet] } else { set frSet 0 }
if {$frSe2>"3"} { set frSe2 [fix:num $frSe2] } else { set frSe2 3 }
if {$frSe2>($frSet + 2)} { set cFdR(dsides) $frSet-$frSe2
} else { set cFdR(dsides) "1-6" }
} else { set cFdR(dsides) "1-6" }
} else { set cFdR(dsides) "1-6" } ; catch {unset frSet frSe2}
putlog "CoinFlip-DiceRoll.tcl Ver. 1.0 by SpiKe^^ loaded."
You wrote:
!roll user1 user2 user3 user4
would do a roll for the people listed. numbers between 1-100
So you may want to change these 2 options as follows...
# Default number of Dice to roll (valid settings: 1 - 20) #
set cFdR(dcount) "2"
# Default numbers on the sides on the Dice #
# for standard six-sided dice, use: "1-6" #
# minimum of 4 sides: "1-4" :or: "0-3" #
# maximum of 100 sides: "1-100" :or: "0-99" #
set cFdR(dsides) "1-50"