Load custom trap/cloner connections from CC1 .DAT levels
This commit is contained in:
parent
7d9426c8e7
commit
1cc631c27e
@ -209,14 +209,31 @@ function parse_level(buf) {
|
|||||||
level.title = util.string_from_buffer_ascii(buf.slice(p, p + field_length - 1));
|
level.title = util.string_from_buffer_ascii(buf.slice(p, p + field_length - 1));
|
||||||
}
|
}
|
||||||
else if (field_type === 0x04) {
|
else if (field_type === 0x04) {
|
||||||
// Trap linkages
|
// Trap linkages (MSCC only, not in Lynx or CC2)
|
||||||
// TODO read this
|
let field_view = new DataView(buf.slice(p, p + field_length));
|
||||||
// TODO under lynx rules these aren't even used, and they cause bugs in mscc1!
|
let q = 0;
|
||||||
|
while (q < field_length) {
|
||||||
|
let button_x = field_view.getUint16(q + 0, true);
|
||||||
|
let button_y = field_view.getUint16(q + 2, true);
|
||||||
|
let trap_x = field_view.getUint16(q + 4, true);
|
||||||
|
let trap_y = field_view.getUint16(q + 6, true);
|
||||||
|
// Fifth u16 is always zero, possibly live game state
|
||||||
|
q += 10;
|
||||||
|
level.custom_trap_wiring[button_x + button_y * level.size_x] = trap_x + trap_y * level.size_x;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (field_type === 0x05) {
|
else if (field_type === 0x05) {
|
||||||
// Trap linkages
|
// Cloner linkages (MSCC only, not in Lynx or CC2)
|
||||||
// TODO read this
|
let field_view = new DataView(buf.slice(p, p + field_length));
|
||||||
// TODO under lynx rules these aren't even used, and they cause bugs in mscc1!
|
let q = 0;
|
||||||
|
while (q < field_length) {
|
||||||
|
let button_x = field_view.getUint16(q + 0, true);
|
||||||
|
let button_y = field_view.getUint16(q + 2, true);
|
||||||
|
let cloner_x = field_view.getUint16(q + 4, true);
|
||||||
|
let cloner_y = field_view.getUint16(q + 6, true);
|
||||||
|
q += 8;
|
||||||
|
level.custom_cloner_wiring[button_x + button_y * level.size_x] = cloner_x + cloner_y * level.size_x;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (field_type === 0x06) {
|
else if (field_type === 0x06) {
|
||||||
// Password, with trailing NUL, and otherwise XORed with 0x99 (?!)
|
// Password, with trailing NUL, and otherwise XORed with 0x99 (?!)
|
||||||
|
|||||||
@ -22,6 +22,11 @@ export class StoredLevel {
|
|||||||
|
|
||||||
this.player_start_x = 0;
|
this.player_start_x = 0;
|
||||||
this.player_start_y = 0;
|
this.player_start_y = 0;
|
||||||
|
|
||||||
|
// Maps of button positions to trap/cloner positions, as scalar indexes
|
||||||
|
// in the linear cell list
|
||||||
|
this.custom_trap_wiring = {};
|
||||||
|
this.custom_cloner_wiring = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
check() {
|
check() {
|
||||||
|
|||||||
34
js/main.js
34
js/main.js
@ -289,15 +289,44 @@ class Level {
|
|||||||
|
|
||||||
// Connect buttons and teleporters
|
// Connect buttons and teleporters
|
||||||
let num_cells = this.width * this.height;
|
let num_cells = this.width * this.height;
|
||||||
|
console.log(this.stored_level.custom_trap_wiring);
|
||||||
|
console.log(this.stored_level.custom_cloner_wiring);
|
||||||
for (let connectable of connectables) {
|
for (let connectable of connectables) {
|
||||||
let x = connectable.x;
|
let x = connectable.x;
|
||||||
let y = connectable.y;
|
let y = connectable.y;
|
||||||
let goal = connectable.type.connects_to;
|
let goal = connectable.type.connects_to;
|
||||||
|
let found = false;
|
||||||
|
|
||||||
|
// Check for custom wiring, for MSCC .DAT levels
|
||||||
|
let n = x + y * this.width;
|
||||||
|
console.log(x, y, n);
|
||||||
|
let target_cell_n = null;
|
||||||
|
if (goal === 'trap') {
|
||||||
|
target_cell_n = this.stored_level.custom_trap_wiring[n] ?? null;
|
||||||
|
}
|
||||||
|
else if (goal === 'cloner') {
|
||||||
|
target_cell_n = this.stored_level.custom_cloner_wiring[n] ?? null;
|
||||||
|
}
|
||||||
|
if (target_cell_n) {
|
||||||
|
// TODO this N could be outside the map bounds
|
||||||
|
let target_cell_x = target_cell_n % this.width;
|
||||||
|
let target_cell_y = Math.floor(target_cell_n / this.width);
|
||||||
|
for (let tile of this.cells[target_cell_y][target_cell_x]) {
|
||||||
|
if (tile.type.name === goal) {
|
||||||
|
connectable.connection = tile;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, look in reading order
|
||||||
let direction = 1;
|
let direction = 1;
|
||||||
if (connectable.type.connect_order == 'backward') {
|
if (connectable.type.connect_order === 'backward') {
|
||||||
direction = -1;
|
direction = -1;
|
||||||
}
|
}
|
||||||
let found = false;
|
|
||||||
for (let i = 0; i < num_cells - 1; i++) {
|
for (let i = 0; i < num_cells - 1; i++) {
|
||||||
x += direction;
|
x += direction;
|
||||||
if (x >= this.width) {
|
if (x >= this.width) {
|
||||||
@ -314,6 +343,7 @@ class Level {
|
|||||||
// TODO should be weak, but you can't destroy cloners so in practice not a concern
|
// TODO should be weak, but you can't destroy cloners so in practice not a concern
|
||||||
connectable.connection = tile;
|
connectable.connection = tile;
|
||||||
found = true;
|
found = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (found)
|
if (found)
|
||||||
|
|||||||
@ -364,7 +364,6 @@ const TILE_TYPES = {
|
|||||||
connect_order: 'forward',
|
connect_order: 'forward',
|
||||||
on_arrive(me, level, other) {
|
on_arrive(me, level, other) {
|
||||||
if (me.connection && ! me.connection.doomed) {
|
if (me.connection && ! me.connection.doomed) {
|
||||||
// TODO do gray buttons affect traps? if so this should use activate()
|
|
||||||
let trap = me.connection;
|
let trap = me.connection;
|
||||||
trap.open = true;
|
trap.open = true;
|
||||||
for (let tile of level.cells[trap.y][trap.x]) {
|
for (let tile of level.cells[trap.y][trap.x]) {
|
||||||
@ -376,7 +375,6 @@ const TILE_TYPES = {
|
|||||||
},
|
},
|
||||||
on_depart(me, level, other) {
|
on_depart(me, level, other) {
|
||||||
if (me.connection && ! me.connection.doomed) {
|
if (me.connection && ! me.connection.doomed) {
|
||||||
// TODO do gray buttons affect traps? if so this should use activate()
|
|
||||||
let trap = me.connection;
|
let trap = me.connection;
|
||||||
trap.open = false;
|
trap.open = false;
|
||||||
for (let tile of level.cells[trap.y][trap.x]) {
|
for (let tile of level.cells[trap.y][trap.x]) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user