Add tooltip help for most tiles in the editor
This commit is contained in:
parent
de53582d47
commit
48803b1483
@ -1255,6 +1255,555 @@ const EDITOR_PALETTE = [{
|
|||||||
],
|
],
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
// TODO loading this from json might actually be faster
|
||||||
|
const EDITOR_TILE_DESCRIPTIONS = {
|
||||||
|
// Basics
|
||||||
|
player: {
|
||||||
|
name: "Lexy",
|
||||||
|
cc2_name: "Chip",
|
||||||
|
desc: "The player, a fox girl who enjoys puzzles. Slides on ice. Can walk on dirt and gravel. Reuses green keys.",
|
||||||
|
},
|
||||||
|
player2: {
|
||||||
|
name: "Cerise",
|
||||||
|
cc2_name: "Melinda",
|
||||||
|
desc: "The player, a gel rabbat who enjoys Lexy. Walks on ice. Stopped by dirt and gravel. Reuses yellow keys.",
|
||||||
|
},
|
||||||
|
hint: {
|
||||||
|
name: "Hint",
|
||||||
|
desc: "Shows a hint or message of the level designer's choosing. Stops dirt blocks and monsters.",
|
||||||
|
},
|
||||||
|
floor: {
|
||||||
|
name: "Floor",
|
||||||
|
desc: "Plain floor. No effect. May contain wires; conducts power in all directions, except that two crossed wires are independent. May contain wire tunnels, which conduct power across long distances.",
|
||||||
|
},
|
||||||
|
wall: {
|
||||||
|
name: "Wall",
|
||||||
|
desc: "Plain wall. Stops almost everything.",
|
||||||
|
},
|
||||||
|
thin_walls: {
|
||||||
|
name: "Thin wall",
|
||||||
|
desc: "Similar to a wall, but squeezed into the edges.",
|
||||||
|
},
|
||||||
|
chip: {
|
||||||
|
name: "Heart",
|
||||||
|
cc2_name: "Chip",
|
||||||
|
desc: "Goal of most levels. Must be collected to open the heart socket. Stops dirt blocks and most monsters, except rovers.",
|
||||||
|
},
|
||||||
|
chip_extra: {
|
||||||
|
name: "Extra heart",
|
||||||
|
cc2_name: "Extra chip",
|
||||||
|
desc: "Appears and acts like a heart, but doesn't contribute to the level's required heart count.",
|
||||||
|
},
|
||||||
|
socket: {
|
||||||
|
name: "Socket",
|
||||||
|
desc: "Can only be opened when the required number of hearts has been collected. Stops dirt blocks and most monsters, except rovers, but can be opened by anything else. Not affected by ghosts.",
|
||||||
|
},
|
||||||
|
exit: {
|
||||||
|
name: "Exit",
|
||||||
|
desc: "All players must step on one to clear the level. Stops dirt blocks and most monsters, except rovers.",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Terrain
|
||||||
|
popwall: {
|
||||||
|
name: "Popwall",
|
||||||
|
desc: "Turns into a wall when something steps off of it. Stops dirt blocks and monsters.",
|
||||||
|
},
|
||||||
|
steel: {
|
||||||
|
name: "Steel wall",
|
||||||
|
desc: "Stops everything, even ghosts. May contain wires; conducts power the same way as floor.",
|
||||||
|
},
|
||||||
|
wall_invisible: {
|
||||||
|
name: "Invisible wall",
|
||||||
|
desc: "Reveals briefly when bumped, then disappears again.",
|
||||||
|
},
|
||||||
|
wall_appearing: {
|
||||||
|
name: "Reveal wall",
|
||||||
|
desc: "Turns into a normal wall when bumped.",
|
||||||
|
},
|
||||||
|
fake_floor: {
|
||||||
|
name: "Fake floor",
|
||||||
|
desc: "Looks like a fake wall, but turns to floor when bumped. Stops dirt blocks and monsters.",
|
||||||
|
},
|
||||||
|
fake_wall: {
|
||||||
|
name: "Fake wall",
|
||||||
|
desc: "Turns to wall when bumped.",
|
||||||
|
},
|
||||||
|
popdown_floor: {
|
||||||
|
name: "Popdown floor",
|
||||||
|
desc: "Looks like a popdown wall, but presses down into floor while something's on it. Stops all blocks.",
|
||||||
|
},
|
||||||
|
popdown_wall: {
|
||||||
|
name: "Popdown wall",
|
||||||
|
desc: "Acts like a normal wall, but is indistinguishable from a popdown floor.",
|
||||||
|
},
|
||||||
|
floor_letter: {
|
||||||
|
name: "Letter tile",
|
||||||
|
desc: "Acts like a normal floor. May contain a single letter, number, arrow, or symbol.",
|
||||||
|
},
|
||||||
|
gravel: {
|
||||||
|
name: "Gravel",
|
||||||
|
desc: "Stops monsters. Stops Cerise (and Doppel-Cerise) unless she has hiking boots.",
|
||||||
|
},
|
||||||
|
dirt: {
|
||||||
|
name: "Dirt",
|
||||||
|
desc: "Stops monsters. Stops Cerise (and Doppel-Cerise) unless she has hiking boots. Turns to floor when stepped on.",
|
||||||
|
},
|
||||||
|
slime: {
|
||||||
|
name: "Slime",
|
||||||
|
desc: "Destroys almost everything. Blobs are unaffected and spread it to neighboring floor. Cleared by blocks (except frame blocks, which are destroyed) without harming the block.",
|
||||||
|
},
|
||||||
|
thief_keys: {
|
||||||
|
name: "Key thief",
|
||||||
|
desc: "Steals all colored keys from a player that steps on it, and cuts bonus points in half. Prefers to take a bribe, and will take one from anything.",
|
||||||
|
},
|
||||||
|
thief_tools: {
|
||||||
|
name: "Tool thief",
|
||||||
|
desc: "Steals all boots and other tools from a player that steps on it, and cuts bonus points in half. Prefers to take a bribe, and will take one from anything.",
|
||||||
|
},
|
||||||
|
no_player1_sign: {
|
||||||
|
name: "'No foxes' sign",
|
||||||
|
desc: "Stops Lexy (and Doppel-Lexy). No other effect.",
|
||||||
|
},
|
||||||
|
no_player2_sign: {
|
||||||
|
name: "'No bunnies' sign",
|
||||||
|
desc: "Stops Cerise (and Doppel-Cerise). No other effect.",
|
||||||
|
},
|
||||||
|
floor_custom_green: {
|
||||||
|
name: "Custom floor",
|
||||||
|
desc: "Decorative flooring. Acts like normal floor. Stops ghosts.",
|
||||||
|
},
|
||||||
|
wall_custom_green: {
|
||||||
|
name: "Custom wall",
|
||||||
|
desc: "Decorative flooring. Acts like normal wall. Stops ghosts.",
|
||||||
|
},
|
||||||
|
door_blue: {
|
||||||
|
name: "Blue door",
|
||||||
|
desc: "Requires a blue key. Turns to floor when opened. Stops dirt blocks and monsters that don't normally collect items, even if they have a key.",
|
||||||
|
},
|
||||||
|
door_red: {
|
||||||
|
name: "Red door",
|
||||||
|
desc: "Requires a red key. Turns to floor when opened. Stops dirt blocks and monsters that don't normally collect items, even if they have a key.",
|
||||||
|
},
|
||||||
|
door_yellow: {
|
||||||
|
name: "Yellow door",
|
||||||
|
desc: "Requires a yellow key. Turns to floor when opened. Stops dirt blocks and monsters that don't normally collect items, even if they have a key.",
|
||||||
|
},
|
||||||
|
door_green: {
|
||||||
|
name: "Green door",
|
||||||
|
desc: "Requires a green key. Turns to floor when opened. Stops dirt blocks and monsters that don't normally collect items, even if they have a key.",
|
||||||
|
},
|
||||||
|
swivel_nw: {
|
||||||
|
name: "Swivel door",
|
||||||
|
desc: "Cannot be entered from the barred sides. Rotates when something leaves through a barred side.",
|
||||||
|
},
|
||||||
|
railroad: {
|
||||||
|
name: "Railroad track",
|
||||||
|
desc: "Anything on it may move at its leisure, but only in legal directions along the track, unless it has a railroad crossing sign. Only blocks may go back the way they came. Attempts to move in illegal directions will be redirected. May contain multiple track pieces, allowing a choice of which way to go. With a track switch, only one track piece may be used at a time, and the active piece will change every time something leaves the track. If connected to wire, the track will instead only switch when receiving a pulse. Gray buttons can switch the track either way.",
|
||||||
|
},
|
||||||
|
water: {
|
||||||
|
name: "Water",
|
||||||
|
desc: "Drowns players and most monsters, unless they have a mermaid tail. Turns dirt blocks into dirt, ice blocks into ice, and frame blocks into floor. Gliders may pass freely. Stops ghosts, unless they have a mermaid tail.",
|
||||||
|
},
|
||||||
|
turtle: {
|
||||||
|
name: "Lilypad",
|
||||||
|
cc2_name: "Turtle",
|
||||||
|
desc: "May be passed safely, but turns to water when something steps off of it. Stops ghosts.",
|
||||||
|
},
|
||||||
|
fire: {
|
||||||
|
name: "Fire",
|
||||||
|
desc: "Destroys players, unless they have fire boots. Stops most monsters, even with fire boots. No effect on fireballs. Erased by ghosts with fire boots. Turns ice blocks to water.",
|
||||||
|
},
|
||||||
|
ice: {
|
||||||
|
name: "Ice",
|
||||||
|
desc: "Causes anything that steps on it to slide uncontrollably, unless it has ice cleats. Anything that hits an obstacle while on ice will turn around and slide back the other way. No effect on Cerise (or Doppel-Cerise).",
|
||||||
|
},
|
||||||
|
ice_nw: {
|
||||||
|
name: "Ice corner",
|
||||||
|
desc: "Acts like ice, but turns anything sliding on it around the corner. Edges act like thin walls.",
|
||||||
|
},
|
||||||
|
force_floor_n: {
|
||||||
|
name: "Force floor",
|
||||||
|
desc: "Slides anything on it in the indicated direction, unless it has suction boots. Players may attempt to step off, but not on their first slide. No effect on ghosts.",
|
||||||
|
},
|
||||||
|
force_floor_all: {
|
||||||
|
name: "All-way force floor",
|
||||||
|
desc: "Acts like force floor, but cycles clockwise through directions. This cycle is shared between every all-way force floor in the level.",
|
||||||
|
},
|
||||||
|
canopy: {
|
||||||
|
name: "Canopy",
|
||||||
|
desc: "Hides everything beneath it from view, unless the player has the x-ray glasses. Stops beetles and rovers. Blobs under a canopy may not move to an adjacent canopy.",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Items
|
||||||
|
key_blue: {
|
||||||
|
name: "Blue key",
|
||||||
|
desc: "Opens blue locks. Picked up by monsters and dirt blocks.",
|
||||||
|
},
|
||||||
|
key_red: {
|
||||||
|
name: "Red key",
|
||||||
|
desc: "Opens red locks. Never picked up by anything besides a player.",
|
||||||
|
},
|
||||||
|
key_yellow: {
|
||||||
|
name: "Yellow key",
|
||||||
|
desc: "Opens yellow locks. Stops dirt blocks and monsters (except rovers).",
|
||||||
|
},
|
||||||
|
key_green: {
|
||||||
|
name: "Green key",
|
||||||
|
desc: "Opens green locks. Stops dirt blocks and monsters (except rovers).",
|
||||||
|
},
|
||||||
|
flippers: {
|
||||||
|
name: "Mermaid tail",
|
||||||
|
cc2_name: "Flippers",
|
||||||
|
desc: "Allows safe passage through water.",
|
||||||
|
},
|
||||||
|
fire_boots: {
|
||||||
|
name: "Fire boots",
|
||||||
|
desc: "Allows safe passage through fire.",
|
||||||
|
},
|
||||||
|
cleats: {
|
||||||
|
name: "Ice cleats",
|
||||||
|
desc: "Allows walking normally on ice.",
|
||||||
|
},
|
||||||
|
suction_boots: {
|
||||||
|
name: "Suction boots",
|
||||||
|
desc: "Allows walking normally on force floors.",
|
||||||
|
},
|
||||||
|
hiking_boots: {
|
||||||
|
name: "Hiking boots",
|
||||||
|
desc: "Allows Cerise to walk on gravel and dirt. Causes ghosts to turn dirt to floor. No effect for other monsters.",
|
||||||
|
},
|
||||||
|
speed_boots: {
|
||||||
|
name: "Speed boots",
|
||||||
|
desc: "Causes the owner to move at double speed.",
|
||||||
|
},
|
||||||
|
lightning_bolt: {
|
||||||
|
name: "Lightning boots",
|
||||||
|
desc: "Powers any wires the owner is standing on.",
|
||||||
|
},
|
||||||
|
railroad_sign: {
|
||||||
|
name: "RR crossing sign",
|
||||||
|
desc: "Allows free movement on railroad tracks.",
|
||||||
|
},
|
||||||
|
helmet: {
|
||||||
|
name: "Helmet",
|
||||||
|
desc: "Prevents monsters or sliding blocks from hitting a player, or a player from walking into a monster.",
|
||||||
|
},
|
||||||
|
foil: {
|
||||||
|
name: "Steel foil",
|
||||||
|
desc: "Causes the owner to turn walls into steel walls when bumping them.",
|
||||||
|
},
|
||||||
|
hook: {
|
||||||
|
name: "Hook",
|
||||||
|
desc: "Causes the owner to pull blocks when moving directly away from them.",
|
||||||
|
},
|
||||||
|
xray_eye: {
|
||||||
|
name: "X-ray glasses",
|
||||||
|
cc2_name: "Secret eye",
|
||||||
|
desc: "Reveals invisible walls, reveal walls, fake floors, popdown floors, floor mimics, and anything underneath dirt blocks, ice blocks, or canopies to the player. No effect for anything else.",
|
||||||
|
},
|
||||||
|
bribe: {
|
||||||
|
name: "Bribe",
|
||||||
|
desc: "Stolen by thieves instead of anything else.",
|
||||||
|
},
|
||||||
|
bowling_ball: {
|
||||||
|
name: "Bowling ball",
|
||||||
|
desc: "When dropped, rolls in a straight line until it hits something. Destroys objects it hits. Picks up items it encounters.",
|
||||||
|
},
|
||||||
|
dynamite: {
|
||||||
|
name: "Time bomb",
|
||||||
|
cc2_name: "Dynamite",
|
||||||
|
desc: "Can only be lit by a player. A few seconds after being dropped, destroys everything in a 5×5 circle around it. Canopies protect anything underneath; objects protect the floor they're on (including objects on a clone machine); steel walls, sockets, and logic gates cannot be destroyed; anything else becomes fire.",
|
||||||
|
},
|
||||||
|
no_sign: {
|
||||||
|
name: "'No' sign",
|
||||||
|
desc: "When placed over an item, stops anything holding that item. When empty, has no effect, but an item may be dropped beneath it.",
|
||||||
|
},
|
||||||
|
score_10: {
|
||||||
|
name: "+10 bonus",
|
||||||
|
desc: "Grants the player 10 bonus points. Can be collected by doppelgangers, rovers, and bowling balls, but will not grant bonus points.",
|
||||||
|
},
|
||||||
|
score_100: {
|
||||||
|
name: "+100 bonus",
|
||||||
|
desc: "Grants the player 100 bonus points. Can be collected by doppelgangers, rovers, and bowling balls, but will not grant bonus points.",
|
||||||
|
},
|
||||||
|
score_1000: {
|
||||||
|
name: "+1000 bonus",
|
||||||
|
desc: "Grants the player 1000 bonus points. Can be collected by doppelgangers, rovers, and bowling balls, but will not grant bonus points.",
|
||||||
|
},
|
||||||
|
score_2x: {
|
||||||
|
name: "×2 bonus",
|
||||||
|
desc: "Doubles the player's current bonus points. Can be collected by doppelgangers, rovers, and bowling balls, but will not grant bonus points.",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Creatures
|
||||||
|
tank_blue: {
|
||||||
|
name: "Blue tank",
|
||||||
|
desc: "Only moves forwards. Reverses direction when a blue button is pressed.",
|
||||||
|
},
|
||||||
|
tank_yellow: {
|
||||||
|
name: "Yellow tank",
|
||||||
|
desc: "Idles. Moves one step in the corresponding direction when a yellow d-pad is pressed.",
|
||||||
|
},
|
||||||
|
ball: {
|
||||||
|
name: "Bouncy ball",
|
||||||
|
desc: "Turns around when it hits something.",
|
||||||
|
},
|
||||||
|
walker: {
|
||||||
|
name: "Walker",
|
||||||
|
desc: "Turns in a random direction when it hits something.",
|
||||||
|
},
|
||||||
|
fireball: {
|
||||||
|
name: "Fireball",
|
||||||
|
cc2_name: "Fire box",
|
||||||
|
desc: "Turns right when it hits something. Can safely pass through fire and flame jets. Melts ice blocks.",
|
||||||
|
},
|
||||||
|
glider: {
|
||||||
|
name: "Glider",
|
||||||
|
cc2_name: "Ship",
|
||||||
|
desc: "Turns left when it hits something. Can safely cross water.",
|
||||||
|
},
|
||||||
|
bug: {
|
||||||
|
name: "Beetle",
|
||||||
|
cc2_name: "Ant",
|
||||||
|
desc: "Follows the left wall.",
|
||||||
|
},
|
||||||
|
paramecium: {
|
||||||
|
name: "Millipede",
|
||||||
|
cc2_name: "Centipede",
|
||||||
|
desc: "Follows the right wall.",
|
||||||
|
},
|
||||||
|
doppelganger1: {
|
||||||
|
name: "Doppel-Lexy",
|
||||||
|
cc2_name: "Mirror Chip",
|
||||||
|
desc: "Copies Lexy's movements. Does almost anything Lexy can do: collect items, push blocks, pass through tiles that block monsters, etc. Cannot collect hearts.",
|
||||||
|
},
|
||||||
|
doppelganger2: {
|
||||||
|
name: "Doppel-Cerise",
|
||||||
|
cc2_name: "Mirror Melinda",
|
||||||
|
desc: "Copies Cerise's movements. Does almost anything Cerise can do: collect items, push blocks, walk normally on ice, pass through tiles that block monsters (but not dirt or gravel), etc. Cannot collect hearts.",
|
||||||
|
},
|
||||||
|
teeth: {
|
||||||
|
name: "Red chomper",
|
||||||
|
cc2_name: "Angry teeth",
|
||||||
|
desc: "Chases after Lexy. Runs away from Cerise. Pauses after each step.",
|
||||||
|
},
|
||||||
|
teeth_timid: {
|
||||||
|
name: "Blue chomper",
|
||||||
|
cc2_name: "Timid teeth",
|
||||||
|
desc: "Chases after Cerise. Runs away from Lexy. Pauses after each step.",
|
||||||
|
},
|
||||||
|
floor_mimic: {
|
||||||
|
name: "Floor mimic",
|
||||||
|
desc: "Looks just like floor, except when moving. Chases after the player. Pauses after each step.",
|
||||||
|
},
|
||||||
|
ghost: {
|
||||||
|
name: "Ghost",
|
||||||
|
desc: "Turns left when it hits something. Passes freely through almost all obstacles except blocks and other monsters, steel walls, water, lilypads, and custom floors/walls. Does not set off mines. Collects items and opens doors. With fire boots, erases fire it steps on. With flippers, can pass through water, but not lilypads. Can only be destroyed by flame jets.",
|
||||||
|
},
|
||||||
|
rover: {
|
||||||
|
name: "Rover",
|
||||||
|
desc: "Cycles through the behavior of other monsters. Collects items and pushes blocks. Moves at half speed.",
|
||||||
|
},
|
||||||
|
blob: {
|
||||||
|
name: "Blob",
|
||||||
|
desc: "Moves in a random direction with every step. Moves at half speed.",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Mechanisms
|
||||||
|
dirt_block: {
|
||||||
|
name: "Dirt block",
|
||||||
|
desc: "Can be pushed, but only one at a time. Resists fire. Turns to dirt in water.",
|
||||||
|
},
|
||||||
|
ice_block: {
|
||||||
|
name: "Ice block",
|
||||||
|
desc: "Can be pushed. Pushes any ice block or frame block ahead of it. Turns to water in fire. Turns to ice in water.",
|
||||||
|
},
|
||||||
|
frame_block: {
|
||||||
|
name: "Frame block",
|
||||||
|
desc: "Can be pushed, but only in the directions given by the arrows. Pushes any other kind of block ahead of it. Can be moved in other directions by ice, force floors, etc. Rotates when moved along a curved railroad track.",
|
||||||
|
},
|
||||||
|
green_floor: {
|
||||||
|
name: "Toggle floor",
|
||||||
|
desc: "Acts like a normal floor. Becomes toggle wall when a green button is pressed.",
|
||||||
|
},
|
||||||
|
green_wall: {
|
||||||
|
name: "Toggle wall",
|
||||||
|
desc: "Acts like a normal wall. Becomes toggle floor when a green button is pressed.",
|
||||||
|
},
|
||||||
|
green_chip: {
|
||||||
|
name: "Toggle heart",
|
||||||
|
cc2_name: "Toggle chip",
|
||||||
|
desc: "Acts like a normal heart. Counts toward the level's required hearts. Becomes a toggle mine when a green button is pressed.",
|
||||||
|
},
|
||||||
|
green_bomb: {
|
||||||
|
name: "Toggle mine",
|
||||||
|
cc2_name: "Toggle bomb",
|
||||||
|
desc: "Acts like a normal mine. Counts toward the level's required hearts. Becomes a toggle heart when a green button is pressed.",
|
||||||
|
},
|
||||||
|
button_green: {
|
||||||
|
name: "Green button",
|
||||||
|
desc: "Exchanges toggle floors with toggle walls, and toggle hearts with toggle mines.",
|
||||||
|
},
|
||||||
|
button_blue: {
|
||||||
|
name: "Blue button",
|
||||||
|
desc: "Reverses the direction of blue tanks.",
|
||||||
|
},
|
||||||
|
button_yellow: {
|
||||||
|
name: "Yellow d-pad",
|
||||||
|
cc2_name: "Yellow button",
|
||||||
|
desc: "Moves yellow tanks one step in the direction it was stepped on.",
|
||||||
|
},
|
||||||
|
bomb: {
|
||||||
|
name: "Mine",
|
||||||
|
cc2_name: "Red bomb",
|
||||||
|
desc: "Detonates and destroys anything that steps on it.",
|
||||||
|
},
|
||||||
|
button_red: {
|
||||||
|
name: "Red button",
|
||||||
|
desc: "Activates the nearest clone machine, searching left to right, top to bottom.",
|
||||||
|
},
|
||||||
|
cloner: {
|
||||||
|
name: "Clone machine",
|
||||||
|
desc: "When activated, creates a duplicate of whatever's on it. Activated by a red button or a wire pulse. If activated by wire and something's in the way, tries cloning in other directions. When empty, can be populated by blocks (except dirt blocks), doppelgängers, ghosts, or rolling bowling balls.",
|
||||||
|
},
|
||||||
|
button_brown: {
|
||||||
|
name: "Brown button",
|
||||||
|
desc: "Opens the nearest trap while held down, searching left to right, top to bottom. Anything freed is immediately spat out in the direction it's facing.",
|
||||||
|
},
|
||||||
|
trap: {
|
||||||
|
name: "Trap",
|
||||||
|
desc: "Prevents anything from leaving unless held open. May be held open by a brown button or wire current. Trapped monsters cannot turn, but a trapped player can.",
|
||||||
|
},
|
||||||
|
button_orange: {
|
||||||
|
name: "Orange button",
|
||||||
|
desc: "Toggles the state of the nearest flame jet while held down, searching outwards in a diamond pattern.",
|
||||||
|
},
|
||||||
|
flame_jet_off: {
|
||||||
|
name: "Flame jet (off)",
|
||||||
|
desc: "No effect. Turned on while an orange button is held or while receiving power. Turned on permanently by a gray button.",
|
||||||
|
},
|
||||||
|
flame_jet_off: {
|
||||||
|
name: "Flame jet (on)",
|
||||||
|
desc: "Destroys almost anything that passes over it, except dirt blocks, fireballs, and anything wearing fire boots. Turned off while an orange button is held or while receiving power. Turned off permanently by a gray button.",
|
||||||
|
},
|
||||||
|
transmogrifier: {
|
||||||
|
name: "Transmogrifier",
|
||||||
|
desc: "Changes most objects into corresponding opposites: Lexy ↔ Cerise, Doppel-Lexy ↔ Doppel-Cerise, dirt block ↔ ice block, bouncy ball ↔ walker, fireball → beetle → glider → millipede → fireball, blue tank ↔ yellow tank, red chomper ↔ blue chomper, blob → one of most monsters chosen at random. If connected to wire, only functions while receiving power.",
|
||||||
|
},
|
||||||
|
teleport_blue: {
|
||||||
|
name: "Blue teleporter",
|
||||||
|
desc: "Teleports a traveller to the nearest available blue teleporter, searching right to left, bottom to top. Only searches for exits in the direction the traveller entered. If connected to wire, will only consider other teleporters on the same circuit (searching one-way through logic gates). May contain wires; conducts power in all four directions.",
|
||||||
|
},
|
||||||
|
teleport_red: {
|
||||||
|
name: "Red teleporter",
|
||||||
|
desc: "Teleports a traveller to the nearest available red teleporter, searching left to right, top to bottom. Searches for exits in any direction. Allows players to exit in a direction of their choice. If connected to wire, will only connect to other red teleporters while receiving power. May contain wires, but does not conduct power.",
|
||||||
|
},
|
||||||
|
teleport_yellow: {
|
||||||
|
name: "Yellow teleporter",
|
||||||
|
desc: "Teleports a traveller to the nearest available yellow teleporter, searching right to left, bottom to top. Only searches for exits in the direction the traveller entered. Allows players to exit in a direction of their choice. If no exit is available, will be picked up like an item, and can be dropped on any floor tile.",
|
||||||
|
},
|
||||||
|
teleport_green: {
|
||||||
|
name: "Green teleporter",
|
||||||
|
desc: "Teleports a traveller to a green teleporter chosen at random. Chooses an available exit direction at random, but if the chosen destination has none, the teleport will fail.",
|
||||||
|
},
|
||||||
|
stopwatch_bonus: {
|
||||||
|
name: "Time bonus",
|
||||||
|
desc: "Adds ten seconds to the clock. An untimed level becomes timed, with ten seconds remaining.",
|
||||||
|
},
|
||||||
|
stopwatch_penalty: {
|
||||||
|
name: "Time penalty",
|
||||||
|
desc: "Subtracts ten seconds from the clock. If less than ten seconds remain, the player will fail immediately. An untimed level becomes timed and fails immediately.",
|
||||||
|
},
|
||||||
|
stopwatch_toggle: {
|
||||||
|
name: "Stopwatch",
|
||||||
|
desc: "Pauses or unpauses the clock. No effect on untimed levels.",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Logic
|
||||||
|
'logic_gate/not': {
|
||||||
|
name: "NOT gate",
|
||||||
|
desc: "Emits power only when not receiving power.",
|
||||||
|
},
|
||||||
|
'logic_gate/and': {
|
||||||
|
name: "AND gate",
|
||||||
|
desc: "Emits power while both inputs are receiving power.",
|
||||||
|
},
|
||||||
|
'logic_gate/or': {
|
||||||
|
name: "OR gate",
|
||||||
|
desc: "Emits power while at least one input is receiving power.",
|
||||||
|
},
|
||||||
|
'logic_gate/xor': {
|
||||||
|
name: "XOR gate",
|
||||||
|
desc: "Emits power while exactly one input is receiving power.",
|
||||||
|
},
|
||||||
|
'logic_gate/nand': {
|
||||||
|
name: "NAND gate",
|
||||||
|
desc: "Emits power while fewer than two inputs are receiving power.",
|
||||||
|
},
|
||||||
|
'logic_gate/latch-cw': {
|
||||||
|
name: "Latch (clockwise)",
|
||||||
|
desc: "Remembers its input and produces output to match. Input is remembered while the chevron input is receiving power, ignored otherwise.",
|
||||||
|
},
|
||||||
|
'logic_gate/latch-ccw': {
|
||||||
|
name: "Latch (counter clockwise)",
|
||||||
|
desc: "Remembers its input and produces output to match. Input is remembered while the chevron input is receiving power, ignored otherwise.",
|
||||||
|
},
|
||||||
|
'logic_gate/counter': {
|
||||||
|
name: "Counter",
|
||||||
|
desc: "Remembers and displays a single decimal digit. Counts up by 1 when it receives a pulse on its right edge; if it wraps around to 0, emits a brief pulse out its left edge. Counts down by 1 when it receives a pulse on its bottom edge; if it wraps around to 9, emits power from its top edge until it next receives power on its right or bottom edge. Cannot be rotated.",
|
||||||
|
},
|
||||||
|
button_pink: {
|
||||||
|
name: "Pink button",
|
||||||
|
desc: "Emits power while held down. May contain wires, but does not conduct power.",
|
||||||
|
},
|
||||||
|
button_black: {
|
||||||
|
name: "Black button",
|
||||||
|
desc: "Emits power while not held down. May contain wires; conducts power separately along horizontal and vertical wires.",
|
||||||
|
},
|
||||||
|
light_switch_off: {
|
||||||
|
name: "Light switch (off)",
|
||||||
|
desc: "No effect. Turns on when stepped on. May contain wires.",
|
||||||
|
},
|
||||||
|
light_switch_off: {
|
||||||
|
name: "Light switch (on)",
|
||||||
|
desc: "Emits power. Turns off when stepped on. May contain wires.",
|
||||||
|
},
|
||||||
|
purple_floor: {
|
||||||
|
name: "Switch floor",
|
||||||
|
desc: "Acts like a normal floor. Becomes switch wall while receiving power, or permanently when affected by a gray button.",
|
||||||
|
},
|
||||||
|
purple_wall: {
|
||||||
|
name: "Switch wall",
|
||||||
|
desc: "Acts like a normal wall. Becomes switch floor while receiving power, or permanently when affected by a gray button.",
|
||||||
|
},
|
||||||
|
button_gray: {
|
||||||
|
name: "Gray button",
|
||||||
|
desc: "Permanently toggles the state of tiles in a surrounding 5×5 square. Rotates swivels clockwise; switches railroad tracks; flips force floors; exchanges toggle walls/floors (but not hearts/mines); exchanges switch walls/floors; activates cloners as if by a red button; and toggles flame jets.",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Experimental
|
||||||
|
circuit_block: {
|
||||||
|
name: "Circuit block",
|
||||||
|
desc: "(Currently non-functional.) May contain wires, which will connect to any adjacent wires and conduct power as normal.",
|
||||||
|
},
|
||||||
|
gift_bow: {
|
||||||
|
name: "Gift bow",
|
||||||
|
desc: "When placed atop an item, anything may step on the item and will pick it up, even if it normally could not do so. When placed alone, has no effect, but an item may be dropped beneath it.",
|
||||||
|
},
|
||||||
|
skeleton_key: {
|
||||||
|
name: "Skeleton key",
|
||||||
|
desc: "Counts as a tool, not a key. Opens any color lock if the owner lacks a matching key.",
|
||||||
|
},
|
||||||
|
gate_red: {
|
||||||
|
name: "Red gate",
|
||||||
|
desc: "Requires a red key. Unlike doors, may be placed on top of other terrain.",
|
||||||
|
},
|
||||||
|
sand: {
|
||||||
|
name: "Sand",
|
||||||
|
desc: "Anything walking on it moves at half speed. Stops all blocks.",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const SPECIAL_PALETTE_ENTRIES = {
|
const SPECIAL_PALETTE_ENTRIES = {
|
||||||
'thin_walls/south': { name: 'thin_walls', edges: DIRECTIONS['south'].bit },
|
'thin_walls/south': { name: 'thin_walls', edges: DIRECTIONS['south'].bit },
|
||||||
'frame_block/0': { name: 'frame_block', direction: 'south', arrows: new Set },
|
'frame_block/0': { name: 'frame_block', direction: 'south', arrows: new Set },
|
||||||
@ -1631,7 +2180,7 @@ export class Editor extends PrimaryView {
|
|||||||
src: tooldef.icon,
|
src: tooldef.icon,
|
||||||
alt: tooldef.name,
|
alt: tooldef.name,
|
||||||
}),
|
}),
|
||||||
mk('div.-help', mk('h3', tooldef.name), tooldef.desc),
|
mk('div.-help.editor-big-tooltip', mk('h3', tooldef.name), tooldef.desc),
|
||||||
);
|
);
|
||||||
this.tool_button_els[toolname] = button;
|
this.tool_button_els[toolname] = button;
|
||||||
toolbox.append(button);
|
toolbox.append(button);
|
||||||
@ -1771,6 +2320,24 @@ export class Editor extends PrimaryView {
|
|||||||
this.select_palette(key, true);
|
this.select_palette(key, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// Hover help
|
||||||
|
palette_el.addEventListener('mouseover', ev => {
|
||||||
|
let entry = ev.target.closest('canvas.palette-entry');
|
||||||
|
if (! entry)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.show_palette_tooltip(entry.getAttribute('data-palette-key'));
|
||||||
|
});
|
||||||
|
palette_el.addEventListener('mouseout', ev => {
|
||||||
|
let entry = ev.target.closest('canvas.palette-entry');
|
||||||
|
if (! entry)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.hide_palette_tooltip();
|
||||||
|
});
|
||||||
|
this.palette_tooltip = mk('div.editor-palette-tooltip.editor-big-tooltip', mk('h3'), mk('p'));
|
||||||
|
this.root.append(this.palette_tooltip);
|
||||||
|
|
||||||
this.palette_selection = null;
|
this.palette_selection = null;
|
||||||
this.select_palette('floor', true);
|
this.select_palette('floor', true);
|
||||||
}
|
}
|
||||||
@ -1982,6 +2549,35 @@ export class Editor extends PrimaryView {
|
|||||||
this.tool_button_els[this.current_tool].classList.add('-selected');
|
this.tool_button_els[this.current_tool].classList.add('-selected');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
show_palette_tooltip(key) {
|
||||||
|
let desc = EDITOR_TILE_DESCRIPTIONS[key];
|
||||||
|
if (! desc && SPECIAL_PALETTE_ENTRIES[key]) {
|
||||||
|
let name = SPECIAL_PALETTE_ENTRIES[key].name;
|
||||||
|
desc = EDITOR_TILE_DESCRIPTIONS[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! desc) {
|
||||||
|
this.palette_tooltip.classList.remove('--visible');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.palette_tooltip.classList.add('--visible');
|
||||||
|
this.palette_tooltip.querySelector('h3').textContent = desc.name;
|
||||||
|
this.palette_tooltip.querySelector('p').textContent = desc.desc;
|
||||||
|
|
||||||
|
// Place it out of the way of the palette (so, overlaying the level) but roughly vertically
|
||||||
|
// aligned
|
||||||
|
let palette_rect = this.root.querySelector('.palette').getBoundingClientRect();
|
||||||
|
let entry_rect = this.palette[key].getBoundingClientRect();
|
||||||
|
let tip_height = this.palette_tooltip.offsetHeight;
|
||||||
|
this.palette_tooltip.style.left = `${palette_rect.right}px`;
|
||||||
|
this.palette_tooltip.style.top = `${Math.min(entry_rect.top, palette_rect.bottom - tip_height)}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
hide_palette_tooltip() {
|
||||||
|
this.palette_tooltip.classList.remove('--visible');
|
||||||
|
}
|
||||||
|
|
||||||
select_palette(name_or_tile, from_palette = false) {
|
select_palette(name_or_tile, from_palette = false) {
|
||||||
let name, tile;
|
let name, tile;
|
||||||
if (typeof name_or_tile === 'string') {
|
if (typeof name_or_tile === 'string') {
|
||||||
@ -2213,5 +2809,3 @@ export class Editor extends PrimaryView {
|
|||||||
this.renderer.draw();
|
this.renderer.draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
69
style.css
69
style.css
@ -1421,6 +1421,35 @@ body.--debug #player-debug {
|
|||||||
fill: black;
|
fill: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.editor-big-tooltip {
|
||||||
|
/* shared between toolbar and palette tooltips */
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
z-index: 1;
|
||||||
|
position: absolute;
|
||||||
|
padding: 0.33em 0.75em;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
transition-property: margin, opacity, visibility;
|
||||||
|
transition-timing-function: ease-out;
|
||||||
|
transition-duration: 0.125s, 0.125s, 0s;
|
||||||
|
transition-delay: 0s, 0s, 0.125s;
|
||||||
|
|
||||||
|
border: 1px solid black;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
line-height: 1.5;
|
||||||
|
text-transform: none;
|
||||||
|
text-align: left;
|
||||||
|
color: #d8d8d8;
|
||||||
|
background: hsl(225, 10%, 20%);
|
||||||
|
box-shadow: 0 1px 2px 1px #0004;
|
||||||
|
}
|
||||||
|
.editor-big-tooltip h3 {
|
||||||
|
font-size: 1.25em;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
border-bottom: 1px solid currentColor;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
#editor .controls {
|
#editor .controls {
|
||||||
/* TODO with the hint area gone i don't think this needs to be a grid? could just flex */
|
/* TODO with the hint area gone i don't think this needs to be a grid? could just flex */
|
||||||
grid-area: controls;
|
grid-area: controls;
|
||||||
@ -1442,33 +1471,9 @@ body.--debug #player-debug {
|
|||||||
grid-area: toolbar;
|
grid-area: toolbar;
|
||||||
}
|
}
|
||||||
#editor-toolbar .-help {
|
#editor-toolbar .-help {
|
||||||
opacity: 0;
|
|
||||||
visibility: hidden;
|
|
||||||
z-index: 1;
|
|
||||||
position: absolute;
|
|
||||||
width: max-content;
|
width: max-content;
|
||||||
margin-top: -0.25em;
|
margin-top: -0.25em;
|
||||||
margin-left: -0.5em;
|
margin-left: -0.5em;
|
||||||
padding: 0.33em 0.75em;
|
|
||||||
pointer-events: none;
|
|
||||||
|
|
||||||
border: 1px solid black;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
line-height: 1.5;
|
|
||||||
text-transform: none;
|
|
||||||
text-align: left;
|
|
||||||
background: hsl(225, 10%, 20%);
|
|
||||||
box-shadow: 0 1px 2px 1px #0004;
|
|
||||||
|
|
||||||
transition-property: margin-top, opacity, visibility;
|
|
||||||
transition-timing-function: ease-out;
|
|
||||||
transition-duration: 0.125s, 0.125s, 0s;
|
|
||||||
transition-delay: 0s, 0s, 0.125s;
|
|
||||||
}
|
|
||||||
#editor-toolbar .-help h3 {
|
|
||||||
font-size: 1.25em;
|
|
||||||
margin-bottom: 0.25rem;
|
|
||||||
border-bottom: 1px solid currentColor;
|
|
||||||
}
|
}
|
||||||
#editor-toolbar button:hover .-help {
|
#editor-toolbar button:hover .-help {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
@ -1533,6 +1538,22 @@ body.--debug #player-debug {
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
box-shadow: 0 0 0 1px black, 0 0 0 3px white;
|
box-shadow: 0 0 0 1px black, 0 0 0 3px white;
|
||||||
}
|
}
|
||||||
|
.editor-palette-tooltip {
|
||||||
|
width: 20em;
|
||||||
|
|
||||||
|
/* Don't immediately hide me when mousing between entries */
|
||||||
|
/* FIXME if it's in mid-fade and you mouse over an entry again, it stays frozen in mid-fade
|
||||||
|
* for 0.5s :( */
|
||||||
|
transition-delay: 0.5s, 0.5s, 0.625s;
|
||||||
|
}
|
||||||
|
.editor-palette-tooltip.--visible {
|
||||||
|
opacity: 1;
|
||||||
|
z-index: 2; /* show above any that are in mid-fade */
|
||||||
|
visibility: visible;
|
||||||
|
margin-left: 1em;
|
||||||
|
transition-delay: 0.5s;
|
||||||
|
transition-timing-function: ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
.editor-level-browser {
|
.editor-level-browser {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user