Merge branch 'mcl_explosions'
[MineClone/MineClone2.git] / mods / ITEMS / mcl_jukebox / init.lua
blobbace6dd20cf06efe0a13bf6bf83de25049e80357
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.
7 local active_huds = {}
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 = {}
13 -- List of music
14 local recorddata = {
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
27 for r=1, records do
28 local doc = false
29 local entryname, longdesc, usagehelp
30 if r == 1 then
31 doc = true
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.")
35 end
36 minetest.register_craftitem("mcl_jukebox:record_"..r, {
37 description =
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",
45 stack_max = 1,
46 groups = { music_record = r },
48 end
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
57 else
58 hud_sequence_numbers[playername] = hud_sequence_numbers[playername] + 1
59 end
61 local id
62 if hud ~= nil then
63 id = hud
64 player:hud_change(id, "text", text)
65 else
66 id = player:hud_add({
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},
71 number = 0x55FFFF,
72 text = text,
73 z_index = 100,
75 active_huds[playername] = id
76 end
77 minetest.after(5, function(tab)
78 local playername = tab[1]
79 local player = minetest.get_player_by_name(playername)
80 local id = tab[2]
81 local seq = tab[3]
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
83 return
84 end
85 if id == active_huds[playername] then
86 player:hud_remove(active_huds[playername])
87 active_huds[playername] = nil
88 end
89 end, {playername, id, hud_sequence_numbers[playername]})
91 end
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
97 end)
99 -- Jukebox crafting
100 minetest.register_craft({
101 output = 'mcl_jukebox:jukebox',
102 recipe = {
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, {
118 to_player = cname,
119 gain = 1,
121 now_playing(player, record_id)
122 return true
124 return false
127 -- Jukebox
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)
141 end,
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)
147 return
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])
156 local lx = pos.x
157 local ly = pos.y+1
158 local lz = pos.z
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
170 else
171 -- Jukebox is empty: Play track if player holds music record
172 local playing = play_record(pos, itemstack, clicker)
173 if playing then
174 local put_itemstack = ItemStack(itemstack)
175 put_itemstack:set_count(1)
176 inv:set_stack("main", 1, put_itemstack)
177 itemstack:take_item()
180 return itemstack
181 end,
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)
186 return 0
187 else
188 return count
190 end,
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)
195 return 0
196 else
197 return stack:get_count()
199 end,
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)
204 return 0
205 else
206 return stack:get_count()
208 end,
209 after_dig_node = function(pos, oldnode, oldmetadata, digger)
210 local name = digger:get_player_name()
211 local meta = minetest.get_meta(pos)
212 local meta2 = meta
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())
229 end,
230 _mcl_blast_resistance = 6,
231 _mcl_hardness = 2,
234 minetest.register_craft({
235 type = "fuel",
236 recipe = "mcl_jukebox:jukebox",
237 burntime = 15,