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); 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) { if (tile.type.is_power_source) {
// TODO could just do this in a pass afterwards // 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; let teleporter = actor.just_stepped_on_teleporter;
delete 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 // 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 // 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.) // 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_green: [[4, 19], [5, 19], [6, 19], [7, 19]],
teleport_yellow: [[8, 19], [9, 19], [10, 19], [11, 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: { teleport_red: {
__special__: 'wires', __special__: 'wires',
base: [0, 2], 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: { wired: {
__special__: 'visual-state', __special__: 'visual-state',
active: [[4, 20], [5, 20], [6, 20], [7, 20]], active: [[4, 20], [5, 20], [6, 20], [7, 20]],
inactive: [4, 20], inactive: [4, 20],
}, },
*/
}, },
slime: [[8, 20], [9, 20], [10, 20], [11, 20], [12, 20], [13, 20], [14, 20], [15, 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', teeth_timid: 'teeth',
}, },
_blob_mogrifications: ['glider', 'paramecium', 'fireball', 'bug', 'walker', 'ball', 'teeth', 'tank_blue', 'teeth_timid'], _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) { on_arrive(me, level, other) {
// Note: Transmogrifiers technically contain wires the way teleports do, and CC2 uses // Note: Transmogrifiers technically contain wires the way teleports do, and CC2 uses
// the presence and poweredness of those wires to determine whether the transmogrifier // 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 // 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 // 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; return;
let name = other.type.name; let name = other.type.name;
if (me.type._mogrifications[name]) { if (me.type._mogrifications[name]) {
@ -1262,15 +1267,18 @@ const TILE_TYPES = {
level.sfx.play_once('transmogrify', me.cell); level.sfx.play_once('transmogrify', me.cell);
}, },
on_power(me, level) { on_power(me, level) {
// No need to do anything, we just need this here as a signal that our .powered_edges if (me.is_wired) {
// needs to be updated 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) { visual_state(me) {
return this._is_active(me) ? 'active' : 'inactive'; return ! me || me.is_active ? 'active' : 'inactive';
}, },
*/
}, },
teleport_blue: { teleport_blue: {
layer: LAYERS.terrain, layer: LAYERS.terrain,
@ -1358,11 +1366,13 @@ const TILE_TYPES = {
slide_mode: 'teleport', slide_mode: 'teleport',
wire_propagation_mode: 'none', wire_propagation_mode: 'none',
teleport_allow_override: true, 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 // 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. // blue teleporter, etc; NOT nothing, a wall, a transmogrifier, a force floor, etc.
// this is also how blue teleporters, transmogrifiers, and railroads work! // 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) { *teleport_dest_order(me, level, other) {
// Wired red teleporters can be turned off, which disconnects them from every other red // 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 // has the bizarre behavior of NOT considering a red teleporter wired if none of its
// wires are directly connected to another neighboring wire. // wires are directly connected to another neighboring wire.
let iterable; let iterable;
if (this._is_active(me, level)) { if (me.is_active) {
iterable = level.iter_tiles_in_reading_order(me.cell, 'teleport_red'); iterable = level.iter_tiles_in_reading_order(me.cell, 'teleport_red');
} }
else { else {
@ -1384,7 +1394,7 @@ const TILE_TYPES = {
if (tile === me) { if (tile === me) {
yield [tile, exit_direction]; yield [tile, exit_direction];
} }
else if (this._is_active(tile, level)) { else if (tile.is_active) {
yield [tile, exit_direction]; yield [tile, exit_direction];
yield [tile, DIRECTIONS[exit_direction].right]; yield [tile, DIRECTIONS[exit_direction].right];
yield [tile, DIRECTIONS[exit_direction].opposite]; 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! on_power(me, level) {
/* if (me.is_wired) {
visual_state(me) { level._set_tile_prop(me, 'is_active', true);
return me && this._is_active(me) ? 'active' : 'inactive'; }
},
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: { teleport_green: {
layer: LAYERS.terrain, layer: LAYERS.terrain,