artifact_one/mods/artifact_player/init.lua

315 lines
11 KiB
Lua

local ns = artifact
ns.players = {}
local db = minetest.get_mod_storage()
include "radial_menu.lua"
Player = setmetatable({
new = function(p)
local m = setmetatable({
object = p,
pitch = 0,
yaw = 0
}, {__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.hud = {}
m.poi = {}
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 yaw = p:get_look_horizontal()
local pitch = p:get_look_vertical()
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
local wi = p:get_wielded_item()
m.wielded_item = wi
if ctl.place and not m.ctl.place and wi:get_name() == "artifact:input" then
artifact.show_radial_menu(m, {
name = "construct",
"test",
"test2",
"test3",
"test4",
"test5"
})
elseif m._menu and not (ctl.place and wi:get_name() == "artifact:input") then
artifact.dismiss_radial_menu(m, "construct")
elseif m._menu then
local dx = m.yaw -yaw
local dy = m.pitch -pitch
if dx ~= 0 and dy ~= 0 then
m._menu.pos.x = m._menu.pos.x +dx *200
m._menu.pos.y = m._menu.pos.y -dy *200
local r = m._menu.pos:distance(vector.zero())
if r > 50 then
r = 50
m._menu.pos = m._menu.pos:normalize() *50
end
p:hud_change(m._menu.cursor._id, "offset", m._menu.pos)
if r > 20 then
local angle = minetest.dir_to_yaw(vector.new(m._menu.pos.x, 0, m._menu.pos.y):normalize())
local idx = math.floor((-angle +math.pi +(m._menu.step /2)) %(math.pi *2) /m._menu.step) +1
if m._menu.selected and m._menu.selected ~= idx then
m._menu[m._menu.selected]:animate{
scale = {
value = {x=0.7, y=0.7},
duration = 0.2
},
opacity = {
value = 128,
duration = 0.2
}
}
end
if m._menu.selected ~= idx and m._menu[idx] then
m._menu.selected = idx
m._menu[m._menu.selected]:animate{
scale = {
value = {x=1, y=1},
duration = 0.2
},
opacity = {
value = 256,
duration = 0.2
}
}
end
elseif m._menu.selected then
m._menu[m._menu.selected]:animate{
scale = {
value = {x=0.7, y=0.7},
duration = 0.2
},
opacity = {
value = 128,
duration = 0.2
}
}
m._menu.selected = nil
end
end
end
m.ctl = ctl
m.yaw = yaw
m.pitch = pitch
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)