From d5b9a2a3077f2a0314b8f1c80dbbd257941f7b0c Mon Sep 17 00:00:00 2001 From: "Eevee (Evelyn Woods)" Date: Mon, 1 Mar 2021 20:21:59 -0700 Subject: [PATCH] Change flame jet activation to be actor-based This fixes CC2LP1's Waterfall, and allows me to remove `on_tic`. --- js/game.js | 37 +++++++++++++++---------------------- js/tiletypes.js | 49 ++++++++++++++++++++----------------------------- 2 files changed, 35 insertions(+), 51 deletions(-) diff --git a/js/game.js b/js/game.js index 11f88a7..48c07d5 100644 --- a/js/game.js +++ b/js/game.js @@ -507,10 +507,6 @@ export class Level extends LevelInterface { // If there's exactly one yellow teleporter when the level loads, it cannot be picked up let yellow_teleporter_count = 0; this.allow_taking_yellow_teleporters = false; - // Speedup for flame jets, which aren't actors but do a thing every tic - // TODO this won't notice if a new tile with an on_tic is created, but that's impossible - // atm... or, at least, it's hacked to still work with flame_jet_off - this.static_on_tic_tiles = []; for (let y = 0; y < this.height; y++) { let row = []; for (let x = 0; x < this.width; x++) { @@ -539,9 +535,6 @@ export class Level extends LevelInterface { if (tile.type.is_actor) { this.actors.push(tile); } - else if (tile.type.on_tic) { - this.static_on_tic_tiles.push(tile); - } cell._add(tile); if (tile.type.connects_to) { @@ -957,11 +950,20 @@ export class Level extends LevelInterface { // the way of the teleporter but finished moving away during the above loop; this is // particularly bad when it happens with a block you're pushing. (CC2 doesn't need to do // this because blocks you're pushing are always a frame ahead of you anyway.) + // This is also where we handle tiles with persistent standing behavior. for (let i = this.actors.length - 1; i >= 0; i--) { let actor = this.actors[i]; if (! actor.cell) continue; + if (actor.type.ttl) + continue; + if (actor.movement_cooldown <= 0) { + let terrain = actor.cell.get_terrain(); + if (terrain.type.on_stand && ! actor.ignores(terrain.type.name)) { + terrain.type.on_stand(terrain, this, actor); + } + } if (actor.just_stepped_on_teleporter) { this.attempt_teleport(actor); } @@ -972,8 +974,6 @@ export class Level extends LevelInterface { this._do_wire_phase(); this._do_wire_phase(); this._do_wire_phase(); - // TODO should this also happen three times? - this._do_static_phase(); this._do_cleanup_phase(); } @@ -997,7 +997,6 @@ export class Level extends LevelInterface { this._do_decision_phase(); this._do_combined_action_phase(3); this._do_wire_phase(); - this._do_static_phase(); this._do_cleanup_phase(); } @@ -1008,12 +1007,10 @@ export class Level extends LevelInterface { this._do_decision_phase(true); this._do_combined_action_phase(1, true); this._do_wire_phase(); - this._do_static_phase(); this._do_decision_phase(true); this._do_combined_action_phase(1, true); this._do_wire_phase(); - this._do_static_phase(); } // This is in the "finish" part to preserve the property turn-based mode expects, where "finish" // picks up right when the player could provide input @@ -1021,7 +1018,6 @@ export class Level extends LevelInterface { this._do_decision_phase(); this._do_combined_action_phase(1); this._do_wire_phase(); - this._do_static_phase(); this._do_cleanup_phase(); } @@ -1094,6 +1090,12 @@ export class Level extends LevelInterface { continue; this._do_actor_cooldown(actor, cooldown); + if (actor.movement_cooldown <= 0) { + let terrain = actor.cell.get_terrain(); + if (terrain.type.on_stand && ! actor.ignores(terrain.type.name)) { + terrain.type.on_stand(terrain, this, actor); + } + } if (actor.just_stepped_on_teleporter) { this.attempt_teleport(actor); } @@ -2154,15 +2156,6 @@ export class Level extends LevelInterface { }); } - // Some non-actor tiles still want to act every tic. Note that this should happen AFTER wiring. - _do_static_phase() { - for (let tile of this.static_on_tic_tiles) { - if (tile.type.on_tic) { - tile.type.on_tic(tile, this); - } - } - } - // ------------------------------------------------------------------------- // Board inspection diff --git a/js/tiletypes.js b/js/tiletypes.js index 6a9d1de..1d964b9 100644 --- a/js/tiletypes.js +++ b/js/tiletypes.js @@ -1812,9 +1812,6 @@ const TILE_TYPES = { on_power(me, level) { me.type.activate(me, level); }, - // This is a silly hack to get us flagged as a static tile, so when we're turned on, that - // tile's on_tic will still run - on_tic() {}, }, flame_jet_on: { layer: LAYERS.terrain, @@ -1827,19 +1824,16 @@ const TILE_TYPES = { on_power(me, level) { me.type.activate(me, level); }, - on_tic(me, level) { - let actor = me.cell.get_actor(); - if (actor && actor.movement_cooldown <= 0 && ! actor.ignores(me.type.name)) { - // Note that (dirt?) blocks, fireballs, and anything with fire boots are immune - // TODO would be neat if this understood "ignores anything with fire immunity" but that - // might be a bit too high-level for this game - if (actor.type.is_real_player) { - level.fail('burned', me, actor); - } - else { - level.sfx.play_once('bomb', me.cell); - level.transmute_tile(actor, 'explosion'); - } + on_stand(me, level, other) { + // Note that (dirt?) blocks, fireballs, and anything with fire boots are immune + // TODO would be neat if this understood "ignores anything with fire immunity" but that + // might be a bit too high-level for this game + if (other.type.is_real_player) { + level.fail('burned', me, other); + } + else { + level.sfx.play_once('bomb', me.cell); + level.transmute_tile(other, 'explosion'); } }, }, @@ -1850,19 +1844,16 @@ const TILE_TYPES = { level._set_tile_prop(me, 'wire_directions', 15); level.recalculate_circuitry_next_wire_phase = true; }, - on_tic(me, level) { - if (me.is_active) - { - let actor = me.cell.get_actor(); - if (actor && actor.movement_cooldown <= 0 && ! actor.ignores(me.type.name)) { - if (actor.type.is_real_player) { - level.fail('electrocuted', me, actor); - } - else { - level.sfx.play_once('bomb', me.cell); - level.transmute_tile(actor, 'explosion'); - } - } + on_stand(me, level, other) { + if (! me.is_active) + return; + + if (other.type.is_real_player) { + level.fail('electrocuted', me, other); + } + else { + level.sfx.play_once('bomb', me.cell); + level.transmute_tile(other, 'explosion'); } }, on_power(me, level) {