local ns = artifact local db = minetest.get_mod_storage() function ns.apply_key(m) m.object:set_properties { textures = {"artifact_key.png"}, visual_size = vector.new(1,1,1) *0.88, eye_height = 1.6 } m.eye_height = 1.6 -- Switch hand appearance. m.inv:set_stack("main", 1, ItemStack("input_"..m.character)) if m.healthbar then m.object:hud_change(m.healthbar, "text", "artifact_heart.png") end m.blackrod = minetest.add_entity(m.object:get_pos(), "display") m.blackrod:set_properties { visual = "mesh", mesh = "artifact_blackrod.obj", textures = {"artifact_blackrod.png"}, visual_size = vector.new(1,1,1) *10 } m.blackrod:set_attach(m.object, "RightArm", vector.new(0.25, -5.5, 0), vector.new(90,0,0)) end function ns.apply_vix(m) m.object:set_properties { textures = {"artifact_vix.png"}, visual_size = vector.new(1,1,1) *0.8, eye_height = 1.5 } m.eye_height = 1.5 -- Switch hand appearance. m.inv:set_stack("main", 1, ItemStack("input_"..m.character)) m.object:hud_change(m.healthbar, "text", "artifact_heart_vix.png") if m.blackrod then m.blackrod:remove() m.blackrod = nil end end function ns.swap_character(m) if m.character == "vix" then artifact.sidekick.character = "vix" m:set_character("key") ns.apply_key(m) else artifact.sidekick.character = "key" m:set_character("vix") ns.apply_vix(m) end -- We don't need to have the sidekick entity during testing. if artifact.sidekick.pos or not artifact.debug then -- `m.pos` includes eye_height, and we don't want that here. local pos = m.object:get_pos() local yaw = m.yaw local pitch = m.pitch if not artifact.sidekick.pos then artifact.sidekick.pos = pos end m.object:set_pos(artifact.sidekick.pos) m.object:set_look_horizontal(artifact.sidekick.yaw) m.object:set_look_vertical(artifact.sidekick.pitch) if not artifact.sidekick.ref then minetest.add_entity(pos, "artifact:sidekick") end artifact.sidekick.ref.object:set_pos(pos) artifact.sidekick.ref.object:set_yaw(yaw) artifact.sidekick.ref.object:set_bone_override("Head", m.object:get_bone_override("Head")) artifact.sidekick.ref.object:set_bone_override("root", m.object:get_bone_override("root")) artifact.sidekick.pos = pos artifact.sidekick.yaw = yaw artifact.sidekick.pitch = pitch local e = artifact.sidekick.ref if artifact.sidekick.character == "vix" then artifact.sidekick.ref.object:set_properties { textures = {"artifact_vix.png"}, visual_size = vector.new(1,1,1) *0.8 } if e.blackrod then e.blackrod:remove() e.blackrod = nil end else e.object:set_properties { textures = {"artifact_key.png"}, visual_size = vector.new(1,1,1) *0.88 } e.blackrod = minetest.add_entity(e.object:get_pos(), "display") e.blackrod:set_properties { visual = "mesh", mesh = "artifact_blackrod.obj", textures = {"artifact_blackrod.png"}, visual_size = vector.new(1,1,1) *10 } e.blackrod:set_attach(e.object, "RightArm", vector.new(0.25, -5.5, 0), vector.new(90,0,0)) end end artifact.sidekick.save() end include "key.lua" include "vix.lua" artifact.sidekick = setmetatable(minetest.deserialize(db:get("sidekick") or "return nil") or { pitch = 0, yaw = 0, character = "vix", }, { __index = { save = function() local ref = artifact.sidekick.ref -- Temporarily erase the entity so we can serialize properly. artifact.sidekick.ref = nil db:set_string("sidekick", minetest.serialize(artifact.sidekick)) artifact.sidekick.ref = ref end } }) minetest.register_entity(":artifact:sidekick", { initial_properties = { visual = "mesh", mesh = "artifact_character.gltf", textures = {"artifact_vix.png"}, visual_size = vector.new(1,1,1) *0.8, physical = true, collisionbox = { -0.3, 0,-0.3, 0.3, 1.77, 0.3 }, collide_with_objects = false }, _interact_marker_offset = function() return vector.new(0, 1.1,0) end, _interact_time = 0.4, on_activate = function(e, data) if data then extend(e, minetest.deserialize(data) or {}) end if artifact.sidekick.character == "key" then e.object:set_properties { textures = {"artifact_key.png"}, visual_size = vector.new(1,1,1) *0.88 } end -- Gravity. e.object:set_acceleration(vector.new(0,-9.81,0)) -- Make quite sure that we only ever have one of these. -- Remove this one because the first one we spawned is _probably_ the -- right one (e.g. if someone got unloaded, then loaded again after -- a replacement was spawned). if artifact.sidekick.ref then e.object:remove() return end artifact.sidekick.pos = e.object:get_pos() artifact.sidekick.ref = e end, on_deactivate = function(e) artifact.sidekick.ref = nil end, get_staticdata = function(e) return minetest.serialize{ cahracter = e.character } end, -- We need this to ensure that the stored position takes gravity into account. on_step = function(e) artifact.sidekick.pos = e.object:get_pos() end, on_interact = function(e, m) ns.swap_character(m) end })