246 lines
7.9 KiB
Lua
246 lines
7.9 KiB
Lua
|
|
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))
|
|
if m.healthbar then
|
|
m.object:hud_change(m.healthbar, "text", "artifact_heart_vix.png")
|
|
end
|
|
if m.blackrod then
|
|
m.blackrod:remove()
|
|
m.blackrod = nil
|
|
end
|
|
end
|
|
|
|
function ns._swap_character(m)
|
|
-- If Key was pointing at something Vix shouldn't be able to interact with,
|
|
-- but Vix is also pointing at it, then remove the interaction marker since
|
|
-- it would be misleading.
|
|
if m.pointed_obj and m.interaction_marker and (not m.pointed_obj._can_interact or m.pointed_obj:_can_interact(m)) then
|
|
m.object:hud_remove(m.interaction_marker)
|
|
m.interaction_marker = nil
|
|
m.interaction_start = nil
|
|
end
|
|
|
|
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
|
|
|
|
-- If Vix was pointing at something whackable, and the player then switches
|
|
-- to Key who is pointing at the same thing, we should show the whack icon.
|
|
if m.character == "key" and m.pointed_node and minetest.registered_nodes[m.pointed_node.node_under.name].groups.whackable then
|
|
m.whack_hud = m.object:hud_add {
|
|
type = "image_waypoint",
|
|
world_pos = m.pointed_node.under,
|
|
scale = {x=3,y=3},
|
|
text = "artifact_icon_whack.png"
|
|
}
|
|
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
|
|
|
|
function ns.swap_character(m)
|
|
if m._swapping_character then return end
|
|
if artifact.sidekick.ref then
|
|
artifact.sidekick.ref._no_interact = true
|
|
end
|
|
m._swapping_character = true
|
|
local fade = artifact.hud_add(m, {
|
|
type = "image",
|
|
pos = {x=0.5,y=1},
|
|
offset = {x=0,y=0},
|
|
align = {x=0,y=0},
|
|
scale = {x=50000,y=50000},
|
|
opacity = 0,
|
|
image = "[fill:1x1:0,0:#000",
|
|
})
|
|
fade:animate {
|
|
opacity = {
|
|
value = 256,
|
|
duration = 0.3
|
|
}
|
|
}
|
|
artifact.play_sound {
|
|
name = "artifact_character_swap",
|
|
to_player = m.name
|
|
}
|
|
minetest.after(0.3, function()
|
|
ns._swap_character(m)
|
|
fade:animate {
|
|
opacity = {
|
|
value = 0,
|
|
duration = 0.3
|
|
}
|
|
}
|
|
minetest.after(0.3, function()
|
|
m._swapping_character = nil
|
|
if artifact.sidekick.ref then
|
|
artifact.sidekick.ref._no_interact = nil
|
|
end
|
|
end)
|
|
end)
|
|
|
|
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
|
|
})
|
|
|