revamp electric floor, perf improvement for circuitry recalculation

Now reads:
Conducts power (like a 4-way wire). While powered, destroys anything not wearing lightning boots (except dirt blocks)
And when you step on it with lightning boots it conducts power
And it's not on by default if it's just sitting on its own somewhere
This commit is contained in:
Timothy Stiles 2021-02-16 17:18:49 +11:00
parent e866710af6
commit 3ea7a045da
3 changed files with 53 additions and 40 deletions

View File

@ -529,7 +529,7 @@ export class Level extends LevelInterface {
this.connect_button(connectable);
}
this.force_next_wire_phase = false;
this.recalculate_circuitry_next_wire_phase = false;
this.undid_past_recalculate_circuitry = false;
this.recalculate_circuitry(true);
@ -756,7 +756,6 @@ export class Level extends LevelInterface {
}
}
this.force_next_wire_phase = true;
if (!undoing) {
this._push_pending_undo(() => this.undid_past_recalculate_circuitry = true);
}
@ -1969,6 +1968,14 @@ export class Level extends LevelInterface {
}
_do_wire_phase() {
let force_next_wire_phase = false;
if (this.recalculate_circuitry_next_wire_phase)
{
this.recalculate_circuitry();
this.recalculate_circuitry_next_wire_phase = false;
force_next_wire_phase = true;
}
if (this.circuits.length === 0)
return;
@ -2014,7 +2021,7 @@ export class Level extends LevelInterface {
this._set_tile_prop(tile, 'emitting_edges', emitting);
}
}
// Next, actors who are standing still, on floor, and holding a lightning bolt
// Next, actors who are standing still, on floor/electrified, and holding a lightning bolt
let externally_powered_circuits = new Set;
for (let actor of this.actors) {
if (! actor.cell)
@ -2022,7 +2029,7 @@ export class Level extends LevelInterface {
let emitting = 0;
if (actor.movement_cooldown === 0 && actor.has_item('lightning_bolt')) {
let wired_tile = actor.cell.get_wired_tile();
if (wired_tile && (wired_tile === actor || wired_tile.type.name === 'floor')) {
if (wired_tile && (wired_tile === actor || wired_tile.type.name === 'floor' || wired_tile.type.name === 'electrified_floor')) {
emitting = wired_tile.wire_directions;
for (let circuit of wired_tile.circuits) {
if (circuit) {
@ -2037,13 +2044,8 @@ export class Level extends LevelInterface {
}
}
if (! any_changed) {
if (this.force_next_wire_phase) {
this.force_next_wire_phase = false;
}
else {
return;
}
if (! any_changed && !force_next_wire_phase) {
return;
}
for (let tile of this.wired_outputs) {
@ -2276,7 +2278,7 @@ export class Level extends LevelInterface {
this.undo_buffer[this.undo_buffer_index] = null;
if (this.undid_past_recalculate_circuitry) {
this.recalculate_circuitry(false, true);
this.recalculate_circuitry_next_wire_phase = true;
this.undid_past_recalculate_circuitry = false;
}
}
@ -2588,7 +2590,7 @@ export class Level extends LevelInterface {
(new_type.is_power_source !== old_type.is_power_source) ||
(new_type.wire_propagation_mode !== old_type.wire_propagation_mode))
{
this.recalculate_circuitry();
this.recalculate_circuitry_next_wire_phase = true;
}
}
}

View File

@ -2219,7 +2219,7 @@ const EDITOR_TILE_DESCRIPTIONS = {
},
electrified_floor: {
name: "Electrified floor",
desc: "Conducts power (like a blue teleporter). While powered, destroys anything not wearing lightning boots (except dirt blocks).",
desc: "Conducts power (like a 4-way wire). While powered, destroys anything not wearing lightning boots (except dirt blocks).",
},
hole: {
name: "Hole",

View File

@ -89,6 +89,30 @@ function _define_gate(key) {
};
}
function update_wireable(me, level) {
if (me.is_wired === undefined) {
//start of the level/first time, then
me.is_wired = level.is_tile_wired(me, false);
me.is_active = !me.is_wired;
}
else {
let new_is_wired = level.is_tile_wired(me, false);
if (new_is_wired && !me.is_wired)
{
//connected
level._set_tile_prop(me, 'is_wired', true);
//TODO: it'll always get on_power called later if it's wired to something already given power, right?
level._set_tile_prop(me, 'is_active', false);
}
else if (!new_is_wired && me.is_wired)
{
//disconnected
level._set_tile_prop(me, 'is_wired', false);
level._set_tile_prop(me, 'is_active', true);
}
}
}
function activate_terraformer(me, level, dx, dy) {
//decide if we're copying from our own tile (if we have an item) or the tile behind us (otherwise)
let did_something = false;
@ -137,7 +161,7 @@ function activate_terraformer(me, level, dx, dy) {
level.transmute_tile(new_terrain, old_terrain.type.name);
if (changed_wiring_properties) {
level.recalculate_circuitry();
level.recalculate_circuitry_next_wire_phase = true;
}
did_something = true;
}
@ -749,9 +773,7 @@ const TILE_TYPES = {
layer: LAYERS.terrain,
wire_propagation_mode: 'all',
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;
update_wireable(me, level);
},
on_arrive(me, level, other) {
if (! me.is_active)
@ -779,9 +801,7 @@ const TILE_TYPES = {
layer: LAYERS.terrain,
wire_propagation_mode: 'all',
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;
update_wireable(me, level);
},
on_arrive(me, level, other) {
if (! me.is_active)
@ -864,7 +884,7 @@ const TILE_TYPES = {
level.transmute_tile(me, 'floor');
level._set_tile_prop(me, 'wire_directions', other.wire_directions);
level.transmute_tile(other, 'splash');
level.recalculate_circuitry();
level.recalculate_circuitry_next_wire_phase = true;
}
else if (other.type.is_real_player) {
level.fail('drowned', me, other);
@ -1593,9 +1613,7 @@ const TILE_TYPES = {
},
_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;
update_wireable(me, level);
},
on_arrive(me, level, other) {
// Note: Transmogrifiers technically contain wires the way teleports do, and CC2 uses
@ -1723,12 +1741,10 @@ const TILE_TYPES = {
wire_propagation_mode: 'none',
teleport_allow_override: true,
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!
me.is_wired = level.is_tile_wired(me);
me.is_active = ! me.is_wired;
update_wireable(me, level);
},
*teleport_dest_order(me, level, other) {
// Wired red teleporters can be turned off, which disconnects them from every other red
@ -2093,9 +2109,8 @@ const TILE_TYPES = {
layer: LAYERS.terrain,
wire_propagation_mode: 'all',
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;
level._set_tile_prop(me, 'wire_directions', 15);
level.recalculate_circuitry_next_wire_phase = true;
},
on_tic(me, level) {
if (me.is_active)
@ -2110,17 +2125,13 @@ const TILE_TYPES = {
level.transmute_tile(actor, 'explosion');
}
}
}
}
},
on_power(me, level) {
if (me.is_wired) {
level._set_tile_prop(me, 'is_active', true);
}
level._set_tile_prop(me, 'is_active', true);
},
on_depower(me, level) {
if (me.is_wired) {
level._set_tile_prop(me, 'is_active', false);
}
level._set_tile_prop(me, 'is_active', false);
},
visual_state(me) {
return ! me || me.is_active ? 'active' : 'inactive';
@ -2512,10 +2523,10 @@ const TILE_TYPES = {
me.wire_directions = original.wire_directions;
},
on_starting_move(me, level) {
level.recalculate_circuitry();
level.recalculate_circuitry_next_wire_phase = true;
},
on_finishing_move(me, level) {
level.recalculate_circuitry();
level.recalculate_circuitry_next_wire_phase = true;
},
},