|
|
@ -13,6 +13,9 @@ const signal_elem = document.getElementById("signal");
|
|
|
|
const state_elem = document.getElementById("state");
|
|
|
|
const state_elem = document.getElementById("state");
|
|
|
|
const tile_elem = document.getElementById("tile");
|
|
|
|
const tile_elem = document.getElementById("tile");
|
|
|
|
const tile_name_elem = document.getElementById("tile-name");
|
|
|
|
const tile_name_elem = document.getElementById("tile-name");
|
|
|
|
|
|
|
|
const properties_elem = document.getElementById("tile-properties");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let templates = new Map();
|
|
|
|
|
|
|
|
|
|
|
|
export function update_selected(x, y) {
|
|
|
|
export function update_selected(x, y) {
|
|
|
|
coordinates.innerText = `(${x}, ${y})`;
|
|
|
|
coordinates.innerText = `(${x}, ${y})`;
|
|
|
@ -54,6 +57,38 @@ export function update_selected(x, y) {
|
|
|
|
|
|
|
|
|
|
|
|
let name = Object.keys(tile)[0];
|
|
|
|
let name = Object.keys(tile)[0];
|
|
|
|
tile_name_elem.innerText = name;
|
|
|
|
tile_name_elem.innerText = name;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Set properties
|
|
|
|
|
|
|
|
// TODO: only change the properties when necessary
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (properties_elem.children.length > 0) {
|
|
|
|
|
|
|
|
properties_elem.removeChild(properties_elem.firstChild);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let schema = full_tile.schema();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (let [label, type, value] of schema_iter(schema, tile[name])) {
|
|
|
|
|
|
|
|
let input = create_input(type, value, on_change);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!input) continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let elem = document.createElement("li");
|
|
|
|
|
|
|
|
let label_elem = document.createElement("b");
|
|
|
|
|
|
|
|
label_elem.innerText = `${label}: `;
|
|
|
|
|
|
|
|
elem.appendChild(label_elem);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
elem.appendChild(input);
|
|
|
|
|
|
|
|
properties_elem.appendChild(elem);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function on_change(new_value) {
|
|
|
|
|
|
|
|
// Traverse `tile` and change the corresponding schema element
|
|
|
|
|
|
|
|
tile[name] = schema_recurse(schema, tile[name], label, new_value);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let full_tile = world.get(x, y);
|
|
|
|
|
|
|
|
full_tile.tile = tile;
|
|
|
|
|
|
|
|
world.set(x, y, full_tile);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
tile_elem.classList.remove("has-tile");
|
|
|
|
tile_elem.classList.remove("has-tile");
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -72,4 +107,159 @@ export function init() {
|
|
|
|
// option.value = name;
|
|
|
|
// option.value = name;
|
|
|
|
// tile_name_elem.appendChild(option);
|
|
|
|
// tile_name_elem.appendChild(option);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
document.querySelectorAll(".property-template").forEach((template) => {
|
|
|
|
|
|
|
|
templates.set(template.attributes?.name?.value ?? template.id, template);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function* schema_iter(schema, tile) {
|
|
|
|
|
|
|
|
if (Array.isArray(schema)) {
|
|
|
|
|
|
|
|
for (let n = 0; n < schema.length; n++) {
|
|
|
|
|
|
|
|
yield* schema_iter(schema[n], tile[n]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (typeof schema === "object") {
|
|
|
|
|
|
|
|
for (let name in schema) {
|
|
|
|
|
|
|
|
yield* schema_iter(schema[name], tile[name]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (typeof schema === "string") {
|
|
|
|
|
|
|
|
let res = schema.split(":");
|
|
|
|
|
|
|
|
res.push(tile);
|
|
|
|
|
|
|
|
yield res;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function schema_recurse(schema, tile, label, value) {
|
|
|
|
|
|
|
|
if (Array.isArray(schema)) {
|
|
|
|
|
|
|
|
for (let n = 0; n < schema.length; n++) {
|
|
|
|
|
|
|
|
tile[n] = schema_recurse(schema[n], tile[n], label, value);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return tile;
|
|
|
|
|
|
|
|
} else if (typeof schema === "object") {
|
|
|
|
|
|
|
|
for (let name in schema) {
|
|
|
|
|
|
|
|
tile[name] = schema_recurse(schema[name], tile[name], label, value);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return tile;
|
|
|
|
|
|
|
|
} else if (typeof schema === "string") {
|
|
|
|
|
|
|
|
if (schema.split(":")[0] === label) {
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
return tile;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function create_input(type, value, change_cb) {
|
|
|
|
|
|
|
|
let options = type.split("|");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (let option of options) {
|
|
|
|
|
|
|
|
if (option === "Value") {
|
|
|
|
|
|
|
|
let res = templates.get("Value").content.cloneNode(true).querySelector("*");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let select_elem = res.querySelector("select");
|
|
|
|
|
|
|
|
let type = Object.keys(value)[0];
|
|
|
|
|
|
|
|
set_type(type);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function set_type(new_type) {
|
|
|
|
|
|
|
|
let map = new Map([["String", "string"], ["Number", "number"]]);
|
|
|
|
|
|
|
|
for (let [ty, cn] of map) {
|
|
|
|
|
|
|
|
if (ty === new_type) {
|
|
|
|
|
|
|
|
res.classList.add(cn);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
res.classList.remove(cn);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
type = new_type;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
select_elem.addEventListener("change", () => {
|
|
|
|
|
|
|
|
set_type(select_elem.value);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (type === "Number") {
|
|
|
|
|
|
|
|
value = {"Number": 0.0};
|
|
|
|
|
|
|
|
number_input.value = 0;
|
|
|
|
|
|
|
|
} else if (type === "String") {
|
|
|
|
|
|
|
|
value = {"String": ""};
|
|
|
|
|
|
|
|
string_input.value = "";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
change_cb(value);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let number_input = res.querySelector(".value-number input");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (type === "Number") {
|
|
|
|
|
|
|
|
number_input.value = value["Number"];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
number_input.addEventListener("change", (evt) => {
|
|
|
|
|
|
|
|
if (type === "Number") {
|
|
|
|
|
|
|
|
value["Number"] = +number_input.value;
|
|
|
|
|
|
|
|
change_cb(value);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let string_input = res.querySelector(".value-string input");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (type === "String") {
|
|
|
|
|
|
|
|
string_input.value = value["String"];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string_input.addEventListener("change", (evt) => {
|
|
|
|
|
|
|
|
if (type === "String") {
|
|
|
|
|
|
|
|
value["String"] = string_input.value;
|
|
|
|
|
|
|
|
change_cb(value);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
|
|
|
} else if (option === "Uint" || option === "Int") {
|
|
|
|
|
|
|
|
let res = templates.get(option).content.cloneNode(true).querySelector("*");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (value !== undefined) {
|
|
|
|
|
|
|
|
res.value = value;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
res.addEventListener("change", () => {
|
|
|
|
|
|
|
|
change_cb(+res.value);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
|
|
|
} else if (option === "Signal") {
|
|
|
|
|
|
|
|
let res = templates.get(option).content.cloneNode(true).querySelector("*");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let stack_elem = res.querySelector(".stack");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (let elem of value.stack) {
|
|
|
|
|
|
|
|
let li = document.createElement("li");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (elem["Number"]) {
|
|
|
|
|
|
|
|
li.innerText = elem["Number"];
|
|
|
|
|
|
|
|
} else if (elem["String"]) {
|
|
|
|
|
|
|
|
li.innerText = `"${elem["String"]}"`;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stack_elem.appendChild(li);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let direction_elem = res.querySelector(".direction");
|
|
|
|
|
|
|
|
direction_elem.value = value.direction;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (templates.has(option)) {
|
|
|
|
|
|
|
|
let res = templates.get(option).content.cloneNode(true).querySelector("*");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (value !== undefined) {
|
|
|
|
|
|
|
|
res.value = value;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
res.addEventListener("change", () => {
|
|
|
|
|
|
|
|
change_cb(res.value);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|