Begrudgingly support letter tiles
This commit is contained in:
parent
a2e1a4fd9a
commit
b3a0ff963c
@ -115,13 +115,12 @@ const TILE_ENCODING = {
|
||||
// 0x6e: (Unused) :
|
||||
// 0x6f: Railroad sign : '#next'
|
||||
// 0x70: Custom wall (green) : Modifier allows other styles, see below
|
||||
// TODO needs a preceding modifier but that's not done yet (and should enforce that a modifier is followed by a modifiable tile?)
|
||||
0x71: 'floor_letter',
|
||||
0x71: ['#mod8', 'floor_letter'],
|
||||
// 0x72: Purple toggle wall :
|
||||
// 0x73: Purple toggle floor :
|
||||
// 0x74: (Unused) :
|
||||
// 0x75: (Unused) :
|
||||
// 0x76: 8-bit Modifier (see Modifier section below) : 1 modifier byte, Tile Specification for affected tile
|
||||
0x76: ['#mod8', '#next'],
|
||||
// 0x77: 16-bit Modifier (see Modifier section below) : 2 modifier bytes, Tile Specification for affected tile
|
||||
// 0x78: 32-bit Modifier (see Modifier section below) : 4 modifier bytes, Tile Specification for affected tile
|
||||
// 0x79: (Unused) : '#direction', '#next'
|
||||
@ -313,29 +312,49 @@ export function parse_level(buf) {
|
||||
level.size_x = width;
|
||||
level.size_y = height;
|
||||
let p = 2;
|
||||
|
||||
function read_spec() {
|
||||
let tile_byte = bytes[p];
|
||||
p++;
|
||||
if (tile_byte >= 0x77 && tile_byte <= 0x78) {
|
||||
// XXX handle these modifier "tiles"
|
||||
p += tile_byte - 0x75;
|
||||
return [];
|
||||
}
|
||||
let spec = TILE_ENCODING[tile_byte];
|
||||
if (! spec)
|
||||
throw new Error(`Unrecognized tile type 0x${tile_byte.toString(16)}`);
|
||||
|
||||
let name;
|
||||
let args = [];
|
||||
if (spec instanceof Array) {
|
||||
return spec;
|
||||
}
|
||||
else {
|
||||
return [spec];
|
||||
}
|
||||
}
|
||||
|
||||
for (let n = 0; n < width * height; n++) {
|
||||
let cell = new util.StoredCell;
|
||||
while (true) {
|
||||
let tile_byte = bytes[p];
|
||||
p++;
|
||||
if (tile_byte >= 0x76 && tile_byte <= 0x78) {
|
||||
// XXX handle these modifier "tiles"
|
||||
p += tile_byte - 0x75;
|
||||
continue;
|
||||
}
|
||||
let spec = TILE_ENCODING[tile_byte];
|
||||
if (! spec)
|
||||
throw new Error(`Unrecognized tile type 0x${tile_byte.toString(16)}`);
|
||||
let [name, ...args] = read_spec();
|
||||
if (name === undefined) continue; // XXX modifier skip hack
|
||||
|
||||
let name;
|
||||
let args = [];
|
||||
if (spec instanceof Array) {
|
||||
[name, ...args] = spec;
|
||||
let modifier;
|
||||
if (name === '#mod8') {
|
||||
if (args[0] !== '#next')
|
||||
throw new Error(`Tile requires a preceding modifier`);
|
||||
|
||||
modifier = bytes[p];
|
||||
p++;
|
||||
let mod_marker;
|
||||
[mod_marker, name, ...args] = read_spec();
|
||||
if (mod_marker !== '#mod8')
|
||||
throw new Error(`Expected a tile requiring a modifier`);
|
||||
}
|
||||
else {
|
||||
name = spec;
|
||||
}
|
||||
let tile = {name};
|
||||
|
||||
let tile = {name, modifier};
|
||||
cell.push(tile);
|
||||
let type = TILE_TYPES[name];
|
||||
if (!type) console.error(name);
|
||||
|
||||
@ -84,7 +84,11 @@ class Tile {
|
||||
static from_template(tile_template, x, y) {
|
||||
let type = TILE_TYPES[tile_template.name];
|
||||
if (! type) console.error(tile_template.name);
|
||||
return new this(type, x, y, tile_template.direction);
|
||||
let tile = new this(type, x, y, tile_template.direction);
|
||||
if (type.load) {
|
||||
type.load(tile, tile_template);
|
||||
}
|
||||
return tile;
|
||||
}
|
||||
|
||||
ignores(name) {
|
||||
|
||||
@ -1,6 +1,19 @@
|
||||
export const CC2_TILESET_LAYOUT = {
|
||||
floor: [0, 2],
|
||||
floor_letter: [2, 2],
|
||||
'floor_letter#ascii': {
|
||||
x0: 0,
|
||||
y0: 0,
|
||||
width: 16,
|
||||
height: 1,
|
||||
},
|
||||
'floor_letter#arrows': {
|
||||
north: [14, 31],
|
||||
east: [14.5, 31],
|
||||
south: [15, 31],
|
||||
west: [15.5, 31],
|
||||
},
|
||||
|
||||
wall: [1, 2],
|
||||
|
||||
fire: [
|
||||
@ -89,10 +102,10 @@ export const CC2_TILESET_LAYOUT = {
|
||||
|
||||
hint: [5, 2],
|
||||
|
||||
score_10: [14, 1],
|
||||
score_100: [13, 1],
|
||||
score_1000: [12, 1],
|
||||
score_2x: [15, 1],
|
||||
score_10: [14, 2],
|
||||
score_100: [13, 2],
|
||||
score_1000: [12, 2],
|
||||
score_2x: [15, 2],
|
||||
};
|
||||
|
||||
// XXX need to specify that you can't use this for cc2 levels, somehow
|
||||
@ -247,10 +260,21 @@ export class Tileset {
|
||||
this.size_y = size_y;
|
||||
}
|
||||
|
||||
// Helper to draw to a canvas using tile coordinates
|
||||
blit(ctx, sx, sy, dx, dy, scale = 1) {
|
||||
let w = this.size_x * scale;
|
||||
let h = this.size_y * scale;
|
||||
ctx.drawImage(
|
||||
this.image,
|
||||
sx * this.size_x, sy * this.size_y, w, h,
|
||||
dx * this.size_x, dy * this.size_y, w, h);
|
||||
}
|
||||
|
||||
draw(tile, ctx, x, y) {
|
||||
let drawspec = this.layout[tile.type.name];
|
||||
let name = tile.type.name;
|
||||
let drawspec = this.layout[name];
|
||||
let coords = drawspec;
|
||||
if (! coords) console.error(tile.type.name);
|
||||
if (! coords) console.error(name);
|
||||
if (!(coords instanceof Array)) {
|
||||
// Must be an object of directions
|
||||
coords = coords[tile.direction ?? 'south'];
|
||||
@ -259,9 +283,38 @@ export class Tileset {
|
||||
coords = coords[0];
|
||||
}
|
||||
|
||||
ctx.drawImage(
|
||||
this.image,
|
||||
coords[0] * this.size_x, coords[1] * this.size_y, this.size_x, this.size_y,
|
||||
x * this.size_x, y * this.size_y, this.size_x, this.size_y);
|
||||
this.blit(ctx, coords[0], coords[1], x, y);
|
||||
|
||||
// Special behavior for special objects
|
||||
// TODO? hardcode this less?
|
||||
if (name === 'floor_letter') {
|
||||
let n = tile.ascii_code - 32;
|
||||
let scale = 0.5;
|
||||
let sx, sy;
|
||||
if (n < 0) {
|
||||
// Arrows
|
||||
if (n < -4) {
|
||||
// Default to south
|
||||
n = -2;
|
||||
}
|
||||
|
||||
let direction = ['north', 'east', 'south', 'west'][n + 4];
|
||||
[sx, sy] = this.layout['floor_letter#arrows'][direction];
|
||||
}
|
||||
else {
|
||||
// ASCII text (only up through uppercase)
|
||||
let letter_spec = this.layout['floor_letter#ascii'];
|
||||
if (n > letter_spec.width / scale * letter_spec.height / scale) {
|
||||
n = 0;
|
||||
}
|
||||
let w = letter_spec.width / scale;
|
||||
sx = (letter_spec.x0 + n % w) * scale;
|
||||
sy = (letter_spec.y0 + Math.floor(n / w)) * scale;
|
||||
}
|
||||
let offset = (1 - scale) / 2;
|
||||
this.blit(
|
||||
ctx, sx, sy,
|
||||
x + offset, y + offset, scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,9 @@ const TILE_TYPES = {
|
||||
floor: {
|
||||
},
|
||||
floor_letter: {
|
||||
load(me, template) {
|
||||
me.ascii_code = template.modifier;
|
||||
}
|
||||
},
|
||||
wall: {
|
||||
blocks: true,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user