Telex mod and terminal integration.
[insidethebox.git] / mods / music / init.lua
blobbce948efbc856cc3389974812ee77afc0cf6d169
2 --[[
4 ITB (insidethebox) minetest game - Copyright (C) 2017-2018 sofar & nore
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public License
8 as published by the Free Software Foundation; either version 2.1
9 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 MA 02111-1307 USA
21 ]]--
23 --[[
25 Music API for itb
27 --]]
30 -- we require `localmusic` to provide event-to-track mappings
32 assert(localmusic, "localmusic mod missing, required to map events to tracks")
34 local LOOP = 7 * 60 -- seconds if looping tracks randomly
37 -- cache data
39 local streams = {}
41 local tracks = {}
45 -- API
47 music = {}
49 music.track = function(player, track)
50 minetest.log("action", "playing music track \"" .. track .. "\" to " .. player:get_player_name())
51 streams[player] = minetest.sound_play(track, {
52 to_player = player:get_player_name(),
53 loop = false,
54 gain = 0.3
56 tracks[player] = track
57 end
59 music.stop = function(player)
60 if streams[player] then
61 minetest.sound_stop(streams[player])
62 streams[player] = nil
63 end
64 tracks[player] = nil
65 end
67 music.loop = function(player, stream, add, track)
68 if streams[player] ~= stream or not streams[player] then
69 -- stream was stopped?
70 return
71 end
73 if not tracks[player] or tracks[player] ~= track then
74 -- somethign else playing?
75 return
76 end
78 music.stop(player)
80 -- pick a track from add[] and adjust streams
81 track = add[math.random(1, #add)]
82 music.track(player, track)
84 minetest.after(LOOP, music.loop, player, streams[player], add, track)
85 end
87 music.start = function(player, info, tag)
88 -- ignore if music disabled.
89 music.stop(player)
91 if player:get_attribute("music") == "0" then
92 return
93 end
95 --TODO use info.box_id to retrieve emblem scoring for a box, then pick emblem tracks.
96 if not localmusic[tag] then
97 minetest.log("error", "missing music track mapping for \"" .. tag .. "\"")
98 else
99 local track = localmusic[tag]
100 music.track(player, track)
102 local add = localmusic[tag .. "_add"]
103 if add then
104 minetest.after(LOOP, music.loop, player, streams[player], add, track)
111 -- joinplayer: main lobby?
113 minetest.register_on_joinplayer(function(player)
114 music.start(player, nil, "join")
115 end)
117 local track_by_number = {}
118 for k, _ in pairs(localmusic) do
119 if not string.find(k, "_add") then
120 table.insert(track_by_number, k)
124 minetest.register_node("music:jukebox", {
125 description = "Jukebox\nLeft/right click to select track",
126 tiles = {"jukebox_top.png", "jukebox_top.png", "jukebox_side.png"},
127 groups = {node = 1, unbreakable = 1, trigger = 1},
128 sounds = sounds.metal,
129 on_punch = function(pos, node, puncher, pointed_thing)
130 local name = puncher:get_player_name()
131 if not puncher or not boxes.players_editing_boxes[name] then
132 return
134 local meta = minetest.get_meta(pos)
135 local track = meta:get_int("track") + 1
136 if track >= #track_by_number then
137 track = 0
139 minetest.chat_send_player(name, "track = " .. track_by_number[track + 1])
140 meta:set_int("track", track)
141 end,
142 on_rightclick = function(pos, node, puncher, itemstack, pointed_thing)
143 local name = puncher:get_player_name()
144 if not puncher or not boxes.players_editing_boxes[name] then
145 return
147 local meta = minetest.get_meta(pos)
148 local track = meta:get_int("track") - 1
149 if track < 0 then
150 track = #track_by_number - 1
152 minetest.chat_send_player(name, "track = " .. track_by_number[track + 1])
153 meta:set_int("track", track)
154 end,
155 on_trigger = function(pos)
156 local box = boxes.find_box(pos)
157 if not box then
158 return
160 local p = minetest.get_player_by_name(box.name)
161 if not p then
162 return
164 local meta = minetest.get_meta(pos)
165 local track = meta:get_int("track")
166 music.start(p, nil, track_by_number[track + 1])
167 end,
168 on_untrigger = function(pos)
169 local box = boxes.find_box(pos)
170 if not box then
171 return
173 local p = minetest.get_player_by_name(box.name)
174 if not p then
175 return
177 music.stop(p)
178 end,
179 on_reveal = function(name, pos)
180 local meta = minetest.get_meta(pos)
181 local track = meta:get_int("track")
182 minetest.chat_send_player(name, minetest.colorize( "#4444ff",
183 "> track = " .. (track_by_number[track + 1] or "default")))
184 end,