Doodads: Small Key Door + Bigger Crumbly Floor
* The crumbly floor doodad was made 50% larger. * New doodad: Small Key and Small Key Door. These work like the colored doors and locks except each Small Key is consumed when it unlocks a door. The door's appearance is of iron bars. * The inventory HUD displays a small quantity label in the lower-right corner of items that have a quantity, such as the Small Key. This is done as a Canvas.CornerLabel string attribute on uix.Canvas. * The "give all keys" cheat adds 99 Small Keys to your inventory.
|
@ -1,6 +1,6 @@
|
||||||
// Crumbly Floor.
|
// Crumbly Floor.
|
||||||
function main() {
|
function main() {
|
||||||
Self.SetHitbox(0, 0, 65, 7);
|
Self.SetHitbox(0, 0, 98, 11);
|
||||||
|
|
||||||
Self.AddAnimation("shake", 100, ["shake1", "shake2", "floor", "shake1", "shake2", "floor"]);
|
Self.AddAnimation("shake", 100, ["shake1", "shake2", "floor", "shake1", "shake2", "floor"]);
|
||||||
Self.AddAnimation("fall", 100, ["fall1", "fall2", "fall3", "fall4"]);
|
Self.AddAnimation("fall", 100, ["fall1", "fall2", "fall3", "fall4"]);
|
||||||
|
|
Before Width: | Height: | Size: 1021 B After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 986 B After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 957 B After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 855 B After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 652 B After Width: | Height: | Size: 415 B |
Before Width: | Height: | Size: 868 B After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 897 B After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 891 B After Width: | Height: | Size: 1.0 KiB |
|
@ -18,13 +18,9 @@ doodad convert -t "Yellow Door" yellow-closed.png yellow-unlocked.png yellow-rig
|
||||||
doodad edit-doodad -q --tag color=yellow door-yellow.doodad
|
doodad edit-doodad -q --tag color=yellow door-yellow.doodad
|
||||||
doodad install-script colored-door.js door-yellow.doodad
|
doodad install-script colored-door.js door-yellow.doodad
|
||||||
|
|
||||||
# doodad convert -t "Green Door" green1.png green2.png door-green.doodad
|
doodad convert -t "Small Key Door" small-closed.png small-unlocked.png small-right.png small-left.png small-key-door.doodad
|
||||||
# doodad edit-doodad -q --tag color=green door-green.doodad
|
doodad edit-doodad -q --tag color=small small-key-door.doodad
|
||||||
# doodad install-script locked-door.js door-green.doodad
|
doodad install-script colored-door.js small-key-door.doodad
|
||||||
#
|
|
||||||
# doodad convert -t "Yellow Door" yellow1.png yellow2.png door-yellow.doodad
|
|
||||||
# doodad edit-doodad -q --tag color=yellow door-yellow.doodad
|
|
||||||
# doodad install-script locked-door.js door-yellow.doodad
|
|
||||||
|
|
||||||
doodad convert -t "Red Key" red-key.png key-red.doodad
|
doodad convert -t "Red Key" red-key.png key-red.doodad
|
||||||
doodad edit-doodad -q --tag color=red key-red.doodad
|
doodad edit-doodad -q --tag color=red key-red.doodad
|
||||||
|
@ -42,7 +38,11 @@ doodad convert -t "Yellow Key" yellow-key.png key-yellow.doodad
|
||||||
doodad edit-doodad -q --tag color=yellow key-yellow.doodad
|
doodad edit-doodad -q --tag color=yellow key-yellow.doodad
|
||||||
doodad install-script keys.js key-yellow.doodad
|
doodad install-script keys.js key-yellow.doodad
|
||||||
|
|
||||||
|
doodad convert -t "Small Key" small-key.png small-key.doodad
|
||||||
|
doodad edit-doodad -q --tag color=small small-key.doodad
|
||||||
|
doodad install-script keys.js small-key.doodad
|
||||||
|
|
||||||
doodad convert -t "Electric Door" electric{1,2,3,4}.png door-electric.doodad
|
doodad convert -t "Electric Door" electric{1,2,3,4}.png door-electric.doodad
|
||||||
doodad install-script electric-door.js door-electric.doodad
|
doodad install-script electric-door.js door-electric.doodad
|
||||||
|
|
||||||
cp door-*.doodad key-*.doodad ../../../assets/doodads/
|
cp door-*.doodad key-*.doodad small-*.doodad ../../../assets/doodads/
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
function main() {
|
function main() {
|
||||||
var color = Self.GetTag("color");
|
var color = Self.GetTag("color");
|
||||||
var keyname = "key-" + color + ".doodad";
|
var keyname = color === "small" ? "small-key.doodad" : "key-" + color + ".doodad";
|
||||||
|
|
||||||
// Layers in the doodad image.
|
// Layers in the doodad image.
|
||||||
var layer = {
|
var layer = {
|
||||||
|
@ -46,7 +46,12 @@ function main() {
|
||||||
if (e.Settled) {
|
if (e.Settled) {
|
||||||
unlocked = true;
|
unlocked = true;
|
||||||
Self.ShowLayer(enterSide < 0 ? layer.right : layer.left);
|
Self.ShowLayer(enterSide < 0 ? layer.right : layer.left);
|
||||||
Sound.Play("unlock.wav")
|
Sound.Play("unlock.wav");
|
||||||
|
|
||||||
|
// If a Small Key door, consume a small key.
|
||||||
|
if (color === "small") {
|
||||||
|
e.Actor.RemoveItem(keyname, 1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
function main() {
|
function main() {
|
||||||
var color = Self.GetTag("color");
|
var color = Self.GetTag("color");
|
||||||
|
var quantity = color === "small" ? 1 : 0;
|
||||||
|
|
||||||
Events.OnCollide(function(e) {
|
Events.OnCollide(function(e) {
|
||||||
if (e.Settled) {
|
if (e.Settled) {
|
||||||
Sound.Play("item-get.wav")
|
Sound.Play("item-get.wav")
|
||||||
e.Actor.AddItem(Self.Filename, 0);
|
e.Actor.AddItem(Self.Filename, quantity);
|
||||||
Self.Destroy();
|
Self.Destroy();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
BIN
dev-assets/doodads/doors/small-closed.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
dev-assets/doodads/doors/small-key.png
Normal file
After Width: | Height: | Size: 682 B |
BIN
dev-assets/doodads/doors/small-left.png
Normal file
After Width: | Height: | Size: 935 B |
BIN
dev-assets/doodads/doors/small-right.png
Normal file
After Width: | Height: | Size: 936 B |
BIN
dev-assets/doodads/doors/small-unlocked.png
Normal file
After Width: | Height: | Size: 932 B |
|
@ -72,6 +72,7 @@ func (c Command) cheatCommand(d *Doodle) bool {
|
||||||
playScene.Player.AddItem("key-blue.doodad", 0)
|
playScene.Player.AddItem("key-blue.doodad", 0)
|
||||||
playScene.Player.AddItem("key-green.doodad", 0)
|
playScene.Player.AddItem("key-green.doodad", 0)
|
||||||
playScene.Player.AddItem("key-yellow.doodad", 0)
|
playScene.Player.AddItem("key-yellow.doodad", 0)
|
||||||
|
playScene.Player.AddItem("small-key.doodad", 99)
|
||||||
d.Flash("Given all keys to the player character.")
|
d.Flash("Given all keys to the player character.")
|
||||||
} else {
|
} else {
|
||||||
d.Flash("Use this cheat in Play Mode to get all colored keys.")
|
d.Flash("Use this cheat in Play Mode to get all colored keys.")
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package doodle
|
package doodle
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"git.kirsle.net/apps/doodle/pkg/balance"
|
"git.kirsle.net/apps/doodle/pkg/balance"
|
||||||
"git.kirsle.net/apps/doodle/pkg/doodads"
|
"git.kirsle.net/apps/doodle/pkg/doodads"
|
||||||
"git.kirsle.net/apps/doodle/pkg/uix"
|
"git.kirsle.net/apps/doodle/pkg/uix"
|
||||||
|
@ -52,70 +54,77 @@ func (s *PlayScene) setupInventoryHud() {
|
||||||
// computeInventory adjusts the inventory HUD when the player's inventory changes.
|
// computeInventory adjusts the inventory HUD when the player's inventory changes.
|
||||||
func (s *PlayScene) computeInventory() {
|
func (s *PlayScene) computeInventory() {
|
||||||
items := s.Player.ListItems()
|
items := s.Player.ListItems()
|
||||||
if len(items) != len(s.invenItems) {
|
|
||||||
// Inventory has changed! See which doodads we have
|
|
||||||
// and which we need to load.
|
|
||||||
var seen = map[string]interface{}{}
|
|
||||||
for _, filename := range items {
|
|
||||||
seen[filename] = nil
|
|
||||||
|
|
||||||
if _, ok := s.invenDoodads[filename]; !ok {
|
// Inventory has changed! See which doodads we have
|
||||||
// Cache miss. Load the doodad here.
|
// and which we need to load.
|
||||||
doodad, err := doodads.LoadFile(filename)
|
var seen = map[string]interface{}{}
|
||||||
if err != nil {
|
for _, filename := range items {
|
||||||
s.d.Flash("Inventory item '%s' error: %s", filename, err)
|
seen[filename] = nil
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas := uix.NewCanvas(doodad.ChunkSize(), false)
|
if _, ok := s.invenDoodads[filename]; !ok {
|
||||||
canvas.LoadDoodad(doodad)
|
// Cache miss. Load the doodad here.
|
||||||
canvas.Resize(render.NewRect(
|
doodad, err := doodads.LoadFile(filename)
|
||||||
doodad.ChunkSize(), doodad.ChunkSize(),
|
if err != nil {
|
||||||
))
|
s.d.Flash("Inventory item '%s' error: %s", filename, err)
|
||||||
s.invenFrame.Pack(canvas, ui.Pack{
|
continue
|
||||||
Side: ui.W,
|
|
||||||
|
|
||||||
// TODO: work around a weird padding bug. item had too
|
|
||||||
// tall a top margin when added to the inventory frame!
|
|
||||||
PadX: 8,
|
|
||||||
})
|
|
||||||
s.invenDoodads[filename] = canvas
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s.invenDoodads[filename].Show()
|
canvas := uix.NewCanvas(doodad.ChunkSize(), false)
|
||||||
|
canvas.SetBackground(render.RGBA(1, 0, 0, 0))
|
||||||
|
canvas.LoadDoodad(doodad)
|
||||||
|
canvas.Resize(render.NewRect(
|
||||||
|
doodad.ChunkSize(), doodad.ChunkSize(),
|
||||||
|
))
|
||||||
|
s.invenFrame.Pack(canvas, ui.Pack{
|
||||||
|
Side: ui.W,
|
||||||
|
|
||||||
|
// TODO: work around a weird padding bug. item had too
|
||||||
|
// tall a top margin when added to the inventory frame!
|
||||||
|
PadX: 8,
|
||||||
|
})
|
||||||
|
s.invenDoodads[filename] = canvas
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide any doodad that used to be in the inventory but now is not.
|
// For items with >1 quantity, show the quantity in the corner.
|
||||||
for filename, canvas := range s.invenDoodads {
|
if qty := s.Player.HasItem(filename); qty > 0 {
|
||||||
if _, ok := seen[filename]; !ok {
|
s.invenDoodads[filename].CornerLabel = fmt.Sprintf("%d", qty)
|
||||||
canvas.Hide()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recompute the size of the inventory frame.
|
|
||||||
// TODO: this works around a bug in ui.Frame, at the bottom of
|
|
||||||
// compute_packed, a frame Resize's itself to fit the children but this
|
|
||||||
// trips the "manually set size" boolean... packing more items after a
|
|
||||||
// computer doesn't resize the frame. So here, we resize-auto it to
|
|
||||||
// reset that boolean so the next compute, picks the right size.
|
|
||||||
s.invenFrame.Configure(ui.Config{
|
|
||||||
AutoResize: true,
|
|
||||||
Width: 1,
|
|
||||||
Height: 1,
|
|
||||||
})
|
|
||||||
s.invenFrame.Compute(s.d.Engine)
|
|
||||||
|
|
||||||
// If we removed all items, hide the frame.
|
|
||||||
if len(items) == 0 {
|
|
||||||
s.invenFrame.Hide()
|
|
||||||
} else {
|
} else {
|
||||||
s.invenFrame.Show()
|
s.invenDoodads[filename].CornerLabel = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache the item list so we don't run the above logic every single tick.
|
s.invenDoodads[filename].Show()
|
||||||
s.invenItems = items
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hide any doodad that used to be in the inventory but now is not.
|
||||||
|
for filename, canvas := range s.invenDoodads {
|
||||||
|
if _, ok := seen[filename]; !ok {
|
||||||
|
canvas.Hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recompute the size of the inventory frame.
|
||||||
|
// TODO: this works around a bug in ui.Frame, at the bottom of
|
||||||
|
// compute_packed, a frame Resize's itself to fit the children but this
|
||||||
|
// trips the "manually set size" boolean... packing more items after a
|
||||||
|
// computer doesn't resize the frame. So here, we resize-auto it to
|
||||||
|
// reset that boolean so the next compute, picks the right size.
|
||||||
|
s.invenFrame.Configure(ui.Config{
|
||||||
|
AutoResize: true,
|
||||||
|
Width: 1,
|
||||||
|
Height: 1,
|
||||||
|
})
|
||||||
|
s.invenFrame.Compute(s.d.Engine)
|
||||||
|
|
||||||
|
// If we removed all items, hide the frame.
|
||||||
|
if len(items) == 0 {
|
||||||
|
s.invenFrame.Hide()
|
||||||
|
} else {
|
||||||
|
s.invenFrame.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache the item list so we don't run the above logic every single tick.
|
||||||
|
s.invenItems = items
|
||||||
|
|
||||||
// Compute the inventory frame so it positions and wraps the items.
|
// Compute the inventory frame so it positions and wraps the items.
|
||||||
s.screen.Compute(s.d.Engine)
|
s.screen.Compute(s.d.Engine)
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,7 +207,11 @@ func (a *Actor) SetNoclip(v bool) {
|
||||||
// Item name is usually the doodad filename.
|
// Item name is usually the doodad filename.
|
||||||
func (a *Actor) AddItem(itemName string, quantity int) {
|
func (a *Actor) AddItem(itemName string, quantity int) {
|
||||||
a.muInventory.Lock()
|
a.muInventory.Lock()
|
||||||
a.inventory[itemName] = quantity
|
if _, ok := a.inventory[itemName]; ok {
|
||||||
|
a.inventory[itemName] += quantity
|
||||||
|
} else {
|
||||||
|
a.inventory[itemName] = quantity
|
||||||
|
}
|
||||||
a.muInventory.Unlock()
|
a.muInventory.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,10 @@ type Canvas struct {
|
||||||
Scrollable bool // Cursor keys will scroll the viewport of this canvas.
|
Scrollable bool // Cursor keys will scroll the viewport of this canvas.
|
||||||
Zoom int // Zoom level on the canvas.
|
Zoom int // Zoom level on the canvas.
|
||||||
|
|
||||||
|
// Custom label to place in the lower-right corner of the canvas.
|
||||||
|
// Used for e.g. the quantity badge on Inventory items.
|
||||||
|
CornerLabel string
|
||||||
|
|
||||||
// Selected draw tool/mode, default Pencil, for editable canvases.
|
// Selected draw tool/mode, default Pencil, for editable canvases.
|
||||||
Tool drawtool.Tool
|
Tool drawtool.Tool
|
||||||
BrushSize int // thickness of selected brush
|
BrushSize int // thickness of selected brush
|
||||||
|
|
|
@ -152,6 +152,24 @@ func (w *Canvas) Present(e render.Engine, p render.Point) {
|
||||||
w.presentStrokes(e)
|
w.presentStrokes(e)
|
||||||
w.presentCursor(e)
|
w.presentCursor(e)
|
||||||
|
|
||||||
|
// Custom label in the canvas corner? (e.g. for Inventory item counts)
|
||||||
|
if w.CornerLabel != "" {
|
||||||
|
label := ui.NewLabel(ui.Label{
|
||||||
|
Text: w.CornerLabel,
|
||||||
|
Font: render.Text{
|
||||||
|
FontFilename: balance.ShellFontFilename,
|
||||||
|
Size: balance.ShellFontSizeSmall,
|
||||||
|
Color: render.White,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
label.SetBackground(render.RGBA(0, 0, 50, 150))
|
||||||
|
label.Compute(e)
|
||||||
|
label.Present(e, render.Point{
|
||||||
|
X: p.X + S.W - label.Size().W - w.BoxThickness(1),
|
||||||
|
Y: p.Y + S.H - label.Size().H - w.BoxThickness(1),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// XXX: Debug, show label in canvas corner.
|
// XXX: Debug, show label in canvas corner.
|
||||||
if balance.DebugCanvasLabel {
|
if balance.DebugCanvasLabel {
|
||||||
rows := []string{
|
rows := []string{
|
||||||
|
|