Give flame jets their own mini-pass

This commit is contained in:
Eevee (Evelyn Woods) 2020-12-26 02:03:39 -07:00
parent 09c1976608
commit 0bb3f78a33
2 changed files with 47 additions and 32 deletions

View File

@ -400,8 +400,10 @@ export class Level extends LevelInterface {
let n = 0;
let connectables = [];
this.remaining_players = 0;
// FIXME handle traps correctly:
// - if an actor is in the cell, set the trap to open and unstick everything in it
// 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++) {
@ -428,6 +430,9 @@ 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) {
@ -742,9 +747,9 @@ export class Level extends LevelInterface {
// are only two wiring updates before everything gets its first chance to move, so we skip
// the very first one here.
if (this.tic_counter !== 0) {
this.update_wiring();
this._do_wire_phase();
}
this.update_wiring();
this._do_wire_phase();
// Advance everyone's cooldowns
// Note that we iterate in reverse order, DESPITE keeping dead actors around with null
@ -775,14 +780,17 @@ export class Level extends LevelInterface {
}
}
this.update_wiring();
this._do_wire_phase();
// TODO should this also happen three times?
this._do_static_phase();
}
// Lynx-style loop: everyone decides, then everyone moves/cools.
_begin_tic_lynx() {
this._do_decision_phase();
this._do_combined_action_phase(3);
this.update_wiring();
this._do_wire_phase();
this._do_static_phase();
this._do_cleanup_phase();
}
@ -792,15 +800,18 @@ export class Level extends LevelInterface {
_begin_tic_lynx60() {
this._do_decision_phase(true);
this._do_combined_action_phase(1, true);
this.update_wiring();
this._do_wire_phase();
this._do_static_phase();
this._do_decision_phase(true);
this._do_combined_action_phase(1, true);
this.update_wiring();
this._do_wire_phase();
this._do_static_phase();
this._do_decision_phase();
this._do_combined_action_phase(1);
this.update_wiring();
this._do_wire_phase();
this._do_static_phase();
this._do_cleanup_phase();
}
@ -1648,7 +1659,7 @@ export class Level extends LevelInterface {
}
}
update_wiring() {
_do_wire_phase() {
if (this.circuits.length === 0)
return;
@ -1778,6 +1789,13 @@ 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) {
tile.type.on_tic(tile, this);
}
}
// -------------------------------------------------------------------------
// Board inspection

View File

@ -804,7 +804,7 @@ const TILE_TYPES = {
on_ready(me, level) {
// FIXME in cc2 only, actors on a bomb immediately explode, but that's tricky for the
// player since we can't kill them before the game even starts. cc2 just murders them
// instantly. maybe we could do that then
// instantly. maybe we could do that then? or use on_tic, like flame jets?
},
on_arrive(me, level, other) {
level.remove_tile(me);
@ -1326,11 +1326,8 @@ const TILE_TYPES = {
draw_layer: DRAW_LAYERS.terrain,
activate(me, level) {
level.transmute_tile(me, 'flame_jet_on');
// If there's anything on us already, nuke it
let actor = me.cell.get_actor();
if (actor && ! actor.movement_cooldown) {
me.type._kill(me, level, actor);
}
// Do NOT immediately nuke anything on us, or it'd be impossible to push a block off an
// adjacent orange button; this is probably why flame jets kill on tics
},
on_gray_button(me, level) {
me.type.activate(me, level);
@ -1338,6 +1335,9 @@ 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: {
draw_layer: DRAW_LAYERS.terrain,
@ -1350,23 +1350,20 @@ const TILE_TYPES = {
on_power(me, level) {
me.type.activate(me, level);
},
// Kill anything that shows up
// FIXME every tic, also kills every actor in the cell (mostly matters if something steps on
// with fire boots and then drops them, which is unlike fire)
_kill(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');
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');
}
else {
// TODO should this play a sound?
level.transmute_tile(actor, 'explosion');
}
}
else {
// TODO should this play a sound?
level.transmute_tile(other, 'explosion');
}
},
on_arrive(me, level, other) {
this._kill(me, level, other);
},
},
// Buttons