Update hint when switching players; parse the keybind placeholders

This commit is contained in:
Eevee (Evelyn Woods) 2021-01-05 20:44:11 -07:00
parent c6d9eb3271
commit 5c1b2dbd9d
4 changed files with 58 additions and 37 deletions

View File

@ -140,7 +140,7 @@
<div class="play-controls"> <div class="play-controls">
<button class="control-pause" type="button" title="pause"> <button class="control-pause" type="button" title="pause">
<svg class="svg-icon" viewBox="0 0 16 16"><path d="M2,1 h4 v14 h-4 z M10,1 h4 v14 h-4 z"></svg> <svg class="svg-icon" viewBox="0 0 16 16"><path d="M2,1 h4 v14 h-4 z M10,1 h4 v14 h-4 z"></svg>
<span class="keyhint">p</span></button> <span class="keyhint"><kbd>p</kbd></span></button>
<button class="control-restart" type="button" title="restart"> <button class="control-restart" type="button" title="restart">
<svg class="svg-icon" viewBox="0 0 16 16"><path d="M13,13 A 7,7 270 1,1 13,3 L15,1 15,7 9,7 11,5 A 4,4 270 1,0 11,11 z"></svg> <svg class="svg-icon" viewBox="0 0 16 16"><path d="M13,13 A 7,7 270 1,1 13,3 L15,1 15,7 9,7 11,5 A 4,4 270 1,0 11,11 z"></svg>
</button> </button>
@ -149,19 +149,19 @@
</button> </button>
<button class="control-rewind" type="button" title="rewind"> <button class="control-rewind" type="button" title="rewind">
<svg class="svg-icon" viewBox="0 0 16 16"><path d="M1,8 7,2 7,14 z M9,8 15,2 15,14 z"></svg> <svg class="svg-icon" viewBox="0 0 16 16"><path d="M1,8 7,2 7,14 z M9,8 15,2 15,14 z"></svg>
<span class="keyhint">z</span></button> <span class="keyhint"><kbd>z</kbd></span></button>
<label><input class="control-turn-based" type="checkbox"> Turn-based mode</label> <label><input class="control-turn-based" type="checkbox"> Turn-based mode</label>
</div> </div>
<div class="actions"> <div class="actions">
<button class="action-drop" type="button"> <button class="action-drop" type="button">
<svg class="svg-icon" viewBox="0 0 16 16"><use href="#svg-icon-drop"></use></svg> <svg class="svg-icon" viewBox="0 0 16 16"><use href="#svg-icon-drop"></use></svg>
drop <span class="keyhint">q</span></button> drop <span class="keyhint"><kbd>q</kbd></span></button>
<button class="action-cycle" type="button"> <button class="action-cycle" type="button">
<svg class="svg-icon" viewBox="0 0 16 16"><use href="#svg-icon-cycle"></use></svg> <svg class="svg-icon" viewBox="0 0 16 16"><use href="#svg-icon-cycle"></use></svg>
cycle <span class="keyhint">e</span></button> cycle <span class="keyhint"><kbd>e</kbd></span></button>
<button class="action-swap" type="button"> <button class="action-swap" type="button">
<svg class="svg-icon" viewBox="0 0 16 16"><use href="#svg-icon-swap"></use></svg> <svg class="svg-icon" viewBox="0 0 16 16"><use href="#svg-icon-swap"></use></svg>
switch <span class="keyhint">c</span></button> switch <span class="keyhint"><kbd>c</kbd></span></button>
</div> </div>
</div> </div>
<section id="player-game-area"> <section id="player-game-area">
@ -172,7 +172,7 @@
<p class="-bottom"></p> <p class="-bottom"></p>
<p class="-keyhint"></p> <p class="-keyhint"></p>
</div> </div>
<div class="message"></div> <div class="player-hint"></div>
<div class="chips"> <div class="chips">
<h3>Hearts</h3> <h3>Hearts</h3>
<output></output> <output></output>

View File

