Checkpoint Flag can Re-assign Player Character

Link a Doodad to a Checkpoint Flag (like you would a Start Flag) and
crossing the flag will replace the player with that doodad. Multiple
checkpoint flags like this can toggle you between characters.

* Azulians are now friendly to player characters who have the word
  "Azulian" in their title.
* Improve Bird as the playable character:
  * Dive animation if the player flies diagonally downwards
  * Animation loop while hovering in the air instead of pausing
* Checkpoint flags don't spam each other on PubSub so much which could
  sometimes lead to deadlocks!

SetPlayerCharacter added to the JavaScript API. The Checkpoint Flag
(not the region) can link to a doodad and replace the player character
with that linked doodad when you activate the checkpoint:

    Actors.SetPlayerCharacter(filename string): like "boy.doodad"

Add various panic catchers to make JavaScript safer and log issues
to console.
master
Noah 2022-01-18 21:24:36 -08:00
parent 0ee7fb4210
commit 2b8005e942
4 changed files with 45 additions and 19 deletions

View File

@ -52,7 +52,7 @@ function main() {
Events.OnCollide((e) => {
// If we're diving and we hit the player, game over!
// Azulians are friendly to Thieves though!
if (e.Settled && e.Actor.IsPlayer() && e.Actor.Doodad().Filename !== "thief.doodad") {
if (e.Settled && e.Actor.IsPlayer() && e.Actor.Doodad().Filename !== "thief.doodad" && e.Actor.Doodad().Title.indexOf("Azulian") < 0) {
FailLevel("Watch out for the Azulians!");
return;
}

View File

@ -144,32 +144,45 @@ function AI_ScanForPlayer() {
// If under control of the player character.
function player() {
var playerSpeed = 12;
Self.SetInventory(true);
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) {
Self.StopAnimation();
Self.ShowLayerNamed("dive-right");
} else if (ev.Down && ev.Left) {
Self.StopAnimation();
Self.ShowLayerNamed("dive-left");
} else if (ev.Right) {
// Fly right.
if (!Self.IsAnimating()) {
Self.PlayAnimation("fly-right", null);
}
Vx = playerSpeed;
} else if (ev.Left) {
// Fly left.
if (!Self.IsAnimating()) {
Self.PlayAnimation("fly-left", null);
}
Vx = -playerSpeed;
} else {
Self.StopAnimation();
animating = false;
// Hover in place.
if (!Self.IsAnimating()) {
Self.PlayAnimation("fly-"+direction);
}
}
Self.SetVelocity(Vector(Vx, Vy));
// Self.SetVelocity(Vector(Vx, Vy));
})
}

View File

@ -1,14 +1,25 @@
// 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", (currentID) => {
setActive(false);
return "a ok";
});
Events.OnCollide((e) => {
@ -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);
}
});
}

View File

@ -107,24 +107,17 @@ function ai() {
// If under control of the player character.
function playable() {
Events.OnKeypress((ev) => {
Vx = 0;
Vy = 0;
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));
})
}