1 local S
= minetest
.get_translator("mcl_jukebox")
3 -- Player name-indexed table containing the currently heard track
4 local active_tracks
= {}
6 -- Player name-indexed table containing the current used HUD ID for the “Now playing” message.
9 -- Player name-indexed table for the “Now playing” message.
10 -- Used to make sure that minetest.after only applies to the latest HUD change event
11 local hud_sequence_numbers
= {}
15 -- { title, author, identifier }
16 { "The Evil Sister (Jordach's Mix)", "SoundHelix", "13" } ,
17 { "The Energetic Rat (Jordach's Mix)", "SoundHelix", "wait" },
18 { "Eastern Feeling", "Jordach", "blocks"},
19 { "Minetest", "Jordach", "far" },
20 { "Credit Roll (Jordach's HD Mix)", "Junichi Masuda", "chirp" },
21 { "Winter Feeling", "Tom Peter", "strad" },
22 { "Synthgroove (Jordach's Mix)", "HeroOfTheWinds", "mellohi" },
23 { "The Clueless Frog (Jordach's Mix)", "SoundHelix", "mall" },
25 local records
= #recorddata
29 local entryname
, longdesc
, usagehelp
32 entryname
= S("Music Disc")
33 longdesc
= S("A music disc holds a single music track which can be used in a jukebox to play music.")
34 usagehelp
= S("Place a music dict 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.")
36 minetest
.register_craftitem("mcl_jukebox:record_"..r
, {
38 core
.colorize("#55FFFF", S("Music Disc")) .. "\n" ..
39 core
.colorize("#989898", S("@1—@2", recorddata
[r
][2], recorddata
[r
][1])),
40 _doc_items_create_entry
= doc
,
41 _doc_items_entry_name
= entryname
,
42 _doc_items_longdesc
= longdesc
,
43 _doc_items_usagehelp
= usagehelp
,
44 inventory_image
= "mcl_jukebox_record_"..recorddata
[r
][3]..".png",
46 groups
= { music_record
= r
},
50 local function now_playing(player
, track_id
)
51 local playername
= player
:get_player_name()
52 local hud
= active_huds
[playername
]
53 local text
= S("Now playing: @1—@2", recorddata
[track_id
][2], recorddata
[track_id
][1])
55 if not hud_sequence_numbers
[playername
] then
56 hud_sequence_numbers
[playername
] = 1
58 hud_sequence_numbers
[playername
] = hud_sequence_numbers
[playername
] + 1
64 player
:hud_change(id
, "text", text
)
67 hud_elem_type
= "text",
68 position
= { x
=0.5, y
=0.8 },
69 offset
= { x
=0, y
= 0 },
70 size
= { x
=100, y
=100},
75 active_huds
[playername
] = id
77 minetest
.after(5, function(tab
)
78 local playername
= tab
[1]
79 local player
= minetest
.get_player_by_name(playername
)
82 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
85 if id
== active_huds
[playername
] then
86 player
:hud_remove(active_huds
[playername
])
87 active_huds
[playername
] = nil
89 end, {playername
, id
, hud_sequence_numbers
[playername
]})
93 minetest
.register_on_leaveplayer(function(player
)
94 active_tracks
[player
:get_player_name()] = nil
95 active_huds
[player
:get_player_name()] = nil
96 hud_sequence_numbers
[player
:get_player_name()] = nil
100 minetest
.register_craft({
101 output
= 'mcl_jukebox:jukebox',
103 {'group:wood', 'group:wood', 'group:wood'},
104 {'group:wood', 'mcl_core:diamond', 'group:wood'},
105 {'group:wood', 'group:wood', 'group:wood'},
109 local play_record
= function(pos
, itemstack
, player
)
110 local record_id
= minetest
.get_item_group(itemstack
:get_name(), "music_record")
111 if record_id
~= 0 then
112 local cname
= player
:get_player_name()
113 if active_tracks
[cname
] ~= nil then
114 minetest
.sound_stop(active_tracks
[cname
])
115 active_tracks
[cname
] = nil
117 active_tracks
[cname
] = minetest
.sound_play("mcl_jukebox_track_"..record_id
, {
121 now_playing(player
, record_id
)
128 minetest
.register_node("mcl_jukebox:jukebox", {
129 description
= S("Jukebox"),
130 _tt_help
= S("Uses music discs to play music"),
131 _doc_items_longdesc
= S("Jukeboxes play music when they're supplied with a music disc."),
132 _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."),
133 tiles
= {"mcl_jukebox_top.png", "mcl_jukebox_side.png", "mcl_jukebox_side.png"},
134 sounds
= mcl_sounds
.node_sound_wood_defaults(),
135 groups
= {handy
=1,axey
=1, container
=7, deco_block
=1, material_wood
=1, flammable
=-1},
136 is_ground_content
= false,
137 on_construct
= function(pos
)
138 local meta
= minetest
.get_meta(pos
)
139 local inv
= meta
:get_inventory()
140 inv
:set_size("main", 1)
142 on_rightclick
= function(pos
, node
, clicker
, itemstack
, pointed_thing
)
143 if not clicker
then return end
144 local cname
= clicker
:get_player_name()
145 if minetest
.is_protected(pos
, cname
) then
146 minetest
.record_protection_violation(pos
, cname
)
149 local meta
= minetest
.get_meta(pos
)
150 local inv
= meta
:get_inventory()
151 if not inv
:is_empty("main") then
152 -- Jukebox contains a disc: Stop music and remove disc
153 if active_tracks
[cname
] ~= nil then
154 minetest
.sound_stop(active_tracks
[cname
])
159 local record
= inv
:get_stack("main", 1)
160 local dropped_item
= minetest
.add_item({x
=lx
, y
=ly
, z
=lz
}, record
)
161 -- Rotate record to match with “slot” texture
162 dropped_item
:set_yaw(math
.pi
/2)
163 inv
:set_stack("main", 1, "")
164 if active_tracks
[cname
] ~= nil then
165 minetest
.sound_stop(active_tracks
[cname
])
166 clicker
:hud_remove(active_huds
[cname
])
167 active_tracks
[cname
] = nil
168 active_huds
[cname
] = nil
171 -- Jukebox is empty: Play track if player holds music record
172 local playing
= play_record(pos
, itemstack
, clicker
)
174 local put_itemstack
= ItemStack(itemstack
)
175 put_itemstack
:set_count(1)
176 inv
:set_stack("main", 1, put_itemstack
)
177 itemstack
:take_item()
182 allow_metadata_inventory_move
= function(pos
, from_list
, from_index
, to_list
, to_index
, count
, player
)
183 local name
= player
:get_player_name()
184 if minetest
.is_protected(pos
, name
) then
185 minetest
.record_protection_violation(pos
, name
)
191 allow_metadata_inventory_take
= function(pos
, listname
, index
, stack
, player
)
192 local name
= player
:get_player_name()
193 if minetest
.is_protected(pos
, name
) then
194 minetest
.record_protection_violation(pos
, name
)
197 return stack
:get_count()
200 allow_metadata_inventory_put
= function(pos
, listname
, index
, stack
, player
)
201 local name
= player
:get_player_name()
202 if minetest
.is_protected(pos
, name
) then
203 minetest
.record_protection_violation(pos
, name
)
206 return stack
:get_count()
209 after_dig_node
= function(pos
, oldnode
, oldmetadata
, digger
)
210 local name
= digger
:get_player_name()
211 local meta
= minetest
.get_meta(pos
)
213 meta
:from_table(oldmetadata
)
214 local inv
= meta
:get_inventory()
215 local stack
= inv
:get_stack("main", 1)
216 if not stack
:is_empty() then
217 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}
218 local dropped_item
= minetest
.add_item(p
, stack
)
219 -- Rotate record to match with “slot” texture
220 dropped_item
:set_yaw(math
.pi
/2)
221 if active_tracks
[name
] ~= nil then
222 minetest
.sound_stop(active_tracks
[name
])
223 digger
:hud_remove(active_huds
[name
])
224 active_tracks
[name
] = nil
225 active_huds
[name
] = nil
228 meta
:from_table(meta2
:to_table())
230 _mcl_blast_resistance
= 6,
234 minetest
.register_craft({
236 recipe
= "mcl_jukebox:jukebox",