From 22c189d899f8183ef82f85b5bacb75f72242e17f Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Sun, 8 May 2022 14:19:34 -0700 Subject: [PATCH] v0.13.0 doodads --- doodads/azulian/Makefile | 5 + doodads/azulian/azulian-red.js | 43 ----- doodads/azulian/azulian.js | 135 ++++++++++++-- doodads/azulian/white-back.png | Bin 0 -> 1029 bytes doodads/azulian/white-front.png | Bin 0 -> 1004 bytes doodads/azulian/white-wl1.png | Bin 0 -> 1041 bytes doodads/azulian/white-wl2.png | Bin 0 -> 1062 bytes doodads/azulian/white-wl3.png | Bin 0 -> 1026 bytes doodads/azulian/white-wl4.png | Bin 0 -> 1002 bytes doodads/azulian/white-wr1.png | Bin 0 -> 994 bytes doodads/azulian/white-wr2.png | Bin 0 -> 1043 bytes doodads/azulian/white-wr3.png | Bin 0 -> 985 bytes doodads/azulian/white-wr4.png | Bin 0 -> 999 bytes doodads/bird/Makefile | 12 +- doodads/bird/bird.js | 249 +++++++++++++++++++++---- doodads/bird/blue/dive-left.png | Bin 0 -> 11089 bytes doodads/bird/blue/dive-right.png | Bin 0 -> 11215 bytes doodads/bird/blue/left-1.png | Bin 0 -> 12128 bytes doodads/bird/blue/left-2.png | Bin 0 -> 11421 bytes doodads/bird/blue/right-1.png | Bin 0 -> 12350 bytes doodads/bird/blue/right-2.png | Bin 0 -> 11476 bytes doodads/bird/{ => red}/dive-left.png | Bin doodads/bird/{ => red}/dive-right.png | Bin doodads/bird/{ => red}/left-1.png | Bin doodads/bird/{ => red}/left-2.png | Bin doodads/bird/{ => red}/right-1.png | Bin doodads/bird/{ => red}/right-2.png | Bin doodads/box/box.js | 29 ++- doodads/boy/Makefile | 2 + doodads/boy/boy.js | 56 ++++-- doodads/boy/idle-left-1.png | Bin 0 -> 11907 bytes doodads/boy/idle-left-2.png | Bin 0 -> 12497 bytes doodads/boy/idle-left-3.png | Bin 0 -> 12288 bytes doodads/boy/idle-right-1.png | Bin 0 -> 11884 bytes doodads/boy/idle-right-2.png | Bin 0 -> 12465 bytes doodads/boy/idle-right-3.png | Bin 0 -> 12267 bytes doodads/build.sh | 15 ++ doodads/buttons/button.js | 26 ++- doodads/buttons/sticky.js | 6 +- doodads/crumbly-floor/crumbly-floor.js | 23 +-- doodads/crusher/Makefile | 14 ++ doodads/crusher/angry.png | Bin 0 -> 2405 bytes doodads/crusher/crusher.js | 207 ++++++++++++++++++++ doodads/crusher/ouch.png | Bin 0 -> 2253 bytes doodads/crusher/peek-left.png | Bin 0 -> 2219 bytes doodads/crusher/peek-right.png | Bin 0 -> 2212 bytes doodads/crusher/sleep.png | Bin 0 -> 2106 bytes doodads/doors/colored-door.js | 22 ++- doodads/doors/electric-door.js | 25 ++- doodads/doors/keys.js | 16 +- doodads/doors/locked-door.js | 27 --- doodads/gems/Makefile | 58 ++++++ doodads/gems/blue-1.png | Bin 0 -> 891 bytes doodads/gems/blue-2.png | Bin 0 -> 927 bytes doodads/gems/blue-3.png | Bin 0 -> 903 bytes doodads/gems/blue-4.png | Bin 0 -> 835 bytes doodads/gems/gemstone.js | 24 +++ doodads/gems/green-1.png | Bin 0 -> 785 bytes doodads/gems/green-2.png | Bin 0 -> 807 bytes doodads/gems/green-3.png | Bin 0 -> 864 bytes doodads/gems/green-4.png | Bin 0 -> 835 bytes doodads/gems/red-1.png | Bin 0 -> 711 bytes doodads/gems/red-2.png | Bin 0 -> 702 bytes doodads/gems/red-3.png | Bin 0 -> 712 bytes doodads/gems/red-4.png | Bin 0 -> 724 bytes doodads/gems/totem-blue-0.png | Bin 0 -> 798 bytes doodads/gems/totem-blue-1.png | Bin 0 -> 958 bytes doodads/gems/totem-blue-2.png | Bin 0 -> 1005 bytes doodads/gems/totem-blue-3.png | Bin 0 -> 987 bytes doodads/gems/totem-blue-4.png | Bin 0 -> 921 bytes doodads/gems/totem-green-0.png | Bin 0 -> 711 bytes doodads/gems/totem-green-1.png | Bin 0 -> 887 bytes doodads/gems/totem-green-2.png | Bin 0 -> 938 bytes doodads/gems/totem-green-3.png | Bin 0 -> 978 bytes doodads/gems/totem-green-4.png | Bin 0 -> 956 bytes doodads/gems/totem-red-0.png | Bin 0 -> 752 bytes doodads/gems/totem-red-1.png | Bin 0 -> 811 bytes doodads/gems/totem-red-2.png | Bin 0 -> 805 bytes doodads/gems/totem-red-3.png | Bin 0 -> 790 bytes doodads/gems/totem-red-4.png | Bin 0 -> 817 bytes doodads/gems/totem-yellow-0.png | Bin 0 -> 837 bytes doodads/gems/totem-yellow-1.png | Bin 0 -> 1097 bytes doodads/gems/totem-yellow-2.png | Bin 0 -> 1082 bytes doodads/gems/totem-yellow-3.png | Bin 0 -> 1054 bytes doodads/gems/totem-yellow-4.png | Bin 0 -> 1062 bytes doodads/gems/totem.js | 100 ++++++++++ doodads/gems/yellow-1.png | Bin 0 -> 971 bytes doodads/gems/yellow-2.png | Bin 0 -> 921 bytes doodads/gems/yellow-3.png | Bin 0 -> 898 bytes doodads/gems/yellow-4.png | Bin 0 -> 879 bytes doodads/objects/anvil.js | 15 +- doodads/objects/checkpoint-flag.js | 32 +++- doodads/objects/exit-flag.js | 2 +- doodads/objects/start-flag.js | 5 +- doodads/on-off/state-block-blue.js | 6 +- doodads/on-off/state-block-orange.js | 6 +- doodads/on-off/state-button.js | 10 +- doodads/regions/Makefile | 11 +- doodads/regions/checkpoint-128.png | Bin 957 -> 956 bytes doodads/regions/checkpoint.js | 6 +- doodads/regions/fire.js | 2 +- doodads/regions/goal-128.png | Bin 986 -> 990 bytes doodads/regions/goal.js | 2 +- doodads/regions/power-64.png | Bin 873 -> 780 bytes doodads/regions/power.js | 2 +- doodads/regions/reset-timer.js | 30 +++ doodads/regions/stall.js | 8 +- doodads/regions/timer-64.png | Bin 0 -> 901 bytes doodads/regions/warp-door-64.png | Bin 0 -> 821 bytes doodads/snake/Makefile | 15 ++ doodads/snake/attack-left-1.png | Bin 0 -> 1202 bytes doodads/snake/attack-left-2.png | Bin 0 -> 1139 bytes doodads/snake/attack-left-3.png | Bin 0 -> 935 bytes doodads/snake/attack-right-1.png | Bin 0 -> 1201 bytes doodads/snake/attack-right-2.png | Bin 0 -> 1127 bytes doodads/snake/attack-right-3.png | Bin 0 -> 916 bytes doodads/snake/left-1.png | Bin 0 -> 1161 bytes doodads/snake/left-2.png | Bin 0 -> 1180 bytes doodads/snake/left-3.png | Bin 0 -> 1152 bytes doodads/snake/right-1.png | Bin 0 -> 1203 bytes doodads/snake/right-2.png | Bin 0 -> 1172 bytes doodads/snake/right-3.png | Bin 0 -> 1145 bytes doodads/snake/snake.js | 131 +++++++++++++ doodads/switches/switch.js | 11 +- doodads/thief/thief.js | 29 ++- doodads/trapdoors/down.js | 36 ---- doodads/trapdoors/trapdoor.js | 26 +-- doodads/warp-door/Makefile | 4 +- doodads/warp-door/warp-door.js | 87 ++++++--- 129 files changed, 1228 insertions(+), 342 deletions(-) delete mode 100644 doodads/azulian/azulian-red.js create mode 100644 doodads/azulian/white-back.png create mode 100644 doodads/azulian/white-front.png create mode 100644 doodads/azulian/white-wl1.png create mode 100644 doodads/azulian/white-wl2.png create mode 100644 doodads/azulian/white-wl3.png create mode 100644 doodads/azulian/white-wl4.png create mode 100644 doodads/azulian/white-wr1.png create mode 100644 doodads/azulian/white-wr2.png create mode 100644 doodads/azulian/white-wr3.png create mode 100644 doodads/azulian/white-wr4.png create mode 100644 doodads/bird/blue/dive-left.png create mode 100644 doodads/bird/blue/dive-right.png create mode 100644 doodads/bird/blue/left-1.png create mode 100644 doodads/bird/blue/left-2.png create mode 100644 doodads/bird/blue/right-1.png create mode 100644 doodads/bird/blue/right-2.png rename doodads/bird/{ => red}/dive-left.png (100%) rename doodads/bird/{ => red}/dive-right.png (100%) rename doodads/bird/{ => red}/left-1.png (100%) rename doodads/bird/{ => red}/left-2.png (100%) rename doodads/bird/{ => red}/right-1.png (100%) rename doodads/bird/{ => red}/right-2.png (100%) create mode 100644 doodads/boy/idle-left-1.png create mode 100644 doodads/boy/idle-left-2.png create mode 100644 doodads/boy/idle-left-3.png create mode 100644 doodads/boy/idle-right-1.png create mode 100644 doodads/boy/idle-right-2.png create mode 100644 doodads/boy/idle-right-3.png create mode 100644 doodads/crusher/Makefile create mode 100644 doodads/crusher/angry.png create mode 100644 doodads/crusher/crusher.js create mode 100644 doodads/crusher/ouch.png create mode 100644 doodads/crusher/peek-left.png create mode 100644 doodads/crusher/peek-right.png create mode 100644 doodads/crusher/sleep.png delete mode 100644 doodads/doors/locked-door.js create mode 100644 doodads/gems/Makefile create mode 100644 doodads/gems/blue-1.png create mode 100644 doodads/gems/blue-2.png create mode 100644 doodads/gems/blue-3.png create mode 100644 doodads/gems/blue-4.png create mode 100644 doodads/gems/gemstone.js create mode 100644 doodads/gems/green-1.png create mode 100644 doodads/gems/green-2.png create mode 100644 doodads/gems/green-3.png create mode 100644 doodads/gems/green-4.png create mode 100644 doodads/gems/red-1.png create mode 100644 doodads/gems/red-2.png create mode 100644 doodads/gems/red-3.png create mode 100644 doodads/gems/red-4.png create mode 100644 doodads/gems/totem-blue-0.png create mode 100644 doodads/gems/totem-blue-1.png create mode 100644 doodads/gems/totem-blue-2.png create mode 100644 doodads/gems/totem-blue-3.png create mode 100644 doodads/gems/totem-blue-4.png create mode 100644 doodads/gems/totem-green-0.png create mode 100644 doodads/gems/totem-green-1.png create mode 100644 doodads/gems/totem-green-2.png create mode 100644 doodads/gems/totem-green-3.png create mode 100644 doodads/gems/totem-green-4.png create mode 100644 doodads/gems/totem-red-0.png create mode 100644 doodads/gems/totem-red-1.png create mode 100644 doodads/gems/totem-red-2.png create mode 100644 doodads/gems/totem-red-3.png create mode 100644 doodads/gems/totem-red-4.png create mode 100644 doodads/gems/totem-yellow-0.png create mode 100644 doodads/gems/totem-yellow-1.png create mode 100644 doodads/gems/totem-yellow-2.png create mode 100644 doodads/gems/totem-yellow-3.png create mode 100644 doodads/gems/totem-yellow-4.png create mode 100644 doodads/gems/totem.js create mode 100644 doodads/gems/yellow-1.png create mode 100644 doodads/gems/yellow-2.png create mode 100644 doodads/gems/yellow-3.png create mode 100644 doodads/gems/yellow-4.png create mode 100644 doodads/regions/reset-timer.js create mode 100644 doodads/regions/timer-64.png create mode 100644 doodads/regions/warp-door-64.png create mode 100644 doodads/snake/Makefile create mode 100644 doodads/snake/attack-left-1.png create mode 100644 doodads/snake/attack-left-2.png create mode 100644 doodads/snake/attack-left-3.png create mode 100644 doodads/snake/attack-right-1.png create mode 100644 doodads/snake/attack-right-2.png create mode 100644 doodads/snake/attack-right-3.png create mode 100644 doodads/snake/left-1.png create mode 100644 doodads/snake/left-2.png create mode 100644 doodads/snake/left-3.png create mode 100644 doodads/snake/right-1.png create mode 100644 doodads/snake/right-2.png create mode 100644 doodads/snake/right-3.png create mode 100644 doodads/snake/snake.js delete mode 100644 doodads/trapdoors/down.js diff --git a/doodads/azulian/Makefile b/doodads/azulian/Makefile index 1fde043..d9e4930 100644 --- a/doodads/azulian/Makefile +++ b/doodads/azulian/Makefile @@ -14,6 +14,11 @@ build: doodad edit-doodad --tag "color=red" azu-red.doodad doodad install-script azulian.js azu-red.doodad + doodad convert -t "White Azulian" white-front.png white-back.png \ + white-wr{1,2,3,4}.png white-wl{1,2,3,4}.png azu-white.doodad + doodad edit-doodad --tag "color=white" azu-white.doodad + doodad install-script azulian.js azu-white.doodad + # Tag the category for these doodads for i in *.doodad; do\ doodad edit-doodad --tag "category=creatures" $${i};\ diff --git a/doodads/azulian/azulian-red.js b/doodads/azulian/azulian-red.js deleted file mode 100644 index aeb5f91..0000000 --- a/doodads/azulian/azulian-red.js +++ /dev/null @@ -1,43 +0,0 @@ -// Azulian (Red) -// DEPRECATED: they both share azulian.js now. - -function main() { - var playerSpeed = 4; - var gravity = 4; - var Vx = Vy = 0; - - var direction = "right"; - - Self.SetHitbox(0, 0, 32, 32) - Self.SetMobile(true); - Self.SetInventory(true); - Self.SetGravity(true); - Self.AddAnimation("walk-left", 100, ["red-wl1", "red-wl2", "red-wl3", "red-wl4"]); - Self.AddAnimation("walk-right", 100, ["red-wr1", "red-wr2", "red-wr3", "red-wr4"]); - - // Sample our X position every few frames and detect if we've hit a solid wall. - var sampleTick = 0; - var sampleRate = 5; - var lastSampledX = 0; - - setInterval(function () { - if (sampleTick % sampleRate === 0) { - var curX = Self.Position().X; - var delta = Math.abs(curX - lastSampledX); - if (delta < 5) { - direction = direction === "right" ? "left" : "right"; - } - lastSampledX = curX; - } - sampleTick++; - - // TODO: Vector() requires floats, pain in the butt for JS, - // the JS API should be friendlier and custom... - var Vx = parseFloat(playerSpeed * (direction === "left" ? -1 : 1)); - Self.SetVelocity(Vector(Vx, 0.0)); - - if (!Self.IsAnimating()) { - Self.PlayAnimation("walk-" + direction, null); - } - }, 100); -} diff --git a/doodads/azulian/azulian.js b/doodads/azulian/azulian.js index bd63b64..73e0943 100644 --- a/doodads/azulian/azulian.js +++ b/doodads/azulian/azulian.js @@ -1,12 +1,29 @@ // Azulian (Red and Blue) -var playerSpeed = 12, + +const color = Self.GetTag("color"); +var playerSpeed = color === 'blue' ? 2 : 4, + swimSpeed = playerSpeed * 0.4, + aggroX = 250, // X/Y distance sensitivity from player + aggroY = color === 'blue' ? 100 : 200, + jumpSpeed = color === 'blue' ? 14 : 18, + swimJumpSpeed = jumpSpeed * 0.4, animating = false, direction = "right", lastDirection = "right"; +// white Azulian is faster yet than the red +if (color === 'white') { + aggroX = 1000; + aggroY = 400; + playerSpeed = 8; + swimSpeed = playerSpeed * 0.4; + jumpSpeed = 20; + swimJumpSpeed = jumpSpeed * 0.4; +} + function setupAnimations(color) { - var left = color === 'blue' ? 'blu-wl' : 'red-wl', - right = color === 'blue' ? 'blu-wr' : 'red-wr', + let left = color === 'blue' ? 'blu-wl' : color + '-wl', + right = color === 'blue' ? 'blu-wr' : color + '-wr', leftFrames = [left + '1', left + '2', left + '3', left + '4'], rightFrames = [right + '1', right + '2', right + '3', right + '4']; @@ -15,9 +32,11 @@ function setupAnimations(color) { } function main() { - var color = Self.GetTag("color"); playerSpeed = color === 'blue' ? 2 : 4; + let swimJumpCooldownTick = 0, // minimum Game Tick before we can jump while swimming + swimJumpCooldown = 10; // CONFIG: delta of ticks between jumps while swimming + Self.SetMobile(true); Self.SetGravity(true); Self.SetInventory(true); @@ -32,23 +51,77 @@ function main() { // when it meets resistance. // Sample our X position every few frames and detect if we've hit a solid wall. - var sampleTick = 0; - var sampleRate = 5; - var lastSampledX = 0; - - setInterval(function () { - if (sampleTick % sampleRate === 0) { - var curX = Self.Position().X; - var delta = Math.abs(curX - lastSampledX); - if (delta < 5) { - direction = direction === "right" ? "left" : "right"; + let sampleTick = 0; + let sampleRate = 5; + let lastSampledX = 0; + + // Get the player on touch. + Events.OnCollide((e) => { + // If we're diving and we hit the player, game over! + // Azulians are friendly to Thieves though! + if (e.Settled && isPlayerFood(e.Actor)) { + FailLevel("Watch out for the Azulians!"); + return; + } + }); + + setInterval(() => { + // If the player is nearby, walk towards them. Otherwise, default pattern + // is to walk back and forth. + let player = Actors.FindPlayer(), + followPlayer = false, + jump = false; + + // Don't follow boring players. + if (player !== null && isPlayerFood(player)) { + let playerPt = player.Position(), + myPt = Self.Position(); + + // If the player is within aggro range, move towards. + if ((Math.abs(playerPt.X - myPt.X) < aggroX && Math.abs(playerPt.Y - myPt.Y) < aggroY) + || (Level.Difficulty > 0)) { + direction = playerPt.X < myPt.X ? "left" : "right"; + followPlayer = true; + + if (playerPt.Y + player.Size().H < myPt.Y + Self.Size().H) { + jump = true; + } + } + } + + // Default AI: sample position so we turn around on obstacles. + if (!followPlayer) { + if (sampleTick % sampleRate === 0) { + let curX = Self.Position().X; + let delta = Math.abs(curX - lastSampledX); + if (delta < 5) { + direction = direction === "right" ? "left" : "right"; + } + lastSampledX = curX; } - lastSampledX = curX; + sampleTick++; } - sampleTick++; - var Vx = parseFloat(playerSpeed * (direction === "left" ? -1 : 1)); - Self.SetVelocity(Vector(Vx, 0.0)); + // Handle being underwater. + let canJump = Self.Grounded(); + if (Self.IsWet()) { + let tick = GetTick(); + if (tick > swimJumpCooldownTick) { + canJump = true; + swimJumpCooldownTick = tick + swimJumpCooldown; + } + } + + // How speedy would our movement and jump be? + let xspeed = playerSpeed, yspeed = jumpSpeed; + if (Self.IsWet()) { + xspeed = swimSpeed; + yspeed = swimJumpSpeed; + } + + let Vx = parseFloat(xspeed * (direction === "left" ? -1 : 1)), + Vy = jump && canJump ? parseFloat(-yspeed) : Self.GetVelocity().Y; + Self.SetVelocity(Vector(Vx, Vy)); // If we changed directions, stop animating now so we can // turn around quickly without moonwalking. @@ -61,12 +134,12 @@ function main() { } lastDirection = direction; - }, 100); + }, 10); } function playerControls() { // Note: player speed is controlled by the engine. - Events.OnKeypress(function (ev) { + Events.OnKeypress((ev) => { if (ev.Right) { if (!Self.IsAnimating()) { Self.PlayAnimation("walk-right", null); @@ -81,3 +154,25 @@ function playerControls() { } }) } + +// Logic to decide if the player is interesting to the Azulian (aka, if the Azulian +// will be hostile towards the player). Boring players will not be chased after and +// the Azulian will not harm them if they make contact. +function isPlayerFood(actor) { + // Not a player or is invulnerable, or Peaceful difficulty. + if (!actor.IsPlayer() || actor.Invulnerable() || Level.Difficulty < 0) { + return false; + } + + // On hard mode they are hostile to any player. + if (Level.Difficulty > 0) { + return true; + } + + // Azulians are friendly to Thieves and other Azulians. + if (actor.Doodad().Filename === "thief.doodad" || actor.Doodad().Title.indexOf("Azulian") > -1) { + return false; + } + + return true; +} diff --git a/doodads/azulian/white-back.png b/doodads/azulian/white-back.png new file mode 100644 index 0000000000000000000000000000000000000000..12f0a740e3f9dc0fdefb681790ed4608412a5519 GIT binary patch literal 1029 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 QGf;-X)78&qol`;+08G`H-v9sr literal 0 HcmV?d00001 diff --git a/doodads/azulian/white-wl3.png b/doodads/azulian/white-wl3.png new file mode 100644 index 0000000000000000000000000000000000000000..a87537f553db50a80fddf5410bc07ba71e18efc4 GIT binary patch literal 1026 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vLGRFxF%`I|pPYCo?c;Ost(~>v1?h zq}4yz+f|FNOrZ2cz+9bW~QF;4C31NwbXxaNO|GBr}w|7e_d7C&B!>hVw&VK-#v~tdo!iyeD7SmMrHMp z=SPy&Vki8V_`2(O{+w<-ZX4sQv`e3l1SV~~anOr>^Q4u6{({Fte3#cKzTSAMvU_vb z%8l1-e{w5V)~3#Uy`^p95v6Ggjx9}6r&b(rn^QJdggev9|HlvZ*!?bgtud(vMLG+( zcsIRf|KEIn^H#3O!f`<=j4g38&y!g=-ZP!u^|(gf+V3+9haGcx)$RCP2IKiluHTM& z!|~!ao8G$Hvo^8EyklVYZ_7EgPGpIy2-kt%lC{BnFZQ!mUE8yB>$$>T3@I65E2SSi z5RlLf`nK!*?%meUzvcU9*V+GdEvhJY*m4>aDajr|z6=aiY77hwEes65fIzr%$ffT4FCWC_s(M02Z}S7 z1o;I6>0f0>?g1&rByV>Yw#2j@wLlJMfk$L91B0G22s2hJwJ!q-vX^-Jy0SlG6lP*k zI@o);04Oxm)5S4FVWer1_1)=3^ZE0n818MsIhRv(`+ujTikpV=X;b=LWM`b&BIO4681OVc=1~* zeAU)nGJ-E(n?Gjm-6(fs&jOSAKu1cJxJHyX=jZ08=9Mrw7o{eaq^2m8XO?6rxO@5r zgg5eu0~M))6r}*AtdhYh7>o>z40R2G$RfnR(8}1t%Ggrdz`)ADK+qr{0YyV@eoAIq zC2kD~xi9VjHAsVO0A?bqH6Ahz*%9LQrQc{bP zi!uvJGV}8oKn_(%D$UF((ap?LC=POW@=13T2C5c?sm@KzD@{vGE-5WaEdnd|nK$7S fPyruYL4HbV4g*MQbb_ZdP=>+N)z4*}Q$iB}EWe0o literal 0 HcmV?d00001 diff --git a/doodads/azulian/white-wl4.png b/doodads/azulian/white-wl4.png new file mode 100644 index 0000000000000000000000000000000000000000..74016073bbc65388fc9ed3ac96f4f9bd0a4a080f GIT binary patch literal 1002 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vLGRFxF%`I|pPYCo?c;Ost(~>v1?h zq}4yz+f|FNOrZ2cz+9bW~QF;4C31NwbXxaNO|GBr}w|7e_d7C&B!>hVw&VK-#v~tdo!iyeD7SmMrHMp z=SPy&Vki8V_`2(O{+w<-ZX4sQv`e3l1SV~~anOr>^Q4u6{({Fte3#cKzTSAMvU_vb z%8l1-e{w5V)~3#Uy`^p95v6Ggjx9}6r&b(rn^QJdggev9|HlvZ*!?bgtud(vMLG+( zcsIRf|KEIn^H#3O!f`<=j4g38&y!g=-ZP!u^|(gf+V3+9haGcx)$RCP2IKiluHTM& z!|~!ao8G$Hvo^8EyklVYZ_7EgPGpIy2-kt%lC{BnFZQ!mUE8yB>$$>T3@I65E2SSi z5RlLf`nK!*?%meUzvcU9*V+GdEvhJY*m4>aDajr|z6=aiY77hwEes65fIOm3p^r=85s1GL71^(seKtxkiEpy*OmPlqc9V@h^myR z7Eq|o)5S4Ff)u3yrL2;{Dj19mj0|-R zfyg4nz|hLr!phiE+rYrez(CL-AOS@~ZhlH;S|x4`3Ar!s05wR1Yyf5!tK|HG%A(Bl zj1q=`(xjZsWCfS}+{DbhZ4(Wnfy$I%%2HB`lZ!G7N;32F7(fnHNGi?DDbdZ$Qz#B{ zck)Sh6b7mmg{jU>%qvYxOfD%cN-Y8__n9~06i@*lTtR+HY7PTPYjlFAGf;-X)78&q Iol`;+0A)md!2kdN literal 0 HcmV?d00001 diff --git a/doodads/azulian/white-wr1.png b/doodads/azulian/white-wr1.png new file mode 100644 index 0000000000000000000000000000000000000000..d9c26d1cbbdf0596f7360a911a278555f6106170 GIT binary patch literal 994 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vLGRFxF%`I|pPYCo?c;Ost(~>v1?h zq}4yz+f|FNOrZ2cz+9bW~QF;4C31NwbXxaNO|GBr}w|7e_d7C&B!>hVw&VK-#v~tdo!iyeD7SmMrHMp z=SPy&Vki8V_`2(O{+w<-ZX4sQv`e3l1SV~~anOr>^Q4u6{({Fte3#cKzTSAMvU_vb z%8l1-e{w5V)~3#Uy`^p95v6Ggjx9}6r&b(rn^QJdggev9|HlvZ*!?bgtud(vMLG+( zcsIRf|KEIn^H#3O!f`<=j4g38&y!g=-ZP!u^|(gf+V3+9haGcx)$RCP2IKiluHTM& z!|~!ao8G$Hvo^8EyklVYZ_7EgPGpIy2-kt%lC{BnFZQ!mUE8yB>$$>T3@I65E2SSi z5RlLf`nK!*?%meUzvcU9*V+GdEvhJY*m4>aDajr|z6=aiY77hwEes65fITT$X?><>&pI&QJ9HE?}YXIXrNG| zr;B5V#`(1q4)QV^a- z=Xft_wS5sw#WIM3mX1dm`g=e9oIZ5p>G|)UnQ$= zz3J@g@@+4}z6crrU|>6^TJ)dmOKHi%caL)!Tg}tg^YZIUpkpLUTq8=H^K)}k z^GX<;i&7IyQd1PlGfOfQ+&z5*!W;R-fr?Z?ic)}5R>@!$3`PbQch;F zf=hmGVrJg9iH4w{Q-Uc=Ni9w;$}A|!%+F&0IaDF3G&83}H#1M6ILO_}C*4sPs9F@J yIyW(|G%Yc?q_ilt2&~*^-h@*?1$=M?`6;P63?Qx137*bC83s>RKbLh*2~7ZAdwjM4 literal 0 HcmV?d00001 diff --git a/doodads/azulian/white-wr2.png b/doodads/azulian/white-wr2.png new file mode 100644 index 0000000000000000000000000000000000000000..1a1a56680c69979ff4e316bee7765121261f5ba4 GIT binary patch literal 1043 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vLGRFxF%`I|pPYCo?c;Ost(~>v1?h zq}4yz+f|FNOrZ2cz+9bW~QF;4C31NwbXxaNO|GBr}w|7e_d7C&B!>hVw&VK-#v~tdo!iyeD7SmMrHMp z=SPy&Vki8V_`2(O{+w<-ZX4sQv`e3l1SV~~anOr>^Q4u6{({Fte3#cKzTSAMvU_vb z%8l1-e{w5V)~3#Uy`^p95v6Ggjx9}6r&b(rn^QJdggev9|HlvZ*!?bgtud(vMLG+( zcsIRf|KEIn^H#3O!f`<=j4g38&y!g=-ZP!u^|(gf+V3+9haGcx)$RCP2IKiluHTM& z!|~!ao8G$Hvo^8EyklVYZ_7EgPGpIy2-kt%lC{BnFZQ!mUE8yB>$$>T3@I65E2SSi z5RlLf`nK!*?%meUzvcU9*V+GdEvhJY*m4>aDajr|z6=aiY77hwEes65fIzr%$ffT3^QlW{Qv*|9J9x1 zKq=;uAirQB{j2QAJs`!H zlfS;Kmk9b*{)vBu_5{%vN{LflLDes;&AvP1}WXTfOh!W@g+}zZ> z5(ej@)Wnk16ovB4k_-iRPv3y>Mm}+%B2|#06rhwc2YH@N=Wo8nRyDuLGDgI>5jrc)uJ%f yxruqDX^F`trA4VlVC6pZCY%B);Dam3Pf5*T0BMa*@N@>sFnGH9xvXv1?h zq}4yz+f|FNOrZ2cz+9bW~QF;4C31NwbXxaNO|GBr}w|7e_d7C&B!>hVw&VK-#v~tdo!iyeD7SmMrHMp z=SPy&Vki8V_`2(O{+w<-ZX4sQv`e3l1SV~~anOr>^Q4u6{({Fte3#cKzTSAMvU_vb z%8l1-e{w5V)~3#Uy`^p95v6Ggjx9}6r&b(rn^QJdggev9|HlvZ*!?bgtud(vMLG+( zcsIRf|KEIn^H#3O!f`<=j4g38&y!g=-ZP!u^|(gf+V3+9haGcx)$RCP2IKiluHTM& z!|~!ao8G$Hvo^8EyklVYZ_7EgPGpIy2-kt%lC{BnFZQ!mUE8yB>$$>T3@I65E2SSi z5RlLf`nK!*?%meUzvcU9*V+GdEvhJY*m4>aDajr|z6=aiY77hwEes65fITT$X?><>&pI&QJ9Iv!sfjeD5X?* zx;TbtoL@WPAnySK4(3GWGi*zwxBPw|=KeR~*QzUjimVJ0zTN&T-ocsGWI82AlzGi1 zu6@f`4qg=%kVy|Vy75@x!Ohtg%CfrY{!h8rW?$2D-fAcj!!~)wD{}>n$o~5x52R0& zS$eJDNjOn?q-TA@VrN!cE#3!)c{9s-%%87VZ3=XQWQl7;iF1B#Zfaf$gL6@8Vo7R> zLV0FMhJw4NZ$Nk>pEyvFDo9ZZP|7M9tb)PFz{pV75Qr>73=FM|Ev$?!wG9lc3=9Mf z0uoR(Rtj{)RRg{0EVoD$v4JcZ&QcPF28M`569QJCu7#Jtk9#N?9F pqSPX=a-Vq4Eq~a*Is;`GJYD@<);T3K0RW;4beRAE literal 0 HcmV?d00001 diff --git a/doodads/azulian/white-wr4.png b/doodads/azulian/white-wr4.png new file mode 100644 index 0000000000000000000000000000000000000000..ee29adbdfdabb47217c607593423eab4aa8f26b6 GIT binary patch literal 999 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vLGRFxF%`I|pPYCo?c;Ost(~>v1?h zq}4yz+f|FNOrZ2cz+9bW~QF;4C31NwbXxaNO|GBr}w|7e_d7C&B!>hVw&VK-#v~tdo!iyeD7SmMrHMp z=SPy&Vki8V_`2(O{+w<-ZX4sQv`e3l1SV~~anOr>^Q4u6{({Fte3#cKzTSAMvU_vb z%8l1-e{w5V)~3#Uy`^p95v6Ggjx9}6r&b(rn^QJdggev9|HlvZ*!?bgtud(vMLG+( zcsIRf|KEIn^H#3O!f`<=j4g38&y!g=-ZP!u^|(gf+V3+9haGcx)$RCP2IKiluHTM& z!|~!ao8G$Hvo^8EyklVYZ_7EgPGpIy2-kt%lC{BnFZQ!mUE8yB>$$>T3@I65E2SSi z5RlLf`nK!*?%meUzvcU9*V+GdEvhJY*m4>aDajr|z6=aiY77hwEes65fIOm3p^r=85s1GL71^(seKtxkiEpy*OmPlqc9UYgZ+Vn z;Xt8gPZ!4!jq`ISUgT|X;BfBeV4i#6$lvry-aa~a=GW}oviDH$$MO`$7YD36 z)HW8F2*k-+u6Ur*>9aw8{t*M?GA2GlzKL79KUqsn2&lVZ(>$f&#}-ZPoM!?JTbId& zeGiS_mff{x)0`FZ7iTG~<_|f(Hhk}|vdv1f^TRs>bmo6Q$GlmM*S*U8nibGFk|nMY zCC>S|xv6<249-QVi6yBi3gww484B*6z5(HleBwYwsvt!vKq;$aunGnv10zFSLm;vU zF)*|;wy-j`)HX1%GB6M{2uMKDkei>9nO2EgLqhJ0J3tN6ARB-=#VR?!pt2}4J)?vn zpfo8bGg-kUKQ}QmZ`(w}XrMABn6i}A;^d;tf|AVqJO+?M6_QFbb4qkG^Aw7M+?{;V z9fg6aMPaIQ6Z1;b5|c|xi&Bfg%6;ZdI0aO|2Un1vlA6N+(i)xM=?s)%@O1TaS?83{ F1OSKvepLVf literal 0 HcmV?d00001 diff --git a/doodads/bird/Makefile b/doodads/bird/Makefile index e70fedc..d0ff88d 100644 --- a/doodads/bird/Makefile +++ b/doodads/bird/Makefile @@ -2,9 +2,17 @@ ALL: build .PHONY: build build: - doodad convert -t "Bird (red)" left-1.png left-2.png right-1.png right-2.png \ - dive-left.png dive-right.png bird-red.doodad + doodad convert -t "Bird (red)" red/left-1.png red/left-2.png red/right-1.png \ + red/right-2.png red/dive-left.png red/dive-right.png \ + bird-red.doodad doodad install-script bird.js bird-red.doodad + doodad edit-doodad --tag "color=red" bird-red.doodad + + doodad convert -t "Bird (blue)" blue/left-1.png blue/left-2.png blue/right-1.png \ + blue/right-2.png blue/dive-left.png blue/dive-right.png \ + bird-blue.doodad + doodad install-script bird.js bird-blue.doodad + doodad edit-doodad --tag "color=blue" bird-blue.doodad # Tag the category for these doodads for i in *.doodad; do\ diff --git a/doodads/bird/bird.js b/doodads/bird/bird.js index 5d94ebe..9a236d8 100644 --- a/doodads/bird/bird.js +++ b/doodads/bird/bird.js @@ -1,18 +1,36 @@ -// Bird +// Bird (red and blue) -function main() { - var speed = 4; - var Vx = Vy = 0; - var altitude = Self.Position().Y; // original height in the level - - var direction = "left", - lastDirection = "left"; - var states = { - flying: 0, - diving: 1, - }; - var state = states.flying; +/* +Base A.I. behaviors (red bird) are: + +- Tries to maintain original altitude in level and flies left/right. +- Divebombs the player to attack, then climbs back to its original + altitude when it hits a floor/wall. + +Blue bird: + +- Flies in a sine wave pattern (its target altitude fluctuates + around the bird's original placement on the level). +- Longer aggro radius to dive. +*/ +let speed = 4, + Vx = Vy = 0, + color = Self.GetTag("color"), // informs our A.I. behaviors + searchStep = 12 // pixels to step while searching for a player + searchLimit = color === "blue" ? 24 : 12, // multiples of searchStep for aggro radius + altitude = Self.Position().Y, // original height in level + targetAltitude = altitude; // bird's target height to maintain + +let direction = "left", + lastDirection = "left"; +let states = { + flying: 0, + diving: 1, +}; +let state = states.flying; + +function main() { Self.SetMobile(true); Self.SetGravity(false); Self.SetHitbox(0, 0, 46, 32); @@ -24,33 +42,75 @@ function main() { return player(); } - Events.OnCollide(function (e) { - if (e.Actor.IsMobile() && e.InHitbox) { + Events.OnCollide((e) => { + // If we're diving and we hit the player, game over! + if (e.Settled && state === states.diving && e.Actor.IsPlayer()) { + FailLevel("Watch out for birds!"); + return; + } + + if (e.Actor.IsMobile() && e.Actor.HasGravity() && e.InHitbox) { return false; } }); // Sample our X position every few frames and detect if we've hit a solid wall. - var sampleTick = 0; - var sampleRate = 2; - var lastSampledX = 0; - var lastSampledY = 0; + let sampleTick = 0, + sampleRate = 2, + lastSampled = Point(0, 0); + + setInterval(() => { + // Run blue bird A.I. if we are blue: moves our target altitude along a sine wave. + if (color === "blue") { + AI_BlueBird(); + } - setInterval(function () { + // Sample how far we've moved to detect hitting a wall. if (sampleTick % sampleRate === 0) { - var curX = Self.Position().X; - var delta = Math.abs(curX - lastSampledX); + let curP = Self.Position() + let delta = Math.abs(curP.X - lastSampled.X); if (delta < 5) { direction = direction === "right" ? "left" : "right"; } - lastSampledX = curX; + + // If we were diving, check Y delta too for if we hit floor + if (state === states.diving && Math.abs(curP.Y - lastSampled.Y) < 5) { + state = states.flying; + } + lastSampled = curP } sampleTick++; + // Are we diving? + if (state === states.diving) { + Vy = speed + } else { + // If we are not flying at our original altitude, correct for that. + let curV = Self.Position(); + Vy = 0.0; + if (curV.Y != targetAltitude) { + Vy = curV.Y < targetAltitude ? 1 : -1; + } + + // Scan for the player character and dive. + try { + AI_ScanForPlayer() + } catch (e) { + console.error("Error in AI_ScanForPlayer: %s", e); + } + } + // TODO: Vector() requires floats, pain in the butt for JS, // the JS API should be friendlier and custom... - var Vx = parseFloat(speed * (direction === "left" ? -1 : 1)); - Self.SetVelocity(Vector(Vx, 0.0)); + let Vx = parseFloat(speed * (direction === "left" ? -1 : 1)); + Self.SetVelocity(Vector(Vx, Vy)); + + // If diving, exit - don't edit animation. + if (state === states.diving) { + Self.ShowLayerNamed("dive-" + direction); + lastDirection = direction; + return; + } // If we changed directions, stop animating now so we can // turn around quickly without moonwalking. @@ -66,34 +126,149 @@ function main() { }, 100); } +// A.I. subroutine: scan for the player character. +// The bird scans in a 45 degree angle downwards, if the +// player is seen nearby in that scan it will begin a dive. +// It's not hostile towards characters that can fly (having +// no gravity). +function AI_ScanForPlayer() { + // If Peaceful difficulty, do not attack. + if (Level.Difficulty < 0) { + return + } + + let stepY = searchStep, // number of pixels to skip + stepX = stepY, + limit = stepX * searchLimit, // furthest we'll scan + scanX = scanY = 0, + size = Self.Size(), + fromPoint = Self.Position(); + + // From what point do we begin the scan? + if (direction === 'left') { + stepX = -stepX; + fromPoint.Y += size.H; + } else { + fromPoint.Y += size.H; + fromPoint.X += size.W; + } + + scanX = fromPoint.X; + scanY = fromPoint.Y; + + for (let i = 0; i < limit; i += stepY) { + scanX += stepX; + scanY += stepY; + for (let actor of Actors.At(Point(scanX, scanY))) { + if (actor.IsPlayer() && actor.HasGravity()) { + state = states.diving; + return; + } + } + } + + return; +} + +// Sine wave controls for the Blue bird. +var sineLimit = 32, + sineCounter = 0, + sineDirection = 1, + sineFrequency = 5, // every 500ms + sineStep = 16; + +// A.I. Subroutine: sine wave pattern (Blue bird). +function AI_BlueBird() { + // The main loop runs on a 100ms interval, control how frequently + // to adjust the bird's target velocity. + if (sineCounter > 0 && (sineCounter % sineFrequency) > 1) { + sineCounter++; + return; + } + sineCounter++; + + targetAltitude += sineStep*sineDirection; + + // Cap the distance between our starting altitude and sine-wave target. + if (targetAltitude < altitude && altitude - targetAltitude >= sineLimit) { + targetAltitude = altitude - sineLimit; + sineDirection = 1 + } else if (targetAltitude > altitude && targetAltitude - altitude >= sineLimit) { + targetAltitude = altitude + sineLimit; + sineDirection = -1 + } +} + // If under control of the player character. function player() { - Self.SetInventory(true); - Events.OnKeypress(function (ev) { + let playerSpeed = 12, + diving = false, + falling = false; + + // The player can dive by moving downwards and laterally, but + // de-cheese their ability to just sweep across the ground; if + // they aren't seen to be moving downwards, cancel the dive. + let lastPoint = Self.Position(); + setInterval(() => { + let nowAt = Self.Position(); + if (nowAt.Y > lastPoint.Y) { + falling = true; + } else { + falling = false; + } + lastPoint = nowAt; + }, 100); + + Events.OnKeypress((ev) => { Vx = 0; Vy = 0; - if (ev.Up) { - Vy = -playerSpeed; - } else if (ev.Down) { - Vy = playerSpeed; + if (ev.Right) { + direction = "right"; + } else if (ev.Left) { + direction = "left"; } - if (ev.Right) { + // Dive! + if (ev.Down && ev.Right && falling) { + Self.StopAnimation(); + Self.ShowLayerNamed("dive-right"); + diving = falling; + } else if (ev.Down && ev.Left && falling) { + Self.StopAnimation(); + Self.ShowLayerNamed("dive-left"); + diving = falling; + } else if (ev.Right) { + // Fly right. if (!Self.IsAnimating()) { Self.PlayAnimation("fly-right", null); } Vx = playerSpeed; + diving = false; } else if (ev.Left) { + // Fly left. if (!Self.IsAnimating()) { Self.PlayAnimation("fly-left", null); } Vx = -playerSpeed; + diving = false; } else { - Self.StopAnimation(); - animating = false; + // Hover in place. + if (!Self.IsAnimating()) { + Self.PlayAnimation("fly-" + direction); + } + diving = false; } - Self.SetVelocity(Vector(Vx, Vy)); - }) -} \ No newline at end of file + // Player is invulnerable while diving. + Self.SetInvulnerable(diving); + }); + + Events.OnCollide((e) => { + // If the player is diving at an enemy mob, destroy it. + if (diving && e.Settled && e.Actor.IsMobile() && !e.Actor.Invulnerable()) { + Sound.Play("crumbly-break.wav"); + e.Actor.Destroy(); + } + }); +} diff --git a/doodads/bird/blue/dive-left.png b/doodads/bird/blue/dive-left.png new file mode 100644 index 0000000000000000000000000000000000000000..1c2f7b77fdd39559b53e77890f8d4fae3a4505bd GIT binary patch literal 11089 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 literal 0 HcmV?d00001 diff --git a/doodads/bird/blue/left-1.png b/doodads/bird/blue/left-1.png new file mode 100644 index 0000000000000000000000000000000000000000..e988064e317c760ece46902874a83247e1b5bead GIT binary patch literal 12128 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 vB$94S?u`?+k{)+O@geuR#PEy+zbS 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 literal 0 HcmV?d00001 diff --git a/doodads/bird/blue/right-1.png b/doodads/bird/blue/right-1.png new file mode 100644 index 0000000000000000000000000000000000000000..7c63982b8167c567652782ddd2409dae6c011b21 GIT binary patch literal 12350 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 literal 0 HcmV?d00001 diff --git a/doodads/bird/dive-left.png b/doodads/bird/red/dive-left.png similarity index 100% rename from doodads/bird/dive-left.png rename to doodads/bird/red/dive-left.png diff --git a/doodads/bird/dive-right.png b/doodads/bird/red/dive-right.png similarity index 100% rename from doodads/bird/dive-right.png rename to doodads/bird/red/dive-right.png diff --git a/doodads/bird/left-1.png b/doodads/bird/red/left-1.png similarity index 100% rename from doodads/bird/left-1.png rename to doodads/bird/red/left-1.png diff --git a/doodads/bird/left-2.png b/doodads/bird/red/left-2.png similarity index 100% rename from doodads/bird/left-2.png rename to doodads/bird/red/left-2.png diff --git a/doodads/bird/right-1.png b/doodads/bird/red/right-1.png similarity index 100% rename from doodads/bird/right-1.png rename to doodads/bird/red/right-1.png diff --git a/doodads/bird/right-2.png b/doodads/bird/red/right-2.png similarity index 100% rename from doodads/bird/right-2.png rename to doodads/bird/red/right-2.png diff --git a/doodads/box/box.js b/doodads/box/box.js index 30d3d6a..0ca950a 100644 --- a/doodads/box/box.js +++ b/doodads/box/box.js @@ -1,23 +1,32 @@ // Pushable Box. -var speed = 4; -var size = 75; + +const speed = 4, + size = 75; function main() { Self.SetMobile(true); + Self.SetInvulnerable(true); Self.SetGravity(true); Self.SetHitbox(0, 0, size, size); - Events.OnCollide(function (e) { + Events.OnCollide((e) => { // Ignore events from neighboring Boxes. if (e.Actor.Actor.Filename === "box.doodad") { return false; } if (e.Actor.IsMobile() && e.InHitbox) { - var overlap = e.Overlap; + let overlap = e.Overlap; if (overlap.Y === 0 && !(overlap.X === 0 && overlap.W < 5) && !(overlap.X === size)) { - // Standing on top, ignore. + // Be sure to position them snug on top. + // TODO: this might be a nice general solution in the + // collision detector... + e.Actor.MoveTo(Point( + e.Actor.Position().X, + Self.Position().Y - e.Actor.Hitbox().Y - e.Actor.Hitbox().H - 2, + )) + e.Actor.SetGrounded(true); return false; } else if (overlap.Y === size) { // From the bottom, boop it up. @@ -39,8 +48,8 @@ function main() { }); // When we receive power, we reset to our original position. - var origPoint = Self.Position(); - Message.Subscribe("power", function (powered) { + let origPoint = Self.Position(); + Message.Subscribe("power", (powered) => { Self.MoveTo(origPoint); Self.SetVelocity(Vector(0, 0)); }); @@ -52,8 +61,8 @@ function main() { function animate() { Self.AddAnimation("animate", 100, [0, 1, 2, 3, 2, 1]); - var running = false; - setInterval(function () { + let running = false; + setInterval(() => { if (!running) { running = true; Self.PlayAnimation("animate", function () { @@ -61,4 +70,4 @@ function animate() { }) } }, 100); -} \ No newline at end of file +} diff --git a/doodads/boy/Makefile b/doodads/boy/Makefile index 39d98a8..aaa98ed 100644 --- a/doodads/boy/Makefile +++ b/doodads/boy/Makefile @@ -5,6 +5,8 @@ build: doodad convert -t "Boy" stand-right.png stand-left.png \ walk-right-1.png walk-right-2.png walk-right-3.png \ walk-left-1.png walk-left-2.png walk-left-3.png \ + idle-right-1.png idle-right-2.png idle-right-3.png \ + idle-left-1.png idle-left-2.png idle-left-3.png \ boy.doodad doodad install-script boy.js boy.doodad diff --git a/doodads/boy/boy.js b/doodads/boy/boy.js index 02f877b..c62bf8d 100644 --- a/doodads/boy/boy.js +++ b/doodads/boy/boy.js @@ -1,38 +1,62 @@ -function main() { - var playerSpeed = 12; - var gravity = 4; - var Vx = Vy = 0; +const playerSpeed = 12; - var animating = false; - var animStart = animEnd = 0; - var animFrame = animStart; +let Vx = Vy = 0, + walking = false, + direction = "right", + lastDirection = direction; +function main() { Self.SetMobile(true); Self.SetInventory(true); Self.SetGravity(true); Self.SetHitbox(0, 0, 32, 52); Self.AddAnimation("walk-left", 200, ["stand-left", "walk-left-1", "walk-left-2", "walk-left-3", "walk-left-2", "walk-left-1"]); Self.AddAnimation("walk-right", 200, ["stand-right", "walk-right-1", "walk-right-2", "walk-right-3", "walk-right-2", "walk-right-1"]); + Self.AddAnimation("idle-left", 200, ["idle-left-1", "idle-left-2", "idle-left-3", "idle-left-2"]); + Self.AddAnimation("idle-right", 200, ["idle-right-1", "idle-right-2", "idle-right-3", "idle-right-2"]); + + // If the player suddenly changes direction, reset the animation state to quickly switch over. + let lastVelocity = Vector(0, 0); - Events.OnKeypress(function (ev) { + Events.OnKeypress((ev) => { Vx = 0; Vy = 0; + let curVelocity = Self.GetVelocity(); + if ((lastVelocity.X < 0 && curVelocity.X > 0) || + (lastVelocity.X > 0 && curVelocity.X < 0)) { + Self.StopAnimation(); + } + lastVelocity = curVelocity; + lastDirection = direction; + + let wasWalking = walking; if (ev.Right) { - if (!Self.IsAnimating()) { - Self.PlayAnimation("walk-right", null); - } + direction = "right"; Vx = playerSpeed; + walking = true; } else if (ev.Left) { - if (!Self.IsAnimating()) { - Self.PlayAnimation("walk-left", null); - } + direction = "left"; Vx = -playerSpeed; + walking = true; } else { + // Has stopped walking! + walking = false; + stoppedWalking = true; + } + + // Should we stop animating? (changed state) + if (direction !== lastDirection || wasWalking !== walking) { Self.StopAnimation(); - animating = false; } - // Self.SetVelocity(Point(Vx, Vy)); + // And play what animation? + if (!Self.IsAnimating()) { + if (walking) { + Self.PlayAnimation("walk-"+direction, null); + } else { + Self.PlayAnimation("idle-"+direction, null); + } + } }) } diff --git a/doodads/boy/idle-left-1.png b/doodads/boy/idle-left-1.png new file mode 100644 index 0000000000000000000000000000000000000000..ca649292a568fc86c6c00a6fad7f27b312900f56 GIT binary patch literal 11907 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 literal 0 HcmV?d00001 diff --git a/doodads/boy/idle-left-2.png b/doodads/boy/idle-left-2.png new file mode 100644 index 0000000000000000000000000000000000000000..192388bceaad66b6eca9f63b2ad0aa1d3d2b2c8e GIT binary patch literal 12497 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 F{{Uj>o~!@> literal 0 HcmV?d00001 diff --git a/doodads/boy/idle-left-3.png b/doodads/boy/idle-left-3.png new file mode 100644 index 0000000000000000000000000000000000000000..7c0aa438a346943e60040cf773bfdd59c4cfa2dd GIT binary patch literal 12288 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 V*C!jf`8^E*YD$`lwepss{|Ea|zLWp} literal 0 HcmV?d00001 diff --git a/doodads/boy/idle-right-3.png b/doodads/boy/idle-right-3.png new file mode 100644 index 0000000000000000000000000000000000000000..345b43f0b599260ed764cf731ce1fff59fb5c52d GIT binary patch literal 12267 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 literal 0 HcmV?d00001 diff --git a/doodads/build.sh b/doodads/build.sh index 6bc41eb..a668a3e 100755 --- a/doodads/build.sh +++ b/doodads/build.sh @@ -34,6 +34,10 @@ doors() { cd doors/ make cd .. + + cd gems/ + make + cd .. } trapdoors() { @@ -84,6 +88,16 @@ warpdoor() { cd .. } +creatures() { + cd snake/ + make + cd .. + + cd crusher/ + make + cd .. +} + boy buttons switches @@ -94,6 +108,7 @@ mobs objects onoff warpdoor +creatures doodad edit-doodad -quiet -lock -author "Noah" ../../assets/doodads/*.doodad doodad edit-doodad ../../assets/doodads/azu-blu.doodad doodad edit-doodad -hide ../../assets/doodads/boy.doodad diff --git a/doodads/buttons/button.js b/doodads/buttons/button.js index c31e342..a07bba2 100644 --- a/doodads/buttons/button.js +++ b/doodads/buttons/button.js @@ -1,19 +1,26 @@ function main() { - var timer = 0; - var pressed = false; + let timer = 0; + let pressed = false; // Has a linked Sticky Button been pressed permanently down? - var stickyDown = false; - Message.Subscribe("sticky:down", function(down) { + let stickyDown = false; + Message.Subscribe("sticky:down", (down) => { stickyDown = down; Self.ShowLayer(stickyDown ? 1 : 0); }); - Events.OnCollide(function(e) { + // Track who all is colliding with us. + let colliders = {}; + + Events.OnCollide((e) => { if (!e.Settled) { return; } + if (colliders[e.Actor.ID()] == undefined) { + colliders[e.Actor.ID()] = true; + } + // If a linked Sticky Button is pressed, button stays down too and // doesn't interact. if (stickyDown) { @@ -37,12 +44,17 @@ function main() { } Self.ShowLayer(1); - timer = setTimeout(function() { + }); + + Events.OnLeave((e) => { + delete colliders[e.Actor.ID()]; + + if (Object.keys(colliders).length === 0 && !stickyDown) { Sound.Play("button-up.wav") Self.ShowLayer(0); Message.Publish("power", false); timer = 0; pressed = false; - }, 200); + } }); } diff --git a/doodads/buttons/sticky.js b/doodads/buttons/sticky.js index 1702f8c..e9d6866 100644 --- a/doodads/buttons/sticky.js +++ b/doodads/buttons/sticky.js @@ -1,8 +1,8 @@ function main() { - var pressed = false; + let pressed = false; // When a sticky button receives power, it pops back up. - Message.Subscribe("power", function (powered) { + Message.Subscribe("power", (powered) => { if (powered && pressed) { Self.ShowLayer(0); pressed = false; @@ -12,7 +12,7 @@ function main() { } }) - Events.OnCollide(function (e) { + Events.OnCollide((e) => { if (!e.Settled) { return; } diff --git a/doodads/crumbly-floor/crumbly-floor.js b/doodads/crumbly-floor/crumbly-floor.js index c7bdf08..283bd65 100644 --- a/doodads/crumbly-floor/crumbly-floor.js +++ b/doodads/crumbly-floor/crumbly-floor.js @@ -6,19 +6,16 @@ function main() { Self.AddAnimation("fall", 100, ["fall1", "fall2", "fall3", "fall4"]); // Recover time for the floor to respawn. - var recover = 5000; + let recover = 5000; // States of the floor. - var stateSolid = 0; - var stateShaking = 1; - var stateFalling = 2; - var stateFallen = 3; - var state = stateSolid; + let stateSolid = 0; + let stateShaking = 1; + let stateFalling = 2; + let stateFallen = 3; + let state = stateSolid; - // Started the animation? - var startedAnimation = false; - - Events.OnCollide(function(e) { + Events.OnCollide((e) => { // If the floor is falling, the player passes right thru. if (state === stateFalling || state === stateFallen) { @@ -40,15 +37,15 @@ function main() { // Begin the animation sequence if we're in the solid state. if (state === stateSolid) { state = stateShaking; - Self.PlayAnimation("shake", function() { + Self.PlayAnimation("shake", () => { state = stateFalling; - Self.PlayAnimation("fall", function() { + Self.PlayAnimation("fall", () => { Sound.Play("crumbly-break.wav") state = stateFallen; Self.ShowLayerNamed("fallen"); // Recover after a while. - setTimeout(function() { + setTimeout(() => { Self.ShowLayer(0); state = stateSolid; }, recover); diff --git a/doodads/crusher/Makefile b/doodads/crusher/Makefile new file mode 100644 index 0000000..abbac86 --- /dev/null +++ b/doodads/crusher/Makefile @@ -0,0 +1,14 @@ +ALL: build + +.PHONY: build +build: + doodad convert -t "Crusher" sleep.png peek-left.png peek-right.png \ + angry.png ouch.png crusher.doodad + doodad install-script crusher.js crusher.doodad + + # Tag the category for these doodads + for i in *.doodad; do\ + doodad edit-doodad --tag "category=creatures" $${i};\ + done + + cp *.doodad ../../../assets/doodads/ \ No newline at end of file diff --git a/doodads/crusher/angry.png b/doodads/crusher/angry.png new file mode 100644 index 0000000000000000000000000000000000000000..6fdc1598a8a4da58d2a8844e60a2bd168c0de973 GIT binary patch literal 2405 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 { + // The bottom is deadly if falling. + if (state === states.falling || state === states.hit && e.Settled) { + if (e.Actor.IsMobile() && e.InHitbox && !e.Actor.Invulnerable()) { + if (e.Overlap.H > 72) { + if (e.Actor.IsPlayer()) { + FailLevel("Don't get crushed!"); + return; + } else { + e.Actor.Destroy(); + } + } + } + } + + // Our top edge is always solid. + if (e.Actor.IsPlayer() && e.InHitbox) { + if (e.Overlap.Y < helmetThickness) { + // Be sure to position them snug on top. + // TODO: this might be a nice general solution in the + // collision detector... + e.Actor.MoveTo(Point( + e.Actor.Position().X, + Self.Position().Y - e.Actor.Hitbox().Y - e.Actor.Hitbox().H, + )) + e.Actor.SetGrounded(true); + } + } + + // The whole hitbox is ordinarily solid. + if (state !== state.falling) { + if (e.Actor.IsMobile() && e.InHitbox) { + return false; + } + } + }); + + setInterval(() => { + // Find the player. + let player = Actors.FindPlayer(), + playerPoint = player.Position(), + point = Self.Position(), + delta = 0, + nearby = false, + below = false; + + // Face the player. + if (playerPoint.X < point.X + (size.W / 2)) { + direction = "left"; + delta = Math.abs(playerPoint.X - (point.X + (size.W/2))); + } + else if (playerPoint.X > point.X + (size.W / 2)) { + direction = "right"; + delta = Math.abs(playerPoint.X - (point.X + (size.W/2))); + } + + if (delta < watchRadius) { + nearby = true; + } + if (delta < fallRadius) { + // Check if the player is below us. + if (playerPoint.Y > point.Y + size.H) { + below = true; + } + } + + switch (state) { + case states.idle: + if (nearby) { + Self.ShowLayerNamed("peek-"+direction); + } else { + Self.ShowLayerNamed("sleep"); + } + + if (below) { + state = states.drop; + } else if (nearby) { + state = states.peeking; + } + + break; + case states.peeking: + if (nearby) { + Self.ShowLayerNamed("peek-"+direction); + } else { + state = states.idle; + break; + } + + if (below) { + state = states.drop; + } + + break; + case states.drop: + // Begin the fall. + Self.ShowLayerNamed("angry"); + Self.SetVelocity(Vector(0.0, dropSpeed)); + lastAltitude = -point.Y; + state = states.falling; + case states.falling: + Self.ShowLayerNamed("angry"); + Self.SetVelocity(Vector(0.0, dropSpeed)); + + // Landed? + if (point.Y === lastAltitude) { + Sound.Play("crumbly-break.wav") + state = states.hit; + Self.PlayAnimation("hit", () => { + state = states.rising; + }); + } + break; + case states.hit: + // A transitory state while the hit animation + // plays out. + break; + case states.rising: + Self.ShowLayerNamed("sleep"); + Self.SetVelocity(Vector(0, -riseSpeed)); + + point = Self.Position(); + if (point.Y <= targetAltitude.Y+4 || point.Y === lastAltitude.Y) { + Self.MoveTo(targetAltitude); + Self.SetVelocity(Vector(0, 0)) + state = states.idle; + } + } + + lastAltitude = point.Y; + }, 100); +} + +// If under control of the player character. +function player() { + Events.OnKeypress((ev) => { + if (ev.Right) { + direction = "right"; + } else if (ev.Left) { + direction = "left"; + } + + // Jump! + if (ev.Down) { + Self.ShowLayerNamed("angry"); + return; + } else if (ev.Right && ev.Left) { + Self.ShowLayerNamed("ouch"); + } else if (ev.Right || ev.Left) { + Self.ShowLayerNamed("peek-"+direction); + } else { + Self.ShowLayerNamed("sleep"); + } + }); +} diff --git a/doodads/crusher/ouch.png b/doodads/crusher/ouch.png new file mode 100644 index 0000000000000000000000000000000000000000..c982e6e66bddf89ccade54e9637e7b9d168de1ef GIT binary patch literal 2253 zcmV;;2r~DHP)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=%+05vTy*3|$202y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00yN=L_t(|+U;DwYa2@t9$l_`wOp7KuP|x?!Ij{e`~@}v zW0x*mIFMH0O1KKD%oFJXagoBLk}(9o`W0yes*J#mIIs)j!mgDr=v60H>;1hmduL}p z2t?<**>C5Ynf-Aq0WcU0JzA=ZMNuq54UWg-7KSa+P7EJPUf8|@0LXPW_j*0=28P2S ziY=9$5I!k*Vf!k_NVCVsN5G2a%9hHG*bV?dS(flmp2N@6)8(~?uU}X0E6b9cSB$^B z1u;FW!v6mL%ICAQvmjfd9npp?1^~dj!^0I(Qt^thqeJHVz?*&_Z2(i*sv_D1Q49cB z5o7Jc2WYq3weZ65mzN+PZ*Sq<;US7BZ~A={Tei%oiUM;j9Zf)1r!!KEp>w<|j}*d1WeC>Hr70O>QLW%pH0cKbx8bss?Li+Fn$;rOITgwN}kFIDyOH6!ph06nC46eu=xk_(dR zHEa_XZ?-BB;~VsnMKPVNY+S&9@Y0b}i1CufkjAY;d~2~N#?fRGjwYMvq-~t2#*f(k zxbPwy)J5V{!lZ)CpRz9*ma;CTDn=OjIUOg}^_VuXobT#GvW4ME_e$#w`C4_as~D!) zjIQHHlg;3Ee7MG#MX3bEqR!$_S)X5&vtjAbAGNBK_#fkA*P9iE<40F zMRCOJaNS0cIfP_Kt%9hW5}FC32&!mx8O$plE?MI{yF{P%VnHldThr;%2`AkvrPD$N zW0$G7s+?8rcRHPAnUXonS!sI7wfFiHbl0~RwFzP(r>o04AxvV}91%0Xi+n^;OyXm| zT|}Q{=>|BTwTErYh#g2>?3?(i+E!f)8An=}V(5s8ox@yMr8p=db2kM7hA8N}y*e={ zR=6%vin-%(G}(lmzx$+vdrlpp)LRXzDJVsz*s=o)Ic9`50hFA?0h}s3|MO%2 zd$CWngo;73FvMQOr2ytPsT!9dzG8@3QPeifPk1Lrha%Q)H-)(ol~TRc2y}q3Z{>_!(tM zP^|^(9>6izK;rw5*mpF^N>KkjedJOEr}}6`NyywaA$9uOpZuIyO>G z(J$N89ddJR-{;;&9F&W3BGmv}=erJHQ8G#*wz{h-Bev&4R@1i4#*j8gcgIm&lP(N} zs8|31n6gUllt@8QEmIG-ZZ00000NkvXXu0mjf!a*@p literal 0 HcmV?d00001 diff --git a/doodads/crusher/peek-left.png b/doodads/crusher/peek-left.png new file mode 100644 index 0000000000000000000000000000000000000000..b2327baf8156aa4567b25cb001323b3a578e8a6e GIT binary patch literal 2219 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 mKp+qZ1OkCTAP@)yM*Ih)gr{Mj;@Bzx0000 literal 0 HcmV?d00001 diff --git a/doodads/crusher/sleep.png b/doodads/crusher/sleep.png new file mode 100644 index 0000000000000000000000000000000000000000..796f656c8c522c8918bb8ef5eb32648f0567a40a GIT binary patch literal 2106 zcmV-A2*vk_P)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=%*H3Bm1r|AFy02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00t6CL_t(|+U;DwYg9oHo;$a*ekp=wIvcBlYy1y_Af!x@ zB7*IKRY)aQ1rIyH6c)kiKoENin}bwo(mjYput@5&le6(1o6Y{3-I?8YaXtu`yZ2_l zoo{A$_D2K|2n22nY#)xt<5jA`#bPm_u%+9{;ls&`+E)Mo%JuMMGC?;mo6SgU+3ck7 zDZz`{SBfIdZf|daDw;c6HamJd003>yJGEjzCqf1w5Oy==q& z{{Efc&(6-0Z0UA%8>Scl0M8E(?}$>0SB@PQhS(RL9vzWQU^ZJ_MEjtN0RVTz*n0H} znx?73i^5+hL0n`TXS*cZgNGa{#6h4rl&2JtY@|Qsj`o zvIV)EPS?h-mP@#tPO}JKPNyVxs6oXm)n7wwBLD!u-@hjrU#aYLxLPjZYPrl7rQ_AM z?fNHG6tkZpTMAoYnM%i!wUwfM02MD+g{Au|#y)x-l0w?G2uj7y&JKJ%IDi+QKCLsO z!{g7NqsvcfUKGKmxXGGzJC`U}F(`Ra3aeauEaUNbHJMCE7CW5L_x0dFCtjQrR@kO# zU^bgs_p!*fPD+4dc!&xAxZm27vYNDcst&&CZmKnbg@L zJ5z{_nbc#PP}>n^cJu+mn$9RKhRgA>JW2?cl_6A>OJ6c3#4(0j?mVJ6Bhl4?@z&nG zXyX(6cS}icjuUpxn$UE=Z|k*gh`aLZd*A zZ^(x%j&ioM@dduaLxUiec-Z>-*S_hd5#9 z4-Ss0yi}=Z^L3x$ z$=jk850w)+MDZ;U=hw$@{_7jc$GtwnrH*EiuqSU&N`ImH+11Rkb;!)ODIZoxgJ&S`8`5#T+KHNu2V?7bOT)$(t*R zIhp#-$GOGuiL&?PEsVBzQR_MK-QH02c3TiWQDVzevn}k<5ef`!nM{$nDp!CMLR{+s z>`5M$M~Mnf#Hg(CIDh5EI?f06Om$Ce)b{u+>Ay_f= ztf+PO%5{&o23S|>F%B-#`B)w~nM|=tM+uTLRAJ^5u3-&hH@AI?4DZD{gj$Fi!;ikV zmeXc*hWJWeY-DiH6Vmr0Nmw{Q4O5 z$vw7Y#FFM-WydTUb?27~qF&w0sk5>69<}O}n;i!nBWhmUU96uCh2*?!Jk=)-C~7lp!aP&}3*EMndm}Y+~BVX>)#k zoW-^1!cdEf6##%QtISS?-qW8qzqdIkWJ7P$XHWmmi27h3*#t3(cZAK~JF+Hek4@KS ztHATCkgW(C_W~i*mi~E6AK5Y5-d*X(ljiRNfj}S-2m}IwKp+qZ1OkCTAP@)y0)apv k5C{YUfj}S-2n1IA1wrNm81poj5 literal 0 HcmV?d00001 diff --git a/doodads/doors/colored-door.js b/doodads/doors/colored-door.js index 0bfba60..1c47ab6 100644 --- a/doodads/doors/colored-door.js +++ b/doodads/doors/colored-door.js @@ -1,9 +1,11 @@ -function main() { - var color = Self.GetTag("color"); - var keyname = color === "small" ? "small-key.doodad" : "key-" + color + ".doodad"; +// Colored Locked Doors. + +const color = Self.GetTag("color"), + keyname = color === "small" ? "small-key.doodad" : "key-" + color + ".doodad"; +function main() { // Layers in the doodad image. - var layer = { + let layer = { closed: 0, unlocked: 1, right: 2, @@ -11,13 +13,13 @@ function main() { }; // Variables that change in event handler. - var unlocked = false; // Key has been used to unlock the door (one time). - var opened = false; // If door is currently showing its opened state. - var enterSide = 0; // Side of player entering the door, -1 or 1, left or right. + let unlocked = false; // Key has been used to unlock the door (one time). + let opened = false; // If door is currently showing its opened state. + let enterSide = 0; // Side of player entering the door, -1 or 1, left or right. Self.SetHitbox(34, 0, 13, 76); - Events.OnCollide(function(e) { + Events.OnCollide((e) => { // Record the side that this actor has touched us, in case the door // needs to open. if (enterSide === 0) { @@ -37,7 +39,7 @@ function main() { } // Do they have our key? - var hasKey = e.Actor.HasItem(keyname) >= 0; + let hasKey = e.Actor.HasItem(keyname) >= 0; if (!hasKey) { // Door is locked. return false; @@ -55,7 +57,7 @@ function main() { } } }); - Events.OnLeave(function(e) { + Events.OnLeave((e) => { Self.ShowLayer(unlocked ? layer.unlocked : layer.closed); // Sound.Play("door-close.wav") diff --git a/doodads/doors/electric-door.js b/doodads/doors/electric-door.js index 1f4be7c..5c35201 100644 --- a/doodads/doors/electric-door.js +++ b/doodads/doors/electric-door.js @@ -1,27 +1,28 @@ -var animating = false; -var opened = false; -var powerState = false; +// Electric Door + +let animating = false; +let opened = false; +let powerState = false; // Function to handle the door opening or closing. function setPoweredState(powered) { powerState = powered; - console.log("setPoweredState: %+v", powered) if (powered) { if (animating || opened) { return; } animating = true; + opened = true; Sound.Play("electric-door.wav") - Self.PlayAnimation("open", function() { - opened = true; + Self.PlayAnimation("open", () => { animating = false; }); } else { animating = true; Sound.Play("electric-door.wav") - Self.PlayAnimation("close", function() { + Self.PlayAnimation("close", () => { opened = false; animating = false; }) @@ -32,7 +33,6 @@ function main() { Self.AddAnimation("open", 100, [0, 1, 2, 3]); Self.AddAnimation("close", 100, [3, 2, 1, 0]); - Self.SetHitbox(0, 0, 34, 76); // A linked Switch that activates the door will send the Toggle signal @@ -40,14 +40,13 @@ function main() { // state on this signal, and ignore the very next Power signal. Ordinary // power sources like Buttons will work as normal, as they emit only a power // signal. - var ignoreNextPower = false; - Message.Subscribe("switch:toggle", function(powered) { - console.log("A switch powered %+v, setPoweredState(%+v) to opposite", powered, powerState); + let ignoreNextPower = false; + Message.Subscribe("switch:toggle", (powered) => { ignoreNextPower = true; setPoweredState(!powerState); }) - Message.Subscribe("power", function(powered) { + Message.Subscribe("power", (powered) => { if (ignoreNextPower) { ignoreNextPower = false; return; @@ -56,7 +55,7 @@ function main() { setPoweredState(powered); }); - Events.OnCollide(function(e) { + Events.OnCollide((e) => { if (e.InHitbox) { if (!opened) { return false; diff --git a/doodads/doors/keys.js b/doodads/doors/keys.js index 469a158..c51154d 100644 --- a/doodads/doors/keys.js +++ b/doodads/doors/keys.js @@ -1,10 +1,18 @@ -function main() { - var color = Self.GetTag("color"); - var quantity = color === "small" ? 1 : 0; +// Colored Keys and Small Key + +const color = Self.GetTag("color"), + quantity = color === "small" ? 1 : 0; - Events.OnCollide(function (e) { +function main() { + Events.OnCollide((e) => { if (e.Settled) { if (e.Actor.HasInventory()) { + // If we don't have a quantity, and the actor already has + // one of us, don't pick it up so the player can get it. + if (quantity === 0 && e.Actor.HasItem(Self.Filename) === 0 && !e.Actor.IsPlayer()) { + return; + } + Sound.Play("item-get.wav") e.Actor.AddItem(Self.Filename, quantity); Self.Destroy(); diff --git a/doodads/doors/locked-door.js b/doodads/doors/locked-door.js deleted file mode 100644 index 820ae1a..0000000 --- a/doodads/doors/locked-door.js +++ /dev/null @@ -1,27 +0,0 @@ -// DEPRECATED: old locked door script. Superceded by colored-door.js. -function main() { - Self.AddAnimation("open", 0, [1]); - var unlocked = false; - var color = Self.GetTag("color"); - - Self.SetHitbox(16, 0, 32, 64); - - Events.OnCollide(function(e) { - if (unlocked) { - return; - } - - if (e.InHitbox) { - var data = e.Actor.GetData("key:" + color); - if (data === "") { - // Door is locked. - return false; - } - - if (e.Settled) { - unlocked = true; - Self.PlayAnimation("open", null); - } - } - }); -} diff --git a/doodads/gems/Makefile b/doodads/gems/Makefile new file mode 100644 index 0000000..f9e5d87 --- /dev/null +++ b/doodads/gems/Makefile @@ -0,0 +1,58 @@ +ALL: build + +.PHONY: build +build: + ### + # Gemstones + ### + + doodad convert -t "Gemstone (Green)" green-1.png green-2.png green-3.png green-4.png \ + gem-green.doodad + doodad install-script gemstone.js gem-green.doodad + doodad edit-doodad --tag "color=green" gem-green.doodad + + doodad convert -t "Gemstone (Red)" red-1.png red-2.png red-3.png red-4.png \ + gem-red.doodad + doodad install-script gemstone.js gem-red.doodad + doodad edit-doodad --tag "color=red" gem-red.doodad + + doodad convert -t "Gemstone (Blue)" blue-1.png blue-2.png blue-3.png blue-4.png \ + gem-blue.doodad + doodad install-script gemstone.js gem-blue.doodad + doodad edit-doodad --tag "color=blue" gem-blue.doodad + + doodad convert -t "Gemstone (Yellow)" yellow-1.png yellow-2.png yellow-3.png yellow-4.png \ + gem-yellow.doodad + doodad install-script gemstone.js gem-yellow.doodad + doodad edit-doodad --tag "color=yellow" gem-yellow.doodad + + ### + # Totems + ### + + doodad convert -t "Gemstone Totem (Green)" totem-green-1.png totem-green-2.png totem-green-3.png \ + totem-green-4.png totem-green-0.png gem-totem-green.doodad + doodad install-script totem.js gem-totem-green.doodad + doodad edit-doodad --tag "color=green" gem-totem-green.doodad + + doodad convert -t "Gemstone Totem (Yellow)" totem-yellow-1.png totem-yellow-2.png totem-yellow-3.png \ + totem-yellow-4.png totem-yellow-0.png gem-totem-yellow.doodad + doodad install-script totem.js gem-totem-yellow.doodad + doodad edit-doodad --tag "color=yellow" gem-totem-yellow.doodad + + doodad convert -t "Gemstone Totem (Blue)" totem-blue-1.png totem-blue-2.png totem-blue-3.png \ + totem-blue-4.png totem-blue-0.png gem-totem-blue.doodad + doodad install-script totem.js gem-totem-blue.doodad + doodad edit-doodad --tag "color=blue" gem-totem-blue.doodad + + doodad convert -t "Gemstone Totem (Red)" totem-red-1.png totem-red-2.png totem-red-3.png \ + totem-red-4.png totem-red-0.png gem-totem-red.doodad + doodad install-script totem.js gem-totem-red.doodad + doodad edit-doodad --tag "color=red" gem-totem-red.doodad + + # Tag the category for these doodads + for i in *.doodad; do\ + doodad edit-doodad --tag "category=doors" $${i};\ + done + + cp *.doodad ../../../assets/doodads/ \ No newline at end of file diff --git a/doodads/gems/blue-1.png b/doodads/gems/blue-1.png new file mode 100644 index 0000000000000000000000000000000000000000..c74d062370aa0836bf0357c5c1c1480712fc5131 GIT binary patch literal 891 zcmV->1BCpEP)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&0Hz>zPugw4e02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00C1;L_t(I%Z=2(OT$1E!0~Uc1)&)%#kzIwk5OHuP!5-_ zrMPz}63Axz7r2Ovb}L8``~&h2xCOyMq>j~qLqKpWT^x!?Tuh1aF1feeare1*?;QsQ zv324`ChLR=WbN0DK#>Pk+8rOD((d?qpfG{r$ODBAstq0AZZsM6djJgjJ?uu4+R)L0 zLI(jHx9R{y^MK@72Z}ssG9Jm(%PW5}9?3jVsA`mk090VQh9VDgS7qt0%F?rpJThi{QZtGdHsw;N8zBe}hI5Sl;$h4@q*cz1CwizPeEg8(eu%U4}F z3j!#nvGr_fEg=GY@3(7lv9lm0rUFeMEtUq84bVZ#n(6+tXdaLS8Hedl`vYo=2F?## R!$JT6002ovPDHLkV1iF7eXali literal 0 HcmV?d00001 diff --git a/doodads/gems/blue-2.png b/doodads/gems/blue-2.png new file mode 100644 index 0000000000000000000000000000000000000000..2760b457e60ead1238b460be8b7dd2dbbf434077 GIT binary patch literal 927 zcmV;Q17Q4#P)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&0H!oQuI&J^}02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00DPNL_t(I%Z-#VYr;SnhTlsAN?pXUAap3Cb?s1!Ah-Dk zoVtn#*`kYUe?a0E2qDlP;BRPyAQZ$x7u#%-(5(a!3T7zRpx zc70O{R79ZXi#uwVmLD(Xl-KoI8Vu7q0xD&o$a7MFVOoCVIkeZ(kj)(_tPFHE+3jDh zUf3Br>N4TPF&1@Z{AOJYy6TffE$K`kYbl>f6 zc4u5rP0f&BGGcCQ~5w5CFK@d5`jI)uLmOxHgFZ)@XMQ z)NtR5K&1ygacz?AdJ(A5vs3pOTLmZsNr&uB`v=4~9qP1GT9^O;002ovPDHLkV1fZa BlVJb= literal 0 HcmV?d00001 diff --git a/doodads/gems/blue-3.png b/doodads/gems/blue-3.png new file mode 100644 index 0000000000000000000000000000000000000000..b40177c9c839ab166e279cbad46c6a7885111fc7 GIT binary patch literal 903 zcmV;219<$2P)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&0H#1ElW+4Co02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00Cb~L_t(I%Z=1MOT$1I2k`%$gNRG%C`7wR)wP32p&Ty# z0)7I61iG1i0&&)Cfl>;(m!e-ljz9*HI<^fifvVsVx&#a;ak_9dFL%#)x%~3HTn^BP z&5K^DvybXPq}9{{sR}YoivxgRT3iKE9Y}-bO{mX zNRD(Gps3vOEI_=NBl0~~^iGypz1`seuzhd{09cL&%rGtfv~$ed+KP{7!P>g`$o=FY z%Zvg*GIUAgd$|USrt3gi&;AcVF3suNtlsYM$oDEC0N9YR-`AI`n9#eEZZ{NbA4Vhm zdYmYs!b6)3T_TQvD37$7P(h`?lMIUStDsz&MI~?T?uFk!aU*zp538Wu0IKe@bQ+)v d(hl95_798m_{+Sgn}+}Z002ovPDHLkV1lHqiiQ9H literal 0 HcmV?d00001 diff --git a/doodads/gems/blue-4.png b/doodads/gems/blue-4.png new file mode 100644 index 0000000000000000000000000000000000000000..63f8480eb5ef9446bc405743753925267d7fd656 GIT binary patch literal 835 zcmV-J1HAl+P)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&0H#bU8qBsBm02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00A3GL_t(I%bnD*io-Ar08q&s^q^bz%xSyc7zqA|{y{hb zw>4S%6K%M~G?;u#O`&5xAanK`I@OaqIk-J17S$;17hx#^AjIPP$575O3WQ$?31lHC zN;3rj5T%(4fh+_qSL-ns0$B*!Zjv#-T&*F_i%F1CAk+2WRyYN+5L8zskJ3yHZNu%k z?IwZU;rI_k3S_Gq+J^5AN96)_RdOu_ju-{9F$bcZBR5RfgAZ~)9_Pi_#Srw=O}9edr4R%F@bQXiDR2NVZpZ9n z&q0&Fla>POs^n9h^g*OOw!huapQm55zunKFt%1~iX1X5Us_5NK`vCqw#K-`)`<(y) N002ovPDHLkV1lxoW0n8_ literal 0 HcmV?d00001 diff --git a/doodads/gems/gemstone.js b/doodads/gems/gemstone.js new file mode 100644 index 0000000..efb9361 --- /dev/null +++ b/doodads/gems/gemstone.js @@ -0,0 +1,24 @@ +// Gem stone collectibles/keys. + +const color = Self.GetTag("color"), + shimmerFreq = 1000; + +function main() { + Self.SetMobile(true); + Self.SetGravity(true); + + Self.AddAnimation("shimmer", 100, [0, 1, 2, 3, 0]); + Events.OnCollide((e) => { + if (e.Settled) { + if (e.Actor.HasInventory()) { + Sound.Play("item-get.wav") + e.Actor.AddItem(Self.Filename, 1); + Self.Destroy(); + } + } + }); + + setInterval(() => { + Self.PlayAnimation("shimmer", null); + }, shimmerFreq); +} \ No newline at end of file diff --git a/doodads/gems/green-1.png b/doodads/gems/green-1.png new file mode 100644 index 0000000000000000000000000000000000000000..ff76d09267ed6f95dd83d3db8518f317eea65e9c GIT binary patch literal 785 zcmV+s1Md8ZP)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&0Hvxt9H=zIk02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{008MpL_t(I%dM0x4#GeXMqisAf*-%CCqUsUk-bC}fm1+G zy#Ru6090KS23xh&1#VFU86ewb%aVR(vzgtO`DQW`kkT@cA^^satuyWWxjd8rRM$#z zgAksee3PqRA@!xEzSJ*}BofJkWS;1J`8!aQ?cRDm$pS1~a z!NYGLIX~;uCo4=cTAcP?9S*+*d_hiFpBmi^2eUOM?0evC^WV>d*fi@U_ed^NHSJim z71;&uOn^Be{woM5%0jv3(yXgwR9!0-Pht%akkXp_%+(N^b=haZkel`atzdKSNn9M= P00000NkvXXu0mjf$x2Ac literal 0 HcmV?d00001 diff --git a/doodads/gems/green-2.png b/doodads/gems/green-2.png new file mode 100644 index 0000000000000000000000000000000000000000..996d565ad208a4be8ca1c89fe38adb3fa405f42c GIT binary patch literal 807 zcmV+?1K9kDP)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&0HwSE%l9T`d02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{0093zF~|;zJ22b= zWG{fKW>D*@Fj!QoOSuIYQkKx9?M%PQB%8PYr%eK+cwr<(0Dvi=5~Y2G@gjDvWrvJV ze_$$6nhPcy=mM0tvKgCwoHIpc(oD!roO5S1wfP!|T#M(`me!Y(_Qu;~WD;=B2z_yU zAom9lI>aTA6m_t%YM&n lfIMUw%jo{N6KVq+NpC0MeLTo?H%tHk002ovPDHLkV1iyeRK@@R literal 0 HcmV?d00001 diff --git a/doodads/gems/green-3.png b/doodads/gems/green-3.png new file mode 100644 index 0000000000000000000000000000000000000000..8449974524299c5dd7e63556fb7bbdccab51a963 GIT binary patch literal 864 zcmV-m1E2hfP)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&0Hw$GT-oF3<02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00B5jL_t(I%dM2LYQj(yhCf3F7k6vum^0l?dFrYvt;>7H5ko3{l9Zr}tNTjc>pK=1W^mX5!~olbQIr zbC7=@`wzNV=F6n_*yH8v&ARKl0R%fc?+Bp!u1;t3u?d12VWFr4IjK>|i>3jDB5Ir1 z&hAd9t<$(^Lj8W9N~-^N=7U2#}(0000EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&0HxTbd7gGQL02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00A3GL_t(I%dM2ZZiFxl#y=24U!i2ilQ(*gQQe4iOW)=e z)GaS?3(VC`*}7M3o^t!~3b)bW8kDvPe_AXd5gY&T=Qv4FVZcU~0RSEW&e;NhA~l&% z?22DLU28)B1>>BpT!kDE0N$QoXn#K0P%;2qJ}v+N^KOW9w$ckFs4#GOhe#*nKE5># z9u9|DX?||zoQf2rlQH=8dIXm|DciJ$TwFRq8tRiGH9l*4m-;=rH4Xf=|L(72&{5|8 ze6prB#3hewKel8v(w~mG(TGV5!a_2a!qd6Gt+8ljOZ()8cZ6+G)wkVT)96*OzgC)s zj)-Z^|6sb-#3kF+VQ}}E51Nwd@1VPe&^y>h_6Y=9W*s_F!8`x} N002ovPDHLkV1gQ?W*`6n literal 0 HcmV?d00001 diff --git a/doodads/gems/red-1.png b/doodads/gems/red-1.png new file mode 100644 index 0000000000000000000000000000000000000000..9a14ea0a730df2b4bada4beb8807a2377cfd0f49 GIT binary patch literal 711 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 literal 0 HcmV?d00001 diff --git a/doodads/gems/totem-blue-1.png b/doodads/gems/totem-blue-1.png new file mode 100644 index 0000000000000000000000000000000000000000..0f561a3593390c7147d7a9e9a4a074665270d6bc GIT binary patch literal 958 zcmV;v13~EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&1BsIX{lmh?&02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00EXsL_t(Y$K}_*O9EjS!11qV4TAm=is7J<+7LCgWZ6=f z|3LqM;GhUC4vwNhL;V?Pv^F~!;;$hDJ6kfc9|+o(T!R^!C*8f0AwApOaeVH%_j#Z9 zeGR*74uu(q#2CTHHT8{wmgddf~O*`I}7V3ypWovqj?_Glo@%Ff56H z%PtoHK95@nmPElph`^E_(7PXC(Pn4UzXO1G+lSF=!ygRlf+am5!1|I60Hsg^V8!0Q z)&ol-;A#4pa5O?PnG%8}tz-Bd1XN)yV=Re)A(NAk$;owHW+QN*8&>VTgLya{N}=|Z zVaVj1~pBYNw6rW zxjCr8gQC$30_ue{vABvQd_ej0o(QPB;SXmF2!TRN+W-cHK;cC^Vd;)d{F!W5M8Wyn gm`%0W{x`>p4+s7lU4F}h%>V!Z07*qoM6N<$f}&ZUeEEX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&1BsjiM=)M2|02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00G5GL_t(Y$K}^gOTu6r2k@_}i_l&~B6#p%(V-Vmur77j z8|Vcj4B8Mnw8M^Khd?@ZFF~zNL1zPF{ZT|j-MnOEe-K=FN$gO2m^pIK6DiW~_-qfK z{hmL+=b3M9In>9PgTn;ES2#K7Keyk|Y_)Lz@c5@#^XUbz?apK}oi0@E%#9aSJ9F?Y zg_vQE1>BOi0RXFu3rsM_0$x@P(#8UFEE#?eK@_QAjuy1D?CTW(z|4Gr8s=EQqsRs% zMaIR=EqN~z3?LR$Ji#0-czv2B&m~31c{+_qFhJV8z?_#w zD-cAH%okSH5sxPbY=Z!hFBGBf!~g*0x(NVC9j69BPs6M6mg{`&C-$&eJR=$AvKa!} z@e??5A!)odG+%-!BA3mOA$5Y~x;YZ`v}K&|-Pe!`qR0$-E)H%P+l!`LH>p6XGHB0n z&ot084FdKW1{FwM@HO5Vs6xGlfplJ{0-26BC(HseAL1Hs4Q>3fTvu4Z>ARTy>azWB bek(ozRr(FvKt?H-00000NkvXXu0mjf@gA|M literal 0 HcmV?d00001 diff --git a/doodads/gems/totem-blue-3.png b/doodads/gems/totem-blue-3.png new file mode 100644 index 0000000000000000000000000000000000000000..8373a3c0adbd3b0e17fb3ae06920ce8212068c7c GIT binary patch literal 987 zcmV<110?*3P)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&1B>;~}VPOCO02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00FZ}L_t(Y$K}_*OCwPb!0~VPY$DmeL5zkVo}3yE(N;;U zG+BtPaJ7Yn*qLJO!fB^}M)a@}OluJd@seu-VXaiuI}x&W>RQBIR^yMn2^!?4+-3PN z^WMyR8<-x8I(%?wbRYudUz^U~t7}fq&pAFldspn_;vbh+_0DAaxzJ2K^s#8B9wHEn zieXIxj?N?jNEn6))}){t5?GUfkli#nl!_SWQyHf zPL#2x3T~{eGhf;9;B5A%@)~!kloX(pY=GbU!z=^`VF)6t4GiG+$YN?_m`v#qQ@2~6 zy>1`+!zosoNTxi{jf0xSja8#it~~pVAAWWAn!1fstTK5QWb!UZyl0SvVX(iw1<=Uw z0R$+NE2QVrti)$oiO-Vy5^4flT2oWE*()73Z4?)F!Ts$m(sOAB`g#HQlh2bY6ki12 z+(>@d-x`tCAKX|q5!h18n7ZB68VSSjN~#LBJRD5j_FCijLsEX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&1B?bQ@mF@rl02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00D7HL_t(Y$K}^QOT$1I2Jk1>x-}mnF;axqwup+E3p%!e z`bnf?hAcv81qb~Yr;Y(aHX989K)2H- z!HfcKs9HQmff)rn+*0H5ilXAkFbctp3WlzSijv?(U`7Ei$LHAJX~N+=zOJRI7!FT! z!Hf!4RSkNt4~KKKv}DD3U`7R_(tCZ__GoVIA~>`6MmZEKbiEV^0DHfyycmr$=U8%( z>b=#hC$Z!Jrt6{GX(zkXFyL?wT|h-}a54Y@Y;P(*_c*iXz+A7_k^|g5JjStzcIf@h z^-|!%jU>WiG$NP+=8B9Z2bs~Jg1MVR1dGv#Hce5mP#d)5AQcS?Sh(S5!9_vRr%i+@ vAo(M1$w4akr5snN;QAfRmO5EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&1BQg=hmuCO~02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{005s!L_t(Y$7A#`SO3pIXTZcT0D$q*#%cfGeE7=n?A0rV zr_W!~%%acVe=&Ui@|oe?htC7!(*d!R1)JdhqbI3mfuprKah5VLFffRUiBoLh>sK%7 z8@%pz=JbtId=}yjUSuF7z)O^6rg~a~H}#HMI%?^trK6UTUknmkyivtcLIpR~gO^qo t;`Qm0HJj*bDYhoYXqF+Xu{~nC6#xi(BxPmyjC241002ovPDHLkV1gg@FfjlC literal 0 HcmV?d00001 diff --git a/doodads/gems/totem-green-1.png b/doodads/gems/totem-green-1.png new file mode 100644 index 0000000000000000000000000000000000000000..4a2e33fb48665af5dab5a3256cebf6c4c09ac640 GIT binary patch literal 887 zcmV--1Bm>IP)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&1Boh+s5&i%G02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00B=)L_t(Y$7A#`SO3pIXTZcT0D$q*#%cfGeE7=n?A0rV zr_W!~%%acVe=&Ui@|oe?htC7!(*d!R1)E^`(?wLXpi?@II7=BA7#J8N85pwC(@D1E z?3xn{3=9kmC*NLVV0cbq@Mfi_GfbN~lW5Bxp1;rV@cezah2`0~qy;Ywc$>K~Olz1) zvTw^V zPCvfz0I!8q%cn3OhOb&g-@<_!7E--L`gs4{z!ih|5)nz3Qj&0pwiH&n4C-3u?cG;I z$1l#p;mzHb3?j`1p1 zy?Vlz4bX$rPs)yA)3ZZl`1CmgLubuo`ZZUuH8F;K!)#z0+aso10RZMngou|jQ!fAj N002ovPDHLkV1g{7f{6eC literal 0 HcmV?d00001 diff --git a/doodads/gems/totem-green-2.png b/doodads/gems/totem-green-2.png new file mode 100644 index 0000000000000000000000000000000000000000..ae892e6d49c21d7aa6e478192053a1a4a65f413e GIT binary patch literal 938 zcmV;b16BNqP)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&1Bo<eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00DwYL_t(Y$7A#`SO3pIXTZcT0D$q*#%cfGeE7=n?A0rV zr_W!~%%acVe=&Ui@|oe?htC7!(*d!R1)E^`(?wLXpi?@II7=BA7#J8N85q3H-0&JG zZ>WeQq zBjF&84GADUPSJsXfCmEu0|Ud#usDYBRf`y84HU4d<7Q!H=&YH{z`(%3AY~xSz_5nI z)Qc+^aal-l>O}`D!yqZJ^6gjg~8iy45l#qoV@4q7$pMx)W zNda%~zG8TL_Z5bZ$;vXYc%9NPgJg%`vly?XTTku6T6p6sabR(|_~-@(KPfxXErnH2 zxGX|WEa<-Sld@yj^z0BBK7G!BS|6^VadQP*6Jy9X%m${hJz}~Q0Fujw=3l2{ApigX M07*qoM6N<$f^`y@zW@LL literal 0 HcmV?d00001 diff --git a/doodads/gems/totem-green-3.png b/doodads/gems/totem-green-3.png new file mode 100644 index 0000000000000000000000000000000000000000..b850991fd6a063f135a5cf12d7b535480f99e376 GIT binary patch literal 978 zcmV;@11EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&1BpPclsagO402y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00F8=L_t(Y$K{u?O9F8e$G?h$)DWa4T}X*UZ5aj*fwR-) zWN?tsAJFX5(0a2e-P&+q)L_u!SSRb%cM)%G(V0jcfqL|unfj4s z0CqlY4hjI617f~a0DwOnF#PetTIh!_&vAf25Gf!5uUi!bJPZN=&v%aifb*LYXey2~ z;ergRfU6atDt-5O9$tn4ipD9WqjB;xmCYXx099Z!nNWP{{h+O^FM-|5Vk$H(Ic^En zt9OoD$G;0K7+JKgWO_W0LQ1Q^LMpBC4Fai1aP;&7fR|x3DV?Auv2%5*?A6vN*Q{?2 za&+BBM_IK?NwKx^(|9|Q9?&SoZjz!m5|VAbR~Ag`p{XoA8+NuHvr)=G-|P&!;g0>0 zs!M`IFqWj(3ZSVv1%QM7L;L5cdOXq5_;)WgSr%+Ai%evf9Gd4i(3BQvRC{X0Zf_*P z=CUJ1DnOct>Pc~8V|w+j7=Qj^=FDaL-#jb608V#>>`x#2^8f$<07*qoM6N<$f*w<= AJOBUy literal 0 HcmV?d00001 diff --git a/doodads/gems/totem-green-4.png b/doodads/gems/totem-green-4.png new file mode 100644 index 0000000000000000000000000000000000000000..4aa4c7d6be64d3c061241962560f33c1bf019c5f GIT binary patch literal 956 zcmV;t14I0YP)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&1BpvlsJox|s02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00ERqL_t(Y$K{tlOF~f?habhEsURiEkP?R`$#if?oEn-W z5OPZV0?mGe5ZXlHZc-o^3f@2n$F_nf!#yHYk_y41XtBY%Uh`^R^(xUjo%3?J5AW~& zbI#Fic~+ZD*z`=nbT?w6`B;CYQmav}K4=DNynWDkY4BWcOefN*Kn+UHNcnJVfap?a zFem_v;4!WNV6vP0{&;!a*5ykG0#sE*3N7IIQ&9o~WP@P>>7*hA;O^=cfc!-Pzs1K% z^-LX90+)(V`f>!r=JO5k<40NC6=!0T{fv@a-rKWmubD3fE( zHs5kws)YW`V=s{0EKVzAMr@gEFwA=@CGFEYp^mkD-vu95-atA@UMxuR29MjVBwuSX z90rlr>Ri!gBK49}t;Bk@O+WG3J7^v&*Z0FgwTklB>K(OUMuv_9rV1+NP9ZlTc@u(w z-|cJ9(gE8d8jlfi?x}|+1OdOL6WFi!LpE^P+Rr9sO80000EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&1Bnj`1=!5_O02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{0078IL_t(Y$7A#`SO3pIXTZcT0D$q*#%cfGeE7=n?A0rV zr_W!~%%acVe=&Ui@|oe?htC7!(@{%DEge`(_a8k;UrYBNJ;@*{CQi1+OypX~z`(%Z zXl+iG#Z2T{C?vp3w#7`8SorMqTe2)>BG*C~Aje`RN-QMTVkSy0M7CI3Qk)?s#E+oG zEW}vIz`(#@s;5PCoW+FrF)UfLiNVp@oOnxNE`9w9QNJ!(vx%(yjLl-Kmf~{ZXn{X! i>8Pax)7Ty{-3kC&oL%~Z{1@E-0000EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&1B@Z9=eDDAO02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{009F@L_t(Y$7A#`SO3pIXTZcT0D$q*#%cfGeE7=n?A0rV zr_W!~%%acVe=&Ui@|oe?htC7!(@{%DEge`()%zCF*HZPqMGWtxMaZ_8i5v@Mq(vAQ z7#J9w+?~j>n28(gr2@(xcBrSSr#*qW8r~=M;IKO>=+(gxl5MCOvGBKsUU@7 zAp-*ggPf8SSr#)9YoWNj5{iW|0JHejizh@|%tDHV3=9km2lgGps`kpoTMYVKTnsLL z9t;e9ix_Se#gT3)vW4sJ++Z*<*M-aRGBIP-bNt_52Fuqk2wIG_KBXk%qXU@5$n_}; pK82%Y@2I7tmJW`__K4|L002huf^we>VE_OC002ovPDHLkV1j&lS;GJT literal 0 HcmV?d00001 diff --git a/doodads/gems/totem-red-2.png b/doodads/gems/totem-red-2.png new file mode 100644 index 0000000000000000000000000000000000000000..d08ce2186913a3b4e0550029cc4036a7ff0ea0e1 GIT binary patch literal 805 zcmeAS@N?(olHy`uVBq!ia0vp^vLMXC1|-8Kr}Hx~Ft%hmI|q0=J1Z0v<)>xlq%tsQ zOst(~>v7mY=4iaV%fzl`Q5RRE5OwZFi~6Ekl|neSI<4kYn_lNQxlQHh(ZB*-iys>! zN(&0FT|F2oz+&$pGk1K+5S6sdPQ8n>qHlfmj~`XyPb2R=|0fgcbuFdAUtwPAu0+9n0sq`6tLL?k z475GCK3aZU;V7aYCqTXw&P-pm+R zgCd;;Jff2xv;S|te|Of-&O&od5$0QQIlq%7GVZg!3cdZ$Zrj^moB|bW>$WW0AH$qx z=egc&>j}XNdwFAG%uOr#cidt8HLv941Q|_-%kxh&zEA(+E4kpg*o&Cr>g+d|H(?D8gCb z5n0T@z%2~Ij105pNB{-dOFVsD*`Kj8il_?Jd=StC3Q3l@MwB?`=jNv7l`uFLr6!i7 zrYMwWmSiZnd-?{1H}Z)C75(*eaSZV|p8Uli{Qr4}^aDo>7#coaI+pqWe$9_lAKqNm zZd-mn{?eI6=kM1W*8KZ4^Wok0^URMg2YS2f%0_r!{VjI!deGN>t~~FTxSrTHqf>@k z_D!w?2+X-N_rxZUK)l_a;|gEC@E%?*?hg@JZ(nij!Go0J1y3L8Zqi9py6(gV1iGe` zV9ud%f4NDyhTNKBMg|53GB?UOR^QSV&o_KgTxh5<^RCks|K9mYxuk`}?Cm9&=|m=$`mGSgeN2{q#Ms%Vm1s e3SM5zz;K{r*5O{Er$2xJ!QkoY=d#Wzp$P!S996{t literal 0 HcmV?d00001 diff --git a/doodads/gems/totem-red-3.png b/doodads/gems/totem-red-3.png new file mode 100644 index 0000000000000000000000000000000000000000..bd5614243b50ec1638276965800956d96c7d57c8 GIT binary patch literal 790 zcmV+x1L^#UP)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&1B^Bb7g^BeSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{008buL_t(Y$7A#`SO3pIXTZcT0D$q*#%cfGeE7=n?A0rV zr_W!~%%acVe=&Ui@|oe?htC7!(@{%DEge`()%zCF*HZPqMGWtxMaZ_8i5v?x6{Hv# z7#J9I^wr3+n28(<#pRV4gr2@(5R;H0%VH*SEIe@V2!n%@9mBqz`^d7GiChaA7#PU5 zn2B5qVSpTqSxB*vfq{YHz`jFR)$ZH5kHN*ygMpcgi-DnU5yQ=*IMOXePNnPa++Yav z^C0MhO)sA^STZp)=vx}#wHRxCN=e2?2QZ6~>r)nd3P;P{QA literal 0 HcmV?d00001 diff --git a/doodads/gems/totem-red-4.png b/doodads/gems/totem-red-4.png new file mode 100644 index 0000000000000000000000000000000000000000..98ddcc98c3e9cb6403424bfb6aac4cb9f3c7175c GIT binary patch literal 817 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 AkN^Mx literal 0 HcmV?d00001 diff --git a/doodads/gems/totem-yellow-3.png b/doodads/gems/totem-yellow-3.png new file mode 100644 index 0000000000000000000000000000000000000000..da774b79766c2fdb601e2d107781107a2a9feb83 GIT binary patch literal 1054 zcmV+(1mXLMP)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&1Br7`ZsbByA02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00H(%L_t(Y$K{vLOTu6n$G`r%h~Bz%2on#&unr1#j>5t} zVj~)K^c>8P9C+>$1Vy<2pi2i$Jb4M~P!cKxic}O8f=UpH9mc!fP3Pva40>Sf-QFJ` zzR&wU&z{-Vmx6u#ve_{Ovt6C+_n%u`+&?|x?&0yrK<&48v^#CQw%XHCIu)pMoWZvp zNw+WHVJ8bEuuV3oyvr4gPEI z;?AN1b~xPDLPoof-kCi1_8wGY7QzKAgbQD8rNBmNon}-f60_hrM%70Y&->I%)Em9; zCkNtIS|NdHfjr0H;P}FN$mEJu-AP)Qtnfo=pPpSi+s&ab8WC+6U)kq*wS#R`E zt94N1ljwEP)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&1BrvdxV2l6&02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00I6A9PMm`11AmkAb?UXLNgAzI)yA zC>;ybh!T9*a|3<3RQdNp6>PpZ1%MD~-q$3HB>{kx9`&Xh8g7IE&KIW;A{`jx_tl&3 zP_PjN_%JgGKxN|qfY+|Xv8{e|c(4%#s9=vD-Pa1$nPXcVwa)=4&E=^zg2A^cy$Mt> zzi(xETB~<#3nTFWfLbGB%N+Jxo|VNwpb+VS`CVC_rm}HBHj~h5gQ`8SPo?x?_29?$ z1pua*j5i#l^nOu!n>lMUynNG&-!kn^{5ia}-HJB`7fV7ne;CVVuHS!Yp}^8YAv#p$ z)Uhpgb~~YfmGyl}bNT*RV)WTND4%|HBi}N)RGE777%4rD+UGd7#jCd;G)O&uQz}g} zNj8&UwYnE?I4Jw{`7WE)Syroix=Q^pfagyOqu(-DYF#Fcdzj``|7})h0W^FNY?#WS zN^_|)wT27i`zJ{a+S+dE3iTJwFkq<9dksdz)wH<@3wxhNTFge-9Q=z}q?(VilKgXv g*?5-i|K_*iC*yX@Q+WDSpa1{>07*qoM6N<$f{G;6eE -1) { + totems[link.ID()] = false; + } else { + linkedReceiver = true; + } + } + + // Shimmer animation is just like the gemstones: first 4 frames + // are the filled socket sprites. + Self.AddAnimation("shimmer", 100, [0, 1, 2, 3, 0]); + + Events.OnCollide((e) => { + if (activated) return; + + if (e.Actor.IsMobile() && e.Settled) { + // Do they have our gemstone? + let hasKey = e.Actor.HasItem(keyname) >= 0; + if (!hasKey) { + return; + } + + // Take the gemstone. + e.Actor.RemoveItem(keyname, 1); + Self.ShowLayer(0); + + // Emit to our linked totem neighbors. + activated = true; + Message.Publish("gem-totem:activated", Self.ID()); + tryPower(); + } + }); + + Message.Subscribe("gem-totem:activated", (totemId) => { + totems[totemId] = true; + tryPower(); + }) + + setInterval(() => { + if (activated) { + Self.PlayAnimation("shimmer", null); + } + }, shimmerFreq); +} + +// Try to send a power signal for an activated totem. +function tryPower() { + // Only emit power if we are linked to something other than a totem. + if (!linkedReceiver) { + return; + } + + // Can't if any of our linked totems aren't activated. + try { + for (let totemId of Object.keys(totems)) { + if (totems[totemId] === false) { + return; + } + } + } catch(e) { + console.error("Caught: %s", e); + } + + // Can't if we aren't powered. + if (activated === false) { + return; + } + + // Emit power! + Message.Publish("power", true); +} \ No newline at end of file diff --git a/doodads/gems/yellow-1.png b/doodads/gems/yellow-1.png new file mode 100644 index 0000000000000000000000000000000000000000..016d42ae867b62360eb04e6dbc8fe341f3015021 GIT binary patch literal 971 zcmV;+12p`JP)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&0Hx-{ReSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00E;(L_t(I%dM25Z^A$n#=mxl7#U{E($o!tY0U)590DAM zKLY`V1cjW!42kKVu@L4~(JWI~Y8pV0+?d#wlpqFKCz^M=-rCOWQ@wY+-+k}y-P4ev zP6tueoZ~=Ci?b}qcw}(^n9eo`)}h(&#^YFilm=xgh#&y4TpeIr27+~%*zo5cKazo3 z9tZ#?PGJ6qB7rVJEms;*=Z zD?S1Mj{BzAh(y4JzXbreUTEt0L&tqHciy%P@vW01awXd*km`!gO1>O%0rwBdVA|p= z$!m20=yxriEXsV*IRQYsRpsqgoQPRe+mu1%3II+hIG^M8;_~zEta#Wlc8d3pF95(z?R@w0`c|r4mpEgmczWikpoBBE tpULS3>(H!T#bettgj=EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&0HyRI+{!IV?02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00D7HL_t(I%dM2XZo)7S$Ip>jkeDlvpe*S-WPpu@$M8TF zq)d4NCZsZ?gCC=++6@Mtp;)S{grSnf9El}J>Cie{9J}q%n<6{+^Zz~xc#Lyse0M?s zah+2iB;lbpXHTz+t(K9#{UsY0l-eKznT!WMVK9wH-{7jjK=KAJk@ci-t z`$NSHkoZ7pCfRnY;d+^A8*HFOSpxt-E))|2NPu6$AX|ljY}S#+YOxW{p_#@beIMPy zWISjU0RUVtGfjs(X1=jwnn{L>lnceEtqMER;f}q(#XW_-;so|Rc$+ zYYla(*u$gjIk{9BJIZt0gB@k7Wu&`J`FC5)!`3&jtA#7&%gs@qVSlJP1?a(C_R}QT z_ifYS#JdVnly#dYtje^L5J0HwH5_ijLyaMLHf`0N*~DXF12DuixQU`Oo33HU$yTR| vE#|j#7pS*_zAjW_hv(ZQ_C6#3xoJNER8iSj9CAby00000NkvXXu0mjf6@ia; literal 0 HcmV?d00001 diff --git a/doodads/gems/yellow-3.png b/doodads/gems/yellow-3.png new file mode 100644 index 0000000000000000000000000000000000000000..fb9ac0f6907c7e9c4482832409979a2b5a2a170c GIT binary patch literal 898 zcmV-|1AY97P)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&0Hy#N6I#d7v02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00CM_L_t(I%dM2ZZo)7S#y>}4;SFvCMU_yWp-VRw9wSSJ z44Lu-ObiSxc?=dd7_6urFeA2$9VS6J1S zQmLveDaa%T^CSSk>3j?JiS(U=yrS`F&;u2D=6no;(pYa=iWR7YNJac^0symV=E9=9 zudmN{Cn3@`em8J)F`qo7{}!KB(~>NakO5$~zmhi3%zsYW YZ@4q%HUkq)!TEX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=&0HzB^87ijeSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00BoyL_t(I%dM25l7lc1hW{`*S>1`e8%+8R6_qu8jF`%* zJ^>0@!(-G`B6tTdOnWYaj;!DWY*|vma5uM(-SFk#&7TMa!WgunT9!dfY1(iN%w_VwdUWY`Xui5U)wHzozps&vl0Kn;7DFC=+wMrA+ zLtdL%4wNAfL3q2AOA~GHk0*wD2b7-t7lR9bxZVa}1OSJ9Y{`^Mf^6ge zJDORVXqy-FD!Kn?B$SggE)S{+h44*F_Bfi@h5)3BuOFF~A9tE)%iYc)+`N;@mfX!L z2v;?NaiBjp{si&XIq2;Gx`Jzm7h!y7{dWELO#J6d`vZ1dzXY%aYNh}H002ovPDHLk FV1jf8d5-`9 literal 0 HcmV?d00001 diff --git a/doodads/objects/anvil.js b/doodads/objects/anvil.js index 2359bca..8ea5d59 100644 --- a/doodads/objects/anvil.js +++ b/doodads/objects/anvil.js @@ -6,11 +6,12 @@ function main() { Self.SetHitbox(0, 0, 48, 25); Self.SetMobile(true); Self.SetGravity(true); + Self.SetInvulnerable(true); // Monitor our Y position to tell if we've been falling. - var lastPoint = Self.Position(); - setInterval(function () { - var nowAt = Self.Position(); + let lastPoint = Self.Position(); + setInterval(() => { + let nowAt = Self.Position(); if (nowAt.Y > lastPoint.Y) { falling = true; } else { @@ -19,7 +20,7 @@ function main() { lastPoint = nowAt; }, 100); - Events.OnCollide(function (e) { + Events.OnCollide((e) => { if (!e.Settled) { return; } @@ -33,7 +34,7 @@ function main() { FailLevel("Watch out for anvils!"); return; } - else if (e.Actor.IsMobile()) { + else if (e.Actor.IsMobile() && !e.Actor.Invulnerable()) { // Destroy mobile doodads. Sound.Play("crumbly-break.wav"); e.Actor.Destroy(); @@ -43,8 +44,8 @@ function main() { }); // When we receive power, we reset to our original position. - var origPoint = Self.Position(); - Message.Subscribe("power", function (powered) { + let origPoint = Self.Position(); + Message.Subscribe("power", (powered) => { Self.MoveTo(origPoint); Self.SetVelocity(Vector(0, 0)); }); diff --git a/doodads/objects/checkpoint-flag.js b/doodads/objects/checkpoint-flag.js index a50608a..5b28815 100644 --- a/doodads/objects/checkpoint-flag.js +++ b/doodads/objects/checkpoint-flag.js @@ -1,17 +1,28 @@ // Checkpoint Flag. -var isCurrentCheckpoint = false; +var isCurrentCheckpoint = false, + playerEntered = false + broadcastCooldown = time.Now(); function main() { Self.SetHitbox(22 + 16, 16, 75 - 16, 86); setActive(false); + // If the checkpoint is linked to any doodad, the player character will + // become that doodad when they cross this checkpoint. + let skin = null; + for (let actor of Self.GetLinks()) { + skin = actor.Filename; + actor.Destroy(); + } + // Checkpoints broadcast to all of their peers so they all // know which one is the most recently activated. - Message.Subscribe("broadcast:checkpoint", function (currentID) { + Message.Subscribe("broadcast:checkpoint", (currentID) => { setActive(false); + return "a ok"; }); - Events.OnCollide(function (e) { + Events.OnCollide((e) => { if (!e.Settled) { return; } @@ -21,10 +32,19 @@ function main() { return; } - // Set the player checkpoint. SetCheckpoint(Self.Position()); setActive(true); - Message.Broadcast("broadcast:checkpoint", Self.ID()) + + // Don't spam the PubSub queue or we get races and deadlocks. + if (time.Now().After(broadcastCooldown)) { + Message.Broadcast("broadcast:checkpoint", Self.ID()); + broadcastCooldown = time.Now().Add(5 * time.Second) + } + + // Are we setting a new player skin? + if (skin && e.Actor.Doodad().Filename !== skin) { + Actors.SetPlayerCharacter(skin); + } }); } @@ -35,4 +55,4 @@ function setActive(v) { isCurrentCheckpoint = v; Self.ShowLayerNamed(v ? "checkpoint-active" : "checkpoint-inactive"); -} \ No newline at end of file +} diff --git a/doodads/objects/exit-flag.js b/doodads/objects/exit-flag.js index 9e65bf1..d45a754 100644 --- a/doodads/objects/exit-flag.js +++ b/doodads/objects/exit-flag.js @@ -2,7 +2,7 @@ function main() { Self.SetHitbox(22 + 16, 16, 75 - 16, 86); - Events.OnCollide(function (e) { + Events.OnCollide((e) => { if (!e.Settled) { return; } diff --git a/doodads/objects/start-flag.js b/doodads/objects/start-flag.js index dc84a77..f215651 100644 --- a/doodads/objects/start-flag.js +++ b/doodads/objects/start-flag.js @@ -4,8 +4,7 @@ function main() { // Linking a doodad to the Start Flag sets the // player character. Destroy the original doodads. - var links = Self.GetLinks(); - for (var i = 0; i < links.length; i++) { - links[i].Destroy(); + for (var link of Self.GetLinks()) { + link.Destroy(); } } diff --git a/doodads/on-off/state-block-blue.js b/doodads/on-off/state-block-blue.js index b754ea7..16e1421 100644 --- a/doodads/on-off/state-block-blue.js +++ b/doodads/on-off/state-block-blue.js @@ -3,9 +3,9 @@ function main() { Self.SetHitbox(0, 0, 42, 42); // Blue block is ON by default. - var state = true; + let state = true; - Message.Subscribe("broadcast:state-change", function(newState) { + Message.Subscribe("broadcast:state-change", (newState) => { state = !newState; // Layer 0: ON @@ -13,7 +13,7 @@ function main() { Self.ShowLayer(state ? 0 : 1); }); - Events.OnCollide(function(e) { + Events.OnCollide((e) => { if (e.Actor.IsMobile() && e.InHitbox) { if (state) { return false; diff --git a/doodads/on-off/state-block-orange.js b/doodads/on-off/state-block-orange.js index 8989f73..7e3d518 100644 --- a/doodads/on-off/state-block-orange.js +++ b/doodads/on-off/state-block-orange.js @@ -3,9 +3,9 @@ function main() { Self.SetHitbox(0, 0, 42, 42); // Orange block is OFF by default. - var state = false; + let state = false; - Message.Subscribe("broadcast:state-change", function(newState) { + Message.Subscribe("broadcast:state-change", (newState) => { state = newState; // Layer 0: OFF @@ -13,7 +13,7 @@ function main() { Self.ShowLayer(state ? 1 : 0); }); - Events.OnCollide(function(e) { + Events.OnCollide((e) => { if (e.Actor.IsMobile() && e.InHitbox) { if (state) { return false; diff --git a/doodads/on-off/state-button.js b/doodads/on-off/state-button.js index f0b02a6..291260c 100644 --- a/doodads/on-off/state-button.js +++ b/doodads/on-off/state-button.js @@ -1,23 +1,23 @@ // State Block Control Button // Button is "OFF" by default. -var state = false; +let state = false; function main() { Self.SetHitbox(0, 0, 42, 42); // When the button is activated, don't keep toggling state until we're not // being touched again. - var colliding = false; + let colliding = false; // If we receive a state change event from a DIFFERENT on/off button, update // ourself to match the state received. - Message.Subscribe("broadcast:state-change", function(value) { + Message.Subscribe("broadcast:state-change", (value) => { state = value; showSprite(); }); - Events.OnCollide(function(e) { + Events.OnCollide((e) => { if (colliding) { return false; } @@ -40,7 +40,7 @@ function main() { return false; }); - Events.OnLeave(function(e) { + Events.OnLeave((e) => { colliding = false; }) } diff --git a/doodads/regions/Makefile b/doodads/regions/Makefile index 7d8c6b2..1c3f568 100644 --- a/doodads/regions/Makefile +++ b/doodads/regions/Makefile @@ -23,7 +23,16 @@ build: doodad convert -t "Power Source" power-64.png power-source.doodad doodad install-script power.js power-source.doodad + # Warp Door + doodad convert -t "Invisible Warp Door" warp-door-64.png reg-warp-door.doodad + doodad edit-doodad --tag "color=invisible" reg-warp-door.doodad + doodad install-script ../warp-door/warp-door.js reg-warp-door.doodad + + # Reset Level Timer + doodad convert -t "Reset Level Timer" timer-64.png reg-reset-timer.doodad + doodad install-script reset-timer.js reg-reset-timer.doodad + for i in *.doodad; do\ doodad edit-doodad --tag "category=technical" $${i};\ done - cp *.doodad ../../../assets/doodads/ \ No newline at end of file + cp *.doodad ../../../assets/doodads/ diff --git a/doodads/regions/checkpoint-128.png b/doodads/regions/checkpoint-128.png index bc1c34e60934afad5258271a0f2e8f53d6297150..13766e692d29a842d95b8a53c235a583caa2fcec 100644 GIT binary patch delta 818 zcmdnXzK4B+libp!TP$uk9#M3Do#GgBBye>=3)jN1jH?HqT++|DG-+ajcKuqd%V+i# zI$YLOp6u1N^Uo@Y3RezCjt*rd#KkKsG9yD^4{}*GJ;zZj1H&^o!_)8 zQ7~V?KR>GU-0vfSVbek%6+bd;*7NvtqV(uf^K+{0tn(yIH_fbkq_HvLRpQe2$eR~B zmUkqtS{A%-LUH8NJx3!~n?*dI_oww?ebc^8XG&)&dn5{aPf&1jWEKrcRCHYJ*VW1M zR^9f`;l6mK=}zmoBrL@On%QoCZ2o`necstePg-V+_%Z#}-}YCKooTnj?#$cwk8itc z$N1;`fvNYtUXMC(M*Zd4bz;^`Y}*>UU$0yChH<*}feXR0W-0EUE{k-zKKR?SPm`bL z9@9b%)9u^O+4;#g=#);~$H>Rmcu^>Ief1ve8@F%oPq+H}mqB`2QA?t%ocrXBj7Iew zOqxbrK3umL7#MeYx;TbZ+diXM&^!>V2x#;A=_^;*fxE_c#FbFVM z+D6Yae17uLpYK(lBL3&Tzgdzyd-b>dbI#=Xmeluei@*Ku&F3epKqOyuA3 z{nm+p*W-3?%ia6eXvVMl>V>X$!Kc5)-eEe&^Fy>>IsMyxqZ6ld7o~5sJYZjwceaLS z`&q_1D~sswKjLK0re9(&FxmL)t^S_x2l99qv>#k`{=inwNAb07f$NyQR@heAyy$sf ze_Ev=`&!M_ne_s9>tAoKsQp^d&2f(L)$`}qHYeuC6&(Gie0;xoydVby14Hv>Eeplf zO`1#&3>*#&Z9tNNQGtO4C<6pNM^`;)S;MsqEXF9o#0ZoD`I!kQ2Lx s?SD{k;{0Ca_ZM&1RokY8Gq5;l#&6KppF2}FlM|%Z)78&qol`;+04Wt|x&QzG delta 819 zcmV-31I+xq2fYW7LLNma6$dMbIAo~eU_n&GQL9jd3ZYhL)xqS_FKE(`kzgx-^)l0} zj&VTKZ8MdKi<#`I*!7AK1oUGRg3K&qPLh)F9bfkd@bxanv;5EfIeOHb#ejfFJj)Ez zCf*>P-n0$Q`@|7elvUz$;xUshNc_lk#p5^51(yY$88OqTdEyAMSZHIVjakvuh^L67 zs-{!EknvdMyv127S6TC({Dt9voW8Qmb(%v+U=d4@AVNVEC6r+!MypPWg%s__ef)#2 zUm}-6t`ZnI7Epl(+4Y0}!S8OZ{N#j}6pjO(FOKsu40P=Rjhf?pA3ILt1PDF@S9;4| zsRJ{gq}N(n^a$wP1}?5!nz9F6?f?T%hHT2N6r?HS^T7KVeNz_by9GihYhG{7eVjf3 zY3eF@0~{OzBL&J{_jz}BdvE`qY4-O6C`EFK@?hTrld%CZe***oB=AYl-4HqoX1uW;|ByM)8pguSsFZF&*|)I zBk$4MetSLU*{zV80Fs;POGo6AL%-_p+!eqr00AHXa=N!XW6qPs`S11QvHsiMv+3G4 zSM7f}ncbS`e;#eWw%yt1?OrC-_p@LAa^NB#aPPH|{ja@tZQFYLWia*s_Ckw%rk3ry zxCNXU@GBli&g{QskeAy;&th|cfB4**`54|d2l(mWY~AB~aWtPvAHdPX>bJk}-UEAU z06h#=eFm;g5dZ2kjB*vI$LrSPL1%pbw@d=JX3bZfe+kk3w?2#4R}Z&{;2fZSer`P* z_T~jw>_2k+d-D~60000mIIDsavMQJ&00e*l1YigRfB+Bx0zd!&00000z*wvbPROcY ziU1G*0uX>95C8%|00;m9AOHXW0001BAeMzEWLY>x00;m92*3~s00AHX1b_el00000 zfU#H=U7V0r!4v@?00bZaLm&VIfB+Bx0ssI20002SVpVWLRs~Z8fB+DH01SZu5C8%| x00@9&zWo#&5&79T@*chIx7TBK1wa6l@&#_HGo!Qy!^Hpq002ovPDHLkV1m7(a+3f6 diff --git a/doodads/regions/checkpoint.js b/doodads/regions/checkpoint.js index 47f5669..1645f69 100644 --- a/doodads/regions/checkpoint.js +++ b/doodads/regions/checkpoint.js @@ -8,11 +8,11 @@ function main() { // Checkpoints broadcast to all of their peers so they all // know which one is the most recently activated. - Message.Subscribe("broadcast:checkpoint", function (currentID) { + Message.Subscribe("broadcast:checkpoint", (currentID) => { setActive(false); }); - Events.OnCollide(function (e) { + Events.OnCollide((e) => { if (isCurrentCheckpoint || !e.Settled) { return; } @@ -35,4 +35,4 @@ function setActive(v) { } isCurrentCheckpoint = v; -} \ No newline at end of file +} diff --git a/doodads/regions/fire.js b/doodads/regions/fire.js index aae40c8..977537a 100644 --- a/doodads/regions/fire.js +++ b/doodads/regions/fire.js @@ -2,7 +2,7 @@ function main() { Self.Hide(); - Events.OnCollide(function (e) { + Events.OnCollide((e) => { if (!e.Settled) { return; } diff --git a/doodads/regions/goal-128.png b/doodads/regions/goal-128.png index b76991735766e6e6762b97b8e7e970c1eccf6a7d..c93dd3c33546f288fe14cc14cf61deaf3425b9a3 100644 GIT binary patch delta 852 zcmcb`evf^Elibp!TP$uk9#M3Do#GgBBye>=3)jN1jH?HqT++|DG-+ajcKuqd%V+i# zI$YLOp6u1N^Uo@Y3RezCjt*rd#KkKsG9yD^4{}*GJ;zZj1H&^o!_)8 zQ7~V?KR>GU-0vfSVbek%6+bd;*7NvtqV(uf^K+{0tn(yIH_fbkq_HvLRpQe2$eR~B zmUkqtS{A%-LUH8NJx3!~n?*dI_oww?ebc^8XG&)&dn5{aPf&1jWEKrcRCHYJ*VW1M zR^9f`;l6mK=}zmoBrL@On%QoCZ2o`necstePg-V+_%Z#}-}YCKooTnj?#$cwk8itc z$N1;`fvNYtUXMC(M*Zd4bz;^`Y}*>UU$0yChH<*}feXR0W-0EUE{k-zKKR?SPm`bL z9@9b%)9u^O+4;#g=#);~$H>Rmcu^>Ief1ve8@F%oPq+H}mqB`2QA?t%ocrXBj7Iew zOuC}pT2)&a7#MGRx;TbZ+{`yOc!?E-t$`HWl_fUKl5HQ?qL#O zU}0cf;QakkU~1yxpA}3>1{fPqbjexnqGW4YsLTLaf~awmP@HUKe@WlZqBOsm*1mT|6iHh za8G<@7Vpu5vZMPi3It!b`8&7v@2tc1_kVW>`%b;36`nc0?yFpO-1diSRO&yS?B>0Z zRTGq5!yA*uQy=hIVa+wUREtXsPCq^!Son7Flf_SOuBzwmy5GB#TQ0l!&CfkQPY6%W z`Y=a&*EWGIq5CeiE{M4B=L;VLLrtbsM%E?y-A$ZK4GanlOba-H9(7;<`4+HcwZkJn&->H*uzt?IO=n7HIeR1sdQVVrauijalBn#q+OMls zboR{j+69?R7k1>`EPYa9c_q8@{8xrJMh*t128Ig@ z!r!ehG>f*F<(VTp-`?K(_l>AOGtO_{ZXu*y@BZq0@N4@cUl`@eDBSoI_9@DiI!)pPCJUrqo0_tvZW*Aff9x-JWH zzIZ?OW4y_cJErIB%j5Sy`LO@ozegcKOZ!euy}i_a@A0T>YxirPykGMviFupQ{3}B7 z%>7c#Q*1c2>$keUTyOH?*N>`@m|q${vnu;u#W%kxPkz;O{GLp;W&XZTM{-OnPVwH2 z=CIO=f9DjSlTla2&cIM-!fRrh*&ln5h0%dQfPwJ>3(%tq3_$-ffPqbS>_Og5+B3jH z3JkMAidY!HYQgdk9CNtyC*(e?B2_ { if (!e.Settled) { return; } diff --git a/doodads/regions/power-64.png b/doodads/regions/power-64.png index cfe47f55a065c001c773b19937b1e605d2e3fd36..14a743c8feeee74e613d50d1c3068f14547be649 100644 GIT binary patch delta 641 zcmV-{0)GAJ28;%fLLQ~1v^dy7#34iLWIEUV91*o(GQcMi&$7B< z5pNJrZ(4QE`@~UJmQ~_&;xU6RNc_lk#pO57C5Hu`88xz*dEzLsSn6S=hgsRsh^L5S zs-{!EkaJn(yv13oHdyDL{Dt9vg1)lMb($kcVG&D^AVNU{6;xp%L90%Ri45&0J^aIt zUm}-6t_m1A7Epr*+3|z_!S8O(;^c&z6ix#DFSh*=2Lii5yJ_3s$F|)*0sPOvmEQH& zTENUF>CLVdI|2r_fs5;|rtATiJHXIWT{dJ#^3xQGMd1C6z9|n3-U6X0HMh6UK29Hi zEOnK>0S*p<(Gq2^d%Qc?+uOfqI{p0s8>VuEVI3Yvld%CZe+U971Hy?rp#T5@2}wjj zRCwC$n@J9YAP@k>knl;~;A4D)pX9`x%#eA+t|3P(EKO@5*e|9x1S; z(zNldZ=SsZVEX(mF<@ST=`nIw1lh4?gZB3RPwxVy#HVJLNRK;b0RR91=!DPW+GhX) z5P$##AOHafKmY;&0000$87e=Dk_sc>kJZ>|eivW~D>>sQ#kCA00000NkvXXu0mjf-^wWi delta 735 zcmV<50wDd22I&TnLLNma6$dMbIAo~eU_n&GQL9jd3ZYhL)xqS_FKE(`kzgx-^)l0} zj&VTKZ8MdKi<#`I*!7AK1oUGRg3K&qPLh)F9bfkd@bxanv;5EfIeOHb#ejfFJj)Ez zCf*>P-n0$Q`@|7elvUz$;xUshNc_lk#p5^51(yY$88OqTdEyAMSZHIVjakvuh^L67 zs-{!EknvdMyv127S6TC({Dt9voW8Qmb(%v+U=d4@AVNVEC6r+!MypPWg%s__ef)#2 zUm}-6t`ZnI7Epl(+4Y0}!S8OZ{N#j}6pjO(FOKsu40P=Rjhf?pA3ILt1PDF@S9;4| zsRJ{gq}N(n^a$wP1}?5!nz9F6?f?T%hHT2N6r?HS^T7KVeNz_by9GihYhG{7eVjf3 zY3eF@0~{OzBL&J{_jz}BdvE`qY4-O6C`EFK@?hTrld%CZe**(ACuazxfdBvjW=TXr zRCwC$TU!o%?JSy00Mj?y~(YuSe^;#@!!?GWhFR03E(FQNfuD}iF=I7Bv5PUtH4|8*9)D||+>ME#TW0ssI2z$;AT>$8-nq8Vd^lAmgAR11ihp?6COadabh|Ir2G7+f7N&?Pe>Mw=OiO)HeSLDqDQw^ z(+z6qLxN}HrxBp30}Y;y7ZJg$vq3F;57Fz&i-o|3I zZLCIuaW23iaN5HP=K>rapgq>10U!VbfB+Bx0zd!==yrpg#ST86MhNJ{4@}Sozy#|o RTL1t62>?k&PDHLkV1g}FQ6T^T diff --git a/doodads/regions/power.js b/doodads/regions/power.js index 072a526..6b555a3 100644 --- a/doodads/regions/power.js +++ b/doodads/regions/power.js @@ -15,7 +15,7 @@ function main() { ); } - Message.Subscribe("broadcast:ready", function () { + Message.Subscribe("broadcast:ready", () => { Message.Publish("switch:toggle", true); Message.Publish("power", true); }); diff --git a/doodads/regions/reset-timer.js b/doodads/regions/reset-timer.js new file mode 100644 index 0000000..eb12c60 --- /dev/null +++ b/doodads/regions/reset-timer.js @@ -0,0 +1,30 @@ +// Reset Level Timer. +function main() { + Self.Hide(); + + // Reset the level timer only once. + let hasReset = false; + + Events.OnCollide((e) => { + if (!e.Settled) { + return; + } + + // Only care if it's the player. + if (!e.Actor.IsPlayer()) { + return; + } + + if (e.InHitbox && !hasReset) { + Level.ResetTimer(); + hasReset = true; + } + }); + + // Receive a power signal resets the doodad. + Message.Subscribe("power", (powered) => { + if (powered) { + hasReset = true; + } + }); +} diff --git a/doodads/regions/stall.js b/doodads/regions/stall.js index c174594..56cf5d4 100644 --- a/doodads/regions/stall.js +++ b/doodads/regions/stall.js @@ -4,7 +4,7 @@ function main() { Self.Hide(); - var active = true, + let active = true, timeout = 250, ms = Self.GetTag("ms"); @@ -12,7 +12,7 @@ function main() { timeout = parseInt(ms); } - Events.OnCollide(function (e) { + Events.OnCollide((e) => { if (!active || !e.Settled) { return; } @@ -25,7 +25,7 @@ function main() { if (e.InHitbox) { // Grab hold of the player. e.Actor.Freeze(); - setTimeout(function () { + setTimeout(() => { e.Actor.Unfreeze(); }, timeout); @@ -34,7 +34,7 @@ function main() { }); // Reset the trap if powered by a button. - Message.Subscribe("power", function (powered) { + Message.Subscribe("power", (powered) => { active = true; }); } diff --git a/doodads/regions/timer-64.png b/doodads/regions/timer-64.png new file mode 100644 index 0000000000000000000000000000000000000000..4c5587974741a99717bc55269fcf4eb0fd0f1fb5 GIT binary patch literal 901 zcmV;01A6?4P)EX>4Tx04R}tkv&MmKp2MKrivmJ1uIB#$WWauh>AFB6^c+H)C#RSm|Xe?O&XFE z7e~Rh;NZ_<)xpJCR|i)?5c~mgbaGO3krKa43N2#1*Znzq)ttqEfJi*c4AUmwAfDc| z4bJ<-VOEq?;&b9LlP*a7$aTfzH_io@1)do;)2VslFtJ!@W2KE*(bR~ih@+~eQ@)V# zSmnIMSu0mr^Pc>Lp`5<5%ynABNMI35kRU=q6(y8mBSyPUiiH%N$9?<}*DsMvAy)~E z91EyGgY5dj|KN9Tt^DMKmlTQvoiC2_F#>e$0*#vEd>=bb;{*sk16O*>U#SB#pQP7X zTJ#9$+XgPKTbi;5TCi1XOrEd$s6h?M(NpVNALh2OR~mM1{yODA>N z%?jOTLI46FU~R~py;UVk-`?xHC&s?EPRJs__OSEV-}BgC{hDhs%0ct@So_d8(}uv8 zwp(&QZDHYB^1inpvL8-B$N|@cZOP7z|Ir~KV;-(MVsjwH-bKQw9P}%3Wai}8B?*@7 z^WCb!oc%Y(u~H#qYLAtwRR910;LAE7Mh{%~BW(8iwH*8EwLp!wcZxc7UZ@TsPUM0x+0Fod80MHOg7B0Sq zhV8?Ld4Ebnq-E_OVwZLyvxU>=fEFakZ9(V+%31@J=z)~Hpz=s9EkHvAAp`*s009sH0T8e(1b?0; b1lGnMaXU~x8$4z=00000NkvXXu0mjfriPUd literal 0 HcmV?d00001 diff --git a/doodads/regions/warp-door-64.png b/doodads/regions/warp-door-64.png new file mode 100644 index 0000000000000000000000000000000000000000..f2b31d43b9e052d0dc7ed90a7a068015bd500e37 GIT binary patch literal 821 zcmV-51Iqk~P)EX>4Tx04R}tkv&MmP!xqvQ$>-AgGEFHGgLvaAS&XhRVYG*P%E_RVDi#GXws0R zxHt-~1qXi?s}3&Cx;nTDg5VE`qmz@OiTyrGnJet4ik&{7FJrA6-y{D4^000SaNLh0L z01FcU01FcV0GgZ_00007bV*G`2j&3-0umG4(lG)600A*cL_t(|+U=WB4uc>JhQW9j z@8dytA5Y_+%m~5NVvu6LFWJL{ZS=R4w%g*mggsR7*+SIJ*M3gx_dl3|bKDCMQ`gbD z-KeBCvjq?U0emw{fg%r#rR!&b^z3Xt=1AkO@qo`3;_)aME{(GVdJC{FVVCa8s5!)R z*PvXOC*8Mc5NuVblwMnk36G`1H5HZ=>GNQA^|{#?kVfb`UeP1UH$4UNJ802BbI0I_ zA^`vZycBgREamc=aSIKRzisg=xqEs|J1)&{Wps60JYTq!3XhN~(-HD6z-(a=J-?na z;Q_rm!sfPs`L_7osBfVKRwY2%7S9(i_4l;>zo)%`-v^Kf00000fKOc30;IwS@MHF9 zH03Z`009sH0T2KI5C8!XAgcy7@aJi^z&rQ?$wSF;A2tV&00000NkvXXu0mjfuGeS^ literal 0 HcmV?d00001 diff --git a/doodads/snake/Makefile b/doodads/snake/Makefile new file mode 100644 index 0000000..6fa8016 --- /dev/null +++ b/doodads/snake/Makefile @@ -0,0 +1,15 @@ +ALL: build + +.PHONY: build +build: + doodad convert -t "Snake" left-1.png left-2.png left-3.png right-1.png right-2.png right-3.png \ + attack-left-1.png attack-left-2.png attack-left-3.png attack-right-1.png attack-right-2.png \ + attack-right-3.png snake.doodad + doodad install-script snake.js snake.doodad + + # Tag the category for these doodads + for i in *.doodad; do\ + doodad edit-doodad --tag "category=creatures" $${i};\ + done + + cp *.doodad ../../../assets/doodads/ \ No newline at end of file diff --git a/doodads/snake/attack-left-1.png b/doodads/snake/attack-left-1.png new file mode 100644 index 0000000000000000000000000000000000000000..d7e3cdfe44bcea1f52e642db598df59e328165a7 GIT binary patch literal 1202 zcmV;j1Wo&iP)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=%)ATBmTM=1aR02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00N3hL_t(|+U=UVPQx%1hL0;R3?R}qLa2x#3p@lPBSXfD zxf|-rQi&BYkq2Pp0eFo{EOg)^RJxW5kXVq+0B((O(l*#WCON+psZpgS{&Ft=aSA{p zkw_#Gi9{liNF)-8L?V#_5W~7~(usw7KFCH46GQ`J(Ne8$6I$J75E0S9iU1u*(f5@C zp+kvMz7(v=fQV9_yU?qxYq&XoLWSWqB8p%Dz!XL;QX@(^{7MVPW=EAl46+e>zWm7j ze*bOJedrF&VzhVBGK4qkS$E8Hg~v*NAyAYULwBgwepfct|kNKwuA9K}7_C zP^`4tLes)3`J;n5~Up0H`XXMbO@MffdaxbeM$(J?G(Lh=n$~lY6CkOLVy6^ zaTi-cP&aEQ!Lj zs4>pNuI$LILr`mqi>Pp3BjimdV1DtN=O=vsUBHW>nrEOEUG%?9jk4`DuXebeNtn-? zuxRHnS#j5Gl-W)JQ-xoqP|lk_f{qA13e+dB=XI3w!o?P)lS>zB)ncnp-joLFLTq(~ zR&Vy3*+qFE%yxay)4=6Ub*ndqlcUw?`SICnX&6@9r|K^CJqQz!MR%@EskHY7QwX<@ z@8S6f)j+9r;V+vqdJT{@Ndnm3Tmb-plOq6tSd@thXNF3>dD9H?mjXA)Mr^Mg3kkqR zRCpP~U9`Nfryh&L1O6i_0A8V%>a=4q?k8g0Pei9({y&PtvzO0k8l{-fJ=} QVE_OC07*qoM6N<$f?FB`mH+?% literal 0 HcmV?d00001 diff --git a/doodads/snake/attack-left-2.png b/doodads/snake/attack-left-2.png new file mode 100644 index 0000000000000000000000000000000000000000..8fec20b4eb488affaf1c5bb592110c99e06cd6ff GIT binary patch literal 1139 zcmV-(1dRKMP)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=%)ATlCC8)g6i02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00K)%L_t(|+U=UZOT$1E$KRDK4vKY+A{B=?DEKcpIyz)5 z&T%UK1%<91+tIa`*YO)Qo~+}#`6gYN7PKOd=iYbcS_@k@I)QYmSHzw z!Y~G+?plcxeY<#vQE!F{!!r4?x@&<0{}Zjd(NB+hGq`#>twyk{yH*r}5ZkBBTVvdx zi^X7_IDY?m4It(JQ}!4U2V*&1ZDD-fl>hk5>yvQ=CIsUk zlH35Wzqwnv7=Z}`Ek^7+H6~quQ=yg?L|h(`2E+suwBV$+Ko%e-Tq3aJ0u>6RU8j7VzaCV?tlj0gtHwEm@1qrC;wf7K5JEk>x-RacV1ji${CPNVHZr*#+@v88Sp z=)p1qB;bkWjD@89yD8sTP4a7+QXJU;*cfKE%lE68`K?wYn#0P=JN+3IsQ zFxv9*!P;>Jz)v+BCtlN*{?L*B(2-tKe~uxF1R~Gl^AE}zA~vP|!{Gn`002ovPDHLk FV1kr;@rnQd literal 0 HcmV?d00001 diff --git a/doodads/snake/attack-left-3.png b/doodads/snake/attack-left-3.png new file mode 100644 index 0000000000000000000000000000000000000000..00948cdd5915c8481d94627abaff20f8b87e39bc GIT binary patch literal 935 zcmeAS@N?(olHy`uVBq!ia0vp^P9V&|1|%PcFuY)3U~I{Bb`J1#c2+1T%1_J8No8Qr zm{>c}*5j~)%+Yvzmx*1?qAspRA?n>>sm^KzrwuKU5SGE0{*#CR?ll6 z8EAWOeYE_z!cknM?#Zq*xwniQd=v41i?phVN&;ISE zLzUf|qgHJ=X8V)dIWjkO=4%sn!Q)EP6r37*xVkhBI!y`d6%qEl)nEDJx9oloy_qqt z21Pmxctj^XX8+%O|L&}vorUI_BFwkqa(*XEWZY+c6?*%h-L|*CI0Y)$)@@m~KZZHY z&U3xl))Rsk_VUKWn44De@3_PGYhKC82{M`vm*<~me4qZsS8~B~u@^DL)!Ai(P=vF< zBeIx*fm;}a85w5HkpK#^mw5WRvOi;GWKyu)I^obeppayVYeb22er|4RUI~M9QEFmI zYKlU6W=V#EyQgnJcq5-UFuLnKT^vIyZoR#|(d)2-1p9~jL%OWSM@*dpt(G)5t$*-> zIpqxVoZy1eGw-hS*){NAxGoSgYoXTBvbBqx#2?Cd-QHq)Mf3j5-}MCnlN^fn|9k(M zcP0D5uF{lg^Sl3DnOq|#f2g#kmP7i~`rotHAG%TQn=G`^_F{y4nlQ4FWqh&d8YY=3do}*$b*mpSW%25#HMUpz`&_CrbmrEWdaAZ~4=o zrEX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=%)At1=$TWeSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00N0gL_t(|+U=P?PXaL*#@{ntNQ7{#gcyy(E&4(H0E~VB zHo|IROk9Z*%*N5d(b2C!;sS$uG0J)v7+grs0js5HFZZX{x4`>MVvf-M?(OqFZ2?Fm z5{X12kw_#Gi9{liNFw{h5Oz+tbE3e;AD2s+JJ2f!u- zR1m63`fX-)^5`J=WXFR~cszR6KI6C9_It#5@RUV*)|Ll`@Ib^X zD>!>Q)jl%2Us`LYs9i&Z@bxiAgMbRcl}d0bP+>!G4g?kir$Ef^m#Dw*R7GG_gOeVy zb0EZa$^XXMXE;?6JW=k{rb|}6RfBq~h8C~ULC9&c-m2{$2;MGb7+A{#1q5%CNicS% zB4ilYRpHDjw%=xJ9uf8On81P(wr z@{h{`;sglY4phGLC=-Z>wG3n>UG(S__9J63m~8-gCTv5@)|<}@z*g8QwIcZB!+r!| zKhkyu-5x`PpbB2jdxYw8muG^kJ4_p`)2c^^)uB6!P(j$}WSP|%RdAB_CmWS4RcW#4 zd4tJzX+1}%Zno0`QFV;6Ji|)+lpTKtQ6|$Azb~gtQ&5=cNvF*YNxtB>Sz_G&`j{)9 zL0cM~^M3&0rJ2Mi0#bpLvxTW8;uV2#-L3w8zPMQ!gOSEBOt;oTOXKDJ8vp=~4=Qlo zt-{4s1W)^rIwzz_m?{9yn5A3|9Ei@m0!VlMs54Q~3(9Jr%tSRDA5?z-yHE}^%ivYe zY^2NFAo%1tklTkP4DX5$81qIvw^>G`AdW^sEOw7gRql#dz5UGxK$7$W?vPAH5y3AP P00000NkvXXu0mjfKPL@u literal 0 HcmV?d00001 diff --git a/doodads/snake/attack-right-2.png b/doodads/snake/attack-right-2.png new file mode 100644 index 0000000000000000000000000000000000000000..6bbef9cf1cd34d8eabf194f4ac6da4291150b009 GIT binary patch literal 1127 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 literal 0 HcmV?d00001 diff --git a/doodads/snake/left-3.png b/doodads/snake/left-3.png new file mode 100644 index 0000000000000000000000000000000000000000..9c8eedb4e2655668f1dbb3fc4e09168972d7c36a GIT binary patch literal 1152 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 R{MP^g002ovPDHLkV1kMO7z6+S literal 0 HcmV?d00001 diff --git a/doodads/snake/right-2.png b/doodads/snake/right-2.png new file mode 100644 index 0000000000000000000000000000000000000000..37828ced4eeecc62d2a719165f37765c480a69fa GIT binary patch literal 1172 zcmV;F1Z(?=P)EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=%)Ar+oepG*J%02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00L}DL_t(|+U=RWPQp+ahTodAFhGPAiNQGF;)OUmbTrO5 z8CDY)*2b+D;OGT#AxsR$#t_y@>fmBh2RzMb=`TIyJL30jKm+yZ_j?2whG7_nVHk#C z7=~dOhG7_nVHk$_!&oNV#Aw_P^FCj=E9;;|NCCr1FM4lwHvhdd3kXA8+@0)2hD9ks z6`(RZn@1u5>_vt!O#%R1y!%44j zygpbF>tzt@3Z}>)8K`8NRBMIj_@o7s)(z1M&KxiqgG}){cnt(-vOezcTY*hO!RS z!kO}&VV$VZvVF>k*zmda6lKny4@rMN!c-I%H_A5pr&T9i&D^+F+GcAF340t}SY}=tkCXb+@QmD0dmAj7yCoDMe5e mNn;LXsz{^!PZ+~6|C=8VeNwA`kv-M`0000EX>4Tx04R}tkv&MmKpe$iKSYs=gB3(YGE^rEqN0vkg(6f4wL+^7CYOFelZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`kex4aNQptJZFtLztVY!7_!BB}Oi6e@tQNBOz zvch?bvs$XK#y$B9Ls@NQnd>wM5yv8yAVPqQ3W_MfLX=jG6cb6>k9qj}9luB}nOsFM zax9<>6_Voz|AXJ%nz@N_Hz^bY+Foq?V;E@P1?pAX{yw(t`Uwzt2ClTGzgz=mK1r`O zwa5|By$xJkH#K<=xZDByo^;8O94SE4pUVO7XY@@Opyw9oTyuMC?BnzSNKsdb8{ps& z7|B!iy2raaT6_EVOryUa#c*=S+P_|M00006VoOIv0RI600RN!9r;`8x010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<^=%)AsLtD(`Ntx02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00L1-L_t(|+U=OVPQx%1g-?(dBtW!lL5PYWEIbG!Lr271 zCd7)=rEA322Vmp@`XHScDk6kf3!(!Hk{Q6kb@S6Uc5PMX+X8`_5BuDE4G=;IA%qY@ z2qA2p_MXGtc{ndu#oC5yEcx zc>Tot<2L}H(Gj^~0A%lMR7RK*)K-sCTt;114eug!3G3(=ir8XL8HkAE+h%1~xshS1 z2cfDAf8i;89u04OgsKi^sZ5iJm#pyCVwcJAA;kNvQ6@td;<}6mF@09aD3W7SND%iC zri?{|n2nfs5#7uG(l>ZmeNlB}*w`JSu7v*0E&$-}ep-3?vPhRX^NiVi&_&svJA@4h zG=_tvze#yW;MCinP~6 zyaTBp4coU(X)?)>vptWEFk@2Ub5b>*#&H00000 LNkvXXu0mjf&>`_Y literal 0 HcmV?d00001 diff --git a/doodads/snake/snake.js b/doodads/snake/snake.js new file mode 100644 index 0000000..952f742 --- /dev/null +++ b/doodads/snake/snake.js @@ -0,0 +1,131 @@ +// Snake + +/* +A.I. Behaviors: + +- Always turns to face the nearest player character +- Jumps up when the player tries to jump over them, + aiming to attack the player. +*/ + +let direction = "left", + jumpSpeed = 12, + watchRadius = 300, // player nearby distance for snake to jump + jumpCooldownStart = time.Now(), + size = Self.Size(); + +const states = { + idle: 0, + attacking: 1, +}; +let state = states.idle; + +function main() { + Self.SetMobile(true); + Self.SetGravity(true); + Self.SetHitbox(20, 0, 28, 58); + Self.AddAnimation("idle-left", 100, ["left-1", "left-2", "left-3", "left-2"]); + Self.AddAnimation("idle-right", 100, ["right-1", "right-2", "right-3", "right-2"]); + Self.AddAnimation("attack-left", 100, ["attack-left-1", "attack-left-2", "attack-left-3"]) + Self.AddAnimation("attack-right", 100, ["attack-right-1", "attack-right-2", "attack-right-3"]) + + // Player Character controls? + if (Self.IsPlayer()) { + return player(); + } + + Events.OnCollide((e) => { + // The snake is deadly to the touch. + if (e.Settled && e.Actor.IsPlayer() && e.InHitbox) { + // Friendly to fellow snakes. + if (e.Actor.Doodad().Filename.indexOf("snake") > -1) { + return; + } + + FailLevel("Watch out for snakes!"); + return; + } + }); + + setInterval(() => { + // Find the player. + let player = Actors.FindPlayer(), + playerPoint = player.Position(), + point = Self.Position(), + delta = 0, + nearby = false; + + // Face the player. + if (playerPoint.X < point.X + (size.W / 2)) { + direction = "left"; + delta = Math.abs(playerPoint.X - (point.X + (size.W/2))); + } + else if (playerPoint.X > point.X + (size.W / 2)) { + direction = "right"; + delta = Math.abs(playerPoint.X - (point.X + (size.W/2))); + } + + if (delta < watchRadius) { + nearby = true; + } + + // If we are idle and the player is jumping nearby... + if (state == states.idle && nearby && Self.Grounded()) { + if (playerPoint.Y - point.Y+(size.H/2) < 20) { + // Enter attack state. + if (time.Since(jumpCooldownStart) > 500 * time.Millisecond) { + state = states.attacking; + Self.SetVelocity(Vector(0, -jumpSpeed)); + Self.StopAnimation(); + Self.PlayAnimation("attack-"+direction, null); + return; + } + } + } + + // If we are attacking and gravity has claimed us back. + if (state === states.attacking && Self.Grounded()) { + state = states.idle; + jumpCooldownStart = time.Now(); + Self.StopAnimation(); + } + + // Ensure that the animations are always rolling. + if (state === states.idle && !Self.IsAnimating()) { + Self.PlayAnimation("idle-"+direction, null); + } + }, 100); +} + +// If under control of the player character. +function player() { + let jumping = false; + + Events.OnKeypress((ev) => { + Vx = 0; + Vy = 0; + + if (ev.Right) { + direction = "right"; + } else if (ev.Left) { + direction = "left"; + } + + // Jump! + if (ev.Up && !jumping) { + Self.StopAnimation(); + Self.PlayAnimation("attack-"+direction, null); + jumping = true; + return; + } + + if (jumping && Self.Grounded()) { + Self.StopAnimation(); + jumping = false; + } + + if (!jumping && !Self.IsAnimating()) { + Self.PlayAnimation("idle-"+direction, null); + } + }); +} diff --git a/doodads/switches/switch.js b/doodads/switches/switch.js index 973a7b3..99fa153 100644 --- a/doodads/switches/switch.js +++ b/doodads/switches/switch.js @@ -4,15 +4,15 @@ function main() { // 0: Off // 1: On - var state = false; - var collide = false; + let state = false; + let collide = false; - Message.Subscribe("power", function (powered) { + Message.Subscribe("power", (powered) => { state = powered; showState(state); }); - Events.OnCollide(function (e) { + Events.OnCollide((e) => { if (!e.Settled || !e.Actor.IsMobile()) { return; } @@ -21,7 +21,6 @@ function main() { Sound.Play("button-down.wav") state = !state; - var nonce = Math.random() * 2147483647; Message.Publish("switch:toggle", state); Message.Publish("power", state); showState(state); @@ -30,7 +29,7 @@ function main() { } }); - Events.OnLeave(function (e) { + Events.OnLeave((e) => { collide = false; }); } diff --git a/doodads/thief/thief.js b/doodads/thief/thief.js index bdc945a..77c2a70 100644 --- a/doodads/thief/thief.js +++ b/doodads/thief/thief.js @@ -21,8 +21,8 @@ function main() { // Common "steal" power between playable and A.I. thieves. function stealable() { // Steals your items. - Events.OnCollide(function (e) { - var victim = e.Actor; + Events.OnCollide((e) => { + let victim = e.Actor; if (!e.Settled) { return; } @@ -33,17 +33,17 @@ function stealable() { } // Steal inventory - var stolen = 0; + let stolen = 0; if (victim.HasInventory()) { - var myInventory = Self.Inventory(), + let myInventory = Self.Inventory(), theirInventory = victim.Inventory(); - for (var key in theirInventory) { + for (let key in theirInventory) { if (!theirInventory.hasOwnProperty(key)) { continue; } - var value = theirInventory[key]; + let value = theirInventory[key]; if (value > 0 || myInventory[key] === undefined) { victim.RemoveItem(key, value); Self.AddItem(key, value); @@ -68,7 +68,7 @@ function stealable() { // when it encounters and obstacle. function ai() { // Walks back and forth. - var Vx = Vy = 0.0, + let Vx = Vy = 0.0, playerSpeed = 4, direction = "right", lastDirection = "right", @@ -76,9 +76,9 @@ function ai() { sampleTick = 0, sampleRate = 2; - setInterval(function () { + setInterval(() => { if (sampleTick % sampleRate === 0) { - var curX = Self.Position().X, + let curX = Self.Position().X, delta = Math.abs(curX - lastSampledX); if (delta < 5) { direction = direction === "right" ? "left" : "right"; @@ -106,25 +106,18 @@ function ai() { // If under control of the player character. function playable() { - Events.OnKeypress(function (ev) { - Vx = 0; - Vy = 0; - + Events.OnKeypress((ev) => { if (ev.Right) { if (!Self.IsAnimating()) { Self.PlayAnimation("walk-right", null); } - Vx = playerSpeed; } else if (ev.Left) { if (!Self.IsAnimating()) { Self.PlayAnimation("walk-left", null); } - Vx = -playerSpeed; } else { Self.StopAnimation(); animating = false; } - - // Self.SetVelocity(Point(Vx, Vy)); }) -} \ No newline at end of file +} diff --git a/doodads/trapdoors/down.js b/doodads/trapdoors/down.js deleted file mode 100644 index 3ea5fba..0000000 --- a/doodads/trapdoors/down.js +++ /dev/null @@ -1,36 +0,0 @@ -function main() { - var timer = 0; - - Self.SetHitbox(0, 0, 72, 6); - - var animationSpeed = 100; - var opened = false; - Self.AddAnimation("open", animationSpeed, ["down1", "down2", "down3", "down4"]); - Self.AddAnimation("close", animationSpeed, ["down4", "down3", "down2", "down1"]); - - Events.OnCollide( function(e) { - if (opened) { - return; - } - - // Is the actor colliding our solid part? - if (e.InHitbox) { - // Touching the top or the bottom? - if (e.Overlap.Y > 0) { - return false; // solid wall when touched from below - } else { - opened = true; - Self.PlayAnimation("open", function() { - }); - } - } - }); - - Events.OnLeave(function() { - if (opened) { - Self.PlayAnimation("close", function() { - opened = false; - }); - } - }) -} diff --git a/doodads/trapdoors/trapdoor.js b/doodads/trapdoors/trapdoor.js index 54dca12..9bb6d70 100644 --- a/doodads/trapdoors/trapdoor.js +++ b/doodads/trapdoors/trapdoor.js @@ -1,12 +1,12 @@ -function main() { - // What direction is the trapdoor facing? - var direction = Self.GetTag("direction"); +// Trapdoors. - var timer = 0; +// What direction is the trapdoor facing? +const direction = Self.GetTag("direction"); +function main() { // Set our hitbox based on our orientation. - var thickness = 10; - var doodadSize = 86; + let thickness = 10; + let doodadSize = 86; if (direction === "left") { Self.SetHitbox(48, 0, doodadSize, doodadSize); } else if (direction === "right") { @@ -17,12 +17,12 @@ function main() { Self.SetHitbox(0, 0, doodadSize, thickness); } - var animationSpeed = 100; - var opened = false; + let animationSpeed = 100; + let opened = false; // Register our animations. - var frames = []; - for (var i = 1; i <= 4; i++) { + let frames = []; + for (let i = 1; i <= 4; i++) { frames.push(direction + i); } @@ -30,7 +30,7 @@ function main() { frames.reverse(); Self.AddAnimation("close", animationSpeed, frames); - Events.OnCollide( function(e) { + Events.OnCollide((e) => { if (opened) { return; } @@ -78,9 +78,9 @@ function main() { } }); - Events.OnLeave(function() { + Events.OnLeave(() => { if (opened) { - Self.PlayAnimation("close", function() { + Self.PlayAnimation("close", () => { opened = false; }); } diff --git a/doodads/warp-door/Makefile b/doodads/warp-door/Makefile index a4842e1..90d80b2 100644 --- a/doodads/warp-door/Makefile +++ b/doodads/warp-door/Makefile @@ -17,10 +17,10 @@ build: doodad install-script warp-door.js warp-door-orange.doodad for i in *.doodad; do\ - doodad edit-doodad --tag "category=doors" $${i};\ + doodad edit-doodad --tag "category=doors" --hitbox=34,76 $${i};\ done for i in warp-door-*.doodad; do\ doodad edit-doodad --tag "category=doors,gizmos" $${i};\ done - cp *.doodad ../../../assets/doodads/ \ No newline at end of file + cp *.doodad ../../../assets/doodads/ diff --git a/doodads/warp-door/warp-door.js b/doodads/warp-door/warp-door.js index 0cb6e1a..2bde9f3 100644 --- a/doodads/warp-door/warp-door.js +++ b/doodads/warp-door/warp-door.js @@ -1,18 +1,17 @@ // Warp Doors -function main() { - Self.SetHitbox(0, 0, 34, 76); - // Are we a blue or orange door? Regular warp door will be 'none' - var color = Self.GetTag("color"); - var isStateDoor = color === 'blue' || color === 'orange'; - var state = color === 'blue'; // Blue door is ON by default. +const color = Self.GetTag("color"), + isStateDoor = color === 'blue' || color === 'orange'; - var animating = false; - var collide = false; +// State in case we're a blue warp door. +let state = color === 'blue', + animating = false, + collide = false; +function main() { // Declare animations and sprite names. - var animSpeed = 100; - var spriteDefault, spriteDisabled; // the latter for state doors. + let animSpeed = 100; + let spriteDefault, spriteDisabled; // the latter for state doors. if (color === 'blue') { Self.AddAnimation("open", animSpeed, ["blue-2", "blue-3", "blue-4"]); Self.AddAnimation("close", animSpeed, ["blue-4", "blue-3", "blue-2", "blue-1"]); @@ -23,6 +22,11 @@ function main() { Self.AddAnimation("close", animSpeed, ["orange-4", "orange-3", "orange-2", "orange-1"]); spriteDefault = "orange-1"; spriteDisabled = "orange-off"; + } else if (color === 'invisible') { + // Invisible Warp Door region. + Self.Hide(); + Self.AddAnimation("open", animSpeed, [0, 0]); + Self.AddAnimation("close", animSpeed, [0, 0]); } else { Self.AddAnimation("open", animSpeed, ["door-2", "door-3", "door-4"]); Self.AddAnimation("close", animSpeed, ["door-4", "door-3", "door-2", "door-1"]); @@ -30,17 +34,17 @@ function main() { } // Find our linked Warp Door. - var links = Self.GetLinks() - var linkedDoor = null; - for (var i = 0; i < links.length; i++) { - if (links[i].Title.indexOf("Warp Door") > -1) { - linkedDoor = links[i]; + let linkedDoor = null; + for (let link of Self.GetLinks()) { + if (link.Title.indexOf("Warp Door") > -1) { + linkedDoor = link; + break; } } // Subscribe to the global state-change if we are a state door. if (isStateDoor) { - Message.Subscribe("broadcast:state-change", function(newState) { + Message.Subscribe("broadcast:state-change", (newState) => { state = color === 'blue' ? !newState : newState; // Activate or deactivate the door. @@ -48,9 +52,12 @@ function main() { }); } + // For player groundedness work-around + let playerLastY = []; // last sampling of Y values + // The player Uses the door. - var flashedCooldown = false; // "Locked Door" flashed message. - Events.OnUse(function(e) { + let flashedCooldown = false; // "Locked Door" flashed message. + Events.OnUse((e) => { if (animating) { return; } @@ -74,14 +81,48 @@ function main() { return; } + // The player must be grounded or have no gravity to open the door. + if (!e.Actor.Grounded() && e.Actor.HasGravity()) { + // Work-around: if two Boxes are stacked atop each other the player can + // get stuck if he jumps on top. He may not be Grounded but isn't changing + // effective Y position and a warp door may work as a good way out. + let yValue = e.Actor.Position().Y; + + // Collect a sampling of last few Y values. If the player Y position + // is constant the last handful of frames, treat them as if they're + // grounded (or else they can't activate the warp door). + playerLastY.unshift(yValue); + if (playerLastY.length < 6) { + return; + } + + // We have enough history. + playerLastY.pop(); + + // Hasn't moved? + let isGrounded = true; + for (let i = 0; i < playerLastY.length; i++) { + if (yValue !== playerLastY[i]) { + isGrounded = false; + break; + } + } + + if (!isGrounded) { + return; + } + + // Player was effectively grounded! No change in Y position. + } + // Freeze the player. e.Actor.Freeze() // Play the open and close animation. animating = true; - Self.PlayAnimation("open", function() { + Self.PlayAnimation("open", () => { e.Actor.Hide() - Self.PlayAnimation("close", function() { + Self.PlayAnimation("close", () => { Self.ShowLayerNamed(isStateDoor && !state ? spriteDisabled : spriteDefault); animating = false; @@ -98,12 +139,12 @@ function main() { }); // Respond to incoming warp events. - Message.Subscribe("warp-door:incoming", function(player) { + Message.Subscribe("warp-door:incoming", (player) => { animating = true; player.Unfreeze(); - Self.PlayAnimation("open", function() { + Self.PlayAnimation("open", () => { player.Show(); - Self.PlayAnimation("close", function() { + Self.PlayAnimation("close", () => { animating = false; // If the receiving door was a State Door, fix its state.