Merge branch 'master' into gh-pages
This commit is contained in:
commit
fcc644a3ad
@ -24,7 +24,7 @@
|
||||
<script>
|
||||
if (typeof module === 'object') {window.module = module; module = undefined;}//jQuery Fix
|
||||
const isApp = typeof require !== 'undefined';
|
||||
const appVersion = '3.6.3';
|
||||
const appVersion = '3.6.4';
|
||||
</script>
|
||||
<div id="loading_error_message" style="display: none;">
|
||||
<div>An error occurred while loading Blockbench</div>
|
||||
|
@ -1382,7 +1382,7 @@ const Animator = {
|
||||
|
||||
animator.sound.forEach(kf => {
|
||||
if (!ani_tag.sound_effects) ani_tag.sound_effects = {};
|
||||
let timecode = Math.clamp(trimFloatNumber(Math.round(kf.time*60)/60), 0) + '';
|
||||
let timecode = trimFloatNumber(Timeline.snapTime(kf.time));
|
||||
if (!timecode.includes('.')) {
|
||||
timecode += '.0';
|
||||
}
|
||||
@ -1392,7 +1392,7 @@ const Animator = {
|
||||
})
|
||||
animator.particle.forEach(kf => {
|
||||
if (!ani_tag.particle_effects) ani_tag.particle_effects = {};
|
||||
let timecode = Math.clamp(trimFloatNumber(Math.round(kf.time*60)/60), 0) + '';
|
||||
let timecode = trimFloatNumber(Timeline.snapTime(kf.time));
|
||||
if (!timecode.includes('.')) {
|
||||
timecode += '.0';
|
||||
}
|
||||
@ -1406,7 +1406,7 @@ const Animator = {
|
||||
})
|
||||
animator.timeline.forEach(kf => {
|
||||
if (!ani_tag.timeline) ani_tag.timeline = {};
|
||||
let timecode = Math.clamp(trimFloatNumber(Math.round(kf.time*60)/60), 0) + '';
|
||||
let timecode = trimFloatNumber(Timeline.snapTime(kf.time));
|
||||
if (!timecode.includes('.')) {
|
||||
timecode += '.0';
|
||||
}
|
||||
@ -1423,7 +1423,7 @@ const Animator = {
|
||||
if (!channels[kf.channel]) {
|
||||
channels[kf.channel] = {};
|
||||
}
|
||||
let timecode = Math.clamp(trimFloatNumber(Math.round(kf.time*60)/60), 0) + '';
|
||||
let timecode = trimFloatNumber(Timeline.snapTime(kf.time));
|
||||
if (!timecode.includes('.')) {
|
||||
timecode = timecode + '.0';
|
||||
}
|
||||
@ -1986,7 +1986,8 @@ Molang.variableHandler = function (variable) {
|
||||
var i = 0;
|
||||
while (i < inputs.length) {
|
||||
let key, val;
|
||||
[key, val] = inputs[i].replace(/[\s;]/g, '').split('=')
|
||||
[key, val] = inputs[i].split(/=(.+)/);
|
||||
key = key.replace(/[\s;]/g, '');
|
||||
if (key === variable) {
|
||||
return Molang.parse(val)
|
||||
}
|
||||
|
@ -18,13 +18,17 @@ if (isApp === false) {
|
||||
Blockbench.browser = 'safari'
|
||||
} else if (!!document.documentMode) {
|
||||
Blockbench.browser = 'internet_explorer'
|
||||
} else if (!!window.StyleMedia) {
|
||||
} else if (!!window.chrome && window.navigator.userAgent.toLowerCase().includes('edg')) {
|
||||
Blockbench.browser = 'edge'
|
||||
} else if (!!window.StyleMedia) {
|
||||
Blockbench.browser = 'proprietary_edge'
|
||||
} else if (!!window.chrome && !window.chrome.webstore) {
|
||||
Blockbench.browser = 'chromium'
|
||||
}
|
||||
if (navigator.appVersion.indexOf("Win") != -1) OSName = 'Windows';
|
||||
if (navigator.appVersion.indexOf("Mac") != -1) OSName = 'MacOS';
|
||||
if (navigator.appVersion.indexOf("Linux") != -1)OSName = 'Linux';
|
||||
if (['edge', 'internet_explorer'].includes(Blockbench.browser)) {
|
||||
if (navigator.appVersion.indexOf("Win") != -1) Blockbench.operating_system = 'Windows';
|
||||
if (navigator.appVersion.indexOf("Mac") != -1) Blockbench.operating_system = 'MacOS';
|
||||
if (navigator.appVersion.indexOf("Linux") != -1) Blockbench.operating_system = 'Linux';
|
||||
if (['proprietary_edge', 'internet_explorer'].includes(Blockbench.browser)) {
|
||||
alert(capitalizeFirstLetter(Blockbench.browser)+' does not support Blockbench')
|
||||
}
|
||||
$('.local_only').remove()
|
||||
|
@ -817,7 +817,9 @@ class BarSelect extends Widget {
|
||||
}
|
||||
this.value = key;
|
||||
let name = this.getNameFor(key);
|
||||
$(this.node).find('bb-select').text(name)
|
||||
this.nodes.forEach(node => {
|
||||
$(node).find('bb-select').text(name)
|
||||
})
|
||||
return this;
|
||||
}
|
||||
get() {
|
||||
@ -1453,14 +1455,6 @@ const BARS = {
|
||||
default_place: true
|
||||
})
|
||||
|
||||
// update 3.4
|
||||
if (!Toolbars.tools.children.includes(BarItems.draw_shape_tool)) {
|
||||
Toolbars.tools.add(BarItems.draw_shape_tool, -1)
|
||||
}
|
||||
if (!Toolbars.tools.children.includes(BarItems.copy_paste_tool)) {
|
||||
Toolbars.tools.add(BarItems.copy_paste_tool, -1)
|
||||
}
|
||||
|
||||
Toolbars.element_position = new Toolbar({
|
||||
id: 'element_position',
|
||||
children: [
|
||||
@ -1517,10 +1511,6 @@ const BARS = {
|
||||
'load_palette',
|
||||
]
|
||||
})
|
||||
//update 3.5
|
||||
if (!Toolbars.palette.children.includes(BarItems.load_palette)) {
|
||||
Toolbars.palette.add(BarItems.load_palette)
|
||||
}
|
||||
Toolbars.color_picker = new Toolbar({
|
||||
id: 'color_picker',
|
||||
children: [
|
||||
|
@ -588,7 +588,18 @@ function addStartScreenSection(id, data) {
|
||||
addStartScreenSection(data.new_version)
|
||||
}
|
||||
if (data.psa) {
|
||||
addStartScreenSection(data.psa)
|
||||
(function() {
|
||||
if (typeof data.psa.version == 'string') {
|
||||
if (data.psa.version.includes('-')) {
|
||||
limits = data.psa.version.split('-');
|
||||
if (limits[0] && compareVersions(limits[0], Blockbench.version)) return;
|
||||
if (limits[1] && compareVersions(Blockbench.version, limits[1])) return;
|
||||
} else {
|
||||
if (data.psa.version != Blockbench.version) return;
|
||||
}
|
||||
}
|
||||
addStartScreenSection(data.psa)
|
||||
})()
|
||||
}
|
||||
|
||||
})
|
||||
@ -628,21 +639,10 @@ function addStartScreenSection(id, data) {
|
||||
]
|
||||
})
|
||||
}
|
||||
//Discord
|
||||
if (Blockbench.startup_count < 6) {
|
||||
addStartScreenSection({
|
||||
color: '#7289da',
|
||||
text_color: '#ffffff',
|
||||
graphic: {type: 'icon', icon: 'fab.fa-discord'},
|
||||
text: [
|
||||
{type: 'h1', text: 'Discord Server'},
|
||||
{text: 'You need help with modeling or you want to chat about Blockbench? Join the [Modeling Discord](https://discord.gg/WVHg5kH)!'}
|
||||
],
|
||||
last: true
|
||||
})
|
||||
}
|
||||
//Twitter
|
||||
let twitter_ad;
|
||||
if (Blockbench.startup_count < 20 && Blockbench.startup_count % 5 === 4) {
|
||||
twitter_ad = true;
|
||||
addStartScreenSection({
|
||||
color: '#1da1f2',
|
||||
text_color: '#ffffff',
|
||||
@ -654,6 +654,19 @@ function addStartScreenSection(id, data) {
|
||||
last: true
|
||||
})
|
||||
}
|
||||
//Discord
|
||||
if (Blockbench.startup_count < 6 && !twitter_ad) {
|
||||
addStartScreenSection({
|
||||
color: '#7289da',
|
||||
text_color: '#ffffff',
|
||||
graphic: {type: 'icon', icon: 'fab.fa-discord'},
|
||||
text: [
|
||||
{type: 'h1', text: 'Discord Server'},
|
||||
{text: 'You need help with modeling or you want to chat about Blockbench? Join the [Modeling Discord](https://discord.gg/WVHg5kH)!'}
|
||||
],
|
||||
last: true
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
})()
|
||||
|
@ -25,6 +25,7 @@ var codec = new Codec('project', {
|
||||
var model = {
|
||||
meta: {
|
||||
format_version: FORMATV,
|
||||
creation_time: Math.round(new Date().getTime()/1000),
|
||||
model_format: Format.id,
|
||||
box_uv: Project.box_uv
|
||||
}
|
||||
|
@ -394,6 +394,11 @@ function loadModelFile(file) {
|
||||
}
|
||||
}
|
||||
EditSession.initNewModel()
|
||||
if (!Format) {
|
||||
Modes.options.start.select()
|
||||
Modes.vue.$forceUpdate()
|
||||
Blockbench.dispatchEvent('close_project');
|
||||
}
|
||||
}
|
||||
}
|
||||
var Extruder = {
|
||||
@ -871,8 +876,8 @@ BARS.defineActions(function() {
|
||||
click: function () {
|
||||
if (isApp) {
|
||||
saveTextures()
|
||||
if (Format.codec && Format.codec.compile) {
|
||||
if (ModelMeta.export_path) {
|
||||
if (Format) {
|
||||
if (ModelMeta.export_path && Format.codec && Format.codec.compile) {
|
||||
Format.codec.write(Format.codec.compile(), ModelMeta.export_path)
|
||||
} else if (ModelMeta.save_path) {
|
||||
Codecs.project.write(Codecs.project.compile(), ModelMeta.save_path);
|
||||
|
@ -135,10 +135,10 @@ function newProject(format, force) {
|
||||
if (Format) {
|
||||
Project.reset();
|
||||
}
|
||||
Modes.options.edit.select();
|
||||
if (format instanceof ModelFormat) {
|
||||
format.select();
|
||||
}
|
||||
Modes.options.edit.select();
|
||||
Blockbench.dispatchEvent('new_project');
|
||||
return true;
|
||||
} else {
|
||||
|
@ -58,9 +58,10 @@ const TextureGenerator = {
|
||||
var dialog2 = new Dialog({
|
||||
id: 'texture_simple',
|
||||
title: tl('action.create_texture'),
|
||||
width: 400,
|
||||
form: {
|
||||
color: {label: 'data.color', type: 'color', colorpicker: TextureGenerator.background_color},
|
||||
resolution: {label: 'dialog.create_texture.resolution', type: 'number', value: 16, min: 16, max: 2048},
|
||||
resolution: {label: 'dialog.create_texture.resolution', type: 'vector', dimensions: 2, value: [16, 16], min: 16, max: 2048},
|
||||
},
|
||||
onConfirm: function(results2) {
|
||||
$.extend(results, results2)
|
||||
@ -76,8 +77,8 @@ const TextureGenerator = {
|
||||
if (typeof options !== 'object') {
|
||||
options = {}
|
||||
}
|
||||
if (isNaN(options.resolution) || !options.resolution) {
|
||||
options.resolution = 16
|
||||
if (!options.resolution || isNaN(options.resolution[0]) || isNaN(options.resolution[1])) {
|
||||
options.resolution = [16, 16]
|
||||
}
|
||||
if (options.color === undefined) {
|
||||
options.color = new tinycolor().toRgb()
|
||||
@ -88,7 +89,6 @@ const TextureGenerator = {
|
||||
var texture = new Texture({
|
||||
mode: 'bitmap',
|
||||
keep_size: true,
|
||||
res: options.resolution,
|
||||
name: options.name ? options.name : 'texture',
|
||||
folder: options.folder ? options.folder : 'block'
|
||||
})
|
||||
@ -125,7 +125,7 @@ const TextureGenerator = {
|
||||
}
|
||||
} else {
|
||||
Undo.initEdit({textures: [], selected_texture: true})
|
||||
TextureGenerator.generateBlank(options.resolution, options.resolution, options.color, makeTexture)
|
||||
TextureGenerator.generateBlank(options.resolution[1], options.resolution[0], options.color, makeTexture)
|
||||
}
|
||||
},
|
||||
generateBlank(height, width, color, cb) {
|
||||
|
@ -992,6 +992,7 @@ class Texture {
|
||||
click: function(texture) { texture.openMenu()}
|
||||
}
|
||||
])
|
||||
Texture.prototype.currentFrame = 0;
|
||||
Texture.all = textures;
|
||||
Texture.getDefault = function() {
|
||||
if (Texture.selected && Texture.all.includes(Texture.selected)) {
|
||||
@ -1184,9 +1185,7 @@ TextureAnimator = {
|
||||
var animated_tex = []
|
||||
textures.forEach(function(tex, i) {
|
||||
if (tex.frameCount > 1) {
|
||||
if (tex.currentFrame === undefined) {
|
||||
tex.currentFrame = 0
|
||||
} else if (tex.currentFrame >= tex.frameCount-1) {
|
||||
if (tex.currentFrame >= tex.frameCount-1) {
|
||||
tex.currentFrame = 0
|
||||
} else {
|
||||
tex.currentFrame++;
|
||||
|
@ -412,15 +412,15 @@ function scaleAll(save, size) {
|
||||
if ($('#model_scale_'+getAxisLetter(i)+'_axis').is(':checked')) {
|
||||
|
||||
if (obj.from) {
|
||||
obj.from[i] = (obj.before.from[i] - ogn) * size;
|
||||
obj.from[i] = (obj.before.from[i] - obj.inflate - ogn) * size;
|
||||
if (obj.from[i] + ogn > 32 || obj.from[i] + ogn < -16) overflow.push(obj);
|
||||
obj.from[i] = limitToBox(obj.from[i] + ogn, -obj.inflate);
|
||||
obj.from[i] = limitToBox(obj.from[i] + obj.inflate + ogn, -obj.inflate);
|
||||
}
|
||||
|
||||
if (obj.to) {
|
||||
obj.to[i] = (obj.before.to[i] - ogn) * size;
|
||||
obj.to[i] = (obj.before.to[i] + obj.inflate - ogn) * size;
|
||||
if (obj.to[i] + ogn > 32 || obj.to[i] + ogn < -16) overflow.push(obj);
|
||||
obj.to[i] = limitToBox(obj.to[i] + ogn, obj.inflate);
|
||||
obj.to[i] = limitToBox(obj.to[i] - obj.inflate + ogn, obj.inflate);
|
||||
if (Format.integer_size) {
|
||||
obj.to[i] = obj.from[i] + Math.round(obj.to[i] - obj.from[i])
|
||||
}
|
||||
|
@ -130,8 +130,6 @@ var Undo = {
|
||||
var scope = this;
|
||||
this.aspects = aspects;
|
||||
|
||||
templog(aspects)
|
||||
|
||||
if (aspects.selection) {
|
||||
this.selection = []
|
||||
selected.forEach(function(obj) {
|
||||
|
@ -28,7 +28,7 @@ const Condition = function(condition, context) {
|
||||
return condition(context)
|
||||
} else if (typeof condition === 'object') {
|
||||
if (condition.modes instanceof Array && condition.modes.includes(Modes.id) === false) return false;
|
||||
if (condition.formats instanceof Array && Format && condition.formats.includes(Format.id) === false) return false;
|
||||
if (condition.formats instanceof Array && condition.formats.includes(Format.id) === false) return false;
|
||||
if (condition.tools instanceof Array && window.Toolbox && condition.tools.includes(Toolbox.selected.id) === false) return false;
|
||||
|
||||
if (condition.method instanceof Function) {
|
||||
|
@ -76,7 +76,7 @@
|
||||
"format.optifine_part.desc": "JPM part for OptiFine entity models",
|
||||
|
||||
"keys.mouse": "Mouse Button %0",
|
||||
"keys.ctrl": "Control",
|
||||
"keys.ctrl": "Ctrl",
|
||||
"keys.shift": "Shift",
|
||||
"keys.alt": "Alt",
|
||||
"keys.meta": "Cmd",
|
||||
|
138
lang/fr.json
138
lang/fr.json
@ -221,7 +221,7 @@
|
||||
"settings.display_grid": "Mode d’affichage",
|
||||
"settings.display_grid.desc": "Afficher la grille en mode affichage",
|
||||
"settings.undo_limit": "Limite d'annulations",
|
||||
"settings.undo_limit.desc": "Nombre d’étapes que vous pouvez annuler",
|
||||
"settings.undo_limit.desc": "Nombre d'étapes gardées en mémoire",
|
||||
"settings.local_move": "Déplacer les cubes selon des axes relatifs",
|
||||
"settings.local_move.desc": "Déplacer les éléments à rotation sur leurs propres axes si possible",
|
||||
"settings.canvas_unselect": "Désélectionner par clic",
|
||||
@ -236,8 +236,8 @@
|
||||
"settings.edit_size.desc": "Résolution de la grille de base sur laquelle les cubes s’alignent",
|
||||
"settings.shift_size": "Résolution shift",
|
||||
"settings.shift_size.desc": "Résolution de la grille en maintenant shift",
|
||||
"settings.ctrl_size": "Résolution ctrl",
|
||||
"settings.ctrl_size.desc": "Résolution de la grille en maintenant ctrl",
|
||||
"settings.ctrl_size": "Résolution Ctrl",
|
||||
"settings.ctrl_size.desc": "Résolution de la grille en maintenant Ctrl",
|
||||
"settings.negative_size": "Taille négative",
|
||||
"settings.negative_size.desc": "Autoriser l'outil d'échelle à utiliser des tailles négatives",
|
||||
"settings.dialog_unsaved_textures": "Textures non sauvegardées",
|
||||
@ -246,12 +246,12 @@
|
||||
"settings.dialog_larger_cubes.desc": "Afficher le dialogue « Modèle trop grand »",
|
||||
"settings.dialog_rotation_limit": "Limites de rotation",
|
||||
"settings.dialog_rotation_limit.desc": "Afficher le dialogue « Limites de rotation »",
|
||||
"settings.minifiedout": "Minimiser les fichiers",
|
||||
"settings.minifiedout": "Minimiser l'exportation",
|
||||
"settings.minifiedout.desc": "Écrire tout le code du modèle sur une ligne",
|
||||
"settings.export_groups": "Exporter les groupes",
|
||||
"settings.export_groups.desc": "Enregistrer les données des groupes dans les fichiers des modèles",
|
||||
"settings.credit": "Crédits",
|
||||
"settings.credit.desc": "Commentaire personnalisé à ajouter en tant que crédit dans les fichiers",
|
||||
"settings.credit.desc": "Commentaire personnalisé à ajouter en tant que crédit dans les fichiers exportés",
|
||||
"settings.default_path": "Chemin par défaut",
|
||||
"settings.default_path.desc": "Dossier à partir duquel Blockbench charge les textures par défaut",
|
||||
"settings.image_editor": "Éditeur d'images",
|
||||
@ -332,10 +332,10 @@
|
||||
"action.uv_dialog.desc": "Ouvrir la boîte de dialogue UV pour voir toutes les faces côte à côte",
|
||||
"action.uv_dialog_full": "Vue complète",
|
||||
"action.uv_dialog_full.desc": "Ouvre la boîte de dialogue UV pour éditer une face en plein écran",
|
||||
"action.undo": "Défaire",
|
||||
"action.undo.desc": "Annule le dernier changement effectué",
|
||||
"action.redo": "Refaire",
|
||||
"action.redo.desc": "Rétablit le dernier changement annulé",
|
||||
"action.undo": "Annuler",
|
||||
"action.undo.desc": "Annule la dernière action effectuée",
|
||||
"action.redo": "Rétablir",
|
||||
"action.redo.desc": "Rétablit la dernière action annulée",
|
||||
"action.copy": "Copier",
|
||||
"action.copy.desc": "Copier les éléments sélectionnés, les données de face ou les paramètres d'affichage",
|
||||
"action.paste": "Coller",
|
||||
@ -351,7 +351,7 @@
|
||||
"action.duplicate": "Dupliquer",
|
||||
"action.duplicate.desc": "Duplique les cubes ou groupes sélectionnés",
|
||||
"action.delete": "Supprimer",
|
||||
"action.delete.desc": "Supprime les cubes ou groupes sélectionnés",
|
||||
"action.delete.desc": "Supprimer les cubes ou groupes sélectionnés",
|
||||
"action.sort_outliner": "Trier la liste",
|
||||
"action.sort_outliner.desc": "Trie la liste par ordre alphabétique",
|
||||
"action.select_window": "Sélectionner…",
|
||||
@ -411,7 +411,7 @@
|
||||
"action.bone_reset_toggle": "Réinitialiser le corps",
|
||||
"action.bone_reset_toggle.desc": "Empêcher le corps d'afficher les cubes du modèle parent",
|
||||
"action.reload": "Recharger Blockbench",
|
||||
"action.reload.desc": "Recharger Blockbench. Cela supprimera tout progrès non sauvegardé.",
|
||||
"action.reload.desc": "Recharger Blockbench. Tout progrès non sauvegardé sera perdu.",
|
||||
"menu.file": "Fichier",
|
||||
"menu.edit": "Édition",
|
||||
"menu.transform": "Transformer",
|
||||
@ -781,22 +781,22 @@
|
||||
"dates.today": "Aujourd'hui",
|
||||
"dates.yesterday": "Hier",
|
||||
"dates.this_week": "Cette semaine",
|
||||
"dates.weeks_ago": "%0 semaines avant",
|
||||
"dates.weeks_ago": "Il y a %0 semaines",
|
||||
"mode.start": "Accueil",
|
||||
"mode.start.new": "Nouveau",
|
||||
"mode.start.recent": "Récent",
|
||||
"format.free": "Modèle libre",
|
||||
"format.free.desc": "Modèle sans restrictions pour Unity etc.",
|
||||
"format.java_block": "Bloc/item Java",
|
||||
"format.java_block.desc": "Model de bloc pour Java Edition. La taille et les rotations sont limitées.",
|
||||
"format.java_block.desc": "Model de bloc pour l'édition Java. La taille et les rotations sont limitées.",
|
||||
"format.bedrock": "Modèle Bedrock",
|
||||
"format.bedrock.desc": "Modèle pour Bedrock Edition",
|
||||
"format.bedrock.desc": "Modèle pour l'édition Bedrock.",
|
||||
"format.bedrock_old": "Ancien modèle Bedrock",
|
||||
"format.bedrock_old.desc": "Modèle d'entité Bedrock antérieur à la 1.12",
|
||||
"format.modded_entity": "Entité modifiée",
|
||||
"format.modded_entity.desc": "Modèle d'entité pour mods. Peut être exporté sous forme de fichiers .java.",
|
||||
"format.modded_entity": "Entité moddée",
|
||||
"format.modded_entity.desc": "Modèle d'entité pour mods. Peut être exporté sous forme de fichier .java.",
|
||||
"format.optifine_entity": "Entité OptiFine",
|
||||
"format.optifine_entity.desc": "Modèle d'entité personnalisé pour OptiFine",
|
||||
"format.optifine_entity.desc": "Modèle d'entité personnalisé pour OptiFine.",
|
||||
"keys.mouse": "Bouton de la souris %0",
|
||||
"message.cleared_blank_faces.title": "Faces vierges",
|
||||
"message.cleared_blank_faces.message": "Blockbench a trouvé %0 cubes sans texture. Voulez-vous retirer ces éléments ?",
|
||||
@ -804,7 +804,7 @@
|
||||
"message.wireframe.disabled": "Vue squelettique désactivée",
|
||||
"dialog.project.box_uv": "Boîte UV",
|
||||
"dialog.convert_project.title": "Convertir le projet",
|
||||
"dialog.convert_project.text": "Êtes-vous sûr·e de vouloir convertir ce projet ? Vous ne pourrez pas revenir en arrière.",
|
||||
"dialog.convert_project.text": "Êtes-vous sûr(e) de vouloir convertir ce projet ? Vous ne pourrez pas revenir en arrière.",
|
||||
"dialog.create_texture.double_use": "Conserver l'occupation de textures multiples",
|
||||
"dialog.model_stats.title": "Statistiques du modèle",
|
||||
"dialog.model_stats.cubes": "Cubes",
|
||||
@ -828,7 +828,7 @@
|
||||
"action.save_project.desc": "Enregistre le modèle actuel en tant que fichier de projet",
|
||||
"action.save_project_as": "Enregistrer le projet sous",
|
||||
"action.save_project_as.desc": "Enregistre le modèle actuel en tant que fichier de projet à un nouvel emplacement",
|
||||
"action.export_over": "Écraser le modèle",
|
||||
"action.export_over": "Enregistrer le modèle",
|
||||
"action.export_over.desc": "Enregistre le modèle, les textures et les animations en écrasant les fichiers",
|
||||
"action.add_locator": "Ajouter un localisateur",
|
||||
"action.add_locator.desc": "Ajoute un nouveau localisateur pour contrôler la position des particules, des laisses, etc.",
|
||||
@ -847,7 +847,7 @@
|
||||
"dialog.settings.search_results": "Résultats de recherche",
|
||||
"settings.animation_snap": "Aligner les animations",
|
||||
"settings.animation_snap.desc": "Intervalle d'alignement des images de l'animation dans la timeline en pas par seconde",
|
||||
"action.import_optifine_part": "Importer une partie OptiFine",
|
||||
"action.import_optifine_part": "Importer partie OptiFine",
|
||||
"action.import_optifine_part.desc": "Importer une partie d'entité pour un modèle OptiFine",
|
||||
"data.locator": "Localisateur",
|
||||
"mode.start.no_recents": "Aucun modèle ouvert récemment",
|
||||
@ -878,7 +878,7 @@
|
||||
"timeline.effects": "Effets",
|
||||
"data.format": "Format",
|
||||
"format.optifine_part": "Partie OptiFine",
|
||||
"format.optifine_part.desc": "Partie JPM pour modèle d'entité OptiFine",
|
||||
"format.optifine_part.desc": "Partie JPM pour modèle d'entité OptiFine.",
|
||||
"action.reverse_keyframes": "Retourner la séquence",
|
||||
"action.reverse_keyframes.desc": "Renverse l'ordre des images sélectionnées",
|
||||
"generic.help": "Aide",
|
||||
@ -968,7 +968,7 @@
|
||||
"action.add_marker.desc": "Définir un repère chronologique",
|
||||
"timeline.pre_effect_script": "Scripte",
|
||||
"format.skin": "Skin",
|
||||
"format.skin.desc": "Modifier les skins des joueurs et des entités",
|
||||
"format.skin.desc": "Modifier les skins de joueurs et d'entités.",
|
||||
"message.sketchfab.setup_guide": "Vous voulez apprendre comment mettre en place des modèles à Sketchfab ? Lire %0",
|
||||
"dialog.skin.title": "Créer un skin",
|
||||
"dialog.skin.model": "Skin",
|
||||
@ -1074,54 +1074,54 @@
|
||||
"settings.large_grid_size": "Taille de la grille",
|
||||
"settings.large_grid_size.desc": "Taille de la grille",
|
||||
"action.load_plugin_from_url": "Charger un plugin via une URL",
|
||||
"action.load_plugin_from_url.desc": "Load a plugin from a server by specifying the URL",
|
||||
"action.cube_counter.desc": "Voir le nombre de bloc actuel et les autres statistiques",
|
||||
"action.unlock_everything": "Tout débloquer",
|
||||
"action.unlock_everything.desc": "Unlock all groups and elements in the outliner.",
|
||||
"action.load_palette": "Load Palette",
|
||||
"action.load_palette.desc": "Load one of the built-in palette presets",
|
||||
"action.toggle_locked": "Toggle Lock",
|
||||
"action.toggle_locked.desc": "Toggle whether the selected elements are locked",
|
||||
"action.apply_display_preset": "Appliquer un préréglage",
|
||||
"action.apply_display_preset.desc": "Apply a default or custom display setting preset",
|
||||
"action.apply_display_preset.here": "Apply To This Slot",
|
||||
"action.apply_display_preset.everywhere": "Apply To All Slots",
|
||||
"action.resolve_keyframe_expressions": "Resolve Keyframe",
|
||||
"action.resolve_keyframe_expressions.desc": "Resolves the math expressions of the selected keyframes",
|
||||
"action.fold_all_animations": "Fold All Animators",
|
||||
"action.timeline_focus.used": "In Use",
|
||||
"action.load_plugin_from_url.desc": "Charge un plugin en fournissant l'URL",
|
||||
"action.cube_counter.desc": "Voir le nombre de cubes actuel et autres stats",
|
||||
"action.unlock_everything": "Débloquer tout",
|
||||
"action.unlock_everything.desc": "Débloquer tous les groupes et éléments dans la liste",
|
||||
"action.load_palette": "Charger palette",
|
||||
"action.load_palette.desc": "Charge l'un des préréglages de palette",
|
||||
"action.toggle_locked": "Basculer verrouillage",
|
||||
"action.toggle_locked.desc": "Verrouille/déverrouille les éléments sélectionnés",
|
||||
"action.apply_display_preset": "Appliquer préréglage",
|
||||
"action.apply_display_preset.desc": "Applique un préréglage d'affichage par défaut, ou personnalisé",
|
||||
"action.apply_display_preset.here": "Appliquer à cet emplacement",
|
||||
"action.apply_display_preset.everywhere": "Appliquer à tous les emplacements",
|
||||
"action.resolve_keyframe_expressions": "Résoudre image",
|
||||
"action.resolve_keyframe_expressions.desc": "Résout les expressions mathématiques des images sélectionnées",
|
||||
"action.fold_all_animations": "Plier tous les animateurs",
|
||||
"action.timeline_focus.used": "Utilisé",
|
||||
"menu.palette.load.empty": "Vide",
|
||||
"switches.lock": "Bloquer",
|
||||
"camera_angle.isometric_right": "Isometrique droit",
|
||||
"camera_angle.isometric_left": "Isometrique gauche",
|
||||
"settings.render_sides": "Render Sides",
|
||||
"settings.render_sides.desc": "Select which side of a face is rendered",
|
||||
"switches.lock": "Verrouiller",
|
||||
"camera_angle.isometric_right": "Isométrique droit",
|
||||
"camera_angle.isometric_left": "Isométrique gauche",
|
||||
"settings.render_sides": "Afficher côtés",
|
||||
"settings.render_sides.desc": "Sélectionner quel côté d'une face est affiché",
|
||||
"settings.render_sides.auto": "Auto",
|
||||
"settings.render_sides.front": "Outside",
|
||||
"settings.render_sides.double": "Inside and Outside",
|
||||
"generic.enable": "Enable",
|
||||
"generic.disable": "Disable",
|
||||
"generic.redacted": "Redacted",
|
||||
"dialog.project.layered_textures": "Layered Textures",
|
||||
"dialog.select_texture.import_all": "Import All",
|
||||
"dialog.skin.layer_template": "Layer Texture",
|
||||
"about.version.up_to_date": "Up to date",
|
||||
"about.version.update_available": "Version %0 is available",
|
||||
"settings.render_sides.front": "Extérieur",
|
||||
"settings.render_sides.double": "Intérieur et extérieur",
|
||||
"generic.enable": "Activé",
|
||||
"generic.disable": "Désactivé",
|
||||
"generic.redacted": "Censuré",
|
||||
"dialog.project.layered_textures": "Textures par couches",
|
||||
"dialog.select_texture.import_all": "Importer tout",
|
||||
"dialog.skin.layer_template": "Couche de texture",
|
||||
"about.version.up_to_date": "À jour",
|
||||
"about.version.update_available": "La version %0 est disponible",
|
||||
"settings.category.application": "Application",
|
||||
"settings.streamer_mode": "Streamer Mode",
|
||||
"settings.streamer_mode.desc": "Hides sensitive information like recent models",
|
||||
"settings.automatic_updates": "Automatic Updates",
|
||||
"settings.automatic_updates.desc": "Automatically download new versions and keep Blockbench up-to-date",
|
||||
"action.rotation_space": "Rotation Space",
|
||||
"action.focus_on_selection": "Center View on Selection",
|
||||
"action.focus_on_selection.desc": "Align the camera to face the center of the current selection",
|
||||
"action.jump_to_timeline_start": "Jump to Animation Start",
|
||||
"action.jump_to_timeline_end": "Jump to Animation End",
|
||||
"menu.help.updating": "Updating (%0%)",
|
||||
"menu.help.update_ready": "Relaunch to Update",
|
||||
"menu.help.update_failed": "Update Failed",
|
||||
"menu.animation.loop.once": "Play Once",
|
||||
"menu.animation.loop.hold": "Hold On Last Frame",
|
||||
"menu.animation.loop.loop": "Loop",
|
||||
"interface.streamer_mode_on": "Streamer Mode Enabled"
|
||||
"settings.streamer_mode": "Mode Streamer",
|
||||
"settings.streamer_mode.desc": "Masque des informations sensibles telles que les modèles récents",
|
||||
"settings.automatic_updates": "Mises à jour automatiques",
|
||||
"settings.automatic_updates.desc": "Télécharger les nouvelles mises à jour automatiquement et garder Blockbench à jour",
|
||||
"action.rotation_space": "Espace de rotation",
|
||||
"action.focus_on_selection": "Centrer la vue sur la sélection",
|
||||
"action.focus_on_selection.desc": "Aligne la caméra en direction du centre de la sélection actuelle",
|
||||
"action.jump_to_timeline_start": "Passer au début de l'animation",
|
||||
"action.jump_to_timeline_end": "Passer à la fin de l'animation",
|
||||
"menu.help.updating": "Mise à jour en cours (%0%)",
|
||||
"menu.help.update_ready": "Relancer pour mettre à jour",
|
||||
"menu.help.update_failed": "Échec de la mise à jour",
|
||||
"menu.animation.loop.once": "Lire une fois",
|
||||
"menu.animation.loop.hold": "Rester à la dernière image",
|
||||
"menu.animation.loop.loop": "Boucle",
|
||||
"interface.streamer_mode_on": "Mode Streamer activé"
|
||||
}
|
26
lang/it.json
26
lang/it.json
@ -5,8 +5,8 @@
|
||||
"dialog.close": "Chiudi",
|
||||
"dialog.import": "Importa",
|
||||
"dialog.save": "Salva",
|
||||
"dialog.discard": "Non Salvare",
|
||||
"dialog.dontshowagain": "Non Mostrare Più",
|
||||
"dialog.discard": "Non salvare",
|
||||
"dialog.dontshowagain": "Non mostrare più",
|
||||
"data.cube": "Cubo",
|
||||
"data.group": "Gruppo",
|
||||
"data.texture": "Texture",
|
||||
@ -47,7 +47,7 @@
|
||||
"keys.printscreen": "Print Screen",
|
||||
"keys.pause": "Pausa",
|
||||
"message.rotation_limit.title": "Limiti di Rotazione",
|
||||
"message.rotation_limit.message": "Le rotazioni sono limitate ad un'asse e incrementi di 22.5 gradi. Ruotando su un'asse differente cancellerà tuttle le rotazioni su altri assi. Disabilita l'opzione \"Rotazione Ristretta\" se stai modellando per altre ragioni e hai bisogno di rotazioni libere",
|
||||
"message.rotation_limit.message": "Le rotazioni sono limitate ad un asse e incrementi di 22.5 gradi. Ruotare su un asse differente cancellerà tutte le rotazioni su altri assi. Disabilita l'opzione \"Rotazione Ristretta\" se stai modellando per altre ragioni e hai bisogno di rotazioni libere",
|
||||
"message.file_not_found.title": "File Non Trovato",
|
||||
"message.file_not_found.message": "Blockbench non ha potuto trovare il file richiesto. Assicurati che sia salvato localmente e non in un cloud.",
|
||||
"message.screenshot.title": "Screenshot",
|
||||
@ -65,9 +65,9 @@
|
||||
"message.unsaved_textures.title": "Texture Non Salvata",
|
||||
"message.unsaved_textures.message": "Questo modello utilizza textures non salvate. Assicurati di salvarle e inserirle nella nella cartella corretta della tua resource pack",
|
||||
"message.model_clipping.title": "Modello Troppo Grande",
|
||||
"message.model_clipping.message": "Il tuo modello contiene %0 cubi che sono più grandi del limite 3x3x3 imposto da Minecraft. Questo modello non funzionera in Minecraft. Abilita la funzione 'Spazio di Lavoro Limitato' per prevenire questo.",
|
||||
"message.loose_texture.title": "Importo Texture",
|
||||
"message.loose_texture.message": "La texture imortata non è contenuta in un resource pack. Minecraft può solo caricare le texture dalla cartella \"textures\" di un resource pack attivo.",
|
||||
"message.model_clipping.message": "Il tuo modello contiene %0 cubi che sono più grandi del limite 3x3x3 imposto da Minecraft. Questo modello non funzionerà su Minecraft. Abilita la funzione 'Spazio di Lavoro Limitato' per prevenire questo.",
|
||||
"message.loose_texture.title": "Importa Texture",
|
||||
"message.loose_texture.message": "La texture importata non è contenuta in un resource pack. Minecraft può solo caricare le texture dalla cartella \"textures\" di un resource pack attivo.",
|
||||
"message.loose_texture.change": "Cambia Percorso",
|
||||
"message.update_res.title": "Risoluzione Texture",
|
||||
"message.update_res.message": "Vorresti aggiornare la risoluzione del progetto con la risoluzione di questa texture? Fai Click su 'Annulla' se la texture ha una risoluzione maggiore del normale.",
|
||||
@ -79,7 +79,7 @@
|
||||
"message.close_warning.web": "Il tuo lavoro corrente verra perso. Sei sicuro di volere uscire?",
|
||||
"message.default_textures.title": "Textures Predefinite",
|
||||
"message.default_textures.message": "Seleziona la cartella \"textures\" del resource pack predefinito",
|
||||
"message.default_textures.detail": "Estrai il resource pack predefinito dal jar Minecraft oppure vai su google per scaricalo. Poi trova la cartella \"textures\" ed aprila. Blockbench memorizzera questa cartella e cercera di prendere le texture da quella cartella se non puo trovarle nel resource pack corrente.",
|
||||
"message.default_textures.detail": "Estrai il resource pack predefinito dal jar di Minecraft oppure vai su google per scaricarlo. Poi trova la cartella \"textures\" ed aprila. Blockbench memorizzerà questa cartella e cercherà di prendere le texture da quella cartella se non può trovarle nel resource pack corrente.",
|
||||
"message.default_textures.select": "Seleziona la cartella \"textures\" predefinita",
|
||||
"message.image_editor.title": "Seleziona un editor di immagini",
|
||||
"message.image_editor.file": "Seleziona un file...",
|
||||
@ -143,7 +143,7 @@
|
||||
"dialog.plugins.app_only": "Solo per l'applicazione desktop",
|
||||
"dialog.plugins.author": "di %0",
|
||||
"dialog.plugins.show_less": "Mostra meno",
|
||||
"dialog.entitylist.title": "Apri Modello Entity",
|
||||
"dialog.entitylist.title": "Apri Modello Entità",
|
||||
"dialog.entitylist.text": "Seleziona il modello da importare",
|
||||
"dialog.entitylist.bones": "Ossa",
|
||||
"dialog.entitylist.cubes": "Cubi",
|
||||
@ -670,7 +670,7 @@
|
||||
"mode.edit": "Modifica",
|
||||
"mode.paint": "Dipingi",
|
||||
"mode.display": "Display",
|
||||
"mode.animate": "Animi",
|
||||
"mode.animate": "Anima",
|
||||
"status_bar.recording_gif": "Registrando GIF",
|
||||
"status_bar.processing_gif": "GIF in lavorazione",
|
||||
"settings.backup_retain": "Durata Conservazione Backup",
|
||||
@ -1119,9 +1119,9 @@
|
||||
"action.jump_to_timeline_end": "Jump to Animation End",
|
||||
"menu.help.updating": "Updating (%0%)",
|
||||
"menu.help.update_ready": "Relaunch to Update",
|
||||
"menu.help.update_failed": "Update Failed",
|
||||
"menu.animation.loop.once": "Play Once",
|
||||
"menu.animation.loop.hold": "Hold On Last Frame",
|
||||
"menu.help.update_failed": "Aggiornamento Fallito",
|
||||
"menu.animation.loop.once": "Riproduci una volta",
|
||||
"menu.animation.loop.hold": "Mantieni l'ultimo frame",
|
||||
"menu.animation.loop.loop": "Loop",
|
||||
"interface.streamer_mode_on": "Streamer Mode Enabled"
|
||||
"interface.streamer_mode_on": "Modalità Streamer attivata"
|
||||
}
|
42
lang/ja.json
42
lang/ja.json
@ -76,18 +76,18 @@
|
||||
"message.bedrock_overwrite_error.backup_overwrite": "バックアップの作成と上書き",
|
||||
"message.bedrock_overwrite_error.overwrite": "上書き",
|
||||
"message.close_warning.message": "モデルを保存しますか?",
|
||||
"message.close_warning.web": "保存が完了してません。本当に終了しますか?",
|
||||
"message.close_warning.web": "保存が完了していません。本当に終了しますか?",
|
||||
"message.default_textures.title": "デフォルトテクスチャ",
|
||||
"message.default_textures.message": "デフォルトのリソースパックのファイルを選択します",
|
||||
"message.default_textures.detail": "Minecraft jarまたはgoogleからデフォルトのリソースパックをダウンロードします。次に、\"textures\"フォルダを開きます。Blockbenchは、現在のリソースパックで見つからない場合はそこからテクスチャを取得しようとします",
|
||||
"message.default_textures.select": "デフォルトの\"textures\"フォルダを選択",
|
||||
"message.image_editor.title": "画像エディタを選択",
|
||||
"message.image_editor.file": "ファイルを選ぶ…",
|
||||
"message.image_editor.file": "ファイルを選択…",
|
||||
"message.image_editor.exe": "使用可能な画像エディタを選択",
|
||||
"message.display_skin.title": "スキン",
|
||||
"message.display_skin.message": "コンピュータからスキンファイルを選択するか、Minecraft IDを入力してください",
|
||||
"message.display_skin.upload": "スキンをアップロード",
|
||||
"message.display_skin.name": "MCID",
|
||||
"message.display_skin.name": "Minecraft ID",
|
||||
"message.display_skin.reset": "リセット",
|
||||
"message.invalid_plugin": "無効なプラグインファイルです。コンソールを参照してください",
|
||||
"message.load_plugin_app": "このプラグインでPCを変更しますか?信頼できるユーザーのプラグインのみを読み込みます",
|
||||
@ -1051,7 +1051,7 @@
|
||||
"menu.help.developer.reset_storage.confirm": "Blockbenchを工場出荷時設定にリセットします。すべてのカスタム設定、キーバインド、およびインストールされたプラグインが削除されます。",
|
||||
"menu.help.developer.cache_reload": "キャッシュのリロード",
|
||||
"menu.texture.resize": "リサイズ...",
|
||||
"menu.preview.orthographic": "Orthographic",
|
||||
"menu.preview.orthographic": "正投影",
|
||||
"menu.preview.save_angle": "アングルを保存...",
|
||||
"menu.preview.angle": "アングル",
|
||||
"menu.preview.angle.initial": "初期角度",
|
||||
@ -1084,8 +1084,8 @@
|
||||
"action.toggle_locked.desc": "ロックするかどうかを切り替えます",
|
||||
"action.apply_display_preset": "プリセットを適用",
|
||||
"action.apply_display_preset.desc": "カスタムの表示設定プリセットを適用します",
|
||||
"action.apply_display_preset.here": "スロットに適応",
|
||||
"action.apply_display_preset.everywhere": "全てのスロットに適応します",
|
||||
"action.apply_display_preset.here": "スロットに適用",
|
||||
"action.apply_display_preset.everywhere": "全てのスロットに適用",
|
||||
"action.resolve_keyframe_expressions": "Resolve Keyframe",
|
||||
"action.resolve_keyframe_expressions.desc": "Resolves the math expressions of the selected keyframes",
|
||||
"action.fold_all_animations": "すべてのアニメーターを折りたたむ",
|
||||
@ -1099,29 +1099,29 @@
|
||||
"settings.render_sides.auto": "オート",
|
||||
"settings.render_sides.front": "アウトサイド",
|
||||
"settings.render_sides.double": "両面",
|
||||
"generic.enable": "Enable",
|
||||
"generic.disable": "Disable",
|
||||
"generic.enable": "有効",
|
||||
"generic.disable": "無効",
|
||||
"generic.redacted": "Redacted",
|
||||
"dialog.project.layered_textures": "Layered Textures",
|
||||
"dialog.select_texture.import_all": "Import All",
|
||||
"dialog.skin.layer_template": "Layer Texture",
|
||||
"about.version.up_to_date": "Up to date",
|
||||
"about.version.update_available": "Version %0 is available",
|
||||
"settings.category.application": "Application",
|
||||
"settings.streamer_mode": "Streamer Mode",
|
||||
"settings.streamer_mode.desc": "Hides sensitive information like recent models",
|
||||
"settings.automatic_updates": "Automatic Updates",
|
||||
"settings.automatic_updates.desc": "Automatically download new versions and keep Blockbench up-to-date",
|
||||
"about.version.up_to_date": "最新",
|
||||
"about.version.update_available": "バージョン %0 が利用可能です",
|
||||
"settings.category.application": "アプリケーション",
|
||||
"settings.streamer_mode": "配信者モード",
|
||||
"settings.streamer_mode.desc": "最近使ったファイルのようなセンシティブな情報を隠します",
|
||||
"settings.automatic_updates": "自動更新",
|
||||
"settings.automatic_updates.desc": "自動的に新しいバージョンをダウンロードし、Blockbenchを最新に保ちます",
|
||||
"action.rotation_space": "Rotation Space",
|
||||
"action.focus_on_selection": "Center View on Selection",
|
||||
"action.focus_on_selection.desc": "Align the camera to face the center of the current selection",
|
||||
"action.jump_to_timeline_start": "Jump to Animation Start",
|
||||
"action.jump_to_timeline_end": "Jump to Animation End",
|
||||
"menu.help.updating": "Updating (%0%)",
|
||||
"menu.help.update_ready": "Relaunch to Update",
|
||||
"menu.help.update_failed": "Update Failed",
|
||||
"menu.animation.loop.once": "Play Once",
|
||||
"menu.help.updating": "更新中 (%0%)",
|
||||
"menu.help.update_ready": "更新のために再起動",
|
||||
"menu.help.update_failed": "更新失敗",
|
||||
"menu.animation.loop.once": "1回のみ",
|
||||
"menu.animation.loop.hold": "Hold On Last Frame",
|
||||
"menu.animation.loop.loop": "Loop",
|
||||
"interface.streamer_mode_on": "Streamer Mode Enabled"
|
||||
"menu.animation.loop.loop": "繰り返し",
|
||||
"interface.streamer_mode_on": "配信者モードが有効"
|
||||
}
|
24
lang/ru.json
24
lang/ru.json
@ -15,28 +15,28 @@
|
||||
"data.toolbar": "Инструменты",
|
||||
"data.image": "Изображение",
|
||||
"keys.ctrl": "Control",
|
||||
"keys.shift": "Shift",
|
||||
"keys.alt": "Alt",
|
||||
"keys.meta": "Cmd",
|
||||
"keys.delete": "Delete",
|
||||
"keys.shift": "Шифт",
|
||||
"keys.alt": "Альт",
|
||||
"keys.meta": "Коммандная Строка",
|
||||
"keys.delete": "Удалить",
|
||||
"keys.space": "Пробел",
|
||||
"keys.leftclick": "ЛКМ",
|
||||
"keys.middleclick": "КМ",
|
||||
"keys.rightclick": "ПКМ",
|
||||
"keys.tab": "Tab",
|
||||
"keys.backspace": "Backspace",
|
||||
"keys.tab": "Таб",
|
||||
"keys.backspace": "Отмена",
|
||||
"keys.enter": "Ввод",
|
||||
"keys.escape": "Escape",
|
||||
"keys.escape": "Пробел",
|
||||
"keys.function": "F%0",
|
||||
"keys.numpad": "%0 (цифр. кл.)",
|
||||
"keys.caps": "Capslock",
|
||||
"keys.caps": "Капслок",
|
||||
"keys.menu": "Меню",
|
||||
"keys.left": "Стрелка влево",
|
||||
"keys.up": "Стрелка вверх",
|
||||
"keys.right": "Стрелка вправо",
|
||||
"keys.down": "Стрелка вниз",
|
||||
"keys.pageup": "Page Up",
|
||||
"keys.pagedown": "Page Down",
|
||||
"keys.pageup": "Пейдж Ап",
|
||||
"keys.pagedown": "Пейдж Даун",
|
||||
"keys.plus": "Плюс",
|
||||
"keys.comma": ",",
|
||||
"keys.point": ".",
|
||||
@ -61,7 +61,7 @@
|
||||
"message.child_model_only.title": "Пустая дочерняя модель",
|
||||
"message.child_model_only.message": "Это дочерняя модель %0, которая не содержит модели.",
|
||||
"message.drag_background.title": "Расположение фона",
|
||||
"message.drag_background.message": "Нажмите и перетаскивайте фон, чтобы изменить его положение. Удерживайте Shift для изменения размера.",
|
||||
"message.drag_background.message": "Нажмите и перетаскивайте фон, чтобы изменить его положение. Удерживайте Шифт для изменения размера.",
|
||||
"message.unsaved_textures.title": "Несохранённые текстуры",
|
||||
"message.unsaved_textures.message": "Ваша модель содержит несохранённые текстуры. Убедитесь, что они сохранены и помещены в ваш набор ресурсов в правильной папке.",
|
||||
"message.model_clipping.title": "Модель слишком большая",
|
||||
@ -518,7 +518,7 @@
|
||||
"display.reference.frame": "Рамка",
|
||||
"display.reference.inventory_nine": "3x3",
|
||||
"display.reference.inventory_full": "Инвентарь",
|
||||
"display.reference.hud": "HUD",
|
||||
"display.reference.hud": "ХУД",
|
||||
"display.preset.blank_name": "Введите название",
|
||||
"display.preset.item": "Предмет",
|
||||
"display.preset.block": "Блок",
|
||||
|
358
lib/molang.js
358
lib/molang.js
@ -1,44 +1,64 @@
|
||||
var Molang = {
|
||||
parse: function (input, variables) {
|
||||
const Molang = {};
|
||||
|
||||
if (typeof input === 'number') {
|
||||
return isNaN(input) ? 0 : input
|
||||
(function() {
|
||||
|
||||
const MathUtil = {
|
||||
random(a, b) {
|
||||
return a + Math.random() * (b-a)
|
||||
},
|
||||
clamp(number, min, max) {
|
||||
if (number > max) number = max;
|
||||
if (number < min || isNaN(number)) number = min;
|
||||
return number;
|
||||
}
|
||||
if (typeof input !== 'string') return 0;
|
||||
input = input.toLowerCase();
|
||||
if (input.substr(-1) === ';') input = input.substr(0, input.length-1)
|
||||
};
|
||||
|
||||
if (Molang.cache_enabled && Molang._cached[input]) {
|
||||
var expression = Molang._cached[input];
|
||||
} else {
|
||||
var expression = new Molang.expression(input)
|
||||
if (Molang.cache_enabled) {
|
||||
Molang._cached[input] = expression;
|
||||
function Expression(string) {
|
||||
this.original_input = string;
|
||||
this.lines = string.split(';').map(line => {
|
||||
return iterateString(line);
|
||||
});
|
||||
}
|
||||
function Comp(operator, a, b, c) {
|
||||
this.operator = operator;
|
||||
this.a = iterateString(a);
|
||||
if (b !== undefined) this.b = iterateString(b);
|
||||
if (c !== undefined) this.c = iterateString(c);
|
||||
}
|
||||
function Allocation(name, value) {
|
||||
this.value = iterateString(value);
|
||||
this.name = name;
|
||||
}
|
||||
function Statement(type, value) {
|
||||
this.value = iterateString(value);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Molang.global_variables = {};
|
||||
Molang.cache_enabled = true;
|
||||
Molang.use_radians = false;
|
||||
Molang.variableHandler;
|
||||
|
||||
const cached = {};
|
||||
let current_variables;
|
||||
|
||||
|
||||
function calculate(expression, variables) {
|
||||
current_variables = variables||{};
|
||||
var i = 0;
|
||||
for (var line of expression.lines) {
|
||||
let result = iterateExp(line);
|
||||
i++;
|
||||
if (i == expression.lines.length || (line instanceof Statement && line.type === 'return')) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
var value = Molang.calculate(expression, variables)
|
||||
return value;
|
||||
},
|
||||
global_variables: {},
|
||||
cache_enabled: true,
|
||||
use_radians: false,
|
||||
expression: function(string) {
|
||||
this.original_input = string;
|
||||
this.data = Molang._itS(string);
|
||||
},
|
||||
calculate: function(expression, variables) {
|
||||
Molang._current_variables = variables||0;
|
||||
return Molang._itEx(expression.data);
|
||||
},
|
||||
Comp: function(operator, a, b, c) {
|
||||
this.operator = operator;
|
||||
this.a = Molang._itS(a);
|
||||
if (b !== undefined) this.b = Molang._itS(b);
|
||||
if (c !== undefined) this.c = Molang._itS(c);
|
||||
},
|
||||
return 0;
|
||||
}
|
||||
|
||||
_cached: {},
|
||||
_itS: function(s) {
|
||||
function iterateString(s) {
|
||||
//Iterates through string, returns float, string or comp;
|
||||
if (!s) return 0;
|
||||
var M = Molang;
|
||||
@ -46,34 +66,48 @@ var Molang = {
|
||||
|
||||
s = s.replace(/\s/g, '')
|
||||
|
||||
while (M._canTrimParentheses(s)) {
|
||||
while (canTrimParentheses(s)) {
|
||||
s = s.substr(1, s.length-2);
|
||||
}
|
||||
|
||||
//Statement
|
||||
var match = s.length > 5 && s.match(/^return/)
|
||||
if (match) {
|
||||
return new Statement(match[0], s.substr(match[0].length))
|
||||
}
|
||||
|
||||
//allocation
|
||||
var match = s.length > 6 && s.match(/(temp|variable)\.\w+=/)
|
||||
if (match) {
|
||||
let name = match[0].replace(/=$/, '');
|
||||
let value = s.substr(match.index + match[0].length)
|
||||
return new Allocation(name, value)
|
||||
}
|
||||
|
||||
//ternary
|
||||
var split = Molang._splitString(s, '?');
|
||||
var split = splitString(s, '?');
|
||||
if (split) {
|
||||
let ab = Molang._splitString(split[1], ':');
|
||||
let ab = splitString(split[1], ':');
|
||||
if (ab && ab.length) {
|
||||
return new Molang.Comp(10, split[0], ab[0], ab[1]);
|
||||
return new Comp(10, split[0], ab[0], ab[1]);
|
||||
}
|
||||
}
|
||||
|
||||
//2 part operators
|
||||
var comp = (
|
||||
M._testOp(s, '&&', 11) ||
|
||||
M._testOp(s, '||', 12) ||
|
||||
M._testOp(s, '<', 13) ||
|
||||
M._testOp(s, '<=', 14) ||
|
||||
M._testOp(s, '>', 15) ||
|
||||
M._testOp(s, '>=', 16) ||
|
||||
M._testOp(s, '==', 17) ||
|
||||
M._testOp(s, '!=', 18) ||
|
||||
testOp(s, '&&', 11) ||
|
||||
testOp(s, '||', 12) ||
|
||||
testOp(s, '<', 13) ||
|
||||
testOp(s, '<=', 14) ||
|
||||
testOp(s, '>', 15) ||
|
||||
testOp(s, '>=', 16) ||
|
||||
testOp(s, '==', 17) ||
|
||||
testOp(s, '!=', 18) ||
|
||||
|
||||
M._testOp(s, '+', 1, true) ||
|
||||
M._testMinus(s, '-', 2, true) ||
|
||||
M._testOp(s, '*', 3) ||
|
||||
M._testOp(s, '/', 4)
|
||||
testOp(s, '+', 1, true) ||
|
||||
testMinus(s, '-', 2, true) ||
|
||||
testOp(s, '*', 3) ||
|
||||
testOp(s, '/', 4)
|
||||
)
|
||||
if (comp) return comp;
|
||||
|
||||
@ -84,9 +118,9 @@ var Molang = {
|
||||
let begin = s.search(/\(/);
|
||||
let operator = s.substr(5, begin-5);
|
||||
let inner = s.substr(begin+1, s.length-begin-2)
|
||||
let params = Molang._splitString(inner, ',')||[inner];
|
||||
let params = splitString(inner, ',')||[inner];
|
||||
if (params.length > 1) {
|
||||
var last2 = Molang._splitString(params[1], ',')
|
||||
var last2 = splitString(params[1], ',')
|
||||
if (last2 && last2.length > 1) {
|
||||
params[1] = last2[0];
|
||||
params[2] = last2[1];
|
||||
@ -95,58 +129,58 @@ var Molang = {
|
||||
|
||||
switch (operator) {
|
||||
case 'abs':
|
||||
return new M.Comp(20, params[0]);
|
||||
return new Comp(20, params[0]);
|
||||
break;
|
||||
case 'sin':
|
||||
return new M.Comp(21, params[0]);
|
||||
return new Comp(21, params[0]);
|
||||
break;
|
||||
case 'cos':
|
||||
return new M.Comp(22, params[0]);
|
||||
return new Comp(22, params[0]);
|
||||
break;
|
||||
case 'exp':
|
||||
return new M.Comp(23, params[0]);
|
||||
return new Comp(23, params[0]);
|
||||
break;
|
||||
case 'ln':
|
||||
return new M.Comp(24, params[0]);
|
||||
return new Comp(24, params[0]);
|
||||
break;
|
||||
case 'pow':
|
||||
return new M.Comp(25, params[0], params[1]);
|
||||
return new Comp(25, params[0], params[1]);
|
||||
break;
|
||||
case 'sqrt':
|
||||
return new M.Comp(26, params[0]);
|
||||
return new Comp(26, params[0]);
|
||||
break;
|
||||
case 'random':
|
||||
return new M.Comp(27, params[0], params[1]);
|
||||
return new Comp(27, params[0], params[1]);
|
||||
break;
|
||||
case 'ceil':
|
||||
return new M.Comp(28, params[0]);
|
||||
return new Comp(28, params[0]);
|
||||
break;
|
||||
case 'round':
|
||||
return new M.Comp(29, params[0]);
|
||||
return new Comp(29, params[0]);
|
||||
break;
|
||||
case 'trunc':
|
||||
return new M.Comp(30, params[0]);
|
||||
return new Comp(30, params[0]);
|
||||
break;
|
||||
case 'floor':
|
||||
return new M.Comp(31, params[0]);
|
||||
return new Comp(31, params[0]);
|
||||
break;
|
||||
case 'mod':
|
||||
return new M.Comp(32, params[0], params[1]);
|
||||
return new Comp(32, params[0], params[1]);
|
||||
break;
|
||||
case 'min':
|
||||
return new M.Comp(33, params[0], params[1]);
|
||||
return new Comp(33, params[0], params[1]);
|
||||
break;
|
||||
case 'max':
|
||||
return new M.Comp(34, params[0], params[1]);
|
||||
return new Comp(34, params[0], params[1]);
|
||||
break;
|
||||
case 'clamp':
|
||||
return new M.Comp(35, params[0], params[1], params[2]);
|
||||
return new Comp(35, params[0], params[1], params[2]);
|
||||
break;
|
||||
case 'lerp':
|
||||
return new M.Comp(36, params[0], params[1], params[2]);
|
||||
return new Comp(36, params[0], params[1], params[2]);
|
||||
break;
|
||||
case 'lerprotate':
|
||||
return new M.Comp(37, params[0], params[1], params[2]);
|
||||
return new Comp(37, params[0], params[1], params[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -155,8 +189,8 @@ var Molang = {
|
||||
return s;
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
_canTrimParentheses: function(s) {
|
||||
}
|
||||
function canTrimParentheses(s) {
|
||||
if (s.substr(0, 1) === '(' && s.substr(-1) === ')') {
|
||||
let level = 0;
|
||||
for (var i = 0; i < s.length-1; i++) {
|
||||
@ -168,35 +202,34 @@ var Molang = {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
},
|
||||
_testOp: function(s, char, operator, inverse) {
|
||||
}
|
||||
function testOp(s, char, operator, inverse) {
|
||||
|
||||
var split = Molang._splitString(s, char, inverse)
|
||||
var split = splitString(s, char, inverse)
|
||||
if (split) {
|
||||
return new Molang.Comp(operator, split[0], split[1])
|
||||
return new Comp(operator, split[0], split[1])
|
||||
}
|
||||
},
|
||||
_testMinus: function(s, char, operator, inverse) {
|
||||
}
|
||||
function testMinus(s, char, operator, inverse) {
|
||||
|
||||
var split = Molang._splitString(s, char, inverse)
|
||||
var split = splitString(s, char, inverse)
|
||||
if (split) {
|
||||
if (split[0].length === 0) {
|
||||
return new Molang.Comp(operator, 0, split[1])
|
||||
return new Comp(operator, 0, split[1])
|
||||
} else if ('+*/<>=|&?:'.includes(split[0].substr(-1)) === false) {
|
||||
return new Molang.Comp(operator, split[0], split[1])
|
||||
return new Comp(operator, split[0], split[1])
|
||||
}
|
||||
}
|
||||
},
|
||||
_splitString: function(s, char, inverse) {
|
||||
}
|
||||
function splitString(s, char, inverse) {
|
||||
var direction = inverse ? -1 : 1;
|
||||
var i = inverse ? s.length-1 : 0;
|
||||
var level = 0;
|
||||
var is_string = typeof char === 'string'
|
||||
while (inverse ? i >= 0 : i < s.length) {
|
||||
let c = s[i];
|
||||
if (c === '(') {
|
||||
if (s[i] === '(') {
|
||||
level += direction;
|
||||
} else if (c === ')') {
|
||||
} else if (s[i] === ')') {
|
||||
level -= direction;
|
||||
} else if (level === 0) {
|
||||
var letters = s.substr(i, char.length)
|
||||
@ -218,142 +251,179 @@ var Molang = {
|
||||
}
|
||||
i += direction;
|
||||
}
|
||||
},
|
||||
get _angleFactor() {
|
||||
}
|
||||
function angleFactor() {
|
||||
return this.use_radians ? 1 : (Math.PI/180);
|
||||
},
|
||||
_itEx: function(T) {
|
||||
}
|
||||
function iterateExp(T) {
|
||||
if (typeof T === 'number') {
|
||||
return T
|
||||
} else if (typeof T === 'string') {
|
||||
var val = Molang._current_variables[T]
|
||||
var val = current_variables[T]
|
||||
if (val === undefined) {
|
||||
val = Molang.global_variables[T];
|
||||
if (T === 'true') {
|
||||
return 1;
|
||||
} else if (T === 'false') {
|
||||
return 0;
|
||||
} else {
|
||||
val = Molang.global_variables[T];
|
||||
}
|
||||
}
|
||||
if (val === undefined && typeof Molang.variableHandler === 'function') {
|
||||
val = Molang.variableHandler(T)
|
||||
val = Molang.variableHandler(T, current_variables)
|
||||
}
|
||||
if (typeof val === 'string') {
|
||||
val = Molang.parse(val, Molang._current_variables)
|
||||
val = Molang.parse(val, current_variables)
|
||||
}
|
||||
return val||0;
|
||||
} else if (T instanceof Molang.Comp) {
|
||||
|
||||
} else if (T instanceof Statement) {
|
||||
return iterateExp(T.value);
|
||||
|
||||
} else if (T instanceof Allocation) {
|
||||
return current_variables[T.name] = iterateExp(T.value);
|
||||
|
||||
} else if (T instanceof Comp) {
|
||||
var M = Molang;
|
||||
switch (T.operator) {
|
||||
//Basic
|
||||
case 1:
|
||||
return M._itEx(T.a) + M._itEx(T.b);
|
||||
return iterateExp(T.a) + iterateExp(T.b);
|
||||
break;
|
||||
case 2:
|
||||
return M._itEx(T.a) - M._itEx(T.b);
|
||||
return iterateExp(T.a) - iterateExp(T.b);
|
||||
break;
|
||||
case 3:
|
||||
return M._itEx(T.a) * M._itEx(T.b);
|
||||
return iterateExp(T.a) * iterateExp(T.b);
|
||||
break;
|
||||
case 4:
|
||||
return M._itEx(T.a) / M._itEx(T.b);
|
||||
return iterateExp(T.a) / iterateExp(T.b);
|
||||
break;
|
||||
//Boolean
|
||||
//Logical
|
||||
case 10:
|
||||
return M._itEx(T.a) ? M._itEx(T.b) : M._itEx(T.c);
|
||||
return iterateExp(T.a) ? iterateExp(T.b) : iterateExp(T.c);
|
||||
break;
|
||||
case 11:
|
||||
return M._itEx(T.a) && M._itEx(T.b) ? 1 : 0;
|
||||
return iterateExp(T.a) && iterateExp(T.b) ? 1 : 0;
|
||||
break;
|
||||
case 12:
|
||||
return M._itEx(T.a) || M._itEx(T.b) ? 1 : 0;
|
||||
return iterateExp(T.a) || iterateExp(T.b) ? 1 : 0;
|
||||
break;
|
||||
case 13:
|
||||
return M._itEx(T.a) < M._itEx(T.b) ? 1 : 0;
|
||||
return iterateExp(T.a) < iterateExp(T.b) ? 1 : 0;
|
||||
break;
|
||||
case 14:
|
||||
return M._itEx(T.a) <= M._itEx(T.b) ? 1 : 0;
|
||||
return iterateExp(T.a) <= iterateExp(T.b) ? 1 : 0;
|
||||
break;
|
||||
case 15:
|
||||
return M._itEx(T.a) > M._itEx(T.b) ? 1 : 0;
|
||||
return iterateExp(T.a) > iterateExp(T.b) ? 1 : 0;
|
||||
break;
|
||||
case 16:
|
||||
return M._itEx(T.a) >= M._itEx(T.b) ? 1 : 0;
|
||||
return iterateExp(T.a) >= iterateExp(T.b) ? 1 : 0;
|
||||
break;
|
||||
case 17:
|
||||
return M._itEx(T.a) === M._itEx(T.b) ? 1 : 0;
|
||||
return iterateExp(T.a) === iterateExp(T.b) ? 1 : 0;
|
||||
break;
|
||||
case 18:
|
||||
return M._itEx(T.a) !== M._itEx(T.b) ? 1 : 0;
|
||||
return iterateExp(T.a) !== iterateExp(T.b) ? 1 : 0;
|
||||
break;
|
||||
//Math
|
||||
case 20:
|
||||
return Math.abs(M._itEx(T.a));
|
||||
return Math.abs(iterateExp(T.a));
|
||||
break;
|
||||
case 21:
|
||||
return Math.sin(M._itEx(T.a) * Molang._angleFactor);
|
||||
return Math.sin(iterateExp(T.a) * angleFactor());
|
||||
break;
|
||||
case 22:
|
||||
return Math.cos(M._itEx(T.a) * Molang._angleFactor);
|
||||
return Math.cos(iterateExp(T.a) * angleFactor());
|
||||
break;
|
||||
case 23:
|
||||
return Math.exp(M._itEx(T.a));
|
||||
return Math.exp(iterateExp(T.a));
|
||||
break;
|
||||
case 24:
|
||||
return Math.log(M._itEx(T.a));
|
||||
return Math.log(iterateExp(T.a));
|
||||
break;
|
||||
case 25:
|
||||
return Math.pow(M._itEx(T.a), M._itEx(T.b));
|
||||
return Math.pow(iterateExp(T.a), iterateExp(T.b));
|
||||
break;
|
||||
case 26:
|
||||
return Math.sqrt(M._itEx(T.a));
|
||||
return Math.sqrt(iterateExp(T.a));
|
||||
break;
|
||||
case 27:
|
||||
return Molang._random(M._itEx(T.a), M._itEx(T.b), M._itEx(T.c));
|
||||
return MathUtil.random(iterateExp(T.a), iterateExp(T.b), iterateExp(T.c));
|
||||
break;
|
||||
case 28:
|
||||
return Math.ceil(M._itEx(T.a));
|
||||
return Math.ceil(iterateExp(T.a));
|
||||
break;
|
||||
case 29:
|
||||
return Math.round(M._itEx(T.a));
|
||||
return Math.round(iterateExp(T.a));
|
||||
break;
|
||||
case 30:
|
||||
return Math.trunc(M._itEx(T.a));
|
||||
return Math.trunc(iterateExp(T.a));
|
||||
break;
|
||||
case 31:
|
||||
return Math.floor(M._itEx(T.a));
|
||||
return Math.floor(iterateExp(T.a));
|
||||
break;
|
||||
case 32:
|
||||
return M._itEx(T.a) % M._itEx(T.b);
|
||||
return iterateExp(T.a) % iterateExp(T.b);
|
||||
break;
|
||||
case 33:
|
||||
return Math.min(M._itEx(T.a), M._itEx(T.b));
|
||||
return Math.min(iterateExp(T.a), iterateExp(T.b));
|
||||
break;
|
||||
case 34:
|
||||
return Math.max(M._itEx(T.a), M._itEx(T.b));
|
||||
return Math.max(iterateExp(T.a), iterateExp(T.b));
|
||||
break;
|
||||
case 35:
|
||||
return Molang._clamp(M._itEx(T.a), M._itEx(T.b), M._itEx(T.c));
|
||||
return MathUtil.clamp(iterateExp(T.a), iterateExp(T.b), iterateExp(T.c));
|
||||
break;
|
||||
case 36:
|
||||
let n1 = M._itEx(T.a);
|
||||
return n1 + (M._itEx(T.b) - n1) * M._itEx(T.c);
|
||||
let n1 = iterateExp(T.a);
|
||||
return n1 + (iterateExp(T.b) - n1) * iterateExp(T.c);
|
||||
break;
|
||||
case 37:
|
||||
let a = (((M._itEx(T.a) + 180) % 360) +180) % 360
|
||||
let b = (((M._itEx(T.b) + 180) % 360) +180) % 360
|
||||
let d = b-a
|
||||
let i = M._itEx(T.c)
|
||||
if (Math.abs(d) > 180) {
|
||||
i *= -1
|
||||
let radify = n => (((n + 180) % 360) +180) % 360;
|
||||
let a = radify(iterateExp(T.a))
|
||||
let b = radify(iterateExp(T.b))
|
||||
let i = iterateExp(T.c)
|
||||
|
||||
if (a > b) [a, b] = [b, a];
|
||||
var diff = b-a;
|
||||
if (diff > 180) {
|
||||
return radify(b + i * (360-diff));
|
||||
} else {
|
||||
return a + i * diff;
|
||||
}
|
||||
return a + v*i
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
function trimInput(string) {
|
||||
string = string.toLowerCase();
|
||||
string = string.replace(/;\s+/g, ';').replace(/;\s*$/, '').trim();
|
||||
return string;
|
||||
}
|
||||
}
|
||||
|
||||
Molang._random = function(a, b) {
|
||||
return a + Math.random() * (b-a)
|
||||
}
|
||||
Molang._clamp = function(number, min, max) {
|
||||
if (number > max) number = max;
|
||||
if (number < min || isNaN(number)) number = min;
|
||||
return number;
|
||||
}
|
||||
Molang.parse = function (input, variables) {
|
||||
|
||||
if (typeof input === 'number') {
|
||||
return isNaN(input) ? 0 : input
|
||||
}
|
||||
if (typeof input !== 'string') return 0;
|
||||
input = trimInput(input);
|
||||
|
||||
if (Molang.cache_enabled && cached[input]) {
|
||||
var expression = cached[input];
|
||||
} else {
|
||||
var expression = new Expression(input)
|
||||
if (Molang.cache_enabled) {
|
||||
cached[input] = expression;
|
||||
}
|
||||
}
|
||||
var value = calculate(expression, variables)
|
||||
return value;
|
||||
};
|
||||
|
||||
})()
|
||||
|
||||
if (typeof module !== 'undefined') module.exports = Molang
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Blockbench",
|
||||
"description": "Model editing and animation software",
|
||||
"version": "3.6.3",
|
||||
"version": "3.6.4",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"author": {
|
||||
"name": "JannisX11",
|
||||
|
Loading…
x
Reference in New Issue
Block a user