347 lines
11 KiB
Lua
347 lines
11 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
|
|
|
|
]]--
|
|
|
|
--[[
|
|
|
|
game menu options for use with sfinv
|
|
|
|
--]]
|
|
|
|
local S = minetest.get_translator("menu")
|
|
local FE = minetest.formspec_escape
|
|
|
|
local function toggle_music(player)
|
|
local pmeta = player:get_meta()
|
|
local m = pmeta:get_string("music")
|
|
if not m or m == "1" then
|
|
music.stop(player)
|
|
m = "0"
|
|
minetest.chat_send_player(player:get_player_name(), S("Music is now disabled."))
|
|
else
|
|
m = "1"
|
|
minetest.chat_send_player(player:get_player_name(), S("Music is now enabled. Music playback will start later."))
|
|
end
|
|
pmeta:set_string("music", m)
|
|
end
|
|
|
|
sfinv.register_page("menu:lobby", {
|
|
title = S("Game"),
|
|
is_in_nav = function(self, player, context)
|
|
local name = player:get_player_name()
|
|
return not boxes.players_editing_boxes[name] and not boxes.players_in_boxes[name]
|
|
end,
|
|
get = function(self, player, context)
|
|
return sfinv.make_formspec(player, context,
|
|
"button[0.5,0.5;4,0.6;music;"..FE(S("Toggle music")).."]" ..
|
|
sfinv.get_hotbar_bg(0,4.7) ..
|
|
sfinv.style.gui_bg .. sfinv.style.gui_bg_img .. sfinv.style.gui_slots
|
|
.. creative.formspec_add, true)
|
|
end,
|
|
on_player_receive_fields = function(self, player, context, fields)
|
|
if fields.music then
|
|
toggle_music(player)
|
|
end
|
|
return
|
|
end,
|
|
})
|
|
|
|
local function callback_erase(player, fields, context)
|
|
local name = player:get_player_name()
|
|
if fields.btn_cancel or fields.quit then
|
|
return true
|
|
end
|
|
if not fields.btn_erase or
|
|
context ~= tonumber(fields.confirm) or
|
|
not boxes.players_editing_boxes[name] then
|
|
return true
|
|
end
|
|
|
|
-- wipe the box
|
|
local box = boxes.players_editing_boxes[name]
|
|
minetest.log("action", name .. " erases all content of box " .. box.box_id)
|
|
|
|
local minp = vector.add(box.minp, 1)
|
|
local maxp = vector.add(box.maxp, -1)
|
|
|
|
-- wipe nodes with meta separately
|
|
for _, p in ipairs(minetest.find_nodes_with_meta(minp, maxp)) do
|
|
minetest.remove_node(p)
|
|
end
|
|
|
|
local cid_air = minetest.get_content_id("air")
|
|
|
|
local vm = minetest.get_voxel_manip(minp, maxp)
|
|
local emin, emax = vm:get_emerged_area()
|
|
local va = VoxelArea:new{MinEdge=emin,MaxEdge=emax}
|
|
local vmdata = vm:get_data()
|
|
local param2 = vm:get_param2_data()
|
|
|
|
for z = minp.z, maxp.z do
|
|
for y = minp.y, maxp.y do
|
|
local index = va:index(minp.x, y, z)
|
|
for x = minp.x, maxp.x do
|
|
vmdata[index] = cid_air
|
|
param2[index] = 0
|
|
index = index + 1
|
|
end
|
|
end
|
|
end
|
|
vm:set_data(vmdata)
|
|
vm:set_param2_data(param2)
|
|
vm:update_liquids()
|
|
vm:write_to_map()
|
|
vm:update_map()
|
|
minetest.after(0.1, minetest.fix_light, minp, maxp)
|
|
|
|
-- reset pedestal number, build time
|
|
box.start_edit_time = minetest.get_gametime()
|
|
box.num_items = 0
|
|
local bmeta = db.box_get_meta(box.box_id)
|
|
bmeta.meta.num_items = 0
|
|
bmeta.meta.build_time = 0
|
|
db.box_set_meta(box.box_id, bmeta)
|
|
|
|
return true
|
|
end
|
|
|
|
local function callback_landscape(player, fields, context)
|
|
local name = player:get_player_name()
|
|
if fields.btn_cancel or fields.quit then
|
|
return true
|
|
end
|
|
if not fields.btn_landscape or
|
|
context ~= tonumber(fields.confirm) or
|
|
not boxes.players_editing_boxes[name] then
|
|
return true
|
|
end
|
|
|
|
-- landscape the box
|
|
local box = boxes.players_editing_boxes[name]
|
|
minetest.log("action", name .. " landscapes box " .. box.box_id)
|
|
|
|
local minp = vector.add(box.minp, 1)
|
|
local maxp = vector.add(box.maxp, -1)
|
|
|
|
local vm = minetest.get_voxel_manip(minp, maxp)
|
|
local emin, emax = vm:get_emerged_area()
|
|
local va = VoxelArea:new{MinEdge=emin,MaxEdge=emax}
|
|
local vmdata = vm:get_data()
|
|
local param2 = vm:get_param2_data()
|
|
|
|
local cursor = 8
|
|
local stack
|
|
|
|
for y = minp.y, maxp.y do
|
|
local inv = player:get_inventory()
|
|
while not stack or stack:is_empty() and cursor > 1 do
|
|
stack = inv:get_stack("landscape", cursor)
|
|
cursor = cursor - 1
|
|
end
|
|
if not stack:is_empty() then
|
|
local item = stack:take_item()
|
|
local iname = item:get_name()
|
|
if iname ~= "torches:torch" and minetest.registered_nodes[iname] then
|
|
local cid = minetest.get_content_id(iname)
|
|
for z = minp.z, maxp.z do
|
|
local index = va:index(minp.x, y, z)
|
|
for x = minp.x, maxp.x do
|
|
vmdata[index] = cid
|
|
param2[index] = 0
|
|
index = index + 1
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
vm:set_data(vmdata)
|
|
vm:set_param2_data(param2)
|
|
vm:update_liquids()
|
|
vm:write_to_map()
|
|
vm:update_map()
|
|
minetest.after(0.1, minetest.fix_light, minp, maxp)
|
|
|
|
-- reset pedestal number, build time
|
|
box.start_edit_time = minetest.get_gametime()
|
|
box.num_items = 0
|
|
local bmeta = db.box_get_meta(box.box_id)
|
|
bmeta.meta.num_items = 0
|
|
bmeta.meta.build_time = 0
|
|
db.box_set_meta(box.box_id, bmeta)
|
|
|
|
return true
|
|
end
|
|
|
|
sfinv.register_page("menu:edit", {
|
|
title = S("Game"),
|
|
is_in_nav = function(self, player, context)
|
|
local name = player:get_player_name()
|
|
return boxes.players_editing_boxes[name]
|
|
end,
|
|
get = function(self, player, context)
|
|
local name = player:get_player_name()
|
|
local box = boxes.players_editing_boxes[name]
|
|
local name_edit = ""
|
|
if box and box.box_name ~= nil then
|
|
name_edit = "field[0.8,2.6;4,0.6;box_name;"..FE(S("Box name"))..";" ..
|
|
minetest.formspec_escape(box.box_name) ..
|
|
"]"
|
|
end
|
|
local skyboxnr = 0
|
|
if box and box.skybox then
|
|
skyboxnr = box.skybox
|
|
end
|
|
local skybox =
|
|
"label[0.5,2.9;"..FE(S("Sky box:")).."]" ..
|
|
"dropdown[0.5,3.3;4.0;skybox;" ..
|
|
"0 - " .. FE(S("off")).."," ..
|
|
"1 - " .. FE(S("Dark and Stormy")).."," ..
|
|
"2 - " .. FE(S("Cloudy with light rays")).."," ..
|
|
"3 - " .. FE(S("Full Moon")).."," ..
|
|
"4 - " .. FE(S("Sunset")).."," ..
|
|
"5 - " .. FE(S("Thick clouds over water")).."," ..
|
|
"6 - " .. FE(S("Tropical sunny day")) ..
|
|
";" .. tostring(skyboxnr + 1) .."]"
|
|
return sfinv.make_formspec(player, context,
|
|
"button[0.5,0.5;4,0.6;save;"..FE(S("Save this box")).."]" ..
|
|
"button[0.5,1.3;4,0.6;stopedit;"..FE(S("Stop editing this box")).."]" ..
|
|
name_edit ..
|
|
skybox ..
|
|
"button[0.5,4.2;4,0.6;erase;"..FE(S("Wipe everything in this box")).."]" ..
|
|
"button[0.5,5.0;4,0.6;landscape;"..FE(S("Landscape this box")).."]" ..
|
|
"button[0.5,5.8;4,0.6;music;"..FE(S("Toggle music")).."]" ..
|
|
sfinv.style.gui_bg .. sfinv.style.gui_bg_img .. sfinv.style.gui_slots, false)
|
|
end,
|
|
on_player_receive_fields = function(self, player, context, fields)
|
|
if fields.stopedit then
|
|
minetest.close_formspec(player:get_player_name(), "")
|
|
boxes.save_edit(player)
|
|
boxes.stop_edit(player)
|
|
music.stop(player)
|
|
players.return_to_lobby(player)
|
|
return
|
|
end
|
|
-- don't elseif here - if text fields change we want to save them anyway.
|
|
if fields.save then
|
|
minetest.close_formspec(player:get_player_name(), "")
|
|
boxes.save_edit(player)
|
|
end
|
|
if fields.skybox then
|
|
local number = tonumber(fields.skybox:sub(1,1))
|
|
skybox.set(player, number)
|
|
boxes.players_editing_boxes[player:get_player_name()].skybox = number
|
|
end
|
|
if fields.box_name then
|
|
boxes.players_editing_boxes[player:get_player_name()].box_name = fields.box_name
|
|
sfinv.set_player_inventory_formspec(player)
|
|
end
|
|
if fields.erase then
|
|
local name = player:get_player_name()
|
|
local token = math.random(10000, 99999)
|
|
fsc.show(name,
|
|
"size[10,7]" ..
|
|
-- TODO: Change to multi-line label
|
|
"textlist[0.5,0.5;8.7,2.0;restettext;" ..
|
|
-- TODO: Make translatable
|
|
"Erasing the content is irreversible\\, and can not," ..
|
|
"be undone. Are you sure you want to continue?,," ..
|
|
"If you are sure\\, then type \"" .. token .. "\" in this " ..
|
|
"text box\\,and press \"Erase Everything\".;0;0]" ..
|
|
"field[4.0,3.5;3.0,1.5;confirm;;]" ..
|
|
"button[0.6,5.5;4.4,1.5;btn_cancel;"..FE(S("Cancel")).."]" ..
|
|
"button[5.0,5.5;4.4,1.5;btn_erase;"..FE(S("Erase everything")).."]",
|
|
token,
|
|
callback_erase
|
|
)
|
|
end
|
|
if fields.landscape then
|
|
local name = player:get_player_name()
|
|
local token = math.random(10000, 99999)
|
|
local inv = minetest.get_inventory({type="player", name = name})
|
|
inv:set_size("landscape", 10)
|
|
fsc.show(name,
|
|
"size[10,10]" ..
|
|
"list[current_player:landscape;landscape;0.2,0;1,8;]" ..
|
|
"list[current_player;main;1.6,0;8,1;]" ..
|
|
"listring[]" ..
|
|
"list[current_player;main;1.6,1.1;8,3;8]" ..
|
|
-- TODO: Make translatable, use multi-line label
|
|
"label[1.6,5;Drop nodes to the left from your inventory to create base layers for]" ..
|
|
"label[1.6,5.4;your box with these nodes. The stack size determines the thickness]" ..
|
|
"label[1.6,5.8;of the layers. Empty slots are omitted. Put torches in to leave]" ..
|
|
"label[1.6,6.2;multiple layers empty. The blocks in those layers will not be removed.]" ..
|
|
"label[1.6,7.6;Put the code \\\"" .. token .. "\\\" in the box here:]" ..
|
|
"field[6.4,7.4;3.0,1.5;confirm;;]" ..
|
|
"button[1.4,8.8;4,1.5;btn_cancel;"..FE(S("Cancel")).."]" ..
|
|
"button[5.4,8.8;4,1.5;btn_landscape;"..FE(S("Landscape this box")).."]",
|
|
token,
|
|
callback_landscape
|
|
)
|
|
end
|
|
if fields.music then
|
|
toggle_music(player)
|
|
end
|
|
end,
|
|
})
|
|
|
|
|
|
sfinv.register_page("menu:play", {
|
|
title = "Game",
|
|
is_in_nav = function(self, player, context)
|
|
local name = player:get_player_name()
|
|
return boxes.players_in_boxes[name]
|
|
end,
|
|
get = function(self, player, context)
|
|
local name = player:get_player_name()
|
|
local box = boxes.players_in_boxes[name]
|
|
local bmeta = db.box_get_meta(box.box_id)
|
|
local label = "label[0.5,0.5;"..FE(S("You are in box @1: \"@2\" by @3",
|
|
box.box_id, bmeta.meta.box_name, bmeta.meta.builder)) .. "]"
|
|
local leave_btn = "button[0.5,2.1;4,0.6;leave;"..FE(S("Leave this box")).."]"
|
|
if conf.tutorial.required then
|
|
local pmeta = player:get_meta()
|
|
if pmeta:get_string("tutorial_completed") ~= "1" then
|
|
leave_btn = ""
|
|
end
|
|
end
|
|
return sfinv.make_formspec(player, context,
|
|
label ..
|
|
leave_btn ..
|
|
"button[0.5,1.3;4,0.6;music;"..FE(S("Toggle music")).."]" ..
|
|
sfinv.get_hotbar_bg(0,4.7) ..
|
|
sfinv.style.gui_bg .. sfinv.style.gui_bg_img .. sfinv.style.gui_slots
|
|
.. creative.formspec_add, true)
|
|
end,
|
|
on_player_receive_fields = function(self, player, context, fields)
|
|
if fields.leave then
|
|
music.stop(player)
|
|
minetest.close_formspec(player:get_player_name(), "")
|
|
boxes.close_box(player)
|
|
players.return_to_lobby(player)
|
|
end
|
|
if fields.music then
|
|
toggle_music(player)
|
|
end
|
|
end,
|
|
})
|
|
|