Switch JavaScript engine to goja

* Switch from otto to goja for JavaScript engine.
* goja supports many ES6 syntax features like arrow functions,
  const/let, for-of with more coming soon.
* Same great features as otto, more modern environment for doodads!
master
Noah 2022-01-16 20:09:27 -08:00
parent ca9ad6e3a8
commit c1a87e03e6
29 changed files with 188 additions and 295 deletions

View File

@ -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);
}

View File

@ -5,7 +5,7 @@ var playerSpeed = 12,
lastDirection = "right"; lastDirection = "right";
function setupAnimations(color) { function setupAnimations(color) {
var left = color === 'blue' ? 'blu-wl' : 'red-wl', let left = color === 'blue' ? 'blu-wl' : 'red-wl',
right = color === 'blue' ? 'blu-wr' : 'red-wr', right = color === 'blue' ? 'blu-wr' : 'red-wr',
leftFrames = [left + '1', left + '2', left + '3', left + '4'], leftFrames = [left + '1', left + '2', left + '3', left + '4'],
rightFrames = [right + '1', right + '2', right + '3', right + '4']; rightFrames = [right + '1', right + '2', right + '3', right + '4'];
@ -15,7 +15,7 @@ function setupAnimations(color) {
} }
function main() { function main() {
var color = Self.GetTag("color"); const color = Self.GetTag("color");
playerSpeed = color === 'blue' ? 2 : 4; playerSpeed = color === 'blue' ? 2 : 4;
Self.SetMobile(true); Self.SetMobile(true);
@ -32,14 +32,14 @@ function main() {
// when it meets resistance. // when it meets resistance.
// Sample our X position every few frames and detect if we've hit a solid wall. // Sample our X position every few frames and detect if we've hit a solid wall.
var sampleTick = 0; let sampleTick = 0;
var sampleRate = 5; let sampleRate = 5;
var lastSampledX = 0; let lastSampledX = 0;
setInterval(function () { setInterval(() => {
if (sampleTick % sampleRate === 0) { if (sampleTick % sampleRate === 0) {
var curX = Self.Position().X; let curX = Self.Position().X;
var delta = Math.abs(curX - lastSampledX); let delta = Math.abs(curX - lastSampledX);
if (delta < 5) { if (delta < 5) {
direction = direction === "right" ? "left" : "right"; direction = direction === "right" ? "left" : "right";
} }
@ -47,7 +47,7 @@ function main() {
} }
sampleTick++; sampleTick++;
var Vx = parseFloat(playerSpeed * (direction === "left" ? -1 : 1)); let Vx = parseFloat(playerSpeed * (direction === "left" ? -1 : 1));
Self.SetVelocity(Vector(Vx, 0.0)); Self.SetVelocity(Vector(Vx, 0.0));
// If we changed directions, stop animating now so we can // If we changed directions, stop animating now so we can
@ -66,7 +66,7 @@ function main() {
function playerControls() { function playerControls() {
// Note: player speed is controlled by the engine. // Note: player speed is controlled by the engine.
Events.OnKeypress(function (ev) { Events.OnKeypress((ev) => {
if (ev.Right) { if (ev.Right) {
if (!Self.IsAnimating()) { if (!Self.IsAnimating()) {
Self.PlayAnimation("walk-right", null); Self.PlayAnimation("walk-right", null);

View File

@ -1,17 +1,17 @@
// Bird // Bird
function main() { function main() {
var speed = 4; let speed = 4,
var Vx = Vy = 0; Vx = Vy = 0,
var altitude = Self.Position().Y; // original height in the level altitude = Self.Position().Y; // original height in the level
var direction = "left", let direction = "left",
lastDirection = "left"; lastDirection = "left";
var states = { let states = {
flying: 0, flying: 0,
diving: 1, diving: 1,
}; };
var state = states.flying; let state = states.flying;
Self.SetMobile(true); Self.SetMobile(true);
Self.SetGravity(false); Self.SetGravity(false);
@ -24,22 +24,22 @@ function main() {
return player(); return player();
} }
Events.OnCollide(function (e) { Events.OnCollide((e) => {
if (e.Actor.IsMobile() && e.InHitbox) { if (e.Actor.IsMobile() && e.InHitbox) {
return false; return false;
} }
}); });
// Sample our X position every few frames and detect if we've hit a solid wall. // Sample our X position every few frames and detect if we've hit a solid wall.
var sampleTick = 0; let sampleTick = 0,
var sampleRate = 2; sampleRate = 2,
var lastSampledX = 0; lastSampledX = 0,
var lastSampledY = 0; lastSampledY = 0;
setInterval(function () { setInterval(() => {
if (sampleTick % sampleRate === 0) { if (sampleTick % sampleRate === 0) {
var curX = Self.Position().X; let curX = Self.Position().X;
var delta = Math.abs(curX - lastSampledX); let delta = Math.abs(curX - lastSampledX);
if (delta < 5) { if (delta < 5) {
direction = direction === "right" ? "left" : "right"; direction = direction === "right" ? "left" : "right";
} }
@ -48,15 +48,15 @@ function main() {
sampleTick++; sampleTick++;
// If we are not flying at our original altitude, correct for that. // If we are not flying at our original altitude, correct for that.
var curV = Self.Position(); let curV = Self.Position();
var Vy = 0.0; let Vy = 0.0;
if (curV.Y != altitude) { if (curV.Y != altitude) {
Vy = curV.Y < altitude ? 1 : -1; Vy = curV.Y < altitude ? 1 : -1;
} }
// TODO: Vector() requires floats, pain in the butt for JS, // TODO: Vector() requires floats, pain in the butt for JS,
// the JS API should be friendlier and custom... // the JS API should be friendlier and custom...
var Vx = parseFloat(speed * (direction === "left" ? -1 : 1)); let Vx = parseFloat(speed * (direction === "left" ? -1 : 1));
Self.SetVelocity(Vector(Vx, Vy)); Self.SetVelocity(Vector(Vx, Vy));
// If we changed directions, stop animating now so we can // If we changed directions, stop animating now so we can
@ -76,7 +76,7 @@ function main() {
// If under control of the player character. // If under control of the player character.
function player() { function player() {
Self.SetInventory(true); Self.SetInventory(true);
Events.OnKeypress(function (ev) { Events.OnKeypress((ev) => {
Vx = 0; Vx = 0;
Vy = 0; Vy = 0;
@ -103,4 +103,4 @@ function player() {
Self.SetVelocity(Vector(Vx, Vy)); Self.SetVelocity(Vector(Vx, Vy));
}) })
} }

View File

@ -1,20 +1,21 @@
// Pushable Box. // Pushable Box.
var speed = 4;
var size = 75; const speed = 4,
size = 75;
function main() { function main() {
Self.SetMobile(true); Self.SetMobile(true);
Self.SetGravity(true); Self.SetGravity(true);
Self.SetHitbox(0, 0, size, size); Self.SetHitbox(0, 0, size, size);
Events.OnCollide(function (e) { Events.OnCollide((e) => {
// Ignore events from neighboring Boxes. // Ignore events from neighboring Boxes.
if (e.Actor.Actor.Filename === "box.doodad") { if (e.Actor.Actor.Filename === "box.doodad") {
return false; return false;
} }
if (e.Actor.IsMobile() && e.InHitbox) { 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)) { if (overlap.Y === 0 && !(overlap.X === 0 && overlap.W < 5) && !(overlap.X === size)) {
// Standing on top, ignore. // Standing on top, ignore.
@ -39,8 +40,8 @@ function main() {
}); });
// When we receive power, we reset to our original position. // When we receive power, we reset to our original position.
var origPoint = Self.Position(); let origPoint = Self.Position();
Message.Subscribe("power", function (powered) { Message.Subscribe("power", (powered) => {
Self.MoveTo(origPoint); Self.MoveTo(origPoint);
Self.SetVelocity(Vector(0, 0)); Self.SetVelocity(Vector(0, 0));
}); });
@ -52,8 +53,8 @@ function main() {
function animate() { function animate() {
Self.AddAnimation("animate", 100, [0, 1, 2, 3, 2, 1]); Self.AddAnimation("animate", 100, [0, 1, 2, 3, 2, 1]);
var running = false; let running = false;
setInterval(function () { setInterval(() => {
if (!running) { if (!running) {
running = true; running = true;
Self.PlayAnimation("animate", function () { Self.PlayAnimation("animate", function () {
@ -61,4 +62,4 @@ function animate() {
}) })
} }
}, 100); }, 100);
} }

View File

@ -1,10 +1,10 @@
const playerSpeed = 12;
let Vx = Vy = 0,
animating = false,
animStart = animEnd = 0;
function main() { function main() {
var playerSpeed = 12;
var Vx = Vy = 0;
var animating = false;
var animStart = animEnd = 0;
Self.SetMobile(true); Self.SetMobile(true);
Self.SetInventory(true); Self.SetInventory(true);
Self.SetGravity(true); Self.SetGravity(true);
@ -13,13 +13,13 @@ function main() {
Self.AddAnimation("walk-right", 200, ["stand-right", "walk-right-1", "walk-right-2", "walk-right-3", "walk-right-2", "walk-right-1"]); Self.AddAnimation("walk-right", 200, ["stand-right", "walk-right-1", "walk-right-2", "walk-right-3", "walk-right-2", "walk-right-1"]);
// If the player suddenly changes direction, reset the animation state to quickly switch over. // If the player suddenly changes direction, reset the animation state to quickly switch over.
var lastVelocity = Vector(0, 0); let lastVelocity = Vector(0, 0);
Events.OnKeypress(function (ev) { Events.OnKeypress((ev) => {
Vx = 0; Vx = 0;
Vy = 0; Vy = 0;
var curVelocity = Self.GetVelocity(); let curVelocity = Self.GetVelocity();
if ((lastVelocity.X < 0 && curVelocity.X > 0) || if ((lastVelocity.X < 0 && curVelocity.X > 0) ||
(lastVelocity.X > 0 && curVelocity.X < 0)) { (lastVelocity.X > 0 && curVelocity.X < 0)) {
Self.StopAnimation(); Self.StopAnimation();
@ -40,7 +40,5 @@ function main() {
Self.StopAnimation(); Self.StopAnimation();
animating = false; animating = false;
} }
// Self.SetVelocity(Point(Vx, Vy));
}) })
} }

View File

@ -1,18 +1,18 @@
function main() { function main() {
var timer = 0; let timer = 0;
var pressed = false; let pressed = false;
// Has a linked Sticky Button been pressed permanently down? // Has a linked Sticky Button been pressed permanently down?
var stickyDown = false; let stickyDown = false;
Message.Subscribe("sticky:down", function (down) { Message.Subscribe("sticky:down", (down) => {
stickyDown = down; stickyDown = down;
Self.ShowLayer(stickyDown ? 1 : 0); Self.ShowLayer(stickyDown ? 1 : 0);
}); });
// Track who all is colliding with us. // Track who all is colliding with us.
var colliders = {}; let colliders = {};
Events.OnCollide(function (e) { Events.OnCollide((e) => {
if (!e.Settled) { if (!e.Settled) {
return; return;
} }
@ -46,7 +46,7 @@ function main() {
Self.ShowLayer(1); Self.ShowLayer(1);
}); });
Events.OnLeave(function (e) { Events.OnLeave((e) => {
delete colliders[e.Actor.ID()]; delete colliders[e.Actor.ID()];
if (Object.keys(colliders).length === 0 && !stickyDown) { if (Object.keys(colliders).length === 0 && !stickyDown) {

View File

@ -1,8 +1,8 @@
function main() { function main() {
var pressed = false; let pressed = false;
// When a sticky button receives power, it pops back up. // When a sticky button receives power, it pops back up.
Message.Subscribe("power", function (powered) { Message.Subscribe("power", (powered) => {
if (powered && pressed) { if (powered && pressed) {
Self.ShowLayer(0); Self.ShowLayer(0);
pressed = false; pressed = false;
@ -12,7 +12,7 @@ function main() {
} }
}) })
Events.OnCollide(function (e) { Events.OnCollide((e) => {
if (!e.Settled) { if (!e.Settled) {
return; return;
} }

View File

@ -6,19 +6,16 @@ function main() {
Self.AddAnimation("fall", 100, ["fall1", "fall2", "fall3", "fall4"]); Self.AddAnimation("fall", 100, ["fall1", "fall2", "fall3", "fall4"]);
// Recover time for the floor to respawn. // Recover time for the floor to respawn.
var recover = 5000; let recover = 5000;
// States of the floor. // States of the floor.
var stateSolid = 0; let stateSolid = 0;
var stateShaking = 1; let stateShaking = 1;
var stateFalling = 2; let stateFalling = 2;
var stateFallen = 3; let stateFallen = 3;
var state = stateSolid; let state = stateSolid;
// Started the animation? Events.OnCollide((e) => {
var startedAnimation = false;
Events.OnCollide(function(e) {
// If the floor is falling, the player passes right thru. // If the floor is falling, the player passes right thru.
if (state === stateFalling || state === stateFallen) { if (state === stateFalling || state === stateFallen) {
@ -40,15 +37,15 @@ function main() {
// Begin the animation sequence if we're in the solid state. // Begin the animation sequence if we're in the solid state.
if (state === stateSolid) { if (state === stateSolid) {
state = stateShaking; state = stateShaking;
Self.PlayAnimation("shake", function() { Self.PlayAnimation("shake", () => {
state = stateFalling; state = stateFalling;
Self.PlayAnimation("fall", function() { Self.PlayAnimation("fall", () => {
Sound.Play("crumbly-break.wav") Sound.Play("crumbly-break.wav")
state = stateFallen; state = stateFallen;
Self.ShowLayerNamed("fallen"); Self.ShowLayerNamed("fallen");
// Recover after a while. // Recover after a while.
setTimeout(function() { setTimeout(() => {
Self.ShowLayer(0); Self.ShowLayer(0);
state = stateSolid; state = stateSolid;
}, recover); }, recover);

View File

@ -1,9 +1,11 @@
function main() { // Colored Locked Doors.
var color = Self.GetTag("color");
var keyname = color === "small" ? "small-key.doodad" : "key-" + color + ".doodad";
const color = Self.GetTag("color"),
keyname = color === "small" ? "small-key.doodad" : "key-" + color + ".doodad";
function main() {
// Layers in the doodad image. // Layers in the doodad image.
var layer = { let layer = {
closed: 0, closed: 0,
unlocked: 1, unlocked: 1,
right: 2, right: 2,
@ -11,13 +13,13 @@ function main() {
}; };
// Variables that change in event handler. // Variables that change in event handler.
var unlocked = false; // Key has been used to unlock the door (one time). let unlocked = false; // Key has been used to unlock the door (one time).
var opened = false; // If door is currently showing its opened state. let 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 enterSide = 0; // Side of player entering the door, -1 or 1, left or right.
Self.SetHitbox(34, 0, 13, 76); 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 // Record the side that this actor has touched us, in case the door
// needs to open. // needs to open.
if (enterSide === 0) { if (enterSide === 0) {
@ -37,7 +39,7 @@ function main() {
} }
// Do they have our key? // Do they have our key?
var hasKey = e.Actor.HasItem(keyname) >= 0; let hasKey = e.Actor.HasItem(keyname) >= 0;
if (!hasKey) { if (!hasKey) {
// Door is locked. // Door is locked.
return false; return false;
@ -55,7 +57,7 @@ function main() {
} }
} }
}); });
Events.OnLeave(function(e) { Events.OnLeave((e) => {
Self.ShowLayer(unlocked ? layer.unlocked : layer.closed); Self.ShowLayer(unlocked ? layer.unlocked : layer.closed);
// Sound.Play("door-close.wav") // Sound.Play("door-close.wav")

View File

@ -1,6 +1,8 @@
var animating = false; // Electric Door
var opened = false;
var powerState = false; let animating = false;
let opened = false;
let powerState = false;
// Function to handle the door opening or closing. // Function to handle the door opening or closing.
function setPoweredState(powered) { function setPoweredState(powered) {
@ -13,14 +15,14 @@ function setPoweredState(powered) {
animating = true; animating = true;
Sound.Play("electric-door.wav") Sound.Play("electric-door.wav")
Self.PlayAnimation("open", function () { Self.PlayAnimation("open", () => {
opened = true; opened = true;
animating = false; animating = false;
}); });
} else { } else {
animating = true; animating = true;
Sound.Play("electric-door.wav") Sound.Play("electric-door.wav")
Self.PlayAnimation("close", function () { Self.PlayAnimation("close", () => {
opened = false; opened = false;
animating = false; animating = false;
}) })
@ -31,7 +33,6 @@ function main() {
Self.AddAnimation("open", 100, [0, 1, 2, 3]); Self.AddAnimation("open", 100, [0, 1, 2, 3]);
Self.AddAnimation("close", 100, [3, 2, 1, 0]); Self.AddAnimation("close", 100, [3, 2, 1, 0]);
Self.SetHitbox(0, 0, 34, 76); Self.SetHitbox(0, 0, 34, 76);
// A linked Switch that activates the door will send the Toggle signal // A linked Switch that activates the door will send the Toggle signal
@ -39,13 +40,13 @@ function main() {
// state on this signal, and ignore the very next Power signal. Ordinary // 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 // power sources like Buttons will work as normal, as they emit only a power
// signal. // signal.
var ignoreNextPower = false; let ignoreNextPower = false;
Message.Subscribe("switch:toggle", function (powered) { Message.Subscribe("switch:toggle", (powered) => {
ignoreNextPower = true; ignoreNextPower = true;
setPoweredState(!powerState); setPoweredState(!powerState);
}) })
Message.Subscribe("power", function (powered) { Message.Subscribe("power", (powered) => {
if (ignoreNextPower) { if (ignoreNextPower) {
ignoreNextPower = false; ignoreNextPower = false;
return; return;
@ -54,7 +55,7 @@ function main() {
setPoweredState(powered); setPoweredState(powered);
}); });
Events.OnCollide(function (e) { Events.OnCollide((e) => {
if (e.InHitbox) { if (e.InHitbox) {
if (!opened) { if (!opened) {
return false; return false;

View File

@ -1,8 +1,10 @@
function main() { // Colored Keys and Small Key
var color = Self.GetTag("color");
var quantity = color === "small" ? 1 : 0;
Events.OnCollide(function (e) { const color = Self.GetTag("color"),
quantity = color === "small" ? 1 : 0;
function main() {
Events.OnCollide((e) => {
if (e.Settled) { if (e.Settled) {
if (e.Actor.HasInventory()) { if (e.Actor.HasInventory()) {
// If we don't have a quantity, and the actor already has // If we don't have a quantity, and the actor already has

View File

@ -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);
}
}
});
}

View File

@ -8,9 +8,9 @@ function main() {
Self.SetGravity(true); Self.SetGravity(true);
// Monitor our Y position to tell if we've been falling. // Monitor our Y position to tell if we've been falling.
var lastPoint = Self.Position(); let lastPoint = Self.Position();
setInterval(function () { setInterval(() => {
var nowAt = Self.Position(); let nowAt = Self.Position();
if (nowAt.Y > lastPoint.Y) { if (nowAt.Y > lastPoint.Y) {
falling = true; falling = true;
} else { } else {
@ -19,7 +19,7 @@ function main() {
lastPoint = nowAt; lastPoint = nowAt;
}, 100); }, 100);
Events.OnCollide(function (e) { Events.OnCollide((e) => {
if (!e.Settled) { if (!e.Settled) {
return; return;
} }
@ -43,8 +43,8 @@ function main() {
}); });
// When we receive power, we reset to our original position. // When we receive power, we reset to our original position.
var origPoint = Self.Position(); let origPoint = Self.Position();
Message.Subscribe("power", function (powered) { Message.Subscribe("power", (powered) => {
Self.MoveTo(origPoint); Self.MoveTo(origPoint);
Self.SetVelocity(Vector(0, 0)); Self.SetVelocity(Vector(0, 0));
}); });

View File

@ -7,11 +7,11 @@ function main() {
// Checkpoints broadcast to all of their peers so they all // Checkpoints broadcast to all of their peers so they all
// know which one is the most recently activated. // know which one is the most recently activated.
Message.Subscribe("broadcast:checkpoint", function (currentID) { Message.Subscribe("broadcast:checkpoint", (currentID) => {
setActive(false); setActive(false);
}); });
Events.OnCollide(function (e) { Events.OnCollide((e) => {
if (!e.Settled) { if (!e.Settled) {
return; return;
} }
@ -35,4 +35,4 @@ function setActive(v) {
isCurrentCheckpoint = v; isCurrentCheckpoint = v;
Self.ShowLayerNamed(v ? "checkpoint-active" : "checkpoint-inactive"); Self.ShowLayerNamed(v ? "checkpoint-active" : "checkpoint-inactive");
} }

View File

@ -2,7 +2,7 @@
function main() { function main() {
Self.SetHitbox(22 + 16, 16, 75 - 16, 86); Self.SetHitbox(22 + 16, 16, 75 - 16, 86);
Events.OnCollide(function (e) { Events.OnCollide((e) => {
if (!e.Settled) { if (!e.Settled) {
return; return;
} }

View File

@ -4,8 +4,7 @@ function main() {
// Linking a doodad to the Start Flag sets the // Linking a doodad to the Start Flag sets the
// player character. Destroy the original doodads. // player character. Destroy the original doodads.
var links = Self.GetLinks(); for (var link of Self.GetLinks()) {
for (var i = 0; i < links.length; i++) { link.Destroy();
links[i].Destroy();
} }
} }

View File

@ -3,9 +3,9 @@ function main() {
Self.SetHitbox(0, 0, 42, 42); Self.SetHitbox(0, 0, 42, 42);
// Blue block is ON by default. // 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; state = !newState;
// Layer 0: ON // Layer 0: ON
@ -13,7 +13,7 @@ function main() {
Self.ShowLayer(state ? 0 : 1); Self.ShowLayer(state ? 0 : 1);
}); });
Events.OnCollide(function(e) { Events.OnCollide((e) => {
if (e.Actor.IsMobile() && e.InHitbox) { if (e.Actor.IsMobile() && e.InHitbox) {
if (state) { if (state) {
return false; return false;

View File

@ -3,9 +3,9 @@ function main() {
Self.SetHitbox(0, 0, 42, 42); Self.SetHitbox(0, 0, 42, 42);
// Orange block is OFF by default. // 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; state = newState;
// Layer 0: OFF // Layer 0: OFF
@ -13,7 +13,7 @@ function main() {
Self.ShowLayer(state ? 1 : 0); Self.ShowLayer(state ? 1 : 0);
}); });
Events.OnCollide(function(e) { Events.OnCollide((e) => {
if (e.Actor.IsMobile() && e.InHitbox) { if (e.Actor.IsMobile() && e.InHitbox) {
if (state) { if (state) {
return false; return false;

View File

@ -1,23 +1,23 @@
// State Block Control Button // State Block Control Button
// Button is "OFF" by default. // Button is "OFF" by default.
var state = false; let state = false;
function main() { function main() {
Self.SetHitbox(0, 0, 42, 42); Self.SetHitbox(0, 0, 42, 42);
// When the button is activated, don't keep toggling state until we're not // When the button is activated, don't keep toggling state until we're not
// being touched again. // being touched again.
var colliding = false; let colliding = false;
// If we receive a state change event from a DIFFERENT on/off button, update // If we receive a state change event from a DIFFERENT on/off button, update
// ourself to match the state received. // ourself to match the state received.
Message.Subscribe("broadcast:state-change", function(value) { Message.Subscribe("broadcast:state-change", (value) => {
state = value; state = value;
showSprite(); showSprite();
}); });
Events.OnCollide(function(e) { Events.OnCollide((e) => {
if (colliding) { if (colliding) {
return false; return false;
} }
@ -40,7 +40,7 @@ function main() {
return false; return false;
}); });
Events.OnLeave(function(e) { Events.OnLeave((e) => {
colliding = false; colliding = false;
}) })
} }

View File

@ -8,11 +8,11 @@ function main() {
// Checkpoints broadcast to all of their peers so they all // Checkpoints broadcast to all of their peers so they all
// know which one is the most recently activated. // know which one is the most recently activated.
Message.Subscribe("broadcast:checkpoint", function (currentID) { Message.Subscribe("broadcast:checkpoint", (currentID) => {
setActive(false); setActive(false);
}); });
Events.OnCollide(function (e) { Events.OnCollide((e) => {
if (isCurrentCheckpoint || !e.Settled) { if (isCurrentCheckpoint || !e.Settled) {
return; return;
} }
@ -35,4 +35,4 @@ function setActive(v) {
} }
isCurrentCheckpoint = v; isCurrentCheckpoint = v;
} }

View File

@ -2,7 +2,7 @@
function main() { function main() {
Self.Hide(); Self.Hide();
Events.OnCollide(function (e) { Events.OnCollide((e) => {
if (!e.Settled) { if (!e.Settled) {
return; return;
} }

View File

@ -2,7 +2,7 @@
function main() { function main() {
Self.Hide(); Self.Hide();
Events.OnCollide(function (e) { Events.OnCollide((e) => {
if (!e.Settled) { if (!e.Settled) {
return; return;
} }

View File

@ -15,7 +15,7 @@ function main() {
); );
} }
Message.Subscribe("broadcast:ready", function () { Message.Subscribe("broadcast:ready", () => {
Message.Publish("switch:toggle", true); Message.Publish("switch:toggle", true);
Message.Publish("power", true); Message.Publish("power", true);
}); });

View File

@ -4,7 +4,7 @@
function main() { function main() {
Self.Hide(); Self.Hide();
var active = true, let active = true,
timeout = 250, timeout = 250,
ms = Self.GetTag("ms"); ms = Self.GetTag("ms");
@ -12,7 +12,7 @@ function main() {
timeout = parseInt(ms); timeout = parseInt(ms);
} }
Events.OnCollide(function (e) { Events.OnCollide((e) => {
if (!active || !e.Settled) { if (!active || !e.Settled) {
return; return;
} }
@ -25,7 +25,7 @@ function main() {
if (e.InHitbox) { if (e.InHitbox) {
// Grab hold of the player. // Grab hold of the player.
e.Actor.Freeze(); e.Actor.Freeze();
setTimeout(function () { setTimeout(() => {
e.Actor.Unfreeze(); e.Actor.Unfreeze();
}, timeout); }, timeout);
@ -34,7 +34,7 @@ function main() {
}); });
// Reset the trap if powered by a button. // Reset the trap if powered by a button.
Message.Subscribe("power", function (powered) { Message.Subscribe("power", (powered) => {
active = true; active = true;
}); });
} }

View File

@ -4,15 +4,15 @@ function main() {
// 0: Off // 0: Off
// 1: On // 1: On
var state = false; let state = false;
var collide = false; let collide = false;
Message.Subscribe("power", function (powered) { Message.Subscribe("power", (powered) => {
state = powered; state = powered;
showState(state); showState(state);
}); });
Events.OnCollide(function (e) { Events.OnCollide((e) => {
if (!e.Settled || !e.Actor.IsMobile()) { if (!e.Settled || !e.Actor.IsMobile()) {
return; return;
} }
@ -21,7 +21,6 @@ function main() {
Sound.Play("button-down.wav") Sound.Play("button-down.wav")
state = !state; state = !state;
var nonce = Math.random() * 2147483647;
Message.Publish("switch:toggle", state); Message.Publish("switch:toggle", state);
Message.Publish("power", state); Message.Publish("power", state);
showState(state); showState(state);
@ -30,7 +29,7 @@ function main() {
} }
}); });
Events.OnLeave(function (e) { Events.OnLeave((e) => {
collide = false; collide = false;
}); });
} }

View File

@ -21,8 +21,8 @@ function main() {
// Common "steal" power between playable and A.I. thieves. // Common "steal" power between playable and A.I. thieves.
function stealable() { function stealable() {
// Steals your items. // Steals your items.
Events.OnCollide(function (e) { Events.OnCollide((e) => {
var victim = e.Actor; let victim = e.Actor;
if (!e.Settled) { if (!e.Settled) {
return; return;
} }
@ -33,17 +33,17 @@ function stealable() {
} }
// Steal inventory // Steal inventory
var stolen = 0; let stolen = 0;
if (victim.HasInventory()) { if (victim.HasInventory()) {
var myInventory = Self.Inventory(), let myInventory = Self.Inventory(),
theirInventory = victim.Inventory(); theirInventory = victim.Inventory();
for (var key in theirInventory) { for (let key in theirInventory) {
if (!theirInventory.hasOwnProperty(key)) { if (!theirInventory.hasOwnProperty(key)) {
continue; continue;
} }
var value = theirInventory[key]; let value = theirInventory[key];
if (value > 0 || myInventory[key] === undefined) { if (value > 0 || myInventory[key] === undefined) {
victim.RemoveItem(key, value); victim.RemoveItem(key, value);
Self.AddItem(key, value); Self.AddItem(key, value);
@ -68,7 +68,7 @@ function stealable() {
// when it encounters and obstacle. // when it encounters and obstacle.
function ai() { function ai() {
// Walks back and forth. // Walks back and forth.
var Vx = Vy = 0.0, let Vx = Vy = 0.0,
playerSpeed = 4, playerSpeed = 4,
direction = "right", direction = "right",
lastDirection = "right", lastDirection = "right",
@ -76,9 +76,9 @@ function ai() {
sampleTick = 0, sampleTick = 0,
sampleRate = 2; sampleRate = 2;
setInterval(function () { setInterval(() => {
if (sampleTick % sampleRate === 0) { if (sampleTick % sampleRate === 0) {
var curX = Self.Position().X, let curX = Self.Position().X,
delta = Math.abs(curX - lastSampledX); delta = Math.abs(curX - lastSampledX);
if (delta < 5) { if (delta < 5) {
direction = direction === "right" ? "left" : "right"; direction = direction === "right" ? "left" : "right";
@ -106,7 +106,7 @@ function ai() {
// If under control of the player character. // If under control of the player character.
function playable() { function playable() {
Events.OnKeypress(function (ev) { Events.OnKeypress((ev) => {
Vx = 0; Vx = 0;
Vy = 0; Vy = 0;
@ -127,4 +127,4 @@ function playable() {
// Self.SetVelocity(Point(Vx, Vy)); // Self.SetVelocity(Point(Vx, Vy));
}) })
} }

View File

@ -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;
});
}
})
}

View File

@ -1,12 +1,12 @@
// Trapdoors.
// What direction is the trapdoor facing?
const direction = Self.GetTag("direction");
function main() { function main() {
// What direction is the trapdoor facing?
var direction = Self.GetTag("direction");
var timer = 0;
// Set our hitbox based on our orientation. // Set our hitbox based on our orientation.
var thickness = 10; let thickness = 10;
var doodadSize = 86; let doodadSize = 86;
if (direction === "left") { if (direction === "left") {
Self.SetHitbox(48, 0, doodadSize, doodadSize); Self.SetHitbox(48, 0, doodadSize, doodadSize);
} else if (direction === "right") { } else if (direction === "right") {
@ -17,12 +17,12 @@ function main() {
Self.SetHitbox(0, 0, doodadSize, thickness); Self.SetHitbox(0, 0, doodadSize, thickness);
} }
var animationSpeed = 100; let animationSpeed = 100;
var opened = false; let opened = false;
// Register our animations. // Register our animations.
var frames = []; let frames = [];
for (var i = 1; i <= 4; i++) { for (let i = 1; i <= 4; i++) {
frames.push(direction + i); frames.push(direction + i);
} }
@ -30,7 +30,7 @@ function main() {
frames.reverse(); frames.reverse();
Self.AddAnimation("close", animationSpeed, frames); Self.AddAnimation("close", animationSpeed, frames);
Events.OnCollide( function(e) { Events.OnCollide((e) => {
if (opened) { if (opened) {
return; return;
} }
@ -78,9 +78,9 @@ function main() {
} }
}); });
Events.OnLeave(function() { Events.OnLeave(() => {
if (opened) { if (opened) {
Self.PlayAnimation("close", function() { Self.PlayAnimation("close", () => {
opened = false; opened = false;
}); });
} }

View File

@ -1,16 +1,17 @@
// Warp Doors // Warp Doors
const color = Self.GetTag("color"),
isStateDoor = color === 'blue' || color === 'orange';
// State in case we're a blue warp door.
let state = color === 'blue',
animating = false,
collide = false;
function main() { function main() {
// 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.
var animating = false;
var collide = false;
// Declare animations and sprite names. // Declare animations and sprite names.
var animSpeed = 100; let animSpeed = 100;
var spriteDefault, spriteDisabled; // the latter for state doors. let spriteDefault, spriteDisabled; // the latter for state doors.
if (color === 'blue') { if (color === 'blue') {
Self.AddAnimation("open", animSpeed, ["blue-2", "blue-3", "blue-4"]); Self.AddAnimation("open", animSpeed, ["blue-2", "blue-3", "blue-4"]);
Self.AddAnimation("close", animSpeed, ["blue-4", "blue-3", "blue-2", "blue-1"]); Self.AddAnimation("close", animSpeed, ["blue-4", "blue-3", "blue-2", "blue-1"]);
@ -33,17 +34,17 @@ function main() {
} }
// Find our linked Warp Door. // Find our linked Warp Door.
var links = Self.GetLinks() let linkedDoor = null;
var linkedDoor = null; for (let link of Self.GetLinks()) {
for (var i = 0; i < links.length; i++) { if (link.Title.indexOf("Warp Door") > -1) {
if (links[i].Title.indexOf("Warp Door") > -1) { linkedDoor = link;
linkedDoor = links[i]; break;
} }
} }
// Subscribe to the global state-change if we are a state door. // Subscribe to the global state-change if we are a state door.
if (isStateDoor) { if (isStateDoor) {
Message.Subscribe("broadcast:state-change", function(newState) { Message.Subscribe("broadcast:state-change", (newState) => {
state = color === 'blue' ? !newState : newState; state = color === 'blue' ? !newState : newState;
// Activate or deactivate the door. // Activate or deactivate the door.
@ -52,12 +53,11 @@ function main() {
} }
// For player groundedness work-around // For player groundedness work-around
var playerLastY = []; // last sampling of Y values let playerLastY = []; // last sampling of Y values
var lastUsed = time.Now();
// The player Uses the door. // The player Uses the door.
var flashedCooldown = false; // "Locked Door" flashed message. let flashedCooldown = false; // "Locked Door" flashed message.
Events.OnUse(function(e) { Events.OnUse((e) => {
if (animating) { if (animating) {
return; return;
} }
@ -86,7 +86,7 @@ function main() {
// Work-around: if two Boxes are stacked atop each other the player can // 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 // 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. // effective Y position and a warp door may work as a good way out.
var yValue = e.Actor.Position().Y; let yValue = e.Actor.Position().Y;
// Collect a sampling of last few Y values. If the player Y position // 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 // is constant the last handful of frames, treat them as if they're
@ -100,8 +100,8 @@ function main() {
playerLastY.pop(); playerLastY.pop();
// Hasn't moved? // Hasn't moved?
var isGrounded = true; let isGrounded = true;
for (var i = 0; i < playerLastY.length; i++) { for (let i = 0; i < playerLastY.length; i++) {
if (yValue !== playerLastY[i]) { if (yValue !== playerLastY[i]) {
isGrounded = false; isGrounded = false;
break; break;
@ -120,9 +120,9 @@ function main() {
// Play the open and close animation. // Play the open and close animation.
animating = true; animating = true;
Self.PlayAnimation("open", function() { Self.PlayAnimation("open", () => {
e.Actor.Hide() e.Actor.Hide()
Self.PlayAnimation("close", function() { Self.PlayAnimation("close", () => {
Self.ShowLayerNamed(isStateDoor && !state ? spriteDisabled : spriteDefault); Self.ShowLayerNamed(isStateDoor && !state ? spriteDisabled : spriteDefault);
animating = false; animating = false;
@ -139,12 +139,12 @@ function main() {
}); });
// Respond to incoming warp events. // Respond to incoming warp events.
Message.Subscribe("warp-door:incoming", function(player) { Message.Subscribe("warp-door:incoming", (player) => {
animating = true; animating = true;
player.Unfreeze(); player.Unfreeze();
Self.PlayAnimation("open", function() { Self.PlayAnimation("open", () => {
player.Show(); player.Show();
Self.PlayAnimation("close", function() { Self.PlayAnimation("close", () => {
animating = false; animating = false;
// If the receiving door was a State Door, fix its state. // If the receiving door was a State Door, fix its state.