Fix teleporters, and more generally out-of-turn movement

This commit is contained in:
Eevee (Evelyn Woods) 2020-12-11 20:58:50 -07:00
parent a96c089d7f
commit 410af788fc
2 changed files with 19 additions and 11 deletions

View File

@ -747,7 +747,7 @@ export class Level {
} }
} }
take_actor_turn(actor, decision, forced = false) { take_actor_turn(actor, decision) {
let moved = false; let moved = false;
if (! actor.cell) if (! actor.cell)
return moved; return moved;
@ -761,7 +761,6 @@ export class Level {
if (actor === this.player && decision && ! moved) { if (actor === this.player && decision && ! moved) {
this.sfx.play_once('blocked'); this.sfx.play_once('blocked');
actor.is_blocked = true; actor.is_blocked = true;
console.log(this.tic_counter, 'bump!');
} }
// Players can also bump the tiles in the cell next to the one they're leaving // Players can also bump the tiles in the cell next to the one they're leaving
@ -779,7 +778,7 @@ export class Level {
if (could_push && actor.can_push(tile, dir2)) { if (could_push && actor.can_push(tile, dir2)) {
// Block slapping: you can shove a block by walking past it sideways // Block slapping: you can shove a block by walking past it sideways
// TODO i think cc2 uses the push pose and possibly even turns you here? // TODO i think cc2 uses the push pose and possibly even turns you here?
this.take_actor_turn(tile, dir2); this.attempt_out_of_turn_step(tile, dir2);
} }
} }
} }
@ -790,9 +789,6 @@ export class Level {
if (actor.forced_turn_tic === this.tic_counter) { if (actor.forced_turn_tic === this.tic_counter) {
return moved; return moved;
} }
else if (forced) {
this._set_tile_prop(actor, 'forced_turn_tic', this.tic_counter);
}
if (actor.movement_cooldown > 0) { if (actor.movement_cooldown > 0) {
this._set_tile_prop(actor, 'movement_cooldown', actor.movement_cooldown - 1); this._set_tile_prop(actor, 'movement_cooldown', actor.movement_cooldown - 1);
@ -810,8 +806,8 @@ export class Level {
return moved; return moved;
} }
// Try to move the given actor one tile in the given direction and update // Try to move the given actor one tile in the given direction and update their cooldown.
// their cooldown. Return true if successful. // Return true if successful.
attempt_step(actor, direction) { attempt_step(actor, direction) {
// In mid-movement, we can't even change direction! // In mid-movement, we can't even change direction!
if (actor.movement_cooldown > 0) if (actor.movement_cooldown > 0)
@ -879,7 +875,7 @@ export class Level {
if (! actor.can_push(tile, direction)) if (! actor.can_push(tile, direction))
continue; continue;
if (! this.take_actor_turn(tile, direction, true) && if (! this.attempt_out_of_turn_step(tile, direction) &&
tile.slide_mode !== null && tile.movement_cooldown !== 0) tile.slide_mode !== null && tile.movement_cooldown !== 0)
{ {
// If the push failed and the obstacle is in the middle of a slide, // If the push failed and the obstacle is in the middle of a slide,
@ -938,6 +934,18 @@ export class Level {
return true; return true;
} }
attempt_out_of_turn_step(actor, direction) {
if (! this.attempt_step(actor, direction))
return false;
// Movement ALWAYS advances by one by the end of the tic. Either this actor has already had
// a turn, and we're responsible for advancing this new move, or their turn is coming up,
// and we use this property to prevent them from advancing a second time
this._set_tile_prop(actor, 'forced_turn_tic', this.tic_counter);
this._set_tile_prop(actor, 'movement_cooldown', actor.movement_cooldown - 1);
return true;
}
// Move the given actor to the given position and perform any appropriate // Move the given actor to the given position and perform any appropriate
// tile interactions. Does NOT check for whether the move is actually // tile interactions. Does NOT check for whether the move is actually
// legal; use attempt_step for that! // legal; use attempt_step for that!
@ -1063,7 +1071,7 @@ export class Level {
break; break;
} }
for (let i = 0; i < num_directions; i++) { for (let i = 0; i < num_directions; i++) {
if (this.attempt_step(actor, direction)) { if (this.attempt_out_of_turn_step(actor, direction)) {
success = true; success = true;
// Sound plays from the origin cell simply because that's where the sfx player // Sound plays from the origin cell simply because that's where the sfx player
// thinks the player is currently; position isn't updated til next turn // thinks the player is currently; position isn't updated til next turn

View File

@ -1013,7 +1013,7 @@ const TILE_TYPES = {
// This temporary flag tells us to let it leave; it doesn't need to be undoable, since // This temporary flag tells us to let it leave; it doesn't need to be undoable, since
// it doesn't persist for more than a tic // it doesn't persist for more than a tic
actor._clone_release = true; actor._clone_release = true;
if (level.take_actor_turn(actor, direction, true)) { if (level.attempt_out_of_turn_step(actor, direction)) {
// FIXME add this underneath, just above the cloner, so the new actor is on top // FIXME add this underneath, just above the cloner, so the new actor is on top
let new_template = new actor.constructor(type, direction); let new_template = new actor.constructor(type, direction);
// TODO maybe make a type method for this // TODO maybe make a type method for this