1063 lines
36 KiB
Lua
1063 lines
36 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 COLOR_PICKER_MODIFIERS = { -32, -8, -1, 1, 8, 32 }
|
||
|
||
local MENU_LASER_ALPHA = "BF"
|
||
|
||
lzr_menu = {}
|
||
|
||
lzr_menu.SHIP_SIZE = nil
|
||
|
||
local registered_on_ship_builts = {}
|
||
-- Register callback function that is called when the ship has been built
|
||
-- and is ready for play. Will be called only once for the current game session.
|
||
function lzr_menu.register_on_ship_built(func)
|
||
table.insert(registered_on_ship_builts, func)
|
||
end
|
||
|
||
local registered_on_ship_rebuilts = {}
|
||
-- Register callback function that is called when the ship has been built
|
||
-- OR rebuilt (after an update).
|
||
function lzr_menu.register_on_ship_rebuilt(func)
|
||
table.insert(registered_on_ship_rebuilts, func)
|
||
end
|
||
|
||
local registered_on_player_ship_enters = {}
|
||
-- Register callback function that is called when the player enters the ship.
|
||
function lzr_menu.register_on_player_ship_enter(func)
|
||
table.insert(registered_on_player_ship_enters, func)
|
||
end
|
||
|
||
local place_gold_stash = function(gold_blocks)
|
||
if gold_blocks <= 0 then
|
||
return
|
||
end
|
||
local min_pos = vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_STASH_OFFSET)
|
||
local max_pos = vector.add(min_pos, lzr_globals.MENU_SHIP_STASH_SIZE)
|
||
local pos = table.copy(min_pos)
|
||
local posses = {}
|
||
for g=0, gold_blocks-1 do
|
||
if pos.z > max_pos.z then
|
||
break
|
||
end
|
||
local gpos = table.copy(pos)
|
||
if g % 4 == 1 then
|
||
gpos.x = gpos.x + 1
|
||
elseif g % 4 == 2 then
|
||
gpos.z = gpos.z + 1
|
||
elseif g % 4 == 3 then
|
||
gpos.x = gpos.x + 1
|
||
gpos.z = gpos.z + 1
|
||
pos.y = pos.y + 1
|
||
if pos.y >= max_pos.y then
|
||
pos.y = min_pos.y
|
||
pos.x = pos.x + 3
|
||
if pos.x > max_pos.x then
|
||
pos.x = min_pos.x
|
||
pos.z = pos.z + 3
|
||
end
|
||
end
|
||
end
|
||
table.insert(posses, gpos)
|
||
end
|
||
minetest.bulk_set_node(posses, {name="lzr_treasure:gold_block"})
|
||
minetest.log("action", "[lzr_menu] Placed "..gold_blocks.." gold block(s) in ship treasure stash")
|
||
end
|
||
|
||
local ship_emerged = false
|
||
local gold_stashed = 0
|
||
|
||
local build_ship = function()
|
||
minetest.place_schematic(lzr_globals.MENU_SHIP_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:level_starter", param2=0})
|
||
minetest.set_node(vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_CUSTOMBOOK_OFFSET), {name="lzr_menu:custom_level_starter", param2=0})
|
||
minetest.set_node(vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_EDITOR_OFFSET), {name="lzr_menu:editor_starter", param2=1})
|
||
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})
|
||
minetest.set_node(vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_HOWTO_BOOKSHELF_OFFSET), {name="lzr_menu:bookshelf_info", param2=1})
|
||
|
||
local core_level_data = lzr_levels.get_level_pack("__core")
|
||
if lzr_levels.are_all_levels_completed(core_level_data) then
|
||
lzr_menu.place_painting("perfect_plunderer")
|
||
end
|
||
|
||
-- Call 'rebuilt' callbacks
|
||
for f=1, #registered_on_ship_rebuilts do
|
||
registered_on_ship_rebuilts[f]()
|
||
end
|
||
end
|
||
|
||
lzr_menu.update_treasure_stash = function(gold_blocks)
|
||
if gold_stashed == gold_blocks then
|
||
return
|
||
end
|
||
if ship_emerged then
|
||
if gold_stashed > gold_blocks then
|
||
build_ship()
|
||
end
|
||
place_gold_stash(gold_blocks)
|
||
gold_stashed = gold_blocks
|
||
else
|
||
gold_stashed = gold_blocks
|
||
end
|
||
end
|
||
|
||
lzr_levels.register_on_collected_treasure(function(treasures)
|
||
lzr_menu.update_treasure_stash(treasures)
|
||
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
|
||
ship_emerged = true
|
||
build_ship()
|
||
minetest.log("action", "[lzr_menu] Ship emerged and built.")
|
||
place_gold_stash(gold_stashed)
|
||
-- 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")
|
||
lzr_menu.teleport_player_to_ship(player, "captain")
|
||
|
||
-- Call 'built' callbacks
|
||
for f=1, #registered_on_ship_builts do
|
||
registered_on_ship_builts[f]()
|
||
end
|
||
|
||
-- Call 'built' callbacks
|
||
for f=1, #registered_on_ship_builts do
|
||
registered_on_ship_builts[f]()
|
||
end
|
||
end
|
||
end
|
||
|
||
local SPEAKER_NOTE_INTERVAL = 1.0
|
||
|
||
local emerge_ship = function(pos)
|
||
local ship_schem = minetest.read_schematic(minetest.get_modpath("lzr_menu").."/schematics/lzr_menu_ship.mts", {write_yslice_prob="none"})
|
||
if not ship_schem then
|
||
minetest.log("error", "[lzr_menu] Could not read ship schematic!")
|
||
return
|
||
end
|
||
|
||
lzr_menu.SHIP_SIZE = ship_schem.size
|
||
|
||
minetest.emerge_area(pos, vector.add(pos, lzr_menu.SHIP_SIZE), emerge_callback)
|
||
end
|
||
|
||
minetest.register_on_joinplayer(function(player)
|
||
emerge_ship(lzr_globals.MENU_SHIP_POS)
|
||
-- NOTE: This teleport happens BEFORE the ship was actually built, so the
|
||
-- player may fall for a moment. This is thus not reliable
|
||
-- and is only made in prepatation for the future ship spawn.
|
||
lzr_menu.teleport_player_to_ship(player, "captain")
|
||
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)
|
||
if lzr_gamestate.get_state() ~= lzr_gamestate.MENU then
|
||
return
|
||
end
|
||
lzr_level_select.open_dialog(puncher, "core")
|
||
end
|
||
local on_rightclick_start_core = function(self, node, clicker)
|
||
if lzr_gamestate.get_state() ~= lzr_gamestate.MENU then
|
||
return
|
||
end
|
||
lzr_level_select.open_dialog(clicker, "core")
|
||
end
|
||
local on_punch_start_custom = function(self, node, puncher)
|
||
if lzr_gamestate.get_state() ~= lzr_gamestate.MENU then
|
||
return
|
||
end
|
||
lzr_level_select.open_dialog(puncher, "custom")
|
||
end
|
||
local on_rightclick_start_custom = function(self, node, clicker)
|
||
if lzr_gamestate.get_state() ~= lzr_gamestate.MENU then
|
||
return
|
||
end
|
||
lzr_level_select.open_dialog(clicker, "custom")
|
||
end
|
||
|
||
-- A node that starts level selection
|
||
minetest.register_node("lzr_menu:level_starter", {
|
||
--~ A node that starts level selection
|
||
description = S("Level Starter"),
|
||
-- symbolized by a map
|
||
tiles = { "lzr_menu_map.png", "blank.png" },
|
||
paramtype = "light",
|
||
paramtype2 = "4dir",
|
||
drawtype = "nodebox",
|
||
node_box = {
|
||
type = "fixed",
|
||
fixed = {
|
||
{ -0.5, -0.5, -0.5, 0.5, -63/128, 0.5 },
|
||
}
|
||
},
|
||
use_texture_alpha = "clip",
|
||
walkable = false,
|
||
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, },
|
||
})
|
||
|
||
-- A node that starts custom level selection
|
||
minetest.register_node("lzr_menu:custom_level_starter", {
|
||
--~ A node that starts custom level selection
|
||
description = S("Custom Level Starter"),
|
||
-- symbolized by a map
|
||
tiles = { "lzr_menu_map_custom.png", "blank.png" },
|
||
paramtype = "light",
|
||
paramtype2 = "4dir",
|
||
drawtype = "nodebox",
|
||
node_box = {
|
||
type = "fixed",
|
||
fixed = {
|
||
{ -0.5, -0.5, -0.5, 0.5, -63/128, 0.5 },
|
||
}
|
||
},
|
||
use_texture_alpha = "clip",
|
||
walkable = false,
|
||
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)
|
||
if lzr_gamestate.get_state() ~= lzr_gamestate.MENU then
|
||
return
|
||
end
|
||
lzr_editor.enter_editor(puncher)
|
||
end
|
||
local on_rightclick_editor = function(self, node, clicker)
|
||
if lzr_gamestate.get_state() ~= lzr_gamestate.MENU then
|
||
return
|
||
end
|
||
lzr_editor.enter_editor(clicker)
|
||
end
|
||
|
||
minetest.register_node("lzr_menu:editor_starter", {
|
||
description = S("Level Editor Starter"),
|
||
-- The level editor starter is represented by a saw
|
||
tiles = { "lzr_menu_saw.png", "blank.png" },
|
||
paramtype = "light",
|
||
paramtype2 = "4dir",
|
||
drawtype = "nodebox",
|
||
node_box = {
|
||
type = "fixed",
|
||
fixed = {
|
||
{ -0.5, -0.5, -0.5, 0.5, -63/128, 0.5 },
|
||
}
|
||
},
|
||
use_texture_alpha = "clip",
|
||
walkable = false,
|
||
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 = { breakable = 1, rotatable = 1, not_in_creative_inventory = 1, },
|
||
})
|
||
|
||
local use_speaker = function(speaker_pos, user)
|
||
if lzr_gamestate.get_state() ~= lzr_gamestate.MENU then
|
||
return
|
||
end
|
||
local state = lzr_ambience.toggle_ambience_by_player(user, true)
|
||
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 music") .. "\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("(Music is enabled)")
|
||
meta:set_int("ambience_state", 1)
|
||
meta:set_string("infotext", infotext)
|
||
elseif not active and ambience_state ~= 2 then
|
||
infotext = infotext .. S("(Music 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", {
|
||
--~ Loudspeaker
|
||
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),
|
||
}
|
||
for c=1, #lzr_globals.COLOR_NAMES do
|
||
local colorname = lzr_globals.COLOR_NAMES[c]
|
||
local setting = minetest.settings:get("lzr_laser_color_"..colorname)
|
||
if not setting or setting == "" then
|
||
setting = lzr_laser.DEFAULT_LASER_COLORS[c]
|
||
end
|
||
graphics_settings_initial["color_"..colorname] = setting
|
||
end
|
||
|
||
local graphics_settings_state = table.copy(graphics_settings_initial)
|
||
|
||
local color_descriptions = {
|
||
-- [laser color] = { <color adjective>, <laser color button tooltip>, <long description> }
|
||
[lzr_globals.COLOR_RED] = { S("red"), S("“red” lasers"), S("Adjust the replacement color for “red” lasers") },
|
||
[lzr_globals.COLOR_GREEN] = { S("green"), S("“green” lasers"), S("Adjust the replacement color for “green” lasers") },
|
||
[lzr_globals.COLOR_BLUE] = { S("blue"), S("“blue” lasers"), S("Adjust the replacement color for “blue” lasers") },
|
||
[lzr_globals.COLOR_YELLOW] = { S("yellow"), S("“yellow” lasers"), S("Adjust the replacement color for “yellow” lasers") },
|
||
[lzr_globals.COLOR_CYAN] = { S("cyan"), S("“cyan” lasers"), S("Adjust the replacement color for “cyan” lasers") },
|
||
[lzr_globals.COLOR_MAGENTA] = { S("magenta"), S("“magenta” lasers"), S("Adjust the replacement color for “magenta” lasers") },
|
||
[lzr_globals.COLOR_WHITE] = { S("white"), S("“white” lasers"), S("Adjust the replacement color for “white” lasers") },
|
||
}
|
||
|
||
local open_color_picker = function(player, colorname)
|
||
local r = graphics_settings_state["picked_color_red"]
|
||
local g = graphics_settings_state["picked_color_green"]
|
||
local b = graphics_settings_state["picked_color_blue"]
|
||
local colorcode = lzr_globals.COLOR_NAMES_SWAPPED[colorname]
|
||
-- If missing or invalid setting, fallback to default
|
||
if not r then
|
||
if colorcode then
|
||
local lhexcode = lzr_laser.DEFAULT_LASER_COLORS[colorcode]
|
||
if lhexcode then
|
||
r, g, b = lzr_util.hexcode_to_rgb(lhexcode)
|
||
end
|
||
end
|
||
if not r then
|
||
minetest.log("error", "[lzr_menu] open_color_picker could not pick default color for: "..colorname.."!")
|
||
return
|
||
end
|
||
end
|
||
local hexcode = lzr_util.rgb_to_hexcode(r,g,b)
|
||
local channels = {
|
||
{ "red", S("Red"), r },
|
||
{ "green", S("Green"), g },
|
||
{ "blue", S("Blue"), b },
|
||
}
|
||
|
||
local lalpha
|
||
if graphics_settings_state.opaque_lasers then
|
||
lalpha = "FF"
|
||
else
|
||
lalpha = MENU_LASER_ALPHA
|
||
end
|
||
local color_adj = color_descriptions[colorcode][1]
|
||
|
||
local form = "" ..
|
||
"formspec_version[7]size[9,7.1]"..
|
||
|
||
"image[8.3,0.3;0.4,0.4;lzr_menu_tooltip_icon.png]"..
|
||
"tooltip[8.3,0.3;0.4,0.4;"..
|
||
minetest.formspec_escape(
|
||
S("Here you can redefine the color @1 for lasers.", color_adj).."\n"..
|
||
S("The game will pretend this is @1, even if the actual color is different.", color_adj)
|
||
).."]"..
|
||
|
||
"label[0.5,0.5;"..minetest.formspec_escape(color_descriptions[colorcode][3]).."]"..
|
||
"box[1.0,1.2;7,0.2;#"..hexcode..lalpha.."]"..
|
||
"container[0.5,2.0]"
|
||
for c=1, #channels do
|
||
local id = channels[c][1]
|
||
local desc = channels[c][2]
|
||
local defval = channels[c][3]
|
||
local y = c - 1
|
||
-- get modifier
|
||
local function gm(index)
|
||
local txt
|
||
if COLOR_PICKER_MODIFIERS[index] < 0 then
|
||
--~ Subtract color value in custom laser color menu
|
||
return FS("−@1", math.abs(COLOR_PICKER_MODIFIERS[index]))
|
||
else
|
||
--~ Add color value in custom laser color menu
|
||
return FS("+@1", COLOR_PICKER_MODIFIERS[index])
|
||
end
|
||
end
|
||
form = form .. "label[0.39,"..(y+0.3)..";"..minetest.formspec_escape(desc).."]" ..
|
||
"button[2,"..y..";0.7,0.5;channel_"..id.."_mmm;"..gm(1).."]" ..
|
||
"button[2.7,"..y..";0.7,0.5;channel_"..id.."_mm;"..gm(2).."]"..
|
||
"button[3.4,"..y..";0.7,0.5;channel_"..id.."_m;"..gm(3).."]"..
|
||
--~ Color value number in custom laser color menu. @1 current value, @2 maximum possible value
|
||
"label[4.4,"..(y+0.3)..";"..FS("@1/@2", defval, 255).."]"..
|
||
"button[5.6,"..y..";0.7,0.5;channel_"..id.."_p;"..gm(4).."]"..
|
||
"button[6.3,"..y..";0.7,0.5;channel_"..id.."_pp;"..gm(5).."]"..
|
||
"button[7.0,"..y..";0.7,0.5;channel_"..id.."_ppp;"..gm(6).."]"
|
||
local chancode
|
||
if id == "red" then
|
||
chancode = string.format("#%02x0000", defval)
|
||
elseif id == "green" then
|
||
chancode = string.format("#00%02x00", defval)
|
||
elseif id == "blue" then
|
||
chancode = string.format("#0000%02x", defval)
|
||
end
|
||
form = form .. "box[0.0,"..(y+0.15)..";0.3,0.3;"..chancode..lalpha.."]"
|
||
end
|
||
form = form .. "container_end[]"
|
||
|
||
form = form .. "button[0.5,4.9;2,0.5;default;"..FS("Default").."]"..
|
||
"tooltip[default;"..FS("Pick the default color").."]"
|
||
|
||
form = form .. "button[0.7,6;3.5,0.8;ok;"..FS("OK").."]"..
|
||
"button[4.75,6;3.5,0.8;cancel;"..FS("Cancel").."]"
|
||
|
||
minetest.show_formspec(player:get_player_name(), "lzr_menu:color_picker", form)
|
||
end
|
||
|
||
local open_graphics_settings = function(player)
|
||
graphics_settings_state.picking_color = nil
|
||
local put_asterisk = function(x, y)
|
||
return "label["..x..","..y..";"..minetest.formspec_escape("(*)").."]" ..
|
||
"tooltip["..(x-0.08)..","..(y-0.2)..";0.4,0.4;"..S("This setting will take effect after a restart.").."]"
|
||
end
|
||
|
||
local form = "" ..
|
||
-- Header
|
||
"formspec_version[7]size[12,6.1]"..
|
||
|
||
-- Opaque lasers
|
||
"container[-0.6,0]" ..
|
||
"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 .. put_asterisk(6, 1)
|
||
end
|
||
|
||
-- Patterned lasers
|
||
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("Draw patterns on lasers")..";"..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 .. put_asterisk(6, 2.1)
|
||
end
|
||
form = form .. "container_end[]"
|
||
|
||
local get_color_setting_texture = function(colorname)
|
||
local hexcode = graphics_settings_state["color_"..colorname]
|
||
local lalpha
|
||
if graphics_settings_state.opaque_lasers then
|
||
lalpha = "FF"
|
||
else
|
||
lalpha = MENU_LASER_ALPHA
|
||
end
|
||
if type(hexcode) == "string" and string.len(hexcode) == 6 then
|
||
return "[fill:16x16:#"..hexcode..lalpha.."^[mask:lzr_menu_color_select_button_mask.png"
|
||
elseif hexcode == "" or hexcode == nil then
|
||
local colorcode = lzr_globals.COLOR_NAMES_SWAPPED[colorname]
|
||
hexcode = lzr_laser.DEFAULT_LASER_COLORS[colorcode]
|
||
-- This is an error
|
||
if not hexcode then
|
||
minetest.log("error", "[lzr_menu] get_color_setting_texture: Could not get default color for: "..colorname)
|
||
return "blank.png"
|
||
end
|
||
return "[fill:16x16:#"..hexcode..lalpha.."^[mask:lzr_menu_color_select_button_mask.png"
|
||
else
|
||
-- Invalid color in settings
|
||
return "blank.png"
|
||
end
|
||
end
|
||
|
||
local are_colors_modified = function(colornames)
|
||
for c=1, #colornames do
|
||
local colorname = colornames[c]
|
||
if graphics_settings_initial["color_"..colorname] ~= graphics_settings_state["color_"..colorname] then
|
||
return true
|
||
end
|
||
end
|
||
end
|
||
|
||
-- Laser colors
|
||
form = form .. "container[6.5,0.6]"
|
||
form = form .. "box[-0.2,-0.2;5.4,3;#00000040]"
|
||
form = form .. "label[0,0;"..FS("Laser colors:").."]"
|
||
|
||
|
||
local ui_colors = { "red", "green", "blue", "yellow", "magenta", "cyan", "white" }
|
||
if are_colors_modified(ui_colors) then
|
||
form = form .. put_asterisk(4.5, 0)
|
||
end
|
||
|
||
|
||
local ibx = 0
|
||
local iby = 0
|
||
local max_x = 0
|
||
local max_y = 0
|
||
for c=1, #ui_colors do
|
||
local col = ui_colors[c]
|
||
local x = 0 + ibx*1.7
|
||
local y = 0.3 + iby
|
||
max_x = math.max(x, max_x)
|
||
max_y = math.max(y, max_y)
|
||
|
||
form = form .. "image_button["..x..","..y..";1.6,0.5;"..minetest.formspec_escape(get_color_setting_texture(col))..";color_"..col..";]" ..
|
||
"tooltip[color_"..col..";"..minetest.formspec_escape(color_descriptions[lzr_globals.COLOR_NAMES_SWAPPED[col]][2]).."]"
|
||
|
||
ibx = ibx + 1
|
||
if ibx >= 3 then
|
||
ibx = 0
|
||
iby = iby + 0.6
|
||
end
|
||
end
|
||
form = form .. "button[0,"..(max_y+0.7)..";3.2,0.5;color_reset;"..FS("Reset").."]" ..
|
||
"tooltip[color_reset;"..FS("Reset all laser colors").."]" ..
|
||
"container_end[]"
|
||
|
||
-- Buttons
|
||
form = form .. "button[2.5,4.7;3.1,0.8;apply;"..FS("Apply").."]"..
|
||
"button_exit[6.5,4.7;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)
|
||
if lzr_gamestate.get_state() ~= lzr_gamestate.MENU then
|
||
return
|
||
end
|
||
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
|
||
for c=1, #lzr_globals.COLOR_NAMES do
|
||
local color = lzr_globals.COLOR_NAMES[c]
|
||
if fields["color_"..color] then
|
||
graphics_settings_state.picking_color = color
|
||
local r, g, b = lzr_util.hexcode_to_rgb(graphics_settings_state["color_"..color])
|
||
graphics_settings_state["picked_color_red"] = r
|
||
graphics_settings_state["picked_color_green"] = g
|
||
graphics_settings_state["picked_color_blue"] = b
|
||
open_color_picker(player, color)
|
||
return
|
||
end
|
||
end
|
||
if fields.color_reset then
|
||
for c=1, #lzr_globals.COLOR_NAMES do
|
||
local colorname = lzr_globals.COLOR_NAMES[c]
|
||
graphics_settings_state["color_"..colorname] = lzr_laser.DEFAULT_LASER_COLORS[c]
|
||
end
|
||
open_graphics_settings(player)
|
||
return
|
||
end
|
||
if fields.apply then
|
||
-- Check if any setting has changed
|
||
local changed = false
|
||
for k, v in pairs(graphics_settings_initial) do
|
||
if v ~= graphics_settings_state[k] then
|
||
changed = true
|
||
break
|
||
end
|
||
end
|
||
if not changed 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)
|
||
|
||
for c=1, #lzr_globals.COLOR_NAMES do
|
||
local colorname = lzr_globals.COLOR_NAMES[c]
|
||
local cvalue = graphics_settings_state["color_"..colorname]
|
||
if not cvalue then
|
||
cvalue = ""
|
||
end
|
||
minetest.settings:set("lzr_laser_color_"..colorname, cvalue)
|
||
end
|
||
|
||
local form = "formspec_version[7]size[10,4]"..
|
||
"textarea[1,0.8;8,1.5;;;"..FS("The game needs to be restarted for the new graphics settings to take effect.").."]"..
|
||
"button_exit[1,2.5;3,0.8;restart;"..FS("Restart").."]"..
|
||
"button_exit[5.5,2.5;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),
|
||
}
|
||
for c=1, #lzr_globals.COLOR_NAMES do
|
||
local colorname = lzr_globals.COLOR_NAMES[c]
|
||
graphics_settings_state["color_"..colorname] = minetest.settings:get("lzr_laser_color_"..colorname)
|
||
end
|
||
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
|
||
elseif formname == "lzr_menu:color_picker" then
|
||
local channels = { "red", "green", "blue" }
|
||
local modifiers = { "mmm", "mm", "m", "p", "pp", "ppp" }
|
||
for c=1, #channels do
|
||
for m=1, #modifiers do
|
||
local channel = channels[c]
|
||
local modifier = modifiers[m]
|
||
if fields["channel_"..channel.."_"..modifier] then
|
||
local val = graphics_settings_state["picked_color_"..channel]
|
||
if val then
|
||
val = val + COLOR_PICKER_MODIFIERS[m]
|
||
val = math.floor(math.min(255, math.max(0, val)))
|
||
else
|
||
val = 255
|
||
end
|
||
|
||
graphics_settings_state["picked_color_"..channel] = val
|
||
open_color_picker(player, graphics_settings_state.picking_color)
|
||
end
|
||
end
|
||
end
|
||
if fields.default then
|
||
local colorname = graphics_settings_state.picking_color
|
||
if colorname then
|
||
local colorcode = lzr_globals.COLOR_NAMES_SWAPPED[colorname]
|
||
local default_color_hex = lzr_laser.DEFAULT_LASER_COLORS[colorcode]
|
||
local r,g,b = lzr_util.hexcode_to_rgb(default_color_hex)
|
||
graphics_settings_state["picked_color_red"] = r
|
||
graphics_settings_state["picked_color_green"] = g
|
||
graphics_settings_state["picked_color_blue"] = b
|
||
open_color_picker(player, colorname)
|
||
end
|
||
end
|
||
if fields.ok then
|
||
local r = graphics_settings_state["picked_color_red"]
|
||
local g = graphics_settings_state["picked_color_green"]
|
||
local b = graphics_settings_state["picked_color_blue"]
|
||
if r and g and b then
|
||
r = math.floor(math.min(255, math.max(0, r)))
|
||
g = math.floor(math.min(255, math.max(0, g)))
|
||
b = math.floor(math.min(255, math.max(0, b)))
|
||
local hex = lzr_util.rgb_to_hexcode(r, g, b)
|
||
if graphics_settings_state.picking_color and hex then
|
||
graphics_settings_state["color_"..graphics_settings_state.picking_color] = hex
|
||
end
|
||
end
|
||
open_graphics_settings(player)
|
||
elseif fields.cancel or fields.quit then
|
||
open_graphics_settings(player)
|
||
end
|
||
end
|
||
end)
|
||
|
||
local function on_rightclick_television(_, _, player)
|
||
if lzr_gamestate.get_state() ~= lzr_gamestate.MENU then
|
||
return
|
||
end
|
||
|
||
open_graphics_settings(player)
|
||
end
|
||
local function on_punch_television(_, _, player)
|
||
if lzr_gamestate.get_state() ~= lzr_gamestate.MENU then
|
||
return
|
||
end
|
||
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,
|
||
})
|
||
|
||
minetest.register_node("lzr_menu:bookshelf_info", {
|
||
description = S("Info Book Bookshelf"),
|
||
paramtype2 = "4dir",
|
||
tiles = {
|
||
{name="default_wood.png", align_style="world"},
|
||
{name="default_wood.png", align_style="world"},
|
||
{name="default_wood.png", align_style="world"},
|
||
{name="default_wood.png", align_style="world"},
|
||
"default_wood.png^lzr_decor_bookshelf.png",
|
||
},
|
||
sounds = lzr_sounds.node_sound_wood_defaults(),
|
||
on_construct = function(pos)
|
||
local meta = minetest.get_meta(pos)
|
||
meta:set_string("infotext", S("Read about how to play the game"))
|
||
end,
|
||
on_punch = function(self, node, puncher)
|
||
if lzr_gamestate.get_state() ~= lzr_gamestate.MENU then
|
||
return
|
||
end
|
||
lzr_infobooks.open_bookshelf(puncher:get_player_name(), "how_to_play")
|
||
end,
|
||
on_rightclick = function(self, node, clicker)
|
||
if lzr_gamestate.get_state() ~= lzr_gamestate.MENU then
|
||
return
|
||
end
|
||
lzr_infobooks.open_bookshelf(clicker:get_player_name(), "how_to_play")
|
||
end,
|
||
groups = { not_in_creative_inventory = 1 },
|
||
})
|
||
|
||
-- This painting symbolizes completion of the game
|
||
minetest.register_node("lzr_menu:painting_perfect_plunderer", {
|
||
description = S("Painting: Perfect Plunderer"),
|
||
drawtype = "nodebox",
|
||
paramtype2 = "wallmounted",
|
||
paramtype = "light",
|
||
sunlight_propagates = true,
|
||
walkable = false,
|
||
node_box = {
|
||
type = "wallmounted",
|
||
wall_top = {-0.4375, 0.4375, -0.3725, 0.4375, 0.5, 0.3725},
|
||
wall_bottom = {-0.4375, -0.5, -0.3725, 0.4375, -0.4375, 0.3725},
|
||
wall_side = {-0.5, -0.3725, -0.4375, -0.4375, 0.3725, 0.4375},
|
||
},
|
||
tiles = {"lzr_menu_painting_perfect_plunderer.png", "lzr_menu_painting_back.png"},
|
||
use_texture_alpha = "clip",
|
||
groups = { breakable = 1, not_in_creative_inventory = 1 },
|
||
on_construct = function(pos)
|
||
local meta = minetest.get_meta(pos)
|
||
meta:set_string("infotext", S("Found every treasure of the known world"))
|
||
end,
|
||
})
|
||
|
||
-- This painting symbolizes finding all hidden parrots
|
||
minetest.register_node("lzr_menu:painting_parrot_finder", {
|
||
description = S("Painting: Parrot Finder"),
|
||
drawtype = "nodebox",
|
||
paramtype2 = "wallmounted",
|
||
paramtype = "light",
|
||
sunlight_propagates = true,
|
||
walkable = false,
|
||
node_box = {
|
||
type = "wallmounted",
|
||
wall_top = {-0.4375, 0.4375, -0.3725, 0.4375, 0.5, 0.3725},
|
||
wall_bottom = {-0.4375, -0.5, -0.3725, 0.4375, -0.4375, 0.3725},
|
||
wall_side = {-0.5, -0.3725, -0.4375, -0.4375, 0.3725, 0.4375},
|
||
},
|
||
tiles = {"lzr_menu_painting_parrot_finder.png", "lzr_menu_painting_back.png"},
|
||
use_texture_alpha = "clip",
|
||
groups = { breakable = 1, not_in_creative_inventory = 1 },
|
||
on_construct = function(pos)
|
||
local meta = minetest.get_meta(pos)
|
||
meta:set_string("infotext", S("Found every hidden parrot"))
|
||
end,
|
||
})
|
||
|
||
function lzr_menu.spawn_hidden_parrot(parrot_name)
|
||
local offset = lzr_globals.MENU_SHIP_HIDDEN_PARROT_OFFSETS[parrot_name]
|
||
if not offset then
|
||
minetest.log("error", "[lzr_menu] Unknown hidden parrot ship spawn offset for parrot '"..tostring(parrot_name).."'!")
|
||
return
|
||
end
|
||
local pos = vector.add(lzr_globals.MENU_SHIP_POS, offset)
|
||
-- Check if this parrot is already spawned at this pos
|
||
local objs = minetest.get_objects_inside_radius(pos, 0.5)
|
||
for o=1, #objs do
|
||
local obj = objs[o]
|
||
local ent = obj:get_luaentity()
|
||
if ent and ent.name == "lzr_parrot_npc:hidden_parrot" and ent._hidden_id == parrot_name then
|
||
-- No spawn if parrot is already there
|
||
return
|
||
end
|
||
end
|
||
|
||
-- Spawn parrot, then check for success
|
||
local obj = minetest.add_entity(pos, "lzr_parrot_npc:hidden_parrot")
|
||
if not obj then
|
||
minetest.log("error", "[lzr_menu] Failed to spawn in-ship hidden parrot '"..tostring(parrot_name).."'!")
|
||
return
|
||
end
|
||
local ent = obj:get_luaentity()
|
||
if not ent then
|
||
minetest.log("error", "[lzr_menu] Failed to get luaentity of in-ship hidden parrot '"..tostring(parrot_name).."'!")
|
||
return
|
||
end
|
||
-- Ship parrots look randomly
|
||
local yaw = (math.random(0,359) / 360) * (math.pi*2)
|
||
obj:set_yaw(yaw)
|
||
|
||
-- Assign parrot name
|
||
ent:_init(parrot_name)
|
||
end
|
||
|
||
function lzr_menu.teleport_player_to_ship(player, location)
|
||
if location == "captain" then
|
||
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)
|
||
elseif location == "skulls" then
|
||
player:set_pos(vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_PLAYER_RESPAWN_OFFSET))
|
||
player:set_look_horizontal(0)
|
||
player:set_look_vertical(0)
|
||
elseif location == "victory" then
|
||
player:set_pos(vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_PLAYER_WINSPAWN_OFFSET))
|
||
player:set_look_horizontal(math.pi)
|
||
player:set_look_vertical(0)
|
||
else
|
||
minetest.log("error", "[lzr_menu] Tried to teleport player to invalid ship location: "..tostring(location))
|
||
return
|
||
end
|
||
for f=1, #registered_on_player_ship_enters do
|
||
registered_on_player_ship_enters[f](player, location)
|
||
end
|
||
end
|
||
|
||
function lzr_menu.remove_hidden_parrots()
|
||
if not lzr_menu.SHIP_SIZE then
|
||
return
|
||
end
|
||
local max_pos = vector.add(lzr_globals.MENU_SHIP_POS, lzr_menu.SHIP_SIZE)
|
||
local objs = minetest.get_objects_in_area(lzr_globals.MENU_SHIP_POS, max_pos)
|
||
for o=1, #objs do
|
||
local obj = objs[o]
|
||
local ent = obj:get_luaentity()
|
||
if ent and ent.name == "lzr_parrot_npc:hidden_parrot" then
|
||
obj:remove()
|
||
end
|
||
end
|
||
end
|
||
|
||
function lzr_menu.place_painting(painting)
|
||
if painting == "perfect_plunderer" then
|
||
minetest.set_node(vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_PAINTING_PERFECT_PLUNDERER_OFFSET), {name="lzr_menu:painting_perfect_plunderer", param2=4})
|
||
minetest.log("action", "[lzr_menu] Added painting 'perfect_plunderer'")
|
||
elseif painting == "parrot_finder" then
|
||
minetest.set_node(vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_PAINTING_PARROT_FINDER_OFFSET), {name="lzr_menu:painting_parrot_finder", param2=4})
|
||
minetest.log("action", "[lzr_menu] Added painting 'parrot_finder'")
|
||
end
|
||
end
|
||
function lzr_menu.remove_painting(painting)
|
||
if painting == "perfect_plunderer" then
|
||
minetest.remove_node(vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_PAINTING_PERFECT_PLUNDERER_OFFSET))
|
||
minetest.log("action", "[lzr_menu] Removed painting 'perfect_plunderer'")
|
||
elseif painting == "parrot_finder" then
|
||
minetest.remove_node(vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_PAINTING_PARROT_FINDER_OFFSET))
|
||
minetest.log("action", "[lzr_menu] Removed painting 'perfect_plunderer'")
|
||
end
|
||
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("village")
|
||
lzr_sky.set_sky("bright_blue")
|
||
lzr_weather.set_weather("clear")
|
||
lzr_triggers.reset_triggers()
|
||
end
|
||
end)
|
||
|
||
local timer = 0
|
||
minetest.register_globalstep(function(dtime)
|
||
timer = timer + dtime
|
||
if timer < 1.5 then
|
||
return
|
||
end
|
||
timer = 0
|
||
if lzr_gamestate.get_state ()~= lzr_gamestate.MENU then
|
||
return
|
||
end
|
||
local player = minetest.get_player_by_name("singleplayer")
|
||
if not player then
|
||
return
|
||
end
|
||
local pos = player:get_pos()
|
||
|
||
-- Render menu markers if player is inside captain's cabin
|
||
local in_cabin = false
|
||
-- Main area
|
||
if vector.in_area(pos,
|
||
vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_CAPTAIN_CABIN_OFFSET_MIN),
|
||
vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_CAPTAIN_CABIN_OFFSET_MAX)) then
|
||
in_cabin = true
|
||
-- Exclusion zones
|
||
for i=1, #lzr_globals.MENU_SHIP_CAPTAIN_CABIN_EXCLUSIONS do
|
||
if vector.in_area(pos,
|
||
vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_CAPTAIN_CABIN_EXCLUSIONS[i][1]),
|
||
vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_CAPTAIN_CABIN_EXCLUSIONS[i][2])) then
|
||
in_cabin = false
|
||
break
|
||
end
|
||
end
|
||
end
|
||
if in_cabin then
|
||
lzr_gui.show_menu_markers(player)
|
||
else
|
||
lzr_gui.hide_menu_markers(player)
|
||
end
|
||
end)
|
||
|
||
-- Force-load the player spawn position
|
||
local function forceload()
|
||
local ok = minetest.forceload_block(vector.add(lzr_globals.MENU_SHIP_POS, lzr_globals.MENU_SHIP_PLAYER_SPAWN_OFFSET), true)
|
||
if not ok then
|
||
minetest.log("warning", "[lzr_menu] Could not forceload menu ship")
|
||
else
|
||
minetest.log("action", "[lzr_menu] Menu ship successfully forceloaded")
|
||
end
|
||
end
|
||
forceload()
|
||
|
||
minetest.register_entity("lzr_menu:arrow", {
|
||
initial_properties = {
|
||
visual = "mesh",
|
||
mesh = "lzr_menu_arrow.gltf",
|
||
visual_size = { x=5, y=5, z=5 },
|
||
textures = {
|
||
"lzr_menu_arrow.png",
|
||
},
|
||
use_texture_alpha = true,
|
||
static_save = false,
|
||
physical = false,
|
||
collide_with_objects = false,
|
||
selectionbox = {
|
||
-0.25, -0.25, -0.25, 0.25, 0.5, 0.25,
|
||
},
|
||
pointable = false,
|
||
automatic_rotate = -0.5,
|
||
},
|
||
on_activate = function(self)
|
||
minetest.log("error", "set_anim")
|
||
self.object:set_animation({x=0,y=48}, 0.5, 0, true)
|
||
end,
|
||
})
|
||
|
||
minetest.register_alias("lzr_menu:editorbook", "lzr_menu:editor_starter")
|
||
minetest.register_alias("lzr_menu:startbook", "lzr_menu:level_starter")
|
||
minetest.register_alias("lzr_menu:startbook_custom", "lzr_menu:custom_level_starter")
|