fix commit

This commit is contained in:
sainagh
2026-07-25 16:20:42 -05:00
parent 9396611ce0
commit c6df59caf7
3226 changed files with 209810 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
#modloaded randomtweaker
#priority -10
#reloadable
import mods.jei.JEI;
import mods.randomtweaker.jei.IJeiPanel;
import mods.randomtweaker.jei.IJeiUtils;
import scripts.enchantwrapper.EnchantUtil;
import scripts.enchantwrapper.EnchantUtil.WrapperRegistry;
var superenchantJEI as IJeiPanel = JEI.createJei("custom_superenchant", "Superenchants");
superenchantJEI.setModid("MeatballCraft");
superenchantJEI.setIcon(<contenttweaker:superenchant_wrapper>);
superenchantJEI.addRecipeCatalyst(<contenttweaker:superenchant_wrapper>);
superenchantJEI.setBackground(IJeiUtils.createBackground(150, 55));
superenchantJEI.addSlot(IJeiUtils.createItemSlot(40, 25, true)); // input
superenchantJEI.addSlot(IJeiUtils.createItemSlot(95, 25, false)); // output
superenchantJEI.addSlot(IJeiUtils.createItemSlot(110, 0, false, false)); // list of enchants
superenchantJEI.addElement(IJeiUtils.createArrowElement(64, 25, 0));
superenchantJEI.addElement(IJeiUtils.createImageElement("mouseLeft", 68, 6, 13, 14, 0, 0, "contenttweaker:textures/gui/mouse_right.png", 16, 16));
superenchantJEI.onTooltip(function(mouseX, mouseY) as string[]{
if (mouseX <= 81 && mouseX >= 68 && mouseY <= 22 && mouseY >= 6) {
return ["Right-click"];
}
else if (mouseX <= 109 && mouseX >= 95 && mouseY <= 18 && mouseY >= 4) {
return ["Will have these enchants"];
}
return [];
});
superenchantJEI.addElement(IJeiUtils.createImageElement("enchantsIn", 95, 4, 14, 14, 0, 0, "contenttweaker:textures/gui/arrow_left_down.png", 18, 14));
superenchantJEI.register();
for wrapperItem in WrapperRegistry.INSTANCE.get() {
val recipe = JEI.createJeiRecipe("custom_superenchant");
recipe.addInput(wrapperItem);
recipe.setOutputs(EnchantUtil.unwrapJEI(wrapperItem));
recipe.build();
}
JEI.addItemNBTSubtype(<contenttweaker:superenchant_wrapper>);
+145
View File
@@ -0,0 +1,145 @@
#priority 10
#reloadable
import crafttweaker.data.IData;
import crafttweaker.enchantments.IEnchantment;
import crafttweaker.item.IItemStack;
import mods.contenttweaker.ResourceLocation;
import mods.zenutils.StaticString;
/**
Same as IEnchantment#makeTag(), but uses int enchant id.
Useful if you have JEID extending enchantment ids.
**/
function makeIntTag(enchant as IEnchantment, isBook as bool) as IData {
var key = "ench";
if (isBook) {
key = "StoredEnchantments";
}
return {
`${key}`: [{
id: enchant.definition.id,
lvl: enchant.level
}]
} as IData;
}
/**
From a superenchant_wrapper item, return the actual superenchanted item.
**/
function unwrap(item as IItemStack) as IItemStack {
if (item.definition.id != "contenttweaker:superenchant_wrapper" || !item.hasTag) {
return null;
}
var out as IItemStack = <item:${item.tag.id}>.withDamage(item.damage);
var enchList = {} as IData;
// Convert delayed enchants to actual enchants.
for enchant in item.tag.delayedEnch.asList() {
// A singleton map of the enchant.
for name, level in enchant.asMap() {
enchList += makeIntTag(<enchantment:${name}>.makeEnchantment(level), false);
}
}
out = out.withTag(item.tag.tag + enchList);
return out;
}
/**
From a superenchant_wrapper item, return a representation of the superenchanted item, split in two items.
1) The actual item to be superenchanted, with all NBT data EXCEPT enchants.
2) An enchanted book with a list of all the enchants that will be applied to the item.
This two-fold representation is needed to display the correct enchants after JEI has already loaded
the recipe, and to preserve the usual "Show recipe/usages" functionality.
**/
function unwrapJEI(wrapper as IItemStack) as IItemStack[] {
if (wrapper.definition.id != "contenttweaker:superenchant_wrapper" || !wrapper.hasTag) {
return null;
}
var base as IItemStack = <item:${wrapper.tag.id}>
.withDamage(wrapper.damage)
.withTag(wrapper.tag.tag);
// Use an extra tag to make sure only this item has its tooltip removed.
val fromJEI = {
fromJEI: true
} as IData;
base = base.withTag(base.tag + fromJEI);
// Add a dummy enchant to the item for the glow.
val dummyEnchant = <enchantment:minecraft:protection>.makeEnchantment(1);
base.addEnchantment(dummyEnchant);
base.removeTooltip(dummyEnchant.displayName);
// Unique identifier for the book when running addAdvancedTooltip.
val identifier = {
id: wrapper.tag.id,
delayedEnch: wrapper.tag.delayedEnch
} as IData;
var book as IItemStack = <minecraft:enchanted_book>.withTag(identifier);
// Setup transformer on book to run later.
// This transforms the book, not the item, because we want to keep recipe lookup functionality
// for the superenchanted item.
var transformed = book.transformNew(function(item) {
var enchList = {} as IData;
for enchant in wrapper.tag.delayedEnch.asList() {
for name, level in enchant.asMap() {
enchList += makeIntTag(<enchantment:${name}>.makeEnchantment(level), true);
}
}
return item.withTag(enchList).withLore(["The superenchanted item will have these enchants"]);
});
// Run the transformer on book tooltip hover.
book.addAdvancedTooltip(function(item) {
transformed.applyNewTransform(item);
return null;
});
return [base, book] as IItemStack[];
}
/**
Holds a map of (ResourceLocation name, int level) enchantment entries with
predictable iteration order (insertion order).
Making an instance would look something like this:
`EnchantMap().add(name1, level1).add(name2, level2)...;`
**/
zenClass EnchantMap {
val enchants as int[ResourceLocation];
zenConstructor() {
enchants = {} as int[ResourceLocation]$orderly;
}
function add(name as string, level as int) as EnchantMap {
if (StaticString.countMatches(name, ':') != 1) {
print("EnchantWrapper.EnchantMap.zs - Add to map failed! name: " + name + " level:" + level);
}
else {
enchants[ResourceLocation.create(name)] = level;
}
return this;
}
function getMap() as int[ResourceLocation] {
return this.enchants;
}
}
/**
Registry that holds all registered superenchant_wrapper items.
For use in EnchantWrapper.SuperEnchantedItem.
**/
zenClass WrapperRegistry {
static INSTANCE = WrapperRegistry();
val wrapperItems as IItemStack[];
zenConstructor() {
wrapperItems = [] as IItemStack[];
}
function add(wrapper as IItemStack) {
wrapperItems += wrapper;
}
function get() as IItemStack[] {
return this.wrapperItems;
}
}
+127
View File
@@ -0,0 +1,127 @@
#modloaded contenttweaker zenutils
#loader crafttweaker
#priority 9
#reloadable
import crafttweaker.data.IData;
import crafttweaker.item.IItemStack;
import mods.contenttweaker.ResourceLocation;
import mods.zenutils.DataUpdateOperation.APPEND;
import mods.zenutils.StaticString;
import scripts.enchantwrapper.EnchantUtil;
import scripts.enchantwrapper.EnchantUtil.EnchantMap;
import scripts.enchantwrapper.EnchantUtil.WrapperRegistry;
/**
This script makes a wrapper item for enchanted items.
This fixes a problem with existing worlds where new enchants being added/removed
would cause CT recipes that output enchanted items to have the wrong enchants
due to a shift in enchantment ids that CT cannot account for.
**/
/**
Controls the actual conversion of the wrapper item to the enchanted item on right click.
**/
<cotItem:superenchant_wrapper>.itemRightClick = function(stack, world, player, hand) {
if (world.isRemote()) {
return "FAIL";
}
val result as IItemStack = EnchantUtil.unwrap(stack);
if (isNull(result)) {
return "FAIL";
}
player.give(result);
if (!player.creative) {
stack.shrink(1);
}
return "SUCCESS";
};
zenClass SuperEnchantedItem {
// The wrapperItem.
var wrapperItem as IItemStack;
// The NBT to write to the wrapper.
var mapNBT as IData;
/**
Constructor to make the superenchant_wrapper item and write its necessary data
to NBT. To get the resultant wrapper IItemStack, call:
`SuperEnchantedItem(IItemStack item, EnchantMap enchants).getItem()`
item is the IItemStack to be superenchanted, possibly with any metadata/NBT.
enchants expects a populated EnchantMap object.
**/
zenConstructor(item as IItemStack, enchants as EnchantMap) {
this.mapNBT = {} as IData;
this.wrapperItem = <contenttweaker:superenchant_wrapper>;
writeItemData(item, enchants.getMap());
this.wrapperItem = this.wrapperItem.withTag(this.mapNBT);
WrapperRegistry.INSTANCE.add(this.getItem());
}
// Writes all necessary item data to wrapper's NBT.
function writeItemData(item as IItemStack, enchants as int[ResourceLocation]) {
this.mapNBT += {
"id": item.definition.id
} as IData;
if (item.isDamageable) {
this.mapNBT += {
"damage": item.damage
} as IData;
}
if (item.hasTag) {
this.mapNBT += {
"tag": item.tag - "ench"
} as IData;
}
this.mapNBT += writeDelayedEnchants(enchants);
writeDisplayData(item);
}
// Write enchants to "delayedEnch" tag.
function writeDelayedEnchants(enchants as int[ResourceLocation]) as IData {
var enchantTags = {
"delayedEnch": {
}
} as IData;
for name, level in enchants {
enchantTags = enchantTags.deepUpdate(this.writeTag(name, level), APPEND);
}
return enchantTags;
}
// Writes tag for a single enchant.
function writeTag(loc as ResourceLocation, level as int) as IData {
val enchantTag = {
"delayedEnch": [{
`${loc.domain}:${loc.path}`: level
}]
} as IData;
return enchantTag;
}
// Writes the name/tooltip to display on the wrapper item.
function writeDisplayData(item as IItemStack) {
var info = ["§r§fItem: " + item.displayName] as string[];
for enchantEntry in this.mapNBT.delayedEnch.asList() {
for name, level in enchantEntry.asMap() {
val enchant = <enchantment:${name}>.makeEnchantment(level);
// Localization for level isn't loaded yet for some reason, let's just use the numeric level if needed.
info += "§r§7" + StaticString.remove(enchant.displayName, "enchantment.level.");
}
}
// Just use an IItemStack to easily store and copy lore.
val tempCopy = this.wrapperItem.withLore(info) as IItemStack;
this.mapNBT += {
"display": {
"Lore": tempCopy.tag.display.Lore,
}
} as IData;
}
function getItem() as IItemStack {
return this.wrapperItem;
}
}
+4
View File
@@ -0,0 +1,4 @@
The scripts in this folder are not meant to be modified unless you need to change some functionality.
You may want to change the modid for the JEI tab in EnchantJEI.zs. This can be any string, not just a specific modid.
These scripts come from the "CT-EnchantWrapper" repo, see the repo's README for more details.
Source: https://github.com/jchung01/CT-EnchantWrapper/
+9
View File
@@ -0,0 +1,9 @@
#loader contenttweaker
import mods.contenttweaker.VanillaFactory;
import mods.contenttweaker.ResourceLocation;
// The CoT item
val wrapperItem = VanillaFactory.createItem("superenchant_wrapper");
wrapperItem.maxStackSize = 1;
wrapperItem.rarity = "epic";
wrapperItem.register();