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
|
||||
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
|
||||
**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
|
||||
|
||||
## 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)
|
||||
- **Mouse** — body + head look-at targets (same position, different smoothing)
|
||||
- **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
|
||||
|
||||
## Demo Walkthrough
|
||||
@@ -109,6 +111,17 @@ Only one rock is spawned per session.
|
||||
|
||||
## 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
|
||||
- **Backpack container**: `composition.define_template{id="backpack"}` now includes
|
||||
`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 +
|
||||
-- hardcoded furniture. Subterrain-style puppet control model:
|
||||
-- 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
|
||||
-- add/remove. Tree-check (CI-gated) verifies child placement in
|
||||
-- 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 camera = require("lib-core.camera")
|
||||
@@ -32,6 +37,8 @@ local interaction = require("lib-core.interaction")
|
||||
local composition = require("lib-core.composition")
|
||||
local actor = require("lib-core.actor")
|
||||
local inventory = require("lib-core.inventory-list")
|
||||
local panel = require("lib-core.panel")
|
||||
local inv_display = require("lib-core.inventory-list-display")
|
||||
|
||||
local M = {}
|
||||
|
||||
@@ -389,6 +396,43 @@ function M.init(ctx)
|
||||
register_pickup(state.rock)
|
||||
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.bind("walk_left", { "a" })
|
||||
input.bind("walk_right", { "d" })
|
||||
@@ -420,6 +464,10 @@ function M.update(ctx, dt)
|
||||
return
|
||||
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
|
||||
-- it to world at player position + 30px right offset, and re-registers
|
||||
-- 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).
|
||||
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 = {}
|
||||
for _, it in ipairs(items) do
|
||||
for _, it in ipairs(remaining_items) do
|
||||
table.insert(ids, tostring(it:get_property("composition.reg_id")))
|
||||
end
|
||||
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
|
||||
-- '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.set_target(actor.position(state.actor))
|
||||
@@ -572,6 +622,8 @@ function M.draw(ctx)
|
||||
ci_sprite_traced = true
|
||||
end
|
||||
end
|
||||
-- Inventory panel overlay (z-top: drawn after all world content).
|
||||
panel.render()
|
||||
end
|
||||
|
||||
-- Engine lifecycle globals (engine looks up by name; module-table is bridged).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"id": "vagrant-skeleton",
|
||||
"version": "0.8.0",
|
||||
"version": "0.9.0",
|
||||
"kind": "module",
|
||||
"api": "^0.1",
|
||||
"ci_frames": 60,
|
||||
@@ -17,6 +17,8 @@
|
||||
{"id": "lib-core.render", "version": "0.2.0"},
|
||||
{"id": "lib-core.composition", "version": "0.2.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.puppet", "version": "0.5.0"},
|
||||
{"id": "lib-core.interaction", "version": "0.1.0"},
|
||||
|
||||
Reference in New Issue
Block a user