2021-05-29 14:12:33 +00:00
local S = minetest.get_translator ( minetest.get_current_modname ( ) )
local C = minetest.colorize
local math = math
2019-03-07 23:22:28 +00:00
2021-03-11 23:10:50 +00:00
mcl_jukebox = { }
mcl_jukebox.registered_records = { }
2017-08-03 13:10:11 +00:00
-- Player name-indexed table containing the currently heard track
2017-01-11 15:25:04 +00:00
local active_tracks = { }
2017-08-03 13:10:11 +00:00
-- Player name-indexed table containing the current used HUD ID for the “Now playing” message.
2017-01-11 21:32:38 +00:00
local active_huds = { }
2017-01-11 15:25:04 +00:00
2017-08-03 13:10:11 +00:00
-- Player name-indexed table for the “Now playing” message.
-- Used to make sure that minetest.after only applies to the latest HUD change event
local hud_sequence_numbers = { }
2021-03-11 23:10:50 +00:00
function mcl_jukebox . register_record ( title , author , identifier , image , sound )
mcl_jukebox.registered_records [ " mcl_jukebox:record_ " .. identifier ] = { title , author , identifier , image , sound }
local entryname = S ( " Music Disc " )
local longdesc = S ( " A music disc holds a single music track which can be used in a jukebox to play music. " )
local usagehelp = S ( " Place a music disc into an empty jukebox to play the music. Use the jukebox again to retrieve the music disc. The music can only be heard by you, not by other players. " )
minetest.register_craftitem ( " :mcl_jukebox:record_ " .. identifier , {
2017-01-11 15:25:04 +00:00
description =
2021-05-29 14:12:33 +00:00
C ( mcl_colors.AQUA , S ( " Music Disc " ) ) .. " \n " ..
C ( mcl_colors.GRAY , S ( " @1—@2 " , author , title ) ) ,
2021-03-11 23:10:50 +00:00
_doc_items_create_entry = true ,
2017-03-10 04:10:08 +00:00
_doc_items_entry_name = entryname ,
_doc_items_longdesc = longdesc ,
_doc_items_usagehelp = usagehelp ,
2021-03-11 23:10:50 +00:00
--inventory_image = "mcl_jukebox_record_"..recorddata[r][3]..".png",
inventory_image = image ,
2017-01-11 15:25:04 +00:00
stack_max = 1 ,
2021-03-11 23:10:50 +00:00
groups = { music_record = 1 } ,
2017-01-11 15:25:04 +00:00
} )
end
2021-03-11 23:10:50 +00:00
local function now_playing ( player , name )
2017-08-03 13:10:11 +00:00
local playername = player : get_player_name ( )
local hud = active_huds [ playername ]
2021-03-11 23:10:50 +00:00
local text = S ( " Now playing: @1—@2 " , mcl_jukebox.registered_records [ name ] [ 2 ] , mcl_jukebox.registered_records [ name ] [ 1 ] )
2017-01-11 21:32:38 +00:00
2017-08-03 13:10:11 +00:00
if not hud_sequence_numbers [ playername ] then
hud_sequence_numbers [ playername ] = 1
else
hud_sequence_numbers [ playername ] = hud_sequence_numbers [ playername ] + 1
end
2017-01-20 02:28:53 +00:00
local id
2021-05-29 14:12:33 +00:00
if hud then
2017-08-03 13:10:11 +00:00
id = hud
player : hud_change ( id , " text " , text )
2017-01-11 21:32:38 +00:00
else
2017-01-20 02:28:53 +00:00
id = player : hud_add ( {
2017-01-11 21:32:38 +00:00
hud_elem_type = " text " ,
position = { x = 0.5 , y = 0.8 } ,
offset = { x = 0 , y = 0 } ,
2017-01-11 23:24:52 +00:00
number = 0x55FFFF ,
2017-01-11 21:32:38 +00:00
text = text ,
2020-04-17 19:27:45 +00:00
z_index = 100 ,
2017-01-11 21:32:38 +00:00
} )
2017-08-03 13:10:11 +00:00
active_huds [ playername ] = id
2017-01-11 21:32:38 +00:00
end
minetest.after ( 5 , function ( tab )
2018-06-03 14:44:37 +00:00
local playername = tab [ 1 ]
local player = minetest.get_player_by_name ( playername )
2017-01-11 21:32:38 +00:00
local id = tab [ 2 ]
2017-08-03 13:10:11 +00:00
local seq = tab [ 3 ]
if not player or not player : is_player ( ) or not active_huds [ playername ] or not hud_sequence_numbers [ playername ] or seq ~= hud_sequence_numbers [ playername ] then
2017-01-11 21:32:38 +00:00
return
end
2021-05-29 14:12:33 +00:00
if id and id == active_huds [ playername ] then
2017-08-03 13:10:11 +00:00
player : hud_remove ( active_huds [ playername ] )
active_huds [ playername ] = nil
2017-01-11 21:32:38 +00:00
end
2018-06-03 14:44:37 +00:00
end , { playername , id , hud_sequence_numbers [ playername ] } )
2017-01-11 21:32:38 +00:00
end
minetest.register_on_leaveplayer ( function ( player )
active_tracks [ player : get_player_name ( ) ] = nil
active_huds [ player : get_player_name ( ) ] = nil
2017-08-03 13:10:11 +00:00
hud_sequence_numbers [ player : get_player_name ( ) ] = nil
2017-01-11 21:32:38 +00:00
end )
2017-01-11 15:25:04 +00:00
-- Jukebox crafting
minetest.register_craft ( {
2021-05-29 14:12:33 +00:00
output = " mcl_jukebox:jukebox " ,
2017-01-11 15:25:04 +00:00
recipe = {
2021-05-29 14:12:33 +00:00
{ " group:wood " , " group:wood " , " group:wood " } ,
{ " group:wood " , " mcl_core:diamond " , " group:wood " } ,
{ " group:wood " , " group:wood " , " group:wood " } ,
2017-01-11 15:25:04 +00:00
}
} )
2021-05-29 14:12:33 +00:00
local function play_record ( pos , itemstack , player )
2021-03-11 23:10:50 +00:00
local name = itemstack : get_name ( )
if mcl_jukebox.registered_records [ name ] then
2018-05-12 20:48:49 +00:00
local cname = player : get_player_name ( )
2021-05-29 14:12:33 +00:00
if active_tracks [ cname ] then
2018-05-12 19:50:56 +00:00
minetest.sound_stop ( active_tracks [ cname ] )
active_tracks [ cname ] = nil
end
2021-03-11 23:10:50 +00:00
active_tracks [ cname ] = minetest.sound_play ( mcl_jukebox.registered_records [ name ] [ 5 ] , {
2018-05-12 20:48:49 +00:00
to_player = cname ,
2018-05-12 19:50:56 +00:00
gain = 1 ,
} )
2021-03-11 23:10:50 +00:00
now_playing ( player , name )
2018-05-12 19:50:56 +00:00
return true
end
return false
end
2017-01-11 21:32:38 +00:00
2017-01-11 15:25:04 +00:00
-- Jukebox
minetest.register_node ( " mcl_jukebox:jukebox " , {
2019-03-07 23:22:28 +00:00
description = S ( " Jukebox " ) ,
2020-02-19 03:54:17 +00:00
_tt_help = S ( " Uses music discs to play music " ) ,
2019-03-07 23:22:28 +00:00
_doc_items_longdesc = S ( " Jukeboxes play music when they're supplied with a music disc. " ) ,
_doc_items_usagehelp = S ( " Place a music disc into an empty jukebox to insert the music disc and play music. If the jukebox already has a music disc, you will retrieve this music disc first. The music can only be heard by you, not by other players. " ) ,
2017-01-11 15:25:04 +00:00
tiles = { " mcl_jukebox_top.png " , " mcl_jukebox_side.png " , " mcl_jukebox_side.png " } ,
2017-02-11 17:46:23 +00:00
sounds = mcl_sounds.node_sound_wood_defaults ( ) ,
2020-04-18 21:24:42 +00:00
groups = { handy = 1 , axey = 1 , container = 7 , deco_block = 1 , material_wood = 1 , flammable =- 1 } ,
2017-03-11 15:36:05 +00:00
is_ground_content = false ,
2017-01-11 15:25:04 +00:00
on_construct = function ( pos )
local meta = minetest.get_meta ( pos )
local inv = meta : get_inventory ( )
inv : set_size ( " main " , 1 )
end ,
2017-01-11 21:40:00 +00:00
on_rightclick = function ( pos , node , clicker , itemstack , pointed_thing )
if not clicker then return end
local cname = clicker : get_player_name ( )
2019-02-08 20:59:01 +00:00
if minetest.is_protected ( pos , cname ) then
minetest.record_protection_violation ( pos , cname )
return
end
2017-01-11 15:25:04 +00:00
local meta = minetest.get_meta ( pos )
local inv = meta : get_inventory ( )
if not inv : is_empty ( " main " ) then
-- Jukebox contains a disc: Stop music and remove disc
2021-05-29 14:12:33 +00:00
if active_tracks [ cname ] then
2017-01-11 21:40:00 +00:00
minetest.sound_stop ( active_tracks [ cname ] )
2017-01-11 15:25:04 +00:00
end
local lx = pos.x
local ly = pos.y + 1
local lz = pos.z
local record = inv : get_stack ( " main " , 1 )
2018-05-12 21:57:49 +00:00
local dropped_item = minetest.add_item ( { x = lx , y = ly , z = lz } , record )
2017-11-18 21:12:36 +00:00
-- Rotate record to match with “slot” texture
dropped_item : set_yaw ( math.pi / 2 )
2017-01-11 15:25:04 +00:00
inv : set_stack ( " main " , 1 , " " )
2021-05-29 14:12:33 +00:00
if active_tracks [ cname ] then
2017-01-11 21:40:00 +00:00
minetest.sound_stop ( active_tracks [ cname ] )
active_tracks [ cname ] = nil
2020-12-21 12:13:01 +00:00
end
2021-05-29 14:12:33 +00:00
if active_huds [ cname ] then
2020-12-21 12:13:01 +00:00
clicker : hud_remove ( active_huds [ cname ] )
2017-01-11 21:40:00 +00:00
active_huds [ cname ] = nil
2017-01-11 15:25:04 +00:00
end
else
-- Jukebox is empty: Play track if player holds music record
2018-05-12 19:50:56 +00:00
local playing = play_record ( pos , itemstack , clicker )
if playing then
2018-05-12 21:57:49 +00:00
local put_itemstack = ItemStack ( itemstack )
put_itemstack : set_count ( 1 )
inv : set_stack ( " main " , 1 , put_itemstack )
2017-01-11 21:40:00 +00:00
itemstack : take_item ( )
2017-01-11 15:25:04 +00:00
end
end
2018-05-12 19:50:56 +00:00
return itemstack
2017-01-11 15:25:04 +00:00
end ,
2019-02-08 20:59:01 +00:00
allow_metadata_inventory_move = function ( pos , from_list , from_index , to_list , to_index , count , player )
local name = player : get_player_name ( )
if minetest.is_protected ( pos , name ) then
minetest.record_protection_violation ( pos , name )
return 0
else
return count
end
end ,
allow_metadata_inventory_take = function ( pos , listname , index , stack , player )
local name = player : get_player_name ( )
if minetest.is_protected ( pos , name ) then
minetest.record_protection_violation ( pos , name )
return 0
else
return stack : get_count ( )
end
end ,
allow_metadata_inventory_put = function ( pos , listname , index , stack , player )
local name = player : get_player_name ( )
if minetest.is_protected ( pos , name ) then
minetest.record_protection_violation ( pos , name )
return 0
else
return stack : get_count ( )
end
end ,
2017-01-11 15:25:04 +00:00
after_dig_node = function ( pos , oldnode , oldmetadata , digger )
2017-01-11 21:52:34 +00:00
local name = digger : get_player_name ( )
2017-01-11 15:25:04 +00:00
local meta = minetest.get_meta ( pos )
local meta2 = meta
meta : from_table ( oldmetadata )
local inv = meta : get_inventory ( )
local stack = inv : get_stack ( " main " , 1 )
if not stack : is_empty ( ) then
local p = { x = pos.x + math.random ( 0 , 10 ) / 10 - 0.5 , y = pos.y , z = pos.z + math.random ( 0 , 10 ) / 10 - 0.5 }
2017-11-18 21:12:36 +00:00
local dropped_item = minetest.add_item ( p , stack )
-- Rotate record to match with “slot” texture
dropped_item : set_yaw ( math.pi / 2 )
2021-05-29 14:12:33 +00:00
if active_tracks [ name ] then
2017-01-11 21:54:31 +00:00
minetest.sound_stop ( active_tracks [ name ] )
2017-01-11 22:22:09 +00:00
active_tracks [ name ] = nil
2020-12-21 12:13:01 +00:00
end
2021-05-29 14:12:33 +00:00
if active_huds [ name ] then
2020-12-21 12:13:01 +00:00
digger : hud_remove ( active_huds [ name ] )
2017-01-11 22:22:09 +00:00
active_huds [ name ] = nil
2017-01-11 21:54:31 +00:00
end
2017-01-11 15:25:04 +00:00
end
meta : from_table ( meta2 : to_table ( ) )
end ,
2020-04-17 19:40:13 +00:00
_mcl_blast_resistance = 6 ,
2017-02-27 00:33:34 +00:00
_mcl_hardness = 2 ,
2017-01-11 15:25:04 +00:00
} )
2017-01-11 21:48:53 +00:00
minetest.register_craft ( {
type = " fuel " ,
recipe = " mcl_jukebox:jukebox " ,
burntime = 15 ,
} )
2021-03-11 23:10:50 +00:00
mcl_jukebox.register_record ( " The Evil Sister (Jordach's Mix) " , " SoundHelix " , " 13 " , " mcl_jukebox_record_13.png " , " mcl_jukebox_track_1 " )
mcl_jukebox.register_record ( " The Energetic Rat (Jordach's Mix) " , " SoundHelix " , " wait " , " mcl_jukebox_record_wait.png " , " mcl_jukebox_track_2 " )
mcl_jukebox.register_record ( " Eastern Feeling " , " Jordach " , " blocks " , " mcl_jukebox_record_blocks.png " , " mcl_jukebox_track_3 " )
mcl_jukebox.register_record ( " Minetest " , " Jordach " , " far " , " mcl_jukebox_record_far.png " , " mcl_jukebox_track_4 " )
mcl_jukebox.register_record ( " Credit Roll (Jordach's HD Mix) " , " Junichi Masuda " , " chirp " , " mcl_jukebox_record_chirp.png " , " mcl_jukebox_track_5 " )
mcl_jukebox.register_record ( " Winter Feeling " , " Tom Peter " , " strad " , " mcl_jukebox_record_strad.png " , " mcl_jukebox_track_6 " )
mcl_jukebox.register_record ( " Synthgroove (Jordach's Mix) " , " HeroOfTheWinds " , " mellohi " , " mcl_jukebox_record_mellohi.png " , " mcl_jukebox_track_7 " )
2021-03-12 14:36:24 +00:00
mcl_jukebox.register_record ( " The Clueless Frog (Jordach's Mix) " , " SoundHelix " , " mall " , " mcl_jukebox_record_mall.png " , " mcl_jukebox_track_8 " )
--add backward compatibility
minetest.register_alias ( " mcl_jukebox:record_1 " , " mcl_jukebox:record_13 " )
minetest.register_alias ( " mcl_jukebox:record_2 " , " mcl_jukebox:record_wait " )
minetest.register_alias ( " mcl_jukebox:record_3 " , " mcl_jukebox:record_blocks " )
minetest.register_alias ( " mcl_jukebox:record_4 " , " mcl_jukebox:record_far " )
minetest.register_alias ( " mcl_jukebox:record_5 " , " mcl_jukebox:record_chirp " )
minetest.register_alias ( " mcl_jukebox:record_6 " , " mcl_jukebox:record_strad " )
minetest.register_alias ( " mcl_jukebox:record_7 " , " mcl_jukebox:record_mellohi " )
minetest.register_alias ( " mcl_jukebox:record_8 " , " mcl_jukebox:record_mall " )