@ -412,7 +412,6 @@ export class Level extends LevelInterface {
// global clock which doesn't get reset between levels (!). // global clock which doesn't get reset between levels (!).
this.step_parity = 5; this.step_parity = 5;
this.hint_shown = null;
// TODO in lynx/steam, this carries over between levels; in tile world, you can set it manually // TODO in lynx/steam, this carries over between levels; in tile world, you can set it manually
this.force_floor_direction = 'north'; this.force_floor_direction = 'north';
// PRNG is initialized to zero // PRNG is initialized to zero
@ -668,9 +667,6 @@ export class Level extends LevelInterface {
if (tile.type.on_ready) { if (tile.type.on_ready) {
tile.type.on_ready(tile, this); tile.type.on_ready(tile, this);
} }
if (cell === this.player.cell && tile.type.is_hint) {
this.hint_shown = tile.hint_text ?? this.stored_level.hint;
}
} }
} }
// Erase undo, in case any on_ready added to it (we don't want to undo initialization!) // Erase undo, in case any on_ready added to it (we don't want to undo initialization!)
@ -760,7 +756,7 @@ export class Level extends LevelInterface {
for (let key of [ for (let key of [
'_rng1', '_rng2', '_blob_modifier', 'force_floor_direction', '_rng1', '_rng2', '_blob_modifier', 'force_floor_direction',
'tic_counter', 'time_remaining', 'timer_paused', 'tic_counter', 'time_remaining', 'timer_paused',
'chips_remaining', 'bonus_points', 'hint_shown', 'state', 'chips_remaining', 'bonus_points', 'state',
'remaining_players', 'player', 'remaining_players', 'player',
]) { ]) {
this.pending_undo.level_props[key] = this[key]; this.pending_undo.level_props[key] = this[key];
@ -1547,17 +1543,6 @@ export class Level extends LevelInterface {
} }
} }
// Check for a couple effects that always apply immediately
if (actor === this.player) {
this.hint_shown = null;
}
for (let tile of goal_cell) {
// FIXME this could go in on_approach now
if (tile && actor === this.player && tile.type.is_hint) {
this.hint_shown = tile.hint_text ?? this.stored_level.hint;
}
}
// Announce we're approaching. Slide mode is set here, since it's about the tile we're // Announce we're approaching. Slide mode is set here, since it's about the tile we're
// moving towards and needs to last through our next decision // moving towards and needs to last through our next decision
this.make_slide(actor, null); this.make_slide(actor, null);
@ -1760,7 +1745,9 @@ export class Level extends LevelInterface {
this.set_actor_direction(actor, direction); this.set_actor_direction(actor, direction);
this.spawn_animation(actor.cell, 'teleport_flash'); this.spawn_animation(actor.cell, 'teleport_flash');
if (dest.cell !== actor.cell) {
this.spawn_animation(dest.cell, 'teleport_flash'); this.spawn_animation(dest.cell, 'teleport_flash');
}
// Now physically move the actor, but their movement waits until next decision phase // Now physically move the actor, but their movement waits until next decision phase
this.remove_tile(actor); this.remove_tile(actor);

View File

@ -296,7 +296,7 @@ class Player extends PrimaryView {
this.root.style.setProperty('--tile-height', `${this.conductor.tileset.size_y}px`); this.root.style.setProperty('--tile-height', `${this.conductor.tileset.size_y}px`);
this.level_el = this.root.querySelector('.level'); this.level_el = this.root.querySelector('.level');
this.overlay_message_el = this.root.querySelector('.overlay-message'); this.overlay_message_el = this.root.querySelector('.overlay-message');
this.message_el = this.root.querySelector('.message'); this.hint_el = this.root.querySelector('.player-hint');
this.chips_el = this.root.querySelector('.chips output'); this.chips_el = this.root.querySelector('.chips output');
this.time_el = this.root.querySelector('.time output'); this.time_el = this.root.querySelector('.time output');
this.bonus_el = this.root.querySelector('.bonus output'); this.bonus_el = this.root.querySelector('.bonus output');
@ -1061,6 +1061,7 @@ class Player extends PrimaryView {
this.last_advance = 0; this.last_advance = 0;
this.current_keyring = {}; this.current_keyring = {};
this.current_toolbelt = []; this.current_toolbelt = [];
this.previous_hint_tile = null;
this.chips_el.classList.remove('--done'); this.chips_el.classList.remove('--done');
this.time_el.classList.remove('--frozen'); this.time_el.classList.remove('--frozen');
@ -1350,7 +1351,38 @@ class Player extends PrimaryView {
if (this.level.bonus_points > 0) { if (this.level.bonus_points > 0) {
this.root.classList.add('--bonus-visible'); this.root.classList.add('--bonus-visible');
} }
this.message_el.textContent = this.level.hint_shown ?? "";
// Check for the player standing on a hint tile; this is slightly invasive but lets us
// notice exactly when it changes (and anyway it's a UI thing, not gameplay)
let terrain = this.level.player.cell.get_terrain();
let hint_tile = null;
if (terrain.type.is_hint) {
hint_tile = terrain;
}
if (hint_tile !== this.previous_hint_tile) {
this.previous_hint_tile = hint_tile;
this.hint_el.textContent = '';
if (hint_tile) {
// Parse out %X sequences and replace them with <kbd> elements
let hint_text = hint_tile.hint_text ?? this.level.stored_level.hint;
for (let [i, chunk] of hint_text.split(/%(\w)/).entries()) {
if (i % 2 === 0) {
this.hint_el.append(chunk);
}
else {
// TODO better place to get these?
// TODO 1 through 7 are player 2's inputs in split-screen mode
let key = {
// up, down, left, right
U: 'W', D: 'S', L: 'A', R: 'D',
// drop, cycle, swap
P: 'Q', C: 'E', S: 'C',
}[chunk] ?? "?";
this.hint_el.append(mk('kbd', key));
}
}
}
}
this.renderer.set_active_player(this.level.remaining_players > 1 ? this.level.player : null); this.renderer.set_active_player(this.level.remaining_players > 1 ? this.level.player : null);

View File

@ -125,6 +125,14 @@ pre {
code { code {
color: #c0c0e0; color: #c0c0e0;
} }
kbd {
padding: 0 0.25em;
border: 1px solid currentColor;
border-radius: 0.25em;
box-shadow: 0 2px 0 currentColor;
text-align: center;
text-transform: uppercase;
}
a { a {
color: #c0c0c0; color: #c0c0c0;
@ -931,7 +939,7 @@ ol.packtest-summary > li {
"level chips" min-content "level chips" min-content
"level time" min-content "level time" min-content
"level bonus" min-content "level bonus" min-content
"level message" 1fr "level hint" 1fr
"level inventory" min-content "level inventory" min-content
/* Need explicit min-content to force the hint to wrap */ /* Need explicit min-content to force the hint to wrap */
/ min-content min-content / min-content min-content
@ -1093,8 +1101,8 @@ dl.score-chart .-sum {
display: flex; display: flex;
} }
.message { #player-game-area > .player-hint {
grid-area: message; grid-area: hint;
align-self: stretch; align-self: stretch;
font-size: calc(var(--tile-height) * var(--scale) / 3); font-size: calc(var(--tile-height) * var(--scale) / 3);
@ -1105,10 +1113,10 @@ dl.score-chart .-sum {
background: #080808; background: #080808;
border: 1px inset #202020; border: 1px inset #202020;
/* FIXME find a way to enforce that the message never makes the grid get bigger */ /* FIXME find a way to enforce that the hint never makes the grid get bigger */
overflow: auto; overflow: auto;
} }
.message:empty { #player-game-area > .player-hint:empty {
display: none; display: none;
} }
@ -1186,14 +1194,8 @@ dl.score-chart .-sum {
left: 0; left: 0;
right: 0; right: 0;
top: -2em; top: -2em;
width: 1em;
margin: auto; margin: auto;
color: #404040; color: #404040;
border: 1px solid #202020;
border-radius: 0.25em;
box-shadow: 0 2px 0 #202020;
text-align: center;
text-transform: uppercase;
} }
#player button:disabled .keyhint { #player button:disabled .keyhint {
display: none; display: none;
@ -1422,7 +1424,7 @@ body.--debug #player-debug {
/* stick me in the center right */ /* stick me in the center right */
place-self: center end; place-self: center end;
} }
#player .message { #player > .player-hint {
/* Overlay hints on the inventory area */ /* Overlay hints on the inventory area */
grid-row: chips / bonus; grid-row: chips / bonus;
grid-column: level; grid-column: level;