diff --git a/plugins.json b/plugins.json index ba3514e7..3d47923a 100644 --- a/plugins.json +++ b/plugins.json @@ -1394,6 +1394,16 @@ "has_changelog": true, "repository": "https://github.com/PasteDev/blockbench-plugins/tree/master/plugins/hytale_avatar_loader" }, + "hytale_hitbox_helper": { + "title": "Hytale Hitbox Helper", + "author": "Marck.A.A", + "version": "1.0.0", + "description": "Dedicated tool to create Hytale hitboxes and JSON export.", + "icon": "icon.png", + "variant": "both", + "min_version": "4.8.0", + "tags": ["Hytale"] + }, "baked_ambient_occlusion": { "title": "Mr Salmon's Baked Ambient Occlusion", "author": "Kai Salmon", diff --git a/plugins/hytale_hitbox_helper/about.md b/plugins/hytale_hitbox_helper/about.md new file mode 100644 index 00000000..9082fdcc --- /dev/null +++ b/plugins/hytale_hitbox_helper/about.md @@ -0,0 +1,18 @@ +**Hytale Hitbox Helper** is a dedicated plugin for Blockbench designed to streamline the creation and export of collision hitboxes for Hytale. + +## Features + +* **Dedicated Format:** Adds a new "Hytale Hitbox" project type. +* **Optimized Workspace:** * Automatic **Wireframe** view mode on activation. +* **Quick Add:** One-click button to add a standard 32x32x32 hitbox. +* **Smart Export:** * Exports strictly to Hytale's `.json` format. + * Only exports elements named "hitbox" (case insensitive). + * Automatic coordinate conversion (32 BB units = 1.0 Hytale unit). + +## How to Use + +1. Go to **File > New** and select **Hytale Hitbox**. +2. Use the **Add Hitbox** button in the "Add Element" menu (sidebar). +3. Resize and position your hitboxes as needed. + * *Note: Ensure the elements are named "hitbox" in the outliner.* +4. Go to **File > Export > Export Hytale Hitbox (.json)** diff --git a/plugins/hytale_hitbox_helper/hytale_hitbox_helper.js b/plugins/hytale_hitbox_helper/hytale_hitbox_helper.js new file mode 100644 index 00000000..7aac66e9 --- /dev/null +++ b/plugins/hytale_hitbox_helper/hytale_hitbox_helper.js @@ -0,0 +1,137 @@ +(function() { + let export_action; + let add_hitbox_action; + + const HITBOX_FORMAT_ID = 'hytale_hitbox'; + + BBPlugin.register('hytale_hitbox_helper', { + title: 'Hytale Hitbox Helper', + author: 'Marck.A.A', + icon: 'icon.png', + description: 'Tool to create easy Hytale hitboxes exportable to JSON.', + min_version: '4.8.0', + version: '1.0.0', + variant: 'both', + onload() { + const format = new ModelFormat(HITBOX_FORMAT_ID, { + name: 'Hytale Hitbox', + description: 'A simple format for creating Hytale hitboxes, exportable to JSON.', + icon: 'icon-format_hytale', + category: 'hytale', + target: 'Hytale', + block_size: 32, + centered_grid: true, + box_uv: false, + optional_box_uv: false, + single_texture: false, + rotate_cubes: false, + + onActivation() { + document.body.classList.add('hytale_hitbox_mode'); + const viewMode = BarItems['view_mode']; + if (viewMode) { + viewMode.value = 'wireframe'; + viewMode.onChange(); + } + Blockbench.showQuickMessage("Hytale Hitbox Mode Active"); + }, + onDeactivation() { + BarItems['view_mode'].value = 'textured'; + BarItems['view_mode'].onChange(); + document.body.classList.remove('hytale_hitbox_mode'); + } + }); + + Blockbench.addCSS(` + body.hytale_hitbox_mode #panel_textures, + body.hytale_hitbox_mode #panel_uv { + display: none !important; + } + `); + + + add_hitbox_action = new Action('add_hytale_hitbox', { + name: 'Add Hitbox', + icon: 'fa-cube', + category: 'edit', + condition: () => Format.id === HITBOX_FORMAT_ID, + click: function() { + const mesh = new Cube({ + name: 'hitbox', + color: 2, + from: [-16, 0, -16], + to: [16, 32, 16], + }).init(); + + mesh.mesh.material.transparent = true; + mesh.mesh.material.opacity = 0.5; + + Undo.initEdit({elements: [mesh], outliner: true}); + Undo.finishEdit('Add Hytale Hitbox'); + } + }); + + BarItems.add_element.side_menu.addAction(add_hitbox_action); + + export_action = new Action('export_hytale_hitbox', { + name: 'Export Hytale Hitbox (.json)', + icon: 'fa-file-export', + category: 'file', + condition: () => Format.id === HITBOX_FORMAT_ID, + click: function() { + exportHytaleHitbox(); + } + }); + + MenuBar.menus.file.addAction(export_action, 'export'); + }, + onunload() { + export_action.delete(); + add_hitbox_action.delete(); + } + }); + + function exportHytaleHitbox() { + const hitboxes = Cube.all.filter(cube => + cube.name.toLowerCase() === 'hitbox' && cube.export + ); + + if (hitboxes.length === 0) { + Blockbench.showMessageBox({ + title: 'No Hitboxes found', + message: 'No elements called "hitbox" were found to export.' + }); + return; + } + + let json_output = { + "Boxes": [] + }; + + hitboxes.forEach(cube => { + json_output.Boxes.push({ + "Min": { + "X": (cube.from[0] + 16) / 32, + "Y": cube.from[1] / 32, + "Z": (cube.from[2] + 16) / 32 + }, + "Max": { + "X": (cube.to[0] + 16) / 32, + "Y": cube.to[1] / 32, + "Z": (cube.to[2] + 16) / 32 + } + }); + }); + + const content = JSON.stringify(json_output, null, 2); + + Blockbench.export({ + type: 'JSON Model', + extensions: ['json'], + name: Project.name || 'hitbox', + content: content, + resource_id: 'hytale_hitbox' + }); + } + +})(); \ No newline at end of file diff --git a/plugins/hytale_hitbox_helper/icon.png b/plugins/hytale_hitbox_helper/icon.png new file mode 100644 index 00000000..8533fb32 Binary files /dev/null and b/plugins/hytale_hitbox_helper/icon.png differ