Add multi-signal doors, basic device deployment, and a target trigger.

This commit is contained in:
Signal 2025-11-17 03:04:16 -05:00
parent 1b2199705b
commit 3bf1d5c6a0
24 changed files with 656 additions and 74 deletions

View file

@ -16,6 +16,7 @@ Player = setmetatable({
m.name = p:get_player_name()
m.meta = p:get_meta()
m.character = m.meta:get("character") or "key"
m.spawn_point = m.meta:get("spawnpoint") or artifact.origin
m.inv = p:get_inventory()
m.inv:set_stack("main", 1, ItemStack("input_"..m.character))
@ -125,7 +126,8 @@ Player = setmetatable({
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
-- We should ignore all objects when placing a grabbed node.
if x and x.type == "object" and not m._grabbed_item then
local e = x.ref:get_luaentity()
-- Ignore players.
if e then
@ -231,6 +233,34 @@ Player = setmetatable({
rotation = {vec = vector.new(0,yaw -m.rot,0), interpolation = 0.1, absolute = true}
})
-- Handle grabbed devices. This trumps other input handling like the radial menu and on_interact.
if m._grabbed_item then
m._grabbed_item:move_to(m.pos +(dir *2))
if ctl.place and m.pointed_node then
m._grabbed_item:move_to(m.pointed_node.above)
m._grabbed_item = nil
-- This should be set dynamically by whatever function put us into the grabbing
-- state, and accordingly should only be valid for the duration of that state.
if m._on_ungrab then
m._on_ungrab()
m._on_ungrab = nil
end
end
-- This code is duplicated from the bottom... but since the
-- only cleaner alternative is goto, I decided to support PUC Lua.
if m.next_regen and time -m.next_regen >= 0 then
m.object:set_hp(m.object:get_hp() +1)
end
m.ctl = ctl
m.yaw = yaw
m.pitch = pitch
m.dir = dir
return
end
-- MARK: Progressive interaction
if ctl.place and m.ctl.place and m.pointed_obj and m.pointed_obj.on_interact and not m.pointed_obj._no_interact then
@ -268,7 +298,7 @@ Player = setmetatable({
-- MARK: Radial menu handling
-- This should only work once we have Vix, since we can't use it without her.
if state >= artifact.story.states.main and ctl.place and not m.ctl.place and wi:get_name():find "artifact:input" and (not m.pointed_obj or m.pointed_obj._no_interact) then
if state >= artifact.story.states.main and ctl.place and not m.ctl.place and wi:get_name():find "artifact:input" and (not m.pointed_obj or not m.pointed_obj.on_interact or m.pointed_obj._no_interact) then
artifact.show_radial_menu(m, {
name = "construct",
"test",
@ -277,7 +307,14 @@ Player = setmetatable({
"test4",
"test5"
})
elseif m._menu and not (ctl.place and wi:get_name():find "artifact:input") or (m.pointed_obj and not m.pointed_obj._no_interact) then
elseif m._menu and not (ctl.place and wi:get_name():find "artifact:input") or (m._menu and m.pointed_obj and m.pointed_obj.on_interact and not m.pointed_obj._no_interact) then
local sel = m._menu[m._menu.selected]
if sel then
local choice = sel.item
if choice == "test" then
artifact.summon_device(m, "block")
end
end
artifact.dismiss_radial_menu(m, "construct")
elseif m._menu then
local dx = m.yaw -yaw
@ -374,12 +411,25 @@ Player = setmetatable({
p:hud_set_hotbar_image("[combine:"..(21 *slots +1).."x22"..list)
p:hud_set_hotbar_selected_image("artifact_hotbar_selected_bg.png")
end,
set_spawnpoint = function(m, pos)
m.spawn_point = pos
m.meta:set_string("spawnpoint", pos:to_string())
end
}, {
__call = function(_, ...)
return Player.new(...)
end
})
-- Override respawning, so we can save progress.
minetest.register_on_respawnplayer(function(p)
local m = artifact.players[p:get_player_name()]
if m.spawn_point then
p:set_pos(m.spawn_point)
return true
end
end)
-- Mirror the player's HP in our custom HUD.
-- (We need a custom HUD so that we can change its appearance dynamically.)
minetest.register_on_player_hpchange(function(p, delta)
@ -403,8 +453,8 @@ function artifact.register_input(name)
description = "",
paramtype = "light",
drawtype = "mesh",
mesh = "artifact_hand.gltf",
tiles = {"artifact_"..name..".png"},
mesh = name == "key" and "artifact_hand_key.gltf" or "artifact_hand.gltf",
tiles = name == "key" and {"artifact_blackrod.png"} or {"artifact_"..name..".png", "artifact_blackrod.png"},
use_texture_alpha = "opaque",
visual_scale = 1,
wield_scale = vector.new(2,2,2),
@ -423,6 +473,11 @@ function artifact.register_input(name)
end,
on_use = function(s, p)
local m = artifact.players[p:get_player_name()]
if m._grabbed_item then return end
if m.pointed_obj and m.pointed_obj._grabbable then
artifact.grab_device(m, m.pointed_obj)
return
end
if m.character == "vix" then
artifact.do_shoot(m)
else
@ -434,6 +489,11 @@ end
artifact.register_input "key"
artifact.register_input "vix"
-- Apparently the hand range is applied very briefly when switching items.
if not artifact.debug then
minetest.override_item("", {range = 0})
end
minetest.register_globalstep(function()
for _, m in pairs(artifact.players) do

View file

@ -18,6 +18,7 @@ function ns.show_radial_menu(m, menu)
local angle = m._menu.step *(i -1) -math.pi
local el = artifact.hud_add(m, {
name = menu.name.."_"..i,
item = x,
type = "image",
pos = {x=0.5,y=0.5},
scale = {x=0.1,y=0.1},