Implement specialized blocking for dirt, gravel, chips, etc.

This commit is contained in:
Eevee (Evelyn Woods) 2020-08-29 02:22:55 -06:00
parent b3a0ff963c
commit 413c511fe1
2 changed files with 62 additions and 33 deletions

View File

@ -67,6 +67,33 @@ async function fetch(url) {
const PAGE_TITLE = "Lexy's Labyrinth"; 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 { class Tile {
constructor(type, x, y, direction = 'south') { constructor(type, x, y, direction = 'south') {
this.type = type; this.type = type;
@ -91,6 +118,24 @@ class Tile {
return 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) { ignores(name) {
if (this.type.ignores && this.type.ignores.has(name)) if (this.type.ignores && this.type.ignores.has(name))
return true; 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 { class Level {
constructor(stored_level) { constructor(stored_level) {
this.stored_level = stored_level; this.stored_level = stored_level;
@ -387,10 +405,7 @@ class Level {
if (! blocked) { if (! blocked) {
let goal_cell = this.cells[goal_y][goal_x]; let goal_cell = this.cells[goal_y][goal_x];
goal_cell.each(tile => { goal_cell.each(tile => {
if (! ( if (! tile.blocks(actor, direction))
tile.type.blocks ||
(tile.type.thin_walls && tile.type.thin_walls.has(DIRECTIONS[direction].opposite))
))
return; return;
if (actor.type.pushes && actor.type.pushes[tile.type.name]) { if (actor.type.pushes && actor.type.pushes[tile.type.name]) {
@ -400,7 +415,7 @@ class Level {
} }
if (tile.type.on_bump) { if (tile.type.on_bump) {
tile.type.on_bump(tile, this, actor); tile.type.on_bump(tile, this, actor);
if (! tile.type.blocks) if (! tile.blocks(actor, direction))
// It became something non-blocking! // It became something non-blocking!
return; return;
} }

View File

@ -100,12 +100,15 @@ const TILE_TYPES = {
// Terrain // Terrain
dirt: { 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) { on_arrive(me, level, other) {
me.become('floor'); me.become('floor');
} }
}, },
gravel: { gravel: {
blocks_monsters: true,
}, },
// Hazards // Hazards
@ -249,39 +252,48 @@ const TILE_TYPES = {
dirt_block: { dirt_block: {
blocks: true, blocks: true,
is_object: true, is_object: true,
is_block: true,
}, },
// Critters // Critters
bug: { bug: {
is_actor: true, is_actor: true,
is_object: true, is_object: true,
is_monster: true,
movement_mode: 'follow-left', movement_mode: 'follow-left',
}, },
paramecium: { paramecium: {
is_actor: true, is_actor: true,
is_object: true, is_object: true,
is_monster: true,
movement_mode: 'follow-right',
}, },
ball: { ball: {
is_actor: true, is_actor: true,
is_object: true, is_object: true,
is_monster: true,
}, },
blob: { blob: {
is_actor: true, is_actor: true,
is_object: true, is_object: true,
is_monster: true,
}, },
teeth: { teeth: {
is_actor: true, is_actor: true,
is_object: true, is_object: true,
is_monster: true,
}, },
fireball: { fireball: {
is_actor: true, is_actor: true,
is_object: true, is_object: true,
is_monster: true,
movement_mode: 'turn-right', movement_mode: 'turn-right',
ignores: new Set(['fire']), ignores: new Set(['fire']),
}, },
glider: { glider: {
is_actor: true, is_actor: true,
is_object: true, is_object: true,
is_monster: true,
movement_mode: 'turn-left', movement_mode: 'turn-left',
ignores: new Set(['water']), ignores: new Set(['water']),
}, },
@ -359,6 +371,8 @@ const TILE_TYPES = {
is_object: true, is_object: true,
is_chip: true, is_chip: true,
is_required_chip: true, is_required_chip: true,
blocks_monsters: true,
blocks_blocks: true,
on_arrive(me, level, other) { on_arrive(me, level, other) {
if (other.type.is_player) { if (other.type.is_player) {
level.collect_chip(); level.collect_chip();