Implement CC2 input handling, bumping, and block slapping
This commit is contained in:
parent
64bd6c49d9
commit
5d39e37ad2
32
js/game.js
32
js/game.js
@ -330,7 +330,7 @@ export class Level {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Move the game state forwards by one tic
|
// Move the game state forwards by one tic
|
||||||
advance_tic(player_direction) {
|
advance_tic(p1_primary_direction, p1_secondary_direction) {
|
||||||
if (this.state !== 'playing') {
|
if (this.state !== 'playing') {
|
||||||
console.warn(`Level.advance_tic() called when state is ${this.state}`);
|
console.warn(`Level.advance_tic() called when state is ${this.state}`);
|
||||||
return;
|
return;
|
||||||
@ -391,6 +391,10 @@ export class Level {
|
|||||||
if (actor.type.uses_teeth_hesitation && (this.tic_counter + this.step_parity) % 8 >= 4)
|
if (actor.type.uses_teeth_hesitation && (this.tic_counter + this.step_parity) % 8 >= 4)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (actor.type.is_player) {
|
||||||
|
this._set_prop(actor, 'secondary_direction', p1_secondary_direction);
|
||||||
|
}
|
||||||
|
|
||||||
let direction_preference;
|
let direction_preference;
|
||||||
// Actors can't make voluntary moves on ice, so they're stuck with
|
// Actors can't make voluntary moves on ice, so they're stuck with
|
||||||
// whatever they've got
|
// whatever they've got
|
||||||
@ -405,10 +409,10 @@ export class Level {
|
|||||||
// can override forwards??) and DEFINITELY all kinds of stuff
|
// can override forwards??) and DEFINITELY all kinds of stuff
|
||||||
// in ms
|
// in ms
|
||||||
if (actor === this.player &&
|
if (actor === this.player &&
|
||||||
player_direction &&
|
p1_primary_direction &&
|
||||||
actor.last_move_was_force)
|
actor.last_move_was_force)
|
||||||
{
|
{
|
||||||
direction_preference = [player_direction];
|
direction_preference = [p1_primary_direction];
|
||||||
this._set_prop(actor, 'last_move_was_force', false);
|
this._set_prop(actor, 'last_move_was_force', false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -419,8 +423,8 @@ export class Level {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (actor === this.player) {
|
else if (actor === this.player) {
|
||||||
if (player_direction) {
|
if (p1_primary_direction) {
|
||||||
direction_preference = [player_direction];
|
direction_preference = [p1_primary_direction];
|
||||||
this._set_prop(actor, 'last_move_was_force', false);
|
this._set_prop(actor, 'last_move_was_force', false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -753,6 +757,24 @@ export class Level {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Players can also bump the tiles next to where they landed
|
||||||
|
if (actor.type.is_player && actor.secondary_direction) {
|
||||||
|
let neighbor = this.cell_with_offset(actor.cell, actor.secondary_direction);
|
||||||
|
if (neighbor) {
|
||||||
|
for (let tile of neighbor) {
|
||||||
|
// TODO repeating myself with tile.stuck (also should technically check for actor)
|
||||||
|
if (actor.type.pushes && actor.type.pushes[tile.type.name] && ! tile.stuck) {
|
||||||
|
// Block slapping: you can shove a block by walking past it sideways
|
||||||
|
this.set_actor_direction(tile, actor.secondary_direction);
|
||||||
|
this.attempt_step(tile, actor.secondary_direction);
|
||||||
|
}
|
||||||
|
else if (tile.type.on_bump) {
|
||||||
|
tile.type.on_bump(tile, this, actor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Handle teleporting, now that the dust has cleared
|
// Handle teleporting, now that the dust has cleared
|
||||||
// FIXME something funny happening here, your input isn't ignore while walking out of it?
|
// FIXME something funny happening here, your input isn't ignore while walking out of it?
|
||||||
let current_cell = actor.cell;
|
let current_cell = actor.cell;
|
||||||
|
|||||||
70
js/main.js
70
js/main.js
@ -414,41 +414,57 @@ class Player extends PrimaryView {
|
|||||||
advance_by(tics) {
|
advance_by(tics) {
|
||||||
for (let i = 0; i < tics; i++) {
|
for (let i = 0; i < tics; i++) {
|
||||||
let input = this.get_input();
|
let input = this.get_input();
|
||||||
let current_input = input;
|
|
||||||
if (! input.has('up') && ! input.has('down') && ! input.has('left') && ! input.has('right')) {
|
|
||||||
//input = this.previous_input;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Choose the movement direction based on the held keys. A
|
// Replica of CC2 input handling, based on experimentation
|
||||||
// newly pressed action takes priority; in the case of a tie,
|
// FIXME unclear how this should interact with undo when playing normally, and
|
||||||
// um, XXX ????
|
// definitely wrong when playing a replay; should this be in Level??
|
||||||
let chosen_action = null;
|
if ((input.has('up') && input.has('down')) || (input.has('left') && input.has('right'))) {
|
||||||
let any_action = null;
|
// If opposing keys are ever held, stop moving and forget our state
|
||||||
for (let action of ['up', 'down', 'left', 'right']) {
|
this.primary_action = null;
|
||||||
if (input.has(action)) {
|
this.secondary_action = null;
|
||||||
if (this.previous_input.has(action)) {
|
}
|
||||||
chosen_action = action;
|
else if (this.primary_action && input.has(this.primary_action)) {
|
||||||
|
// Our primary action is locked in as long as it's held down, but check for a
|
||||||
|
// newly pressed secondary action; remember, there can't be two opposing keys held,
|
||||||
|
// because we already checked for that above, so this is only necessary if there's
|
||||||
|
// not already a secondary action
|
||||||
|
if (! this.secondary_action) {
|
||||||
|
for (let action of ['down', 'left', 'right', 'up']) {
|
||||||
|
if (action !== this.primary_action &&
|
||||||
|
input.has(action) && ! this.previous_input.has(action))
|
||||||
|
{
|
||||||
|
this.secondary_action = action;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
any_action = action;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! chosen_action) {
|
else {
|
||||||
// No keys are new, so check whether we were previously
|
// Either we weren't holding any keys, or we let go of our primary action; either
|
||||||
// holding a key and are still doing it
|
// way, act like we're starting from scratch and check keys in priority order
|
||||||
if (this.previous_action && input.has(this.previous_action)) {
|
this.primary_action = null;
|
||||||
chosen_action = this.previous_action;
|
this.secondary_action = null;
|
||||||
}
|
for (let action of ['down', 'left', 'right', 'up']) {
|
||||||
else {
|
if (! input.has(action))
|
||||||
// No dice, so use an arbitrary action
|
continue;
|
||||||
chosen_action = any_action;
|
|
||||||
|
if (! this.primary_action) {
|
||||||
|
this.primary_action = action;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Note that because of the opposing keys check, there can never be more
|
||||||
|
// than two keys held down here
|
||||||
|
this.secondary_action = action;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let player_move = chosen_action ? ACTION_DIRECTIONS[chosen_action] : null;
|
this.previous_input = input;
|
||||||
this.previous_action = chosen_action;
|
|
||||||
this.previous_input = current_input;
|
|
||||||
|
|
||||||
this.level.advance_tic(player_move);
|
this.level.advance_tic(
|
||||||
|
this.primary_action ? ACTION_DIRECTIONS[this.primary_action] : null,
|
||||||
|
this.secondary_action ? ACTION_DIRECTIONS[this.secondary_action] : null,
|
||||||
|
);
|
||||||
|
|
||||||
if (this.level.state !== 'playing') {
|
if (this.level.state !== 'playing') {
|
||||||
// We either won or lost!
|
// We either won or lost!
|
||||||
|
|||||||
@ -111,6 +111,7 @@ const TILE_TYPES = {
|
|||||||
},
|
},
|
||||||
popdown_floor: {
|
popdown_floor: {
|
||||||
draw_layer: LAYER_TERRAIN,
|
draw_layer: LAYER_TERRAIN,
|
||||||
|
// FIXME should be on_approach
|
||||||
on_arrive(me, level, other) {
|
on_arrive(me, level, other) {
|
||||||
// FIXME could probably do this with state? or, eh
|
// FIXME could probably do this with state? or, eh
|
||||||
level.transmute_tile(me, 'popdown_floor_visible');
|
level.transmute_tile(me, 'popdown_floor_visible');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user