local ns = artifact ns.players = {} local db = minetest.get_mod_storage() Player = setmetatable({ new = function(p) local m = setmetatable({ object = p }, {__index = Player}) m.name = p:get_player_name() m.meta = p:get_meta() m.character = m.meta:get("character") or "key" m.inv = p:get_inventory() m.inv:set_stack("main", 1, ItemStack("input")) -- Generic black sky, since the whole game takes place underground. p:set_sky{ type = "basic", base_color = "#000", clouds = false } p:set_sun{visible = false} p:set_moon{visible = false} p:set_stars{visible = false} p:set_properties { visual = "mesh", mesh = "artifact_character.gltf", shaded = false } if m.character == "vix" then artifact.apply_vix(m) else artifact.apply_key(m) end p:hud_set_flags { healthbar = false, breathbar = false, hotbar = artifact.debug, minimap = false, basic_debug = false } m:create_hud() m:set_hotbar_size(8) m.ctl = p:get_player_control() return m end, tick = function(m) local time = minetest.get_us_time() local p = m.object local pos = p:get_pos() local dir = p:get_look_dir() m.pos = pos m.pos.y = m.pos.y +m.eye_height local pointed_found = nil m.pointed_node = nil for x in minetest.raycast(m.pos, m.pos +(dir *5)) do if x and x.type == "object" then local e = x.ref:get_luaentity() -- Ignore players. if e then local names_match = m.pointed_obj and (m.pointed_obj._name or m.pointed_obj.name) == (e._name or e.name) if m.pointed_obj and not names_match then if m.pointed_obj.on_unhover then m.pointed_obj:on_unhover(m) end if m.pointed_obj.on_interact and m.interaction_marker then m.interaction_marker:remove() m.interaction_marker = nil end end if (m.pointed_obj and not names_match and e.on_hover) or not m.pointed_obj then if e.on_hover then e:on_hover(m) end if e.on_interact then if m.interaction_marker then m.interaction_marker:remove() end m.interaction_marker = minetest.add_entity(e.object:get_pos(), "display") m.interaction_marker:set_properties { visual = "sprite", textures = {"artifact_rmb.png"} } end pointed_found = true m.pointed_obj = e break elseif m.pointed_obj and names_match then pointed_found = true break end end elseif x and x.type == "node" then m.pointed_node = x end end if not pointed_found and m.pointed_obj then if m.pointed_obj.on_unhover then m.pointed_obj:on_unhover(m) end if m.pointed_obj.on_interact and m.interaction_marker then m.interaction_marker:remove() m.interaction_marker = nil end m.pointed_obj = nil end local ctl = m.object:get_player_control() if ctl.place and not m.ctl.place and m.pointed_obj and m.pointed_obj.on_interact then if not m.interaction_start then m.interaction_start = time -- m.interaction_marker = minetest.add_entity(m.pointed_obj, "display") -- m.interaction_marker:set_properties { -- visual = "sprite", -- textures = {"rgt_interact_progress_0.png"} -- } else if time -m.interaction_start > 1100000 then m.interaction_marker:remove() m.pointed_obj:on_interact(m) elseif time -m.interaction_start > 1000000 then m.interaction_marker:set_properties { textures = {"artifact_rmb_100.png"} } elseif time -m.interaction_start > 750000 then m.interaction_marker:set_properties { textures = {"artifact_rmb_75.png"} } elseif time -m.interaction_start > 500000 then m.interaction_marker:set_properties { textures = {"artifact_rmb_50.png"} } elseif time -m.interaction_start > 250000 then m.interaction_marker:set_properties { textures = {"artifact_rmb_25.png"} } end end elseif not ctl.place and m.ctl.place and m.interaction_start then m.interacting_with = nil m.interaction_start = nil end m.ctl = ctl end, set_character = function(m, to) m.character = to m.meta:set_string("character", to) end, -- Initialize the player's primary HUD display based on saved state. create_hud = function(m) -- If called post-init, make sure we delete the previous HUD. -- This is useful when we want to recreate the HUD in response -- to an event, like freeing Vix. if m.hud then for _, x in pairs(m.hud) do if type(x) == "table" then for _, y in pairs(x) do m.object:hud_remove(y) end else m.object:hud_remove(x) end end end m.hud = { key_health = m.object:hud_add { type = "statbar", position = {x=0.5,y=1}, offset = {x=-27 *5,y=artifact.debug and -96 or -30}, scale = {x=4,y=4}, alignment = {x=-1, y=-1}, size = {x=27,y=27}, text = "artifact_heart_vix.png", text2 = "artifact_heart_bg.png", number = 20 } } if artifact.debug or artifact.story.states[artifact.story.get_state()] >= artifact.story.states.main then end end, set_hotbar_size = function(m, slots) local p = m.object p:hud_set_hotbar_itemcount(slots) local list = "" for i = 0, slots do list = list..":"..(21*i)..",0=artifact_hotbar_bg.png" end p:hud_set_hotbar_image("[combine:"..(21 *slots +1).."x22"..list) p:hud_set_hotbar_selected_image("artifact_hotbar_selected_bg.png") end, }, { __call = function(_, ...) return Player.new(...) end }) artifact.register_craftitem("input", { inventory_image = "artifact_rmb_100.png", on_drop = function(s, p, pos) local m = artifact.players[p:get_player_name()] if artifact.debug or artifat.story.state > artifact.story.states.pre_vix then artifact.swap_character(m) end return s end }) minetest.register_globalstep(function() for _, m in pairs(artifact.players) do m:tick() end end) minetest.register_on_joinplayer(function(p) artifact.players[p:get_player_name()] = Player(p) if artifact.debug then -- Make sure we don't have to `/grantme` a million times while testing. minetest.registered_chatcommands.grantme.func(p:get_player_name(), "all") end end)