Get wire rendering correctly, at least for floors

This commit is contained in:
Eevee (Evelyn Woods) 2020-09-14 19:34:48 -06:00
parent 13b4180ab8
commit 468a1d44ba
4 changed files with 96 additions and 10 deletions

View File

@ -3,24 +3,28 @@ export const TICS_PER_SECOND = 20;
export const DIRECTIONS = {
north: {
movement: [0, -1],
bit: 0x01,
left: 'west',
right: 'east',
opposite: 'south',
},
south: {
movement: [0, 1],
bit: 0x04,
left: 'east',
right: 'west',
opposite: 'north',
},
west: {
movement: [-1, 0],
bit: 0x08,
left: 'south',
right: 'north',
opposite: 'east',
},
east: {
movement: [1, 0],
bit: 0x02,
left: 'north',
right: 'south',
opposite: 'west',

View File

@ -64,9 +64,15 @@ class CC2Demo {
}
}
function parse_modifier_wire(tile, modifier) {
tile.wire_directions = modifier & 0x0f;
tile.wire_tunnel_directions = (modifier & 0xf0) >> 4;
}
// TODO assert that direction + next match the tile types
const TILE_ENCODING = {
0x01: ['#mod', 'floor'], // XXX wire
0x01: ['floor', parse_modifier_wire],
0x02: 'wall',
0x03: 'ice',
0x04: 'ice_sw',
@ -81,8 +87,8 @@ const TILE_ENCODING = {
0x0d: 'force_floor_w',
0x0e: 'green_wall',
0x0f: 'green_floor',
0x10: ['#mod', 'teleport_red'], // XXX wire
0x11: ['#mod', 'teleport_blue'], // XXX wire
0x10: ['teleport_red', parse_modifier_wire],
0x11: ['teleport_blue', parse_modifier_wire],
0x12: 'teleport_yellow',
0x13: 'teleport_green',
0x14: 'exit',
@ -143,9 +149,9 @@ const TILE_ENCODING = {
0x4b: ['swivel_se', 'swivel_floor'],
0x4c: ['stopwatch_bonus', '#next'],
0x4d: ['stopwatch_toggle', '#next'],
0x4e: ['#mod', 'transmogrifier'], // XXX wire
0x4e: ['transmogrifier', parse_modifier_wire],
0x4f: ['#mod', 'railroad'],
0x50: ['#mod', 'steel'], // XXX wire
0x50: ['steel', parse_modifier_wire],
0x51: ['dynamite', '#next'],
0x52: ['helmet', '#next'],
0x56: ['player2', '#direction', '#next'],
@ -155,7 +161,7 @@ const TILE_ENCODING = {
0x5a: ['no_player2_sign'],
0x5b: ['no_player1_sign'],
// 0x5c: Inverter gate (N) : Modifier allows other gates, see below
0x5e: ['#mod', 'button_pink'], // XXX wire
0x5e: ['button_pink', parse_modifier_wire],
0x5f: 'flame_jet_off',
0x60: 'flame_jet_on',
0x61: 'button_orange',
@ -188,7 +194,7 @@ const TILE_ENCODING = {
0x82: ['floor_mimic', '#direction', '#next'],
0x83: ['green_bomb', '#next'],
0x84: ['green_chip', '#next'],
0x87: ['#mod', 'button_black'], // XXX wire
0x87: ['button_black', parse_modifier_wire],
// 0x88: ON/OFF switch (OFF) :
// 0x89: ON/OFF switch (ON) :
0x8a: 'thief_keys',
@ -407,10 +413,14 @@ export function parse_level(buf) {
modifier = map_view.getUint32(p, true);
p += 4;
}
[name, ...args] = read_spec();
/*
* TODO check for modifier expected and warn?
let mod_marker;
[mod_marker, name, ...args] = read_spec();
if (mod_marker !== '#mod')
throw new Error(`Expected a tile requiring a modifier; got ${name}`);
*/
}
if (name === '#mod') {
@ -502,6 +512,10 @@ export function parse_level(buf) {
}
tile.directional_block_arrows = arrows;
}
else if (arg instanceof Function) {
// Functions handle modifiers
arg(tile, modifier);
}
else {
// Anything else is an implicit next tile, e.g.
// turtles imply water underneath

View File

@ -1,3 +1,5 @@
import { DIRECTIONS } from './defs.js';
// TODO really need to specify this format more concretely, whoof
// XXX special kinds of drawing i know this has for a fact:
// - letter tiles draw from a block of half-tiles onto the center of the base
@ -9,6 +11,8 @@
// - directional blocks have arrows in an awkward layout, not 4x4 grid but actually positioned on the edges
// - green and purple toggle walls use an overlay
export const CC2_TILESET_LAYOUT = {
'#wire-width': 1/16,
door_red: [0, 1],
door_blue: [1, 1],
door_yellow: [2, 1],
@ -27,7 +31,12 @@ export const CC2_TILESET_LAYOUT = {
ice_nw: [14, 1],
cloner: [15, 1],
floor: [0, 2],
floor: {
// Wiring!
base: [0, 2],
wired: [8, 26],
is_wired_optional: true,
},
wall_invisible: [0, 2],
wall_appearing: [0, 2],
wall: [1, 2],
@ -105,8 +114,14 @@ export const CC2_TILESET_LAYOUT = {
button_green: [9, 6],
button_red: [10, 6],
button_brown: [11, 6],
button_pink: [12, 6],
button_black: [13, 6],
button_pink: {
base: [0, 2],
wired: [12, 6],
},
button_black: {
base: [0, 2],
wired: [13, 6],
},
button_orange: [14, 6],
button_yellow: [15, 6],
@ -275,6 +290,9 @@ export const CC2_TILESET_LAYOUT = {
[15, 24],
],
'#unpowered': [13, 26],
'#powered': [15, 26],
player2: {
moving: {
north: [[0, 27], [1, 27], [2, 27], [3, 27], [4, 27], [5, 27], [6, 27], [7, 27]],
@ -501,6 +519,47 @@ export class Tileset {
// tile, so some adjustments are needed; see below
coords = drawspec.tile;
}
else if (drawspec.wired) {
if (tile && tile.wire_directions !== undefined && tile.wire_directions !== 0) {
// TODO all four is a different thing entirely
// Draw the appropriate wire underlay
this.draw_type('#unpowered', tile, level, ctx, x, y);
// Draw a masked part of the base tile
let wiredir = tile.wire_directions;
let wire_radius = this.layout['#wire-width'] / 2;
let wire0 = 0.5 - wire_radius;
let wire1 = 0.5 + wire_radius;
let [bx, by] = drawspec.base;
if ((wiredir & DIRECTIONS['north'].bit) === 0) {
this.blit(ctx, bx, by, x, y, 1, wire0);
}
if ((wiredir & DIRECTIONS['south'].bit) === 0) {
this.blit(ctx, bx, by + wire1, x, y + wire1, 1, wire0);
}
if ((wiredir & DIRECTIONS['west'].bit) === 0) {
this.blit(ctx, bx, by, x, y, wire0, 1);
}
if ((wiredir & DIRECTIONS['east'].bit) === 0) {
this.blit(ctx, bx + wire1, by, x + wire1, y, wire0, 1);
}
// Then draw the wired tile as normal
coords = drawspec.wired;
}
else {
// There's no wiring here, so just draw the base and then draw the wired part on top
// as normal. If the wired part is optional (as is the case for flooring in the CC2
// tileset), draw the base as normal instead.
if (drawspec.is_wired_optional) {
coords = drawspec.base;
}
else {
this.blit(ctx, drawspec.base[0], drawspec.base[1], x, y);
coords = drawspec.wired;
}
}
}
// Unwrap animations etc.
if (!(coords instanceof Array)) {

View File

@ -8,10 +8,15 @@ const LAYER_OVERLAY = 3;
// TODO cc2 order is: swivel, thinwalls, canopy (and yes you can have them all in the same tile)
// TODO get rid of mentions of 'modifier' here, put them in the c2m loader
// TODO maybe get rid of 'load' entirely and copy everything from the tile template. also make the template ref the type instead of just having a name. in fact just make them fucking tiles? (ah but they shouldn't have state like inventory)
const TILE_TYPES = {
// Floors and walls
floor: {
draw_layer: LAYER_TERRAIN,
load(me, template) {
me.wire_directions = template.wire_directions;
me.wire_tunnel_directions = template.wire_tunnel_directions;
},
},
floor_letter: {
draw_layer: LAYER_TERRAIN,
@ -784,6 +789,10 @@ const TILE_TYPES = {
button_pink: {
// TODO not implemented
draw_layer: LAYER_TERRAIN,
load(me, template) {
me.wire_directions = template.wire_directions;
me.wire_tunnel_directions = template.wire_tunnel_directions;
},
},
button_black: {
// TODO not implemented