diff --git a/js/main-editor.js b/js/main-editor.js index abe472f..262ded0 100644 --- a/js/main-editor.js +++ b/js/main-editor.js @@ -2180,7 +2180,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.", + 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.", }, }; diff --git a/js/tiletypes.js b/js/tiletypes.js index 8ac7625..92d680f 100644 --- a/js/tiletypes.js +++ b/js/tiletypes.js @@ -1628,6 +1628,85 @@ const TILE_TYPES = { me.type.activate(me, level); }, }, + global_cycler: { + 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. + let cells = [level.cell( + (me.cell.x + 0 + level.width) % level.width, + (me.cell.y - 1 + level.height) % level.height), + level.cell( + (me.cell.x + 1 + level.width) % level.width, + (me.cell.y + 0 + level.height) % level.height), + level.cell( + (me.cell.x + 0 + level.width) % level.width, + (me.cell.y + 1 + level.height) % level.height), + level.cell( + (me.cell.x - 1 + level.width) % level.width, + (me.cell.y + 0 + level.height) % level.height)].filter(x => x.get_item_mod()?.type.name != 'no_sign'); + let terrains = cells.map(x => x.get_terrain().type.name); + let items = cells.map(x => x.get_item()?.type.name ?? null).filter(x => x != null); + + //globally cycle terrain + if (terrains[0] != terrains[1] + || terrains[1] != terrains[2] + || terrains[2] != terrains[3] + || terrains[3] != terrains[0]) + { + for (var i = 0; i < level.width; ++i) + { + for (var j = 0; j < level.height; ++j) + { + let thing = level.cell(i, j).get_terrain(); + let things = terrains; + for (var k = 0; k < things.length; ++k) + { + if (thing.type.name == things[k] && thing.type.name != things[(k - 1 + things.length) % things.length]) + { + level.transmute_tile(thing, things[(k + 1) % things.length]); + break; + } + } + } + } + } + + //globally cycle items + //some logic: we skip over itemless spots and if two items in the row are a same, then that item stays the same + if (new Set(items).size > 1) + { + for (var i = 0; i < level.width; ++i) + { + for (var j = 0; j < level.height; ++j) + { + let thing = level.cell(i, j).get_item(); + let things = items; + if (thing == null) + { + continue; + } + for (var k = 0; k < things.length; ++k) + { + if (thing.type.name == things[k] && thing.type.name != things[(k - 1 + things.length) % things.length]) + { + level.transmute_tile(thing, things[(k + 1) % things.length]); + break; + } + } + } + } + } + }, + // Also activates on rising pulse or gray button + on_power(me, level) { + me.type.activate(me, level); + }, + on_gray_button(me, level) { + me.type.activate(me, level); + }, + }, // Buttons button_blue: { layer: LAYERS.terrain, diff --git a/tileset-lexy.png b/tileset-lexy.png index fc5fc46..7580b4f 100644 Binary files a/tileset-lexy.png and b/tileset-lexy.png differ