Spoiler --[[
Extended vote system
version 1.0
Author: Kiffer-Opa
Licence:
You can use this script for your server.
You can edit and use the code if you want, if you mention all other authors.
]]
if xvote==nil then xvote={} end
-- load configuration file
dofile("sys/lua/xvoteconfig.lua")
parse("mp_mapvoteratio 1.00")
parse("mp_kickpercent 1.00")
-- turn off automatic stuff (autoteambalance etc.) and some restrictions
parse('exec "sys/norestrictions.cfg"')
xvote.votecolor = "©000255150"
function xvote.initArray(size,value)
local array = {}
for i=1,size do
array[i]=value
end
return array
end
function xvote.getHumans()
local humans=0
for i=1,#player(0,"table") do
p=player(0,"table")[i]
if(player(p,"bot")==false) then
humans=humans+1
end
end
return humans
end
function xvote.getPlayers()
local players=0
for i=1,#player(0,"table") do
players=players+1
end
return players
end
function xvote.getMaxPlayerID()
local max = 0
for i=1,#player(0,"table") do
max = math.max(max,player(0,"table")[i])
end
return max
end
function xvote.getVotes(votetable,value)
local votes=0
for i=1,#votetable do
if(votetable[i]==value) then
votes=votes+1
end
end
return votes
end
function xvote.humans()
local table = {}
for i=1,32 do
if(player(i,"exists")) then
if(player(i,"bot")==false) then
table[#table+1]=i
end
end
end
return table
end
function xvote.players()
local table = {}
for i=1,32 do
if(player(i,"exists")) then
table[#table+1]=i
end
end
return table
end
function xvote.getMajority(votetable)
local possiblevotes = xvote.getVoteOptions(votetable)
local votecount = xvote.initArray(#possiblevotes,0)
local majority = nil
local max = 0
local humans = xvote.humans()
local id
for v=1,#humans do
id=humans[v]
for p=1,#possiblevotes do
if(votetable[id]==possiblevotes[p]) then
votecount[p] = votecount[p]+1
end
end
end
for c=1,#votecount do
if(votecount[c]>max) then
majority = possiblevotes[c]
max = votecount[c]
elseif(votecount[c]==max) then
majority = nil
end
end
return majority
end
function xvote.getVoteOptions(votetable)
local options = {}
local counted = false
for i=1,32 do
counted = false
for j=1,#options do
if(votetable[i]==options[j]) then
counted=true
end
end
if(counted==false) then
options[#options+1]=votetable[i]
end
end
return options
end
function xvote.getIDFromName(name)
for p=1,32 do
if(name==player(p,"name")) then
return p
end
end
return nil
end
function xvote.serveraction(playerID,action)
if(action == xvote.serveractionkey) then
xvote.refreshmenus()
menu(playerID, xvote.menu.game)
end
end
addhook("serveraction","xvote.serveraction",-10)
function xvote.say(playerID,text)
if(string.lower(text)=="!xvote") then
menu(playerID, xvote.menu.game)
return 1
end
return 0
end
addhook("say","xvote.say")
addhook("sayteam","xvote.say")
function xvote.votemenu(playerID,votemode,param)
local victim, map
if(votemode==1) then -- votekick
if(param~="") then
victim = xvote.getIDFromName(param)
if(victim~=nil) then
--msg(xvote.votecolor..player(playerID,"name").." votes to kick "..player(victim,"name")..".")
xvote.vote.kick[victim][playerID] = true
if(xvote.getMajority(xvote.vote.kick[victim])==true) then
parse("kick "..victim)
end
else
msg2(playerID,"©255000000This player is not on the server.@C")
end
else
for i=1,32 do
xvote.vote.kick[i][playerID] = false
end
msg(xvote.votecolor..player(playerID,"name").." withdrew the kick votes.")
end
elseif(votemode==2) then -- votemap
xvote.vote.map[playerID] = param
if(param=="") then
msg(xvote.votecolor..player(playerID,"name").." votes against mapchange.")
--[[
else
msg(xvote.votecolor..player(playerID,"name").." votes for map "..param)
]]
end
map=xvote.getMajority(xvote.vote.map)
if(map~="") then
parse("sv_map "..map)
end
end
end
addhook("vote","xvote.votemenu")
function xvote.getVoteRatio(votetable,value)
local votes = xvote.getVotes(votetable,value)
local humans =xvote.getHumans()
return ( votes/humans ) * 100
end
function xvote.voteString(votetable,vote,title)
return title.."|"..string.format('%.1f',xvote.getVoteRatio(votetable,vote)).."%"
end
function xvote.mapcycle(filter)
local maptable = {}
file = io.open(xvote.votemaps,"r")
if(filter==nil) then filter="" end
for line in io.lines("sys/mapcycle.cfg","r") do
local match = string.match(line,"^"..filter.."[^/][%w%d%p]+")
if(match ~= nil) then
table.insert(maptable,match)
end
end
file:close()
return maptable
end
function xvote.openVotemapMenu(playerID,page,filter,openmenu)
if(filter==nil) then filter="" end
if(filter=="") then space="" else space=" " end
if(openmenu==nil) then openmenu=true end
local str = "Vote for "..filter..space.."map (page "..page..")"
local start = 1 + (page-1)*7
local c = 1
local maps = xvote.mapcycle(filter)
for i=start,math.min(#maps,start+6) do
str = str..","..xvote.voteString(xvote.vote.map, maps[i], maps[i])
c = c+1
end
for i=c, 7 do
str = str..","
end
if(page~=1) then
str = str..",« previous page"
else
str = str..","
end
if(#maps~=math.min(#maps,start+6)) then
str = str..",next page »"
end
if(openmenu==true) then
menu(playerID,str)
end
return str
end
-- vote tables
xvote.vote = {}
xvote.vote.makespec = {}
xvote.vote.kick = {}
for i=1,32 do
xvote.vote.makespec[i] = {} -- create a new row
xvote.vote.kick[i] = {}
for j=1,32 do
xvote.vote.makespec[i][j] = false
xvote.vote.kick[i][j] = false
end
end
xvote.vote.fow = xvote.initArray(32,false) -- toggle Fog of War
xvote.vote.ff = xvote.initArray(32,false) -- toggle Friendly Fire
xvote.vote.infammo = xvote.initArray(32,false) -- toggle infinite ammo
xvote.vote.map = xvote.initArray(32,false) -- change map
xvote.vote.gamemode = xvote.initArray(32,false) -- set game mode
xvote.vote.specmode = xvote.initArray(32,false) -- set spectator mode
xvote.vote.roundtime = xvote.initArray(32,false) -- set round time
xvote.vote.freezetime = xvote.initArray(32,false) -- set freezetime
xvote.vote.buytime = xvote.initArray(32,false) -- set buytime
xvote.vote.startmoney = xvote.initArray(32,false) -- set start money
xvote.vote.curtailedexplosions = xvote.initArray(32,false)-- set curtailed explosions
xvote.vote.restart = xvote.initArray(32,false) -- restart round
xvote.menu = {}
xvote.menu.main = "XVote menu,Player,Game Options"
xvote.menu.map = "Select map type"
function xvote.refreshmenus()
xvote.menu.fow = "Vote for Fog of War,"..xvote.voteString(xvote.vote.fow,true,"on")..","..xvote.voteString(xvote.vote.fow,false,"off")..",(don't change)"
xvote.menu.ff = "Vote for Friendly Fire,"..xvote.voteString(xvote.vote.ff,true,"on")..","..xvote.voteString(xvote.vote.ff,false,"off")..",(don't change)"
xvote.menu.infammo = "Vote for infinite ammo"..xvote.voteString(xvote.vote.infammo,true,"on")..","..xvote.voteString(xvote.vote.infammo,false,"off")..",(don't change)"
xvote.menu.curtailedexplosions = "Vote for curtailed explosions,"..xvote.voteString(xvote.vote.curtailedexplosions,true,"on")..","..xvote.voteString(xvote.vote.curtailedexplosions,false,"off")..",(don't change)"
xvote.menu.gamemode = "Vote for game mode,"..xvote.voteString(xvote.vote.gamemode,0,"Standard")..","..xvote.voteString(xvote.vote.gamemode,1,"Deathmatch")..","..xvote.voteString(xvote.vote.gamemode,2,"Team Deathmatch")..","..xvote.voteString(xvote.vote.gamemode,3,"Construction")..","..xvote.voteString(xvote.vote.gamemode,4,"Zombies!")..",(current mode)"
xvote.menu.specmode = "Vote to allow to spectate ...,"..xvote.voteString(xvote.vote.specmode,1,"everything")..","..xvote.voteString(xvote.vote.specmode,2,"own team only")..","..xvote.voteString(xvote.vote.specmode,0,"nothing")..",(current setting)"
xvote.menu.game = "Vote game options,map,kick player,game mode,spectator mode,"..xvote.voteString(xvote.vote.fow,true,"Fog of War")..","..xvote.voteString(xvote.vote.ff,true,"Friendly Fire")..","..xvote.voteString(xvote.vote.infammo,true,"infinite ammo")..","..xvote.voteString(xvote.vote.restart,true,"restart round")..",withdraw my votes"
xvote.menu.construction = "Vote Construction options,unlimited buildings,instant build"
if(#xvote.mapcycle("") > 7) then
temp = {"","","","","","","","",""}
if(xvote.mapcycle("")~=nil) then
temp[1]="any map"
end
if(xvote.mapcycle("as_")~=nil) then
temp[2]="Assassination|as_"
end
if(xvote.mapcycle("cs_")~=nil) then
temp[3]="Hostage Rescue|cs_"
end
if(xvote.mapcycle("de_")~=nil) then
temp[4]="Bomb Defuse|de_"
end
if(xvote.mapcycle("dm_")~=nil) then
temp[5]="Deathmatch|dm_"
end
if(xvote.mapcycle("ctf_")~=nil) then
temp[6]="Capture the Flag|ctf_"
end
if(xvote.mapcycle("dom_")~=nil) then
temp[7]="Domination|dom_"
end
if(xvote.mapcycle("zm_")~=nil) then
temp[8]="Zombie map|zm_"
end
if(xvote.mapcycle("gg_")~=nil) then
temp[9]="GunGame|gg_"
end
for i=1,9 do
xvote.menu.map = xvote.menu.map..","..temp[i]
end
else
xvote.menu.map = xvote.openVotemapMenu(0,1,"",false)
end
end
xvote.refreshmenus()
function xvote.clearvotes(votetable)
votetable = {}
end
function xvote.clearPlayerVotes(playerID)
xvote.vote.fow[playerID] = false
xvote.vote.ff[playerID] = false
xvote.vote.infammo[playerID] = false
xvote.vote.map[playerID] = false
xvote.vote.gamemode[playerID] = false
xvote.vote.specmode[playerID] = false
xvote.vote.roundtime[playerID] = false
xvote.vote.freezetime[playerID] = false
xvote.vote.buytime[playerID] = false
xvote.vote.startmoney[playerID] = false
xvote.vote.curtailedexplosions[playerID] = false
xvote.vote.restart[playerID] = false
for i=1,32 do
xvote.vote.kick[i][playerID] = false
xvote.vote.makespec[i][playerID] = false
end
end
function xvote.join(playerID)
xvote.clearPlayerVotes(playerID)
end
addhook("join","xvote.join")
function xvote.leave(playerID,reason)
xvote.clearPlayerVotes(playerID)
end
addhook("leave","xvote.leave")
function xvote.toggle(votetable, playerID, option, condition, positive, negative, name)
if(votetable[playerID]~=true) then
votetable[playerID]=true
msg(xvote.votecolor..player(playerID,"name").." votes to toggle "..name..".")
parse('sv_sound "player/vote.wav"')
end
if(xvote.getMajority(votetable)==true) then
if(tonumber(game(option))==condition) then
parse(negative)
else
parse(positive)
end
return true
end
return false
end
function xvote.openVotekickMenu(playerID,page)
local str = "Vote to kick player (page "..page..")"
local start = 1 + (page-1)*7
local c = 1
for i=start,math.min(xvote.getPlayers(),start+6) do
p = xvote.players()[i]
if(player(p,"exists")) then
str = str..","..xvote.voteString(xvote.vote.kick[p], true, player(p,"name"))
else
str = str..","
end
c = c+1
end
for i=c, 7 do
str = str..","
end
if(page~=1) then
str = str..",« previous page"
else
str = str..","
end
if(xvote.getPlayers()~=math.min(xvote.getPlayers(),start+6)) then
str = str..",next page »"
end
menu(playerID,str)
return str
end
function xvote.menucall(playerID,title,button)
if(title=="Vote game options") then
if(button==1) then
--xvote.openVotemapMenu(playerID,1)
menu(playerID,xvote.menu.map)
elseif(button==5) then
if(xvote.toggle(xvote.vote.fow, playerID, "sv_fow", 1, "sv_fow 1", "sv_fow 0", "Fog of War")) then
xvote.vote.fow = xvote.initArray(32,false)
end
elseif(button==6) then
if(xvote.toggle(xvote.vote.ff, playerID, "sv_friendlyfire", 1, "sv_friendlyfire 1", "sv_friendlyfire 0", "Friendly Fire")) then
xvote.vote.ff = xvote.initArray(32,false)
end
elseif(button==7) then
if(xvote.toggle(xvote.vote.infammo, playerID, "mp_infammo", 1, "mp_infammo 1", "mp_infammo 0", "infinite ammo")) then
xvote.vote.infammo = xvote.initArray(32,false)
end
elseif(button==3) then
menu(playerID,xvote.menu.gamemode)
elseif(button==4) then
menu(playerID,xvote.menu.specmode)
elseif(button==2) then
xvote.openVotekickMenu(playerID,1)
elseif(button==8) then
if(xvote.vote.restart~=true) then
xvote.vote.restart[playerID]=true
msg(xvote.votecolor..player(playerID,"name").." votes for a round restart.")
end
if(xvote.getMajority(xvote.vote.restart)==true) then
parse("sv_restartround")
xvote.vote.restart = xvote.initArray(32,false)
end
elseif(button==9) then
xvote.clearPlayerVotes(playerID)
msg(xvote.votecolor..player(playerID,"name").." withdraws his votes.")
end
elseif(title=="Vote for game mode") then
if(button>=1 and button<=5) then
xvote.vote.gamemode[playerID] = button-1
if(xvote.vote.gamemode[playerID]==0) then
msg(xvote.votecolor..player(playerID,"name").." votes the gamemode Standard.")
elseif(xvote.vote.gamemode[playerID]==1) then
msg(xvote.votecolor..player(playerID,"name").." votes the gamemode Deathmatch.")
elseif(xvote.vote.gamemode[playerID]==2) then
msg(xvote.votecolor..player(playerID,"name").." votes the gamemode Team Deathmatch.")
elseif(xvote.vote.gamemode[playerID]==3) then
msg(xvote.votecolor..player(playerID,"name").." votes the gamemode Construction.")
elseif(xvote.vote.gamemode[playerID]==4) then
msg(xvote.votecolor..player(playerID,"name").." votes the gamemode Zombies!")
end
parse('sv_sound "player/vote.wav"')
if(xvote.getMajority(xvote.vote.gamemode)~=false and xvote.getMajority(xvote.vote.gamemode)~=nil) then
parse("sv_gamemode "..xvote.vote.gamemode[playerID])
xvote.vote.gamemode = xvote.initArray(32,false)
end
elseif(button==6) then
xvote.vote.gamemode[playerID] = false
msg(xvote.votecolor..player(playerID,"name").." withdraws the vote on gamemode.")
end
elseif(title=="Vote to allow to spectate ...") then
if (button==1) then
xvote.vote.specmode[playerID] = 1 -- everything
msg(xvote.votecolor..player(playerID,"name").." votes to allow full spectating.")
elseif(button==2) then
xvote.vote.specmode[playerID] = 2 -- own team only
msg(xvote.votecolor..player(playerID,"name").." votes to to allow spectating own team only.")
elseif(button==3) then
xvote.vote.specmode[playerID] = 0 -- nothing
msg(xvote.votecolor..player(playerID,"name").." votes to disable spectating.")
elseif(button==4) then
xvote.vote.specmode[playerID] = false
msg(xvote.votecolor..player(playerID,"name").." withdraws the vote on spectating mode.")
end
parse('sv_sound "player/vote.wav"')
if(xvote.getMajority(xvote.vote.specmode)~=false and xvote.getMajority(xvote.vote.specmode)~=nil) then
parse("sv_specmode "..xvote.vote.specmode[playerID])
xvote.vote.specmode = xvote.initArray(32,false)
end
elseif(title=="Select map type") then
if(button==1) then
xvote.openVotemapMenu(playerID,1,"")
elseif(button==2) then
xvote.openVotemapMenu(playerID,1,"as_")
elseif(button==3) then
xvote.openVotemapMenu(playerID,1,"cs_")
elseif(button==4) then
xvote.openVotemapMenu(playerID,1,"de_")
elseif(button==5) then
xvote.openVotemapMenu(playerID,1,"dm_")
elseif(button==6) then
xvote.openVotemapMenu(playerID,1,"ctf_")
elseif(button==7) then
xvote.openVotemapMenu(playerID,1,"dom_")
elseif(button==8) then
xvote.openVotemapMenu(playerID,1,"zm_")
elseif(button==9) then
xvote.openVotemapMenu(playerID,1,"gg_")
end
elseif(string.sub(title,1,9)=="Vote for " and string.match(title,"map")~=nil) then
local page = string.match(title,"(%d+)")
local filter = string.match(title,"%a+_")
if filter==nil then filter="" end
local start = (page-1)*7
if(button>=1 and button<=7) then
maps=xvote.mapcycle(filter)
map = start+button
xvote.vote.map[playerID] = maps[map]
msg(xvote.votecolor..player(playerID,"name").." votes the map "..maps[map]..".")
parse('sv_sound "player/vote.wav"')
if(xvote.getMajority(xvote.vote.map)==maps[map]) then
parse("sv_map "..maps[map])
end
elseif(button==8) then
xvote.openVotemapMenu(playerID,page-1,filter)
elseif(button==9) then
xvote.openVotemapMenu(playerID,page+1,filter)
end
elseif(string.sub(title,1,19)=="Vote to kick player") then
local page = string.match(title,"(%d+)")
local start = (page-1)*7
if(button>=1 and button<=7) then
victim = xvote.players()[start+button]
xvote.vote.kick[victim][playerID] = true
msg(xvote.votecolor..player(playerID,"name").." votes to kick "..player(victim,"name")..".")
parse('sv_sound "player/vote.wav"')
if(xvote.getMajority(xvote.vote.kick[victim])==true) then
parse("kick "..victim)
end
elseif(button==8) then
xvote.openVotekickMenu(playerID,page-1)
elseif(button==9) then
xvote.openVotekickMenu(playerID,page+1)
end
end
end
addhook("menu","xvote.menucall")