diff --git a/.travis.yml b/.travis.yml index c9e4fc5a4..e4e6340ed 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,7 @@ jobs: - name: "Linux" os: linux script: + - npm install electron@30.0.3 - npm run prepublish - sudo apt-get install rpm - electron-builder --publish=onTagOrDraft diff --git a/css/panels.css b/css/panels.css index 0047436e6..d868f3fa9 100644 --- a/css/panels.css +++ b/css/panels.css @@ -1280,7 +1280,7 @@ width: 144px; flex-shrink: 0; background-color: var(--color-back); - z-index: 4; + z-index: 6; border-bottom: 1px solid var(--color-border); height: calc(100% + 1px); } diff --git a/js/animations/animation.js b/js/animations/animation.js index 4eabbf23f..79455d41b 100644 --- a/js/animations/animation.js +++ b/js/animations/animation.js @@ -1794,180 +1794,4 @@ Interface.definePanels(function() { 'save_all_animations', ]) }) - - new Panel('variable_placeholders', { - icon: 'fas.fa-stream', - condition: {modes: ['animate']}, - growable: true, - resizable: true, - default_position: { - slot: 'left_bar', - float_position: [0, 0], - float_size: [300, 400], - height: 400 - }, - component: { - name: 'panel-placeholders', - components: {VuePrismEditor}, - data() { return { - text: '', - buttons: [] - }}, - methods: { - updateButtons() { - let old_values = {}; - this.buttons.forEach(b => old_values[b.id] = b.value); - this.buttons.empty(); - - let text = this.text//.toLowerCase(); - let matches = text.matchAll(/(slider|toggle|impulse)\(.+\)/gi); - - for (let match of matches) { - let [type, content] = match[0].substring(0, match[0].length - 1).split(/\(/); - let [id, ...args] = content.split(/\(|, */); - id = id.replace(/['"]/g, ''); - if (this.buttons.find(b => b.id == id)) return; - - let variable = text.substring(0, match.index).match(/[\w.-]+ *= *$/); - variable = variable ? variable[0].replace(/[ =]+/g, '').replace(/^v\./i, 'variable.').replace(/^q\./i, 'query.').replace(/^t\./i, 'temp.').replace(/^c\./i, 'context.') : undefined; - - if (type == 'slider') { - this.buttons.push({ - type, - id, - value: old_values[id] || 0, - variable, - step: isNaN(args[0]) ? undefined : parseFloat(args[0]), - min: isNaN(args[1]) ? undefined : parseFloat(args[1]), - max: isNaN(args[2]) ? undefined : parseFloat(args[2]) - }) - } else if (type == 'toggle') { - this.buttons.push({ - type, - id, - value: old_values[id] || 0, - variable, - }) - } else if (type == 'impulse') { - this.buttons.push({ - type, - id, - value: 0, - variable, - duration: parseFloat(args[0]) || 0.1 - }) - } - } - }, - changeButtonValue(button, event) { - if (button.type == 'toggle') { - button.value = event.target.checked ? 1 : 0; - } - if (button.type == 'impulse') { - button.value = 1; - setTimeout(() => { - button.value = 0; - }, Math.clamp(button.duration, 0, 1) * 1000); - } - if (button.variable) { - delete Animator.MolangParser.variables[button.variable]; - } - Animator.preview(); - }, - slideButton(button, e1) { - convertTouchEvent(e1); - let last_event = e1; - let started = false; - let move_calls = 0; - let last_val = 0; - let total = 0; - let clientX = e1.clientX; - function start() { - started = true; - if (!e1.touches && last_event == e1 && e1.target.requestPointerLock) e1.target.requestPointerLock(); - } - - function move(e2) { - convertTouchEvent(e2); - if (!started && Math.abs(e2.clientX - e1.clientX) > 5) { - start() - } - if (started) { - if (e1.touches) { - clientX = e2.clientX; - } else { - let limit = move_calls <= 2 ? 1 : 100; - clientX += Math.clamp(e2.movementX, -limit, limit); - } - let val = Math.round((clientX - e1.clientX) / 45); - let difference = (val - last_val); - if (!difference) return; - if (button.step) { - difference *= button.step; - } else { - difference *= canvasGridSize(e2.shiftKey || Pressing.overrides.shift, e2.ctrlOrCmd || Pressing.overrides.ctrl); - } - - - button.value = Math.clamp(Math.roundTo((parseFloat(button.value) || 0) + difference, 4), button.min, button.max); - - last_val = val; - last_event = e2; - total += difference; - move_calls++; - - Animator.preview() - Blockbench.setStatusBarText(trimFloatNumber(total)); - } - } - function off(e2) { - if (document.exitPointerLock) document.exitPointerLock() - removeEventListeners(document, 'mousemove touchmove', move); - removeEventListeners(document, 'mouseup touchend', off); - } - addEventListeners(document, 'mouseup touchend', off); - addEventListeners(document, 'mousemove touchmove', move); - }, - autocomplete(text, position) { - let test = Animator.autocompleteMolang(text, position, 'placeholders'); - return test; - } - }, - watch: { - text(text) { - if (Project && typeof text == 'string') { - Project.variable_placeholders = text; - this.updateButtons(); - Project.variable_placeholder_buttons.replace(this.buttons); - } - } - }, - template: ` -
- - - -

${tl('panel.variable_placeholders.info')}

- - -
- ` - } - }) }) diff --git a/js/animations/animation_mode.js b/js/animations/animation_mode.js index 209a3ce68..3c7d6a42d 100644 --- a/js/animations/animation_mode.js +++ b/js/animations/animation_mode.js @@ -1415,6 +1415,7 @@ Interface.definePanels(function() { if (document.exitPointerLock) document.exitPointerLock() removeEventListeners(document, 'mousemove touchmove', move); removeEventListeners(document, 'mouseup touchend', off); + Blockbench.setStatusBarText(); } addEventListeners(document, 'mouseup touchend', off); addEventListeners(document, 'mousemove touchmove', move); diff --git a/js/interface/settings.js b/js/interface/settings.js index 98f0b12a0..02d574553 100644 --- a/js/interface/settings.js +++ b/js/interface/settings.js @@ -582,6 +582,10 @@ const Settings = { settings.brush_opacity_modifier.set('none'); settings.brush_size_modifier.set('none'); }) + let date = new Date(); + if (date.getMonth() >= 5 && date.getDate() >= 13) { + settings.bedrock_uv_rotations.set(true); + } }, setupProfiles() { if (localStorage.getItem('settings_profiles') != null) { diff --git a/js/io/formats/skin.js b/js/io/formats/skin.js index fad4fc837..d1f7e7f30 100644 --- a/js/io/formats/skin.js +++ b/js/io/formats/skin.js @@ -1839,6 +1839,252 @@ skin_presets.boat = { ] }` }; +skin_presets.bogged = { + display_name: 'Bogged', + model: `{ + "name": "bogged", + "texturewidth": 64, + "textureheight": 32, + "eyes": [ + [9, 12, 2, 1], + [13, 12, 2, 1] + ], + "bones": [ + { + "name": "body", + "pivot": [0, 24, 0], + "cubes": [ + {"origin": [-4, 12, -2], "size": [8, 12, 4], "uv": [16, 16]} + ] + }, + { + "name": "waist", + "pivot": [0, 12, 0] + }, + { + "name": "head", + "pivot": [0, 24, 0], + "cubes": [ + {"origin": [-4, 24, -4], "size": [8, 8, 8], "uv": [0, 0]} + ] + }, + { + "name": "mushrooms", + "parent": "head", + "pivot": [3, 31.5, 3], + "cubes": [ + {"origin": [-6, 31, -3], "size": [6, 4, 0], "pivot": [-3, 32.5, -3], "rotation": [0, -45, 0], "uv": [50, 22]}, + {"origin": [-6, 31, -3], "size": [6, 4, 0], "pivot": [-3, 32.5, -3], "rotation": [0, 45, 0], "uv": [50, 22]}, + {"origin": [0, 31, 3], "size": [6, 4, 0], "pivot": [3, 31.5, 3], "rotation": [0, 45, 0], "uv": [50, 16]}, + {"origin": [0, 31, 3], "size": [6, 4, 0], "pivot": [3, 31.5, 3], "rotation": [0, -45, 0], "uv": [50, 16]}, + {"origin": [-5, 25, 3], "size": [6, 5, 0], "pivot": [-2, 25, 3], "rotation": [-90, 0, 45], "uv": [50, 27]}, + {"origin": [-5, 25, 3], "size": [6, 5, 0], "pivot": [-2, 25, 3], "rotation": [-90, 0, 135], "uv": [50, 27]} + ] + }, + { + "name": "hat", + "pivot": [0, 24, 0], + "cubes": [ + {"origin": [-4, 24, -4], "size": [8, 8, 8], "inflate": 0.2, "uv": [32, 0], "layer": true} + ] + }, + { + "name": "rightArm", + "pivot": [-5, 22, 0], + "cubes": [ + {"origin": [-6, 12, -1], "size": [2, 12, 2], "uv": [40, 16]} + ] + }, + { + "name": "rightItem", + "parent": "rightArm", + "pivot": [-6, 15, 1] + }, + { + "name": "leftArm", + "pivot": [5, 22, 0], + "mirror": true, + "cubes": [ + {"origin": [4, 12, -1], "size": [2, 12, 2], "uv": [40, 16], "mirror": true} + ] + }, + { + "name": "leftItem", + "parent": "leftArm", + "pivot": [6, 15, 1] + }, + { + "name": "rightLeg", + "pivot": [-2, 12, 0], + "cubes": [ + {"origin": [-3, 0, -1], "size": [2, 12, 2], "uv": [0, 16]} + ] + }, + { + "name": "leftLeg", + "pivot": [2, 12, 0], + "mirror": true, + "cubes": [ + {"origin": [1, 0, -1], "size": [2, 12, 2], "uv": [0, 16], "mirror": true} + ] + } + ] + }` +}; +skin_presets.bogged_layer = { + display_name: 'Bogged/Stray Layer', + model: `{ + "name": "bogged_layer", + "texturewidth": 64, + "textureheight": 32, + "eyes": [ + [9, 12, 2, 1], + [13, 12, 2, 1] + ], + "bones": [ + { + "name": "body", + "pivot": [0, 24, 0], + "cubes": [ + {"origin": [-4, 12, -2], "size": [8, 12, 4], "uv": [16, 16]} + ] + }, + { + "name": "leftArm", + "parent": "body", + "pivot": [5, 22, 0], + "mirror": true, + "cubes": [ + {"origin": [4, 12, -2], "size": [4, 12, 4], "uv": [40, 16], "mirror": true} + ] + }, + { + "name": "head", + "pivot": [0, 24, 0], + "cubes": [ + {"origin": [-4, 24, -4], "size": [8, 8, 8], "uv": [0, 0]} + ] + }, + { + "name": "hat", + "pivot": [0, 24, 0], + "cubes": [ + {"origin": [-4, 24, -4], "size": [8, 8, 8], "inflate": 0.5, "uv": [32, 0], "layer": true, , "visibility": false} + ] + }, + { + "name": "rightArm", + "pivot": [-5, 22, 0], + "cubes": [ + {"origin": [-8, 12, -2], "size": [4, 12, 4], "uv": [40, 16]} + ] + }, + { + "name": "rightLeg", + "pivot": [-1.9, 12, 0], + "cubes": [ + {"origin": [-3.9, 0, -2], "size": [4, 12, 4], "uv": [0, 16]} + ] + }, + { + "name": "leftLeg", + "pivot": [1.9, 12, 0], + "mirror": true, + "cubes": [ + {"origin": [-0.1, 0, -2], "size": [4, 12, 4], "uv": [0, 16], "mirror": true} + ] + } + ] + }` +}; +skin_presets.breeze = { + display_name: 'Breeze', + model: `{ + "name": "breeze", + "texturewidth": 32, + "textureheight": 32, + "eyes": [ + [7, 14, 3, 1], + [14, 14, 3, 1], + [6, 29, 5, 1], + [15, 29, 5, 1] + ], + "bones": [ + { + "name": "body", + "pivot": [0, 0, 0] + }, + { + "name": "rods", + "parent": "body", + "pivot": [0, 16, 0], + "cubes": [ + {"origin": [-1, 11, -6], "size": [2, 8, 2], "pivot": [0, 19, -3], "rotation": [22.5, 0, 0], "uv": [0, 17]}, + {"origin": [-3.59808, 11, -1.5], "size": [2, 8, 2], "pivot": [-2.59808, 19, 1.5], "rotation": [-157.5, 60, 180], "uv": [0, 17]}, + {"origin": [1.59808, 11, -1.5], "size": [2, 8, 2], "pivot": [2.59808, 19, 1.5], "rotation": [-157.5, -60, 180], "uv": [0, 17]} + ] + }, + { + "name": "head", + "parent": "body", + "pivot": [0, 20, 0], + "cubes": [ + {"origin": [-4, 20, -4], "size": [8, 8, 8], "uv": [0, 0]} + ] + }, + { + "name": "eyes", + "parent": "head", + "pivot": [0, 20, 0], + "cubes": [ + {"origin": [-5, 22, -4.2], "size": [10, 3, 4], "uv": [4, 24], "layer": true} + ] + } + ] + }` +} +skin_presets.breeze_tornado = { + display_name: 'Breeze Tornado', + model: `{ + "name": "breeze_wind", + "texturewidth": 128, + "textureheight": 128, + "bones": [ + { + "name": "tornado_body", + "pivot": [0, 0, 0] + }, + { + "name": "tornado_bottom", + "parent": "tornado_body", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [-2.5, 0, -2.5], "size": [5, 7, 5], "uv": [1, 83]} + ] + }, + { + "name": "tornado_mid", + "parent": "tornado_bottom", + "pivot": [0, 7, 0], + "cubes": [ + {"origin": [-2.5, 7, -2.5], "size": [5, 6, 5], "uv": [49, 71]}, + {"origin": [-4, 7, -4], "size": [8, 6, 8], "uv": [78, 32]}, + {"origin": [-6, 7, -6], "size": [12, 6, 12], "uv": [74, 28]} + ] + }, + { + "name": "tornado_top", + "parent": "tornado_mid", + "pivot": [0, 13, 0], + "cubes": [ + {"origin": [-2.5, 13, -2.5], "size": [5, 8, 5], "uv": [105, 57]}, + {"origin": [-6, 13, -6], "size": [12, 8, 12], "uv": [6, 6]}, + {"origin": [-9, 13, -9], "size": [18, 8, 18], "uv": [0, 0]} + ] + } + ] + }` +} skin_presets.camel = { display_name: 'Camel', model: `{ @@ -5440,7 +5686,7 @@ skin_presets.silverfish = { }` }; skin_presets.skeleton = { - display_name: 'Skeleton', + display_name: 'Skeleton/Stray', model: `{ "name": "skeleton", "texturewidth": 64, diff --git a/js/texturing/textures.js b/js/texturing/textures.js index 0e806a9fd..89842eea2 100644 --- a/js/texturing/textures.js +++ b/js/texturing/textures.js @@ -877,15 +877,17 @@ class Texture { if (event instanceof Event) { Prop.active_panel = 'textures'; } - if (event && (event.shiftKey || event.ctrlKey)) { - this.multi_selected = true; - if (event.shiftKey) { + if (event && (event.shiftKey || event.ctrlOrCmd || Pressing.overrides.ctrl || Pressing.overrides.shift)) { + if (event.shiftKey || Pressing.overrides.shift) { + this.multi_selected = true; let start_i = Texture.last_selected; let end_i = Texture.all.indexOf(this); if (start_i > end_i) [start_i, end_i] = [end_i, start_i]; for (let i = start_i+1; i < end_i; i++) { Texture.all[i].multi_selected = true; } + } else { + this.multi_selected = !this.multi_selected; } Texture.last_selected = Texture.all.indexOf(this); return; @@ -1097,10 +1099,9 @@ class Texture { return this; } showContextMenu(event) { - var scope = this; - scope.select() + if (this != Texture.selected) this.select() Prop.active_panel = 'textures' - this.menu.open(event, scope) + this.menu.open(event, this) } openMenu() { this.select(); diff --git a/package.json b/package.json index 26fb41173..54a254402 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "Blockbench", "description": "Low-poly modeling and animation software", - "version": "4.10.2", + "version": "4.10.3", "license": "GPL-3.0-or-later", "author": { "name": "JannisX11", @@ -105,7 +105,7 @@ "publish-windows": "npm run bundle && electron-builder -w --publish=onTagOrDraft && node ./scripts/rename_portable.js && electron-builder --windows portable --publish=onTagOrDraft", "pwa": "node ./scripts/generate_pwa.js", "prepublish": "npm run bundle && npm run pwa", - "webapp": "git checkout gh-pages && git merge master && git push && git checkout master" + "webapp": "git checkout gh-pages && git pull && git merge master && git push && git checkout master" }, "devDependencies": { "@electron/notarize": "^2.3.0",