You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tobspr_shapez.io/src/js/game/hud/parts/entity_debugger.js

163 lines
4.9 KiB

/* dev:start */
import { makeDiv, removeAllChildren } from "../../../core/utils";
import { Vector } from "../../../core/vector";
import { Entity } from "../../entity";
import { BaseHUDPart } from "../base_hud_part";
import { DynamicDomAttach } from "../dynamic_dom_attach";
/**
* Allows to inspect entities by pressing F8 while hovering them
*/
export class HUDEntityDebugger extends BaseHUDPart {
createElements(parent) {
this.element = makeDiv(
parent,
"ingame_HUD_EntityDebugger",
[],
`
<label>Entity Debugger</label>
<span class="hint">Use F8 to toggle this overlay</span>
<div class="propertyTable">
<div class="entityComponents"></div>
</div>
`
);
this.componentsElem = this.element.querySelector(".entityComponents");
}
initialize() {
this.root.gameState.inputReciever.keydown.add(key => {
if (key.keyCode === 119) {
// F8
this.pickEntity();
}
});
/**
* The currently selected entity
* @type {Entity}
*/
this.selectedEntity = null;
this.lastUpdate = 0;
this.domAttach = new DynamicDomAttach(this.root, this.element);
}
pickEntity() {
const mousePos = this.root.app.mousePosition;
if (!mousePos) {
return;
}
const worldPos = this.root.camera.screenToWorld(mousePos);
const worldTile = worldPos.toTileSpace();
const entity = this.root.map.getTileContent(worldTile, this.root.currentLayer);
this.selectedEntity = entity;
if (entity) {
this.rerenderFull(entity);
}
}
/**
*
* @param {string} name
* @param {any} val
* @param {number} indent
* @param {Array} recursion
*/
propertyToHTML(name, val, indent = 0, recursion = []) {
if (indent > 20) {
return;
}
if (val !== null && typeof val === "object") {
// Array is displayed like object, with indexes
recursion.push(val);
// Get type class name (like Array, Object, Vector...)
let typeName = `(${val.constructor ? val.constructor.name : "unknown"})`;
if (Array.isArray(val)) {
typeName = `(Array[${val.length}])`;
}
if (val instanceof Vector) {
typeName = `(Vector[${val.x}, ${val.y}])`;
}
const colorStyle = `color: hsl(${30 * indent}, 100%, 80%)`;
let html = `<details class="object" style="${colorStyle}">
<summary>${name} ${typeName}</summary>
<div>`;
for (const property in val) {
Mod Support - 1.5.0 Update (#1361) * initial modloader draft * modloader features * Refactor mods to use signals * Add support for modifying and registering new transltions * Minor adjustments * Support for string building ids for mods * Initial support for adding new buildings * Refactor how mods are loaded to resolve circular dependencies and prepare for future mod loading * Lazy Load mods to make sure all dependencies are loaded * Expose all exported members automatically to mods * Fix duplicate exports * Allow loading mods from standalone * update changelog * Fix mods folder incorrect path * Fix modloading in standalone * Fix sprites not getting replaced, update demo mod * Load dev mod via raw loader * Improve mod developing so mods are directly ready to be deployed, load mods from local file server * Proper mods ui * Allow mods to register game systems and draw stuff * Change mods path * Fix sprites not loading * Minor adjustments, closes #1333 * Add support for loading atlases via mods * Add support for loading mods from external sources in DEV * Add confirmation when loading mods * Fix circular dependency * Minor Keybindings refactor, add support for keybindings to mods, add support for dialogs to mods * Add some mod signals * refactor game loading states * Make shapez exports global * Start to make mods safer * Refactor file system electron event handling * Properly isolate electron renderer process * Update to latest electron * Show errors when loading mods * Update confirm dialgo * Minor restructure, start to add mod examples * Allow adding custom themesw * Add more examples and allow defining custom item processor operations * Add interface to register new buildings * Fixed typescript type errors (#1335) * Refactor building registry, make it easier for mods to add new buildings * Allow overriding existing methods * Add more examples and more features * More mod examples * Make mod loading simpler * Add example how to add custom drawings * Remove unused code * Minor modloader adjustments * Support for rotation variants in mods (was broken previously) * Allow mods to replace builtin sub shapes * Add helper methods to extend classes * Fix menu bar on mac os * Remember window state * Add support for paste signals * Add example how to add custom components and systems * Support for mod settings * Add example for adding a new item type * Update class extensions * Minor adjustments * Fix typo * Add notification blocks mod example * Add small tutorial * Update readme * Add better instructions * Update JSDoc for Replacing Methods (#1336) * upgraded types for overriding methods * updated comments Co-authored-by: Edward Badel <you@example.com> * Direction lock now indicates when there is a building inbetween * Fix mod examples * Fix linter error * Game state register (#1341) * Added a gamestate register helper Added a gamestate register helper * Update mod_interface.js * export build options * Fix runBeforeMethod and runAfterMethod * Minor game system code cleanup * Belt path drawing optimization * Fix belt path optimization * Belt drawing improvements, again * Do not render belts in statics disabled view * Allow external URL to load more than one mod (#1337) * Allow external URL to load more than one mod Instead of loading the text returned from the remote server, load a JSON object with a `mods` field, containing strings of all the mods. This lets us work on more than one mod at a time or without separate repos. This will break tooling such as `create-shapezio-mod` though. * Update modloader.js * Prettier fixes * Added link to create-shapezio-mod npm page (#1339) Added link to create-shapezio-mod npm page: https://www.npmjs.com/package/create-shapezio-mod * allow command line switch to load more than one mod (#1342) * Fixed class handle type (#1345) * Fixed class handle type * Fixed import game state * Minor adjustments * Refactor item acceptor to allow only single direction slots * Allow specifying minimumGameVersion * Add sandbox example * Replaced concatenated strings with template literals (#1347) * Mod improvements * Make wired pins component optional on the storage * Fix mod examples * Bind `this` for method overriding JSDoc (#1352) * fix entity debugger reaching HTML elements (#1353) * Store mods in savegame and show warning when it differs * Closes #1357 * Fix All Shapez Exports Being Const (#1358) * Allowed setting of variables inside webpack modules * remove console log * Fix stringification of things inside of eval Co-authored-by: Edward Badel <you@example.com> * Fix building placer intersection warning * Add example for storing data in the savegame * Fix double painter bug (#1349) * Add example on how to extend builtin buildings * update readme * Disable steam achievements when playing with mods * Update translations Co-authored-by: Thomas (DJ1TJOO) <44841260+DJ1TJOO@users.noreply.github.com> Co-authored-by: Bagel03 <70449196+Bagel03@users.noreply.github.com> Co-authored-by: Edward Badel <you@example.com> Co-authored-by: Emerald Block <69981203+EmeraldBlock@users.noreply.github.com> Co-authored-by: saile515 <63782477+saile515@users.noreply.github.com> Co-authored-by: Sense101 <67970865+Sense101@users.noreply.github.com>
2 years ago
let hiddenValue = null;
if (val[property] == this.root) {
hiddenValue = "<root>";
} else if (val[property] instanceof Node) {
hiddenValue = `<${val[property].constructor.name}>`;
} else if (recursion.includes(val[property])) {
// Avoid recursion by not "expanding" object more than once
hiddenValue = "<recursion>";
}
html += this.propertyToHTML(
property,
hiddenValue ? hiddenValue : val[property],
indent + 1,
[...recursion] // still expand same value in other "branches"
);
}
html += "</div></details>";
return html;
}
const displayValue = (val + "")
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;");
return `<label>${name}</label> <span>${displayValue}</span>`;
}
/**
* Rerenders the whole container
* @param {Entity} entity
*/
rerenderFull(entity) {
removeAllChildren(this.componentsElem);
let html = "";
const property = (strings, val) => `<label>${strings[0]}</label> <span>${val}</span>`;
html += property`registered ${!!entity.registered}`;
html += property`uid ${entity.uid}`;
html += property`destroyed ${!!entity.destroyed}`;
for (const componentId in entity.components) {
const data = entity.components[componentId];
html += "<details class='object'>";
html += "<summary>" + componentId + "</summary><div>";
for (const property in data) {
// Put entity into recursion list, so it won't get "expanded"
html += this.propertyToHTML(property, data[property], 0, [entity]);
}
html += "</div></details>";
}
this.componentsElem.innerHTML = html;
}
update() {
this.domAttach.update(!!this.selectedEntity);
}
}
/* dev:end */