mirror of
https://github.com/haselkern/Minecraft-ArmorStand.git
synced 2025-05-17 15:05:33 +00:00
1328 lines
No EOL
37 KiB
JavaScript
1328 lines
No EOL
37 KiB
JavaScript
// BIG Thanks to tutsplus.com
|
|
// http://code.tutsplus.com/tutorials/webgl-with-threejs-basics--net-35688
|
|
// for helping me getting started
|
|
|
|
//Stuff for rendering
|
|
var DEG2RAD = Math.PI / 180;
|
|
var width, height, renderer, scene, camera;
|
|
var clock = new THREE.Clock;
|
|
var rotY = 0, rotX = 0;
|
|
var matWood = new THREE.MeshLambertMaterial({ color: 0x826841 });
|
|
//var matWood = new THREE.MeshLambertMaterial({ color: 0x826841, transparent: true, opacity: 0.5 }); //For testing the mesh alignment
|
|
var matStone = new THREE.MeshLambertMaterial({ color: 0xadadad });
|
|
var matTransparentStone = new THREE.MeshLambertMaterial({ color: 0xadadad });
|
|
matTransparentStone.opacity = 0.8;
|
|
matTransparentStone.transparent = true;
|
|
var viewCenter = new THREE.Vector3(0,0,0);
|
|
// Meshes
|
|
// The ones marked with //* are not real meshes, but contain a child (or more) which gets rendered.
|
|
// This is done, so these can easily be rotated around an accurate pivot point.
|
|
var mBasePlate;
|
|
var mBody; //*
|
|
var mHead; //*
|
|
var mSkull;
|
|
var mLegLeft; //*
|
|
var mLegRight; //*
|
|
var mArmLeft; //*
|
|
var mArmRight; //*
|
|
var armorstand, armorstandWrapper; //Group all the other elements
|
|
|
|
|
|
//DATA -> Stuff that we'll use to generate the command. Fetched from the controls.
|
|
|
|
var mcVersion;
|
|
|
|
var invisible = false;
|
|
var invulnerable = false;
|
|
var persistencerequired = false;
|
|
var noBasePlate = false;
|
|
var noGravity = false;
|
|
var showArms = false;
|
|
var small = false;
|
|
var marker = false;
|
|
var centercorrected = false;
|
|
var give = false;
|
|
|
|
var useEquipment;
|
|
var equipHandRight;
|
|
var equipHandLeft;
|
|
var equipShoes;
|
|
var equipLeggings;
|
|
var equipChestplate;
|
|
var equipHelmet = "";
|
|
var equipCustomHeadMode;
|
|
var equipColorShoes;
|
|
var equipColorLeggings;
|
|
var equipColorChestplate;
|
|
var equipColorHelmet;
|
|
var helmetList;
|
|
var chestplateList;
|
|
var leggingsList;
|
|
var bootsList;
|
|
|
|
var customName;
|
|
var showCustomName;
|
|
var nameColor;
|
|
var nameBold;
|
|
var nameItalic;
|
|
var nameobfuscated;
|
|
var nameStrikethrough;
|
|
|
|
var useDisabledSlots;
|
|
|
|
var scoreboardTags;
|
|
|
|
|
|
//The rotation values are all in degrees.
|
|
var head = new THREE.Vector3(0,0,0);
|
|
var body = new THREE.Vector3(0,0,0);
|
|
var leftLeg = new THREE.Vector3(0,0,0);
|
|
var rightLeg = new THREE.Vector3(0,0,0);
|
|
var leftArm = new THREE.Vector3(0,0,0);
|
|
var rightArm = new THREE.Vector3(0,0,0);
|
|
var rotation = 0;
|
|
|
|
//Stuff for mouse movements
|
|
var mouseDownX;
|
|
var mouseDownY;
|
|
var mouseMoveX;
|
|
var mouseMoveY;
|
|
var mouseRotationMultiplier = 0.008;
|
|
//A point class will help us manage the mouse movements.
|
|
Point = {
|
|
x:null,
|
|
y:null
|
|
};
|
|
|
|
jQuery.fn.selectAndCopyText = function(){
|
|
// https://stackoverflow.com/a/9976413/1456971
|
|
this.find('input').each(function() {
|
|
if($(this).prev().length == 0 || !$(this).prev().hasClass('p_copy')) {
|
|
$('<p class="p_copy" style="position: absolute; z-index: -1;"></p>').insertBefore($(this));
|
|
}
|
|
$(this).prev().html($(this).val());
|
|
});
|
|
|
|
var doc = document;
|
|
var element = this[0];
|
|
if (doc.body.createTextRange) {
|
|
var range = document.body.createTextRange();
|
|
range.moveToElementText(element);
|
|
range.select();
|
|
} else if (window.getSelection) {
|
|
var selection = window.getSelection();
|
|
var range = document.createRange();
|
|
range.selectNodeContents(element);
|
|
selection.removeAllRanges();
|
|
selection.addRange(range);
|
|
}
|
|
|
|
document.execCommand("copy");
|
|
};
|
|
|
|
$(document).ready(function(){
|
|
//Init
|
|
setup();
|
|
updateUI();
|
|
render();
|
|
loadScreen();
|
|
|
|
// Confirm exit
|
|
window.onbeforeunload = function(){
|
|
return "Unsaved changes will NOT be saved. Exit anyways?";
|
|
};
|
|
|
|
// Copy code on click
|
|
$(".code").click(function(){
|
|
$("#code").selectAndCopyText();
|
|
});
|
|
|
|
//Stuff to handle and update input
|
|
$("input").on("input", function(){
|
|
handleInput();
|
|
});
|
|
$(':checkbox, #equipCustomHeadMode, #equipmode, #mcversion').change(function() {
|
|
handleInput();
|
|
});
|
|
|
|
|
|
//Handle rotating with mouse
|
|
$("#gl")
|
|
.mousedown(function(event){
|
|
mouseDownX = event.pageX;
|
|
mouseDownY = event.pageY;
|
|
})
|
|
.mousemove(function(event){
|
|
mouseMoveX = event.pageX;
|
|
mouseMoveY = event.pageY;
|
|
})
|
|
.mouseup(function(event){
|
|
rotY += getMouseDeltaX();
|
|
rotX += getMouseDeltaY();
|
|
mouseDownX = null;
|
|
mouseDownY = null;
|
|
});
|
|
|
|
//Hide elements
|
|
$("#getcommandblock").hide();
|
|
$("#saveandload").hide();
|
|
$("#troubleshooting").hide();
|
|
$("#inputarms").hide();
|
|
$("#customequipment").hide();
|
|
$("#disabledslots").hide();
|
|
$("#namecustomization").hide();
|
|
|
|
//Show elements
|
|
$("#namecustomization").show();
|
|
$("#centercorrected").show();
|
|
|
|
//Initialize colorpickers
|
|
$('.colorfield').colpick({
|
|
colorScheme:'light',
|
|
layout:'hex',
|
|
color:'ff8800',
|
|
onSubmit:function(hsb,hex,rgb,el) {
|
|
$(el).css('background-color', '#'+hex);
|
|
$(el).colpickHide();
|
|
handleInput();
|
|
}
|
|
});
|
|
|
|
helmetList = $("#list-helmet").find("option");
|
|
chestplateList = $("#list-chestplate").find("option");
|
|
leggingsList = $("#list-leggings").find("option");
|
|
bootsList = $("#list-shoes").find("option");
|
|
|
|
});
|
|
|
|
function loadScreen() {
|
|
$(`#creationname`).attr(`placeholder`, `My Armor Stand #${localStorage.length + 1}`);
|
|
if (!localStorage.length) {
|
|
$(`#loadlistopts`).hide();
|
|
$(`#loadmessage`).text(`You do not have any creations to load!`);
|
|
} else {
|
|
$(`#loadlistopts`).show();
|
|
$(`#loadmessage`).text(`Load your saved creations`);
|
|
$(`#loadlist`).empty();
|
|
for (let i = 0; i < localStorage.length; i++) {
|
|
$(`#loadlist`).append(`<option value="${localStorage.key(i)}">${localStorage.key(i)}</option>`);
|
|
};
|
|
};
|
|
};
|
|
|
|
function setup(){
|
|
width = $("#gl").width();
|
|
height = $("#gl").height();
|
|
|
|
renderer = new THREE.WebGLRenderer({ antialias: true, alpha:true });
|
|
renderer.setSize(width, height);
|
|
$("#gl").append(renderer.domElement);
|
|
|
|
|
|
scene = new THREE.Scene();
|
|
armorstand = new THREE.Object3D();
|
|
//Add an armorstandWrapper to the scene, so the armorstand can be rotated naturally.
|
|
armorstandWrapper = new THREE.Object3D();
|
|
armorstand.position.set(0,-0.5,0);
|
|
armorstandWrapper.add(armorstand);
|
|
|
|
|
|
//BasePlate
|
|
mBasePlate = new THREE.Mesh(
|
|
new THREE.BoxGeometry(12/16, 1/16, 12/16),
|
|
matStone);
|
|
mBasePlate.position.y = - (1/32 - armorstand.position.y);
|
|
armorstandWrapper.add(mBasePlate);
|
|
//Add a little dot, so the user knows which way is forward
|
|
var mmBaseDot = new THREE.Mesh(
|
|
new THREE.BoxGeometry(2/16, 1/16, 4/16),
|
|
matStone);
|
|
mmBaseDot.position.set(0,mBasePlate.position.y,10/16);
|
|
armorstandWrapper.add(mmBaseDot);
|
|
|
|
// To Generate the other body parts, we will use a mesh to display,
|
|
// and add it as a child to the object that serves as a pivot.
|
|
|
|
//Left Leg
|
|
var mmLegLeft = new THREE.Mesh(
|
|
new THREE.BoxGeometry(2/16, 11/16, 2/16),
|
|
matWood);
|
|
mmLegLeft.position.set(0,-5.5/16,0);
|
|
mLegLeft = new THREE.Object3D();
|
|
mLegLeft.position.set(2/16,11/16,0); //Pivot Point
|
|
mLegLeft.add(mmLegLeft);
|
|
armorstand.add(mLegLeft);
|
|
|
|
//Right Leg
|
|
var mmLegRight = new THREE.Mesh(
|
|
new THREE.BoxGeometry(2/16, 11/16, 2/16),
|
|
matWood);
|
|
mmLegRight.position.set(0,-5.5/16,0);
|
|
mLegRight = new THREE.Object3D();
|
|
mLegRight.position.set(-2/16,11/16,0); //Pivot Point
|
|
mLegRight.add(mmLegRight);
|
|
armorstand.add(mLegRight);
|
|
|
|
//Left Arm
|
|
var mmArmLeft = new THREE.Mesh(
|
|
new THREE.BoxGeometry(2/16, 12/16, 2/16),
|
|
matWood);
|
|
mmArmLeft.position.set(0,-4/16,0);
|
|
mArmLeft = new THREE.Object3D();
|
|
mArmLeft.position.set(6/16,21/16,0); //Pivot Point
|
|
mArmLeft.add(mmArmLeft);
|
|
armorstand.add(mArmLeft);
|
|
|
|
//Right Arm
|
|
var mmArmRight = new THREE.Mesh(
|
|
new THREE.BoxGeometry(2/16, 12/16, 2/16),
|
|
matWood);
|
|
mmArmRight.position.set(0,-4/16,0);
|
|
mArmRight = new THREE.Object3D();
|
|
mArmRight.position.set(-6/16,21/16,0); //Pivot Point
|
|
mArmRight.add(mmArmRight);
|
|
armorstand.add(mArmRight);
|
|
|
|
//Body (consists of four parts)
|
|
var mmHip = new THREE.Mesh(
|
|
new THREE.BoxGeometry(8/16, 2/16, 2/16),
|
|
matWood);
|
|
mmHip.position.set(0,-11/16,0);
|
|
var mmBodyLeft = new THREE.Mesh(
|
|
new THREE.BoxGeometry(2/16, 7/16, 2/16),
|
|
matWood);
|
|
mmBodyLeft.position.set(2/16,-6.5/16,0);
|
|
var mmBodyRight = new THREE.Mesh(
|
|
new THREE.BoxGeometry(2/16, 7/16, 2/16),
|
|
matWood);
|
|
mmBodyRight.position.set(-2/16,-6.5/16,0);
|
|
var mmShoulders = new THREE.Mesh(
|
|
new THREE.BoxGeometry(12/16, 3/16, 3/16),
|
|
matWood);
|
|
mmShoulders.position.set(0,-1.5/16,0);
|
|
mBody = new THREE.Object3D();
|
|
mBody.position.set(0,23/16,0); //Pivot Point
|
|
mBody.add(mmHip);
|
|
mBody.add(mmBodyLeft);
|
|
mBody.add(mmBodyRight);
|
|
mBody.add(mmShoulders);
|
|
armorstand.add(mBody);
|
|
|
|
//Head (neck and skull)
|
|
var mmNeck = new THREE.Mesh(
|
|
new THREE.BoxGeometry(2/16, 7/16, 2/16),
|
|
matWood);
|
|
mmNeck.position.set(0,3.5/16,0);
|
|
mSkull = new THREE.Mesh(
|
|
new THREE.BoxGeometry(10/16, 10/16, 10/16),
|
|
matTransparentStone);
|
|
mSkull.position.set(0,5/16,0);
|
|
mHead = new THREE.Object3D();
|
|
mHead.position.set(0,22/16,0); //Pivot Point
|
|
mHead.add(mmNeck);
|
|
mHead.add(mSkull);
|
|
armorstand.add(mHead);
|
|
|
|
|
|
scene.add(armorstandWrapper);
|
|
|
|
camera = new THREE.PerspectiveCamera(45, width/height, 0.1, 1000);
|
|
camera.position.y = 2;
|
|
camera.position.z = 4;
|
|
camera.lookAt(viewCenter);
|
|
scene.add(camera);
|
|
|
|
var pointLight = new THREE.PointLight(0xffffff);
|
|
pointLight.position.set(0, 300, 200);
|
|
|
|
scene.add(pointLight);
|
|
|
|
// Resize view
|
|
window.addEventListener("resize", () => {
|
|
width = $("#gl").width();
|
|
height = $("#gl").height();
|
|
|
|
camera.aspect = width / height;
|
|
camera.updateProjectionMatrix();
|
|
|
|
renderer.setSize(width, height);
|
|
});
|
|
}
|
|
|
|
const MC_VERSION = Object.freeze({
|
|
v1_8: 0,
|
|
v1_9: 1,
|
|
v1_11: 2,
|
|
v1_13: 3,
|
|
v1_14: 4,
|
|
v1_16: 5,
|
|
v1_20_5: 6,
|
|
v1_21: 7
|
|
});
|
|
|
|
function getMcVersion() {
|
|
let tag = document.getElementById("mcversion");
|
|
return tag.options.length - tag.selectedIndex - 1;
|
|
}
|
|
|
|
// Write stuff from input into variables
|
|
function handleInput(){
|
|
|
|
mcVersion = getMcVersion();
|
|
|
|
invisible = getCheckBoxInput("invisible");
|
|
invulnerable = getCheckBoxInput("invulnerable");
|
|
persistencerequired = getCheckBoxInput("persistencerequired");
|
|
noBasePlate = getCheckBoxInput("nobaseplate");
|
|
noGravity = getCheckBoxInput("nogravity");
|
|
showArms = getCheckBoxInput("showarms");
|
|
small = getCheckBoxInput("small");
|
|
marker = getCheckBoxInput("marker");
|
|
centercorrected = getCheckBoxInput("center-corrected");
|
|
|
|
useEquipment = getCheckBoxInput("useequipment");
|
|
equipHandRight = getInput("equipHandRight");
|
|
equipHandLeft = getInput("equipHandLeft");
|
|
equipShoes = getInput("equipShoes");
|
|
equipLeggings = getInput("equipLeggings");
|
|
equipChestplate = getInput("equipChestplate");
|
|
equipHelmet = getInput("equipHelmet");
|
|
equipCustomHeadMode = $("#equipCustomHeadMode").val();
|
|
|
|
equipColorShoes = $("#boots_color").css("background-color");
|
|
equipColorLeggings = $("#leggings_color").css("background-color");
|
|
equipColorChestplate = $("#chestplate_color").css("background-color");
|
|
equipColorHelmet = $("#helmet_color").css("background-color");
|
|
|
|
customName = getInput("customname");
|
|
showCustomName = getCheckBoxInput("showcustomname");
|
|
nameColor = getInput("namecolor");
|
|
nameBold = getCheckBoxInput("namebold");
|
|
nameItalic = getCheckBoxInput("nameitalic");
|
|
nameObfuscated = getCheckBoxInput("nameobfuscated");
|
|
nameStrikethrough = getCheckBoxInput("namestrikethrough");
|
|
|
|
scoreboardTags = getInput("scoreboardtags");
|
|
|
|
useDisabledSlots = getCheckBoxInput("usedisabledslots");
|
|
give = getCheckBoxInput("slashgive");
|
|
|
|
body.set(getRangeInput("bodyX"), getRangeInput("bodyY"), getRangeInput("bodyZ"));
|
|
head.set(getRangeInput("headX"), getRangeInput("headY"), getRangeInput("headZ"));
|
|
leftLeg.set(getRangeInput("leftLegX"), getRangeInput("leftLegY"), getRangeInput("leftLegZ"));
|
|
rightLeg.set(getRangeInput("rightLegX"), getRangeInput("rightLegY"), getRangeInput("rightLegZ"));
|
|
leftArm.set(getRangeInput("leftArmX"), getRangeInput("leftArmY"), getRangeInput("leftArmZ"));
|
|
rightArm.set(getRangeInput("rightArmX"), getRangeInput("rightArmY"), getRangeInput("rightArmZ"));
|
|
|
|
rotation = getRangeInput("rotation");
|
|
|
|
updateUI();
|
|
};
|
|
|
|
function getCheckBoxInput(name) {
|
|
return $("input[name="+name+"]").prop("checked");
|
|
};
|
|
|
|
function getRangeInput(name) {
|
|
return $("input[name="+name+"]").val();
|
|
};
|
|
|
|
function getInput(name) {
|
|
return $("input[name="+name+"]").val();
|
|
};
|
|
|
|
/** Changes stuff according to our input values */
|
|
function updateUI(){
|
|
|
|
//Hide/Show different inputs
|
|
|
|
if(showArms)
|
|
$("#inputarms").slideDown();
|
|
else
|
|
$("#inputarms").slideUp();
|
|
|
|
if(useEquipment){
|
|
$("#customequipment").slideDown();
|
|
|
|
// Hide left hand item input for minecraft 1.8
|
|
if(mcVersion < MC_VERSION.v1_9) {
|
|
$("#equipHandLeft").hide();
|
|
} else {
|
|
$("#equipHandLeft").show();
|
|
}
|
|
|
|
let chestplate = chestplateList;
|
|
let helmet = helmetList;
|
|
let boots = bootsList;
|
|
let leggings = leggingsList;
|
|
|
|
// Hide elytra for versions <1.9
|
|
if (mcVersion < MC_VERSION.v1_9) {
|
|
chestplate = chestplate.filter("[value!=elytra]");
|
|
}
|
|
|
|
// Hide turtle_helmet for versions <1.13
|
|
if (mcVersion < MC_VERSION.v1_13) {
|
|
helmet = helmet.filter("[value!=turtle_helmet]");
|
|
}
|
|
|
|
// Hide netherite armor for versions < 1.16
|
|
if (mcVersion < MC_VERSION.v1_16) {
|
|
helmet = helmet.filter("[value!=netherite_helmet]");
|
|
chestplate = chestplate.filter("[value!=netherite_chestplate]");
|
|
leggings = leggings.filter("[value!=netherite_leggings]");
|
|
boots = boots.filter("[value!=netherite_boots]");
|
|
}
|
|
|
|
$("#list-helmet").empty().append(helmet);
|
|
$("#list-chestplate").empty().append(chestplate);
|
|
$("#list-leggings").empty().append(leggings);
|
|
$("#list-shoes").empty().append(boots);
|
|
|
|
}
|
|
else
|
|
$("#customequipment").slideUp();
|
|
|
|
//Different colorinputs for armorparts
|
|
if(isLeatherArmor(equipShoes))
|
|
$("#boots_color").slideDown();
|
|
else
|
|
$("#boots_color").slideUp();
|
|
if(isLeatherArmor(equipLeggings))
|
|
$("#leggings_color").slideDown();
|
|
else
|
|
$("#leggings_color").slideUp();
|
|
if(isLeatherArmor(equipChestplate))
|
|
$("#chestplate_color").slideDown();
|
|
else
|
|
$("#chestplate_color").slideUp();
|
|
if(isLeatherArmor(equipHelmet))
|
|
$("#helmet_color").slideDown();
|
|
else
|
|
$("#helmet_color").slideUp();
|
|
|
|
// Link to minecraft-heads.com
|
|
if(equipCustomHeadMode == "givecode"){
|
|
$("#minecraft-heads").slideDown();
|
|
}
|
|
else{
|
|
$("#minecraft-heads").slideUp();
|
|
}
|
|
|
|
// Show disabled slots
|
|
if(useDisabledSlots) {
|
|
// Hide offhand disabled slot buttons for versions below 1.13
|
|
if (mcVersion > MC_VERSION.v1_13) {
|
|
$(".sprite.offhand").show();
|
|
$("#dO").show();
|
|
$("#rO").show();
|
|
$("#pO").show();
|
|
} else {
|
|
$(".sprite.offhand").hide();
|
|
$("#dO").hide();
|
|
$("#rO").hide();
|
|
$("#pO").hide();
|
|
}
|
|
|
|
$("#disabledslots").slideDown();
|
|
} else {
|
|
$("#disabledslots").slideUp();
|
|
}
|
|
|
|
//Hide 1.13 features for 1.12 and lower.
|
|
if (mcVersion < MC_VERSION.v1_13) {
|
|
$("#namecustomization").hide();
|
|
$("#centercorrected").hide();
|
|
} else {
|
|
$("#namecustomization").show();
|
|
$("#centercorrected").show();
|
|
}
|
|
|
|
// Generate code
|
|
const generatedCode = generateCode();
|
|
$("#code").text(generatedCode);
|
|
|
|
// Show hint, when command is too long
|
|
const characterLimit = (mcVersion <= MC_VERSION.v1_9) ? 100 : 256;
|
|
if (generatedCode.length > characterLimit)
|
|
$("#codeinfo").slideDown();
|
|
else
|
|
$("#codeinfo").slideUp();
|
|
|
|
|
|
// Rotate 3D Stuff
|
|
// y and z rotation needs to be inverted
|
|
setRotation(mBody, body);
|
|
setRotation(mHead, head);
|
|
setRotation(mLegLeft, leftLeg);
|
|
setRotation(mLegRight, rightLeg);
|
|
setRotation(mArmLeft, leftArm);
|
|
setRotation(mArmRight, rightArm);
|
|
armorstand.rotation.y = -rotation * DEG2RAD;
|
|
|
|
// Scale model, depending on small variable
|
|
if(small)
|
|
armorstand.scale.set(0.6, 0.6, 0.6);
|
|
else
|
|
armorstand.scale.set(1, 1, 1);
|
|
|
|
//Set Visibility
|
|
mArmRight.visible = mArmLeft.visible = showArms;
|
|
mBasePlate.visible = !noBasePlate;
|
|
mSkull.visible = equipHelmet != "";
|
|
}
|
|
|
|
function generateCode() {
|
|
const tags = {
|
|
Invisible: invisible || null,
|
|
Invulnerable: invulnerable || null,
|
|
PersistenceRequired: persistencerequired || null,
|
|
NoBasePlate: noBasePlate || null,
|
|
NoGravity: noGravity || null,
|
|
ShowArms: showArms || null,
|
|
Small: small || null,
|
|
Marker: marker || null,
|
|
|
|
Rotation: (rotation != 0) ? [ new NBTFloat(rotation) ] : null,
|
|
|
|
CustomNameVisible: showCustomName || null,
|
|
CustomName: (customName) ? generateCustomName() : null,
|
|
|
|
DisabledSlots: (useDisabledSlots) ? calculateDisabledSlotsFlag() : null,
|
|
Pose: generatePose(),
|
|
};
|
|
|
|
// Equipment
|
|
if (useEquipment) {
|
|
if (mcVersion == MC_VERSION.v1_8) {
|
|
// Old 1.8 Equipment format
|
|
// Equipment: [ RightHand, Boots, Leggings, Chestplate, Helmet ]
|
|
const rightHandItem = generateHandItems()[0];
|
|
tags.Equipment = [rightHandItem, ...generateArmorItems()];
|
|
} else {
|
|
// New 1.9+ Equipment format
|
|
if (equipShoes != "" || equipLeggings != "" || equipChestplate != "" || equipHelmet != "") {
|
|
tags.ArmorItems = generateArmorItems();
|
|
}
|
|
|
|
if (equipHandRight != "" || equipHandLeft != "") {
|
|
tags.HandItems = generateHandItems();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Scoreboard tags
|
|
if (scoreboardTags) {
|
|
const tagsList = scoreboardTags.split(',');
|
|
if (!tagsList[tagsList.length - 1].trim()) {
|
|
tagsList.pop();
|
|
}
|
|
|
|
tags.Tags = tagsList.map(value => value.trim());
|
|
}
|
|
|
|
// Generate the final command
|
|
if (give && mcVersion > MC_VERSION.v1_16) {
|
|
tags.id = "minecraft:armor_stand";
|
|
}
|
|
|
|
const parsedTags = NBT.stringify(tags);
|
|
|
|
if (give) {
|
|
let command = "/give @p ";
|
|
if (mcVersion <= MC_VERSION.v1_11) {
|
|
return command + "minecraft:armor_stand 1 0 {EntityTag:" + parsedTags + "}";
|
|
|
|
} else if (mcVersion <= MC_VERSION.v1_16) {
|
|
return command + "minecraft:armor_stand{EntityTag:" + parsedTags + "} 1"
|
|
|
|
} else {
|
|
let code = "minecraft:armor_stand[minecraft:entity_data=" + parsedTags;
|
|
if (customName && mcVersion >= MC_VERSION.v1_21) {
|
|
code += `,minecraft:custom_name=${generateCustomName()}`
|
|
}
|
|
return command + code + "] 1";
|
|
}
|
|
} else {
|
|
if (mcVersion <= MC_VERSION.v1_9) {
|
|
// Old entity name
|
|
return "/summon ArmorStand ~ ~ ~ " + parsedTags;
|
|
|
|
} else if (mcVersion < MC_VERSION.v1_13) {
|
|
return "/summon minecraft:armor_stand ~ ~ ~ " + parsedTags;
|
|
|
|
} else {
|
|
// In 1.13, positions are no longer center-corrected.
|
|
// Adding .5 makes it centered. However for players it is already center-corrected
|
|
let position = centercorrected ? "~ ~-0.5 ~" : "~ ~ ~";
|
|
return "/summon minecraft:armor_stand " + position + " " + parsedTags;
|
|
}
|
|
}
|
|
}
|
|
|
|
function generateCustomName() {
|
|
if (mcVersion <= MC_VERSION.v1_11) {
|
|
// Versions less than 1.12 did not support styles
|
|
return customName;
|
|
}
|
|
|
|
let props = {};
|
|
|
|
if (customName) {
|
|
props.text = customName;
|
|
}
|
|
|
|
if (nameColor) {
|
|
props.color = nameColor;
|
|
}
|
|
|
|
if (nameBold) {
|
|
props.bold = nameBold;
|
|
}
|
|
|
|
if (nameItalic) {
|
|
props.italic = nameItalic;
|
|
}
|
|
|
|
if (nameStrikethrough) {
|
|
props.strikethrough = nameStrikethrough;
|
|
}
|
|
|
|
if (nameObfuscated) {
|
|
props.obfuscated = nameObfuscated;
|
|
}
|
|
|
|
let stringified = JSON.stringify(props);
|
|
if (mcVersion < MC_VERSION.v1_14) {
|
|
// Stringify again to escape double quotes, as versions below 1.14
|
|
// did not have the ability to use single quotes as strings
|
|
return new NBTRaw(JSON.stringify(stringified));
|
|
}
|
|
|
|
return new NBTRaw("'" + stringified + "'");
|
|
}
|
|
|
|
function generateArmorItems() {
|
|
function generateArmorItem(armorID) {
|
|
if (armorID === "") {
|
|
return {};
|
|
}
|
|
|
|
let data = {
|
|
id: armorID,
|
|
Count: 1,
|
|
}
|
|
|
|
// If the armor is leather, then apply its color
|
|
if (isLeatherArmor(armorID)) {
|
|
const element = $(`#${armorID.substring(8) + "_color"}`);
|
|
const color = getDecimalRGB(element.css("background-color"));
|
|
|
|
if (mcVersion >= MC_VERSION.v1_20_5) {
|
|
data.components = {
|
|
dyed_color: { rgb: color }
|
|
};
|
|
} else {
|
|
data.tag = {
|
|
display: {
|
|
color: color
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
// Equipments (aka ArmorItems) are order-sensitive
|
|
// and must follow the order: feet, legs, chest, head
|
|
let items = [
|
|
generateArmorItem(equipShoes),
|
|
generateArmorItem(equipLeggings),
|
|
generateArmorItem(equipChestplate),
|
|
];
|
|
|
|
// Handle different items in the head slot
|
|
if (equipHelmet == "") {
|
|
items.push({});
|
|
return items;
|
|
}
|
|
|
|
switch (equipCustomHeadMode) {
|
|
case "item":
|
|
items.push(generateArmorItem(equipHelmet));
|
|
break;
|
|
|
|
// Head is a player head with the given name
|
|
case "player": {
|
|
let data = {
|
|
id: (mcVersion <= MC_VERSION.v1_11) ? "skull" : "player_head",
|
|
Count: 1,
|
|
};
|
|
|
|
if (mcVersion <= MC_VERSION.v1_11) {
|
|
data.Damage = 3;
|
|
}
|
|
|
|
if (mcVersion <= MC_VERSION.v1_16) {
|
|
data.tag = { SkullOwner: equipHelmet };
|
|
} else {
|
|
data.components = {
|
|
profile: { name: equipHelmet }
|
|
};
|
|
}
|
|
|
|
items.push(data);
|
|
break;
|
|
}
|
|
|
|
case "url": {
|
|
// Best reference: http://redd.it/24quwx
|
|
const base64Value = btoa(JSON.stringify({
|
|
textures: {
|
|
SKIN: { url: equipHelmet }
|
|
}
|
|
}));
|
|
|
|
const innerNBT = {
|
|
Id: (mcVersion >= MC_VERSION.v1_16) ? generateIntArray() : generateUUID(),
|
|
Properties: {
|
|
textures: [{ Value: base64Value }]
|
|
}
|
|
};
|
|
|
|
const data = {
|
|
id: "minecraft:player_head",
|
|
Count: 1
|
|
};
|
|
|
|
if (mcVersion >= MC_VERSION.v1_20_5) {
|
|
data.components = {
|
|
profile: innerNBT
|
|
};
|
|
|
|
} else {
|
|
data.tag = {
|
|
SkullOwner: innerNBT
|
|
};
|
|
|
|
if (mcVersion < MC_VERSION.v1_13) {
|
|
data.id = "skull";
|
|
data.Damage = 3;
|
|
}
|
|
}
|
|
|
|
items.push(data);
|
|
break;
|
|
}
|
|
|
|
case "givecode": {
|
|
// For now, assume the give code is from minecraft-heads
|
|
// TODO Parser to read any valid give codes
|
|
const data = {
|
|
id: "minecraft:player_head",
|
|
Count: 1
|
|
};
|
|
|
|
if (mcVersion < MC_VERSION.v1_13) {
|
|
data.id = "skull";
|
|
data.Damage = 3;
|
|
data.tag = new NBTRaw(equipHelmet.trim().slice(29));
|
|
|
|
} else if (mcVersion < MC_VERSION.v1_20_5) {
|
|
data.tag = new NBTRaw(equipHelmet.trim().slice(30, -2));
|
|
|
|
} else {
|
|
// Extracting the entity data for versions greater than 1.20.5 requires more work.
|
|
// Format of the give code that is generated from minecraft-heads:
|
|
// /give @p minecraft:player_head[minecraft:custom_name='...', minecraft:lore=[...], profile={...}] 1
|
|
|
|
const nameIndex = equipHelmet.indexOf("minecraft:custom_name=");
|
|
const loreIndex = equipHelmet.indexOf("minecraft:lore=");
|
|
const profileIndex = equipHelmet.indexOf("profile=");
|
|
|
|
const customName = equipHelmet.slice(nameIndex + 22, loreIndex - 1);
|
|
const lore = equipHelmet.slice(loreIndex + 15, profileIndex - 1);
|
|
const profile = equipHelmet.slice(profileIndex + 8, -3);
|
|
|
|
data.components = {
|
|
custom_name: new NBTRaw(customName),
|
|
lore: new NBTRaw(lore),
|
|
profile: new NBTRaw(profile),
|
|
};
|
|
}
|
|
|
|
items.push(data);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return items;
|
|
}
|
|
|
|
function generateHandItems() {
|
|
function generateHandItem(item) {
|
|
if (item == "") {
|
|
return {};
|
|
}
|
|
|
|
return {
|
|
id: item,
|
|
Count: 1
|
|
};
|
|
}
|
|
|
|
// HandItems must follow the order: Main hand (right hand), Off hand (left hand)
|
|
return [
|
|
generateHandItem(equipHandRight),
|
|
generateHandItem(equipHandLeft),
|
|
];
|
|
}
|
|
|
|
function generatePose() {
|
|
const pose = {};
|
|
|
|
if (!isZero(body)) {
|
|
pose.Body = toNBTFloatArray(body);
|
|
}
|
|
|
|
if (!isZero(head)) {
|
|
pose.Head = toNBTFloatArray(head);
|
|
}
|
|
|
|
if (!isZero(leftLeg)) {
|
|
pose.LeftLeg = toNBTFloatArray(leftLeg);
|
|
}
|
|
|
|
if (!isZero(rightLeg)) {
|
|
pose.RightLeg = toNBTFloatArray(rightLeg);
|
|
}
|
|
|
|
if (showArms) {
|
|
if (!isZero(leftArm)) {
|
|
pose.LeftArm = toNBTFloatArray(leftArm);
|
|
}
|
|
|
|
if (!isZero(rightArm)) {
|
|
pose.RightArm = toNBTFloatArray(rightArm);
|
|
}
|
|
}
|
|
|
|
return (Object.keys(pose).length > 0) ? pose : null;
|
|
}
|
|
|
|
function calculateDisabledSlotsFlag() {
|
|
var dO = $("#dO").is(":checked") ? 1 << (5) : 0;
|
|
var dH = $("#dH").is(":checked") ? 1 << (4) : 0;
|
|
var dC = $("#dC").is(":checked") ? 1 << (3) : 0;
|
|
var dL = $("#dL").is(":checked") ? 1 << (2) : 0;
|
|
var dB = $("#dB").is(":checked") ? 1 << (1) : 0;
|
|
var dW = $("#dW").is(":checked") ? 1 << (0) : 0;
|
|
var dR = dO + dH + dC + dL + dB + dW;
|
|
|
|
var rO = $("#rO").is(":checked") ? 1 << (5 + 8) : 0;
|
|
var rH = $("#rH").is(":checked") ? 1 << (4 + 8) : 0;
|
|
var rC = $("#rC").is(":checked") ? 1 << (3 + 8) : 0;
|
|
var rL = $("#rL").is(":checked") ? 1 << (2 + 8) : 0;
|
|
var rB = $("#rB").is(":checked") ? 1 << (1 + 8) : 0;
|
|
var rW = $("#rW").is(":checked") ? 1 << (0 + 8) : 0;
|
|
var rR = rO + rH + rC + rL + rB + rW;
|
|
|
|
var pO = $("#pO").is(":checked") ? 1 << (5 + 16) : 0;
|
|
var pH = $("#pH").is(":checked") ? 1 << (4 + 16) : 0;
|
|
var pC = $("#pC").is(":checked") ? 1 << (3 + 16) : 0;
|
|
var pL = $("#pL").is(":checked") ? 1 << (2 + 16) : 0;
|
|
var pB = $("#pB").is(":checked") ? 1 << (1 + 16) : 0;
|
|
var pW = $("#pW").is(":checked") ? 1 << (0 + 16) : 0;
|
|
var pR = pO + pH + pC + pL + pB + pW;
|
|
|
|
var result = dR + rR + pR;
|
|
return result;
|
|
}
|
|
|
|
function isZero(vector) {
|
|
return vector.x == 0 && vector.y == 0 && vector.z == 0;
|
|
}
|
|
|
|
function toNBTFloatArray(vector) {
|
|
return [ new NBTFloat(vector.x), new NBTFloat(vector.y), new NBTFloat(vector.z) ];
|
|
}
|
|
|
|
function getMouseDeltaX(){
|
|
var mouseDeltaX = 0;
|
|
if(mouseDownX != null && mouseMoveX != null){
|
|
mouseDeltaX = mouseMoveX - mouseDownX;
|
|
}
|
|
return mouseDeltaX * mouseRotationMultiplier;
|
|
}
|
|
function getMouseDeltaY(){
|
|
var mouseDeltaY = 0;
|
|
if(mouseDownY != null && mouseMoveY != null){
|
|
mouseDeltaY = mouseMoveY - mouseDownY;
|
|
}
|
|
return mouseDeltaY * mouseRotationMultiplier;
|
|
}
|
|
|
|
function render(){
|
|
renderer.render(scene, camera);
|
|
|
|
armorstandWrapper.rotation.y = rotY + getMouseDeltaX();
|
|
armorstandWrapper.rotation.x = rotX + getMouseDeltaY();
|
|
|
|
requestAnimationFrame(render);
|
|
}
|
|
|
|
// ---- Additional functions
|
|
|
|
function generateUUID() {
|
|
// From here: http://stackoverflow.com/a/8809472/1456971
|
|
var d = new Date().getTime();
|
|
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
var r = (d + Math.random()*16)%16 | 0;
|
|
d = Math.floor(d/16);
|
|
return (c=='x' ? r : (r&0x3|0x8)).toString(16);
|
|
});
|
|
|
|
return uuid;
|
|
}
|
|
|
|
function generateIntArray() {
|
|
const buffer = new Uint32Array(4);
|
|
const UUID = new DataView(buffer.buffer);
|
|
const paddings = [8, 4, 4, 4, 12];
|
|
|
|
let hexUUID = generateUUID().split("-").map((val, i) => val.padStart(paddings[i], "0")).join("");
|
|
let ints = [];
|
|
|
|
for (let i = 0; i < 4; i++) {
|
|
num = Number("0x" + hexUUID.substring(i*8, (i+1)*8));
|
|
UUID.setInt32(i*4, num);
|
|
ints.push(UUID.getInt32(i*4));
|
|
}
|
|
|
|
return new NBTArrayInt(ints);
|
|
}
|
|
|
|
function getDecimalRGB(rgb){
|
|
//The string has the format 'rgb(r, g, b)'
|
|
|
|
//Remove whitespaces. Now formatted: 'rgb(r,g,b)'
|
|
rgb = rgb.replace(/ /g,"");
|
|
|
|
var r = rgb.substring(4,rgb.indexOf(","));
|
|
var g = rgb.substring(rgb.indexOf(",")+1,rgb.lastIndexOf(","));
|
|
var b = rgb.substring(rgb.lastIndexOf(",")+1, rgb.length-1);
|
|
|
|
|
|
return (r << 16) | (g << 8) | b;
|
|
}
|
|
|
|
function isLeatherArmor(item) {
|
|
return item ? item.startsWith("leather_") : false;
|
|
}
|
|
|
|
// Rotate three.js mesh to fit the minecraft rotation
|
|
function setRotation(mesh, rotation){
|
|
rotateAroundWorldAxis(mesh, new THREE.Vector3(1,0,0), rotation.x * DEG2RAD, true);
|
|
rotateAroundWorldAxis(mesh, new THREE.Vector3(0,1,0), -rotation.y * DEG2RAD, false);
|
|
rotateAroundWorldAxis(mesh, new THREE.Vector3(0,0,1), -rotation.z * DEG2RAD, false);
|
|
}
|
|
|
|
// From here: http://stackoverflow.com/a/11124197/1456971
|
|
var rotWorldMatrix;
|
|
// Rotate an object around an arbitrary axis in world space
|
|
function rotateAroundWorldAxis(object, axis, radians, reset) {
|
|
rotWorldMatrix = new THREE.Matrix4();
|
|
rotWorldMatrix.makeRotationAxis(axis.normalize(), radians);
|
|
if(!reset)
|
|
rotWorldMatrix.multiply(object.matrix); // pre-multiply
|
|
object.matrix = rotWorldMatrix;
|
|
object.rotation.setFromRotationMatrix(object.matrix);
|
|
}
|
|
|
|
function saveData() {
|
|
// Handles saving of armor stand data
|
|
const SAVE_DATA = {
|
|
name: $(`#creationname`).val() === `` ? `My Armor Stand #${localStorage.length + 1}` : $(`#creationname`).val(),
|
|
version: $(`#mcversion`).val(),
|
|
|
|
options: {
|
|
invisible: getCheckBoxInput("invisible"),
|
|
invulnerable: getCheckBoxInput("invulnerable"),
|
|
presistence_required: getCheckBoxInput("persistencerequired"),
|
|
no_base_plate: getCheckBoxInput("nobaseplate"),
|
|
no_gravity: getCheckBoxInput("nogravity"),
|
|
show_arms: getCheckBoxInput("showarms"),
|
|
small: getCheckBoxInput("small"),
|
|
marker: getCheckBoxInput("marker"),
|
|
center_corrected: getCheckBoxInput("center-corrected")
|
|
},
|
|
|
|
rotation: {
|
|
main: getRangeInput("rotation"),
|
|
head: [getRangeInput("headX"), getRangeInput("headY"), getRangeInput("headZ")],
|
|
body: [getRangeInput("bodyX"), getRangeInput("bodyY"), getRangeInput("bodyZ")],
|
|
legs: {
|
|
left: [getRangeInput("leftLegX"), getRangeInput("leftLegY"), getRangeInput("leftLegZ")],
|
|
right: [getRangeInput("rightLegX"), getRangeInput("rightLegY"), getRangeInput("rightLegZ")],
|
|
},
|
|
arms: {
|
|
left: [getRangeInput("leftArmX"), getRangeInput("leftArmY"), getRangeInput("leftArmZ")],
|
|
right: [getRangeInput("rightArmX"), getRangeInput("rightArmY"), getRangeInput("rightArmZ")]
|
|
}
|
|
},
|
|
|
|
equipment: {
|
|
enabled: getCheckBoxInput("useequipment"),
|
|
hands: {
|
|
right: getInput("equipHandRight"),
|
|
left: getInput("equipHandLeft")
|
|
},
|
|
boots: getInput("equipShoes"),
|
|
leggings: getInput("equipLeggings"),
|
|
chestplate: getInput("equipChestplate"),
|
|
helmet: getInput("equipHelmet"),
|
|
helmet_specifies: $("#equipCustomHeadMode").val(),
|
|
|
|
leather_colours: {
|
|
helmet: $(`#helmet_color`).css(`background-color`),
|
|
chestplate: $(`#chestplate_color`).css(`background-color`),
|
|
leggings: $(`#leggings_color`).css(`background-color`),
|
|
boots: $(`#boots_color`).css(`background-color`)
|
|
}
|
|
},
|
|
|
|
custom_name: {
|
|
name: $(`#customname`).val(),
|
|
show_custom_name: getCheckBoxInput("showcustomname"),
|
|
name_color: getInput("namecolor"),
|
|
options: {
|
|
bold: getCheckBoxInput("namebold"),
|
|
italic: getCheckBoxInput("nameitalic"),
|
|
obfuscated: getCheckBoxInput("nameobfuscated"),
|
|
strikethrough: getCheckBoxInput("namestrikethrough")
|
|
}
|
|
},
|
|
|
|
scoreboard_tags: getInput("scoreboardtags"),
|
|
|
|
lock_slot_interaction: {
|
|
enabled: $("input[name=usedisabledslots]").is(":checked"),
|
|
remove: {
|
|
helmet: $("#dH").is(":checked"),
|
|
chestplate: $("#dC").is(":checked"),
|
|
leggings: $("#dL").is(":checked"),
|
|
boots: $("#dB").is(":checked"),
|
|
weapons: $("#dW").is(":checked"),
|
|
offhand: $("#dO").is(":checked")
|
|
},
|
|
replace: {
|
|
helmet: $("#rH").is(":checked"),
|
|
chestplate: $("#rC").is(":checked"),
|
|
leggings: $("#rL").is(":checked"),
|
|
boots: $("#rB").is(":checked"),
|
|
weapons: $("#rW").is(":checked"),
|
|
offhand: $("#rO").is(":checked")
|
|
},
|
|
place: {
|
|
helmet: $("#pH").is(":checked"),
|
|
chestplate: $("#pC").is(":checked"),
|
|
leggings: $("#pL").is(":checked"),
|
|
boots: $("#pB").is(":checked"),
|
|
weapons: $("#pW").is(":checked"),
|
|
offhand: $("#pO").is(":checked")
|
|
}
|
|
}
|
|
};
|
|
|
|
localStorage.setItem(SAVE_DATA.name, JSON.stringify(SAVE_DATA));
|
|
loadScreen();
|
|
$(`#creationname`).val(``);
|
|
alert(`Awesome! Your creation has been saved as ${SAVE_DATA.name}.`);
|
|
};
|
|
|
|
function loadData(data) {
|
|
//console.log(`loading data!`);
|
|
data = localStorage.getItem(data);
|
|
if (!data) return alert(`An error occurred while loading the creation.`);
|
|
|
|
try {
|
|
data = JSON.parse(data);
|
|
|
|
// version
|
|
$(`#mcversion`).val(data.version);
|
|
|
|
// options
|
|
$("input[name=invisible]").prop(`checked`, data.options.invisible);
|
|
$("input[name=invulnerable]").prop(`checked`, data.options.invulnerable);
|
|
$("input[name=persistencerequired]").prop(`checked`, data.options.presistence_required);
|
|
$("input[name=nobaseplate]").prop(`checked`, data.options.no_base_plate);
|
|
$("input[name=nogravity]").prop(`checked`, data.options.no_gravity);
|
|
$("input[name=showarms]").prop(`checked`, data.options.show_arms);
|
|
$("input[name=small]").prop(`checked`, data.options.small);
|
|
$("input[name=marker]").prop(`checked`, data.options.marker);
|
|
$("input[name=center-corrected]").prop(`checked`, data.options.center_corrected);
|
|
|
|
// rotation
|
|
$("input[name=rotation]").val(data.rotation.main);
|
|
$("input[name=headX]").val(data.rotation.head[0]);
|
|
$("input[name=headY]").val(data.rotation.head[1]);
|
|
$("input[name=headZ]").val(data.rotation.head[2]);
|
|
|
|
$("input[name=bodyX]").val(data.rotation.body[0]);
|
|
$("input[name=bodyY]").val(data.rotation.body[1]);
|
|
$("input[name=bodyZ]").val(data.rotation.body[2]);
|
|
|
|
$("input[name=leftLegX]").val(data.rotation.legs.left[0]);
|
|
$("input[name=leftLegY]").val(data.rotation.legs.left[1]);
|
|
$("input[name=leftLegZ]").val(data.rotation.legs.left[2]);
|
|
|
|
$("input[name=rightLegX]").val(data.rotation.legs.right[0]);
|
|
$("input[name=rightLegY]").val(data.rotation.legs.right[1]);
|
|
$("input[name=rightLegZ]").val(data.rotation.legs.right[2]);
|
|
|
|
$("input[name=leftArmX]").val(data.rotation.arms.left[0]);
|
|
$("input[name=leftArmY]").val(data.rotation.arms.left[1]);
|
|
$("input[name=leftArmZ]").val(data.rotation.arms.left[2]);
|
|
|
|
$("input[name=rightArmX]").val(data.rotation.arms.right[0]);
|
|
$("input[name=rightArmY]").val(data.rotation.arms.right[1]);
|
|
$("input[name=rightArmZ]").val(data.rotation.arms.right[2]);
|
|
|
|
//equipment
|
|
$("input[name=useequipment]").prop(`checked`, data.equipment.enabled);
|
|
$(`input[name=equipShoes]`).val(data.equipment.boots);
|
|
$(`input[name=equipLeggings]`).val(data.equipment.leggings);
|
|
$(`input[name=equipChestplate]`).val(data.equipment.chestplate);
|
|
$(`input[name=equipHelmet]`).val(data.equipment.helmet);
|
|
$(`input[name=equipHandRight]`).val(data.equipment.hands.right);
|
|
$(`input[name=equipHandLeft]`).val(data.equipment.hands.left);
|
|
$(`#equipCustomHeadMode`).val(data.equipment.helmet_specifies);
|
|
|
|
$(`#helmet_color`).css(`background-color`, data.equipment.leather_colours.helmet);
|
|
$(`#chestplate_color`).css(`background-color`, data.equipment.leather_colours.chestplate);
|
|
$(`#leggings_color`).css(`background-color`, data.equipment.leather_colours.leggings);
|
|
$(`#boots_color`).css(`background-color`, data.equipment.leather_colours.boots);
|
|
|
|
//custom name
|
|
$(`#customname`).val(data.custom_name.name);
|
|
$(`input[name=showcustomname]`).prop(`checked`, data.custom_name.show_custom_name);
|
|
$(`input[name=namecolor]`).val(data.custom_name.name_color);
|
|
$("input[name=namebold]").prop(`checked`, data.custom_name.options.bold);
|
|
$("input[name=nameitalic]").prop(`checked`, data.custom_name.options.italic);
|
|
$("input[name=nameobfuscated]").prop(`checked`, data.custom_name.options.obfuscated);
|
|
$("input[name=namestrikethrough]").prop(`checked`, data.custom_name.options.strikethrough);
|
|
|
|
$("input[name=scoreboardtags]").val(data.scoreboard_tags);
|
|
|
|
//lock slot interaction
|
|
$("input[name=usedisabledslots]").prop(`checked`, data.lock_slot_interaction.enabled);
|
|
|
|
$(`#dO`).prop(`checked`, data.lock_slot_interaction.remove.offhand);
|
|
$(`#dH`).prop(`checked`, data.lock_slot_interaction.remove.helmet);
|
|
$(`#dC`).prop(`checked`, data.lock_slot_interaction.remove.chestplate);
|
|
$(`#dL`).prop(`checked`, data.lock_slot_interaction.remove.leggings);
|
|
$(`#dB`).prop(`checked`, data.lock_slot_interaction.remove.boots);
|
|
$(`#dW`).prop(`checked`, data.lock_slot_interaction.remove.weapons);
|
|
|
|
$(`#rO`).prop(`checked`, data.lock_slot_interaction.replace.offhand);
|
|
$(`#rH`).prop(`checked`, data.lock_slot_interaction.replace.helmet);
|
|
$(`#rC`).prop(`checked`, data.lock_slot_interaction.replace.chestplate);
|
|
$(`#rL`).prop(`checked`, data.lock_slot_interaction.replace.leggings);
|
|
$(`#rB`).prop(`checked`, data.lock_slot_interaction.replace.boots);
|
|
$(`#rW`).prop(`checked`, data.lock_slot_interaction.replace.weapons);
|
|
|
|
$(`#pO`).prop(`checked`, data.lock_slot_interaction.place.offhand);
|
|
$(`#pH`).prop(`checked`, data.lock_slot_interaction.place.helmet);
|
|
$(`#pC`).prop(`checked`, data.lock_slot_interaction.place.chestplate);
|
|
$(`#pL`).prop(`checked`, data.lock_slot_interaction.place.leggings);
|
|
$(`#pB`).prop(`checked`, data.lock_slot_interaction.place.boots);
|
|
$(`#pW`).prop(`checked`, data.lock_slot_interaction.place.weapons);
|
|
|
|
handleInput();
|
|
} catch (err) {
|
|
console.error(err);
|
|
alert(`An error occurred while loading the creation.`);
|
|
};
|
|
|
|
//loadScreen();
|
|
};
|
|
|
|
function deleteSave(data) {
|
|
localStorage.removeItem(data);
|
|
loadScreen();
|
|
alert(`${data} has been deleted!`);
|
|
};
|
|
|
|
// Define NBT classes for properly stringifying JS objects to NBT
|
|
class NBTObject {};
|
|
|
|
class NBTRaw extends NBTObject {
|
|
constructor(raw) {
|
|
super();
|
|
this.raw = raw;
|
|
}
|
|
|
|
toString() {
|
|
return this.raw;
|
|
}
|
|
}
|
|
|
|
class NBTFloat extends NBTObject {
|
|
constructor(n) {
|
|
super();
|
|
this.n = n;
|
|
}
|
|
|
|
toString() {
|
|
return this.n + "f";
|
|
}
|
|
}
|
|
|
|
class NBTArrayInt extends NBTObject {
|
|
constructor(arr) {
|
|
super();
|
|
this.arr = arr;
|
|
}
|
|
|
|
toString() {
|
|
return "[I;" + this.arr.join(",") + "]";
|
|
}
|
|
};
|
|
|
|
class NBT {
|
|
static stringify(object) {
|
|
const type = typeof object;
|
|
switch (type) {
|
|
case "string":
|
|
return '"' + object + '"';
|
|
|
|
case "number":
|
|
case "boolean":
|
|
return new String(object);
|
|
|
|
case "object": {
|
|
if (Array.isArray(object)) {
|
|
return "[" +
|
|
object
|
|
.filter(value => value != null)
|
|
.map(value => NBT.stringify(value))
|
|
.join(",")
|
|
+ "]";
|
|
}
|
|
|
|
if (object instanceof NBTObject) {
|
|
return object.toString();
|
|
}
|
|
|
|
// Fallback (javascript object)
|
|
return "{" +
|
|
Object.entries(object)
|
|
.filter(([key, value]) => value != null)
|
|
.map(([key, value]) => key + ":" + NBT.stringify(value))
|
|
.join(",")
|
|
+ "}";
|
|
}
|
|
}
|
|
}
|
|
} |