vote/init.lua

345 lines
7.9 KiB
Lua
Raw Normal View History

2015-07-16 19:12:25 +03:00
vote = {
active = {},
queue = {}
}
local storage = core.get_mod_storage()
2015-07-16 19:12:25 +03:00
function vote.new_vote(creator, voteset)
2015-07-16 20:01:31 +03:00
local max_votes = tonumber(minetest.setting_get("vote.maximum_active")) or 1
2015-07-16 19:12:25 +03:00
if #vote.active < max_votes then
vote.start_vote(voteset)
else
table.insert(vote.queue, voteset)
if creator then
minetest.chat_send_player(creator,
"Vote queued until there is less then " .. max_votes ..
" votes active.")
end
end
end
function vote.start_vote(voteset)
minetest.log("action", "Vote started: " .. voteset.description)
table.insert(vote.active, voteset)
-- Build results table
voteset.results = {
abstain = {},
voted = {}
}
if voteset.options then
for _, option in pairs(voteset.options) do
voteset.results[option] = {}
print(" - " .. option)
end
else
voteset.results.yes = {}
voteset.results.no = {}
end
-- Run start callback
if voteset.on_start then
voteset:on_start()
end
-- Timer for end
2015-07-16 20:12:08 +03:00
if voteset.duration or voteset.time then
minetest.after(voteset.duration + 0.1, function()
2015-07-16 19:12:25 +03:00
vote.end_vote(voteset)
end)
end
2015-07-16 20:01:31 +03:00
-- Show HUD a.s.a.p.
vote.update_all_hud()
2015-07-16 19:12:25 +03:00
end
function vote.end_vote(voteset)
local removed = false
for i, voteset2 in pairs(vote.active) do
if voteset == voteset2 then
table.remove(vote.active, i, 1)
removed = true
end
end
if not removed then
return
end
local result = nil
if voteset.on_decide then
result = voteset:on_decide(voteset.results)
elseif voteset.results.yes and voteset.results.no then
local total = #voteset.results.yes + #voteset.results.no
2015-07-16 20:12:08 +03:00
local perc_needed = voteset.perc_needed or 0.5
2015-07-16 19:12:25 +03:00
2015-07-16 20:12:08 +03:00
if #voteset.results.yes / total > perc_needed then
2015-07-16 19:12:25 +03:00
result = "yes"
else
result = "no"
end
end
minetest.log("action", "Vote '" .. voteset.description ..
"' ended with result '" .. result .. "'.")
if voteset.on_result then
voteset:on_result(result, voteset.results)
end
2015-07-16 20:01:31 +03:00
local max_votes = tonumber(minetest.setting_get("vote.maximum_active")) or 1
2015-07-16 19:12:25 +03:00
if #vote.active < max_votes and #vote.queue > 0 then
local nextvote = table.remove(vote.queue, 1)
vote.start_vote(nextvote)
2015-07-16 20:01:31 +03:00
else
-- Update HUD a.s.a.p.
vote.update_all_hud()
2015-07-16 19:12:25 +03:00
end
2015-07-16 20:01:31 +03:00
2015-07-16 19:12:25 +03:00
end
function vote.get_next_vote(name)
for _, voteset in pairs(vote.active) do
if not voteset.results.voted[name] then
return voteset
end
end
return nil
end
function vote.check_vote(voteset)
local all_players_voted = true
local players = minetest.get_connected_players()
local ignored_players = storage:get_string("ignored_players"):split(" ")
2015-07-16 19:12:25 +03:00
for _, player in pairs(players) do
local name = player:get_player_name()
2024-12-07 11:53:53 +03:00
local is_ignored = false
for _, ignored_name in ipairs(ignored_players) do
if name == ignored_name then
is_ignored = true
break
end
end
if is_ignored then
break
end
2015-07-16 19:12:25 +03:00
if not voteset.results.voted[name] then
all_players_voted = false
break
end
end
if all_players_voted then
vote.end_vote(voteset)
end
end
function vote.vote(voteset, name, value)
if not voteset.results[value] then
return
end
minetest.log("action", name .. " voted '" .. value .. "' to '"
.. voteset.description .. "'")
table.insert(voteset.results[value], name)
voteset.results.voted[name] = true
if voteset.on_vote then
voteset:on_vote(name, value)
end
vote.check_vote(voteset)
2015-07-16 20:01:31 +03:00
end
2015-12-08 01:52:26 +03:00
minetest.register_privilege("vote_admin", {
description = "Allows a player to manage running votes."
})
minetest.register_chatcommand("vote_clear", {
privs = {
vote_admin = true,
},
func = function(name, params)
vote.active = {}
vote.queue = {}
vote.update_all_hud()
end
})
2015-07-16 20:01:31 +03:00
local hudkit = dofile(minetest.get_modpath("vote") .. "/hudkit.lua")
vote.hud = hudkit()
function vote.update_hud(player)
local name = player:get_player_name()
local voteset = vote.get_next_vote(name)
if not voteset then
vote.hud:remove(player, "vote:desc")
vote.hud:remove(player, "vote:bg")
vote.hud:remove(player, "vote:help")
return
end
2015-07-16 19:12:25 +03:00
2015-07-16 20:01:31 +03:00
if not vote.hud:exists(player, "vote:bg") then
vote.hud:add(player, "vote:bg", {
hud_elem_type = "image",
position = {x = 1, y = 0.5},
scale = {x = 1, y = 1},
text = "vote_background.png",
offset = {x=-100, y = 10},
number = 0xFFFFFF
})
end
if vote.hud:exists(player, "vote:desc") then
vote.hud:change(player, "vote:desc", "text", voteset.description .. "?")
else
vote.hud:add(player, "vote:desc", {
hud_elem_type = "text",
position = {x = 1, y = 0.5},
scale = {x = 100, y = 100},
text = voteset.description .. "?",
offset = {x=-100, y = 0},
number = 0xFFFFFF
})
end
if voteset.help then
if vote.hud:exists(player, "vote:help") then
vote.hud:change(player, "vote:help", "text", voteset.help)
else
vote.hud:add(player, "vote:help", {
hud_elem_type = "text",
position = {x = 1, y = 0.5},
scale = {x = 100, y = 100},
text = voteset.help,
offset = {x=-100, y = 20},
number = 0xFFFFFF
})
2015-07-16 19:12:25 +03:00
end
2015-07-16 20:01:31 +03:00
else
vote.hud:remove(player, "vote:help")
2015-07-16 19:12:25 +03:00
end
end
2015-07-16 20:01:31 +03:00
minetest.register_on_leaveplayer(function(player)
vote.hud.players[player:get_player_name()] = nil
end)
function vote.update_all_hud()
local players = minetest.get_connected_players()
for _, player in pairs(players) do
vote.update_hud(player)
end
minetest.after(5, vote.update_all_hud)
end
minetest.after(5, vote.update_all_hud)
2015-07-16 19:12:25 +03:00
minetest.register_chatcommand("yes", {
privs = {
interact = true
},
func = function(name, params)
local voteset = vote.get_next_vote(name)
if not voteset then
2015-07-16 19:15:34 +03:00
minetest.chat_send_player(name,
"There is no vote currently running!")
2015-07-16 19:12:25 +03:00
return
elseif not voteset.results.yes then
minetest.chat_send_player(name, "The vote is not a yes/no one.")
return
elseif voteset.can_vote and not voteset:can_vote(name) then
2015-07-16 19:15:34 +03:00
minetest.chat_send_player(name,
"You can't vote in the currently active vote!")
2015-07-16 19:12:25 +03:00
return
end
vote.vote(voteset, name, "yes")
end
})
minetest.register_chatcommand("no", {
privs = {
interact = true
},
func = function(name, params)
local voteset = vote.get_next_vote(name)
if not voteset then
2015-07-16 19:15:34 +03:00
minetest.chat_send_player(name,
"There is no vote currently running!")
2015-07-16 19:12:25 +03:00
return
elseif not voteset.results.no then
minetest.chat_send_player(name, "The vote is not a yes/no one.")
return
elseif voteset.can_vote and not voteset:can_vote(name) then
2015-07-16 19:15:34 +03:00
minetest.chat_send_player(name,
"You can't vote in the currently active vote!")
2015-07-16 19:12:25 +03:00
return
end
vote.vote(voteset, name, "no")
end
})
minetest.register_chatcommand("abstain", {
privs = {
interact = true
},
func = function(name, params)
local voteset = vote.get_next_vote(name)
if not voteset then
2015-07-16 19:15:34 +03:00
minetest.chat_send_player(name,
"There is no vote currently running!")
2015-07-16 19:12:25 +03:00
return
elseif voteset.can_vote and not voteset:can_vote(name) then
2015-07-16 19:15:34 +03:00
minetest.chat_send_player(name,
"You can't vote in the currently active vote!")
2015-07-16 19:12:25 +03:00
return
end
table.insert(voteset.results.abstain, name)
voteset.results.voted[name] = true
if voteset.on_abstain then
voteset:on_abstain(name)
end
vote.check_vote(voteset)
end
})
2024-12-07 11:53:53 +03:00
minetest.register_chatcommand("vote_list_ignored", {
2024-12-07 11:53:53 +03:00
privs = {
vote_admin = true,
},
description = "Get a list of players ignored during voting",
func = function(name, params)
minetest.chat_send_player(
name,
"Ignored players: " .. storage:get_string("ignored_players")
2024-12-07 11:53:53 +03:00
)
end
})
minetest.register_chatcommand("vote_ignore", {
privs = {
vote_admin = true,
},
description = "Ignore player(s) during voting",
params = "<PlayerName>...",
func = function(name, params)
storage:set_string(
2024-12-07 11:53:53 +03:00
"ignored_players",
storage:get_string("ignored_players") .. params.. " "
2024-12-07 11:53:53 +03:00
)
end
})
minetest.register_chatcommand("vote_clear_ignored", {
privs = {
vote_admin = true,
},
description = "Clear list of players ignored during voting",
func = function(name, params)
storage:set_string("ignored_players","")
minetest.chat_send_player(
name,
"The list of ignored players has been cleared"
)
end
})