Disable animation on inactive red teleporters and transmogrifiers (fixes #28)

This commit is contained in:
Eevee (Evelyn Woods) 2021-01-16 20:53:30 -07:00
parent 5653fc9c12
commit 6a2d6d608d
3 changed files with 44 additions and 21 deletions

View File

@ -639,6 +639,11 @@ export class Level extends LevelInterface {
}
}
add_to_edge_map(circuit.tiles, tile, edges);
if (tile.type.on_power) {
// Red teleporters contain wires and /also/ have an on_power
// FIXME this isn't quite right since there's seemingly a 1-frame delay
wired_outputs.add(tile);
}
if (tile.type.is_power_source) {
// TODO could just do this in a pass afterwards
@ -1681,7 +1686,7 @@ export class Level extends LevelInterface {
let teleporter = actor.just_stepped_on_teleporter;
delete actor.just_stepped_on_teleporter;
if (teleporter.type.name === 'teleport_red' && ! teleporter.type._is_active(teleporter, this)) {
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
// other actors cannot. (Normally, a teleport slide ends after one decision phase.)

View File

@ -423,18 +423,19 @@ export const CC2_TILESET_LAYOUT = {
},
teleport_green: [[4, 19], [5, 19], [6, 19], [7, 19]],
teleport_yellow: [[8, 19], [9, 19], [10, 19], [11, 19]],
transmogrifier: [[12, 19], [13, 19], [14, 19], [15, 19]],
transmogrifier: {
__special__: 'visual-state',
active: [[12, 19], [13, 19], [14, 19], [15, 19]],
inactive: [12, 19],
},
teleport_red: {
__special__: 'wires',
base: [0, 2],
wired: [[4, 20], [5, 20], [6, 20], [7, 20]],
/* FIXME don't animate when disabled, but that requires inspecting the level
wired: {
__special__: 'visual-state',
active: [[4, 20], [5, 20], [6, 20], [7, 20]],
inactive: [4, 20],
},
*/
},
slime: [[8, 20], [9, 20], [10, 20], [11, 20], [12, 20], [13, 20], [14, 20], [15, 20]],

View File

@ -1240,12 +1240,17 @@ const TILE_TYPES = {
teeth_timid: 'teeth',
},
_blob_mogrifications: ['glider', 'paramecium', 'fireball', 'bug', 'walker', 'ball', 'teeth', 'tank_blue', 'teeth_timid'],
on_begin(me, level) {
// TODO if wire destruction is ever allowed, this will need to update somehow
me.is_wired = level.is_tile_wired(me, false);
me.is_active = ! me.is_wired;
},
on_arrive(me, level, other) {
// Note: Transmogrifiers technically contain wires the way teleports do, and CC2 uses
// the presence and poweredness of those wires to determine whether the transmogrifier
// should appear to be on or off, but the /functionality/ is controlled entirely by
// whether an adjoining cell carries current to our edge, like a railroad or cloner
if (level.is_tile_wired(me, false) && ! me.powered_edges)
if (! me.is_active)
return;
let name = other.type.name;
if (me.type._mogrifications[name]) {
@ -1262,15 +1267,18 @@ const TILE_TYPES = {
level.sfx.play_once('transmogrify', me.cell);
},
on_power(me, level) {
// No need to do anything, we just need this here as a signal that our .powered_edges
// needs to be updated
if (me.is_wired) {
level._set_tile_prop(me, 'is_active', true);
}
},
on_depower(me, level) {
if (me.is_wired) {
level._set_tile_prop(me, 'is_active', false);
}
},
// FIXME don't animate when inactive, but that required inspecting the level!
/*
visual_state(me) {
return this._is_active(me) ? 'active' : 'inactive';
return ! me || me.is_active ? 'active' : 'inactive';
},
*/
},
teleport_blue: {
layer: LAYERS.terrain,
@ -1358,11 +1366,13 @@ const TILE_TYPES = {
slide_mode: 'teleport',
wire_propagation_mode: 'none',
teleport_allow_override: true,
_is_active(me, level) {
on_begin(me, level) {
// TODO if wire destruction is ever allowed, this will need to update somehow
// FIXME must be connected to something that can convey current: a wire, a switch, a
// blue teleporter, etc; NOT nothing, a wall, a transmogrifier, a force floor, etc.
// this is also how blue teleporters, transmogrifiers, and railroads work!
return me.powered_edges || ! level.is_tile_wired(me);
me.is_wired = level.is_tile_wired(me);
me.is_active = ! me.is_wired;
},
*teleport_dest_order(me, level, other) {
// Wired red teleporters can be turned off, which disconnects them from every other red
@ -1371,7 +1381,7 @@ const TILE_TYPES = {
// has the bizarre behavior of NOT considering a red teleporter wired if none of its
// wires are directly connected to another neighboring wire.
let iterable;
if (this._is_active(me, level)) {
if (me.is_active) {
iterable = level.iter_tiles_in_reading_order(me.cell, 'teleport_red');
}
else {
@ -1384,7 +1394,7 @@ const TILE_TYPES = {
if (tile === me) {
yield [tile, exit_direction];
}
else if (this._is_active(tile, level)) {
else if (tile.is_active) {
yield [tile, exit_direction];
yield [tile, DIRECTIONS[exit_direction].right];
yield [tile, DIRECTIONS[exit_direction].opposite];
@ -1392,12 +1402,19 @@ const TILE_TYPES = {
}
}
},
// FIXME don't animate when inactive, but that required inspecting the level!
/*
visual_state(me) {
return me && this._is_active(me) ? 'active' : 'inactive';
on_power(me, level) {
if (me.is_wired) {
level._set_tile_prop(me, 'is_active', true);
}
},
on_depower(me, level) {
if (me.is_wired) {
level._set_tile_prop(me, 'is_active', false);
}
},
visual_state(me) {
return ! me || me.is_active ? 'active' : 'inactive';
},
*/
},
teleport_green: {
layer: LAYERS.terrain,