- Mark: a debug non-collidable named destination (pixel-art target icon), editor tool + name modal, globally-unique names, programmatic Room:addMark - NPCs walk to Marks: each RGB copy is a per-room resident (like the player), running its own A* on its own colour layer, transferring rooms as it crosses seams; rendered and collided by the room it currently stands in - Player copies are obstacles in NPC pathfinding - A* is footprint-aware for multi-cell NPCs - Editor: click an NPC to open a filterable destination picker - Ink: Dialogue.open binds walk_to; Jorge can be sent to "end"/"begin" - Fix: a blocked NPC now replans each tick and resumes instead of freezing - [npc] move diagnostics under DEBUG (start/goal/route or block reason) - Docs (adding-npcs) + CLAUDE.md LÖVE 11.x/float-colour corrections - Fix test harness loadSprite stub; movement tests green (28) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
27 lines
991 B
Lua
27 lines
991 B
Lua
-- Dialogable: a mixin that makes any Entity subclass talkable. `include` it and
|
|
-- give the entity a `self.book` (an Ink book); bumping the entity then opens the
|
|
-- modal Dialogue. npcs, signs, artifacts — anything you can talk to — are just
|
|
-- Dialogables. For now an entity carries one book; later it can swap books as it
|
|
-- progresses. All it does is route a bump to the dialogue manager.
|
|
Dialogable = {}
|
|
|
|
function Dialogable:onBump()
|
|
if self.book then
|
|
local wasOpen = Dialogue.isOpen()
|
|
Dialogue.open(self.book, self:dialogueBindings())
|
|
if Sound and not wasOpen then Sound.jabber() end
|
|
end
|
|
return true
|
|
end
|
|
|
|
-- Ink external functions exposed to this talker's book. A walking NPC (one that
|
|
-- includes Walker) can be sent to a named Mark with `~ walk_to("mark_name")`,
|
|
-- e.g. to leave after a conversation.
|
|
function Dialogable:dialogueBindings()
|
|
local talker = self
|
|
return {
|
|
walk_to = function(markName)
|
|
if talker.sendTo then talker:sendTo(markName) end
|
|
end,
|
|
}
|
|
end
|