quikbild/minigame_manager.lua

466 lines
18 KiB
Lua

local S = minetest.get_translator("quikbild")
local storage = quikbild.storage
-- funcs defined
local clearinv = function(p_name) end
local send_lang_fs = function(p_name) end
arena_lib.on_load("quikbild", function(arena)
--randomize math.random
math.randomseed = os.time()
local f = quikbild.csv.open(minetest.get_modpath("quikbild")..arena.word_list_path)
if not f then
f = quikbild.csv.open(minetest.get_worldpath()..arena.word_list_path)
end
if f then
local word_list = {}
for fields in f:lines() do
local translation_list = {}
for i, v in ipairs(fields) do
table.insert(translation_list,v)
end
table.insert(word_list,translation_list)
end
arena.word_list = word_list
end
-- send the lang chooser fs
for pl_name,stats in pairs(arena.players) do
local code = storage:get_string("lang_"..pl_name)
code = tonumber(code) or 1
arena.players[pl_name].lang = code
end
local poss = {}
local ser_poss = storage:get_string("pos_"..arena.name)
if ser_poss then
poss = minetest.deserialize(ser_poss)
if poss == nil then poss = {} end
end
for _,pos in ipairs(poss) do
minetest.set_node(pos, {name="quikbild:climb"})
end
storage:set_string("pos_"..arena.name,minetest.serialize({}))
end)
arena_lib.on_time_tick('quikbild', function(arena)
-- kick players who have been voted out
-- if arena.state ~= "game_over" and arena.in_celebration == false then
-- local num_players = 0
-- for pl_name,stats in pairs(arena.players) do
-- num_players = num_players + 1
-- end
-- for pl_name,stats in pairs(arena.players) do
-- if stats.kickvotes > num_players/3 and num_players > 4 then
-- arena_lib.remove_player_from_arena(pl_name, 2)
-- local msg = S("You were kicked by vote. Feel free to play again, but try not to be AFK during your turn, build letters, or tell players what your word is when you are the builder.")
-- minetest.chat_send_player(pl_name,minetest.colorize("#7D7071",">> "..msg))
-- end
-- end
-- end
if arena.state == 'choose_artist' then
--choose the artist
local artist_canidates = {}
for pl_name,stats in pairs(arena.players) do
if arena.has_built[pl_name] ~= true then
table.insert(artist_canidates,pl_name)
end
end
if #artist_canidates == 0 then --we have reached game's end
arena.state = 'game_over'
local winning_score = 0
local winners = {}
for pl_name,stats in pairs(arena.players) do
if stats.score == winning_score then
table.insert(winners,pl_name)
elseif stats.score > winning_score then
winning_score = stats.score
winners = {pl_name}
end
end
if winning_score == 0 then --if no one got any points, then eliminate everyone
arena_lib.HUD_send_msg_all("broadcast", arena, S('No one got any points')..' :( '..S('Try again!'), 3 ,'sumo_lose',0xFF0000)
minetest.after(4,function(arena)
arena_lib.force_arena_ending('quikbild', arena,'Game')
end,arena)
else
local winner_string = ''
local pts = 0
for _,pl_name in pairs(winners) do
winner_string = winner_string..pl_name..", "
end
arena_lib.HUD_send_msg_all("broadcast", arena, winner_string..' '..S('won with')..' '..winning_score.. ' pts!', 3 ,'sumo_win',0x0000AA)
-- minetest.log(dump(winners))
minetest.after(4,function(arena) --cant use arena_lib.load celebration rn, doesnt recognize more than 1 winner
arena_lib.force_arena_ending('quikbild', arena,'Game')
end,arena)
end
return
end
--game isn't over, so we choose the artist
local rand_art_idx = math.random(1,#artist_canidates)
arena.artist = artist_canidates[rand_art_idx]
arena.has_built[arena.artist] = true --indicate that they were the artist
arena.state = 'build_think' --change the arena state so we dont run this code again
--send info messages
arena_lib.HUD_send_msg("broadcast", arena.artist, S('You are the Artist. Build the word you see'), 4 ,nil,0xFF0000)
for pl_name,stats in pairs(arena.players) do
if pl_name ~= arena.artist then
arena_lib.HUD_send_msg("broadcast", pl_name, arena.artist .. ' '..S('is the artist.'), 2 ,nil,0xFF0000)
-- give everyone except the artist helpful tools
local l_player = minetest.get_player_by_name(pl_name)
l_player:hud_set_hotbar_itemcount(2)
for idx ,itemname in pairs({
"quikbild:lang",
"quikbild:help",
--"quikbild:kick"
}) do
local item = ItemStack(itemname)
l_player:get_inventory():set_stack("main", idx, item)
end
minetest.after(2, function(arena,pl_name)
arena_lib.HUD_send_msg("hotbar", pl_name, S('Guess what they are building.'), 2 ,nil,0xFF0000)
end,arena,pl_name)
else
-- set the artist's hotbar larger
local player = minetest.get_player_by_name(pl_name)
player:hud_set_hotbar_itemcount(#dye.dyes)
end
end
--choose the word
arena.word = arena.word_list[math.random(1,#arena.word_list)]
-- clear the board of old building peices
local poss = {}
local ser_poss = storage:get_string("pos_"..arena.name)
if ser_poss then
poss = minetest.deserialize(ser_poss)
if poss == nil then poss = {} end
end
for _,pos in ipairs(poss) do
minetest.set_node(pos, {name="quikbild:climb"})
end
storage:set_string("pos_"..arena.name,minetest.serialize({}))
-- teleport the artist in to the building area.
local artist_pl = minetest.get_player_by_name(arena.artist)
artist_pl:move_to(arena.artist_spawn_pos)
end
if arena.state == 'build_think' then
arena.state_time = arena.state_time + 1 --increase the timer counter
if arena.state_time == 4 then
--send the word to the artist
arena_lib.HUD_send_msg("title", arena.artist, arena.word[arena.players[arena.artist].lang], 4 ,nil,0xFF0000)
arena_lib.HUD_send_msg_all("broadcast", arena, S('Round begins in')..' 5', 1 ,nil,0xFF0000)
end
if arena.state_time == 5 then
arena_lib.HUD_send_msg_all("broadcast", arena, S('Round begins in')..' 4', 1 ,nil,0xFF0000)
end
if arena.state_time == 6 then
arena_lib.HUD_send_msg_all("broadcast", arena, S('Round begins in')..' 3', 1 ,nil,0xFF0000)
end
if arena.state_time == 7 then
arena_lib.HUD_send_msg_all("broadcast", arena, S('Round begins in')..' 2', 1 ,nil,0xFF0000)
end
if arena.state_time == 8 then
arena_lib.HUD_send_msg_all("broadcast", arena, S('Round begins in')..' 1', 1 ,nil,0xFF0000)
end
if arena.state_time == 9 then
--give the artist his tools, send start to everyone, change state
for pl_name, stats in pairs(arena.players) do
if pl_name == arena.artist then
local player = minetest.get_player_by_name(pl_name)
for idx ,itemname in pairs(quikbild.items) do
local item = ItemStack(itemname)
player:get_inventory():set_stack("main", idx, item)
end
arena_lib.HUD_send_msg("title", pl_name, S('BUILD!'), 1 ,nil,0x00FF00)
else
arena_lib.HUD_send_msg("title", pl_name, S('BEGIN GUESSSING!'), 1 ,nil,0x00FF00)
end
arena.state = 'build'
arena.state_time = 0
end
end
end
if arena.state == 'build' then
if not arena.stall then
local time_left = arena.build_time - arena.state_time
local art_is_in_game = false
for pl_name,stats in pairs(arena.players) do
if pl_name == arena.artist then
art_is_in_game = true
end
end
if not(art_is_in_game) then --if arena.artist is no longer in the game, then send message to players, and change game state to choose artist, and return
for pl_name,stats in pairs(arena.players) do
local msg = S("Oops! The artist left the game. The word was").." "..arena.word[stats.lang]
arena_lib.HUD_send_msg("title", pl_name, msg, 3, 'sumo_elim',0xFFFFFF)
minetest.chat_send_player(pl_name,minetest.colorize("#7D7071",">> "..msg))
end
arena.stall = true --stop gameplay for 3 sec
minetest.after(3,function(arena)
if arena.in_game then
arena.stall = false
arena.state = 'choose_artist'
arena.state_time = 0
for pl_name,stats in pairs(arena.players) do
local pos = arena_lib.get_random_spawner(arena)
local pl_obj = minetest.get_player_by_name(pl_name)
pl_obj:move_to(pos)
clearinv(pl_name)
end
end
end,arena)
return
end
if time_left == 0 then
--change game state
for pl_name,stats in pairs(arena.players) do
local msg = S("TIME's UP! The word was:").." "..arena.word[stats.lang]
arena_lib.HUD_send_msg("title", pl_name, msg, 3, 'sumo_lose',0xFFFFFF)
minetest.chat_send_player(pl_name,minetest.colorize("#7D7071",">> "..msg))
end
arena.stall = true --stop gameplay for 3 sec
minetest.after(3,function(arena)
if arena.in_game then
arena.stall = false
arena.state = 'choose_artist'
arena.state_time = 0
for pl_name,stats in pairs(arena.players) do
local pos = arena_lib.get_random_spawner(arena)
local pl_obj = minetest.get_player_by_name(pl_name)
pl_obj:move_to(pos)
clearinv(pl_name)
end
end
end,arena)
return
end
for pl_name,stats in pairs(arena.players) do
if pl_name == arena.artist then
arena_lib.HUD_send_msg("hotbar", pl_name, S("WORD")..": ".. arena.word[stats.lang] .." TIME: "..time_left, 1 ,nil,0xFFFFFF)
else
arena_lib.HUD_send_msg("hotbar", pl_name, S("TIME LEFT IN ROUND")..": "..time_left, 1 ,nil,0xFFFFFF)
end
end
arena.state_time = arena.state_time + 1
end
end
end)
table.insert(minetest.registered_on_chat_messages, 1, function(p_name, message) --thanks rubenwardy, for giving this code snippet that works around Arena_libs's chat prevention!
if message:sub(1, 1) == "/" then
return false
end
if arena_lib.is_player_in_arena(p_name,'quikbild') then
local arena = arena_lib.get_arena_by_player(p_name)
if not(arena.in_queue) and not(arena.in_celebration) and not(arena.in_loading) then
if arena.state == 'build' and arena.stall == false then
if p_name == arena.artist then
return true -- prevent cheating!
else
if string.find(message,arena.word[arena.players[p_name].lang]) then -- if the word was said...
for pl_name, stats in pairs(arena.players) do
if pl_name == p_name then
local list = {S('Correct!'), S('You got it!'),S('Way to go!'), S('Outstanding!'), S('Yay!')}
local msg = list[math.random(1,5)]..' +1 pt'
arena_lib.HUD_send_msg("title", pl_name, msg, 3 ,'sumo_win',0x00FF00)
minetest.chat_send_player(pl_name,minetest.colorize("#7D7071",">> "..msg.." "..S("The word was:").." "..arena.word[stats.lang]))
arena.players[p_name].score = arena.players[p_name].score + 1
elseif pl_name == arena.artist then
local msg = S('Yay!').. ' '.. p_name ..' ' .. S('guessed your word.') ..' +1 pt'
arena_lib.HUD_send_msg("title", pl_name, msg, 3 ,'sumo_win',0x00FF00)
arena.players[pl_name].score = arena.players[pl_name].score + 1
else
local msg = p_name..' '..S('guessed the word. Round over!')
arena_lib.HUD_send_msg("title", pl_name, msg, 3 ,'sumo_elim',0x00FF00)
minetest.chat_send_player(pl_name,minetest.colorize("#7D7071",">> "..msg.." "..S("The word was:").." "..arena.word[stats.lang]))
end
end
arena.stall = true --stop gameplay for 3 sec
minetest.after(3,function(arena)
if arena.in_game then
arena.stall = false
arena.state = 'choose_artist'
arena.state_time = 0
for pl_name,stats in pairs(arena.players) do
local pos = arena_lib.get_random_spawner(arena)
local pl_obj = minetest.get_player_by_name(pl_name)
pl_obj:move_to(pos)
clearinv(pl_name)
end
end
end,arena)
end
end
end
end
end
end)
arena_lib.on_celebration('quikbild', function(arena, winner_name)
for pl_name,stats in pairs(arena.players) do
minetest.close_formspec(pl_name, "qb_lang")
end
end)
arena_lib.on_quit('quikbild', function(arena, p_name, is_forced)
minetest.close_formspec(p_name, "qb_lang")
end)
minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
clearinv(name)
end)
-- ##########################
-- Functions Defined
-- ##########################
-- clears inventory of quikbild items
clearinv = function(p_name)
local player = minetest.get_player_by_name(p_name)
local inv = player:get_inventory()
for idx ,itemname in pairs(quikbild.items) do
local stack = ItemStack(itemname)
local taken = inv:remove_item("main", stack)
end
local list = inv:get_list("main")
for k, v in pairs(list) do
if v:get_name() == "quikbild:lang" or v:get_name() == "quikbild:help" or v:get_name() == "quikbild:kick" then
inv:remove_item("main", v)
end
end
end
send_lang_fs = function(p_name)
minetest.show_formspec(p_name, "qb_lang", "formspec_version[5]"..
"size[16.6,3]"..
"background9[0,0;0,0;quikbild_gui_bg.png;true;6,6]"..
"style_type[image_button;textcolor=#302C2E;font=normal,bold]"..
"image_button[0.6,0.6;2.6,1.8;english.png;english;EN;false;true]"..
"image_button[3.8,0.6;2.6,1.8;italian.png;italian;IT;false;true]"..
"image_button[7,0.6;2.6,1.8;spanish.png;spanish;ES;false;true]"..
"image_button[10.2,0.6;2.6,1.8;french.png;french;FR;false;true]"..
"image_button[13.4,0.6;2.6,1.8;german.png;german;DE;false;true]")
end
quikbild.send_lang_fs = send_lang_fs
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "qb_lang" then return end
local p_name = player:get_player_name()
local arena = arena_lib.get_arena_by_player(p_name)
local setting = 0
if fields.english then
setting = 1
minetest.close_formspec(p_name, "qb_lang")
end
if fields.italian then
setting = 2
minetest.close_formspec(p_name, "qb_lang")
end
if fields.spanish then
setting = 3
minetest.close_formspec(p_name, "qb_lang")
end
if fields.french then
setting = 4
minetest.close_formspec(p_name, "qb_lang")
end
if fields.german then
setting = 5
minetest.close_formspec(p_name, "qb_lang")
end
if setting ~= 0 then
local code = setting
code = tostring(code)
storage:set_string("lang_"..p_name,code)
if arena then
arena.players[p_name].lang = setting
end
minetest.chat_send_player(p_name,minetest.colorize("#7D7071",">> "..S("Language setting confirmed!")))
end
end)