implement the Terraformer

The Terraformer is like a clone machine for everything that isn't an actor. It copies the terrain (and item) behind it to in front of it when powered.
This commit is contained in:
Timothy Stiles 2021-02-05 14:41:11 +11:00
parent da18684cbb
commit 9b76c6b9ce
3 changed files with 135 additions and 1 deletions

View File

@ -1598,6 +1598,8 @@ const EDITOR_PALETTE = [{
'gate_yellow',
'gate_green',
'sand',
'terraformer_n',
'global_cycler',
],
}];
@ -2171,7 +2173,15 @@ const EDITOR_TILE_DESCRIPTIONS = {
sand: {
name: "Sand",
desc: "Anything walking on it moves at half speed. Stops all blocks.",
}
},
terraformer_n: {
name: "Terraformer",
desc: "When activated, copies the terrain and item behind it to the tile in front of it.",
},
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.",
},
};
const SPECIAL_PALETTE_ENTRIES = {
@ -2418,6 +2428,7 @@ for (let cycle of [
['force_floor_n', 'force_floor_e', 'force_floor_s', 'force_floor_w'],
['ice_nw', 'ice_ne', 'ice_se', 'ice_sw'],
['swivel_nw', 'swivel_ne', 'swivel_se', 'swivel_sw'],
['terraformer_n', 'terraformer_e', 'terraformer_s', 'terraformer_w'],
]) {
for (let [i, name] of cycle.entries()) {
let left = cycle[(i - 1 + cycle.length) % cycle.length];

View File

@ -1031,6 +1031,12 @@ export const LL_TILESET_LAYOUT = Object.assign({}, CC2_TILESET_LAYOUT, {
skeleton_key: [4, 40],
sand: [10, 41],
terraformer_n: [0, 43],
terraformer_e: [1, 43],
terraformer_s: [2, 43],
terraformer_w: [3, 43],
global_cycler: [4, 43],
});
export const TILESET_LAYOUTS = {

View File

@ -89,6 +89,67 @@ function _define_gate(key) {
};
}
function activate_terraformer(me, level, dx, dy) {
let did_something = false;
let old_cell = level.cell(
(me.cell.x - dx + level.width) % level.width,
(me.cell.y - dy + level.height) % level.height);
let new_cell = level.cell(
(me.cell.x + dx + level.width) % level.width,
(me.cell.y + dy + level.height) % level.height);
let old_terrain = old_cell.get_terrain();
let new_terrain = new_cell.get_terrain();
if (old_terrain.type.name != new_terrain.type.name)
{
level.transmute_tile(new_cell.get_terrain(), old_terrain.type.name);
did_something = true;
}
let old_item = old_cell.get_item();
if (old_item != null)
{
let new_item = new_cell.get_item();
if (new_item != null)
{
if (old_item.type.name != new_item.type.name)
{
level.transmute_tile(new_item, old_item.type.name)
did_something = true;
}
}
else
{
let type = TILE_TYPES[old_item.type.name];
let tile = new old_item.constructor(type);
level.add_tile(tile, new_cell);
did_something = true;
}
}
let old_item_mod = old_cell.get_item_mod();
if (old_item_mod != null)
{
let new_item_mod = new_cell.get_item_mod();
if (new_item_mod != null)
{
if (old_item_mod.type.name != new_item_mod.type.name)
{
level.transmute_tile(new_item_mod, old_item_mod.type.name)
did_something = true;
}
}
else
{
let type = TILE_TYPES[old_item_mod.type.name];
let tile = new old_item_mod.constructor(type);
level.add_tile(tile, new_cell);
did_something = true;
}
}
if (did_something)
{
level.spawn_animation(new_cell, 'transmogrify_flash');
}
}
function player_visual_state(me) {
if (! me) {
return 'normal';
@ -1511,6 +1572,62 @@ const TILE_TYPES = {
}
},
},
terraformer_n: {
layer: LAYERS.terrain,
blocks_collision: COLLISION.real_player | COLLISION.block_cc1 | COLLISION.monster_solid,
activate(me, level) {
activate_terraformer(me, level, 0, -1);
},
// Also terraforms 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);
},
},
terraformer_e: {
layer: LAYERS.terrain,
blocks_collision: COLLISION.real_player | COLLISION.block_cc1 | COLLISION.monster_solid,
activate(me, level) {
activate_terraformer(me, level, 1, 0);
},
// Also terraforms 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);
},
},
terraformer_s: {
layer: LAYERS.terrain,
blocks_collision: COLLISION.real_player | COLLISION.block_cc1 | COLLISION.monster_solid,
activate(me, level) {
activate_terraformer(me, level, 0, 1);
},
// Also terraforms 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);
},
},
terraformer_w: {
layer: LAYERS.terrain,
blocks_collision: COLLISION.real_player | COLLISION.block_cc1 | COLLISION.monster_solid,
activate(me, level) {
activate_terraformer(me, level, -1, 0);
},
// Also terraforms 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,