189 lines
4.7 KiB
Lua
189 lines
4.7 KiB
Lua
|
|
--[[
|
|
|
|
ITB (insidethebox) minetest game - Copyright (C) 2017-2018 sofar & nore
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public License
|
|
as published by the Free Software Foundation; either version 2.1
|
|
of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free
|
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
MA 02111-1307 USA
|
|
|
|
]]--
|
|
|
|
local S = minetest.get_translator("music")
|
|
|
|
--[[
|
|
|
|
Music API for itb
|
|
|
|
--]]
|
|
|
|
--
|
|
-- we require `localmusic` to provide event-to-track mappings
|
|
--
|
|
assert(localmusic, "localmusic mod missing, required to map events to tracks")
|
|
|
|
local LOOP = 7 * 60 -- seconds if looping tracks randomly
|
|
|
|
--
|
|
-- cache data
|
|
--
|
|
local streams = {}
|
|
|
|
local tracks = {}
|
|
|
|
|
|
--
|
|
-- API
|
|
--
|
|
music = {}
|
|
|
|
music.track = function(player, track)
|
|
minetest.log("action", "playing music track \"" .. track .. "\" to " .. player:get_player_name())
|
|
streams[player] = minetest.sound_play(track, {
|
|
to_player = player:get_player_name(),
|
|
loop = false,
|
|
gain = 0.3
|
|
})
|
|
tracks[player] = track
|
|
end
|
|
|
|
music.stop = function(player)
|
|
if streams[player] then
|
|
minetest.sound_stop(streams[player])
|
|
streams[player] = nil
|
|
end
|
|
tracks[player] = nil
|
|
end
|
|
|
|
music.loop = function(player, stream, add, track)
|
|
if streams[player] ~= stream or not streams[player] then
|
|
-- stream was stopped?
|
|
return
|
|
end
|
|
|
|
if not tracks[player] or tracks[player] ~= track then
|
|
-- somethign else playing?
|
|
return
|
|
end
|
|
|
|
music.stop(player)
|
|
|
|
-- pick a track from add[] and adjust streams
|
|
track = add[math.random(1, #add)]
|
|
music.track(player, track)
|
|
|
|
minetest.after(LOOP, music.loop, player, streams[player], add, track)
|
|
end
|
|
|
|
music.start = function(player, info, tag)
|
|
-- ignore if music disabled.
|
|
music.stop(player)
|
|
|
|
local pmeta = player:get_meta()
|
|
if pmeta:get_string("music") == "0" then
|
|
return
|
|
end
|
|
|
|
--TODO use info.box_id to retrieve emblem scoring for a box, then pick emblem tracks.
|
|
if not localmusic[tag] then
|
|
minetest.log("error", "missing music track mapping for \"" .. tag .. "\"")
|
|
else
|
|
local track = localmusic[tag]
|
|
music.track(player, track)
|
|
|
|
local add = localmusic[tag .. "_add"]
|
|
if add then
|
|
minetest.after(LOOP, music.loop, player, streams[player], add, track)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
--
|
|
-- joinplayer: main lobby?
|
|
--
|
|
minetest.register_on_joinplayer(function(player)
|
|
music.start(player, nil, "join")
|
|
end)
|
|
|
|
local track_by_number = {}
|
|
for k, _ in pairs(localmusic) do
|
|
if not string.find(k, "_add") then
|
|
table.insert(track_by_number, k)
|
|
end
|
|
end
|
|
|
|
minetest.register_node("music:jukebox", {
|
|
description = S("Jukebox").."\n"..S("Left/right-click to select track"),
|
|
tiles = {"jukebox_top.png", "jukebox_top.png", "jukebox_side.png"},
|
|
groups = {node = 1, unbreakable = 1, trigger = 1},
|
|
sounds = sounds.metal,
|
|
on_punch = function(pos, node, puncher, pointed_thing)
|
|
local name = puncher:get_player_name()
|
|
if not puncher or not boxes.players_editing_boxes[name] then
|
|
return
|
|
end
|
|
local meta = minetest.get_meta(pos)
|
|
local track = meta:get_int("track") + 1
|
|
if track >= #track_by_number then
|
|
track = 0
|
|
end
|
|
minetest.chat_send_player(name, "track = " .. track_by_number[track + 1])
|
|
meta:set_int("track", track)
|
|
end,
|
|
on_rightclick = function(pos, node, puncher, itemstack, pointed_thing)
|
|
local name = puncher:get_player_name()
|
|
if not puncher or not boxes.players_editing_boxes[name] then
|
|
return
|
|
end
|
|
local meta = minetest.get_meta(pos)
|
|
local track = meta:get_int("track") - 1
|
|
if track < 0 then
|
|
track = #track_by_number - 1
|
|
end
|
|
minetest.chat_send_player(name, "track = " .. track_by_number[track + 1])
|
|
meta:set_int("track", track)
|
|
end,
|
|
on_trigger = function(pos)
|
|
local box = boxes.find_box(pos)
|
|
if not box then
|
|
return
|
|
end
|
|
local p = minetest.get_player_by_name(box.name)
|
|
if not p then
|
|
return
|
|
end
|
|
local meta = minetest.get_meta(pos)
|
|
local track = meta:get_int("track")
|
|
music.start(p, nil, track_by_number[track + 1])
|
|
end,
|
|
on_untrigger = function(pos)
|
|
local box = boxes.find_box(pos)
|
|
if not box then
|
|
return
|
|
end
|
|
local p = minetest.get_player_by_name(box.name)
|
|
if not p then
|
|
return
|
|
end
|
|
music.stop(p)
|
|
end,
|
|
on_reveal = function(name, pos)
|
|
local meta = minetest.get_meta(pos)
|
|
local track = meta:get_int("track")
|
|
minetest.chat_send_player(name, minetest.colorize( "#4444ff",
|
|
"> track = " .. (track_by_number[track + 1] or "default")))
|
|
end,
|
|
})
|