From 80973398864089dd7979ef2c4f773bdeef7f3668 Mon Sep 17 00:00:00 2001 From: "Eevee (Evelyn Woods)" Date: Tue, 8 Sep 2020 14:42:38 -0600 Subject: [PATCH] Implement green bombs/chips, ice blocks, and custom walls/floors --- js/format-c2m.js | 20 +++++++--- js/tileset.js | 19 ++++++--- js/tiletypes.js | 101 ++++++++++++++++++++++++++++++++++------------- 3 files changed, 101 insertions(+), 39 deletions(-) diff --git a/js/format-c2m.js b/js/format-c2m.js index 2883907..9589fc4 100644 --- a/js/format-c2m.js +++ b/js/format-c2m.js @@ -169,12 +169,12 @@ const TILE_ENCODING = { // 0x68: Bowling ball : '#next' // 0x69: Rover : '#direction', '#next' // 0x6a: Time penalty : '#next' - // 0x6b: Custom floor (green) : Modifier allows other styles, see below + 0x6b: ['#mod8?', ['floor_custom_green', 'floor_custom_pink', 'floor_custom_yellow', 'floor_custom_blue']], // 0x6c: (Unused) : 0x6d: ['#thinwall/canopy', '#next'], // 0x6e: (Unused) : // 0x6f: Railroad sign : '#next' - // 0x70: Custom wall (green) : Modifier allows other styles, see below + 0x70: ['#mod8?', ['wall_custom_green', 'wall_custom_pink', 'wall_custom_yellow', 'wall_custom_blue']], 0x71: ['#mod8', 'floor_letter'], // 0x72: Purple toggle wall : // 0x73: Purple toggle floor : @@ -193,8 +193,8 @@ const TILE_ENCODING = { 0x80: ['score_2x', '#next'], // 0x81: Directional block : '#direction', Directional Arrows Bitmask, '#next' // 0x82: Floor mimic : '#direction', '#next' - // 0x83: Green bomb : '#next' - // 0x84: Green chip : '#next' + 0x83: ['green_bomb', '#next'], + 0x84: ['green_chip', '#next'], // 0x85: (Unused) : '#next' // 0x86: (Unused) : '#next' // 0x87: Black button : @@ -411,9 +411,14 @@ export function parse_level(buf) { p++; let mod_marker; [mod_marker, name, ...args] = read_spec(); - if (mod_marker !== '#mod8') + if (mod_marker !== '#mod8' && mod_marker !== '#mod8?') throw new Error(`Expected a tile requiring a modifier`); } + else if (name === '#mod8?') { + // This is optional, so if we didn't get one, the modifier is 0 + modifier = 0; + [name, ...args] = args; + } // Make a tile template, possibly dealing with some special cases if (name === '#thinwall/canopy') { @@ -444,6 +449,11 @@ export function parse_level(buf) { // it, so that's fine continue; } + else if (name instanceof Array) { + // Custom floors and walls are one of several options, + // given by an optional modifier + name = name[modifier]; + } let tile = {name, modifier}; cell.push(tile); diff --git a/js/tileset.js b/js/tileset.js index 2f4a9d4..e24e353 100644 --- a/js/tileset.js +++ b/js/tileset.js @@ -53,14 +53,15 @@ export const CC2_TILESET_LAYOUT = { [8, 2], [9, 2], ], - // ice block, xray - score_10: [14, 2], - score_100: [13, 2], + ice_block: [10, 2], + // TODO ice block xray score_1000: [12, 2], + score_100: [13, 2], + score_10: [14, 2], score_2x: [15, 2], // LCD digit font - green_chip: [10, 3], + green_chip: [9, 3], chip_extra: [10, 3], chip: [11, 3], // bribe @@ -71,8 +72,14 @@ export const CC2_TILESET_LAYOUT = { bomb: [5, 4], green_bomb: [6, 4], // ??? tiny fireworks - // custom floors - // custom walls + floor_custom_green: [8, 4], + floor_custom_pink: [9, 4], + floor_custom_yellow: [10, 4], + floor_custom_blue: [11, 4], + wall_custom_green: [12, 4], + wall_custom_pink: [13, 4], + wall_custom_yellow: [14, 4], + wall_custom_blue: [15, 4], // explosion // splash diff --git a/js/tiletypes.js b/js/tiletypes.js index 31183a1..0cdf895 100644 --- a/js/tiletypes.js +++ b/js/tiletypes.js @@ -18,10 +18,38 @@ const TILE_TYPES = { me.ascii_code = template.modifier; }, }, + floor_custom_green: { + draw_layer: LAYER_TERRAIN, + }, + floor_custom_pink: { + draw_layer: LAYER_TERRAIN, + }, + floor_custom_yellow: { + draw_layer: LAYER_TERRAIN, + }, + floor_custom_blue: { + draw_layer: LAYER_TERRAIN, + }, wall: { draw_layer: LAYER_TERRAIN, blocks: true, }, + wall_custom_green: { + draw_layer: LAYER_TERRAIN, + blocks: true, + }, + wall_custom_pink: { + draw_layer: LAYER_TERRAIN, + blocks: true, + }, + wall_custom_yellow: { + draw_layer: LAYER_TERRAIN, + blocks: true, + }, + wall_custom_blue: { + draw_layer: LAYER_TERRAIN, + blocks: true, + }, wall_invisible: { draw_layer: LAYER_TERRAIN, // TODO cc2 seems to make these flicker briefly @@ -195,7 +223,11 @@ const TILE_TYPES = { fire: { draw_layer: LAYER_TERRAIN, on_arrive(me, level, other) { - if (other.type.is_player) { + if (other.type.name === 'ice_block') { + level.remove_tile(other); + level.transmute_tile(me, 'water'); + } + else if (other.type.is_player) { level.fail("Oops! You can't walk on fire without fire boots!"); level.transmute_tile(other, 'player_burned'); } @@ -208,10 +240,14 @@ const TILE_TYPES = { draw_layer: LAYER_TERRAIN, on_arrive(me, level, other) { // TODO cc1 allows items under water, i think; water was on the upper layer - if (other.type.name == 'dirt_block' || other.type.name == 'clone_block') { + if (other.type.name === 'dirt_block' || other.type.name === 'clone_block') { level.remove_tile(other); level.transmute_tile(me, 'dirt'); } + else if (other.type.name === 'ice_block') { + level.remove_tile(other); + level.transmute_tile(me, 'ice'); + } else if (other.type.is_player) { level.fail("swimming with the fishes"); level.transmute_tile(other, 'player_drowned'); @@ -363,7 +399,6 @@ const TILE_TYPES = { dirt_block: { draw_layer: LAYER_ACTOR, blocks: true, - is_object: true, is_actor: true, is_block: true, ignores: new Set(['fire']), @@ -373,12 +408,21 @@ const TILE_TYPES = { draw_layer: LAYER_ACTOR, // TODO is this in any way distinct from dirt block blocks: true, - is_object: true, is_actor: true, is_block: true, ignores: new Set(['fire']), movement_speed: 4, }, + ice_block: { + draw_layer: LAYER_ACTOR, + blocks: true, + is_actor: true, + is_block: true, + movement_speed: 4, + pushes: { + ice_block: true, + }, + }, green_floor: { draw_layer: LAYER_TERRAIN, }, @@ -386,6 +430,30 @@ const TILE_TYPES = { draw_layer: LAYER_TERRAIN, blocks: true, }, + green_chip: { + draw_layer: LAYER_ITEM, + is_chip: true, + is_required_chip: true, + blocks_monsters: true, + blocks_blocks: true, + on_arrive(me, level, other) { + if (other.type.is_player) { + level.collect_chip(); + level.remove_tile(me); + } + }, + }, + green_bomb: { + draw_layer: LAYER_ITEM, + on_arrive(me, level, other) { + // TODO explode + level.remove_tile(me); + level.remove_tile(other); + if (other.type.is_player) { + level.fail("watch where you step"); + } + }, + }, cloner: { draw_layer: LAYER_TERRAIN, blocks: true, @@ -513,7 +581,6 @@ const TILE_TYPES = { bug: { draw_layer: LAYER_ACTOR, is_actor: true, - is_object: true, is_monster: true, blocks_monsters: true, blocks_blocks: true, @@ -523,7 +590,6 @@ const TILE_TYPES = { paramecium: { draw_layer: LAYER_ACTOR, is_actor: true, - is_object: true, is_monster: true, blocks_monsters: true, blocks_blocks: true, @@ -533,7 +599,6 @@ const TILE_TYPES = { ball: { draw_layer: LAYER_ACTOR, is_actor: true, - is_object: true, is_monster: true, blocks_monsters: true, blocks_blocks: true, @@ -543,7 +608,6 @@ const TILE_TYPES = { walker: { draw_layer: LAYER_ACTOR, is_actor: true, - is_object: true, is_monster: true, blocks_monsters: true, blocks_blocks: true, @@ -553,7 +617,6 @@ const TILE_TYPES = { tank_blue: { draw_layer: LAYER_ACTOR, is_actor: true, - is_object: true, is_monster: true, blocks_monsters: true, blocks_blocks: true, @@ -563,7 +626,6 @@ const TILE_TYPES = { blob: { draw_layer: LAYER_ACTOR, is_actor: true, - is_object: true, is_monster: true, blocks_monsters: true, blocks_blocks: true, @@ -573,7 +635,6 @@ const TILE_TYPES = { teeth: { draw_layer: LAYER_ACTOR, is_actor: true, - is_object: true, is_monster: true, blocks_monsters: true, blocks_blocks: true, @@ -584,7 +645,6 @@ const TILE_TYPES = { fireball: { draw_layer: LAYER_ACTOR, is_actor: true, - is_object: true, is_monster: true, blocks_monsters: true, blocks_blocks: true, @@ -595,7 +655,6 @@ const TILE_TYPES = { glider: { draw_layer: LAYER_ACTOR, is_actor: true, - is_object: true, is_monster: true, blocks_monsters: true, blocks_blocks: true, @@ -607,39 +666,33 @@ const TILE_TYPES = { // Keys key_red: { draw_layer: LAYER_ITEM, - is_object: true, is_item: true, is_key: true, }, key_blue: { draw_layer: LAYER_ITEM, - is_object: true, is_item: true, is_key: true, }, key_yellow: { draw_layer: LAYER_ITEM, - is_object: true, is_item: true, is_key: true, }, key_green: { draw_layer: LAYER_ITEM, - is_object: true, is_item: true, is_key: true, }, // Tools cleats: { draw_layer: LAYER_ITEM, - is_object: true, is_item: true, is_tool: true, item_ignores: new Set(['ice', 'ice_nw', 'ice_ne', 'ice_sw', 'ice_se']), }, suction_boots: { draw_layer: LAYER_ITEM, - is_object: true, is_item: true, is_tool: true, item_ignores: new Set([ @@ -652,14 +705,12 @@ const TILE_TYPES = { }, fire_boots: { draw_layer: LAYER_ITEM, - is_object: true, is_item: true, is_tool: true, item_ignores: new Set(['fire']), }, flippers: { draw_layer: LAYER_ITEM, - is_object: true, is_item: true, is_tool: true, item_ignores: new Set(['water']), @@ -671,11 +722,11 @@ const TILE_TYPES = { is_actor: true, is_player: true, has_inventory: true, - is_object: true, movement_speed: 4, pushes: { dirt_block: true, clone_block: true, + ice_block: true, }, // FIXME this prevents thief from taking green key infinite_items: { @@ -690,7 +741,6 @@ const TILE_TYPES = { }, chip: { draw_layer: LAYER_ITEM, - is_object: true, is_chip: true, is_required_chip: true, blocks_monsters: true, @@ -705,7 +755,6 @@ const TILE_TYPES = { chip_extra: { draw_layer: LAYER_ITEM, is_chip: true, - is_object: true, blocks_monsters: true, blocks_blocks: true, on_arrive(me, level, other) { @@ -717,19 +766,15 @@ const TILE_TYPES = { }, score_10: { draw_layer: LAYER_ITEM, - is_object: true, }, score_100: { draw_layer: LAYER_ITEM, - is_object: true, }, score_1000: { draw_layer: LAYER_ITEM, - is_object: true, }, score_2x: { draw_layer: LAYER_ITEM, - is_object: true, }, hint: {