Introduce a DrawPacket to consolidate draw arguments; fix blurriness of double-size monsters
This commit is contained in:
parent
c60158cc47
commit
8f40f575bf
@ -1,7 +1,36 @@
|
|||||||
import { DIRECTIONS, LAYERS } from './defs.js';
|
import { DIRECTIONS, LAYERS } from './defs.js';
|
||||||
import { mk } from './util.js';
|
import { mk } from './util.js';
|
||||||
|
import { DrawPacket } from './tileset.js';
|
||||||
import TILE_TYPES from './tiletypes.js';
|
import TILE_TYPES from './tiletypes.js';
|
||||||
|
|
||||||
|
class CanvasRendererDrawPacket extends DrawPacket {
|
||||||
|
constructor(renderer, ctx, tic, perception) {
|
||||||
|
super(tic, perception);
|
||||||
|
this.renderer = renderer;
|
||||||
|
this.ctx = ctx;
|
||||||
|
// Canvas position of the cell being drawn
|
||||||
|
this.x = 0;
|
||||||
|
this.y = 0;
|
||||||
|
// Offset within the cell, for actors in motion
|
||||||
|
this.offsetx = 0;
|
||||||
|
this.offsety = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
blit(tx, ty, mx = 0, my = 0, mw = 1, mh = mw, mdx = mx, mdy = my) {
|
||||||
|
this.renderer.blit(this.ctx,
|
||||||
|
tx + mx, ty + my,
|
||||||
|
this.x + this.offsetx + mdx, this.y + this.offsety + mdy,
|
||||||
|
mw, mh);
|
||||||
|
}
|
||||||
|
|
||||||
|
blit_aligned(tx, ty, mx = 0, my = 0, mw = 1, mh = mw, mdx = mx, mdy = my) {
|
||||||
|
this.renderer.blit(this.ctx,
|
||||||
|
tx + mx, ty + my,
|
||||||
|
this.x + mdx, this.y + mdy,
|
||||||
|
mw, mh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class CanvasRenderer {
|
export class CanvasRenderer {
|
||||||
constructor(tileset, fixed_size = null) {
|
constructor(tileset, fixed_size = null) {
|
||||||
this.tileset = tileset;
|
this.tileset = tileset;
|
||||||
@ -92,18 +121,6 @@ export class CanvasRenderer {
|
|||||||
dx * tw, dy * th, w * tw, h * th);
|
dx * tw, dy * th, w * tw, h * th);
|
||||||
}
|
}
|
||||||
|
|
||||||
_make_tileset_blitter(ctx, offsetx = 0, offsety = 0) {
|
|
||||||
// The blit we pass to the tileset has a different signature than our own:
|
|
||||||
// blit(
|
|
||||||
// source_tile_x, source_tile_y,
|
|
||||||
// mask_x = 0, mask_y = 0, mask_width = 1, mask_height = mask_width,
|
|
||||||
// mask_dx = mask_x, mask_dy = mask_y)
|
|
||||||
// This makes it easier to use in the extremely common case of drawing part of one tile atop
|
|
||||||
// another tile, but still aligned to the grid.
|
|
||||||
return (tx, ty, mx = 0, my = 0, mw = 1, mh = mw, mdx = mx, mdy = my) =>
|
|
||||||
this.blit(ctx, tx + mx, ty + my, offsetx + mdx, offsety + mdy, mw, mh);
|
|
||||||
}
|
|
||||||
|
|
||||||
_adjust_viewport_if_dirty() {
|
_adjust_viewport_if_dirty() {
|
||||||
if (! this.viewport_dirty)
|
if (! this.viewport_dirty)
|
||||||
return;
|
return;
|
||||||
@ -171,6 +188,7 @@ export class CanvasRenderer {
|
|||||||
// Tiles in motion (i.e., actors) don't want to be overdrawn by neighboring tiles' terrain,
|
// Tiles in motion (i.e., actors) don't want to be overdrawn by neighboring tiles' terrain,
|
||||||
// so draw in three passes: everything below actors, actors, and everything above actors
|
// so draw in three passes: everything below actors, actors, and everything above actors
|
||||||
// neighboring terrain
|
// neighboring terrain
|
||||||
|
let packet = new CanvasRendererDrawPacket(this, this.ctx, tic, this.perception);
|
||||||
for (let x = xf0; x <= x1; x++) {
|
for (let x = xf0; x <= x1; x++) {
|
||||||
for (let y = yf0; y <= y1; y++) {
|
for (let y = yf0; y <= y1; y++) {
|
||||||
let cell = this.level.cell(x, y);
|
let cell = this.level.cell(x, y);
|
||||||
@ -179,9 +197,9 @@ export class CanvasRenderer {
|
|||||||
if (! tile)
|
if (! tile)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
this.tileset.draw(
|
packet.x = x - x0;
|
||||||
tile, tic, this.perception,
|
packet.y = y - y0;
|
||||||
this._make_tileset_blitter(this.ctx, x - x0, y - y0));
|
this.tileset.draw(tile, packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,24 +217,30 @@ export class CanvasRenderer {
|
|||||||
vy = Math.floor(vy * th + 0.5) / th;
|
vy = Math.floor(vy * th + 0.5) / th;
|
||||||
|
|
||||||
// For blocks, perception only applies if there's something of interest underneath
|
// For blocks, perception only applies if there's something of interest underneath
|
||||||
let perception = this.perception;
|
if (this.perception !== 'normal' && actor.type.is_block &&
|
||||||
if (perception !== 'normal' && actor.type.is_block &&
|
|
||||||
! cell.some(t => t && t.type.layer < LAYERS.actor && ! (
|
! cell.some(t => t && t.type.layer < LAYERS.actor && ! (
|
||||||
t.type.name === 'floor' && (t.wire_directions | t.wire_tunnel_directions) === 0)))
|
t.type.name === 'floor' && (t.wire_directions | t.wire_tunnel_directions) === 0)))
|
||||||
{
|
{
|
||||||
perception = 'normal';
|
packet.perception = 'normal';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
packet.perception = this.perception;
|
||||||
}
|
}
|
||||||
|
|
||||||
let blit = this._make_tileset_blitter(this.ctx, vx - x0, vy - y0);
|
packet.x = x - x0;
|
||||||
|
packet.y = y - y0;
|
||||||
|
packet.offsetx = vx - x;
|
||||||
|
packet.offsety = vy - y;
|
||||||
|
|
||||||
// Draw the active player background
|
// Draw the active player background
|
||||||
if (actor === this.active_player) {
|
if (actor === this.active_player) {
|
||||||
this.tileset.draw_type('#active-player-background', null, tic, perception, blit);
|
this.tileset.draw_type('#active-player-background', null, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.tileset.draw(actor, tic, perception, blit);
|
this.tileset.draw(actor, packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
packet.perception = this.perception;
|
||||||
for (let x = xf0; x <= x1; x++) {
|
for (let x = xf0; x <= x1; x++) {
|
||||||
for (let y = yf0; y <= y1; y++) {
|
for (let y = yf0; y <= y1; y++) {
|
||||||
let cell = this.level.cell(x, y);
|
let cell = this.level.cell(x, y);
|
||||||
@ -225,9 +249,7 @@ export class CanvasRenderer {
|
|||||||
if (! tile)
|
if (! tile)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
this.tileset.draw(
|
this.tileset.draw(tile, packet);
|
||||||
tile, tic, this.perception,
|
|
||||||
this._make_tileset_blitter(this.ctx, x - x0, y - y0));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -270,6 +292,7 @@ export class CanvasRenderer {
|
|||||||
draw_static_region(x0, y0, x1, y1, destx = x0, desty = y0) {
|
draw_static_region(x0, y0, x1, y1, destx = x0, desty = y0) {
|
||||||
this._adjust_viewport_if_dirty();
|
this._adjust_viewport_if_dirty();
|
||||||
|
|
||||||
|
let packet = new CanvasRendererDrawPacket(this, this.ctx, 0.0, this.perception);
|
||||||
for (let x = x0; x <= x1; x++) {
|
for (let x = x0; x <= x1; x++) {
|
||||||
for (let y = y0; y <= y1; y++) {
|
for (let y = y0; y <= y1; y++) {
|
||||||
let cell = this.level.cell(x, y);
|
let cell = this.level.cell(x, y);
|
||||||
@ -283,9 +306,11 @@ export class CanvasRenderer {
|
|||||||
|
|
||||||
// For actors (i.e., blocks), perception only applies if there's something
|
// For actors (i.e., blocks), perception only applies if there's something
|
||||||
// of potential interest underneath
|
// of potential interest underneath
|
||||||
let perception = this.perception;
|
if (this.perception !== 'normal' && tile.type.is_block && ! seen_anything_interesting) {
|
||||||
if (perception !== 'normal' && tile.type.is_actor && ! seen_anything_interesting) {
|
packet.perception = 'normal';
|
||||||
perception = 'normal';
|
}
|
||||||
|
else {
|
||||||
|
packet.perception = this.perception;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tile.type.layer < LAYERS.actor && ! (
|
if (tile.type.layer < LAYERS.actor && ! (
|
||||||
@ -294,9 +319,9 @@ export class CanvasRenderer {
|
|||||||
seen_anything_interesting = true;
|
seen_anything_interesting = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.tileset.draw(
|
packet.x = destx + x - x0;
|
||||||
tile, 0, perception,
|
packet.y = desty + y - y0;
|
||||||
this._make_tileset_blitter(this.ctx, destx + x - x0, desty + y - y0));
|
this.tileset.draw(tile, packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -305,8 +330,10 @@ export class CanvasRenderer {
|
|||||||
create_tile_type_canvas(name, tile = null) {
|
create_tile_type_canvas(name, tile = null) {
|
||||||
let canvas = mk('canvas', {width: this.tileset.size_x, height: this.tileset.size_y});
|
let canvas = mk('canvas', {width: this.tileset.size_x, height: this.tileset.size_y});
|
||||||
let ctx = canvas.getContext('2d');
|
let ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
// Individual tile types always reveal what they are
|
// Individual tile types always reveal what they are
|
||||||
this.tileset.draw_type(name, tile, 0, 'palette', this._make_tileset_blitter(ctx));
|
let packet = new CanvasRendererDrawPacket(this, ctx, 0.0, 'palette');
|
||||||
|
this.tileset.draw_type(name, tile, packet);
|
||||||
return canvas;
|
return canvas;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
186
js/tileset.js
186
js/tileset.js
@ -948,6 +948,26 @@ export const TILESET_LAYOUTS = {
|
|||||||
lexy: LL_TILESET_LAYOUT,
|
lexy: LL_TILESET_LAYOUT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Bundle of arguments for drawing a tile, containing some standard state about the game
|
||||||
|
export class DrawPacket {
|
||||||
|
constructor(tic = 0, perception = 'normal') {
|
||||||
|
this.tic = tic;
|
||||||
|
this.perception = 'normal';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw a tile (or region) from the tileset. The caller is presumed to know where the tile
|
||||||
|
// goes, so the arguments here are only about how to find the tile on the sheet.
|
||||||
|
// tx, ty: Tile coordinates (from the tileset, measured in cells)
|
||||||
|
// mx, my, mw, mh: Optional mask to use for drawing a subset of a tile (or occasionally tiles)
|
||||||
|
// mdx, mdy: Where to draw the masked part; defaults to drawing aligned with the tile
|
||||||
|
blit(tx, ty, mx = 0, my = 0, mw = 1, mh = mw, mdx = mx, mdy = my) {}
|
||||||
|
|
||||||
|
// Same, but do not interpolate the position of an actor in motion; always draw it exactly in
|
||||||
|
// the cell it claims to be in
|
||||||
|
blit_aligned(tx, ty, mx = 0, my = 0, mw = 1, mh = mw, mdx = mx, mdy = my) {}
|
||||||
|
}
|
||||||
|
|
||||||
export class Tileset {
|
export class Tileset {
|
||||||
constructor(image, layout, size_x, size_y) {
|
constructor(image, layout, size_x, size_y) {
|
||||||
// XXX curiously, i note that .image is never used within this class
|
// XXX curiously, i note that .image is never used within this class
|
||||||
@ -958,15 +978,15 @@ export class Tileset {
|
|||||||
this.animation_slowdown = 2;
|
this.animation_slowdown = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
draw(tile, tic, perception, blit) {
|
draw(tile, packet) {
|
||||||
this.draw_type(tile.type.name, tile, tic, perception, blit);
|
this.draw_type(tile.type.name, tile, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a "standard" drawspec, which is either:
|
// Draw a "standard" drawspec, which is either:
|
||||||
// - a single tile: [x, y]
|
// - a single tile: [x, y]
|
||||||
// - an animation: [[x0, y0], [x1, y1], ...]
|
// - an animation: [[x0, y0], [x1, y1], ...]
|
||||||
// - a directional tile: { north: T, east: T, ... } where T is either of the above
|
// - a directional tile: { north: T, east: T, ... } where T is either of the above
|
||||||
_draw_standard(drawspec, tile, tic, blit, mask = []) {
|
_draw_standard(drawspec, tile, packet) {
|
||||||
// If we have an object, it must be a table of directions
|
// If we have an object, it must be a table of directions
|
||||||
let coords = drawspec;
|
let coords = drawspec;
|
||||||
if (!(coords instanceof Array)) {
|
if (!(coords instanceof Array)) {
|
||||||
@ -975,14 +995,11 @@ export class Tileset {
|
|||||||
|
|
||||||
// Deal with animation
|
// Deal with animation
|
||||||
if (coords[0] instanceof Array) {
|
if (coords[0] instanceof Array) {
|
||||||
if (tic === null) {
|
if (tile && tile.movement_speed) {
|
||||||
coords = coords[0];
|
|
||||||
}
|
|
||||||
else if (tile && tile.movement_speed) {
|
|
||||||
// This tile reports its own animation timing (in frames), so trust that, and use
|
// This tile reports its own animation timing (in frames), so trust that, and use
|
||||||
// the current tic's fraction. If we're between tics, interpolate.
|
// the current tic's fraction. If we're between tics, interpolate.
|
||||||
// FIXME if the game ever runs every frame we will have to adjust the interpolation
|
// FIXME if the game ever runs every frame we will have to adjust the interpolation
|
||||||
let p = ((tile.movement_speed - tile.movement_cooldown) + tic % 1 * 3) / tile.movement_speed;
|
let p = ((tile.movement_speed - tile.movement_cooldown) + packet.tic % 1 * 3) / tile.movement_speed;
|
||||||
if (this.animation_slowdown > 1 && ! tile.type.ttl) {
|
if (this.animation_slowdown > 1 && ! tile.type.ttl) {
|
||||||
// The players have full walk animations, but they look very silly when squeezed
|
// The players have full walk animations, but they look very silly when squeezed
|
||||||
// into the span of a single step, so instead we only play half at a time. The
|
// into the span of a single step, so instead we only play half at a time. The
|
||||||
@ -993,7 +1010,7 @@ export class Tileset {
|
|||||||
// offset us into which half to play, then divide by 2 to renormalize.
|
// offset us into which half to play, then divide by 2 to renormalize.
|
||||||
// Which half to use is determined by when the animation /started/, as measured
|
// Which half to use is determined by when the animation /started/, as measured
|
||||||
// in animation lengths.
|
// in animation lengths.
|
||||||
let start_time = (tic * 3 / tile.movement_speed) - p;
|
let start_time = (packet.tic * 3 / tile.movement_speed) - p;
|
||||||
// Rounding smooths out float error (assuming the framerate never exceeds 1000)
|
// Rounding smooths out float error (assuming the framerate never exceeds 1000)
|
||||||
let segment = Math.floor(Math.round(start_time * 1000) / 1000 % this.animation_slowdown);
|
let segment = Math.floor(Math.round(start_time * 1000) / 1000 % this.animation_slowdown);
|
||||||
p = (p + segment) / this.animation_slowdown;
|
p = (p + segment) / this.animation_slowdown;
|
||||||
@ -1012,21 +1029,21 @@ export class Tileset {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// This tile animates on a global timer, one cycle every quarter of a second
|
// This tile animates on a global timer, one cycle every quarter of a second
|
||||||
coords = coords[Math.floor(tic / this.animation_slowdown % 5 / 5 * coords.length)];
|
coords = coords[Math.floor(packet.tic / this.animation_slowdown % 5 / 5 * coords.length)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
blit(coords[0], coords[1], ...mask);
|
packet.blit(coords[0], coords[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
_draw_letter(drawspec, tile, tic, blit) {
|
_draw_letter(drawspec, tile, packet) {
|
||||||
this._draw_standard(drawspec.base, tile, tic, blit);
|
this._draw_standard(drawspec.base, tile, packet);
|
||||||
|
|
||||||
let glyph = tile ? tile.overlaid_glyph : "?";
|
let glyph = tile ? tile.overlaid_glyph : "?";
|
||||||
if (drawspec.letter_glyphs[glyph]) {
|
if (drawspec.letter_glyphs[glyph]) {
|
||||||
let [x, y] = drawspec.letter_glyphs[glyph];
|
let [x, y] = drawspec.letter_glyphs[glyph];
|
||||||
// XXX size is hardcoded here, but not below, meh
|
// XXX size is hardcoded here, but not below, meh
|
||||||
blit(x, y, 0, 0, 0.5, 0.5, 0.25, 0.25);
|
packet.blit(x, y, 0, 0, 0.5, 0.5, 0.25, 0.25);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Look for a range
|
// Look for a range
|
||||||
@ -1036,7 +1053,7 @@ export class Tileset {
|
|||||||
let t = u - rangedef.range[0];
|
let t = u - rangedef.range[0];
|
||||||
let x = rangedef.x0 + rangedef.w * (t % rangedef.columns);
|
let x = rangedef.x0 + rangedef.w * (t % rangedef.columns);
|
||||||
let y = rangedef.y0 + rangedef.h * Math.floor(t / rangedef.columns);
|
let y = rangedef.y0 + rangedef.h * Math.floor(t / rangedef.columns);
|
||||||
blit(x, y, 0, 0, rangedef.w, rangedef.h,
|
packet.blit(x, y, 0, 0, rangedef.w, rangedef.h,
|
||||||
(1 - rangedef.w) / 2, (1 - rangedef.h) / 2);
|
(1 - rangedef.w) / 2, (1 - rangedef.h) / 2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1044,65 +1061,65 @@ export class Tileset {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_draw_thin_walls(drawspec, tile, tic, blit) {
|
_draw_thin_walls(drawspec, tile, packet) {
|
||||||
let edges = tile ? tile.edges : 0x0f;
|
let edges = tile ? tile.edges : 0x0f;
|
||||||
|
|
||||||
// TODO it would be /extremely/ cool to join corners diagonally, but i can't do that without
|
// TODO it would be /extremely/ cool to join corners diagonally, but i can't do that without
|
||||||
// access to the context, which defeats the whole purpose of this scheme. damn
|
// access to the context, which defeats the whole purpose of this scheme. damn
|
||||||
if (edges & DIRECTIONS['north'].bit) {
|
if (edges & DIRECTIONS['north'].bit) {
|
||||||
blit(...drawspec.thin_walls_ns, 0, 0, 1, 0.5);
|
packet.blit(...drawspec.thin_walls_ns, 0, 0, 1, 0.5);
|
||||||
}
|
}
|
||||||
if (edges & DIRECTIONS['east'].bit) {
|
if (edges & DIRECTIONS['east'].bit) {
|
||||||
blit(...drawspec.thin_walls_ew, 0.5, 0, 0.5, 1);
|
packet.blit(...drawspec.thin_walls_ew, 0.5, 0, 0.5, 1);
|
||||||
}
|
}
|
||||||
if (edges & DIRECTIONS['south'].bit) {
|
if (edges & DIRECTIONS['south'].bit) {
|
||||||
blit(...drawspec.thin_walls_ns, 0, 0.5, 1, 0.5);
|
packet.blit(...drawspec.thin_walls_ns, 0, 0.5, 1, 0.5);
|
||||||
}
|
}
|
||||||
if (edges & DIRECTIONS['west'].bit) {
|
if (edges & DIRECTIONS['west'].bit) {
|
||||||
blit(...drawspec.thin_walls_ew, 0, 0, 0.5, 1);
|
packet.blit(...drawspec.thin_walls_ew, 0, 0, 0.5, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_draw_thin_walls_cc1(drawspec, tile, tic, blit) {
|
_draw_thin_walls_cc1(drawspec, tile, packet) {
|
||||||
let edges = tile ? tile.edges : 0x0f;
|
let edges = tile ? tile.edges : 0x0f;
|
||||||
|
|
||||||
// This is kinda best-effort since the tiles are opaque and not designed to combine
|
// This is kinda best-effort since the tiles are opaque and not designed to combine
|
||||||
if (edges === (DIRECTIONS['south'].bit | DIRECTIONS['east'].bit)) {
|
if (edges === (DIRECTIONS['south'].bit | DIRECTIONS['east'].bit)) {
|
||||||
blit(...drawspec.southeast);
|
packet.blit(...drawspec.southeast);
|
||||||
}
|
}
|
||||||
else if (edges & DIRECTIONS['north'].bit) {
|
else if (edges & DIRECTIONS['north'].bit) {
|
||||||
blit(...drawspec.north);
|
packet.blit(...drawspec.north);
|
||||||
}
|
}
|
||||||
else if (edges & DIRECTIONS['east'].bit) {
|
else if (edges & DIRECTIONS['east'].bit) {
|
||||||
blit(...drawspec.east);
|
packet.blit(...drawspec.east);
|
||||||
}
|
}
|
||||||
else if (edges & DIRECTIONS['south'].bit) {
|
else if (edges & DIRECTIONS['south'].bit) {
|
||||||
blit(...drawspec.south);
|
packet.blit(...drawspec.south);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
blit(...drawspec.west);
|
packet.blit(...drawspec.west);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_draw_bomb_fuse(drawspec, tile, tic, blit) {
|
_draw_bomb_fuse(drawspec, tile, packet) {
|
||||||
// Draw the base bomb
|
// Draw the base bomb
|
||||||
this._draw_standard(drawspec.bomb, tile, tic, blit);
|
this._draw_standard(drawspec.bomb, tile, packet);
|
||||||
|
|
||||||
// The fuse is made up of four quarter-tiles and animates... um... at a rate. I cannot
|
// The fuse is made up of four quarter-tiles and animates... um... at a rate. I cannot
|
||||||
// tell. I have spent over an hour poring over this and cannot find a consistent pattern.
|
// tell. I have spent over an hour poring over this and cannot find a consistent pattern.
|
||||||
// It might be random! I'm gonna say it loops every 0.3 seconds = 18 frames, so 4.5 frames
|
// It might be random! I'm gonna say it loops every 0.3 seconds = 18 frames, so 4.5 frames
|
||||||
// per cel, I guess. No one will know. (But... I'll know.)
|
// per cel, I guess. No one will know. (But... I'll know.)
|
||||||
// Also it's drawn in the upper right, that's important.
|
// Also it's drawn in the upper right, that's important.
|
||||||
let cel = Math.floor(tic / 0.3 * 4) % 4;
|
let cel = Math.floor(packet.tic / 0.3 * 4) % 4;
|
||||||
blit(...drawspec.fuse, 0.5 * (cel % 2), 0.5 * Math.floor(cel / 2), 0.5, 0.5, 0.5, 0);
|
packet.blit(...drawspec.fuse, 0.5 * (cel % 2), 0.5 * Math.floor(cel / 2), 0.5, 0.5, 0.5, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
_draw_double_size_monster(drawspec, tile, tic, blit) {
|
_draw_double_size_monster(drawspec, tile, packet) {
|
||||||
// CC2's tileset has double-size art for blobs and walkers that spans the tile they're
|
// CC2's tileset has double-size art for blobs and walkers that spans the tile they're
|
||||||
// moving from AND the tile they're moving into.
|
// moving from AND the tile they're moving into.
|
||||||
// First, of course, this only happens if they're moving at all.
|
// First, of course, this only happens if they're moving at all.
|
||||||
if (! tile || ! tile.movement_speed) {
|
if (! tile || ! tile.movement_speed) {
|
||||||
this._draw_standard(drawspec.base, tile, tic, blit);
|
this._draw_standard(drawspec.base, tile, packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1118,6 +1135,7 @@ export class Tileset {
|
|||||||
else if (tile.direction === 'south') {
|
else if (tile.direction === 'south') {
|
||||||
axis_cels = drawspec.vertical;
|
axis_cels = drawspec.vertical;
|
||||||
h = 2;
|
h = 2;
|
||||||
|
y = -1;
|
||||||
}
|
}
|
||||||
else if (tile.direction === 'west') {
|
else if (tile.direction === 'west') {
|
||||||
axis_cels = drawspec.horizontal;
|
axis_cels = drawspec.horizontal;
|
||||||
@ -1127,32 +1145,28 @@ export class Tileset {
|
|||||||
else if (tile.direction === 'east') {
|
else if (tile.direction === 'east') {
|
||||||
axis_cels = drawspec.horizontal;
|
axis_cels = drawspec.horizontal;
|
||||||
w = 2;
|
w = 2;
|
||||||
|
x = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME lexy is n to 1, cc2 n-1 to 0, and this mixes them
|
// FIXME lexy is n to 1, cc2 n-1 to 0, and this mixes them
|
||||||
let p = tile.movement_speed - tile.movement_cooldown;
|
let p = tile.movement_speed - tile.movement_cooldown;
|
||||||
p = (p + tic % 1 * 3) / tile.movement_speed;
|
p = (p + packet.tic % 1 * 3) / tile.movement_speed;
|
||||||
p = Math.min(p, 0.999); // FIXME hack for differing movement counters
|
p = Math.min(p, 0.999); // FIXME hack for differing movement counters
|
||||||
let index = Math.floor(p * (axis_cels.length + 1));
|
let index = Math.floor(p * (axis_cels.length + 1));
|
||||||
if (index === 0 || index > axis_cels.length) {
|
if (index === 0 || index > axis_cels.length) {
|
||||||
this._draw_standard(drawspec.base, tile, tic, blit);
|
this._draw_standard(drawspec.base, tile, packet);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Tragically we have to counter the renderer's attempts to place the tile at its visual
|
|
||||||
// position
|
|
||||||
// FIXME this gets off the pixel grid because the value already baked into blit() has
|
|
||||||
// already been rounded. i don't know how to fix this
|
|
||||||
let [vx, vy] = tile.visual_position(tic % 1);
|
|
||||||
let cel = reverse ? axis_cels[axis_cels.length - index] : axis_cels[index - 1];
|
let cel = reverse ? axis_cels[axis_cels.length - index] : axis_cels[index - 1];
|
||||||
blit(...cel, 0, 0, w, h, x - vx % 1, y - vy % 1);
|
packet.blit_aligned(...cel, 0, 0, w, h, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_draw_rover(drawspec, tile, tic, blit) {
|
_draw_rover(drawspec, tile, packet) {
|
||||||
// Rovers draw fairly normally (with their visual_state giving the monster they're copying),
|
// Rovers draw fairly normally (with their visual_state giving the monster they're copying),
|
||||||
// but they also have an overlay indicating their direction
|
// but they also have an overlay indicating their direction
|
||||||
let state = tile ? tile.type.visual_state(tile) : 'inert';
|
let state = tile ? tile.type.visual_state(tile) : 'inert';
|
||||||
this._draw_standard(drawspec[state], tile, tic, blit);
|
this._draw_standard(drawspec[state], tile, packet);
|
||||||
|
|
||||||
if (! tile)
|
if (! tile)
|
||||||
return;
|
return;
|
||||||
@ -1163,68 +1177,68 @@ export class Tileset {
|
|||||||
let index = {north: 0, east: 1, west: 2, south: 3}[tile.direction];
|
let index = {north: 0, east: 1, west: 2, south: 3}[tile.direction];
|
||||||
if (index === undefined)
|
if (index === undefined)
|
||||||
return;
|
return;
|
||||||
blit(
|
packet.blit(
|
||||||
...drawspec.direction,
|
...drawspec.direction,
|
||||||
0.5 * (index % 2), 0.5 * Math.floor(index / 2), 0.5, 0.5,
|
0.5 * (index % 2), 0.5 * Math.floor(index / 2), 0.5, 0.5,
|
||||||
overlay_position[0], overlay_position[1]);
|
overlay_position[0], overlay_position[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
_draw_logic_gate(drawspec, tile, tic, blit) {
|
_draw_logic_gate(drawspec, tile, packet) {
|
||||||
// Layer 1: wiring state
|
// Layer 1: wiring state
|
||||||
// Always draw the unpowered wire base
|
// Always draw the unpowered wire base
|
||||||
let unpowered_coords = this.layout['#unpowered'];
|
let unpowered_coords = this.layout['#unpowered'];
|
||||||
let powered_coords = this.layout['#powered'];
|
let powered_coords = this.layout['#powered'];
|
||||||
blit(...unpowered_coords);
|
packet.blit(...unpowered_coords);
|
||||||
if (tile && tile.cell) {
|
if (tile && tile.cell) {
|
||||||
// What goes on top varies a bit...
|
// What goes on top varies a bit...
|
||||||
let r = this.layout['#wire-width'] / 2;
|
let r = this.layout['#wire-width'] / 2;
|
||||||
if (tile.gate_type === 'not' || tile.gate_type === 'counter') {
|
if (tile.gate_type === 'not' || tile.gate_type === 'counter') {
|
||||||
this._draw_fourway_tile_power(tile, 0x0f, blit);
|
this._draw_fourway_tile_power(tile, 0x0f, packet);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (tile.powered_edges & DIRECTIONS[tile.direction].bit) {
|
if (tile.powered_edges & DIRECTIONS[tile.direction].bit) {
|
||||||
// Output (on top)
|
// Output (on top)
|
||||||
let [x0, y0, x1, y1] = this._rotate(tile.direction, 0.5 - r, 0, 0.5 + r, 0.5);
|
let [x0, y0, x1, y1] = this._rotate(tile.direction, 0.5 - r, 0, 0.5 + r, 0.5);
|
||||||
blit(powered_coords[0], powered_coords[1], x0, y0, x1 - x0, y1 - y0);
|
packet.blit(powered_coords[0], powered_coords[1], x0, y0, x1 - x0, y1 - y0);
|
||||||
}
|
}
|
||||||
if (tile.powered_edges & DIRECTIONS[DIRECTIONS[tile.direction].right].bit) {
|
if (tile.powered_edges & DIRECTIONS[DIRECTIONS[tile.direction].right].bit) {
|
||||||
// Right input, which includes the middle
|
// Right input, which includes the middle
|
||||||
// This actually covers the entire lower right corner, for bent inputs.
|
// This actually covers the entire lower right corner, for bent inputs.
|
||||||
let [x0, y0, x1, y1] = this._rotate(tile.direction, 0.5 - r, 0.5 - r, 1, 1);
|
let [x0, y0, x1, y1] = this._rotate(tile.direction, 0.5 - r, 0.5 - r, 1, 1);
|
||||||
blit(powered_coords[0], powered_coords[1], x0, y0, x1 - x0, y1 - y0);
|
packet.blit(powered_coords[0], powered_coords[1], x0, y0, x1 - x0, y1 - y0);
|
||||||
}
|
}
|
||||||
if (tile.powered_edges & DIRECTIONS[DIRECTIONS[tile.direction].left].bit) {
|
if (tile.powered_edges & DIRECTIONS[DIRECTIONS[tile.direction].left].bit) {
|
||||||
// Left input, which does not include the middle
|
// Left input, which does not include the middle
|
||||||
// This actually covers the entire lower left corner, for bent inputs.
|
// This actually covers the entire lower left corner, for bent inputs.
|
||||||
let [x0, y0, x1, y1] = this._rotate(tile.direction, 0, 0.5 - r, 0.5 - r, 1);
|
let [x0, y0, x1, y1] = this._rotate(tile.direction, 0, 0.5 - r, 0.5 - r, 1);
|
||||||
blit(powered_coords[0], powered_coords[1], x0, y0, x1 - x0, y1 - y0);
|
packet.blit(powered_coords[0], powered_coords[1], x0, y0, x1 - x0, y1 - y0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layer 2: the tile itself
|
// Layer 2: the tile itself
|
||||||
this._draw_standard(drawspec.logic_gate_tiles[tile.gate_type], tile, tic, blit);
|
this._draw_standard(drawspec.logic_gate_tiles[tile.gate_type], tile, packet);
|
||||||
|
|
||||||
// Layer 3: counter number
|
// Layer 3: counter number
|
||||||
if (tile.gate_type === 'counter') {
|
if (tile.gate_type === 'counter') {
|
||||||
blit(0, 3, tile.memory * 0.75, 0, 0.75, 1, 0.125, 0);
|
packet.blit(0, 3, tile.memory * 0.75, 0, 0.75, 1, 0.125, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_draw_fourway_tile_power(tile, wires, blit) {
|
_draw_fourway_tile_power(tile, wires, packet) {
|
||||||
// Draw the unpowered tile underneath, if any edge is unpowered (and in fact if /none/ of it
|
// Draw the unpowered tile underneath, if any edge is unpowered (and in fact if /none/ of it
|
||||||
// is powered then we're done here)
|
// is powered then we're done here)
|
||||||
let powered = (tile.cell ? tile.powered_edges : 0) & wires;
|
let powered = (tile.cell ? tile.powered_edges : 0) & wires;
|
||||||
if (! tile.cell || powered !== tile.wire_directions) {
|
if (! tile.cell || powered !== tile.wire_directions) {
|
||||||
this._draw_fourway_power_underlay(this.layout['#unpowered'], wires, blit);
|
this._draw_fourway_power_underlay(this.layout['#unpowered'], wires, packet);
|
||||||
if (! tile.cell || powered === 0)
|
if (! tile.cell || powered === 0)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._draw_fourway_power_underlay(this.layout['#powered'], powered, blit);
|
this._draw_fourway_power_underlay(this.layout['#powered'], powered, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
_draw_fourway_power_underlay(drawspec, bits, blit) {
|
_draw_fourway_power_underlay(drawspec, bits, packet) {
|
||||||
// Draw the part as a single rectangle, initially just a small dot in the center, but
|
// Draw the part as a single rectangle, initially just a small dot in the center, but
|
||||||
// extending out to any edge that has a bit present
|
// extending out to any edge that has a bit present
|
||||||
let wire_radius = this.layout['#wire-width'] / 2;
|
let wire_radius = this.layout['#wire-width'] / 2;
|
||||||
@ -1244,13 +1258,13 @@ export class Tileset {
|
|||||||
if (bits & DIRECTIONS['west'].bit) {
|
if (bits & DIRECTIONS['west'].bit) {
|
||||||
x0 = 0;
|
x0 = 0;
|
||||||
}
|
}
|
||||||
blit(drawspec[0], drawspec[1], x0, y0, x1 - x0, y1 - y0);
|
packet.blit(drawspec[0], drawspec[1], x0, y0, x1 - x0, y1 - y0);
|
||||||
}
|
}
|
||||||
|
|
||||||
_draw_railroad(drawspec, tile, tic, blit) {
|
_draw_railroad(drawspec, tile, packet) {
|
||||||
// All railroads have regular gravel underneath
|
// All railroads have regular gravel underneath
|
||||||
// TODO would be nice to disambiguate since it's possible to have nothing visible
|
// TODO would be nice to disambiguate since it's possible to have nothing visible
|
||||||
this._draw_standard(this.layout['gravel'], tile, tic, blit);
|
this._draw_standard(this.layout['gravel'], tile, packet);
|
||||||
|
|
||||||
// FIXME what do i draw if there's no tile?
|
// FIXME what do i draw if there's no tile?
|
||||||
let part_order = ['ne', 'se', 'sw', 'nw', 'ew', 'ns'];
|
let part_order = ['ne', 'se', 'sw', 'nw', 'ew', 'ns'];
|
||||||
@ -1267,26 +1281,26 @@ export class Tileset {
|
|||||||
|
|
||||||
let has_switch = (tile && tile.track_switch !== null);
|
let has_switch = (tile && tile.track_switch !== null);
|
||||||
for (let part of visible_parts) {
|
for (let part of visible_parts) {
|
||||||
this._draw_standard(drawspec.railroad_ties[part], tile, tic, blit);
|
this._draw_standard(drawspec.railroad_ties[part], tile, packet);
|
||||||
}
|
}
|
||||||
let tracks = has_switch ? drawspec.railroad_inactive : drawspec.railroad_active;
|
let tracks = has_switch ? drawspec.railroad_inactive : drawspec.railroad_active;
|
||||||
for (let part of visible_parts) {
|
for (let part of visible_parts) {
|
||||||
if (part !== topmost_part) {
|
if (part !== topmost_part) {
|
||||||
this._draw_standard(tracks[part], tile, tic, blit);
|
this._draw_standard(tracks[part], tile, packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topmost_part) {
|
if (topmost_part) {
|
||||||
this._draw_standard(drawspec.railroad_active[topmost_part], tile, tic, blit);
|
this._draw_standard(drawspec.railroad_active[topmost_part], tile, packet);
|
||||||
}
|
}
|
||||||
if (has_switch) {
|
if (has_switch) {
|
||||||
this._draw_standard(drawspec.railroad_switch, tile, tic, blit);
|
this._draw_standard(drawspec.railroad_switch, tile, packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draws a tile type, given by name. Passing in a tile is optional, but
|
// Draws a tile type, given by name. Passing in a tile is optional, but
|
||||||
// without it you'll get defaults.
|
// without it you'll get defaults.
|
||||||
draw_type(name, tile, tic, perception, blit) {
|
draw_type(name, tile, packet) {
|
||||||
let drawspec = this.layout[name];
|
let drawspec = this.layout[name];
|
||||||
if (drawspec === null) {
|
if (drawspec === null) {
|
||||||
// This is explicitly never drawn (used for extra visual-only frills that don't exist in
|
// This is explicitly never drawn (used for extra visual-only frills that don't exist in
|
||||||
@ -1305,13 +1319,13 @@ export class Tileset {
|
|||||||
// the overlay (either a type name or a regular draw spec).
|
// the overlay (either a type name or a regular draw spec).
|
||||||
// TODO chance of infinite recursion here
|
// TODO chance of infinite recursion here
|
||||||
if (typeof drawspec.base === 'string') {
|
if (typeof drawspec.base === 'string') {
|
||||||
this.draw_type(drawspec.base, tile, tic, perception, blit);
|
this.draw_type(drawspec.base, tile, packet);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this._draw_standard(drawspec.base, tile, tic, blit);
|
this._draw_standard(drawspec.base, tile, packet);
|
||||||
}
|
}
|
||||||
if (typeof drawspec.overlay === 'string') {
|
if (typeof drawspec.overlay === 'string') {
|
||||||
this.draw_type(drawspec.overlay, tile, tic, perception, blit);
|
this.draw_type(drawspec.overlay, tile, packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1322,31 +1336,31 @@ export class Tileset {
|
|||||||
// TODO shift everything to use this style, this is ridiculous
|
// TODO shift everything to use this style, this is ridiculous
|
||||||
if (drawspec.special) {
|
if (drawspec.special) {
|
||||||
if (drawspec.special === 'letter') {
|
if (drawspec.special === 'letter') {
|
||||||
this._draw_letter(drawspec, tile, tic, blit);
|
this._draw_letter(drawspec, tile, packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (drawspec.special === 'thin_walls') {
|
else if (drawspec.special === 'thin_walls') {
|
||||||
this._draw_thin_walls(drawspec, tile, tic, blit);
|
this._draw_thin_walls(drawspec, tile, packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (drawspec.special === 'thin_walls_cc1') {
|
else if (drawspec.special === 'thin_walls_cc1') {
|
||||||
this._draw_thin_walls_cc1(drawspec, tile, tic, blit);
|
this._draw_thin_walls_cc1(drawspec, tile, packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (drawspec.special === 'bomb-fuse') {
|
else if (drawspec.special === 'bomb-fuse') {
|
||||||
this._draw_bomb_fuse(drawspec, tile, tic, blit);
|
this._draw_bomb_fuse(drawspec, tile, packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (drawspec.special === 'double-size-monster') {
|
else if (drawspec.special === 'double-size-monster') {
|
||||||
this._draw_double_size_monster(drawspec, tile, tic, blit);
|
this._draw_double_size_monster(drawspec, tile, packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (drawspec.special === 'rover') {
|
else if (drawspec.special === 'rover') {
|
||||||
this._draw_rover(drawspec, tile, tic, blit);
|
this._draw_rover(drawspec, tile, packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (drawspec.special === 'perception') {
|
else if (drawspec.special === 'perception') {
|
||||||
if (drawspec.modes.has(perception)) {
|
if (drawspec.modes.has(packet.perception)) {
|
||||||
drawspec = drawspec.revealed;
|
drawspec = drawspec.revealed;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1354,11 +1368,11 @@ export class Tileset {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (drawspec.special === 'logic-gate') {
|
else if (drawspec.special === 'logic-gate') {
|
||||||
this._draw_logic_gate(drawspec, tile, tic, blit);
|
this._draw_logic_gate(drawspec, tile, packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (drawspec.special === 'railroad') {
|
else if (drawspec.special === 'railroad') {
|
||||||
this._draw_railroad(drawspec, tile, tic, blit);
|
this._draw_railroad(drawspec, tile, packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1371,9 +1385,9 @@ export class Tileset {
|
|||||||
// TODO circuit block in motion doesn't inherit cell's power
|
// TODO circuit block in motion doesn't inherit cell's power
|
||||||
if (tile && tile.wire_directions) {
|
if (tile && tile.wire_directions) {
|
||||||
// Draw the base tile
|
// Draw the base tile
|
||||||
blit(drawspec.base[0], drawspec.base[1]);
|
packet.blit(drawspec.base[0], drawspec.base[1]);
|
||||||
|
|
||||||
this._draw_fourway_tile_power(tile, tile.wire_directions, blit);
|
this._draw_fourway_tile_power(tile, tile.wire_directions, packet);
|
||||||
|
|
||||||
// Then draw the wired tile on top of it all
|
// Then draw the wired tile on top of it all
|
||||||
if (tile.wire_directions === 0x0f && drawspec.wired_cross) {
|
if (tile.wire_directions === 0x0f && drawspec.wired_cross) {
|
||||||
@ -1392,7 +1406,7 @@ export class Tileset {
|
|||||||
coords = drawspec.base;
|
coords = drawspec.base;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
blit(drawspec.base[0], drawspec.base[1]);
|
packet.blit(drawspec.base[0], drawspec.base[1]);
|
||||||
coords = drawspec.wired;
|
coords = drawspec.wired;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1405,7 +1419,7 @@ export class Tileset {
|
|||||||
// Force floors animate their... cutout, I guess?
|
// Force floors animate their... cutout, I guess?
|
||||||
let [x, y] = drawspec.base;
|
let [x, y] = drawspec.base;
|
||||||
let duration = 3 * this.animation_slowdown;
|
let duration = 3 * this.animation_slowdown;
|
||||||
x += drawspec.animate_width * (tic % duration / duration);
|
x += drawspec.animate_width * (packet.tic % duration / duration);
|
||||||
// Round to tile width
|
// Round to tile width
|
||||||
x = Math.floor(x * this.size_x + 0.5) / this.size_x;
|
x = Math.floor(x * this.size_x + 0.5) / this.size_x;
|
||||||
coords = [x, y];
|
coords = [x, y];
|
||||||
@ -1414,7 +1428,7 @@ export class Tileset {
|
|||||||
// Same, but along the other axis
|
// Same, but along the other axis
|
||||||
let [x, y] = drawspec.base;
|
let [x, y] = drawspec.base;
|
||||||
let duration = 3 * this.animation_slowdown;
|
let duration = 3 * this.animation_slowdown;
|
||||||
y += drawspec.animate_height * (tic % duration / duration);
|
y += drawspec.animate_height * (packet.tic % duration / duration);
|
||||||
// Round to tile height
|
// Round to tile height
|
||||||
y = Math.floor(y * this.size_y + 0.5) / this.size_y;
|
y = Math.floor(y * this.size_y + 0.5) / this.size_y;
|
||||||
coords = [x, y];
|
coords = [x, y];
|
||||||
@ -1437,7 +1451,7 @@ export class Tileset {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._draw_standard(coords, tile, tic, blit);
|
this._draw_standard(coords, tile, packet);
|
||||||
|
|
||||||
// Wired tiles may also have tunnels, drawn on top of everything else
|
// Wired tiles may also have tunnels, drawn on top of everything else
|
||||||
if (drawspec.wired && tile && tile.wire_tunnel_directions) {
|
if (drawspec.wired && tile && tile.wire_tunnel_directions) {
|
||||||
@ -1446,19 +1460,19 @@ export class Tileset {
|
|||||||
let tunnel_length = 12/32;
|
let tunnel_length = 12/32;
|
||||||
let tunnel_offset = (1 - tunnel_width) / 2;
|
let tunnel_offset = (1 - tunnel_width) / 2;
|
||||||
if (tile.wire_tunnel_directions & DIRECTIONS['north'].bit) {
|
if (tile.wire_tunnel_directions & DIRECTIONS['north'].bit) {
|
||||||
blit(tunnel_coords[0], tunnel_coords[1],
|
packet.blit(tunnel_coords[0], tunnel_coords[1],
|
||||||
tunnel_offset, 0, tunnel_width, tunnel_length);
|
tunnel_offset, 0, tunnel_width, tunnel_length);
|
||||||
}
|
}
|
||||||
if (tile.wire_tunnel_directions & DIRECTIONS['south'].bit) {
|
if (tile.wire_tunnel_directions & DIRECTIONS['south'].bit) {
|
||||||
blit(tunnel_coords[0], tunnel_coords[1],
|
packet.blit(tunnel_coords[0], tunnel_coords[1],
|
||||||
tunnel_offset, 1 - tunnel_length, tunnel_width, tunnel_length);
|
tunnel_offset, 1 - tunnel_length, tunnel_width, tunnel_length);
|
||||||
}
|
}
|
||||||
if (tile.wire_tunnel_directions & DIRECTIONS['west'].bit) {
|
if (tile.wire_tunnel_directions & DIRECTIONS['west'].bit) {
|
||||||
blit(tunnel_coords[0], tunnel_coords[1],
|
packet.blit(tunnel_coords[0], tunnel_coords[1],
|
||||||
0, tunnel_offset, tunnel_length, tunnel_width);
|
0, tunnel_offset, tunnel_length, tunnel_width);
|
||||||
}
|
}
|
||||||
if (tile.wire_tunnel_directions & DIRECTIONS['east'].bit) {
|
if (tile.wire_tunnel_directions & DIRECTIONS['east'].bit) {
|
||||||
blit(tunnel_coords[0], tunnel_coords[1],
|
packet.blit(tunnel_coords[0], tunnel_coords[1],
|
||||||
1 - tunnel_length, tunnel_offset, tunnel_length, tunnel_width);
|
1 - tunnel_length, tunnel_offset, tunnel_length, tunnel_width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1480,7 +1494,7 @@ export class Tileset {
|
|||||||
if (tile.arrows.has('west')) {
|
if (tile.arrows.has('west')) {
|
||||||
x0 = 0;
|
x0 = 0;
|
||||||
}
|
}
|
||||||
blit(x, y, x0, y0, x1 - x0, y1 - y0);
|
packet.blit(x, y, x0, y0, x1 - x0, y1 - y0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user