mirror of
https://github.com/JannisX11/blockbench.git
synced 2025-01-18 15:26:19 +08:00
Merge branch 'master' into next
This commit is contained in:
commit
c62729362f
@ -147,6 +147,9 @@
|
||||
.dialog_bar > label {
|
||||
width: var(--max_label_width);
|
||||
}
|
||||
.dialog_bar > .molang_input {
|
||||
width: calc(100% - var(--max_label_width));
|
||||
}
|
||||
/*.dialog_bar::after {
|
||||
content: "";
|
||||
clear: both;
|
||||
@ -1493,6 +1496,7 @@ dialog#edit_bedrock_binding > .dialog_wrapper > .dialog_content {
|
||||
color: var(--color-subtle_text);
|
||||
margin-left: auto;
|
||||
cursor: inherit;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2672,6 +2672,7 @@ span.controller_state_section_info {
|
||||
padding: 2px;
|
||||
min-height: 160px;
|
||||
max-height: 232px;
|
||||
line-height: 0;
|
||||
}
|
||||
#palette_list .color {
|
||||
display: inline-block;
|
||||
|
@ -178,7 +178,8 @@ class AnimationControllerState {
|
||||
if (this.transitions.length) {
|
||||
object.transitions = this.transitions.map(transition => {
|
||||
let state = this.controller.states.find(s => s.uuid == transition.target);
|
||||
return new oneLiner({[state ? state.name : 'missing_state']: transition.condition})
|
||||
let condition = transition.condition.replace(/\n/g, '');
|
||||
return new oneLiner({[state ? state.name : 'missing_state']: condition})
|
||||
})
|
||||
}
|
||||
if (this.blend_transition) object.blend_transition = this.blend_transition;
|
||||
@ -1723,7 +1724,7 @@ Interface.definePanels(() => {
|
||||
</ul>
|
||||
<div class="controller_state_input_bar">
|
||||
<label>${tl('animation_controllers.state.blend_transition')}</label>
|
||||
<numeric-input style="width: 70px;" v-model.number="state.blend_transition" min="0" step="0.05" />
|
||||
<numeric-input style="width: 70px;" v-model.number="state.blend_transition" :min="0" :step="0.05" />
|
||||
</div>
|
||||
<div class="controller_state_input_bar">
|
||||
<label :for="state.uuid + '_shortest_path'">${tl('animation_controllers.state.shortest_path')}</label>
|
||||
|
@ -2016,7 +2016,7 @@ BARS.defineActions(function() {
|
||||
"position": [4, 12, -2],
|
||||
"size": [4, 12, 4],
|
||||
"origin": [5, 22, 0],
|
||||
"rotation": [-1, 0, 3],
|
||||
"rotation": [15, 0, 0],
|
||||
"faces": {
|
||||
"north": {"uv": [44, 20, 48, 32]},
|
||||
"east": {"uv": [40, 20, 44, 32]},
|
||||
@ -2031,7 +2031,7 @@ BARS.defineActions(function() {
|
||||
"position": [3.75, 11.75, -2.25],
|
||||
"size": [4.5, 12.5, 4.5],
|
||||
"origin": [5, 22, 0],
|
||||
"rotation": [-1, 0, 3],
|
||||
"rotation": [15, 0, 0],
|
||||
"faces": {
|
||||
"north": {"uv": [44, 36, 48, 48]},
|
||||
"east": {"uv": [40, 36, 44, 48]},
|
||||
@ -2079,7 +2079,7 @@ BARS.defineActions(function() {
|
||||
"position": [4, 11.5, -2],
|
||||
"size": [3, 12, 4],
|
||||
"origin": [5, 21.5, 0],
|
||||
"rotation": [-1, 0, 3],
|
||||
"rotation": [15, 0, 0],
|
||||
"faces": {
|
||||
"north": {"uv": [44,20,47,32]},
|
||||
"east": {"uv": [40,20,44,32]},
|
||||
@ -2094,7 +2094,7 @@ BARS.defineActions(function() {
|
||||
"position": [3.75, 11.25, -2.25],
|
||||
"size": [3.5, 12.5, 4.5],
|
||||
"origin": [5, 21.5, 0],
|
||||
"rotation": [-1, 0, 3],
|
||||
"rotation": [15, 0, 0],
|
||||
"faces": {
|
||||
"north": {"uv": [44,36,47,48]},
|
||||
"east": {"uv": [40,36,44,48]},
|
||||
@ -2193,6 +2193,7 @@ BARS.defineActions(function() {
|
||||
|
||||
window.player_attachable_reference_model = player_attachable_reference_model;
|
||||
player_attachable_reference_model.updateArmVariant = player_preview_model.updateArmVariant;
|
||||
player_attachable_reference_model.updateArmVariant();
|
||||
|
||||
let camera_preset_1st = {
|
||||
name: tl('action.bedrock_animation_mode.attachable_first'),
|
||||
|
@ -1688,7 +1688,12 @@ class Toolbar {
|
||||
if (arr.equals(this.default_children)) {
|
||||
delete BARS.stored[this.id];
|
||||
}
|
||||
localStorage.setItem('toolbars', JSON.stringify(BARS.stored))
|
||||
// Temporary fix
|
||||
try {
|
||||
localStorage.setItem('toolbars', JSON.stringify(BARS.stored))
|
||||
} catch (err) {
|
||||
localStorage.removeItem('backup_model');
|
||||
}
|
||||
return this;
|
||||
}
|
||||
reset() {
|
||||
|
@ -744,7 +744,7 @@ window.Dialog = class Dialog {
|
||||
handle.append(title);
|
||||
|
||||
let jq_dialog = $(this.object);
|
||||
this.max_label_width = 0;
|
||||
this.max_label_width = 140;
|
||||
this.uses_wide_inputs = false;
|
||||
|
||||
let wrapper = document.createElement('div');
|
||||
|
@ -478,7 +478,7 @@ const MenuBar = {
|
||||
'open_dev_tools',
|
||||
{name: 'Error Log', condition: () => window.ErrorLog.length, icon: 'error', color: 'red', keybind: {toString: () => window.ErrorLog.length.toString()}, click() {
|
||||
let lines = window.ErrorLog.slice(0, 64).map((error) => {
|
||||
return Interface.createElement('p', {}, `${error.message}\n - In .${error.file.split(location.origin).join('')} : ${error.line}`);
|
||||
return Interface.createElement('p', {style: 'word-break: break-word;'}, `${error.message}\n - In .${error.file.split(location.origin).join('')} : ${error.line}`);
|
||||
})
|
||||
new Dialog({
|
||||
id: 'error_log',
|
||||
|
@ -134,7 +134,12 @@ Vue.component('numeric-input', {
|
||||
<input class="dark_bordered focusable_input" :value="string_value" @input="change($event.target.value)" inputmode="decimal" lang="en" @focusout="resolve($event)" @dblclick="resolve($event)">
|
||||
<div class="tool numeric_input_slider" @mousedown="slide($event)" @touchstart="slide($event)"><i class="material-icons">code</i></div>
|
||||
</div>
|
||||
`
|
||||
`,
|
||||
mounted() {
|
||||
if (typeof this.min == 'string') console.warn('Argument "min" should be set as a numeric property via "v-bind:"')
|
||||
if (typeof this.max == 'string') console.warn('Argument "max" should be set as a numeric property via "v-bind:"')
|
||||
if (typeof this.step == 'string') console.warn('Argument "step" should be set as a numeric property via "v-bind:"')
|
||||
}
|
||||
})
|
||||
Vue.component('dynamic-icon', {
|
||||
props: {
|
||||
|
@ -106,7 +106,8 @@ class Codec extends EventSystem {
|
||||
}
|
||||
async export() {
|
||||
if (Object.keys(this.export_options).length) {
|
||||
await this.promptExportOptions();
|
||||
let result = await this.promptExportOptions();
|
||||
if (result === null) return;
|
||||
}
|
||||
Blockbench.export({
|
||||
resource_id: 'model',
|
||||
|
@ -1051,7 +1051,8 @@ var codec = new Codec('fbx', {
|
||||
},
|
||||
async export() {
|
||||
if (Object.keys(this.export_options).length) {
|
||||
await this.promptExportOptions();
|
||||
let result = await this.promptExportOptions();
|
||||
if (result === null) return;
|
||||
}
|
||||
var scope = this;
|
||||
if (isApp) {
|
||||
|
@ -345,7 +345,8 @@ var codec = new Codec('gltf', {
|
||||
}
|
||||
},
|
||||
async export() {
|
||||
await this.promptExportOptions();
|
||||
let options = await this.promptExportOptions();
|
||||
if (options === null) return;
|
||||
let content = await this.compile();
|
||||
await new Promise(r => setTimeout(r, 20));
|
||||
Blockbench.export({
|
||||
|
13
js/io/io.js
13
js/io/io.js
@ -127,8 +127,12 @@ async function loadImages(files, event) {
|
||||
if (img.naturalHeight == img.naturalWidth && [64, 128].includes(img.naturalWidth)) {
|
||||
options.minecraft_skin = 'format.skin';
|
||||
}
|
||||
if (Project && !Format.image_editor && Condition(Panels.textures.condition)) {
|
||||
options.texture = 'action.import_texture';
|
||||
if (Project && Condition(Panels.textures.condition)) {
|
||||
if (Format.image_editor) {
|
||||
options.texture = 'message.load_images.add_image';
|
||||
} else {
|
||||
options.texture = 'action.import_texture';
|
||||
}
|
||||
}
|
||||
if (Project && (!Project.box_uv || Format.optional_box_uv)) {
|
||||
options.extrude_with_cubes = 'dialog.extrude.title';
|
||||
@ -138,9 +142,12 @@ async function loadImages(files, event) {
|
||||
if (method == 'texture') {
|
||||
let new_textures = [];
|
||||
Undo.initEdit({textures: new_textures});
|
||||
files.forEach(function(f) {
|
||||
files.forEach(function(f, i) {
|
||||
let tex = new Texture().fromFile(f).add().fillParticle();
|
||||
new_textures.push(tex);
|
||||
if (Format.image_editor && i == 0) {
|
||||
tex.select();
|
||||
}
|
||||
});
|
||||
Undo.finishEdit('Add texture');
|
||||
|
||||
|
@ -748,9 +748,11 @@ class Cube extends OutlinerElement {
|
||||
} else if (scope.autouv === 1) {
|
||||
|
||||
function calcAutoUV(face, size) {
|
||||
var sx = scope.faces[face].uv[0]
|
||||
var sy = scope.faces[face].uv[1]
|
||||
var rot = scope.faces[face].rotation
|
||||
size[0] = Math.abs(size[0]);
|
||||
size[1] = Math.abs(size[1]);
|
||||
var sx = scope.faces[face].uv[0];
|
||||
var sy = scope.faces[face].uv[1];
|
||||
var rot = scope.faces[face].rotation;
|
||||
|
||||
//Match To Rotation
|
||||
if (rot === 90 || rot === 270) {
|
||||
|
@ -262,7 +262,6 @@ class Group extends OutlinerNode {
|
||||
return array;
|
||||
}
|
||||
showContextMenu(event) {
|
||||
Prop.active_panel = 'outliner'
|
||||
if (this.locked) return this;
|
||||
if (Group.selected != this) this.select(event);
|
||||
this.menu.open(event, this)
|
||||
|
@ -369,7 +369,6 @@ class OutlinerElement extends OutlinerNode {
|
||||
return this;
|
||||
}
|
||||
showContextMenu(event) {
|
||||
Prop.active_panel = 'outliner'
|
||||
if (this.locked) return this;
|
||||
if (!this.selected) {
|
||||
this.select()
|
||||
|
@ -436,7 +436,8 @@ class Plugin {
|
||||
this.unload()
|
||||
this.tags.empty();
|
||||
this.dependencies.empty();
|
||||
Plugins.all.remove(this)
|
||||
Plugins.all.remove(this);
|
||||
this.details = null;
|
||||
|
||||
if (this.source == 'file') {
|
||||
this.loadFromFile({path: this.path}, false)
|
||||
@ -808,10 +809,14 @@ async function loadInstalledPlugins() {
|
||||
}
|
||||
|
||||
} else if (plugin.source == 'url') {
|
||||
var instance = new Plugin(plugin.id, {disabled: plugin.disabled});
|
||||
install_promises.push(instance.loadFromURL(plugin.path, false));
|
||||
load_counter++;
|
||||
console.log(`🧩🌐 Loaded plugin "${plugin.id || plugin.path}" from URL`);
|
||||
if (plugin.path) {
|
||||
var instance = new Plugin(plugin.id, {disabled: plugin.disabled});
|
||||
install_promises.push(instance.loadFromURL(plugin.path, false));
|
||||
load_counter++;
|
||||
console.log(`🧩🌐 Loaded plugin "${plugin.id || plugin.path}" from URL`);
|
||||
} else {
|
||||
Plugins.installed.remove(plugin);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (Plugins.all.find(p => p.id == plugin.id)) {
|
||||
@ -1317,7 +1322,7 @@ BARS.defineActions(function() {
|
||||
</tr>
|
||||
<tr v-if="selected_plugin.details.website">
|
||||
<td>Website</td>
|
||||
<td>{{ selected_plugin.details.website }}</td>
|
||||
<td><a :href="selected_plugin.details.website" :title="selected_plugin.details.website">{{ reduceLink(selected_plugin.details.website) }}</a></td>
|
||||
</tr>
|
||||
<tr v-if="selected_plugin.details.repository">
|
||||
<td>Plugin source</td>
|
||||
|
@ -311,11 +311,11 @@ const PredicateOverrideEditor = {
|
||||
<select-input v-model="generator.type" :options="available_predicate_options" @input="updateGeneratorType()" />
|
||||
|
||||
<label>${tl('dialog.predicate_overrides.variants')}</label>
|
||||
<numeric-input v-model.number="generator.variants" min="1" step="1" style="width: 70px;" />
|
||||
<numeric-input v-model.number="generator.variants" :min="1" :step="1" style="width: 70px;" />
|
||||
|
||||
<template v-if="generator.type == 'custom_model_data'">
|
||||
<label>${tl('dialog.predicate_overrides.start_value')}</label>
|
||||
<numeric-input v-model.number="generator.start_value" min="0" step="1" style="width: 45px;" />
|
||||
<numeric-input v-model.number="generator.start_value" :min="0" :step="1" style="width: 45px;" />
|
||||
</template>
|
||||
|
||||
<label>${tl('dialog.predicate_overrides.model')}</label>
|
||||
|
@ -655,7 +655,7 @@ class Preview {
|
||||
position: {label: 'dialog.save_angle.position', type: 'vector', dimensions: 3, value: position},
|
||||
target: {label: 'dialog.save_angle.target', type: 'vector', dimensions: 3, value: target, condition: ({rotation_mode}) => rotation_mode == 'target'},
|
||||
rotation: {label: 'dialog.save_angle.rotation', type: 'vector', dimensions: 2, condition: ({rotation_mode}) => rotation_mode == 'rotation'},
|
||||
zoom: {label: 'dialog.save_angle.zoom', type: 'number', value: 1, condition: result => (result.projection == 'orthographic')},
|
||||
zoom: {label: 'dialog.save_angle.zoom', type: 'number', value: Math.roundTo(scope.camOrtho.zoom || 1, 4), condition: result => scope.isOrtho},
|
||||
},
|
||||
onFormChange(form) {
|
||||
if (form.rotation_mode !== rotation_mode) {
|
||||
@ -677,7 +677,7 @@ class Preview {
|
||||
position: formResult.position,
|
||||
target: formResult.target,
|
||||
}
|
||||
if (this.isOrtho) preset.zoom = this.camOrtho.zoom;
|
||||
if (scope.isOrtho) preset.zoom = scope.camOrtho.zoom;
|
||||
|
||||
let presets = localStorage.getItem('camera_presets');
|
||||
try {
|
||||
@ -1894,6 +1894,444 @@ window.addEventListener("gamepadconnected", function(event) {
|
||||
}
|
||||
});
|
||||
|
||||
if (new Date().getDate() == 1 && new Date().getMonth() == 3) {
|
||||
class RainbowRace {
|
||||
constructor() {
|
||||
this.velocity = 0.03;
|
||||
this.y_velocity = 0;
|
||||
this.steering_angle = 0;
|
||||
this.steer_direction = 0;
|
||||
this.turn_axis = new THREE.Vector3(0, 1, 0);
|
||||
this.step = 4;
|
||||
this.path = [];
|
||||
this.waypoints = [];
|
||||
|
||||
this.material = new THREE.MeshPhongMaterial({
|
||||
color: 0xffffff,
|
||||
flatShading: true,
|
||||
vertexColors: true,
|
||||
shininess: 0,
|
||||
side: THREE.DoubleSide
|
||||
});
|
||||
this.geometry = new THREE.BufferGeometry();
|
||||
this.track_width = 6;
|
||||
this.track_length = 250;
|
||||
this.track_length_back = 12;
|
||||
this.collision_length = 64;
|
||||
|
||||
this.ticks = 0;
|
||||
this.playing = false;
|
||||
this.on_track = true;
|
||||
this.score = 0;
|
||||
|
||||
for (let i = 0; i < this.track_length; i++) {
|
||||
this.addPathPoint(i < this.track_length_back);
|
||||
}
|
||||
|
||||
let colors = [
|
||||
[128/255, 75/255, 227/255],
|
||||
[ 21/255, 118/255, 240/255],
|
||||
[ 68/255, 189/255, 96/255],
|
||||
[253/255, 203/255, 42/255],
|
||||
[252/255, 137/255, 46/255],
|
||||
[240/255, 40/255, 67/255],
|
||||
]
|
||||
let bg_color = new THREE.Color(CustomTheme.data.colors.dark);
|
||||
|
||||
let vertex_count = 4 * this.track_width * this.track_length;
|
||||
this.geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(vertex_count * 3), 3));
|
||||
this.geometry.setAttribute('color', new THREE.BufferAttribute( new Float32Array(vertex_count * 3), 3));
|
||||
|
||||
for (let i = 0; i < this.track_length * 20; i++) {
|
||||
for (let j = 0; j < 4; j++) {
|
||||
let k = 0;
|
||||
for (let color of colors) {
|
||||
let color_factor = 1;
|
||||
if ( (k==0 && j%2==0) || (k==5 && j%2==1) ) {
|
||||
color_factor = 1.5;
|
||||
}
|
||||
let fade = Math.min(Math.pow(i / (this.track_length * 0.97), 2), 1);
|
||||
this.geometry.attributes.color.setXYZ(
|
||||
(i*6 + k) * 4 + j,
|
||||
Math.lerp(color[0] * color_factor, bg_color.r, fade),
|
||||
Math.lerp(color[1] * color_factor, bg_color.g, fade),
|
||||
Math.lerp(color[2] * color_factor, bg_color.b, fade)
|
||||
);
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.updateGeometry();
|
||||
|
||||
this.coin_geometry = new THREE.OctahedronGeometry(5, 0);
|
||||
this.coin_geometry2 = new THREE.OctahedronGeometry(6.2, 0);
|
||||
this.coin_material = new THREE.MeshPhongMaterial({
|
||||
color: new THREE.Color(3.3, 3.2, 0.8),
|
||||
flatShading: false,
|
||||
shininess: 1
|
||||
});
|
||||
this.coin_material2 = new THREE.MeshPhongMaterial({
|
||||
color: 0xff9c2b,
|
||||
flatShading: true,
|
||||
shininess: 0,
|
||||
opacity: 0.5,
|
||||
transparent: true
|
||||
});
|
||||
this.coins = [];
|
||||
|
||||
this.scene = new THREE.Object3D();
|
||||
this.world = new THREE.Object3D();
|
||||
this.track = new THREE.Mesh(this.geometry, this.material);
|
||||
this.scene.add(this.world);
|
||||
this.world.add(this.track);
|
||||
this.position = new THREE.Vector3();
|
||||
|
||||
this.keys = {
|
||||
w: false,
|
||||
s: false,
|
||||
a: false,
|
||||
d: false,
|
||||
};
|
||||
document.addEventListener('keydown', event => {
|
||||
if (event.key == 'w') this.keys.w = true;
|
||||
if (event.key == 's') this.keys.s = true;
|
||||
if (event.key == 'a') this.keys.a = true;
|
||||
if (event.key == 'd') this.keys.d = true;
|
||||
})
|
||||
document.addEventListener('keyup', event => {
|
||||
if (event.key == 'w') this.keys.w = false;
|
||||
if (event.key == 's') this.keys.s = false;
|
||||
if (event.key == 'a') this.keys.a = false;
|
||||
if (event.key == 'd') this.keys.d = false;
|
||||
})
|
||||
|
||||
this.interval = setInterval(() => {
|
||||
this.tick();
|
||||
}, 1000/30);
|
||||
}
|
||||
async start() {
|
||||
if (this.playing) this.stop();
|
||||
|
||||
Canvas.scene.add(this.scene);
|
||||
three_grid.visible = false;
|
||||
|
||||
let model_size = 3 / calculateVisibleBox()[0];
|
||||
Project.model_3d.scale.set(model_size, model_size, model_size);
|
||||
|
||||
let path_scale = 3;
|
||||
this.track.scale.set(path_scale, path_scale, path_scale);
|
||||
this.velocity = 0;
|
||||
this.y_velocity = 0;
|
||||
this.on_track = true;
|
||||
this.playing = true;
|
||||
this.score = 0;
|
||||
this.steer_direction = 0;
|
||||
this.scene.rotation.set(0, 0, 0);
|
||||
this.world.position.set(0, 0, -this.track_length_back * path_scale);
|
||||
this.track.position.set(0, 0, 0);
|
||||
this.track.rotation.set(0, 0, 0);
|
||||
|
||||
let camera_preset = {
|
||||
projection: 'perspective',
|
||||
position: [0, 32, -40],
|
||||
target: [0, 20, 0]
|
||||
};
|
||||
Preview.selected.loadAnglePreset(camera_preset);
|
||||
|
||||
this.front_right_wheel = Group.all.find(g => {
|
||||
let name = g.name.toLowerCase();
|
||||
return name.includes('wheel') && name.includes('front') && name.includes('right')
|
||||
})?.mesh;
|
||||
this.front_left_wheel = Group.all.find(g => {
|
||||
let name = g.name.toLowerCase();
|
||||
return name.includes('wheel') && name.includes('front') && name.includes('left')
|
||||
})?.mesh;
|
||||
let rear_wheel = Group.all.find(g => {
|
||||
let name = g.name.toLowerCase();
|
||||
return (name.includes('wheel') || name.includes('axle') || name.includes('axis')) && (name.includes('rear') || name.includes('back'))
|
||||
})
|
||||
this.rotation_adjustment = Math.PI;
|
||||
if (rear_wheel) {
|
||||
if (rear_wheel.origin[2] < 0) {
|
||||
this.rotation_adjustment = 0;
|
||||
Project.model_3d.position.z -= rear_wheel.origin[2] * model_size;
|
||||
} else {
|
||||
Project.model_3d.position.z += rear_wheel.origin[2] * model_size;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
stop() {
|
||||
Canvas.scene.remove(this.scene);
|
||||
three_grid.visible = true;
|
||||
this.playing = false;
|
||||
Project.model_3d.rotation.y = 0;
|
||||
Project.model_3d.scale.set(1, 1, 1);
|
||||
Project.model_3d.position.set(0, 0, 0);
|
||||
Blockbench.setStatusBarText();
|
||||
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
delete this.timeout;
|
||||
}
|
||||
}
|
||||
tick() {
|
||||
if (!this.playing) {
|
||||
return;
|
||||
}
|
||||
|
||||
let steering_amount = 0.2 * (1-Math.exp(0.2 * (this.velocity - 18)));
|
||||
if (this.keys.a) {
|
||||
this.steering_angle -= steering_amount * (1+Math.pow( this.steering_angle / 2, 3));
|
||||
} else if (this.keys.d) {
|
||||
this.steering_angle += steering_amount * (1+Math.pow(-this.steering_angle / 2, 3));
|
||||
} else if (this.steering_angle) {
|
||||
//this.steering_angle -= (this.steering_angle > 0 ? 1 : -1) * 0.14;
|
||||
//if (Math.abs(this.steering_angle) < 0.1) this.steering_angle = 0;
|
||||
this.steering_angle *= 0.8;
|
||||
}
|
||||
this.steering_angle = Math.clamp(this.steering_angle, -1.5, 1.4);
|
||||
|
||||
if (this.keys.w) {
|
||||
this.velocity += 0.1 * (1-Math.exp(0.3 * (this.velocity - 7)));
|
||||
} else if (this.keys.s) {
|
||||
this.velocity -= this.velocity > 0 ? 0.15 : 0.1;
|
||||
} else {
|
||||
this.velocity -= this.velocity > 0 ? 0.1 : -0.1;
|
||||
if (Math.abs(this.velocity) < 0.1) this.velocity = 0;
|
||||
}
|
||||
this.velocity = Math.clamp(this.velocity, -4, 10);
|
||||
|
||||
if (!this.on_track) {
|
||||
this.y_velocity = Math.clamp(this.y_velocity - 0.2, -4, 4);
|
||||
}
|
||||
|
||||
let movement = new THREE.Vector3(0, -this.y_velocity, -this.velocity);
|
||||
this.steer_direction = this.steer_direction + this.steering_angle * Math.min(this.velocity, 1.4) * 0.02;
|
||||
movement.applyAxisAngle(this.turn_axis, -this.steer_direction + 0);
|
||||
this.scene.rotation.y = Math.lerp(this.scene.rotation.y, this.steer_direction, 0.1);
|
||||
Project.model_3d.rotation.y = this.rotation_adjustment + this.scene.rotation.y - this.steer_direction;
|
||||
this.world.position.add(movement);
|
||||
|
||||
if (this.front_right_wheel) this.front_right_wheel.rotation.y = this.steering_angle * -0.5;
|
||||
if (this.front_left_wheel) this.front_left_wheel.rotation.y = this.steering_angle * -0.5;
|
||||
|
||||
let closest_waypoint = this.getClosestWaypoint();
|
||||
if (closest_waypoint) {
|
||||
let segments_regenerated = false;
|
||||
while (closest_waypoint.index > this.track_length_back) {
|
||||
this.generatePathStep();
|
||||
segments_regenerated = true;
|
||||
closest_waypoint.index--;
|
||||
}
|
||||
if (segments_regenerated) this.updateGeometry();
|
||||
} else if (this.on_track) {
|
||||
// Fall off
|
||||
this.fall();
|
||||
}
|
||||
|
||||
this.coins.forEach(coin => {
|
||||
coin.rotation.y += 0.01;
|
||||
coin.position.y = 10 + Math.sin(this.ticks * 0.1) * 0.8;
|
||||
|
||||
let offset = Reusable.vec2.set(0, 0, 0);
|
||||
coin.localToWorld(offset);
|
||||
let distance = offset.length();
|
||||
if (distance && distance < 34) {
|
||||
this.collectCoin(coin);
|
||||
}
|
||||
});
|
||||
|
||||
Blockbench.setStatusBarText(`Score: ${separateThousands(this.score)}`);
|
||||
|
||||
this.ticks++;
|
||||
}
|
||||
fall() {
|
||||
this.on_track = false;
|
||||
let previous_highscore = localStorage.getItem('rainbow_game.highscore') || 0;
|
||||
if (this.score > previous_highscore) {
|
||||
Blockbench.showQuickMessage(`New Highscore: ${separateThousands(this.score)}`);
|
||||
localStorage.setItem('rainbow_game.highscore', this.score);
|
||||
} else {
|
||||
Blockbench.showQuickMessage(`Score: ${separateThousands(this.score)}`);
|
||||
}
|
||||
|
||||
this.timeout = setTimeout(() => {
|
||||
this.stop();
|
||||
}, 1000)
|
||||
}
|
||||
createCoin(position) {
|
||||
let coin = new THREE.Mesh(this.coin_geometry, this.coin_material);
|
||||
let coin_glow = new THREE.Mesh(this.coin_geometry2, this.coin_material2);
|
||||
coin.add(coin_glow);
|
||||
coin.position.copy(position);
|
||||
coin.position.y = 10;
|
||||
coin.scale.y = 1.4;
|
||||
this.world.add(coin);
|
||||
this.coins.push(coin);
|
||||
|
||||
if (this.coins.length > 40) {
|
||||
this.world.remove(this.coins.shift());
|
||||
}
|
||||
}
|
||||
collectCoin(coin) {
|
||||
this.score += 5;
|
||||
setTimeout(() => {
|
||||
this.coins.remove(coin);
|
||||
}, 40);
|
||||
let interval = setInterval(() => {
|
||||
coin.position.y *= 1.1;
|
||||
coin.scale.multiplyScalar(0.95);
|
||||
}, 16)
|
||||
setTimeout(() => {
|
||||
clearInterval(interval);
|
||||
this.coins.remove(coin);
|
||||
this.world.remove(coin);
|
||||
}, 150);
|
||||
}
|
||||
generatePathStep() {
|
||||
this.track.rotation.y += this.path[0];
|
||||
let offset = new THREE.Vector3(0, 0, -this.step * this.track.scale.x);
|
||||
offset.applyAxisAngle(this.turn_axis, this.track.rotation.y);
|
||||
//offset.x *= this.track.scale.x;
|
||||
//offset.z *= this.track.scale.x;
|
||||
this.track.position.sub(offset);
|
||||
|
||||
if (Math.random() < 1/24) {
|
||||
// Coin
|
||||
let waypoint = this.waypoints[this.collision_length - 2];
|
||||
let position = Reusable.vec1.copy(waypoint.position);
|
||||
position.applyMatrix4(this.track.matrix);
|
||||
this.createCoin(position);
|
||||
}
|
||||
|
||||
this.path.shift();
|
||||
this.addPathPoint();
|
||||
this.score++;
|
||||
}
|
||||
getClosestWaypoint() {
|
||||
let position = new THREE.Vector3();
|
||||
this.track.worldToLocal(position);
|
||||
let distance = new THREE.Vector3();
|
||||
let waypoints_in_reach = this.waypoints.filter((waypoint, index) => {
|
||||
waypoint.index = index;
|
||||
waypoint.distance = distance.copy(position).sub(waypoint.position).length();
|
||||
return waypoint.distance <= (this.track_width + 2);
|
||||
});
|
||||
waypoints_in_reach.sort((a, b) => a.distance - b.distance);
|
||||
return waypoints_in_reach[0];
|
||||
}
|
||||
updateGeometry() {
|
||||
let segment_width = 2;
|
||||
let angle = 0;
|
||||
let trailhead = new THREE.Vector3(0, 0, 0);
|
||||
let offset1 = new THREE.Vector3(0, 0, 0);
|
||||
let offset2 = new THREE.Vector3(0, 0, 0);
|
||||
let offset3 = new THREE.Vector3(0, 0, 0);
|
||||
let offset4 = new THREE.Vector3(0, 0, 0);
|
||||
|
||||
let quad_index = 0;
|
||||
let indices = [];
|
||||
let positions = [];
|
||||
|
||||
this.waypoints.empty();
|
||||
|
||||
let i = 0;
|
||||
for (let curvature of this.path) {
|
||||
let old_angle = angle;
|
||||
angle += curvature;
|
||||
if (i < this.collision_length) {
|
||||
this.waypoints.push({position: new THREE.Vector3().copy(trailhead)});
|
||||
}
|
||||
for (let x = -3; x < 3; x++) {
|
||||
offset1.set(x * segment_width, 0, 0)
|
||||
offset1.applyAxisAngle(this.turn_axis, old_angle);
|
||||
offset1.add(trailhead);
|
||||
positions.push(offset1.x, offset1.y, offset1.z);
|
||||
|
||||
offset2.set((x+1) * segment_width, 0, 0)
|
||||
offset2.applyAxisAngle(this.turn_axis, old_angle);
|
||||
offset2.add(trailhead);
|
||||
positions.push(offset2.x, offset2.y, offset2.z);
|
||||
|
||||
offset3.set(x * segment_width, 0, this.step);
|
||||
offset3.applyAxisAngle(this.turn_axis, angle);
|
||||
offset3.add(trailhead);
|
||||
positions.push(offset3.x, offset3.y, offset3.z);
|
||||
|
||||
offset4.set((x+1) * segment_width, 0, this.step);
|
||||
offset4.applyAxisAngle(this.turn_axis, angle);
|
||||
offset4.add(trailhead);
|
||||
positions.push(offset4.x, offset4.y, offset4.z);
|
||||
|
||||
indices.push(quad_index*4 + 0, quad_index*4 + 3, quad_index*4 + 1, quad_index*4 + 0, quad_index*4 + 2, quad_index*4 + 3);
|
||||
|
||||
quad_index++;
|
||||
}
|
||||
offset1.set(0, -0.005, this.step);
|
||||
offset1.applyAxisAngle(this.turn_axis, angle);
|
||||
trailhead.add(offset1);
|
||||
i++;
|
||||
}
|
||||
this.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
|
||||
this.geometry.setIndex(indices);
|
||||
}
|
||||
addPathPoint(straight) {
|
||||
let last_point = this.path.last() || 0;
|
||||
let influence = straight ? 0 : Math.pow(Math.randomab(-1, 1), 3) * 0.5;
|
||||
this.path.push(Math.lerp(last_point, influence, 0.075));
|
||||
}
|
||||
|
||||
}
|
||||
RainbowRace.start = () => {
|
||||
if (!RainbowRace.current_race) {
|
||||
RainbowRace.current_race = new RainbowRace();
|
||||
}
|
||||
RainbowRace.current_race.start();
|
||||
}
|
||||
RainbowRace.stop = () => {
|
||||
RainbowRace.current_race.stop();
|
||||
}
|
||||
Interface.definePanels(() => {
|
||||
let buttons = [
|
||||
Interface.createElement('div', {}, Blockbench.getIconNode('play_arrow')),
|
||||
Interface.createElement('div', {}, Blockbench.getIconNode('pause')),
|
||||
];
|
||||
let controls = Interface.createElement('div', {id: 'rainbow_game_controls'}, buttons);
|
||||
Interface.preview.append(controls);
|
||||
buttons[0].onclick = RainbowRace.start;
|
||||
buttons[1].onclick = RainbowRace.stop;
|
||||
|
||||
Blockbench.addCSS(`
|
||||
#rainbow_game_controls {
|
||||
width: 64px;
|
||||
height: 30px;
|
||||
margin: auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 1px;
|
||||
background-color: var(--color-ui);
|
||||
display: flex;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
border-bottom-right-radius: 2px;
|
||||
border-bottom-left-radius: 2px;
|
||||
}
|
||||
#rainbow_game_controls > div {
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
#rainbow_game_controls > div:hover {
|
||||
color: var(--color-light);
|
||||
}
|
||||
`);
|
||||
})
|
||||
window.RainbowRace = RainbowRace;
|
||||
}
|
||||
|
||||
|
||||
//Init/Update
|
||||
function initCanvas() {
|
||||
|
@ -672,6 +672,7 @@ class ReferenceImage {
|
||||
static image_extensions = ['png', 'jpg', 'jpeg', 'bmp', 'tiff', 'tif', 'gif'];
|
||||
static video_extensions = ['mp4', 'wmv', 'mov'];
|
||||
}
|
||||
ReferenceImage.supported_extensions = ['png', 'jpg', 'jpeg', 'webp', 'bmp', 'tiff', 'tif', 'gif'];
|
||||
ReferenceImage.prototype.menu = new Menu([
|
||||
new MenuSeparator('settings'),
|
||||
{
|
||||
|
@ -194,8 +194,14 @@ class TextureLayer {
|
||||
}
|
||||
down_layer.expandTo(this.offset, this.offset.slice().V2_add(this.width, this.height));
|
||||
down_layer.ctx.imageSmoothingEnabled = false;
|
||||
down_layer.ctx.filter = `opacity(${this.opacity / 100})`;
|
||||
down_layer.ctx.globalCompositeOperation = Painter.getBlendModeCompositeOperation(this.blend_mode);
|
||||
|
||||
down_layer.ctx.drawImage(this.canvas, this.offset[0] - down_layer.offset[0], this.offset[1] - down_layer.offset[1], this.scaled_width, this.scaled_height);
|
||||
|
||||
down_layer.ctx.filter = '';
|
||||
down_layer.ctx.globalCompositeOperation = 'source-over';
|
||||
|
||||
let index = this.texture.layers.indexOf(this);
|
||||
this.texture.layers.splice(index, 1);
|
||||
if (this.texture.selected_layer == this) {
|
||||
|
@ -355,7 +355,9 @@ const Painter = {
|
||||
if (Painter.currentPixel[0] === x && Painter.currentPixel[1] === y) return;
|
||||
Painter.currentPixel = [x, y];
|
||||
Painter.brushChanges = true;
|
||||
UVEditor.vue.last_brush_position.V2_set(x, y);
|
||||
if (!is_opposite) {
|
||||
UVEditor.vue.last_brush_position.V2_set(x, y);
|
||||
}
|
||||
let uvFactorX = texture.width / texture.getUVWidth();
|
||||
let uvFactorY = texture.display_height / texture.getUVHeight();
|
||||
|
||||
|
@ -1242,34 +1242,58 @@ class Texture {
|
||||
})
|
||||
|
||||
scope.edit((canvas) => {
|
||||
let temp_canvas = document.createElement('canvas');
|
||||
let temp_ctx = temp_canvas.getContext('2d');
|
||||
let resizeCanvas = (ctx) => {
|
||||
temp_canvas.width = ctx.canvas.width;
|
||||
temp_canvas.height = ctx.canvas.height;
|
||||
temp_ctx.drawImage(ctx.canvas, 0, 0);
|
||||
|
||||
scope.canvas.width = formResult.size[0];
|
||||
scope.canvas.height = formResult.size[1];
|
||||
let new_ctx = scope.canvas.getContext('2d');
|
||||
new_ctx.imageSmoothingEnabled = false;
|
||||
|
||||
if (formResult.mode == 'crop') {
|
||||
switch (formResult.fill) {
|
||||
case 'transparent':
|
||||
new_ctx.drawImage(scope.img, 0, 0, scope.width, scope.height);
|
||||
break;
|
||||
case 'color':
|
||||
new_ctx.fillStyle = ColorPanel.get();
|
||||
new_ctx.fillRect(0, 0, formResult.size[0], formResult.size[1])
|
||||
new_ctx.clearRect(0, 0, scope.width, scope.height)
|
||||
new_ctx.drawImage(scope.img, 0, 0, scope.width, scope.height);
|
||||
break;
|
||||
case 'repeat':
|
||||
for (var x = 0; x < formResult.size[0]; x += scope.width) {
|
||||
for (var y = 0; y < formResult.size[1]; y += scope.height) {
|
||||
new_ctx.drawImage(scope.img, x, y, scope.width, scope.height);
|
||||
if (ctx.canvas.width == scope.canvas.width && ctx.canvas.height == scope.canvas.height) {
|
||||
ctx.canvas.width = formResult.size[0];
|
||||
ctx.canvas.height = formResult.size[1];
|
||||
} else if (formResult.mode == 'scale') {
|
||||
ctx.canvas.width = Math.round(ctx.canvas.width * (formResult.size[0] / scope.canvas.width));
|
||||
ctx.canvas.height = Math.round(ctx.canvas.height * (formResult.size[1] / scope.canvas.height));
|
||||
}
|
||||
ctx.imageSmoothingEnabled = false;
|
||||
|
||||
if (formResult.mode == 'crop') {
|
||||
switch (formResult.fill) {
|
||||
case 'transparent':
|
||||
ctx.drawImage(temp_canvas, 0, 0, temp_canvas.width, temp_canvas.height);
|
||||
break;
|
||||
case 'color':
|
||||
ctx.fillStyle = ColorPanel.get();
|
||||
ctx.fillRect(0, 0, formResult.size[0], formResult.size[1])
|
||||
ctx.clearRect(0, 0, temp_canvas.width, temp_canvas.height)
|
||||
ctx.drawImage(temp_canvas, 0, 0, temp_canvas.width, temp_canvas.height);
|
||||
break;
|
||||
case 'repeat':
|
||||
for (var x = 0; x < formResult.size[0]; x += temp_canvas.width) {
|
||||
for (var y = 0; y < formResult.size[1]; y += temp_canvas.height) {
|
||||
ctx.drawImage(temp_canvas, x, y, temp_canvas.width, temp_canvas.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ctx.drawImage(temp_canvas, 0, 0, ctx.canvas.width, ctx.canvas.height);
|
||||
}
|
||||
}
|
||||
|
||||
if (scope.layers_enabled && scope.layers.length) {
|
||||
for (let layer of scope.layers) {
|
||||
resizeCanvas(layer.ctx);
|
||||
if (formResult.mode == 'scale') {
|
||||
layer.offset[0] = Math.round(layer.offset[0] * (formResult.size[0] / scope.width));
|
||||
layer.offset[1] = Math.round(layer.offset[1] * (formResult.size[1] / scope.height));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
new_ctx.drawImage(scope.img, 0, 0, formResult.size[0], formResult.size[1]);
|
||||
resizeCanvas(scope.ctx);
|
||||
}
|
||||
|
||||
scope.width = formResult.size[0];
|
||||
scope.height = formResult.size[1];
|
||||
|
||||
@ -1326,6 +1350,7 @@ class Texture {
|
||||
|
||||
Undo.finishEdit('Resize texture');
|
||||
|
||||
UVEditor.vue.updateTexture();
|
||||
setTimeout(updateSelection, 100);
|
||||
}
|
||||
})
|
||||
@ -1658,7 +1683,7 @@ class Texture {
|
||||
this.ctx.filter = '';
|
||||
this.ctx.globalCompositeOperation = 'source-over';
|
||||
|
||||
if (!Format.image_editor) {
|
||||
if (!Format.image_editor && this.getMaterial()) {
|
||||
this.getMaterial().map.needsUpdate = true;
|
||||
}
|
||||
if (update_data_url) {
|
||||
|
@ -572,6 +572,7 @@ const UVEditor = {
|
||||
if (isNaN(face.uv[vkey][axis])) face.uv[vkey][axis] = start;
|
||||
})
|
||||
})
|
||||
Mesh.preview_controller.updateUV(mesh);
|
||||
})
|
||||
this.displayTools()
|
||||
this.disableAutoUV()
|
||||
@ -729,14 +730,14 @@ const UVEditor = {
|
||||
face.uv[0] = Math.min(face.uv[0], face.uv[2]);
|
||||
face.uv[1] = Math.min(face.uv[1], face.uv[3]);
|
||||
if (side == 'north' || side == 'south') {
|
||||
width = obj.size(0);
|
||||
height = obj.size(1);
|
||||
width = Math.abs(obj.size(0));
|
||||
height = Math.abs(obj.size(1));
|
||||
} else if (side == 'east' || side == 'west') {
|
||||
width = obj.size(2);
|
||||
height = obj.size(1);
|
||||
width = Math.abs(obj.size(2));
|
||||
height = Math.abs(obj.size(1));
|
||||
} else if (side == 'up' || side == 'down') {
|
||||
width = obj.size(0);
|
||||
height = obj.size(2);
|
||||
width = Math.abs(obj.size(0));
|
||||
height = Math.abs(obj.size(2));
|
||||
}
|
||||
if (face.rotation % 180) {
|
||||
[width, height] = [height, width];
|
||||
@ -2888,21 +2889,28 @@ Interface.definePanels(function() {
|
||||
})
|
||||
|
||||
} else if (element instanceof Mesh) {
|
||||
function setUV(angle) {
|
||||
scope.selected_faces.forEach(fkey => {
|
||||
let face = element.faces[fkey];
|
||||
if (!face) return;
|
||||
let sin = Math.sin(Math.degToRad(angle));
|
||||
let cos = Math.cos(Math.degToRad(angle));
|
||||
face.vertices.forEach(vkey => {
|
||||
if (!face.uv[vkey]) return;
|
||||
face.uv[vkey][0] = face.old_uv[vkey][0] - face_center[0];
|
||||
face.uv[vkey][1] = face.old_uv[vkey][1] - face_center[1];
|
||||
let a = (face.uv[vkey][0] * cos - face.uv[vkey][1] * sin);
|
||||
let b = (face.uv[vkey][0] * sin + face.uv[vkey][1] * cos);
|
||||
face.uv[vkey][0] = Math.clamp(a + face_center[0], 0, UVEditor.getUVWidth());
|
||||
face.uv[vkey][1] = Math.clamp(b + face_center[1], 0, UVEditor.getUVHeight());
|
||||
})
|
||||
})
|
||||
}
|
||||
setUV(angle);
|
||||
let e = 0.6;
|
||||
scope.selected_faces.forEach(fkey => {
|
||||
let face = element.faces[fkey];
|
||||
if (!face) return;
|
||||
face.vertices.forEach(vkey => {
|
||||
if (!face.uv[vkey]) return;
|
||||
let sin = Math.sin(Math.degToRad(angle));
|
||||
let cos = Math.cos(Math.degToRad(angle));
|
||||
face.uv[vkey][0] = face.old_uv[vkey][0] - face_center[0];
|
||||
face.uv[vkey][1] = face.old_uv[vkey][1] - face_center[1];
|
||||
let a = (face.uv[vkey][0] * cos - face.uv[vkey][1] * sin);
|
||||
let b = (face.uv[vkey][0] * sin + face.uv[vkey][1] * cos);
|
||||
face.uv[vkey][0] = Math.clamp(a + face_center[0], 0, UVEditor.getUVWidth());
|
||||
face.uv[vkey][1] = Math.clamp(b + face_center[1], 0, UVEditor.getUVHeight());
|
||||
})
|
||||
let e = 0.6;
|
||||
face.vertices.forEach((vkey, i) => {
|
||||
for (let j = i+1; j < face.vertices.length; j++) {
|
||||
let relative_angle = Math.radToDeg(Math.PI + Math.atan2(
|
||||
@ -2910,16 +2918,21 @@ Interface.definePanels(function() {
|
||||
face.uv[vkey][0] - face.uv[face.vertices[j]][0],
|
||||
)) % 180;
|
||||
if (Math.abs(relative_angle - 90) < e) {
|
||||
straight_angle = angle;
|
||||
straight_angle = angle - (relative_angle - 90);
|
||||
if (scope.helper_lines.x == -1) scope.helper_lines.x = face.uv[vkey][0];
|
||||
break;
|
||||
}
|
||||
if (relative_angle < e || 180 - relative_angle < e) {
|
||||
straight_angle = angle;
|
||||
straight_angle = angle - (relative_angle > 90 ? (relative_angle-180) : relative_angle);
|
||||
if (scope.helper_lines.y == -1) scope.helper_lines.y = face.uv[vkey][1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
if (straight_angle) {
|
||||
setUV(straight_angle);
|
||||
}
|
||||
}
|
||||
})
|
||||
UVEditor.turnMapping()
|
||||
|
@ -384,6 +384,7 @@
|
||||
|
||||
"message.load_images.title": "Load Images",
|
||||
"message.load_images.edit_image": "Edit Image",
|
||||
"message.load_images.add_image": "Add Image",
|
||||
|
||||
"message.import_palette.replace_palette": "Replace old palette",
|
||||
"message.import_palette.threshold": "Merge Threshold",
|
||||
|
20
package-lock.json
generated
20
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Blockbench",
|
||||
"version": "4.9.0-beta.2",
|
||||
"version": "4.9.4",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@ -2841,9 +2841,9 @@
|
||||
}
|
||||
},
|
||||
"electron": {
|
||||
"version": "26.6.1",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-26.6.1.tgz",
|
||||
"integrity": "sha512-4Vz9u0Jt/khPa/en2l8Jv6SWEfsK/ieWYtchl5j0clbNSjdeTucnEFOhz9B9WwsAmfQjxBnpuMZpmdBuyxq+wg==",
|
||||
"version": "26.6.9",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-26.6.9.tgz",
|
||||
"integrity": "sha512-R4uWUzwUwlYwFPS+BY4Dg9KzbIpqdfiLepmcrYHHOUb0dYf2TeYtFPBGYo3kF2L0JmLy1lFtIExCRaMB+J6yow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@electron/get": "^2.0.0",
|
||||
@ -2852,9 +2852,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "18.18.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.12.tgz",
|
||||
"integrity": "sha512-G7slVfkwOm7g8VqcEF1/5SXiMjP3Tbt+pXDU3r/qhlM2KkGm786DUD4xyMA2QzEElFrv/KZV9gjygv4LnkpbMQ==",
|
||||
"version": "18.19.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.17.tgz",
|
||||
"integrity": "sha512-SzyGKgwPzuWp2SHhlpXKzCX0pIOfcI4V2eF37nNBJOhwlegQ83omtVQ1XxZpDE06V/d6AQvfQdPfnw0tRC//Ng==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"undici-types": "~5.26.4"
|
||||
@ -3563,9 +3563,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
||||
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
|
||||
"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Blockbench",
|
||||
"description": "Low-poly modeling and animation software",
|
||||
"version": "4.9.3",
|
||||
"version": "4.9.4",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"author": {
|
||||
"name": "JannisX11",
|
||||
@ -109,7 +109,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"blockbench-types": "^4.6.1",
|
||||
"electron": "^26.6.1",
|
||||
"electron": "^26.6.9",
|
||||
"electron-builder": "^23.6.0",
|
||||
"electron-notarize": "^1.0.0",
|
||||
"webpack": "^5.74.0",
|
||||
|
Loading…
Reference in New Issue
Block a user