2022-05-29 16:28:20 -07:00
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 )
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 )
if arena.state == ' choose_artist ' then
--choose the artist
local artist_canidates = { }
for pl_name , stats in pairs ( arena.players ) do
if stats.has_built == false 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.players [ arena.artist ] . has_built = 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 " } ) 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 " 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[13.5,3] " ..
" background9[0,0;0,0;quikbild_gui_bg.png;true;6,6] " ..
" 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] " )
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 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 )