diff --git a/Changes.md b/Changes.md index 79edca6..e5fbc47 100644 --- a/Changes.md +++ b/Changes.md @@ -1,5 +1,93 @@ # Changes +## v0.8.0 (TBD) + +To Do: +* Thief needs animations +* New levels + +This release brings some new features, new doodads, and new levels. + +New features: + +* **All Characters are Playable!** Use the Link Tool to connect your + Start Flag with another doodad on your level, and you will play + **as** that doodad when the level starts. The Creature doodads are + all intended to be fully functional; playing as buttons and doors + leads to strange results. + +New doodads have been added: + +* The **Anvil** is a heavy metal object which is affected by gravity. + It is harmless to collision, but if the anvil is in freefall, it + will destroy every mobile doodad that it touches, and is deadly + to the player character. +* The **Electric Trapdoor** is a trapdoor that opens and closes when + powered by a button or switch. It is a horizontal version of the + Electric Door. +* The **Thief** is a new character which will steal items from the + player or other mobile doodads. The Thief is able to pick up items + and unlock doors and he walks back and forth like the Azulians. +* The **Blue Azulian** is now selectable from the Doodads menu. It + behaves like the Red Azulian but moves at half the speed. The + Azulians can pick up items and open doors. + +Some doodads have changed behavior: + +* The **Bird** can no longer pick up items, unless controlled by + the player character. +* The **Anvil** and **Box** will reset to their original locations + if they receive a power signal from a linked button or switch. + +The user interface has been improved: + +* **Tabbed windows!** The Doodad Dropper window of the level editor + and the Settings window use new, tabbed interfaces. +* **Doodad Categories:** the Doodad Dropper's tabs are divided into + a few major categories. + 1. Objects: Anvil, Box, Crumbly Floor, and Flags + 2. Doors: Doors, Trapdoors, and Keys + 3. Gizmos: Buttons, Switches, Electric Doors, etc. + 4. Creatures: Bird, Azulians, Thief + 5. All: a classic view paging over all doodads (and doodads + not fitting any of the above categories). + + doodad edit-doodad --tag "categories=doors,gizmos" filename.doodad + +New functions are available in the JavaScript API for custom doodads: + +* FailLevel(message string): global function that kills the player + with a custom death message. +* Self.MoveTo(Point(x, y int)) +* Self.IsPlayer() bool +* Self.SetInventory(bool): turn on or off inventory. Keys and other + items will now only give themselves to mobile doodads which have + inventory. +* Self.HasInventory() bool +* Self.AddItem(filename string, quantity int) - zero quantity for + permanent items like the colored keys. +* Self.RemoveItem(filename string, quantity int) +* Self.HasItem(filename string) +* Self.Inventory() map[string]int + +The Events.OnLeave() callback now receives a CollideEvent argument, +like OnCollide, instead of the useless actor ID string. Notable +properties on the CollideEvent will be the .Actor which is leaving +and Settled=true. + +Other miscellaneous changes: + +* The **Link Tool** can now un-link two doodads by clicking on + them again. +* Actor UUIDs in your levels will now be Type 1 UUIDs (time-based) + instead of random. This will ensure each newly added doodad gets + a larger ID than the previous one, so in cases of draw order + conflicts or that sort of thing, the winner can be picked + deterministically (most recently added renders on top). +* A **death barrier** will prevent Boy from falling forever on unbounded + maps should he somehow fall off the level. The death barrier is a + Y value 1,000 pixels below the lowest pixel on your map. + ## v0.7.2 (July 19 2021) This release brings some new features and some new content. diff --git a/pkg/cheats.go b/pkg/cheats.go index 8ba5909..99a19b6 100644 --- a/pkg/cheats.go +++ b/pkg/cheats.go @@ -1,5 +1,7 @@ package doodle +import "git.kirsle.net/apps/doodle/pkg/balance" + // cheatCommand is a subroutine of the Command.Run() method of the Doodle // developer shell (commands.go). It looks for special cheat codes entered // into the command shell and executes them. @@ -86,6 +88,22 @@ func (c Command) cheatCommand(d *Doodle) bool { d.Flash("Use this cheat in Play Mode to clear your inventory.") } + case "fly like a bird": + balance.PlayerCharacterDoodad = "bird-red.doodad" + d.Flash("Set default player character to Bird (red)") + + case "pinocchio": + balance.PlayerCharacterDoodad = "boy.doodad" + d.Flash("Set default player character to Boy") + + case "the cell": + balance.PlayerCharacterDoodad = "azu-blu.doodad" + d.Flash("Set default player character to Blue Azulian") + + case "play as thief": + balance.PlayerCharacterDoodad = "thief.doodad" + d.Flash("Set default player character to Thief") + default: return false } diff --git a/pkg/play_scene.go b/pkg/play_scene.go index 977b6dd..b1d9385 100644 --- a/pkg/play_scene.go +++ b/pkg/play_scene.go @@ -27,10 +27,11 @@ type PlayScene struct { HasNext bool // has a next level to load next // Private variables. - d *Doodle - drawing *uix.Canvas - scripting *scripting.Supervisor - running bool + d *Doodle + drawing *uix.Canvas + scripting *scripting.Supervisor + running bool + deathBarrier int // Y position of death barrier in case of falling OOB. // UI widgets. supervisor *ui.Supervisor @@ -211,6 +212,12 @@ func (s *PlayScene) setupAsync(d *Doodle) error { s.drawing.InstallActors(s.Level.Actors) } + // Choose a death barrier in case the user falls off the map, + // so they don't fall forever. + worldSize := s.Level.Chunker.WorldSize() + s.deathBarrier = worldSize.H + 1000 + log.Debug("Death barrier at %d", s.deathBarrier) + // Set the loading screen text with the level metadata. loadscreen.SetSubtitle( s.Level.Title, @@ -257,7 +264,7 @@ func (s *PlayScene) setupPlayer() { playerCharacterFilename = balance.PlayerCharacterDoodad spawn render.Point - flag *level.Actor + flag = &level.Actor{} flagSize = render.NewRect(86, 86) // TODO: start-flag.doodad is 86x86 px flagCount int ) @@ -483,6 +490,11 @@ func (s *PlayScene) Loop(d *Doodle, ev *event.State) error { log.Error("Drawing loop error: %s", err.Error()) } + // Check if the player hit the death barrier. + if s.Player.Position().Y > s.deathBarrier { + s.DieByFire("falling off the map") + } + // Update the inventory HUD. s.computeInventory() }