doodle/dev-assets/doodads/objects/checkpoint-flag.js
Noah Petherbridge 626fd53a84 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.
2022-01-18 21:24:36 -08:00

59 lines
1.6 KiB
JavaScript

// Checkpoint Flag.
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) => {
if (!e.Settled) {
return;
}
// Only care about the player character.
if (!e.Actor.IsPlayer()) {
return;
}
SetCheckpoint(Self.Position());
setActive(true);
// 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);
}
});
}
function setActive(v) {
if (v && !isCurrentCheckpoint) {
Flash("Checkpoint!");
}
isCurrentCheckpoint = v;
Self.ShowLayerNamed(v ? "checkpoint-active" : "checkpoint-inactive");
}