From 1ce9ab22bff29f44528431eab4f0f4e9a611102c Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Sat, 12 May 2018 21:50:56 +0200 Subject: [PATCH] Turn jukebox into a container (part 1) --- GROUPS.md | 1 + mods/CORE/mcl_util/init.lua | 27 +++++++++++++++++--- mods/ITEMS/mcl_jukebox/init.lua | 44 ++++++++++++++++++++++----------- 3 files changed, 55 insertions(+), 17 deletions(-) diff --git a/GROUPS.md b/GROUPS.md index 9000ee3fc..217d18c19 100644 --- a/GROUPS.md +++ b/GROUPS.md @@ -151,6 +151,7 @@ These groups are used mostly for informational purposes * `container=5`: Left part of a 2-part horizontal connected container. Both parts have a `"main"` inventory list. Both inventories are considered to belong together. This is used for large chests. * `container=6`: Same as above, but for the right part. + * `container=7`: Same as `container=2`, but only music discs can be inserted * `container=1`: Other/unspecified container type * `spawn_egg=1`: Spawn egg diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index ae238ab6c..cb70fe758 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -149,12 +149,18 @@ function mcl_util.get_eligible_transfer_item_slot(src_inventory, src_list, dst_i return nil end --- Returns true if given itemstack is a shulker box +-- Returns true if itemstack is a shulker box local is_not_shulker_box = function(itemstack) local g = minetest.get_item_group(itemstack:get_name(), "shulker_box") return g == 0 or g == nil end +-- Returns true itemstack is music disc +local is_music_disc = function(itemstack) + local g = minetest.get_item_group(itemstack:get_name(), "music_record") + return g ~= 0 and g ~= nil +end + -- Moves a single item from one inventory to another. --- source_inventory: Inventory to take the item from --- source_list: List name of the source inventory from which to take the item @@ -235,7 +241,7 @@ function mcl_util.move_item_container(source_pos, destination_pos, source_list, -- Default source lists if not source_list then -- Main inventory for most container types - if sctype == 2 or sctype == 3 or sctype == 5 or sctype == 6 then + if sctype == 2 or sctype == 3 or sctype == 5 or sctype == 6 or sctype == 7 then source_list = "main" -- Furnace: output elseif sctype == 4 then @@ -256,6 +262,10 @@ function mcl_util.move_item_container(source_pos, destination_pos, source_list, if dctype == 3 then cond = is_not_shulker_box end + -- Music disc only + if dctype == 7 then + cond = is_music_disc + end source_stack_id = mcl_util.get_eligible_transfer_item_slot(sinv, source_list, dinv, dpos, cond) if not source_stack_id then -- Try again if source is a double container @@ -281,13 +291,20 @@ function mcl_util.move_item_container(source_pos, destination_pos, source_list, return false end end + -- Container type 7 conly allows music discs + if dctype == 7 then + local stack = sinv:get_stack(source_list, source_stack_id) + if stack and minetest.get_item_group(stack:get_name(), "music_record") == 0 then + return false + end + end -- If it's a container, put it into the container if dctype ~= 0 then -- Automatically select a destination list if omitted if not destination_list then -- Main inventory for most container types - if dctype == 2 or dctype == 3 or dctype == 5 or dctype == 6 then + if dctype == 2 or dctype == 3 or dctype == 5 or dctype == 6 or dctype == 7 then destination_list = "main" -- Furnace source slot elseif dctype == 4 then @@ -312,6 +329,10 @@ function mcl_util.move_item_container(source_pos, destination_pos, source_list, -- Start furnace's timer function, it will sort out whether furnace can burn or not. minetest.get_node_timer(dpos):start(1.0) end + -- Update jukebox + if ok and dctype == 7 then + minetest.get_node_timer(dpos):start(0.0) + end return ok end diff --git a/mods/ITEMS/mcl_jukebox/init.lua b/mods/ITEMS/mcl_jukebox/init.lua index 7b0f2397d..d54a235cf 100644 --- a/mods/ITEMS/mcl_jukebox/init.lua +++ b/mods/ITEMS/mcl_jukebox/init.lua @@ -103,6 +103,24 @@ minetest.register_craft({ } }) +local play_record = function(pos, itemstack, player) + local record_id = minetest.get_item_group(itemstack:get_name(), "music_record") + if record_id ~= 0 then + local cname = "singleplayer" -- player:get_player_name() + if active_tracks[cname] ~= nil then + minetest.sound_stop(active_tracks[cname]) + active_tracks[cname] = nil + end + active_tracks[cname] = minetest.sound_play("mcl_jukebox_track_"..record_id, { + --to_player = cname, + max_hear_distance = 16, + gain = 1, + }) + --now_playing(player, record_id) + return true + end + return false +end -- Jukebox minetest.register_node("mcl_jukebox:jukebox", { @@ -111,7 +129,7 @@ minetest.register_node("mcl_jukebox:jukebox", { _doc_items_usagehelp = "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.", tiles = {"mcl_jukebox_top.png", "mcl_jukebox_side.png", "mcl_jukebox_side.png"}, sounds = mcl_sounds.node_sound_wood_defaults(), - groups = {handy=1,axey=1, deco_block=1, material_wood=1}, + groups = {handy=1,axey=1, container=7, deco_block=1, material_wood=1}, is_ground_content = false, on_construct = function(pos) local meta = minetest.get_meta(pos) @@ -145,23 +163,13 @@ minetest.register_node("mcl_jukebox:jukebox", { end else -- Jukebox is empty: Play track if player holds music record - local record_id = minetest.get_item_group(itemstack:get_name(), "music_record") - if record_id ~= 0 then - if active_tracks[cname] ~= nil then - minetest.sound_stop(active_tracks[cname]) - active_tracks[cname] = nil - end - active_tracks[cname] = minetest.sound_play("mcl_jukebox_track_"..record_id, { - to_player = cname, - --max_hear_distance = 16, - gain = 1, - }) - now_playing(clicker, record_id) + local playing = play_record(pos, itemstack, clicker) + if playing then inv:set_stack("main", 1, itemstack:get_name()) itemstack:take_item() - return itemstack end end + return itemstack end, after_dig_node = function(pos, oldnode, oldmetadata, digger) local name = digger:get_player_name() @@ -184,6 +192,14 @@ minetest.register_node("mcl_jukebox:jukebox", { end meta:from_table(meta2:to_table()) end, + on_timer = function(pos, elapsed) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack("main", 1) + if not stack:is_empty() then + play_record(pos, stack) + end + end, _mcl_blast_resistance = 30, _mcl_hardness = 2, })