Add a further hack atop the cooldown delay hack to fix adjacent trap release
This commit is contained in:
parent
c34aaadf06
commit
00ac94ac8c
42
js/game.js
42
js/game.js
@ -564,7 +564,15 @@ export class Level {
|
|||||||
if (! actor.cell)
|
if (! actor.cell)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (actor.movement_cooldown > 0 && actor.cooldown_delay_tic !== this.tic_counter) {
|
if (actor.movement_cooldown <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (actor.cooldown_delay_hack) {
|
||||||
|
// See the extensive comment in attempt_out_of_turn_step
|
||||||
|
actor.cooldown_delay_hack += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
this._set_tile_prop(actor, 'movement_cooldown', Math.max(0, actor.movement_cooldown - 1));
|
this._set_tile_prop(actor, 'movement_cooldown', Math.max(0, actor.movement_cooldown - 1));
|
||||||
|
|
||||||
if (actor.movement_cooldown <= 0) {
|
if (actor.movement_cooldown <= 0) {
|
||||||
@ -587,7 +595,6 @@ export class Level {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Mini extra pass: deal with teleporting separately. Otherwise, actors may have been in
|
// Mini extra pass: deal with teleporting separately. Otherwise, actors may have been in
|
||||||
// the way of the teleporter but finished moving away during the above loop; this is
|
// the way of the teleporter but finished moving away during the above loop; this is
|
||||||
@ -687,6 +694,9 @@ export class Level {
|
|||||||
let p = 0;
|
let p = 0;
|
||||||
for (let i = 0, l = this.actors.length; i < l; i++) {
|
for (let i = 0, l = this.actors.length; i < l; i++) {
|
||||||
let actor = this.actors[i];
|
let actor = this.actors[i];
|
||||||
|
// While we're here, delete this guy
|
||||||
|
delete actor.cooldown_delay_hack;
|
||||||
|
|
||||||
if (actor.cell) {
|
if (actor.cell) {
|
||||||
if (p !== i) {
|
if (p !== i) {
|
||||||
this.actors[p] = actor;
|
this.actors[p] = actor;
|
||||||
@ -1077,10 +1087,30 @@ export class Level {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME delete this
|
|
||||||
attempt_out_of_turn_step(actor, direction) {
|
attempt_out_of_turn_step(actor, direction) {
|
||||||
if (this.attempt_step(actor, direction)) {
|
if (this.attempt_step(actor, direction)) {
|
||||||
this._set_tile_prop(actor, 'cooldown_delay_tic', this.tic_counter);
|
// Here's the problem.
|
||||||
|
// In CC2, cooldown is measured in frames, not tics, and it decrements every frame, not
|
||||||
|
// every tic. You usually don't notice because actors can only initiate moves every
|
||||||
|
// three frames (= 1 tic), so the vast majority of the game is tic-aligned.
|
||||||
|
// This is where it leaks. If actor X's cooldown causes them to press a button which
|
||||||
|
// then initiates an out-of-turn move (i.e. the forced move from a clone or trap
|
||||||
|
// ejection) for actor Y, and actor Y comes later in the actor order, then actor Y will
|
||||||
|
// decrement its cooldown during that same cooldown phase, putting it /between/ tics.
|
||||||
|
// If I copy this behavior and decrement by an entire tic, then actor Y will stay a full
|
||||||
|
// tic ahead indefinitely, whereas in CC2 it would only be a frame ahead and would
|
||||||
|
// eventually have to wait a frame before it could move again. If I ignore this
|
||||||
|
// behavior wholesale and don't let actor Y decrement at all, then a player being
|
||||||
|
// ejected from a trap could still have her tail bitten. So here's the compromise: I
|
||||||
|
// set this turn-local flag on actor Y; then if they do have a cooldown later, it's
|
||||||
|
// ignored BUT the flag is incremented; and then if the flag is 2, the actor is exempt
|
||||||
|
// from tail-biting. (I am reasonably confident that tail-biting is the only possible
|
||||||
|
// side effect here, since actor Y has left the cell even if they haven't visibly moved
|
||||||
|
// yet, and tail-biting is the sole effect that looks "back in time".)
|
||||||
|
// XXX that's still not perfect; if actor X is tic-misaligned, like if there's a chain
|
||||||
|
// of 3 or more actors cloning directly onto red buttons for other cloners, then this
|
||||||
|
// cannot possibly work
|
||||||
|
actor.cooldown_delay_hack = 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1141,7 +1171,9 @@ export class Level {
|
|||||||
// TODO the rules in lynx might be slightly different?
|
// TODO the rules in lynx might be slightly different?
|
||||||
if (actor.type.is_monster && goal_cell === this.player.previous_cell &&
|
if (actor.type.is_monster && goal_cell === this.player.previous_cell &&
|
||||||
// Player has decided to leave their cell, but hasn't actually taken a step yet
|
// Player has decided to leave their cell, but hasn't actually taken a step yet
|
||||||
this.player.movement_cooldown === this.player.movement_speed)
|
this.player.movement_cooldown === this.player.movement_speed &&
|
||||||
|
// See the extensive comment in attempt_out_of_turn_step
|
||||||
|
this.player.cooldown_delay_hack !== 2)
|
||||||
{
|
{
|
||||||
this.fail(actor.type.name);
|
this.fail(actor.type.name);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user