feat(vagrant): Tab-Toggle inventory panel + right-click context menu
- lib-core.panel and lib-core.inventory-list-display added to deps (v0.1.0 each) - backpack-widget created in M.init with label-resolver returning "Rock" - Drop action registered: removes from backpack, relocates to player position, re-registers pickup trigger - Inspect action registered: prints reg_id via engine.print - M.update: panel.update(dt) + is_pausing() early-return added after quit_to_launcher check - interaction.update wrapped in panel.is_open() guard to block world triggers while panel is visible - M.draw: panel.render() added at z-top after CI traces - Q-drop (LIFO quick-drop via Q key) unchanged and parallel to panel Drop action
This commit is contained in:
19
README.md
19
README.md
@@ -8,9 +8,9 @@ callback, foot-body-orientation ("tactical twist"), scale-deformation walk
|
|||||||
cycle, and inheritance-decoupled foot sprites. End-to-end inventory pickup/drop
|
cycle, and inheritance-decoupled foot sprites. End-to-end inventory pickup/drop
|
||||||
demo: pick up a rock into a backpack container, drop it back into the world.
|
demo: pick up a rock into a backpack container, drop it back into the world.
|
||||||
|
|
||||||
**Version:** 0.8.0
|
**Version:** 0.9.0
|
||||||
**Module-ID:** vagrant-skeleton
|
**Module-ID:** vagrant-skeleton
|
||||||
**Requires:** lib-core.input >=0.4.0, lib-core.camera >=0.3.0, lib-core.render >=0.1.0, lib-core.maps >=0.1.2, lib-core.puppet >=0.4.4, lib-core.interaction >=0.1.0, lib-core.composition >=0.2.0, lib-core.inventory-list >=0.1.0, lib-asset.prototype-subterrain >=0.1.0
|
**Requires:** lib-core.input >=0.4.0, lib-core.camera >=0.3.0, lib-core.render >=0.1.0, lib-core.maps >=0.1.2, lib-core.puppet >=0.4.4, lib-core.interaction >=0.1.0, lib-core.composition >=0.2.0, lib-core.actor >=0.1.0, lib-core.inventory-list >=0.1.0, lib-core.panel >=0.1.0, lib-core.inventory-list-display >=0.1.0, lib-asset.prototype-subterrain >=0.1.0
|
||||||
**Tags:** test-chamber, puppet, walking-sim, interaction
|
**Tags:** test-chamber, puppet, walking-sim, interaction
|
||||||
|
|
||||||
## Topology
|
## Topology
|
||||||
@@ -24,7 +24,9 @@ demo: pick up a rock into a backpack container, drop it back into the world.
|
|||||||
- **Shift + WASD** — sprint (2x player speed + 2x walk-anim cadence)
|
- **Shift + WASD** — sprint (2x player speed + 2x walk-anim cadence)
|
||||||
- **Mouse** — body + head look-at targets (same position, different smoothing)
|
- **Mouse** — body + head look-at targets (same position, different smoothing)
|
||||||
- **E** — interact: if within range of the rock, picks it up into the backpack
|
- **E** — interact: if within range of the rock, picks it up into the backpack
|
||||||
- **Q** — drop: places the most-recently-added backpack item at player position (+30px right)
|
- **Q** — quick-drop (LIFO): places the most-recently-added backpack item at player position (+30px right)
|
||||||
|
- **Tab** — toggle inventory panel (Backpack contents)
|
||||||
|
- **Right-Click on item row** (while panel open): context menu with **Drop** / **Inspect** options
|
||||||
- **ESC** — return to launcher
|
- **ESC** — return to launcher
|
||||||
|
|
||||||
## Demo Walkthrough
|
## Demo Walkthrough
|
||||||
@@ -109,6 +111,17 @@ Only one rock is spawned per session.
|
|||||||
|
|
||||||
## CHANGELOG
|
## CHANGELOG
|
||||||
|
|
||||||
|
### v0.9.0 — inventory panel UI
|
||||||
|
- **Panel overlay**: `lib-core.panel` + `lib-core.inventory-list-display` wired in.
|
||||||
|
Tab key toggles a panel overlay showing backpack contents.
|
||||||
|
- **Context menu actions**: right-clicking an item row opens a context menu with
|
||||||
|
**Drop** (re-parents item to world at player position, re-registers pickup trigger)
|
||||||
|
and **Inspect** (prints `reg_id` to console).
|
||||||
|
- **Q-drop unchanged**: LIFO quick-drop via Q remains available in parallel to the
|
||||||
|
panel-based drop action.
|
||||||
|
- **Interaction guard**: `interaction.update` is suppressed while the panel is open
|
||||||
|
so world triggers don't fire during menu navigation.
|
||||||
|
|
||||||
### v0.8.0 — end-to-end inventory demo functional
|
### v0.8.0 — end-to-end inventory demo functional
|
||||||
- **Backpack container**: `composition.define_template{id="backpack"}` now includes
|
- **Backpack container**: `composition.define_template{id="backpack"}` now includes
|
||||||
`container={kind="list"}`. The composition v0.2 validator accepts this; the backpack
|
`container={kind="list"}`. The composition v0.2 validator accepts this; the backpack
|
||||||
|
|||||||
60
init.lua
60
init.lua
@@ -1,4 +1,4 @@
|
|||||||
-- sporel-module-vagrant-skeleton v0.8.0
|
-- sporel-module-vagrant-skeleton v0.9.0
|
||||||
-- Sprite-mode test-chamber: 13-bone humanoid puppet + sprite-tilemap +
|
-- Sprite-mode test-chamber: 13-bone humanoid puppet + sprite-tilemap +
|
||||||
-- hardcoded furniture. Subterrain-style puppet control model:
|
-- hardcoded furniture. Subterrain-style puppet control model:
|
||||||
-- multi-look-target (aim/soft), slerp body rotation, hip-static legs,
|
-- multi-look-target (aim/soft), slerp body rotation, hip-static legs,
|
||||||
@@ -22,6 +22,11 @@
|
|||||||
-- position. engine.print shows inventory count + item-IDs after each
|
-- position. engine.print shows inventory count + item-IDs after each
|
||||||
-- add/remove. Tree-check (CI-gated) verifies child placement in
|
-- add/remove. Tree-check (CI-gated) verifies child placement in
|
||||||
-- composition tree.
|
-- composition tree.
|
||||||
|
--
|
||||||
|
-- v0.9.0: Inventory panel UI wired in. Tab toggles a panel overlay
|
||||||
|
-- showing backpack contents. Right-click on an item row opens a context
|
||||||
|
-- menu with Drop and Inspect actions. Q-drop (LIFO quick-drop) remains
|
||||||
|
-- available in parallel.
|
||||||
|
|
||||||
local input = require("lib-core.input")
|
local input = require("lib-core.input")
|
||||||
local camera = require("lib-core.camera")
|
local camera = require("lib-core.camera")
|
||||||
@@ -32,6 +37,8 @@ local interaction = require("lib-core.interaction")
|
|||||||
local composition = require("lib-core.composition")
|
local composition = require("lib-core.composition")
|
||||||
local actor = require("lib-core.actor")
|
local actor = require("lib-core.actor")
|
||||||
local inventory = require("lib-core.inventory-list")
|
local inventory = require("lib-core.inventory-list")
|
||||||
|
local panel = require("lib-core.panel")
|
||||||
|
local inv_display = require("lib-core.inventory-list-display")
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
@@ -389,6 +396,43 @@ function M.init(ctx)
|
|||||||
register_pickup(state.rock)
|
register_pickup(state.rock)
|
||||||
if CI_FRAME_PERF then engine.print("vagrant: rock_spawned") end
|
if CI_FRAME_PERF then engine.print("vagrant: rock_spawned") end
|
||||||
|
|
||||||
|
-- Inventory-UI Setup
|
||||||
|
panel.set_theme{ panel_width_frac = 0.4, font_size_title = 20 }
|
||||||
|
|
||||||
|
local backpack_widget = inv_display.create(state.backpack, {
|
||||||
|
title = "Backpack",
|
||||||
|
widget_id = "backpack",
|
||||||
|
pause_on_open = false,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Module-side label-resolver (display lib's default returns "Item").
|
||||||
|
-- Vagrant currently has one item template (rock); hardcoded for v0.9.
|
||||||
|
inv_display.set_label_resolver(backpack_widget, function(item)
|
||||||
|
return "Rock"
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Drop action: knows world-reparenting + player position
|
||||||
|
inv_display.register_action(backpack_widget, "Drop", function(item, c)
|
||||||
|
inventory.remove(state.backpack, item)
|
||||||
|
local px = state.actor:get_property("position.x")
|
||||||
|
local py = state.actor:get_property("position.y")
|
||||||
|
item:set_property("position.x", px + 30)
|
||||||
|
item:set_property("position.y", py)
|
||||||
|
register_pickup(item)
|
||||||
|
c.close_menu()
|
||||||
|
if CI_FRAME_PERF then engine.print("vagrant: event=drop_via_menu") end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Inspect action: dumps reg_id to console
|
||||||
|
inv_display.register_action(backpack_widget, "Inspect", function(item, c)
|
||||||
|
engine.print(string.format("vagrant: inspect: reg_id=%s",
|
||||||
|
tostring(item:get_property("composition.reg_id"))))
|
||||||
|
c.close_menu()
|
||||||
|
end)
|
||||||
|
|
||||||
|
panel.register("backpack", backpack_widget)
|
||||||
|
panel.bind_default_trigger("tab", "backpack")
|
||||||
|
|
||||||
-- Input bindings.
|
-- Input bindings.
|
||||||
input.bind("walk_left", { "a" })
|
input.bind("walk_left", { "a" })
|
||||||
input.bind("walk_right", { "d" })
|
input.bind("walk_right", { "d" })
|
||||||
@@ -420,6 +464,10 @@ function M.update(ctx, dt)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Inventory panel input handling
|
||||||
|
panel.update(dt)
|
||||||
|
if panel.is_pausing() then return end
|
||||||
|
|
||||||
-- Drop: Q pops the most-recently-added item from backpack, relocates
|
-- Drop: Q pops the most-recently-added item from backpack, relocates
|
||||||
-- it to world at player position + 30px right offset, and re-registers
|
-- it to world at player position + 30px right offset, and re-registers
|
||||||
-- a pickup-trigger. inventory.remove restores the renderable tag.
|
-- a pickup-trigger. inventory.remove restores the renderable tag.
|
||||||
@@ -436,9 +484,9 @@ function M.update(ctx, dt)
|
|||||||
|
|
||||||
-- Inventory inspection trace (unconditional — user-facing demo output).
|
-- Inventory inspection trace (unconditional — user-facing demo output).
|
||||||
local count = inventory.count(state.backpack)
|
local count = inventory.count(state.backpack)
|
||||||
local items = inventory.contents(state.backpack)
|
local remaining_items = inventory.contents(state.backpack) -- re-read post-remove
|
||||||
local ids = {}
|
local ids = {}
|
||||||
for _, it in ipairs(items) do
|
for _, it in ipairs(remaining_items) do
|
||||||
table.insert(ids, tostring(it:get_property("composition.reg_id")))
|
table.insert(ids, tostring(it:get_property("composition.reg_id")))
|
||||||
end
|
end
|
||||||
engine.print(string.format("vagrant: backpack count=%d items=[%s]",
|
engine.print(string.format("vagrant: backpack count=%d items=[%s]",
|
||||||
@@ -525,7 +573,9 @@ function M.update(ctx, dt)
|
|||||||
|
|
||||||
-- Interaction: dispatches the nearest matching proximity-trigger when
|
-- Interaction: dispatches the nearest matching proximity-trigger when
|
||||||
-- 'interact' was pressed this frame. Uses actor.position as anchor.
|
-- 'interact' was pressed this frame. Uses actor.position as anchor.
|
||||||
interaction.update(actor.position(state.actor))
|
if not panel.is_open() then
|
||||||
|
interaction.update(actor.position(state.actor))
|
||||||
|
end
|
||||||
|
|
||||||
-- Camera follows actor position each frame.
|
-- Camera follows actor position each frame.
|
||||||
camera.set_target(actor.position(state.actor))
|
camera.set_target(actor.position(state.actor))
|
||||||
@@ -572,6 +622,8 @@ function M.draw(ctx)
|
|||||||
ci_sprite_traced = true
|
ci_sprite_traced = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-- Inventory panel overlay (z-top: drawn after all world content).
|
||||||
|
panel.render()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Engine lifecycle globals (engine looks up by name; module-table is bridged).
|
-- Engine lifecycle globals (engine looks up by name; module-table is bridged).
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"id": "vagrant-skeleton",
|
"id": "vagrant-skeleton",
|
||||||
"version": "0.8.0",
|
"version": "0.9.0",
|
||||||
"kind": "module",
|
"kind": "module",
|
||||||
"api": "^0.1",
|
"api": "^0.1",
|
||||||
"ci_frames": 60,
|
"ci_frames": 60,
|
||||||
@@ -17,6 +17,8 @@
|
|||||||
{"id": "lib-core.render", "version": "0.2.0"},
|
{"id": "lib-core.render", "version": "0.2.0"},
|
||||||
{"id": "lib-core.composition", "version": "0.2.0"},
|
{"id": "lib-core.composition", "version": "0.2.0"},
|
||||||
{"id": "lib-core.actor", "version": "0.1.0"},
|
{"id": "lib-core.actor", "version": "0.1.0"},
|
||||||
|
{"id": "lib-core.panel", "version": "0.1.0"},
|
||||||
|
{"id": "lib-core.inventory-list-display", "version": "0.1.0"},
|
||||||
{"id": "lib-core.maps","version":"0.5.7"},
|
{"id": "lib-core.maps","version":"0.5.7"},
|
||||||
{"id": "lib-core.puppet", "version": "0.5.0"},
|
{"id": "lib-core.puppet", "version": "0.5.0"},
|
||||||
{"id": "lib-core.interaction", "version": "0.1.0"},
|
{"id": "lib-core.interaction", "version": "0.1.0"},
|
||||||
|
|||||||
Reference in New Issue
Block a user