Implement the CC2 "no sign"

This commit is contained in:
Eevee (Evelyn Woods) 2020-10-23 17:37:50 -06:00
parent 8c2f71294f
commit 2820c067c5
6 changed files with 38 additions and 13 deletions

View File

@ -536,7 +536,7 @@ const TILE_ENCODING = {
name: 'popdown_floor',
},
0x7f: {
name: 'forbidden',
name: 'no_sign',
has_next: true,
},
0x80: {

View File

@ -884,14 +884,15 @@ export class Level {
continue;
// TODO some actors can pick up some items...
if (actor.type.is_player && tile.type.is_item && this.give_actor(actor, tile.type.name)) {
if (actor.type.is_player && tile.type.is_item &&
this.attempt_take(actor, tile))
{
if (tile.type.is_key) {
this.sfx.play_once('get-key', cell);
}
else {
this.sfx.play_once('get-tool', cell);
}
this.remove_tile(tile);
}
else if (tile.type.teleport_dest_order) {
teleporter = tile;
@ -1257,6 +1258,18 @@ export class Level {
}
}
// Have an actor try to pick up a particular tile; it's prevented if there's a no sign, and the
// tile is removed if successful
attempt_take(actor, tile) {
if (! tile.cell.some(t => t.type.disables_pickup) &&
this.give_actor(actor, tile.type.name))
{
this.remove_tile(tile);
return true;
}
return false;
}
// Give an item to an actor, even if it's not supposed to have an inventory
give_actor(actor, name) {
if (! actor.type.is_actor)

View File

@ -126,7 +126,9 @@ export class CanvasRenderer {
// Draw one layer at a time, so animated objects aren't overdrawn by
// neighboring terrain
// XXX layer count hardcoded here
for (let layer = 0; layer < 4; layer++) {
// FIXME this is a bit inefficient when there are a lot of rarely-used layers; consider
// instead drawing everything under actors, then actors, then everything above actors?
for (let layer = 0; layer < 5; layer++) {
for (let x = xf0; x <= x1; x++) {
for (let y = yf0; y <= y1; y++) {
for (let tile of this.level.cells[y][x]) {

View File

@ -98,7 +98,7 @@ export const CC2_TILESET_LAYOUT = {
popdown_wall: [12, 5],
popdown_floor: [12, 5],
popdown_floor_visible: [13, 5],
forbidden: [14, 5],
no_sign: [14, 5],
// TODO arrows overlay at [3, 10]
directional_block: [15, 5],

View File

@ -4,8 +4,9 @@ import { random_choice } from './util.js';
// Draw layers
const LAYER_TERRAIN = 0;
const LAYER_ITEM = 1;
const LAYER_ACTOR = 2;
const LAYER_OVERLAY = 3;
const LAYER_NO_SIGN = 2;
const LAYER_ACTOR = 3;
const LAYER_OVERLAY = 4;
// TODO cc2 order is: swivel, thinwalls, canopy (and yes you can have them all in the same tile)
function player_visual_state(me) {
@ -543,8 +544,19 @@ const TILE_TYPES = {
}
},
},
forbidden: {
draw_layer: LAYER_TERRAIN,
no_sign: {
draw_layer: LAYER_NO_SIGN,
disables_pickup: true,
blocks(me, level, other) {
let item;
for (let tile of me.cell) {
if (tile.type.is_item) {
item = tile.type.name;
break;
}
}
return item && other.has_item(item);
},
},
// Mechanisms
@ -829,7 +841,7 @@ const TILE_TYPES = {
teleport_yellow: {
draw_layer: LAYER_TERRAIN,
teleport_dest_order(me, level) {
// FIXME special pickup behavior
// FIXME special pickup behavior; NOT an item though, does not combine with no sign
return level.iter_tiles_in_reading_order(me.cell, 'teleport_yellow', true);
},
},
@ -1207,9 +1219,7 @@ const TILE_TYPES = {
// TODO make this a... flag? i don't know?
// TODO major difference from lynx...
if (other.type.name !== 'ice_block' && other.type.name !== 'directional_block') {
if (level.give_actor(other, me.type.name)) {
level.remove_tile(me);
}
level.attempt_take(other, me);
}
},
},

Binary file not shown.