Implement "hide logic", and actually save options (fixes #52)
This commit is contained in:
parent
028fc016b0
commit
dd10236b22
@ -113,6 +113,7 @@ export class StoredLevel extends LevelInterface {
|
||||
// 1 - 4 patterns (default; PRNG + rotating through 0-3)
|
||||
// 2 - extra random (like deterministic, but initial seed is "actually" random)
|
||||
this.blob_behavior = 1;
|
||||
this.hide_logic = false;
|
||||
|
||||
// Lazy-loading that allows for checking existence (see methods below)
|
||||
// TODO this needs a better interface, these get accessed too much atm
|
||||
|
||||
@ -1130,11 +1130,11 @@ export function parse_level(buf, number = 1) {
|
||||
|
||||
if (view.byteLength <= 22)
|
||||
continue;
|
||||
//options.hide_logic = view.getUint8(22, true);
|
||||
level.hide_logic = !! view.getUint8(22, true);
|
||||
|
||||
if (view.byteLength <= 23)
|
||||
continue;
|
||||
level.use_cc1_boots = view.getUint8(23, true);
|
||||
level.use_cc1_boots = !! view.getUint8(23, true);
|
||||
|
||||
if (view.byteLength <= 24)
|
||||
continue;
|
||||
@ -1482,17 +1482,32 @@ export function synthesize_level(stored_level) {
|
||||
}
|
||||
|
||||
// Options block
|
||||
let options = new Uint8Array(3);
|
||||
let options = new Uint8Array(25); // max possible size
|
||||
let options_length = 0;
|
||||
new DataView(options.buffer).setUint16(0, stored_level.time_limit, true);
|
||||
if (stored_level.viewport_size === 10) {
|
||||
options[2] = 0;
|
||||
}
|
||||
else if (stored_level.viewport_size === 9) {
|
||||
options[2] = 1;
|
||||
options_length = 3;
|
||||
}
|
||||
if (stored_level.hide_logic) {
|
||||
options[22] = 1;
|
||||
options_length = 23;
|
||||
}
|
||||
if (stored_level.use_cc1_boots) {
|
||||
options[23] = 1;
|
||||
options_length = 24;
|
||||
}
|
||||
if (stored_level.blob_behavior !== 0) {
|
||||
options[24] = stored_level.blob_behavior;
|
||||
options_length = 25;
|
||||
}
|
||||
// TODO split
|
||||
// TODO for size purposes, omit the block entirely if all options are defaults?
|
||||
c2m.add_section('OPTN', options);
|
||||
if (options_length > 0) {
|
||||
c2m.add_section('OPTN', options.slice(0, options_length));
|
||||
}
|
||||
|
||||
// Store camera regions
|
||||
// TODO LL feature, should be distinguished somehow
|
||||
|
||||
@ -141,17 +141,24 @@ class EditorLevelMetaOverlay extends DialogOverlay {
|
||||
mk('br'),
|
||||
mk('label',
|
||||
mk('input', {name: 'blob_behavior', type: 'radio', value: '1'}),
|
||||
" 4 patterns (default; PRNG + rotating offset)"),
|
||||
" 4 patterns (CC2 default; PRNG + rotating offset)"),
|
||||
mk('br'),
|
||||
mk('label',
|
||||
mk('input', {name: 'blob_behavior', type: 'radio', value: '2'}),
|
||||
" Extra random (initial seed is truly random)"),
|
||||
" Extra random (LL default; initial seed is truly random)"),
|
||||
),
|
||||
mk('dt', "Options"),
|
||||
mk('dd', mk('label',
|
||||
mk('input', {name: 'hide_logic', type: 'checkbox'}),
|
||||
" Hide wires and logic gates (warning: CC2 also hides pink/black buttons!)")),
|
||||
mk('dd', mk('label',
|
||||
mk('input', {name: 'use_cc1_boots', type: 'checkbox'}),
|
||||
" Use CC1-style inventory (can only pick up the four classic boots; can't drop or cycle)")),
|
||||
);
|
||||
this.root.elements['viewport'].value = stored_level.viewport_size;
|
||||
// FIXME this isn't actually saved lol but also it's 24 bytes into the damn options. also
|
||||
// it should default to 2, the good one
|
||||
this.root.elements['blob_behavior'].value = stored_level.blob_behavior;
|
||||
this.root.elements['hide_logic'].checked = stored_level.hide_logic;
|
||||
this.root.elements['use_cc1_boots'].checked = stored_level.use_cc1_boots;
|
||||
// TODO:
|
||||
// - chips?
|
||||
// - password???
|
||||
@ -183,6 +190,8 @@ class EditorLevelMetaOverlay extends DialogOverlay {
|
||||
}
|
||||
|
||||
stored_level.blob_behavior = parseInt(els.blob_behavior.value, 10);
|
||||
stored_level.hide_logic = els.hide_logic.checked;
|
||||
stored_level.use_cc1_boots = els.use_cc1_boots.checked;
|
||||
stored_level.viewport_size = parseInt(els.viewport.value, 10);
|
||||
this.conductor.player.update_viewport_size();
|
||||
|
||||
@ -3212,6 +3221,7 @@ export class Editor extends PrimaryView {
|
||||
stored_level.size_x = size_x;
|
||||
stored_level.size_y = size_y;
|
||||
stored_level.viewport_size = 10;
|
||||
stored_level.blob_behavior = 2; // extra random
|
||||
for (let i = 0; i < size_x * size_y; i++) {
|
||||
stored_level.linear_cells.push(this.make_blank_cell(...stored_level.scalar_to_coords(i)));
|
||||
}
|
||||
|
||||
@ -1334,6 +1334,8 @@ class Player extends PrimaryView {
|
||||
// (This happens here because we could technically still do 20tps if we wanted, and the
|
||||
// renderer doesn't actually have any way to know that)
|
||||
this.renderer.update_rate = this.level.update_rate;
|
||||
// Likewise, we don't want this automatically read from the level, but we do respect it here
|
||||
this.renderer.hide_logic = this.level.stored_level.hide_logic;
|
||||
|
||||
this.update_ui();
|
||||
// Force a redraw, which won't happen on its own since the game isn't running
|
||||
|
||||
@ -5,7 +5,7 @@ import TILE_TYPES from './tiletypes.js';
|
||||
|
||||
class CanvasRendererDrawPacket extends DrawPacket {
|
||||
constructor(renderer, ctx, perception, clock, update_progress, update_rate) {
|
||||
super(perception, clock, update_progress, update_rate);
|
||||
super(perception, renderer.hide_logic, clock, update_progress, update_rate);
|
||||
this.renderer = renderer;
|
||||
this.ctx = ctx;
|
||||
// Canvas position of the cell being drawn
|
||||
@ -62,6 +62,7 @@ export class CanvasRenderer {
|
||||
this.show_actor_order = false;
|
||||
this.use_rewind_effect = false;
|
||||
this.perception = 'normal'; // normal, xray, editor, palette
|
||||
this.hide_logic = false;
|
||||
this.update_rate = 3;
|
||||
this.use_cc2_anim_speed = false;
|
||||
this.active_player = null;
|
||||
|
||||
@ -1994,8 +1994,9 @@ export const TILESET_LAYOUTS = {
|
||||
|
||||
// Bundle of arguments for drawing a tile, containing some standard state about the game
|
||||
export class DrawPacket {
|
||||
constructor(perception = 'normal', clock = 0, update_progress = 0, update_rate = 3) {
|
||||
constructor(perception = 'normal', hide_logic = false, clock = 0, update_progress = 0, update_rate = 3) {
|
||||
this.perception = perception;
|
||||
this.hide_logic = hide_logic && perception === 'normal';
|
||||
this.use_cc2_anim_speed = false;
|
||||
this.clock = clock;
|
||||
this.update_progress = update_progress;
|
||||
@ -2177,7 +2178,7 @@ export class Tileset {
|
||||
let wire_radius = this.layout['#wire-width'] / 2;
|
||||
// TODO circuit block with a lightning bolt is always powered
|
||||
// TODO circuit block in motion doesn't inherit cell's power
|
||||
if (tile && tile.wire_directions) {
|
||||
if (tile && tile.wire_directions && ! packet.hide_logic) {
|
||||
// Draw the base tile
|
||||
packet.blit(drawspec.base[0], drawspec.base[1]);
|
||||
|
||||
@ -2210,9 +2211,8 @@ export class Tileset {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Wired tiles may also have tunnels, drawn on top of everything else
|
||||
if (tile && tile.wire_tunnel_directions) {
|
||||
if (tile && tile.wire_tunnel_directions && ! packet.hide_logic) {
|
||||
let tunnel_coords = this.layout['#wire-tunnel'];
|
||||
let tunnel_width = 6/32;
|
||||
let tunnel_length = 12/32;
|
||||
@ -2602,8 +2602,13 @@ export class Tileset {
|
||||
}
|
||||
}
|
||||
else if (drawspec.__special__ === 'logic-gate') {
|
||||
if (packet.hide_logic) {
|
||||
this.draw_type('floor', tile, packet);
|
||||
}
|
||||
else {
|
||||
this._draw_logic_gate(drawspec, name, tile, packet);
|
||||
}
|
||||
}
|
||||
else if (drawspec.__special__ === 'railroad') {
|
||||
this._draw_railroad(drawspec, name, tile, packet);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user