375 lines
14 KiB
Lua
375 lines
14 KiB
Lua
local S = minetest.get_translator("lzr_menu")
|
||
local FS = function(...) return minetest.formspec_escape(S(...)) end
|
||
|
||
local SPEAKER_POS = vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_SPEAKER_OFFSET)
|
||
|
||
local build_ship = function(pos)
|
||
minetest.place_schematic(pos, minetest.get_modpath("lzr_menu").."/schematics/lzr_menu_ship.mts", "0", {}, true, "")
|
||
minetest.set_node(vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_STARTBOOK_OFFSET), {name="lzr_menu:startbook", param2=0})
|
||
minetest.set_node(vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_CUSTOMBOOK_OFFSET), {name="lzr_menu:startbook_custom", param2=0})
|
||
minetest.set_node(vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_EDITOR_OFFSET), {name="lzr_menu:editorbook", param2=3})
|
||
minetest.set_node(SPEAKER_POS, {name="lzr_menu:speaker", param2=2})
|
||
minetest.set_node(vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_TELEVISION_OFFSET), {name="lzr_menu:television", param2=2})
|
||
end
|
||
|
||
local emerge_callback = function(blockpos, action, calls_remaining, param)
|
||
minetest.log("verbose", "[lzr_menu] emerge_callback() ...")
|
||
if action == minetest.EMERGE_ERRORED then
|
||
minetest.log("error", "[lzr_menu] Emerging error.")
|
||
elseif action == minetest.EMERGE_CANCELLED then
|
||
minetest.log("error", "[lzr_menu] Emerging cancelled.")
|
||
elseif calls_remaining == 0 and (action == minetest.EMERGE_GENERATED or action == minetest.EMERGE_FROM_DISK or action == minetest.EMERGE_FROM_MEMORY) then
|
||
build_ship(param.pos)
|
||
minetest.log("action", "[lzr_menu] Ship emerged and built.")
|
||
-- Now that the ship has *actually* been built,
|
||
-- setting the player pos should guarantee the player
|
||
-- stands on solid ground
|
||
local player = minetest.get_player_by_name("singleplayer")
|
||
player:set_pos(vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_PLAYER_SPAWN_OFFSET))
|
||
end
|
||
end
|
||
|
||
local SHIP_SIZE = { x = 30, y = 30, z = 30 }
|
||
|
||
local SPEAKER_NOTE_INTERVAL = 1.0
|
||
|
||
local emerge_ship = function(pos)
|
||
minetest.emerge_area(pos, vector.add(pos, SHIP_SIZE), emerge_callback, {pos=pos, size=SHIP_SIZE})
|
||
end
|
||
|
||
minetest.register_on_joinplayer(function(player)
|
||
emerge_ship(lzr_globals.MENU_SHIP_POS)
|
||
-- NOTE: This set_pos happens BEFORE the ship was actually built, so the
|
||
-- player may fall for a moment. This set_pos is thus not reliable
|
||
-- and is only made in prepatation for the future ship spawn.
|
||
player:set_pos(vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_PLAYER_SPAWN_OFFSET))
|
||
player:set_look_horizontal(0)
|
||
player:set_look_vertical(0)
|
||
local inv = player:get_inventory()
|
||
for i=1,inv:get_size("main") do
|
||
inv:set_stack("main", i, "")
|
||
end
|
||
end)
|
||
|
||
local on_punch_start_core = function(self, node, puncher)
|
||
lzr_level_select.open_dialog(puncher, "core")
|
||
end
|
||
local on_rightclick_start_core = function(self, node, clicker)
|
||
lzr_level_select.open_dialog(clicker, "core")
|
||
end
|
||
local on_punch_start_custom = function(self, node, puncher)
|
||
lzr_level_select.open_dialog(puncher, "custom")
|
||
end
|
||
local on_rightclick_start_custom = function(self, node, clicker)
|
||
lzr_level_select.open_dialog(clicker, "custom")
|
||
end
|
||
|
||
minetest.register_node("lzr_menu:startbook", {
|
||
description = S("Start Game Book"),
|
||
tiles = { "lzr_menu_book_top.png", "lzr_menu_book_bottom.png", "lzr_menu_book_side.png", "lzr_menu_book_side.png", "lzr_menu_book_end.png", "lzr_menu_book_end.png" },
|
||
paramtype = "light",
|
||
paramtype2 = "facedir",
|
||
drawtype = "nodebox",
|
||
node_box = {
|
||
type = "fixed",
|
||
fixed = {
|
||
{ -0.4375, -0.5, -0.375, 0.4375, -0.4375, 0.1875 },
|
||
{ -0.375, -0.4375, -0.375, 0.375, -0.375, 0.1875 }
|
||
}
|
||
},
|
||
sunlight_propagates = true,
|
||
on_construct = function(pos)
|
||
local meta = minetest.get_meta(pos)
|
||
meta:set_string("infotext", S("Start playing"))
|
||
end,
|
||
on_punch = on_punch_start_core,
|
||
on_rightclick = on_rightclick_start_core,
|
||
groups = { snappy = 3, not_in_creative_inventory = 1, },
|
||
})
|
||
|
||
minetest.register_node("lzr_menu:startbook_custom", {
|
||
description = S("Custom Level Game Book"),
|
||
tiles = { "lzr_menu_book_top.png", "lzr_menu_book_bottom.png", "lzr_menu_book_side.png", "lzr_menu_book_side.png", "lzr_menu_book_end.png", "lzr_menu_book_end.png" },
|
||
paramtype = "light",
|
||
paramtype2 = "facedir",
|
||
drawtype = "nodebox",
|
||
node_box = {
|
||
type = "fixed",
|
||
fixed = {
|
||
{ -0.4375, -0.5, -0.375, 0.4375, -0.4375, 0.1875 },
|
||
{ -0.375, -0.4375, -0.375, 0.375, -0.375, 0.1875 }
|
||
}
|
||
},
|
||
sunlight_propagates = true,
|
||
on_construct = function(pos)
|
||
local meta = minetest.get_meta(pos)
|
||
meta:set_string("infotext", S("Play custom levels"))
|
||
end,
|
||
on_punch = on_punch_start_custom,
|
||
on_rightclick = on_rightclick_start_custom,
|
||
groups = { snappy = 3, not_in_creative_inventory = 1, },
|
||
})
|
||
|
||
local on_punch_editor = function(self, node, puncher)
|
||
lzr_editor.enter_editor(puncher)
|
||
end
|
||
local on_rightclick_editor = function(self, node, clicker)
|
||
lzr_editor.enter_editor(clicker)
|
||
end
|
||
minetest.register_node("lzr_menu:editorbook", {
|
||
description = S("Level Editor Book"),
|
||
tiles = { "lzr_menu_book_editor_top.png", "lzr_menu_book_editor_bottom.png", "lzr_menu_book_editor_side.png", "lzr_menu_book_editor_side.png", "lzr_menu_book_editor_end.png", "lzr_menu_book_editor_end.png" },
|
||
paramtype = "light",
|
||
paramtype2 = "facedir",
|
||
drawtype = "nodebox",
|
||
node_box = {
|
||
type = "fixed",
|
||
fixed = {
|
||
{ -0.4375, -0.5, -0.375, 0.4375, -0.4375, 0.1875 },
|
||
{ -0.375, -0.4375, -0.375, 0.375, -0.375, 0.1875 }
|
||
}
|
||
},
|
||
sunlight_propagates = true,
|
||
on_construct = function(pos)
|
||
local meta = minetest.get_meta(pos)
|
||
meta:set_string("infotext", S("Enter the level editor"))
|
||
end,
|
||
on_punch = on_punch_editor,
|
||
on_rightclick = on_rightclick_editor,
|
||
groups = { snappy = 3, not_in_creative_inventory = 1, },
|
||
})
|
||
|
||
local use_speaker = function(speaker_pos, user)
|
||
local state = lzr_ambience.toggle_ambience_by_player(user)
|
||
if state then
|
||
minetest.sound_play({name="lzr_menu_speaker_turn_on", gain=0.4}, {pos=speaker_pos}, true)
|
||
else
|
||
minetest.sound_play({name="lzr_menu_speaker_turn_off", gain=0.4}, {pos=speaker_pos}, true)
|
||
end
|
||
end
|
||
|
||
local update_speaker_infotext = function(pos)
|
||
if minetest.get_node(pos).name ~= "lzr_menu:speaker" then
|
||
return
|
||
end
|
||
local meta = minetest.get_meta(pos)
|
||
local infotext = S("Toggle ambience sounds") .. "\n\n"
|
||
local active = lzr_ambience.is_active()
|
||
local ambience_state = meta:get_int("ambience_state")
|
||
-- Update infotext only if neccessary
|
||
if active and ambience_state ~= 1 then
|
||
infotext = infotext .. S("(Ambience is enabled)")
|
||
meta:set_int("ambience_state", 1)
|
||
meta:set_string("infotext", infotext)
|
||
elseif not active and ambience_state ~= 2 then
|
||
infotext = infotext .. S("(Ambience is disabled)")
|
||
meta:set_int("ambience_state", 2)
|
||
meta:set_string("infotext", infotext)
|
||
end
|
||
end
|
||
|
||
local on_punch_speaker = function(pos, node, puncher)
|
||
use_speaker(pos, puncher)
|
||
update_speaker_infotext(pos)
|
||
end
|
||
local on_rightclick_speaker = function(pos, node, clicker)
|
||
use_speaker(pos, clicker)
|
||
update_speaker_infotext(pos)
|
||
end
|
||
|
||
minetest.register_node("lzr_menu:speaker", {
|
||
description = S("Speaker"),
|
||
tiles = {
|
||
"lzr_menu_speaker_top.png",
|
||
"lzr_menu_speaker_side.png",
|
||
"lzr_menu_speaker_side.png",
|
||
"lzr_menu_speaker_side.png",
|
||
"lzr_menu_speaker_back.png",
|
||
"lzr_menu_speaker_front.png",
|
||
},
|
||
paramtype2 = "4dir",
|
||
groups = { breakable = 1, rotatable = 1, not_in_creative_inventory = 1},
|
||
sounds = lzr_sounds.node_sound_wood_defaults(),
|
||
is_ground_content = false,
|
||
on_punch = on_punch_speaker,
|
||
on_rightclick = on_rightclick_speaker,
|
||
on_construct = function(pos)
|
||
update_speaker_infotext(pos)
|
||
local timer = minetest.get_node_timer(pos)
|
||
timer:start(SPEAKER_NOTE_INTERVAL)
|
||
end,
|
||
on_timer = function(pos)
|
||
if lzr_ambience.is_active() then
|
||
local node = minetest.get_node(pos)
|
||
local dir = minetest.fourdir_to_dir(node.param2)
|
||
local notes = {
|
||
"lzr_menu_speaker_note_quarter.png",
|
||
"lzr_menu_speaker_note_eighth.png",
|
||
"lzr_menu_speaker_note_eighth_2.png",
|
||
}
|
||
local note = notes[math.random(1, #notes)]
|
||
local hue = math.random(-12, 12) * 15
|
||
note = note .. "^[hsl:"..hue..":0:0"
|
||
local notepos = vector.add(pos, vector.multiply(dir, -0.65))
|
||
notepos = vector.offset(notepos, 0, -2/16, 0)
|
||
minetest.add_particlespawner({
|
||
amount = 1,
|
||
time = SPEAKER_NOTE_INTERVAL / 2,
|
||
pos = notepos,
|
||
texture = {
|
||
name = note,
|
||
alpha_tween = { start = 0.6, 1, 0 },
|
||
},
|
||
size = 3,
|
||
exptime = 1,
|
||
vel = {
|
||
min = vector.new(0, 0.2, 0),
|
||
max = vector.new(0, 0.6, 0),
|
||
},
|
||
})
|
||
end
|
||
update_speaker_infotext(pos)
|
||
local timer = minetest.get_node_timer(pos)
|
||
timer:start(SPEAKER_NOTE_INTERVAL)
|
||
end,
|
||
})
|
||
|
||
-- Instantly update the ship speaker infotext when ambience status
|
||
-- was changed (could be by chat command)
|
||
lzr_ambience.register_on_ambience_change(function(state)
|
||
update_speaker_infotext(SPEAKER_POS)
|
||
end)
|
||
|
||
local graphics_settings_initial = {
|
||
opaque_lasers = minetest.settings:get_bool("lzr_opaque_lasers", false),
|
||
patterned_lasers = minetest.settings:get_bool("lzr_patterned_lasers", false),
|
||
}
|
||
|
||
local graphics_settings_state = table.copy(graphics_settings_initial)
|
||
|
||
local open_graphics_settings = function(player)
|
||
local form = "formspec_version[4]size[9,5.1]"..
|
||
"checkbox[2.3,1;opaque_lasers;"..FS("Opaque lasers")..";"..tostring(graphics_settings_state.opaque_lasers).."]"
|
||
|
||
form = form .. "box[1,0.5;1,1;#0000003f]"
|
||
if graphics_settings_state.opaque_lasers then
|
||
form = form .. "image[1.1,0.6;0.8,0.8;lzr_menu_settings_opaque_lasers_on.png]"
|
||
else
|
||
form = form .. "image[1.1,0.6;0.8,0.8;lzr_menu_settings_opaque_lasers_off.png]"
|
||
end
|
||
form = form .. "tooltip[opaque_lasers;"..FS("If enabled, lasers aren’t translucent. Can improve performance.").."]"
|
||
if graphics_settings_state.opaque_lasers ~= graphics_settings_initial.opaque_lasers then
|
||
form = form .. "label[6,1;"..minetest.formspec_escape("(*)").."]" ..
|
||
"tooltip[5.92,0.8;0.4,0.4;"..S("This setting will take effect after a restart.").."]"
|
||
end
|
||
|
||
form = form .. "box[1,1.6;1,1;#0000003f]"
|
||
if graphics_settings_state.patterned_lasers then
|
||
form = form .. "image[1.1,1.7.1;0.8,0.8;lzr_menu_settings_patterned_lasers_on.png]"
|
||
else
|
||
form = form .. "image[1.1,1.7.1;0.8,0.8;lzr_menu_settings_patterned_lasers_off.png]"
|
||
end
|
||
form = form .. "checkbox[2.3,2.1;patterned_lasers;"..FS("Laser color patterns")..";"..tostring(graphics_settings_state.patterned_lasers).."]" ..
|
||
"tooltip[patterned_lasers;"..FS("Special patterns will appear on the lasers, one for each color. Helps to distinguish lasers without relying on color alone.").."]"
|
||
|
||
if graphics_settings_state.patterned_lasers ~= graphics_settings_initial.patterned_lasers then
|
||
form = form .. "label[6,2.1;"..minetest.formspec_escape("(*)").."]" ..
|
||
"tooltip[5.92,1.9;0.4,0.4;"..S("This setting will take effect after a restart.").."]"
|
||
end
|
||
|
||
form = form .. "button[1,3.5;3.1,0.8;apply;"..FS("Apply").."]"..
|
||
"button_exit[5,3.5;3.1,0.8;cancel;"..FS("Cancel").."]"
|
||
|
||
minetest.show_formspec(player:get_player_name(), "lzr_menu:graphics_settings", form)
|
||
end
|
||
|
||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||
local pname = player:get_player_name()
|
||
if formname == "lzr_menu:graphics_settings" then
|
||
if fields.opaque_lasers == "true" then
|
||
graphics_settings_state.opaque_lasers = true
|
||
open_graphics_settings(player)
|
||
elseif fields.opaque_lasers == "false" then
|
||
graphics_settings_state.opaque_lasers = false
|
||
open_graphics_settings(player)
|
||
end
|
||
if fields.patterned_lasers == "true" then
|
||
graphics_settings_state.patterned_lasers = true
|
||
open_graphics_settings(player)
|
||
elseif fields.patterned_lasers == "false" then
|
||
graphics_settings_state.patterned_lasers = false
|
||
open_graphics_settings(player)
|
||
end
|
||
if fields.apply then
|
||
if graphics_settings_initial.opaque_lasers == graphics_settings_state.opaque_lasers and
|
||
graphics_settings_initial.patterned_lasers == graphics_settings_state.patterned_lasers then
|
||
-- Nothing has changed: Nothing to do.
|
||
minetest.close_formspec(pname, "lzr_menu:graphics_settings")
|
||
return
|
||
end
|
||
|
||
minetest.settings:set_bool("lzr_opaque_lasers", graphics_settings_state.opaque_lasers)
|
||
minetest.settings:set_bool("lzr_patterned_lasers", graphics_settings_state.patterned_lasers)
|
||
|
||
local form = "formspec_version[4]size[10,4]"..
|
||
"label[1,1;"..FS("The game needs to be restarted for the new graphics settings to take effect.").."]"..
|
||
"button_exit[1,2;3,0.8;restart;"..FS("Restart").."]"..
|
||
"button_exit[5,2;3,0.8;cancel;"..FS("Keep playing").."]"
|
||
minetest.show_formspec(pname, "lzr_menu:confirm_restart", form)
|
||
elseif fields.quit or fields.cancel then
|
||
graphics_settings_state = {
|
||
opaque_lasers = minetest.settings:get_bool("lzr_opaque_lasers", false),
|
||
patterned_lasers = minetest.settings:get_bool("lzr_patterned_lasers", false),
|
||
}
|
||
end
|
||
elseif formname == "lzr_menu:confirm_restart" then
|
||
if fields.restart then
|
||
minetest.disconnect_player(pname, S("You’ve quit the game. Start the game again for the settings to take effect."))
|
||
end
|
||
end
|
||
end)
|
||
|
||
local function on_rightclick_television(_, _, player)
|
||
open_graphics_settings(player)
|
||
end
|
||
local function on_punch_television(_, _, player)
|
||
open_graphics_settings(player)
|
||
end
|
||
|
||
-- Television to update graphics settings
|
||
minetest.register_node("lzr_menu:television", {
|
||
description = S("Television"),
|
||
tiles = {
|
||
"xdecor_television_left.png^[transformR90",
|
||
"xdecor_television_left.png^[transformR270",
|
||
"xdecor_television_left.png",
|
||
"xdecor_television_left.png^[transformR180",
|
||
"xdecor_television_back.png",
|
||
{ name = "xdecor_television_front_animated.png", animation = { type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 1 } },
|
||
},
|
||
paramtype2 = "4dir",
|
||
groups = { breakable = 1, rotatable = 1, not_in_creative_inventory = 1},
|
||
sounds = lzr_sounds.node_sound_metal_defaults(),
|
||
is_ground_content = false,
|
||
on_punch = on_punch_television,
|
||
on_rightclick = on_rightclick_television,
|
||
on_construct = function(pos)
|
||
local meta = minetest.get_meta(pos)
|
||
meta:set_string("infotext", S("Change graphics settings"))
|
||
end,
|
||
})
|
||
|
||
|
||
|
||
lzr_gamestate.register_on_enter_state(function(state)
|
||
if state == lzr_gamestate.MENU then
|
||
local player = minetest.get_player_by_name("singleplayer")
|
||
lzr_player.set_menu_inventory(player)
|
||
lzr_gui.set_menu_gui(player)
|
||
lzr_ambience.set_ambience("ocean")
|
||
lzr_sky.set_sky("bright_blue")
|
||
lzr_weather.set_weather("clear")
|
||
end
|
||
end)
|
||
|