diff --git a/js/main.js b/js/main.js index 4ee836e..714fc4d 100644 --- a/js/main.js +++ b/js/main.js @@ -67,6 +67,33 @@ async function fetch(url) { const PAGE_TITLE = "Lexy's Labyrinth"; +const DIRECTIONS = { + north: { + movement: [0, -1], + left: 'west', + right: 'east', + opposite: 'south', + }, + south: { + movement: [0, 1], + left: 'east', + right: 'west', + opposite: 'north', + }, + west: { + movement: [-1, 0], + left: 'south', + right: 'north', + opposite: 'east', + }, + east: { + movement: [1, 0], + left: 'north', + right: 'south', + opposite: 'west', + }, +}; + class Tile { constructor(type, x, y, direction = 'south') { this.type = type; @@ -91,6 +118,24 @@ class Tile { return tile; } + blocks(other, direction) { + if (this.type.blocks) + return true; + + if (this.type.thin_walls && + this.type.thin_walls.has(DIRECTIONS[direction].opposite)) + return true; + + if (other.type.is_player && this.type.blocks_players) + return true; + if (other.type.is_monster && this.type.blocks_monsters) + return true; + if (other.type.is_block && this.type.blocks_blocks) + return true; + + return false; + } + ignores(name) { if (this.type.ignores && this.type.ignores.has(name)) return true; @@ -179,33 +224,6 @@ class Cell extends Array { } } -const DIRECTIONS = { - north: { - movement: [0, -1], - left: 'west', - right: 'east', - opposite: 'south', - }, - south: { - movement: [0, 1], - left: 'east', - right: 'west', - opposite: 'north', - }, - west: { - movement: [-1, 0], - left: 'south', - right: 'north', - opposite: 'east', - }, - east: { - movement: [1, 0], - left: 'north', - right: 'south', - opposite: 'west', - }, -}; - class Level { constructor(stored_level) { this.stored_level = stored_level; @@ -387,10 +405,7 @@ class Level { if (! blocked) { let goal_cell = this.cells[goal_y][goal_x]; goal_cell.each(tile => { - if (! ( - tile.type.blocks || - (tile.type.thin_walls && tile.type.thin_walls.has(DIRECTIONS[direction].opposite)) - )) + if (! tile.blocks(actor, direction)) return; if (actor.type.pushes && actor.type.pushes[tile.type.name]) { @@ -400,7 +415,7 @@ class Level { } if (tile.type.on_bump) { tile.type.on_bump(tile, this, actor); - if (! tile.type.blocks) + if (! tile.blocks(actor, direction)) // It became something non-blocking! return; } diff --git a/js/tiletypes.js b/js/tiletypes.js index b927931..b651865 100644 --- a/js/tiletypes.js +++ b/js/tiletypes.js @@ -100,12 +100,15 @@ const TILE_TYPES = { // Terrain dirt: { - // TODO block monsters, and melinda only without the hiking boots + blocks_monsters: true, + blocks_blocks: true, + // TODO block melinda only without the hiking boots; can't use ignore because then she wouldn't step on it :S also ignore doesn't apply to blocks anyway. on_arrive(me, level, other) { me.become('floor'); } }, gravel: { + blocks_monsters: true, }, // Hazards @@ -249,39 +252,48 @@ const TILE_TYPES = { dirt_block: { blocks: true, is_object: true, + is_block: true, }, // Critters bug: { is_actor: true, is_object: true, + is_monster: true, movement_mode: 'follow-left', }, paramecium: { is_actor: true, is_object: true, + is_monster: true, + movement_mode: 'follow-right', }, ball: { is_actor: true, is_object: true, + is_monster: true, }, blob: { is_actor: true, is_object: true, + is_monster: true, }, teeth: { is_actor: true, is_object: true, + is_monster: true, }, fireball: { is_actor: true, is_object: true, + is_monster: true, movement_mode: 'turn-right', ignores: new Set(['fire']), }, glider: { is_actor: true, is_object: true, + is_monster: true, movement_mode: 'turn-left', ignores: new Set(['water']), }, @@ -359,6 +371,8 @@ const TILE_TYPES = { is_object: true, 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();