Fix several renderer interpolation bugs

This commit is contained in:
Eevee (Evelyn Woods) 2021-01-22 09:12:02 -07:00
parent 69a344595c
commit 0c774d343e
2 changed files with 31 additions and 18 deletions

View File

@ -37,21 +37,19 @@ export class Tile {
// Gives the effective position of an actor in motion, given smooth scrolling
visual_position(tic_offset = 0, interpolate_backwards_by = 0) {
let x = this.cell.x;
let y = this.cell.y;
if (! this.previous_cell || this.movement_speed === null) {
return [x, y];
return [this.cell.x, this.cell.y];
}
else {
let cell = this.destination_cell ?? this.cell;
// For a movement speed of N, the cooldown is set to N during the tic an actor starts
// moving, and we interpolate it from there to N - 1 over the course of the duration
let p = this.movement_progress(tic_offset, interpolate_backwards_by);
return [
(1 - p) * this.previous_cell.x + p * x,
(1 - p) * this.previous_cell.y + p * y,
(1 - p) * this.previous_cell.x + p * cell.x,
(1 - p) * this.previous_cell.y + p * cell.y,
];
}
}
// TODO don't love that the arg order is different here vs tile type, but also don't love that
// the name is the same?
@ -931,6 +929,10 @@ export class Level extends LevelInterface {
// Clear any old decisions ASAP. Note that this prop is only used internally within a
// single tic, so it doesn't need to be undoable
actor.decision = null;
// This is a renderer prop and only exists between two loops
if (actor.destination_cell) {
this._set_tile_prop(actor, 'destination_cell', null);
}
if (! actor.cell)
continue;
@ -1690,6 +1692,10 @@ export class Level extends LevelInterface {
let teleporter = actor.just_stepped_on_teleporter;
delete actor.just_stepped_on_teleporter;
// We're about to abruptly move the actor, and the renderer needs to know to interpolate its
// movement towards the teleporter it just stepped on, not the teleporter it's moved to
this._set_tile_prop(actor, 'destination_cell', actor.cell);
if (teleporter.type.name === 'teleport_red' && ! teleporter.is_active) {
// Curious special-case red teleporter behavior: if you pass through a wired but
// inactive one, you keep sliding indefinitely. Players can override out of it, but
@ -2352,6 +2358,11 @@ export class Level extends LevelInterface {
this._set_tile_prop(tile, 'previous_cell', null);
this._set_tile_prop(tile, 'movement_speed', tile.type.ttl);
this._set_tile_prop(tile, 'movement_cooldown', tile.type.ttl);
// This is effectively a completely new object, so remove double cooldown prevention;
// this cooldown MUST happen, because the renderer can't handle cooldown == speed
if (tile.last_extra_cooldown_tic) {
this._set_tile_prop(tile, 'last_extra_cooldown_tic', null);
}
this._do_extra_cooldown(tile);
}
}

View File

@ -2777,36 +2777,38 @@ const TILE_TYPES = {
},
},
// New VFX (not in CC2, so they don't block to avoid altering gameplay)
// TODO would like these to play faster but the first frame is often skipped due to other bugs
// Note that these need to NOT have a duration that's an even number of tics, or the last frame
// will be skipped when playing at 20fps; the cooldown will be 3, then decremented to 0, and the
// tile will immediately be removed!
player1_exit: {
layer: LAYERS.vfx,
is_actor: true,
collision_mask: 0,
ttl: 8 * 3,
ttl: 8 * 3 + 1,
},
player2_exit: {
layer: LAYERS.vfx,
is_actor: true,
collision_mask: 0,
ttl: 8 * 3,
ttl: 8 * 3 + 1,
},
teleport_flash: {
layer: LAYERS.vfx,
is_actor: true,
collision_mask: 0,
ttl: 8 * 3,
ttl: 8 * 3 + 1,
},
transmogrify_flash: {
layer: LAYERS.vfx,
is_actor: true,
collision_mask: 0,
ttl: 4 * 3,
ttl: 4 * 3 + 1,
},
puff: {
layer: LAYERS.vfx,
is_actor: true,
collision_mask: 0,
ttl: 4 * 3,
ttl: 4 * 3 + 1,
},
// Invalid tiles that appear in some CCL levels because community level