Implement green bombs/chips, ice blocks, and custom walls/floors

This commit is contained in:
Eevee (Evelyn Woods) 2020-09-08 14:42:38 -06:00
parent 88ec9f89e7
commit 8097339886
3 changed files with 101 additions and 39 deletions

View File

@ -169,12 +169,12 @@ const TILE_ENCODING = {
// 0x68: Bowling ball : '#next' // 0x68: Bowling ball : '#next'
// 0x69: Rover : '#direction', '#next' // 0x69: Rover : '#direction', '#next'
// 0x6a: Time penalty : '#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) : // 0x6c: (Unused) :
0x6d: ['#thinwall/canopy', '#next'], 0x6d: ['#thinwall/canopy', '#next'],
// 0x6e: (Unused) : // 0x6e: (Unused) :
// 0x6f: Railroad sign : '#next' // 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'], 0x71: ['#mod8', 'floor_letter'],
// 0x72: Purple toggle wall : // 0x72: Purple toggle wall :
// 0x73: Purple toggle floor : // 0x73: Purple toggle floor :
@ -193,8 +193,8 @@ const TILE_ENCODING = {
0x80: ['score_2x', '#next'], 0x80: ['score_2x', '#next'],
// 0x81: Directional block : '#direction', Directional Arrows Bitmask, '#next' // 0x81: Directional block : '#direction', Directional Arrows Bitmask, '#next'
// 0x82: Floor mimic : '#direction', '#next' // 0x82: Floor mimic : '#direction', '#next'
// 0x83: Green bomb : '#next' 0x83: ['green_bomb', '#next'],
// 0x84: Green chip : '#next' 0x84: ['green_chip', '#next'],
// 0x85: (Unused) : '#next' // 0x85: (Unused) : '#next'
// 0x86: (Unused) : '#next' // 0x86: (Unused) : '#next'
// 0x87: Black button : // 0x87: Black button :
@ -411,9 +411,14 @@ export function parse_level(buf) {
p++; p++;
let mod_marker; let mod_marker;
[mod_marker, name, ...args] = read_spec(); [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`); 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 // Make a tile template, possibly dealing with some special cases
if (name === '#thinwall/canopy') { if (name === '#thinwall/canopy') {
@ -444,6 +449,11 @@ export function parse_level(buf) {
// it, so that's fine // it, so that's fine
continue; 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}; let tile = {name, modifier};
cell.push(tile); cell.push(tile);

View File

@ -53,14 +53,15 @@ export const CC2_TILESET_LAYOUT = {
[8, 2], [8, 2],
[9, 2], [9, 2],
], ],
// ice block, xray ice_block: [10, 2],
score_10: [14, 2], // TODO ice block xray
score_100: [13, 2],
score_1000: [12, 2], score_1000: [12, 2],
score_100: [13, 2],
score_10: [14, 2],
score_2x: [15, 2], score_2x: [15, 2],
// LCD digit font // LCD digit font
green_chip: [10, 3], green_chip: [9, 3],
chip_extra: [10, 3], chip_extra: [10, 3],
chip: [11, 3], chip: [11, 3],
// bribe // bribe
@ -71,8 +72,14 @@ export const CC2_TILESET_LAYOUT = {
bomb: [5, 4], bomb: [5, 4],
green_bomb: [6, 4], green_bomb: [6, 4],
// ??? tiny fireworks // ??? tiny fireworks
// custom floors floor_custom_green: [8, 4],
// custom walls 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 // explosion
// splash // splash

View File

@ -18,10 +18,38 @@ const TILE_TYPES = {
me.ascii_code = template.modifier; 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: { wall: {
draw_layer: LAYER_TERRAIN, draw_layer: LAYER_TERRAIN,
blocks: true, 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: { wall_invisible: {
draw_layer: LAYER_TERRAIN, draw_layer: LAYER_TERRAIN,
// TODO cc2 seems to make these flicker briefly // TODO cc2 seems to make these flicker briefly
@ -195,7 +223,11 @@ const TILE_TYPES = {
fire: { fire: {
draw_layer: LAYER_TERRAIN, draw_layer: LAYER_TERRAIN,
on_arrive(me, level, other) { 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.fail("Oops! You can't walk on fire without fire boots!");
level.transmute_tile(other, 'player_burned'); level.transmute_tile(other, 'player_burned');
} }
@ -208,10 +240,14 @@ const TILE_TYPES = {
draw_layer: LAYER_TERRAIN, draw_layer: LAYER_TERRAIN,
on_arrive(me, level, other) { on_arrive(me, level, other) {
// TODO cc1 allows items under water, i think; water was on the upper layer // 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.remove_tile(other);
level.transmute_tile(me, 'dirt'); 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) { else if (other.type.is_player) {
level.fail("swimming with the fishes"); level.fail("swimming with the fishes");
level.transmute_tile(other, 'player_drowned'); level.transmute_tile(other, 'player_drowned');
@ -363,7 +399,6 @@ const TILE_TYPES = {
dirt_block: { dirt_block: {
draw_layer: LAYER_ACTOR, draw_layer: LAYER_ACTOR,
blocks: true, blocks: true,
is_object: true,
is_actor: true, is_actor: true,
is_block: true, is_block: true,
ignores: new Set(['fire']), ignores: new Set(['fire']),
@ -373,12 +408,21 @@ const TILE_TYPES = {
draw_layer: LAYER_ACTOR, draw_layer: LAYER_ACTOR,
// TODO is this in any way distinct from dirt block // TODO is this in any way distinct from dirt block
blocks: true, blocks: true,
is_object: true,
is_actor: true, is_actor: true,
is_block: true, is_block: true,
ignores: new Set(['fire']), ignores: new Set(['fire']),
movement_speed: 4, 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: { green_floor: {
draw_layer: LAYER_TERRAIN, draw_layer: LAYER_TERRAIN,
}, },
@ -386,6 +430,30 @@ const TILE_TYPES = {
draw_layer: LAYER_TERRAIN, draw_layer: LAYER_TERRAIN,
blocks: true, 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: { cloner: {
draw_layer: LAYER_TERRAIN, draw_layer: LAYER_TERRAIN,
blocks: true, blocks: true,
@ -513,7 +581,6 @@ const TILE_TYPES = {
bug: { bug: {
draw_layer: LAYER_ACTOR, draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true,
is_monster: true, is_monster: true,
blocks_monsters: true, blocks_monsters: true,
blocks_blocks: true, blocks_blocks: true,
@ -523,7 +590,6 @@ const TILE_TYPES = {
paramecium: { paramecium: {
draw_layer: LAYER_ACTOR, draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true,
is_monster: true, is_monster: true,
blocks_monsters: true, blocks_monsters: true,
blocks_blocks: true, blocks_blocks: true,
@ -533,7 +599,6 @@ const TILE_TYPES = {
ball: { ball: {
draw_layer: LAYER_ACTOR, draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true,
is_monster: true, is_monster: true,
blocks_monsters: true, blocks_monsters: true,
blocks_blocks: true, blocks_blocks: true,
@ -543,7 +608,6 @@ const TILE_TYPES = {
walker: { walker: {
draw_layer: LAYER_ACTOR, draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true,
is_monster: true, is_monster: true,
blocks_monsters: true, blocks_monsters: true,
blocks_blocks: true, blocks_blocks: true,
@ -553,7 +617,6 @@ const TILE_TYPES = {
tank_blue: { tank_blue: {
draw_layer: LAYER_ACTOR, draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true,
is_monster: true, is_monster: true,
blocks_monsters: true, blocks_monsters: true,
blocks_blocks: true, blocks_blocks: true,
@ -563,7 +626,6 @@ const TILE_TYPES = {
blob: { blob: {
draw_layer: LAYER_ACTOR, draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true,
is_monster: true, is_monster: true,
blocks_monsters: true, blocks_monsters: true,
blocks_blocks: true, blocks_blocks: true,
@ -573,7 +635,6 @@ const TILE_TYPES = {
teeth: { teeth: {
draw_layer: LAYER_ACTOR, draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true,
is_monster: true, is_monster: true,
blocks_monsters: true, blocks_monsters: true,
blocks_blocks: true, blocks_blocks: true,
@ -584,7 +645,6 @@ const TILE_TYPES = {
fireball: { fireball: {
draw_layer: LAYER_ACTOR, draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true,
is_monster: true, is_monster: true,
blocks_monsters: true, blocks_monsters: true,
blocks_blocks: true, blocks_blocks: true,
@ -595,7 +655,6 @@ const TILE_TYPES = {
glider: { glider: {
draw_layer: LAYER_ACTOR, draw_layer: LAYER_ACTOR,
is_actor: true, is_actor: true,
is_object: true,
is_monster: true, is_monster: true,
blocks_monsters: true, blocks_monsters: true,
blocks_blocks: true, blocks_blocks: true,
@ -607,39 +666,33 @@ const TILE_TYPES = {
// Keys // Keys
key_red: { key_red: {
draw_layer: LAYER_ITEM, draw_layer: LAYER_ITEM,
is_object: true,
is_item: true, is_item: true,
is_key: true, is_key: true,
}, },
key_blue: { key_blue: {
draw_layer: LAYER_ITEM, draw_layer: LAYER_ITEM,
is_object: true,
is_item: true, is_item: true,
is_key: true, is_key: true,
}, },
key_yellow: { key_yellow: {
draw_layer: LAYER_ITEM, draw_layer: LAYER_ITEM,
is_object: true,
is_item: true, is_item: true,
is_key: true, is_key: true,
}, },
key_green: { key_green: {
draw_layer: LAYER_ITEM, draw_layer: LAYER_ITEM,
is_object: true,
is_item: true, is_item: true,
is_key: true, is_key: true,
}, },
// Tools // Tools
cleats: { cleats: {
draw_layer: LAYER_ITEM, draw_layer: LAYER_ITEM,
is_object: true,
is_item: true, is_item: true,
is_tool: true, is_tool: true,
item_ignores: new Set(['ice', 'ice_nw', 'ice_ne', 'ice_sw', 'ice_se']), item_ignores: new Set(['ice', 'ice_nw', 'ice_ne', 'ice_sw', 'ice_se']),
}, },
suction_boots: { suction_boots: {
draw_layer: LAYER_ITEM, draw_layer: LAYER_ITEM,
is_object: true,
is_item: true, is_item: true,
is_tool: true, is_tool: true,
item_ignores: new Set([ item_ignores: new Set([
@ -652,14 +705,12 @@ const TILE_TYPES = {
}, },
fire_boots: { fire_boots: {
draw_layer: LAYER_ITEM, draw_layer: LAYER_ITEM,
is_object: true,
is_item: true, is_item: true,
is_tool: true, is_tool: true,
item_ignores: new Set(['fire']), item_ignores: new Set(['fire']),
}, },
flippers: { flippers: {
draw_layer: LAYER_ITEM, draw_layer: LAYER_ITEM,
is_object: true,
is_item: true, is_item: true,
is_tool: true, is_tool: true,
item_ignores: new Set(['water']), item_ignores: new Set(['water']),
@ -671,11 +722,11 @@ const TILE_TYPES = {
is_actor: true, is_actor: true,
is_player: true, is_player: true,
has_inventory: true, has_inventory: true,
is_object: true,
movement_speed: 4, movement_speed: 4,
pushes: { pushes: {
dirt_block: true, dirt_block: true,
clone_block: true, clone_block: true,
ice_block: true,
}, },
// FIXME this prevents thief from taking green key // FIXME this prevents thief from taking green key
infinite_items: { infinite_items: {
@ -690,7 +741,6 @@ const TILE_TYPES = {
}, },
chip: { chip: {
draw_layer: LAYER_ITEM, draw_layer: LAYER_ITEM,
is_object: true,
is_chip: true, is_chip: true,
is_required_chip: true, is_required_chip: true,
blocks_monsters: true, blocks_monsters: true,
@ -705,7 +755,6 @@ const TILE_TYPES = {
chip_extra: { chip_extra: {
draw_layer: LAYER_ITEM, draw_layer: LAYER_ITEM,
is_chip: true, is_chip: true,
is_object: true,
blocks_monsters: true, blocks_monsters: true,
blocks_blocks: true, blocks_blocks: true,
on_arrive(me, level, other) { on_arrive(me, level, other) {
@ -717,19 +766,15 @@ const TILE_TYPES = {
}, },
score_10: { score_10: {
draw_layer: LAYER_ITEM, draw_layer: LAYER_ITEM,
is_object: true,
}, },
score_100: { score_100: {
draw_layer: LAYER_ITEM, draw_layer: LAYER_ITEM,
is_object: true,
}, },
score_1000: { score_1000: {
draw_layer: LAYER_ITEM, draw_layer: LAYER_ITEM,
is_object: true,
}, },
score_2x: { score_2x: {
draw_layer: LAYER_ITEM, draw_layer: LAYER_ITEM,
is_object: true,
}, },
hint: { hint: {