Add color swappers, color swapping, and color targets.

This commit is contained in:
Signal 2025-11-19 11:43:24 -05:00
parent 9acd605c86
commit 5fd67703c0
34 changed files with 688 additions and 29 deletions

View file

@ -17,6 +17,7 @@ Player = setmetatable({
m.meta = p:get_meta()
m.character = m.meta:get("character") or "key"
m.spawn_point = m.meta:get("spawnpoint") or artifact.origin
m.color = m.meta:get("color")
m.inv = p:get_inventory()
m.inv:set_stack("main", 1, ItemStack("input_"..m.character))
@ -82,6 +83,10 @@ Player = setmetatable({
-- No unreasonable FOV settings here.
p:set_fov(72)
p:set_fov(0, true, 0)
-- Tell raycast collisions that we're a player.
p:set_armor_groups(extend(p:get_armor_groups(), {player = 1}))
m.hud = {}
m.poi = {}
@ -142,7 +147,7 @@ Player = setmetatable({
m.interaction_start = nil
end
end
if e.on_interact and not e._no_interact and (not names_match or names_match and not m.interaction_marker) then
if e.on_interact and not e._no_interact and (not names_match or names_match and not m.interaction_marker) and (not e._can_interact or e:_can_interact(m)) then
if m.interaction_marker then m.object:hud_remove(m.interaction_marker) end
local dst = e.object:get_pos()
if e._interact_marker_offset then dst = dst +e:_interact_marker_offset() end
@ -204,13 +209,25 @@ Player = setmetatable({
p:set_physics_override{
speed = 1.5
}
p:set_fov(1.1, true, 0.2)
else
if p:get_animation().y ~= 1 then p:set_animation({x=0, y=1}, 1.5, 0.2, true) end
p:set_physics_override{
speed = 1
}
p:set_fov(0, true, 0.2)
end
else
-- We can't call this unconditionally because during the first couple
-- globalsteps, doing so will heavily distort the player's FOV for
-- some reason. Since `m.moving` is never set to true until the player
-- starts sprinting, we can sidestep this issue fairly trivially.
if m.moving then
p:set_physics_override{
speed = 1
}
p:set_fov(0, true, 0.2)
end
m.moving = false
if p:get_animation().y ~= 0 then p:set_animation({x=0, y=0}) end
end
@ -263,7 +280,7 @@ Player = setmetatable({
-- 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
if ctl.place and m.ctl.place and m.pointed_obj and m.pointed_obj.on_interact and not m.pointed_obj._no_interact and (not m.pointed_obj._can_interact or m.pointed_obj:_can_interact(m)) then
if not m.interaction_start then
m.interaction_start = time
else
@ -284,7 +301,7 @@ Player = setmetatable({
m.object:hud_change(m.interaction_marker, "text", "artifact_rmb_25.png")
end
end
elseif not ctl.place and m.interaction_start and (not m.pointed_obj or not m.pointed_obj._no_interact) then
elseif not ctl.place and m.interaction_start and (not m.pointed_obj or not m.pointed_obj._no_interact or m.pointed_obj._can_interact and m.pointed_obj:_can_interact(m)) then
m.interaction_start = nil
if m.interaction_marker then
m.object:hud_change(m.interaction_marker, "text", "artifact_rmb.png")
@ -386,12 +403,72 @@ Player = setmetatable({
set_character = function(m, to)
m.character = to
m.meta:set_string("character", to)
if to == "vix" then
if m.color_hud then
m.object:hud_remove(m.color_hud)
m.color_hud = nil
end
else
if m.color and not m.color_hud then
m.color_hud = m.object:hud_add {
type = "image",
position = {x=0.5,y=1},
offset = {x=0,y=0},
alignment = {x=0,y=-1},
scale = {x=500,y=5},
text = "[fill:1x1:0,0:"..artifact.colors[m.color],
}
end
end
end,
set_color = function(m, color)
if artifact.debug or artifact.story.get_state() > artifact.story.states.pre_vix and m.character == "key" then
m.color = color
m.meta:set_string("color", color or "")
if m.color_hud then
m.object:hud_remove(m.color_hud)
end
-- If we cleared the color by passing nil, there's no need to animate or re-add the HUD.
if not color then return end
m.color_hud = m.object:hud_add {
type = "image",
position = {x=0.5,y=1},
offset = {x=0,y=0},
alignment = {x=0,y=-1},
scale = {x=500,y=5},
text = "[fill:1x1:0,0:"..artifact.colors[m.color],
}
local el = artifact.hud_add(m, {
type = "image",
pos = {x=0.5,y=0.5},
scale = {x=10000,y=10000},
opacity = 0,
image = "[fill:1x1:"..artifact.colors[m.color]
})
el:animate {
opacity = {
value = 25,
duration = 0.3
}
}
minetest.after(0.3, function()
el:animate {
opacity = {
value = 0,
duration = 0.3
}
}
minetest.after(0.3, function()
el:remove(m)
end)
end)
end
end,
add_health_bar = function(m)
m.healthbar = m.object:hud_add {
type = "statbar",
position = {x=0.5,y=1},
offset = {x=-27 *5,y=artifact.debug and -96 or -40},
offset = {x=-27 *5,y=artifact.debug and -96 or -42},
scale = {x=4,y=4},
alignment = {x=-1, y=-1},
size = {x=27,y=27},
@ -464,10 +541,27 @@ function artifact.register_input(name)
end,
drop = "",
range = 0,
pointabilities = {
nodes = {
["group:everything"] = false
},
objects = {
["group:immortal"] = false,
["group:fleshy"] = false
}
},
on_drop = function(s, p, pos)
local m = artifact.players[p:get_player_name()]
if artifact.debug or artifact.story.get_state() > artifact.story.states.pre_vix then
if not m._swapping_character and (artifact.debug or artifact.story.get_state() > artifact.story.states.pre_vix) then
artifact.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
end
return s
end,