Compare commits
5 Commits
68d4f7b209
...
767eb58b95
Author | SHA1 | Date |
---|---|---|
Wuzzy | 767eb58b95 | |
Wuzzy | 3bcaab4da2 | |
Wuzzy | 27edb029ca | |
Wuzzy | cb1cee225c | |
Wuzzy | 288ec1a5da |
22
README.md
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
Created by Wuzzy
|
Created by Wuzzy
|
||||||
|
|
||||||
Version: 3.2.0
|
Version: 3.3.0
|
||||||
Playable in Minetest 5.5.0 or later.
|
Playable in Minetest 5.5.0 or later.
|
||||||
|
|
||||||
Learn how to use and play Minetest in a nice and cozy castle. Here you learn most of the basics of Minetest and how to play.
|
Learn how to use and play Minetest in a nice and cozy castle. Here you learn most of the basics of Minetest and how to play.
|
||||||
|
@ -23,7 +23,7 @@ Depending on your operating system, you have to put it into the following direct
|
||||||
|
|
||||||
* GNU/Linux: $HOME/.minetest/games, where “$HOME” refers to your home directory.
|
* GNU/Linux: $HOME/.minetest/games, where “$HOME” refers to your home directory.
|
||||||
* MacOS: $HOME/.minetest/games, where “$HOME” refers to your home directory.
|
* MacOS: $HOME/.minetest/games, where “$HOME” refers to your home directory.
|
||||||
* Windows: into the "games" sub-directory of the program folder in which you have installed Minetest. It is the directory containing the directories (not necessarily exhaustive list) bin (which in turn contains minetest.exe), builtin, client, doc, fonts, games, locale, mods and textures.
|
* Windows: into the "games" sub-directory of the program folder in which you have installed Minetest. It is the directory containing the directories (not necessarily exhaustive list) bin (which in turn contains minetest.exe), builtin, client, doc, fonts, games, locale, mods and textures.
|
||||||
|
|
||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
|
@ -61,7 +61,7 @@ There's also a secret prize, can you win it?
|
||||||
## Legalities
|
## Legalities
|
||||||
This tutorial is free software. You can legally study, copy, share, transform, remix, distribute this to your liking, under certain conditions.
|
This tutorial is free software. You can legally study, copy, share, transform, remix, distribute this to your liking, under certain conditions.
|
||||||
|
|
||||||
The mods “`tutorial`” and “supplemental” as well the tutorial world are original work by Wuzzy and fall under the MIT License.
|
The mods “`tutorial`” and “`tutorial_supplemental`” as well the tutorial world are original work by Wuzzy and fall under the MIT License.
|
||||||
The mod “`tutorial_mapgen`” (Tutorial World generator) is also original work by Wuzzy, same license, but it contains contributions.
|
The mod “`tutorial_mapgen`” (Tutorial World generator) is also original work by Wuzzy, same license, but it contains contributions.
|
||||||
|
|
||||||
Contributions:
|
Contributions:
|
||||||
|
@ -71,15 +71,15 @@ Contributions:
|
||||||
|
|
||||||
Other mods are creation by other people, but heavily modified to fit the Tutorial's needs.
|
Other mods are creation by other people, but heavily modified to fit the Tutorial's needs.
|
||||||
|
|
||||||
The mods “`default`” and “`creative`” falls under the GNU LGPLv2.1 for the code and the CC BY-SA 3.0 for artwork.
|
The mods “`tutorial_default`” and “`tutorial_creative`” falls under the GNU LGPLv2.1 for the code and the CC BY-SA 3.0 for artwork.
|
||||||
The mod “`darkage`” falls under the MIT License.
|
The mod “`tutorial_darkage`” falls under the MIT License.
|
||||||
The mod “`mpd`” falls under the MIT License for the code and the CC BY 3.0 for the music.
|
The mod “`tutorial_music`” falls under the MIT License for the code and the CC BY 3.0 for the music.
|
||||||
The mod “`castle`” falls under the MIT License (the author allowed me an exception).
|
The mod “`tutorial_castle`” falls under the MIT License (the author allowed me an exception).
|
||||||
The mod “`arrow_signs`” falls under the CC BY-SA 3.0.
|
The mod “`tutorial_arrow_signs`” falls under the CC BY-SA 3.0.
|
||||||
The mod “`areas`” falls under the GNU LGPLv2.1 (or later).
|
The mod “`tutorial_areas`” falls under the GNU LGPLv2.1 (or later).
|
||||||
The mod “`cottages`” falls under the GNU GPLv2 (the author allowed me an exception).
|
The mod “`tutorial_cottages`” falls under the GNU GPLv2 (the author allowed me an exception).
|
||||||
The mod “`show_wielded_item`” is licensed under the GNU LGPLv2 or later.
|
The mod “`show_wielded_item`” is licensed under the GNU LGPLv2 or later.
|
||||||
The mod “`supplemental`” falls under the MIT License, with one exception:
|
The mod “`tutorial_supplemental`” falls under the MIT License, with one exception:
|
||||||
The texture `supplemental_loudspeaker.png` falls under the CC BY-SA 3.0 (from the developers of the Mesecons mod).
|
The texture `supplemental_loudspeaker.png` falls under the CC BY-SA 3.0 (from the developers of the Mesecons mod).
|
||||||
Everything else falls under the MIT License.
|
Everything else falls under the MIT License.
|
||||||
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
name = mpd
|
|
|
@ -1,3 +0,0 @@
|
||||||
name = supplemental
|
|
||||||
depends = tutorial_default, mpd
|
|
||||||
optional_depends = intllib
|
|
|
@ -1181,9 +1181,13 @@ minetest.register_node("tutorial:itemspawner", {
|
||||||
|
|
||||||
local offset = minetest.string_to_pos(meta:get_string("offset"))
|
local offset = minetest.string_to_pos(meta:get_string("offset"))
|
||||||
local itemstring = meta:get_string("itemstring")
|
local itemstring = meta:get_string("itemstring")
|
||||||
local alias = minetest.registered_aliases[itemstring]
|
local test_item = ItemStack(itemstring)
|
||||||
|
local test_itemname = test_item:get_name()
|
||||||
|
local alias = minetest.registered_aliases[test_itemname]
|
||||||
|
local itemname
|
||||||
if alias then
|
if alias then
|
||||||
itemstring = alias
|
test_item:set_name(alias)
|
||||||
|
itemstring = test_item:to_string()
|
||||||
end
|
end
|
||||||
local x, y, z = offset.x, offset.y, offset.z
|
local x, y, z = offset.x, offset.y, offset.z
|
||||||
local spawnpos = {x=pos.x+x, y=pos.y+y, z=pos.z+z}
|
local spawnpos = {x=pos.x+x, y=pos.y+y, z=pos.z+z}
|
||||||
|
@ -1191,7 +1195,9 @@ minetest.register_node("tutorial:itemspawner", {
|
||||||
for o=1, #objs do
|
for o=1, #objs do
|
||||||
local ent = objs[o]:get_luaentity()
|
local ent = objs[o]:get_luaentity()
|
||||||
if ent then
|
if ent then
|
||||||
if ent.name == "__builtin:item" and ent.itemstring == itemstring then
|
local ent_itemstack = ItemStack(ent.itemstring)
|
||||||
|
local itemstack = ItemStack(itemstring)
|
||||||
|
if ent.name == "__builtin:item" and ent_itemstack:get_name() == itemstack:get_name() then
|
||||||
-- Remove node when item was spawned successfully.
|
-- Remove node when item was spawned successfully.
|
||||||
-- So it doesn't get in the way.
|
-- So it doesn't get in the way.
|
||||||
minetest.remove_node(pos)
|
minetest.remove_node(pos)
|
||||||
|
|
|
@ -28,7 +28,7 @@ function default.get_hotbar_bg(x,y)
|
||||||
end
|
end
|
||||||
|
|
||||||
local music = ""
|
local music = ""
|
||||||
if minetest.get_modpath("mpd") then
|
if minetest.get_modpath("tutorial_music") then
|
||||||
music = "button[-0.1,0.7;3,1;togglemusic;"..minetest.formspec_escape(S("Toggle music")).."]"
|
music = "button[-0.1,0.7;3,1;togglemusic;"..minetest.formspec_escape(S("Toggle music")).."]"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
name = tutorial_default
|
name = tutorial_default
|
||||||
optional_depends = intllib
|
optional_depends = intllib, tutorial_music
|
||||||
|
|
|
@ -1,46 +1,46 @@
|
||||||
|
|
||||||
mpd={}
|
tutorial_music={}
|
||||||
|
|
||||||
--config
|
--config
|
||||||
mpd.pause_between_songs=7
|
tutorial_music.pause_between_songs=7
|
||||||
|
|
||||||
--end config
|
--end config
|
||||||
|
|
||||||
mpd.modpath=minetest.get_modpath("mpd")
|
tutorial_music.modpath=minetest.get_modpath("tutorial_music")
|
||||||
if not mpd.modpath then
|
if not tutorial_music.modpath then
|
||||||
error("mpd mod folder has to be named 'mpd'!")
|
error("mod folder has to be named 'tutorial_music'!")
|
||||||
end
|
end
|
||||||
--{name, length, gain~1}
|
--{name, length, gain~1}
|
||||||
mpd.songs = {}
|
tutorial_music.songs = {}
|
||||||
local sfile, sfileerr=io.open(mpd.modpath.."/songs.txt")
|
local sfile, sfileerr=io.open(tutorial_music.modpath.."/songs.txt")
|
||||||
if not sfile then error("Error opening songs.txt: "..sfileerr) end
|
if not sfile then error("Error opening songs.txt: "..sfileerr) end
|
||||||
for line in sfile:lines() do
|
for line in sfile:lines() do
|
||||||
if line~="" and line[1]~="#" then
|
if line~="" and line[1]~="#" then
|
||||||
local name, timeMinsStr, timeSecsStr, gainStr = string.match(line, "^(%S+)%s+(%d+):([%d%.]+)%s+([%d%.]+)$")
|
local name, timeMinsStr, timeSecsStr, gainStr = string.match(line, "^(%S+)%s+(%d+):([%d%.]+)%s+([%d%.]+)$")
|
||||||
local timeMins, timeSecs, gain = tonumber(timeMinsStr), tonumber(timeSecsStr), tonumber(gainStr)
|
local timeMins, timeSecs, gain = tonumber(timeMinsStr), tonumber(timeSecsStr), tonumber(gainStr)
|
||||||
if name and timeMins and timeSecs and gain then
|
if name and timeMins and timeSecs and gain then
|
||||||
mpd.songs[#mpd.songs+1]={name=name, length=timeMins*60+timeSecs, lengthhr=timeMinsStr..":"..timeSecsStr, gain=gain}
|
tutorial_music.songs[#tutorial_music.songs+1]={name=name, length=timeMins*60+timeSecs, lengthhr=timeMinsStr..":"..timeSecsStr, gain=gain}
|
||||||
else
|
else
|
||||||
minetest.log("warning", "[mpd] Misformatted song entry in songs.txt: "..line)
|
minetest.log("warning", "[tutorial_music] Misformatted song entry in songs.txt: "..line)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
sfile:close()
|
sfile:close()
|
||||||
|
|
||||||
if #mpd.songs==0 then
|
if #tutorial_music.songs==0 then
|
||||||
print("[mpd]no songs registered, not doing anything")
|
minetest.log("error", "[tutorial_music] no songs registered, not doing anything")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
mpd.storage = minetest.get_mod_storage()
|
tutorial_music.storage = minetest.get_mod_storage()
|
||||||
|
|
||||||
mpd.handles={}
|
tutorial_music.handles={}
|
||||||
|
|
||||||
mpd.playing=false
|
tutorial_music.playing=false
|
||||||
mpd.id_playing=nil
|
tutorial_music.id_playing=nil
|
||||||
mpd.song_time_left=nil
|
tutorial_music.song_time_left=nil
|
||||||
mpd.time_next=10 --sekunden
|
tutorial_music.time_next=10 --sekunden
|
||||||
mpd.id_last_played=nil
|
tutorial_music.id_last_played=nil
|
||||||
|
|
||||||
minetest.register_on_joinplayer(function(player)
|
minetest.register_on_joinplayer(function(player)
|
||||||
local meta = player:get_meta()
|
local meta = player:get_meta()
|
||||||
|
@ -52,131 +52,131 @@ minetest.register_on_joinplayer(function(player)
|
||||||
play = false
|
play = false
|
||||||
end
|
end
|
||||||
if play then
|
if play then
|
||||||
mpd.next_song()
|
tutorial_music.next_song()
|
||||||
else
|
else
|
||||||
mpd.stop_song()
|
tutorial_music.stop_song()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.register_globalstep(function(dtime)
|
minetest.register_globalstep(function(dtime)
|
||||||
if mpd.playing then
|
if tutorial_music.playing then
|
||||||
if mpd.song_time_left<=0 then
|
if tutorial_music.song_time_left<=0 then
|
||||||
mpd.stop_song()
|
tutorial_music.stop_song()
|
||||||
mpd.time_next=mpd.pause_between_songs
|
tutorial_music.time_next=tutorial_music.pause_between_songs
|
||||||
else
|
else
|
||||||
mpd.song_time_left=mpd.song_time_left-dtime
|
tutorial_music.song_time_left=tutorial_music.song_time_left-dtime
|
||||||
end
|
end
|
||||||
elseif mpd.time_next then
|
elseif tutorial_music.time_next then
|
||||||
if mpd.time_next<=0 then
|
if tutorial_music.time_next<=0 then
|
||||||
mpd.next_song()
|
tutorial_music.next_song()
|
||||||
else
|
else
|
||||||
mpd.time_next=mpd.time_next-dtime
|
tutorial_music.time_next=tutorial_music.time_next-dtime
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
mpd.play_song=function(id)
|
tutorial_music.play_song=function(id)
|
||||||
if mpd.playing then
|
if tutorial_music.playing then
|
||||||
mpd.stop_song()
|
tutorial_music.stop_song()
|
||||||
end
|
end
|
||||||
local song=mpd.songs[id]
|
local song=tutorial_music.songs[id]
|
||||||
if not song then return end
|
if not song then return end
|
||||||
for _,player in ipairs(minetest.get_connected_players()) do
|
for _,player in ipairs(minetest.get_connected_players()) do
|
||||||
local pname=player:get_player_name()
|
local pname=player:get_player_name()
|
||||||
local pvolume=tonumber(mpd.storage:get_string("vol_"..pname))
|
local pvolume=tonumber(tutorial_music.storage:get_string("vol_"..pname))
|
||||||
if not pvolume then pvolume=1 end
|
if not pvolume then pvolume=1 end
|
||||||
if pvolume>0 then
|
if pvolume>0 then
|
||||||
local handle = minetest.sound_play(song.name, {to_player=pname, gain=song.gain*pvolume})
|
local handle = minetest.sound_play(song.name, {to_player=pname, gain=song.gain*pvolume})
|
||||||
if handle then
|
if handle then
|
||||||
mpd.handles[pname]=handle
|
tutorial_music.handles[pname]=handle
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
mpd.playing=id
|
tutorial_music.playing=id
|
||||||
--adding 2 seconds as security
|
--adding 2 seconds as security
|
||||||
mpd.song_time_left = song.length + 2
|
tutorial_music.song_time_left = song.length + 2
|
||||||
end
|
end
|
||||||
mpd.stop_song=function()
|
tutorial_music.stop_song=function()
|
||||||
for pname, handle in pairs(mpd.handles) do
|
for pname, handle in pairs(tutorial_music.handles) do
|
||||||
minetest.sound_stop(handle)
|
minetest.sound_stop(handle)
|
||||||
end
|
end
|
||||||
mpd.id_last_played=mpd.playing
|
tutorial_music.id_last_played=tutorial_music.playing
|
||||||
mpd.playing=nil
|
tutorial_music.playing=nil
|
||||||
mpd.handles={}
|
tutorial_music.handles={}
|
||||||
mpd.time_next=nil
|
tutorial_music.time_next=nil
|
||||||
end
|
end
|
||||||
|
|
||||||
mpd.next_song=function()
|
tutorial_music.next_song=function()
|
||||||
local next
|
local next
|
||||||
repeat
|
repeat
|
||||||
next=math.random(1,#mpd.songs)
|
next=math.random(1,#tutorial_music.songs)
|
||||||
until #mpd.songs==1 or next~=mpd.id_last_played
|
until #tutorial_music.songs==1 or next~=tutorial_music.id_last_played
|
||||||
mpd.play_song(next)
|
tutorial_music.play_song(next)
|
||||||
end
|
end
|
||||||
|
|
||||||
mpd.song_human_readable=function(id)
|
tutorial_music.song_human_readable=function(id)
|
||||||
local song=mpd.songs[id]
|
local song=tutorial_music.songs[id]
|
||||||
return id..": "..song.name.." ["..song.lengthhr.."]"
|
return id..": "..song.name.." ["..song.lengthhr.."]"
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_privilege("mpd", "may control the music player daemon (mpd) mod")
|
minetest.register_privilege("mpd", "May control the music")
|
||||||
|
|
||||||
minetest.register_chatcommand("mpd_stop", {
|
minetest.register_chatcommand("music_stop", {
|
||||||
params = "",
|
params = "",
|
||||||
description = "Stop the song currently playing",
|
description = "Stop the song currently playing",
|
||||||
privs = {mpd=true},
|
privs = {mpd=true},
|
||||||
func = function(name, param)
|
func = function(name, param)
|
||||||
local player = minetest.get_player_by_name(name)
|
local player = minetest.get_player_by_name(name)
|
||||||
player:get_meta():set_string("play_music", "0")
|
player:get_meta():set_string("play_music", "0")
|
||||||
mpd.stop_song()
|
tutorial_music.stop_song()
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
minetest.register_chatcommand("mpd_list", {
|
minetest.register_chatcommand("music_list", {
|
||||||
params = "",
|
params = "",
|
||||||
description = "List all available songs and their IDs",
|
description = "List all available songs and their IDs",
|
||||||
privs = {mpd=true},
|
privs = {mpd=true},
|
||||||
func = function(name, param)
|
func = function(name, param)
|
||||||
for k,v in ipairs(mpd.songs) do
|
for k,v in ipairs(tutorial_music.songs) do
|
||||||
minetest.chat_send_player(name, mpd.song_human_readable(k))
|
minetest.chat_send_player(name, tutorial_music.song_human_readable(k))
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
minetest.register_chatcommand("mpd_play", {
|
minetest.register_chatcommand("music_play", {
|
||||||
params = "<id>",
|
params = "<id>",
|
||||||
description = "Play the songs with the given ID (see ids with /mpd_list)",
|
description = "Play the songs with the given ID (see IDs with /music_list)",
|
||||||
privs = {mpd=true},
|
privs = {mpd=true},
|
||||||
func = function(name, param)
|
func = function(name, param)
|
||||||
id=tonumber(param)
|
id=tonumber(param)
|
||||||
if id and id>0 and id<=#mpd.songs then
|
if id and id>0 and id<=#tutorial_music.songs then
|
||||||
local player = minetest.get_player_by_name(name)
|
local player = minetest.get_player_by_name(name)
|
||||||
player:get_meta():set_string("play_music", "1")
|
player:get_meta():set_string("play_music", "1")
|
||||||
mpd.play_song(id)
|
tutorial_music.play_song(id)
|
||||||
return true,"Playing: "..mpd.song_human_readable(id)
|
return true,"Playing: "..tutorial_music.song_human_readable(id)
|
||||||
end
|
end
|
||||||
return false, "Invalid song ID!"
|
return false, "Invalid song ID!"
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
minetest.register_chatcommand("mpd_what", {
|
minetest.register_chatcommand("music_what", {
|
||||||
params = "",
|
params = "",
|
||||||
description = "Display the currently played song.",
|
description = "Display the currently played song.",
|
||||||
privs = {mpd=true},
|
privs = {mpd=true},
|
||||||
func = function(name, param)
|
func = function(name, param)
|
||||||
if not mpd.playing then return true,"Nothing playing, "..math.floor(mpd.time_next or 0).." sec. left until next song." end
|
if not tutorial_music.playing then return true,"Nothing playing, "..math.floor(tutorial_music.time_next or 0).." sec. left until next song." end
|
||||||
return true,"Playing: "..mpd.song_human_readable(mpd.playing).."\nTime Left: "..math.floor(mpd.song_time_left or 0).." sec."
|
return true,"Playing: "..tutorial_music.song_human_readable(tutorial_music.playing).."\nTime left: "..math.floor(tutorial_music.song_time_left or 0).." sec."
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
minetest.register_chatcommand("mpd_next", {
|
minetest.register_chatcommand("music_next", {
|
||||||
params = "[seconds]",
|
params = "[seconds]",
|
||||||
description = "Start the next song, either immediately (no parameters) or after n seconds.",
|
description = "Start the next song, either immediately (no parameters) or after n seconds.",
|
||||||
privs = {mpd=true},
|
privs = {mpd=true},
|
||||||
func = function(name, param)
|
func = function(name, param)
|
||||||
local player = minetest.get_player_by_name(name)
|
local player = minetest.get_player_by_name(name)
|
||||||
player:get_meta():set_string("play_music", "1")
|
player:get_meta():set_string("play_music", "1")
|
||||||
mpd.stop_song()
|
tutorial_music.stop_song()
|
||||||
if param and tonumber(param) then
|
if param and tonumber(param) then
|
||||||
mpd.time_next=tonumber(param)
|
tutorial_music.time_next=tonumber(param)
|
||||||
return true,"Next song in "..param.." seconds!"
|
return true,"Next song in "..param.." seconds!"
|
||||||
else
|
else
|
||||||
mpd.next_song()
|
tutorial_music.next_song()
|
||||||
return true,"Next song started!"
|
return true,"Next song started!"
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
@ -187,13 +187,13 @@ minetest.register_chatcommand("mvolume", {
|
||||||
privs = {},
|
privs = {},
|
||||||
func = function(pname, param)
|
func = function(pname, param)
|
||||||
if not param or param=="" then
|
if not param or param=="" then
|
||||||
local pvolume=tonumber(mpd.storage:get_string("vol_"..pname))
|
local pvolume=tonumber(tutorial_music.storage:get_string("vol_"..pname))
|
||||||
if not pvolume then pvolume=1 end
|
if not pvolume then pvolume=1 end
|
||||||
if pvolume>0 then
|
if pvolume>0 then
|
||||||
return true, "Your music volume is set to "..pvolume.."."
|
return true, "Your music volume is set to "..pvolume.."."
|
||||||
else
|
else
|
||||||
if mpd.handles[pname] then
|
if tutorial_music.handles[pname] then
|
||||||
minetest.sound_stop(mpd.handles[pname])
|
minetest.sound_stop(tutorial_music.handles[pname])
|
||||||
end
|
end
|
||||||
return true, "Background music is disabled for you. Use '/mvolume 1' to enable it again."
|
return true, "Background music is disabled for you. Use '/mvolume 1' to enable it again."
|
||||||
end
|
end
|
||||||
|
@ -204,12 +204,12 @@ minetest.register_chatcommand("mvolume", {
|
||||||
end
|
end
|
||||||
pvolume = math.min(pvolume, 1)
|
pvolume = math.min(pvolume, 1)
|
||||||
pvolume = math.max(pvolume, 0)
|
pvolume = math.max(pvolume, 0)
|
||||||
mpd.storage:set_string("vol_"..pname, pvolume)
|
tutorial_music.storage:set_string("vol_"..pname, pvolume)
|
||||||
if pvolume>0 then
|
if pvolume>0 then
|
||||||
return true, "Music volume set to "..pvolume..". Change will take effect when the next song starts."
|
return true, "Music volume set to "..pvolume..". Change will take effect when the next song starts."
|
||||||
else
|
else
|
||||||
if mpd.handles[pname] then
|
if tutorial_music.handles[pname] then
|
||||||
minetest.sound_stop(mpd.handles[pname])
|
minetest.sound_stop(tutorial_music.handles[pname])
|
||||||
end
|
end
|
||||||
return true, "Disabled background music for you. Use /mvol to enable it again."
|
return true, "Disabled background music for you. Use /mvol to enable it again."
|
||||||
end
|
end
|
||||||
|
@ -218,11 +218,11 @@ minetest.register_chatcommand("mvolume", {
|
||||||
|
|
||||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
if(fields.togglemusic) then
|
if(fields.togglemusic) then
|
||||||
if mpd.playing then
|
if tutorial_music.playing then
|
||||||
mpd.stop_song()
|
tutorial_music.stop_song()
|
||||||
player:get_meta():set_string("play_music", "0")
|
player:get_meta():set_string("play_music", "0")
|
||||||
else
|
else
|
||||||
mpd.next_song()
|
tutorial_music.next_song()
|
||||||
player:get_meta():set_string("play_music", "1")
|
player:get_meta():set_string("play_music", "1")
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -0,0 +1 @@
|
||||||
|
name = tutorial_music
|
|
@ -1,7 +1,9 @@
|
||||||
|
|
||||||
### mpd Mod for Minetest
|
### Tutorial music mod
|
||||||
(c) 2017 orwell96
|
|
||||||
Slightly modified for the Tutorial.
|
Based on the MPD mod ((c) 2017 orwell96)
|
||||||
|
|
||||||
|
Modified for the Tutorial.
|
||||||
|
|
||||||
This mod is licensed under the MIT License.
|
This mod is licensed under the MIT License.
|
||||||
|
|
|
@ -6,7 +6,7 @@ else
|
||||||
S = function ( s ) return s end
|
S = function ( s ) return s end
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_node("supplemental:sticky", {
|
minetest.register_node("tutorial_supplemental:sticky", {
|
||||||
description = S("sticky stone brick"),
|
description = S("sticky stone brick"),
|
||||||
tiles = {"default_stone_brick.png^supplemental_splat.png",
|
tiles = {"default_stone_brick.png^supplemental_splat.png",
|
||||||
"default_stone_brick.png", "default_stone_brick.png", "default_stone_brick.png",
|
"default_stone_brick.png", "default_stone_brick.png", "default_stone_brick.png",
|
||||||
|
@ -15,7 +15,7 @@ minetest.register_node("supplemental:sticky", {
|
||||||
sounds = default.node_sound_stone_defaults()
|
sounds = default.node_sound_stone_defaults()
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("supplemental:bouncy", {
|
minetest.register_node("tutorial_supplemental:bouncy", {
|
||||||
description = S("bouncy block"),
|
description = S("bouncy block"),
|
||||||
tiles = {"supplemental_bouncy.png"},
|
tiles = {"supplemental_bouncy.png"},
|
||||||
groups = {creative_breakable=1, bouncy=70, fall_damage_add_percent=-100},
|
groups = {creative_breakable=1, bouncy=70, fall_damage_add_percent=-100},
|
||||||
|
@ -24,22 +24,22 @@ minetest.register_node("supplemental:bouncy", {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
minetest.register_node("supplemental:conglomerate", {
|
minetest.register_node("tutorial_supplemental:conglomerate", {
|
||||||
description = S("conglomerate"),
|
description = S("conglomerate"),
|
||||||
tiles = {"supplemental_conglomerate.png" },
|
tiles = {"supplemental_conglomerate.png" },
|
||||||
groups = {cracky=3},
|
groups = {cracky=3},
|
||||||
drop = { items = {
|
drop = { items = {
|
||||||
{ items={"supplemental:rock"} },
|
{ items={"tutorial_supplemental:rock"} },
|
||||||
{ items={"supplemental:rock"}, rarity = 5 },
|
{ items={"tutorial_supplemental:rock"}, rarity = 5 },
|
||||||
{ items={"supplemental:rock"}, rarity = 5 },
|
{ items={"tutorial_supplemental:rock"}, rarity = 5 },
|
||||||
{ items={"supplemental:rock"}, rarity = 5 },
|
{ items={"tutorial_supplemental:rock"}, rarity = 5 },
|
||||||
{ items={"supplemental:rock"}, rarity = 5 },
|
{ items={"tutorial_supplemental:rock"}, rarity = 5 },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sounds = default.node_sound_stone_defaults()
|
sounds = default.node_sound_stone_defaults()
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("supplemental:frame",{
|
minetest.register_node("tutorial_supplemental:frame",{
|
||||||
description = S("picture frame"),
|
description = S("picture frame"),
|
||||||
drawtype = "signlike",
|
drawtype = "signlike",
|
||||||
selection_box = { type = "wallmounted" },
|
selection_box = { type = "wallmounted" },
|
||||||
|
@ -55,7 +55,7 @@ minetest.register_node("supplemental:frame",{
|
||||||
sounds = default.node_sound_defaults(),
|
sounds = default.node_sound_defaults(),
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("supplemental:spikes", {
|
minetest.register_node("tutorial_supplemental:spikes", {
|
||||||
description = S("short spikes"),
|
description = S("short spikes"),
|
||||||
tiles = {"supplemental_spikes_small.png"},
|
tiles = {"supplemental_spikes_small.png"},
|
||||||
inventory_image = "supplemental_spikes_small.png",
|
inventory_image = "supplemental_spikes_small.png",
|
||||||
|
@ -76,7 +76,7 @@ minetest.register_node("supplemental:spikes", {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("supplemental:spikes_large", {
|
minetest.register_node("tutorial_supplemental:spikes_large", {
|
||||||
description = S("long spikes"),
|
description = S("long spikes"),
|
||||||
tiles = {"supplemental_spikes_large.png"},
|
tiles = {"supplemental_spikes_large.png"},
|
||||||
inventory_image = "supplemental_spikes_large.png",
|
inventory_image = "supplemental_spikes_large.png",
|
||||||
|
@ -96,18 +96,18 @@ local set_loudspeaker_infotext = function(pos)
|
||||||
meta:set_string("infotext", S("loudspeaker (rightclick to toggle music)"))
|
meta:set_string("infotext", S("loudspeaker (rightclick to toggle music)"))
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_node("supplemental:loudspeaker", {
|
minetest.register_node("tutorial_supplemental:loudspeaker", {
|
||||||
description = S("loudspeaker"),
|
description = S("loudspeaker"),
|
||||||
tiles = {"supplemental_loudspeaker.png"},
|
tiles = {"supplemental_loudspeaker.png"},
|
||||||
groups = { creative_breakable = 1 },
|
groups = { creative_breakable = 1 },
|
||||||
sounds = default.node_sound_wood_defaults(),
|
sounds = default.node_sound_wood_defaults(),
|
||||||
on_construct = set_loudspeaker_infotext,
|
on_construct = set_loudspeaker_infotext,
|
||||||
on_rightclick = function(pos, node, clicker)
|
on_rightclick = function(pos, node, clicker)
|
||||||
if mpd.playing then
|
if tutorial_music.playing then
|
||||||
mpd.stop_song()
|
tutorial_music.stop_song()
|
||||||
clicker:get_meta():set_string("play_music", "0")
|
clicker:get_meta():set_string("play_music", "0")
|
||||||
else
|
else
|
||||||
mpd.next_song()
|
tutorial_music.next_song()
|
||||||
clicker:get_meta():set_string("play_music", "1")
|
clicker:get_meta():set_string("play_music", "1")
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
@ -115,50 +115,50 @@ minetest.register_node("supplemental:loudspeaker", {
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
nodenames = { "supplemental:loudspeaker" },
|
nodenames = { "tutorial_supplemental:loudspeaker" },
|
||||||
interval = 5,
|
interval = 5,
|
||||||
chance = 1,
|
chance = 1,
|
||||||
action = set_loudspeaker_infotext,
|
action = set_loudspeaker_infotext,
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_craftitem("supplemental:rock", {
|
minetest.register_craftitem("tutorial_supplemental:rock", {
|
||||||
description = S("piece of rock"),
|
description = S("piece of rock"),
|
||||||
inventory_image = "supplemental_rock.png",
|
inventory_image = "supplemental_rock.png",
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_craftitem("supplemental:wheat", {
|
minetest.register_craftitem("tutorial_supplemental:wheat", {
|
||||||
description = S("wheat"),
|
description = S("wheat"),
|
||||||
inventory_image = "supplemental_wheat.png",
|
inventory_image = "supplemental_wheat.png",
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_craftitem("supplemental:flour", {
|
minetest.register_craftitem("tutorial_supplemental:flour", {
|
||||||
description = S("flour"),
|
description = S("flour"),
|
||||||
inventory_image = "supplemental_flour.png",
|
inventory_image = "supplemental_flour.png",
|
||||||
})
|
})
|
||||||
-- Crafting example #2
|
-- Crafting example #2
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
type = "shapeless",
|
type = "shapeless",
|
||||||
output = "supplemental:flour",
|
output = "tutorial_supplemental:flour",
|
||||||
recipe = {"supplemental:wheat", "supplemental:wheat", "supplemental:wheat", "supplemental:wheat"}
|
recipe = {"tutorial_supplemental:wheat", "tutorial_supplemental:wheat", "tutorial_supplemental:wheat", "tutorial_supplemental:wheat"}
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Items for crafting examples #1, #4 and #5
|
-- Items for crafting examples #1, #4 and #5
|
||||||
minetest.register_craftitem("supplemental:paper_white", {
|
minetest.register_craftitem("tutorial_supplemental:paper_white", {
|
||||||
description = S("white sheet of paper"),
|
description = S("white sheet of paper"),
|
||||||
inventory_image = "default_paper.png",
|
inventory_image = "default_paper.png",
|
||||||
groups = { paper = 1 },
|
groups = { paper = 1 },
|
||||||
})
|
})
|
||||||
minetest.register_craftitem("supplemental:paper_orange", {
|
minetest.register_craftitem("tutorial_supplemental:paper_orange", {
|
||||||
description = S("orange sheet of paper"),
|
description = S("orange sheet of paper"),
|
||||||
inventory_image = "supplemental_paper_orange.png",
|
inventory_image = "supplemental_paper_orange.png",
|
||||||
groups = { paper = 1 },
|
groups = { paper = 1 },
|
||||||
})
|
})
|
||||||
minetest.register_craftitem("supplemental:paper_purple", {
|
minetest.register_craftitem("tutorial_supplemental:paper_purple", {
|
||||||
description = S("purple sheet of paper"),
|
description = S("purple sheet of paper"),
|
||||||
inventory_image = "supplemental_paper_purple.png",
|
inventory_image = "supplemental_paper_purple.png",
|
||||||
groups = { paper = 1 },
|
groups = { paper = 1 },
|
||||||
})
|
})
|
||||||
minetest.register_craftitem("supplemental:paper_green", {
|
minetest.register_craftitem("tutorial_supplemental:paper_green", {
|
||||||
description = S("green sheet of paper"),
|
description = S("green sheet of paper"),
|
||||||
inventory_image = "supplemental_paper_green.png",
|
inventory_image = "supplemental_paper_green.png",
|
||||||
groups = { paper = 1 },
|
groups = { paper = 1 },
|
||||||
|
@ -176,7 +176,7 @@ minetest.register_craft({
|
||||||
|
|
||||||
-- 8 viscosity example liquids
|
-- 8 viscosity example liquids
|
||||||
for v=0,7 do
|
for v=0,7 do
|
||||||
minetest.register_node("supplemental:liquid"..v, {
|
minetest.register_node("tutorial_supplemental:liquid"..v, {
|
||||||
description = string.format(S("flowing test liquid %i"), v),
|
description = string.format(S("flowing test liquid %i"), v),
|
||||||
inventory_image = minetest.inventorycube("supplemental_testliquid"..v..".png"),
|
inventory_image = minetest.inventorycube("supplemental_testliquid"..v..".png"),
|
||||||
drawtype = "flowingliquid",
|
drawtype = "flowingliquid",
|
||||||
|
@ -202,14 +202,14 @@ for v=0,7 do
|
||||||
drop = "",
|
drop = "",
|
||||||
drowning = 1,
|
drowning = 1,
|
||||||
liquidtype = "flowing",
|
liquidtype = "flowing",
|
||||||
liquid_alternative_flowing = "supplemental:liquid"..v,
|
liquid_alternative_flowing = "tutorial_supplemental:liquid"..v,
|
||||||
liquid_alternative_source = "supplemental:liquidsource"..v,
|
liquid_alternative_source = "tutorial_supplemental:liquidsource"..v,
|
||||||
liquid_viscosity = v,
|
liquid_viscosity = v,
|
||||||
groups = {not_in_creative_inventory = 1},
|
groups = {not_in_creative_inventory = 1},
|
||||||
sounds = default.node_sound_water_defaults(),
|
sounds = default.node_sound_water_defaults(),
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("supplemental:liquidsource"..v, {
|
minetest.register_node("tutorial_supplemental:liquidsource"..v, {
|
||||||
description = string.format(S("test liquid source %i"), v),
|
description = string.format(S("test liquid source %i"), v),
|
||||||
inventory_image = minetest.inventorycube("supplemental_testliquid"..v..".png"),
|
inventory_image = minetest.inventorycube("supplemental_testliquid"..v..".png"),
|
||||||
drawtype = "liquid",
|
drawtype = "liquid",
|
||||||
|
@ -229,10 +229,30 @@ for v=0,7 do
|
||||||
drop = "",
|
drop = "",
|
||||||
drowning = 1,
|
drowning = 1,
|
||||||
liquidtype = "source",
|
liquidtype = "source",
|
||||||
liquid_alternative_flowing = "supplemental:liquid"..v,
|
liquid_alternative_flowing = "tutorial_supplemental:liquid"..v,
|
||||||
liquid_alternative_source = "supplemental:liquidsource"..v,
|
liquid_alternative_source = "tutorial_supplemental:liquidsource"..v,
|
||||||
liquid_viscosity = v,
|
liquid_viscosity = v,
|
||||||
groups = {},
|
groups = {},
|
||||||
sounds = default.node_sound_water_defaults(),
|
sounds = default.node_sound_water_defaults(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_alias("supplemental:liquid"..v, "tutorial_supplemental:liquid"..v)
|
||||||
|
minetest.register_alias("supplemental:liquidsource"..v, "tutorial_supplemental:liquidsource"..v)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_alias("supplemental:sticky", "tutorial_supplemental:sticky")
|
||||||
|
minetest.register_alias("supplemental:bouncy", "tutorial_supplemental:bouncy")
|
||||||
|
minetest.register_alias("supplemental:conglomerate", "tutorial_supplemental:conglomerate")
|
||||||
|
minetest.register_alias("supplemental:frame", "tutorial_supplemental:frame")
|
||||||
|
minetest.register_alias("supplemental:spikes", "tutorial_supplemental:spikes")
|
||||||
|
minetest.register_alias("supplemental:spikes_large", "tutorial_supplemental:spikes_large")
|
||||||
|
minetest.register_alias("supplemental:loudspeaker", "tutorial_supplemental:loudspeaker")
|
||||||
|
minetest.register_alias("supplemental:rock", "tutorial_supplemental:rock")
|
||||||
|
minetest.register_alias("supplemental:wheat", "tutorial_supplemental:wheat")
|
||||||
|
minetest.register_alias("supplemental:flour", "tutorial_supplemental:flour")
|
||||||
|
minetest.register_alias("supplemental:paper_white", "tutorial_supplemental:paper_white")
|
||||||
|
minetest.register_alias("supplemental:paper_orange", "tutorial_supplemental:paper_orange")
|
||||||
|
minetest.register_alias("supplemental:paper_purple", "tutorial_supplemental:paper_purple")
|
||||||
|
minetest.register_alias("supplemental:paper_green", "tutorial_supplemental:paper_green")
|
||||||
|
minetest.register_alias("supplemental:book", "tutorial_supplemental:book")
|
|
@ -0,0 +1,3 @@
|
||||||
|
name = tutorial_supplemental
|
||||||
|
depends = tutorial_default, tutorial_music
|
||||||
|
optional_depends = intllib
|
Before Width: | Height: | Size: 341 B After Width: | Height: | Size: 341 B |
Before Width: | Height: | Size: 621 B After Width: | Height: | Size: 621 B |
Before Width: | Height: | Size: 335 B After Width: | Height: | Size: 335 B |
Before Width: | Height: | Size: 227 B After Width: | Height: | Size: 227 B |
Before Width: | Height: | Size: 814 B After Width: | Height: | Size: 814 B |
Before Width: | Height: | Size: 391 B After Width: | Height: | Size: 391 B |
Before Width: | Height: | Size: 340 B After Width: | Height: | Size: 340 B |
Before Width: | Height: | Size: 375 B After Width: | Height: | Size: 375 B |
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 387 B |
Before Width: | Height: | Size: 376 B After Width: | Height: | Size: 376 B |
Before Width: | Height: | Size: 220 B After Width: | Height: | Size: 220 B |
Before Width: | Height: | Size: 842 B After Width: | Height: | Size: 842 B |
Before Width: | Height: | Size: 690 B After Width: | Height: | Size: 690 B |
Before Width: | Height: | Size: 706 B After Width: | Height: | Size: 706 B |
Before Width: | Height: | Size: 710 B After Width: | Height: | Size: 710 B |
Before Width: | Height: | Size: 484 B After Width: | Height: | Size: 484 B |
Before Width: | Height: | Size: 552 B After Width: | Height: | Size: 552 B |
Before Width: | Height: | Size: 511 B After Width: | Height: | Size: 511 B |
Before Width: | Height: | Size: 448 B After Width: | Height: | Size: 448 B |
Before Width: | Height: | Size: 492 B After Width: | Height: | Size: 492 B |
Before Width: | Height: | Size: 547 B After Width: | Height: | Size: 547 B |