diff --git a/js/format-c2g.js b/js/format-c2g.js index c22255a..2259636 100644 --- a/js/format-c2g.js +++ b/js/format-c2g.js @@ -834,6 +834,12 @@ const TILE_ENCODING = { modifier: modifier_wire, is_extension: true, }, + 0xda: { + name: 'glass_block', + has_next: true, + extra_args: [arg_direction], + is_extension: true, + }, 0xe0: { name: 'gift_bow', has_next: true, diff --git a/js/game.js b/js/game.js index d1cc9a3..ed7f544 100644 --- a/js/game.js +++ b/js/game.js @@ -2542,6 +2542,9 @@ export class Level extends LevelInterface { this._set_tile_prop(tile, 'last_extra_cooldown_tic', null); } this._do_extra_cooldown(tile); + if (old_type.on_death) { + old_type.on_death(tile, this); + } } } diff --git a/js/main-editor.js b/js/main-editor.js index e1efaf5..f442b2b 100644 --- a/js/main-editor.js +++ b/js/main-editor.js @@ -1611,6 +1611,7 @@ const EDITOR_PALETTE = [{ 'item_lock', 'score_5x', 'boulder', + 'glass_block', 'logic_gate/diode', ], }]; @@ -2242,6 +2243,10 @@ const EDITOR_TILE_DESCRIPTIONS = { name: "Blue teleporter exit", desc: "A blue teleporter for all intents and purposes except it can only be exited, not entered.", }, + glass_block: { + name: "Glass block", + desc: "Similar to a dirt block, but stores the first item it moves over, dropping it when destroyed and cloning it in a cloning machine. Has ice block/frame block collision. Turns into floor in water. Doesn't have dirt block immunities.", + }, }; const SPECIAL_PALETTE_ENTRIES = { diff --git a/js/tileset.js b/js/tileset.js index d2087fa..a152967 100644 --- a/js/tileset.js +++ b/js/tileset.js @@ -1080,6 +1080,10 @@ export const LL_TILESET_LAYOUT = Object.assign({}, CC2_TILESET_LAYOUT, { base: [0, 2], wired: [11, 41], }, + glass_block: { + __special__: 'encased_item', + base: [14, 41], + } }); export const TILESET_LAYOUTS = { @@ -1591,6 +1595,16 @@ export class Tileset { this.draw_drawspec(drawspec.railroad_switch, name, tile, packet); } } + + _draw_encased_item(drawspec, name, tile, packet) { + //draw the encased item + if (tile !== null && tile.encased_item !== undefined && tile.encased_item !== null) { + this._draw_standard(this.layout[tile.encased_item], tile.encased_item, TILE_TYPES[tile.encased_item], packet); + } + //then draw the glass block + this._draw_standard(drawspec.base, name, tile, packet); + } + draw_drawspec(drawspec, name, tile, packet) { if (drawspec.__special__) { @@ -1641,6 +1655,9 @@ export class Tileset { else if (drawspec.__special__ === 'railroad') { this._draw_railroad(drawspec, name, tile, packet); } + else if (drawspec.__special__ === 'encased_item') { + this._draw_encased_item(drawspec, name, tile, packet); + } else { console.error(`No such special ${drawspec.__special__} for ${name}`); } diff --git a/js/tiletypes.js b/js/tiletypes.js index ad4fbd2..a1f7950 100644 --- a/js/tiletypes.js +++ b/js/tiletypes.js @@ -763,6 +763,10 @@ const TILE_TYPES = { level.transmute_tile(other, 'splash'); level.transmute_tile(me, 'floor'); } + else if (other.type.name === 'glass_block') { + level.transmute_tile(other, 'splash'); + level.transmute_tile(me, 'floor'); + } else if (other.type.name === 'ice_block') { level.transmute_tile(other, 'splash'); level.transmute_tile(me, 'ice'); @@ -1218,6 +1222,7 @@ const TILE_TYPES = { ice_block: true, frame_block: true, boulder: true, + glass_block: true, }, on_clone(me, original) { me.arrows = new Set(original.arrows); @@ -1277,26 +1282,55 @@ const TILE_TYPES = { can_reveal_walls: true, can_reverse_on_railroad: true, movement_speed: 4, - allows_push(me, direction) { - return me.arrows && me.arrows.has(direction); + try_pickup_item(me, level) { + if (me.encased_item === null) { + let item = me.cell.get_item(); + if (item && !item.type.is_chip) { + level.attempt_take(me, item); + //then if we picked it up, encase it (so we have max one item at a time and so we can't 'use' the item) + if (me.keyring !== undefined && me.keyring !== null && Object.keys(me.keyring).length > 0) { + level._set_tile_prop(me, 'encased_item', Object.keys(me.keyring)[0]); + level.take_all_keys_from_actor(me); + } + else if (me.toolbelt !== undefined && me.toolbelt !== null && me.toolbelt.length > 0) + { + level._set_tile_prop(me, 'encased_item', me.toolbelt[0]); + level.take_all_tools_from_actor(me); + } + } + } + /*if ((me.keyring === undefined || Object.keys(me.keyring).length == 0) && + (me.toolbelt === undefined || me.toolbelt.length == 0)) { + let item = me.cell.get_item(); + if (item) { + level.attempt_take(me, item); + } + }*/ }, - pushes: { - dirt_block: true, - ice_block: true, - frame_block: true, - boulder: true, + on_ready(me, level) { + level._set_tile_prop(me, 'encased_item', null); + this.try_pickup_item(me, level); }, on_clone(me, original) { - me.arrows = new Set(original.arrows); - }, - on_rotate(me, level, turn) { - // We rotate when turned on railroads - let new_arrows = new Set; - for (let arrow of me.arrows) { - new_arrows.add(DIRECTIONS[arrow][turn]); + me.encased_item = original.encased_item; + /*if (original.keyring !== undefined) { + me.keyring = {}; + Object.assign(me.keyring, original.keyring); } - level._set_tile_prop(me, 'arrows', new_arrows); + if (original.toolbelt !== undefined) { + me.toolbelt = original.toolbelt.map((x) => x); + }*/ }, + on_finishing_move(me, level) { + this.try_pickup_item(me, level); + }, + on_death(me, level) { + //needs to be called by transmute_tile to ttl and by lit_dynamite before remove_tile + if (me.encased_item !== null) { + level._place_dropped_item(me.encased_item, me.cell, me); + level._set_tile_prop(me, 'encased_item', null); + } + } }, green_floor: { layer: LAYERS.terrain, @@ -2318,6 +2352,7 @@ const TILE_TYPES = { frame_block: true, circuit_block: true, boulder: true, + glass_block: true, }, movement_speed: 4, decide_movement(me, level) { @@ -2470,6 +2505,7 @@ const TILE_TYPES = { frame_block: true, circuit_block: true, boulder: true, + glass_block: true, }, on_ready(me, level) { me.current_emulatee = 0; @@ -2653,6 +2689,9 @@ const TILE_TYPES = { } else { // Everything else is destroyed + if (tile.type.on_death) { + tile.type.on_death(tile, level); + } level.remove_tile(tile); removed_anything = true; } @@ -2835,6 +2874,7 @@ const TILE_TYPES = { frame_block: true, circuit_block: true, boulder: true, + glass_block: true, }, infinite_items: { key_green: true, @@ -2858,6 +2898,7 @@ const TILE_TYPES = { frame_block: true, circuit_block: true, boulder: true, + glass_block: true, }, infinite_items: { key_yellow: true, @@ -2880,6 +2921,7 @@ const TILE_TYPES = { frame_block: true, circuit_block: true, boulder: true, + glass_block: true, }, infinite_items: { key_green: true, @@ -2906,6 +2948,7 @@ const TILE_TYPES = { frame_block: true, circuit_block: true, boulder: true, + glass_block: true, }, infinite_items: { key_yellow: true,