Noah Petherbridge
9b75f1b039
* New built-in wallpaper: "Dotted paper (dark)" is a dark-themed wallpaper. * New built-in palette: "Neon Bright" with bright colors for dark levels. * New cheat: "warp whistle" to automatically win the level. * In case the user has a VERY LARGE screen resolution bigger than the full bounds of a Bounded level, the Play Scene will cap the size and center the level canvas onto the window. This is preferable to being able to see beyond the level's boundaries and hitting an invisible wall in-game. * Make the titlescreen Lazy Scroll work on unbounded levels. It can't bounce off scroll boundaries but it will reverse course if it reaches the level's furthest limits. * Bugfix: characters' white eyes were transparent in-game. Multiple culprits from the `doodad convert` tool defaulting the chroma key to white, to the SDL2 textures considering white to be transparent. For the latter, the game offsets the color by -1 blue.
100 lines
2.7 KiB
JavaScript
100 lines
2.7 KiB
JavaScript
// Gem stone totem socket.
|
|
|
|
/*
|
|
The Totem is a type of key-door that holds onto its corresponding
|
|
Gemstone. When a doodad holding the right Gemstone touches the
|
|
totem, the totem takes the gemstone and activates.
|
|
|
|
If the Totem is not linked to any other Totems, it immediately
|
|
sends a power(true) signal upon activation.
|
|
|
|
If the Totem is linked to other Totems, it waits until all totems
|
|
have been activated before it will emit a power signal. Only one
|
|
such totem needs to be linked to e.g. an Electric Door - no matter
|
|
which totem is solved last, they'll all emit a power signal when
|
|
all of their linked totems are activated.
|
|
*/
|
|
|
|
let color = Self.GetTag("color"),
|
|
keyname = "gem-"+color+".doodad",
|
|
activated = false,
|
|
linkedReceiver = false, // is linked to a non-totem which might want power
|
|
totems = {}, // linked totems
|
|
shimmerFreq = 1000;
|
|
|
|
function main() {
|
|
// Show the hollow socket on level load (last layer)
|
|
Self.ShowLayer(4);
|
|
|
|
// Find any linked totems.
|
|
for (let link of Self.GetLinks()) {
|
|
if (link.Filename.indexOf("gem-totem") > -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);
|
|
} |