Global Cyclers can cycle actors now too
This commit is contained in:
parent
f79a8cc259
commit
5cc5370817
19
js/game.js
19
js/game.js
@ -1566,7 +1566,7 @@ export class Level extends LevelInterface {
|
||||
let original_cell = actor.cell;
|
||||
// Physically remove the actor first, so that it won't get in the way of e.g. a splash
|
||||
// spawned from stepping off of a lilypad
|
||||
this.remove_tile(actor);
|
||||
this.remove_tile(actor, true);
|
||||
|
||||
// Announce we're leaving, for the handful of tiles that care about it
|
||||
for (let tile of original_cell) {
|
||||
@ -1796,7 +1796,7 @@ export class Level extends LevelInterface {
|
||||
}
|
||||
|
||||
// Now physically move the actor, but their movement waits until next decision phase
|
||||
this.remove_tile(actor);
|
||||
this.remove_tile(actor, true);
|
||||
this.add_tile(actor, dest.cell);
|
||||
}
|
||||
|
||||
@ -1874,7 +1874,7 @@ export class Level extends LevelInterface {
|
||||
// already in this cell's actor layer. But we also know for sure that there's no
|
||||
// item in this cell, so we'll cheat a little: remove the dropping actor, set the
|
||||
// item moving, then put the dropping actor back before anyone notices.
|
||||
this.remove_tile(dropping_actor);
|
||||
this.remove_tile(dropping_actor, true);
|
||||
this.add_tile(tile, cell);
|
||||
if (! this.attempt_out_of_turn_step(tile, dropping_actor.direction)) {
|
||||
// It was unable to move, so there's nothing we can do but destroy it
|
||||
@ -2279,7 +2279,7 @@ export class Level extends LevelInterface {
|
||||
player = this.player;
|
||||
}
|
||||
|
||||
if (this.take_tool_from_actor(player, 'halo')) {
|
||||
if (player != null && reason !== 'nonexistence' && this.take_tool_from_actor(player, 'halo')) {
|
||||
this.sfx.play_once('revive');
|
||||
if (reason === 'time')
|
||||
{
|
||||
@ -2301,11 +2301,11 @@ export class Level extends LevelInterface {
|
||||
|
||||
this._push_pending_undo(() => {
|
||||
this.fail_reason = null;
|
||||
player.fail_reason = null;
|
||||
if (player != null) { player.fail_reason = null; }
|
||||
});
|
||||
this.state = 'failure';
|
||||
this.fail_reason = reason;
|
||||
player.fail_reason = reason;
|
||||
if (player != null) { player.fail_reason = reason; }
|
||||
}
|
||||
|
||||
win() {
|
||||
@ -2346,7 +2346,12 @@ export class Level extends LevelInterface {
|
||||
// have things stacked in a weird order though
|
||||
// TODO would be nice to make these not be closures but order matters much more here
|
||||
|
||||
remove_tile(tile) {
|
||||
remove_tile(tile, temporary = false) {
|
||||
if (!temporary && tile == this.player)
|
||||
{
|
||||
this.fail('nonexistence');
|
||||
return;
|
||||
}
|
||||
let cell = tile.cell;
|
||||
cell._remove(tile);
|
||||
this._push_pending_undo(() => cell._add(tile));
|
||||
|
||||
@ -2184,7 +2184,7 @@ const EDITOR_TILE_DESCRIPTIONS = {
|
||||
},
|
||||
global_cycler: {
|
||||
name: "Global Cycler",
|
||||
desc: "When activated, every terrain/item on the surrounding four tiles in the entire level becomes the terrain/item one clockwise. Adjacent tiles with a 'no sign' on them are ignored. Two of the same tile in a row mean that tile will not be transformed and will stay as-is. Tiles next to Global Cyclers are not transformed.",
|
||||
desc: "When activated, every terrain/item/actor on the surrounding four tiles in the entire level becomes the terrain/item/actor one clockwise. Adjacent tiles with a 'no sign' on them are ignored. Two of the same tile in a row mean that tile will not be transformed and will stay as-is. Actors facing different directions will cause a relative direction change. Tiles next to Global Cyclers are not transformed.",
|
||||
},
|
||||
halo: {
|
||||
name: "Halo",
|
||||
|
||||
@ -85,6 +85,12 @@ const OBITUARIES = {
|
||||
"you're feeling quite alarmed",
|
||||
//"
|
||||
],
|
||||
nonexistence: [
|
||||
"I guess you don't exist",
|
||||
"critical existence failure",
|
||||
"no place to be",
|
||||
"on a trip to nowhere",
|
||||
],
|
||||
generic: [
|
||||
"you had a bad time",
|
||||
],
|
||||
|
||||
@ -1718,6 +1718,7 @@ const TILE_TYPES = {
|
||||
layer: LAYERS.terrain,
|
||||
blocks_collision: COLLISION.real_player | COLLISION.block_cc1 | COLLISION.monster_solid,
|
||||
activate(me, level) {
|
||||
|
||||
//learn about surrounding tiles
|
||||
//some logic: we ignore tiles with a 'no sign' on them. for items, we ignore itemless tiles. if the same terrain/item is twice in a row, it stays the same. tiles next to global cycles aren't touched.
|
||||
let cells = [level.cell(
|
||||
@ -1732,8 +1733,10 @@ const TILE_TYPES = {
|
||||
level.cell(
|
||||
me.cell.x - 1,
|
||||
me.cell.y + 0)].filter(x => x != null && x.get_item_mod()?.type.name != 'no_sign');
|
||||
|
||||
let terrains = cells.map(x => x.get_terrain().type.name).filter(x => x != 'global_cycler');
|
||||
let items = cells.map(x => x.get_item()?.type.name ?? null).filter(x => x != null);
|
||||
let actors = cells.map(x => x.get_actor()).filter(x => x != null);
|
||||
|
||||
//globally cycle terrain
|
||||
if (new Set(terrains).size > 1)
|
||||
@ -1784,17 +1787,20 @@ const TILE_TYPES = {
|
||||
for (var j = 0; j < level.height; ++j)
|
||||
{
|
||||
let target_safe = [level.cell(
|
||||
(i + 0 + level.width) % level.width,
|
||||
(j - 1 + level.height) % level.height),
|
||||
i + 0,
|
||||
j + 0),
|
||||
level.cell(
|
||||
(i + 1 + level.width) % level.width,
|
||||
(j + 0 + level.height) % level.height),
|
||||
i + 0,
|
||||
j - 1),
|
||||
level.cell(
|
||||
(i + 0 + level.width) % level.width,
|
||||
(j + 1 + level.height) % level.height),
|
||||
i + 1,
|
||||
j + 0),
|
||||
level.cell(
|
||||
(i- 1 + level.width) % level.width,
|
||||
(j + 0 + level.height) % level.height)].filter(x => x.get_terrain().type.name == 'global_cycler');
|
||||
i + 0,
|
||||
j + 1),
|
||||
level.cell(
|
||||
i - 1,
|
||||
j + 0)].filter(x => x != null && x.get_terrain().type.name == 'global_cycler');
|
||||
if (target_safe.length > 0)
|
||||
{
|
||||
continue;
|
||||
@ -1816,6 +1822,60 @@ const TILE_TYPES = {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//globally cycle... actors???
|
||||
//intended logic: if the same monster exists twice in a row we rotate it it by the relative direction (left, right, flip or do nothing). if it's two different monsters, we do that AND transmute.
|
||||
//this code is slightly different from the previous two blocks!
|
||||
if (actors.length > 1)
|
||||
{
|
||||
for (let a = level.actors.length - 1; a >= 0; a--)
|
||||
{
|
||||
let thing = level.actors[a];
|
||||
let i = thing.cell.x;
|
||||
let j = thing.cell.y;
|
||||
|
||||
let target_safe = [level.cell(
|
||||
i + 0,
|
||||
j + 0),
|
||||
level.cell(
|
||||
i + 0,
|
||||
j - 1),
|
||||
level.cell(
|
||||
i + 1,
|
||||
j + 0),
|
||||
level.cell(
|
||||
i + 0,
|
||||
j + 1),
|
||||
level.cell(
|
||||
i - 1,
|
||||
j + 0)].filter(x => x != null && x.get_terrain().type.name == 'global_cycler');
|
||||
if (target_safe.length > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let things = actors;
|
||||
|
||||
for (var k = 0; k < things.length; ++k)
|
||||
{
|
||||
if (thing.type.name == things[k].type.name)
|
||||
{
|
||||
let turn = ['right', 'left', 'opposite'].filter(t => {
|
||||
return DIRECTIONS[things[k].direction][t] === things[(k + 1) % things.length].direction;
|
||||
})[0]
|
||||
if (turn !== undefined)
|
||||
{
|
||||
thing.direction = DIRECTIONS[thing.direction][turn];
|
||||
}
|
||||
if (thing.type.name != things[(k - 1 + things.length) % things.length].type.name)
|
||||
{
|
||||
level.transmute_tile(thing, things[(k + 1) % things.length].type.name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// Also activates on rising pulse or gray button
|
||||
on_power(me, level) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user