mirror of
https://github.com/haselkern/Minecraft-ArmorStand.git
synced 2025-05-17 15:05:33 +00:00
Support 1.20.5 and 1.21 + more
* Add support for versions 1.20.5+ and 1.21 (Fixes #49). * Add `elytra` as an option for chestplates. * Reimplement the code generation of the armor stand, to make it easy to support future versions.
This commit is contained in:
parent
46864f706c
commit
ea0195b36b
2 changed files with 447 additions and 336 deletions
31
index.htm
31
index.htm
|
@ -32,7 +32,9 @@
|
||||||
|
|
||||||
<div class="padding underline">
|
<div class="padding underline">
|
||||||
<select id="mcversion">
|
<select id="mcversion">
|
||||||
<option value="1.16">Minecraft 1.16 and above</option>
|
<option value="1.21">Minecraft 1.21 and above</option>
|
||||||
|
<option value="1.20.5">Minecraft 1.20.5 & 1.20.6</option>
|
||||||
|
<option value="1.16">Minecraft 1.16 to 1.20.4</option>
|
||||||
<option value="1.14">Minecraft 1.14 & 1.15</option>
|
<option value="1.14">Minecraft 1.14 & 1.15</option>
|
||||||
<option value="1.13">Minecraft 1.13</option>
|
<option value="1.13">Minecraft 1.13</option>
|
||||||
<option value="1.11">Minecraft 1.11 & 1.12</option>
|
<option value="1.11">Minecraft 1.11 & 1.12</option>
|
||||||
|
@ -116,48 +118,49 @@
|
||||||
|
|
||||||
<input type="text" class="equipment" name="equipShoes" placeholder="Boots" list="list-shoes">
|
<input type="text" class="equipment" name="equipShoes" placeholder="Boots" list="list-shoes">
|
||||||
<datalist id="list-shoes">
|
<datalist id="list-shoes">
|
||||||
<option value="chainmail_boots">
|
<option value="netherite_boots">
|
||||||
<option value="diamond_boots">
|
<option value="diamond_boots">
|
||||||
<option value="golden_boots">
|
<option value="golden_boots">
|
||||||
<option value="netherite_boots">
|
|
||||||
<option value="iron_boots">
|
<option value="iron_boots">
|
||||||
|
<option value="chainmail_boots">
|
||||||
<option value="leather_boots">
|
<option value="leather_boots">
|
||||||
</datalist>
|
</datalist>
|
||||||
<div class="colorfield" id="shoecolor"></div>
|
<div class="colorfield" id="boots_color"></div>
|
||||||
|
|
||||||
<input type="text" class="equipment" name="equipLeggings" placeholder="Leggings" list="list-leggings">
|
<input type="text" class="equipment" name="equipLeggings" placeholder="Leggings" list="list-leggings">
|
||||||
<datalist id="list-leggings">
|
<datalist id="list-leggings">
|
||||||
<option value="chainmail_leggings">
|
<option value="netherite_leggings">
|
||||||
<option value="diamond_leggings">
|
<option value="diamond_leggings">
|
||||||
<option value="golden_leggings">
|
<option value="golden_leggings">
|
||||||
<option value="netherite_leggings">
|
|
||||||
<option value="iron_leggings">
|
<option value="iron_leggings">
|
||||||
|
<option value="chainmail_leggings">
|
||||||
<option value="leather_leggings">
|
<option value="leather_leggings">
|
||||||
</datalist>
|
</datalist>
|
||||||
<div class="colorfield" id="leggingscolor"></div>
|
<div class="colorfield" id="leggings_color"></div>
|
||||||
|
|
||||||
<input type="text" class="equipment" name="equipChestplate" placeholder="Chestplate" list="list-chestplate">
|
<input type="text" class="equipment" name="equipChestplate" placeholder="Chestplate" list="list-chestplate">
|
||||||
<datalist id="list-chestplate">
|
<datalist id="list-chestplate">
|
||||||
<option value="chainmail_chestplate">
|
<option value="netherite_chestplate">
|
||||||
<option value="diamond_chestplate">
|
<option value="diamond_chestplate">
|
||||||
<option value="golden_chestplate">
|
<option value="golden_chestplate">
|
||||||
<option value="netherite_chestplate">
|
|
||||||
<option value="iron_chestplate">
|
<option value="iron_chestplate">
|
||||||
|
<option value="chainmail_chestplate">
|
||||||
<option value="leather_chestplate">
|
<option value="leather_chestplate">
|
||||||
|
<option value="elytra">
|
||||||
</datalist>
|
</datalist>
|
||||||
<div class="colorfield" id="chestplatecolor"></div>
|
<div class="colorfield" id="chestplate_color"></div>
|
||||||
|
|
||||||
<input type="text" class="equipment" name="equipHelmet" placeholder="Helmet" list="list-helmet">
|
<input type="text" class="equipment" name="equipHelmet" placeholder="Helmet" list="list-helmet">
|
||||||
<datalist id="list-helmet">
|
<datalist id="list-helmet">
|
||||||
<option value="turtle_helmet">
|
<option value="netherite_helmet">
|
||||||
<option value="chainmail_helmet">
|
|
||||||
<option value="diamond_helmet">
|
<option value="diamond_helmet">
|
||||||
<option value="golden_helmet">
|
<option value="golden_helmet">
|
||||||
<option value="netherite_helmet">
|
|
||||||
<option value="iron_helmet">
|
<option value="iron_helmet">
|
||||||
|
<option value="chainmail_helmet">
|
||||||
<option value="leather_helmet">
|
<option value="leather_helmet">
|
||||||
|
<option value="turtle_helmet">
|
||||||
</datalist>
|
</datalist>
|
||||||
<div class="colorfield" id="helmetcolor"></div>
|
<div class="colorfield" id="helmet_color"></div>
|
||||||
|
|
||||||
<br>Helmet specifies
|
<br>Helmet specifies
|
||||||
<select id="equipCustomHeadMode">
|
<select id="equipCustomHeadMode">
|
||||||
|
|
752
js/main.js
752
js/main.js
|
@ -355,7 +355,9 @@ const MC_VERSION = Object.freeze({
|
||||||
v1_11: 2,
|
v1_11: 2,
|
||||||
v1_13: 3,
|
v1_13: 3,
|
||||||
v1_14: 4,
|
v1_14: 4,
|
||||||
v1_16: 5
|
v1_16: 5,
|
||||||
|
v1_20_5: 6,
|
||||||
|
v1_21: 7
|
||||||
});
|
});
|
||||||
|
|
||||||
function getMcVersion() {
|
function getMcVersion() {
|
||||||
|
@ -387,10 +389,10 @@ function handleInput(){
|
||||||
equipHelmet = getInput("equipHelmet");
|
equipHelmet = getInput("equipHelmet");
|
||||||
equipCustomHeadMode = $("#equipCustomHeadMode").val();
|
equipCustomHeadMode = $("#equipCustomHeadMode").val();
|
||||||
|
|
||||||
equipColorShoes = $("#shoecolor").css("background-color");
|
equipColorShoes = $("#boots_color").css("background-color");
|
||||||
equipColorLeggings = $("#leggingscolor").css("background-color");
|
equipColorLeggings = $("#leggings_color").css("background-color");
|
||||||
equipColorChestplate = $("#chestplatecolor").css("background-color");
|
equipColorChestplate = $("#chestplate_color").css("background-color");
|
||||||
equipColorHelmet = $("#helmetcolor").css("background-color");
|
equipColorHelmet = $("#helmet_color").css("background-color");
|
||||||
|
|
||||||
customName = getInput("customname");
|
customName = getInput("customname");
|
||||||
showCustomName = getCheckBoxInput("showcustomname");
|
showCustomName = getCheckBoxInput("showcustomname");
|
||||||
|
@ -441,34 +443,63 @@ function updateUI(){
|
||||||
|
|
||||||
if(useEquipment){
|
if(useEquipment){
|
||||||
$("#customequipment").slideDown();
|
$("#customequipment").slideDown();
|
||||||
|
|
||||||
// Hide left hand item input for minecraft 1.8
|
// Hide left hand item input for minecraft 1.8
|
||||||
if(mcVersion == "1.8"){
|
if(mcVersion < MC_VERSION.v1_9) {
|
||||||
$("#equipHandLeft").hide();
|
$("#equipHandLeft").hide();
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
$("#equipHandLeft").show();
|
$("#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
|
else
|
||||||
$("#customequipment").slideUp();
|
$("#customequipment").slideUp();
|
||||||
|
|
||||||
//Different colorinputs for armorparts
|
//Different colorinputs for armorparts
|
||||||
if(isLeatherArmor(equipShoes))
|
if(isLeatherArmor(equipShoes))
|
||||||
$("#shoecolor").slideDown();
|
$("#boots_color").slideDown();
|
||||||
else
|
else
|
||||||
$("#shoecolor").slideUp();
|
$("#boots_color").slideUp();
|
||||||
if(isLeatherArmor(equipLeggings))
|
if(isLeatherArmor(equipLeggings))
|
||||||
$("#leggingscolor").slideDown();
|
$("#leggings_color").slideDown();
|
||||||
else
|
else
|
||||||
$("#leggingscolor").slideUp();
|
$("#leggings_color").slideUp();
|
||||||
if(isLeatherArmor(equipChestplate))
|
if(isLeatherArmor(equipChestplate))
|
||||||
$("#chestplatecolor").slideDown();
|
$("#chestplate_color").slideDown();
|
||||||
else
|
else
|
||||||
$("#chestplatecolor").slideUp();
|
$("#chestplate_color").slideUp();
|
||||||
if(isLeatherArmor(equipHelmet))
|
if(isLeatherArmor(equipHelmet))
|
||||||
$("#helmetcolor").slideDown();
|
$("#helmet_color").slideDown();
|
||||||
else
|
else
|
||||||
$("#helmetcolor").slideUp();
|
$("#helmet_color").slideUp();
|
||||||
|
|
||||||
// Link to minecraft-heads.com
|
// Link to minecraft-heads.com
|
||||||
if(equipCustomHeadMode == "givecode"){
|
if(equipCustomHeadMode == "givecode"){
|
||||||
|
@ -541,321 +572,345 @@ function updateUI(){
|
||||||
mSkull.visible = equipHelmet != "";
|
mSkull.visible = equipHelmet != "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateCode(){
|
function generateCode() {
|
||||||
var code = "/summon armor_stand ~ ~ ~ {" //in 1.13, positions are no longer center-corrected. Adding .5 makes it centered. However for players it is already center-corrected
|
const tags = {
|
||||||
|
Invisible: invisible || null,
|
||||||
if (!give) {
|
Invulnerable: invulnerable || null,
|
||||||
// Old entity name
|
PersistenceRequired: persistencerequired || null,
|
||||||
if (mcVersion <= MC_VERSION.v1_9) {
|
NoBasePlate: noBasePlate || null,
|
||||||
code = "/summon ArmorStand ~ ~ ~ {";
|
NoGravity: noGravity || null,
|
||||||
} else if (mcVersion == MC_VERSION.v1_11) {
|
ShowArms: showArms || null,
|
||||||
code = "/summon armor_stand ~ ~ ~ {";
|
Small: small || null,
|
||||||
} else {
|
Marker: marker || null,
|
||||||
centercorrected ? code = "/summon armor_stand ~ ~-0.5 ~ {" : code = "/summon armor_stand ~ ~ ~ {"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(mcVersion <= MC_VERSION.v1_11){
|
|
||||||
code = "/give @p minecraft:armor_stand 1 0 {EntityTag:{";
|
|
||||||
} else {
|
|
||||||
code = "/give @p armor_stand{EntityTag:{"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var tags = [];
|
Rotation: (rotation != 0) ? [ new NBTFloat(rotation) ] : null,
|
||||||
|
|
||||||
//CheckBoxes
|
CustomNameVisible: showCustomName || null,
|
||||||
if(invisible)
|
CustomName: (customName) ? generateCustomName() : null,
|
||||||
tags.push("Invisible:1b");
|
|
||||||
if(invulnerable)
|
|
||||||
tags.push("Invulnerable:1b");
|
|
||||||
if(persistencerequired)
|
|
||||||
tags.push("PersistenceRequired:1b");
|
|
||||||
if(noBasePlate)
|
|
||||||
tags.push("NoBasePlate:1b");
|
|
||||||
if(noGravity)
|
|
||||||
tags.push("NoGravity:1b");
|
|
||||||
if(showArms)
|
|
||||||
tags.push("ShowArms:1b");
|
|
||||||
if(small)
|
|
||||||
tags.push("Small:1b");
|
|
||||||
if(marker)
|
|
||||||
tags.push("Marker:1b");
|
|
||||||
|
|
||||||
//Sliders
|
DisabledSlots: (useDisabledSlots) ? calculateDisabledSlotsFlag() : null,
|
||||||
if(rotation != 0)
|
Pose: generatePose(),
|
||||||
tags.push("Rotation:["+rotation+"f]");
|
};
|
||||||
|
|
||||||
// Equipment
|
// Equipment
|
||||||
if(useEquipment){
|
if (useEquipment) {
|
||||||
// Old 1.8 Equipment format
|
|
||||||
if (mcVersion == MC_VERSION.v1_8) {
|
if (mcVersion == MC_VERSION.v1_8) {
|
||||||
var armor = [];
|
// Old 1.8 Equipment format
|
||||||
|
// Equipment: [ RightHand, Boots, Leggings, Chestplate, Helmet ]
|
||||||
armor.push(getHandRightItem());
|
const armorItems = generateArmorItems();
|
||||||
armor.push(getShoesItem());
|
const handItems = generateHandItems();
|
||||||
armor.push(getLeggingsItem());
|
tags.Equipment = armorItems.splice(0, 0, handItems[0]);
|
||||||
armor.push(getChestplateItem());
|
|
||||||
armor.push(getHeadItem());
|
|
||||||
|
|
||||||
tags.push("Equipment:["+armor.join(",")+"]");
|
|
||||||
}
|
|
||||||
// New 1.9+ Equipment format
|
|
||||||
else{
|
|
||||||
var armor = [];
|
|
||||||
|
|
||||||
armor.push(getShoesItem());
|
|
||||||
armor.push(getLeggingsItem());
|
|
||||||
armor.push(getChestplateItem());
|
|
||||||
armor.push(getHeadItem());
|
|
||||||
|
|
||||||
tags.push("ArmorItems:["+armor.join(",")+"]");
|
|
||||||
|
|
||||||
var hands = [];
|
|
||||||
|
|
||||||
hands.push(getHandRightItem());
|
|
||||||
hands.push(getHandLeftItem());
|
|
||||||
|
|
||||||
tags.push("HandItems:["+hands.join(",")+"]");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide netherite armour for lower versions
|
|
||||||
if (mcVersion <= MC_VERSION.v1_11) {
|
|
||||||
$("#list-helmet").empty().append(helmetList.filter("[value!=netherite_helmet]").filter("[value!=turtle_helmet]"));
|
|
||||||
$("#list-chestplate").empty().append(chestplateList.filter("[value!=netherite_chestplate]").filter("[value!=turtle_chestplate]"));
|
|
||||||
$("#list-leggings").empty().append(leggingsList.filter("[value!=netherite_leggings]").filter("[value!=turtle_leggings]"));
|
|
||||||
$("#list-shoes").empty().append(bootsList.filter("[value!=netherite_boots]").filter("[value!=turtle_boots]"));
|
|
||||||
|
|
||||||
} else if (mcVersion <= MC_VERSION.v1_14) {
|
|
||||||
$("#list-helmet").empty().append(helmetList.filter("[value!=netherite_helmet]"));
|
|
||||||
$("#list-chestplate").empty().append(chestplateList.filter("[value!=netherite_chestplate]"));
|
|
||||||
$("#list-leggings").empty().append(leggingsList.filter("[value!=netherite_leggings]"));
|
|
||||||
$("#list-shoes").empty().append(bootsList.filter("[value!=netherite_boots]"));
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$("#list-helmet").empty().append(helmetList);
|
// New 1.9+ Equipment format
|
||||||
$("#list-chestplate").empty().append(chestplateList);
|
if (equipShoes != "" || equipLeggings != "" || equipChestplate != "" || equipHelmet != "") {
|
||||||
$("#list-leggings").empty().append(leggingsList);
|
tags.ArmorItems = generateArmorItems();
|
||||||
$("#list-shoes").empty().append(bootsList);
|
}
|
||||||
|
|
||||||
|
if (equipHandRight != "" || equipHandLeft != "") {
|
||||||
|
tags.HandItems = generateHandItems();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom name
|
// Scoreboard tags
|
||||||
if(customName) {
|
|
||||||
let name = [];
|
|
||||||
if (mcVersion <= MC_VERSION.v1_11) {
|
|
||||||
tags.push(`CustomName:"${customName}"`);
|
|
||||||
|
|
||||||
} else if (mcVersion == MC_VERSION.v1_13) {
|
|
||||||
name.push(getName());
|
|
||||||
name.push(getNameColor());
|
|
||||||
name.push(getNameBold());
|
|
||||||
name.push(getNameItalic());
|
|
||||||
name.push(getNameObfuscated());
|
|
||||||
name.push(getNameStrikethrough());
|
|
||||||
|
|
||||||
tags.push(`CustomName:"{${name.join("")}}"`);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// CustomNames from 1.14+ can now use single quotes to contain json
|
|
||||||
// Replace escaped double quotes with single quotes to make it look pretty
|
|
||||||
name.push(getName().replaceAll("\\", ""));
|
|
||||||
name.push(getNameColor().replaceAll("\\", ""));
|
|
||||||
name.push(getNameBold().replaceAll("\\", ""));
|
|
||||||
name.push(getNameItalic().replaceAll("\\", ""));
|
|
||||||
name.push(getNameObfuscated().replaceAll("\\", ""));
|
|
||||||
name.push(getNameStrikethrough().replaceAll("\\", ""));
|
|
||||||
tags.push(`CustomName:'{${name.join("")}}'`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(showCustomName)
|
|
||||||
tags.push("CustomNameVisible:1b");
|
|
||||||
|
|
||||||
//Scoreboard tags
|
|
||||||
if (scoreboardTags) {
|
if (scoreboardTags) {
|
||||||
const tagsList = scoreboardTags.split(',');
|
const tagsList = scoreboardTags.split(',');
|
||||||
if (!tagsList[tagsList.length - 1].trim())
|
if (!tagsList[tagsList.length - 1].trim()) {
|
||||||
tagsList.pop();
|
tagsList.pop();
|
||||||
|
}
|
||||||
for (let i = 0; i < tagsList.length; i++)
|
|
||||||
tagsList[i] = `"${tagsList[i].trim()}"`;
|
|
||||||
|
|
||||||
tags.push(`Tags:[${tagsList.join(",")}]`);
|
tags.Tags = tagsList.map(value => value.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
//DisabledSlots
|
// Generate the final command
|
||||||
if(useDisabledSlots){
|
if (give && mcVersion > MC_VERSION.v1_16) {
|
||||||
tags.push("DisabledSlots:"+calculateDisabledSlotsFlag());
|
tags.id = "minecraft:armor_stand";
|
||||||
}
|
}
|
||||||
|
|
||||||
//Now the pose
|
const parsedTags = NBT.stringify(tags);
|
||||||
var pose = [];
|
|
||||||
if(!isZero(body))
|
|
||||||
pose.push("Body:"+getJSONArray(body));
|
|
||||||
if(!isZero(head))
|
|
||||||
pose.push("Head:"+getJSONArray(head));
|
|
||||||
if(!isZero(leftLeg))
|
|
||||||
pose.push("LeftLeg:"+getJSONArray(leftLeg));
|
|
||||||
if(!isZero(rightLeg))
|
|
||||||
pose.push("RightLeg:"+getJSONArray(rightLeg));
|
|
||||||
if(showArms){
|
|
||||||
if(!isZero(leftArm))
|
|
||||||
pose.push("LeftArm:"+getJSONArray(leftArm));
|
|
||||||
if(!isZero(rightArm))
|
|
||||||
pose.push("RightArm:"+getJSONArray(rightArm));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(pose.length > 0)
|
|
||||||
tags.push("Pose:{"+pose.join(",")+"}");
|
|
||||||
|
|
||||||
code += tags.join(",");
|
|
||||||
code += "}";
|
|
||||||
if (give) {
|
if (give) {
|
||||||
code += "}";
|
let command = "/give @p ";
|
||||||
if (mcVersion > MC_VERSION.v_11) {
|
|
||||||
code += " 1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getHandRightItem(){
|
|
||||||
if(equipHandRight == "") return "{}";
|
|
||||||
return "{id:\""+equipHandRight+"\",Count:1b}";
|
|
||||||
}
|
|
||||||
|
|
||||||
function getHandLeftItem(){
|
|
||||||
if(equipHandLeft == "") return "{}";
|
|
||||||
return "{id:\""+equipHandLeft+"\",Count:1b}";
|
|
||||||
}
|
|
||||||
|
|
||||||
function getShoesItem(){
|
|
||||||
if(equipShoes == "") return "{}";
|
|
||||||
return "{id:\""+equipShoes+"\",Count:1b"
|
|
||||||
+getLeatherColorString($("#shoecolor"), isLeatherArmor(equipShoes))
|
|
||||||
+"}";
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLeggingsItem(){
|
|
||||||
if(equipLeggings == "") return "{}";
|
|
||||||
return "{id:\""+equipLeggings+"\",Count:1b"
|
|
||||||
+getLeatherColorString($("#leggingscolor"), isLeatherArmor(equipLeggings))
|
|
||||||
+"}";
|
|
||||||
}
|
|
||||||
|
|
||||||
function getChestplateItem(){
|
|
||||||
if(equipChestplate == "") return "{}";
|
|
||||||
return "{id:\""+equipChestplate+"\",Count:1b"
|
|
||||||
+getLeatherColorString($("#chestplatecolor"), isLeatherArmor(equipChestplate))
|
|
||||||
+"}";
|
|
||||||
}
|
|
||||||
|
|
||||||
function getHeadItem(){
|
|
||||||
if(equipHelmet == "") return "{}";
|
|
||||||
|
|
||||||
// Use input as item
|
|
||||||
if(equipCustomHeadMode == "item"){
|
|
||||||
return "{id:\""+equipHelmet+"\",Count:1b"
|
|
||||||
+getLeatherColorString($("#helmetcolor"), isLeatherArmor(equipHelmet))
|
|
||||||
+"}";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use input as player name
|
|
||||||
else if(equipCustomHeadMode == "player"){
|
|
||||||
if (mcVersion <= MC_VERSION.v1_11) {
|
if (mcVersion <= MC_VERSION.v1_11) {
|
||||||
return "{id:\"skull\",Count:1b,Damage:3b,tag:{SkullOwner:\""+equipHelmet+"\"}}";
|
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 {
|
} else {
|
||||||
return "{id:\"player_head\",Count:1b,tag:{SkullOwner:\""+equipHelmet+"\"}}";
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Use input as url
|
function generateCustomName() {
|
||||||
// Best reference: http://redd.it/24quwx
|
if (mcVersion <= MC_VERSION.v1_11) {
|
||||||
else if(equipCustomHeadMode == "url"){
|
// Versions less than 1.12 did not support styles
|
||||||
var base64Value = btoa('{"textures":{"SKIN":{"url":"'+equipHelmet+'"}}}');
|
return customName;
|
||||||
|
|
||||||
if (mcVersion <= MC_VERSION.v1_11) {
|
|
||||||
return '{id:"skull",Count:1b,Damage:3b,tag:{SkullOwner:{Id:"'+generateUUID()+'",Properties:{textures:[{Value:"'+base64Value+'"}]}}}}';
|
|
||||||
} else if (mcVersion <= MC_VERSION.v1_14) {
|
|
||||||
return '{id:"minecraft:player_head",Count:1b,tag:{SkullOwner:{Id:"'+generateUUID()+'",Properties:{textures:[{Value:"'+base64Value+'"}]}}}}';
|
|
||||||
} else {
|
|
||||||
return '{id:"minecraft:player_head",Count:1b,tag:{SkullOwner:{Id:'+generateIntArray()+',Properties:{textures:[{Value:"'+base64Value+'"}]}}}}';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse give code
|
let props = {};
|
||||||
else if(equipCustomHeadMode == "givecode"){
|
|
||||||
|
|
||||||
// Give Code in this format: /give @p skull 1 3 {display:{Name:"Some Name"},SkullOwner:{Id:"a74719ce...
|
|
||||||
// Give code in 1.13 has changed to this format: /give @p player_head{display:{Name:"Some Name"},SkullOwner:{Id:"a74719ce...
|
|
||||||
if(equipHelmet.indexOf("SkullOwner:{") >= 0){
|
|
||||||
var skullOwnerRaw = equipHelmet.substring(equipHelmet.indexOf("SkullOwner"));
|
|
||||||
var parsed = "";
|
|
||||||
var bracketCounter = 0;
|
|
||||||
var bracketsStarted = false;
|
|
||||||
|
|
||||||
for(var i = 0; i < skullOwnerRaw.length; i++){
|
if (customName) {
|
||||||
var c = skullOwnerRaw[i];
|
props.text = customName;
|
||||||
|
}
|
||||||
|
|
||||||
if(c == "{") bracketCounter++;
|
if (nameColor) {
|
||||||
if(c == "}") bracketCounter--;
|
props.color = nameColor;
|
||||||
|
}
|
||||||
|
|
||||||
parsed += c;
|
if (nameBold) {
|
||||||
if(bracketCounter == 0 && bracketsStarted) break;
|
props.bold = nameBold;
|
||||||
if(c == ":") bracketsStarted = true;
|
}
|
||||||
|
|
||||||
|
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_11) {
|
if (mcVersion <= MC_VERSION.v1_16) {
|
||||||
return '{id:"skull",Count:1b,Damage:3b,tag:{'+parsed+'}}';
|
data.tag = { SkullOwner: equipHelmet };
|
||||||
} else {
|
} else {
|
||||||
return '{id:"player_head",Count:1b,tag:{'+parsed+'}}';
|
data.components = {
|
||||||
}
|
profile: { name: equipHelmet }
|
||||||
}
|
};
|
||||||
// Give Code in this format: /give @p skull 1 3 {SkullOwner:"playername"} (quotes optional)
|
|
||||||
// Give code in 1.13 has changed to this format: /give @p player_head{display:{Name:"Some Name"},SkullOwner:{Id"a74719ce...
|
|
||||||
else{
|
|
||||||
var skullOwnerRaw = equipHelmet.substring(equipHelmet.indexOf("SkullOwner:"));
|
|
||||||
skullOwnerRaw = skullOwnerRaw.substring(0, skullOwnerRaw.indexOf("}"));
|
|
||||||
if (mcVersion <= MC_VERSION.v1_11) {
|
|
||||||
return '{id:"skull",Count:1b,Damage:3b,tag:{'+skullOwnerRaw+'}}';
|
|
||||||
} else {
|
|
||||||
return '{id:"player_head",Count:1b,tag:{'+skullOwnerRaw+'}}';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 getName() {
|
function generateHandItems() {
|
||||||
if (!customName) return ""
|
function generateHandItem(item) {
|
||||||
return `\\"text\\":\\"${customName}\\"`
|
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 getNameColor() {
|
function generatePose() {
|
||||||
if (nameColor == "") return ""
|
const pose = {};
|
||||||
return `,\\"color\\":\\"${nameColor}\\"`
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNameBold() {
|
if (!isZero(body)) {
|
||||||
if (!nameBold) return ""
|
pose.Body = toNBTFloatArray(body);
|
||||||
return `,\\"bold\\":\\"true\\"`
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function getNameItalic() {
|
if (!isZero(head)) {
|
||||||
if (!nameItalic) return ""
|
pose.Head = toNBTFloatArray(head);
|
||||||
return `,\\"italic\\":\\"true\\"`
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function getNameStrikethrough() {
|
if (!isZero(leftLeg)) {
|
||||||
if (!nameStrikethrough) return ""
|
pose.LeftLeg = toNBTFloatArray(leftLeg);
|
||||||
return `,\\"strikethrough\\":\\"true\\"`
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function getNameObfuscated() {
|
if (!isZero(rightLeg)) {
|
||||||
if (!nameObfuscated) return ""
|
pose.RightLeft = toNBTFloatArray(rightLeg);
|
||||||
return `,\\"obfuscated\\":\\"true\\"`
|
}
|
||||||
|
|
||||||
|
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() {
|
function calculateDisabledSlotsFlag() {
|
||||||
|
@ -887,11 +942,12 @@ function calculateDisabledSlotsFlag() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isZero(vector){
|
function isZero(vector) {
|
||||||
return vector.x == 0 && vector.y == 0 && vector.z == 0;
|
return vector.x == 0 && vector.y == 0 && vector.z == 0;
|
||||||
}
|
}
|
||||||
function getJSONArray(vector){
|
|
||||||
return "["+vector.x+"f,"+vector.y+"f,"+vector.z+"f]";
|
function toNBTFloatArray(vector) {
|
||||||
|
return [ new NBTFloat(vector.x), new NBTFloat(vector.y), new NBTFloat(vector.z) ];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMouseDeltaX(){
|
function getMouseDeltaX(){
|
||||||
|
@ -912,27 +968,23 @@ function getMouseDeltaY(){
|
||||||
function render(){
|
function render(){
|
||||||
renderer.render(scene, camera);
|
renderer.render(scene, camera);
|
||||||
|
|
||||||
var deltaTime = clock.getDelta();
|
|
||||||
|
|
||||||
armorstandWrapper.rotation.y = rotY + getMouseDeltaX();
|
armorstandWrapper.rotation.y = rotY + getMouseDeltaX();
|
||||||
armorstandWrapper.rotation.x = rotX + getMouseDeltaY();
|
armorstandWrapper.rotation.x = rotX + getMouseDeltaY();
|
||||||
|
|
||||||
requestAnimationFrame(render);
|
requestAnimationFrame(render);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ---- Additional functions
|
// ---- Additional functions
|
||||||
|
|
||||||
// From here: http://stackoverflow.com/a/8809472/1456971
|
function generateUUID() {
|
||||||
function generateUUID(){
|
// From here: http://stackoverflow.com/a/8809472/1456971
|
||||||
var d = new Date().getTime();
|
var d = new Date().getTime();
|
||||||
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||||
var r = (d + Math.random()*16)%16 | 0;
|
var r = (d + Math.random()*16)%16 | 0;
|
||||||
d = Math.floor(d/16);
|
d = Math.floor(d/16);
|
||||||
return (c=='x' ? r : (r&0x3|0x8)).toString(16);
|
return (c=='x' ? r : (r&0x3|0x8)).toString(16);
|
||||||
});
|
});
|
||||||
|
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -950,7 +1002,7 @@ function generateIntArray() {
|
||||||
ints.push(UUID.getInt32(i*4));
|
ints.push(UUID.getInt32(i*4));
|
||||||
}
|
}
|
||||||
|
|
||||||
return '[I;' + ints.join(",") + ']';
|
return new NBTArrayInt(ints);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDecimalRGB(rgb){
|
function getDecimalRGB(rgb){
|
||||||
|
@ -967,19 +1019,8 @@ function getDecimalRGB(rgb){
|
||||||
return (r << 16) | (g << 8) | b;
|
return (r << 16) | (g << 8) | b;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isLeatherArmor(item){
|
function isLeatherArmor(item) {
|
||||||
if(item == null)
|
return item ? item.startsWith("leather_") : false;
|
||||||
return false;
|
|
||||||
return item.indexOf("leather") == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pass the colorpicker element as element. If condition is true, it will return a proper datatag for use in items, otherwise it will return an empty string.
|
|
||||||
function getLeatherColorString(element, condition){
|
|
||||||
if(condition){
|
|
||||||
var rgb = getDecimalRGB(element.css("background-color"));
|
|
||||||
return ",tag:{display:{color:"+rgb+"}}";
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rotate three.js mesh to fit the minecraft rotation
|
// Rotate three.js mesh to fit the minecraft rotation
|
||||||
|
@ -1046,10 +1087,10 @@ function saveData() {
|
||||||
helmet_specifies: $("#equipCustomHeadMode").val(),
|
helmet_specifies: $("#equipCustomHeadMode").val(),
|
||||||
|
|
||||||
leather_colours: {
|
leather_colours: {
|
||||||
helmet: $(`#helmetcolor`).css(`background-color`),
|
helmet: $(`#helmet_color`).css(`background-color`),
|
||||||
chestplate: $(`#chestplatecolor`).css(`background-color`),
|
chestplate: $(`#chestplate_color`).css(`background-color`),
|
||||||
leggings: $(`#leggingscolor`).css(`background-color`),
|
leggings: $(`#leggings_color`).css(`background-color`),
|
||||||
boots: $(`#shoecolor`).css(`background-color`)
|
boots: $(`#boots_color`).css(`background-color`)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1160,15 +1201,10 @@ function loadData(data) {
|
||||||
$(`input[name=equipHandLeft]`).val(data.equipment.hands.left);
|
$(`input[name=equipHandLeft]`).val(data.equipment.hands.left);
|
||||||
$(`#equipCustomHeadMode`).val(data.equipment.helmet_specifies);
|
$(`#equipCustomHeadMode`).val(data.equipment.helmet_specifies);
|
||||||
|
|
||||||
$(`#helmetcolor`).css(`background-color`, data.equipment.leather_colours.helmet);
|
$(`#helmet_color`).css(`background-color`, data.equipment.leather_colours.helmet);
|
||||||
$(`#chestplatecolor`).css(`background-color`, data.equipment.leather_colours.chestplate);
|
$(`#chestplate_color`).css(`background-color`, data.equipment.leather_colours.chestplate);
|
||||||
$(`#leggingscolor`).css(`background-color`, data.equipment.leather_colours.leggings);
|
$(`#leggings_color`).css(`background-color`, data.equipment.leather_colours.leggings);
|
||||||
$(`#shoecolor`).css(`background-color`, data.equipment.leather_colours.boots);
|
$(`#boots_color`).css(`background-color`, data.equipment.leather_colours.boots);
|
||||||
|
|
||||||
getLeatherColorString($("#helmetcolor"))
|
|
||||||
getLeatherColorString($("#chestplatecolor"))
|
|
||||||
getLeatherColorString($("#leggingscolor"))
|
|
||||||
getLeatherColorString($("#shoecolor"))
|
|
||||||
|
|
||||||
//custom name
|
//custom name
|
||||||
$(`#customname`).val(data.custom_name.name);
|
$(`#customname`).val(data.custom_name.name);
|
||||||
|
@ -1206,7 +1242,6 @@ function loadData(data) {
|
||||||
$(`#pW`).prop(`checked`, data.lock_slot_interaction.place.weapons);
|
$(`#pW`).prop(`checked`, data.lock_slot_interaction.place.weapons);
|
||||||
|
|
||||||
handleInput();
|
handleInput();
|
||||||
//console.log(`done loading!`)
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
alert(`An error occurred while loading the creation.`);
|
alert(`An error occurred while loading the creation.`);
|
||||||
|
@ -1220,3 +1255,76 @@ function deleteSave(data) {
|
||||||
loadScreen();
|
loadScreen();
|
||||||
alert(`${data} has been deleted!`);
|
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(",")
|
||||||
|
+ "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue