note blocks and sticky test
This commit is contained in:
parent
1bc1cdb11f
commit
d829b4972f
11 changed files with 3389 additions and 118 deletions
BIN
art/_debug/notepad.png
Normal file
BIN
art/_debug/notepad.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 459 B |
|
|
@ -1,6 +1,7 @@
|
||||||
require "level_editor/object_attributes"
|
require "level_editor/object_attributes"
|
||||||
require "level_editor/gui"
|
require "level_editor/gui"
|
||||||
require "level_editor/layout"
|
require "level_editor/layout"
|
||||||
|
require "level_editor/note_editor"
|
||||||
|
|
||||||
editorView = "room" --can be "off", "room", "world", "asset"
|
editorView = "room" --can be "off", "room", "world", "asset"
|
||||||
selectedColor = "white"
|
selectedColor = "white"
|
||||||
|
|
@ -10,6 +11,7 @@ local folderSprite = love.graphics.newImage("art/_ui/folder.png")
|
||||||
local cancelSprite = love.graphics.newImage("art/_ui/cancel.png")
|
local cancelSprite = love.graphics.newImage("art/_ui/cancel.png")
|
||||||
local confirmSprite = love.graphics.newImage("art/_ui/confirm.png")
|
local confirmSprite = love.graphics.newImage("art/_ui/confirm.png")
|
||||||
local clearSavesSprite = love.graphics.newImage("art/_ui/clear_saves.png")
|
local clearSavesSprite = love.graphics.newImage("art/_ui/clear_saves.png")
|
||||||
|
local notepadSprite = love.graphics.newImage("art/_debug/notepad.png")
|
||||||
|
|
||||||
local selectedFolder = nil
|
local selectedFolder = nil
|
||||||
local selectedAsset = nil
|
local selectedAsset = nil
|
||||||
|
|
@ -53,6 +55,12 @@ local boxPaletteOpen = false
|
||||||
local boxPaletteScroll = { scroll = 0 }
|
local boxPaletteScroll = { scroll = 0 }
|
||||||
local boxPaletteSections = {}
|
local boxPaletteSections = {}
|
||||||
|
|
||||||
|
-- Note authoring state. `noteMode` is nil normally, "create" while placing a new
|
||||||
|
-- note (click a cell to drop it and finish), or "edit" while retyping an
|
||||||
|
-- existing note (with Save / Discard). `editingNote` is the note being edited.
|
||||||
|
local noteMode = nil
|
||||||
|
local editingNote = nil
|
||||||
|
|
||||||
-- Convert a pointer position into a valid room cell. Keeping brush state in
|
-- Convert a pointer position into a valid room cell. Keeping brush state in
|
||||||
-- cell coordinates means a click that jitters within a tile cannot place or
|
-- cell coordinates means a click that jitters within a tile cannot place or
|
||||||
-- erase that tile more than once.
|
-- erase that tile more than once.
|
||||||
|
|
@ -241,6 +249,19 @@ local function roomSections()
|
||||||
return { search = search, listRect = list, status = status, controls = controls }
|
return { search = search, listRect = list, status = status, controls = controls }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Save / Discard buttons for note edit mode, laid out in the status strip. Runs
|
||||||
|
-- for both drawing and hit-testing so the two never disagree.
|
||||||
|
local function noteEditButtonRects(s)
|
||||||
|
local gap = 8
|
||||||
|
local h = math.min(28, s.status.h)
|
||||||
|
local w = (s.status.w - gap) / 2
|
||||||
|
local y = s.status.y + (s.status.h - h) / 2
|
||||||
|
return {
|
||||||
|
save = { x = s.status.x, y = y, w = w, h = h },
|
||||||
|
discard = { x = s.status.x + w + gap, y = y, w = w, h = h },
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
-- Position the bottom control cluster inside its section: level-name field, a
|
-- Position the bottom control cluster inside its section: level-name field, a
|
||||||
-- row of colour buttons, then a row of action buttons. Runs for both drawing
|
-- row of colour buttons, then a row of action buttons. Runs for both drawing
|
||||||
-- and hit-testing so the two never disagree.
|
-- and hit-testing so the two never disagree.
|
||||||
|
|
@ -297,7 +318,7 @@ local function layoutRoomControls(c, s)
|
||||||
|
|
||||||
placeRow({ "white", "red", "green", "blue" }, 22)
|
placeRow({ "white", "red", "green", "blue" }, 22)
|
||||||
placeRow({ "quick_player", "quick_static_wall", "quick_switch", "quick_door", "quick_wired_switch", "quick_wired_door", "quick_box" }, 22)
|
placeRow({ "quick_player", "quick_static_wall", "quick_switch", "quick_door", "quick_wired_switch", "quick_wired_door", "quick_box" }, 22)
|
||||||
placeRow({ "save", "clearSaves", "world", "wire" }, 28)
|
placeRow({ "save", "clearSaves", "world", "wire", "note" }, 28)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Build the full room-view layout (sections + a scroll list + a back/search
|
-- Build the full room-view layout (sections + a scroll list + a back/search
|
||||||
|
|
@ -723,6 +744,16 @@ function _initLevelEditor()
|
||||||
y = 0,
|
y = 0,
|
||||||
}, "wire")
|
}, "wire")
|
||||||
|
|
||||||
|
_addUIButton(createUIElement{
|
||||||
|
name = "note",
|
||||||
|
sprite = notepadSprite,
|
||||||
|
onClic = { left = function()
|
||||||
|
if editorView == "room" then beginNoteCreate() end
|
||||||
|
end },
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
}, "note")
|
||||||
|
|
||||||
roomNameField = createUIElement{
|
roomNameField = createUIElement{
|
||||||
name = "roomName",
|
name = "roomName",
|
||||||
text = editorRoomName,
|
text = editorRoomName,
|
||||||
|
|
@ -783,9 +814,50 @@ end
|
||||||
function selectAsset(asset)
|
function selectAsset(asset)
|
||||||
print("selecting", asset)
|
print("selecting", asset)
|
||||||
selectedAsset = asset
|
selectedAsset = asset
|
||||||
|
exitNoteMode() -- picking any real asset closes the note text field
|
||||||
print(selectedAsset)
|
print(selectedAsset)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Close the note text box and return to whatever the sidebar was showing before.
|
||||||
|
function exitNoteMode()
|
||||||
|
noteMode = nil
|
||||||
|
editingNote = nil
|
||||||
|
noteEditorBlur()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Start authoring a new note: focus a blank text field. The author types, then
|
||||||
|
-- clicks a grid cell to drop the note there (that placement is the "done").
|
||||||
|
function beginNoteCreate()
|
||||||
|
if editorView ~= "room" then return end
|
||||||
|
boxPaletteOpen = false
|
||||||
|
noteMode = "create"
|
||||||
|
editingNote = nil
|
||||||
|
noteEditorSetText("")
|
||||||
|
noteEditorFocus()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Left-clicking an existing note reopens it for editing, with Save / Discard.
|
||||||
|
function beginNoteEdit(note)
|
||||||
|
noteMode = "edit"
|
||||||
|
editingNote = note
|
||||||
|
noteEditorSetText(note.text)
|
||||||
|
noteEditorFocus()
|
||||||
|
end
|
||||||
|
|
||||||
|
function saveNoteEdit()
|
||||||
|
if editingNote then editingNote.text = noteEditorText() end
|
||||||
|
exitNoteMode()
|
||||||
|
end
|
||||||
|
|
||||||
|
function discardNoteEdit()
|
||||||
|
exitNoteMode()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Keyboard Escape while the field is focused: discard the edit / cancel placing.
|
||||||
|
function cancelNoteMode()
|
||||||
|
exitNoteMode()
|
||||||
|
end
|
||||||
|
|
||||||
function selectQuickAsset(asset)
|
function selectQuickAsset(asset)
|
||||||
selectAsset(asset)
|
selectAsset(asset)
|
||||||
boxPaletteOpen = asset == "box"
|
boxPaletteOpen = asset == "box"
|
||||||
|
|
@ -922,6 +994,7 @@ function wireView()
|
||||||
editorStatus = "Place this room in the world before drawing cross-room wires."
|
editorStatus = "Place this room in the world before drawing cross-room wires."
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
exitNoteMode()
|
||||||
editorView = "wire"
|
editorView = "wire"
|
||||||
activeField = nil
|
activeField = nil
|
||||||
roomBrush = nil
|
roomBrush = nil
|
||||||
|
|
@ -935,6 +1008,7 @@ function wireView()
|
||||||
end
|
end
|
||||||
|
|
||||||
function worldView()
|
function worldView()
|
||||||
|
exitNoteMode()
|
||||||
editorView = "world"
|
editorView = "world"
|
||||||
wireBrush = nil
|
wireBrush = nil
|
||||||
activeField = nil
|
activeField = nil
|
||||||
|
|
@ -1169,6 +1243,22 @@ function editorMouseHandler(x, y, button)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- While authoring a note, the field takes over the list area: a click
|
||||||
|
-- there positions the caret / starts a selection (its rect is set each
|
||||||
|
-- frame by noteEditorDraw). In edit mode, Save / Discard live in the
|
||||||
|
-- status strip.
|
||||||
|
if noteMode then
|
||||||
|
if noteMode == "edit" and button == 1 then
|
||||||
|
local nb = noteEditButtonRects(s)
|
||||||
|
if Layout.hit(nb.save, x, y) then saveNoteEdit(); return end
|
||||||
|
if Layout.hit(nb.discard, x, y) then discardNoteEdit(); return end
|
||||||
|
end
|
||||||
|
if noteEditorMousepressed(x, y) then return end
|
||||||
|
-- The field covers the list area; swallow other clicks there so the
|
||||||
|
-- hidden asset list underneath can't be selected by accident.
|
||||||
|
if Layout.hit(s.listRect, x, y) then return end
|
||||||
|
end
|
||||||
|
|
||||||
if s.boxPicker then
|
if s.boxPicker then
|
||||||
local asset = s.boxPicker.at(x, y)
|
local asset = s.boxPicker.at(x, y)
|
||||||
if asset then
|
if asset then
|
||||||
|
|
@ -1185,7 +1275,7 @@ function editorMouseHandler(x, y, button)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- control cluster (only the buttons that live there)
|
-- control cluster (only the buttons that live there)
|
||||||
for _, name in ipairs({ "roomName", "white", "red", "green", "blue", "quick_player", "quick_static_wall", "quick_switch", "quick_door", "quick_wired_switch", "quick_wired_door", "quick_box", "save", "clearSaves", "world", "wire" }) do
|
for _, name in ipairs({ "roomName", "white", "red", "green", "blue", "quick_player", "quick_static_wall", "quick_switch", "quick_door", "quick_wired_switch", "quick_wired_door", "quick_box", "save", "clearSaves", "world", "wire", "note" }) do
|
||||||
local b = uiButtons[name]
|
local b = uiButtons[name]
|
||||||
if b and b:clicIsInBox(x, y) then
|
if b and b:clicIsInBox(x, y) then
|
||||||
b:onClic(button)
|
b:onClic(button)
|
||||||
|
|
@ -1232,6 +1322,20 @@ function editorMouseHandler(x, y, button)
|
||||||
else
|
else
|
||||||
-- click landed on the grid (game area): place the selected asset
|
-- click landed on the grid (game area): place the selected asset
|
||||||
if editorView == "room" then
|
if editorView == "room" then
|
||||||
|
local cell = button == 1 and roomCellAt(x, y)
|
||||||
|
-- Placing a new note: drop it here carrying the typed text, then finish
|
||||||
|
-- (the drop is the "done"), returning the sidebar to its prior view.
|
||||||
|
if cell and noteMode == "create" then
|
||||||
|
currentRoom:attemptPlaceAtCell("note", nil, cell, selectedColor, noteEditorText())
|
||||||
|
exitNoteMode()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- Left-clicking an existing note opens it for editing instead of
|
||||||
|
-- painting over it.
|
||||||
|
if cell then
|
||||||
|
local note = currentRoom:noteAtCell(cell)
|
||||||
|
if note then beginNoteEdit(note); return end
|
||||||
|
end
|
||||||
beginRoomBrush(x, y, button)
|
beginRoomBrush(x, y, button)
|
||||||
elseif editorView == "wire" then
|
elseif editorView == "wire" then
|
||||||
beginWireBrush(x, y, button)
|
beginWireBrush(x, y, button)
|
||||||
|
|
@ -1257,6 +1361,11 @@ function editorMouseHandler(x, y, button)
|
||||||
end
|
end
|
||||||
|
|
||||||
function editorMouseMoved(x, y)
|
function editorMouseMoved(x, y)
|
||||||
|
if noteEditorActive() and x >= sideBarBox.x then
|
||||||
|
local vx = (x - sideBarBox.x) * sb.w / sideBarBox.w
|
||||||
|
local vy = y * sb.h / sideBarBox.h
|
||||||
|
if noteEditorMousemoved(vx, vy) then return end
|
||||||
|
end
|
||||||
if wireBrush then
|
if wireBrush then
|
||||||
if editorView ~= "wire" then wireBrush = nil; return end
|
if editorView ~= "wire" then wireBrush = nil; return end
|
||||||
local cell = wireCellAt(x, y)
|
local cell = wireCellAt(x, y)
|
||||||
|
|
@ -1286,6 +1395,7 @@ function editorMouseMoved(x, y)
|
||||||
end
|
end
|
||||||
|
|
||||||
function editorMouseReleased(_, _, button)
|
function editorMouseReleased(_, _, button)
|
||||||
|
noteEditorMousereleased()
|
||||||
if roomBrush and roomBrush.button == button then roomBrush = nil end
|
if roomBrush and roomBrush.button == button then roomBrush = nil end
|
||||||
if wireBrush and wireBrush.button == button then wireBrush = nil end
|
if wireBrush and wireBrush.button == button then wireBrush = nil end
|
||||||
end
|
end
|
||||||
|
|
@ -1355,6 +1465,36 @@ function createUIElement(t)
|
||||||
return GUI:new(t)
|
return GUI:new(t)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Hover readout for note blocks, drawn in screen space over the play area (not
|
||||||
|
-- the sidebar). Mirrors World:drawHoveredRoomName's pointer-anchored tooltip so
|
||||||
|
-- it matches the overworld hover style. Only meaningful while notes are shown.
|
||||||
|
function editorDrawNoteHover()
|
||||||
|
if not (DEBUG and NOTES_VISIBLE) then return end
|
||||||
|
if editorView ~= "room" then return end
|
||||||
|
local mouseX, mouseY = love.mouse.getPosition()
|
||||||
|
if mouseX < 0 or mouseX >= width or mouseY < 0 or mouseY >= height then return end
|
||||||
|
|
||||||
|
local note = currentRoom:noteAtCell(currentRoom:getCellFromMousePos(mouseX, mouseY))
|
||||||
|
if not note or note.text == "" then return end
|
||||||
|
|
||||||
|
local pad = 6
|
||||||
|
local maxW = math.min(280, width - 8)
|
||||||
|
local _, wrapped = font:getWrap(note.text, maxW - pad * 2)
|
||||||
|
local textW = 0
|
||||||
|
for _, line in ipairs(wrapped) do textW = math.max(textW, font:getWidth(line)) end
|
||||||
|
local tooltipW = math.min(textW + pad * 2, maxW)
|
||||||
|
local tooltipH = #wrapped * font:getHeight() + pad * 2
|
||||||
|
|
||||||
|
local tooltipX = math.max(4, math.min(mouseX + 14, width - tooltipW - 4))
|
||||||
|
local tooltipY = math.max(4, math.min(mouseY + 14, height - tooltipH - 4))
|
||||||
|
|
||||||
|
love.graphics.setColor(0, 0, 0, 0.9)
|
||||||
|
love.graphics.rectangle("fill", tooltipX, tooltipY, tooltipW, tooltipH)
|
||||||
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
|
love.graphics.rectangle("line", tooltipX, tooltipY, tooltipW, tooltipH)
|
||||||
|
love.graphics.printf(note.text, tooltipX + pad, tooltipY + pad, tooltipW - pad * 2, "left")
|
||||||
|
end
|
||||||
|
|
||||||
function editorDraw()
|
function editorDraw()
|
||||||
if editorView == "room" then
|
if editorView == "room" then
|
||||||
local s = buildRoomLayout()
|
local s = buildRoomLayout()
|
||||||
|
|
@ -1373,7 +1513,17 @@ function editorDraw()
|
||||||
love.graphics.rectangle("line", s.searchBox.x, s.searchBox.y, s.searchBox.w, s.searchBox.h)
|
love.graphics.rectangle("line", s.searchBox.x, s.searchBox.y, s.searchBox.w, s.searchBox.h)
|
||||||
love.graphics.printf(boxPaletteOpen and "QUICK PALETTE" or "SEARCH: " .. assetSearchText, s.searchBox.x + 6, s.searchBox.y + 9, s.searchBox.w - 12, "left")
|
love.graphics.printf(boxPaletteOpen and "QUICK PALETTE" or "SEARCH: " .. assetSearchText, s.searchBox.x + 6, s.searchBox.y + 9, s.searchBox.w - 12, "left")
|
||||||
|
|
||||||
if s.boxPicker then
|
if noteMode then
|
||||||
|
-- Authoring a note: the text field replaces the asset list. In create
|
||||||
|
-- mode you click a grid cell to drop it; in edit mode Save / Discard sit
|
||||||
|
-- in the status strip below.
|
||||||
|
local labelH = 18
|
||||||
|
local hint = noteMode == "edit" and "EDIT NOTE" or "NEW NOTE (click grid to place)"
|
||||||
|
love.graphics.setColor(gColor.white:set())
|
||||||
|
love.graphics.printf(hint, s.listRect.x, s.listRect.y, s.listRect.w, "left")
|
||||||
|
noteEditorSetRect(s.listRect.x, s.listRect.y + labelH, s.listRect.w, s.listRect.h - labelH)
|
||||||
|
noteEditorDraw()
|
||||||
|
elseif s.boxPicker then
|
||||||
drawBoxPicker(s.boxPicker)
|
drawBoxPicker(s.boxPicker)
|
||||||
else
|
else
|
||||||
-- Scrolling list, clipped to its section so nothing bleeds into others.
|
-- Scrolling list, clipped to its section so nothing bleeds into others.
|
||||||
|
|
@ -1397,7 +1547,7 @@ function editorDraw()
|
||||||
-- control cluster
|
-- control cluster
|
||||||
love.graphics.setColor(gColor.white:set())
|
love.graphics.setColor(gColor.white:set())
|
||||||
love.graphics.printf("LEVEL NAME", s.controls.x, s.labelY, s.controls.w, "center")
|
love.graphics.printf("LEVEL NAME", s.controls.x, s.labelY, s.controls.w, "center")
|
||||||
for _, name in ipairs({ "roomName", "white", "red", "green", "blue", "quick_player", "quick_static_wall", "quick_switch", "quick_door", "quick_wired_switch", "quick_wired_door", "quick_box", "save", "clearSaves", "world", "wire" }) do
|
for _, name in ipairs({ "roomName", "white", "red", "green", "blue", "quick_player", "quick_static_wall", "quick_switch", "quick_door", "quick_wired_switch", "quick_wired_door", "quick_box", "save", "clearSaves", "world", "wire", "note" }) do
|
||||||
local button = uiButtons[name]
|
local button = uiButtons[name]
|
||||||
if button then
|
if button then
|
||||||
button:draw()
|
button:draw()
|
||||||
|
|
@ -1406,7 +1556,7 @@ function editorDraw()
|
||||||
love.graphics.setColor(1, 1, 1, 1)
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
love.graphics.print("W", button.x + button.w - 7, button.y - 4)
|
love.graphics.print("W", button.x + button.w - 7, button.y - 4)
|
||||||
end
|
end
|
||||||
if asset and selectedAsset == asset then
|
if (asset and selectedAsset == asset) or (name == "note" and noteMode ~= nil) then
|
||||||
love.graphics.setColor(1, 0.85, 0.2, 1)
|
love.graphics.setColor(1, 0.85, 0.2, 1)
|
||||||
love.graphics.setLineWidth(2)
|
love.graphics.setLineWidth(2)
|
||||||
love.graphics.rectangle("line", button.x - 1, button.y - 1, button.w + 2, button.h + 2)
|
love.graphics.rectangle("line", button.x - 1, button.y - 1, button.w + 2, button.h + 2)
|
||||||
|
|
@ -1414,8 +1564,17 @@ function editorDraw()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- status strip between the list and the controls
|
-- status strip between the list and the controls: Save / Discard while
|
||||||
if editorStatus then
|
-- editing an existing note, otherwise the ordinary status line.
|
||||||
|
if noteMode == "edit" then
|
||||||
|
local nb = noteEditButtonRects(s)
|
||||||
|
love.graphics.setColor(gColor.white:set())
|
||||||
|
for label, r in pairs({ SAVE = nb.save, DISCARD = nb.discard }) do
|
||||||
|
love.graphics.setLineWidth(2)
|
||||||
|
love.graphics.rectangle("line", r.x, r.y, r.w, r.h)
|
||||||
|
love.graphics.printf(label, r.x, r.y + (r.h - font:getHeight()) / 2, r.w, "center")
|
||||||
|
end
|
||||||
|
elseif editorStatus then
|
||||||
Layout.clip(s.status)
|
Layout.clip(s.status)
|
||||||
love.graphics.setColor(gColor.white:set())
|
love.graphics.setColor(gColor.white:set())
|
||||||
love.graphics.printf(editorStatus, s.status.x, s.status.y + 4, s.status.w, "center")
|
love.graphics.printf(editorStatus, s.status.x, s.status.y + 4, s.status.w, "center")
|
||||||
|
|
|
||||||
299
level_editor/note_editor.lua
Normal file
299
level_editor/note_editor.lua
Normal file
|
|
@ -0,0 +1,299 @@
|
||||||
|
-- A small, self-contained multi-line text field for the level editor sidebar.
|
||||||
|
-- LÖVE ships no GUI widgets, so this rolls the minimum needed to feel like a
|
||||||
|
-- normal text box: a caret, a selection, mouse click/drag positioning, and the
|
||||||
|
-- usual keyboard shortcuts (arrows, word-jump, home/end, select-all, clipboard).
|
||||||
|
--
|
||||||
|
-- Text is kept as an array of one-character strings (utf8-aware) with the caret
|
||||||
|
-- and selection anchor expressed as caret indices (0..#chars, a position between
|
||||||
|
-- characters). Everything else is derived from that.
|
||||||
|
|
||||||
|
local utf8 = require("utf8")
|
||||||
|
|
||||||
|
local pad = 6
|
||||||
|
|
||||||
|
local note = {
|
||||||
|
active = false,
|
||||||
|
chars = {}, -- array of single utf8 characters
|
||||||
|
caret = 0, -- 0..#chars
|
||||||
|
anchor = nil, -- selection start (caret index) or nil
|
||||||
|
rect = { x = 0, y = 0, w = 0, h = 0 },
|
||||||
|
dragging = false,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- ── helpers ─────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
local function toChars(str)
|
||||||
|
local t = {}
|
||||||
|
local i, len = 1, #str
|
||||||
|
while i <= len do
|
||||||
|
local nexti = utf8.offset(str, 2, i) or (len + 1)
|
||||||
|
t[#t + 1] = str:sub(i, nexti - 1)
|
||||||
|
i = nexti
|
||||||
|
end
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
|
||||||
|
local function clamp(v, lo, hi)
|
||||||
|
if v < lo then return lo elseif v > hi then return hi else return v end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function isWordChar(c)
|
||||||
|
return c ~= nil and c:match("[%w_]") ~= nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Line ranges as caret-index pairs: line covers caret indices s..e, and its text
|
||||||
|
-- is chars[s+1 .. e]. A blank final line after a trailing newline is included.
|
||||||
|
local function buildLines()
|
||||||
|
local lines, start = {}, 0
|
||||||
|
for k = 1, #note.chars do
|
||||||
|
if note.chars[k] == "\n" then
|
||||||
|
lines[#lines + 1] = { s = start, e = k - 1 }
|
||||||
|
start = k
|
||||||
|
end
|
||||||
|
end
|
||||||
|
lines[#lines + 1] = { s = start, e = #note.chars }
|
||||||
|
return lines
|
||||||
|
end
|
||||||
|
|
||||||
|
local function lineIndexOf(caret, lines)
|
||||||
|
for i, line in ipairs(lines) do
|
||||||
|
if caret >= line.s and caret <= line.e then return i end
|
||||||
|
end
|
||||||
|
return #lines
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Pixel width from a line's start up to `col` characters into it.
|
||||||
|
local function colWidth(line, col)
|
||||||
|
local s = table.concat(note.chars, "", line.s + 1, line.s + col)
|
||||||
|
return font:getWidth(s)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ── selection / mutation ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
local function selectionRange()
|
||||||
|
if not note.anchor or note.anchor == note.caret then return nil end
|
||||||
|
return math.min(note.anchor, note.caret), math.max(note.anchor, note.caret)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function deleteRange(lo, hi)
|
||||||
|
for k = hi, lo + 1, -1 do table.remove(note.chars, k) end
|
||||||
|
note.caret = lo
|
||||||
|
note.anchor = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function deleteSelection()
|
||||||
|
local lo, hi = selectionRange()
|
||||||
|
if not lo then return false end
|
||||||
|
deleteRange(lo, hi)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function insertText(str)
|
||||||
|
deleteSelection()
|
||||||
|
local ins = toChars(str)
|
||||||
|
for offset, c in ipairs(ins) do
|
||||||
|
table.insert(note.chars, note.caret + offset, c)
|
||||||
|
end
|
||||||
|
note.caret = note.caret + #ins
|
||||||
|
note.anchor = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Move the caret, extending or clearing the selection depending on shift.
|
||||||
|
local function moveCaret(pos, keepSelection)
|
||||||
|
if keepSelection then
|
||||||
|
if not note.anchor then note.anchor = note.caret end
|
||||||
|
else
|
||||||
|
note.anchor = nil
|
||||||
|
end
|
||||||
|
note.caret = clamp(pos, 0, #note.chars)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function wordLeft(i)
|
||||||
|
local j = i
|
||||||
|
while j > 0 and not isWordChar(note.chars[j]) do j = j - 1 end
|
||||||
|
while j > 0 and isWordChar(note.chars[j]) do j = j - 1 end
|
||||||
|
return j
|
||||||
|
end
|
||||||
|
|
||||||
|
local function wordRight(i)
|
||||||
|
local n = #note.chars
|
||||||
|
local j = i
|
||||||
|
while j < n and not isWordChar(note.chars[j + 1]) do j = j + 1 end
|
||||||
|
while j < n and isWordChar(note.chars[j + 1]) do j = j + 1 end
|
||||||
|
return j
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Map a point (sidebar-virtual coords) to the nearest caret index.
|
||||||
|
local function caretFromPoint(px, py)
|
||||||
|
local lines = buildLines()
|
||||||
|
local lineH = font:getHeight()
|
||||||
|
local row = clamp(math.floor((py - (note.rect.y + pad)) / lineH) + 1, 1, #lines)
|
||||||
|
local line = lines[row]
|
||||||
|
local target = px - (note.rect.x + pad)
|
||||||
|
local best, bestDist = 0, math.huge
|
||||||
|
for col = 0, line.e - line.s do
|
||||||
|
local dist = math.abs(colWidth(line, col) - target)
|
||||||
|
if dist < bestDist then best, bestDist = col, dist end
|
||||||
|
end
|
||||||
|
return line.s + best
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ── public API (globals, matching the editor's module style) ─────────────────
|
||||||
|
|
||||||
|
function noteEditorActive()
|
||||||
|
return note.active and editorView == "room"
|
||||||
|
end
|
||||||
|
|
||||||
|
function noteEditorFocus()
|
||||||
|
note.active = true
|
||||||
|
end
|
||||||
|
|
||||||
|
function noteEditorBlur()
|
||||||
|
note.active = false
|
||||||
|
note.dragging = false
|
||||||
|
end
|
||||||
|
|
||||||
|
function noteEditorText()
|
||||||
|
return table.concat(note.chars)
|
||||||
|
end
|
||||||
|
|
||||||
|
function noteEditorSetText(str)
|
||||||
|
note.chars = toChars(str or "")
|
||||||
|
note.caret = #note.chars
|
||||||
|
note.anchor = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function noteEditorSetRect(x, y, w, h)
|
||||||
|
note.rect.x, note.rect.y, note.rect.w, note.rect.h = x, y, w, h
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Click landed somewhere in the sidebar (virtual coords). Returns true if it hit
|
||||||
|
-- the field (so the caller stops looking for another control).
|
||||||
|
function noteEditorMousepressed(x, y)
|
||||||
|
local r = note.rect
|
||||||
|
if x < r.x or x > r.x + r.w or y < r.y or y > r.y + r.h then return false end
|
||||||
|
note.active = true
|
||||||
|
note.caret = caretFromPoint(x, y)
|
||||||
|
note.anchor = note.caret
|
||||||
|
note.dragging = true
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function noteEditorMousemoved(x, y)
|
||||||
|
if not note.dragging then return false end
|
||||||
|
note.caret = caretFromPoint(x, y)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function noteEditorMousereleased()
|
||||||
|
note.dragging = false
|
||||||
|
if note.anchor == note.caret then note.anchor = nil end
|
||||||
|
end
|
||||||
|
|
||||||
|
function noteEditorTextinput(t)
|
||||||
|
insertText(t)
|
||||||
|
end
|
||||||
|
|
||||||
|
function noteEditorKeypressed(key)
|
||||||
|
local ctrl = love.keyboard.isDown("lctrl", "rctrl", "lgui", "rgui")
|
||||||
|
local shift = love.keyboard.isDown("lshift", "rshift")
|
||||||
|
|
||||||
|
if key == "escape" then
|
||||||
|
noteEditorBlur()
|
||||||
|
elseif key == "return" or key == "kpenter" then
|
||||||
|
insertText("\n")
|
||||||
|
elseif key == "backspace" then
|
||||||
|
if not deleteSelection() then
|
||||||
|
local to = ctrl and wordLeft(note.caret) or note.caret - 1
|
||||||
|
if to >= 0 and note.caret > 0 then deleteRange(math.max(0, to), note.caret) end
|
||||||
|
end
|
||||||
|
elseif key == "delete" then
|
||||||
|
if not deleteSelection() then
|
||||||
|
local to = ctrl and wordRight(note.caret) or note.caret + 1
|
||||||
|
if note.caret < #note.chars then deleteRange(note.caret, math.min(#note.chars, to)) end
|
||||||
|
end
|
||||||
|
elseif key == "left" then
|
||||||
|
moveCaret(ctrl and wordLeft(note.caret) or note.caret - 1, shift)
|
||||||
|
elseif key == "right" then
|
||||||
|
moveCaret(ctrl and wordRight(note.caret) or note.caret + 1, shift)
|
||||||
|
elseif key == "up" or key == "down" then
|
||||||
|
local lines = buildLines()
|
||||||
|
local row = lineIndexOf(note.caret, lines)
|
||||||
|
local col = note.caret - lines[row].s
|
||||||
|
local target = clamp(row + (key == "up" and -1 or 1), 1, #lines)
|
||||||
|
local line = lines[target]
|
||||||
|
moveCaret(line.s + math.min(col, line.e - line.s), shift)
|
||||||
|
elseif key == "home" then
|
||||||
|
if ctrl then
|
||||||
|
moveCaret(0, shift)
|
||||||
|
else
|
||||||
|
local lines = buildLines()
|
||||||
|
moveCaret(lines[lineIndexOf(note.caret, lines)].s, shift)
|
||||||
|
end
|
||||||
|
elseif key == "end" then
|
||||||
|
if ctrl then
|
||||||
|
moveCaret(#note.chars, shift)
|
||||||
|
else
|
||||||
|
local lines = buildLines()
|
||||||
|
moveCaret(lines[lineIndexOf(note.caret, lines)].e, shift)
|
||||||
|
end
|
||||||
|
elseif ctrl and key == "a" then
|
||||||
|
note.anchor = 0
|
||||||
|
note.caret = #note.chars
|
||||||
|
elseif ctrl and (key == "c" or key == "x") then
|
||||||
|
local lo, hi = selectionRange()
|
||||||
|
if lo then
|
||||||
|
love.system.setClipboardText(table.concat(note.chars, "", lo + 1, hi))
|
||||||
|
if key == "x" then deleteRange(lo, hi) end
|
||||||
|
end
|
||||||
|
elseif ctrl and key == "v" then
|
||||||
|
insertText(love.system.getClipboardText() or "")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Rendered inside the room-view sidebar (virtual space), clipped to its rect.
|
||||||
|
function noteEditorDraw()
|
||||||
|
local r = note.rect
|
||||||
|
local lines = buildLines()
|
||||||
|
local lineH = font:getHeight()
|
||||||
|
local ox, oy = r.x + pad, r.y + pad
|
||||||
|
|
||||||
|
love.graphics.setColor(0, 0, 0, 0.85)
|
||||||
|
love.graphics.rectangle("fill", r.x, r.y, r.w, r.h)
|
||||||
|
love.graphics.setColor(gColor.white:set())
|
||||||
|
love.graphics.setLineWidth(noteEditorActive() and 2 or 1)
|
||||||
|
love.graphics.rectangle("line", r.x, r.y, r.w, r.h)
|
||||||
|
|
||||||
|
Layout.clip({ x = r.x, y = r.y, w = r.w, h = r.h })
|
||||||
|
|
||||||
|
-- selection highlight
|
||||||
|
local lo, hi = selectionRange()
|
||||||
|
if lo then
|
||||||
|
love.graphics.setColor(0.25, 0.45, 0.9, 0.6)
|
||||||
|
for i, line in ipairs(lines) do
|
||||||
|
local segStart, segEnd = math.max(lo, line.s), math.min(hi, line.e)
|
||||||
|
if segEnd > segStart then
|
||||||
|
local x1 = ox + colWidth(line, segStart - line.s)
|
||||||
|
local x2 = ox + colWidth(line, segEnd - line.s)
|
||||||
|
love.graphics.rectangle("fill", x1, oy + (i - 1) * lineH, x2 - x1, lineH)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
love.graphics.setColor(gColor.white:set())
|
||||||
|
for i, line in ipairs(lines) do
|
||||||
|
local text = table.concat(note.chars, "", line.s + 1, line.e)
|
||||||
|
love.graphics.print(text, ox, oy + (i - 1) * lineH)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- caret (blinking) — only while focused
|
||||||
|
if noteEditorActive() and (love.timer.getTime() % 1) < 0.5 then
|
||||||
|
local row = lineIndexOf(note.caret, lines)
|
||||||
|
local cx = ox + colWidth(lines[row], note.caret - lines[row].s)
|
||||||
|
local cy = oy + (row - 1) * lineH
|
||||||
|
love.graphics.setLineWidth(1)
|
||||||
|
love.graphics.line(cx, cy, cx, cy + lineH)
|
||||||
|
end
|
||||||
|
|
||||||
|
Layout.unclip()
|
||||||
|
end
|
||||||
22
main.lua
22
main.lua
|
|
@ -35,6 +35,10 @@ jorgeBook = require "stories.jorge"
|
||||||
-- the DEBUG env var (DEBUG=0 to force off, DEBUG=1 to force on).
|
-- the DEBUG env var (DEBUG=0 to force off, DEBUG=1 to force on).
|
||||||
DEBUG = os.getenv("DEBUG") ~= "0"
|
DEBUG = os.getenv("DEBUG") ~= "0"
|
||||||
|
|
||||||
|
-- Whether editor "note" annotations render over the room. Toggled with Tab (see
|
||||||
|
-- love.keypressed); default on. Only ever consulted under DEBUG (see Room:draw).
|
||||||
|
NOTES_VISIBLE = true
|
||||||
|
|
||||||
function love.load()
|
function love.load()
|
||||||
globalAssetProperties = {} -- rebuilt from the filesystem (art/ + .meta) by getAllAssets
|
globalAssetProperties = {} -- rebuilt from the filesystem (art/ + .meta) by getAllAssets
|
||||||
|
|
||||||
|
|
@ -165,6 +169,7 @@ function love.draw()
|
||||||
love.graphics.setBlendMode("alpha")
|
love.graphics.setBlendMode("alpha")
|
||||||
love.graphics.setColor(1, 1, 1, 1)
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
if DEBUG then love.graphics.draw(sideBarCanvas, sideBarBox.x, sideBarBox.y) end
|
if DEBUG then love.graphics.draw(sideBarCanvas, sideBarBox.x, sideBarBox.y) end
|
||||||
|
if DEBUG then editorDrawNoteHover() end
|
||||||
love.graphics.print("Current FPS: "..tostring(love.timer.getFPS( )), 10, 10)
|
love.graphics.print("Current FPS: "..tostring(love.timer.getFPS( )), 10, 10)
|
||||||
PerfProfiler:draw()
|
PerfProfiler:draw()
|
||||||
Dialogue.draw()
|
Dialogue.draw()
|
||||||
|
|
@ -206,6 +211,19 @@ function love.keypressed(key)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- The focused note text field owns the keyboard entirely: arrows navigate the
|
||||||
|
-- text instead of moving the player, Return inserts a newline, etc.
|
||||||
|
if DEBUG and noteEditorActive() then
|
||||||
|
if key == "escape" then cancelNoteMode() else noteEditorKeypressed(key) end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Tab toggles the editor's note overlay (DEBUG-only; default on).
|
||||||
|
if DEBUG and key == "tab" then
|
||||||
|
NOTES_VISIBLE = not NOTES_VISIBLE
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if editorView == "wire" and editorWireKeypressed(key) then return end
|
if editorView == "wire" and editorWireKeypressed(key) then return end
|
||||||
|
|
||||||
if editorView ~= "world" and editorView ~= "wire" and Input.isPlayerMove(key) then
|
if editorView ~= "world" and editorView ~= "wire" and Input.isPlayerMove(key) then
|
||||||
|
|
@ -264,6 +282,10 @@ end
|
||||||
|
|
||||||
function love.textinput(t)
|
function love.textinput(t)
|
||||||
if not DEBUG then return end
|
if not DEBUG then return end
|
||||||
|
if noteEditorActive() then
|
||||||
|
noteEditorTextinput(t)
|
||||||
|
return
|
||||||
|
end
|
||||||
response = response .. t
|
response = response .. t
|
||||||
editorTextHandler(response)
|
editorTextHandler(response)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
30
note.lua
Normal file
30
note.lua
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
require "entity"
|
||||||
|
|
||||||
|
-- An editor annotation dropped onto the grid. A Note is a normal Entity (so it
|
||||||
|
-- serializes, places and hit-tests like any other object) that carries a bit of
|
||||||
|
-- author text. It is deliberately non-collidable — the player passes straight
|
||||||
|
-- through it — and only ever renders as a translucent icon while the editor is
|
||||||
|
-- available (DEBUG) and notes are toggled on (see NOTES_VISIBLE / Room:draw).
|
||||||
|
Note = class("Note", Entity)
|
||||||
|
|
||||||
|
local noteSprite = loadSprite("art/_debug/notepad.png")
|
||||||
|
|
||||||
|
function Note:initialize(x, y, text)
|
||||||
|
self.text = text or ""
|
||||||
|
self.saveClass = "note"
|
||||||
|
Entity.initialize(self, {
|
||||||
|
x = x, y = y,
|
||||||
|
color = "white", -- representative only; Note:draw ignores channels
|
||||||
|
collision = "none",
|
||||||
|
sprite = noteSprite,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Drawn once (not per-channel) as a faint overlay. Called directly from the
|
||||||
|
-- room's note pass, so it takes no channel argument.
|
||||||
|
function Note:draw()
|
||||||
|
love.graphics.setColor(1, 1, 1, 0.85)
|
||||||
|
local p = self:getDrawPos()
|
||||||
|
love.graphics.draw(self.sprite, p.x, p.y, 0, drawScale, drawScale)
|
||||||
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
|
end
|
||||||
56
room.lua
56
room.lua
|
|
@ -17,6 +17,7 @@ require "generic_skewer"
|
||||||
require "generic_spiky"
|
require "generic_spiky"
|
||||||
require "generic_unmoveable"
|
require "generic_unmoveable"
|
||||||
require "generic_player_blocker"
|
require "generic_player_blocker"
|
||||||
|
require "note"
|
||||||
|
|
||||||
local Movement = require "movement"
|
local Movement = require "movement"
|
||||||
local Wire = require "wire"
|
local Wire = require "wire"
|
||||||
|
|
@ -31,6 +32,7 @@ function Room:initialize(t)
|
||||||
self.collideables = { red = {}, green = {}, blue = {} }
|
self.collideables = { red = {}, green = {}, blue = {} }
|
||||||
self.playerBlockers = { red = {}, green = {}, blue = {} }
|
self.playerBlockers = { red = {}, green = {}, blue = {} }
|
||||||
self.npcs = {}
|
self.npcs = {}
|
||||||
|
self.notes = {}
|
||||||
self.activeColors = {red = false, green = false, blue = false}
|
self.activeColors = {red = false, green = false, blue = false}
|
||||||
self.colorsPlayerHas = {}
|
self.colorsPlayerHas = {}
|
||||||
|
|
||||||
|
|
@ -172,6 +174,16 @@ function Room:draw(drawChannels)
|
||||||
for _, switch in ipairs(self.wiredSwitches) do switch:draw(channel) end
|
for _, switch in ipairs(self.wiredSwitches) do switch:draw(channel) end
|
||||||
for _, npc in ipairs(self.npcs) do npc:draw(channel) end
|
for _, npc in ipairs(self.npcs) do npc:draw(channel) end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Notes are an editor-only overlay: shown only while the editor build is
|
||||||
|
-- running (DEBUG) and the NOTES_VISIBLE toggle is on. Drawn once (not per
|
||||||
|
-- channel) in alpha so the faint icon reads as itself instead of screen-adding.
|
||||||
|
if DEBUG and NOTES_VISIBLE and #self.notes > 0 then
|
||||||
|
local mode, alphaMode = love.graphics.getBlendMode()
|
||||||
|
love.graphics.setBlendMode("alpha")
|
||||||
|
for _, note in ipairs(self.notes) do note:draw() end
|
||||||
|
love.graphics.setBlendMode(mode, alphaMode)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Room:wireTracksAt(cell, create)
|
function Room:wireTracksAt(cell, create)
|
||||||
|
|
@ -739,6 +751,11 @@ function Room:createEntity(class, color, x, y, data)
|
||||||
self:registerNpc(entity)
|
self:registerNpc(entity)
|
||||||
return entity
|
return entity
|
||||||
end
|
end
|
||||||
|
if class == "note" then
|
||||||
|
local entity = Note:new(x, y, data.text)
|
||||||
|
self:registerNote(entity)
|
||||||
|
return entity
|
||||||
|
end
|
||||||
|
|
||||||
local props = globalAssetProperties and globalAssetProperties[class]
|
local props = globalAssetProperties and globalAssetProperties[class]
|
||||||
local behavior = props and props.class or "immoveable"
|
local behavior = props and props.class or "immoveable"
|
||||||
|
|
@ -857,6 +874,22 @@ function Room:registerNpc(entity)
|
||||||
table.insert(self.npcs, entity)
|
table.insert(self.npcs, entity)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Room:registerNote(entity)
|
||||||
|
-- Notes are like switches: a passable object kept in their own registry, so
|
||||||
|
-- serialize's note loop round-trips them and movement never sees them (their
|
||||||
|
-- "none" collision means canPassOver, so they are not stamped into a matrix).
|
||||||
|
table.insert(self.notes, entity)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- The note (if any) under a given grid cell — used by the editor's hover/click.
|
||||||
|
function Room:noteAtCell(cell)
|
||||||
|
if not cell then return nil end
|
||||||
|
for _, note in ipairs(self.notes) do
|
||||||
|
if note:occupiesCell(cell) then return note end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
function Room:getCellFromMousePos(mouseX, mouseY)
|
function Room:getCellFromMousePos(mouseX, mouseY)
|
||||||
if gameWorld and gameWorld.levels and gameWorld.levels[self.name] == self and
|
if gameWorld and gameWorld.levels and gameWorld.levels[self.name] == self and
|
||||||
not gameWorld.drawingRoomNeighborhood then
|
not gameWorld.drawingRoomNeighborhood then
|
||||||
|
|
@ -933,6 +966,11 @@ function Room:attemptDeleteAtCell(cell, color)
|
||||||
for index = #self.npcs, 1, -1 do
|
for index = #self.npcs, 1, -1 do
|
||||||
if self.npcs[index]:occupiesCell(cell) then table.remove(self.npcs, index) end
|
if self.npcs[index]:occupiesCell(cell) then table.remove(self.npcs, index) end
|
||||||
end
|
end
|
||||||
|
-- Notes are non-collidable and colourless, so a right-click removes them
|
||||||
|
-- regardless of the currently selected editor colour.
|
||||||
|
for index = #self.notes, 1, -1 do
|
||||||
|
if self.notes[index]:occupiesCell(cell) then table.remove(self.notes, index) end
|
||||||
|
end
|
||||||
self:tick()
|
self:tick()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -940,7 +978,19 @@ function Room:attemptDelete(mouseX, mouseY, color)
|
||||||
return self:attemptDeleteAtCell(self:getCellFromMousePos(mouseX, mouseY), color)
|
return self:attemptDeleteAtCell(self:getCellFromMousePos(mouseX, mouseY), color)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Room:attemptPlaceAtCell(name, props, cell, color)
|
function Room:attemptPlaceAtCell(name, props, cell, color, text)
|
||||||
|
-- Notes are colourless, single-instance annotations (no per-channel sprites),
|
||||||
|
-- so they place once carrying their text rather than one copy per colour. One
|
||||||
|
-- note per cell: drop any note already here before adding the new one.
|
||||||
|
if name == "note" then
|
||||||
|
if not cell then return end
|
||||||
|
for index = #self.notes, 1, -1 do
|
||||||
|
if self.notes[index]:occupiesCell(cell) then table.remove(self.notes, index) end
|
||||||
|
end
|
||||||
|
self:createEntity("note", nil, cell.x, cell.y, { text = text })
|
||||||
|
self:tick()
|
||||||
|
return
|
||||||
|
end
|
||||||
if not props or not props.sprites then return end
|
if not props or not props.sprites then return end
|
||||||
if not cell then return end
|
if not cell then return end
|
||||||
-- Jorge is one dialogable NPC with three display channels, not three
|
-- Jorge is one dialogable NPC with three display channels, not three
|
||||||
|
|
@ -1101,6 +1151,10 @@ function Room:serialize(includePlayers)
|
||||||
table.insert(objects, { class = npc.saveClass or "npc", x = npc.x, y = npc.y })
|
table.insert(objects, { class = npc.saveClass or "npc", x = npc.x, y = npc.y })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
for _, note in ipairs(self.notes) do
|
||||||
|
table.insert(objects, { class = "note", x = note.x, y = note.y, text = note.text })
|
||||||
|
end
|
||||||
|
|
||||||
return { objects = objects, wires = self:serializeWires() }
|
return { objects = objects, wires = self:serializeWires() }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
6
rooms/room_05_15.sav
Normal file
6
rooms/room_05_15.sav
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
objects={
|
||||||
|
},
|
||||||
|
wires={
|
||||||
|
}
|
||||||
|
}
|
||||||
711
rooms/sticky_test_5.sav
Normal file
711
rooms/sticky_test_5.sav
Normal file
|
|
@ -0,0 +1,711 @@
|
||||||
|
{
|
||||||
|
objects={
|
||||||
|
{
|
||||||
|
class="player",
|
||||||
|
x=4,
|
||||||
|
color="green",
|
||||||
|
active=true,
|
||||||
|
y=9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
class="player",
|
||||||
|
x=4,
|
||||||
|
color="blue",
|
||||||
|
active=true,
|
||||||
|
y=9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
class="player",
|
||||||
|
x=4,
|
||||||
|
color="red",
|
||||||
|
active=true,
|
||||||
|
y=9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=10,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=9,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=8,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=6,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=5,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=6,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=7,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=5,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=4,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=3,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=2,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=3,
|
||||||
|
class="david_small",
|
||||||
|
x=7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
y=3,
|
||||||
|
class="the_scream",
|
||||||
|
x=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=10,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=9,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=8,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=6,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=5,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=6,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=7,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=5,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=4,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=3,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=2,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=3,
|
||||||
|
class="david_small",
|
||||||
|
x=7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
y=3,
|
||||||
|
class="the_scream",
|
||||||
|
x=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=11,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=10,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=9,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=8,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=6,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=5,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=6,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=7,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=5,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=4,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=3,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=2,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=1,
|
||||||
|
class="static_wall",
|
||||||
|
x=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=3,
|
||||||
|
class="david_small",
|
||||||
|
x=7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
y=3,
|
||||||
|
class="the_scream",
|
||||||
|
x=2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
wires={
|
||||||
|
}
|
||||||
|
}
|
||||||
1139
rooms/testing_sticky_3.sav
Normal file
1139
rooms/testing_sticky_3.sav
Normal file
File diff suppressed because it is too large
Load diff
831
rooms/testing_sticky_4.sav
Normal file
831
rooms/testing_sticky_4.sav
Normal file
|
|
@ -0,0 +1,831 @@
|
||||||
|
{
|
||||||
|
objects={
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=1,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=2,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=3,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=4,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=5,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=6,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=7,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=8,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=9,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=10,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=10,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=9,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=8,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=7,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=5,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=4,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=3,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=2,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=1,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=11,
|
||||||
|
class="door",
|
||||||
|
y=9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=2,
|
||||||
|
class="static_wall",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=2,
|
||||||
|
class="static_wall",
|
||||||
|
y=9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=6,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=1,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=2,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=3,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=4,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=5,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=6,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=7,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=8,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=9,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=10,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=10,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=9,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=8,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=7,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=5,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=4,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=3,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=2,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=1,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=11,
|
||||||
|
class="door",
|
||||||
|
y=9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=2,
|
||||||
|
class="static_wall",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=2,
|
||||||
|
class="static_wall",
|
||||||
|
y=9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=6,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=1,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=2,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=3,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=4,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=5,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=6,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=7,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=8,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=9,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=10,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=11,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=10,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=9,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=8,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=7,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=5,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=4,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=3,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=2,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=1,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=11,
|
||||||
|
class="door",
|
||||||
|
y=9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=2,
|
||||||
|
class="static_wall",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=2,
|
||||||
|
class="static_wall",
|
||||||
|
y=9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=6,
|
||||||
|
class="static_wall",
|
||||||
|
y=1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=7,
|
||||||
|
class="player_blocker",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=8,
|
||||||
|
class="player_blocker",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=9,
|
||||||
|
class="player_blocker",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=10,
|
||||||
|
class="player_blocker",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=7,
|
||||||
|
class="player_blocker",
|
||||||
|
y=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=7,
|
||||||
|
class="player_blocker",
|
||||||
|
y=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=7,
|
||||||
|
class="player_blocker",
|
||||||
|
y=4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=7,
|
||||||
|
class="player_blocker",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=8,
|
||||||
|
class="player_blocker",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=9,
|
||||||
|
class="player_blocker",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=10,
|
||||||
|
class="player_blocker",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=7,
|
||||||
|
class="player_blocker",
|
||||||
|
y=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=7,
|
||||||
|
class="player_blocker",
|
||||||
|
y=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=7,
|
||||||
|
class="player_blocker",
|
||||||
|
y=4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=7,
|
||||||
|
class="player_blocker",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=8,
|
||||||
|
class="player_blocker",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=9,
|
||||||
|
class="player_blocker",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=10,
|
||||||
|
class="player_blocker",
|
||||||
|
y=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=7,
|
||||||
|
class="player_blocker",
|
||||||
|
y=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=7,
|
||||||
|
class="player_blocker",
|
||||||
|
y=3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=7,
|
||||||
|
class="player_blocker",
|
||||||
|
y=4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="red",
|
||||||
|
x=10,
|
||||||
|
class="switch",
|
||||||
|
y=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="green",
|
||||||
|
x=10,
|
||||||
|
class="switch",
|
||||||
|
y=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color="blue",
|
||||||
|
x=10,
|
||||||
|
class="switch",
|
||||||
|
y=2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text="right now it's possible to like...strand the sticky block\
|
||||||
|
here if it's at the end of one of the Ls and you push it with the other l.\
|
||||||
|
\
|
||||||
|
\
|
||||||
|
is this something we can address? it would require the reset\
|
||||||
|
block but idk. the only other thing is making it so\
|
||||||
|
there's always a sticky and one non sticky. if you have\
|
||||||
|
mopre than one nonsticky it will always be possible to strand \
|
||||||
|
at certain depths of playerblockers.\
|
||||||
|
",
|
||||||
|
x=5,
|
||||||
|
class="note",
|
||||||
|
y=3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
wires={
|
||||||
|
}
|
||||||
|
}
|
||||||
240
rooms/world.sav
240
rooms/world.sav
|
|
@ -1,272 +1,292 @@
|
||||||
{
|
{
|
||||||
width=18,
|
|
||||||
height=18,
|
|
||||||
lastRoom="testing_sticky",
|
|
||||||
rooms={
|
rooms={
|
||||||
{
|
{
|
||||||
y=10,
|
y=10,
|
||||||
x=10,
|
name="3",
|
||||||
name="3"
|
x=10
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=10,
|
y=10,
|
||||||
x=12,
|
name="5",
|
||||||
name="5"
|
x=12
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=9,
|
y=9,
|
||||||
x=12,
|
name="village_1",
|
||||||
name="village_1"
|
x=12
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=8,
|
y=8,
|
||||||
x=11,
|
name="village_4",
|
||||||
name="village_4"
|
x=11
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=7,
|
y=7,
|
||||||
x=11,
|
name="yellow_1",
|
||||||
name="yellow_1"
|
x=11
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=6,
|
y=6,
|
||||||
x=11,
|
name="yellow_3",
|
||||||
name="yellow_3"
|
x=11
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=7,
|
y=7,
|
||||||
x=12,
|
name="yellow_2",
|
||||||
name="yellow_2"
|
x=12
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=5,
|
y=5,
|
||||||
x=11,
|
name="yellow_4",
|
||||||
name="yellow_4"
|
x=11
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=4,
|
y=4,
|
||||||
x=11,
|
name="yellow_5",
|
||||||
name="yellow_5"
|
x=11
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=5,
|
y=5,
|
||||||
x=10,
|
name="yellow_6",
|
||||||
name="yellow_6"
|
x=10
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=1,
|
y=1,
|
||||||
x=1,
|
name="default",
|
||||||
name="default"
|
x=1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=1,
|
y=1,
|
||||||
x=3,
|
name="old_yellow_3",
|
||||||
name="old_yellow_3"
|
x=3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=1,
|
y=1,
|
||||||
x=5,
|
name="test_patt",
|
||||||
name="test_patt"
|
x=5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=1,
|
y=1,
|
||||||
x=7,
|
name="test_patt_update",
|
||||||
name="test_patt_update"
|
x=7
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=1,
|
y=1,
|
||||||
x=9,
|
name="white_asymmetrical",
|
||||||
name="white_asymmetrical"
|
x=9
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=1,
|
y=1,
|
||||||
x=11,
|
name="white_ok",
|
||||||
name="white_ok"
|
x=11
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=1,
|
y=1,
|
||||||
x=13,
|
name="white_primary",
|
||||||
name="white_primary"
|
x=13
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=1,
|
y=1,
|
||||||
x=15,
|
name="yellow_arches",
|
||||||
name="yellow_arches"
|
x=15
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=1,
|
y=1,
|
||||||
x=17,
|
name="yellow_asymmetrical",
|
||||||
name="yellow_asymmetrical"
|
x=17
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=3,
|
y=3,
|
||||||
x=1,
|
name="yellow_cc_moustache",
|
||||||
name="yellow_cc_moustache"
|
x=1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=3,
|
y=3,
|
||||||
x=3,
|
name="yellow_color_changing_levvel_1",
|
||||||
name="yellow_color_changing_levvel_1"
|
x=3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=3,
|
y=3,
|
||||||
x=7,
|
name="yellow_smile",
|
||||||
name="yellow_smile"
|
x=7
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=10,
|
y=10,
|
||||||
x=9,
|
name="2",
|
||||||
name="2"
|
x=9
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=9,
|
y=9,
|
||||||
x=11,
|
name="room_11_09",
|
||||||
name="room_11_09"
|
x=11
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=3,
|
y=3,
|
||||||
x=9,
|
name="yellow_skull",
|
||||||
name="yellow_skull"
|
x=9
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=5,
|
y=5,
|
||||||
x=5,
|
name="jorge_room",
|
||||||
name="jorge_room"
|
x=5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=10,
|
y=10,
|
||||||
x=11,
|
name="4",
|
||||||
name="4"
|
x=11
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=5,
|
y=5,
|
||||||
x=1,
|
name="room_01_05",
|
||||||
name="room_01_05"
|
x=1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=8,
|
y=8,
|
||||||
x=2,
|
name="ok",
|
||||||
name="ok"
|
x=2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=18,
|
y=18,
|
||||||
x=5,
|
name="room_05_18",
|
||||||
name="room_05_18"
|
x=5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=11,
|
y=11,
|
||||||
x=9,
|
name="village_start",
|
||||||
name="village_start"
|
x=9
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=8,
|
y=8,
|
||||||
x=4,
|
name="spiky_test",
|
||||||
name="spiky_test"
|
x=4
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=7,
|
y=7,
|
||||||
x=5,
|
name="corner_trimino_test",
|
||||||
name="corner_trimino_test"
|
x=5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=7,
|
y=7,
|
||||||
x=6,
|
name="tetromino_loop_t",
|
||||||
name="tetromino_loop_t"
|
x=6
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=6,
|
y=6,
|
||||||
x=5,
|
name="corner_trimino_test_copy",
|
||||||
name="corner_trimino_test_copy"
|
x=5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=7,
|
y=7,
|
||||||
x=7,
|
name="blocker_test",
|
||||||
name="blocker_test"
|
x=7
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=8,
|
y=8,
|
||||||
x=5,
|
name="spiky_test_2",
|
||||||
name="spiky_test_2"
|
x=5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=9,
|
y=9,
|
||||||
x=5,
|
name="spiky_test_3",
|
||||||
name="spiky_test_3"
|
x=5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=14,
|
y=14,
|
||||||
x=3,
|
name="jorge2",
|
||||||
name="jorge2"
|
x=3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=7,
|
y=7,
|
||||||
x=8,
|
name="room_08_07",
|
||||||
name="room_08_07"
|
x=8
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=8,
|
y=8,
|
||||||
x=13,
|
name="village_3",
|
||||||
name="village_3"
|
x=13
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=8,
|
y=8,
|
||||||
x=12,
|
name="village_2",
|
||||||
name="village_2"
|
x=12
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=7,
|
y=7,
|
||||||
x=14,
|
name="room_14_07",
|
||||||
name="room_14_07"
|
x=14
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=13,
|
y=13,
|
||||||
x=9,
|
name="room_09_13",
|
||||||
name="room_09_13"
|
x=9
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=13,
|
y=13,
|
||||||
x=8,
|
name="room_08_13",
|
||||||
name="room_08_13"
|
x=8
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=15,
|
y=15,
|
||||||
x=9,
|
name="room_10_15",
|
||||||
name="room_10_15"
|
x=9
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=14,
|
y=14,
|
||||||
x=14,
|
name="room_14_14",
|
||||||
name="room_14_14"
|
x=14
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=13,
|
y=13,
|
||||||
x=13,
|
name="room_13_13",
|
||||||
name="room_13_13"
|
x=13
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=14,
|
y=14,
|
||||||
x=12,
|
name="room_12_14",
|
||||||
name="room_12_14"
|
x=12
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=14,
|
y=14,
|
||||||
x=13,
|
name="room_13_14",
|
||||||
name="room_13_14"
|
x=13
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=13,
|
y=13,
|
||||||
x=5,
|
name="testing_sticky",
|
||||||
name="testing_sticky"
|
x=5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=13,
|
y=13,
|
||||||
x=6,
|
name="testing_sticky_two",
|
||||||
name="testing_sticky_two"
|
x=6
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
y=14,
|
y=14,
|
||||||
x=5,
|
name="room_05_14",
|
||||||
name="room_05_14"
|
x=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
y=16,
|
||||||
|
name="testing_sticky_3",
|
||||||
|
x=5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
y=16,
|
||||||
|
name="testing_sticky_4",
|
||||||
|
x=6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
y=16,
|
||||||
|
name="sticky_test_5",
|
||||||
|
x=7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
y=15,
|
||||||
|
name="room_05_15",
|
||||||
|
x=5
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
width=18,
|
||||||
|
height=18,
|
||||||
|
lastRoom="testing_sticky_3"
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue