feat: v0.12.0 Workbench-Integration
Workbench-Entity bei (350, 380) als Crafting-Context-Erweiterung.
Right-Click oeffnet Workbench-Crafting-Panel + Workbench-Inventory.
Crafting nutzt Multi-Source-Locale {backpack, workbench} mit sink
= workbench; Take-Action verschiebt vom Workbench-Inventory zum
Backpack. C-Key Backpack-Crafting bleibt unveraendert via Bw-
Compat-Shim in crafting v0.2.0.
Deps: crafting 0.1.0 -> 0.2.0, crafting-display 0.1.0 -> 0.2.0.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
65
README.md
65
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.11.0
|
||||
**Version:** 0.12.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.3.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-core.notify >=0.1.0, lib-core.notify-display >=0.1.0, lib-core.world-overlay >=0.1.0, lib-core.crafting >=0.1.0, lib-core.crafting-display >=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.3.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-core.notify >=0.1.0, lib-core.notify-display >=0.1.0, lib-core.world-overlay >=0.1.0, lib-core.crafting >=0.2.0, lib-core.crafting-display >=0.2.0, lib-asset.prototype-subterrain >=0.1.0
|
||||
**Tags:** test-chamber, puppet, walking-sim, interaction
|
||||
|
||||
## Topology
|
||||
@@ -26,19 +26,21 @@ demo: pick up a rock into a backpack container, drop it back into the world.
|
||||
- **E** — interact: if within range of the rock or stick, picks it up into the backpack
|
||||
- **Q** — quick-drop (LIFO): places the most-recently-added backpack item at player position (+30px right)
|
||||
- **Tab** — toggle inventory panel (Backpack contents)
|
||||
- **C** — toggle Crafting panel (lists known recipes; availability dimmed by inventory)
|
||||
- **Right-Click on item row** (inventory panel): context menu with **Drop** / **Inspect**
|
||||
- **C** — toggle Backpack-Crafting panel (lists known recipes; availability dimmed by inventory)
|
||||
- **Right-Click on Workbench** (within range) — opens Workbench-Crafting + Workbench-Inventory panels (Phase D v0.2)
|
||||
- **Right-Click on item row** (inventory panel): context menu with **Drop** / **Inspect** (Backpack) or **Take** / **Inspect** (Workbench)
|
||||
- **Right-Click on recipe row** (crafting panel): context menu with **Craft** / **Inspect**
|
||||
- **L** — toggle game-log (chronological list of all events)
|
||||
- **Right-Click on item row → Inspect** — opens a modal Item Details panel (instead of console-only output)
|
||||
- **Pickup (E)** — shows "+1 <name>" floating above the player + toast at top-right + log entry
|
||||
- **Drop (right-click on item → Drop, or Q for LIFO quick-drop)** — toast at top-right + log entry
|
||||
- **Craft (right-click on recipe → Craft)** — consumes inputs from backpack, adds output, posts a success/failure toast
|
||||
- **ESC** — return to launcher
|
||||
- **Craft (right-click on recipe → Craft)** — consumes inputs from current locale, adds output, posts a success/failure toast
|
||||
- **Take (right-click on Workbench-item → Take)** — moves item from Workbench → Backpack + toast
|
||||
- **ESC** — close any open panel; if no panel is open, return to launcher
|
||||
|
||||
## Demo Walkthrough
|
||||
|
||||
The world contains four notable entities at startup:
|
||||
The world contains five notable entities at startup:
|
||||
|
||||
1. **Player** — spawns at (320, 240), controlled via WASD + mouse.
|
||||
2. **Backpack** — a visible sprite at (350, 400). Acts as a container (kind="list").
|
||||
@@ -48,6 +50,9 @@ The world contains four notable entities at startup:
|
||||
4. **Stick** — a placeholder pickup-item at (190, 400), 160px to the left of the backpack.
|
||||
Re-uses the `slot_04_straight` blob_rect_stone tile for its visual (Phase C-Q10
|
||||
pragmatic resolution — echtes Stick-Sprite folgt mit dem ersten atlas-baker-decals-Slice).
|
||||
5. **Workbench** — a crafting bench at (350, 380), just above the backpack. Container
|
||||
(kind="list"); placeholder visual re-uses the `slot_07_tee_full` blob_rect_stone tile.
|
||||
Right-Click within range opens Workbench-Crafting + Workbench-Inventory panels.
|
||||
|
||||
**Pickup flow:**
|
||||
- Walk toward the rock (it sits to the left of the backpack).
|
||||
@@ -67,6 +72,21 @@ The world contains four notable entities at startup:
|
||||
**Multiple pickups:** Each E → Q → E cycle moves the same rock in and out.
|
||||
Only one rock is spawned per session.
|
||||
|
||||
**Workbench flow (Phase D v0.2):**
|
||||
- Pick up rock + stick into the backpack (E on each).
|
||||
- Walk to the Workbench (just above the Backpack at (350, 380)) and
|
||||
right-click within 40px range.
|
||||
- Two panels open simultaneously (Workbench-Crafting + Workbench-Inventory).
|
||||
Because `lib-core.panel` v0.1 is single-active, only one panel is visible
|
||||
at a time — closing it (X) reveals the other.
|
||||
- Right-click on a recipe row (e.g. **Stone Pick**) → context menu with
|
||||
**Craft** + **Inspect**. Click **Craft** → crafted item lands in
|
||||
**Workbench-Inventory** (NOT Backpack).
|
||||
- Open Workbench-Inventory, right-click on the crafted item → **Take** moves
|
||||
it to the Backpack; a "Took <item>" toast appears.
|
||||
- Crafting inputs are aggregated from `{backpack, workbench}` (drain order:
|
||||
backpack first, then workbench).
|
||||
|
||||
## Demonstrates
|
||||
|
||||
- lib-core.puppet v0.4.3 integration:
|
||||
@@ -121,6 +141,37 @@ Only one rock is spawned per session.
|
||||
|
||||
## CHANGELOG
|
||||
|
||||
### v0.12.0 — Workbench
|
||||
|
||||
- **New: Workbench entity** in the world at (350, 380) — `composition.define_template`
|
||||
with `container = {kind="list"}`, tagged `renderable`, `container`, `workbench`,
|
||||
`interactable`. Placeholder visual re-uses the `slot_07_tee_full`
|
||||
blob_rect_stone tile (visually distinct from rock/stick/rock_pick/rock_pile).
|
||||
- **New: Right-Click on Workbench** opens two panels:
|
||||
- **Workbench Crafting** — recipes are still listed by `lib-core.crafting`,
|
||||
but availability + craft-action use a **multi-source locale**
|
||||
`{sources={backpack, workbench}, sink=workbench}` (crafting v0.2.0 API).
|
||||
Inputs are drained greedy in source-array order (backpack first, then
|
||||
workbench). Output lands in the Workbench, not the Backpack.
|
||||
- **Workbench Inventory** — workbench contents with **Take** + **Inspect**
|
||||
actions on right-click. Take moves the item to the Backpack and fires
|
||||
a `transfer` event-toast.
|
||||
- **Still works**: C-key Backpack-Crafting (basic recipes still craftable
|
||||
with Backpack-only via the bw-compat shim in crafting v0.2.0). The
|
||||
Phase-C C-key callsite passes `state.backpack` as a bare entity-handle;
|
||||
crafting v0.2.0's resolve_locale wraps that as `{sources={backpack},
|
||||
sink=backpack}` transparently.
|
||||
- **Caveat (panel-lib v0.1 single-active)**: `lib-core.panel` v0.1.1
|
||||
enforces one active widget. Opening both Workbench panels means only
|
||||
the second (`workbench_inv`) is visible until the player closes it (X);
|
||||
closing it reveals `workbench_crafting`. Proper side-by-side stacking
|
||||
is a future panel-lib slice.
|
||||
- **Deps**: crafting 0.1.0 → 0.2.0, crafting-display 0.1.0 → 0.2.0.
|
||||
- **Notify events-Channel**: filter um `"transfer"` erweitert, damit
|
||||
Take-Action-Toasts im events-channel landen.
|
||||
- **Input binding**: `"use"` bound to `mouse_right` (mirrors the lib-core.input
|
||||
v0.3.0 unified key+mouse binding).
|
||||
|
||||
### v0.11.0 — crafting integration
|
||||
|
||||
- **New: stick pickup-item** neben rock am Boden (Position 190,400 — 160px links
|
||||
|
||||
256
init.lua
256
init.lua
@@ -1,4 +1,4 @@
|
||||
-- sporel-module-vagrant-skeleton v0.11.0
|
||||
-- sporel-module-vagrant-skeleton v0.12.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,
|
||||
@@ -49,6 +49,17 @@
|
||||
-- Right-click a recipe row → Craft + Inspect actions; Craft consumes
|
||||
-- inputs from the backpack and adds the output; Inspect routes
|
||||
-- recipe details to a notify-display detail-channel.
|
||||
--
|
||||
-- v0.12.0: Workbench-Entity added at (350, 380). Right-Click on the
|
||||
-- workbench opens a Workbench-Crafting panel + Workbench-Inventory
|
||||
-- panel. The crafting panel uses a multi-source locale {backpack,
|
||||
-- workbench} via crafting v0.2.0's locale-factory API; output lands
|
||||
-- in the workbench. Take-action in workbench-inv moves an item back
|
||||
-- to the backpack. C-key Backpack-Crafting remains via the bw-compat
|
||||
-- shim in crafting v0.2.0 (Form-1 bare entity-handle stays valid).
|
||||
-- Panel-lib v0.1 is single-active so opening both panels lets
|
||||
-- workbench_inv win; user can close it (X) to reveal workbench_crafting
|
||||
-- below — Gate-2 walkthrough documents the flow.
|
||||
|
||||
local input = require("lib-core.input")
|
||||
local camera = require("lib-core.camera")
|
||||
@@ -196,7 +207,10 @@ local state = {
|
||||
backpack = nil, -- composition-entity, created in M.init after atlas load
|
||||
rock = nil, -- composition-entity (item), created in M.init after blob_rect_stone load
|
||||
stick = nil, -- composition-entity (item), placeholder for crafting demo
|
||||
crafting_widget = nil, -- crafting-display widget handle
|
||||
workbench = nil, -- composition-entity (container), Phase D Workbench
|
||||
crafting_widget = nil, -- crafting-display widget handle (Backpack)
|
||||
workbench_crafting_widget = nil, -- crafting-display widget handle (Workbench-context)
|
||||
workbench_inv_widget = nil, -- inventory-list-display widget handle (Workbench-Inv)
|
||||
-- Subterrain-style controller state:
|
||||
walk_anim_current = nil, -- "walk_fwd_lower" / "walk_back_lower" / etc. (nil = idle_lower)
|
||||
lower_control_rot_deg = 0,
|
||||
@@ -276,6 +290,59 @@ local function register_pickup(item)
|
||||
end)
|
||||
end
|
||||
|
||||
-- register_interaction_use(entity)
|
||||
-- Phase D Workbench: registers a right-click ("use") interaction-trigger at
|
||||
-- the entity's current world position. When the player fires "use" within
|
||||
-- INTERACTION_RANGE, the callback opens both the Workbench-Crafting and
|
||||
-- Workbench-Inventory panels.
|
||||
--
|
||||
-- lib-core.interaction v0.1.0 is XY-based (not entity-bound); the trigger
|
||||
-- snapshots the position at registration time. Workbench is static in v0.12
|
||||
-- so a single registration suffices. Action-name "use" is bound to
|
||||
-- mouse_right in M.init's input.bind block.
|
||||
--
|
||||
-- Note on dual-panel-open: lib-core.panel v0.1.1 enforces a single active
|
||||
-- widget. Calling panel.open twice means the second call wins
|
||||
-- (workbench_inv shows on top; workbench_crafting is hidden until the
|
||||
-- player closes the inv panel via X). This matches the spec §4.4 note that
|
||||
-- "v0.2 default ist whatever panel-lib default" — proper side-by-side
|
||||
-- layout is a panel-lib v0.2 task, out of scope for D.2.
|
||||
local function register_interaction_use(entity)
|
||||
local x = entity:get_property("position.x")
|
||||
local y = entity:get_property("position.y")
|
||||
interaction.register(x, y, INTERACTION_RANGE, "use", function()
|
||||
panel.open("workbench_crafting")
|
||||
panel.open("workbench_inv")
|
||||
if CI_FRAME_PERF then engine.print("vagrant: event=workbench_use") end
|
||||
end)
|
||||
end
|
||||
|
||||
-- discover_sources(workbench) → array of container entities
|
||||
-- Phase D v0.2 source-discovery policy: Player-Backpack is always a source
|
||||
-- (independent of workbench position; player carries it everywhere), and
|
||||
-- the workbench itself is always a source. Forward-compat stub below
|
||||
-- documents the intended adjacent-container scan (deferred to a future
|
||||
-- slice with multi-container demos).
|
||||
local function discover_sources(workbench)
|
||||
local sources = { state.backpack, workbench }
|
||||
-- Forward-compat stub for adjacent-container scan (deferred):
|
||||
-- for _, ent in ipairs(composition.list_by_tag("container")) do
|
||||
-- if ent ~= workbench and ent ~= state.backpack then
|
||||
-- local wx = workbench:get_property("position.x")
|
||||
-- local wy = workbench:get_property("position.y")
|
||||
-- local ex = ent:get_property("position.x")
|
||||
-- local ey = ent:get_property("position.y")
|
||||
-- if ex and ey and wx and wy then
|
||||
-- local dx, dy = math.abs(ex - wx), math.abs(ey - wy)
|
||||
-- if math.max(dx, dy) <= 1 then -- Chebyshev radius 1
|
||||
-- sources[#sources + 1] = ent
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
return sources
|
||||
end
|
||||
|
||||
-- Signed angle between two 2D vectors (in degrees, range [-180, 180]).
|
||||
-- Sporel uses Y-down screen-coords. Substrate's math assumes Y-up; the cross
|
||||
-- component is flipped so "positive num = move-direction is CCW from body-fwd
|
||||
@@ -511,6 +578,34 @@ function M.init(ctx)
|
||||
tags = {"renderable", "item"},
|
||||
}
|
||||
|
||||
-- Workbench-Template (Phase D v0.2). Container-kind=list so it can
|
||||
-- accept items via inventory.add (crafting output landing spot).
|
||||
-- Placeholder visual re-uses the blob_rect_stone atlas with
|
||||
-- slot_07_tee_full — visually distinct from the slots already taken
|
||||
-- (00=rock, 04=stick, 05=rock_pick, 13=rock_pile). slot_07 is a
|
||||
-- filled T-junction shape — dense + asymmetric, reads as a sturdy
|
||||
-- piece of furniture against the rest of the in-world items. A
|
||||
-- proper sprite would come from atlas-baker-decals in a future slice.
|
||||
local workbench_uv = stone_uvs["slot_07_tee_full"]
|
||||
composition.define_template{
|
||||
id = "workbench",
|
||||
properties = {
|
||||
stack_mode = "individual",
|
||||
name = "Workbench",
|
||||
description = "A crafting bench.",
|
||||
weight = 50,
|
||||
volume = 100,
|
||||
["composition.wood"] = 0.7,
|
||||
["composition.stone"] = 0.3,
|
||||
sprite_atlas = stone_atlas_png,
|
||||
sprite_uv = {x = workbench_uv.x, y = workbench_uv.y,
|
||||
w = workbench_uv.w, h = workbench_uv.h},
|
||||
position = {x = 0, y = 0},
|
||||
},
|
||||
container = { kind = "list" },
|
||||
tags = { "renderable", "container", "workbench", "interactable" },
|
||||
}
|
||||
|
||||
-- Spawn Rock-Entity 80px to the left of the backpack so it sits in a
|
||||
-- distinct position: visible to the player on first load, not overlapping
|
||||
-- the backpack, reachable by walking left from spawn.
|
||||
@@ -546,6 +641,18 @@ function M.init(ctx)
|
||||
register_pickup(state.stick)
|
||||
if CI_FRAME_PERF then engine.print("vagrant: stick_spawned") end
|
||||
|
||||
-- Workbench spawn (Phase D v0.2). Placed at (350, 380) — 20px above
|
||||
-- the backpack (at 350, 400) so they are visually distinct but still
|
||||
-- on the visible-on-spawn area. register_interaction_use registers a
|
||||
-- right-click ("use") proximity-trigger at the workbench position.
|
||||
state.workbench = composition.create{
|
||||
template = "workbench",
|
||||
properties = {
|
||||
position = {x = 350, y = 380},
|
||||
},
|
||||
}
|
||||
if CI_FRAME_PERF then engine.print("vagrant: workbench_spawned") end
|
||||
|
||||
-- ====== Crafting Recipes ======
|
||||
crafting.define_recipe{
|
||||
id = "rock_pick",
|
||||
@@ -692,12 +799,154 @@ function M.init(ctx)
|
||||
panel.register("crafting", state.crafting_widget)
|
||||
panel.bind_default_trigger("c", "crafting")
|
||||
|
||||
-- ====== Workbench Crafting Widget (Phase D v0.2) ======
|
||||
-- Locale-Factory returns Form-2 locale {sources, sink}: sources come
|
||||
-- from discover_sources (player-backpack + workbench), sink is the
|
||||
-- workbench. Crafting v0.2.0 greedy-drains sources in array-order
|
||||
-- (backpack first, then workbench) before adding the output to sink.
|
||||
state.workbench_crafting_widget = crafting_display.create(
|
||||
function()
|
||||
return {
|
||||
sources = discover_sources(state.workbench),
|
||||
sink = state.workbench,
|
||||
}
|
||||
end,
|
||||
{
|
||||
title = "Workbench Crafting",
|
||||
widget_id = "workbench_crafting",
|
||||
pause_on_open = false,
|
||||
ctx_factory = function()
|
||||
return { actor = state.actor, at_workbench = true }
|
||||
end,
|
||||
})
|
||||
|
||||
-- Craft action: invokes crafting.craft on the resolved locale (multi-
|
||||
-- source), posts a success or warning toast. ctx_inner.locale carries
|
||||
-- the per-frame-resolved Form-2 locale; we forward it verbatim.
|
||||
crafting_display.register_action(state.workbench_crafting_widget,
|
||||
"Craft", function(recipe_id, ctx_inner)
|
||||
local r = crafting.craft(recipe_id, ctx_inner.locale,
|
||||
{ actor = state.actor, at_workbench = true })
|
||||
if r.ok then
|
||||
local recipe = crafting.get_recipe(recipe_id)
|
||||
notify.post{
|
||||
tags = {"craft", "event"},
|
||||
text = "Crafted " .. (recipe.name or recipe_id),
|
||||
severity = "info",
|
||||
}
|
||||
if CI_FRAME_PERF then
|
||||
engine.print("vagrant: event=craft_ok recipe=" .. recipe_id
|
||||
.. " at_workbench=1")
|
||||
end
|
||||
else
|
||||
local msg
|
||||
if r.error == "missing_inputs" then
|
||||
msg = "Missing inputs"
|
||||
else
|
||||
msg = "Cannot craft: " .. tostring(r.error)
|
||||
end
|
||||
notify.warn({"craft", "event"}, msg)
|
||||
if CI_FRAME_PERF then
|
||||
engine.print("vagrant: event=craft_fail recipe=" .. recipe_id
|
||||
.. " error=" .. tostring(r.error)
|
||||
.. " at_workbench=1")
|
||||
end
|
||||
end
|
||||
ctx_inner.close_menu()
|
||||
end)
|
||||
|
||||
-- Inspect action: routes recipe details to the notify detail-channel
|
||||
-- (same pattern as backpack-crafting Inspect).
|
||||
crafting_display.register_action(state.workbench_crafting_widget,
|
||||
"Inspect", function(recipe_id, ctx_inner)
|
||||
local recipe = crafting.get_recipe(recipe_id)
|
||||
local lines = {
|
||||
recipe.name or recipe.id,
|
||||
"",
|
||||
recipe.description or "",
|
||||
"",
|
||||
"Inputs:",
|
||||
}
|
||||
for _, inp in ipairs(recipe.inputs) do
|
||||
lines[#lines + 1] = " " .. inp.template
|
||||
.. " \xc3\x97 " .. inp.count
|
||||
end
|
||||
lines[#lines + 1] = ""
|
||||
lines[#lines + 1] = "Output: " .. recipe.output.template
|
||||
.. " \xc3\x97 " .. recipe.output.count
|
||||
notify.post{
|
||||
tags = {"inspect", "detail"},
|
||||
text = table.concat(lines, "\n"),
|
||||
severity = "info",
|
||||
}
|
||||
ctx_inner.close_menu()
|
||||
end)
|
||||
|
||||
panel.register("workbench_crafting", state.workbench_crafting_widget)
|
||||
-- KEIN bind_default_trigger: trigger is the workbench right-click via
|
||||
-- register_interaction_use(state.workbench) below.
|
||||
|
||||
-- ====== Workbench Inventory Widget (Phase D v0.2) ======
|
||||
state.workbench_inv_widget = inv_display.create(state.workbench, {
|
||||
title = "Workbench Inventory",
|
||||
widget_id = "workbench_inv",
|
||||
pause_on_open = false,
|
||||
})
|
||||
|
||||
-- Take action: moves an item from workbench → backpack via
|
||||
-- inventory.remove + inventory.add. Posts a transfer-event toast.
|
||||
inv_display.register_action(state.workbench_inv_widget, "Take",
|
||||
function(item, c)
|
||||
inventory.remove(state.workbench, item)
|
||||
inventory.add(state.backpack, item)
|
||||
notify.post{
|
||||
tags = {"transfer", "event"},
|
||||
text = "Took " .. (item:get_property("name")
|
||||
or composition.template_of(item) or "item"),
|
||||
severity = "info",
|
||||
}
|
||||
c.close_menu()
|
||||
if CI_FRAME_PERF then engine.print("vagrant: event=take") end
|
||||
if c.refresh then c.refresh() end
|
||||
end)
|
||||
|
||||
-- Inspect action: mirrors the backpack-inv Inspect so that workbench
|
||||
-- contents have the same detail-modal payload (name + description +
|
||||
-- weight + volume + composition.* materials).
|
||||
inv_display.register_action(state.workbench_inv_widget, "Inspect",
|
||||
function(item, c)
|
||||
local props = item:get_properties()
|
||||
local comp = {}
|
||||
for k, v in pairs(props) do
|
||||
local mat = k:match("^composition%.(.+)$")
|
||||
if mat and mat ~= "reg_id" then comp[mat] = v end
|
||||
end
|
||||
notify.post{
|
||||
tags = {"inspect"},
|
||||
text = item:get_property("name") or "(unnamed)",
|
||||
data = {
|
||||
description = item:get_property("description"),
|
||||
weight = item:get_property("weight"),
|
||||
volume = item:get_property("volume"),
|
||||
composition = comp,
|
||||
},
|
||||
}
|
||||
c.close_menu()
|
||||
end)
|
||||
|
||||
panel.register("workbench_inv", state.workbench_inv_widget)
|
||||
|
||||
-- Right-click trigger registered AFTER both workbench widgets are
|
||||
-- panel.register'd; the callback panel.open()s them by id, so they
|
||||
-- must already be in the panel registry.
|
||||
register_interaction_use(state.workbench)
|
||||
|
||||
-- ====== Notification System Setup ======
|
||||
|
||||
-- Channels (created BEFORE display attach + widget register)
|
||||
notify.create_channel{ id = "inspect", filter = {"inspect"},
|
||||
display_mode = "detail" }
|
||||
notify.create_channel{ id = "events", filter = {"pickup", "drop", "craft"},
|
||||
notify.create_channel{ id = "events", filter = {"pickup", "drop", "craft", "transfer"},
|
||||
display_mode = "toast" }
|
||||
notify.create_channel{ id = "log", filter = {}, -- catch-all
|
||||
display_mode = "log" }
|
||||
@@ -726,6 +975,7 @@ function M.init(ctx)
|
||||
input.bind("walk_down", { "s" })
|
||||
input.bind("sprint", { "shift" }) -- held while walking → 2x speed
|
||||
input.bind("interact", { "e" }) -- fires nearest proximity-trigger
|
||||
input.bind("use", { "mouse_right" }) -- Phase D right-click "use" trigger (workbench)
|
||||
input.bind("drop", { "q" }) -- drop most-recent item from backpack
|
||||
input.bind("quit_to_launcher", { "escape" })
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"id": "vagrant-skeleton",
|
||||
"version": "0.11.0",
|
||||
"version": "0.12.0",
|
||||
"kind": "module",
|
||||
"api": "^0.1",
|
||||
"ci_frames": 60,
|
||||
@@ -26,8 +26,8 @@
|
||||
{"id": "lib-core.puppet", "version": "0.5.0"},
|
||||
{"id": "lib-core.interaction", "version": "0.1.0"},
|
||||
{"id": "lib-core.inventory-list", "version": "0.1.0"},
|
||||
{"id": "lib-core.crafting", "version": "0.1.0"},
|
||||
{"id": "lib-core.crafting-display", "version": "0.1.0"},
|
||||
{"id": "lib-core.crafting", "version": "0.2.0"},
|
||||
{"id": "lib-core.crafting-display", "version": "0.2.0"},
|
||||
{"id": "lib-asset.prototype-subterrain", "version": "0.2.0"},
|
||||
{"id": "lib-asset.prototype-blob-geom", "version": "0.1.0"}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user