local S = minetest.get_translator("lzr_menu") 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}) 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) 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)